tx · HEUQwFTosusBuQ6C6rj9ZAKDBD49rus4e1aotDZwurZc

3P5Bfd58PPfNvBM2Hy8QfbcDqMeNtzg7KfP:  -0.01400000 Waves

2020.03.18 17:43 [1977993] smart account 3P5Bfd58PPfNvBM2Hy8QfbcDqMeNtzg7KfP > SELF 0.00000000 Waves

{ "type": 13, "id": "HEUQwFTosusBuQ6C6rj9ZAKDBD49rus4e1aotDZwurZc", "fee": 1400000, "feeAssetId": null, "timestamp": 1584540539889, "version": 1, "sender": "3P5Bfd58PPfNvBM2Hy8QfbcDqMeNtzg7KfP", "senderPublicKey": "GqXuX2WHNr3WUqTaeH2YCySFY45NAJoE9RmY9bEWkzh", "proofs": [ "2Y3M8tLL22jQb8225XxXC8rYgZdFZfHeWNX16q8Zbhyt3dsxGEnf3icgqweP1YUFkxPkzURYw6mTRVqmj8k7Qmtm", "4Ynpu1NrNa3WrTS2sv7TtW8ZVvvji98FRko8S3YYJARRoh2RvADQYM7b3ugjqo7aHSTDSiP7zhk6qGGg7Gc58MFQ", "qk3HcFqmvJrfg3E3Bag2v5dBQCegksSbzgLMYyfikN6s69ysuNkdkpUNVuWUxkoXZmGLiNDtdeKc7crH1FXYAdV" ], "script": "base64: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bGUAAAAAAAAAAAQAAAAAD25ldXRyaW5vQWRkcmVzcwkBAAAAFGFkZHJlc3NGcm9tUHVibGljS2V5AAAAAQkAAlkAAAABAgAAACxCUm5Wd1NWY3RuVjhwZ2U1dlJwc0pkV25raldFSnNwRmI2UXZybVp2dTNIdAAAAAASbGlxdWlkYXRpb25BZGRyZXNzCQEAAAAUYWRkcmVzc0Zyb21QdWJsaWNLZXkAAAABCQACWQAAAAECAAAALEg4R29vcWdrNDQ4Nk1rcUVRVndBQ3Bnb3lFanQ1UHg0ZXNreXNuRURaMW5SAAAAAA1uZXV0cmlub0Fzc2V0CQACWQAAAAECAAAALERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwAAAAABVuZXV0cmlub0xvY2tlZEJhbGFuY2UEAAAAByRtYXRjaDAJAAQaAAAAAgUAAAAPbmV1dHJpbm9BZGRyZXNzAgAAABViYWxhbmNlX2xvY2tfbmV1dHJpbm8DCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAABYQUAAAAHJG1hdGNoMAUAAAABYQAAAAAAAAAAAAAAAAASd2F2ZXNMb2NrZWRCYWxhbmNlBAAAAAckbWF0Y2gwCQAEGgAAAAIFAAAAD25ldXRyaW5vQWRkcmVzcwIAAAASYmFsYW5jZV9sb2NrX3dhdmVzAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAANJbnQEAAAAAWEFAAAAByRtYXRjaDAFAAAAAWEAAAAAAAAAAAAAAAAAB3Jlc2VydmUJAABlAAAAAgkBAAAADHdhdmVzQmFsYW5jZQAAAAEFAAAAD25ldXRyaW5vQWRkcmVzcwUAAAASd2F2ZXNMb2NrZWRCYWxhbmNlAAAAAA5uZXV0cmlub1N1cHBseQkAAGUAAAACCQAAZQAAAAIJAABkAAAAAgUAAAAVbmV1dHJpbm9Mb2NrZWRCYWxhbmNlCAkBAAAAB2V4dHJhY3QAAAABCQAD7AAAAAEFAAAADW5ldXRyaW5vQXNzZXQAAAAIcXVhbnRpdHkJAAPrAAAAAgUAAAAPbmV1dHJpbm9BZGRyZXNzBQAAAA1uZXV0cmlub0Fzc2V0CQAD6wAAAAIFAAAAEmxpcXVpZGF0aW9uQWRkcmVzcwUAAAANbmV1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", "chainId": 87, "height": 1977993, "spentComplexity": 0 } View: original | compacted Prev: 5kHRp32F3b637u9B6u1V5pWj8fL7zxzXf5wmZo6PXs4e Next: tDxgNmFjEJUiQMqbwDEz5ohyPsn3SDZBaA7nADYMGb7 Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 3 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-func getNumberByKey (key) = match getInteger(this, key) {
5- case a: Int =>
6- a
7- case _ =>
8- 0
9-}
4+func convertWavesToNeutrino (amount,price) = fraction(fraction(amount, price, 100), 1000000, 100000000)
105
116
127 func getStringByKey (key) = match getString(this, key) {
1712 }
1813
1914
20-func getBoolByKey (key) = match getBoolean(this, key) {
21- case a: Boolean =>
15+func getNumberByAddressAndKey (address,key) = match getInteger(addressFromStringValue(address), key) {
16+ case a: Int =>
2217 a
2318 case _ =>
24- false
19+ 0
2520 }
2621
2722
28-func getNumberByAddressAndKey (address,key) = match getInteger(address, key) {
23+func getOracleProvideHeight (ownerPub,height) = match getInteger(addressFromPublicKey(ownerPub), ("price_" + toString(height))) {
2924 case a: Int =>
3025 a
3126 case _ =>
5247 func convertJsonArrayToList (jsonArray) = split(jsonArray, ",")
5348
5449
55-let BLOCK = "block"
50+let price = match getInteger(this, "price") {
51+ case a: Int =>
52+ a
53+ case _ =>
54+ 0
55+}
5656
57-let UNBLOCK = "unblock"
57+let priceIndex = match getInteger(this, "price_index") {
58+ case a: Int =>
59+ a
60+ case _ =>
61+ 0
62+}
5863
59-let UPDATE = "update"
64+let isBlocked = match getBoolean(this, "is_blocked") {
65+ case a: Boolean =>
66+ a
67+ case _ =>
68+ false
69+}
6070
61-let OraclesKey = "oracles"
71+let percentPriceOffset = 7
6272
63-let PriceOffsetKey = "price_offset"
73+let pubKeyOracles = getStringByKey("oracles")
6474
65-let AutoEmergencyOracleAddress = "3P7ihFVxBNbHK237TNdPxT1xHEu8pHexXTr"
75+let pubKeyOraclesList = convertJsonArrayToList(pubKeyOracles)
6676
67-let PriceKey = "price"
77+let bftCoefficientOracle = 4
6878
69-let IsBlockedKey = "is_blocked"
79+let neutrinoAddress = addressFromPublicKey(fromBase58String("BRnVwSVctnV8pge5vRpsJdWnkjWEJspFb6QvrmZvu3Ht"))
7080
71-let IsBlockedCallerKey = "is_blocked_caller"
81+let liquidationAddress = addressFromPublicKey(fromBase58String("H8Gooqgk4486MkqEQVwACpgoyEjt5Px4eskysnEDZ1nR"))
7282
73-let IsBlockedReasonKey = "is_blocked_reason"
83+let neutrinoAsset = fromBase58String("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
7484
75-let PriceIndexKey = "price_index"
85+let neutrinoLockedBalance = match getInteger(neutrinoAddress, "balance_lock_neutrino") {
86+ case a: Int =>
87+ a
88+ case _ =>
89+ 0
90+}
7691
77-func getBlackSwarmPriceKey (block) = (("black_swarm_price" + "_") + toString(block))
92+let wavesLockedBalance = match getInteger(neutrinoAddress, "balance_lock_waves") {
93+ case a: Int =>
94+ a
95+ case _ =>
96+ 0
97+}
7898
99+let reserve = (wavesBalance(neutrinoAddress) - wavesLockedBalance)
79100
80-func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block))
101+let neutrinoSupply = (((neutrinoLockedBalance + extract(assetInfo(neutrinoAsset)).quantity) - assetBalance(neutrinoAddress, neutrinoAsset)) - assetBalance(liquidationAddress, neutrinoAsset))
81102
82-
83-func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index))
84-
85-
86-func getOracleProvidePriceKey (height) = ("price_" + toString(height))
87-
88-
89-let price = getNumberByKey(PriceKey)
90-
91-let priceIndex = getNumberByKey(PriceIndexKey)
92-
93-let isBlocked = getBoolByKey(IsBlockedKey)
94-
95-let isBlockedCaller = getBoolByKey(IsBlockedCallerKey)
96-
97-let bftCoefficientOracle = 3
98-
99-let percentPriceOffset = getNumberByKey(PriceOffsetKey)
100-
101-let oracles = getStringByKey(OraclesKey)
102-
103-let oraclesList = convertJsonArrayToList(oracles)
104-
105-func getOracleProvideHeight (owner,height) = getNumberByAddressAndKey(addressFromStringValue(owner), getOracleProvidePriceKey(height))
106-
107-
108-func getPriceHistory (height) = getNumberByKey(getPriceHistoryKey(height))
109-
110-
111-func isOracle (address) = isDefined(indexOf(oracles, address))
112-
113-
114-func filterAdminsVoteByAction (result,address,action) = address :: result
115-
116-
117-func filterAdminsVoteByBlockAction (result,address) = filterAdminsVoteByAction(result, address, BLOCK)
118-
119-
120-func filterAdminsVoteByUnblockAction (result,address) = filterAdminsVoteByAction(result, address, UNBLOCK)
121-
122-
123-func filterAdminsVoteByUpdateAction (result,address) = filterAdminsVoteByAction(result, address, UPDATE)
124-
103+let deficit = (neutrinoSupply - convertWavesToNeutrino(reserve, price))
125104
126105 func findPricesInRange (prices) = {
127106 let minPercentBound = 90
290269 }
291270
292271
272+func formattingPriceMsg (price,height) = toBytes((((("WAVESNEUTRINOPREFIX" + "_") + toString(height)) + "_") + toString(price)))
273+
274+
293275 @Callable(i)
294276 func callEmergencyShutdown (reason) = {
277+ let AutoEmergencyOracleAddress = "3P7ihFVxBNbHK237TNdPxT1xHEu8pHexXTr"
295278 let callerAddress = toString(i.caller)
296279 if ((AutoEmergencyOracleAddress != callerAddress))
297280 then throw("caller must be one an emergency oracle")
298- else WriteSet([DataEntry(IsBlockedKey, true), DataEntry(IsBlockedCallerKey, callerAddress), DataEntry(IsBlockedReasonKey, reason)])
281+ else WriteSet([DataEntry("is_blocked", true), DataEntry("is_blocked_caller", callerAddress), DataEntry("is_blocked_reason", reason)])
299282 }
300283
301284
302285
303286 @Callable(i)
304-func finalizeCurrentPrice () = if (isBlocked)
287+func finalizeCurrentPrice (price1,sign1,price2,sign2,price3,sign3,price4,sign4,price5,sign5) = if (isBlocked)
305288 then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
306- else if ((getPriceHistory(height) != 0))
289+ else if (( match getInteger(this, ("price_" + toString(height))) {
290+ case a: Int =>
291+ a
292+ case _ =>
293+ 0
294+ } != 0))
307295 then throw("wait next block")
308- else {
309- let prices = [getOracleProvideHeight(oraclesList[0], height), getOracleProvideHeight(oraclesList[1], height), getOracleProvideHeight(oraclesList[2], height), getOracleProvideHeight(oraclesList[3], height), getOracleProvideHeight(oraclesList[4], height)]
310- let pricesInRange = findPricesInRange(prices)
311- let priceProvidingCount = size(pricesInRange)
312- if ((3 > priceProvidingCount))
313- then throw(((((((((((((((((((((("Could not finalize price because of big variation: height=" + toString(height)) + "
314-") + oraclesList[0]) + "=") + toString(prices[0])) + "
315-") + oraclesList[1]) + "=") + toString(prices[1])) + "
316-") + oraclesList[2]) + "=") + toString(prices[2])) + "
317-") + oraclesList[3]) + "=") + toString(prices[3])) + "
318-") + oraclesList[4]) + "=") + toString(prices[4])))
319- else {
320- let sum1 = ((prices[pricesInRange[0]] + prices[pricesInRange[1]]) + prices[pricesInRange[2]])
321- let sum2 = if ((priceProvidingCount >= 4))
322- then (sum1 + prices[pricesInRange[3]])
323- else sum1
324- let priceSum = if ((priceProvidingCount >= 5))
325- then (sum2 + prices[pricesInRange[4]])
326- else sum2
327- if ((priceProvidingCount >= 6))
328- then throw("Invalid pricesInRange creation")
329- else {
330- let newPrice = (priceSum / priceProvidingCount)
331- if (if ((newPrice >= (price + ((price * percentPriceOffset) / 100))))
332- then true
333- else ((price - ((price * percentPriceOffset) / 100)) >= newPrice))
334- then WriteSet([DataEntry(IsBlockedKey, true), DataEntry(getBlackSwarmPriceKey(height), newPrice)])
335- else {
336- let newPriceIndex = (priceIndex + 1)
337- WriteSet([DataEntry(PriceKey, newPrice), DataEntry(getPriceHistoryKey(height), newPrice), DataEntry(PriceIndexKey, newPriceIndex), DataEntry(getHeightPriceByIndexKey(newPriceIndex), height)])
338- }
339- }
340- }
341- }
296+ else if ((pubKeyOraclesList[(height % 5)] != toBase58String(i.callerPublicKey)))
297+ then throw(((("Out of turn finalization: " + toString(height)) + " block should be finalize by ") + pubKeyOraclesList[(height % 5)]))
298+ else {
299+ let prices = [if (sigVerify(formattingPriceMsg(price1, height), sign1, fromBase58String(pubKeyOraclesList[0])))
300+ then price1
301+ else 0, if (sigVerify(formattingPriceMsg(price2, height), sign2, fromBase58String(pubKeyOraclesList[1])))
302+ then price2
303+ else 0, if (sigVerify(formattingPriceMsg(price3, height), sign3, fromBase58String(pubKeyOraclesList[2])))
304+ then price3
305+ else 0, if (sigVerify(formattingPriceMsg(price4, height), sign4, fromBase58String(pubKeyOraclesList[3])))
306+ then price4
307+ else 0, if (sigVerify(formattingPriceMsg(price5, height), sign5, fromBase58String(pubKeyOraclesList[4])))
308+ then price5
309+ else 0]
310+ let pricesInRange = findPricesInRange(prices)
311+ let priceProvidingCount = size(pricesInRange)
312+ if ((3 > priceProvidingCount))
313+ then throw(((((((((((((((((((((("Could not finalize price because of big variation: height=" + toString(height)) + "
314+") + pubKeyOraclesList[0]) + "=") + toString(prices[0])) + "
315+") + pubKeyOraclesList[1]) + "=") + toString(prices[1])) + "
316+") + pubKeyOraclesList[2]) + "=") + toString(prices[2])) + "
317+") + pubKeyOraclesList[3]) + "=") + toString(prices[3])) + "
318+") + pubKeyOraclesList[4]) + "=") + toString(prices[4])))
319+ else {
320+ let sum1 = ((prices[pricesInRange[0]] + prices[pricesInRange[1]]) + prices[pricesInRange[2]])
321+ let sum2 = if ((priceProvidingCount >= 4))
322+ then (sum1 + prices[pricesInRange[3]])
323+ else sum1
324+ let priceSum = if ((priceProvidingCount >= 5))
325+ then (sum2 + prices[pricesInRange[4]])
326+ else sum2
327+ if ((priceProvidingCount >= 6))
328+ then throw("Invalid pricesInRange creation")
329+ else {
330+ let newPrice = (priceSum / priceProvidingCount)
331+ if (if ((newPrice >= (price + ((price * percentPriceOffset) / 100))))
332+ then true
333+ else ((price - ((price * percentPriceOffset) / 100)) >= newPrice))
334+ then WriteSet([DataEntry("is_blocked", true), DataEntry((("black_swarm_price" + "_") + toString(height)), newPrice)])
335+ else {
336+ let newPriceIndex = (priceIndex + 1)
337+ WriteSet([DataEntry("price", newPrice), DataEntry(("price_" + toString(height)), newPrice), DataEntry("price_index", newPriceIndex), DataEntry(("price_index_" + toString(newPriceIndex)), height), DataEntry(("deficit_" + toString(height)), deficit), DataEntry(("neutrinoSupply_" + toString(height)), neutrinoSupply), DataEntry(("deficit_percent_" + toString(height)), if ((neutrinoSupply != 0))
338+ then ((deficit * 100) / neutrinoSupply)
339+ else 0)])
340+ }
341+ }
342+ }
343+ }
342344
343345
344346 @Verifier(tx)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 3 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-func getNumberByKey (key) = match getInteger(this, key) {
5- case a: Int =>
6- a
7- case _ =>
8- 0
9-}
4+func convertWavesToNeutrino (amount,price) = fraction(fraction(amount, price, 100), 1000000, 100000000)
105
116
127 func getStringByKey (key) = match getString(this, key) {
138 case a: String =>
149 a
1510 case _ =>
1611 ""
1712 }
1813
1914
20-func getBoolByKey (key) = match getBoolean(this, key) {
21- case a: Boolean =>
15+func getNumberByAddressAndKey (address,key) = match getInteger(addressFromStringValue(address), key) {
16+ case a: Int =>
2217 a
2318 case _ =>
24- false
19+ 0
2520 }
2621
2722
28-func getNumberByAddressAndKey (address,key) = match getInteger(address, key) {
23+func getOracleProvideHeight (ownerPub,height) = match getInteger(addressFromPublicKey(ownerPub), ("price_" + toString(height))) {
2924 case a: Int =>
3025 a
3126 case _ =>
3227 0
3328 }
3429
3530
3631 func getStringByAddressAndKey (address,key) = match getString(address, key) {
3732 case a: String =>
3833 a
3934 case _ =>
4035 ""
4136 }
4237
4338
4439 func dropElementInJsonArray (array,element) = {
4540 let splitedArray = split(array, element)
4641 if ((take(splitedArray[1], 1) == ","))
4742 then (splitedArray[0] + drop(splitedArray[1], 1))
4843 else (dropRight(splitedArray[0], 1) + splitedArray[1])
4944 }
5045
5146
5247 func convertJsonArrayToList (jsonArray) = split(jsonArray, ",")
5348
5449
55-let BLOCK = "block"
50+let price = match getInteger(this, "price") {
51+ case a: Int =>
52+ a
53+ case _ =>
54+ 0
55+}
5656
57-let UNBLOCK = "unblock"
57+let priceIndex = match getInteger(this, "price_index") {
58+ case a: Int =>
59+ a
60+ case _ =>
61+ 0
62+}
5863
59-let UPDATE = "update"
64+let isBlocked = match getBoolean(this, "is_blocked") {
65+ case a: Boolean =>
66+ a
67+ case _ =>
68+ false
69+}
6070
61-let OraclesKey = "oracles"
71+let percentPriceOffset = 7
6272
63-let PriceOffsetKey = "price_offset"
73+let pubKeyOracles = getStringByKey("oracles")
6474
65-let AutoEmergencyOracleAddress = "3P7ihFVxBNbHK237TNdPxT1xHEu8pHexXTr"
75+let pubKeyOraclesList = convertJsonArrayToList(pubKeyOracles)
6676
67-let PriceKey = "price"
77+let bftCoefficientOracle = 4
6878
69-let IsBlockedKey = "is_blocked"
79+let neutrinoAddress = addressFromPublicKey(fromBase58String("BRnVwSVctnV8pge5vRpsJdWnkjWEJspFb6QvrmZvu3Ht"))
7080
71-let IsBlockedCallerKey = "is_blocked_caller"
81+let liquidationAddress = addressFromPublicKey(fromBase58String("H8Gooqgk4486MkqEQVwACpgoyEjt5Px4eskysnEDZ1nR"))
7282
73-let IsBlockedReasonKey = "is_blocked_reason"
83+let neutrinoAsset = fromBase58String("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
7484
75-let PriceIndexKey = "price_index"
85+let neutrinoLockedBalance = match getInteger(neutrinoAddress, "balance_lock_neutrino") {
86+ case a: Int =>
87+ a
88+ case _ =>
89+ 0
90+}
7691
77-func getBlackSwarmPriceKey (block) = (("black_swarm_price" + "_") + toString(block))
92+let wavesLockedBalance = match getInteger(neutrinoAddress, "balance_lock_waves") {
93+ case a: Int =>
94+ a
95+ case _ =>
96+ 0
97+}
7898
99+let reserve = (wavesBalance(neutrinoAddress) - wavesLockedBalance)
79100
80-func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block))
101+let neutrinoSupply = (((neutrinoLockedBalance + extract(assetInfo(neutrinoAsset)).quantity) - assetBalance(neutrinoAddress, neutrinoAsset)) - assetBalance(liquidationAddress, neutrinoAsset))
81102
82-
83-func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index))
84-
85-
86-func getOracleProvidePriceKey (height) = ("price_" + toString(height))
87-
88-
89-let price = getNumberByKey(PriceKey)
90-
91-let priceIndex = getNumberByKey(PriceIndexKey)
92-
93-let isBlocked = getBoolByKey(IsBlockedKey)
94-
95-let isBlockedCaller = getBoolByKey(IsBlockedCallerKey)
96-
97-let bftCoefficientOracle = 3
98-
99-let percentPriceOffset = getNumberByKey(PriceOffsetKey)
100-
101-let oracles = getStringByKey(OraclesKey)
102-
103-let oraclesList = convertJsonArrayToList(oracles)
104-
105-func getOracleProvideHeight (owner,height) = getNumberByAddressAndKey(addressFromStringValue(owner), getOracleProvidePriceKey(height))
106-
107-
108-func getPriceHistory (height) = getNumberByKey(getPriceHistoryKey(height))
109-
110-
111-func isOracle (address) = isDefined(indexOf(oracles, address))
112-
113-
114-func filterAdminsVoteByAction (result,address,action) = address :: result
115-
116-
117-func filterAdminsVoteByBlockAction (result,address) = filterAdminsVoteByAction(result, address, BLOCK)
118-
119-
120-func filterAdminsVoteByUnblockAction (result,address) = filterAdminsVoteByAction(result, address, UNBLOCK)
121-
122-
123-func filterAdminsVoteByUpdateAction (result,address) = filterAdminsVoteByAction(result, address, UPDATE)
124-
103+let deficit = (neutrinoSupply - convertWavesToNeutrino(reserve, price))
125104
126105 func findPricesInRange (prices) = {
127106 let minPercentBound = 90
128107 let maxPercentBound = 110
129108 let p0 = prices[0]
130109 let check0 = if ((0 >= prices[0]))
131110 then [0]
132111 else {
133112 let p01 = ((prices[1] * 100) / p0)
134113 let p02 = ((prices[2] * 100) / p0)
135114 let p03 = ((prices[3] * 100) / p0)
136115 let p04 = ((prices[4] * 100) / p0)
137116 let array1 = if (if ((maxPercentBound > p01))
138117 then (p01 > minPercentBound)
139118 else false)
140119 then [1, 0]
141120 else [0]
142121 let array2 = if (if ((maxPercentBound > p02))
143122 then (p02 > minPercentBound)
144123 else false)
145124 then 2 :: array1
146125 else array1
147126 let array3 = if (if ((maxPercentBound > p03))
148127 then (p03 > minPercentBound)
149128 else false)
150129 then 3 :: array2
151130 else array2
152131 if (if ((maxPercentBound > p04))
153132 then (p04 > minPercentBound)
154133 else false)
155134 then 4 :: array3
156135 else array3
157136 }
158137 let check1 = if ((size(check0) >= 3))
159138 then check0
160139 else {
161140 let p1 = prices[1]
162141 if ((0 >= p1))
163142 then [1]
164143 else {
165144 let p10 = ((prices[0] * 100) / p1)
166145 let p12 = ((prices[2] * 100) / p1)
167146 let p13 = ((prices[3] * 100) / p1)
168147 let p14 = ((prices[4] * 100) / p1)
169148 let array1 = if (if ((maxPercentBound > p10))
170149 then (p10 > minPercentBound)
171150 else false)
172151 then [0, 1]
173152 else [1]
174153 let array2 = if (if ((maxPercentBound > p12))
175154 then (p12 > minPercentBound)
176155 else false)
177156 then 2 :: array1
178157 else array1
179158 let array3 = if (if ((maxPercentBound > p13))
180159 then (p13 > minPercentBound)
181160 else false)
182161 then 3 :: array2
183162 else array2
184163 if (if ((maxPercentBound > p14))
185164 then (p14 > minPercentBound)
186165 else false)
187166 then 4 :: array3
188167 else array3
189168 }
190169 }
191170 let check2 = if ((size(check1) >= 3))
192171 then check1
193172 else {
194173 let p2 = prices[2]
195174 if ((0 >= p2))
196175 then [2]
197176 else {
198177 let p20 = ((prices[0] * 100) / p2)
199178 let p21 = ((prices[1] * 100) / p2)
200179 let p23 = ((prices[3] * 100) / p2)
201180 let p24 = ((prices[4] * 100) / p2)
202181 let array1 = if (if ((maxPercentBound > p20))
203182 then (p20 > minPercentBound)
204183 else false)
205184 then [0, 2]
206185 else [2]
207186 let array2 = if (if ((maxPercentBound > p21))
208187 then (p21 > minPercentBound)
209188 else false)
210189 then 1 :: array1
211190 else array1
212191 let array3 = if (if ((maxPercentBound > p23))
213192 then (p23 > minPercentBound)
214193 else false)
215194 then 3 :: array2
216195 else array2
217196 if (if ((maxPercentBound > p24))
218197 then (p24 > minPercentBound)
219198 else false)
220199 then 4 :: array3
221200 else array3
222201 }
223202 }
224203 let check3 = if ((size(check2) >= 3))
225204 then check2
226205 else {
227206 let p3 = prices[3]
228207 if ((0 >= p3))
229208 then [3]
230209 else {
231210 let p30 = ((prices[0] * 100) / p3)
232211 let p31 = ((prices[1] * 100) / p3)
233212 let p32 = ((prices[2] * 100) / p3)
234213 let p34 = ((prices[4] * 100) / p3)
235214 let array1 = if (if ((maxPercentBound > p30))
236215 then (p30 > minPercentBound)
237216 else false)
238217 then [0, 3]
239218 else [3]
240219 let array2 = if (if ((maxPercentBound > p31))
241220 then (p31 > minPercentBound)
242221 else false)
243222 then 1 :: array1
244223 else array1
245224 let array3 = if (if ((maxPercentBound > p32))
246225 then (p32 > minPercentBound)
247226 else false)
248227 then 2 :: array2
249228 else array2
250229 if (if ((maxPercentBound > p34))
251230 then (p34 > minPercentBound)
252231 else false)
253232 then 4 :: array3
254233 else array3
255234 }
256235 }
257236 if ((size(check3) >= 3))
258237 then check3
259238 else {
260239 let p4 = prices[4]
261240 if ((0 >= p4))
262241 then [4]
263242 else {
264243 let p40 = ((prices[0] * 100) / p4)
265244 let p41 = ((prices[1] * 100) / p4)
266245 let p42 = ((prices[2] * 100) / p4)
267246 let p43 = ((prices[3] * 100) / p4)
268247 let array1 = if (if ((maxPercentBound > p40))
269248 then (p40 > minPercentBound)
270249 else false)
271250 then [0, 4]
272251 else [4]
273252 let array2 = if (if ((maxPercentBound > p41))
274253 then (p41 > minPercentBound)
275254 else false)
276255 then 1 :: array1
277256 else array1
278257 let array3 = if (if ((maxPercentBound > p42))
279258 then (p42 > minPercentBound)
280259 else false)
281260 then 2 :: array2
282261 else array2
283262 if (if ((maxPercentBound > p43))
284263 then (p43 > minPercentBound)
285264 else false)
286265 then 3 :: array3
287266 else array3
288267 }
289268 }
290269 }
291270
292271
272+func formattingPriceMsg (price,height) = toBytes((((("WAVESNEUTRINOPREFIX" + "_") + toString(height)) + "_") + toString(price)))
273+
274+
293275 @Callable(i)
294276 func callEmergencyShutdown (reason) = {
277+ let AutoEmergencyOracleAddress = "3P7ihFVxBNbHK237TNdPxT1xHEu8pHexXTr"
295278 let callerAddress = toString(i.caller)
296279 if ((AutoEmergencyOracleAddress != callerAddress))
297280 then throw("caller must be one an emergency oracle")
298- else WriteSet([DataEntry(IsBlockedKey, true), DataEntry(IsBlockedCallerKey, callerAddress), DataEntry(IsBlockedReasonKey, reason)])
281+ else WriteSet([DataEntry("is_blocked", true), DataEntry("is_blocked_caller", callerAddress), DataEntry("is_blocked_reason", reason)])
299282 }
300283
301284
302285
303286 @Callable(i)
304-func finalizeCurrentPrice () = if (isBlocked)
287+func finalizeCurrentPrice (price1,sign1,price2,sign2,price3,sign3,price4,sign4,price5,sign5) = if (isBlocked)
305288 then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
306- else if ((getPriceHistory(height) != 0))
289+ else if (( match getInteger(this, ("price_" + toString(height))) {
290+ case a: Int =>
291+ a
292+ case _ =>
293+ 0
294+ } != 0))
307295 then throw("wait next block")
308- else {
309- let prices = [getOracleProvideHeight(oraclesList[0], height), getOracleProvideHeight(oraclesList[1], height), getOracleProvideHeight(oraclesList[2], height), getOracleProvideHeight(oraclesList[3], height), getOracleProvideHeight(oraclesList[4], height)]
310- let pricesInRange = findPricesInRange(prices)
311- let priceProvidingCount = size(pricesInRange)
312- if ((3 > priceProvidingCount))
313- then throw(((((((((((((((((((((("Could not finalize price because of big variation: height=" + toString(height)) + "
314-") + oraclesList[0]) + "=") + toString(prices[0])) + "
315-") + oraclesList[1]) + "=") + toString(prices[1])) + "
316-") + oraclesList[2]) + "=") + toString(prices[2])) + "
317-") + oraclesList[3]) + "=") + toString(prices[3])) + "
318-") + oraclesList[4]) + "=") + toString(prices[4])))
319- else {
320- let sum1 = ((prices[pricesInRange[0]] + prices[pricesInRange[1]]) + prices[pricesInRange[2]])
321- let sum2 = if ((priceProvidingCount >= 4))
322- then (sum1 + prices[pricesInRange[3]])
323- else sum1
324- let priceSum = if ((priceProvidingCount >= 5))
325- then (sum2 + prices[pricesInRange[4]])
326- else sum2
327- if ((priceProvidingCount >= 6))
328- then throw("Invalid pricesInRange creation")
329- else {
330- let newPrice = (priceSum / priceProvidingCount)
331- if (if ((newPrice >= (price + ((price * percentPriceOffset) / 100))))
332- then true
333- else ((price - ((price * percentPriceOffset) / 100)) >= newPrice))
334- then WriteSet([DataEntry(IsBlockedKey, true), DataEntry(getBlackSwarmPriceKey(height), newPrice)])
335- else {
336- let newPriceIndex = (priceIndex + 1)
337- WriteSet([DataEntry(PriceKey, newPrice), DataEntry(getPriceHistoryKey(height), newPrice), DataEntry(PriceIndexKey, newPriceIndex), DataEntry(getHeightPriceByIndexKey(newPriceIndex), height)])
338- }
339- }
340- }
341- }
296+ else if ((pubKeyOraclesList[(height % 5)] != toBase58String(i.callerPublicKey)))
297+ then throw(((("Out of turn finalization: " + toString(height)) + " block should be finalize by ") + pubKeyOraclesList[(height % 5)]))
298+ else {
299+ let prices = [if (sigVerify(formattingPriceMsg(price1, height), sign1, fromBase58String(pubKeyOraclesList[0])))
300+ then price1
301+ else 0, if (sigVerify(formattingPriceMsg(price2, height), sign2, fromBase58String(pubKeyOraclesList[1])))
302+ then price2
303+ else 0, if (sigVerify(formattingPriceMsg(price3, height), sign3, fromBase58String(pubKeyOraclesList[2])))
304+ then price3
305+ else 0, if (sigVerify(formattingPriceMsg(price4, height), sign4, fromBase58String(pubKeyOraclesList[3])))
306+ then price4
307+ else 0, if (sigVerify(formattingPriceMsg(price5, height), sign5, fromBase58String(pubKeyOraclesList[4])))
308+ then price5
309+ else 0]
310+ let pricesInRange = findPricesInRange(prices)
311+ let priceProvidingCount = size(pricesInRange)
312+ if ((3 > priceProvidingCount))
313+ then throw(((((((((((((((((((((("Could not finalize price because of big variation: height=" + toString(height)) + "
314+") + pubKeyOraclesList[0]) + "=") + toString(prices[0])) + "
315+") + pubKeyOraclesList[1]) + "=") + toString(prices[1])) + "
316+") + pubKeyOraclesList[2]) + "=") + toString(prices[2])) + "
317+") + pubKeyOraclesList[3]) + "=") + toString(prices[3])) + "
318+") + pubKeyOraclesList[4]) + "=") + toString(prices[4])))
319+ else {
320+ let sum1 = ((prices[pricesInRange[0]] + prices[pricesInRange[1]]) + prices[pricesInRange[2]])
321+ let sum2 = if ((priceProvidingCount >= 4))
322+ then (sum1 + prices[pricesInRange[3]])
323+ else sum1
324+ let priceSum = if ((priceProvidingCount >= 5))
325+ then (sum2 + prices[pricesInRange[4]])
326+ else sum2
327+ if ((priceProvidingCount >= 6))
328+ then throw("Invalid pricesInRange creation")
329+ else {
330+ let newPrice = (priceSum / priceProvidingCount)
331+ if (if ((newPrice >= (price + ((price * percentPriceOffset) / 100))))
332+ then true
333+ else ((price - ((price * percentPriceOffset) / 100)) >= newPrice))
334+ then WriteSet([DataEntry("is_blocked", true), DataEntry((("black_swarm_price" + "_") + toString(height)), newPrice)])
335+ else {
336+ let newPriceIndex = (priceIndex + 1)
337+ WriteSet([DataEntry("price", newPrice), DataEntry(("price_" + toString(height)), newPrice), DataEntry("price_index", newPriceIndex), DataEntry(("price_index_" + toString(newPriceIndex)), height), DataEntry(("deficit_" + toString(height)), deficit), DataEntry(("neutrinoSupply_" + toString(height)), neutrinoSupply), DataEntry(("deficit_percent_" + toString(height)), if ((neutrinoSupply != 0))
338+ then ((deficit * 100) / neutrinoSupply)
339+ else 0)])
340+ }
341+ }
342+ }
343+ }
342344
343345
344346 @Verifier(tx)
345347 func verify () = {
346348 let pubKeyAdminsList = ["BLEoguzPVKVTfXxxT3W7Rqf8aUm2ggC9Vemd2MQawM2G", "FWVffYr2ALmHMejZm3WqeLz6Sdym3gLFGtJn4KTwyU5x", "3Wh2LaWcb5gg7K2pPcW3Ep6EAuRBzYkAgrdpt43jTDFa", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
347349 let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
348350 then 1
349351 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
350352 then 1
351353 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2])))
352354 then 1
353355 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[3], fromBase58String(pubKeyAdminsList[3])))
354356 then 2
355357 else 0))
356358 (count >= 3)
357359 }
358360

github/deemru/w8io/6500d08 
84.56 ms