tx · EiYtiNxGypRLMXonv3PwcCaLAMy1ea4zRGt7CmVUsyZB

3P5sWCrmDJzbHFWU8rQqkJ9LZ46SeByaSJi:  -0.01400000 Waves

2021.03.12 15:05 [2499121] smart account 3P5sWCrmDJzbHFWU8rQqkJ9LZ46SeByaSJi > SELF 0.00000000 Waves

{ "type": 13, "id": "EiYtiNxGypRLMXonv3PwcCaLAMy1ea4zRGt7CmVUsyZB", "fee": 1400000, "feeAssetId": null, "timestamp": 1615550607560, "version": 1, "sender": "3P5sWCrmDJzbHFWU8rQqkJ9LZ46SeByaSJi", "senderPublicKey": "73hwsXA1FUh4WArEp9yXsnXK2HszQ4t2QgpmWf3TEsdE", "proofs": [ "4oYDFanjZLbeeoUyhAY3jqLSqERp7TsuDvWJ8on5JFrgEmUYUjy8dBtbt5ejkTt7a3Nne6u35EagrVSMAAzzbL1N", "3JZR7uEJzq6qXjrBRuScG424cDRUJiagoP2wA28by3TSujUXq5Ayu1JW7uagoscLAmyojxZmVb8JcDjAiXUeVAMn" ], "script": "base64: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", "chainId": 87, "height": 2499121, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 9S81jGNo9EZVJsipF8Uh6YTc1AC1NgGDcsPr3pd9Cw1z Next: none Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 4 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-func SE (k,v) = StringEntry(k, v)
5-
6-
7-func IE (k,v) = IntegerEntry(k, v)
8-
9-
10-func ST (a,amt,t) = ScriptTransfer(a, amt, t)
11-
12-
13-let ten6 = 1000000
14-
15-let ten8 = 100000000
16-
17-let MAX = 9223372036854775807
18-
19-let configProviderKey = "configProvider"
20-
21-let configProvider = match getString(this, configProviderKey) {
22- case s: String =>
23- addressFromStringValue(s)
24- case _ =>
25- this
26-}
27-
284 func localI (k,e) = valueOrErrorMessage(getInteger(this, k), e)
295
306
317 func localS (k,e) = valueOrErrorMessage(getString(this, k), e)
32-
33-
34-func confI (k,e) = valueOrErrorMessage(getInteger(configProvider, k), e)
35-
36-
37-func confS (k,e) = valueOrErrorMessage(getString(configProvider, k), e)
388
399
4010 let BULLK = "BULLId"
5121
5222 let BEARCIRCK = "bearCirculation"
5323
54-let ISSPERCK = "issuePercentile"
55-
56-let REDPERCK = "redeemPercentile"
57-
58-let MINISSK = "minIssue"
59-
60-let MINREDK = "minRedeem"
61-
62-let MINPOOLK = "minPool"
63-
6424 let FEEACCK = "feesAccumulated"
65-
66-let WLISTK = "issueWhiteList"
67-
68-let REBPERCK = "rebalancePercentile"
69-
70-let REBIDXK = "lastSettlementPriceId"
71-
72-let HEADK = "headPointer"
73-
74-let TAILK = "tailPointer"
75-
76-let QSIZEK = "queueSize"
77-
78-let POOLUSDNK = "poolMainTokenValue"
79-
80-let POOLUPK = "poolUp"
81-
82-let POOLDWNK = "poolDwn"
83-
84-let POOLCIRCK = "poolTokenCirculation"
85-
86-let POOLK = "poolToken"
87-
88-let ASSNAMEK = "defoAssetName"
89-
90-let LEVK = "leverage"
91-
92-let WAVESFEEK = "wavesPacemakerFee"
93-
94-let USDNFEEK = "usdnPacemakerFee"
95-
96-let oraclePKKey = "oracle"
97-
98-func lastPriceIndexKey (assetId) = if ((assetId == ""))
99- then "price_index"
100- else ("%s%s__idxCurrent__" + assetId)
101-
102-
103-func priceIndexPrefix (assetId) = if ((assetId == ""))
104- then "price_index_"
105- else (("%s%s%d__idx2Height__" + assetId) + "__")
106-
107-
108-func priceHeightPrefix (assetId) = if ((assetId == ""))
109- then "price_"
110- else (("%s%s%d__priceByHeight__" + assetId) + "__")
111-
112-
113-let minUsdnFee = valueOrElse(getInteger(configProvider, USDNFEEK), 0)
114-
115-let minWavesFee = valueOrElse(getInteger(configProvider, WAVESFEEK), 0)
116-
117-let assetName = valueOrElse(getString(this, ASSNAMEK), "")
11825
11926 let bullCol = localI(BULLCOLK, "no 0")
12027
13037
13138 let mainToken = localS(USDNK, "no 16")
13239
133-let issuePercentile = confI(ISSPERCK, "no 4")
134-
135-let redeemPercentile = confI(REDPERCK, "no 5")
136-
137-let minIssue = confI(MINISSK, "no 6")
138-
139-let minRedeem = confI(MINREDK, "no 7")
140-
141-let minPool = confI(MINPOOLK, "no 8")
142-
143-let rebalancePercentile = valueOrElse(getInteger(configProvider, ((toString(this) + "_") + REBPERCK)), 0)
144-
145-let whitelist = confS(WLISTK, "no 9")
146-
147-func allowed (a) = if ((whitelist == ""))
148- then true
149- else isDefined(indexOf(whitelist, toString(a)))
150-
151-
152-let poolMain = localI(POOLUSDNK, "no")
153-
154-let poolUp = localI(POOLUPK, "no 10")
155-
156-let poolDwn = localI(POOLDWNK, "no 11")
157-
158-let poolToken = localS(POOLK, "no 12")
159-
160-let poolTokenCirculation = localI(POOLCIRCK, "no 13")
161-
162-let poolBullExposure = fraction(bullCol, poolUp, bullCirc)
163-
164-let poolBearExposure = fraction(bearCol, poolDwn, bearCirc)
165-
166-let poolValue = ((poolMain + poolBullExposure) + poolBearExposure)
167-
168-let oracle = valueOrErrorMessage(addressFromPublicKey(fromBase58String(valueOrErrorMessage(getString(this, oraclePKKey), "no oraclePKKey"))), "bad oracle address")
169-
170-let rebalancedPriceIndex = valueOrErrorMessage(getInteger(this, REBIDXK), "no last rebalance price")
171-
172-let oraclePriceIndex = valueOrErrorMessage(getInteger(oracle, lastPriceIndexKey(assetName)), ((("bad oracle data at " + toString(oracle)) + ": no integer at ") + lastPriceIndexKey(assetName)))
173-
174-let leverage = valueOrElse(getInteger(this, LEVK), 3)
175-
176-func heightByIndex (assetName,priceIndex) = valueOrErrorMessage(getInteger(oracle, (priceIndexPrefix(assetName) + toString(priceIndex))), ("no data at index " + toString(priceIndex)))
177-
178-
179-func priceByHeight (assetName,priceHeight) = valueOrErrorMessage(getInteger(oracle, (priceHeightPrefix(assetName) + toString(priceHeight))), ("no data for height " + toString(priceHeight)))
180-
181-
182-func priceByIndex (assetName,priceIndex) = priceByHeight(assetName, heightByIndex(assetName, priceIndex))
183-
184-
185-let queueSize = valueOrElse(getInteger(this, QSIZEK), 0)
186-
187-let headPointer = valueOrElse(getString(this, HEADK), "")
188-
189-let tailPointer = valueOrElse(getString(this, TAILK), "")
190-
191-let feesAccumulated = valueOrElse(getInteger(this, FEEACCK), 0)
192-
193-let ISSUE = "ISSUE"
194-
195-let REDEEM = "REDEEM"
196-
197-let POOL = "POOL"
198-
199-let UNPOOL = "UNPOOL"
200-
20140 let feeAddrKey = "feeAddress"
20241
203-let stakingAddrKey = "stakingAddress"
204-
205-let daemonPubKeyKey = "daemonPublicKey"
206-
207-let feeAddress = valueOrErrorMessage(addressFromString(confS(feeAddrKey, "no feeAddress")), "bad feeAddress")
208-
209-let stakingAddress = confS(stakingAddrKey, "no stakingAddress")
210-
211-let daemonPublicKey = fromBase58String(confS(daemonPubKeyKey, "no daemonPublicKey"))
212-
213-let rpdAddress = addressFromString("3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ")
214-
215-let admins = ["2HHqV8W9DJayV5R6tBD2Sb8srphpoboDi7r1t1aPiumC", "5ZXe82RRASU7qshXM2J9JNYhqJ9GWYjjVq2gwUV5Naz9", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
216-
217-let opn = valueOrElse(getBoolean(oracle, ("%s%s__isMarketOpened__" + assetName)), true)
218-
219-func buildNewItem (action,amt,token,priceIndex,invoker,minPayout,maxPayout) = (((((((((((((action + "|") + toString(amt)) + "|") + token) + "|") + toString(priceIndex)) + "|") + invoker) + "|") + toString(minPayout)) + "|") + toString(maxPayout)) + "|")
220-
221-
222-func userDiffAbs () = {
223- let $t058835972 = $Tuple2((bullCol - poolBullExposure), (bearCol - poolBearExposure))
224- let userBullCol = $t058835972._1
225- let userBearCol = $t058835972._2
226- let diff = (userBullCol - userBearCol)
227- if ((diff > 0))
228- then diff
229- else (0 - diff)
230- }
231-
232-
233-func maxIssue (tokenId) = {
234- let poolInvestment = if ((poolUp > 0))
235- then BULL
236- else BEAR
237- if ((tokenId != poolInvestment))
238- then poolMain
239- else (userDiffAbs() + poolValue)
240- }
241-
242-
243-func validatePMFee (i,minPayout) = if ((0 > minPayout))
244- then throw("negative min payout")
245- else {
246- let p = i.payments[1]
247- let ok = match p.assetId {
248- case bv: ByteVector =>
249- if ((toBase58String(bv) == mainToken))
250- then (p.amount >= minUsdnFee)
251- else false
252- case waves: Unit =>
253- (p.amount >= minWavesFee)
254- case _ =>
255- throw("Match error")
256- }
257- if (!(ok))
258- then throw("incorrect pacemaker fee")
259- else true
260- }
261-
262-
263-func validateRequestRedeem (inv) = if ((inv.caller == this))
264- then throw("can't do")
265- else {
266- func errorMessage (got) = throw(((((("bad token att: only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") tokens are accepted, received: ") + got))
267-
268- let assetId = toBase58String(valueOrErrorMessage(value(inv.payments[0]).assetId, "bad token att"))
269- if (if ((assetId != BEAR))
270- then (assetId != BULL)
271- else false)
272- then errorMessage(assetId)
273- else {
274- let attachedAmount = inv.payments[0].amount
275- let col = if ((assetId == BEAR))
276- then bearCol
277- else bullCol
278- let circ = if ((assetId == BEAR))
279- then bearCirc
280- else bullCirc
281- let estimated = fraction(col, attachedAmount, circ)
282- if ((minRedeem > estimated))
283- then throw((((((((((("Attached payment too small. Min redeem amount is " + toString((minRedeem / 1000000))) + " USDN, ") + "attached amount: ") + toString(attachedAmount)) + ", col: ") + toString(col)) + ", circ: ") + toString(circ)) + ", estimated: ") + toString(estimated)))
284- else unit
285- }
286- }
287-
288-
289-func enqueue (id,action,amt,token,priceIndex,invoker,minPayout,maxPayout) = {
290- let increaseQueueSize = IE(QSIZEK, (queueSize + 1))
291- let itm = buildNewItem(action, amt, token, priceIndex, invoker, minPayout, maxPayout)
292- if ((queueSize == 0))
293- then [SE(HEADK, id), SE(TAILK, id), SE(id, itm), increaseQueueSize]
294- else {
295- let prevId = localS(TAILK, "can't get tail pointer")
296- let prevItm = localS(prevId, "can't resolve pointer")
297- let updatedPrevItm = (prevItm + id)
298-[SE(prevId, updatedPrevItm), SE(id, itm), SE(TAILK, id), increaseQueueSize]
299- }
300- }
301-
302-
303-func poolSupport (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0,curPoolMain0,curPoolUp0,curPoolDwn0) = {
304- func closeUp (c1,c2,a0,a1,c0,pu,pd) = {
305- let diff = (c1 - c2)
306- let exp = fraction(c1, pu, a0)
307- let liquidatedTokens = if ((diff > exp))
308- then pu
309- else fraction(diff, a0, c1)
310- let liquidatedValue = if ((diff > exp))
311- then exp
312- else fraction(liquidatedTokens, c1, a0)
313- $Tuple7((c1 - liquidatedValue), c2, (a0 - liquidatedTokens), a1, (c0 + liquidatedValue), (pu - liquidatedTokens), pd)
314- }
315-
316- func closeDwn (c1,c2,a0,a1,c0,pu,pd) = {
317- let diff = (c2 - c1)
318- let exp = fraction(c2, pd, a1)
319- let liquidatedTokens = if ((diff > exp))
320- then pd
321- else fraction(diff, a1, c2)
322- let liquidatedValue = if ((diff > exp))
323- then exp
324- else fraction(liquidatedTokens, c2, a1)
325- $Tuple7(c1, (c2 - liquidatedValue), a0, (a1 - liquidatedTokens), (c0 + liquidatedValue), pu, (pd - liquidatedTokens))
326- }
327-
328- func openDwn (c1,c2,a0,a1,c0,pu,pd) = {
329- let diff = (c1 - c2)
330- let spentPoolValue = if ((c0 > diff))
331- then diff
332- else c0
333- let acquiredTokens = fraction(spentPoolValue, a1, c2)
334- $Tuple7(c1, (c2 + spentPoolValue), a0, (a1 + acquiredTokens), (c0 - spentPoolValue), pu, (pd + acquiredTokens))
335- }
336-
337- func openUp (c1,c2,a0,a1,c0,pu,pd) = {
338- let diff = (c2 - c1)
339- let spentPoolValue = if ((c0 > diff))
340- then diff
341- else c0
342- let acquiredTokens = fraction(spentPoolValue, a0, c1)
343- $Tuple7((c1 + spentPoolValue), c2, (a0 + acquiredTokens), a1, (c0 - spentPoolValue), (pu + acquiredTokens), pd)
344- }
345-
346- let $t01034111376 = if ((curBullCol0 > curBearCol0))
347- then {
348- let afterCloseUp = closeUp(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0)
349- let $t01056710704 = afterCloseUp
350- let a = $t01056710704._1
351- let b = $t01056710704._2
352- let c = $t01056710704._3
353- let d = $t01056710704._4
354- let e = $t01056710704._5
355- let f = $t01056710704._6
356- let g = $t01056710704._7
357- if ((f > 0))
358- then afterCloseUp
359- else if ((f == 0))
360- then openDwn(a, b, c, d, e, f, g)
361- else throw("poolUp < 0")
362- }
363- else {
364- let afterCloseDwn = closeDwn(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0)
365- let $t01105511195 = afterCloseDwn
366- let a = $t01105511195._1
367- let b = $t01105511195._2
368- let c = $t01105511195._3
369- let d = $t01105511195._4
370- let e = $t01105511195._5
371- let f = $t01105511195._6
372- let g = $t01105511195._7
373- if ((g > 0))
374- then afterCloseDwn
375- else if ((g == 0))
376- then openUp(a, b, c, d, e, f, g)
377- else throw("poolDwn < 0")
378- }
379- let c1 = $t01034111376._1
380- let c2 = $t01034111376._2
381- let a0 = $t01034111376._3
382- let a1 = $t01034111376._4
383- let c0 = $t01034111376._5
384- let pu = $t01034111376._6
385- let pd = $t01034111376._7
386- let charge = fraction(userDiffAbs(), rebalancePercentile, ((1440 * 100) * 100))
387- let percentileActivated = (height >= valueOrElse(getInteger(configProvider, "percentileActivationHeight"), 10000000))
388- let c1SplitP = if (if (percentileActivated)
389- then (pd > 0)
390- else false)
391- then charge
392- else 0
393- let c2SplitP = if (if (percentileActivated)
394- then (pu > 0)
395- else false)
396- then charge
397- else 0
398- $Tuple7((c1 - c1SplitP), (c2 - c2SplitP), a0, a1, ((c0 + c1SplitP) + c2SplitP), pu, pd)
399- }
400-
401-
402-func poolSup (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0) = {
403- let $t01195712139 = poolSupport(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, poolMain, poolUp, poolDwn)
404- let bullCol1 = $t01195712139._1
405- let bearCol1 = $t01195712139._2
406- let bullCic1 = $t01195712139._3
407- let bearCirc1 = $t01195712139._4
408- let poolMain1 = $t01195712139._5
409- let poolUp1 = $t01195712139._6
410- let poolDwn1 = $t01195712139._7
411-[IE(BULLCOLK, bullCol1), IE(BULLCIRCK, bullCic1), IE(BEARCOLK, bearCol1), IE(BEARCIRCK, bearCirc1), IE(POOLUSDNK, poolMain1), IE(POOLUPK, poolUp1), IE(POOLDWNK, poolDwn1)]
412- }
413-
414-
415-func dequeue () = {
416- func sp (a,mx) = if ((mx >= a))
417- then $Tuple2(a, 0)
418- else $Tuple2(mx, (a - mx))
419-
420- if ((queueSize == 0))
421- then throw("nothing to settle")
422- else {
423- func collectFee (fees) = IE(FEEACCK, (feesAccumulated + fees))
424-
425- let decreaseQueueSize = IE(QSIZEK, (queueSize - 1))
426- let isLastElement = (headPointer == tailPointer)
427- let overwriteTail = SE(TAILK, "")
428- let dataStr = localS(headPointer, "bad head pointer(dequeue)")
429- let data = split(dataStr, "|")
430- let action = data[0]
431- let amt = parseIntValue(data[1])
432- let token = data[2]
433- let priceIndex = parseIntValue(data[3])
434- let invoker = addressFromStringValue(data[4])
435- let minPayout = if ((8 > size(data)))
436- then 0
437- else parseIntValue(data[5])
438- let maxPayout = if ((8 > size(data)))
439- then MAX
440- else parseIntValue(data[6])
441- let next = data[(size(data) - 1)]
442- func payback (tkn) = [SE(HEADK, next), decreaseQueueSize, ST(invoker, amt, fromBase58String(tkn))]
443-
444- let items = if ((rebalancedPriceIndex > priceIndex))
445- then throw(((("corrupt state, rebalancedPriceIndex=" + toString(rebalancedPriceIndex)) + ", request price id=") + toString(priceIndex)))
446- else if ((priceIndex > rebalancedPriceIndex))
447- then throw("can't dequeue, too early, rebalance first")
448- else if ((action == ISSUE))
449- then {
450- let feeSize = fraction(amt, issuePercentile, 10000)
451- let addedCollateral = (amt - feeSize)
452- let a = if ((token == BULL))
453- then fraction(bullCirc, addedCollateral, bullCol)
454- else if ((token == BEAR))
455- then fraction(bearCirc, addedCollateral, bearCol)
456- else throw("bad token id")
457- let $t01425314309 = sp(a, maxPayout)
458- let addedToCirculation = $t01425314309._1
459- let extraTokens = $t01425314309._2
460- let $t01432614497 = if ((token == BULL))
461- then $Tuple4(addedToCirculation, addedCollateral, 0, 0)
462- else $Tuple4(0, 0, addedToCirculation, addedCollateral)
463- let plusBulls = $t01432614497._1
464- let plusBullCol = $t01432614497._2
465- let plusBears = $t01432614497._3
466- let plusBearCol = $t01432614497._4
467- if ((minPayout > addedToCirculation))
468- then payback(mainToken)
469- else (poolSup((bullCol + plusBullCol), (bearCol + plusBearCol), (bullCirc + plusBulls), (bearCirc + plusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, addedToCirculation, fromBase58String(token)), ST(feeAddress, extraTokens, fromBase58String(token))])
470- }
471- else if ((action == REDEEM))
472- then {
473- let removedTokens = amt
474- let calcPo = if ((token == BULL))
475- then fraction(bullCol, removedTokens, bullCirc)
476- else if ((token == BEAR))
477- then fraction(bearCol, removedTokens, bearCirc)
478- else throw("bad token id")
479- let $t01541215461 = sp(calcPo, maxPayout)
480- let payoutCapped = $t01541215461._1
481- let extra = $t01541215461._2
482- let feeSize = fraction(payoutCapped, redeemPercentile, 10000)
483- let payout = if ((payoutCapped > feeSize))
484- then (payoutCapped - feeSize)
485- else 0
486- let $t01564715806 = if ((token == BULL))
487- then $Tuple4(removedTokens, payoutCapped, 0, 0)
488- else $Tuple4(0, 0, removedTokens, payoutCapped)
489- let minusBulls = $t01564715806._1
490- let minusBullCol = $t01564715806._2
491- let minusBears = $t01564715806._3
492- let minusBearCol = $t01564715806._4
493- if ((minPayout > payout))
494- then payback(token)
495- else (poolSup((bullCol - minusBullCol), (bearCol - minusBearCol), (bullCirc - minusBulls), (bearCirc - minusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, payout, fromBase58String(mainToken)), ST(feeAddress, extra, fromBase58String(mainToken))])
496- }
497- else if ((action == POOL))
498- then {
499- let issueTokens = fraction(poolTokenCirculation, amt, poolValue)
500- if ((minPayout > issueTokens))
501- then payback(mainToken)
502- else [IE(POOLUSDNK, (poolMain + amt)), IE(POOLCIRCK, (poolTokenCirculation + issueTokens)), SE(HEADK, next), decreaseQueueSize, ST(invoker, issueTokens, fromBase58String(poolToken))]
503- }
504- else if ((action == UNPOOL))
505- then {
506- func share (a) = fraction(a, amt, poolTokenCirculation)
507-
508- let unpooledMain = share(poolMain)
509- let unpooledUp = share(poolUp)
510- let unpooledDwn = share(poolDwn)
511- let unpooledUpValue = fraction(unpooledUp, bullCol, bullCirc)
512- let unpooledDwnValue = fraction(unpooledDwn, bearCol, bearCirc)
513- let totalUnpooledValue = ((unpooledMain + unpooledUpValue) + unpooledDwnValue)
514- if ((minPayout > totalUnpooledValue))
515- then payback(poolToken)
516- else [IE(POOLUSDNK, (poolMain - unpooledMain)), IE(POOLCIRCK, (poolTokenCirculation - amt)), IE(POOLUPK, (poolUp - unpooledUp)), IE(POOLDWNK, (poolDwn - unpooledDwn)), IE(BULLCIRCK, (bullCirc - unpooledUp)), IE(BEARCIRCK, (bearCirc - unpooledDwn)), IE(BULLCOLK, (bullCol - unpooledUpValue)), IE(BEARCOLK, (bearCol - unpooledDwnValue)), SE(HEADK, next), decreaseQueueSize, ST(invoker, totalUnpooledValue, fromBase58String(mainToken))]
517- }
518- else throw(("bad action: " + action))
519- if (isLastElement)
520- then overwriteTail :: items
521- else items
522- }
523- }
524-
525-
526-func rebalance () = {
527- func LV (v,p0,p1,m) = {
528- let denom = {
529- let md = (((2 * (if ((p1 > p0))
530- then p1
531- else p0)) * m) / 3037000499)
532- if ((10 > md))
533- then 10
534- else if ((100 > md))
535- then 100
536- else 1000
537- }
538- let pmax = ((if ((p1 > p0))
539- then p1
540- else p0) / denom)
541- let pmin = ((if ((p0 > p1))
542- then p1
543- else p0) / denom)
544- let a = (pmin * pmin)
545- let b = ((((m * m) * pmax) * pmax) - (((((2 * m) * m) - m) * pmax) * pmin))
546- let ma = ((m * m) - m)
547- fraction(v, ((ma * a) + b), (((ma + 1) * a) + b))
548- }
549-
550- let settledPriceIndex = valueOrErrorMessage(getInteger(this, REBIDXK), "inconsistent data")
551- let unsettledPriceIndex = (settledPriceIndex + 1)
552- if (!(opn))
553- then [IE(REBIDXK, unsettledPriceIndex)]
554- else {
555- let settledPrice = priceByIndex(assetName, settledPriceIndex)
556- let nextPrice = priceByIndex(assetName, unsettledPriceIndex)
557- let minVol = if ((bearCol > bullCol))
558- then bullCol
559- else bearCol
560- let redist = LV(minVol, settledPrice, nextPrice, leverage)
561- let priceUpGoodForBulls = (assetName == "")
562- let priceGoesUp = (nextPrice > settledPrice)
563- let bullsEarn = (priceUpGoodForBulls == priceGoesUp)
564- let newBullCol = if (bullsEarn)
565- then (bullCol + redist)
566- else (bullCol - redist)
567- let newBearCol = if (bullsEarn)
568- then (bearCol - redist)
569- else (bearCol + redist)
570- let $t01979219982 = poolSupport(newBullCol, newBearCol, bullCirc, bearCirc, poolMain, poolUp, poolDwn)
571- let updBullCol = $t01979219982._1
572- let updBearCol = $t01979219982._2
573- let updBullCirc = $t01979219982._3
574- let updBearCirc = $t01979219982._4
575- let updPoolMain = $t01979219982._5
576- let updPoolUp = $t01979219982._6
577- let updPoolDwn = $t01979219982._7
578-[IE(BULLCOLK, updBullCol), IE(BEARCOLK, updBearCol), IE(BULLCIRCK, updBullCirc), IE(BEARCIRCK, updBearCirc), IE(POOLUSDNK, updPoolMain), IE(POOLUPK, updPoolUp), IE(POOLDWNK, updPoolDwn), IE(REBIDXK, unsettledPriceIndex)]
579- }
580- }
581-
582-
583-func calcMax (min,avg) = if ((min > avg))
584- then throw(((("price too old: minPayout " + toString(min)) + " > avg = ") + toString(avg)))
585- else ((avg + avg) - min)
586-
42+let feeAddress = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, feeAddrKey), "no fee address")), "bad feeAddress")
58743
58844 func requestIssueInternal (inv,tokenId,minPayout) = throw("issuing of EURUP and EURDOWN is disabled")
58945
59046
591-func requestRedeemInternal (inv,minPayout) = {
592- let amt = inv.payments[0].amount
593- let tokenId = toBase58String(valueOrErrorMessage(inv.payments[0].assetId, "bad token att"))
594- if (if ((tokenId != BULL))
595- then (tokenId != BEAR)
596- else false)
597- then throw("bad token req")
598- else {
599- let $t02094021079 = if ((tokenId == BULL))
600- then $Tuple2(bullCol, bullCirc)
601- else if ((tokenId == BEAR))
602- then $Tuple2(bearCol, bearCirc)
603- else throw("bad token req")
604- let col = $t02094021079._1
605- let circ = $t02094021079._2
606- let est = fraction(amt, col, circ)
607- let $t02112721221 = if ((minPayout == 0))
608- then $Tuple2(0, MAX)
609- else $Tuple2(minPayout, calcMax(minPayout, est))
610- let minP = $t02112721221._1
611- let maxP = $t02112721221._2
612- if ((validateRequestRedeem(inv) == unit))
613- then enqueue(toBase58String(inv.transactionId), REDEEM, amt, tokenId, (oraclePriceIndex + 1), toString(inv.caller), minP, maxP)
614- else throw("doesn't happen")
47+func requestRedeemInternal (inv) = {
48+ let removedTokens = inv.payments[0].amount
49+ let tokenId = toBase58String(value(inv.payments[0].assetId))
50+ let invoker = inv.caller
51+ if ((tokenId == BULL))
52+ then {
53+ let payout = fraction(bullCol, removedTokens, bullCirc)
54+[IntegerEntry(BULLCOLK, (bullCol - payout)), IntegerEntry(BULLCIRCK, (bullCirc - removedTokens)), ScriptTransfer(invoker, payout, fromBase58String(mainToken))]
61555 }
56+ else if ((tokenId == BEAR))
57+ then {
58+ let payout = fraction(bearCol, removedTokens, bearCirc)
59+[IntegerEntry(BEARCOLK, (bearCol - payout)), IntegerEntry(BEARCIRCK, (bearCirc - removedTokens)), ScriptTransfer(invoker, payout, fromBase58String(mainToken))]
60+ }
61+ else throw("bad token attached")
61662 }
61763
61864
619-func requestPoolInternal (inv,minPayout) = if (!(allowed(inv.caller)))
620- then throw("only whitelisted can do")
621- else {
622- let errMessage = "USDN required"
623- let pmt = inv.payments[0]
624- if ((pmt.assetId != fromBase58String(mainToken)))
625- then throw(errMessage)
626- else if ((minPool > pmt.amount))
627- then throw(("pool min: " + toString(minPool)))
628- else {
629- let estimate = fraction(poolTokenCirculation, pmt.amount, poolValue)
630- let $t02201422113 = if ((minPayout == 0))
631- then $Tuple2(0, MAX)
632- else $Tuple2(minPayout, calcMax(minPayout, estimate))
633- let minP = $t02201422113._1
634- let maxP = $t02201422113._2
635- enqueue(toBase58String(inv.transactionId), POOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller), minP, maxP)
636- }
637- }
638-
639-
640-func requestUnpoolInternal (inv,minPayout) = {
641- let errMessage = (("only pool token allowed(" + poolToken) + ")")
642- let pmt = inv.payments[0]
643- if ((pmt.assetId != fromBase58String(poolToken)))
644- then throw(errMessage)
645- else {
646- let estimate = fraction(poolValue, pmt.amount, poolTokenCirculation)
647- if ((minPool > estimate))
648- then throw(((("unpool at least for" + toString(minPool)) + " ") + mainToken))
649- else {
650- let $t02277022869 = if ((minPayout == 0))
651- then $Tuple2(0, MAX)
652- else $Tuple2(minPayout, calcMax(minPayout, estimate))
653- let minP = $t02277022869._1
654- let maxP = $t02277022869._2
655- enqueue(toBase58String(inv.transactionId), UNPOOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller), minP, maxP)
656- }
657- }
65+@Callable(i)
66+func withdrawFee (amount) = {
67+ let acc = valueOrErrorMessage(getInteger(this, FEEACCK), "no fees acc")
68+ if ((amount > acc))
69+ then throw(("too much. available: " + toString(acc)))
70+ else [IntegerEntry(FEEACCK, (acc - amount)), ScriptTransfer(feeAddress, amount, fromBase58String(mainToken))]
65871 }
659-
660-
661-@Callable(inv)
662-func init (config,oraclePK,nameup,namedwn,descUp,descDwn,poolName,poolDesc,defoAssetName,denom,lev) = if (isDefined(getString(this, BULLK)))
663- then throw("already initialized")
664- else {
665- let totalOwnedMainToken = inv.payments[0].amount
666- let bulls = (totalOwnedMainToken / 3)
667- let bears = bulls
668- let pools = ((totalOwnedMainToken - bulls) - bears)
669- if (if (if ((bears == 0))
670- then true
671- else (bulls == 0))
672- then true
673- else (pools == 0))
674- then throw("can't init balances")
675- else {
676- let oracleCurrentPriceIndex = valueOrErrorMessage(getInteger(valueOrErrorMessage(addressFromPublicKey(fromBase58String(oraclePK)), "bad oracle address"), lastPriceIndexKey(defoAssetName)), "no last price index")
677- let bull = Issue(nameup, descUp, ((100 * ten6) * ten6), 6, true)
678- let bear = Issue(namedwn, descDwn, ((100 * ten6) * ten6), 6, true)
679- let pool = Issue(poolName, poolDesc, ((100 * ten6) * ten6), 6, true)
680- let buid = calculateAssetId(bull)
681- let beid = calculateAssetId(bear)
682- let poid = calculateAssetId(pool)
683-[bull, bear, pool, SE(BULLK, toBase58String(buid)), SE(BEARK, toBase58String(beid)), SE(USDNK, toBase58String(value(inv.payments[0].assetId))), SE(POOLK, toBase58String(poid)), SE(ASSNAMEK, defoAssetName), SE(oraclePKKey, oraclePK), IE(REBIDXK, oracleCurrentPriceIndex), IE(BULLCOLK, bulls), IE(BEARCOLK, bears), IE(BULLCIRCK, (bulls / denom)), IE(BEARCIRCK, (bears / denom)), IE(POOLCIRCK, (pools / denom)), IE(POOLDWNK, 0), IE(POOLUPK, 0), IE(POOLUSDNK, pools), SE(configProviderKey, config), IE(LEVK, lev), ST(inv.caller, (bulls / denom), buid), ST(inv.caller, (bears / denom), beid), ST(inv.caller, (pools / denom), poid)]
684- }
685- }
686-
687-
688-
689-@Callable(i)
690-func withdrawFee (amount) = if ((amount > feesAccumulated))
691- then throw(("too much. available: " + toString(feesAccumulated)))
692- else [IE(FEEACCK, (feesAccumulated - amount)), ST(feeAddress, amount, fromBase58String(mainToken))]
69372
69473
69574
69675 @Callable(inv)
697-func requestRedeem () = requestRedeemInternal(inv, 0)
76+func requestRedeem () = requestRedeemInternal(inv)
69877
69978
70079
70180 @Callable(inv)
702-func requestRedeemSl (sl) = if (validatePMFee(inv, sl))
703- then requestRedeemInternal(inv, sl)
704- else throw()
81+func requestRedeemSl (sl) = requestRedeemInternal(inv)
70582
70683
70784
70885 @Callable(inv)
709-func requestIssue (tokenId) = requestIssueInternal(inv, tokenId, 0)
86+func requestIssue (tokenId) = throw("issuing of EURUP and EURDOWN is disabled")
71087
71188
71289
71390 @Callable(inv)
714-func requestIssueSl (tokenId,sl) = if (validatePMFee(inv, sl))
715- then requestIssueInternal(inv, tokenId, sl)
716- else throw()
717-
718-
719-
720-@Callable(inv)
721-func requestPool () = requestPoolInternal(inv, 0)
722-
723-
724-
725-@Callable(inv)
726-func requestPoolSl (sl) = if (validatePMFee(inv, sl))
727- then requestPoolInternal(inv, sl)
728- else throw()
729-
730-
731-
732-@Callable(inv)
733-func requestUnpool () = requestUnpoolInternal(inv, 0)
734-
735-
736-
737-@Callable(inv)
738-func requestUnpoolSl (sl) = if (validatePMFee(inv, sl))
739- then requestUnpoolInternal(inv, sl)
740- else throw()
741-
742-
743-
744-@Callable(inv)
745-func settle () = {
746- let queueEmpty = (headPointer == "")
747- let canRebalance = (oraclePriceIndex > rebalancedPriceIndex)
748- if (queueEmpty)
749- then if (canRebalance)
750- then rebalance()
751- else throw("[OK] all done, carry on")
752- else {
753- let data = split(valueOrErrorMessage(getString(this, headPointer), ("bad head pointer(settle): " + headPointer)), "|")
754- let priceIndex = parseIntValue(data[3])
755- if ((priceIndex > rebalancedPriceIndex))
756- then if (canRebalance)
757- then rebalance()
758- else throw("[OK] need to wait")
759- else if ((priceIndex == rebalancedPriceIndex))
760- then dequeue()
761- else throw("future price already rebalanced")
762- }
763- }
91+func requestIssueSl (tokenId,sl) = throw("issuing of EURUP and EURDOWN is disabled")
76492
76593
76694 @Verifier(tx)
76795 func verify () = {
768- let initial = if (!(isDefined(getString(this, BULLK))))
769- then sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
770- else false
771- let adminAction = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(admins[0])))
96+ let adm = ["2HHqV8W9DJayV5R6tBD2Sb8srphpoboDi7r1t1aPiumC", "5ZXe82RRASU7qshXM2J9JNYhqJ9GWYjjVq2gwUV5Naz9", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
97+ ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(adm[0])))
77298 then 1
773- else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(admins[1])))
99+ else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(adm[1])))
774100 then 1
775- else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(admins[2])))
101+ else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(adm[2])))
776102 then 1
777103 else 0)) > 1)
778- let stakingAction = match tx {
779- case tx: InvokeScriptTransaction =>
780- let signedCorrectly = sigVerify(tx.bodyBytes, tx.proofs[0], daemonPublicKey)
781- let feesCorrect = if ((tx.feeAssetId == unit))
782- then ((1000 * 1000) >= tx.fee)
783- else false
784- let dappCorrect = (tx.dApp == rpdAddress)
785- let unlock = (tx.function == "unlockNeutrino")
786- let lock = if (if ((tx.function == "lockNeutrinoSP"))
787- then (tx.args[0] == stakingAddress)
788- else false)
789- then (wavesBalance(this).available >= ten8)
790- else false
791- let funcCorrect = if (lock)
792- then true
793- else unlock
794- if (if (if (signedCorrectly)
795- then feesCorrect
796- else false)
797- then dappCorrect
798- else false)
799- then funcCorrect
800- else false
801- case _ =>
802- false
803- }
804- if (if (initial)
805- then true
806- else adminAction)
807- then true
808- else stakingAction
809104 }
810105
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 4 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-func SE (k,v) = StringEntry(k, v)
5-
6-
7-func IE (k,v) = IntegerEntry(k, v)
8-
9-
10-func ST (a,amt,t) = ScriptTransfer(a, amt, t)
11-
12-
13-let ten6 = 1000000
14-
15-let ten8 = 100000000
16-
17-let MAX = 9223372036854775807
18-
19-let configProviderKey = "configProvider"
20-
21-let configProvider = match getString(this, configProviderKey) {
22- case s: String =>
23- addressFromStringValue(s)
24- case _ =>
25- this
26-}
27-
284 func localI (k,e) = valueOrErrorMessage(getInteger(this, k), e)
295
306
317 func localS (k,e) = valueOrErrorMessage(getString(this, k), e)
32-
33-
34-func confI (k,e) = valueOrErrorMessage(getInteger(configProvider, k), e)
35-
36-
37-func confS (k,e) = valueOrErrorMessage(getString(configProvider, k), e)
388
399
4010 let BULLK = "BULLId"
4111
4212 let BEARK = "BEARId"
4313
4414 let USDNK = "mainTokenId"
4515
4616 let BULLCOLK = "bullCollateral"
4717
4818 let BEARCOLK = "bearCollateral"
4919
5020 let BULLCIRCK = "bullCirculation"
5121
5222 let BEARCIRCK = "bearCirculation"
5323
54-let ISSPERCK = "issuePercentile"
55-
56-let REDPERCK = "redeemPercentile"
57-
58-let MINISSK = "minIssue"
59-
60-let MINREDK = "minRedeem"
61-
62-let MINPOOLK = "minPool"
63-
6424 let FEEACCK = "feesAccumulated"
65-
66-let WLISTK = "issueWhiteList"
67-
68-let REBPERCK = "rebalancePercentile"
69-
70-let REBIDXK = "lastSettlementPriceId"
71-
72-let HEADK = "headPointer"
73-
74-let TAILK = "tailPointer"
75-
76-let QSIZEK = "queueSize"
77-
78-let POOLUSDNK = "poolMainTokenValue"
79-
80-let POOLUPK = "poolUp"
81-
82-let POOLDWNK = "poolDwn"
83-
84-let POOLCIRCK = "poolTokenCirculation"
85-
86-let POOLK = "poolToken"
87-
88-let ASSNAMEK = "defoAssetName"
89-
90-let LEVK = "leverage"
91-
92-let WAVESFEEK = "wavesPacemakerFee"
93-
94-let USDNFEEK = "usdnPacemakerFee"
95-
96-let oraclePKKey = "oracle"
97-
98-func lastPriceIndexKey (assetId) = if ((assetId == ""))
99- then "price_index"
100- else ("%s%s__idxCurrent__" + assetId)
101-
102-
103-func priceIndexPrefix (assetId) = if ((assetId == ""))
104- then "price_index_"
105- else (("%s%s%d__idx2Height__" + assetId) + "__")
106-
107-
108-func priceHeightPrefix (assetId) = if ((assetId == ""))
109- then "price_"
110- else (("%s%s%d__priceByHeight__" + assetId) + "__")
111-
112-
113-let minUsdnFee = valueOrElse(getInteger(configProvider, USDNFEEK), 0)
114-
115-let minWavesFee = valueOrElse(getInteger(configProvider, WAVESFEEK), 0)
116-
117-let assetName = valueOrElse(getString(this, ASSNAMEK), "")
11825
11926 let bullCol = localI(BULLCOLK, "no 0")
12027
12128 let bearCol = localI(BEARCOLK, "no 1")
12229
12330 let bullCirc = localI(BULLCIRCK, "no 2")
12431
12532 let bearCirc = localI(BEARCIRCK, "no 3")
12633
12734 let BULL = localS(BULLK, "no 14")
12835
12936 let BEAR = localS(BEARK, "no 15")
13037
13138 let mainToken = localS(USDNK, "no 16")
13239
133-let issuePercentile = confI(ISSPERCK, "no 4")
134-
135-let redeemPercentile = confI(REDPERCK, "no 5")
136-
137-let minIssue = confI(MINISSK, "no 6")
138-
139-let minRedeem = confI(MINREDK, "no 7")
140-
141-let minPool = confI(MINPOOLK, "no 8")
142-
143-let rebalancePercentile = valueOrElse(getInteger(configProvider, ((toString(this) + "_") + REBPERCK)), 0)
144-
145-let whitelist = confS(WLISTK, "no 9")
146-
147-func allowed (a) = if ((whitelist == ""))
148- then true
149- else isDefined(indexOf(whitelist, toString(a)))
150-
151-
152-let poolMain = localI(POOLUSDNK, "no")
153-
154-let poolUp = localI(POOLUPK, "no 10")
155-
156-let poolDwn = localI(POOLDWNK, "no 11")
157-
158-let poolToken = localS(POOLK, "no 12")
159-
160-let poolTokenCirculation = localI(POOLCIRCK, "no 13")
161-
162-let poolBullExposure = fraction(bullCol, poolUp, bullCirc)
163-
164-let poolBearExposure = fraction(bearCol, poolDwn, bearCirc)
165-
166-let poolValue = ((poolMain + poolBullExposure) + poolBearExposure)
167-
168-let oracle = valueOrErrorMessage(addressFromPublicKey(fromBase58String(valueOrErrorMessage(getString(this, oraclePKKey), "no oraclePKKey"))), "bad oracle address")
169-
170-let rebalancedPriceIndex = valueOrErrorMessage(getInteger(this, REBIDXK), "no last rebalance price")
171-
172-let oraclePriceIndex = valueOrErrorMessage(getInteger(oracle, lastPriceIndexKey(assetName)), ((("bad oracle data at " + toString(oracle)) + ": no integer at ") + lastPriceIndexKey(assetName)))
173-
174-let leverage = valueOrElse(getInteger(this, LEVK), 3)
175-
176-func heightByIndex (assetName,priceIndex) = valueOrErrorMessage(getInteger(oracle, (priceIndexPrefix(assetName) + toString(priceIndex))), ("no data at index " + toString(priceIndex)))
177-
178-
179-func priceByHeight (assetName,priceHeight) = valueOrErrorMessage(getInteger(oracle, (priceHeightPrefix(assetName) + toString(priceHeight))), ("no data for height " + toString(priceHeight)))
180-
181-
182-func priceByIndex (assetName,priceIndex) = priceByHeight(assetName, heightByIndex(assetName, priceIndex))
183-
184-
185-let queueSize = valueOrElse(getInteger(this, QSIZEK), 0)
186-
187-let headPointer = valueOrElse(getString(this, HEADK), "")
188-
189-let tailPointer = valueOrElse(getString(this, TAILK), "")
190-
191-let feesAccumulated = valueOrElse(getInteger(this, FEEACCK), 0)
192-
193-let ISSUE = "ISSUE"
194-
195-let REDEEM = "REDEEM"
196-
197-let POOL = "POOL"
198-
199-let UNPOOL = "UNPOOL"
200-
20140 let feeAddrKey = "feeAddress"
20241
203-let stakingAddrKey = "stakingAddress"
204-
205-let daemonPubKeyKey = "daemonPublicKey"
206-
207-let feeAddress = valueOrErrorMessage(addressFromString(confS(feeAddrKey, "no feeAddress")), "bad feeAddress")
208-
209-let stakingAddress = confS(stakingAddrKey, "no stakingAddress")
210-
211-let daemonPublicKey = fromBase58String(confS(daemonPubKeyKey, "no daemonPublicKey"))
212-
213-let rpdAddress = addressFromString("3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ")
214-
215-let admins = ["2HHqV8W9DJayV5R6tBD2Sb8srphpoboDi7r1t1aPiumC", "5ZXe82RRASU7qshXM2J9JNYhqJ9GWYjjVq2gwUV5Naz9", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
216-
217-let opn = valueOrElse(getBoolean(oracle, ("%s%s__isMarketOpened__" + assetName)), true)
218-
219-func buildNewItem (action,amt,token,priceIndex,invoker,minPayout,maxPayout) = (((((((((((((action + "|") + toString(amt)) + "|") + token) + "|") + toString(priceIndex)) + "|") + invoker) + "|") + toString(minPayout)) + "|") + toString(maxPayout)) + "|")
220-
221-
222-func userDiffAbs () = {
223- let $t058835972 = $Tuple2((bullCol - poolBullExposure), (bearCol - poolBearExposure))
224- let userBullCol = $t058835972._1
225- let userBearCol = $t058835972._2
226- let diff = (userBullCol - userBearCol)
227- if ((diff > 0))
228- then diff
229- else (0 - diff)
230- }
231-
232-
233-func maxIssue (tokenId) = {
234- let poolInvestment = if ((poolUp > 0))
235- then BULL
236- else BEAR
237- if ((tokenId != poolInvestment))
238- then poolMain
239- else (userDiffAbs() + poolValue)
240- }
241-
242-
243-func validatePMFee (i,minPayout) = if ((0 > minPayout))
244- then throw("negative min payout")
245- else {
246- let p = i.payments[1]
247- let ok = match p.assetId {
248- case bv: ByteVector =>
249- if ((toBase58String(bv) == mainToken))
250- then (p.amount >= minUsdnFee)
251- else false
252- case waves: Unit =>
253- (p.amount >= minWavesFee)
254- case _ =>
255- throw("Match error")
256- }
257- if (!(ok))
258- then throw("incorrect pacemaker fee")
259- else true
260- }
261-
262-
263-func validateRequestRedeem (inv) = if ((inv.caller == this))
264- then throw("can't do")
265- else {
266- func errorMessage (got) = throw(((((("bad token att: only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") tokens are accepted, received: ") + got))
267-
268- let assetId = toBase58String(valueOrErrorMessage(value(inv.payments[0]).assetId, "bad token att"))
269- if (if ((assetId != BEAR))
270- then (assetId != BULL)
271- else false)
272- then errorMessage(assetId)
273- else {
274- let attachedAmount = inv.payments[0].amount
275- let col = if ((assetId == BEAR))
276- then bearCol
277- else bullCol
278- let circ = if ((assetId == BEAR))
279- then bearCirc
280- else bullCirc
281- let estimated = fraction(col, attachedAmount, circ)
282- if ((minRedeem > estimated))
283- then throw((((((((((("Attached payment too small. Min redeem amount is " + toString((minRedeem / 1000000))) + " USDN, ") + "attached amount: ") + toString(attachedAmount)) + ", col: ") + toString(col)) + ", circ: ") + toString(circ)) + ", estimated: ") + toString(estimated)))
284- else unit
285- }
286- }
287-
288-
289-func enqueue (id,action,amt,token,priceIndex,invoker,minPayout,maxPayout) = {
290- let increaseQueueSize = IE(QSIZEK, (queueSize + 1))
291- let itm = buildNewItem(action, amt, token, priceIndex, invoker, minPayout, maxPayout)
292- if ((queueSize == 0))
293- then [SE(HEADK, id), SE(TAILK, id), SE(id, itm), increaseQueueSize]
294- else {
295- let prevId = localS(TAILK, "can't get tail pointer")
296- let prevItm = localS(prevId, "can't resolve pointer")
297- let updatedPrevItm = (prevItm + id)
298-[SE(prevId, updatedPrevItm), SE(id, itm), SE(TAILK, id), increaseQueueSize]
299- }
300- }
301-
302-
303-func poolSupport (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0,curPoolMain0,curPoolUp0,curPoolDwn0) = {
304- func closeUp (c1,c2,a0,a1,c0,pu,pd) = {
305- let diff = (c1 - c2)
306- let exp = fraction(c1, pu, a0)
307- let liquidatedTokens = if ((diff > exp))
308- then pu
309- else fraction(diff, a0, c1)
310- let liquidatedValue = if ((diff > exp))
311- then exp
312- else fraction(liquidatedTokens, c1, a0)
313- $Tuple7((c1 - liquidatedValue), c2, (a0 - liquidatedTokens), a1, (c0 + liquidatedValue), (pu - liquidatedTokens), pd)
314- }
315-
316- func closeDwn (c1,c2,a0,a1,c0,pu,pd) = {
317- let diff = (c2 - c1)
318- let exp = fraction(c2, pd, a1)
319- let liquidatedTokens = if ((diff > exp))
320- then pd
321- else fraction(diff, a1, c2)
322- let liquidatedValue = if ((diff > exp))
323- then exp
324- else fraction(liquidatedTokens, c2, a1)
325- $Tuple7(c1, (c2 - liquidatedValue), a0, (a1 - liquidatedTokens), (c0 + liquidatedValue), pu, (pd - liquidatedTokens))
326- }
327-
328- func openDwn (c1,c2,a0,a1,c0,pu,pd) = {
329- let diff = (c1 - c2)
330- let spentPoolValue = if ((c0 > diff))
331- then diff
332- else c0
333- let acquiredTokens = fraction(spentPoolValue, a1, c2)
334- $Tuple7(c1, (c2 + spentPoolValue), a0, (a1 + acquiredTokens), (c0 - spentPoolValue), pu, (pd + acquiredTokens))
335- }
336-
337- func openUp (c1,c2,a0,a1,c0,pu,pd) = {
338- let diff = (c2 - c1)
339- let spentPoolValue = if ((c0 > diff))
340- then diff
341- else c0
342- let acquiredTokens = fraction(spentPoolValue, a0, c1)
343- $Tuple7((c1 + spentPoolValue), c2, (a0 + acquiredTokens), a1, (c0 - spentPoolValue), (pu + acquiredTokens), pd)
344- }
345-
346- let $t01034111376 = if ((curBullCol0 > curBearCol0))
347- then {
348- let afterCloseUp = closeUp(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0)
349- let $t01056710704 = afterCloseUp
350- let a = $t01056710704._1
351- let b = $t01056710704._2
352- let c = $t01056710704._3
353- let d = $t01056710704._4
354- let e = $t01056710704._5
355- let f = $t01056710704._6
356- let g = $t01056710704._7
357- if ((f > 0))
358- then afterCloseUp
359- else if ((f == 0))
360- then openDwn(a, b, c, d, e, f, g)
361- else throw("poolUp < 0")
362- }
363- else {
364- let afterCloseDwn = closeDwn(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0)
365- let $t01105511195 = afterCloseDwn
366- let a = $t01105511195._1
367- let b = $t01105511195._2
368- let c = $t01105511195._3
369- let d = $t01105511195._4
370- let e = $t01105511195._5
371- let f = $t01105511195._6
372- let g = $t01105511195._7
373- if ((g > 0))
374- then afterCloseDwn
375- else if ((g == 0))
376- then openUp(a, b, c, d, e, f, g)
377- else throw("poolDwn < 0")
378- }
379- let c1 = $t01034111376._1
380- let c2 = $t01034111376._2
381- let a0 = $t01034111376._3
382- let a1 = $t01034111376._4
383- let c0 = $t01034111376._5
384- let pu = $t01034111376._6
385- let pd = $t01034111376._7
386- let charge = fraction(userDiffAbs(), rebalancePercentile, ((1440 * 100) * 100))
387- let percentileActivated = (height >= valueOrElse(getInteger(configProvider, "percentileActivationHeight"), 10000000))
388- let c1SplitP = if (if (percentileActivated)
389- then (pd > 0)
390- else false)
391- then charge
392- else 0
393- let c2SplitP = if (if (percentileActivated)
394- then (pu > 0)
395- else false)
396- then charge
397- else 0
398- $Tuple7((c1 - c1SplitP), (c2 - c2SplitP), a0, a1, ((c0 + c1SplitP) + c2SplitP), pu, pd)
399- }
400-
401-
402-func poolSup (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0) = {
403- let $t01195712139 = poolSupport(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, poolMain, poolUp, poolDwn)
404- let bullCol1 = $t01195712139._1
405- let bearCol1 = $t01195712139._2
406- let bullCic1 = $t01195712139._3
407- let bearCirc1 = $t01195712139._4
408- let poolMain1 = $t01195712139._5
409- let poolUp1 = $t01195712139._6
410- let poolDwn1 = $t01195712139._7
411-[IE(BULLCOLK, bullCol1), IE(BULLCIRCK, bullCic1), IE(BEARCOLK, bearCol1), IE(BEARCIRCK, bearCirc1), IE(POOLUSDNK, poolMain1), IE(POOLUPK, poolUp1), IE(POOLDWNK, poolDwn1)]
412- }
413-
414-
415-func dequeue () = {
416- func sp (a,mx) = if ((mx >= a))
417- then $Tuple2(a, 0)
418- else $Tuple2(mx, (a - mx))
419-
420- if ((queueSize == 0))
421- then throw("nothing to settle")
422- else {
423- func collectFee (fees) = IE(FEEACCK, (feesAccumulated + fees))
424-
425- let decreaseQueueSize = IE(QSIZEK, (queueSize - 1))
426- let isLastElement = (headPointer == tailPointer)
427- let overwriteTail = SE(TAILK, "")
428- let dataStr = localS(headPointer, "bad head pointer(dequeue)")
429- let data = split(dataStr, "|")
430- let action = data[0]
431- let amt = parseIntValue(data[1])
432- let token = data[2]
433- let priceIndex = parseIntValue(data[3])
434- let invoker = addressFromStringValue(data[4])
435- let minPayout = if ((8 > size(data)))
436- then 0
437- else parseIntValue(data[5])
438- let maxPayout = if ((8 > size(data)))
439- then MAX
440- else parseIntValue(data[6])
441- let next = data[(size(data) - 1)]
442- func payback (tkn) = [SE(HEADK, next), decreaseQueueSize, ST(invoker, amt, fromBase58String(tkn))]
443-
444- let items = if ((rebalancedPriceIndex > priceIndex))
445- then throw(((("corrupt state, rebalancedPriceIndex=" + toString(rebalancedPriceIndex)) + ", request price id=") + toString(priceIndex)))
446- else if ((priceIndex > rebalancedPriceIndex))
447- then throw("can't dequeue, too early, rebalance first")
448- else if ((action == ISSUE))
449- then {
450- let feeSize = fraction(amt, issuePercentile, 10000)
451- let addedCollateral = (amt - feeSize)
452- let a = if ((token == BULL))
453- then fraction(bullCirc, addedCollateral, bullCol)
454- else if ((token == BEAR))
455- then fraction(bearCirc, addedCollateral, bearCol)
456- else throw("bad token id")
457- let $t01425314309 = sp(a, maxPayout)
458- let addedToCirculation = $t01425314309._1
459- let extraTokens = $t01425314309._2
460- let $t01432614497 = if ((token == BULL))
461- then $Tuple4(addedToCirculation, addedCollateral, 0, 0)
462- else $Tuple4(0, 0, addedToCirculation, addedCollateral)
463- let plusBulls = $t01432614497._1
464- let plusBullCol = $t01432614497._2
465- let plusBears = $t01432614497._3
466- let plusBearCol = $t01432614497._4
467- if ((minPayout > addedToCirculation))
468- then payback(mainToken)
469- else (poolSup((bullCol + plusBullCol), (bearCol + plusBearCol), (bullCirc + plusBulls), (bearCirc + plusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, addedToCirculation, fromBase58String(token)), ST(feeAddress, extraTokens, fromBase58String(token))])
470- }
471- else if ((action == REDEEM))
472- then {
473- let removedTokens = amt
474- let calcPo = if ((token == BULL))
475- then fraction(bullCol, removedTokens, bullCirc)
476- else if ((token == BEAR))
477- then fraction(bearCol, removedTokens, bearCirc)
478- else throw("bad token id")
479- let $t01541215461 = sp(calcPo, maxPayout)
480- let payoutCapped = $t01541215461._1
481- let extra = $t01541215461._2
482- let feeSize = fraction(payoutCapped, redeemPercentile, 10000)
483- let payout = if ((payoutCapped > feeSize))
484- then (payoutCapped - feeSize)
485- else 0
486- let $t01564715806 = if ((token == BULL))
487- then $Tuple4(removedTokens, payoutCapped, 0, 0)
488- else $Tuple4(0, 0, removedTokens, payoutCapped)
489- let minusBulls = $t01564715806._1
490- let minusBullCol = $t01564715806._2
491- let minusBears = $t01564715806._3
492- let minusBearCol = $t01564715806._4
493- if ((minPayout > payout))
494- then payback(token)
495- else (poolSup((bullCol - minusBullCol), (bearCol - minusBearCol), (bullCirc - minusBulls), (bearCirc - minusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, payout, fromBase58String(mainToken)), ST(feeAddress, extra, fromBase58String(mainToken))])
496- }
497- else if ((action == POOL))
498- then {
499- let issueTokens = fraction(poolTokenCirculation, amt, poolValue)
500- if ((minPayout > issueTokens))
501- then payback(mainToken)
502- else [IE(POOLUSDNK, (poolMain + amt)), IE(POOLCIRCK, (poolTokenCirculation + issueTokens)), SE(HEADK, next), decreaseQueueSize, ST(invoker, issueTokens, fromBase58String(poolToken))]
503- }
504- else if ((action == UNPOOL))
505- then {
506- func share (a) = fraction(a, amt, poolTokenCirculation)
507-
508- let unpooledMain = share(poolMain)
509- let unpooledUp = share(poolUp)
510- let unpooledDwn = share(poolDwn)
511- let unpooledUpValue = fraction(unpooledUp, bullCol, bullCirc)
512- let unpooledDwnValue = fraction(unpooledDwn, bearCol, bearCirc)
513- let totalUnpooledValue = ((unpooledMain + unpooledUpValue) + unpooledDwnValue)
514- if ((minPayout > totalUnpooledValue))
515- then payback(poolToken)
516- else [IE(POOLUSDNK, (poolMain - unpooledMain)), IE(POOLCIRCK, (poolTokenCirculation - amt)), IE(POOLUPK, (poolUp - unpooledUp)), IE(POOLDWNK, (poolDwn - unpooledDwn)), IE(BULLCIRCK, (bullCirc - unpooledUp)), IE(BEARCIRCK, (bearCirc - unpooledDwn)), IE(BULLCOLK, (bullCol - unpooledUpValue)), IE(BEARCOLK, (bearCol - unpooledDwnValue)), SE(HEADK, next), decreaseQueueSize, ST(invoker, totalUnpooledValue, fromBase58String(mainToken))]
517- }
518- else throw(("bad action: " + action))
519- if (isLastElement)
520- then overwriteTail :: items
521- else items
522- }
523- }
524-
525-
526-func rebalance () = {
527- func LV (v,p0,p1,m) = {
528- let denom = {
529- let md = (((2 * (if ((p1 > p0))
530- then p1
531- else p0)) * m) / 3037000499)
532- if ((10 > md))
533- then 10
534- else if ((100 > md))
535- then 100
536- else 1000
537- }
538- let pmax = ((if ((p1 > p0))
539- then p1
540- else p0) / denom)
541- let pmin = ((if ((p0 > p1))
542- then p1
543- else p0) / denom)
544- let a = (pmin * pmin)
545- let b = ((((m * m) * pmax) * pmax) - (((((2 * m) * m) - m) * pmax) * pmin))
546- let ma = ((m * m) - m)
547- fraction(v, ((ma * a) + b), (((ma + 1) * a) + b))
548- }
549-
550- let settledPriceIndex = valueOrErrorMessage(getInteger(this, REBIDXK), "inconsistent data")
551- let unsettledPriceIndex = (settledPriceIndex + 1)
552- if (!(opn))
553- then [IE(REBIDXK, unsettledPriceIndex)]
554- else {
555- let settledPrice = priceByIndex(assetName, settledPriceIndex)
556- let nextPrice = priceByIndex(assetName, unsettledPriceIndex)
557- let minVol = if ((bearCol > bullCol))
558- then bullCol
559- else bearCol
560- let redist = LV(minVol, settledPrice, nextPrice, leverage)
561- let priceUpGoodForBulls = (assetName == "")
562- let priceGoesUp = (nextPrice > settledPrice)
563- let bullsEarn = (priceUpGoodForBulls == priceGoesUp)
564- let newBullCol = if (bullsEarn)
565- then (bullCol + redist)
566- else (bullCol - redist)
567- let newBearCol = if (bullsEarn)
568- then (bearCol - redist)
569- else (bearCol + redist)
570- let $t01979219982 = poolSupport(newBullCol, newBearCol, bullCirc, bearCirc, poolMain, poolUp, poolDwn)
571- let updBullCol = $t01979219982._1
572- let updBearCol = $t01979219982._2
573- let updBullCirc = $t01979219982._3
574- let updBearCirc = $t01979219982._4
575- let updPoolMain = $t01979219982._5
576- let updPoolUp = $t01979219982._6
577- let updPoolDwn = $t01979219982._7
578-[IE(BULLCOLK, updBullCol), IE(BEARCOLK, updBearCol), IE(BULLCIRCK, updBullCirc), IE(BEARCIRCK, updBearCirc), IE(POOLUSDNK, updPoolMain), IE(POOLUPK, updPoolUp), IE(POOLDWNK, updPoolDwn), IE(REBIDXK, unsettledPriceIndex)]
579- }
580- }
581-
582-
583-func calcMax (min,avg) = if ((min > avg))
584- then throw(((("price too old: minPayout " + toString(min)) + " > avg = ") + toString(avg)))
585- else ((avg + avg) - min)
586-
42+let feeAddress = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, feeAddrKey), "no fee address")), "bad feeAddress")
58743
58844 func requestIssueInternal (inv,tokenId,minPayout) = throw("issuing of EURUP and EURDOWN is disabled")
58945
59046
591-func requestRedeemInternal (inv,minPayout) = {
592- let amt = inv.payments[0].amount
593- let tokenId = toBase58String(valueOrErrorMessage(inv.payments[0].assetId, "bad token att"))
594- if (if ((tokenId != BULL))
595- then (tokenId != BEAR)
596- else false)
597- then throw("bad token req")
598- else {
599- let $t02094021079 = if ((tokenId == BULL))
600- then $Tuple2(bullCol, bullCirc)
601- else if ((tokenId == BEAR))
602- then $Tuple2(bearCol, bearCirc)
603- else throw("bad token req")
604- let col = $t02094021079._1
605- let circ = $t02094021079._2
606- let est = fraction(amt, col, circ)
607- let $t02112721221 = if ((minPayout == 0))
608- then $Tuple2(0, MAX)
609- else $Tuple2(minPayout, calcMax(minPayout, est))
610- let minP = $t02112721221._1
611- let maxP = $t02112721221._2
612- if ((validateRequestRedeem(inv) == unit))
613- then enqueue(toBase58String(inv.transactionId), REDEEM, amt, tokenId, (oraclePriceIndex + 1), toString(inv.caller), minP, maxP)
614- else throw("doesn't happen")
47+func requestRedeemInternal (inv) = {
48+ let removedTokens = inv.payments[0].amount
49+ let tokenId = toBase58String(value(inv.payments[0].assetId))
50+ let invoker = inv.caller
51+ if ((tokenId == BULL))
52+ then {
53+ let payout = fraction(bullCol, removedTokens, bullCirc)
54+[IntegerEntry(BULLCOLK, (bullCol - payout)), IntegerEntry(BULLCIRCK, (bullCirc - removedTokens)), ScriptTransfer(invoker, payout, fromBase58String(mainToken))]
61555 }
56+ else if ((tokenId == BEAR))
57+ then {
58+ let payout = fraction(bearCol, removedTokens, bearCirc)
59+[IntegerEntry(BEARCOLK, (bearCol - payout)), IntegerEntry(BEARCIRCK, (bearCirc - removedTokens)), ScriptTransfer(invoker, payout, fromBase58String(mainToken))]
60+ }
61+ else throw("bad token attached")
61662 }
61763
61864
619-func requestPoolInternal (inv,minPayout) = if (!(allowed(inv.caller)))
620- then throw("only whitelisted can do")
621- else {
622- let errMessage = "USDN required"
623- let pmt = inv.payments[0]
624- if ((pmt.assetId != fromBase58String(mainToken)))
625- then throw(errMessage)
626- else if ((minPool > pmt.amount))
627- then throw(("pool min: " + toString(minPool)))
628- else {
629- let estimate = fraction(poolTokenCirculation, pmt.amount, poolValue)
630- let $t02201422113 = if ((minPayout == 0))
631- then $Tuple2(0, MAX)
632- else $Tuple2(minPayout, calcMax(minPayout, estimate))
633- let minP = $t02201422113._1
634- let maxP = $t02201422113._2
635- enqueue(toBase58String(inv.transactionId), POOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller), minP, maxP)
636- }
637- }
638-
639-
640-func requestUnpoolInternal (inv,minPayout) = {
641- let errMessage = (("only pool token allowed(" + poolToken) + ")")
642- let pmt = inv.payments[0]
643- if ((pmt.assetId != fromBase58String(poolToken)))
644- then throw(errMessage)
645- else {
646- let estimate = fraction(poolValue, pmt.amount, poolTokenCirculation)
647- if ((minPool > estimate))
648- then throw(((("unpool at least for" + toString(minPool)) + " ") + mainToken))
649- else {
650- let $t02277022869 = if ((minPayout == 0))
651- then $Tuple2(0, MAX)
652- else $Tuple2(minPayout, calcMax(minPayout, estimate))
653- let minP = $t02277022869._1
654- let maxP = $t02277022869._2
655- enqueue(toBase58String(inv.transactionId), UNPOOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller), minP, maxP)
656- }
657- }
65+@Callable(i)
66+func withdrawFee (amount) = {
67+ let acc = valueOrErrorMessage(getInteger(this, FEEACCK), "no fees acc")
68+ if ((amount > acc))
69+ then throw(("too much. available: " + toString(acc)))
70+ else [IntegerEntry(FEEACCK, (acc - amount)), ScriptTransfer(feeAddress, amount, fromBase58String(mainToken))]
65871 }
659-
660-
661-@Callable(inv)
662-func init (config,oraclePK,nameup,namedwn,descUp,descDwn,poolName,poolDesc,defoAssetName,denom,lev) = if (isDefined(getString(this, BULLK)))
663- then throw("already initialized")
664- else {
665- let totalOwnedMainToken = inv.payments[0].amount
666- let bulls = (totalOwnedMainToken / 3)
667- let bears = bulls
668- let pools = ((totalOwnedMainToken - bulls) - bears)
669- if (if (if ((bears == 0))
670- then true
671- else (bulls == 0))
672- then true
673- else (pools == 0))
674- then throw("can't init balances")
675- else {
676- let oracleCurrentPriceIndex = valueOrErrorMessage(getInteger(valueOrErrorMessage(addressFromPublicKey(fromBase58String(oraclePK)), "bad oracle address"), lastPriceIndexKey(defoAssetName)), "no last price index")
677- let bull = Issue(nameup, descUp, ((100 * ten6) * ten6), 6, true)
678- let bear = Issue(namedwn, descDwn, ((100 * ten6) * ten6), 6, true)
679- let pool = Issue(poolName, poolDesc, ((100 * ten6) * ten6), 6, true)
680- let buid = calculateAssetId(bull)
681- let beid = calculateAssetId(bear)
682- let poid = calculateAssetId(pool)
683-[bull, bear, pool, SE(BULLK, toBase58String(buid)), SE(BEARK, toBase58String(beid)), SE(USDNK, toBase58String(value(inv.payments[0].assetId))), SE(POOLK, toBase58String(poid)), SE(ASSNAMEK, defoAssetName), SE(oraclePKKey, oraclePK), IE(REBIDXK, oracleCurrentPriceIndex), IE(BULLCOLK, bulls), IE(BEARCOLK, bears), IE(BULLCIRCK, (bulls / denom)), IE(BEARCIRCK, (bears / denom)), IE(POOLCIRCK, (pools / denom)), IE(POOLDWNK, 0), IE(POOLUPK, 0), IE(POOLUSDNK, pools), SE(configProviderKey, config), IE(LEVK, lev), ST(inv.caller, (bulls / denom), buid), ST(inv.caller, (bears / denom), beid), ST(inv.caller, (pools / denom), poid)]
684- }
685- }
686-
687-
688-
689-@Callable(i)
690-func withdrawFee (amount) = if ((amount > feesAccumulated))
691- then throw(("too much. available: " + toString(feesAccumulated)))
692- else [IE(FEEACCK, (feesAccumulated - amount)), ST(feeAddress, amount, fromBase58String(mainToken))]
69372
69473
69574
69675 @Callable(inv)
697-func requestRedeem () = requestRedeemInternal(inv, 0)
76+func requestRedeem () = requestRedeemInternal(inv)
69877
69978
70079
70180 @Callable(inv)
702-func requestRedeemSl (sl) = if (validatePMFee(inv, sl))
703- then requestRedeemInternal(inv, sl)
704- else throw()
81+func requestRedeemSl (sl) = requestRedeemInternal(inv)
70582
70683
70784
70885 @Callable(inv)
709-func requestIssue (tokenId) = requestIssueInternal(inv, tokenId, 0)
86+func requestIssue (tokenId) = throw("issuing of EURUP and EURDOWN is disabled")
71087
71188
71289
71390 @Callable(inv)
714-func requestIssueSl (tokenId,sl) = if (validatePMFee(inv, sl))
715- then requestIssueInternal(inv, tokenId, sl)
716- else throw()
717-
718-
719-
720-@Callable(inv)
721-func requestPool () = requestPoolInternal(inv, 0)
722-
723-
724-
725-@Callable(inv)
726-func requestPoolSl (sl) = if (validatePMFee(inv, sl))
727- then requestPoolInternal(inv, sl)
728- else throw()
729-
730-
731-
732-@Callable(inv)
733-func requestUnpool () = requestUnpoolInternal(inv, 0)
734-
735-
736-
737-@Callable(inv)
738-func requestUnpoolSl (sl) = if (validatePMFee(inv, sl))
739- then requestUnpoolInternal(inv, sl)
740- else throw()
741-
742-
743-
744-@Callable(inv)
745-func settle () = {
746- let queueEmpty = (headPointer == "")
747- let canRebalance = (oraclePriceIndex > rebalancedPriceIndex)
748- if (queueEmpty)
749- then if (canRebalance)
750- then rebalance()
751- else throw("[OK] all done, carry on")
752- else {
753- let data = split(valueOrErrorMessage(getString(this, headPointer), ("bad head pointer(settle): " + headPointer)), "|")
754- let priceIndex = parseIntValue(data[3])
755- if ((priceIndex > rebalancedPriceIndex))
756- then if (canRebalance)
757- then rebalance()
758- else throw("[OK] need to wait")
759- else if ((priceIndex == rebalancedPriceIndex))
760- then dequeue()
761- else throw("future price already rebalanced")
762- }
763- }
91+func requestIssueSl (tokenId,sl) = throw("issuing of EURUP and EURDOWN is disabled")
76492
76593
76694 @Verifier(tx)
76795 func verify () = {
768- let initial = if (!(isDefined(getString(this, BULLK))))
769- then sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
770- else false
771- let adminAction = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(admins[0])))
96+ let adm = ["2HHqV8W9DJayV5R6tBD2Sb8srphpoboDi7r1t1aPiumC", "5ZXe82RRASU7qshXM2J9JNYhqJ9GWYjjVq2gwUV5Naz9", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
97+ ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(adm[0])))
77298 then 1
773- else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(admins[1])))
99+ else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(adm[1])))
774100 then 1
775- else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(admins[2])))
101+ else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(adm[2])))
776102 then 1
777103 else 0)) > 1)
778- let stakingAction = match tx {
779- case tx: InvokeScriptTransaction =>
780- let signedCorrectly = sigVerify(tx.bodyBytes, tx.proofs[0], daemonPublicKey)
781- let feesCorrect = if ((tx.feeAssetId == unit))
782- then ((1000 * 1000) >= tx.fee)
783- else false
784- let dappCorrect = (tx.dApp == rpdAddress)
785- let unlock = (tx.function == "unlockNeutrino")
786- let lock = if (if ((tx.function == "lockNeutrinoSP"))
787- then (tx.args[0] == stakingAddress)
788- else false)
789- then (wavesBalance(this).available >= ten8)
790- else false
791- let funcCorrect = if (lock)
792- then true
793- else unlock
794- if (if (if (signedCorrectly)
795- then feesCorrect
796- else false)
797- then dappCorrect
798- else false)
799- then funcCorrect
800- else false
801- case _ =>
802- false
803- }
804- if (if (initial)
805- then true
806- else adminAction)
807- then true
808- else stakingAction
809104 }
810105

github/deemru/w8io/6500d08 
99.32 ms