-
Notifications
You must be signed in to change notification settings - Fork 0
/
MULTIARTIST_NFT_CHARITY_AUCTION
148 lines (131 loc) · 5.45 KB
/
MULTIARTIST_NFT_CHARITY_AUCTION
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
type token_id is nat;
type auction_id is nat;
type bid is record
bidder : address;
amount : tez;
end;
type auction is record
token : token_id;
highest_bid : bid;
end_time : timestamp;
end;
type token is record
id : token_id;
owner : address;
artist : address;
image_url : string;
metadata : map(string, string); // Additional metadata about the token
royalties : nat; // The royalty percentage for the artist, represented as an integer between 0 and 100
end;
type storage is record
tokens : map(token_id, token);
auctions : map(auction_id, auction);
minter : address; // The address that's allowed to mint new tokens
end;
type mint_params is token;
type transfer_params is record
token : token_id;
to : address;
end;
type start_auction_params is record
token : token_id;
start_price : tez;
end_time : timestamp;
end;
type bid_params is record
auction : auction_id;
amount : tez;
end;
type end_auction_params is auction_id;
type action is
| Mint of mint_params
type end_auction_params is auction_id;
function end_auction (const eap : end_auction_params; const storage : storage) : (list(operation), storage) is
block {
const auction_opt : option(auction) = Map.find_opt(eap, storage.auctions);
case auction_opt of
None -> failwith("Auction does not exist")
| Some(auction) ->
if now < auction.end_time
then failwith("Auction has not ended yet")
else skip;
const token_opt : option(token) = Map.find_opt(auction.token, storage.tokens);
case token_opt of
None -> failwith("Token does not exist")
| Some(token) ->
if sender <> token.owner
then failwith("Only the owner can end the auction")
else skip;
const new_token : token = { token with owner = auction.highest_bid.bidder };
const tokens : map(token_id, token) = Map.update(auction.token, Some(new_token), storage.tokens);
const auctions : map(auction_id, auction) = Map.remove(eap, storage.auctions);
const op : operation = Tezos.transaction(auction.highest_bid.amount, 0tz, token.owner);
end
} with (list [op], { storage with tokens = tokens; auctions = auctions })
| Transfer of transfer_params
| StartAuction of start_auction_params
| Bid on bid_params
| EndAuction of end_auction_params;
function mint (const mp : mint_params; const storage : storage) : storage is
block {
if sender <> storage.minter
then failwith("Only the minter can mint new tokens")
else skip;
if Map.mem(mp.id, storage.tokens)
then failwith("Token already exists")
else skip;
if mp.royalties < 0n or mp.royalties > 100n
then failwith("Royalties must be between 0 and 100")
else skip;
const tokens : map(token_id, token) = Map.update(mp.id, Some(mp), storage.tokens);
} with { storage with tokens = tokens }
function transfer (const tp : transfer_params; const storage : storage) : storage is
block {
const token_opt : option(token) = Map.find_opt(tp.token, storage.tokens);
case token_opt of
None -> failwith("Token does not exist")
| Some(token) ->
if sender <> token.owner
then failwith("Only the owner can transfer the token")
else skip;
const new_token : token = { token with owner = tp.to };
const tokens : map(token_id, token) = Map.update(tp.token, Some(new_token), storage.tokens);
end
} with { storage with tokens = tokens }
function start_auction (const sap : start_auction_params; const storage : storage) : storage is
block {
const token_opt : option(token) = Map.find_opt(sap.token, storage.tokens);
case token_opt of
None -> failwith("Token does not exist")
| Some(token) ->
if sender <> token.owner
then failwith("Only the owner can start an auction")
else skip;
const auction : auction = { token = sap.token; highest_bid = { bidder = (null : option(address)); amount = 0tz }; end_time = sap.end_time };
const auctions : map(auction_id, auction) = Map.update(sap.token, Some(auction), storage.auctions);
end
} with { storage with auctions = auctions }
function bid (const bp : bid_params; const storage : storage) : storage is
block {
const auction_opt : option(auction) = Map.find_opt(bp.auction, storage.auctions);
case auction_opt of
None -> failwith("Auction does not exist")
| Some(auction) ->
if now >= auction.end_time
then failwith("Auction has ended")
else skip;
if bp.amount <= auction.highest_bid.amount
then failwith("Bid must be higher than the current highest bid")
else skip;
const new_auction : auction = { auction with highest_bid = { bidder = Some(sender); amount = bp.amount } };
const auctions : map(auction_id, auction) = Map.update(bp.auction, Some(new_auction), storage.auctions);
end
} with { storage with auctions = auctions }
function main (const action : action; const storage : storage) : (list(operation), storage) is
case action of
Mint(mp) -> (nil : list(operation)), mint(mp, storage)
| Transfer(tp) -> (nil : list(operation)), transfer(tp, storage)
| StartAuction(sap) -> (nil : list(operation)), start_auction(sap, storage)
| Bid(bp) -> (nil : list(operation)), bid(bp, storage)
| EndAuction(eap) -> end_auction(eap, storage)
end;