tx · FiXn4xRdmpQs68NzfBf8rmJdcjs1EYpQPsfxbxd97hFk

3MwNfynRH5bFf25GzWjcEdi6kSkX4AwR9Bz:  -0.00500000 Waves

2023.03.16 13:54 [2492487] smart account 3MwNfynRH5bFf25GzWjcEdi6kSkX4AwR9Bz > SELF 0.00000000 Waves

{ "type": 13, "id": "FiXn4xRdmpQs68NzfBf8rmJdcjs1EYpQPsfxbxd97hFk", "fee": 500000, "feeAssetId": null, "timestamp": 1678964148621, "version": 2, "chainId": 84, "sender": "3MwNfynRH5bFf25GzWjcEdi6kSkX4AwR9Bz", "senderPublicKey": "CP4TEKgebTgiDjwiN6XPMRxxtJr9ZNVotimqif4HEqx5", "proofs": [ "pbt7VGdSyjH8jESY2f2YKoFk4Fg1E4VK3CbwEMTFS1zbt52FX7pH19WHtmVNs6nRH6fmMu6KqC4Axk7XmVPBEFL" ], "script": null, "height": 2492487, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 6i3ZHedn6edyx8Fz2kfV9MJSBkw3q8ccrZVU4T5VeDzn Next: FNL94GTM7mLzxcPW31ogLyGBgo8rVVyDW2CkG6YofEff Full:
OldNewDifferences
1-{-# STDLIB_VERSION 6 #-}
2-{-# SCRIPT_TYPE ACCOUNT #-}
3-{-# CONTENT_TYPE DAPP #-}
4-let SCALE8 = 8
5-
6-let MULT8 = 100000000
7-
8-let SCALE18 = 18
9-
10-let MULT18 = toBigInt(1000000000000000000)
11-
12-let SEP = "__"
13-
14-let POOLWEIGHTMULT = MULT8
15-
16-let zeroBigInt = toBigInt(0)
17-
18-let oneBigInt = toBigInt(1)
19-
20-func wrapErr (msg) = makeString(["staking.ride:", toString(this), msg], " ")
21-
22-
23-func throwErr (msg) = throw(wrapErr(msg))
24-
25-
26-func asAnyList (val) = match val {
27- case valAnyLyst: List[Any] =>
28- valAnyLyst
29- case _ =>
30- throw("fail to cast into List[Any]")
31-}
32-
33-
34-func asInt (val) = match val {
35- case valInt: Int =>
36- valInt
37- case _ =>
38- throw("fail to cast into Int")
39-}
40-
41-
42-func asString (val) = match val {
43- case valStr: String =>
44- valStr
45- case _ =>
46- throw("fail to cast into Int")
47-}
48-
49-
50-func asByteVector (val) = match val {
51- case valBin: ByteVector =>
52- valBin
53- case _ =>
54- throw("fail to cast into Int")
55-}
56-
57-
58-func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined"))
59-
60-
61-func getStringByAddressOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
62-
63-
64-func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
65-
66-
67-func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
68-
69-
70-func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
71-
72-
73-func getBigIntFromStringOrZero (address,key) = value(parseBigInt(valueOrElse(getString(address, key), "0")))
74-
75-
76-func getBigIntFromStringOrDefault (address,key,defaultVal) = match getString(address, key) {
77- case s: String =>
78- value(parseBigInt(s))
79- case _: Unit =>
80- defaultVal
81- case _ =>
82- throw("Match error")
83-}
84-
85-
86-func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULT18, toBigInt(origScaleMult))
87-
88-
89-func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULT18))
90-
91-
92-func keyFactoryAddress () = "%s%s__config__factoryAddress"
93-
94-
95-func keyVotingEmissionContract () = "%s__votingEmissionContract"
96-
97-
98-let IdxFactoryCfgStakingDapp = 1
99-
100-let IdxFactoryCfgBoostingDapp = 2
101-
102-let IdxFactoryCfgIdoDapp = 3
103-
104-let IdxFactoryCfgTeamDapp = 4
105-
106-let IdxFactoryCfgEmissionDapp = 5
107-
108-let IdxFactoryCfgRestDapp = 6
109-
110-let IdxFactoryCfgSlippageDapp = 7
111-
112-func keyFactoryCfg () = "%s__factoryConfig"
113-
114-
115-func keyManagerPublicKey () = "%s__managerPublicKey"
116-
117-
118-func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
119-
120-
121-func keyStablePoolAddonAddr () = "%s__stablePoolAddonAddr"
122-
123-
124-func keyAddonAddr () = "%s__addonAddr"
125-
126-
127-func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
128-
129-
130-func keyFactoryLpList () = "%s__lpTokensList"
131-
132-
133-func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
134-
135-
136-func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
137-
138-
139-func readLpList (factory) = split(valueOrElse(getString(factory, keyFactoryLpList()), ""), SEP)
140-
141-
142-func readFactoryCfgOrFail (factory) = split(getStringByAddressOrFail(factory, keyFactoryCfg()), SEP)
143-
144-
145-func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
146-
147-
148-func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
149-
150-
151-func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
152-
153-
154-func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
155-
156-
157-func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
158-
159-
160-func keyEmissionStartBlock () = "%s%s__emission__startBlock"
161-
162-
163-func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
164-
165-
166-func keyEmissionEndBlock () = "%s%s__emission__endBlock"
167-
168-
169-func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s__staked", userAddressStr, lpAssetIdStr], SEP)
170-
171-
172-func keyStakedTotal (lpAssetIdStr) = ("%s%s%s__staked__total__" + lpAssetIdStr)
173-
174-
175-func keyClaimedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimed", userAddressStr, lpAssetIdStr], SEP)
176-
177-
178-func keyClaimedByUserMinReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedMinReward", userAddressStr, lpAssetIdStr], SEP)
179-
180-
181-func keyClaimedByUserBoostReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedBoostReward", userAddressStr, lpAssetIdStr], SEP)
182-
183-
184-func keyClaimedTotal (lpAssetIdStr) = makeString(["%s%s%s__claimed__total", lpAssetIdStr], SEP)
185-
186-
187-func readStaked (key) = valueOrElse(getInteger(this, key), 0)
188-
189-
190-func keyLastTotalLpBalance (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "bal"], SEP)
191-
192-
193-func keyLastUserLpBalance (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "bal"], SEP)
194-
195-
196-func keyTotalLpBalanceIntegral (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "balINT"], SEP)
197-
198-
199-func keyUserLpBalanceIntegral (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "balINT"], SEP)
200-
201-
202-func keyTotalLpBalanceIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "lastUpd"], SEP)
203-
204-
205-func keyUserLpBalanceIntegralLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "lastUpd"], SEP)
206-
207-
208-func keyWxPerLpIntegral (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpInt"], SEP)
209-
210-
211-func keyWxPerLpIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpIntH"], SEP)
212-
213-
214-func keyWxToClaimUser (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpInt"], SEP)
215-
216-
217-func keyWxPerLpIntegralUserLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpIntH"], SEP)
218-
219-
220-func keyWxPerLp (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLp"], SEP)
221-
222-
223-func keyWxPerLpX18 (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLpX18"], SEP)
224-
225-
226-func keyWxPerLpIntegralUserLast (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "uIntL"], SEP)
227-
228-
229-func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
230-
231-
232-func formatHistoryRecord (userAddress,lpAssetId,type,amount) = makeString(["%s%s%s%d%d%d", userAddress, lpAssetId, type, toString(height), toString(lastBlock.timestamp), toString(amount)], SEP)
233-
234-
235-func OperationHistoryEntry (type,userAddress,lpAssetId,amount,txId) = StringEntry(keyOperationHistoryRecord(type, userAddress, toBase58String(txId)), formatHistoryRecord(userAddress, lpAssetId, type, amount))
236-
237-
238-let factoryAddress = getStringOrFail(this, keyFactoryAddress())
239-
240-let factoryContract = addressFromStringValue(factoryAddress)
241-
242-let factoryCfg = readFactoryCfgOrFail(factoryContract)
243-
244-let emissionContract = getEmissionAddressOrFail(factoryCfg)
245-
246-let boostingContract = getBoostingAddressOrFail(factoryCfg)
247-
248-let lpStakingPoolsContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(makeString(["%s", "lpStakingPoolsContract"], SEP)), wrapErr("lp_staking_pools contract address is undefined"))), wrapErr("invalid lp_staking_pools contract address"))
249-
250-func keyNextUser (lpAssetId) = makeString(["%s%s", lpAssetId, "nextUser"], SEP)
251-
252-
253-func getUsersListName (lpAssetId) = makeString(["users", lpAssetId], SEP)
254-
255-
256-func keyListHead (listName) = makeString(["%s%s%s", listName, "head"], SEP)
257-
258-
259-func keyListSize (listName) = makeString(["%s%s%s", listName, "size"], SEP)
260-
261-
262-func keyListPrev (listName,id) = makeString(["%s%s%s%s", listName, id, "prev"], SEP)
263-
264-
265-func keyListNext (listName,id) = makeString(["%s%s%s%s", listName, id, "next"], SEP)
266-
267-
268-func containsNode (listName,id) = {
269- let headOrUnit = getString(this, keyListHead(listName))
270- let prevOrUnit = getString(this, keyListPrev(listName, id))
271- let nextOrUnit = getString(this, keyListNext(listName, id))
272- if (if ((id == valueOrElse(headOrUnit, "")))
273- then true
274- else (prevOrUnit != unit))
275- then true
276- else (nextOrUnit != unit)
277- }
278-
279-
280-func insertNodeActions (listName,id) = {
281- let headOrUnit = getString(this, keyListHead(listName))
282- let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
283- let checkNode = if (!(containsNode(listName, id)))
284- then true
285- else throw("Node exists")
286- if ((checkNode == checkNode))
287- then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
288- then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
289- else nil)) ++ [StringEntry(keyListHead(listName), id)])
290- else throw("Strict value is not equal to itself.")
291- }
292-
293-
294-func deleteNodeActions (listName,id) = {
295- let headOrUnit = getString(this, keyListHead(listName))
296- let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
297- let prevOrUnit = getString(this, keyListPrev(listName, id))
298- let nextOrUnit = getString(this, keyListNext(listName, id))
299- ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
300- then (nextOrUnit != unit)
301- else false)
302- then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
303- else if ((nextOrUnit != unit))
304- then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
305- else if ((prevOrUnit != unit))
306- then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
307- else if ((id == valueOrElse(headOrUnit, "")))
308- then [DeleteEntry(keyListHead(listName))]
309- else throw(((("invalid node: " + listName) + ".") + id))))
310- }
311-
312-
313-func calcWxPerLpIntegralUserLast (stakedByUser,wxPerLpIntegralUserLastUpdHeightOrZero,wxPerLpIntegralNew,wxPerLpIntegralUserLastKEY) = if (if ((wxPerLpIntegralUserLastUpdHeightOrZero == zeroBigInt))
314- then (stakedByUser > zeroBigInt)
315- else false)
316- then zeroBigInt
317- else if ((stakedByUser == zeroBigInt))
318- then wxPerLpIntegralNew
319- else if (if ((wxPerLpIntegralUserLastUpdHeightOrZero > zeroBigInt))
320- then (stakedByUser > zeroBigInt)
321- else false)
322- then value(parseBigInt(getStringOrFail(this, wxPerLpIntegralUserLastKEY)))
323- else throw("calcWxPerLpIntegralUserLast: unexpected state")
324-
325-
326-func refreshPoolINTEGRALS (lpAssetIdStr,poolAddressStr,lpDeltaAmount) = {
327- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
328- let stakedTotal = toBigInt(readStaked(stakedTotalKEY))
329- let nonZeroStakedTotal = if ((stakedTotal == zeroBigInt))
330- then oneBigInt
331- else stakedTotal
332- let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
333- let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
334- let MULT3 = 1000
335- let wxEmissionPerBlockX3 = (getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) * MULT3)
336- let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * 3))
337- let wxPerLpIntegralKEY = keyWxPerLpIntegral(lpAssetIdStr)
338- let wxPerLpIntegralLastUpdHeightKEY = keyWxPerLpIntegralLastUpdHeight(lpAssetIdStr)
339- let wxPerLpKEY = keyWxPerLp(lpAssetIdStr)
340- let wxPerLpIntegralLastUpdHeight = getIntOrDefault(this, wxPerLpIntegralLastUpdHeightKEY, emissionStartBlock)
341- let wxPerLpIntegral = getBigIntFromStringOrZero(this, wxPerLpIntegralKEY)
342- let wxPerLpOrZeroX3 = 0
343- let dh = max([(height - wxPerLpIntegralLastUpdHeight), 0])
344- let wxPerLpX3 = if ((wxPerLpOrZeroX3 != 0))
345- then toBigInt(wxPerLpOrZeroX3)
346- else fraction(toBigInt(poolWxEmissionPerBlockX3), toBigInt(MULT8), nonZeroStakedTotal)
347- let stakedTotalNew = (stakedTotal + toBigInt(lpDeltaAmount))
348- let nonZeroStakedTotalNew = if ((stakedTotalNew == zeroBigInt))
349- then oneBigInt
350- else stakedTotalNew
351- let wxPerLpIntegralNew = (wxPerLpIntegral + (wxPerLpX3 * toBigInt(dh)))
352- let wxPerLpX3New = (toBigInt(poolWxEmissionPerBlockX3) / nonZeroStakedTotalNew)
353- let wxPerLpIntegralLastUpdHeightNew = height
354- let debug = makeString([toString(wxPerLpIntegralNew), toString(dh), toString(wxPerLpX3), toString(stakedTotal), toString(poolWxEmissionPerBlockX3), toString(wxEmissionPerBlockX3), toString(poolWeight)], "::")
355- $Tuple3(wxPerLpIntegralNew, [StringEntry(wxPerLpIntegralKEY, toString(wxPerLpIntegralNew)), IntegerEntry(wxPerLpIntegralLastUpdHeightKEY, wxPerLpIntegralLastUpdHeightNew), StringEntry(wxPerLpKEY, toString(wxPerLpX3New))], debug)
356- }
357-
358-
359-func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
360- let $t01506115183 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
361- let wxPerLpIntegralNew = $t01506115183._1
362- let poolIntegralSTATE = $t01506115183._2
363- let poolDEBUG = $t01506115183._3
364- let MULT3 = 1000
365- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
366- let stakedByUser = readStaked(stakedByUserKEY)
367- let wxToClaimUserKEY = keyWxToClaimUser(lpAssetIdStr, userAddressStr)
368- let wxPerLpIntegralUserLastUpdHeightKEY = keyWxPerLpIntegralUserLastUpdHeight(lpAssetIdStr, userAddressStr)
369- let wxPerLpIntegralUserLastKEY = keyWxPerLpIntegralUserLast(lpAssetIdStr, userAddressStr)
370- let wxToClaimUser = getBigIntFromStringOrZero(this, wxToClaimUserKEY)
371- let wxPerLpIntegralUserLastUpdHeightOrZero = getIntOrZero(this, wxPerLpIntegralUserLastUpdHeightKEY)
372- let wxPerLpIntegralUserLast = calcWxPerLpIntegralUserLast(toBigInt(stakedByUser), toBigInt(wxPerLpIntegralUserLastUpdHeightOrZero), wxPerLpIntegralNew, wxPerLpIntegralUserLastKEY)
373- let MULT11 = (MULT8 * MULT3)
374- let wxToClaimUserNew = max([(wxToClaimUser + fraction((wxPerLpIntegralNew - wxPerLpIntegralUserLast), toBigInt(stakedByUser), toBigInt(MULT11))), zeroBigInt])
375- let wxPerLpIntegralUserLastNew = wxPerLpIntegralNew
376- let wxPerLpIntegralUserLastUpdHeightNew = height
377- let debug = makeString([toString(wxToClaimUser), toString(wxPerLpIntegralUserLast), toString(stakedByUser), poolDEBUG, toString(height)], "::")
378- $Tuple3(wxToClaimUserNew, (poolIntegralSTATE ++ [StringEntry(wxToClaimUserKEY, toString(wxToClaimUserNew)), IntegerEntry(wxPerLpIntegralUserLastUpdHeightKEY, wxPerLpIntegralUserLastUpdHeightNew), StringEntry(wxPerLpIntegralUserLastKEY, toString(wxPerLpIntegralUserLastNew))]), debug)
379- }
380-
381-
382-func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
383- case s: String =>
384- fromBase58String(s)
385- case _: Unit =>
386- unit
387- case _ =>
388- throw("Match error")
389-}
390-
391-
392-func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
393- case s: String =>
394- fromBase58String(s)
395- case _: Unit =>
396- unit
397- case _ =>
398- throw("Match error")
399-}
400-
401-
402-let permissionDeniedError = throw("Permission denied")
403-
404-func mustThis (i) = if ((i.caller == this))
405- then true
406- else permissionDeniedError
407-
408-
409-func mustManager (i) = match managerPublicKeyOrUnit() {
410- case pk: ByteVector =>
411- if ((i.callerPublicKey == pk))
412- then true
413- else permissionDeniedError
414- case _: Unit =>
415- if ((i.caller == this))
416- then true
417- else permissionDeniedError
418- case _ =>
419- throw("Match error")
420-}
421-
422-
423-func unstakeActions (i,lpAssetId,poolAddress,userAddress,lpAssetRecipientAddress,amount) = {
424- let userAddressStr = toString(userAddress)
425- let lpAssetIdStr = toBase58String(lpAssetId)
426- let poolAddressStr = toString(poolAddress)
427- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
428- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
429- let stakedByUser = readStaked(stakedByUserKEY)
430- let stakedTotal = readStaked(stakedTotalKEY)
431- let integralSTATE = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))._2
432- let listName = getUsersListName(lpAssetIdStr)
433- let listActions = if (if (containsNode(listName, userAddressStr))
434- then (amount == stakedByUser)
435- else false)
436- then deleteNodeActions(listName, userAddressStr)
437- else nil
438- let refreshStakedVote = if ((amount == stakedByUser))
439- then invoke(boostingContract, "onStakedVoteUpdate", [lpAssetIdStr, userAddressStr, false], nil)
440- else unit
441- if ((refreshStakedVote == refreshStakedVote))
442- then {
443- let claimedByUserMinReward = getBigIntFromStringOrZero(this, keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr))
444- let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)._1
445- let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
446- let throwIfNothingToClaim = true
447- let r = if ((availableToClaim > zeroBigInt))
448- then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
449- else unit
450- if ((r == r))
451- then if ((amount > stakedByUser))
452- then throw(((((((("passed amount=" + toString(amount)) + " is greater than available=") + toString(stakedByUser)) + ". lpAssetId=") + lpAssetIdStr) + ". stakedByUserKEY=") + stakedByUserKEY))
453- else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(lpAssetRecipientAddress, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
454- else throw("Strict value is not equal to itself.")
455- }
456- else throw("Strict value is not equal to itself.")
457- }
458-
459-
460-@Callable(i)
461-func constructor (factoryAddressStr) = {
462- let checkCaller = mustManager(i)
463- if ((checkCaller == checkCaller))
464- then [StringEntry(keyFactoryAddress(), factoryAddressStr)]
465- else throw("Strict value is not equal to itself.")
466- }
467-
468-
469-
470-@Callable(i)
471-func constructorV2 (votingEmissionContract) = {
472- let cheks = [mustManager(i), if ((addressFromString(votingEmissionContract) != unit))
473- then true
474- else "invalid voting emission contract address"]
475- if ((cheks == cheks))
476- then [StringEntry(keyVotingEmissionContract(), votingEmissionContract)]
477- else throw("Strict value is not equal to itself.")
478- }
479-
480-
481-
482-@Callable(i)
483-func setManager (pendingManagerPublicKey) = {
484- let checkCaller = mustManager(i)
485- if ((checkCaller == checkCaller))
486- then {
487- let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
488- if ((checkManagerPublicKey == checkManagerPublicKey))
489- then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
490- else throw("Strict value is not equal to itself.")
491- }
492- else throw("Strict value is not equal to itself.")
493- }
494-
495-
496-
497-@Callable(i)
498-func confirmManager () = {
499- let pm = pendingManagerPublicKeyOrUnit()
500- let hasPM = if (isDefined(pm))
501- then true
502- else throw("No pending manager")
503- if ((hasPM == hasPM))
504- then {
505- let checkPM = if ((i.callerPublicKey == value(pm)))
506- then true
507- else throw("You are not pending manager")
508- if ((checkPM == checkPM))
509- then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
510- else throw("Strict value is not equal to itself.")
511- }
512- else throw("Strict value is not equal to itself.")
513- }
514-
515-
516-
517-@Callable(i)
518-func stake () = if ((size(i.payments) != 1))
519- then throw("invalid payment - exact one payment must be attached")
520- else {
521- let pmt = i.payments[0]
522- let lpAssetId = value(pmt.assetId)
523- let lpAssetIdStr = toBase58String(lpAssetId)
524- let amount = pmt.amount
525- let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
526- let callerStr = toString(i.caller)
527- let userAddressStr = if ((callerStr == poolAddressStr))
528- then toString(i.originCaller)
529- else callerStr
530- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
531- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
532- let stakedByUser = readStaked(stakedByUserKEY)
533- let refreshStakedVote = if ((stakedByUser == 0))
534- then invoke(boostingContract, "onStakedVoteUpdate", [lpAssetIdStr, userAddressStr, true], nil)
535- else unit
536- if ((refreshStakedVote == refreshStakedVote))
537- then {
538- let stakedTotal = readStaked(stakedTotalKEY)
539- let $t02210022217 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
540- let wxToClaimUserNew = $t02210022217._1
541- let integralSTATE = $t02210022217._2
542- let debug = $t02210022217._3
543- let listName = getUsersListName(lpAssetIdStr)
544- let listActions = if (containsNode(listName, userAddressStr))
545- then nil
546- else insertNodeActions(listName, userAddressStr)
547- (([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
548- }
549- else throw("Strict value is not equal to itself.")
550- }
551-
552-
553-
554-@Callable(i)
555-func unstake (lpAssetIdStr,amount) = {
556- let lpAssetId = fromBase58String(lpAssetIdStr)
557- let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
558- let poolAddress = addressFromStringValue(poolAddressStr)
559- let poolAddon = valueOrElse(getString(poolAddress, keyAddonAddr()), poolAddressStr)
560- let callerStr = toString(i.caller)
561- let userAddress = if (if ((callerStr == poolAddressStr))
562- then true
563- else (callerStr == poolAddon))
564- then i.originCaller
565- else i.caller
566- let lpAssetRecipientAddress = i.caller
567- unstakeActions(i, lpAssetId, poolAddress, userAddress, lpAssetRecipientAddress, amount)
568- }
569-
570-
571-
572-@Callable(i)
573-func unstakeINTERNAL (lpAssetId,amount,userAddress,lpAssetRecipientAddress) = {
574- let lpAssetIdStr = toBase58String(lpAssetId)
575- let poolAddress = addressFromStringValue(valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr)))
576- let checkCaller = if ((i.caller == poolAddress))
577- then true
578- else permissionDeniedError
579- if ((checkCaller == checkCaller))
580- then unstakeActions(i, lpAssetId, poolAddress, Address(userAddress), Address(lpAssetRecipientAddress), amount)
581- else throw("Strict value is not equal to itself.")
582- }
583-
584-
585-
586-@Callable(i)
587-func claimWx (lpAssetIdStr) = {
588- let userAddressStr = toString(i.caller)
589- let throwIfNothingToClaim = true
590- let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
591- $Tuple2(nil, result)
592- }
593-
594-
595-
596-@Callable(i)
597-func claimWxDoNotThrow (lpAssetIdStr) = {
598- let userAddressStr = toString(i.caller)
599- let throwIfNothingToClaim = false
600- let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
601- $Tuple2(nil, result)
602- }
603-
604-
605-
606-@Callable(i)
607-func claimWxINTERNAL (lpAssetIdStr,userAddressStr,throwIfNothingToClaim) = {
608- let checkCaller = mustThis(i)
609- if ((checkCaller == checkCaller))
610- then {
611- let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), "claimWxINTERNAL: invalid user address")
612- let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
613- let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
614- let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr)
615- let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
616- let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr)
617- let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
618- let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
619- let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
620- let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
621- let $t02569425806 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
622- let wxToClaimUserNew = $t02569425806._1
623- let integralSTATE = $t02569425806._2
624- let debug = $t02569425806._3
625- let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
626- if ((zeroBigInt >= availableToClaim))
627- then if (throwIfNothingToClaim)
628- then throw("nothing to claim")
629- else $Tuple2(nil, 0)
630- else {
631- let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
632- let minRewardPart = availableToClaim
633- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
634- let totalReward = (minRewardPart + boostRewardPart)
635- let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
636- let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
637- if ((emitBoost == emitBoost))
638- then {
639- let claimedByUserValue = ((claimedByUser + minRewardPart) + boostRewardPart)
640- let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
641- let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserBoostReward + boostRewardPart)
642- let claimedTotalPlusAvailableToClaim = (claimedTotal + availableToClaim)
643- $Tuple2([StringEntry(claimedByUserKEY, toString(claimedByUserValue)), StringEntry(claimedByUserMinRewardKEY, toString(claimedByUserMinRewardPlusPart)), StringEntry(claimedByUserBoostRewardKEY, toString(claimedByUserBoostRewardPlusBoostRewardPart)), StringEntry(claimedTotalKEY, toString(claimedTotalPlusAvailableToClaim)), ScriptTransfer(userAddress, toInt(minRewardPart), wxAssetId), ScriptTransfer(userAddress, toInt(boostRewardPart), wxAssetId), OperationHistoryEntry("claim", userAddressStr, lpAssetIdStr, toInt(availableToClaim), i.transactionId)], toInt(totalReward))
644- }
645- else throw("Strict value is not equal to itself.")
646- }
647- }
648- else throw("Strict value is not equal to itself.")
649- }
650-
651-
652-
653-@Callable(i)
654-func claimWxBulkInternalREADONLY (currentIter,lpAssetIds,userAddressStr,resAcc) = if ((currentIter == size(lpAssetIds)))
655- then $Tuple2(nil, resAcc)
656- else {
657- let lpAssetId = lpAssetIds[currentIter]
658- let info = split({
659- let @ = invoke(this, "claimWxREADONLY", [lpAssetId, userAddressStr], nil)
660- if ($isInstanceOf(@, "String"))
661- then @
662- else throw(($getType(@) + " couldn't be cast to String"))
663- }, SEP)
664- let unclaimed = info[3]
665- let claimed = info[4]
666- let res = (resAcc :+ makeString(["%d%d", unclaimed, claimed], SEP))
667- let inv = {
668- let @ = invoke(this, "claimWxBulkInternalREADONLY", [(currentIter + 1), lpAssetIds, userAddressStr, res], nil)
669- if ($isInstanceOf(@, "List[Any]"))
670- then @
671- else throw(($getType(@) + " couldn't be cast to List[Any]"))
672- }
673- if ((inv == inv))
674- then $Tuple2(nil, inv)
675- else throw("Strict value is not equal to itself.")
676- }
677-
678-
679-
680-@Callable(i)
681-func claimWxBulkREADONLY (lpAssetIds,userAddressStr) = {
682- let res = invoke(this, "claimWxBulkInternalREADONLY", [0, lpAssetIds, userAddressStr, nil], nil)
683- $Tuple2(nil, res)
684- }
685-
686-
687-
688-@Callable(i)
689-func claimWxREADONLY (lpAssetIdStr,userAddressStr) = {
690- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
691- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
692- let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
693- let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
694- let stakedByUser = readStaked(stakedByUserKEY)
695- let stakedTotal = readStaked(stakedTotalKEY)
696- let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
697- let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
698- let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
699- let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
700- let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
701- let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
702- let passedBlocks = if ((emissionStartBlock > height))
703- then 0
704- else (height - emissionStartBlock)
705- let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
706- let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
707- let $t02969029802 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
708- let wxToClaimUserNew = $t02969029802._1
709- let integralSTATE = $t02969029802._2
710- let debug = $t02969029802._3
711- let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
712- let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
713- let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
714- let boostDebug = asString(boostInvResult[1])
715- let minRewardPart = availableToClaim
716- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
717- let totalReward = (minRewardPart + boostRewardPart)
718- $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), "soon"], SEP))
719- }
720-
721-
722-
723-@Callable(i)
724-func stakedByUserREADONLY (lpAssetIdStr,userAddressStr) = {
725- let stakedByUser = valueOrElse(getInteger(keyStakedByUser(userAddressStr, lpAssetIdStr)), 0)
726- $Tuple2(nil, stakedByUser)
727- }
728-
729-
730-
731-@Callable(i)
732-func usersListTraversal (lpAssetId) = {
733- let checkCaller = if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionContract()), "")))
734- then true
735- else mustManager(i)
736- if ((checkCaller == checkCaller))
737- then {
738- let listName = getUsersListName(lpAssetId)
739- let userOrUnit = getString(keyNextUser(lpAssetId))
740- let headOrUnit = getString(keyListHead(listName))
741- match userOrUnit {
742- case _: Unit =>
743- match headOrUnit {
744- case _: Unit =>
745- $Tuple2(nil, false)
746- case head: String =>
747- $Tuple2([StringEntry(keyNextUser(lpAssetId), head)], true)
748- case _ =>
749- throw("Match error")
750- }
751- case userAddress: String =>
752- let claimedByUserMinReward = getBigIntFromStringOrZero(this, keyClaimedByUserMinReward(lpAssetId, userAddress))
753- let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetId))
754- let wxToClaimUserNew = refreshINTEGRALS(lpAssetId, userAddress, poolAddress, 0)._1
755- let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
756- let throwIfNothingToClaim = true
757- let r = if ((availableToClaim > zeroBigInt))
758- then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress, throwIfNothingToClaim], nil)
759- else unit
760- if ((r == r))
761- then {
762- let nextUserOrUnit = getString(keyListNext(listName, userAddress))
763- match nextUserOrUnit {
764- case _: Unit =>
765- $Tuple2([DeleteEntry(keyNextUser(lpAssetId))], false)
766- case nextUser: String =>
767- $Tuple2([StringEntry(keyNextUser(lpAssetId), nextUser)], true)
768- case _ =>
769- throw("Match error")
770- }
771- }
772- else throw("Strict value is not equal to itself.")
773- case _ =>
774- throw("Match error")
775- }
776- }
777- else throw("Strict value is not equal to itself.")
778- }
779-
780-
781-
782-@Callable(i)
783-func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
784- then throw("permissions denied")
785- else {
786- let $t03246832578 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
787- let wxPerLpIntegralNew = $t03246832578._1
788- let poolIntegralSTATE = $t03246832578._2
789- let poolDEBUG = $t03246832578._3
790- poolIntegralSTATE
791- }
792-
793-
794-@Verifier(tx)
795-func verify () = {
796- let targetPublicKey = match managerPublicKeyOrUnit() {
797- case pk: ByteVector =>
798- pk
799- case _: Unit =>
800- tx.senderPublicKey
801- case _ =>
802- throw("Match error")
803- }
804- sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
805- }
806-
1+# no script

github/deemru/w8io/873ac7e 
86.12 ms