-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtoken.reliq
90 lines (82 loc) · 3.06 KB
/
token.reliq
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
type account = {
balance: nat,
allowances: map(address, nat),
};
type storage = {
accounts: big_map(address, account),
version: nat /* version of token standard */,
totalSupply: nat,
decimals: nat,
name: string,
symbol: string,
owner: address,
};
let%init storage = (owner, totalSupply, decimals, name, symbol) => {
let owner_account = {balance: totalSupply, allowances: Map};
let accounts = Map.add(owner, owner_account, BigMap);
{accounts, version: 1p, totalSupply, decimals, name, symbol, owner};
};
let get_account = ((a, accounts: big_map(address, account))) =>
switch (Map.find(a, accounts)) {
| None => {balance: 0p, allowances: Map}
| Some(account) => account
};
let perform_transfer = ((from, dest, tokens, storage)) => {
let accounts = storage.accounts;
let account_sender = get_account((from, accounts));
let new_account_sender =
switch (is_nat(account_sender.balance - tokens)) {
| None =>
failwith(("Not enough tokens for transfer", account_sender.balance))
| Some(b) => account_sender.balance = b
};
let accounts = Map.add(from, new_account_sender, accounts);
let account_dest = get_account((dest, accounts));
let new_account_dest = account_dest.balance = account_dest.balance + tokens;
let accounts = Map.add(dest, new_account_dest, accounts);
([], storage.accounts = accounts);
};
let%entry transfer = ((dest, tokens), storage) =>
perform_transfer((Current.sender(), dest, tokens, storage));
let%entry approve = ((spender, tokens), storage) => {
let account_sender = get_account((Current.sender(), storage.accounts));
let account_sender =
account_sender.allowances = (
if (tokens == 0p) {
Map.remove(spender, account_sender.allowances);
} else {
Map.add(spender, tokens, account_sender.allowances);
}
);
let storage =
storage.accounts =
Map.add(Current.sender(), account_sender, storage.accounts);
([], storage);
};
let%entry transferFrom = ((from, dest, tokens), storage) => {
let account_from = get_account((from, storage.accounts));
let new_allowances_from =
switch (Map.find(Current.sender(), account_from.allowances)) {
| None => failwith(("Not allowed to spend from", from))
| Some(allowed) =>
switch (is_nat(allowed - tokens)) {
| None => failwith(("Not enough allowance for transfer", allowed))
| Some(allowed) =>
if (allowed == 0p) {
Map.remove(Current.sender(), account_from.allowances);
} else {
Map.add(Current.sender(), allowed, account_from.allowances);
}
}
};
let account_from = account_from.allowances = new_allowances_from;
let storage =
storage.accounts = Map.add(from, account_from, storage.accounts);
perform_transfer((from, dest, tokens, storage));
}
let%entry createAccount = ((dest, tokens), storage) => {
if (Current.sender() != storage.owner) {
failwith("Only owner can create accounts");
};
perform_transfer((storage.owner, dest, tokens, storage));
};