tx · BATGpHBi6zcHXq2Q6n2f9DP7xt3tn529LRdQmX7gcE1y

3MwNfynRH5bFf25GzWjcEdi6kSkX4AwR9Bz:  -0.00500000 Waves

2023.03.16 11:34 [2492340] smart account 3MwNfynRH5bFf25GzWjcEdi6kSkX4AwR9Bz > SELF 0.00000000 Waves

{ "type": 13, "id": "BATGpHBi6zcHXq2Q6n2f9DP7xt3tn529LRdQmX7gcE1y", "fee": 500000, "feeAssetId": null, "timestamp": 1678955700452, "version": 2, "chainId": 84, "sender": "3MwNfynRH5bFf25GzWjcEdi6kSkX4AwR9Bz", "senderPublicKey": "CP4TEKgebTgiDjwiN6XPMRxxtJr9ZNVotimqif4HEqx5", "proofs": [ "2JUHrYkuV7tKAdenqZS2nMP9VE1cVd54XYzdAjoyNTLXtNN7SFurwczQ8fkqUoaay3rifRPpmXm4med8jkTjwYmg" ], "script": null, "height": 2492340, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: C1eiGvZaaLDBGuaRXs6y3E811HDFmtoioeCCN48voGuK Next: DPRBicGgWKLWFQAEyeTLHXxDLUDixATiX7nevbiRZGeZ 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 claimedByUserMinReward = getBigIntFromStringOrZero(this, keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr))
439- let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)._1
440- let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
441- let throwIfNothingToClaim = true
442- let r = if ((availableToClaim > zeroBigInt))
443- then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
444- else unit
445- if ((r == r))
446- then if ((amount > stakedByUser))
447- then throw(((((((("passed amount=" + toString(amount)) + " is greater than available=") + toString(stakedByUser)) + ". lpAssetId=") + lpAssetIdStr) + ". stakedByUserKEY=") + stakedByUserKEY))
448- else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(lpAssetRecipientAddress, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
449- else throw("Strict value is not equal to itself.")
450- }
451-
452-
453-@Callable(i)
454-func constructor (factoryAddressStr) = {
455- let checkCaller = mustManager(i)
456- if ((checkCaller == checkCaller))
457- then [StringEntry(keyFactoryAddress(), factoryAddressStr)]
458- else throw("Strict value is not equal to itself.")
459- }
460-
461-
462-
463-@Callable(i)
464-func constructorV2 (votingEmissionContract) = {
465- let cheks = [mustManager(i), if ((addressFromString(votingEmissionContract) != unit))
466- then true
467- else "invalid voting emission contract address"]
468- if ((cheks == cheks))
469- then [StringEntry(keyVotingEmissionContract(), votingEmissionContract)]
470- else throw("Strict value is not equal to itself.")
471- }
472-
473-
474-
475-@Callable(i)
476-func setManager (pendingManagerPublicKey) = {
477- let checkCaller = mustManager(i)
478- if ((checkCaller == checkCaller))
479- then {
480- let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
481- if ((checkManagerPublicKey == checkManagerPublicKey))
482- then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
483- else throw("Strict value is not equal to itself.")
484- }
485- else throw("Strict value is not equal to itself.")
486- }
487-
488-
489-
490-@Callable(i)
491-func confirmManager () = {
492- let pm = pendingManagerPublicKeyOrUnit()
493- let hasPM = if (isDefined(pm))
494- then true
495- else throw("No pending manager")
496- if ((hasPM == hasPM))
497- then {
498- let checkPM = if ((i.callerPublicKey == value(pm)))
499- then true
500- else throw("You are not pending manager")
501- if ((checkPM == checkPM))
502- then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
503- else throw("Strict value is not equal to itself.")
504- }
505- else throw("Strict value is not equal to itself.")
506- }
507-
508-
509-
510-@Callable(i)
511-func stake () = if ((size(i.payments) != 1))
512- then throw("invalid payment - exact one payment must be attached")
513- else {
514- let pmt = i.payments[0]
515- let lpAssetId = value(pmt.assetId)
516- let lpAssetIdStr = toBase58String(lpAssetId)
517- let amount = pmt.amount
518- let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
519- let callerStr = toString(i.caller)
520- let userAddressStr = if ((callerStr == poolAddressStr))
521- then toString(i.originCaller)
522- else callerStr
523- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
524- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
525- let stakedByUser = readStaked(stakedByUserKEY)
526- let stakedTotal = readStaked(stakedTotalKEY)
527- let $t02175621873 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
528- let wxToClaimUserNew = $t02175621873._1
529- let integralSTATE = $t02175621873._2
530- let debug = $t02175621873._3
531- let listName = getUsersListName(lpAssetIdStr)
532- let listActions = if (containsNode(listName, userAddressStr))
533- then nil
534- else insertNodeActions(listName, userAddressStr)
535- (([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
536- }
537-
538-
539-
540-@Callable(i)
541-func unstake (lpAssetIdStr,amount) = {
542- let lpAssetId = fromBase58String(lpAssetIdStr)
543- let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
544- let poolAddress = addressFromStringValue(poolAddressStr)
545- let poolAddon = valueOrElse(getString(poolAddress, keyAddonAddr()), poolAddressStr)
546- let callerStr = toString(i.caller)
547- let userAddress = if (if ((callerStr == poolAddressStr))
548- then true
549- else (callerStr == poolAddon))
550- then i.originCaller
551- else i.caller
552- let lpAssetRecipientAddress = i.caller
553- unstakeActions(i, lpAssetId, poolAddress, userAddress, lpAssetRecipientAddress, amount)
554- }
555-
556-
557-
558-@Callable(i)
559-func unstakeINTERNAL (lpAssetId,amount,userAddress,lpAssetRecipientAddress) = {
560- let lpAssetIdStr = toBase58String(lpAssetId)
561- let poolAddress = addressFromStringValue(valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr)))
562- let checkCaller = if ((i.caller == poolAddress))
563- then true
564- else permissionDeniedError
565- if ((checkCaller == checkCaller))
566- then unstakeActions(i, lpAssetId, poolAddress, Address(userAddress), Address(lpAssetRecipientAddress), amount)
567- else throw("Strict value is not equal to itself.")
568- }
569-
570-
571-
572-@Callable(i)
573-func claimWx (lpAssetIdStr) = {
574- let userAddressStr = toString(i.caller)
575- let throwIfNothingToClaim = true
576- let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
577- $Tuple2(nil, result)
578- }
579-
580-
581-
582-@Callable(i)
583-func claimWxDoNotThrow (lpAssetIdStr) = {
584- let userAddressStr = toString(i.caller)
585- let throwIfNothingToClaim = false
586- let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
587- $Tuple2(nil, result)
588- }
589-
590-
591-
592-@Callable(i)
593-func claimWxINTERNAL (lpAssetIdStr,userAddressStr,throwIfNothingToClaim) = {
594- let checkCaller = mustThis(i)
595- if ((checkCaller == checkCaller))
596- then {
597- let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), "claimWxINTERNAL: invalid user address")
598- let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
599- let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
600- let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr)
601- let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
602- let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr)
603- let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
604- let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
605- let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
606- let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
607- let $t02535025462 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
608- let wxToClaimUserNew = $t02535025462._1
609- let integralSTATE = $t02535025462._2
610- let debug = $t02535025462._3
611- let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
612- if ((zeroBigInt >= availableToClaim))
613- then if (throwIfNothingToClaim)
614- then throw("nothing to claim")
615- else $Tuple2(nil, 0)
616- else {
617- let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
618- let minRewardPart = availableToClaim
619- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
620- let totalReward = (minRewardPart + boostRewardPart)
621- let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
622- let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
623- if ((emitBoost == emitBoost))
624- then {
625- let claimedByUserValue = ((claimedByUser + minRewardPart) + boostRewardPart)
626- let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
627- let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserBoostReward + boostRewardPart)
628- let claimedTotalPlusAvailableToClaim = (claimedTotal + availableToClaim)
629- $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))
630- }
631- else throw("Strict value is not equal to itself.")
632- }
633- }
634- else throw("Strict value is not equal to itself.")
635- }
636-
637-
638-
639-@Callable(i)
640-func claimWxBulkInternalREADONLY (currentIter,lpAssetIds,userAddressStr,resAcc) = if ((currentIter == size(lpAssetIds)))
641- then $Tuple2(nil, resAcc)
642- else {
643- let lpAssetId = lpAssetIds[currentIter]
644- let info = split({
645- let @ = invoke(this, "claimWxREADONLY", [lpAssetId, userAddressStr], nil)
646- if ($isInstanceOf(@, "String"))
647- then @
648- else throw(($getType(@) + " couldn't be cast to String"))
649- }, SEP)
650- let unclaimed = info[3]
651- let claimed = info[4]
652- let res = (resAcc :+ makeString(["%d%d", unclaimed, claimed], SEP))
653- let inv = {
654- let @ = invoke(this, "claimWxBulkInternalREADONLY", [(currentIter + 1), lpAssetIds, userAddressStr, res], nil)
655- if ($isInstanceOf(@, "List[Any]"))
656- then @
657- else throw(($getType(@) + " couldn't be cast to List[Any]"))
658- }
659- if ((inv == inv))
660- then $Tuple2(nil, inv)
661- else throw("Strict value is not equal to itself.")
662- }
663-
664-
665-
666-@Callable(i)
667-func claimWxBulkREADONLY (lpAssetIds,userAddressStr) = {
668- let res = invoke(this, "claimWxBulkInternalREADONLY", [0, lpAssetIds, userAddressStr, nil], nil)
669- $Tuple2(nil, res)
670- }
671-
672-
673-
674-@Callable(i)
675-func claimWxREADONLY (lpAssetIdStr,userAddressStr) = {
676- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
677- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
678- let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
679- let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
680- let stakedByUser = readStaked(stakedByUserKEY)
681- let stakedTotal = readStaked(stakedTotalKEY)
682- let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
683- let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
684- let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
685- let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
686- let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
687- let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
688- let passedBlocks = if ((emissionStartBlock > height))
689- then 0
690- else (height - emissionStartBlock)
691- let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
692- let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
693- let $t02934629458 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
694- let wxToClaimUserNew = $t02934629458._1
695- let integralSTATE = $t02934629458._2
696- let debug = $t02934629458._3
697- let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
698- let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
699- let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
700- let boostDebug = asString(boostInvResult[1])
701- let minRewardPart = availableToClaim
702- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
703- let totalReward = (minRewardPart + boostRewardPart)
704- $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), "soon"], SEP))
705- }
706-
707-
708-
709-@Callable(i)
710-func stakedByUserREADONLY (lpAssetIdStr,userAddressStr) = {
711- let stakedByUser = valueOrElse(getInteger(keyStakedByUser(userAddressStr, lpAssetIdStr)), 0)
712- $Tuple2(nil, stakedByUser)
713- }
714-
715-
716-
717-@Callable(i)
718-func usersListTraversal (lpAssetId) = {
719- let checkCaller = if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionContract()), "")))
720- then true
721- else mustManager(i)
722- if ((checkCaller == checkCaller))
723- then {
724- let listName = getUsersListName(lpAssetId)
725- let userOrUnit = getString(keyNextUser(lpAssetId))
726- let headOrUnit = getString(keyListHead(listName))
727- match userOrUnit {
728- case _: Unit =>
729- match headOrUnit {
730- case _: Unit =>
731- $Tuple2(nil, false)
732- case head: String =>
733- $Tuple2([StringEntry(keyNextUser(lpAssetId), head)], true)
734- case _ =>
735- throw("Match error")
736- }
737- case userAddress: String =>
738- let claimedByUserMinReward = getBigIntFromStringOrZero(this, keyClaimedByUserMinReward(lpAssetId, userAddress))
739- let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetId))
740- let wxToClaimUserNew = refreshINTEGRALS(lpAssetId, userAddress, poolAddress, 0)._1
741- let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
742- let throwIfNothingToClaim = true
743- let r = if ((availableToClaim > zeroBigInt))
744- then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress, throwIfNothingToClaim], nil)
745- else unit
746- if ((r == r))
747- then {
748- let nextUserOrUnit = getString(keyListNext(listName, userAddress))
749- match nextUserOrUnit {
750- case _: Unit =>
751- $Tuple2([DeleteEntry(keyNextUser(lpAssetId))], false)
752- case nextUser: String =>
753- $Tuple2([StringEntry(keyNextUser(lpAssetId), nextUser)], true)
754- case _ =>
755- throw("Match error")
756- }
757- }
758- else throw("Strict value is not equal to itself.")
759- case _ =>
760- throw("Match error")
761- }
762- }
763- else throw("Strict value is not equal to itself.")
764- }
765-
766-
767-
768-@Callable(i)
769-func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
770- then throw("permissions denied")
771- else {
772- let $t03212432234 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
773- let wxPerLpIntegralNew = $t03212432234._1
774- let poolIntegralSTATE = $t03212432234._2
775- let poolDEBUG = $t03212432234._3
776- poolIntegralSTATE
777- }
778-
779-
780-@Verifier(tx)
781-func verify () = {
782- let targetPublicKey = match managerPublicKeyOrUnit() {
783- case pk: ByteVector =>
784- pk
785- case _: Unit =>
786- tx.senderPublicKey
787- case _ =>
788- throw("Match error")
789- }
790- sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
791- }
792-
1+# no script

github/deemru/w8io/169f3d6 
41.56 ms