tx · 8b1uJezXg8LSAntZu2jiiKATGpn66kRRk9GxSvSDQDdj

3NCWFHDzdPHZC6636ZkMLNDup9mjpbTLs7h:  -0.05000000 Waves

2023.03.27 10:14 [2508069] smart account 3NCWFHDzdPHZC6636ZkMLNDup9mjpbTLs7h > SELF 0.00000000 Waves

{ "type": 13, "id": "8b1uJezXg8LSAntZu2jiiKATGpn66kRRk9GxSvSDQDdj", "fee": 5000000, "feeAssetId": null, "timestamp": 1679900972445, "version": 2, "chainId": 84, "sender": "3NCWFHDzdPHZC6636ZkMLNDup9mjpbTLs7h", "senderPublicKey": "3z8Q6Zu3KppVmn6fJJvrLc1Wo3krVHSvfaNcerm82md2", "proofs": [ "4n12akYfgjJNxXHqWz2qjF7EFVi1qU1Q8pSRGyzhWVTm3RqvG4KZuQyWNQJPRVGfp5pCjBnXRjZMbAnfiFwuKF1y" ], "script": null, "height": 2508069, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: DF2cUS5AjznwE7V43C2X4WLfj2SgD8rdJwkmb2bjChUT Next: A3jPEWp8p3Q6MQ9w3nAebdfeSFPXebMqf6hEUzN3V7RC Full:
OldNewDifferences
1-{-# STDLIB_VERSION 5 #-}
2-{-# SCRIPT_TYPE ACCOUNT #-}
3-{-# CONTENT_TYPE DAPP #-}
4-func getStringOrFail (key) = valueOrErrorMessage(getString(key), (("mandatory this." + key) + " is not defined"))
5-
6-
7-let SEP = "__"
8-
9-let BUFSCALE = toBigInt(1000000000000000000)
10-
11-func convertPriceAssetIntoIdoAsset (priceAssetAmount,priceAssetMULT,price,priceMULT,idoAssetMULT) = {
12- let bPriceAssetMULT = toBigInt(priceAssetMULT)
13- let bIdoAssetMULT = toBigInt(idoAssetMULT)
14- let bPriceAssetBUF = fraction(toBigInt(priceAssetAmount), BUFSCALE, bPriceAssetMULT)
15- let bAmountAssetBUF = fraction(bPriceAssetBUF, toBigInt(priceMULT), toBigInt(price))
16- toInt(fraction(bAmountAssetBUF, toBigInt(idoAssetMULT), BUFSCALE))
17- }
18-
19-
20-let IdxCfgIdoStart = 1
21-
22-let IdxCfgIdoDuration = 2
23-
24-let IdxCfgClaimStart = 3
25-
26-let IdxCfgClaimDuration = 4
27-
28-let IdxCfgPrice = 5
29-
30-let IdxCfgPriceMult = 6
31-
32-let IdxCfgIdoAssetId = 7
33-
34-let IdxCfgIdoAssetMult = 8
35-
36-let IdxCfgPriceAssetId = 9
37-
38-let IdxCfgPriceAssetMult = 10
39-
40-let IdxCfgMinInvestAmount = 11
41-
42-func fromatConfigS (idoStart,idoDuration,claimStart,claimDuration,price,priceMult,idoAssetId58,idoAssetMult,priceAssetId58,priceAssetMult,minInvestAmount,totalIdoAssetToSell) = makeString(["%d%d%d%d%d%d%s%d%s%d%d%d", idoStart, idoDuration, claimStart, claimDuration, price, priceMult, idoAssetId58, idoAssetMult, priceAssetId58, priceAssetMult, minInvestAmount, totalIdoAssetToSell], SEP)
43-
44-
45-func fromatConfig (idoStart,idoDuration,claimStart,claimDuration,price,priceMult,idoAssetId58,idoAssetMult,priceAssetId58,priceAssetMult,minInvestAmount,totalIdoAssetToSell) = fromatConfigS(toString(idoStart), toString(idoDuration), toString(claimStart), toString(claimDuration), toString(price), toString(priceMult), idoAssetId58, toString(idoAssetMult), priceAssetId58, toString(priceAssetMult), toString(minInvestAmount), toString(totalIdoAssetToSell))
46-
47-
48-let IdxInvTotalAmount = 1
49-
50-let IdxInvRemainingAmount = 2
51-
52-let IdxInvClaimedPriceAssetAmount = 3
53-
54-let IdxInvClaimedIdoAssetAmount = 4
55-
56-let IdxInvLastClaimedHeight = 5
57-
58-func formatInvestorS (totalAmount,remainingAmount,claimedPriceAssetAmount,claimedIdoAssetAmount,lastClaimedHeight) = makeString(["%d%d%d%d%d", totalAmount, remainingAmount, claimedPriceAssetAmount, claimedIdoAssetAmount, lastClaimedHeight], SEP)
59-
60-
61-func formatInvestor (totalAmount,remainingAmount,claimedPriceAssetAmount,claimedIdoAssetAmount,lastClaimedHeight) = formatInvestorS(toString(totalAmount), toString(remainingAmount), toString(claimedPriceAssetAmount), toString(claimedIdoAssetAmount), toString(lastClaimedHeight))
62-
63-
64-func formatHistoryRecord (priceAssetAmount,idoAssetAmount) = makeString(["%d%d%d%d", toString(height), toString(lastBlock.timestamp), toString(priceAssetAmount), toString(idoAssetAmount)], SEP)
65-
66-
67-func keyConfig () = "%s__config"
68-
69-
70-func keyInvestor (userAddress) = ("%s__" + userAddress)
71-
72-
73-func keyTotals () = "%s__totals"
74-
75-
76-func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
77-
78-
79-func keyManagerPublicKey () = "%s__managerPublicKey"
80-
81-
82-func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
83-
84-
85-func readConfigArray () = split(getStringOrFail(keyConfig()), SEP)
86-
87-
88-func readTotalsArrayOrDefaultByCustomKey (customKey) = split(valueOrElse(getString(customKey), formatInvestorS("0", "0", "0", "0", "0")), SEP)
89-
90-
91-func readTotalsArrayOrDefault () = readTotalsArrayOrDefaultByCustomKey(keyTotals())
92-
93-
94-func readInvestorArrayOrDefault (userAddress) = readTotalsArrayOrDefaultByCustomKey(keyInvestor(userAddress))
95-
96-
97-func readInvestorArrayOrFail (userAddress) = split(getStringOrFail(keyInvestor(userAddress)), SEP)
98-
99-
100-let IdxDiffTotalIncrement = 0
101-
102-let IdxDiffRemainingPriceAmountIncrement = 1
103-
104-let IdxDiffClaimedPriceAmountIncrement = 2
105-
106-let IdxDiffClaimedIdoAssetAmountIncrement = 3
107-
108-func TotalsEntry (key,origArray,incrementDiff,newLastClaimedHeight) = {
109- let totalAmount = parseIntValue(origArray[IdxInvTotalAmount])
110- let remainingAmount = parseIntValue(origArray[IdxInvRemainingAmount])
111- let claimedPriceAssetAmount = parseIntValue(origArray[IdxInvClaimedPriceAssetAmount])
112- let claimedIdoAssetAmount = parseIntValue(origArray[IdxInvClaimedIdoAssetAmount])
113- let lastClaimedHeight = parseIntValue(origArray[IdxInvLastClaimedHeight])
114- let newTotalAmount = (totalAmount + incrementDiff[IdxDiffTotalIncrement])
115- let newRemainingAmount = (remainingAmount + incrementDiff[IdxDiffRemainingPriceAmountIncrement])
116- let newClaimedPriceAssetAmount = (claimedPriceAssetAmount + incrementDiff[IdxDiffClaimedPriceAmountIncrement])
117- let newClaimedIdoAssetAmount = (claimedIdoAssetAmount + incrementDiff[IdxDiffClaimedIdoAssetAmountIncrement])
118- if ((0 > newRemainingAmount))
119- then throw("invalid math")
120- else StringEntry(key, formatInvestor(newTotalAmount, newRemainingAmount, newClaimedPriceAssetAmount, newClaimedIdoAssetAmount, newLastClaimedHeight))
121- }
122-
123-
124-func InvestOperationHistoryEntry (userAddress,priceAssetAmount,idoAssetAmount,txId) = StringEntry(keyOperationHistoryRecord("invest", userAddress, toBase58String(txId)), formatHistoryRecord(priceAssetAmount, idoAssetAmount))
125-
126-
127-func ClaimOperationHistoryEntry (userAddress,priceAssetAmount,idoAssetAmount,txId) = StringEntry(keyOperationHistoryRecord("claim", userAddress, toBase58String(txId)), formatHistoryRecord(priceAssetAmount, idoAssetAmount))
128-
129-
130-func internalClaim (claimedAssetId58,userAddress,txId) = {
131- let cfgArray = readConfigArray()
132- let claimStart = parseIntValue(cfgArray[IdxCfgClaimStart])
133- let claimDuration = parseIntValue(cfgArray[IdxCfgClaimDuration])
134- let claimEnd = (claimStart + claimDuration)
135- let price = parseIntValue(cfgArray[IdxCfgPrice])
136- let priceMult = parseIntValue(cfgArray[IdxCfgPriceMult])
137- let idoAssetId58 = cfgArray[IdxCfgIdoAssetId]
138- let idoAssetId = fromBase58String(idoAssetId58)
139- let idoAssetMult = parseIntValue(cfgArray[IdxCfgIdoAssetMult])
140- let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
141- let priceAssetId = fromBase58String(priceAssetId58)
142- let priceAssetMult = parseIntValue(cfgArray[IdxCfgPriceAssetMult])
143- let userAddress58 = toString(userAddress)
144- let origInvestArray = readInvestorArrayOrFail(userAddress58)
145- let investTotalAmount = parseIntValue(origInvestArray[IdxInvTotalAmount])
146- let investLastClaimedHeightTMP = parseIntValue(origInvestArray[IdxInvLastClaimedHeight])
147- let investLastClaimedHeight = if ((claimStart >= investLastClaimedHeightTMP))
148- then claimStart
149- else investLastClaimedHeightTMP
150- let newClaimPeriodHeight = if ((height > claimEnd))
151- then claimEnd
152- else if ((claimStart > height))
153- then claimStart
154- else height
155- let claimingBlocks = (newClaimPeriodHeight - investLastClaimedHeight)
156- let claimingPriceAssetAmount = fraction(investTotalAmount, claimingBlocks, claimDuration)
157- let claimingIdoAssetAmount = convertPriceAssetIntoIdoAsset(claimingPriceAssetAmount, priceAssetMult, price, priceMult, idoAssetMult)
158- if ((claimedAssetId58 == priceAssetId58))
159- then $Tuple6([0, -(claimingPriceAssetAmount), claimingPriceAssetAmount, 0], claimingPriceAssetAmount, priceAssetId, origInvestArray, newClaimPeriodHeight, [claimingPriceAssetAmount, claimingIdoAssetAmount])
160- else if ((claimedAssetId58 == idoAssetId58))
161- then $Tuple6([0, -(claimingPriceAssetAmount), 0, claimingIdoAssetAmount], claimingIdoAssetAmount, idoAssetId, origInvestArray, newClaimPeriodHeight, [claimingPriceAssetAmount, claimingIdoAssetAmount])
162- else throw(("unsupported assetId: " + claimedAssetId58))
163- }
164-
165-
166-func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
167- case s: String =>
168- fromBase58String(s)
169- case _: Unit =>
170- unit
171- case _ =>
172- throw("Match error")
173-}
174-
175-
176-func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
177- case s: String =>
178- fromBase58String(s)
179- case _: Unit =>
180- unit
181- case _ =>
182- throw("Match error")
183-}
184-
185-
186-func mustManager (i) = {
187- let pd = throw("Permission denied")
188- match managerPublicKeyOrUnit() {
189- case pk: ByteVector =>
190- if ((i.callerPublicKey == pk))
191- then true
192- else pd
193- case _: Unit =>
194- if ((i.caller == this))
195- then true
196- else pd
197- case _ =>
198- throw("Match error")
199- }
200- }
201-
202-
203-@Callable(i)
204-func constructor (idoStart,idoDuration,claimStart,claimDuration,price,priceAssetId58,minInvestAmount) = {
205- let priceMult = ((100 * 1000) * 1000)
206- let idoEnd = (idoStart + idoDuration)
207- if (isDefined(getString(keyConfig())))
208- then throw("already initialized")
209- else if (("3PMEHLx1j6zerarZTYfsGqDeeZqQoMpxq5S" != toString(i.caller)))
210- then throw("not authorized")
211- else if ((size(i.payments) != 1))
212- then throw("exactly 1 payment must be attached")
213- else if ((idoEnd >= claimStart))
214- then throw("claimStart must be greater than idoEnd")
215- else {
216- let pmt = value(i.payments[0])
217- let idoAssetId = value(pmt.assetId)
218- let idoAssetInfo = valueOrErrorMessage(assetInfo(idoAssetId), "fail to load ido asset info")
219- let idoAssetId58 = toBase58String(idoAssetId)
220- let idoAssetMult = pow(10, 0, idoAssetInfo.decimals, 0, 0, DOWN)
221- let priceAssetId = fromBase58String(priceAssetId58)
222- let priceAssetInfo = valueOrErrorMessage(assetInfo(priceAssetId), "fail to load price asset info")
223- let priceAssetMult = pow(10, 0, priceAssetInfo.decimals, 0, 0, DOWN)
224- let origTotalsArray = readTotalsArrayOrDefault()
225- let totalsDiff = [0, 0, 0, 0]
226-[StringEntry(keyConfig(), fromatConfig(idoStart, idoDuration, claimStart, claimDuration, price, priceMult, idoAssetId58, idoAssetMult, priceAssetId58, priceAssetMult, minInvestAmount, pmt.amount)), TotalsEntry(keyTotals(), origTotalsArray, totalsDiff, claimStart)]
227- }
228- }
229-
230-
231-
232-@Callable(i)
233-func invest () = {
234- let cfgArray = readConfigArray()
235- let idoStart = parseIntValue(cfgArray[IdxCfgIdoStart])
236- let idoDuration = parseIntValue(cfgArray[IdxCfgIdoDuration])
237- let idoEnd = (idoStart + idoDuration)
238- let claimStart = parseIntValue(cfgArray[IdxCfgClaimStart])
239- let claimDuration = parseIntValue(cfgArray[IdxCfgClaimDuration])
240- let price = parseIntValue(cfgArray[IdxCfgPrice])
241- let priceMult = parseIntValue(cfgArray[IdxCfgPriceMult])
242- let idoAssetId58 = cfgArray[IdxCfgIdoAssetId]
243- let idoAssetId = fromBase58String(idoAssetId58)
244- let idoAssetMult = parseIntValue(cfgArray[IdxCfgIdoAssetMult])
245- let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
246- let priceAssetId = fromBase58String(priceAssetId58)
247- let priceAssetMult = parseIntValue(cfgArray[IdxCfgPriceAssetMult])
248- let minIvestAmount = parseIntValue(cfgArray[IdxCfgMinInvestAmount])
249- let userAddress = toString(i.caller)
250- if ((idoStart > height))
251- then throw("ido has not been started yet")
252- else if ((height > idoEnd))
253- then throw("ido has been already ended")
254- else if ((size(i.payments) != 1))
255- then throw("exactly 1 payment is expected")
256- else {
257- let pmt = value(i.payments[0])
258- let pmtAssetId = value(pmt.assetId)
259- let pmtAmount = pmt.amount
260- if ((pmtAssetId != priceAssetId))
261- then throw((("invalid payment asset id: " + toBase58String(pmtAssetId)) + " is expected"))
262- else {
263- let origInvestorArray = readInvestorArrayOrDefault(userAddress)
264- let origTotalsArray = readTotalsArrayOrDefault()
265- let newPriceTotalAmount = (parseIntValue(origTotalsArray[IdxInvTotalAmount]) + pmtAmount)
266- let requiredIdoAssetAmount = (newPriceTotalAmount * 100)
267- if ((requiredIdoAssetAmount > assetBalance(this, idoAssetId)))
268- then throw("IDO asset has been - sold consider to use smaller payment")
269- else {
270- let totalsDiff = [pmtAmount, pmtAmount, 0, 0]
271-[TotalsEntry(keyInvestor(userAddress), origInvestorArray, totalsDiff, claimStart), TotalsEntry(keyTotals(), origTotalsArray, totalsDiff, claimStart), InvestOperationHistoryEntry(userAddress, pmtAmount, 0, i.transactionId)]
272- }
273- }
274- }
275- }
276-
277-
278-
279-@Callable(i)
280-func claim (claimedAssetId58,userAddress58) = {
281- let callerAddress58 = toString(i.caller)
282- if ((userAddress58 != callerAddress58))
283- then throw("not authorized")
284- else {
285- let claimResultTuple = internalClaim(claimedAssetId58, i.caller, i.transactionId)
286- let totalsDiff = claimResultTuple._1
287- let outAmount = claimResultTuple._2
288- let outAssetId = claimResultTuple._3
289- let origInvestArray = claimResultTuple._4
290- let newClaimPeriodHeight = claimResultTuple._5
291- let claimedPriceAmountFromDiff = totalsDiff[IdxDiffClaimedPriceAmountIncrement]
292- let claimedIdoAssetAmountFromDiff = totalsDiff[IdxDiffClaimedIdoAssetAmountIncrement]
293- $Tuple2([ScriptTransfer(i.caller, outAmount, outAssetId), TotalsEntry(keyInvestor(userAddress58), origInvestArray, totalsDiff, newClaimPeriodHeight), TotalsEntry(keyTotals(), readTotalsArrayOrDefault(), totalsDiff, newClaimPeriodHeight), ClaimOperationHistoryEntry(userAddress58, claimedPriceAmountFromDiff, claimedIdoAssetAmountFromDiff, i.transactionId)], unit)
294- }
295- }
296-
297-
298-
299-@Callable(i)
300-func claimREADONLY (claimedAssetId58,userAddress58) = {
301- let claimResultTuple = internalClaim(claimedAssetId58, addressFromStringValue(userAddress58), fromBase58String(""))
302- let totalsDiff = claimResultTuple._1
303- let outAmount = claimResultTuple._2
304- let outAssetId = claimResultTuple._3
305- let origInvestArray = claimResultTuple._4
306- let newClaimPeriodHeight = claimResultTuple._5
307- let availableToClaimArray = claimResultTuple._6
308- let availablePriceAmountToClaim = availableToClaimArray[0]
309- let availableIdoAmountToClaim = availableToClaimArray[1]
310- $Tuple2(nil, makeString(["%s%d%d", userAddress58, toString(availablePriceAmountToClaim), toString(availableIdoAmountToClaim)], SEP))
311- }
312-
313-
314-
315-@Callable(i)
316-func setManager (pendingManagerPublicKey) = {
317- let checkCaller = mustManager(i)
318- if ((checkCaller == checkCaller))
319- then {
320- let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
321- if ((checkManagerPublicKey == checkManagerPublicKey))
322- then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
323- else throw("Strict value is not equal to itself.")
324- }
325- else throw("Strict value is not equal to itself.")
326- }
327-
328-
329-
330-@Callable(i)
331-func confirmManager () = {
332- let pm = pendingManagerPublicKeyOrUnit()
333- let hasPM = if (isDefined(pm))
334- then true
335- else throw("No pending manager")
336- if ((hasPM == hasPM))
337- then {
338- let checkPM = if ((i.callerPublicKey == value(pm)))
339- then true
340- else throw("You are not pending manager")
341- if ((checkPM == checkPM))
342- then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
343- else throw("Strict value is not equal to itself.")
344- }
345- else throw("Strict value is not equal to itself.")
346- }
347-
348-
349-@Verifier(tx)
350-func verify () = {
351- let targetPublicKey = match managerPublicKeyOrUnit() {
352- case pk: ByteVector =>
353- pk
354- case _: Unit =>
355- tx.senderPublicKey
356- case _ =>
357- throw("Match error")
358- }
359- sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
360- }
361-
1+# no script

github/deemru/w8io/873ac7e 
45.46 ms