tx · 55GJUzcALJ8yTorrX4nwJuc3Fb88VMpHJSaHA2RozkUG 3P9qEs3aQgRgzBLo7hRvQahNRJvTTGoTWAP: -0.00800000 Waves 2023.12.09 04:03 [3944336] smart account 3P9qEs3aQgRgzBLo7hRvQahNRJvTTGoTWAP > SELF 0.00000000 Waves
{ "type": 13, "id": "55GJUzcALJ8yTorrX4nwJuc3Fb88VMpHJSaHA2RozkUG", "fee": 800000, "feeAssetId": null, "timestamp": 1702083898016, "version": 1, "sender": "3P9qEs3aQgRgzBLo7hRvQahNRJvTTGoTWAP", "senderPublicKey": "82tJD4S4PqubHb5MGYkwokWMWR3LvY4UgyXTxsT6JWPn", "proofs": [ "5166JdqwKkvcYW19DcnRZokJuwZ66uhdKdPu6GkBQHa38EA26BrfjF22KQ7dkr7NE4SXq2tF6rbe473B88gNfTC5" ], "script": "base64:BgI6CAISAwoBBBIDCgEIEgcKBQgIAQEIEgcKBQgICAEBEgUKAwgICBIFCgMICAgSBQoDCAgIEgUKAwgICBkABVFVQU5UALDqAQAJTUFYX0NFTExTAHgACU1BWF9JTkRFWAkAZQIFCU1BWF9DRUxMUwABAARNSVNTAXj///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8ABENFTEwBeAABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2dwAJUFJFQ0lTSU9OCQC2AgEAgICE/qbe4REABVpFUk83AQcAAAAAAAAAAARCaWcxCQC2AgEAAQAEQmlnMAkAtgIBAAAAE2xhc3RCbG9ja190aW1lc3RhbXAIBQlsYXN0QmxvY2sJdGltZXN0YW1wAAZUMTVNSU4AoPc2AAVUSE9VUgCA3dsBAARUREFZAIC4mSkABlRNT05USACAkPvTCQAGQUNUSVZFCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMCBmFjdGl2ZQYBBWdldElkBAdhZGRyZXNzBmFzc2V0QQZhc3NldEIGY3JlYXRlBANrZXkJAKwCAgkArAICCQCsAgIJAKwCAgUHYWRkcmVzcwIBXwUGYXNzZXRBAgFfBQZhc3NldEIEAmlkCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFA2tleQIAAwkBAiE9AgUCaWQCAAUCaWQDBQZjcmVhdGUKAAFACQD8BwQFBHRoaXMCBW5ld0lkCQDMCAIFA2tleQUDbmlsBQNuaWwDCQABAgUBQAIGU3RyaW5nBQFACQACAQkArAICCQADAQUBQAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nAgABCmxhc3RWYWx1ZXMBA2tleQQGdmFsdWVzCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUDa2V5AgkwXzBfMF8wXzACAV8JAJcKBQkBBXZhbHVlAQkAqAMBCQCRAwIFBnZhbHVlcwAACQEFdmFsdWUBCQCoAwEJAJEDAgUGdmFsdWVzAAEJAQV2YWx1ZQEJAKgDAQkAkQMCBQZ2YWx1ZXMAAgkBBXZhbHVlAQkAqAMBCQCRAwIFBnZhbHVlcwADCQEFdmFsdWUBCQC2CQEJAJEDAgUGdmFsdWVzAAQBDWxhc3RGcm9tQ2VsbHMBBWNlbGxzCQCxCQEJAMwBAgUFY2VsbHMACAEMaGl0RnJvbUNlbGxzAgVieXRlcwVpbmRleAkAsQkBCQDLAQIFBVpFUk83CQDJAQIJAMoBAgUFYnl0ZXMFBWluZGV4AAEBBnNldEhpdAMDa2V5BWluZGV4C2xhc3RfcGVyaW9kBAckbWF0Y2gwCQCcCAIFBHRoaXMFA2tleQMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAVjZWxscwUHJG1hdGNoMAMJAAACCQEMaGl0RnJvbUNlbGxzAgUFY2VsbHMFBWluZGV4AAAFA25pbAkAzAgCCQELQmluYXJ5RW50cnkCBQNrZXkJAMsBAgkAywECCQDJAQIFBWNlbGxzBQVpbmRleAkAyQECBQRDRUxMCQBlAgB4BQVpbmRleAkAzAECBQVjZWxscwAIBQNuaWwJAMwIAgkBC0JpbmFyeUVudHJ5AgUDa2V5CQDLAQIJAMsBAgkAyQECBQRNSVNTBQVpbmRleAkAyQECBQRDRUxMCQBlAgB4BQVpbmRleAkAmgMBBQtsYXN0X3BlcmlvZAUDbmlsAQduZWFyZXN0BAJpZAtzdGVwX3BlcmlvZAVzdGVwcwtwcmV2X3BlcmlvZAoBBmNvbW1vbgMFY2VsbHMGcGVyaW9kC2xhc3RfcGVyaW9kBAVpbmRleAMJAAACBQtsYXN0X3BlcmlvZAD///////////8BBQlNQVhfSU5ERVgJAGoCBQtsYXN0X3BlcmlvZAUJTUFYX0NFTExTBANoaXQJAQxoaXRGcm9tQ2VsbHMCBQVjZWxscwUFaW5kZXgDCQAAAgUDaGl0AP8BCQCVCgMGCQENbGFzdEZyb21DZWxscwEFBWNlbGxzAAAEC25leHRfcGVyaW9kCQBlAgkAZAIJAGgCBQZwZXJpb2QFCU1BWF9DRUxMUwUFaW5kZXgFA2hpdAkA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BQVwcmljZQIBXwkApgMBBQd2b2x1bWVBAgFfCQCmAwEFB3ZvbHVtZUIJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCAgR0d2FwBQZyZXN1bHQFA25pbAUGcmVzdWx0CAFpAQlzZXRBY3RpdmUBBmFjdGl2ZQMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECEkludGVybmFsIGNhbGwgb25seQkAzAgCCQEMQm9vbGVhbkVudHJ5AgIGYWN0aXZlBQZhY3RpdmUFA25pbAFpAQVuZXdJZAEDa2V5AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQISSW50ZXJuYWwgY2FsbCBvbmx5BAlpZENvdW50ZXIJAGQCCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMCA2lkcwAAAAEEAmlkCQCkAwEFCWlkQ291bnRlcgkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCAgNpZHMFCWlkQ291bnRlcgkAzAgCCQELU3RyaW5nRW50cnkCBQNrZXkFAmlkCQDMCAIJAQtTdHJpbmdFbnRyeQIFAmlkBQNrZXkJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUCaWQCBl9maXJzdAUTbGFzdEJsb2NrX3RpbWVzdGFtcAUDbmlsBQJpZAFpAQRwdXNoBQZhc3NldEEGYXNzZXRCB2Ftb3VudEEHYW1vdW50QgdwcmljZUFCBAJpZAkBBWdldElkBAkApQgBCAUBaQZjYWxsZXIFBmFzc2V0QQUGYXNzZXRCBgQFcHJpY2UDCQAAAgUHcHJpY2VBQgIACQC8AgMJALYCAQUHYW1vdW50QQUJUFJFQ0lTSU9OCQC2AgEFB2Ftb3VudEIDCQAAAgUHcHJpY2VBQgIBJQUEQmlnMAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCoAwEFB3ByaWNlQUICHHB1c2goKTogY2Fubm90IHBhcnNlIHByaWNlQUIEB3ZvbHVtZUEJALYCAQUHYW1vdW50QQQHdm9sdW1lQgMJAAACBQdwcmljZUFCAgElCQC8AgMJALYCAQUHYW1vdW50QQUJUFJFQ0lTSU9OCQC2AgEFB2Ftb3VudEIJALYCAQUHYW1vdW50QgQGcGVyaW9kCQBpAgUTbGFzdEJsb2NrX3RpbWVzdGFtcAUFUVVBTlQEB2lkX2xhc3QJAKwCAgUCaWQCBV9sYXN0BAwkdDA5OTE2MTAwMTUJAQpsYXN0VmFsdWVzAQUHaWRfbGFzdAQObGFzdF9wcmljZV9zdW0IBQwkdDA5OTE2MTAwMTUCXzEECmxhc3RfcHJpY2UIBQwkdDA5OTE2MTAwMTUCXzIEDGxhc3Rfdm9sdW1lQQgFDCR0MDk5MTYxMDAxNQJfMwQMbGFzdF92b2x1bWVCCAUMJHQwOTkxNjEwMDE1Al80BAtsYXN0X3BlcmlvZAgFDCR0MDk5MTYxMDAxNQJfNQQNJHQwMTAwMjAxMDUzNgMJAAACBQtsYXN0X3BlcmlvZAAACQCVCgMFBXByaWNlBQd2b2x1bWVBBQd2b2x1bWVCAwkAZgIFC2xhc3RfcGVyaW9kBQZwZXJpb2QJAAIBAhRVbmV4cGVjdGVkIHRpbWUgZmxvdwQHZ2FwX3N1bQkAvAIDBQpsYXN0X3ByaWNlCQC2AgEJAGUCCQBlAgUGcGVyaW9kBQtsYXN0X3BlcmlvZAABBQRCaWcxCQCVCgMJALcCAgkAtwICBQ5sYXN0X3ByaWNlX3N1bQUHZ2FwX3N1bQUFcHJpY2UJALcCAgUMbGFzdF92b2x1bWVBBQd2b2x1bWVBCQC3AgIFDGxhc3Rfdm9sdW1lQgUHdm9sdW1lQgQNbmV3X3ByaWNlX3N1bQgFDSR0MDEwMDIwMTA1MzYCXzEEC25ld192b2x1bWVBCAUNJHQwMTAwMjAxMDUzNgJfMgQLbmV3X3ZvbHVtZUIIBQ0kdDAxMDAyMDEwNTM2Al8zBANrZXkJAKwCAgkArAICBQJpZAIBXwkApAMBBQZwZXJpb2QECm5ld192YWx1ZXMJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKYDAQUNbmV3X3ByaWNlX3N1bQIBXwkApgMBBQVwcmljZQIBXwkApgMBBQtuZXdfdm9sdW1lQQIBXwkApgMBBQtuZXdfdm9sdW1lQgkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQIFA2tleQUKbmV3X3ZhbHVlcwkAzAgCCQELU3RyaW5nRW50cnkCBQdpZF9sYXN0CQCsAgIJAKwCAgUKbmV3X3ZhbHVlcwIBXwkApAMBBQZwZXJpb2QFA25pbAkBBG1hcmsDBQJpZAUGcGVyaW9kBQtsYXN0X3BlcmlvZAFpAQR0d2FwBQdhZGRyZXNzBmFzc2V0QQZhc3NldEIEZnJvbQJ0bwkBDHR3YXBJbnRlcm5hbAMJAQVnZXRJZAQFB2FkZHJlc3MFBmFzc2V0QQUGYXNzZXRCBwUEZnJvbQUCdG8BaQEGdHdhcDE1AwdhZGRyZXNzBmFzc2V0QQZhc3NldEIJAQx0d2FwSW50ZXJuYWwDCQEFZ2V0SWQEBQdhZGRyZXNzBQZhc3NldEEFBmFzc2V0QgcJAQEtAQUGVDE1TUlOAAABaQEIdHdhcEhPVVIDB2FkZHJlc3MGYXNzZXRBBmFzc2V0QgkBDHR3YXBJbnRlcm5hbAMJAQVnZXRJZAQFB2FkZHJlc3MFBmFzc2V0QQUGYXNzZXRCBwkBAS0BBQVUSE9VUgAAAWkBB3R3YXBEQVkDB2FkZHJlc3MGYXNzZXRBBmFzc2V0QgkBDHR3YXBJbnRlcm5hbAMJAQVnZXRJZAQFB2FkZHJlc3MFBmFzc2V0QQUGYXNzZXRCBwkBAS0BBQRUREFZAAABaQEJdHdhcE1PTlRIAwdhZGRyZXNzBmFzc2V0QQZhc3NldEIJAQx0d2FwSW50ZXJuYWwDCQEFZ2V0SWQEBQdhZGRyZXNzBQZhc3NldEEFBmFzc2V0QgcJAQEtAQUGVE1PTlRIAAAAgFUGFA==", "chainId": 87, "height": 3944336, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: EeLhMsPKkfMeCcLiEEEsWzbL8oosYCvJe1chqjseGou2 Next: none Diff:
Old | New | Differences | |
---|---|---|---|
278 | 278 | let id = getId(toString(i.caller), assetA, assetB, true) | |
279 | 279 | let price = if ((priceAB == "")) | |
280 | 280 | then fraction(toBigInt(amountA), PRECISION, toBigInt(amountB)) | |
281 | - | else valueOrErrorMessage(parseBigInt(priceAB), "push(): cannot parse priceAB") | |
281 | + | else if ((priceAB == "%")) | |
282 | + | then Big0 | |
283 | + | else valueOrErrorMessage(parseBigInt(priceAB), "push(): cannot parse priceAB") | |
282 | 284 | let volumeA = toBigInt(amountA) | |
283 | - | let volumeB = toBigInt(amountB) | |
285 | + | let volumeB = if ((priceAB == "%")) | |
286 | + | then fraction(toBigInt(amountA), PRECISION, toBigInt(amountB)) | |
287 | + | else toBigInt(amountB) | |
284 | 288 | let period = (lastBlock_timestamp / QUANT) | |
285 | 289 | let id_last = (id + "_last") | |
286 | - | let $ | |
287 | - | let last_price_sum = $ | |
288 | - | let last_price = $ | |
289 | - | let last_volumeA = $ | |
290 | - | let last_volumeB = $ | |
291 | - | let last_period = $ | |
292 | - | let $ | |
290 | + | let $t0991610015 = lastValues(id_last) | |
291 | + | let last_price_sum = $t0991610015._1 | |
292 | + | let last_price = $t0991610015._2 | |
293 | + | let last_volumeA = $t0991610015._3 | |
294 | + | let last_volumeB = $t0991610015._4 | |
295 | + | let last_period = $t0991610015._5 | |
296 | + | let $t01002010536 = if ((last_period == 0)) | |
293 | 297 | then $Tuple3(price, volumeA, volumeB) | |
294 | 298 | else if ((last_period > period)) | |
295 | 299 | then throw("Unexpected time flow") | |
297 | 301 | let gap_sum = fraction(last_price, toBigInt(((period - last_period) - 1)), Big1) | |
298 | 302 | $Tuple3(((last_price_sum + gap_sum) + price), (last_volumeA + volumeA), (last_volumeB + volumeB)) | |
299 | 303 | } | |
300 | - | let new_price_sum = $ | |
301 | - | let new_volumeA = $ | |
302 | - | let new_volumeB = $ | |
304 | + | let new_price_sum = $t01002010536._1 | |
305 | + | let new_volumeA = $t01002010536._2 | |
306 | + | let new_volumeB = $t01002010536._3 | |
303 | 307 | let key = ((id + "_") + toString(period)) | |
304 | 308 | let new_values = ((((((toString(new_price_sum) + "_") + toString(price)) + "_") + toString(new_volumeA)) + "_") + toString(new_volumeB)) | |
305 | 309 | ([StringEntry(key, new_values), StringEntry(id_last, ((new_values + "_") + toString(period)))] ++ mark(id, period, last_period)) |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 6 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let QUANT = 30000 | |
5 | 5 | ||
6 | 6 | let MAX_CELLS = 120 | |
7 | 7 | ||
8 | 8 | let MAX_INDEX = (MAX_CELLS - 1) | |
9 | 9 | ||
10 | 10 | let MISS = base58'cV5GFKqAEHzMpSVgxZNfnSshMAWUKwrMGf7BnfGWecLnGSp8Cn8oe2cL1MVVzKbcBrcupnZxW6KLJ2w3TekHrEkszJr9VVSdZ6yMmEH7RNgR4M1jkykBM6M5hKjdDCZw2rGU8b5inXoL2kQswFLG9XCHYBS9vSGcmY7Q' | |
11 | 11 | ||
12 | 12 | let CELL = base58'12qUPiDTnRmrmhCq8caXpQ1aJTHdJ28hGxW9j9vsVuAGJFZLj1C8XWiYnVJ5XPrMNJZA4FFRo5KfhuaCLJcGUNRAw4JQeYZRTaGG8owfnCzxhDhh9At9YAVA6CtHnbLgcMN6ns62CN7qsMGNASJm97bjo1uttCryNjG' | |
13 | 13 | ||
14 | 14 | let PRECISION = toBigInt(10000000000000000) | |
15 | 15 | ||
16 | 16 | let ZERO7 = base58'1111111' | |
17 | 17 | ||
18 | 18 | let Big1 = toBigInt(1) | |
19 | 19 | ||
20 | 20 | let Big0 = toBigInt(0) | |
21 | 21 | ||
22 | 22 | let lastBlock_timestamp = lastBlock.timestamp | |
23 | 23 | ||
24 | 24 | let T15MIN = 900000 | |
25 | 25 | ||
26 | 26 | let THOUR = 3600000 | |
27 | 27 | ||
28 | 28 | let TDAY = 86400000 | |
29 | 29 | ||
30 | 30 | let TMONTH = 2592000000 | |
31 | 31 | ||
32 | 32 | let ACTIVE = valueOrElse(getBoolean(this, "active"), true) | |
33 | 33 | ||
34 | 34 | func getId (address,assetA,assetB,create) = { | |
35 | 35 | let key = ((((address + "_") + assetA) + "_") + assetB) | |
36 | 36 | let id = valueOrElse(getString(this, key), "") | |
37 | 37 | if ((id != "")) | |
38 | 38 | then id | |
39 | 39 | else if (create) | |
40 | 40 | then { | |
41 | 41 | let @ = invoke(this, "newId", [key], nil) | |
42 | 42 | if ($isInstanceOf(@, "String")) | |
43 | 43 | then @ | |
44 | 44 | else throw(($getType(@) + " couldn't be cast to String")) | |
45 | 45 | } | |
46 | 46 | else "" | |
47 | 47 | } | |
48 | 48 | ||
49 | 49 | ||
50 | 50 | func lastValues (key) = { | |
51 | 51 | let values = split(valueOrElse(getString(this, key), "0_0_0_0_0"), "_") | |
52 | 52 | $Tuple5(value(parseBigInt(values[0])), value(parseBigInt(values[1])), value(parseBigInt(values[2])), value(parseBigInt(values[3])), value(parseInt(values[4]))) | |
53 | 53 | } | |
54 | 54 | ||
55 | 55 | ||
56 | 56 | func lastFromCells (cells) = toInt(takeRight(cells, 8)) | |
57 | 57 | ||
58 | 58 | ||
59 | 59 | func hitFromCells (bytes,index) = toInt((ZERO7 + take(drop(bytes, index), 1))) | |
60 | 60 | ||
61 | 61 | ||
62 | 62 | func setHit (key,index,last_period) = match getBinary(this, key) { | |
63 | 63 | case cells: ByteVector => | |
64 | 64 | if ((hitFromCells(cells, index) == 0)) | |
65 | 65 | then nil | |
66 | 66 | else [BinaryEntry(key, ((take(cells, index) + take(CELL, (120 - index))) + takeRight(cells, 8)))] | |
67 | 67 | case _ => | |
68 | 68 | [BinaryEntry(key, ((take(MISS, index) + take(CELL, (120 - index))) + toBytes(last_period)))] | |
69 | 69 | } | |
70 | 70 | ||
71 | 71 | ||
72 | 72 | func nearest (id,step_period,steps,prev_period) = { | |
73 | 73 | func common (cells,period,last_period) = { | |
74 | 74 | let index = if ((last_period == -1)) | |
75 | 75 | then MAX_INDEX | |
76 | 76 | else (last_period % MAX_CELLS) | |
77 | 77 | let hit = hitFromCells(cells, index) | |
78 | 78 | if ((hit == 255)) | |
79 | 79 | then $Tuple3(true, lastFromCells(cells), 0) | |
80 | 80 | else { | |
81 | 81 | let next_period = (((period * MAX_CELLS) + index) - hit) | |
82 | 82 | $Tuple3(false, next_period, -1) | |
83 | 83 | } | |
84 | 84 | } | |
85 | 85 | ||
86 | 86 | func fold (acc,step) = if (if ((acc._1 == true)) | |
87 | 87 | then true | |
88 | 88 | else (step == "")) | |
89 | 89 | then acc | |
90 | 90 | else { | |
91 | 91 | let period = acc._2 | |
92 | 92 | let data = getBinary(this, ((id + step) + toString(period))) | |
93 | 93 | if (isDefined(data)) | |
94 | 94 | then common(value(data), period, acc._3) | |
95 | 95 | else if ((step != "_3_")) | |
96 | 96 | then $Tuple3(true, 0, 0) | |
97 | 97 | else { | |
98 | 98 | let period_lastChance = (period - 1) | |
99 | 99 | let data_lastChance = getBinary(this, ((id + step) + toString(period_lastChance))) | |
100 | 100 | if (isDefined(data_lastChance)) | |
101 | 101 | then common(value(data_lastChance), period_lastChance, -1) | |
102 | 102 | else $Tuple3(true, 0, 0) | |
103 | 103 | } | |
104 | 104 | } | |
105 | 105 | ||
106 | 106 | ( let $l = steps | |
107 | 107 | let $s = size($l) | |
108 | 108 | let $acc0 = $Tuple3(false, step_period, prev_period) | |
109 | 109 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
110 | 110 | then $a | |
111 | 111 | else fold($a, $l[$i]) | |
112 | 112 | ||
113 | 113 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
114 | 114 | then $a | |
115 | 115 | else throw("List size exceeds 3") | |
116 | 116 | ||
117 | 117 | $f0_2($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3))._2 | |
118 | 118 | } | |
119 | 119 | ||
120 | 120 | ||
121 | 121 | func dataByTimestamp (id,period) = { | |
122 | 122 | let key = ((id + "_") + toString(period)) | |
123 | 123 | match getString(this, key) { | |
124 | 124 | case data: String => | |
125 | 125 | $Tuple2(period, data) | |
126 | 126 | case _ => | |
127 | 127 | func fold (acc,steps) = if ((acc._1 == true)) | |
128 | 128 | then acc | |
129 | 129 | else { | |
130 | 130 | let prev_period = (acc._2 - 1) | |
131 | 131 | let step_period = (prev_period / MAX_CELLS) | |
132 | 132 | let nearest_period = nearest(id, step_period, steps, prev_period) | |
133 | 133 | if ((nearest_period == 0)) | |
134 | 134 | then $Tuple2(false, step_period) | |
135 | 135 | else $Tuple2(true, nearest_period) | |
136 | 136 | } | |
137 | 137 | ||
138 | 138 | let $t051375277 = { | |
139 | 139 | let $l = [["_1_", "", ""], ["_2_", "_1_", ""], ["_3_", "_2_", "_1_"]] | |
140 | 140 | let $s = size($l) | |
141 | 141 | let $acc0 = $Tuple2(false, period) | |
142 | 142 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
143 | 143 | then $a | |
144 | 144 | else fold($a, $l[$i]) | |
145 | 145 | ||
146 | 146 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
147 | 147 | then $a | |
148 | 148 | else throw("List size exceeds 3") | |
149 | 149 | ||
150 | 150 | $f0_2($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3) | |
151 | 151 | } | |
152 | 152 | let found = $t051375277._1 | |
153 | 153 | let nearest_period = $t051375277._2 | |
154 | 154 | if (found) | |
155 | 155 | then $Tuple2(nearest_period, getStringValue(this, ((id + "_") + toString(nearest_period)))) | |
156 | 156 | else $Tuple2(0, "") | |
157 | 157 | } | |
158 | 158 | } | |
159 | 159 | ||
160 | 160 | ||
161 | 161 | func mark (id,period,last_period) = { | |
162 | 162 | func fold (acc,step) = { | |
163 | 163 | let last_step_period = acc._1 | |
164 | 164 | let step_period = (last_step_period / MAX_CELLS) | |
165 | 165 | let key = ((id + step) + toString(step_period)) | |
166 | 166 | let index = (last_step_period % MAX_CELLS) | |
167 | 167 | let hit_actions = setHit(key, index, last_period) | |
168 | 168 | $Tuple2(step_period, (acc._2 ++ hit_actions)) | |
169 | 169 | } | |
170 | 170 | ||
171 | 171 | ( let $l = ["_1_", "_2_", "_3_"] | |
172 | 172 | let $s = size($l) | |
173 | 173 | let $acc0 = $Tuple2(period, nil) | |
174 | 174 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
175 | 175 | then $a | |
176 | 176 | else fold($a, $l[$i]) | |
177 | 177 | ||
178 | 178 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
179 | 179 | then $a | |
180 | 180 | else throw("List size exceeds 3") | |
181 | 181 | ||
182 | 182 | $f0_2($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3))._2 | |
183 | 183 | } | |
184 | 184 | ||
185 | 185 | ||
186 | 186 | func extend (p0,p1,sum,price) = (sum + fraction(price, toBigInt((p1 - p0)), Big1)) | |
187 | 187 | ||
188 | 188 | ||
189 | 189 | func twapInternal (id,_t0,_t1) = { | |
190 | 190 | let result = if (!(ACTIVE)) | |
191 | 191 | then "1_0_0_0_0" | |
192 | 192 | else if ((id == "")) | |
193 | 193 | then "2_0_0_0_0" | |
194 | 194 | else { | |
195 | 195 | let t_first = getIntegerValue(this, (id + "_first")) | |
196 | 196 | let t0_ = if ((0 >= _t0)) | |
197 | 197 | then (lastBlock_timestamp + _t0) | |
198 | 198 | else _t0 | |
199 | 199 | let t1_ = if ((0 >= _t1)) | |
200 | 200 | then (lastBlock_timestamp + _t1) | |
201 | 201 | else _t1 | |
202 | 202 | if ((t0_ > t1_)) | |
203 | 203 | then throw("t0 > t1") | |
204 | 204 | else { | |
205 | 205 | let $t068846969 = if ((t_first > t0_)) | |
206 | 206 | then $Tuple2(t_first, true) | |
207 | 207 | else $Tuple2(t0_, false) | |
208 | 208 | let t0 = $t068846969._1 | |
209 | 209 | let is_first = $t068846969._2 | |
210 | 210 | let t1 = if ((t_first > t1_)) | |
211 | 211 | then t_first | |
212 | 212 | else t1_ | |
213 | 213 | let p0 = (t0 / QUANT) | |
214 | 214 | let p1 = (t1 / QUANT) | |
215 | 215 | if ((p0 == p1)) | |
216 | 216 | then "3_0_0_0_0" | |
217 | 217 | else { | |
218 | 218 | let $t071457193 = dataByTimestamp(id, p0) | |
219 | 219 | let found_p0 = $t071457193._1 | |
220 | 220 | let v0 = $t071457193._2 | |
221 | 221 | let $t071987246 = dataByTimestamp(id, p1) | |
222 | 222 | let found_p1 = $t071987246._1 | |
223 | 223 | let v1 = $t071987246._2 | |
224 | 224 | if ((found_p0 == 0)) | |
225 | 225 | then "4_0_0_0_0" | |
226 | 226 | else if ((found_p1 == 0)) | |
227 | 227 | then "5_0_0_0_0" | |
228 | 228 | else { | |
229 | 229 | let vs0 = split(v0, "_") | |
230 | 230 | let vs1 = split(v1, "_") | |
231 | 231 | let found_sum0 = value(parseBigInt(vs0[0])) | |
232 | 232 | let found_price0 = value(parseBigInt(vs0[1])) | |
233 | 233 | let found_volumeA0 = if (is_first) | |
234 | 234 | then Big0 | |
235 | 235 | else value(parseBigInt(vs0[2])) | |
236 | 236 | let found_volumeB0 = if (is_first) | |
237 | 237 | then Big0 | |
238 | 238 | else value(parseBigInt(vs0[3])) | |
239 | 239 | let sum0 = extend(found_p0, p0, found_sum0, found_price0) | |
240 | 240 | let found_sum1 = value(parseBigInt(vs1[0])) | |
241 | 241 | let found_price1 = value(parseBigInt(vs1[1])) | |
242 | 242 | let found_volumeA1 = value(parseBigInt(vs1[2])) | |
243 | 243 | let found_volumeB1 = value(parseBigInt(vs1[3])) | |
244 | 244 | let sum1 = extend(found_p1, p1, found_sum1, found_price1) | |
245 | 245 | let twap = fraction((sum1 - sum0), Big1, toBigInt((p1 - p0))) | |
246 | 246 | let price = found_price1 | |
247 | 247 | let volumeA = (found_volumeA1 - found_volumeA0) | |
248 | 248 | let volumeB = (found_volumeB1 - found_volumeB0) | |
249 | 249 | ((((((("0_" + toString(twap)) + "_") + toString(price)) + "_") + toString(volumeA)) + "_") + toString(volumeB)) | |
250 | 250 | } | |
251 | 251 | } | |
252 | 252 | } | |
253 | 253 | } | |
254 | 254 | $Tuple2([StringEntry("twap", result)], result) | |
255 | 255 | } | |
256 | 256 | ||
257 | 257 | ||
258 | 258 | @Callable(i) | |
259 | 259 | func setActive (active) = if ((i.caller != this)) | |
260 | 260 | then throw("Internal call only") | |
261 | 261 | else [BooleanEntry("active", active)] | |
262 | 262 | ||
263 | 263 | ||
264 | 264 | ||
265 | 265 | @Callable(i) | |
266 | 266 | func newId (key) = if ((i.caller != this)) | |
267 | 267 | then throw("Internal call only") | |
268 | 268 | else { | |
269 | 269 | let idCounter = (valueOrElse(getInteger(this, "ids"), 0) + 1) | |
270 | 270 | let id = toString(idCounter) | |
271 | 271 | $Tuple2([IntegerEntry("ids", idCounter), StringEntry(key, id), StringEntry(id, key), IntegerEntry((id + "_first"), lastBlock_timestamp)], id) | |
272 | 272 | } | |
273 | 273 | ||
274 | 274 | ||
275 | 275 | ||
276 | 276 | @Callable(i) | |
277 | 277 | func push (assetA,assetB,amountA,amountB,priceAB) = { | |
278 | 278 | let id = getId(toString(i.caller), assetA, assetB, true) | |
279 | 279 | let price = if ((priceAB == "")) | |
280 | 280 | then fraction(toBigInt(amountA), PRECISION, toBigInt(amountB)) | |
281 | - | else valueOrErrorMessage(parseBigInt(priceAB), "push(): cannot parse priceAB") | |
281 | + | else if ((priceAB == "%")) | |
282 | + | then Big0 | |
283 | + | else valueOrErrorMessage(parseBigInt(priceAB), "push(): cannot parse priceAB") | |
282 | 284 | let volumeA = toBigInt(amountA) | |
283 | - | let volumeB = toBigInt(amountB) | |
285 | + | let volumeB = if ((priceAB == "%")) | |
286 | + | then fraction(toBigInt(amountA), PRECISION, toBigInt(amountB)) | |
287 | + | else toBigInt(amountB) | |
284 | 288 | let period = (lastBlock_timestamp / QUANT) | |
285 | 289 | let id_last = (id + "_last") | |
286 | - | let $ | |
287 | - | let last_price_sum = $ | |
288 | - | let last_price = $ | |
289 | - | let last_volumeA = $ | |
290 | - | let last_volumeB = $ | |
291 | - | let last_period = $ | |
292 | - | let $ | |
290 | + | let $t0991610015 = lastValues(id_last) | |
291 | + | let last_price_sum = $t0991610015._1 | |
292 | + | let last_price = $t0991610015._2 | |
293 | + | let last_volumeA = $t0991610015._3 | |
294 | + | let last_volumeB = $t0991610015._4 | |
295 | + | let last_period = $t0991610015._5 | |
296 | + | let $t01002010536 = if ((last_period == 0)) | |
293 | 297 | then $Tuple3(price, volumeA, volumeB) | |
294 | 298 | else if ((last_period > period)) | |
295 | 299 | then throw("Unexpected time flow") | |
296 | 300 | else { | |
297 | 301 | let gap_sum = fraction(last_price, toBigInt(((period - last_period) - 1)), Big1) | |
298 | 302 | $Tuple3(((last_price_sum + gap_sum) + price), (last_volumeA + volumeA), (last_volumeB + volumeB)) | |
299 | 303 | } | |
300 | - | let new_price_sum = $ | |
301 | - | let new_volumeA = $ | |
302 | - | let new_volumeB = $ | |
304 | + | let new_price_sum = $t01002010536._1 | |
305 | + | let new_volumeA = $t01002010536._2 | |
306 | + | let new_volumeB = $t01002010536._3 | |
303 | 307 | let key = ((id + "_") + toString(period)) | |
304 | 308 | let new_values = ((((((toString(new_price_sum) + "_") + toString(price)) + "_") + toString(new_volumeA)) + "_") + toString(new_volumeB)) | |
305 | 309 | ([StringEntry(key, new_values), StringEntry(id_last, ((new_values + "_") + toString(period)))] ++ mark(id, period, last_period)) | |
306 | 310 | } | |
307 | 311 | ||
308 | 312 | ||
309 | 313 | ||
310 | 314 | @Callable(i) | |
311 | 315 | func twap (address,assetA,assetB,from,to) = twapInternal(getId(address, assetA, assetB, false), from, to) | |
312 | 316 | ||
313 | 317 | ||
314 | 318 | ||
315 | 319 | @Callable(i) | |
316 | 320 | func twap15 (address,assetA,assetB) = twapInternal(getId(address, assetA, assetB, false), -(T15MIN), 0) | |
317 | 321 | ||
318 | 322 | ||
319 | 323 | ||
320 | 324 | @Callable(i) | |
321 | 325 | func twapHOUR (address,assetA,assetB) = twapInternal(getId(address, assetA, assetB, false), -(THOUR), 0) | |
322 | 326 | ||
323 | 327 | ||
324 | 328 | ||
325 | 329 | @Callable(i) | |
326 | 330 | func twapDAY (address,assetA,assetB) = twapInternal(getId(address, assetA, assetB, false), -(TDAY), 0) | |
327 | 331 | ||
328 | 332 | ||
329 | 333 | ||
330 | 334 | @Callable(i) | |
331 | 335 | func twapMONTH (address,assetA,assetB) = twapInternal(getId(address, assetA, assetB, false), -(TMONTH), 0) | |
332 | 336 | ||
333 | 337 |
github/deemru/w8io/3ef1775 47.62 ms ◑