tx · GPCRaLfmCssrDvqhoPNDt8ZoDeLkwsc1cHsezzwTr7on 3N1WbxZTdjLm3L8faJGiCTRk3kfaAofzd16: -1.20000000 Waves 2022.11.15 17:42 [2318372] smart account 3N1WbxZTdjLm3L8faJGiCTRk3kfaAofzd16 > SELF 0.00000000 Waves
{ "type": 13, "id": "GPCRaLfmCssrDvqhoPNDt8ZoDeLkwsc1cHsezzwTr7on", "fee": 120000000, "feeAssetId": null, "timestamp": 1668523398822, "version": 2, "chainId": 84, "sender": "3N1WbxZTdjLm3L8faJGiCTRk3kfaAofzd16", "senderPublicKey": "BrpLGAiTnNa5QohVytFPYdF7oZR7Gk1UZfA7c9Uxs9Fw", "proofs": [ "2oWpuxuDRHi3HvxVpSvCYNb4AkDqTJJo2G2gpkFX2ndZ7pLZ4bFiNLTzHYd28oAWBQswckAZqPGd5wUd6iHfqV9k" ], "script": "base64:AAIFAAAAAAAAAAkIAhIDCgEIEgAAAAAEAQAAABNrZXlNYW5hZ2VyUHVibGljS2V5AAAAAAkABCIAAAABAgAAABBtYW5hZ2VyUHVibGljS2V5AQAAABZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAAAAAQAAAAHJG1hdGNoMAkBAAAAE2tleU1hbmFnZXJQdWJsaWNLZXkAAAAAAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAAZTdHJpbmcEAAAAAXMFAAAAByRtYXRjaDAJAAJZAAAAAQUAAAABcwMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAEVW5pdAUAAAAEdW5pdAkAAAIAAAABAgAAAAtNYXRjaCBlcnJvcgEAAAALbXVzdE1hbmFnZXIAAAABAAAAAWkEAAAAAnBkCQAAAgAAAAECAAAAEXBlcm1pc3Npb24gZGVuaWVkBAAAAAckbWF0Y2gwCQEAAAAWbWFuYWdlclB1YmxpY0tleU9yVW5pdAAAAAADCQAAAQAAAAIFAAAAByRtYXRjaDACAAAACkJ5dGVWZWN0b3IEAAAAAnBrBQAAAAckbWF0Y2gwAwkAAAAAAAACCAUAAAABaQAAAA9jYWxsZXJQdWJsaWNLZXkFAAAAAnBrBgUAAAACcGQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABFVuaXQDCQAAAAAAAAIIBQAAAAFpAAAABmNhbGxlcgUAAAAEdGhpcwYFAAAAAnBkCQAAAgAAAAECAAAAC01hdGNoIGVycm9yAQAAAA1tdXN0Tm90SW5pdGVkAAAAAAQAAAAHJG1hdGNoMAkABCAAAAABAgAAAAZpbml0ZWQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAB0Jvb2xlYW4EAAAABmluaXRlZAUAAAAHJG1hdGNoMAMJAAAAAAAAAgUAAAAGaW5pdGVkBwYJAAACAAAAAQIAAAAOQWxyZWFkeSBpbml0ZWQDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABFVuaXQHCQAAAgAAAAECAAAAC01hdGNoIGVycm9yAAAAAgAAAAFpAQAAAARpbml0AAAAAQAAAAttYWluQWRkcmVzcwQAAAAGY2hlY2tzCQAETAAAAAIJAQAAAAttdXN0TWFuYWdlcgAAAAEFAAAAAWkJAARMAAAAAgkBAAAADW11c3ROb3RJbml0ZWQAAAAABQAAAANuaWwDCQAAAAAAAAIFAAAABmNoZWNrcwUAAAAGY2hlY2tzCQAETAAAAAIJAQAAAAxCb29sZWFuRW50cnkAAAACAgAAAAZpbml0ZWQGCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAICAAAAC21haW5BZGRyZXNzBQAAAAttYWluQWRkcmVzcwUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAAh3aXRoZHJhdwAAAAAEAAAAC21haW5BZGRyZXNzCQEAAAAHQWRkcmVzcwAAAAEJAAJZAAAAAQkBAAAAEUBleHRyTmF0aXZlKDEwNTgpAAAAAQIAAAALbWFpbkFkZHJlc3MEAAAADnJlZ3VsYXJCYWxhbmNlCAkAA+8AAAABBQAAAAR0aGlzAAAAB3JlZ3VsYXIDCQEAAAACIT0AAAACCAUAAAABaQAAAAZjYWxsZXIFAAAAC21haW5BZGRyZXNzCQAAAgAAAAECAAAAKU9ubHkgbWFpbiBjb250cmFjdCBjYW4gaW52b2tlIHRoaXMgbWV0aG9kCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMFAAAAC21haW5BZGRyZXNzBQAAAA5yZWd1bGFyQmFsYW5jZQUAAAAEdW5pdAUAAAADbmlsAAAAAQAAAAJ0eAEAAAAGdmVyaWZ5AAAAAAkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAIBQAAAAJ0eAAAAA9zZW5kZXJQdWJsaWNLZXlZx2US", "height": 2318372, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: ChFNu4pTY1Sa3K8cLSjnwRy8FYHgvHYxXjciEh1gSypr Next: DJ9cpmfJMhr7wuqx68UUgZJSW81YzvqeMDNJemQWu4Ya Diff:
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 5 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | - | let PRECISION = 1000000000000000000 | |
5 | - | ||
6 | - | let DURATION = ((60 * 60) * 24) | |
7 | - | ||
8 | - | let DECIMALS = 100000000 | |
9 | - | ||
10 | - | let k_lastCompoundTime = "k_lastCompoundTime" | |
11 | - | ||
12 | - | let k_periodFinish = "k_periodFinish" | |
13 | - | ||
14 | - | let k_lastRate = "k_lastRate" | |
15 | - | ||
16 | - | let k_growthRate = "k_growthRate" | |
17 | - | ||
18 | - | let k_balance = "k_balance" | |
19 | - | ||
20 | - | let k_leaseId = "k_leaseId" | |
21 | - | ||
22 | - | let k_initialized = "k_initialized" | |
23 | - | ||
24 | - | let k_adminPublicKey = "k_adminPublicKey" | |
25 | - | ||
26 | - | let k_adminAddress = "k_adminAddress" | |
27 | - | ||
28 | - | let k_minerAddress = "k_minerAddress" | |
29 | - | ||
30 | - | let k_sWavesAsset = "k_sWavesAssetId" | |
31 | - | ||
32 | - | func divd (_x,_y) = fraction(_x, DECIMALS, _y, HALFEVEN) | |
4 | + | func keyManagerPublicKey () = getString("managerPublicKey") | |
33 | 5 | ||
34 | 6 | ||
35 | - | func muld (_x,_y) = fraction(_x, _y, DECIMALS, HALFEVEN) | |
36 | - | ||
37 | - | ||
38 | - | func divp (_x,_y) = fraction(_x, PRECISION, _y, HALFEVEN) | |
39 | - | ||
40 | - | ||
41 | - | func mulp (_x,_y) = fraction(_x, _y, PRECISION, HALFEVEN) | |
42 | - | ||
43 | - | ||
44 | - | func abs (_x) = if ((_x > 0)) | |
45 | - | then _x | |
46 | - | else -(_x) | |
47 | - | ||
48 | - | ||
49 | - | func minv (_x,_y) = if ((_x > _y)) | |
50 | - | then _y | |
51 | - | else _x | |
52 | - | ||
53 | - | ||
54 | - | func toCompositeKey (_key,_address) = ((_key + "_") + _address) | |
55 | - | ||
56 | - | ||
57 | - | func adminAddress () = addressFromString(getStringValue(this, k_adminAddress)) | |
58 | - | ||
59 | - | ||
60 | - | func adminPublicKey () = fromBase58String(getStringValue(this, k_adminPublicKey)) | |
61 | - | ||
62 | - | ||
63 | - | func minerAddress () = valueOrErrorMessage(addressFromString(getStringValue(this, k_minerAddress)), "Invalid miner address is not set") | |
64 | - | ||
65 | - | ||
66 | - | func sWavesAsset () = fromBase58String(getStringValue(this, k_sWavesAsset)) | |
67 | - | ||
68 | - | ||
69 | - | func initialized () = valueOrElse(getBoolean(this, k_initialized), false) | |
70 | - | ||
71 | - | ||
72 | - | func int (k) = valueOrErrorMessage(getInteger(this, k), ("No value for " + k)) | |
73 | - | ||
74 | - | ||
75 | - | func int0 (k) = valueOrElse(getInteger(this, k), 0) | |
76 | - | ||
77 | - | ||
78 | - | func lastCompoundTime () = int0(k_lastCompoundTime) | |
79 | - | ||
80 | - | ||
81 | - | func growthRate () = int0(k_growthRate) | |
82 | - | ||
83 | - | ||
84 | - | func balance () = int0(k_balance) | |
85 | - | ||
86 | - | ||
87 | - | func lastRate () = int(k_lastRate) | |
88 | - | ||
89 | - | ||
90 | - | func periodFinish () = int0(k_periodFinish) | |
91 | - | ||
92 | - | ||
93 | - | func adminPublicKeyOrUnit () = match getString(this, k_adminPublicKey) { | |
7 | + | func managerPublicKeyOrUnit () = match keyManagerPublicKey() { | |
94 | 8 | case s: String => | |
95 | 9 | fromBase58String(s) | |
96 | 10 | case _: Unit => | |
100 | 14 | } | |
101 | 15 | ||
102 | 16 | ||
103 | - | func | |
17 | + | func mustManager (i) = { | |
104 | 18 | let pd = throw("permission denied") | |
105 | - | match | |
19 | + | match managerPublicKeyOrUnit() { | |
106 | 20 | case pk: ByteVector => | |
107 | 21 | if ((i.callerPublicKey == pk)) | |
108 | 22 | then true | |
117 | 31 | } | |
118 | 32 | ||
119 | 33 | ||
120 | - | func currentTimestampSec () = (lastBlock.timestamp / 1000) | |
121 | - | ||
122 | - | ||
123 | - | func dt () = minv(currentTimestampSec(), periodFinish()) | |
124 | - | ||
125 | - | ||
126 | - | func cancelLease () = match getBinary(k_leaseId) { | |
127 | - | case id: ByteVector => | |
128 | - | [LeaseCancel(id), DeleteEntry(k_leaseId)] | |
34 | + | func mustNotInited () = match getBoolean("inited") { | |
35 | + | case inited: Boolean => | |
36 | + | if ((inited == false)) | |
37 | + | then true | |
38 | + | else throw("Already inited") | |
129 | 39 | case _: Unit => | |
130 | - | | |
40 | + | false | |
131 | 41 | case _ => | |
132 | 42 | throw("Match error") | |
133 | 43 | } | |
134 | 44 | ||
135 | 45 | ||
136 | - | func updateBalance (_amount) = [IntegerEntry(k_balance, _amount)] | |
137 | - | ||
138 | - | ||
139 | - | func updateTime (_lastCompoundTime,_periodFinish) = [IntegerEntry(k_lastCompoundTime, _lastCompoundTime), IntegerEntry(k_periodFinish, _periodFinish)] | |
140 | - | ||
141 | - | ||
142 | - | func updateRate (_rate,_growthRate) = [IntegerEntry(k_lastRate, _rate), IntegerEntry(k_growthRate, _growthRate)] | |
143 | - | ||
144 | - | ||
145 | - | func updateLease (_amount) = if ((_amount > 0)) | |
146 | - | then { | |
147 | - | let newLease = Lease(minerAddress(), _amount) | |
148 | - | let newLeaseId = calculateLeaseId(newLease) | |
149 | - | [newLease, BinaryEntry(k_leaseId, newLeaseId)] | |
150 | - | } | |
151 | - | else nil | |
152 | - | ||
153 | - | ||
154 | - | func lease (_amount) = if ((_amount == 0)) | |
155 | - | then nil | |
156 | - | else { | |
157 | - | let newAmount = (balance() + _amount) | |
158 | - | ((cancelLease() ++ updateLease(newAmount)) ++ updateBalance(newAmount)) | |
159 | - | } | |
160 | - | ||
161 | - | ||
162 | - | func issueSWaves (_amount) = [Reissue(sWavesAsset(), _amount, true)] | |
163 | - | ||
164 | - | ||
165 | - | func burnSWaves (_amount) = [Burn(sWavesAsset(), _amount)] | |
166 | - | ||
167 | - | ||
168 | - | func sendSWaves (_recipient,_amount) = [ScriptTransfer(_recipient, _amount, sWavesAsset())] | |
169 | - | ||
170 | - | ||
171 | - | func sendWaves (_recipient,_amount) = [ScriptTransfer(_recipient, _amount, unit)] | |
172 | - | ||
173 | - | ||
174 | - | func sWavesQuantity () = match assetInfo(sWavesAsset()) { | |
175 | - | case asset: Asset => | |
176 | - | asset.quantity | |
177 | - | case _ => | |
178 | - | throw("Can't find asset") | |
179 | - | } | |
180 | - | ||
181 | - | ||
182 | - | func getExcessWaves () = wavesBalance(minerAddress()).regular | |
183 | - | ||
184 | - | ||
185 | - | func withdraw () = { | |
186 | - | let result = invoke(minerAddress(), "withdraw", nil, nil) | |
187 | - | if ((result == result)) | |
188 | - | then result | |
189 | - | else throw("Strict value is not equal to itself.") | |
190 | - | } | |
191 | - | ||
192 | - | ||
193 | - | func currentRate () = (lastRate() + (growthRate() * dt())) | |
194 | - | ||
195 | - | ||
196 | 46 | @Callable(i) | |
197 | - | func init (_minerAddress) = { | |
198 | - | let check = mustAdmin(i) | |
199 | - | if ((check == check)) | |
200 | - | then if (initialized()) | |
201 | - | then throw("Already initialized") | |
202 | - | else { | |
203 | - | let sWaves = Issue("sWaves", "", 0, 8, true, unit, 0) | |
204 | - | let sWavesAssetId = calculateAssetId(sWaves) | |
205 | - | [BooleanEntry(k_initialized, true), StringEntry(k_sWavesAsset, toBase58String(sWavesAssetId)), StringEntry(k_minerAddress, _minerAddress), IntegerEntry(k_lastRate, PRECISION), sWaves] | |
206 | - | } | |
47 | + | func init (mainAddress) = { | |
48 | + | let checks = [mustManager(i), mustNotInited()] | |
49 | + | if ((checks == checks)) | |
50 | + | then [BooleanEntry("inited", true), StringEntry("mainAddress", mainAddress)] | |
207 | 51 | else throw("Strict value is not equal to itself.") | |
208 | 52 | } | |
209 | 53 | ||
210 | 54 | ||
211 | 55 | ||
212 | 56 | @Callable(i) | |
213 | - | func compound () = if ((size(i.payments) != 0)) | |
214 | - | then throw("No payments allowed") | |
215 | - | else { | |
216 | - | let excessWaves = getExcessWaves() | |
217 | - | if ((excessWaves == excessWaves)) | |
218 | - | then if (((1 * DECIMALS) > excessWaves)) | |
219 | - | then nil | |
220 | - | else { | |
221 | - | let doWithdraw = withdraw() | |
222 | - | if ((doWithdraw == doWithdraw)) | |
223 | - | then { | |
224 | - | let newRate = currentRate() | |
225 | - | let timestamp = currentTimestampSec() | |
226 | - | let newGrowthRate = if ((timestamp > periodFinish())) | |
227 | - | then (divp(excessWaves, DECIMALS) / DURATION) | |
228 | - | else { | |
229 | - | let remainingTime = (periodFinish() - timestamp) | |
230 | - | let leftover = (growthRate() * remainingTime) | |
231 | - | (divp((excessWaves + leftover), DECIMALS) / DURATION) | |
232 | - | } | |
233 | - | ((lease(excessWaves) ++ updateRate(newRate, newGrowthRate)) ++ updateTime(timestamp, (timestamp + DURATION))) | |
234 | - | } | |
235 | - | else throw("Strict value is not equal to itself.") | |
236 | - | } | |
237 | - | else throw("Strict value is not equal to itself.") | |
238 | - | } | |
239 | - | ||
240 | - | ||
241 | - | ||
242 | - | @Callable(i) | |
243 | - | func stake () = { | |
244 | - | let doCompound = invoke(this, "compound", nil, nil) | |
245 | - | if ((doCompound == doCompound)) | |
246 | - | then { | |
247 | - | let payment = i.payments[0] | |
248 | - | if ((payment.assetId != unit)) | |
249 | - | then throw("Only WAVES supported") | |
250 | - | else if ((size(i.payments) != 1)) | |
251 | - | then throw("Wrong payments amount") | |
252 | - | else { | |
253 | - | let rate = currentRate() | |
254 | - | let toReissue = divp(payment.amount, rate) | |
255 | - | ((lease(payment.amount) ++ issueSWaves(toReissue)) ++ sendSWaves(i.caller, toReissue)) | |
256 | - | } | |
257 | - | } | |
258 | - | else throw("Strict value is not equal to itself.") | |
259 | - | } | |
260 | - | ||
261 | - | ||
262 | - | ||
263 | - | @Callable(i) | |
264 | - | func unstake () = { | |
265 | - | let doCompound = invoke(this, "compound", nil, nil) | |
266 | - | if ((doCompound == doCompound)) | |
267 | - | then { | |
268 | - | let payment = i.payments[0] | |
269 | - | if ((payment.assetId != sWavesAsset())) | |
270 | - | then throw("Only sWAVES supported") | |
271 | - | else if ((size(i.payments) != 1)) | |
272 | - | then throw("Wrong payments amount") | |
273 | - | else { | |
274 | - | let rate = currentRate() | |
275 | - | let transferAmount = mulp(payment.amount, rate) | |
276 | - | ((lease(-(transferAmount)) ++ burnSWaves(payment.amount)) ++ sendWaves(i.caller, transferAmount)) | |
277 | - | } | |
278 | - | } | |
279 | - | else throw("Strict value is not equal to itself.") | |
57 | + | func withdraw () = { | |
58 | + | let mainAddress = Address(fromBase58String(getStringValue("mainAddress"))) | |
59 | + | let regularBalance = wavesBalance(this).regular | |
60 | + | if ((i.caller != mainAddress)) | |
61 | + | then throw("Only main contract can invoke this method") | |
62 | + | else [ScriptTransfer(mainAddress, regularBalance, unit)] | |
280 | 63 | } | |
281 | 64 | ||
282 | 65 |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 5 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | - | let PRECISION = 1000000000000000000 | |
5 | - | ||
6 | - | let DURATION = ((60 * 60) * 24) | |
7 | - | ||
8 | - | let DECIMALS = 100000000 | |
9 | - | ||
10 | - | let k_lastCompoundTime = "k_lastCompoundTime" | |
11 | - | ||
12 | - | let k_periodFinish = "k_periodFinish" | |
13 | - | ||
14 | - | let k_lastRate = "k_lastRate" | |
15 | - | ||
16 | - | let k_growthRate = "k_growthRate" | |
17 | - | ||
18 | - | let k_balance = "k_balance" | |
19 | - | ||
20 | - | let k_leaseId = "k_leaseId" | |
21 | - | ||
22 | - | let k_initialized = "k_initialized" | |
23 | - | ||
24 | - | let k_adminPublicKey = "k_adminPublicKey" | |
25 | - | ||
26 | - | let k_adminAddress = "k_adminAddress" | |
27 | - | ||
28 | - | let k_minerAddress = "k_minerAddress" | |
29 | - | ||
30 | - | let k_sWavesAsset = "k_sWavesAssetId" | |
31 | - | ||
32 | - | func divd (_x,_y) = fraction(_x, DECIMALS, _y, HALFEVEN) | |
4 | + | func keyManagerPublicKey () = getString("managerPublicKey") | |
33 | 5 | ||
34 | 6 | ||
35 | - | func muld (_x,_y) = fraction(_x, _y, DECIMALS, HALFEVEN) | |
36 | - | ||
37 | - | ||
38 | - | func divp (_x,_y) = fraction(_x, PRECISION, _y, HALFEVEN) | |
39 | - | ||
40 | - | ||
41 | - | func mulp (_x,_y) = fraction(_x, _y, PRECISION, HALFEVEN) | |
42 | - | ||
43 | - | ||
44 | - | func abs (_x) = if ((_x > 0)) | |
45 | - | then _x | |
46 | - | else -(_x) | |
47 | - | ||
48 | - | ||
49 | - | func minv (_x,_y) = if ((_x > _y)) | |
50 | - | then _y | |
51 | - | else _x | |
52 | - | ||
53 | - | ||
54 | - | func toCompositeKey (_key,_address) = ((_key + "_") + _address) | |
55 | - | ||
56 | - | ||
57 | - | func adminAddress () = addressFromString(getStringValue(this, k_adminAddress)) | |
58 | - | ||
59 | - | ||
60 | - | func adminPublicKey () = fromBase58String(getStringValue(this, k_adminPublicKey)) | |
61 | - | ||
62 | - | ||
63 | - | func minerAddress () = valueOrErrorMessage(addressFromString(getStringValue(this, k_minerAddress)), "Invalid miner address is not set") | |
64 | - | ||
65 | - | ||
66 | - | func sWavesAsset () = fromBase58String(getStringValue(this, k_sWavesAsset)) | |
67 | - | ||
68 | - | ||
69 | - | func initialized () = valueOrElse(getBoolean(this, k_initialized), false) | |
70 | - | ||
71 | - | ||
72 | - | func int (k) = valueOrErrorMessage(getInteger(this, k), ("No value for " + k)) | |
73 | - | ||
74 | - | ||
75 | - | func int0 (k) = valueOrElse(getInteger(this, k), 0) | |
76 | - | ||
77 | - | ||
78 | - | func lastCompoundTime () = int0(k_lastCompoundTime) | |
79 | - | ||
80 | - | ||
81 | - | func growthRate () = int0(k_growthRate) | |
82 | - | ||
83 | - | ||
84 | - | func balance () = int0(k_balance) | |
85 | - | ||
86 | - | ||
87 | - | func lastRate () = int(k_lastRate) | |
88 | - | ||
89 | - | ||
90 | - | func periodFinish () = int0(k_periodFinish) | |
91 | - | ||
92 | - | ||
93 | - | func adminPublicKeyOrUnit () = match getString(this, k_adminPublicKey) { | |
7 | + | func managerPublicKeyOrUnit () = match keyManagerPublicKey() { | |
94 | 8 | case s: String => | |
95 | 9 | fromBase58String(s) | |
96 | 10 | case _: Unit => | |
97 | 11 | unit | |
98 | 12 | case _ => | |
99 | 13 | throw("Match error") | |
100 | 14 | } | |
101 | 15 | ||
102 | 16 | ||
103 | - | func | |
17 | + | func mustManager (i) = { | |
104 | 18 | let pd = throw("permission denied") | |
105 | - | match | |
19 | + | match managerPublicKeyOrUnit() { | |
106 | 20 | case pk: ByteVector => | |
107 | 21 | if ((i.callerPublicKey == pk)) | |
108 | 22 | then true | |
109 | 23 | else pd | |
110 | 24 | case _: Unit => | |
111 | 25 | if ((i.caller == this)) | |
112 | 26 | then true | |
113 | 27 | else pd | |
114 | 28 | case _ => | |
115 | 29 | throw("Match error") | |
116 | 30 | } | |
117 | 31 | } | |
118 | 32 | ||
119 | 33 | ||
120 | - | func currentTimestampSec () = (lastBlock.timestamp / 1000) | |
121 | - | ||
122 | - | ||
123 | - | func dt () = minv(currentTimestampSec(), periodFinish()) | |
124 | - | ||
125 | - | ||
126 | - | func cancelLease () = match getBinary(k_leaseId) { | |
127 | - | case id: ByteVector => | |
128 | - | [LeaseCancel(id), DeleteEntry(k_leaseId)] | |
34 | + | func mustNotInited () = match getBoolean("inited") { | |
35 | + | case inited: Boolean => | |
36 | + | if ((inited == false)) | |
37 | + | then true | |
38 | + | else throw("Already inited") | |
129 | 39 | case _: Unit => | |
130 | - | | |
40 | + | false | |
131 | 41 | case _ => | |
132 | 42 | throw("Match error") | |
133 | 43 | } | |
134 | 44 | ||
135 | 45 | ||
136 | - | func updateBalance (_amount) = [IntegerEntry(k_balance, _amount)] | |
137 | - | ||
138 | - | ||
139 | - | func updateTime (_lastCompoundTime,_periodFinish) = [IntegerEntry(k_lastCompoundTime, _lastCompoundTime), IntegerEntry(k_periodFinish, _periodFinish)] | |
140 | - | ||
141 | - | ||
142 | - | func updateRate (_rate,_growthRate) = [IntegerEntry(k_lastRate, _rate), IntegerEntry(k_growthRate, _growthRate)] | |
143 | - | ||
144 | - | ||
145 | - | func updateLease (_amount) = if ((_amount > 0)) | |
146 | - | then { | |
147 | - | let newLease = Lease(minerAddress(), _amount) | |
148 | - | let newLeaseId = calculateLeaseId(newLease) | |
149 | - | [newLease, BinaryEntry(k_leaseId, newLeaseId)] | |
150 | - | } | |
151 | - | else nil | |
152 | - | ||
153 | - | ||
154 | - | func lease (_amount) = if ((_amount == 0)) | |
155 | - | then nil | |
156 | - | else { | |
157 | - | let newAmount = (balance() + _amount) | |
158 | - | ((cancelLease() ++ updateLease(newAmount)) ++ updateBalance(newAmount)) | |
159 | - | } | |
160 | - | ||
161 | - | ||
162 | - | func issueSWaves (_amount) = [Reissue(sWavesAsset(), _amount, true)] | |
163 | - | ||
164 | - | ||
165 | - | func burnSWaves (_amount) = [Burn(sWavesAsset(), _amount)] | |
166 | - | ||
167 | - | ||
168 | - | func sendSWaves (_recipient,_amount) = [ScriptTransfer(_recipient, _amount, sWavesAsset())] | |
169 | - | ||
170 | - | ||
171 | - | func sendWaves (_recipient,_amount) = [ScriptTransfer(_recipient, _amount, unit)] | |
172 | - | ||
173 | - | ||
174 | - | func sWavesQuantity () = match assetInfo(sWavesAsset()) { | |
175 | - | case asset: Asset => | |
176 | - | asset.quantity | |
177 | - | case _ => | |
178 | - | throw("Can't find asset") | |
179 | - | } | |
180 | - | ||
181 | - | ||
182 | - | func getExcessWaves () = wavesBalance(minerAddress()).regular | |
183 | - | ||
184 | - | ||
185 | - | func withdraw () = { | |
186 | - | let result = invoke(minerAddress(), "withdraw", nil, nil) | |
187 | - | if ((result == result)) | |
188 | - | then result | |
189 | - | else throw("Strict value is not equal to itself.") | |
190 | - | } | |
191 | - | ||
192 | - | ||
193 | - | func currentRate () = (lastRate() + (growthRate() * dt())) | |
194 | - | ||
195 | - | ||
196 | 46 | @Callable(i) | |
197 | - | func init (_minerAddress) = { | |
198 | - | let check = mustAdmin(i) | |
199 | - | if ((check == check)) | |
200 | - | then if (initialized()) | |
201 | - | then throw("Already initialized") | |
202 | - | else { | |
203 | - | let sWaves = Issue("sWaves", "", 0, 8, true, unit, 0) | |
204 | - | let sWavesAssetId = calculateAssetId(sWaves) | |
205 | - | [BooleanEntry(k_initialized, true), StringEntry(k_sWavesAsset, toBase58String(sWavesAssetId)), StringEntry(k_minerAddress, _minerAddress), IntegerEntry(k_lastRate, PRECISION), sWaves] | |
206 | - | } | |
47 | + | func init (mainAddress) = { | |
48 | + | let checks = [mustManager(i), mustNotInited()] | |
49 | + | if ((checks == checks)) | |
50 | + | then [BooleanEntry("inited", true), StringEntry("mainAddress", mainAddress)] | |
207 | 51 | else throw("Strict value is not equal to itself.") | |
208 | 52 | } | |
209 | 53 | ||
210 | 54 | ||
211 | 55 | ||
212 | 56 | @Callable(i) | |
213 | - | func compound () = if ((size(i.payments) != 0)) | |
214 | - | then throw("No payments allowed") | |
215 | - | else { | |
216 | - | let excessWaves = getExcessWaves() | |
217 | - | if ((excessWaves == excessWaves)) | |
218 | - | then if (((1 * DECIMALS) > excessWaves)) | |
219 | - | then nil | |
220 | - | else { | |
221 | - | let doWithdraw = withdraw() | |
222 | - | if ((doWithdraw == doWithdraw)) | |
223 | - | then { | |
224 | - | let newRate = currentRate() | |
225 | - | let timestamp = currentTimestampSec() | |
226 | - | let newGrowthRate = if ((timestamp > periodFinish())) | |
227 | - | then (divp(excessWaves, DECIMALS) / DURATION) | |
228 | - | else { | |
229 | - | let remainingTime = (periodFinish() - timestamp) | |
230 | - | let leftover = (growthRate() * remainingTime) | |
231 | - | (divp((excessWaves + leftover), DECIMALS) / DURATION) | |
232 | - | } | |
233 | - | ((lease(excessWaves) ++ updateRate(newRate, newGrowthRate)) ++ updateTime(timestamp, (timestamp + DURATION))) | |
234 | - | } | |
235 | - | else throw("Strict value is not equal to itself.") | |
236 | - | } | |
237 | - | else throw("Strict value is not equal to itself.") | |
238 | - | } | |
239 | - | ||
240 | - | ||
241 | - | ||
242 | - | @Callable(i) | |
243 | - | func stake () = { | |
244 | - | let doCompound = invoke(this, "compound", nil, nil) | |
245 | - | if ((doCompound == doCompound)) | |
246 | - | then { | |
247 | - | let payment = i.payments[0] | |
248 | - | if ((payment.assetId != unit)) | |
249 | - | then throw("Only WAVES supported") | |
250 | - | else if ((size(i.payments) != 1)) | |
251 | - | then throw("Wrong payments amount") | |
252 | - | else { | |
253 | - | let rate = currentRate() | |
254 | - | let toReissue = divp(payment.amount, rate) | |
255 | - | ((lease(payment.amount) ++ issueSWaves(toReissue)) ++ sendSWaves(i.caller, toReissue)) | |
256 | - | } | |
257 | - | } | |
258 | - | else throw("Strict value is not equal to itself.") | |
259 | - | } | |
260 | - | ||
261 | - | ||
262 | - | ||
263 | - | @Callable(i) | |
264 | - | func unstake () = { | |
265 | - | let doCompound = invoke(this, "compound", nil, nil) | |
266 | - | if ((doCompound == doCompound)) | |
267 | - | then { | |
268 | - | let payment = i.payments[0] | |
269 | - | if ((payment.assetId != sWavesAsset())) | |
270 | - | then throw("Only sWAVES supported") | |
271 | - | else if ((size(i.payments) != 1)) | |
272 | - | then throw("Wrong payments amount") | |
273 | - | else { | |
274 | - | let rate = currentRate() | |
275 | - | let transferAmount = mulp(payment.amount, rate) | |
276 | - | ((lease(-(transferAmount)) ++ burnSWaves(payment.amount)) ++ sendWaves(i.caller, transferAmount)) | |
277 | - | } | |
278 | - | } | |
279 | - | else throw("Strict value is not equal to itself.") | |
57 | + | func withdraw () = { | |
58 | + | let mainAddress = Address(fromBase58String(getStringValue("mainAddress"))) | |
59 | + | let regularBalance = wavesBalance(this).regular | |
60 | + | if ((i.caller != mainAddress)) | |
61 | + | then throw("Only main contract can invoke this method") | |
62 | + | else [ScriptTransfer(mainAddress, regularBalance, unit)] | |
280 | 63 | } | |
281 | 64 | ||
282 | 65 | ||
283 | 66 | @Verifier(tx) | |
284 | 67 | func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
285 | 68 |
github/deemru/w8io/026f985 29.66 ms ◑