tx · GjVctdxeMZEvRrm783dvzbK9MACnyfsz8d2bNdweL8L6

3N4upXkARvecPGQAtpSQ11CFASTFsvEPiP2:  -0.01000000 Waves

2022.02.21 21:20 [1933775] smart account 3N4upXkARvecPGQAtpSQ11CFASTFsvEPiP2 > SELF 0.00000000 Waves

{ "type": 13, "id": "GjVctdxeMZEvRrm783dvzbK9MACnyfsz8d2bNdweL8L6", "fee": 1000000, "feeAssetId": null, "timestamp": 1645467639329, "version": 2, "chainId": 84, "sender": "3N4upXkARvecPGQAtpSQ11CFASTFsvEPiP2", "senderPublicKey": "5dTGvAkGC1ryvEkRCst923pqULtN3qWs6XXueerWos1D", "proofs": [ "2Q9Zg8xpKy3H1zrC5ho6vitwCrDoPUA6BRQpzdV5tTDxbcjk82yYCTuMRChJJYTncMoN1H3P5T9HkbYGcxe4FAqY" ], "script": "base64:AAIFAAAAAAAAAAcIAhIDCgEIAAAAAgAAAAAMa2V5Rmlyc3ROb2RlAgAAAAlmaXJzdE5vZGUAAAAACWZpcnN0Tm9kZQkABB0AAAACBQAAAAR0aGlzBQAAAAxrZXlGaXJzdE5vZGUAAAABAAAAAWkBAAAAC2luc2VydEZpcnN0AAAAAQAAAAJpZAQAAAAMc3RhdGVDaGFuZ2VzCQAETgAAAAIFAAAAA25pbAMJAQAAAAlpc0RlZmluZWQAAAABBQAAAAlmaXJzdE5vZGUJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkAASwAAAACBQAAAAJpZAIAAAAFX25leHQJAQAAAAV2YWx1ZQAAAAEFAAAACWZpcnN0Tm9kZQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQABLAAAAAIJAQAAAAV2YWx1ZQAAAAEFAAAACWZpcnN0Tm9kZQIAAAAFX3ByZXYFAAAAAmlkBQAAAANuaWwJAAROAAAAAgUAAAADbmlsCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAADGtleUZpcnN0Tm9kZQUAAAACaWQFAAAAA25pbAkABRQAAAACBQAAAAxzdGF0ZUNoYW5nZXMFAAAABHVuaXQAAAAAqa/AHw==", "height": 1933775, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: CAAN3NneZKMijyNsLNjYRTHEqaQ9Akjswa6QTNiE2ksY Next: GWLMnidYPvpS9dkDWYp18BuU6MfRQTDKuCHo5LLsuWtS Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let revisionNum = ""
4+let keyFirstNode = "firstNode"
55
6-let SEP = "__"
7-
8-let MAXDEPTH = 17
9-
10-let USERDEPTH = 26
11-
12-let SCALE = 1000
13-
14-func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
15-
16-
17-func getStringByKey (key) = valueOrElse(getString(this, key), "")
18-
19-
20-func getStringOrFail (key) = valueOrErrorMessage(getString(key), (("mandatory this." + key) + " is not defined"))
21-
22-
23-let IdxCfgNeutrinoContract = 1
24-
25-let IdxCfgNsbtLockContract = 2
26-
27-let IdxCfgMaxDepth = 3
28-
29-let IdxCfgPeriodDelay = 4
30-
31-func keyConfig () = "%s__config"
32-
33-
34-func readConfigArrayOrFail () = split(getStringOrFail(keyConfig()), SEP)
35-
36-
37-func formatConfig (neutrinoContractAddressStr,nsbtLockContractAddressStr,maxDepth,periodDelay) = makeString(["%s%s%d%d", neutrinoContractAddressStr, nsbtLockContractAddressStr, toString(maxDepth), toString(periodDelay)], SEP)
38-
39-
40-func keyUsersCount () = "%s__nextUserNum"
41-
42-
43-func keyMaxLockDuration () = "%s__maxLockDuration"
44-
45-
46-func keyNextProcessedUser () = "%s__nextProcessedUser"
47-
48-
49-func keyLatestPeriod () = "%s__latestPeriod"
50-
51-
52-func keyNextPeriod () = "%s__nextPeriod"
53-
54-
55-func keyNextProcessedPeriod () = "%s__nextProcessedPeriod"
56-
57-
58-func keyNextUnlaimedPeriodOfUser (userIndex) = makeString(["%s%d__nextClaimedPeriod", toString(userIndex)], SEP)
59-
60-
61-func keyLastProcessedPeriodOfUser (userIndex) = makeString(["%s%d__lastProcessedPeriod", toString(userIndex)], SEP)
62-
63-
64-func keyHeightForPeriod (period) = makeString(["%s%d__startHeightForPeriod", toString(period)], SEP)
65-
66-
67-func keyTotalAmountForPeriod (period,isWaves) = makeString([if (isWaves)
68- then "%s%d__totalWavesAmountForPeriod"
69- else "%s%d__totalUsdnAmountForPeriod", toString(period)], SEP)
70-
71-
72-func keyTotalAmount (isWaves) = if (isWaves)
73- then "%s__totalWavesAmount"
74- else "%s__totalUsdnAmount"
75-
76-
77-func keyTotalWeightForPeriod (period) = makeString(["%s%d__totalWeightForPeriod", toString(period)], SEP)
78-
79-
80-func keyUserKValueForPeriod (period,userIndex) = makeString(["%s%d%s%d__paramByPeriod", toString(userIndex), "k", toString(period)], SEP)
81-
82-
83-func keyUserBValueForPeriod (period,userIndex) = makeString(["%s%d%s%d__paramByPeriod", toString(userIndex), "b", toString(period)], SEP)
84-
85-
86-func HistoryEntry (type,user,usdnAmount,wavesAamount,currentPeriod,latestPeriod,i) = {
87- let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
88- let historyDATA = makeString(["%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(usdnAmount), toString(wavesAamount), toString(currentPeriod), toString(latestPeriod)], SEP)
89- StringEntry(historyKEY, historyDATA)
90- }
91-
92-
93-func getUsdnAssetId (neutrinoContractAddress) = valueOrErrorMessage(getString(neutrinoContractAddress, "neutrino_asset_id"), "mandatory key neutrino_asset_id is not defined")
94-
95-
96-func getNsbtAssetId (neutrinoContractAddress) = valueOrErrorMessage(getString(neutrinoContractAddress, "bond_asset_id"), "mandatory key bond_asset_id is not defined")
97-
98-
99-func calcUserWeight (nsbtLockContractAddress,heightForPeriod,period,userIndex) = {
100- let kLast = keyLastProcessedPeriodOfUser(userIndex)
101- let kKey = keyUserKValueForPeriod(period, userIndex)
102- let kRaw = getInteger(nsbtLockContractAddress, kKey)
103- if (isDefined(kRaw))
104- then {
105- let k = value(kRaw)
106- let b = value(getInteger(nsbtLockContractAddress, keyUserBValueForPeriod(period, userIndex)))
107- let w = ((k * heightForPeriod) + b)
108- if ((w > 0))
109- then $Tuple2((w / SCALE), [IntegerEntry(kLast, period)])
110- else $Tuple2(0, nil)
111- }
112- else {
113- let p = getInteger(this, kLast)
114- if (isDefined(p))
115- then {
116- let pv = value(p)
117- let k = value(getInteger(nsbtLockContractAddress, keyUserKValueForPeriod(pv, userIndex)))
118- let b = value(getInteger(nsbtLockContractAddress, keyUserBValueForPeriod(pv, userIndex)))
119- let w = ((k * heightForPeriod) + b)
120- if ((w > 0))
121- then $Tuple2((w / SCALE), nil)
122- else $Tuple2(0, nil)
123- }
124- else $Tuple2(0, nil)
125- }
126- }
127-
128-
129-func getUserIndexByAddress (nsbtLockContractAddressStr,userAddress) = {
130- let key = makeString(["%s%s%s", "mapping", "user2num", userAddress], SEP)
131- valueOrErrorMessage(getInteger(Address(fromBase58String(nsbtLockContractAddressStr)), key), ((("User address " + userAddress) + " is not found in nsbtLock contract data, key=") + key))
132- }
133-
134-
135-func nextPeriod () = getNumberByKey(keyNextPeriod())
136-
137-
138-func DepositEntry (period,pmt,finalize) = [IntegerEntry(keyLatestPeriod(), if (finalize)
139- then (period - 1)
140- else -1), IntegerEntry(keyHeightForPeriod(period), height), IntegerEntry(keyTotalAmountForPeriod(period, (pmt.assetId == unit)), pmt.amount), IntegerEntry(keyTotalAmount((pmt.assetId == unit)), (getNumberByKey(keyTotalAmount((pmt.assetId == unit))) + pmt.amount)), IntegerEntry(keyNextPeriod(), period)]
141-
142-
143-func invokeProcess (nsbtLockContract,period,user,depth,weight) = {
144- let result = invoke(this, "processNextBatch", [nsbtLockContract, period, user, depth, weight], nil)
145- if ((result == result))
146- then match result {
147- case r: (Int, Int, Int) =>
148- r
149- case _ =>
150- throw("Incorrect invoke result")
151- }
152- else throw("Strict value is not equal to itself.")
153- }
154-
155-
156-func processNextBatchInternal (nsbtLockContract,currentPeriod,currentUser,depth,totalWeight) = {
157- let nsbtLockContractAddress = Address(nsbtLockContract)
158- let latestPeriod = getNumberByKey(keyLatestPeriod())
159- let usersCount = valueOrElse(getInteger(nsbtLockContractAddress, keyUsersCount()), 0)
160- let totalWeightKey = keyTotalWeightForPeriod(currentPeriod)
161- let heightForPeriod = getNumberByKey(keyHeightForPeriod(currentPeriod))
162- if (if ((depth > 0))
163- then (latestPeriod >= currentPeriod)
164- else false)
165- then {
166- let t0 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, currentUser)
167- let weight0 = (totalWeight + t0._1)
168- if ((usersCount > (currentUser + 1)))
169- then {
170- let t1 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 1))
171- let weight1 = (weight0 + t1._1)
172- if ((usersCount > (currentUser + 2)))
173- then {
174- let t2 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 2))
175- let weight2 = (weight1 + t2._1)
176- if ((usersCount > (currentUser + 3)))
177- then {
178- let t3 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 3))
179- let weight3 = (weight2 + t3._1)
180- if ((usersCount > (currentUser + 4)))
181- then {
182- let t4 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 4))
183- let weight4 = (weight3 + t4._1)
184- if ((usersCount > (currentUser + 5)))
185- then {
186- let t5 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, (currentUser + 5))
187- let weight5 = (weight4 + t5._1)
188- if ((usersCount > (currentUser + 6)))
189- then {
190- let r5 = invokeProcess(nsbtLockContract, currentPeriod, (currentUser + 6), (depth - 1), weight5)
191- $Tuple4((((((t0._2 ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2) ++ t5._2), r5._1, r5._2, r5._3)
192- }
193- else $Tuple4((((((([IntegerEntry(totalWeightKey, weight5)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2) ++ t5._2), (currentPeriod + 1), 0, 0)
194- }
195- else $Tuple4(((((([IntegerEntry(totalWeightKey, weight4)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2) ++ t4._2), (currentPeriod + 1), 0, 0)
196- }
197- else $Tuple4((((([IntegerEntry(totalWeightKey, weight3)] ++ t0._2) ++ t1._2) ++ t2._2) ++ t3._2), (currentPeriod + 1), 0, 0)
198- }
199- else $Tuple4(((([IntegerEntry(totalWeightKey, weight2)] ++ t0._2) ++ t1._2) ++ t2._2), (currentPeriod + 1), 0, 0)
200- }
201- else $Tuple4((([IntegerEntry(totalWeightKey, weight1)] ++ t0._2) ++ t1._2), (currentPeriod + 1), 0, 0)
202- }
203- else $Tuple4(([IntegerEntry(totalWeightKey, weight0)] ++ t0._2), (currentPeriod + 1), 0, 0)
204- }
205- else if ((currentUser == 0))
206- then $Tuple4(nil, currentPeriod, 0, 0)
207- else $Tuple4([IntegerEntry(totalWeightKey, totalWeight)], currentPeriod, currentUser, 0)
208- }
209-
210-
211-func invokeClaim (nsbtLockContract,period,user,depth,totalUsdn,totalWaves) = {
212- let result = invoke(this, "claimNextBatch", [nsbtLockContract, period, user, depth, totalUsdn, totalWaves], nil)
213- if ((result == result))
214- then match result {
215- case r: (Int, Int, Int) =>
216- r
217- case _ =>
218- throw("Incorrect invoke result")
219- }
220- else throw("Strict value is not equal to itself.")
221- }
222-
223-
224-func claimInternal (nsbtLockContract,currentPeriod,currentUser,depth,userUsdnAccumulated,userWavesAccumulated) = {
225- let nsbtLockContractAddress = Address(nsbtLockContract)
226- let latestPeriod = getNumberByKey(keyNextProcessedPeriod())
227- let totalWeight = getNumberByKey(keyTotalWeightForPeriod(currentPeriod))
228- let heightForPeriod = getNumberByKey(keyHeightForPeriod(currentPeriod))
229- let $t01096311075 = calcUserWeight(nsbtLockContractAddress, heightForPeriod, currentPeriod, currentUser)
230- let userWeight = $t01096311075._1
231- let ignored = $t01096311075._2
232- let userUsdnAmountForPeriod = fraction(getNumberByKey(keyTotalAmountForPeriod(currentPeriod, false)), userWeight, totalWeight)
233- let userWavesAmountForPeriod = fraction(getNumberByKey(keyTotalAmountForPeriod(currentPeriod, true)), userWeight, totalWeight)
234- if (if ((0 >= depth))
235- then true
236- else ((currentPeriod + 1) >= latestPeriod))
237- then $Tuple3((currentPeriod + 1), (userUsdnAccumulated + userUsdnAmountForPeriod), (userWavesAccumulated + userWavesAmountForPeriod))
238- else invokeClaim(nsbtLockContract, (currentPeriod + 1), currentUser, (depth - 1), (userUsdnAccumulated + userUsdnAmountForPeriod), (userWavesAccumulated + userWavesAmountForPeriod))
239- }
240-
6+let firstNode = getString(this, keyFirstNode)
2417
2428 @Callable(i)
243-func processNextBatch (nsbtLockContract,currentPeriod,currentUser,depth,totalWeight) = if ((i.caller != this))
244- then throw("Should be called by this script only")
245- else {
246- let tpl = processNextBatchInternal(nsbtLockContract, currentPeriod, currentUser, depth, totalWeight)
247- $Tuple2(tpl._1, $Tuple3(tpl._2, tpl._3, tpl._4))
248- }
249-
250-
251-
252-@Callable(i)
253-func processPendingPeriodsAndUsers () = {
254- let currentPeriod = getNumberByKey(keyNextProcessedPeriod())
255- if ((currentPeriod > getNumberByKey(keyLatestPeriod())))
256- then throw("Nothing to process")
257- else {
258- let cfgArray = readConfigArrayOrFail()
259- let depth = parseIntValue(cfgArray[IdxCfgMaxDepth])
260- if ((depth > MAXDEPTH))
261- then throw("Depth exceeds MAXDEPTH")
262- else {
263- let nsbtLockContract = fromBase58String(cfgArray[IdxCfgNsbtLockContract])
264- let currentUser = getNumberByKey(keyNextProcessedUser())
265- let totalWeight = getNumberByKey(keyTotalWeightForPeriod(currentPeriod))
266- let r = processNextBatchInternal(nsbtLockContract, currentPeriod, currentUser, depth, totalWeight)
267- ((r._1 :+ IntegerEntry(keyNextProcessedPeriod(), r._2)) :+ IntegerEntry(keyNextProcessedUser(), r._3))
268- }
269- }
9+func insertFirst (id) = {
10+ let stateChanges = (nil ++ (if (isDefined(firstNode))
11+ then [StringEntry((id + "_next"), value(firstNode)), StringEntry((value(firstNode) + "_prev"), id)]
12+ else (nil ++ [StringEntry(keyFirstNode, id)])))
13+ $Tuple2(stateChanges, unit)
27014 }
271-
272-
273-
274-@Callable(i)
275-func deposit () = {
276- let cfgArray = readConfigArrayOrFail()
277- let neutrinoContract = Address(fromBase58String(cfgArray[IdxCfgNeutrinoContract]))
278- if ((i.caller != neutrinoContract))
279- then throw("Wrong caller address")
280- else {
281- let pmt = value(i.payments[0])
282- let assetId = pmt.assetId
283- let period = getNumberByKey(keyNextPeriod())
284- let hRaw = getInteger(this, keyHeightForPeriod(period))
285- let delay = parseIntValue(cfgArray[IdxCfgPeriodDelay])
286- if (!(isDefined(hRaw)))
287- then DepositEntry(period, pmt, false)
288- else if ((height >= (value(hRaw) + delay)))
289- then DepositEntry((period + 1), pmt, true)
290- else {
291- let keyAmount = keyTotalAmountForPeriod(period, (assetId == unit))
292-[IntegerEntry(keyAmount, (getNumberByKey(keyAmount) + pmt.amount)), IntegerEntry(keyTotalAmount((assetId == unit)), (getNumberByKey(keyTotalAmount((assetId == unit))) + pmt.amount))]
293- }
294- }
295- }
296-
297-
298-
299-@Callable(i)
300-func claimNextBatch (nsbtLockContract,currentPeriod,currentUser,depth,usdnAccumulated,wavesAccumulated) = if ((i.caller != this))
301- then throw("Should be called by this script only")
302- else {
303- let periodAndTotals = claimInternal(nsbtLockContract, currentPeriod, currentUser, depth, usdnAccumulated, wavesAccumulated)
304- $Tuple2(nil, periodAndTotals)
305- }
306-
307-
308-
309-@Callable(i)
310-func claimReward () = {
311- let cfgArray = readConfigArrayOrFail()
312- let address = toString(i.caller)
313- let userIdx = getUserIndexByAddress(cfgArray[IdxCfgNsbtLockContract], address)
314- let currentPeriod = getNumberByKey(keyNextUnlaimedPeriodOfUser(userIdx))
315- let latestPeriod = getNumberByKey(keyNextProcessedPeriod())
316- if ((currentPeriod >= latestPeriod))
317- then throw("Nothing to claim")
318- else {
319- let nsbtLockContract = fromBase58String(cfgArray[IdxCfgNsbtLockContract])
320- let $t01558715699 = claimInternal(nsbtLockContract, currentPeriod, userIdx, USERDEPTH, 0, 0)
321- let period = $t01558715699._1
322- let usdnAmount = $t01558715699._2
323- let wavesAmount = $t01558715699._3
324- if (if ((0 >= usdnAmount))
325- then (0 >= wavesAmount)
326- else false)
327- then throw("No payouts available")
328- else {
329- let neutrinoContract = Address(fromBase58String(cfgArray[IdxCfgNeutrinoContract]))
330- $Tuple2(([IntegerEntry(keyNextUnlaimedPeriodOfUser(userIdx), period), HistoryEntry("claimReward", address, usdnAmount, wavesAmount, period, latestPeriod, i)] ++ (if ((usdnAmount > 0))
331- then [ScriptTransfer(i.caller, usdnAmount, fromBase58String(getUsdnAssetId(neutrinoContract))), IntegerEntry(keyTotalAmount(false), (getNumberByKey(keyTotalAmount(false)) - usdnAmount))]
332- else (nil ++ (if ((wavesAmount > 0))
333- then [ScriptTransfer(i.caller, wavesAmount, unit), IntegerEntry(keyTotalAmount(true), (getNumberByKey(keyTotalAmount(true)) - wavesAmount))]
334- else nil)))), $Tuple2(usdnAmount, wavesAmount))
335- }
336- }
337- }
338-
339-
340-
341-@Callable(i)
342-func calcGovernanceParamsREADONLY (nsbtLockedAmount,lockStartHeight,lockDurationBlocks) = {
343- let cfgArray = readConfigArrayOrFail()
344- let nsbtLockContract = fromBase58String(cfgArray[IdxCfgNsbtLockContract])
345- let maxDuration = getIntegerValue(Address(nsbtLockContract), keyMaxLockDuration())
346- let lockEndHeight = (lockStartHeight + lockDurationBlocks)
347- let k = -(fraction(nsbtLockedAmount, SCALE, maxDuration))
348- let b = (-(k) * lockEndHeight)
349- $Tuple2(nil, [k, b, nextPeriod()])
350- }
351-
352-
353-
354-@Callable(i)
355-func getTotalRewardREADONLY () = $Tuple2(nil, [getNumberByKey(keyTotalAmount(false)), getNumberByKey(keyTotalAmount(true))])
356-
357-
358-
359-@Callable(i)
360-func paramsREADONLY () = {
361- let cfgArray = readConfigArrayOrFail()
362- let periodDelay = parseIntValue(cfgArray[IdxCfgPeriodDelay])
363- $Tuple2(nil, [periodDelay])
364- }
365-
366-
367-
368-@Callable(i)
369-func rewardsPerGNsbtForPeriodREADONLY (period) = {
370- let latestPeriod = getNumberByKey(keyLatestPeriod())
371- if (if ((0 > period))
372- then true
373- else (period > latestPeriod))
374- then throw("Invalid period")
375- else {
376- let totalWeight = getNumberByKey(keyTotalWeightForPeriod(period))
377- let $t01767317914 = if ((totalWeight > 0))
378- then $Tuple2((getNumberByKey(keyTotalAmountForPeriod(period, true)) / totalWeight), (getNumberByKey(keyTotalAmountForPeriod(period, false)) / totalWeight))
379- else $Tuple2(0, 0)
380- let wavesPerGNsbt = $t01767317914._1
381- let usdnPerGNsbt = $t01767317914._2
382- $Tuple2(nil, [wavesPerGNsbt, usdnPerGNsbt])
383- }
384- }
385-
386-
387-
388-@Callable(i)
389-func constructor (neutrinoContractAddressStr,nsbtLockContractAddressStr,maxDepth,periodDelay) = if ((this != i.caller))
390- then throw("not authorized")
391- else [StringEntry(keyConfig(), formatConfig(neutrinoContractAddressStr, nsbtLockContractAddressStr, maxDepth, periodDelay))]
39215
39316

github/deemru/w8io/169f3d6 
38.74 ms