tx · DEQbkGJAGJLkBj9sooumWCBCk9Warjo3EhEm7KiJTQa6

3P2YBCpek2KbwaxHBSRRa4DWcJUkPu2mCCj:  -0.01000000 Waves

2024.04.09 01:00 [4120311] smart account 3P2YBCpek2KbwaxHBSRRa4DWcJUkPu2mCCj > SELF 0.00000000 Waves

{ "type": 13, "id": "DEQbkGJAGJLkBj9sooumWCBCk9Warjo3EhEm7KiJTQa6", "fee": 1000000, "feeAssetId": null, "timestamp": 1712613602050, "version": 2, "chainId": 87, "sender": "3P2YBCpek2KbwaxHBSRRa4DWcJUkPu2mCCj", "senderPublicKey": "3C2anUH59qjkVSB8AuFYGBNhSqcgvJhq1BBRodM74pEf", "proofs": [ "2i7NnwFxfiD5opXRsT4KMjTbf1A9TaYeJ8MQCznuzNHr6R4zenN8YK64jpDACrZoBwsSDdmAuRA9VBjKLALShcd3" ], "script": "base64:BgIGCAISABIAEwEJYXNBbnlMaXN0AQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAglMaXN0W0FueV0ECnZhbEFueUxpc3QFByRtYXRjaDAFCnZhbEFueUxpc3QJAAIBAhtmYWlsIHRvIGNhc3QgaW50byBMaXN0W0FueV0BCGFzU3RyaW5nAQF2BAckbWF0Y2gwBQF2AwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAUBcwkAAgECGGZhaWwgdG8gY2FzdCBpbnRvIFN0cmluZwEFYXNJbnQBAXYEByRtYXRjaDAFAXYDCQABAgUHJG1hdGNoMAIDSW50BAFpBQckbWF0Y2gwBQFpCQACAQIVZmFpbCB0byBjYXN0IGludG8gSW50AAtwdXp6bGVJZFN0cgIsSEVCOFFhdzl4cldwV3M4dEhzaUFUWUdCV0RCdFAyUzdrY1BBTHJNdTQzQVMACHB1enpsZUlkCQDZBAEFC3B1enpsZUlkU3RyAAh4dG5JZFN0cgIsREcyeEZrUGREd0tVb0JrekdBaFF0THBTR3pmWExpQ1lQRXplS0gyQWQyNHAABXh0bklkCQDZBAEFCHh0bklkU3RyAAhwekZvcmJlcwkBEUBleHRyTmF0aXZlKDEwNjIpAQIjM1BRbnpwNVlvZ0J2Sm13UG52U1dvYXJnUE1jZDFSNEdMYTgADXB6QmFzaWNQdXp6bGUJARFAZXh0ck5hdGl2ZSgxMDYyKQECIzNQUUFoUE01aUhReVlyQXFUVnRzNTNVZ2lMR3RWdVNaOHhEAAZ3eFJlc3QJARFAZXh0ck5hdGl2ZSgxMDYyKQECIzNQOE1vUG5zYXVyb2ZrMVZ5aHNkQUZrZVE2aWpwSllYQ3BXAAZ3eFN3b3AJARFAZXh0ck5hdGl2ZSgxMDYyKQECIzNQNjh6Tml1ZnN1MXZpWnB1MWFZM2NkYWhSUktjdlY1TjkzAA13eFB1enpsZVdhdmVzCQERQGV4dHJOYXRpdmUoMTA2MikBAiMzUFFhWW00cGJSVnJOVFRuTDhwREpaVHhoY21ENGpSc2tyegALd3hQdXp6bGVYdG4JARFAZXh0ck5hdGl2ZSgxMDYyKQECIzNQNjE1eVhlUTlRdTRxQk0xUUdpbUd6aXh5TVM1VzRLdHVnAAp3eFdhdmVzWHRuCQERQGV4dHJOYXRpdmUoMTA2MikBAiMzUFBaV2dGTlJLSEx2TTUxcHdTOTM0QzhWWjdkMkY0WjU4ZwANc3dvcFB1enpsZVh0bgkBEUBleHRyTmF0aXZlKDEwNjIpAQIjM1BCSHlFd21FUlIxQ0VrclROYlBqMmJneWlzVGZQUnFmZWUADHN3b3BXYXZlc1h0bgkBEUBleHRyTmF0aXZlKDEwNjIpAQIjM1BIYU5nb21Ca3J2RUwyUW51SmFyUVZKYTcxd2p3OXFpcUcBC3N3b3BCYWxhbmNlAgtwb29sQWRkcmVzcwRBb3JCCQERQGV4dHJOYXRpdmUoMTA1MCkCBQtwb29sQWRkcmVzcwkArAICBQRBb3JCAg5fYXNzZXRfYmFsYW5jZQENd3hQb29sQmFsYW5jZQILcG9vbEFkZHJlc3MKYXNzZXRJbmRleAQMd3hSZXN0UmVzdWx0CQC1CQIJAQhhc1N0cmluZwEJAPwHBAUGd3hSZXN0AhFwb29sU3RhdHNSRUFET05MWQkAzAgCCQClCAEFC3Bvb2xBZGRyZXNzBQNuaWwFA25pbAICX18JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQx3eFJlc3RSZXN1bHQFCmFzc2V0SW5kZXgBCXB6QmFsYW5jZQILcG9vbEFkZHJlc3MHYXNzZXRJZAkA8AcCBQtwb29sQWRkcmVzcwUHYXNzZXRJZAIBaQEOYnV5WHRuRm9yV2F2ZXMABANwbXQJAQV2YWx1ZQEJAJEDAggFAWkIcGF5bWVudHMAAAQId2F2ZXNBbXQIBQNwbXQGYW1vdW50BA93YXZlc1RvWHRuVmlhV3gJAQ13eFBvb2xCYWxhbmNlAgUKd3hXYXZlc1h0bgABBBF3YXZlc1RvWHRuVmlhU3dvcAkBC3N3b3BCYWxhbmNlAgUMc3dvcFdhdmVzWHRuAgFBBA93YXZlc1RvWHRuVG90YWwJAGQCBQ93YXZlc1RvWHRuVmlhV3gFEXdhdmVzVG9YdG5WaWFTd29wBBJ3YXZlc1RvWHRuVmlhV3hBbXQJAGsDBQh3YXZlc0FtdAUPd2F2ZXNUb1h0blZpYVd4BQ93YXZlc1RvWHRuVG90YWwEFHdhdmVzVG9YdG5WaWFTd29wQW10CQBrAwUId2F2ZXNBbXQFEXdhdmVzVG9YdG5WaWFTd29wBQ93YXZlc1RvWHRuVG90YWwEFXdhdmVzVG9YdG5WaWFXeFJlc3VsdAkA/AcEBQZ3eFN3b3ACBHN3YXAJAMwIAgABCQDMCAIFCHh0bklkU3RyCQDMCAIJAKUIAQUEdGhpcwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQR1bml0BRJ3YXZlc1RvWHRuVmlhV3hBbXQFA25pbAMJAAACBRV3YXZlc1RvWHRuVmlhV3hSZXN1bHQFFXdhdmVzVG9YdG5WaWFXeFJlc3VsdAQXd2F2ZXNUb1h0blZpYVN3b3BSZXN1bHQJAQlhc0FueUxpc3QBCQD8BwQFDHN3b3BXYXZlc1h0bgIIZXhjaGFuZ2UJAMwIAgABBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFBHVuaXQFFHdhdmVzVG9YdG5WaWFTd29wQW10BQNuaWwDCQAAAgUXd2F2ZXNUb1h0blZpYVN3b3BSZXN1bHQFF3dhdmVzVG9YdG5WaWFTd29wUmVzdWx0BAZ4dG5BbXQJAPAHAgUEdGhpcwUFeHRuSWQJAJQKAgUDbmlsBQZ4dG5BbXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQERYnV5UHV6emxlRm9yV2F2ZXMABA1wekZvcmJlc1ZhbHVlCQEJcHpCYWxhbmNlAgUIcHpGb3JiZXMFCHB1enpsZUlkBBJwekJhc2ljUHV6emxlVmFsdWUJAQlwekJhbGFuY2UCBQ1wekJhc2ljUHV6emxlBQhwdXp6bGVJZAQSd3hQdXp6bGVXYXZlc1ZhbHVlCQENd3hQb29sQmFsYW5jZQIFDXd4UHV6emxlV2F2ZXMAAQQSc3dvcFB1enpsZVh0blZhbHVlCQELc3dvcEJhbGFuY2UCBQ1zd29wUHV6emxlWHRuAgFBBAV0b3RhbAkAZAIJAGQCCQBkAgUNcHpGb3JiZXNWYWx1ZQUScHpCYXNpY1B1enpsZVZhbHVlBRJ3eFB1enpsZVdhdmVzVmFsdWUFEnN3b3BQdXp6bGVYdG5WYWx1ZQQDcG10CQEFdmFsdWUBCQCRAwIIBQFpCHBheW1lbnRzAAAEBnBtdEFtdAgFA3BtdAZhbW91bnQEDHB6Rm9yYmVzUGFydAkAawMFDXB6Rm9yYmVzVmFsdWUFBnBtdEFtdAUFdG90YWwEEXB6QmFzaWNQdXp6bGVQYXJ0CQBrAwUScHpCYXNpY1B1enpsZVZhbHVlBQZwbXRBbXQFBXRvdGFsBBF3eFB1enpsZVdhdmVzUGFydAkAawMFEnd4UHV6emxlV2F2ZXNWYWx1ZQUGcG10QW10BQV0b3RhbAQRc3dvcFB1enpsZVh0blBhcnQJAGsDBRJzd29wUHV6emxlWHRuVmFsdWUFBnBtdEFtdAUFdG90YWwEBnh0bkFtdAkBBWFzSW50AQkA/AcEBQR0aGlzAg5idXlYdG5Gb3JXYXZlcwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQR1bml0BRFzd29wUHV6emxlWHRuUGFydAUDbmlsAwkAAAIFBnh0bkFtdAUGeHRuQW10BBx3YXZlc1RvUHV6emxlVmlhRm9yYmVzUmVzdWx0CQD8BwQFCHB6Rm9yYmVzAgRzd2FwCQDMCAIFC3B1enpsZUlkU3RyCQDMCAIAAQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQR1bml0BQxwekZvcmJlc1BhcnQFA25pbAMJAAACBRx3YXZlc1RvUHV6emxlVmlhRm9yYmVzUmVzdWx0BRx3YXZlc1RvUHV6emxlVmlhRm9yYmVzUmVzdWx0BBt3YXZlc1RvUHV6emxlVmlhQmFzaWNSZXN1bHQJAPwHBAUNcHpCYXNpY1B1enpsZQIEc3dhcAkAzAgCBQtwdXp6bGVJZFN0cgkAzAgCAAEFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUEdW5pdAURcHpCYXNpY1B1enpsZVBhcnQFA25pbAMJAAACBRt3YXZlc1RvUHV6emxlVmlhQmFzaWNSZXN1bHQFG3dhdmVzVG9QdXp6bGVWaWFCYXNpY1Jlc3VsdAQYd2F2ZXNUb1B1enpsZVZpYVd4UmVzdWx0CQD8BwQFBnd4U3dvcAIEc3dhcAkAzAgCAAEJAMwIAgULcHV6emxlSWRTdHIJAMwIAgkApQgBBQR0aGlzBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFBHVuaXQFEXd4UHV6emxlV2F2ZXNQYXJ0BQNuaWwDCQAAAgUYd2F2ZXNUb1B1enpsZVZpYVd4UmVzdWx0BRh3YXZlc1RvUHV6emxlVmlhV3hSZXN1bHQEGHh0blRvUHV6emxlVmlhU3dvcFJlc3VsdAkBCWFzQW55TGlzdAEJAPwHBAUNc3dvcFB1enpsZVh0bgIIZXhjaGFuZ2UJAMwIAgABBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFBXh0bklkBQZ4dG5BbXQFA25pbAMJAAACBRh4dG5Ub1B1enpsZVZpYVN3b3BSZXN1bHQFGHh0blRvUHV6emxlVmlhU3dvcFJlc3VsdAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIICQDvBwEFBHRoaXMJYXZhaWxhYmxlBQR1bml0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AyIjPfw==", "height": 4120311, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 4qowiJio2r7jxg2TxbgU1RphfaqaE6jQB8iBa7oU7SpQ Next: 4CamTyyYwMtz1vuUyia97QYz7u8QGraBhYNqQ8AaVWz1 Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let ProtocolSEP = ":"
4+func asAnyList (val) = match val {
5+ case valAnyList: List[Any] =>
6+ valAnyList
7+ case _ =>
8+ throw("fail to cast into List[Any]")
9+}
510
6-let SEP = "__"
7-
8-let percentPriceOffset = 95
911
1012 func asString (v) = match v {
1113 case s: String =>
1517 }
1618
1719
18-func keyPrice (symbol) = ("%s%s__price__" + symbol)
20+func asInt (v) = match v {
21+ case i: Int =>
22+ i
23+ case _ =>
24+ throw("fail to cast into Int")
25+}
1926
2027
21-func keyOracles () = "%s%s__config__oracles"
28+let puzzleIdStr = "HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS"
29+
30+let puzzleId = fromBase58String(puzzleIdStr)
31+
32+let xtnIdStr = "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"
33+
34+let xtnId = fromBase58String(xtnIdStr)
35+
36+let pzForbes = addressFromStringValue("3PQnzp5YogBvJmwPnvSWoargPMcd1R4GLa8")
37+
38+let pzBasicPuzzle = addressFromStringValue("3PQAhPM5iHQyYrAqTVts53UgiLGtVuSZ8xD")
39+
40+let wxRest = addressFromStringValue("3P8MoPnsaurofk1VyhsdAFkeQ6ijpJYXCpW")
41+
42+let wxSwop = addressFromStringValue("3P68zNiufsu1viZpu1aY3cdahRRKcvV5N93")
43+
44+let wxPuzzleWaves = addressFromStringValue("3PQaYm4pbRVrNTTnL8pDJZTxhcmD4jRskrz")
45+
46+let wxPuzzleXtn = addressFromStringValue("3P615yXeQ9Qu4qBM1QGimGzixyMS5W4Ktug")
47+
48+let wxWavesXtn = addressFromStringValue("3PPZWgFNRKHLvM51pwS934C8VZ7d2F4Z58g")
49+
50+let swopPuzzleXtn = addressFromStringValue("3PBHyEwmERR1CEkrTNbPj2bgyisTfPRqfee")
51+
52+let swopWavesXtn = addressFromStringValue("3PHaNgomBkrvEL2QnuJarQVJa71wjw9qiqG")
53+
54+func swopBalance (poolAddress,AorB) = getIntegerValue(poolAddress, (AorB + "_asset_balance"))
2255
2356
24-func keyGroupData (groupNum) = ("%s%d__group__" + groupNum)
25-
26-
27-func keyMinConsensus () = "%s%s__config__minConsensus"
28-
29-
30-func keyPriceFailure (symbol) = makeString(["%s%s%d__finalizationFailure", symbol, toString(height)], SEP)
31-
32-
33-func keyLastHeight (symbol) = ("%s%s__lastHeight__" + symbol)
34-
35-
36-func keyPriceByHeight (symbol,h) = makeString(["%s%s%d__priceByHeight", symbol, toString(h)], SEP)
37-
38-
39-func keyIdx (symbol) = ("%s%s__idxCurrent__" + symbol)
40-
41-
42-func keyIdx2Height (symbol,idx) = makeString(["%s%s%d__idx2Height", symbol, toString(idx)], SEP)
43-
44-
45-func keyHeight2Idx (symbol,h) = makeString(["%s%s%d__height2Idx", symbol, toString(h)], SEP)
46-
47-
48-func keyGroupStatus (groupNum,finHeightStr) = makeString(["%s%d%d__groupStatus", groupNum, finHeightStr], SEP)
49-
50-
51-func keyIsMarketOpened (symbol) = ("%s%s__isMarketOpened__" + symbol)
52-
53-
54-func keyEmptyPriceMsg (position) = makeString(["%s%d%d__emptyPriceMsg", toString(height), toString(position)], SEP)
55-
56-
57-func keyIsBlocked (symbol) = ("%s%s__isBlocked__" + symbol)
58-
59-
60-func keyIsBlockedSender (symbol) = makeString(["%s%s%s__isBlocked", symbol, "sender"], SEP)
61-
62-
63-func keyIsBlockedReason (symbol) = makeString(["%s%s%s__isBlocked", symbol, "reason"], SEP)
64-
65-
66-func keyBlackSwarmPrice (h,symbol) = makeString(["%s%s%s%d__isBlocked", symbol, "blackSwarmPrice", toString(h)], SEP)
67-
68-
69-let DAYMILLIS = 86400000
70-
71-let H4MILLIS = 14400000
72-
73-func toPeriod (timestamp,period) = ((timestamp / period) * period)
74-
75-
76-func keyStats1stPeriod (symbol) = makeString(["%s%s", "stats1stPeriod", symbol], SEP)
77-
78-
79-func keyStatsPriceSum (symbol) = makeString(["%s%s", "statsPriceSum", symbol], SEP)
80-
81-
82-func keyStatsCountSum (symbol) = makeString(["%s%s", "statsCountSum", symbol], SEP)
83-
84-
85-func keyStatsByPeriodPriceSum (symbol,period) = makeString(["%s%s%d", "statsPriceSum", symbol, period], SEP)
86-
87-
88-func keyStatsByPeriodCountSum (symbol,period) = makeString(["%s%s%d", "statsCountSum", symbol, period], SEP)
89-
90-
91-func keyStatsByPeriodMin (symbol,period) = makeString(["%s%s%d", "statsPriceMin", symbol, period], SEP)
92-
93-
94-func keyStatsByPeriodMax (symbol,period) = makeString(["%s%s%d", "statsPriceMax", symbol, period], SEP)
95-
96-
97-func StatsEntry (symbol,price) = {
98- let period = toPeriod(lastBlock.timestamp, H4MILLIS)
99- let periodStr = toString(period)
100- let stats1stPeriodKEY = keyStats1stPeriod(symbol)
101- let statsPriceSumKEY = keyStatsPriceSum(symbol)
102- let statsCountSumKEY = keyStatsCountSum(symbol)
103- let statsByPeriodPriceSumKEY = keyStatsByPeriodPriceSum(symbol, periodStr)
104- let statsByPeriodCountSumKEY = keyStatsByPeriodCountSum(symbol, periodStr)
105- let statsByPeriodMinKEY = keyStatsByPeriodMin(symbol, periodStr)
106- let statsByPeriodMaxKEY = keyStatsByPeriodMax(symbol, periodStr)
107- let statsPriceSum = parseBigIntValue(valueOrElse(getString(this, statsPriceSumKEY), "0"))
108- let statsCountSum = valueOrElse(getInteger(this, statsCountSumKEY), 0)
109- let statsByPeriodMin = valueOrElse(getInteger(this, statsByPeriodMinKEY), 9223372036854775)
110- let statsByPeriodMax = valueOrElse(getInteger(this, statsByPeriodMaxKEY), 0)
111- let newStatsPriceSum = (statsPriceSum + toBigInt(price))
112- let newStatsCountSum = (statsCountSum + 1)
113- let newStatsByPeriodPriceSum = newStatsPriceSum
114- let newStatsByPeriodCountSum = newStatsCountSum
115- let newStatsByPeriodMin = min([statsByPeriodMin, price])
116- let newStatsByPeriodMax = max([statsByPeriodMax, price])
117- let stats1stPeriod = valueOrElse(getInteger(this, stats1stPeriodKEY), -1)
118- ([StringEntry(statsPriceSumKEY, toString(newStatsPriceSum)), IntegerEntry(statsCountSumKEY, newStatsCountSum), StringEntry(statsByPeriodPriceSumKEY, toString(newStatsByPeriodPriceSum)), IntegerEntry(statsByPeriodCountSumKEY, newStatsByPeriodCountSum), IntegerEntry(statsByPeriodMinKEY, newStatsByPeriodMin), IntegerEntry(statsByPeriodMaxKEY, newStatsByPeriodMax)] ++ (if ((0 > stats1stPeriod))
119- then [IntegerEntry(stats1stPeriodKEY, period)]
120- else nil))
57+func wxPoolBalance (poolAddress,assetIndex) = {
58+ let wxRestResult = split(asString(invoke(wxRest, "poolStatsREADONLY", [toString(poolAddress)], nil)), "__")
59+ parseIntValue(wxRestResult[assetIndex])
12160 }
12261
12362
124-func isGroupFinalaized (groupNum,finHeightStr) = isDefined(getBoolean(this, keyGroupStatus(groupNum, finHeightStr)))
125-
126-
127-func readGroupDataOrFail (groupNum) = {
128- let k = keyGroupData(groupNum)
129- let groupDataOpt = getString(this, k)
130- if (isDefined(groupDataOpt))
131- then value(groupDataOpt)
132- else throw(("empty group data for key=" + k))
133- }
134-
135-
136-let pubKeyOraclesList = split(getStringValue(this, keyOracles()), ",")
137-
138-let oracleCount = size(pubKeyOraclesList)
139-
140-let minConsensus = valueOrElse(getInteger(this, keyMinConsensus()), 3)
141-
142-func PriceFailedResult (symbol,msg) = [StringEntry(keyPriceFailure(symbol), msg)]
143-
144-
145-func throwInvalidFinalizationHeight (finHeightStr) = throw(((("invalid finalization height: height=" + toString(height)) + " finalizationHeight=") + finHeightStr))
146-
147-
148-func throwGroupAlreadyFinalized (groupNum,finHeightStr) = throw((((("prices for groupNum=" + groupNum) + " at ") + finHeightStr) + " height have been already finalized"))
149-
150-
151-func throwInvalidSignsParamLength (num,param) = throw(((((("invalid signs" + toString(num)) + " parameter: actual.size=") + toString(size(param))) + " base58Val=") + toBase58String(param)))
152-
153-
154-func throwOutOfTurnFinalization () = throw(((("Out of turn finalization: " + toString(height)) + " block should be finalize by ") + pubKeyOraclesList[(height % oracleCount)]))
155-
156-
157-func throwBlockedError () = throw("contract is blocked by EMERGENCY SHUTDOWN action")
158-
159-
160-func PriceEntry (symbol,newPrice,isMarketOpened) = {
161- let idx = valueOrElse(getInteger(this, keyIdx(symbol)), 0)
162- let newIdx = (idx + 1)
163-[IntegerEntry(keyPrice(symbol), newPrice), IntegerEntry(keyLastHeight(symbol), height), IntegerEntry(keyPriceByHeight(symbol, height), newPrice), IntegerEntry(keyIdx(symbol), newIdx), IntegerEntry(keyIdx2Height(symbol, newIdx), height), IntegerEntry(keyHeight2Idx(symbol, height), newIdx), BooleanEntry(keyIsMarketOpened(symbol), isMarketOpened)]
164- }
165-
166-
167-func finalizeUsdnUsdtOnchain () = {
168- let symbol = "USDN-USDT"
169- let usdnId = "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"
170- let usdtId = "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ"
171- let usdnAmount = 1000000000
172- let wxPoolAddressStr = "3P8KMyAJCPWNcyedqrmymxaeWonvmkhGauz"
173- let wxPoolAddress = addressFromStringValue(wxPoolAddressStr)
174- let $t077107849 = {
175- let @ = invoke(wxPoolAddress, "putOneTknV2WithBonusREADONLY", [usdnAmount, usdnId], nil)
176- if ($isInstanceOf(@, "(Int, Int, Int)"))
177- then @
178- else throw(($getType(@) + " couldn't be cast to (Int, Int, Int)"))
179- }
180- let lpAmount = $t077107849._1
181- let feeAmount1 = $t077107849._2
182- let bonus = $t077107849._3
183- let $t078527970 = {
184- let @ = invoke(wxPoolAddress, "getOneTknV2READONLY", [usdtId, lpAmount], nil)
185- if ($isInstanceOf(@, "(Int, Int)"))
186- then @
187- else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
188- }
189- let usdtAmount = $t078527970._1
190- let feeAmount2 = $t078527970._2
191- let newPrice = fraction(usdtAmount, 1000000, usdnAmount)
192- (PriceEntry(symbol, newPrice, true) ++ StatsEntry(symbol, newPrice))
193- }
194-
195-
196-func finalizePwrUsdtOnchainV2 () = {
197- let symbol = "PWR-USDT"
198- let wavesUsdPriceX6 = getIntegerValue(this, "%s%s__price__WAVES-USDT")
199- let ethUsdtPriceX6 = getIntegerValue(this, "%s%s__price__ETH-USDT")
200- let wx_restAddressStr = "3P8MoPnsaurofk1VyhsdAFkeQ6ijpJYXCpW"
201- let wx_restDapp = addressFromStringValue(wx_restAddressStr)
202- let wx_pwrWavesPoolStr = "3PDi7Qq8pLQYvtKyTfQuqqPUWyhoYbU957t"
203- let wx_pwrWavesPoolAddress = addressFromStringValue(wx_pwrWavesPoolStr)
204- let wx_PwrWaves_lp = "AKQsEQoeinKRFtdx6rhKWcpkAMu6cbDLdtSWnR8tpBCq"
205- let wxRestResult = split(asString(invoke(wx_restDapp, "poolStatsREADONLY", [wx_PwrWaves_lp], nil)), "__")
206- let wx_PwrWaves_WavesX8 = parseIntValue(wxRestResult[2])
207- let wx_PwrWaves_PwrX8 = parseIntValue(wxRestResult[1])
208- let wx_PwrWaves_WxUsdPriceX6 = fraction(wx_PwrWaves_WavesX8, wavesUsdPriceX6, wx_PwrWaves_PwrX8)
209- let debug = ((((("wavesUsdPriceX6=" + toString(wavesUsdPriceX6)) + " wx_PwrWaves_WavesX8=") + toString(wx_PwrWaves_WavesX8)) + " wx_PwrWaves_PwrX8=") + toString(wx_PwrWaves_PwrX8))
210- $Tuple2(wx_PwrWaves_WxUsdPriceX6, debug)
211- }
212-
213-
214-func finalizeUsdnUsdtOnchainV2 () = {
215- let wavesUsdtPriceX6 = getIntegerValue(this, "%s%s__price__WAVES-USDT")
216- let ethUsdtPriceX6 = getIntegerValue(this, "%s%s__price__ETH-USDT")
217- let symbol = "USDN-USDT"
218- let xtnIdStr = "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"
219- let xtnId = fromBase58String(xtnIdStr)
220- let usdtIdStr = "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ"
221- let usdnAmount = 1000000000
222- let wxUsdtXtnPoolStr = "3P8KMyAJCPWNcyedqrmymxaeWonvmkhGauz"
223- let wxUsdtXtnPoolAddress = addressFromStringValue(wxUsdtXtnPoolStr)
224- let wxUsdtXtnW = 67
225- let $t097969944 = {
226- let @ = invoke(wxUsdtXtnPoolAddress, "putOneTknV2WithBonusREADONLY", [usdnAmount, xtnIdStr], nil)
227- if ($isInstanceOf(@, "(Int, Int, Int)"))
228- then @
229- else throw(($getType(@) + " couldn't be cast to (Int, Int, Int)"))
230- }
231- let lpAmount = $t097969944._1
232- let feeAmount1 = $t097969944._2
233- let bonus = $t097969944._3
234- let $t0994710075 = {
235- let @ = invoke(wxUsdtXtnPoolAddress, "getOneTknV2READONLY", [usdtIdStr, lpAmount], nil)
236- if ($isInstanceOf(@, "(Int, Int)"))
237- then @
238- else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
239- }
240- let usdtAmount = $t0994710075._1
241- let feeAmount2 = $t0994710075._2
242- let wxUsdtXtnPrice = fraction(usdtAmount, 1000000, usdnAmount)
243- let wxWavesXtnW = 550
244- let wxWavesXtnPoolStr = "3PPZWgFNRKHLvM51pwS934C8VZ7d2F4Z58g"
245- let wxWavesXtnPoolAddress = addressFromStringValue(wxWavesXtnPoolStr)
246- let wavesWavesXtnX8 = wavesBalance(wxWavesXtnPoolAddress).regular
247- let xtnWavesXtnX6 = assetBalance(wxWavesXtnPoolAddress, xtnId)
248- let wavesXtnPriceX6 = fraction(xtnWavesXtnX6, 100000000, wavesWavesXtnX8)
249- let wxWavesUsdtXtnPrice = fraction(wavesUsdtPriceX6, 1000000, wavesXtnPriceX6)
250- let wxEthXtnW = 5
251- let ethIdStr = "474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu"
252- let ethId = fromBase58String(ethIdStr)
253- let wxEthXtnPoolStr = "3PEMqetsaJDbYMw1XGovmE37FB8VUhGnX9A"
254- let wxEthXtnPoolAddress = addressFromStringValue(wxEthXtnPoolStr)
255- let ethEthXtnX8 = assetBalance(wxEthXtnPoolAddress, ethId)
256- let xtnEthXtnX6 = assetBalance(wxEthXtnPoolAddress, xtnId)
257- let ethXtnPriceX6 = fraction(xtnEthXtnX6, 100000000, ethEthXtnX8)
258- let wxEthUsdtXtnPrice = fraction(ethUsdtPriceX6, 1000000, ethXtnPriceX6)
259- let swopfiWavesXtnW = 1000
260- let swopfiRest = addressFromStringValue("3P56jNQzECXnrWpnbbSJKw7Eooo6fkUaMPp")
261- let swopfiWavesXtnPriceX6 = {
262- let @ = invoke(swopfiRest, "calcGetAmountCPMM", ["3PHaNgomBkrvEL2QnuJarQVJa71wjw9qiqG", "3PQHCTqfzE8e1Jo8m1QVaCXATSKyMmkYasF", "WAVES", 100000000], nil)
263- if ($isInstanceOf(@, "Int"))
264- then @
265- else throw(($getType(@) + " couldn't be cast to Int"))
266- }
267- let swopfiWavesUsdtXtnPrice = fraction(wavesUsdtPriceX6, 1000000, swopfiWavesXtnPriceX6)
268- let newPrice = fraction(swopfiWavesUsdtXtnPrice, swopfiWavesXtnW, 1000)
269- (PriceEntry(symbol, newPrice, true) ++ StatsEntry(symbol, newPrice))
270- }
271-
272-
273-func finalizePriceV2Common (position,groupNum,groupDataStr,msgArray,signs) = {
274- let msgOffset = (position * 3)
275- if ((msgOffset >= size(msgArray)))
276- then [StringEntry(keyEmptyPriceMsg(position), "price data is empty")]
277- else {
278- let symbol = msgArray[(msgOffset + 0)]
279- let newPriceStr = msgArray[(msgOffset + 1)]
280- let isMarketOpenedStr = msgArray[(msgOffset + 2)]
281- let newPriceOpt = parseInt(newPriceStr)
282- let isMarketOpenedOpt = parseInt(isMarketOpenedStr)
283- let sig0 = take(signs, 64)
284- let sig1 = take(drop(signs, 64), 64)
285- let sig2 = take(drop(signs, 128), 64)
286- let sig3 = take(drop(signs, 192), 64)
287- let sig4 = takeRight(signs, 64)
288- let isBlocked = valueOrElse(getBoolean(this, keyIsBlocked(symbol)), false)
289- if ((symbol == ""))
290- then nil
291- else if (isBlocked)
292- then PriceFailedResult(symbol, (symbol + " is blocked"))
293- else if (contains(groupDataStr, symbol))
294- then if (if (isDefined(newPriceOpt))
295- then isDefined(isMarketOpenedOpt)
296- else false)
297- then {
298- let newPrice = value(newPriceOpt)
299- let isMarketOpened = if ((value(isMarketOpenedOpt) == 1))
300- then true
301- else false
302- let priceMsgStr = makeString(["WAVES-DORA2", groupNum, toString(height), symbol, newPriceStr, isMarketOpenedStr], ProtocolSEP)
303- let priceMsg = toBytes(priceMsgStr)
304- let verificationsCount = (((((if (sigVerify_8Kb(priceMsg, sig0, fromBase58String(pubKeyOraclesList[0])))
305- then 1
306- else 0) + (if (sigVerify_8Kb(priceMsg, sig1, fromBase58String(pubKeyOraclesList[1])))
307- then 1
308- else 0)) + (if (sigVerify_8Kb(priceMsg, sig2, fromBase58String(pubKeyOraclesList[2])))
309- then 1
310- else 0)) + (if (sigVerify_8Kb(priceMsg, sig3, fromBase58String(pubKeyOraclesList[3])))
311- then 1
312- else 0)) + (if (sigVerify_8Kb(priceMsg, sig4, fromBase58String(pubKeyOraclesList[4])))
313- then 1
314- else 0))
315- if ((verificationsCount >= minConsensus))
316- then {
317- let price = valueOrElse(getInteger(this, keyPrice(symbol)), 0)
318- if (if ((price != 0))
319- then if ((newPrice >= (price + ((price * percentPriceOffset) / 100))))
320- then true
321- else ((price - ((price * percentPriceOffset) / 100)) >= newPrice)
322- else false)
323- then {
324- let reason = "automatic emergency shutdown because of large price variability"
325-[BooleanEntry(keyIsBlocked(symbol), true), StringEntry(keyIsBlockedSender(symbol), toString(this)), StringEntry(keyIsBlockedReason(symbol), reason), IntegerEntry(keyBlackSwarmPrice(height, symbol), newPrice)]
326- }
327- else (PriceEntry(symbol, newPrice, isMarketOpened) ++ StatsEntry(symbol, newPrice))
328- }
329- else PriceFailedResult(symbol, ((((((((("verificationsCount = " + toString(verificationsCount)) + "signs0.length=") + toString(size(signs))) + " msg0 = ") + priceMsgStr) + " sig0 = ") + toBase58String(sig0)) + " key0 = ") + pubKeyOraclesList[0]))
330- }
331- else PriceFailedResult(symbol, ((("data parsing error: newPrice=" + newPriceStr) + " isMarketOpened=") + isMarketOpenedStr))
332- else PriceFailedResult(symbol, ((symbol + " doesn't exist in group: groupDataStr=") + groupDataStr))
333- }
334- }
63+func pzBalance (poolAddress,assetId) = assetBalance(poolAddress, assetId)
33564
33665
33766 @Callable(i)
338-func finalizeDORA2 (header,msg,signs0,signs1,signs2,signs3) = {
339- let headerArray = split(header, ProtocolSEP)
340- let groupNum = headerArray[1]
341- let finHeightStr = headerArray[2]
342- let finHeight = parseIntValue(finHeightStr)
343- let signsLength = (64 * oracleCount)
344- if ((height != finHeight))
345- then throwInvalidFinalizationHeight(finHeightStr)
346- else if (isGroupFinalaized(groupNum, finHeightStr))
347- then throwGroupAlreadyFinalized(groupNum, finHeightStr)
348- else if ((pubKeyOraclesList[(height % oracleCount)] != toBase58String(i.callerPublicKey)))
349- then throwOutOfTurnFinalization()
350- else if ((size(signs0) != signsLength))
351- then throwInvalidSignsParamLength(0, signs0)
352- else if ((size(signs1) != signsLength))
353- then throwInvalidSignsParamLength(1, signs1)
354- else if ((size(signs2) != signsLength))
355- then throwInvalidSignsParamLength(2, signs2)
356- else if ((size(signs3) != signsLength))
357- then throwInvalidSignsParamLength(3, signs3)
358- else {
359- let groupDataKey = keyGroupData(groupNum)
360- let groupDataStr = valueOrErrorMessage(getString(this, groupDataKey), ("empty group data for key=" + groupDataKey))
361- let msgArray = split(msg, ProtocolSEP)
362- if (((size(msgArray) % 3) != 0))
363- then throw(("msg parameters count must be multiple of 3: msgArray.size=" + toString(size(msg))))
364- else ((((finalizePriceV2Common(0, groupNum, groupDataStr, msgArray, signs0) ++ finalizePriceV2Common(1, groupNum, groupDataStr, msgArray, signs1)) ++ finalizePriceV2Common(2, groupNum, groupDataStr, msgArray, signs2)) ++ (if ((groupNum == "0"))
365- then finalizeUsdnUsdtOnchainV2()
366- else finalizePriceV2Common(3, groupNum, groupDataStr, msgArray, signs3))) :+ BooleanEntry(keyGroupStatus(groupNum, finHeightStr), true))
367- }
67+func buyXtnForWaves () = {
68+ let pmt = value(i.payments[0])
69+ let wavesAmt = pmt.amount
70+ let wavesToXtnViaWx = wxPoolBalance(wxWavesXtn, 1)
71+ let wavesToXtnViaSwop = swopBalance(swopWavesXtn, "A")
72+ let wavesToXtnTotal = (wavesToXtnViaWx + wavesToXtnViaSwop)
73+ let wavesToXtnViaWxAmt = fraction(wavesAmt, wavesToXtnViaWx, wavesToXtnTotal)
74+ let wavesToXtnViaSwopAmt = fraction(wavesAmt, wavesToXtnViaSwop, wavesToXtnTotal)
75+ let wavesToXtnViaWxResult = invoke(wxSwop, "swap", [1, xtnIdStr, toString(this)], [AttachedPayment(unit, wavesToXtnViaWxAmt)])
76+ if ((wavesToXtnViaWxResult == wavesToXtnViaWxResult))
77+ then {
78+ let wavesToXtnViaSwopResult = asAnyList(invoke(swopWavesXtn, "exchange", [1], [AttachedPayment(unit, wavesToXtnViaSwopAmt)]))
79+ if ((wavesToXtnViaSwopResult == wavesToXtnViaSwopResult))
80+ then {
81+ let xtnAmt = assetBalance(this, xtnId)
82+ $Tuple2(nil, xtnAmt)
83+ }
84+ else throw("Strict value is not equal to itself.")
85+ }
86+ else throw("Strict value is not equal to itself.")
36887 }
36988
37089
37190
37291 @Callable(i)
373-func price (hours) = {
374- let symbol = "USDN-USDT"
375- let periodSTEP = H4MILLIS
376- let maxHours = 80
377- let iters = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
378- if ((hours > maxHours))
379- then throw("hours is greater then max 80")
380- else if ((4 > hours))
381- then throw("hours is less then min value 4")
382- else {
383- let currTime = lastBlock.timestamp
384- let startTime = ((currTime - (hours * 3600000)) - H4MILLIS)
385- let period = toPeriod(currTime, periodSTEP)
386- let periodStr = toString(period)
387- let smallestPeriod = getIntegerValue(this, keyStats1stPeriod(symbol))
388- let startPeriodTmp = toPeriod(startTime, periodSTEP)
389- let isEnoughData = (startPeriodTmp >= smallestPeriod)
390- let startPeriod = if (isEnoughData)
391- then startPeriodTmp
392- else smallestPeriod
393- let startPeriodStr = toString(startPeriod)
394- let startPriceSumX = parseBigIntValue(getStringValue(this, keyStatsByPeriodPriceSum(symbol, startPeriodStr)))
395- let startCountSum = getIntegerValue(this, keyStatsByPeriodCountSum(symbol, startPeriodStr))
396- let endPriceSumX = if (isEnoughData)
397- then parseBigIntValue(getStringValue(this, keyStatsByPeriodPriceSum(symbol, periodStr)))
398- else toBigInt(0)
399- let endCountSum = if (isEnoughData)
400- then getIntegerValue(this, keyStatsByPeriodCountSum(symbol, periodStr))
401- else 0
402- let priceSum = toInt((endPriceSumX - startPriceSumX))
403- let priceCount = (endCountSum - startCountSum)
404- let priceAvg = (priceSum / priceCount)
405- if ((0 >= priceAvg))
406- then throw("calculation error")
407- else {
408- func findMinMax (minAndMax,nextIdx) = {
409- let periodToCheck = (period - (nextIdx * periodSTEP))
410- if ((startPeriod > periodToCheck))
411- then minAndMax
412- else {
413- let periodToCheckStr = toString(periodToCheck)
414- let minVal = minAndMax._1
415- let maxVal = minAndMax._2
416- let newMinVal = getIntegerValue(this, keyStatsByPeriodMin(symbol, periodToCheckStr))
417- let newMaxVal = getIntegerValue(this, keyStatsByPeriodMax(symbol, periodToCheckStr))
418- $Tuple2(min([minVal, newMinVal]), max([maxVal, newMaxVal]))
92+func buyPuzzleForWaves () = {
93+ let pzForbesValue = pzBalance(pzForbes, puzzleId)
94+ let pzBasicPuzzleValue = pzBalance(pzBasicPuzzle, puzzleId)
95+ let wxPuzzleWavesValue = wxPoolBalance(wxPuzzleWaves, 1)
96+ let swopPuzzleXtnValue = swopBalance(swopPuzzleXtn, "A")
97+ let total = (((pzForbesValue + pzBasicPuzzleValue) + wxPuzzleWavesValue) + swopPuzzleXtnValue)
98+ let pmt = value(i.payments[0])
99+ let pmtAmt = pmt.amount
100+ let pzForbesPart = fraction(pzForbesValue, pmtAmt, total)
101+ let pzBasicPuzzlePart = fraction(pzBasicPuzzleValue, pmtAmt, total)
102+ let wxPuzzleWavesPart = fraction(wxPuzzleWavesValue, pmtAmt, total)
103+ let swopPuzzleXtnPart = fraction(swopPuzzleXtnValue, pmtAmt, total)
104+ let xtnAmt = asInt(invoke(this, "buyXtnForWaves", nil, [AttachedPayment(unit, swopPuzzleXtnPart)]))
105+ if ((xtnAmt == xtnAmt))
106+ then {
107+ let wavesToPuzzleViaForbesResult = invoke(pzForbes, "swap", [puzzleIdStr, 1], [AttachedPayment(unit, pzForbesPart)])
108+ if ((wavesToPuzzleViaForbesResult == wavesToPuzzleViaForbesResult))
109+ then {
110+ let wavesToPuzzleViaBasicResult = invoke(pzBasicPuzzle, "swap", [puzzleIdStr, 1], [AttachedPayment(unit, pzBasicPuzzlePart)])
111+ if ((wavesToPuzzleViaBasicResult == wavesToPuzzleViaBasicResult))
112+ then {
113+ let wavesToPuzzleViaWxResult = invoke(wxSwop, "swap", [1, puzzleIdStr, toString(this)], [AttachedPayment(unit, wxPuzzleWavesPart)])
114+ if ((wavesToPuzzleViaWxResult == wavesToPuzzleViaWxResult))
115+ then {
116+ let xtnToPuzzleViaSwopResult = asAnyList(invoke(swopPuzzleXtn, "exchange", [1], [AttachedPayment(xtnId, xtnAmt)]))
117+ if ((xtnToPuzzleViaSwopResult == xtnToPuzzleViaSwopResult))
118+ then [ScriptTransfer(i.caller, wavesBalance(this).available, unit)]
119+ else throw("Strict value is not equal to itself.")
419120 }
121+ else throw("Strict value is not equal to itself.")
420122 }
421-
422- let price = getIntegerValue(this, keyPrice(symbol))
423- let minMaxSTRUCT = {
424- let $l = iters
425- let $s = size($l)
426- let $acc0 = $Tuple2(9223372036854775, 0)
427- func $f0_1 ($a,$i) = if (($i >= $s))
428- then $a
429- else findMinMax($a, $l[$i])
430-
431- func $f0_2 ($a,$i) = if (($i >= $s))
432- then $a
433- else throw("List size exceeds 21")
434-
435- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21)
436- }
437- $Tuple2(nil, $Tuple4(price, priceAvg, minMaxSTRUCT._1, minMaxSTRUCT._2))
438- }
439- }
123+ else throw("Strict value is not equal to itself.")
124+ }
125+ else throw("Strict value is not equal to itself.")
126+ }
127+ else throw("Strict value is not equal to itself.")
440128 }
441129
442130
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let ProtocolSEP = ":"
4+func asAnyList (val) = match val {
5+ case valAnyList: List[Any] =>
6+ valAnyList
7+ case _ =>
8+ throw("fail to cast into List[Any]")
9+}
510
6-let SEP = "__"
7-
8-let percentPriceOffset = 95
911
1012 func asString (v) = match v {
1113 case s: String =>
1214 s
1315 case _ =>
1416 throw("fail to cast into String")
1517 }
1618
1719
18-func keyPrice (symbol) = ("%s%s__price__" + symbol)
20+func asInt (v) = match v {
21+ case i: Int =>
22+ i
23+ case _ =>
24+ throw("fail to cast into Int")
25+}
1926
2027
21-func keyOracles () = "%s%s__config__oracles"
28+let puzzleIdStr = "HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS"
29+
30+let puzzleId = fromBase58String(puzzleIdStr)
31+
32+let xtnIdStr = "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"
33+
34+let xtnId = fromBase58String(xtnIdStr)
35+
36+let pzForbes = addressFromStringValue("3PQnzp5YogBvJmwPnvSWoargPMcd1R4GLa8")
37+
38+let pzBasicPuzzle = addressFromStringValue("3PQAhPM5iHQyYrAqTVts53UgiLGtVuSZ8xD")
39+
40+let wxRest = addressFromStringValue("3P8MoPnsaurofk1VyhsdAFkeQ6ijpJYXCpW")
41+
42+let wxSwop = addressFromStringValue("3P68zNiufsu1viZpu1aY3cdahRRKcvV5N93")
43+
44+let wxPuzzleWaves = addressFromStringValue("3PQaYm4pbRVrNTTnL8pDJZTxhcmD4jRskrz")
45+
46+let wxPuzzleXtn = addressFromStringValue("3P615yXeQ9Qu4qBM1QGimGzixyMS5W4Ktug")
47+
48+let wxWavesXtn = addressFromStringValue("3PPZWgFNRKHLvM51pwS934C8VZ7d2F4Z58g")
49+
50+let swopPuzzleXtn = addressFromStringValue("3PBHyEwmERR1CEkrTNbPj2bgyisTfPRqfee")
51+
52+let swopWavesXtn = addressFromStringValue("3PHaNgomBkrvEL2QnuJarQVJa71wjw9qiqG")
53+
54+func swopBalance (poolAddress,AorB) = getIntegerValue(poolAddress, (AorB + "_asset_balance"))
2255
2356
24-func keyGroupData (groupNum) = ("%s%d__group__" + groupNum)
25-
26-
27-func keyMinConsensus () = "%s%s__config__minConsensus"
28-
29-
30-func keyPriceFailure (symbol) = makeString(["%s%s%d__finalizationFailure", symbol, toString(height)], SEP)
31-
32-
33-func keyLastHeight (symbol) = ("%s%s__lastHeight__" + symbol)
34-
35-
36-func keyPriceByHeight (symbol,h) = makeString(["%s%s%d__priceByHeight", symbol, toString(h)], SEP)
37-
38-
39-func keyIdx (symbol) = ("%s%s__idxCurrent__" + symbol)
40-
41-
42-func keyIdx2Height (symbol,idx) = makeString(["%s%s%d__idx2Height", symbol, toString(idx)], SEP)
43-
44-
45-func keyHeight2Idx (symbol,h) = makeString(["%s%s%d__height2Idx", symbol, toString(h)], SEP)
46-
47-
48-func keyGroupStatus (groupNum,finHeightStr) = makeString(["%s%d%d__groupStatus", groupNum, finHeightStr], SEP)
49-
50-
51-func keyIsMarketOpened (symbol) = ("%s%s__isMarketOpened__" + symbol)
52-
53-
54-func keyEmptyPriceMsg (position) = makeString(["%s%d%d__emptyPriceMsg", toString(height), toString(position)], SEP)
55-
56-
57-func keyIsBlocked (symbol) = ("%s%s__isBlocked__" + symbol)
58-
59-
60-func keyIsBlockedSender (symbol) = makeString(["%s%s%s__isBlocked", symbol, "sender"], SEP)
61-
62-
63-func keyIsBlockedReason (symbol) = makeString(["%s%s%s__isBlocked", symbol, "reason"], SEP)
64-
65-
66-func keyBlackSwarmPrice (h,symbol) = makeString(["%s%s%s%d__isBlocked", symbol, "blackSwarmPrice", toString(h)], SEP)
67-
68-
69-let DAYMILLIS = 86400000
70-
71-let H4MILLIS = 14400000
72-
73-func toPeriod (timestamp,period) = ((timestamp / period) * period)
74-
75-
76-func keyStats1stPeriod (symbol) = makeString(["%s%s", "stats1stPeriod", symbol], SEP)
77-
78-
79-func keyStatsPriceSum (symbol) = makeString(["%s%s", "statsPriceSum", symbol], SEP)
80-
81-
82-func keyStatsCountSum (symbol) = makeString(["%s%s", "statsCountSum", symbol], SEP)
83-
84-
85-func keyStatsByPeriodPriceSum (symbol,period) = makeString(["%s%s%d", "statsPriceSum", symbol, period], SEP)
86-
87-
88-func keyStatsByPeriodCountSum (symbol,period) = makeString(["%s%s%d", "statsCountSum", symbol, period], SEP)
89-
90-
91-func keyStatsByPeriodMin (symbol,period) = makeString(["%s%s%d", "statsPriceMin", symbol, period], SEP)
92-
93-
94-func keyStatsByPeriodMax (symbol,period) = makeString(["%s%s%d", "statsPriceMax", symbol, period], SEP)
95-
96-
97-func StatsEntry (symbol,price) = {
98- let period = toPeriod(lastBlock.timestamp, H4MILLIS)
99- let periodStr = toString(period)
100- let stats1stPeriodKEY = keyStats1stPeriod(symbol)
101- let statsPriceSumKEY = keyStatsPriceSum(symbol)
102- let statsCountSumKEY = keyStatsCountSum(symbol)
103- let statsByPeriodPriceSumKEY = keyStatsByPeriodPriceSum(symbol, periodStr)
104- let statsByPeriodCountSumKEY = keyStatsByPeriodCountSum(symbol, periodStr)
105- let statsByPeriodMinKEY = keyStatsByPeriodMin(symbol, periodStr)
106- let statsByPeriodMaxKEY = keyStatsByPeriodMax(symbol, periodStr)
107- let statsPriceSum = parseBigIntValue(valueOrElse(getString(this, statsPriceSumKEY), "0"))
108- let statsCountSum = valueOrElse(getInteger(this, statsCountSumKEY), 0)
109- let statsByPeriodMin = valueOrElse(getInteger(this, statsByPeriodMinKEY), 9223372036854775)
110- let statsByPeriodMax = valueOrElse(getInteger(this, statsByPeriodMaxKEY), 0)
111- let newStatsPriceSum = (statsPriceSum + toBigInt(price))
112- let newStatsCountSum = (statsCountSum + 1)
113- let newStatsByPeriodPriceSum = newStatsPriceSum
114- let newStatsByPeriodCountSum = newStatsCountSum
115- let newStatsByPeriodMin = min([statsByPeriodMin, price])
116- let newStatsByPeriodMax = max([statsByPeriodMax, price])
117- let stats1stPeriod = valueOrElse(getInteger(this, stats1stPeriodKEY), -1)
118- ([StringEntry(statsPriceSumKEY, toString(newStatsPriceSum)), IntegerEntry(statsCountSumKEY, newStatsCountSum), StringEntry(statsByPeriodPriceSumKEY, toString(newStatsByPeriodPriceSum)), IntegerEntry(statsByPeriodCountSumKEY, newStatsByPeriodCountSum), IntegerEntry(statsByPeriodMinKEY, newStatsByPeriodMin), IntegerEntry(statsByPeriodMaxKEY, newStatsByPeriodMax)] ++ (if ((0 > stats1stPeriod))
119- then [IntegerEntry(stats1stPeriodKEY, period)]
120- else nil))
57+func wxPoolBalance (poolAddress,assetIndex) = {
58+ let wxRestResult = split(asString(invoke(wxRest, "poolStatsREADONLY", [toString(poolAddress)], nil)), "__")
59+ parseIntValue(wxRestResult[assetIndex])
12160 }
12261
12362
124-func isGroupFinalaized (groupNum,finHeightStr) = isDefined(getBoolean(this, keyGroupStatus(groupNum, finHeightStr)))
125-
126-
127-func readGroupDataOrFail (groupNum) = {
128- let k = keyGroupData(groupNum)
129- let groupDataOpt = getString(this, k)
130- if (isDefined(groupDataOpt))
131- then value(groupDataOpt)
132- else throw(("empty group data for key=" + k))
133- }
134-
135-
136-let pubKeyOraclesList = split(getStringValue(this, keyOracles()), ",")
137-
138-let oracleCount = size(pubKeyOraclesList)
139-
140-let minConsensus = valueOrElse(getInteger(this, keyMinConsensus()), 3)
141-
142-func PriceFailedResult (symbol,msg) = [StringEntry(keyPriceFailure(symbol), msg)]
143-
144-
145-func throwInvalidFinalizationHeight (finHeightStr) = throw(((("invalid finalization height: height=" + toString(height)) + " finalizationHeight=") + finHeightStr))
146-
147-
148-func throwGroupAlreadyFinalized (groupNum,finHeightStr) = throw((((("prices for groupNum=" + groupNum) + " at ") + finHeightStr) + " height have been already finalized"))
149-
150-
151-func throwInvalidSignsParamLength (num,param) = throw(((((("invalid signs" + toString(num)) + " parameter: actual.size=") + toString(size(param))) + " base58Val=") + toBase58String(param)))
152-
153-
154-func throwOutOfTurnFinalization () = throw(((("Out of turn finalization: " + toString(height)) + " block should be finalize by ") + pubKeyOraclesList[(height % oracleCount)]))
155-
156-
157-func throwBlockedError () = throw("contract is blocked by EMERGENCY SHUTDOWN action")
158-
159-
160-func PriceEntry (symbol,newPrice,isMarketOpened) = {
161- let idx = valueOrElse(getInteger(this, keyIdx(symbol)), 0)
162- let newIdx = (idx + 1)
163-[IntegerEntry(keyPrice(symbol), newPrice), IntegerEntry(keyLastHeight(symbol), height), IntegerEntry(keyPriceByHeight(symbol, height), newPrice), IntegerEntry(keyIdx(symbol), newIdx), IntegerEntry(keyIdx2Height(symbol, newIdx), height), IntegerEntry(keyHeight2Idx(symbol, height), newIdx), BooleanEntry(keyIsMarketOpened(symbol), isMarketOpened)]
164- }
165-
166-
167-func finalizeUsdnUsdtOnchain () = {
168- let symbol = "USDN-USDT"
169- let usdnId = "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"
170- let usdtId = "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ"
171- let usdnAmount = 1000000000
172- let wxPoolAddressStr = "3P8KMyAJCPWNcyedqrmymxaeWonvmkhGauz"
173- let wxPoolAddress = addressFromStringValue(wxPoolAddressStr)
174- let $t077107849 = {
175- let @ = invoke(wxPoolAddress, "putOneTknV2WithBonusREADONLY", [usdnAmount, usdnId], nil)
176- if ($isInstanceOf(@, "(Int, Int, Int)"))
177- then @
178- else throw(($getType(@) + " couldn't be cast to (Int, Int, Int)"))
179- }
180- let lpAmount = $t077107849._1
181- let feeAmount1 = $t077107849._2
182- let bonus = $t077107849._3
183- let $t078527970 = {
184- let @ = invoke(wxPoolAddress, "getOneTknV2READONLY", [usdtId, lpAmount], nil)
185- if ($isInstanceOf(@, "(Int, Int)"))
186- then @
187- else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
188- }
189- let usdtAmount = $t078527970._1
190- let feeAmount2 = $t078527970._2
191- let newPrice = fraction(usdtAmount, 1000000, usdnAmount)
192- (PriceEntry(symbol, newPrice, true) ++ StatsEntry(symbol, newPrice))
193- }
194-
195-
196-func finalizePwrUsdtOnchainV2 () = {
197- let symbol = "PWR-USDT"
198- let wavesUsdPriceX6 = getIntegerValue(this, "%s%s__price__WAVES-USDT")
199- let ethUsdtPriceX6 = getIntegerValue(this, "%s%s__price__ETH-USDT")
200- let wx_restAddressStr = "3P8MoPnsaurofk1VyhsdAFkeQ6ijpJYXCpW"
201- let wx_restDapp = addressFromStringValue(wx_restAddressStr)
202- let wx_pwrWavesPoolStr = "3PDi7Qq8pLQYvtKyTfQuqqPUWyhoYbU957t"
203- let wx_pwrWavesPoolAddress = addressFromStringValue(wx_pwrWavesPoolStr)
204- let wx_PwrWaves_lp = "AKQsEQoeinKRFtdx6rhKWcpkAMu6cbDLdtSWnR8tpBCq"
205- let wxRestResult = split(asString(invoke(wx_restDapp, "poolStatsREADONLY", [wx_PwrWaves_lp], nil)), "__")
206- let wx_PwrWaves_WavesX8 = parseIntValue(wxRestResult[2])
207- let wx_PwrWaves_PwrX8 = parseIntValue(wxRestResult[1])
208- let wx_PwrWaves_WxUsdPriceX6 = fraction(wx_PwrWaves_WavesX8, wavesUsdPriceX6, wx_PwrWaves_PwrX8)
209- let debug = ((((("wavesUsdPriceX6=" + toString(wavesUsdPriceX6)) + " wx_PwrWaves_WavesX8=") + toString(wx_PwrWaves_WavesX8)) + " wx_PwrWaves_PwrX8=") + toString(wx_PwrWaves_PwrX8))
210- $Tuple2(wx_PwrWaves_WxUsdPriceX6, debug)
211- }
212-
213-
214-func finalizeUsdnUsdtOnchainV2 () = {
215- let wavesUsdtPriceX6 = getIntegerValue(this, "%s%s__price__WAVES-USDT")
216- let ethUsdtPriceX6 = getIntegerValue(this, "%s%s__price__ETH-USDT")
217- let symbol = "USDN-USDT"
218- let xtnIdStr = "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"
219- let xtnId = fromBase58String(xtnIdStr)
220- let usdtIdStr = "34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ"
221- let usdnAmount = 1000000000
222- let wxUsdtXtnPoolStr = "3P8KMyAJCPWNcyedqrmymxaeWonvmkhGauz"
223- let wxUsdtXtnPoolAddress = addressFromStringValue(wxUsdtXtnPoolStr)
224- let wxUsdtXtnW = 67
225- let $t097969944 = {
226- let @ = invoke(wxUsdtXtnPoolAddress, "putOneTknV2WithBonusREADONLY", [usdnAmount, xtnIdStr], nil)
227- if ($isInstanceOf(@, "(Int, Int, Int)"))
228- then @
229- else throw(($getType(@) + " couldn't be cast to (Int, Int, Int)"))
230- }
231- let lpAmount = $t097969944._1
232- let feeAmount1 = $t097969944._2
233- let bonus = $t097969944._3
234- let $t0994710075 = {
235- let @ = invoke(wxUsdtXtnPoolAddress, "getOneTknV2READONLY", [usdtIdStr, lpAmount], nil)
236- if ($isInstanceOf(@, "(Int, Int)"))
237- then @
238- else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
239- }
240- let usdtAmount = $t0994710075._1
241- let feeAmount2 = $t0994710075._2
242- let wxUsdtXtnPrice = fraction(usdtAmount, 1000000, usdnAmount)
243- let wxWavesXtnW = 550
244- let wxWavesXtnPoolStr = "3PPZWgFNRKHLvM51pwS934C8VZ7d2F4Z58g"
245- let wxWavesXtnPoolAddress = addressFromStringValue(wxWavesXtnPoolStr)
246- let wavesWavesXtnX8 = wavesBalance(wxWavesXtnPoolAddress).regular
247- let xtnWavesXtnX6 = assetBalance(wxWavesXtnPoolAddress, xtnId)
248- let wavesXtnPriceX6 = fraction(xtnWavesXtnX6, 100000000, wavesWavesXtnX8)
249- let wxWavesUsdtXtnPrice = fraction(wavesUsdtPriceX6, 1000000, wavesXtnPriceX6)
250- let wxEthXtnW = 5
251- let ethIdStr = "474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu"
252- let ethId = fromBase58String(ethIdStr)
253- let wxEthXtnPoolStr = "3PEMqetsaJDbYMw1XGovmE37FB8VUhGnX9A"
254- let wxEthXtnPoolAddress = addressFromStringValue(wxEthXtnPoolStr)
255- let ethEthXtnX8 = assetBalance(wxEthXtnPoolAddress, ethId)
256- let xtnEthXtnX6 = assetBalance(wxEthXtnPoolAddress, xtnId)
257- let ethXtnPriceX6 = fraction(xtnEthXtnX6, 100000000, ethEthXtnX8)
258- let wxEthUsdtXtnPrice = fraction(ethUsdtPriceX6, 1000000, ethXtnPriceX6)
259- let swopfiWavesXtnW = 1000
260- let swopfiRest = addressFromStringValue("3P56jNQzECXnrWpnbbSJKw7Eooo6fkUaMPp")
261- let swopfiWavesXtnPriceX6 = {
262- let @ = invoke(swopfiRest, "calcGetAmountCPMM", ["3PHaNgomBkrvEL2QnuJarQVJa71wjw9qiqG", "3PQHCTqfzE8e1Jo8m1QVaCXATSKyMmkYasF", "WAVES", 100000000], nil)
263- if ($isInstanceOf(@, "Int"))
264- then @
265- else throw(($getType(@) + " couldn't be cast to Int"))
266- }
267- let swopfiWavesUsdtXtnPrice = fraction(wavesUsdtPriceX6, 1000000, swopfiWavesXtnPriceX6)
268- let newPrice = fraction(swopfiWavesUsdtXtnPrice, swopfiWavesXtnW, 1000)
269- (PriceEntry(symbol, newPrice, true) ++ StatsEntry(symbol, newPrice))
270- }
271-
272-
273-func finalizePriceV2Common (position,groupNum,groupDataStr,msgArray,signs) = {
274- let msgOffset = (position * 3)
275- if ((msgOffset >= size(msgArray)))
276- then [StringEntry(keyEmptyPriceMsg(position), "price data is empty")]
277- else {
278- let symbol = msgArray[(msgOffset + 0)]
279- let newPriceStr = msgArray[(msgOffset + 1)]
280- let isMarketOpenedStr = msgArray[(msgOffset + 2)]
281- let newPriceOpt = parseInt(newPriceStr)
282- let isMarketOpenedOpt = parseInt(isMarketOpenedStr)
283- let sig0 = take(signs, 64)
284- let sig1 = take(drop(signs, 64), 64)
285- let sig2 = take(drop(signs, 128), 64)
286- let sig3 = take(drop(signs, 192), 64)
287- let sig4 = takeRight(signs, 64)
288- let isBlocked = valueOrElse(getBoolean(this, keyIsBlocked(symbol)), false)
289- if ((symbol == ""))
290- then nil
291- else if (isBlocked)
292- then PriceFailedResult(symbol, (symbol + " is blocked"))
293- else if (contains(groupDataStr, symbol))
294- then if (if (isDefined(newPriceOpt))
295- then isDefined(isMarketOpenedOpt)
296- else false)
297- then {
298- let newPrice = value(newPriceOpt)
299- let isMarketOpened = if ((value(isMarketOpenedOpt) == 1))
300- then true
301- else false
302- let priceMsgStr = makeString(["WAVES-DORA2", groupNum, toString(height), symbol, newPriceStr, isMarketOpenedStr], ProtocolSEP)
303- let priceMsg = toBytes(priceMsgStr)
304- let verificationsCount = (((((if (sigVerify_8Kb(priceMsg, sig0, fromBase58String(pubKeyOraclesList[0])))
305- then 1
306- else 0) + (if (sigVerify_8Kb(priceMsg, sig1, fromBase58String(pubKeyOraclesList[1])))
307- then 1
308- else 0)) + (if (sigVerify_8Kb(priceMsg, sig2, fromBase58String(pubKeyOraclesList[2])))
309- then 1
310- else 0)) + (if (sigVerify_8Kb(priceMsg, sig3, fromBase58String(pubKeyOraclesList[3])))
311- then 1
312- else 0)) + (if (sigVerify_8Kb(priceMsg, sig4, fromBase58String(pubKeyOraclesList[4])))
313- then 1
314- else 0))
315- if ((verificationsCount >= minConsensus))
316- then {
317- let price = valueOrElse(getInteger(this, keyPrice(symbol)), 0)
318- if (if ((price != 0))
319- then if ((newPrice >= (price + ((price * percentPriceOffset) / 100))))
320- then true
321- else ((price - ((price * percentPriceOffset) / 100)) >= newPrice)
322- else false)
323- then {
324- let reason = "automatic emergency shutdown because of large price variability"
325-[BooleanEntry(keyIsBlocked(symbol), true), StringEntry(keyIsBlockedSender(symbol), toString(this)), StringEntry(keyIsBlockedReason(symbol), reason), IntegerEntry(keyBlackSwarmPrice(height, symbol), newPrice)]
326- }
327- else (PriceEntry(symbol, newPrice, isMarketOpened) ++ StatsEntry(symbol, newPrice))
328- }
329- else PriceFailedResult(symbol, ((((((((("verificationsCount = " + toString(verificationsCount)) + "signs0.length=") + toString(size(signs))) + " msg0 = ") + priceMsgStr) + " sig0 = ") + toBase58String(sig0)) + " key0 = ") + pubKeyOraclesList[0]))
330- }
331- else PriceFailedResult(symbol, ((("data parsing error: newPrice=" + newPriceStr) + " isMarketOpened=") + isMarketOpenedStr))
332- else PriceFailedResult(symbol, ((symbol + " doesn't exist in group: groupDataStr=") + groupDataStr))
333- }
334- }
63+func pzBalance (poolAddress,assetId) = assetBalance(poolAddress, assetId)
33564
33665
33766 @Callable(i)
338-func finalizeDORA2 (header,msg,signs0,signs1,signs2,signs3) = {
339- let headerArray = split(header, ProtocolSEP)
340- let groupNum = headerArray[1]
341- let finHeightStr = headerArray[2]
342- let finHeight = parseIntValue(finHeightStr)
343- let signsLength = (64 * oracleCount)
344- if ((height != finHeight))
345- then throwInvalidFinalizationHeight(finHeightStr)
346- else if (isGroupFinalaized(groupNum, finHeightStr))
347- then throwGroupAlreadyFinalized(groupNum, finHeightStr)
348- else if ((pubKeyOraclesList[(height % oracleCount)] != toBase58String(i.callerPublicKey)))
349- then throwOutOfTurnFinalization()
350- else if ((size(signs0) != signsLength))
351- then throwInvalidSignsParamLength(0, signs0)
352- else if ((size(signs1) != signsLength))
353- then throwInvalidSignsParamLength(1, signs1)
354- else if ((size(signs2) != signsLength))
355- then throwInvalidSignsParamLength(2, signs2)
356- else if ((size(signs3) != signsLength))
357- then throwInvalidSignsParamLength(3, signs3)
358- else {
359- let groupDataKey = keyGroupData(groupNum)
360- let groupDataStr = valueOrErrorMessage(getString(this, groupDataKey), ("empty group data for key=" + groupDataKey))
361- let msgArray = split(msg, ProtocolSEP)
362- if (((size(msgArray) % 3) != 0))
363- then throw(("msg parameters count must be multiple of 3: msgArray.size=" + toString(size(msg))))
364- else ((((finalizePriceV2Common(0, groupNum, groupDataStr, msgArray, signs0) ++ finalizePriceV2Common(1, groupNum, groupDataStr, msgArray, signs1)) ++ finalizePriceV2Common(2, groupNum, groupDataStr, msgArray, signs2)) ++ (if ((groupNum == "0"))
365- then finalizeUsdnUsdtOnchainV2()
366- else finalizePriceV2Common(3, groupNum, groupDataStr, msgArray, signs3))) :+ BooleanEntry(keyGroupStatus(groupNum, finHeightStr), true))
367- }
67+func buyXtnForWaves () = {
68+ let pmt = value(i.payments[0])
69+ let wavesAmt = pmt.amount
70+ let wavesToXtnViaWx = wxPoolBalance(wxWavesXtn, 1)
71+ let wavesToXtnViaSwop = swopBalance(swopWavesXtn, "A")
72+ let wavesToXtnTotal = (wavesToXtnViaWx + wavesToXtnViaSwop)
73+ let wavesToXtnViaWxAmt = fraction(wavesAmt, wavesToXtnViaWx, wavesToXtnTotal)
74+ let wavesToXtnViaSwopAmt = fraction(wavesAmt, wavesToXtnViaSwop, wavesToXtnTotal)
75+ let wavesToXtnViaWxResult = invoke(wxSwop, "swap", [1, xtnIdStr, toString(this)], [AttachedPayment(unit, wavesToXtnViaWxAmt)])
76+ if ((wavesToXtnViaWxResult == wavesToXtnViaWxResult))
77+ then {
78+ let wavesToXtnViaSwopResult = asAnyList(invoke(swopWavesXtn, "exchange", [1], [AttachedPayment(unit, wavesToXtnViaSwopAmt)]))
79+ if ((wavesToXtnViaSwopResult == wavesToXtnViaSwopResult))
80+ then {
81+ let xtnAmt = assetBalance(this, xtnId)
82+ $Tuple2(nil, xtnAmt)
83+ }
84+ else throw("Strict value is not equal to itself.")
85+ }
86+ else throw("Strict value is not equal to itself.")
36887 }
36988
37089
37190
37291 @Callable(i)
373-func price (hours) = {
374- let symbol = "USDN-USDT"
375- let periodSTEP = H4MILLIS
376- let maxHours = 80
377- let iters = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
378- if ((hours > maxHours))
379- then throw("hours is greater then max 80")
380- else if ((4 > hours))
381- then throw("hours is less then min value 4")
382- else {
383- let currTime = lastBlock.timestamp
384- let startTime = ((currTime - (hours * 3600000)) - H4MILLIS)
385- let period = toPeriod(currTime, periodSTEP)
386- let periodStr = toString(period)
387- let smallestPeriod = getIntegerValue(this, keyStats1stPeriod(symbol))
388- let startPeriodTmp = toPeriod(startTime, periodSTEP)
389- let isEnoughData = (startPeriodTmp >= smallestPeriod)
390- let startPeriod = if (isEnoughData)
391- then startPeriodTmp
392- else smallestPeriod
393- let startPeriodStr = toString(startPeriod)
394- let startPriceSumX = parseBigIntValue(getStringValue(this, keyStatsByPeriodPriceSum(symbol, startPeriodStr)))
395- let startCountSum = getIntegerValue(this, keyStatsByPeriodCountSum(symbol, startPeriodStr))
396- let endPriceSumX = if (isEnoughData)
397- then parseBigIntValue(getStringValue(this, keyStatsByPeriodPriceSum(symbol, periodStr)))
398- else toBigInt(0)
399- let endCountSum = if (isEnoughData)
400- then getIntegerValue(this, keyStatsByPeriodCountSum(symbol, periodStr))
401- else 0
402- let priceSum = toInt((endPriceSumX - startPriceSumX))
403- let priceCount = (endCountSum - startCountSum)
404- let priceAvg = (priceSum / priceCount)
405- if ((0 >= priceAvg))
406- then throw("calculation error")
407- else {
408- func findMinMax (minAndMax,nextIdx) = {
409- let periodToCheck = (period - (nextIdx * periodSTEP))
410- if ((startPeriod > periodToCheck))
411- then minAndMax
412- else {
413- let periodToCheckStr = toString(periodToCheck)
414- let minVal = minAndMax._1
415- let maxVal = minAndMax._2
416- let newMinVal = getIntegerValue(this, keyStatsByPeriodMin(symbol, periodToCheckStr))
417- let newMaxVal = getIntegerValue(this, keyStatsByPeriodMax(symbol, periodToCheckStr))
418- $Tuple2(min([minVal, newMinVal]), max([maxVal, newMaxVal]))
92+func buyPuzzleForWaves () = {
93+ let pzForbesValue = pzBalance(pzForbes, puzzleId)
94+ let pzBasicPuzzleValue = pzBalance(pzBasicPuzzle, puzzleId)
95+ let wxPuzzleWavesValue = wxPoolBalance(wxPuzzleWaves, 1)
96+ let swopPuzzleXtnValue = swopBalance(swopPuzzleXtn, "A")
97+ let total = (((pzForbesValue + pzBasicPuzzleValue) + wxPuzzleWavesValue) + swopPuzzleXtnValue)
98+ let pmt = value(i.payments[0])
99+ let pmtAmt = pmt.amount
100+ let pzForbesPart = fraction(pzForbesValue, pmtAmt, total)
101+ let pzBasicPuzzlePart = fraction(pzBasicPuzzleValue, pmtAmt, total)
102+ let wxPuzzleWavesPart = fraction(wxPuzzleWavesValue, pmtAmt, total)
103+ let swopPuzzleXtnPart = fraction(swopPuzzleXtnValue, pmtAmt, total)
104+ let xtnAmt = asInt(invoke(this, "buyXtnForWaves", nil, [AttachedPayment(unit, swopPuzzleXtnPart)]))
105+ if ((xtnAmt == xtnAmt))
106+ then {
107+ let wavesToPuzzleViaForbesResult = invoke(pzForbes, "swap", [puzzleIdStr, 1], [AttachedPayment(unit, pzForbesPart)])
108+ if ((wavesToPuzzleViaForbesResult == wavesToPuzzleViaForbesResult))
109+ then {
110+ let wavesToPuzzleViaBasicResult = invoke(pzBasicPuzzle, "swap", [puzzleIdStr, 1], [AttachedPayment(unit, pzBasicPuzzlePart)])
111+ if ((wavesToPuzzleViaBasicResult == wavesToPuzzleViaBasicResult))
112+ then {
113+ let wavesToPuzzleViaWxResult = invoke(wxSwop, "swap", [1, puzzleIdStr, toString(this)], [AttachedPayment(unit, wxPuzzleWavesPart)])
114+ if ((wavesToPuzzleViaWxResult == wavesToPuzzleViaWxResult))
115+ then {
116+ let xtnToPuzzleViaSwopResult = asAnyList(invoke(swopPuzzleXtn, "exchange", [1], [AttachedPayment(xtnId, xtnAmt)]))
117+ if ((xtnToPuzzleViaSwopResult == xtnToPuzzleViaSwopResult))
118+ then [ScriptTransfer(i.caller, wavesBalance(this).available, unit)]
119+ else throw("Strict value is not equal to itself.")
419120 }
121+ else throw("Strict value is not equal to itself.")
420122 }
421-
422- let price = getIntegerValue(this, keyPrice(symbol))
423- let minMaxSTRUCT = {
424- let $l = iters
425- let $s = size($l)
426- let $acc0 = $Tuple2(9223372036854775, 0)
427- func $f0_1 ($a,$i) = if (($i >= $s))
428- then $a
429- else findMinMax($a, $l[$i])
430-
431- func $f0_2 ($a,$i) = if (($i >= $s))
432- then $a
433- else throw("List size exceeds 21")
434-
435- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21)
436- }
437- $Tuple2(nil, $Tuple4(price, priceAvg, minMaxSTRUCT._1, minMaxSTRUCT._2))
438- }
439- }
123+ else throw("Strict value is not equal to itself.")
124+ }
125+ else throw("Strict value is not equal to itself.")
126+ }
127+ else throw("Strict value is not equal to itself.")
440128 }
441129
442130

github/deemru/w8io/3ef1775 
47.74 ms