tx · 6qdqLaiqQi76NeXy3oRkFC3fqhpKeKDcrvBQjmF5K6hQ

3N69G8EDDEcxUmYNRYF87HjSSg4EWdjLkga:  -0.01400000 Waves

2020.10.12 06:04 [1216772] smart account 3N69G8EDDEcxUmYNRYF87HjSSg4EWdjLkga > SELF 0.00000000 Waves

{ "type": 13, "id": "6qdqLaiqQi76NeXy3oRkFC3fqhpKeKDcrvBQjmF5K6hQ", "fee": 1400000, "feeAssetId": null, "timestamp": 1602471918282, "version": 2, "chainId": 84, "sender": "3N69G8EDDEcxUmYNRYF87HjSSg4EWdjLkga", "senderPublicKey": "FriuqysnUhq2iJmD6pxeLdGJogF25kMigmCQr5tNinkF", "proofs": [ "5E6iL3xpTa11KhTdoq78xF1YQ4oXAEMitcppdPPnn54CmKE3rui5z9BaFhfymHErAXWFxnSpmpk1PyZ5LXeKQELF" ], "script": "base64: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", "height": 1216772, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: HvYU83jXHwbtq7nmQCxzu3AaodcQ6LyNTDs7Tf9gsRJ7 Next: DbLoKNbGt3fYFt5xTKqcdvq6dN3SAkqsT9nCb4kpYwt Full:
OldNewDifferences
11 {-# STDLIB_VERSION 3 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-func getNumberByKey (key) = match getInteger(this, key) {
5- case a: Int =>
6- a
7- case _ =>
8- 0
9-}
4+let QUORUM = 50
105
6+let USDN = base58'4zfrrwDVjbGFM8wxbZGriVLY4XJsVD4oNMp21FnDnMAa'
117
12-func getStringByKey (key) = match getString(this, key) {
13- case a: String =>
14- a
15- case _ =>
16- ""
17-}
18-
19-
20-func getBoolByKey (key) = match getBoolean(this, key) {
21- case a: Boolean =>
22- a
23- case _ =>
24- false
25-}
26-
27-
28-func getNumberByAddressAndKey (address,key) = match getInteger(addressFromStringValue(address), key) {
29- case a: Int =>
30- a
31- case _ =>
32- 0
33-}
34-
35-
36-func getStringByAddressAndKey (address,key) = match getString(addressFromStringValue(address), key) {
37- case a: String =>
38- a
39- case _ =>
40- ""
41-}
42-
43-
44-func getBoolByAddressAndKey (address,key) = match getBoolean(addressFromStringValue(address), key) {
45- case a: Boolean =>
46- a
47- case _ =>
48- false
49-}
50-
51-
52-let SENDTXEXPIRE = 30
53-
54-let LISTSPLITSYMBOL = "_"
55-
56-let LISTDATASYMBOL = "+"
57-
58-let WAVELET = 100000000
59-
60-let PAULI = 1000000
61-
62-let NeutrinoAssetIdKey = "neutrino_asset_id"
63-
64-let BondAssetIdKey = "bond_asset_id"
65-
66-let AuctionContractKey = "auction_contract"
67-
68-let LiquidationContractKey = "liquidation_contract"
69-
70-let RPDContractKey = "rpd_contract"
71-
72-let ContolContractKey = "control_contract"
73-
74-let BalanceWavesLockIntervalKey = "balance_waves_lock_interval"
75-
76-let BalanceNeutrinoLockIntervalKey = "balance_neutrino_lock_interval"
77-
78-let MinWavesSwapAmountKey = "min_waves_swap_amount"
79-
80-let MinNeutrinoSwapAmountKey = "min_neutrino_swap_amount"
81-
82-let NodeOracleProviderPubKeyKey = "node_oracle_provider"
83-
84-let RPDBalanceKey = "rpd_balance"
85-
86-func getRPDContractBalanceKey (assetId) = ((RPDBalanceKey + "_") + toBase58String(assetId))
87-
88-
89-let PriceKey = "price"
90-
91-let PriceIndexKey = "price_index"
92-
93-let IsBlockedKey = "is_blocked"
94-
95-func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block))
96-
97-
98-func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index))
99-
100-
101-let BalanceLockedkKey = "balance_lock_"
102-
103-let WavesLockedBalanceKey = (BalanceLockedkKey + "waves")
104-
105-let NeutrinoLockedBalanceKey = (BalanceLockedkKey + "neutrino")
106-
107-func getRPDSnapshotContractBalanceKey (count,assetId) = ((((RPDBalanceKey + "_") + toBase58String(assetId)) + "_") + toString(count))
108-
109-
110-func getCancelLeaseTxReserveFeeKey (hash) = (("cancel_lease_tx_reserve_fee" + "_") + hash)
111-
112-
113-func getWavesLockedBalanceKey (owner) = ((WavesLockedBalanceKey + "_") + owner)
114-
115-
116-func getNeutrinoLockedBalanceKey (owner) = ((NeutrinoLockedBalanceKey + "_") + owner)
117-
118-
119-func getBalanceUnlockBlockKey (owner) = ("balance_unlock_block_" + owner)
120-
121-
122-func getRPDProfitKey (count) = (("rpd_profit" + "_") + toString(count))
123-
124-
125-func convertNeutrinoToWaves (amount,price) = fraction(fraction(amount, 100, price), WAVELET, PAULI)
126-
127-
128-func convertWavesToNeutrino (amount,price) = fraction(fraction(amount, price, 100), PAULI, WAVELET)
129-
130-
131-func convertWavesToBond (amount,price) = convertWavesToNeutrino(amount, price)
132-
133-
134-func convertJsonArrayToList (jsonArray) = split(jsonArray, ",")
135-
136-
137-let liquidationContract = getStringByKey(LiquidationContractKey)
138-
139-let neutrinoAssetIdString = getStringByKey(NeutrinoAssetIdKey)
140-
141-let neutrinoAssetId = base58'GXEFzEQ6BwnQcftiAFXCygb7tc5Rwq2dMQEfsZxcD1Pu'
142-
143-let auctionContract = getStringByKey(AuctionContractKey)
144-
145-let rpdContract = getStringByKey(RPDContractKey)
146-
147-let controlContract = getStringByKey(ContolContractKey)
148-
149-let priceIndex = getNumberByAddressAndKey(controlContract, PriceIndexKey)
150-
151-let isBlocked = getBoolByAddressAndKey(controlContract, IsBlockedKey)
152-
153-let nodeOracleProviderPubKey = fromBase58String(getStringByKey(NodeOracleProviderPubKeyKey))
154-
155-let balanceWavesLockInterval = getNumberByKey(BalanceWavesLockIntervalKey)
156-
157-let balanceNeutrinoLockInterval = getNumberByKey(BalanceNeutrinoLockIntervalKey)
158-
159-let minWavesSwapAmount = getNumberByKey(MinWavesSwapAmountKey)
160-
161-let minNeutrinoSwapAmount = getNumberByKey(MinNeutrinoSwapAmountKey)
162-
163-let bondAssetId = fromBase58String("6nSpVyNH7yM69eg446wrQR94ipbbcmZMU1ENPwanC97g")
164-
165-let deprecatedBondAssetId = fromBase58String("975akZBfnMj513U7MZaHKzQrmsEx5aE3wdWKTrHBhbjF")
166-
167-let neutrinoContract = this
168-
169-let currentPrice = getNumberByAddressAndKey(controlContract, PriceKey)
170-
171-let neutrinoLockedBalance = getNumberByKey(NeutrinoLockedBalanceKey)
172-
173-let wavesLockedBalance = getNumberByKey(WavesLockedBalanceKey)
174-
175-let reserve = (wavesBalance(neutrinoContract) - wavesLockedBalance)
176-
177-let neutrinoSupply = (((neutrinoLockedBalance + extract(assetInfo(neutrinoAssetId)).quantity) - assetBalance(neutrinoContract, neutrinoAssetId)) - assetBalance(addressFromStringValue(liquidationContract), neutrinoAssetId))
178-
179-let surplus = (convertWavesToNeutrino(reserve, currentPrice) - neutrinoSupply)
180-
181-let deficit = (neutrinoSupply - convertWavesToNeutrino(reserve, currentPrice))
182-
183-func checkIsValidMinSponsoredFee (tx) = {
184- let MINTRANSFERFEE = 100000
185- let SponsoredFeeUpperBound = 1000
186- let realNeutrinoFee = convertWavesToNeutrino(MINTRANSFERFEE, currentPrice)
187- let minNeutrinoFee = (realNeutrinoFee * 2)
188- let maxNeutrinoFee = fraction(realNeutrinoFee, SponsoredFeeUpperBound, 100)
189- let inputFee = extract(tx.minSponsoredAssetFee)
190- if (if ((inputFee >= minNeutrinoFee))
191- then (maxNeutrinoFee >= inputFee)
192- else false)
193- then (tx.assetId == neutrinoAssetId)
194- else false
8+func tryGetInteger (key) = {
9+ let val = match getInteger(this, key) {
10+ case b: Int =>
11+ b
12+ case _ =>
13+ 0
14+ }
15+ val
19516 }
19617
19718
198-func getRPDContractBalance (assetId) = getNumberByAddressAndKey(rpdContract, getRPDContractBalanceKey(assetId))
19+@Callable(i)
20+func voteOnSplit (g1,g2,g3) = if ((((g1 + g2) + g3) > 10))
21+ then throw("Please disperse max 10 points")
22+ else if ((tryGetInteger((toString(i.caller) + "_voted")) != 0))
23+ then throw("You have already voted")
24+ else {
25+ let newG1 = (tryGetInteger("group1_share") + g1)
26+ let newG2 = (tryGetInteger("group2_share") + g2)
27+ let newG3 = (tryGetInteger("group3_share") + g3)
28+ WriteSet([DataEntry("group1_share", newG1), DataEntry("group2_share", newG2), DataEntry("group3_share", newG3), DataEntry((toString(i.caller) + "_voted"), ((g1 + g2) + g3))])
29+ }
19930
200-
201-func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block))
202-
203-
204-func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index))
205-
206-
207-func getCancelLeaseTxReserveFee (hash) = getNumberByKey(getCancelLeaseTxReserveFeeKey(hash))
208-
209-
210-func getWavesLockedBalance (owner) = getNumberByKey(getWavesLockedBalanceKey(owner))
211-
212-
213-func getNeutrinoLockedBalance (owner) = getNumberByKey(getNeutrinoLockedBalanceKey(owner))
214-
215-
216-func getUnlockBalanceBlock (owner) = getNumberByKey(getBalanceUnlockBlockKey(owner))
217-
218-
219-func getRPDProfit (count) = getNumberByKey(getRPDProfitKey(count))
22031
22132
22233 @Callable(i)
223-func swapWavesToNeutrino () = {
34+func addTips (itemId,g1,g2,g3) = {
22435 let pmt = extract(i.payment)
225- let account = toString(i.caller)
226- if ((minWavesSwapAmount > pmt.amount))
227- then throw((("The specified Waves amount is less than the required minimum of " + toString(minWavesSwapAmount)) + " wavelets."))
228- else WriteSet([DataEntry(getWavesLockedBalanceKey(account), pmt.amount), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceWavesLockInterval)), DataEntry(WavesLockedBalanceKey, (wavesLockedBalance + pmt.amount))])
36+ if ((pmt.assetId != USDN))
37+ then throw("Tips accepted only in USDN")
38+ else {
39+ let g1Share = tryGetInteger("group1_share")
40+ let g2Share = tryGetInteger("group2_share")
41+ let g3Share = tryGetInteger("group3_share")
42+ ScriptResult(WriteSet([DataEntry(("tips_amount_" + itemId), pmt.amount)]), TransferSet([ScriptTransfer(addressFromStringValue(g1), ((pmt.amount * g1Share) / ((g1Share + g2Share) + g3Share)), USDN), ScriptTransfer(addressFromStringValue(g2), ((pmt.amount * g2Share) / ((g1Share + g2Share) + g3Share)), USDN), ScriptTransfer(addressFromStringValue(g3), ((pmt.amount * g3Share) / ((g1Share + g2Share) + g3Share)), USDN)]))
43+ }
22944 }
23045
23146
23247
23348 @Callable(i)
234-func swapNeutrinoToWaves () = {
235- let pmt = extract(i.payment)
236- let account = toString(i.caller)
237- if ((minNeutrinoSwapAmount > pmt.amount))
238- then throw((("The specified Neutrino amount is less than the required minimum of " + toString(minNeutrinoSwapAmount)) + " Neutrino cents."))
239- else if (isBlocked)
240- then throw("The contract is blocked by EMERGENCY SHUTDOWN. Please wait for reactivation by emergency oracles.")
241- else if ((pmt.assetId != neutrinoAssetId))
242- then throw("Only appropriate Neutrino tokens are allowed for swapping.")
243- else if ((getUnlockBalanceBlock(account) > height))
244- then throw((("await " + toString((getUnlockBalanceBlock(account) - height))) + " blocks"))
245- else if (if ((getNeutrinoLockedBalance(account) != 0))
246- then true
247- else (getWavesLockedBalance(account) != 0))
248- then throw("please withdraw locked funds first")
249- else WriteSet([DataEntry(getNeutrinoLockedBalanceKey(account), pmt.amount), DataEntry(getBalanceUnlockBlockKey(account), (height + balanceNeutrinoLockInterval)), DataEntry(NeutrinoLockedBalanceKey, (neutrinoLockedBalance + pmt.amount))])
250- }
49+func withdrawTips (amount) = WriteSet(nil)
25150
25251
25352
25453 @Callable(i)
255-func withdraw (account,index) = {
256- let unlockHeight = getUnlockBalanceBlock(account)
257- let userWavesLockedBalance = getWavesLockedBalance(account)
258- let userNeutrinoLockedBalance = getNeutrinoLockedBalance(account)
259- let indexHeight = getHeightPriceByIndex(index)
260- let prevIndexHeight = getHeightPriceByIndex((index - 1))
261- let priceByIndex = getPriceHistory(indexHeight)
262- let spread = if ((100 > priceByIndex))
263- then 1
264- else (priceByIndex / 100)
265- let neutrinoAmount = convertWavesToNeutrino(userWavesLockedBalance, (priceByIndex - spread))
266- let wavesAmount = convertNeutrinoToWaves(userNeutrinoLockedBalance, (priceByIndex + spread))
267- if (isBlocked)
268- then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
269- else if ((unlockHeight > height))
270- then throw((("please wait for: " + toString(unlockHeight)) + " block height to withdraw WAVES funds"))
271- else if (if (if ((index > priceIndex))
272- then true
273- else (unlockHeight > indexHeight))
274- then true
275- else if ((prevIndexHeight != 0))
276- then (prevIndexHeight >= unlockHeight)
277- else false)
278- then throw(((((((((("invalid price history index: index=" + toString(index)) + " priceIndex=") + toString(priceIndex)) + " indexHeight=") + toString(indexHeight)) + " unlockHeight=") + toString(unlockHeight)) + " prevIndexHeight=") + toString(prevIndexHeight)))
279- else if (if ((0 >= neutrinoAmount))
280- then (0 >= wavesAmount)
281- else false)
282- then throw("balance equals zero")
283- else ScriptResult(WriteSet([DataEntry(getWavesLockedBalanceKey(account), 0), DataEntry(getNeutrinoLockedBalanceKey(account), 0), DataEntry(WavesLockedBalanceKey, (wavesLockedBalance - userWavesLockedBalance)), DataEntry(NeutrinoLockedBalanceKey, (neutrinoLockedBalance - userNeutrinoLockedBalance))]), TransferSet([ScriptTransfer(addressFromStringValue(account), wavesAmount, unit), ScriptTransfer(addressFromStringValue(account), neutrinoAmount, neutrinoAssetId)]))
284- }
285-
286-
287-
288-@Callable(i)
289-func transferToAuction () = {
290- let auctionNBAmount = (neutrinoSupply - assetBalance(addressFromStringValue(auctionContract), bondAssetId))
291- let surplusWithLiquidation = (surplus - assetBalance(addressFromStringValue(liquidationContract), neutrinoAssetId))
292- if (isBlocked)
293- then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
294- else if ((auctionNBAmount > (1 * PAULI)))
295- then TransferSet([ScriptTransfer(addressFromStringValue(auctionContract), auctionNBAmount, bondAssetId)])
296- else if ((surplusWithLiquidation >= (1 * PAULI)))
297- then TransferSet([ScriptTransfer(addressFromStringValue(liquidationContract), surplusWithLiquidation, neutrinoAssetId)])
298- else throw(((((((("bond were generated or do not need it. Deficit:" + toString(auctionNBAmount)) + "|") + toString(0)) + ". Surplus:") + toString(surplusWithLiquidation)) + "|") + toString(surplus)))
299- }
300-
301-
302-
303-@Callable(i)
304-func transfer (account) = {
305- let pmt = extract(i.payment)
306- TransferSet([ScriptTransfer(addressFromStringValue(account), pmt.amount, pmt.assetId)])
307- }
308-
309-
310-
311-@Callable(i)
312-func migrationUSDNB2NSBTSwap () = {
313- let pmt = extract(i.payment)
314- let account = i.caller
315- if ((deprecatedBondAssetId != pmt.assetId))
316- then throw("error: attempt to swap not USDNB tokens")
317- else TransferSet([ScriptTransfer(account, (pmt.amount * PAULI), bondAssetId)])
318- }
54+func addTipsReceivers () = WriteSet(nil)
31955
32056

github/deemru/w8io/169f3d6 
32.56 ms