tx · DNcrzR2jfxShwvZnwrRXMvsvsYqeGUH3owszfVi5HcN7 3PPpppPpSCRStzVGeZTPsZb5h467qbyqadm: -0.01400000 Waves 2019.10.17 12:25 [1753988] smart account 3PPpppPpSCRStzVGeZTPsZb5h467qbyqadm > SELF 0.00000000 Waves
{ "type": 13, "id": "DNcrzR2jfxShwvZnwrRXMvsvsYqeGUH3owszfVi5HcN7", "fee": 1400000, "feeAssetId": null, "timestamp": 1571304322130, "version": 1, "sender": "3PPpppPpSCRStzVGeZTPsZb5h467qbyqadm", "senderPublicKey": "9h8XTnBfjfoV5MWJVDUMkaLNMZbWpUqrTz1wjaAejUez", "proofs": [ "r6t46Zvz37v6Ph5Xm6xkF5aMbJZ959p4nPLbZg9HCtVdmEb36xbdkYtNsNzPHQdKyAnCVNhFZfoQV8sMoQUx3cf" ], "script": "base64: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", "chainId": 87, "height": 1753988, "spentComplexity": 0 } View: original | compacted Prev: 4se9jS3yRz5YkVqs8GzYoAebzjYt7pRxR8Xso2PL4Esn Next: FvLcM1tS3Ax2eZkT8HjwxD2hAd9Gq2nACcHqkmEc6fd2 Diff:
Old | New | Differences | |
---|---|---|---|
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let uTokenId = base58'GHh7EMnVnUBCYNJMktuLPVr3P2oCqBCb4c87fBCZ5CzY' | |
5 | 5 | ||
6 | - | let admin = | |
6 | + | let admin = addressFromPublicKey(base58'GfQfmZD32YEkaMEgDUB7iesZaJf7NysjxxSheA8PzSYV') | |
7 | 7 | ||
8 | 8 | let shutdownFlag = match getBoolean(this, "shutdown_flag") { | |
9 | 9 | case bool: Boolean => | |
276 | 276 | ||
277 | 277 | ||
278 | 278 | @Callable(i) | |
279 | - | func takeSell ( | |
279 | + | func takeSell (id,sig) = if (shutdownFlag) | |
280 | 280 | then throw(shutdownMessage) | |
281 | 281 | else { | |
282 | + | let orderId = ("order_" + id) | |
282 | 283 | let payment = valueOrErrorMessage(i.payment, "Where is payment?") | |
283 | 284 | let priceAssetAmount = payment.amount | |
284 | 285 | if ((0 >= priceAssetAmount)) | |
341 | 342 | ||
342 | 343 | ||
343 | 344 | @Callable(i) | |
344 | - | func takeBuy ( | |
345 | + | func takeBuy (id,sig) = if (shutdownFlag) | |
345 | 346 | then throw(shutdownMessage) | |
346 | 347 | else { | |
348 | + | let orderId = ("order_" + id) | |
347 | 349 | let payment = valueOrErrorMessage(i.payment, "where is payment?") | |
348 | 350 | let amount = payment.amount | |
349 | 351 | if ((0 >= amount)) | |
406 | 408 | ||
407 | 409 | ||
408 | 410 | @Callable(i) | |
409 | - | func returnSell (orderId) = { | |
411 | + | func returnSell (id) = { | |
412 | + | let orderId = ("order_" + id) | |
410 | 413 | let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id") | |
411 | 414 | let parts = split(data, "_") | |
412 | 415 | let orderType = parts[0] | |
425 | 428 | else if (if ((orderOwner != i.caller)) | |
426 | 429 | then !(shutdownFlag) | |
427 | 430 | else false) | |
428 | - | then throw(" | |
431 | + | then throw("Return should be called by order owner") | |
429 | 432 | else { | |
430 | 433 | let returnAmount = (orderAmount - orderSpent) | |
431 | 434 | if ((0 >= returnAmount)) | |
432 | - | then throw(" | |
435 | + | then throw("Nothing to return") | |
433 | 436 | else { | |
434 | 437 | let newData = (dropRight(data, size(parts[8])) + toString(orderAmount)) | |
435 | 438 | ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([ScriptTransfer(orderOwner, returnAmount, if ((orderAmountAsset == "WAVES")) | |
442 | 445 | ||
443 | 446 | ||
444 | 447 | @Callable(i) | |
445 | - | func returnBuy (orderId) = { | |
448 | + | func returnBuy (id) = { | |
449 | + | let orderId = ("order_" + id) | |
446 | 450 | let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id") | |
447 | 451 | let parts = split(data, "_") | |
448 | 452 | let orderType = parts[0] | |
465 | 469 | else { | |
466 | 470 | let returnAmount = (orderPriceAssetAmount - orderSpent) | |
467 | 471 | if ((0 >= returnAmount)) | |
468 | - | then throw(" | |
472 | + | then throw("Nothing to return") | |
469 | 473 | else { | |
470 | 474 | let newData = (dropRight(data, size(parts[8])) + toString(orderPriceAssetAmount)) | |
471 | 475 | ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([ScriptTransfer(orderOwner, returnAmount, if ((orderPriceAsset == "WAVES")) | |
511 | 515 | ||
512 | 516 | ||
513 | 517 | @Callable(i) | |
514 | - | func | |
518 | + | func shutdown (msg) = if ((i.caller != admin)) | |
515 | 519 | then throw("You should be an admin") | |
516 | 520 | else WriteSet([DataEntry("shutdown_flag", true), DataEntry("shutdown_message", msg)]) | |
517 | 521 |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 3 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let uTokenId = base58'GHh7EMnVnUBCYNJMktuLPVr3P2oCqBCb4c87fBCZ5CzY' | |
5 | 5 | ||
6 | - | let admin = | |
6 | + | let admin = addressFromPublicKey(base58'GfQfmZD32YEkaMEgDUB7iesZaJf7NysjxxSheA8PzSYV') | |
7 | 7 | ||
8 | 8 | let shutdownFlag = match getBoolean(this, "shutdown_flag") { | |
9 | 9 | case bool: Boolean => | |
10 | 10 | bool | |
11 | 11 | case _: Unit => | |
12 | 12 | false | |
13 | 13 | case _ => | |
14 | 14 | throw() | |
15 | 15 | } | |
16 | 16 | ||
17 | 17 | let shutdownMessage = match getString(this, "shutdown_message") { | |
18 | 18 | case str: String => | |
19 | 19 | str | |
20 | 20 | case _: Unit => | |
21 | 21 | "Forbidden" | |
22 | 22 | case _ => | |
23 | 23 | throw() | |
24 | 24 | } | |
25 | 25 | ||
26 | 26 | let reserve = match getInteger(this, "reserve") { | |
27 | 27 | case int: Int => | |
28 | 28 | int | |
29 | 29 | case _: Unit => | |
30 | 30 | 0 | |
31 | 31 | case _ => | |
32 | 32 | throw() | |
33 | 33 | } | |
34 | 34 | ||
35 | 35 | let balance = match getInteger(this, "balance") { | |
36 | 36 | case int: Int => | |
37 | 37 | int | |
38 | 38 | case _: Unit => | |
39 | 39 | 0 | |
40 | 40 | case _ => | |
41 | 41 | throw() | |
42 | 42 | } | |
43 | 43 | ||
44 | 44 | func checkStatus (address) = { | |
45 | 45 | let statusUnlimited = match getBoolean(this, (address + "_unlimited")) { | |
46 | 46 | case bool: Boolean => | |
47 | 47 | bool | |
48 | 48 | case _: Unit => | |
49 | 49 | false | |
50 | 50 | case _ => | |
51 | 51 | throw() | |
52 | 52 | } | |
53 | 53 | let statusTime = match getInteger(this, (address + "_time")) { | |
54 | 54 | case int: Int => | |
55 | 55 | int | |
56 | 56 | case _: Unit => | |
57 | 57 | 0 | |
58 | 58 | case _ => | |
59 | 59 | throw() | |
60 | 60 | } | |
61 | 61 | if (statusUnlimited) | |
62 | 62 | then true | |
63 | 63 | else (statusTime > lastBlock.timestamp) | |
64 | 64 | } | |
65 | 65 | ||
66 | 66 | ||
67 | 67 | @Callable(i) | |
68 | 68 | func addAsset (assetId) = if (shutdownFlag) | |
69 | 69 | then throw(shutdownMessage) | |
70 | 70 | else { | |
71 | 71 | let addingPrice = (100 * 100000000) | |
72 | 72 | let addingPriceStr = "100" | |
73 | 73 | let payment = valueOrErrorMessage(i.payment, "Where is payment?") | |
74 | 74 | if (if (isDefined(payment.assetId)) | |
75 | 75 | then (payment.assetId != uTokenId) | |
76 | 76 | else false) | |
77 | 77 | then throw("OTCu or WAVES only") | |
78 | 78 | else if ((payment.amount != addingPrice)) | |
79 | 79 | then throw((("You have to pay " + addingPriceStr) + " OTCu or WAVES")) | |
80 | 80 | else if (!(isDefined(assetInfo(fromBase58String(assetId))))) | |
81 | 81 | then throw("There is no asset with specified id") | |
82 | 82 | else { | |
83 | 83 | let assets = match getString(this, "assets") { | |
84 | 84 | case str: String => | |
85 | 85 | str | |
86 | 86 | case _: Unit => | |
87 | 87 | "" | |
88 | 88 | case _ => | |
89 | 89 | throw() | |
90 | 90 | } | |
91 | 91 | if (isDefined(indexOf(assets, assetId))) | |
92 | 92 | then throw("Asset is already available") | |
93 | 93 | else { | |
94 | 94 | let list0 = [DataEntry("assets", ((assets + assetId) + ","))] | |
95 | 95 | let list1 = if ((payment.assetId == uTokenId)) | |
96 | 96 | then DataEntry("reserve", (reserve + payment.amount)) :: list0 | |
97 | 97 | else if (!(isDefined(payment.assetId))) | |
98 | 98 | then DataEntry("balance", (balance + payment.amount)) :: list0 | |
99 | 99 | else list0 | |
100 | 100 | WriteSet(list1) | |
101 | 101 | } | |
102 | 102 | } | |
103 | 103 | } | |
104 | 104 | ||
105 | 105 | ||
106 | 106 | ||
107 | 107 | @Callable(i) | |
108 | 108 | func pro () = if (shutdownFlag) | |
109 | 109 | then throw(shutdownMessage) | |
110 | 110 | else { | |
111 | 111 | let address = toBase58String(i.caller.bytes) | |
112 | 112 | let unlimitedPrice = (50 * 100000000) | |
113 | 113 | let unlimitedPriceStr = "50" | |
114 | 114 | let monthPrice = (10 * 100000000) | |
115 | 115 | let monthPriceStr = "10" | |
116 | 116 | let payment = valueOrErrorMessage(i.payment, "Where is payment?") | |
117 | 117 | if (if (isDefined(payment.assetId)) | |
118 | 118 | then (payment.assetId != uTokenId) | |
119 | 119 | else false) | |
120 | 120 | then throw("OTCu or WAVES only") | |
121 | 121 | else if (if ((payment.amount != unlimitedPrice)) | |
122 | 122 | then (payment.amount != monthPrice) | |
123 | 123 | else false) | |
124 | 124 | then throw("Invalid payment") | |
125 | 125 | else { | |
126 | 126 | let unlimited = (payment.amount == unlimitedPrice) | |
127 | 127 | let currentUnlimited = match getBoolean(this, (address + "_unlimited")) { | |
128 | 128 | case bool: Boolean => | |
129 | 129 | bool | |
130 | 130 | case _: Unit => | |
131 | 131 | false | |
132 | 132 | case _ => | |
133 | 133 | throw() | |
134 | 134 | } | |
135 | 135 | let currentTime = match getInteger(this, (address + "_time")) { | |
136 | 136 | case int: Int => | |
137 | 137 | int | |
138 | 138 | case _: Unit => | |
139 | 139 | lastBlock.timestamp | |
140 | 140 | case _ => | |
141 | 141 | throw() | |
142 | 142 | } | |
143 | 143 | if (currentUnlimited) | |
144 | 144 | then throw("You have unlimited PRO status already. What do you want?") | |
145 | 145 | else { | |
146 | 146 | let month = 2629743000 | |
147 | 147 | let list0 = [DataEntry((address + "_unlimited"), unlimited), DataEntry((address + "_time"), if (unlimited) | |
148 | 148 | then 0 | |
149 | 149 | else (currentTime + month))] | |
150 | 150 | let list1 = if ((payment.assetId == uTokenId)) | |
151 | 151 | then DataEntry("reserve", (reserve + payment.amount)) :: list0 | |
152 | 152 | else if (!(isDefined(payment.assetId))) | |
153 | 153 | then DataEntry("balance", (balance + payment.amount)) :: list0 | |
154 | 154 | else list0 | |
155 | 155 | WriteSet(list1) | |
156 | 156 | } | |
157 | 157 | } | |
158 | 158 | } | |
159 | 159 | ||
160 | 160 | ||
161 | 161 | ||
162 | 162 | @Callable(i) | |
163 | 163 | func buyUtilityToken () = if (shutdownFlag) | |
164 | 164 | then throw(shutdownMessage) | |
165 | 165 | else { | |
166 | 166 | let payment = valueOrErrorMessage(i.payment, "Where is payment?") | |
167 | 167 | if (isDefined(payment.assetId)) | |
168 | 168 | then throw("WAVES only") | |
169 | 169 | else if ((payment.amount > reserve)) | |
170 | 170 | then throw("Not enougth asset in dApp") | |
171 | 171 | else ScriptResult(WriteSet([DataEntry("reserve", (reserve - payment.amount)), DataEntry("balance", (balance + payment.amount))]), TransferSet([ScriptTransfer(i.caller, payment.amount, uTokenId)])) | |
172 | 172 | } | |
173 | 173 | ||
174 | 174 | ||
175 | 175 | ||
176 | 176 | @Callable(i) | |
177 | 177 | func makeSell (priceAsset,priceAssetAmount,all,password) = if (shutdownFlag) | |
178 | 178 | then throw(shutdownMessage) | |
179 | 179 | else if (if ((priceAsset != "WAVES")) | |
180 | 180 | then !(isDefined(assetInfo(fromBase58String(priceAsset)))) | |
181 | 181 | else false) | |
182 | 182 | then throw("There is no asset with specified id") | |
183 | 183 | else if ((0 >= priceAssetAmount)) | |
184 | 184 | then throw("Amount of price asset must be positive") | |
185 | 185 | else { | |
186 | 186 | let payment = valueOrErrorMessage(i.payment, "Where is payment?") | |
187 | 187 | if ((0 >= payment.amount)) | |
188 | 188 | then throw("Amount must be positive") | |
189 | 189 | else { | |
190 | 190 | let amountAsset = match payment.assetId { | |
191 | 191 | case p: ByteVector => | |
192 | 192 | toBase58String(p) | |
193 | 193 | case _ => | |
194 | 194 | "WAVES" | |
195 | 195 | } | |
196 | 196 | if ((amountAsset == priceAsset)) | |
197 | 197 | then throw("Invalid pair") | |
198 | 198 | else { | |
199 | 199 | let assets = valueOrErrorMessage(getString(this, "assets"), "There are not available assets") | |
200 | 200 | if (if (!(isDefined(indexOf(assets, priceAsset)))) | |
201 | 201 | then true | |
202 | 202 | else !(isDefined(indexOf(assets, amountAsset)))) | |
203 | 203 | then throw("Asset are not available for trading") | |
204 | 204 | else { | |
205 | 205 | let address = toBase58String(i.caller.bytes) | |
206 | 206 | if (if (!(checkStatus(address))) | |
207 | 207 | then if (all) | |
208 | 208 | then true | |
209 | 209 | else (password != "") | |
210 | 210 | else false) | |
211 | 211 | then throw("You must have pro status to use these features") | |
212 | 212 | else { | |
213 | 213 | let orderId = ("order_" + toBase58String(i.transactionId)) | |
214 | 214 | let passwordValid = fromBase58String(password) | |
215 | 215 | let data = (((((((((((((((("sell" + "_") + toString(payment.amount)) + "_") + amountAsset) + "_") + toString(priceAssetAmount)) + "_") + priceAsset) + "_") + address) + "_") + toString(all)) + "_") + password) + "_") + toString(0)) | |
216 | 216 | WriteSet([DataEntry(orderId, data)]) | |
217 | 217 | } | |
218 | 218 | } | |
219 | 219 | } | |
220 | 220 | } | |
221 | 221 | } | |
222 | 222 | ||
223 | 223 | ||
224 | 224 | ||
225 | 225 | @Callable(i) | |
226 | 226 | func makeBuy (amountAsset,amount,all,password) = if (shutdownFlag) | |
227 | 227 | then throw(shutdownMessage) | |
228 | 228 | else if (if ((amountAsset != "WAVES")) | |
229 | 229 | then !(isDefined(assetInfo(fromBase58String(amountAsset)))) | |
230 | 230 | else false) | |
231 | 231 | then throw("There is no asset with specified id") | |
232 | 232 | else if ((0 >= amount)) | |
233 | 233 | then throw("Amount must be positive") | |
234 | 234 | else { | |
235 | 235 | let payment = valueOrErrorMessage(i.payment, "where is payment?") | |
236 | 236 | let priceAssetAmount = payment.amount | |
237 | 237 | if ((0 >= priceAssetAmount)) | |
238 | 238 | then throw("amount must be positive") | |
239 | 239 | else { | |
240 | 240 | let priceAsset = match payment.assetId { | |
241 | 241 | case p: ByteVector => | |
242 | 242 | toBase58String(p) | |
243 | 243 | case _ => | |
244 | 244 | "WAVES" | |
245 | 245 | } | |
246 | 246 | if ((amountAsset == priceAsset)) | |
247 | 247 | then throw("Invalid pair") | |
248 | 248 | else { | |
249 | 249 | let assets = valueOrErrorMessage(getString(this, "assets"), "There are not available assets") | |
250 | 250 | if (if (!(isDefined(indexOf(assets, priceAsset)))) | |
251 | 251 | then true | |
252 | 252 | else !(isDefined(indexOf(assets, amountAsset)))) | |
253 | 253 | then throw("Asset are not available for trading") | |
254 | 254 | else { | |
255 | 255 | let address = toBase58String(i.caller.bytes) | |
256 | 256 | if (if (!(checkStatus(address))) | |
257 | 257 | then if (all) | |
258 | 258 | then true | |
259 | 259 | else (password != "") | |
260 | 260 | else false) | |
261 | 261 | then throw("You must have pro status to use these features") | |
262 | 262 | else { | |
263 | 263 | let orderId = ("order_" + toBase58String(i.transactionId)) | |
264 | 264 | if ((amount == 0)) | |
265 | 265 | then throw("invalid buy amount") | |
266 | 266 | else { | |
267 | 267 | let data = (((((((((((((((("buy" + "_") + toString(amount)) + "_") + amountAsset) + "_") + toString(priceAssetAmount)) + "_") + priceAsset) + "_") + address) + "_") + toString(all)) + "_") + password) + "_") + toString(0)) | |
268 | 268 | WriteSet([DataEntry(orderId, data)]) | |
269 | 269 | } | |
270 | 270 | } | |
271 | 271 | } | |
272 | 272 | } | |
273 | 273 | } | |
274 | 274 | } | |
275 | 275 | ||
276 | 276 | ||
277 | 277 | ||
278 | 278 | @Callable(i) | |
279 | - | func takeSell ( | |
279 | + | func takeSell (id,sig) = if (shutdownFlag) | |
280 | 280 | then throw(shutdownMessage) | |
281 | 281 | else { | |
282 | + | let orderId = ("order_" + id) | |
282 | 283 | let payment = valueOrErrorMessage(i.payment, "Where is payment?") | |
283 | 284 | let priceAssetAmount = payment.amount | |
284 | 285 | if ((0 >= priceAssetAmount)) | |
285 | 286 | then throw("Amount must be positive") | |
286 | 287 | else { | |
287 | 288 | let priceAsset = match payment.assetId { | |
288 | 289 | case p: ByteVector => | |
289 | 290 | toBase58String(p) | |
290 | 291 | case _ => | |
291 | 292 | "WAVES" | |
292 | 293 | } | |
293 | 294 | let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id") | |
294 | 295 | let parts = split(data, "_") | |
295 | 296 | let orderType = parts[0] | |
296 | 297 | let orderAmount = parseIntValue(parts[1]) | |
297 | 298 | let orderAmountAsset = parts[2] | |
298 | 299 | let orderPriceAssetAmount = parseIntValue(parts[3]) | |
299 | 300 | let orderPriceAsset = parts[4] | |
300 | 301 | let orderOwner = value(addressFromString(parts[5])) | |
301 | 302 | let orderAll = if ((parts[6] == "true")) | |
302 | 303 | then true | |
303 | 304 | else false | |
304 | 305 | let orderPassword = parts[7] | |
305 | 306 | let orderSpent = parseIntValue(parts[8]) | |
306 | 307 | if ((orderType != "sell")) | |
307 | 308 | then throw("Invalid order type") | |
308 | 309 | else if ((orderPriceAsset != priceAsset)) | |
309 | 310 | then throw(("Payment asset must be " + orderPriceAsset)) | |
310 | 311 | else { | |
311 | 312 | let valid = if ((orderPassword != "")) | |
312 | 313 | then sigVerify(i.callerPublicKey, fromBase58String(sig), fromBase58String(orderPassword)) | |
313 | 314 | else true | |
314 | 315 | if (!(valid)) | |
315 | 316 | then throw("The order is private") | |
316 | 317 | else { | |
317 | 318 | let amount = ((priceAssetAmount * orderAmount) / orderPriceAssetAmount) | |
318 | 319 | if ((amount == 0)) | |
319 | 320 | then throw("Invalid amount") | |
320 | 321 | else if (if (orderAll) | |
321 | 322 | then (orderAmount > amount) | |
322 | 323 | else false) | |
323 | 324 | then throw("You must take all or none") | |
324 | 325 | else if ((amount > (orderAmount - orderSpent))) | |
325 | 326 | then throw("Not enougth asset in order") | |
326 | 327 | else { | |
327 | 328 | let newData = (dropRight(data, size(parts[8])) + toString((orderSpent + amount))) | |
328 | 329 | let toCaller = ScriptTransfer(i.caller, amount, if ((orderAmountAsset == "WAVES")) | |
329 | 330 | then unit | |
330 | 331 | else fromBase58String(orderAmountAsset)) | |
331 | 332 | let toOwner = ScriptTransfer(orderOwner, priceAssetAmount, if ((orderPriceAsset == "WAVES")) | |
332 | 333 | then unit | |
333 | 334 | else fromBase58String(orderPriceAsset)) | |
334 | 335 | ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([toCaller, toOwner])) | |
335 | 336 | } | |
336 | 337 | } | |
337 | 338 | } | |
338 | 339 | } | |
339 | 340 | } | |
340 | 341 | ||
341 | 342 | ||
342 | 343 | ||
343 | 344 | @Callable(i) | |
344 | - | func takeBuy ( | |
345 | + | func takeBuy (id,sig) = if (shutdownFlag) | |
345 | 346 | then throw(shutdownMessage) | |
346 | 347 | else { | |
348 | + | let orderId = ("order_" + id) | |
347 | 349 | let payment = valueOrErrorMessage(i.payment, "where is payment?") | |
348 | 350 | let amount = payment.amount | |
349 | 351 | if ((0 >= amount)) | |
350 | 352 | then throw("amount must be positive") | |
351 | 353 | else { | |
352 | 354 | let amountAsset = match payment.assetId { | |
353 | 355 | case p: ByteVector => | |
354 | 356 | toBase58String(p) | |
355 | 357 | case _ => | |
356 | 358 | "WAVES" | |
357 | 359 | } | |
358 | 360 | let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id") | |
359 | 361 | let parts = split(data, "_") | |
360 | 362 | let orderType = parts[0] | |
361 | 363 | let orderAmount = parseIntValue(parts[1]) | |
362 | 364 | let orderAmountAsset = parts[2] | |
363 | 365 | let orderPriceAssetAmount = parseIntValue(parts[3]) | |
364 | 366 | let orderPriceAsset = parts[4] | |
365 | 367 | let orderOwner = value(addressFromString(parts[5])) | |
366 | 368 | let orderAll = if ((parts[6] == "true")) | |
367 | 369 | then true | |
368 | 370 | else false | |
369 | 371 | let orderPassword = parts[7] | |
370 | 372 | let orderSpent = parseIntValue(parts[8]) | |
371 | 373 | if ((orderType != "buy")) | |
372 | 374 | then throw("Invalid order type") | |
373 | 375 | else if ((orderAmountAsset != amountAsset)) | |
374 | 376 | then throw(("payment asset must be " + orderAmountAsset)) | |
375 | 377 | else { | |
376 | 378 | let valid = if ((orderPassword != "")) | |
377 | 379 | then sigVerify(i.callerPublicKey, fromBase58String(sig), fromBase58String(orderPassword)) | |
378 | 380 | else true | |
379 | 381 | if (!(valid)) | |
380 | 382 | then throw("The order is private") | |
381 | 383 | else { | |
382 | 384 | let priceAssetAmount = ((amount * orderPriceAssetAmount) / orderAmount) | |
383 | 385 | if ((priceAssetAmount == 0)) | |
384 | 386 | then throw("Invalid amount") | |
385 | 387 | else if (if (orderAll) | |
386 | 388 | then (orderPriceAssetAmount > priceAssetAmount) | |
387 | 389 | else false) | |
388 | 390 | then throw("You must take all or none") | |
389 | 391 | else if ((priceAssetAmount > (orderPriceAssetAmount - orderSpent))) | |
390 | 392 | then throw("not enougth asset in order") | |
391 | 393 | else { | |
392 | 394 | let newData = (dropRight(data, size(parts[8])) + toString((orderSpent + priceAssetAmount))) | |
393 | 395 | let toCaller = ScriptTransfer(i.caller, priceAssetAmount, if ((orderPriceAsset == "WAVES")) | |
394 | 396 | then unit | |
395 | 397 | else fromBase58String(orderPriceAsset)) | |
396 | 398 | let toOwner = ScriptTransfer(orderOwner, amount, if ((orderAmountAsset == "WAVES")) | |
397 | 399 | then unit | |
398 | 400 | else fromBase58String(orderAmountAsset)) | |
399 | 401 | ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([toCaller, toOwner])) | |
400 | 402 | } | |
401 | 403 | } | |
402 | 404 | } | |
403 | 405 | } | |
404 | 406 | } | |
405 | 407 | ||
406 | 408 | ||
407 | 409 | ||
408 | 410 | @Callable(i) | |
409 | - | func returnSell (orderId) = { | |
411 | + | func returnSell (id) = { | |
412 | + | let orderId = ("order_" + id) | |
410 | 413 | let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id") | |
411 | 414 | let parts = split(data, "_") | |
412 | 415 | let orderType = parts[0] | |
413 | 416 | let orderAmount = parseIntValue(parts[1]) | |
414 | 417 | let orderAmountAsset = parts[2] | |
415 | 418 | let orderPriceAssetAmount = parseIntValue(parts[3]) | |
416 | 419 | let orderPriceAsset = parts[4] | |
417 | 420 | let orderOwner = value(addressFromString(parts[5])) | |
418 | 421 | let orderAll = if ((parts[6] == "true")) | |
419 | 422 | then true | |
420 | 423 | else false | |
421 | 424 | let orderPassword = parts[7] | |
422 | 425 | let orderSpent = parseIntValue(parts[8]) | |
423 | 426 | if ((orderType != "sell")) | |
424 | 427 | then throw("Invalid order type") | |
425 | 428 | else if (if ((orderOwner != i.caller)) | |
426 | 429 | then !(shutdownFlag) | |
427 | 430 | else false) | |
428 | - | then throw(" | |
431 | + | then throw("Return should be called by order owner") | |
429 | 432 | else { | |
430 | 433 | let returnAmount = (orderAmount - orderSpent) | |
431 | 434 | if ((0 >= returnAmount)) | |
432 | - | then throw(" | |
435 | + | then throw("Nothing to return") | |
433 | 436 | else { | |
434 | 437 | let newData = (dropRight(data, size(parts[8])) + toString(orderAmount)) | |
435 | 438 | ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([ScriptTransfer(orderOwner, returnAmount, if ((orderAmountAsset == "WAVES")) | |
436 | 439 | then unit | |
437 | 440 | else fromBase58String(orderAmountAsset))])) | |
438 | 441 | } | |
439 | 442 | } | |
440 | 443 | } | |
441 | 444 | ||
442 | 445 | ||
443 | 446 | ||
444 | 447 | @Callable(i) | |
445 | - | func returnBuy (orderId) = { | |
448 | + | func returnBuy (id) = { | |
449 | + | let orderId = ("order_" + id) | |
446 | 450 | let data = valueOrErrorMessage(getString(this, orderId), "Invalid order id") | |
447 | 451 | let parts = split(data, "_") | |
448 | 452 | let orderType = parts[0] | |
449 | 453 | let orderAmount = parseIntValue(parts[1]) | |
450 | 454 | let orderAmountAsset = parts[2] | |
451 | 455 | let orderPriceAssetAmount = parseIntValue(parts[3]) | |
452 | 456 | let orderPriceAsset = parts[4] | |
453 | 457 | let orderOwner = value(addressFromString(parts[5])) | |
454 | 458 | let orderAll = if ((parts[6] == "true")) | |
455 | 459 | then true | |
456 | 460 | else false | |
457 | 461 | let orderPassword = parts[7] | |
458 | 462 | let orderSpent = parseIntValue(parts[8]) | |
459 | 463 | if ((orderType != "buy")) | |
460 | 464 | then throw("Invalid order type") | |
461 | 465 | else if (if ((orderOwner != i.caller)) | |
462 | 466 | then !(shutdownFlag) | |
463 | 467 | else false) | |
464 | 468 | then throw("Return should be called by order owner") | |
465 | 469 | else { | |
466 | 470 | let returnAmount = (orderPriceAssetAmount - orderSpent) | |
467 | 471 | if ((0 >= returnAmount)) | |
468 | - | then throw(" | |
472 | + | then throw("Nothing to return") | |
469 | 473 | else { | |
470 | 474 | let newData = (dropRight(data, size(parts[8])) + toString(orderPriceAssetAmount)) | |
471 | 475 | ScriptResult(WriteSet([DataEntry(orderId, newData)]), TransferSet([ScriptTransfer(orderOwner, returnAmount, if ((orderPriceAsset == "WAVES")) | |
472 | 476 | then unit | |
473 | 477 | else fromBase58String(orderPriceAsset))])) | |
474 | 478 | } | |
475 | 479 | } | |
476 | 480 | } | |
477 | 481 | ||
478 | 482 | ||
479 | 483 | ||
480 | 484 | @Callable(i) | |
481 | 485 | func withdraw (mode) = if ((i.caller != admin)) | |
482 | 486 | then throw("You should be an admin") | |
483 | 487 | else if (if (if ((mode != "balance")) | |
484 | 488 | then (mode != "reserve") | |
485 | 489 | else false) | |
486 | 490 | then (mode != "all") | |
487 | 491 | else false) | |
488 | 492 | then throw("Specify the mode: balance, reserve or all") | |
489 | 493 | else { | |
490 | 494 | let balanceEntry = DataEntry("balance", 0) | |
491 | 495 | let balanceTransfer = ScriptTransfer(admin, balance, unit) | |
492 | 496 | let reserveEntry = DataEntry("reserve", 0) | |
493 | 497 | let reserveTransfer = ScriptTransfer(admin, reserve, unit) | |
494 | 498 | let writeSet = if ((mode == "balance")) | |
495 | 499 | then [balanceEntry] | |
496 | 500 | else if ((mode == "reserve")) | |
497 | 501 | then [reserveEntry] | |
498 | 502 | else if ((mode == "all")) | |
499 | 503 | then [balanceEntry, reserveEntry] | |
500 | 504 | else nil | |
501 | 505 | let transferSet = if ((mode == "balance")) | |
502 | 506 | then [balanceTransfer] | |
503 | 507 | else if ((mode == "reserve")) | |
504 | 508 | then [reserveTransfer] | |
505 | 509 | else if ((mode == "all")) | |
506 | 510 | then [balanceTransfer, reserveTransfer] | |
507 | 511 | else nil | |
508 | 512 | ScriptResult(WriteSet(writeSet), TransferSet(transferSet)) | |
509 | 513 | } | |
510 | 514 | ||
511 | 515 | ||
512 | 516 | ||
513 | 517 | @Callable(i) | |
514 | - | func | |
518 | + | func shutdown (msg) = if ((i.caller != admin)) | |
515 | 519 | then throw("You should be an admin") | |
516 | 520 | else WriteSet([DataEntry("shutdown_flag", true), DataEntry("shutdown_message", msg)]) | |
517 | 521 | ||
518 | 522 |
github/deemru/w8io/3ef1775 81.14 ms ◑