-
Notifications
You must be signed in to change notification settings - Fork 9
/
nominator_requests.fc
147 lines (142 loc) · 5.84 KB
/
nominator_requests.fc
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
() add_stake (slice s_addr, int msg_value, tuple storage, int query_id) impure {
(slice _1,
int total_active,
int _3,
int reward_per_gram,
int undistributed_reward,
int _6,
int _7,
cell nominators,
cell _9, cell _10, cell _11) = storage_untuple(storage);
(int wc, int addr_hash) = parse_std_addr(s_addr);
(int active, int locked, int paid_reward_per_gram, int last_stake_utime) = nominators.get_nominator_data(wc, addr_hash, reward_per_gram);
;; distribute profit to nominator
if(paid_reward_per_gram != reward_per_gram) {
int nominator_share = (reward_per_gram - paid_reward_per_gram) * active / 1000000000;
active = active + nominator_share;
total_active = total_active + nominator_share;
undistributed_reward = undistributed_reward - nominator_share;
}
int put_fee = 200000000; ;; 0.2 Gram
int stake = msg_value - put_fee;
active = active + stake;
throw_unless (393, active >= 0); ;; This check here to get error code, negative active will throw anyway during serialization
nominators~set_nominator_data(wc, addr_hash, active, locked, reward_per_gram, now());
total_active = total_active + stake;
save_data(_1, total_active, _3, reward_per_gram, undistributed_reward, _6, _7, nominators, _9, _10, _11);
if ( query_id ) {
return send_receipt_message(s_addr, 0xfeedc0de + 0x00001000, query_id, 0, put_fee / 2, 1);
} else {
return send_text_stake_accept_message(s_addr, stake, put_fee / 2);
}
}
() lock_stake (slice s_addr, int msg_value, tuple storage, int query_id, int amount) impure {
(slice _1,
int total_active,
int total_locked,
int reward_per_gram,
int undistributed_reward,
int _6, int _7,
cell nominators,
cell _9, cell _10, cell _11) = storage_untuple(storage);
(int wc, int addr_hash) = parse_std_addr(s_addr);
(int active, int locked, int paid_reward_per_gram, int last_stake_utime) = nominators.get_nominator_data(wc, addr_hash, reward_per_gram);
(int __1, int __2, int prev_set_utime_since) = stake_lock_durations();
throw_unless(313, last_stake_utime < prev_set_utime_since);
;; distribute profit to nominator
if(paid_reward_per_gram != reward_per_gram) {
int nominator_share = calc_nominator_profit_share(active, paid_reward_per_gram, reward_per_gram);
active = active + nominator_share;
total_active = total_active + nominator_share;
undistributed_reward = undistributed_reward - nominator_share;
}
if( amount == 0) {
amount = active;
}
active = active - amount;
total_active = total_active - amount;
locked = locked + amount;
total_locked = total_locked + amount;
throw_unless (396, (active >= 0) | (total_active >= 0)); ;; This check here to get error code, negative active will throw anyway during serialization
nominators~set_nominator_data(wc, addr_hash, active, locked, reward_per_gram, last_stake_utime);
save_data(_1, total_active, total_locked, reward_per_gram, undistributed_reward, _6, _7, nominators, _9, _10, _11);
if ( query_id ) {
return send_receipt_message(s_addr, 0x0c0010ff + 0x00001000, query_id, 0, 0, 64);
} else {
return send_text_lock_accept_message(s_addr, amount);
}
}
() withdraw_locked (slice s_addr, int msg_value, tuple storage, int query_id) impure {
(slice _1,
int total_active,
int total_locked,
int reward_per_gram,
int undistributed_reward,
int _6, int _7,
cell nominators,
cell _9, cell _10, cell _11) = storage_untuple(storage);
(int wc, int addr_hash) = parse_std_addr(s_addr);
(int active, int locked, int paid_reward_per_gram, int last_stake_utime) = nominators.get_nominator_data(wc, addr_hash, reward_per_gram);
[int pool_balance, cell cur_col] = get_balance();
if(pool_balance < locked) {
;; we need to wait till refund from the pool
if ( query_id ) {
return send_receipt_message(s_addr, 0x006e7bac + 0xf0001000, query_id, 0, 0, 64);
} else {
return send_text_withdrawal_not_ready_message(s_addr);
}
} else {
;; distribute profit to nominator
if(paid_reward_per_gram != reward_per_gram) {
int nominator_share = (reward_per_gram - paid_reward_per_gram) * active / 1000000000;
active = active + nominator_share;
total_active = total_active + nominator_share;
undistributed_reward = undistributed_reward - nominator_share;
}
int amount = locked;
locked = 0;
total_locked = total_locked - amount;
throw_unless (398, total_locked >= 0); ;; This check here to get error code, negative locked will throw anyway during serialization
nominators~set_nominator_data(wc, addr_hash, active, locked, reward_per_gram, last_stake_utime);
save_data(_1, total_active, total_locked, reward_per_gram, undistributed_reward, _6, _7, nominators, _9, _10, _11);
if ( query_id ) {
return send_receipt_message(s_addr, 0x006e7bac + 0x00001000, query_id, 0, amount, 64);
} else {
return send_text_withdraw_message(s_addr, amount);
}
}
}
(int) process_nominator_request (slice in_msg, int msg_value, tuple storage, slice s_addr) impure {
int query_id = 0;
int op = in_msg~load_uint(32);
if ( ~ op ) {
op = in_msg~parse_text_command();
} else {
query_id = in_msg~load_uint(64);
}
if (op == 0xfeedc0de ) {
;; put stake into pool
add_stake(s_addr, msg_value, storage, query_id);
return true;
}
if (op == 0x0c0010ff ) {
;; lock stake from being used for validation
int amount = 0; ;; 0 means lock all available
if (query_id) {
amount = in_msg~load_grams();
}
lock_stake(s_addr, msg_value, storage, query_id, amount);
return true;
}
if (op == 0x006e7bac ) {
withdraw_locked(s_addr, msg_value, storage, query_id);
return true;
}
if (op == 0xdead10cc) {
;; validator's function allowed for nominators
throw_unless(112, msg_value > 1000000000);
recover_stake(msg_value, query_id, storage, s_addr);
return true;
}
return false;
}