Skip to content
This repository has been archived by the owner on Aug 4, 2023. It is now read-only.

NFT with Royalty #40

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
499 changes: 499 additions & 0 deletions contracts/bin/nft_royalty_faucet.tz

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion contracts/ligo/fa2/fa2_errors.mligo
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ and it is initiated neither by the token owner nor a permitted operator
let fa2_not_operator = "FA2_NOT_OPERATOR"
(**
`update_operators` entrypoint is invoked and `operator_transfer_policy` is
`No_transfer` or `Owner_transfer`
`No_transfer` or `Owner_transfer` or `Operator_transfer`
*)
let fa2_operators_not_supported = "FA2_OPERATORS_UNSUPPORTED"
(**
Expand Down
1 change: 1 addition & 0 deletions contracts/ligo/fa2/fa2_interface.mligo
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ type operator_transfer_policy =
| No_transfer
| Owner_transfer
| Owner_or_operator_transfer
| Operator_transfer

type owner_hook_policy =
[@layout:comb]
Expand Down
2 changes: 2 additions & 0 deletions contracts/ligo/fa2/lib/fa2_operator_lib.mligo
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ helper functions
To be part of FA2 storage to manage permitted operators
*)
type operator_storage = ((address * (address * token_id)), unit) big_map
type contract_operator_storage = address list

(**
Updates operator storage using an `update_operator` command.
Expand Down Expand Up @@ -66,6 +67,7 @@ let make_operator_validator (tx_policy : operator_transfer_policy) : operator_va
| No_transfer -> (failwith fa2_tx_denied : bool * bool)
| Owner_transfer -> true, false
| Owner_or_operator_transfer -> true, true
| Operator_transfer -> false, true
in
(fun (owner, operator, token_id, ops_storage
: address * address * token_id * operator_storage) ->
Expand Down
7 changes: 7 additions & 0 deletions contracts/ligo/math.mligo
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
let ceil_div (tz_qty, nat_qty : tez * nat) : tez =
let ediv1 : (tez * tez) option = ediv tz_qty nat_qty in
match ediv1 with
| None -> (failwith "DIVISION_BY_ZERO" : tez)
| Some e ->
let (quotient, remainder) = e in
if remainder > 0mutez then (quotient + 1mutez) else quotient
9 changes: 1 addition & 8 deletions contracts/ligo/src/english_auction/english_auction_tez.mligo
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "../../fa2/fa2_interface.mligo"
#include "../../fa2_modules/pauseable_admin_option.mligo"
#include "../../math.mligo"

type fa2_tokens =
[@layout:comb]
Expand Down Expand Up @@ -115,14 +116,6 @@ let auction_in_progress (auction : auction) : bool =
let first_bid (auction : auction) : bool =
auction.highest_bidder = auction.seller

let ceil_div (tz_qty, nat_qty : tez * nat) : tez =
let ediv1 : (tez * tez) option = ediv tz_qty nat_qty in
match ediv1 with
| None -> (failwith "DIVISION_BY_ZERO" : tez)
| Some e ->
let (quotient, remainder) = e in
if remainder > 0mutez then (quotient + 1mutez) else quotient

let valid_bid_amount (auction : auction) : bool =
(Tezos.amount >= (auction.current_bid + (ceil_div (auction.min_raise_percent * auction.current_bid, 100n)))) ||
(Tezos.amount >= auction.current_bid + auction.min_raise) ||
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "fa2_multi_nft_token_with_royalty.mligo"
#include "fa2_multi_nft_manager.mligo"

type nft_faucet_entrypoints =
| Assets of fa2_royalty_entry_points
| Mint of mint_tokens_param

type nft_faucet_storage = {
assets: nft_token_storage;
metadata: (string, bytes) big_map; (* contract metadata *)
}

let nft_royalty_faucet_main (param, storage : nft_faucet_entrypoints * nft_faucet_storage)
: operation list * nft_faucet_storage =
match param with
| Assets fa2 ->
let ops, new_assets = fa2_royalty_main (fa2, storage.assets) in
ops, { storage with assets = new_assets; }
| Mint mp ->
let ops, new_assets = mint_tokens (mp, storage.assets) in
ops, { storage with assets = new_assets; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#if !FA2_MULTI_NFT_TOKEN_WITH_ROYALTY

#define FA2_MULTI_NFT_TOKEN_WITH_ROYALTY

#include "../../fa2/fa2_interface.mligo"
#include "../../fa2/fa2_errors.mligo"

#include "../../fa2/lib/fa2_operator_lib.mligo"
#include "../../fa2/lib/fa2_owner_hooks_lib.mligo"
#include "../../math.mligo"
#include "fa2_multi_nft_token.mligo"

type royalty_data =
[@layout:comb]
{
creator : address;
fee_percent : nat
}

type get_royalty_params =
[@layout:comb]
{
token_id : token_id;
fee : tez;
cb : (address * tez) contract;
}

type fa2_royalty_entry_points =
| FA2 of fa2_entry_points
| Get_Royalty of get_royalty_params

let royalty_undefined = "FA2_ROYALTY_UNDEFINED"

let getRoyalty (params, storage : get_royalty_params * nft_token_storage)
: (operation list) * nft_token_storage =
let royalty_data : royalty_data = ( match (Big_map.find_opt params.token_id storage.token_metadata) with
| Some md -> (match (Big_map.find_opt "royalty" md.token_info) with
| Some royalty_bytes -> ( match ((Bytes.unpack royalty_bytes) : royalty_data option ) with
| Some royalty_data -> royalty_data
| None -> (failwith royalty_undefined : royalty_data))
| None -> (failwith royalty_undefined : royalty_data))
| None -> (failwith fa2_token_undefined : royalty_data)) in
let royalty_fee = ceil_div(royalty_data.fee_percent * params.fee, 100n) in
let op = Tezos.transaction (royalty_data.creator, royalty_fee) 0mutez params.cb
in [op], storage

let fa2_main (param, storage : fa2_entry_points * nft_token_storage)
: (operation list) * nft_token_storage =
match param with
| Transfer txs ->
let tx_descriptors = transfers_to_descriptors txs in
let operator_transfer : operator_transfer_policy = Operator_transfer in
let operator_validator = make_operator_validator operator_transfer in
(* will validate that a sender is an operator.*)
fa2_transfer (tx_descriptors, operator_validator, storage)
| Balance_of p ->
let op = get_balance (p, storage.ledger) in
[op], storage
| Update_operators updates ->
let u = (failwith fa2_operators_not_supported : (operation list) * nft_token_storage)
in u

let fa2_royalty_main (param, storage : fa2_royalty_entry_points * nft_token_storage)
: (operation list) * nft_token_storage = match param with
| FA2 entrypoints -> fa2_main(entrypoints, storage)
| Get_Royalty royalty_param -> getRoyalty(royalty_param, storage)

#endif
12 changes: 12 additions & 0 deletions contracts/src/compile-contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ async function main(): Promise<void> {
await compileEnglishAuctionTezContract(env);
await compileFtFaucetContract(env);
await compileFtContract(env);
await compileNftWithRoyaltyFaucetContract(env);
// add other contracts here

process.exit(0);
Expand Down Expand Up @@ -46,6 +47,17 @@ async function compileNftContract(env: LigoEnv): Promise<void> {
$log.info('compiled NFT contract');
}

async function compileNftWithRoyaltyFaucetContract(env: LigoEnv): Promise<void> {
$log.info('compiling nft with royalty faucet contract');

await compileContract(
env,
'minter_collection/fa2_multi_nft_faucet_with_royalty.mligo',
'nft_royalty_faucet_main',
'nft_royalty_faucet.tz'
);
$log.info('compiled nft with royalty faucet contract');
}

async function compileFtFaucetContract(env: LigoEnv): Promise<void> {
$log.info('compiling FT faucet contract');
Expand Down