2020.01.23 17:35 [1897557] smart account 3P5Bfd58PPfNvBM2Hy8QfbcDqMeNtzg7KfP > SELF 0.00000000 Waves

{ "type": 13, "id": "4rKsJoCdotWQCih4tqjSoRhSF9qEDjqmk3kd7mU9mAN3", "fee": 1400000, "feeAssetId": null, "timestamp": 1579787001516, "version": 1, "sender": "3P5Bfd58PPfNvBM2Hy8QfbcDqMeNtzg7KfP", "senderPublicKey": "GqXuX2WHNr3WUqTaeH2YCySFY45NAJoE9RmY9bEWkzh", "proofs": [ "3URyhoFTduMPk3EtXBxyeg9hnQ4ghXYYywBVQKDLRXbzCyVMJByJyPftH4XsjAHF3Q4NdWGj17YcgCEQ87zDZywD", "3PaauQsivWWuo88q2ZPKT6HPJ9u4yHUMEDgoBXfaTRDV3t75fXicbsH5nnGFgPvevJx5cUAqYntbUWB4aPzYuCbT", "64fuSYX8F6G8D1Z4KbvwHpKTxJgt74FysQyiTZyk8kyT14G7BZ1LzMk6DzLrV4Pfp7WaCZqkviwcpzydcXAhyQJB" ], "script": "base64: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YmVyQnlLZXkAAAABBQAAAA1QcmljZUluZGV4S2V5AAAAAAlpc0Jsb2NrZWQJAQAAAAxnZXRCb29sQnlLZXkAAAABBQAAAAxJc0Jsb2NrZWRLZXkAAAAAFGJmdENvZWZmaWNpZW50T3JhY2xlAAAAAAAAAAADAAAAABJwZXJjZW50UHJpY2VPZmZzZXQJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEFAAAADlByaWNlT2Zmc2V0S2V5AAAAAAdvcmFjbGVzCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAAApPcmFjbGVzS2V5AAAAAAtvcmFjbGVzTGlzdAkBAAAAFmNvbnZlcnRKc29uQXJyYXlUb0xpc3QAAAABBQAAAAdvcmFjbGVzAQAAABZnZXRPcmFjbGVQcm92aWRlSGVpZ2h0AAAAAgAAAAVvd25lcgAAAAZoZWlnaHQJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACCQEAAAAcQGV4dHJVc2VyKGFkZHJlc3NGcm9tU3RyaW5nKQAAAAEFAAAABW93bmVyCQEAAAAYZ2V0T3JhY2xlUHJvdmlkZVByaWNlS2V5AAAAAQUAAAAGaGVpZ2h0AQAAAA9nZXRQcmljZUhpc3RvcnkAAAABAAAABmhlaWdodAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAEmdldFByaWNlSGlzdG9yeUtleQAAAAEFAAAABmhlaWdodAEAAAAIaXNPcmFjbGUAAAABAAAAB2FkZHJlc3MJAQAAAAlpc0RlZmluZWQAAAABCQAEswAAAAIFAAAAB29yYWNsZXMFAAAAB2FkZHJlc3MBAAAAGGZpbHRlckFkbWluc1ZvdGVCeUFjdGlvbgAAAAMAAAAGcmVzdWx0AAAAB2FkZHJlc3MAAAAGYWN0aW9uCQAETAAAAAIFAAAAB2FkZHJlc3MFAAAABnJlc3VsdAEAAAAdZmlsdGVyQWRtaW5zVm90ZUJ5QmxvY2tBY3Rpb24AAAACAAAABnJlc3VsdAAAAAdhZGRyZXNzCQEAAAAYZmlsdGVyQWRtaW5zVm90ZUJ5QWN0aW9uAAAAAwUAAAAGcmVzdWx0BQAAAAdhZGRyZXNzBQAAAAVCTE9DSwEAAAAfZmlsdGVyQWRtaW5zVm90ZUJ5VW5ibG9ja0Fj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", "chainId": 87, "height": 1897557, "spentComplexity": 0 } View: original | compacted Prev: 7DRyRYFS9mcnbQDQnhZGwY4xaTc35BXfYtcsGJv59VAz Next: 5AtmaD7Vre1AMSxEh6JvXbKZSv8QeSFoK39n8gK1iXD4 Diff:
OldNewDifferences
6060
6161 let OraclesKey = "oracles"
6262
63-let AdminsKey = "admins"
64-
65-let VoteIntervalKey = "vote_interval"
66-
67-let CoefficientOracleKey = "coefficient_oracle"
68-
69-let CoefficientAdminKey = "coefficient_admin"
70-
71-let ScriptUpdateIntervalKey = "script_update_interval"
72-
7363 let PriceOffsetKey = "price_offset"
7464
7565 let PriceKey = "price"
7666
7767 let IsBlockedKey = "is_blocked"
7868
79-let BlockExpireVoteKey = "vote_expire_block"
80-
81-let ScriptUpdateBlockKey = "script_update_block"
82-
8369 let PriceIndexKey = "price_index"
84-
85-func getAdminVoteKey (owner) = ("admin_vote_" + owner)
86-
87-
88-func getAdminVoteActionKey (owner) = ((getAdminVoteKey(owner) + "_") + "action")
89-
9070
9171 func getBlackSwarmPriceKey (block) = (("black_swarm_price" + "_") + toString(block))
9272
10484
10585 let priceIndex = getNumberByKey(PriceIndexKey)
10686
107-let blockExpireVote = getNumberByKey(BlockExpireVoteKey)
108-
109-let scriptUpdateBlock = getNumberByKey(ScriptUpdateBlockKey)
110-
111-let scriptUpdateInterval = getNumberByKey(ScriptUpdateIntervalKey)
112-
11387 let isBlocked = getBoolByKey(IsBlockedKey)
11488
115-let bftCoefficientOracle = getNumberByKey(CoefficientOracleKey)
116-
117-let bftCoefficientAdmin = getNumberByKey(CoefficientAdminKey)
89+let bftCoefficientOracle = 3
11890
11991 let percentPriceOffset = getNumberByKey(PriceOffsetKey)
120-
121-let voteInterval = getNumberByKey(VoteIntervalKey)
12292
12393 let oracles = getStringByKey(OraclesKey)
12494
12595 let oraclesList = convertJsonArrayToList(oracles)
126-
127-func getAdminVoteAction (owner) = getStringByKey(getAdminVoteActionKey(owner))
128-
12996
13097 func getOracleProvideHeight (owner,height) = getNumberByAddressAndKey(addressFromStringValue(owner), getOracleProvidePriceKey(height))
13198
148115 func filterAdminsVoteByUpdateAction (result,address) = filterAdminsVoteByAction(result, address, UPDATE)
149116
150117
118+func findPricesInRange (prices) = {
119+ let minPercentBound = 90
120+ let maxPercentBound = 110
121+ let p0 = prices[0]
122+ let check0 = if ((0 >= prices[0]))
123+ then [0]
124+ else {
125+ let p01 = ((prices[1] * 100) / p0)
126+ let p02 = ((prices[2] * 100) / p0)
127+ let p03 = ((prices[3] * 100) / p0)
128+ let p04 = ((prices[4] * 100) / p0)
129+ let array1 = if (if ((maxPercentBound > p01))
130+ then (p01 > minPercentBound)
131+ else false)
132+ then [1, 0]
133+ else [0]
134+ let array2 = if (if ((maxPercentBound > p02))
135+ then (p02 > minPercentBound)
136+ else false)
137+ then 2 :: array1
138+ else array1
139+ let array3 = if (if ((maxPercentBound > p03))
140+ then (p03 > minPercentBound)
141+ else false)
142+ then 3 :: array2
143+ else array2
144+ if (if ((maxPercentBound > p04))
145+ then (p04 > minPercentBound)
146+ else false)
147+ then 4 :: array3
148+ else array3
149+ }
150+ let check1 = if ((size(check0) >= 3))
151+ then check0
152+ else {
153+ let p1 = prices[1]
154+ if ((0 >= p1))
155+ then [1]
156+ else {
157+ let p10 = ((prices[0] * 100) / p1)
158+ let p12 = ((prices[2] * 100) / p1)
159+ let p13 = ((prices[3] * 100) / p1)
160+ let p14 = ((prices[4] * 100) / p1)
161+ let array1 = if (if ((maxPercentBound > p10))
162+ then (p10 > minPercentBound)
163+ else false)
164+ then [0, 1]
165+ else [1]
166+ let array2 = if (if ((maxPercentBound > p12))
167+ then (p12 > minPercentBound)
168+ else false)
169+ then 2 :: array1
170+ else array1
171+ let array3 = if (if ((maxPercentBound > p13))
172+ then (p13 > minPercentBound)
173+ else false)
174+ then 3 :: array2
175+ else array2
176+ if (if ((maxPercentBound > p14))
177+ then (p14 > minPercentBound)
178+ else false)
179+ then 4 :: array3
180+ else array3
181+ }
182+ }
183+ let check2 = if ((size(check1) >= 3))
184+ then check1
185+ else {
186+ let p2 = prices[2]
187+ if ((0 >= p2))
188+ then [2]
189+ else {
190+ let p20 = ((prices[0] * 100) / p2)
191+ let p21 = ((prices[1] * 100) / p2)
192+ let p23 = ((prices[3] * 100) / p2)
193+ let p24 = ((prices[4] * 100) / p2)
194+ let array1 = if (if ((maxPercentBound > p20))
195+ then (p20 > minPercentBound)
196+ else false)
197+ then [0, 2]
198+ else [2]
199+ let array2 = if (if ((maxPercentBound > p21))
200+ then (p21 > minPercentBound)
201+ else false)
202+ then 1 :: array1
203+ else array1
204+ let array3 = if (if ((maxPercentBound > p23))
205+ then (p23 > minPercentBound)
206+ else false)
207+ then 3 :: array2
208+ else array2
209+ if (if ((maxPercentBound > p24))
210+ then (p24 > minPercentBound)
211+ else false)
212+ then 4 :: array3
213+ else array3
214+ }
215+ }
216+ let check3 = if ((size(check2) >= 3))
217+ then check2
218+ else {
219+ let p3 = prices[3]
220+ if ((0 >= p3))
221+ then [3]
222+ else {
223+ let p30 = ((prices[0] * 100) / p3)
224+ let p31 = ((prices[1] * 100) / p3)
225+ let p32 = ((prices[2] * 100) / p3)
226+ let p34 = ((prices[4] * 100) / p3)
227+ let array1 = if (if ((maxPercentBound > p30))
228+ then (p30 > minPercentBound)
229+ else false)
230+ then [0, 3]
231+ else [3]
232+ let array2 = if (if ((maxPercentBound > p31))
233+ then (p31 > minPercentBound)
234+ else false)
235+ then 1 :: array1
236+ else array1
237+ let array3 = if (if ((maxPercentBound > p32))
238+ then (p32 > minPercentBound)
239+ else false)
240+ then 2 :: array2
241+ else array2
242+ if (if ((maxPercentBound > p34))
243+ then (p34 > minPercentBound)
244+ else false)
245+ then 4 :: array3
246+ else array3
247+ }
248+ }
249+ if ((size(check3) >= 3))
250+ then check3
251+ else {
252+ let p4 = prices[4]
253+ if ((0 >= p4))
254+ then [4]
255+ else {
256+ let p40 = ((prices[0] * 100) / p4)
257+ let p41 = ((prices[1] * 100) / p4)
258+ let p42 = ((prices[2] * 100) / p4)
259+ let p43 = ((prices[3] * 100) / p4)
260+ let array1 = if (if ((maxPercentBound > p40))
261+ then (p40 > minPercentBound)
262+ else false)
263+ then [0, 4]
264+ else [4]
265+ let array2 = if (if ((maxPercentBound > p41))
266+ then (p41 > minPercentBound)
267+ else false)
268+ then 1 :: array1
269+ else array1
270+ let array3 = if (if ((maxPercentBound > p42))
271+ then (p42 > minPercentBound)
272+ else false)
273+ then 2 :: array2
274+ else array2
275+ if (if ((maxPercentBound > p43))
276+ then (p43 > minPercentBound)
277+ else false)
278+ then 3 :: array3
279+ else array3
280+ }
281+ }
282+ }
283+
284+
151285 @Callable(i)
152286 func finalizeCurrentPrice () = {
153287 let prices = [getOracleProvideHeight(oraclesList[0], height), getOracleProvideHeight(oraclesList[1], height), getOracleProvideHeight(oraclesList[2], height), getOracleProvideHeight(oraclesList[3], height), getOracleProvideHeight(oraclesList[4], height)]
154- let priceProvidingCount = (((((if ((prices[0] != 0))
155- then 1
156- else 0) + (if ((prices[1] != 0))
157- then 1
158- else 0)) + (if ((prices[2] != 0))
159- then 1
160- else 0)) + (if ((prices[3] != 0))
161- then 1
162- else 0)) + (if ((prices[4] != 0))
163- then 1
164- else 0))
165- let priceSum = ((((prices[0] + prices[1]) + prices[2]) + prices[3]) + prices[4])
166- let newPrice = (priceSum / priceProvidingCount)
167- if (isBlocked)
168- then throw("contract is blocked")
169- else if ((getPriceHistory(height) != 0))
170- then throw("wait next block")
171- else if ((bftCoefficientOracle > priceProvidingCount))
172- then throw((((toString(bftCoefficientOracle) + "/5 oracles need to set a price (") + toString(priceProvidingCount)) + ")"))
173- else if (if ((newPrice >= (price + ((price * percentPriceOffset) / 100))))
174- then true
175- else ((price - ((price * percentPriceOffset) / 100)) >= newPrice))
176- then WriteSet([DataEntry(IsBlockedKey, true), DataEntry(getBlackSwarmPriceKey(height), newPrice)])
177- else {
178- let newPriceIndex = (priceIndex + 1)
179- WriteSet([DataEntry(PriceKey, newPrice), DataEntry(getPriceHistoryKey(height), newPrice), DataEntry(PriceIndexKey, newPriceIndex), DataEntry(getHeightPriceByIndexKey(newPriceIndex), height)])
180- }
288+ let pricesInRange = findPricesInRange(prices)
289+ let priceProvidingCount = size(pricesInRange)
290+ if ((3 > priceProvidingCount))
291+ then throw("Could not finalize price because of big variation")
292+ else {
293+ let sum1 = ((prices[pricesInRange[0]] + prices[pricesInRange[1]]) + prices[pricesInRange[2]])
294+ let sum2 = if ((priceProvidingCount >= 4))
295+ then (sum1 + prices[pricesInRange[3]])
296+ else sum1
297+ let priceSum = if ((priceProvidingCount >= 5))
298+ then (sum2 + prices[pricesInRange[4]])
299+ else sum2
300+ if ((priceProvidingCount >= 6))
301+ then throw("Invalid pricesInRange creation")
302+ else {
303+ let newPrice = (priceSum / priceProvidingCount)
304+ if (isBlocked)
305+ then throw("contract is blocked")
306+ else if ((getPriceHistory(height) != 0))
307+ then throw("wait next block")
308+ else if ((bftCoefficientOracle > priceProvidingCount))
309+ then throw((((toString(bftCoefficientOracle) + "/5 oracles need to set a price (") + toString(priceProvidingCount)) + ")"))
310+ else if (if ((newPrice >= (price + ((price * percentPriceOffset) / 100))))
311+ then true
312+ else ((price - ((price * percentPriceOffset) / 100)) >= newPrice))
313+ then WriteSet([DataEntry(IsBlockedKey, true), DataEntry(getBlackSwarmPriceKey(height), newPrice)])
314+ else {
315+ let newPriceIndex = (priceIndex + 1)
316+ WriteSet([DataEntry(PriceKey, newPrice), DataEntry(getPriceHistoryKey(height), newPrice), DataEntry(PriceIndexKey, newPriceIndex), DataEntry(getHeightPriceByIndexKey(newPriceIndex), height)])
317+ }
318+ }
319+ }
181320 }
182321
183322
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 3 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func getNumberByKey (key) = match getInteger(this, key) {
55 case a: Int =>
66 a
77 case _ =>
88 0
99 }
1010
1111
1212 func getStringByKey (key) = match getString(this, key) {
1313 case a: String =>
1414 a
1515 case _ =>
1616 ""
1717 }
1818
1919
2020 func getBoolByKey (key) = match getBoolean(this, key) {
2121 case a: Boolean =>
2222 a
2323 case _ =>
2424 false
2525 }
2626
2727
2828 func getNumberByAddressAndKey (address,key) = match getInteger(address, key) {
2929 case a: Int =>
3030 a
3131 case _ =>
3232 0
3333 }
3434
3535
3636 func getStringByAddressAndKey (address,key) = match getString(address, key) {
3737 case a: String =>
3838 a
3939 case _ =>
4040 ""
4141 }
4242
4343
4444 func dropElementInJsonArray (array,element) = {
4545 let splitedArray = split(array, element)
4646 if ((take(splitedArray[1], 1) == ","))
4747 then (splitedArray[0] + drop(splitedArray[1], 1))
4848 else (dropRight(splitedArray[0], 1) + splitedArray[1])
4949 }
5050
5151
5252 func convertJsonArrayToList (jsonArray) = split(jsonArray, ",")
5353
5454
5555 let BLOCK = "block"
5656
5757 let UNBLOCK = "unblock"
5858
5959 let UPDATE = "update"
6060
6161 let OraclesKey = "oracles"
6262
63-let AdminsKey = "admins"
64-
65-let VoteIntervalKey = "vote_interval"
66-
67-let CoefficientOracleKey = "coefficient_oracle"
68-
69-let CoefficientAdminKey = "coefficient_admin"
70-
71-let ScriptUpdateIntervalKey = "script_update_interval"
72-
7363 let PriceOffsetKey = "price_offset"
7464
7565 let PriceKey = "price"
7666
7767 let IsBlockedKey = "is_blocked"
7868
79-let BlockExpireVoteKey = "vote_expire_block"
80-
81-let ScriptUpdateBlockKey = "script_update_block"
82-
8369 let PriceIndexKey = "price_index"
84-
85-func getAdminVoteKey (owner) = ("admin_vote_" + owner)
86-
87-
88-func getAdminVoteActionKey (owner) = ((getAdminVoteKey(owner) + "_") + "action")
89-
9070
9171 func getBlackSwarmPriceKey (block) = (("black_swarm_price" + "_") + toString(block))
9272
9373
9474 func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block))
9575
9676
9777 func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index))
9878
9979
10080 func getOracleProvidePriceKey (height) = ("price_" + toString(height))
10181
10282
10383 let price = getNumberByKey(PriceKey)
10484
10585 let priceIndex = getNumberByKey(PriceIndexKey)
10686
107-let blockExpireVote = getNumberByKey(BlockExpireVoteKey)
108-
109-let scriptUpdateBlock = getNumberByKey(ScriptUpdateBlockKey)
110-
111-let scriptUpdateInterval = getNumberByKey(ScriptUpdateIntervalKey)
112-
11387 let isBlocked = getBoolByKey(IsBlockedKey)
11488
115-let bftCoefficientOracle = getNumberByKey(CoefficientOracleKey)
116-
117-let bftCoefficientAdmin = getNumberByKey(CoefficientAdminKey)
89+let bftCoefficientOracle = 3
11890
11991 let percentPriceOffset = getNumberByKey(PriceOffsetKey)
120-
121-let voteInterval = getNumberByKey(VoteIntervalKey)
12292
12393 let oracles = getStringByKey(OraclesKey)
12494
12595 let oraclesList = convertJsonArrayToList(oracles)
126-
127-func getAdminVoteAction (owner) = getStringByKey(getAdminVoteActionKey(owner))
128-
12996
13097 func getOracleProvideHeight (owner,height) = getNumberByAddressAndKey(addressFromStringValue(owner), getOracleProvidePriceKey(height))
13198
13299
133100 func getPriceHistory (height) = getNumberByKey(getPriceHistoryKey(height))
134101
135102
136103 func isOracle (address) = isDefined(indexOf(oracles, address))
137104
138105
139106 func filterAdminsVoteByAction (result,address,action) = address :: result
140107
141108
142109 func filterAdminsVoteByBlockAction (result,address) = filterAdminsVoteByAction(result, address, BLOCK)
143110
144111
145112 func filterAdminsVoteByUnblockAction (result,address) = filterAdminsVoteByAction(result, address, UNBLOCK)
146113
147114
148115 func filterAdminsVoteByUpdateAction (result,address) = filterAdminsVoteByAction(result, address, UPDATE)
149116
150117
118+func findPricesInRange (prices) = {
119+ let minPercentBound = 90
120+ let maxPercentBound = 110
121+ let p0 = prices[0]
122+ let check0 = if ((0 >= prices[0]))
123+ then [0]
124+ else {
125+ let p01 = ((prices[1] * 100) / p0)
126+ let p02 = ((prices[2] * 100) / p0)
127+ let p03 = ((prices[3] * 100) / p0)
128+ let p04 = ((prices[4] * 100) / p0)
129+ let array1 = if (if ((maxPercentBound > p01))
130+ then (p01 > minPercentBound)
131+ else false)
132+ then [1, 0]
133+ else [0]
134+ let array2 = if (if ((maxPercentBound > p02))
135+ then (p02 > minPercentBound)
136+ else false)
137+ then 2 :: array1
138+ else array1
139+ let array3 = if (if ((maxPercentBound > p03))
140+ then (p03 > minPercentBound)
141+ else false)
142+ then 3 :: array2
143+ else array2
144+ if (if ((maxPercentBound > p04))
145+ then (p04 > minPercentBound)
146+ else false)
147+ then 4 :: array3
148+ else array3
149+ }
150+ let check1 = if ((size(check0) >= 3))
151+ then check0
152+ else {
153+ let p1 = prices[1]
154+ if ((0 >= p1))
155+ then [1]
156+ else {
157+ let p10 = ((prices[0] * 100) / p1)
158+ let p12 = ((prices[2] * 100) / p1)
159+ let p13 = ((prices[3] * 100) / p1)
160+ let p14 = ((prices[4] * 100) / p1)
161+ let array1 = if (if ((maxPercentBound > p10))
162+ then (p10 > minPercentBound)
163+ else false)
164+ then [0, 1]
165+ else [1]
166+ let array2 = if (if ((maxPercentBound > p12))
167+ then (p12 > minPercentBound)
168+ else false)
169+ then 2 :: array1
170+ else array1
171+ let array3 = if (if ((maxPercentBound > p13))
172+ then (p13 > minPercentBound)
173+ else false)
174+ then 3 :: array2
175+ else array2
176+ if (if ((maxPercentBound > p14))
177+ then (p14 > minPercentBound)
178+ else false)
179+ then 4 :: array3
180+ else array3
181+ }
182+ }
183+ let check2 = if ((size(check1) >= 3))
184+ then check1
185+ else {
186+ let p2 = prices[2]
187+ if ((0 >= p2))
188+ then [2]
189+ else {
190+ let p20 = ((prices[0] * 100) / p2)
191+ let p21 = ((prices[1] * 100) / p2)
192+ let p23 = ((prices[3] * 100) / p2)
193+ let p24 = ((prices[4] * 100) / p2)
194+ let array1 = if (if ((maxPercentBound > p20))
195+ then (p20 > minPercentBound)
196+ else false)
197+ then [0, 2]
198+ else [2]
199+ let array2 = if (if ((maxPercentBound > p21))
200+ then (p21 > minPercentBound)
201+ else false)
202+ then 1 :: array1
203+ else array1
204+ let array3 = if (if ((maxPercentBound > p23))
205+ then (p23 > minPercentBound)
206+ else false)
207+ then 3 :: array2
208+ else array2
209+ if (if ((maxPercentBound > p24))
210+ then (p24 > minPercentBound)
211+ else false)
212+ then 4 :: array3
213+ else array3
214+ }
215+ }
216+ let check3 = if ((size(check2) >= 3))
217+ then check2
218+ else {
219+ let p3 = prices[3]
220+ if ((0 >= p3))
221+ then [3]
222+ else {
223+ let p30 = ((prices[0] * 100) / p3)
224+ let p31 = ((prices[1] * 100) / p3)
225+ let p32 = ((prices[2] * 100) / p3)
226+ let p34 = ((prices[4] * 100) / p3)
227+ let array1 = if (if ((maxPercentBound > p30))
228+ then (p30 > minPercentBound)
229+ else false)
230+ then [0, 3]
231+ else [3]
232+ let array2 = if (if ((maxPercentBound > p31))
233+ then (p31 > minPercentBound)
234+ else false)
235+ then 1 :: array1
236+ else array1
237+ let array3 = if (if ((maxPercentBound > p32))
238+ then (p32 > minPercentBound)
239+ else false)
240+ then 2 :: array2
241+ else array2
242+ if (if ((maxPercentBound > p34))
243+ then (p34 > minPercentBound)
244+ else false)
245+ then 4 :: array3
246+ else array3
247+ }
248+ }
249+ if ((size(check3) >= 3))
250+ then check3
251+ else {
252+ let p4 = prices[4]
253+ if ((0 >= p4))
254+ then [4]
255+ else {
256+ let p40 = ((prices[0] * 100) / p4)
257+ let p41 = ((prices[1] * 100) / p4)
258+ let p42 = ((prices[2] * 100) / p4)
259+ let p43 = ((prices[3] * 100) / p4)
260+ let array1 = if (if ((maxPercentBound > p40))
261+ then (p40 > minPercentBound)
262+ else false)
263+ then [0, 4]
264+ else [4]
265+ let array2 = if (if ((maxPercentBound > p41))
266+ then (p41 > minPercentBound)
267+ else false)
268+ then 1 :: array1
269+ else array1
270+ let array3 = if (if ((maxPercentBound > p42))
271+ then (p42 > minPercentBound)
272+ else false)
273+ then 2 :: array2
274+ else array2
275+ if (if ((maxPercentBound > p43))
276+ then (p43 > minPercentBound)
277+ else false)
278+ then 3 :: array3
279+ else array3
280+ }
281+ }
282+ }
283+
284+
151285 @Callable(i)
152286 func finalizeCurrentPrice () = {
153287 let prices = [getOracleProvideHeight(oraclesList[0], height), getOracleProvideHeight(oraclesList[1], height), getOracleProvideHeight(oraclesList[2], height), getOracleProvideHeight(oraclesList[3], height), getOracleProvideHeight(oraclesList[4], height)]
154- let priceProvidingCount = (((((if ((prices[0] != 0))
155- then 1
156- else 0) + (if ((prices[1] != 0))
157- then 1
158- else 0)) + (if ((prices[2] != 0))
159- then 1
160- else 0)) + (if ((prices[3] != 0))
161- then 1
162- else 0)) + (if ((prices[4] != 0))
163- then 1
164- else 0))
165- let priceSum = ((((prices[0] + prices[1]) + prices[2]) + prices[3]) + prices[4])
166- let newPrice = (priceSum / priceProvidingCount)
167- if (isBlocked)
168- then throw("contract is blocked")
169- else if ((getPriceHistory(height) != 0))
170- then throw("wait next block")
171- else if ((bftCoefficientOracle > priceProvidingCount))
172- then throw((((toString(bftCoefficientOracle) + "/5 oracles need to set a price (") + toString(priceProvidingCount)) + ")"))
173- else if (if ((newPrice >= (price + ((price * percentPriceOffset) / 100))))
174- then true
175- else ((price - ((price * percentPriceOffset) / 100)) >= newPrice))
176- then WriteSet([DataEntry(IsBlockedKey, true), DataEntry(getBlackSwarmPriceKey(height), newPrice)])
177- else {
178- let newPriceIndex = (priceIndex + 1)
179- WriteSet([DataEntry(PriceKey, newPrice), DataEntry(getPriceHistoryKey(height), newPrice), DataEntry(PriceIndexKey, newPriceIndex), DataEntry(getHeightPriceByIndexKey(newPriceIndex), height)])
180- }
288+ let pricesInRange = findPricesInRange(prices)
289+ let priceProvidingCount = size(pricesInRange)
290+ if ((3 > priceProvidingCount))
291+ then throw("Could not finalize price because of big variation")
292+ else {
293+ let sum1 = ((prices[pricesInRange[0]] + prices[pricesInRange[1]]) + prices[pricesInRange[2]])
294+ let sum2 = if ((priceProvidingCount >= 4))
295+ then (sum1 + prices[pricesInRange[3]])
296+ else sum1
297+ let priceSum = if ((priceProvidingCount >= 5))
298+ then (sum2 + prices[pricesInRange[4]])
299+ else sum2
300+ if ((priceProvidingCount >= 6))
301+ then throw("Invalid pricesInRange creation")
302+ else {
303+ let newPrice = (priceSum / priceProvidingCount)
304+ if (isBlocked)
305+ then throw("contract is blocked")
306+ else if ((getPriceHistory(height) != 0))
307+ then throw("wait next block")
308+ else if ((bftCoefficientOracle > priceProvidingCount))
309+ then throw((((toString(bftCoefficientOracle) + "/5 oracles need to set a price (") + toString(priceProvidingCount)) + ")"))
310+ else if (if ((newPrice >= (price + ((price * percentPriceOffset) / 100))))
311+ then true
312+ else ((price - ((price * percentPriceOffset) / 100)) >= newPrice))
313+ then WriteSet([DataEntry(IsBlockedKey, true), DataEntry(getBlackSwarmPriceKey(height), newPrice)])
314+ else {
315+ let newPriceIndex = (priceIndex + 1)
316+ WriteSet([DataEntry(PriceKey, newPrice), DataEntry(getPriceHistoryKey(height), newPrice), DataEntry(PriceIndexKey, newPriceIndex), DataEntry(getHeightPriceByIndexKey(newPriceIndex), height)])
317+ }
318+ }
319+ }
181320 }
182321
183322
184323 @Verifier(tx)
185324 func verify () = {
186325 let pubKeyAdminsList = ["BLEoguzPVKVTfXxxT3W7Rqf8aUm2ggC9Vemd2MQawM2G", "FWVffYr2ALmHMejZm3WqeLz6Sdym3gLFGtJn4KTwyU5x", "3Wh2LaWcb5gg7K2pPcW3Ep6EAuRBzYkAgrdpt43jTDFa", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
187326 let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
188327 then 1
189328 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
190329 then 1
191330 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2])))
192331 then 1
193332 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[3], fromBase58String(pubKeyAdminsList[3])))
194333 then 2
195334 else 0))
196335 (count >= 3)
197336 }
198337

github/deemru/w8io/786bc32 
66.17 ms