-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwu-token.cpp
More file actions
154 lines (125 loc) · 5.15 KB
/
Copy pathwu-token.cpp
File metadata and controls
154 lines (125 loc) · 5.15 KB
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
149
150
151
152
153
154
#include "wu-token.hpp"
#include "config.h"
#include "str_expand.h"
wutoken::wutoken(account_name self) :
eosio::contract(self),
exchange(eosio::string_to_name(STR(EXCHANGE)))
{}
void wutoken::create(account_name issuer, eosio::asset maximum_supply) {
require_auth(this->_self);
auto sym = maximum_supply.symbol;
eosio_assert(sym.is_valid(), "invalid symbol name");
eosio_assert(maximum_supply.is_valid(), "invalid supply");
eosio_assert(maximum_supply.amount > 0, "max-supply must be positive");
stats statstable(this->_self, sym.name());
auto existing = statstable.find(sym.name());
eosio_assert(existing == statstable.end(), "token with symbol already exists");
statstable.emplace(this->_self, [&](auto& s) {
s.supply.symbol = maximum_supply.symbol;
s.max_supply = maximum_supply;
s.issuer = issuer;
});
}
void wutoken::issue(account_name to, eosio::asset quantity, std::string memo) {
auto sym = quantity.symbol;
eosio_assert(sym.is_valid(), "invalid symbol name");
eosio_assert(memo.size() <= 256, "memo has more than 256 bytes");
auto sym_name = sym.name();
stats statstable(this->_self, sym_name);
auto existing = statstable.find(sym_name);
eosio_assert(existing != statstable.end(), "token with symbol does not exist, create token before issue");
const auto& st = *existing;
require_auth(st.issuer);
eosio_assert(quantity.is_valid(), "invalid quantity");
eosio_assert(quantity.amount > 0, "must issue positive quantity");
eosio_assert(quantity.symbol == st.supply.symbol, "symbol precision mismatch");
eosio_assert(quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply");
statstable.modify(st, 0, [&](auto& s) {
s.supply += quantity;
});
add_balance(to, quantity, st.issuer);
}
void wutoken::transfer(account_name from, account_name to, eosio::asset quantity, std::string memo) {
eosio_assert(from != to, "cannot transfer to self");
require_auth(from);
eosio_assert(is_account(to), "to account does not exist");
auto sym = quantity.symbol.name();
stats statstable(this->_self, sym);
const auto& st = statstable.get(sym);
require_recipient(from);
require_recipient(to);
eosio_assert(quantity.is_valid(), "invalid quantity");
eosio_assert(quantity.amount > 0, "must transfer positive quantity");
eosio_assert(quantity.symbol == st.supply.symbol, "symbol precision mismatch");
eosio_assert(memo.size() <= 256, "memo has more than 256 bytes");
sub_balance(from, quantity, from);
add_balance(to, quantity, from);
}
void wutoken::allowclaim(account_name from, eosio::asset quantity) {
require_auth(from);
require_auth(this->exchange);
accounts from_acnts(this->_self, from);
const auto& account = from_acnts.find(quantity.symbol.name());
eosio_assert(account != from_acnts.end(), "symbol not found (allowclaim)");
eosio_assert(account->balance.amount - account->blocked >= quantity.amount, "overdrawn allowclaim");
from_acnts.modify(account, from, [quantity](auto& a) {
a.blocked += quantity.amount;
});
}
void wutoken::claim(account_name from, eosio::asset quantity) {
require_auth(this->exchange);
eosio_assert(quantity.amount > 0, "claim must be positive");
accounts from_acnts(this->_self, from);
const auto& account = from_acnts.find(quantity.symbol.name());
eosio_assert(account != from_acnts.end(), "symbol not found (claim)");
eosio_assert(account->blocked >= quantity.amount, ("overdrawn claim from user '" + eosio::name{from}.to_string() + "'").c_str());
from_acnts.modify(account, this->exchange, [quantity](auto& a) {
a.blocked -= quantity.amount;
});
sub_balance(from, quantity, this->exchange);
add_balance(this->exchange, quantity, this->exchange);
}
void wutoken::cleanstate(eosio::vector<eosio::symbol_type> symbs, eosio::vector<account_name> accs) {
require_auth(this->_self);
// stats
for (auto symbol = symbs.begin(); symbol != symbs.end(); symbol++) {
stats statstable(this->_self, symbol->name());
for (auto stat = statstable.begin(); stat != statstable.end(); ) {
stat = statstable.erase(stat);
}
}
for (auto account = accs.begin(); account != accs.end(); account++) {
// accounts
accounts accountstable(this->_self, *account);
for (auto balance = accountstable.begin(); balance != accountstable.end(); ) {
balance = accountstable.erase(balance);
}
}
}
void wutoken::sub_balance(account_name owner, eosio::asset value, account_name ram_payer) {
accounts from_acnts(this->_self, owner);
const auto& from = from_acnts.get(value.symbol.name(), "no balance object found");
eosio_assert(from.balance.amount - from.blocked >= value.amount, "overdrawn balance");
if (from.balance.amount == value.amount) {
from_acnts.erase(from);
} else {
from_acnts.modify(from, ram_payer, [&](auto& a) {
a.balance -= value;
});
}
}
void wutoken::add_balance(account_name owner, eosio::asset value, account_name ram_payer) {
accounts to_acnts(this->_self, owner);
auto to = to_acnts.find(value.symbol.name());
if (to == to_acnts.end()) {
to_acnts.emplace(ram_payer, [&](auto& a) {
a.balance = value;
a.blocked = 0;
});
} else {
to_acnts.modify(to, 0, [&](auto& a) {
a.balance += value;
});
}
}
EOSIO_ABI(wutoken, (create)(issue)(transfer)(allowclaim)(claim)(cleanstate))