forked from oxheadalpha/smart-contracts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtoken_manager.mligo
102 lines (84 loc) · 2.95 KB
/
token_manager.mligo
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
(*
Token manager API allows to mint and burn tokens to some existing or new owner account.
Burn operation fails if the owner holds
less tokens then burn amount.
*)
#if !TOKEN_MANAGER
#define TOKEN_MANAGER
#include "fa2_single_token.mligo"
type mint_burn_tx =
[@layout:comb]
{
owner : address;
amount : nat;
}
type mint_burn_tokens_param = mint_burn_tx list
(* `token_manager` entry points *)
type token_manager =
| Mint_tokens of mint_burn_tokens_param
| Burn_tokens of mint_burn_tokens_param
let get_total_supply_change (txs : mint_burn_tx list) : nat =
List.fold (fun (total, tx : nat * mint_burn_tx) -> total + tx.amount) txs 0n
let mint_params_to_descriptors(txs : mint_burn_tokens_param)
: transfer_descriptor list =
let param_to_destination = fun (p : mint_burn_tx)
: transfer_destination_descriptor -> {
to_ = Some p.owner;
token_id = 0n;
amount = p.amount;
}
in
let destinations : transfer_destination_descriptor list =
List.map param_to_destination txs in
[{
from_ = (None : address option);
txs = destinations;
}]
let burn_params_to_descriptors(txs : mint_burn_tokens_param)
: transfer_descriptor list =
let param_to_descriptor = fun (p : mint_burn_tx) : transfer_descriptor ->
let dst : transfer_destination_descriptor = {
to_ = (None : address option);
token_id = 0n;
amount = p.amount;
} in
{
from_ = Some p.owner;
txs = [dst]
} in
List.map param_to_descriptor txs
let mint_tokens (txs, storage : mint_burn_tokens_param * SingleToken.storage)
: (operation list) * SingleToken.storage =
let tx_descriptors = mint_params_to_descriptors txs in
let nop_operator_validator =
fun (_ : address * address * token_id * operator_storage) -> () in
let ops, new_s1 = SingleToken.fa2_transfer
(tx_descriptors, nop_operator_validator, storage) in
let supply_change = get_total_supply_change txs in
let new_s2 = { new_s1 with
total_supply = storage.total_supply + supply_change;
} in
ops, new_s2
let burn_tokens (txs, storage : mint_burn_tokens_param * SingleToken.storage)
: (operation list) * SingleToken.storage =
let tx_descriptors = burn_params_to_descriptors txs in
let nop_operator_validator =
fun (_ : address * address * token_id * operator_storage) -> () in
let ops, new_s1 = SingleToken.fa2_transfer
(tx_descriptors, nop_operator_validator, storage) in
let supply_change = get_total_supply_change txs in
let new_supply_opt = is_nat (storage.total_supply - supply_change) in
let new_supply = match new_supply_opt with
| None -> (failwith fa2_insufficient_balance : nat)
| Some s -> s
in
let new_s2 = { new_s1 with
total_supply = new_supply;
} in
ops, new_s2
let token_manager (param, s : token_manager * SingleToken.storage)
: (operation list) * SingleToken.storage =
match param with
| Mint_tokens txs -> mint_tokens (txs, s)
| Burn_tokens txs -> burn_tokens (txs, s)
#endif