tx · GdrRXWwTCaUfpvWwP2nJCwiycPCuXDsJYhrpntDzSEo5

3N4PzCkHU7VTJeNCPpT8w9XZLnjTsi2YMHN:  -0.01000000 Waves

2022.04.08 11:33 [1999356] smart account 3N4PzCkHU7VTJeNCPpT8w9XZLnjTsi2YMHN > SELF 0.00000000 Waves

{ "type": 13, "id": "GdrRXWwTCaUfpvWwP2nJCwiycPCuXDsJYhrpntDzSEo5", "fee": 1000000, "feeAssetId": null, "timestamp": 1649406892397, "version": 2, "chainId": 84, "sender": "3N4PzCkHU7VTJeNCPpT8w9XZLnjTsi2YMHN", "senderPublicKey": "2DVVUYkJNWCMHSCPWEXRjF3THHEdc5bVinyp2c4z8nV8", "proofs": [ "SLsB7ShW9MQcdJo4SWafNdpLRg7fVhx4ad6kUjpu8FcQ6JunVxupfYWpu3BHGWa595oPTBoBXZKgk5y6My9n1zL" ], "script": "base64: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", "height": 1999356, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: BtjiSioBKbapZmQ6YQ7Qo9PkFG2XkcuXTPQ2RuRmEY63 Next: none Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let stakeAmountThreshold = 1
5+
6+let lockPeriodsInDays = [1, 10, 30, 90, 180]
7+
8+let possibleTokensForRewards = ["REDSmb", "rBTC"]
9+
10+let hours24 = 86400000
11+
12+let apr8of2022 = 1649376000000
13+
14+let currentTimestamp = lastBlock.timestamp
15+
416 let keyInit = "init"
517
618 let keyAssetId = "assetId"
1931 func extractPaymentAmount (payments) = if ((size(payments) != 1))
2032 then throw("Single payment required")
2133 else if ((payments[0].assetId != assetId))
22- then throw("Payment should be in REDS token")
23- else if ((0 >= payments[0].amount))
24- then throw("Payment amount must be greater then 0")
34+ then throw("Only REDSmb token is accepted")
35+ else if ((stakeAmountThreshold > payments[0].amount))
36+ then throw(("Payment amount must be greater then threshold " + toString(stakeAmountThreshold)))
2537 else payments[0].amount
2638
2739
3951
4052
4153 @Callable(inv)
42-func stake () = {
54+func createNewStaking (forRewardIn,daysToMine) = {
4355 let callerStr = toString(inv.caller)
4456 let pmtAmount = extractPaymentAmount(inv.payments)
45- let currentStakeAmount = getCurrentStakedAmount(callerStr)
46-[IntegerEntry(keyStaked(callerStr), (currentStakeAmount + pmtAmount)), IntegerEntry(keyTotal, (totalStaked + pmtAmount))]
57+ let beginningOfNexDayTimestamp = ((currentTimestamp + hours24) - (currentTimestamp % hours24))
58+ let lockUntilTimestamp = (beginningOfNexDayTimestamp + (daysToMine * hours24))
59+ let stakingKey = ((callerStr + "_") + toBase58String(inv.transactionId))
60+ let stakingValue = makeString([toString(pmtAmount), forRewardIn, toString(daysToMine), toString(currentTimestamp), toString(lockUntilTimestamp)], ",")
61+ if (isDefined(getString(this, stakingKey)))
62+ then throw((("Staking '" + stakingKey) + "' already exists"))
63+ else if (!(containsElement(lockPeriodsInDays, daysToMine)))
64+ then throw((("Unsupported number of days " + toString(daysToMine)) + " to mine"))
65+ else if (!(containsElement(possibleTokensForRewards, forRewardIn)))
66+ then throw((("Unsupported reward type '" + forRewardIn) + "'"))
67+ else [StringEntry(stakingKey, stakingValue), IntegerEntry(keyTotal, (totalStaked + pmtAmount))]
4768 }
4869
4970
5071
5172 @Callable(inv)
52-func withdraw (amount) = {
53- let callerStr = toString(inv.caller)
54- let stakedByCaller = getCurrentStakedAmount(callerStr)
73+func withdraw (user,staking) = {
74+ let userAddress = valueOrErrorMessage(addressFromString(user), (("Can't parse user address '" + user) + "'"))
75+ func extractStaking (acc,txId) = {
76+ let parameters = {
77+ let val = split(valueOrErrorMessage(getString(this, ((user + "_") + txId)), ((("Staking " + txId) + " doesn't exist for user ") + user)), ",")
78+ if ((size(val) != 5))
79+ then throw(("Can't parse parameters of staking " + txId))
80+ else val
81+ }
82+ let $t035943682 = $Tuple2(parseIntValue(parameters[0]), parseIntValue(parameters[4]))
83+ let amount = $t035943682._1
84+ let lockUntil = $t035943682._2
85+ if ((lockUntil > currentTimestamp))
86+ then throw(((("Unable to withdraw staking " + txId) + " because it is still locked until ") + toString(lockUntil)))
87+ else $Tuple2((acc._1 :+ DeleteEntry(((user + "_") + txId))), (acc._2 + amount))
88+ }
89+
90+ let $t039424020 = {
91+ let $l = staking
92+ let $s = size($l)
93+ let $acc0 = $Tuple2(nil, 0)
94+ func $f0_1 ($a,$i) = if (($i >= $s))
95+ then $a
96+ else extractStaking($a, $l[$i])
97+
98+ func $f0_2 ($a,$i) = if (($i >= $s))
99+ then $a
100+ else throw("List size exceeds 10")
101+
102+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
103+ }
104+ let unstakeList = $t039424020._1
105+ let totalUnstaked = $t039424020._2
55106 if ((size(inv.payments) != 0))
56107 then throw("There should be no payments for this function")
57- else if ((0 >= amount))
58- then throw("Amount must be positive")
59- else if ((amount > totalStaked))
60- then throw("You cannot withdraw more funds than total staked on the dApp")
61- else if ((amount > stakedByCaller))
62- then throw("You don't have enough staked funds available to withdraw")
63- else [if ((amount == stakedByCaller))
64- then DeleteEntry(keyStaked(callerStr))
65- else IntegerEntry(keyStaked(callerStr), (stakedByCaller - amount)), IntegerEntry(keyTotal, (totalStaked - amount)), ScriptTransfer(inv.caller, amount, assetId)]
108+ else if (if ((inv.caller != this))
109+ then (userAddress != inv.caller)
110+ else false)
111+ then throw("Only users themselves can withdraw their unlocked staking, or admin for them")
112+ else (unstakeList ++ [IntegerEntry(keyTotal, (totalStaked - totalUnstaked)), ScriptTransfer(userAddress, totalUnstaked, assetId)])
66113 }
67114
68115
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let stakeAmountThreshold = 1
5+
6+let lockPeriodsInDays = [1, 10, 30, 90, 180]
7+
8+let possibleTokensForRewards = ["REDSmb", "rBTC"]
9+
10+let hours24 = 86400000
11+
12+let apr8of2022 = 1649376000000
13+
14+let currentTimestamp = lastBlock.timestamp
15+
416 let keyInit = "init"
517
618 let keyAssetId = "assetId"
719
820 let keyTotal = "staked_total"
921
1022 func keyStaked (address) = address
1123
1224
1325 let isInit = valueOrElse(getBoolean(this, keyInit), false)
1426
1527 let assetId = fromBase58String(getStringValue(this, keyAssetId))
1628
1729 let totalStaked = valueOrErrorMessage(getInteger(this, keyTotal), (("Can't read field '" + keyTotal) + "'"))
1830
1931 func extractPaymentAmount (payments) = if ((size(payments) != 1))
2032 then throw("Single payment required")
2133 else if ((payments[0].assetId != assetId))
22- then throw("Payment should be in REDS token")
23- else if ((0 >= payments[0].amount))
24- then throw("Payment amount must be greater then 0")
34+ then throw("Only REDSmb token is accepted")
35+ else if ((stakeAmountThreshold > payments[0].amount))
36+ then throw(("Payment amount must be greater then threshold " + toString(stakeAmountThreshold)))
2537 else payments[0].amount
2638
2739
2840 func getCurrentStakedAmount (user) = valueOrElse(getInteger(this, keyStaked(user)), 0)
2941
3042
3143 @Callable(inv)
3244 func init (hashrateAssetId) = {
3345 let newAssetId = valueOrErrorMessage(assetInfo(fromBase58String(hashrateAssetId)), "Can't find asset").id
3446 if (isInit)
3547 then throw("DApp is already init")
3648 else [BooleanEntry(keyInit, true), StringEntry("assetId", toBase58String(newAssetId)), IntegerEntry(keyTotal, 0)]
3749 }
3850
3951
4052
4153 @Callable(inv)
42-func stake () = {
54+func createNewStaking (forRewardIn,daysToMine) = {
4355 let callerStr = toString(inv.caller)
4456 let pmtAmount = extractPaymentAmount(inv.payments)
45- let currentStakeAmount = getCurrentStakedAmount(callerStr)
46-[IntegerEntry(keyStaked(callerStr), (currentStakeAmount + pmtAmount)), IntegerEntry(keyTotal, (totalStaked + pmtAmount))]
57+ let beginningOfNexDayTimestamp = ((currentTimestamp + hours24) - (currentTimestamp % hours24))
58+ let lockUntilTimestamp = (beginningOfNexDayTimestamp + (daysToMine * hours24))
59+ let stakingKey = ((callerStr + "_") + toBase58String(inv.transactionId))
60+ let stakingValue = makeString([toString(pmtAmount), forRewardIn, toString(daysToMine), toString(currentTimestamp), toString(lockUntilTimestamp)], ",")
61+ if (isDefined(getString(this, stakingKey)))
62+ then throw((("Staking '" + stakingKey) + "' already exists"))
63+ else if (!(containsElement(lockPeriodsInDays, daysToMine)))
64+ then throw((("Unsupported number of days " + toString(daysToMine)) + " to mine"))
65+ else if (!(containsElement(possibleTokensForRewards, forRewardIn)))
66+ then throw((("Unsupported reward type '" + forRewardIn) + "'"))
67+ else [StringEntry(stakingKey, stakingValue), IntegerEntry(keyTotal, (totalStaked + pmtAmount))]
4768 }
4869
4970
5071
5172 @Callable(inv)
52-func withdraw (amount) = {
53- let callerStr = toString(inv.caller)
54- let stakedByCaller = getCurrentStakedAmount(callerStr)
73+func withdraw (user,staking) = {
74+ let userAddress = valueOrErrorMessage(addressFromString(user), (("Can't parse user address '" + user) + "'"))
75+ func extractStaking (acc,txId) = {
76+ let parameters = {
77+ let val = split(valueOrErrorMessage(getString(this, ((user + "_") + txId)), ((("Staking " + txId) + " doesn't exist for user ") + user)), ",")
78+ if ((size(val) != 5))
79+ then throw(("Can't parse parameters of staking " + txId))
80+ else val
81+ }
82+ let $t035943682 = $Tuple2(parseIntValue(parameters[0]), parseIntValue(parameters[4]))
83+ let amount = $t035943682._1
84+ let lockUntil = $t035943682._2
85+ if ((lockUntil > currentTimestamp))
86+ then throw(((("Unable to withdraw staking " + txId) + " because it is still locked until ") + toString(lockUntil)))
87+ else $Tuple2((acc._1 :+ DeleteEntry(((user + "_") + txId))), (acc._2 + amount))
88+ }
89+
90+ let $t039424020 = {
91+ let $l = staking
92+ let $s = size($l)
93+ let $acc0 = $Tuple2(nil, 0)
94+ func $f0_1 ($a,$i) = if (($i >= $s))
95+ then $a
96+ else extractStaking($a, $l[$i])
97+
98+ func $f0_2 ($a,$i) = if (($i >= $s))
99+ then $a
100+ else throw("List size exceeds 10")
101+
102+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
103+ }
104+ let unstakeList = $t039424020._1
105+ let totalUnstaked = $t039424020._2
55106 if ((size(inv.payments) != 0))
56107 then throw("There should be no payments for this function")
57- else if ((0 >= amount))
58- then throw("Amount must be positive")
59- else if ((amount > totalStaked))
60- then throw("You cannot withdraw more funds than total staked on the dApp")
61- else if ((amount > stakedByCaller))
62- then throw("You don't have enough staked funds available to withdraw")
63- else [if ((amount == stakedByCaller))
64- then DeleteEntry(keyStaked(callerStr))
65- else IntegerEntry(keyStaked(callerStr), (stakedByCaller - amount)), IntegerEntry(keyTotal, (totalStaked - amount)), ScriptTransfer(inv.caller, amount, assetId)]
108+ else if (if ((inv.caller != this))
109+ then (userAddress != inv.caller)
110+ else false)
111+ then throw("Only users themselves can withdraw their unlocked staking, or admin for them")
112+ else (unstakeList ++ [IntegerEntry(keyTotal, (totalStaked - totalUnstaked)), ScriptTransfer(userAddress, totalUnstaked, assetId)])
66113 }
67114
68115

github/deemru/w8io/169f3d6 
28.99 ms