tx · DPDfhm8NCXXzVcfNAew3vix8XWAG7ZzoGaJuRo1MRYGN

3MqK3QivUqcHSqrFc9xujtfQm5V23muXK8V:  -0.14000000 Waves

2022.05.18 12:03 [2056890] smart account 3MqK3QivUqcHSqrFc9xujtfQm5V23muXK8V > SELF 0.00000000 Waves

{ "type": 13, "id": "DPDfhm8NCXXzVcfNAew3vix8XWAG7ZzoGaJuRo1MRYGN", "fee": 14000000, "feeAssetId": null, "timestamp": 1652864465212, "version": 2, "chainId": 84, "sender": "3MqK3QivUqcHSqrFc9xujtfQm5V23muXK8V", "senderPublicKey": "fQPbnv8c6teuJQb4xTtny9SsaxUFGZsANEVjZaNDWdj", "proofs": [ "61pnwkCsiHxGZp3yB2dSWekLY5Rtq4B45F5MtJLUC2A4RwXPUdV6V3wH168QCFpWq7DHNGT1v5H8v6uBgCcXRDmZ", "4bbGJKpmsutS7mgdc9G1HvdAacquqFdtwvQXVqsSed45Rnqrj3MEX89xGaW11EJKcDvXatueE2MYK2tiG4Ddms9" ], "script": "base64:AAIFAAAAAAAAABMIAhIECgIIGBIAEgASBQoDBAEIAAAAIgAAAAAHa0FjdGl2ZQIAAAAGYWN0aXZlAAAAAAZrQ2F1c2UCAAAADnNodXRkb3duX2NhdXNlAAAAAAxrVVNETkFkZHJlc3MCAAAAGHN0YWtpbmdfdXNkbm5zYnRfYWRkcmVzcwAAAAAMa0VVUk5BZGRyZXNzAgAAABRzdGFraW5nX2V1cm5fYWRkcmVzcwAAAAAMa0xlYXNpbmdQb29sAgAAAA9sZWFzaW5nX2FkZHJlc3MAAAAADmtMZWFzaW5nQW1vdW50AgAAAA5sZWFzaW5nX2Ftb3VudAAAAAAKa0xlYXNpbmdJZAIAAAAKbGVhc2luZ19pZAAAAAANa0FkbWluUHViS2V5MQIAAAALYWRtaW5fcHViXzEAAAAADWtBZG1pblB1YktleTICAAAAC2FkbWluX3B1Yl8yAAAAAA1rQWRtaW5QdWJLZXkzAgAAAAthZG1pbl9wdWJfMwAAAAASa0FkbWluSW52b2tlUHViS2V5AgAAABBhZG1pbl9pbnZva2VfcHViAAAAAA1rQ3BtbUNvbnRyYWN0AgAAAA1jcG1tX2NvbnRyYWN0AAAAAAxrVVNETkFzc2V0SWQCAAAADXVzZG5fYXNzZXRfaWQAAAAADGtFVVJOQXNzZXRJZAIAAAANZXVybl9hc3NldF9pZAAAAAAOa1N0YWtpbmdBc3NldHMCAAAADnN0YWtpbmdfYXNzZXRzAAAAAAZvcmFjbGUJAQAAAAdBZGRyZXNzAAAAAQEAAAAaAVTpRaoekC86rvG6DuYumpJfGpiE4fNiswgBAAAAE2dldEJhc2U1OEZyb21PcmFjbGUAAAABAAAAA2tleQQAAAAHJG1hdGNoMAkABB0AAAACBQAAAAZvcmFjbGUFAAAAA2tleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAGU3RyaW5nBAAAAAZzdHJpbmcFAAAAByRtYXRjaDAJAAJZAAAAAQUAAAAGc3RyaW5nBAAAAAdub3RoaW5nBQAAAAckbWF0Y2gwCQAAAgAAAAEJAAEsAAAAAgUAAAADa2V5AgAAAAhpcyBlbXB0eQAAAAAMYWRtaW5QdWJLZXkxCQEAAAATZ2V0QmFzZTU4RnJvbU9yYWNsZQAAAAEFAAAADWtBZG1pblB1YktleTEAAAAADGFkbWluUHViS2V5MgkBAAAAE2dldEJhc2U1OEZyb21PcmFjbGUAAAABBQAAAA1rQWRtaW5QdWJLZXkyAAAAAAxhZG1pblB1YktleTMJAQAAABNnZXRCYXNlNThGcm9tT3JhY2xlAAAAAQUAAAANa0FkbWluUHViS2V5MwAAAAARYWRtaW5QdWJLZXlJbnZva2UJAQAAABNnZXRCYXNlNThGcm9tT3JhY2xlAAAAAQUAAAASa0FkbWluSW52b2tlUHViS2V5AAAAABJzdGFraW5nVVNETkFkZHJlc3MJAQAAAAdBZGRyZXNzAAAAAQkBAAAAE2dldEJhc2U1OEZyb21PcmFjbGUAAAABBQAAAAxrVVNETkFkZHJlc3MAAAAAEnN0YWtpbmdFVVJOQWRkcmVzcwkBAAAAB0FkZHJlc3MAAAABCQEAAAATZ2V0QmFzZTU4RnJvbU9yYWNsZQAAAAEFAAAADGtFVVJOQWRkcmVzcwAAAAAMY3BtbUNvbnRyYWN0CQEAAAAHQWRkcmVzcwAAAAEJAQAAABNnZXRCYXNlNThGcm9tT3JhY2xlAAAAAQUAAAANa0NwbW1Db250cmFjdAAAAAAEVVNETgkBAAAAE2dldEJhc2U1OEZyb21PcmFjbGUAAAABBQAAAAxrVVNETkFzc2V0SWQAAAAABEVVUk4JAQAAABNnZXRCYXNlNThGcm9tT3JhY2xlAAAAAQUAAAAMa0VVUk5Bc3NldElkAAAAAA1zdGFraW5nQXNzZXRzCQEAAAARQGV4dHJOYXRpdmUoMTA1MykAAAACBQAAAAZvcmFjbGUFAAAADmtTdGFraW5nQXNzZXRzAAAAAAZhY3RpdmUJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQbAAAAAgUAAAAEdGhpcwUAAAAHa0FjdGl2ZQYBAAAACGlzQWN0aXZlAAAAAAMFAAAABmFjdGl2ZQUAAAAEdW5pdAkAAAIAAAABAgAAAB9EQXBwIGlzIGluYWN0aXZlIGF0IHRoaXMgbW9tZW50AQAAAAdzdXNwZW5kAAAAAQAAAAVjYXVzZQkABEwAAAACCQEAAAAMQm9vbGVhbkVudHJ5AAAAAgUAAAAHa0FjdGl2ZQcJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAGa0NhdXNlBQAAAAVjYXVzZQUAAAADbmlsAQAAABhjYWxjU3Rha2luZ0Z1bmNBbmRBZGRyZXMAAAACAAAABXN0YWtlAAAAB2Fzc2V0SWQDBQAAAAVzdGFrZQMJAAAAAAAAAgUAAAAHYXNzZXRJZAUAAAAEVVNETgkABRQAAAACAgAAAAxsb2NrTmV1dHJpbm8FAAAAEnN0YWtpbmdVU0ROQWRkcmVzcwkABRQAAAACAgAAAAxzdGFydFN0YWtpbmcFAAAAEnN0YWtpbmdFVVJOQWRkcmVzcwMJAAAAAAAAAgUAAAAHYXNzZXRJZAUAAAAEVVNETgkABRQAAAACAgAAAA51bmxvY2tOZXV0cmlubwUAAAASc3Rha2luZ1VTRE5BZGRyZXNzCQAFFAAAAAICAAAAC3N0b3BTdGFraW5nBQAAABJzdGFraW5nRVVSTkFkZHJlc3MBAAAAEWNhbGNTdGFraW5nUGFyYW1zAAAAAwAAAAVzdGFrZQAAAAZhbW91bnQAAAAHYXNzZXRJZAMFAAAABXN0YWtlBAAAAAskdDAyMTEzMjE3OQkBAAAAGGNhbGNTdGFraW5nRnVuY0FuZEFkZHJlcwAAAAIFAAAABXN0YWtlBQAAAAdhc3NldElkBAAAAARjYWxsCAUAAAALJHQwMjExMzIxNzkAAAACXzEEAAAAC3N0YWtpbmdBZGRyCAUAAAALJHQwMjExMzIxNzkAAAACXzIJAAUWAAAABAUAAAAEY2FsbAUAAAALc3Rha2luZ0FkZHIFAAAAA25pbAkABEwAAAACCQEAAAAPQXR0YWNoZWRQYXltZW50AAAAAgUAAAAHYXNzZXRJZAUAAAAGYW1vdW50BQAAAANuaWwEAAAACyR0MDIyNjUyMzMxCQEAAAAYY2FsY1N0YWtpbmdGdW5jQW5kQWRkcmVzAAAAAgUAAAAFc3Rha2UFAAAAB2Fzc2V0SWQEAAAABGNhbGwIBQAAAAskdDAyMjY1MjMzMQAAAAJfMQQAAAALc3Rha2luZ0FkZHIIBQAAAAskdDAyMjY1MjMzMQAAAAJfMgkABRYAAAAEBQAAAARjYWxsBQAAAAtzdGFraW5nQWRkcgkABEwAAAACBQAAAAZhbW91bnQJAARMAAAAAgkAAlgAAAABBQAAAAdhc3NldElkBQAAAANuaWwFAAAAA25pbAEAAAAPY29sbGVjdFBheW1l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", "height": 2056890, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: Arckk8ud3k5zQVnbdK2uSD8W6eDysh9hLWvchk9Nfz4Z Next: 3RDKHEirazGbU99iECJ7GcBZTtYYUGaJP11k9eiAEo21 Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let version = "1.0.0"
5-
6-let kVersion = "version"
7-
84 let kActive = "active"
95
10-let kAssetIdA = "A_asset_id"
11-
12-let kAssetIdB = "B_asset_id"
13-
14-let kBalanceA = "A_asset_balance"
15-
16-let kBalanceB = "B_asset_balance"
17-
18-let kBalanceInitA = "A_asset_init"
19-
20-let kBalanceInitB = "B_asset_init"
21-
22-let kShareAssetId = "share_asset_id"
23-
24-let kShareAssetSupply = "share_asset_supply"
25-
26-let kFee = "commission"
27-
286 let kCause = "shutdown_cause"
29-
30-let kFirstHarvest = "first_harvest"
31-
32-let kFirstHarvestHeight = "first_harvest_height"
33-
34-let kShareLimit = "share_limit_on_first_harvest"
35-
36-let kBasePeriod = "base_period"
37-
38-let kPeriodLength = "period_length"
39-
40-let kStartHeight = "start_height"
417
428 let kUSDNAddress = "staking_usdnnsbt_address"
439
5723
5824 let kAdminInvokePubKey = "admin_invoke_pub"
5925
60-let kMoneyBoxAddress = "money_box_address"
26+let kCpmmContract = "cpmm_contract"
27+
28+let kUSDNAssetId = "usdn_asset_id"
29+
30+let kEURNAssetId = "eurn_asset_id"
31+
32+let kStakingAssets = "staking_assets"
6133
6234 let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
6335
7547
7648 let adminPubKey3 = getBase58FromOracle(kAdminPubKey3)
7749
78-let adminInvokePubKey = getBase58FromOracle(kAdminInvokePubKey)
79-
80-let moneyBoxAddress = Address(getBase58FromOracle(kMoneyBoxAddress))
81-
82-let votingAddress = Address(base58'3MrJgdL1GniipErHy44YF9idzLaUL2iX5DQ')
83-
84-let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
85-
86-let SWOP = base58'2HAJrwa8q4SxBx9cHYaBTQdBjdk5wwqdof7ccpAx2uhZ'
87-
88-let EURN = base58'ECBCkHS68DckpBrzLeoRgYbFg7sCVqR176mPqbXsj9pA'
89-
90-let stakingAssets = ["WAVES", toBase58String(USDN), toBase58String(EURN)]
50+let adminPubKeyInvoke = getBase58FromOracle(kAdminInvokePubKey)
9151
9252 let stakingUSDNAddress = Address(getBase58FromOracle(kUSDNAddress))
9353
9454 let stakingEURNAddress = Address(getBase58FromOracle(kEURNAddress))
9555
96-let basePeriod = valueOrErrorMessage(getInteger(votingAddress, kBasePeriod), "Empty kBasePeriod")
56+let cpmmContract = Address(getBase58FromOracle(kCpmmContract))
9757
98-let startHeight = valueOrErrorMessage(getInteger(votingAddress, kStartHeight), "Empty kStartHeight")
58+let USDN = getBase58FromOracle(kUSDNAssetId)
9959
100-let periodLength = valueOrErrorMessage(getInteger(votingAddress, kPeriodLength), "Empty kPeriodLength")
60+let EURN = getBase58FromOracle(kEURNAssetId)
10161
102-let firstHarvestEndPeriod = ((basePeriod + ((height - startHeight) / periodLength)) + 3)
62+let stakingAssets = getStringValue(oracle, kStakingAssets)
10363
104-let active = getBooleanValue(this, kActive)
64+let active = valueOrElse(getBoolean(this, kActive), true)
10565
106-let strAssetIdA = getStringValue(this, kAssetIdA)
107-
108-let strAssetIdB = getStringValue(this, kAssetIdB)
109-
110-let assetIdA = if ((strAssetIdA == "WAVES"))
66+func isActive () = if (active)
11167 then unit
112- else fromBase58String(strAssetIdA)
113-
114-let assetIdB = if ((strAssetIdB == "WAVES"))
115- then unit
116- else fromBase58String(strAssetIdB)
117-
118-let assetNameA = match assetIdA {
119- case id: ByteVector =>
120- value(assetInfo(id)).name
121- case waves: Unit =>
122- "WAVES"
123- case _ =>
124- throw("Match error")
125-}
126-
127-let assetNameB = match assetIdB {
128- case id: ByteVector =>
129- value(assetInfo(id)).name
130- case waves: Unit =>
131- "WAVES"
132- case _ =>
133- throw("Match error")
134-}
135-
136-let balanceA = getIntegerValue(this, kBalanceA)
137-
138-let balanceB = getIntegerValue(this, kBalanceB)
139-
140-let shareAssetId = fromBase58String(getStringValue(this, kShareAssetId))
141-
142-let shareAssetSupply = getIntegerValue(this, kShareAssetSupply)
143-
144-let fee = getIntegerValue(this, kFee)
145-
146-let feeGovernance = fraction(fee, 40, 100)
147-
148-let feeScale6 = 1000000
149-
150-let scaleValue3 = 1000
151-
152-let scaleValue8 = 100000000
153-
154-let slippageToleranceDelimiter = 1000
155-
156-let scaleValue8Digits = 8
157-
158-func accountBalance (assetId) = match assetId {
159- case id: ByteVector =>
160- assetBalance(this, id)
161- case waves: Unit =>
162- wavesBalance(this).available
163- case _ =>
164- throw("Match error")
165-}
166-
167-
168-func stakedAmount (assetId) = {
169- let stakedAmountCalculated = match assetId {
170- case aId: ByteVector =>
171- if ((aId == USDN))
172- then getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
173- else if ((aId == EURN))
174- then getInteger(stakingEURNAddress, ((("%s%s%s__stakingBalance__" + toBase58String(aId)) + "__") + toString(this)))
175- else 0
176- case _: Unit =>
177- valueOrElse(getInteger(this, kLeasingAmount), 0)
178- case _ =>
179- throw("Match error")
180- }
181- match stakedAmountCalculated {
182- case i: Int =>
183- i
184- case _ =>
185- 0
186- }
187- }
188-
189-
190-let stakedAmountA = stakedAmount(assetIdA)
191-
192-let stakedAmountB = stakedAmount(assetIdB)
193-
194-let assetInitA = getIntegerValue(this, kBalanceInitA)
195-
196-let assetInitB = getIntegerValue(this, kBalanceInitB)
197-
198-let availableBalanceA = (balanceA - stakedAmountA)
199-
200-let availableBalanceB = (balanceB - stakedAmountB)
201-
202-let accountBalanceWithStakedA = (accountBalance(assetIdA) + stakedAmountA)
203-
204-let accountBalanceWithStakedB = (accountBalance(assetIdB) + stakedAmountB)
205-
206-let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA))
207- then (accountBalanceWithStakedB >= balanceB)
208- else false
209-
210-func getAssetInfo (assetId) = match assetId {
211- case id: ByteVector =>
212- let stringId = toBase58String(id)
213- let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
214- $Tuple3(stringId, info.name, info.decimals)
215- case waves: Unit =>
216- $Tuple3("WAVES", "WAVES", 8)
217- case _ =>
218- throw("Match error")
219-}
220-
221-
222-func getAssetInfoFromString (assetStr) = if ((assetStr == "WAVES"))
223- then $Tuple3("WAVES", "WAVES", 8)
224- else {
225- let stringId = assetStr
226- let id = fromBase58String(assetStr)
227- let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
228- $Tuple3(stringId, info.name, info.decimals)
229- }
68+ else throw("DApp is inactive at this moment")
23069
23170
23271 func suspend (cause) = [BooleanEntry(kActive, false), StringEntry(kCause, cause)]
24382
24483 func calcStakingParams (stake,amount,assetId) = if (stake)
24584 then {
246- let $t060896155 = calcStakingFuncAndAddres(stake, assetId)
247- let call = $t060896155._1
248- let stakingAddr = $t060896155._2
85+ let $t021132179 = calcStakingFuncAndAddres(stake, assetId)
86+ let call = $t021132179._1
87+ let stakingAddr = $t021132179._2
24988 $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
25089 }
25190 else {
252- let $t062416307 = calcStakingFuncAndAddres(stake, assetId)
253- let call = $t062416307._1
254- let stakingAddr = $t062416307._2
91+ let $t022652331 = calcStakingFuncAndAddres(stake, assetId)
92+ let call = $t022652331._1
93+ let stakingAddr = $t022652331._2
25594 $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
25695 }
25796
25897
259-func calculateFees (pmtAmount,minAmountToReceive,tokenFrom,tokenTo) = {
260- let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
261- let amountWithFee = fraction(amountWithoutFee, (feeScale6 - fee), feeScale6)
262- let governanceReward = fraction(amountWithoutFee, feeGovernance, feeScale6)
263- if ((minAmountToReceive > amountWithFee))
264- then throw(((("Calculated amount to receive " + toString(amountWithFee)) + " is less than specified minimum ") + toString(minAmountToReceive)))
265- else $Tuple3(amountWithoutFee, amountWithFee, governanceReward)
98+func collectPayments (acc,payment) = {
99+ let $t024932536 = acc
100+ let paymentAmounts = $t024932536._1
101+ let paymentAssetIds = $t024932536._2
102+ $Tuple2((paymentAmounts :+ payment.amount), (paymentAssetIds :+ payment.assetId))
266103 }
267104
268105
269-func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(accountBalanceWithStakedA)) + " ") + assetNameA) + ", ") + toString(accountBalanceWithStakedB)) + " ") + assetNameB) + ". State: ") + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB))
270-
271-
272-func isActive () = if (active)
273- then unit
274- else throw("DApp is inactive at this moment")
106+func collectState (result,source) = match source {
107+ case e: Issue|Burn|Reissue|ScriptTransfer|BinaryEntry|BooleanEntry|StringEntry|IntegerEntry =>
108+ (result :+ e)
109+ case _ =>
110+ result
111+}
275112
276113
277114 @Callable(i)
278-func init (firstHarvest) = {
279- let $t074187495 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
280- let pmtAmountA = $t074187495._1
281- let pmtAssetIdA = $t074187495._2
282- let $t075007577 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
283- let pmtAmountB = $t075007577._1
284- let pmtAssetIdB = $t075007577._2
285- let $t075827659 = getAssetInfo(pmtAssetIdA)
286- let pmtStrAssetIdA = $t075827659._1
287- let pmtAssetNameA = $t075827659._2
288- let pmtDecimalsA = $t075827659._3
289- let $t076647741 = getAssetInfo(pmtAssetIdB)
290- let pmtStrAssetIdB = $t076647741._1
291- let pmtAssetNameB = $t076647741._2
292- let pmtDecimalsB = $t076647741._3
293- if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminInvokePubKey], i.callerPublicKey)))
294- then throw("Only admin can call this function")
295- else if (isDefined(getBoolean(this, kActive)))
296- then throw("DApp is already active")
297- else if ((pmtAssetIdA == pmtAssetIdB))
298- then throw("Assets must be different")
299- else {
300- let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
301- let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
302- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
303- let arg1 = pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN)
304- let arg2 = pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN)
305- let arg3 = pow(10, 0, shareDecimals, 0, 0, DOWN)
306- let shareInitialSupply = fraction(arg1, arg2, arg3)
307- let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
308- let shareIssueId = calculateAssetId(shareIssue)
309- let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
310- then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
311- else 0
312- if ((stake1 == stake1))
313- then {
314- let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
315- then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
316- else 0
317- if ((stake2 == stake2))
318- then {
319- let baseEntry = [StringEntry(kVersion, version), BooleanEntry(kActive, true), StringEntry(kAssetIdA, pmtStrAssetIdA), StringEntry(kAssetIdB, pmtStrAssetIdB), IntegerEntry(kBalanceA, pmtAmountA), IntegerEntry(kBalanceB, pmtAmountB), IntegerEntry(kFee, getIntegerValue(oracle, "base_fee_cpmm")), shareIssue, StringEntry(kShareAssetId, toBase58String(shareIssueId)), IntegerEntry(kShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
320- if (firstHarvest)
321- then (baseEntry ++ [BooleanEntry(kFirstHarvest, firstHarvest), IntegerEntry(kFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
322- else baseEntry
323- }
324- else throw("Strict value is not equal to itself.")
325- }
326- else throw("Strict value is not equal to itself.")
327- }
328- }
115+func callFunction (funcName,args) = valueOrElse(isActive(), {
116+ let $t030463132 = {
117+ let $l = i.payments
118+ let $s = size($l)
119+ let $acc0 = $Tuple2(nil, nil)
120+ func $f0_1 ($a,$i) = if (($i >= $s))
121+ then $a
122+ else collectPayments($a, $l[$i])
329123
124+ func $f0_2 ($a,$i) = if (($i >= $s))
125+ then $a
126+ else throw("List size exceeds 10")
330127
128+ $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)
129+ }
130+ let paymentAmounts = $t030463132._1
131+ let paymentAssetIds = $t030463132._2
132+ let r = {
133+ let @ = reentrantInvoke(cpmmContract, funcName, [i.caller.bytes, args, paymentAmounts, paymentAssetIds], nil)
134+ if ($isInstanceOf(@, "List[Any]"))
135+ then @
136+ else throw("Couldn't cast Any to List[Any]")
137+ }
138+ if ((r == r))
139+ then {
140+ let $l = r
141+ let $s = size($l)
142+ let $acc0 = nil
143+ func $f1_1 ($a,$i) = if (($i >= $s))
144+ then $a
145+ else collectState($a, $l[$i])
331146
332-@Callable(i)
333-func initWithInitRatio (amtAssetA,amtAssetB,strAssetIdA,strAssetIdB,firstHarvest) = {
334- let $t01024610333 = getAssetInfoFromString(strAssetIdA)
335- let pmtStrAssetIdA = $t01024610333._1
336- let pmtAssetNameA = $t01024610333._2
337- let pmtDecimalsA = $t01024610333._3
338- let $t01033810425 = getAssetInfoFromString(strAssetIdB)
339- let pmtStrAssetIdB = $t01033810425._1
340- let pmtAssetNameB = $t01033810425._2
341- let pmtDecimalsB = $t01033810425._3
342- if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminInvokePubKey], i.callerPublicKey)))
343- then throw("Only admin can call this function")
344- else if (isDefined(getBoolean(this, kActive)))
345- then throw("DApp is already active")
346- else if ((strAssetIdA == strAssetIdB))
347- then throw("Assets must be different")
348- else {
349- let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
350- let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
351- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
352- let shareInitialSupply = 0
353- let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
354- let shareIssueId = calculateAssetId(shareIssue)
355- let baseEntry = [StringEntry(kVersion, version), BooleanEntry(kActive, true), StringEntry(kAssetIdA, pmtStrAssetIdA), StringEntry(kAssetIdB, pmtStrAssetIdB), IntegerEntry(kBalanceInitA, amtAssetA), IntegerEntry(kBalanceInitB, amtAssetB), IntegerEntry(kBalanceA, 0), IntegerEntry(kBalanceB, 0), IntegerEntry(kFee, getIntegerValue(oracle, "base_fee_cpmm")), shareIssue, StringEntry(kShareAssetId, toBase58String(shareIssueId)), IntegerEntry(kShareAssetSupply, shareInitialSupply)]
356- if (firstHarvest)
357- then (baseEntry ++ [BooleanEntry(kFirstHarvest, firstHarvest), IntegerEntry(kFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
358- else baseEntry
359- }
360- }
147+ func $f1_2 ($a,$i) = if (($i >= $s))
148+ then $a
149+ else throw("List size exceeds 15")
361150
362-
363-
364-@Callable(i)
365-func keepLimitForFirstHarvest (shareLimit) = valueOrElse(isActive(), if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminInvokePubKey], i.callerPublicKey)))
366- then throw("Only admin can call this function")
367- else [IntegerEntry(kShareLimit, shareLimit)])
368-
369-
370-
371-@Callable(i)
372-func replenishWithTwoTokens (slippageTolerance) = valueOrElse(isActive(), {
373- let pmtAssetIdA = i.payments[0].assetId
374- let pmtAssetIdB = i.payments[1].assetId
375- let pmtAmountA = i.payments[0].amount
376- let pmtAmountB = i.payments[1].amount
377- let $t01280412881 = getAssetInfo(pmtAssetIdA)
378- let pmtStrAssetIdA = $t01280412881._1
379- let pmtAssetNameA = $t01280412881._2
380- let pmtDecimalsA = $t01280412881._3
381- let $t01288612963 = getAssetInfo(pmtAssetIdB)
382- let pmtStrAssetIdB = $t01288612963._1
383- let pmtAssetNameB = $t01288612963._2
384- let pmtDecimalsB = $t01288612963._3
385- let inital = if (if ((balanceA == 0))
386- then (balanceB == 0)
387- else false)
388- then true
389- else false
390- let tokenRatio = if (inital)
391- then fraction(fraction(assetInitA, scaleValue8, pmtAmountA), scaleValue3, fraction(assetInitB, scaleValue8, pmtAmountB))
392- else fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
393- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
394- let shareTokenToPayAmount = if (inital)
395- then fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
396- else fraction(min([fraction(pmtAmountA, scaleValue8, balanceA), fraction(pmtAmountB, scaleValue8, balanceB)]), shareAssetSupply, scaleValue8)
397- if (if ((0 > slippageTolerance))
398- then true
399- else (slippageTolerance > slippageToleranceDelimiter))
400- then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
401- else if ((size(i.payments) != 2))
402- then throw("Two attached assets expected")
403- else if (if ((pmtAssetIdA != assetIdA))
404- then true
405- else (pmtAssetIdB != assetIdB))
406- then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
407- else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
408- then true
409- else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
410- then throw("Incorrect assets amount: amounts must have the contract ratio")
411- else if ((shareTokenToPayAmount == 0))
412- then throw("Too small amount to replenish")
413- else if (!(hasEnoughBalance))
414- then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
415- else {
416- let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
417- then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
418- else 0
419- if ((stake1 == stake1))
420- then {
421- let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
422- then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
423- else 0
424- if ((stake2 == stake2))
425- then [Reissue(shareAssetId, shareTokenToPayAmount, true), IntegerEntry(kBalanceA, (balanceA + pmtAmountA)), IntegerEntry(kBalanceB, (balanceB + pmtAmountB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
426- else throw("Strict value is not equal to itself.")
427- }
428- else throw("Strict value is not equal to itself.")
429- }
430- })
431-
432-
433-
434-@Callable(i)
435-func withdraw () = valueOrElse(isActive(), {
436- let $t01576315838 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
437- let pmtAmount = $t01576315838._1
438- let pmtAssetId = $t01576315838._2
439- let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
440- let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
441- if ((size(i.payments) != 1))
442- then throw("One attached payment expected")
443- else if ((pmtAssetId != shareAssetId))
444- then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
445- else if (!(hasEnoughBalance))
446- then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
447- else {
448- let stake1 = if (containsElement(stakingAssets, strAssetIdA))
449- then invoke(this, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
450- else 0
451- if ((stake1 == stake1))
452- then {
453- let stake2 = if (containsElement(stakingAssets, strAssetIdB))
454- then invoke(this, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
455- else 0
456- if ((stake2 == stake2))
457- then [IntegerEntry(kBalanceA, (balanceA - amountToPayA)), IntegerEntry(kBalanceB, (balanceB - amountToPayB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply - pmtAmount)), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
458- else throw("Strict value is not equal to itself.")
459- }
460- else throw("Strict value is not equal to itself.")
461- }
462- })
463-
464-
465-
466-@Callable(i)
467-func exchange (minAmountToReceive) = valueOrElse(isActive(), {
468- let $t01713717212 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
469- let pmtAmount = $t01713717212._1
470- let pmtAssetId = $t01713717212._2
471- if (if ((balanceA == 0))
472- then true
473- else (balanceB == 0))
474- then throw("Can't exchange with zero balance")
475- else if ((0 >= minAmountToReceive))
476- then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive)))
477- else if ((size(i.payments) != 1))
478- then throw("One attached payment expected")
479- else if (!(hasEnoughBalance))
480- then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
481- else if ((pmtAssetId == assetIdA))
482- then {
483- let assetIdSend = assetIdB
484- let $t01776317885 = calculateFees(pmtAmount, minAmountToReceive, balanceA, balanceB)
485- let amountWithoutFee = $t01776317885._1
486- let amountWithFee = $t01776317885._2
487- let governanceReward = $t01776317885._3
488- let newBalanceA = (balanceA + pmtAmount)
489- let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
490- let stake1 = if (containsElement(stakingAssets, strAssetIdA))
491- then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdA], nil)
492- else 0
493- if ((stake1 == stake1))
494- then {
495- let stake2 = if (containsElement(stakingAssets, strAssetIdB))
496- then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdB], nil)
497- else 0
498- if ((stake2 == stake2))
499- then $Tuple2([IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(moneyBoxAddress, governanceReward, assetIdSend)], $Tuple2(amountWithFee, assetIdSend))
500- else throw("Strict value is not equal to itself.")
501- }
502- else throw("Strict value is not equal to itself.")
503- }
504- else if ((pmtAssetId == assetIdB))
505- then {
506- let assetIdSend = assetIdA
507- let $t01887718999 = calculateFees(pmtAmount, minAmountToReceive, balanceB, balanceA)
508- let amountWithoutFee = $t01887718999._1
509- let amountWithFee = $t01887718999._2
510- let governanceReward = $t01887718999._3
511- let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
512- let newBalanceB = (balanceB + pmtAmount)
513- let stake1 = if (containsElement(stakingAssets, strAssetIdA))
514- then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdA], nil)
515- else 0
516- if ((stake1 == stake1))
517- then {
518- let stake2 = if (containsElement(stakingAssets, strAssetIdB))
519- then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdB], nil)
520- else 0
521- if ((stake2 == stake2))
522- then $Tuple2([IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(moneyBoxAddress, governanceReward, assetIdSend)], $Tuple2(amountWithFee, assetIdSend))
523- else throw("Strict value is not equal to itself.")
524- }
525- else throw("Strict value is not equal to itself.")
526- }
527- else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
151+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
152+ }
153+ else throw("Strict value is not equal to itself.")
528154 })
529155
530156
548174
549175
550176 @Callable(i)
551-func takeIntoAccountExtraFunds () = valueOrElse(isActive(), {
552- let amountEnrollA = (accountBalanceWithStakedA - balanceA)
553- let amountEnrollB = (accountBalanceWithStakedB - balanceB)
554- if ((i.caller != moneyBoxAddress))
555- then throw("Only the wallet can call this function")
556- else if (if ((0 > amountEnrollA))
557- then true
558- else (0 > amountEnrollB))
559- then suspend("Enroll amount negative")
560- else if (if ((amountEnrollA == 0))
561- then (amountEnrollB == 0)
562- else false)
563- then throw("No money to take")
564- else {
565- let stake1 = if (containsElement(stakingAssets, strAssetIdA))
566- then invoke(this, "stakeUnstake", [true, amountEnrollA, strAssetIdA], nil)
567- else 0
568- if ((stake1 == stake1))
569- then {
570- let stake2 = if (containsElement(stakingAssets, strAssetIdB))
571- then invoke(this, "stakeUnstake", [true, amountEnrollB, strAssetIdB], nil)
572- else 0
573- if ((stake2 == stake2))
574- then [IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
575- else throw("Strict value is not equal to itself.")
576- }
577- else throw("Strict value is not equal to itself.")
578- }
579- })
580-
581-
582-
583-@Callable(i)
584-func stakeUnstake (stake,amount,assetIdString) = if ((i.caller != this))
585- then throw("Only contract itself can invoke this function")
177+func stakeUnstake (stake,amount,assetIdString) = valueOrElse(isActive(), if ((i.caller != cpmmContract))
178+ then throw("Only global Contract can invoke this function")
586179 else if ((assetIdString == "WAVES"))
587180 then {
588181 let pool = addressFromStringValue(valueOrErrorMessage(getString(oracle, kLeasingPool), "No leasing pool in oracle"))
602195 }
603196 }
604197 else {
605- let $t02275322856 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
606- let call = $t02275322856._1
607- let addr = $t02275322856._2
608- let params = $t02275322856._3
609- let payments = $t02275322856._4
198+ let $t050745177 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
199+ let call = $t050745177._1
200+ let addr = $t050745177._2
201+ let params = $t050745177._3
202+ let payments = $t050745177._4
610203 let inv = invoke(addr, call, params, payments)
611204 if ((inv == inv))
612205 then nil
613206 else throw("Strict value is not equal to itself.")
614- }
615-
616-
617-
618-@Callable(i)
619-func stakeAll () = valueOrElse(isActive(), if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
620- then throw("Only admin can call this function")
621- else {
622- let stake1 = if (containsElement(stakingAssets, strAssetIdA))
623- then {
624- let amountA = (balanceA - stakedAmountA)
625- if ((amountA > 0))
626- then invoke(this, "stakeUnstake", [true, amountA, strAssetIdA], nil)
627- else 0
628- }
629- else 0
630- if ((stake1 == stake1))
631- then {
632- let stake2 = if (containsElement(stakingAssets, strAssetIdB))
633- then {
634- let amountB = (balanceB - stakedAmountB)
635- if ((amountB > 0))
636- then invoke(this, "stakeUnstake", [true, amountB, strAssetIdB], nil)
637- else 0
638- }
639- else 0
640- if ((stake2 == stake2))
641- then nil
642- else throw("Strict value is not equal to itself.")
643- }
644- else throw("Strict value is not equal to itself.")
645- })
207+ })
646208
647209
648210 @Verifier(tx)
659221 else 0
660222 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
661223 }
662- match tx {
663- case inv: InvokeScriptTransaction =>
664- let callTakeIntoAccount = if ((inv.dApp == this))
665- then (inv.function == "takeIntoAccountExtraFunds")
666- else false
667- let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
668- then true
669- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
670- then true
671- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
672- then true
673- else sigVerify(tx.bodyBytes, tx.proofs[0], adminInvokePubKey)
674- if (if (callTakeIntoAccount)
675- then signedByAdmin
676- else false)
677- then true
678- else multiSignedByAdmins
679- case _ =>
680- multiSignedByAdmins
681- }
224+ multiSignedByAdmins
682225 }
683226
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let version = "1.0.0"
5-
6-let kVersion = "version"
7-
84 let kActive = "active"
95
10-let kAssetIdA = "A_asset_id"
11-
12-let kAssetIdB = "B_asset_id"
13-
14-let kBalanceA = "A_asset_balance"
15-
16-let kBalanceB = "B_asset_balance"
17-
18-let kBalanceInitA = "A_asset_init"
19-
20-let kBalanceInitB = "B_asset_init"
21-
22-let kShareAssetId = "share_asset_id"
23-
24-let kShareAssetSupply = "share_asset_supply"
25-
26-let kFee = "commission"
27-
286 let kCause = "shutdown_cause"
29-
30-let kFirstHarvest = "first_harvest"
31-
32-let kFirstHarvestHeight = "first_harvest_height"
33-
34-let kShareLimit = "share_limit_on_first_harvest"
35-
36-let kBasePeriod = "base_period"
37-
38-let kPeriodLength = "period_length"
39-
40-let kStartHeight = "start_height"
417
428 let kUSDNAddress = "staking_usdnnsbt_address"
439
4410 let kEURNAddress = "staking_eurn_address"
4511
4612 let kLeasingPool = "leasing_address"
4713
4814 let kLeasingAmount = "leasing_amount"
4915
5016 let kLeasingId = "leasing_id"
5117
5218 let kAdminPubKey1 = "admin_pub_1"
5319
5420 let kAdminPubKey2 = "admin_pub_2"
5521
5622 let kAdminPubKey3 = "admin_pub_3"
5723
5824 let kAdminInvokePubKey = "admin_invoke_pub"
5925
60-let kMoneyBoxAddress = "money_box_address"
26+let kCpmmContract = "cpmm_contract"
27+
28+let kUSDNAssetId = "usdn_asset_id"
29+
30+let kEURNAssetId = "eurn_asset_id"
31+
32+let kStakingAssets = "staking_assets"
6133
6234 let oracle = Address(base58'3NBBWfzZtZtszaXbitTKnrB2xXwv26Bn7H9')
6335
6436 func getBase58FromOracle (key) = match getString(oracle, key) {
6537 case string: String =>
6638 fromBase58String(string)
6739 case nothing =>
6840 throw((key + "is empty"))
6941 }
7042
7143
7244 let adminPubKey1 = getBase58FromOracle(kAdminPubKey1)
7345
7446 let adminPubKey2 = getBase58FromOracle(kAdminPubKey2)
7547
7648 let adminPubKey3 = getBase58FromOracle(kAdminPubKey3)
7749
78-let adminInvokePubKey = getBase58FromOracle(kAdminInvokePubKey)
79-
80-let moneyBoxAddress = Address(getBase58FromOracle(kMoneyBoxAddress))
81-
82-let votingAddress = Address(base58'3MrJgdL1GniipErHy44YF9idzLaUL2iX5DQ')
83-
84-let USDN = base58'8UrfDVd5GreeUwm7uPk7eYz1eMv376kzR52C6sANPkwS'
85-
86-let SWOP = base58'2HAJrwa8q4SxBx9cHYaBTQdBjdk5wwqdof7ccpAx2uhZ'
87-
88-let EURN = base58'ECBCkHS68DckpBrzLeoRgYbFg7sCVqR176mPqbXsj9pA'
89-
90-let stakingAssets = ["WAVES", toBase58String(USDN), toBase58String(EURN)]
50+let adminPubKeyInvoke = getBase58FromOracle(kAdminInvokePubKey)
9151
9252 let stakingUSDNAddress = Address(getBase58FromOracle(kUSDNAddress))
9353
9454 let stakingEURNAddress = Address(getBase58FromOracle(kEURNAddress))
9555
96-let basePeriod = valueOrErrorMessage(getInteger(votingAddress, kBasePeriod), "Empty kBasePeriod")
56+let cpmmContract = Address(getBase58FromOracle(kCpmmContract))
9757
98-let startHeight = valueOrErrorMessage(getInteger(votingAddress, kStartHeight), "Empty kStartHeight")
58+let USDN = getBase58FromOracle(kUSDNAssetId)
9959
100-let periodLength = valueOrErrorMessage(getInteger(votingAddress, kPeriodLength), "Empty kPeriodLength")
60+let EURN = getBase58FromOracle(kEURNAssetId)
10161
102-let firstHarvestEndPeriod = ((basePeriod + ((height - startHeight) / periodLength)) + 3)
62+let stakingAssets = getStringValue(oracle, kStakingAssets)
10363
104-let active = getBooleanValue(this, kActive)
64+let active = valueOrElse(getBoolean(this, kActive), true)
10565
106-let strAssetIdA = getStringValue(this, kAssetIdA)
107-
108-let strAssetIdB = getStringValue(this, kAssetIdB)
109-
110-let assetIdA = if ((strAssetIdA == "WAVES"))
66+func isActive () = if (active)
11167 then unit
112- else fromBase58String(strAssetIdA)
113-
114-let assetIdB = if ((strAssetIdB == "WAVES"))
115- then unit
116- else fromBase58String(strAssetIdB)
117-
118-let assetNameA = match assetIdA {
119- case id: ByteVector =>
120- value(assetInfo(id)).name
121- case waves: Unit =>
122- "WAVES"
123- case _ =>
124- throw("Match error")
125-}
126-
127-let assetNameB = match assetIdB {
128- case id: ByteVector =>
129- value(assetInfo(id)).name
130- case waves: Unit =>
131- "WAVES"
132- case _ =>
133- throw("Match error")
134-}
135-
136-let balanceA = getIntegerValue(this, kBalanceA)
137-
138-let balanceB = getIntegerValue(this, kBalanceB)
139-
140-let shareAssetId = fromBase58String(getStringValue(this, kShareAssetId))
141-
142-let shareAssetSupply = getIntegerValue(this, kShareAssetSupply)
143-
144-let fee = getIntegerValue(this, kFee)
145-
146-let feeGovernance = fraction(fee, 40, 100)
147-
148-let feeScale6 = 1000000
149-
150-let scaleValue3 = 1000
151-
152-let scaleValue8 = 100000000
153-
154-let slippageToleranceDelimiter = 1000
155-
156-let scaleValue8Digits = 8
157-
158-func accountBalance (assetId) = match assetId {
159- case id: ByteVector =>
160- assetBalance(this, id)
161- case waves: Unit =>
162- wavesBalance(this).available
163- case _ =>
164- throw("Match error")
165-}
166-
167-
168-func stakedAmount (assetId) = {
169- let stakedAmountCalculated = match assetId {
170- case aId: ByteVector =>
171- if ((aId == USDN))
172- then getInteger(stakingUSDNAddress, ((("rpd_balance_" + toBase58String(aId)) + "_") + toString(this)))
173- else if ((aId == EURN))
174- then getInteger(stakingEURNAddress, ((("%s%s%s__stakingBalance__" + toBase58String(aId)) + "__") + toString(this)))
175- else 0
176- case _: Unit =>
177- valueOrElse(getInteger(this, kLeasingAmount), 0)
178- case _ =>
179- throw("Match error")
180- }
181- match stakedAmountCalculated {
182- case i: Int =>
183- i
184- case _ =>
185- 0
186- }
187- }
188-
189-
190-let stakedAmountA = stakedAmount(assetIdA)
191-
192-let stakedAmountB = stakedAmount(assetIdB)
193-
194-let assetInitA = getIntegerValue(this, kBalanceInitA)
195-
196-let assetInitB = getIntegerValue(this, kBalanceInitB)
197-
198-let availableBalanceA = (balanceA - stakedAmountA)
199-
200-let availableBalanceB = (balanceB - stakedAmountB)
201-
202-let accountBalanceWithStakedA = (accountBalance(assetIdA) + stakedAmountA)
203-
204-let accountBalanceWithStakedB = (accountBalance(assetIdB) + stakedAmountB)
205-
206-let hasEnoughBalance = if ((accountBalanceWithStakedA >= balanceA))
207- then (accountBalanceWithStakedB >= balanceB)
208- else false
209-
210-func getAssetInfo (assetId) = match assetId {
211- case id: ByteVector =>
212- let stringId = toBase58String(id)
213- let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
214- $Tuple3(stringId, info.name, info.decimals)
215- case waves: Unit =>
216- $Tuple3("WAVES", "WAVES", 8)
217- case _ =>
218- throw("Match error")
219-}
220-
221-
222-func getAssetInfoFromString (assetStr) = if ((assetStr == "WAVES"))
223- then $Tuple3("WAVES", "WAVES", 8)
224- else {
225- let stringId = assetStr
226- let id = fromBase58String(assetStr)
227- let info = valueOrErrorMessage(assetInfo(id), (("Asset " + stringId) + " doesn't exist"))
228- $Tuple3(stringId, info.name, info.decimals)
229- }
68+ else throw("DApp is inactive at this moment")
23069
23170
23271 func suspend (cause) = [BooleanEntry(kActive, false), StringEntry(kCause, cause)]
23372
23473
23574 func calcStakingFuncAndAddres (stake,assetId) = if (stake)
23675 then if ((assetId == USDN))
23776 then $Tuple2("lockNeutrino", stakingUSDNAddress)
23877 else $Tuple2("startStaking", stakingEURNAddress)
23978 else if ((assetId == USDN))
24079 then $Tuple2("unlockNeutrino", stakingUSDNAddress)
24180 else $Tuple2("stopStaking", stakingEURNAddress)
24281
24382
24483 func calcStakingParams (stake,amount,assetId) = if (stake)
24584 then {
246- let $t060896155 = calcStakingFuncAndAddres(stake, assetId)
247- let call = $t060896155._1
248- let stakingAddr = $t060896155._2
85+ let $t021132179 = calcStakingFuncAndAddres(stake, assetId)
86+ let call = $t021132179._1
87+ let stakingAddr = $t021132179._2
24988 $Tuple4(call, stakingAddr, nil, [AttachedPayment(assetId, amount)])
25089 }
25190 else {
252- let $t062416307 = calcStakingFuncAndAddres(stake, assetId)
253- let call = $t062416307._1
254- let stakingAddr = $t062416307._2
91+ let $t022652331 = calcStakingFuncAndAddres(stake, assetId)
92+ let call = $t022652331._1
93+ let stakingAddr = $t022652331._2
25594 $Tuple4(call, stakingAddr, [amount, toBase58String(assetId)], nil)
25695 }
25796
25897
259-func calculateFees (pmtAmount,minAmountToReceive,tokenFrom,tokenTo) = {
260- let amountWithoutFee = fraction(tokenTo, pmtAmount, (pmtAmount + tokenFrom))
261- let amountWithFee = fraction(amountWithoutFee, (feeScale6 - fee), feeScale6)
262- let governanceReward = fraction(amountWithoutFee, feeGovernance, feeScale6)
263- if ((minAmountToReceive > amountWithFee))
264- then throw(((("Calculated amount to receive " + toString(amountWithFee)) + " is less than specified minimum ") + toString(minAmountToReceive)))
265- else $Tuple3(amountWithoutFee, amountWithFee, governanceReward)
98+func collectPayments (acc,payment) = {
99+ let $t024932536 = acc
100+ let paymentAmounts = $t024932536._1
101+ let paymentAssetIds = $t024932536._2
102+ $Tuple2((paymentAmounts :+ payment.amount), (paymentAssetIds :+ payment.assetId))
266103 }
267104
268105
269-func suspendSuspicious () = suspend(((((((((((((((("Suspicious state. Actual balances: " + toString(accountBalanceWithStakedA)) + " ") + assetNameA) + ", ") + toString(accountBalanceWithStakedB)) + " ") + assetNameB) + ". State: ") + toString(balanceA)) + " ") + assetNameA) + ", ") + toString(balanceB)) + " ") + assetNameB))
270-
271-
272-func isActive () = if (active)
273- then unit
274- else throw("DApp is inactive at this moment")
106+func collectState (result,source) = match source {
107+ case e: Issue|Burn|Reissue|ScriptTransfer|BinaryEntry|BooleanEntry|StringEntry|IntegerEntry =>
108+ (result :+ e)
109+ case _ =>
110+ result
111+}
275112
276113
277114 @Callable(i)
278-func init (firstHarvest) = {
279- let $t074187495 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
280- let pmtAmountA = $t074187495._1
281- let pmtAssetIdA = $t074187495._2
282- let $t075007577 = $Tuple2(i.payments[1].amount, i.payments[1].assetId)
283- let pmtAmountB = $t075007577._1
284- let pmtAssetIdB = $t075007577._2
285- let $t075827659 = getAssetInfo(pmtAssetIdA)
286- let pmtStrAssetIdA = $t075827659._1
287- let pmtAssetNameA = $t075827659._2
288- let pmtDecimalsA = $t075827659._3
289- let $t076647741 = getAssetInfo(pmtAssetIdB)
290- let pmtStrAssetIdB = $t076647741._1
291- let pmtAssetNameB = $t076647741._2
292- let pmtDecimalsB = $t076647741._3
293- if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminInvokePubKey], i.callerPublicKey)))
294- then throw("Only admin can call this function")
295- else if (isDefined(getBoolean(this, kActive)))
296- then throw("DApp is already active")
297- else if ((pmtAssetIdA == pmtAssetIdB))
298- then throw("Assets must be different")
299- else {
300- let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
301- let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
302- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
303- let arg1 = pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN)
304- let arg2 = pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN)
305- let arg3 = pow(10, 0, shareDecimals, 0, 0, DOWN)
306- let shareInitialSupply = fraction(arg1, arg2, arg3)
307- let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
308- let shareIssueId = calculateAssetId(shareIssue)
309- let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
310- then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
311- else 0
312- if ((stake1 == stake1))
313- then {
314- let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
315- then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
316- else 0
317- if ((stake2 == stake2))
318- then {
319- let baseEntry = [StringEntry(kVersion, version), BooleanEntry(kActive, true), StringEntry(kAssetIdA, pmtStrAssetIdA), StringEntry(kAssetIdB, pmtStrAssetIdB), IntegerEntry(kBalanceA, pmtAmountA), IntegerEntry(kBalanceB, pmtAmountB), IntegerEntry(kFee, getIntegerValue(oracle, "base_fee_cpmm")), shareIssue, StringEntry(kShareAssetId, toBase58String(shareIssueId)), IntegerEntry(kShareAssetSupply, shareInitialSupply), ScriptTransfer(i.caller, shareInitialSupply, shareIssueId)]
320- if (firstHarvest)
321- then (baseEntry ++ [BooleanEntry(kFirstHarvest, firstHarvest), IntegerEntry(kFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
322- else baseEntry
323- }
324- else throw("Strict value is not equal to itself.")
325- }
326- else throw("Strict value is not equal to itself.")
327- }
328- }
115+func callFunction (funcName,args) = valueOrElse(isActive(), {
116+ let $t030463132 = {
117+ let $l = i.payments
118+ let $s = size($l)
119+ let $acc0 = $Tuple2(nil, nil)
120+ func $f0_1 ($a,$i) = if (($i >= $s))
121+ then $a
122+ else collectPayments($a, $l[$i])
329123
124+ func $f0_2 ($a,$i) = if (($i >= $s))
125+ then $a
126+ else throw("List size exceeds 10")
330127
128+ $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)
129+ }
130+ let paymentAmounts = $t030463132._1
131+ let paymentAssetIds = $t030463132._2
132+ let r = {
133+ let @ = reentrantInvoke(cpmmContract, funcName, [i.caller.bytes, args, paymentAmounts, paymentAssetIds], nil)
134+ if ($isInstanceOf(@, "List[Any]"))
135+ then @
136+ else throw("Couldn't cast Any to List[Any]")
137+ }
138+ if ((r == r))
139+ then {
140+ let $l = r
141+ let $s = size($l)
142+ let $acc0 = nil
143+ func $f1_1 ($a,$i) = if (($i >= $s))
144+ then $a
145+ else collectState($a, $l[$i])
331146
332-@Callable(i)
333-func initWithInitRatio (amtAssetA,amtAssetB,strAssetIdA,strAssetIdB,firstHarvest) = {
334- let $t01024610333 = getAssetInfoFromString(strAssetIdA)
335- let pmtStrAssetIdA = $t01024610333._1
336- let pmtAssetNameA = $t01024610333._2
337- let pmtDecimalsA = $t01024610333._3
338- let $t01033810425 = getAssetInfoFromString(strAssetIdB)
339- let pmtStrAssetIdB = $t01033810425._1
340- let pmtAssetNameB = $t01033810425._2
341- let pmtDecimalsB = $t01033810425._3
342- if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminInvokePubKey], i.callerPublicKey)))
343- then throw("Only admin can call this function")
344- else if (isDefined(getBoolean(this, kActive)))
345- then throw("DApp is already active")
346- else if ((strAssetIdA == strAssetIdB))
347- then throw("Assets must be different")
348- else {
349- let shareName = ((("s" + take(pmtAssetNameA, 7)) + "_") + take(pmtAssetNameB, 7))
350- let shareDescription = ((((("ShareToken of SwopFi protocol for " + pmtAssetNameA) + " and ") + pmtAssetNameB) + " at address ") + toString(this))
351- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
352- let shareInitialSupply = 0
353- let shareIssue = Issue(shareName, shareDescription, shareInitialSupply, shareDecimals, true)
354- let shareIssueId = calculateAssetId(shareIssue)
355- let baseEntry = [StringEntry(kVersion, version), BooleanEntry(kActive, true), StringEntry(kAssetIdA, pmtStrAssetIdA), StringEntry(kAssetIdB, pmtStrAssetIdB), IntegerEntry(kBalanceInitA, amtAssetA), IntegerEntry(kBalanceInitB, amtAssetB), IntegerEntry(kBalanceA, 0), IntegerEntry(kBalanceB, 0), IntegerEntry(kFee, getIntegerValue(oracle, "base_fee_cpmm")), shareIssue, StringEntry(kShareAssetId, toBase58String(shareIssueId)), IntegerEntry(kShareAssetSupply, shareInitialSupply)]
356- if (firstHarvest)
357- then (baseEntry ++ [BooleanEntry(kFirstHarvest, firstHarvest), IntegerEntry(kFirstHarvestHeight, (startHeight + (firstHarvestEndPeriod * periodLength)))])
358- else baseEntry
359- }
360- }
147+ func $f1_2 ($a,$i) = if (($i >= $s))
148+ then $a
149+ else throw("List size exceeds 15")
361150
362-
363-
364-@Callable(i)
365-func keepLimitForFirstHarvest (shareLimit) = valueOrElse(isActive(), if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3, adminInvokePubKey], i.callerPublicKey)))
366- then throw("Only admin can call this function")
367- else [IntegerEntry(kShareLimit, shareLimit)])
368-
369-
370-
371-@Callable(i)
372-func replenishWithTwoTokens (slippageTolerance) = valueOrElse(isActive(), {
373- let pmtAssetIdA = i.payments[0].assetId
374- let pmtAssetIdB = i.payments[1].assetId
375- let pmtAmountA = i.payments[0].amount
376- let pmtAmountB = i.payments[1].amount
377- let $t01280412881 = getAssetInfo(pmtAssetIdA)
378- let pmtStrAssetIdA = $t01280412881._1
379- let pmtAssetNameA = $t01280412881._2
380- let pmtDecimalsA = $t01280412881._3
381- let $t01288612963 = getAssetInfo(pmtAssetIdB)
382- let pmtStrAssetIdB = $t01288612963._1
383- let pmtAssetNameB = $t01288612963._2
384- let pmtDecimalsB = $t01288612963._3
385- let inital = if (if ((balanceA == 0))
386- then (balanceB == 0)
387- else false)
388- then true
389- else false
390- let tokenRatio = if (inital)
391- then fraction(fraction(assetInitA, scaleValue8, pmtAmountA), scaleValue3, fraction(assetInitB, scaleValue8, pmtAmountB))
392- else fraction(fraction(balanceA, scaleValue8, pmtAmountA), scaleValue3, fraction(balanceB, scaleValue8, pmtAmountB))
393- let shareDecimals = ((pmtDecimalsA + pmtDecimalsB) / 2)
394- let shareTokenToPayAmount = if (inital)
395- then fraction(pow(pmtAmountA, pmtDecimalsA, 5, 1, pmtDecimalsA, DOWN), pow(pmtAmountB, pmtDecimalsB, 5, 1, pmtDecimalsB, DOWN), pow(10, 0, shareDecimals, 0, 0, DOWN))
396- else fraction(min([fraction(pmtAmountA, scaleValue8, balanceA), fraction(pmtAmountB, scaleValue8, balanceB)]), shareAssetSupply, scaleValue8)
397- if (if ((0 > slippageTolerance))
398- then true
399- else (slippageTolerance > slippageToleranceDelimiter))
400- then throw(((("Slippage tolerance must be between 0 and " + toString(slippageToleranceDelimiter)) + " inclusively. Actual: ") + toString(slippageTolerance)))
401- else if ((size(i.payments) != 2))
402- then throw("Two attached assets expected")
403- else if (if ((pmtAssetIdA != assetIdA))
404- then true
405- else (pmtAssetIdB != assetIdB))
406- then throw(((("Incorrect assets attached. Expected: " + strAssetIdA) + " and ") + strAssetIdB))
407- else if (if ((((scaleValue3 * (slippageToleranceDelimiter - slippageTolerance)) / slippageToleranceDelimiter) > tokenRatio))
408- then true
409- else (tokenRatio > ((scaleValue3 * (slippageToleranceDelimiter + slippageTolerance)) / slippageToleranceDelimiter)))
410- then throw("Incorrect assets amount: amounts must have the contract ratio")
411- else if ((shareTokenToPayAmount == 0))
412- then throw("Too small amount to replenish")
413- else if (!(hasEnoughBalance))
414- then ([ScriptTransfer(i.caller, pmtAmountA, pmtAssetIdA), ScriptTransfer(i.caller, pmtAmountB, pmtAssetIdB)] ++ suspendSuspicious())
415- else {
416- let stake1 = if (containsElement(stakingAssets, pmtStrAssetIdA))
417- then invoke(this, "stakeUnstake", [true, pmtAmountA, pmtStrAssetIdA], nil)
418- else 0
419- if ((stake1 == stake1))
420- then {
421- let stake2 = if (containsElement(stakingAssets, pmtStrAssetIdB))
422- then invoke(this, "stakeUnstake", [true, pmtAmountB, pmtStrAssetIdB], nil)
423- else 0
424- if ((stake2 == stake2))
425- then [Reissue(shareAssetId, shareTokenToPayAmount, true), IntegerEntry(kBalanceA, (balanceA + pmtAmountA)), IntegerEntry(kBalanceB, (balanceB + pmtAmountB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply + shareTokenToPayAmount)), ScriptTransfer(i.caller, shareTokenToPayAmount, shareAssetId)]
426- else throw("Strict value is not equal to itself.")
427- }
428- else throw("Strict value is not equal to itself.")
429- }
430- })
431-
432-
433-
434-@Callable(i)
435-func withdraw () = valueOrElse(isActive(), {
436- let $t01576315838 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
437- let pmtAmount = $t01576315838._1
438- let pmtAssetId = $t01576315838._2
439- let amountToPayA = fraction(pmtAmount, balanceA, shareAssetSupply)
440- let amountToPayB = fraction(pmtAmount, balanceB, shareAssetSupply)
441- if ((size(i.payments) != 1))
442- then throw("One attached payment expected")
443- else if ((pmtAssetId != shareAssetId))
444- then throw(("Incorrect asset attached. Expected: " + toBase58String(shareAssetId)))
445- else if (!(hasEnoughBalance))
446- then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
447- else {
448- let stake1 = if (containsElement(stakingAssets, strAssetIdA))
449- then invoke(this, "stakeUnstake", [false, amountToPayA, strAssetIdA], nil)
450- else 0
451- if ((stake1 == stake1))
452- then {
453- let stake2 = if (containsElement(stakingAssets, strAssetIdB))
454- then invoke(this, "stakeUnstake", [false, amountToPayB, strAssetIdB], nil)
455- else 0
456- if ((stake2 == stake2))
457- then [IntegerEntry(kBalanceA, (balanceA - amountToPayA)), IntegerEntry(kBalanceB, (balanceB - amountToPayB)), IntegerEntry(kShareAssetSupply, (shareAssetSupply - pmtAmount)), Burn(shareAssetId, pmtAmount), ScriptTransfer(i.caller, amountToPayA, assetIdA), ScriptTransfer(i.caller, amountToPayB, assetIdB)]
458- else throw("Strict value is not equal to itself.")
459- }
460- else throw("Strict value is not equal to itself.")
461- }
462- })
463-
464-
465-
466-@Callable(i)
467-func exchange (minAmountToReceive) = valueOrElse(isActive(), {
468- let $t01713717212 = $Tuple2(i.payments[0].amount, i.payments[0].assetId)
469- let pmtAmount = $t01713717212._1
470- let pmtAssetId = $t01713717212._2
471- if (if ((balanceA == 0))
472- then true
473- else (balanceB == 0))
474- then throw("Can't exchange with zero balance")
475- else if ((0 >= minAmountToReceive))
476- then throw(("Minimal amount to receive must be positive. Actual: " + toString(minAmountToReceive)))
477- else if ((size(i.payments) != 1))
478- then throw("One attached payment expected")
479- else if (!(hasEnoughBalance))
480- then ([ScriptTransfer(i.caller, pmtAmount, pmtAssetId)] ++ suspendSuspicious())
481- else if ((pmtAssetId == assetIdA))
482- then {
483- let assetIdSend = assetIdB
484- let $t01776317885 = calculateFees(pmtAmount, minAmountToReceive, balanceA, balanceB)
485- let amountWithoutFee = $t01776317885._1
486- let amountWithFee = $t01776317885._2
487- let governanceReward = $t01776317885._3
488- let newBalanceA = (balanceA + pmtAmount)
489- let newBalanceB = ((balanceB - amountWithFee) - governanceReward)
490- let stake1 = if (containsElement(stakingAssets, strAssetIdA))
491- then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdA], nil)
492- else 0
493- if ((stake1 == stake1))
494- then {
495- let stake2 = if (containsElement(stakingAssets, strAssetIdB))
496- then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdB], nil)
497- else 0
498- if ((stake2 == stake2))
499- then $Tuple2([IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(moneyBoxAddress, governanceReward, assetIdSend)], $Tuple2(amountWithFee, assetIdSend))
500- else throw("Strict value is not equal to itself.")
501- }
502- else throw("Strict value is not equal to itself.")
503- }
504- else if ((pmtAssetId == assetIdB))
505- then {
506- let assetIdSend = assetIdA
507- let $t01887718999 = calculateFees(pmtAmount, minAmountToReceive, balanceB, balanceA)
508- let amountWithoutFee = $t01887718999._1
509- let amountWithFee = $t01887718999._2
510- let governanceReward = $t01887718999._3
511- let newBalanceA = ((balanceA - amountWithFee) - governanceReward)
512- let newBalanceB = (balanceB + pmtAmount)
513- let stake1 = if (containsElement(stakingAssets, strAssetIdA))
514- then invoke(this, "stakeUnstake", [false, (amountWithFee + governanceReward), strAssetIdA], nil)
515- else 0
516- if ((stake1 == stake1))
517- then {
518- let stake2 = if (containsElement(stakingAssets, strAssetIdB))
519- then invoke(this, "stakeUnstake", [true, pmtAmount, strAssetIdB], nil)
520- else 0
521- if ((stake2 == stake2))
522- then $Tuple2([IntegerEntry(kBalanceA, newBalanceA), IntegerEntry(kBalanceB, newBalanceB), ScriptTransfer(i.caller, amountWithFee, assetIdSend), ScriptTransfer(moneyBoxAddress, governanceReward, assetIdSend)], $Tuple2(amountWithFee, assetIdSend))
523- else throw("Strict value is not equal to itself.")
524- }
525- else throw("Strict value is not equal to itself.")
526- }
527- else throw(((("Incorrect asset attached. Expected: " + strAssetIdA) + " or ") + strAssetIdB))
151+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
152+ }
153+ else throw("Strict value is not equal to itself.")
528154 })
529155
530156
531157
532158 @Callable(i)
533159 func shutdown () = if (!(active))
534160 then throw(("DApp is already suspended. Cause: " + valueOrElse(getString(this, kCause), "the cause wasn't specified")))
535161 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
536162 then throw("Only admin can call this function")
537163 else suspend("Paused by admin")
538164
539165
540166
541167 @Callable(i)
542168 func activate () = if (active)
543169 then throw("DApp is already active")
544170 else if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
545171 then throw("Only admin can call this function")
546172 else [BooleanEntry(kActive, true), DeleteEntry(kCause)]
547173
548174
549175
550176 @Callable(i)
551-func takeIntoAccountExtraFunds () = valueOrElse(isActive(), {
552- let amountEnrollA = (accountBalanceWithStakedA - balanceA)
553- let amountEnrollB = (accountBalanceWithStakedB - balanceB)
554- if ((i.caller != moneyBoxAddress))
555- then throw("Only the wallet can call this function")
556- else if (if ((0 > amountEnrollA))
557- then true
558- else (0 > amountEnrollB))
559- then suspend("Enroll amount negative")
560- else if (if ((amountEnrollA == 0))
561- then (amountEnrollB == 0)
562- else false)
563- then throw("No money to take")
564- else {
565- let stake1 = if (containsElement(stakingAssets, strAssetIdA))
566- then invoke(this, "stakeUnstake", [true, amountEnrollA, strAssetIdA], nil)
567- else 0
568- if ((stake1 == stake1))
569- then {
570- let stake2 = if (containsElement(stakingAssets, strAssetIdB))
571- then invoke(this, "stakeUnstake", [true, amountEnrollB, strAssetIdB], nil)
572- else 0
573- if ((stake2 == stake2))
574- then [IntegerEntry(kBalanceA, (balanceA + amountEnrollA)), IntegerEntry(kBalanceB, (balanceB + amountEnrollB)), IntegerEntry(("last_income_" + strAssetIdA), amountEnrollA), IntegerEntry(("last_income_" + strAssetIdB), amountEnrollB)]
575- else throw("Strict value is not equal to itself.")
576- }
577- else throw("Strict value is not equal to itself.")
578- }
579- })
580-
581-
582-
583-@Callable(i)
584-func stakeUnstake (stake,amount,assetIdString) = if ((i.caller != this))
585- then throw("Only contract itself can invoke this function")
177+func stakeUnstake (stake,amount,assetIdString) = valueOrElse(isActive(), if ((i.caller != cpmmContract))
178+ then throw("Only global Contract can invoke this function")
586179 else if ((assetIdString == "WAVES"))
587180 then {
588181 let pool = addressFromStringValue(valueOrErrorMessage(getString(oracle, kLeasingPool), "No leasing pool in oracle"))
589182 let leasingId = getBinary(this, kLeasingId)
590183 let leasingAmount = valueOrElse(getInteger(this, kLeasingAmount), 0)
591184 let newLeaseAmount = if (stake)
592185 then (leasingAmount + amount)
593186 else (leasingAmount - amount)
594187 let newLease = Lease(pool, newLeaseAmount)
595188 let newLeaseId = calculateLeaseId(newLease)
596189 let baseEtry = [newLease, BinaryEntry(kLeasingId, newLeaseId), IntegerEntry(kLeasingAmount, newLeaseAmount)]
597190 match leasingId {
598191 case lId: ByteVector =>
599192 ([LeaseCancel(lId)] ++ baseEtry)
600193 case _ =>
601194 baseEtry
602195 }
603196 }
604197 else {
605- let $t02275322856 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
606- let call = $t02275322856._1
607- let addr = $t02275322856._2
608- let params = $t02275322856._3
609- let payments = $t02275322856._4
198+ let $t050745177 = calcStakingParams(stake, amount, fromBase58String(assetIdString))
199+ let call = $t050745177._1
200+ let addr = $t050745177._2
201+ let params = $t050745177._3
202+ let payments = $t050745177._4
610203 let inv = invoke(addr, call, params, payments)
611204 if ((inv == inv))
612205 then nil
613206 else throw("Strict value is not equal to itself.")
614- }
615-
616-
617-
618-@Callable(i)
619-func stakeAll () = valueOrElse(isActive(), if (!(containsElement([adminPubKey1, adminPubKey2, adminPubKey3], i.callerPublicKey)))
620- then throw("Only admin can call this function")
621- else {
622- let stake1 = if (containsElement(stakingAssets, strAssetIdA))
623- then {
624- let amountA = (balanceA - stakedAmountA)
625- if ((amountA > 0))
626- then invoke(this, "stakeUnstake", [true, amountA, strAssetIdA], nil)
627- else 0
628- }
629- else 0
630- if ((stake1 == stake1))
631- then {
632- let stake2 = if (containsElement(stakingAssets, strAssetIdB))
633- then {
634- let amountB = (balanceB - stakedAmountB)
635- if ((amountB > 0))
636- then invoke(this, "stakeUnstake", [true, amountB, strAssetIdB], nil)
637- else 0
638- }
639- else 0
640- if ((stake2 == stake2))
641- then nil
642- else throw("Strict value is not equal to itself.")
643- }
644- else throw("Strict value is not equal to itself.")
645- })
207+ })
646208
647209
648210 @Verifier(tx)
649211 func verify () = {
650212 let multiSignedByAdmins = {
651213 let adminPubKey1Signed = if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
652214 then 1
653215 else 0
654216 let adminPubKey2Signed = if (sigVerify(tx.bodyBytes, tx.proofs[1], adminPubKey2))
655217 then 1
656218 else 0
657219 let adminPubKey3Signed = if (sigVerify(tx.bodyBytes, tx.proofs[2], adminPubKey3))
658220 then 1
659221 else 0
660222 (((adminPubKey1Signed + adminPubKey2Signed) + adminPubKey3Signed) >= 2)
661223 }
662- match tx {
663- case inv: InvokeScriptTransaction =>
664- let callTakeIntoAccount = if ((inv.dApp == this))
665- then (inv.function == "takeIntoAccountExtraFunds")
666- else false
667- let signedByAdmin = if (if (if (sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey1))
668- then true
669- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey2))
670- then true
671- else sigVerify(tx.bodyBytes, tx.proofs[0], adminPubKey3))
672- then true
673- else sigVerify(tx.bodyBytes, tx.proofs[0], adminInvokePubKey)
674- if (if (callTakeIntoAccount)
675- then signedByAdmin
676- else false)
677- then true
678- else multiSignedByAdmins
679- case _ =>
680- multiSignedByAdmins
681- }
224+ multiSignedByAdmins
682225 }
683226

github/deemru/w8io/169f3d6 
71.80 ms