tx · HaVpyFqJnevtuT5tXzhhWsj392VEnEcnSfsR3Ahh3zf2

3N5NAftzfcw3gAt8nc35bNr9UdPTVgC81fd:  -0.04000000 Waves

2022.07.01 23:38 [2121074] smart account 3N5NAftzfcw3gAt8nc35bNr9UdPTVgC81fd > SELF 0.00000000 Waves

{ "type": 13, "id": "HaVpyFqJnevtuT5tXzhhWsj392VEnEcnSfsR3Ahh3zf2", "fee": 4000000, "feeAssetId": null, "timestamp": 1656707908783, "version": 1, "sender": "3N5NAftzfcw3gAt8nc35bNr9UdPTVgC81fd", "senderPublicKey": "CdnTmMHxT68Qa4MtHEnAiUhsdKTi2YkHPGn92ThinVNt", "proofs": [ "uavEkhNuFoXUkiTswbAx2rHaJXZ3C7q76SrFQBwJuXMiefaa3YcTffoL2FHHscGNP2x8ZqoRAzaYqapiuLibjXD", "wiq9Z2TczneAxty4GFmD8uqTTMu4iqMkVuMBz7DNHbEwxQ3yLwnWSfGNbR7mgSnVFmFnXYr8SexDABkAvUug8PM", "9VLroCrBVYGpofuvaNERapng7E49FaCMJMCV6Wutt3RNkbEMQXjCNQhmH4yaCHUyPfYoqYnNNJ8NKSBgQd6MyVf" ], "script": "base64:AAIFAAAAAAAAACYIAhIFCgMIAQESBAoCAQESABIAEgMKAQgSABIAEgASABIECgIBBAAAAFgBAAAADmdldE51bWJlckJ5S2V5AAAAAQAAAANrZXkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAADa2V5AAAAAAAAAAAAAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEAAAADa2V5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAA2tleQIAAAAAAQAAABZnZXRCb29sQnlBZGRyZXNzQW5kS2V5AAAAAgAAAAdhZGRyZXNzAAAAA2tleQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBsAAAACBQAAAAdhZGRyZXNzBQAAAANrZXkHAQAAABhnZXRTdHJpbmdCeUFkZHJlc3NBbmRLZXkAAAACAAAAB2FkZHJlc3MAAAADa2V5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAAB2FkZHJlc3MFAAAAA2tleQIAAAAAAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACAAAAB2FkZHJlc3MAAAADa2V5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAAB2FkZHJlc3MFAAAAA2tleQAAAAAAAAAAAAEAAAAJYXNBbnlMaXN0AAAAAQAAAAN2YWwEAAAAByRtYXRjaDAFAAAAA3ZhbAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAJTGlzdFtBbnldBAAAAAp2YWxBbnlMeXN0BQAAAAckbWF0Y2gwBQAAAAp2YWxBbnlMeXN0CQAAAgAAAAECAAAAG2ZhaWwgdG8gY2FzdCBpbnRvIExpc3RbQW55XQEAAAAIYXNTdHJpbmcAAAABAAAAA3ZhbAQAAAAHJG1hdGNoMAUAAAADdmFsAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAAZTdHJpbmcEAAAABnZhbFN0cgUAAAAHJG1hdGNoMAUAAAAGdmFsU3RyCQAAAgAAAAECAAAAGGZhaWwgdG8gY2FzdCBpbnRvIFN0cmluZwEAAAAFYXNJbnQAAAABAAAAA3ZhbAQAAAAHJG1hdGNoMAUAAAADdmFsAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAANJbnQEAAAABnZhbEludAUAAAAHJG1hdGNoMAUAAAAGdmFsSW50CQAAAgAAAAECAAAAFWZhaWwgdG8gY2FzdCBpbnRvIEludAAAAAADU0VQAgAAAAJfXwAAAAAFTVVMVDYAAAAAAAAPQkAAAAAABU1VTFQ4AAAAAAAF9eEAAAAAAAdNVUxUWDE2CQABNgAAAAEAACOG8m/BAAAAAAAACENBTkNFTEVEAgAAAAhjYW5jZWxlZAAAAAADTkVXAgAAAANuZXcAAAAABkZJTExFRAIAAAAGZmlsbGVkAAAAAAdXQVZFU0lECQACWQAAAAECAAAABVdBVkVTAAAAAA9uTWV0cmljSWR4UHJpY2UAAAAAAAAAAAAAAAAAG25NZXRyaWNJZHhVc2RuTG9ja2VkQmFsYW5jZQAAAAAAAAAAAQAAAAAcbk1ldHJpY0lkeFdhdmVzTG9ja2VkQmFsYW5jZQAAAAAAAAAAAgAAAAARbk1ldHJpY0lkeFJlc2VydmUAAAAAAAAAAAMAAAAAF25NZXRyaWNJZHhSZXNlcnZlSW5Vc2RuAAAAAAAAAAAEAAAAABRuTWV0cmljSWR4VXNkblN1cHBseQAAAAAAAAAABQAAAAARbk1ldHJpY0lkeFN1cnBsdXMAAAAAAAAAAAYAAAAAGG5NZXRyaWNJZHhTdXJwbHVzUGVyY2VudAAAAAAAAAAABwAAAAAMbk1ldHJpY0lkeEJSAAAAAAAAAAAIAAAAABRuTWV0cmljSWR4TnNidFN1cHBseQAAAAAAAAAACQAAAAAXbk1ldHJpY0lkeE1heE5zYnRTdXBwbHkAAAAAAAAAAAoAAAAADGJGdW5jSWR4U3VyZgAAAAAAAAAAAAAAAAANYkZ1bmNJZHhXYXZlcwAAAAAAAAAAAQAAAAAMYkZ1bmNJZHhVc2RuAAAAAAAAAAACAAAAABRiRnVuY0lkeFJlc2VydmVTdGFydAAAAAAAAAAAAwAAAAATYkZ1bmNJZHhTdXBwbHlTdGFydAAAAAAAAAAABAAAAAAPYkZ1bmNJZHhCUlN0YXJ0AAAAAAAAAAAFAAAAABJiRnVuY0lkeFJlc2VydmVFbmQAAAAAAAAAAAYAAAAAEWJGdW5jSWR4U3VwcGx5RW5kAAAAAAAAAAAHAAAAAA1iRnVuY0lkeEJSRW5kAAAAAAAAAAAIAAAAABFiRnVuY0lkeFJlc3RXYXZlcwAAAAAAAAAACQAAAAAQYkZ1bmNJZHhSZXN0VXNkbgAAAAAAAAAACgAAAAAIUHJpY2VLZXkCAAAABXByaWNlAAAAAA5Oc2J0QXNzZXRJZEtleQIAAAANYm9uZF9hc3NldF9pZAAAAAASTmV1dHJpbm9Bc3NldElkS2V5AgAAABFuZXV0cmlub19hc3NldF9pZAAAAAAOU3VyZkFzc2V0SWRLZXkCAAAADXN1cmZfYXNzZXRfaWQAAAAAEUJhbGFuY2VMb2NrZWRrS2V5AgAAAA1iYWxhbmNlX2xvY2tfAAAAABVXYXZlc0xvY2tlZEJhbGFuY2VLZXkJAAEsAAAAAgUAAAARQmFsYW5jZUxvY2tlZGtLZXkCAAAABXdhdmVzAAAAABhOZXV0cmlub0xvY2tlZEJhbGFuY2VLZXkJAAEsAAAAAgUAAAARQmFsYW5jZUxvY2tlZGtLZXkCAAAACG5ldXRyaW5vAAAAAA1GaXJzdE9yZGVyS2V5AgAAAAtvcmRlcl9maXJzdAAAAAAPTWF0aENvbnRyYWN0S2V5AgAAAA1tYXRoX2NvbnRyYWN0AAAAABVNaW5XYXZlc0Zvck5zYnRCdXlLZXkCAAAAEm1pbl93YXZlc19uc2J0X2J1eQAAAAAOTWluTnNidFNlbGxLZXkCAAAADW1pbl9uc2J0X3NlbGwAAAAAFU1pbldhdmVzRm9yU3VyZkJ1eUtleQIAAAASbWluX3dhdmVzX3N1cmZfYnV5AAAAABRNaW5Vc2RuRm9yU3VyZkJ1eUtleQIAAAARbWluX3VzZG5fc3VyZl9idXkBAAAAEmdldFJvaUJ5T3JkZXJJZEtleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACAgAAABBkZWJ1Z19vcmRlcl9yb2lfBQAAAAdvcmRlcklkAQAAABBnZXRPcmRlclByaWNlS2V5AAAAAQAAAAdvcmRlcklkCQABLAAAAAICAAAADG9yZGVyX3ByaWNlXwUAAAAHb3JkZXJJZAEAAAAQZ2V0T3JkZXJUb3RhbEtleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACAgAAAAxvcmRlcl90b3RhbF8FAAAAB29yZGVySWQBAAAAEGdldE9yZGVyT3duZXJLZXkAAAABAAAAB29yZGVySWQJAAEsAAAAAgIAAAAMb3JkZXJfb3duZXJfBQAAAAdvcmRlcklkAQAAABFnZXRPcmRlckhlaWdodEtleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACAgAAAA1vcmRlcl9oZWlnaHRfBQAAAAdvcmRlcklkAQAAABFnZXRPcmRlclN0YXR1c0tleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACAgAAAA1vcmRlcl9zdGF0dXNfBQAAAAdvcmRlcklkAQAAABZnZXRPcmRlckZpbGxlZFRvdGFsS2V5AAAAAQAAAAdvcmRlcklkCQABLAAAAAICAAAAE29yZGVyX2ZpbGxlZF90b3RhbF8FAAAAB29yZGVySWQBAAAAD2dldFByZXZPcmRlcktleQAAAAEAAAAHb3JkZXJJZAkAASwAAAACAgAAAAtvcmRlcl9wcmV2XwUAAAAHb3JkZXJJZAEAAAAPZ2V0TmV4dE9yZGVyS2V5AAAAAQAAAAdvcmRlcklkCQABLAAAAAICAAAAC29yZGVyX25leHRfBQAAAAdvcmRlcklkAQAAABZjb252ZXJ0TmV1dHJpbm9Ub1dhdmVzAAAAAgAAAAZhbW91bnQAAAAFcHJpY2UJAABrAAAAAwUAAAAGYW1vdW50BQAAAAVNVUxUOAUAAAAFcHJpY2UBAAAAFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8AAAACAAAABmFtb3VudAAAAAVwcmljZQkAAGsAAAADBQAAAAZhbW91bnQFAAAABXByaWNlBQAAAAVNVUxUOAEAAAAFdG9YMTYAAAACAAAAB29yaWdWYWwAAAANb3JpZ1NjYWxlTXVsdAkAATwAAAADCQABNgAAAAEFAAAAB29yaWdWYWwFAAAAB01VTFRYMTYJAAE2AAAAAQUAAAANb3JpZ1NjYWxlTXVsdAEAAAAHZnJvbVgxNgAAAAIAAAADdmFsAAAAD3Jlc3VsdFNjYWxlTXVsdAkAAaAAAAABCQABPAAAAAMFAAAAA3ZhbAkAATYAAAABBQAAAA9yZXN1bHRTY2FsZU11bHQFAAAAB01VTFRYMTYAAAAAEG5ldXRyaW5vQ29udHJhY3QJAQAAAAdBZGRyZXNzAAAAAQEAAAAaAVTX5YnYYiLrMWyfu8rmkonHDc0g4nCta94AAAAAD2NvbnRyb2xDb250cmFjdAkBAAAAB0FkZHJlc3MAAAABAQAAABoBVCFBmWCv1bHMtRUHYsxdLI5/1uzEtUljoQAAAAATbGlxdWlkYXRpb25Db250cmFjdAkBAAAAB0FkZHJlc3MAAAABAQAAABoBVIU74x8XFOr+m4eGxNcmrGVmBniai3IguQAAAAAMbWF0aENvbnRyYWN0CQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAAA9NYXRoQ29udHJhY3RLZXkAAAAAD25ldXRyaW5vQXNzZXRJZAEAAAAg93bq9/eDymXbbhPuAjvPWCmVqcHRjfJL2mzYHWKAyN4AAAAAC25zYnRBc3NldElkAQAAACDQtcyxzfaIZM1HKi2M+rz5PsT9DiVMH3RcKTr+nWmhEAAAAAAJaXNCbG9ja2VkCQEAAAAWZ2V0Qm9vbEJ5QWRkcmVzc0FuZEtleQAAAAIFAAAAD2NvbnRyb2xDb250cmFjdAIAAAAKaXNfYmxvY2tlZAAAAAAVbWluV2F2ZXNBbW91bnROc2J0QnV5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAFU1pbldhdmVzRm9yTnNidEJ1eUtleQAAAAAAO5rKAAAAAAALbWluTnNidFNlbGwJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAOTWluTnNidFNlbGxLZXkAAAAAAAAPQkAAAAAAFW1pbldhdmVzQW1vdW50U3VyZkJ1eQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAABVNaW5XYXZlc0ZvclN1cmZCdXlLZXkAAAAAAAX14QAAAAAAFG1pblVzZG5BbW91bnRTdXJmQnV5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAFE1pblVzZG5Gb3JTdXJmQnV5S2V5AAAAAAAAmJaAAAAAAApmaXJzdE9yZGVyCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAAA1GaXJzdE9yZGVyS2V5AQAAAA1nZXRPcmRlclByaWNlAAAAAQAAAAJpZAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAEGdldE9yZGVyUHJpY2VLZXkAAAABBQAAAAJpZAEAAAANZ2V0T3JkZXJUb3RhbAAAAAEAAAACaWQJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABBnZXRPcmRlclRvdGFsS2V5AAAAAQUAAAACaWQBAAAADWdldE9yZGVyT3duZXIAAAABAAAAAmlkCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABCQEAAAAQZ2V0T3JkZXJPd25lcktleQAAAAEFAAAAAmlkAQAAAA5nZXRPcmRlclN0YXR1cwAAAAEAAAACaWQJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEJAQAAABFnZXRPcmRlclN0YXR1c0tleQAAAAEFAAAAAmlkAQAAABNnZXRPcmRlckZpbGxlZFRvdGFsAAAAAQAAAAJpZAkBAAAADmdldE51bWJlckJ5S2V5AAAAAQkBAAAAFmdldE9yZGVyRmlsbGVkVG90YWxLZXkAAAABBQAAAAJpZAEAAAAMZ2V0UHJldk9yZGVyAAAAAQAAAAJpZAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQkBAAAAD2dldFByZXZPcmRlcktleQAAAAEFAAAAAmlkAQAAAAxnZXROZXh0T3JkZXIAAAABAAAAAmlkCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABCQEAAAAPZ2V0TmV4dE9yZGVyS2V5AAAAAQUAAAACaWQBAAAAD2dldFJldmVyc2VQcmljZQAAAAEAAAAFcHJpY2UJAABpAAAAAgkAAGgAAAACBQAAAAVNVUxUNgUAAAAFTVVMVDYFAAAABXByaWNlAQAAABZjYWxjTnNidDJXYXZlc1ByaWNlUmF3AAAAAgAAAA1zcGVudFdhdmVzUmF3AAAAD3JlY2VpdmVkTnNidFJhdwkAATwAAAADCQABNgAAAAEFAAAADXNwZW50V2F2ZXNSYXcJAAE2AAAAAQkAAGgAAAACBQAAAAVNVUxUNgUAAAAFTVVMVDYJAAE2AAAAAQUAAAAPcmVjZWl2ZWROc2J0UmF3AQAAAAlvcmRlckRhdGEAAAAIAAAAB29yZGVySWQAAAANdG90YWxXYXZlbGV0cwAAAA5maWxsZWRXYXZlbGV0cwAAAAVvd25lcgAAAAZzdGF0dXMAAAADcm9pAAAABXByaWNlAAAADGN1cnJlbnRQcmljZQkABEwAAAACCQEA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", "chainId": 84, "height": 2121074, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: E71eN7Gsta5dtEjg5AAZsrD5r2qvMUn5xj31Ku5Qr7KD Next: Bp1n5bin2Tv2iA1xf6yFEF6fQdQwaDNyZ86VwA24DyMR Diff:
OldNewDifferences
4040 }
4141
4242
43-let WAVELET = 100000000
43+let SEP = "__"
4444
45-let PAULI = 1000000
45+let MULT6 = 1000000
4646
47-let BIGPAULI = toBigInt(1000000)
47+let MULT8 = 100000000
4848
49-let PRICELET = 1000000
50-
51-let MULT = 100000000
52-
53-let BIGMULT16 = toBigInt(10000000000000000)
54-
55-let SCALE8 = 8
56-
57-let SCALE16 = 16
58-
59-let MINORDERTOTAL = (10 * WAVELET)
60-
61-let MAXROI = 95
49+let MULTX16 = toBigInt(10000000000000000)
6250
6351 let CANCELED = "canceled"
6452
6654
6755 let FILLED = "filled"
6856
57+let WAVESID = fromBase58String("WAVES")
58+
59+let nMetricIdxPrice = 0
60+
61+let nMetricIdxUsdnLockedBalance = 1
62+
63+let nMetricIdxWavesLockedBalance = 2
64+
65+let nMetricIdxReserve = 3
66+
67+let nMetricIdxReserveInUsdn = 4
68+
69+let nMetricIdxUsdnSupply = 5
70+
71+let nMetricIdxSurplus = 6
72+
73+let nMetricIdxSurplusPercent = 7
74+
75+let nMetricIdxBR = 8
76+
77+let nMetricIdxNsbtSupply = 9
78+
79+let nMetricIdxMaxNsbtSupply = 10
80+
81+let bFuncIdxSurf = 0
82+
83+let bFuncIdxWaves = 1
84+
85+let bFuncIdxUsdn = 2
86+
87+let bFuncIdxReserveStart = 3
88+
89+let bFuncIdxSupplyStart = 4
90+
91+let bFuncIdxBRStart = 5
92+
93+let bFuncIdxReserveEnd = 6
94+
95+let bFuncIdxSupplyEnd = 7
96+
97+let bFuncIdxBREnd = 8
98+
99+let bFuncIdxRestWaves = 9
100+
101+let bFuncIdxRestUsdn = 10
102+
69103 let PriceKey = "price"
70104
71105 let NsbtAssetIdKey = "bond_asset_id"
72106
73107 let NeutrinoAssetIdKey = "neutrino_asset_id"
108+
109+let SurfAssetIdKey = "surf_asset_id"
74110
75111 let BalanceLockedkKey = "balance_lock_"
76112
85121 let MinWavesForNsbtBuyKey = "min_waves_nsbt_buy"
86122
87123 let MinNsbtSellKey = "min_nsbt_sell"
124+
125+let MinWavesForSurfBuyKey = "min_waves_surf_buy"
126+
127+let MinUsdnForSurfBuyKey = "min_usdn_surf_buy"
88128
89129 func getRoiByOrderIdKey (orderId) = ("debug_order_roi_" + orderId)
90130
113153 func getNextOrderKey (orderId) = ("order_next_" + orderId)
114154
115155
116-func convertNeutrinoToWaves (amount,price) = fraction(fraction(amount, PRICELET, price), WAVELET, PAULI)
156+func convertNeutrinoToWaves (amount,price) = fraction(amount, MULT8, price)
117157
118158
119-func convertWavesToNeutrino (amount,price) = fraction(fraction(amount, price, PRICELET), PAULI, WAVELET)
159+func convertWavesToNeutrino (amount,price) = fraction(amount, price, MULT8)
120160
121161
122-func convertWavesToBond (amount,price) = convertWavesToNeutrino(amount, price)
162+func toX16 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULTX16, toBigInt(origScaleMult))
123163
124164
125-func convertBondToWaves (amount,price) = convertNeutrinoToWaves(amount, price)
126-
127-
128-func toX16 (origVal,origScaleMult) = fraction(toBigInt(origVal), BIGMULT16, toBigInt(origScaleMult))
129-
130-
131-func fromX16 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), BIGMULT16))
165+func fromX16 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULTX16))
132166
133167
134168 let neutrinoContract = Address(base58'3N9be2mwrA52WJho6DiesZkk4351GvpnWuj')
148182 let minWavesAmountNsbtBuy = valueOrElse(getInteger(this, MinWavesForNsbtBuyKey), 1000000000)
149183
150184 let minNsbtSell = valueOrElse(getInteger(this, MinNsbtSellKey), 1000000)
185+
186+let minWavesAmountSurfBuy = valueOrElse(getInteger(this, MinWavesForSurfBuyKey), 100000000)
187+
188+let minUsdnAmountSurfBuy = valueOrElse(getInteger(this, MinUsdnForSurfBuyKey), 10000000)
151189
152190 let firstOrder = getStringByKey(FirstOrderKey)
153191
172210 func getNextOrder (id) = getStringByKey(getNextOrderKey(id))
173211
174212
175-func getReversePrice (price) = ((PRICELET * PRICELET) / price)
213+func getReversePrice (price) = ((MULT6 * MULT6) / price)
176214
177215
178-func calcNsbt2WavesPriceRaw (spentWavesRaw,receivedNsbtRaw) = fraction(toBigInt(spentWavesRaw), toBigInt((PAULI * PRICELET)), toBigInt(receivedNsbtRaw))
216+func calcNsbt2WavesPriceRaw (spentWavesRaw,receivedNsbtRaw) = fraction(toBigInt(spentWavesRaw), toBigInt((MULT6 * MULT6)), toBigInt(receivedNsbtRaw))
179217
180218
181219 func orderData (orderId,totalWavelets,filledWavelets,owner,status,roi,price,currentPrice) = [StringEntry(getOrderPriceKey(orderId), toString(price)), IntegerEntry(getOrderTotalKey(orderId), totalWavelets), IntegerEntry(getOrderFilledTotalKey(orderId), filledWavelets), StringEntry(getOrderOwnerKey(orderId), owner), IntegerEntry(getOrderHeightKey(orderId), height), StringEntry(getOrderStatusKey(orderId), status), IntegerEntry(("debug_order_currentPrice_" + orderId), currentPrice), IntegerEntry(getRoiByOrderIdKey(orderId), roi)]
182220
183221
184222 func toStr (name,curveResult) = (((((((((((((((((((((((((((((((((((name + "[nsbtAmountRaw=") + toString(asInt(curveResult[0]))) + " usdnPayment=") + toString(asInt(curveResult[1]))) + " wRaw=") + toString(asInt(curveResult[2]))) + " uRaw=") + toString(asInt(curveResult[3]))) + " mRaw=") + toString(asInt(curveResult[4]))) + " sRaw=") + toString(asInt(curveResult[5]))) + " nsbtCurveParam_a=") + toString(asInt(curveResult[6]))) + " nsbtCurveParam_b=") + toString(asInt(curveResult[7]))) + " wReservesInUsdn=") + toString(asInt(curveResult[8]))) + " price=") + toString(asInt(curveResult[9]))) + " multBR=") + toString(asInt(curveResult[10]))) + " multPower=") + toString(asInt(curveResult[11]))) + " multExpInPower=") + asString(curveResult[12])) + " multK=") + asString(curveResult[13])) + " step1=") + asString(curveResult[14])) + " step2=") + asString(curveResult[15])) + " step3=") + toString(asInt(curveResult[16]))) + "]")
223+
224+
225+func surfData (surfResult) = StringEntry("debug_surfResult", makeString(["%d%d%d%d%d%d%d%d%d%d%d", toString(asInt(surfResult[bFuncIdxSurf])), toString(asInt(surfResult[bFuncIdxWaves])), toString(asInt(surfResult[bFuncIdxUsdn])), toString(asInt(surfResult[bFuncIdxReserveStart])), toString(asInt(surfResult[bFuncIdxSupplyStart])), toString(asInt(surfResult[bFuncIdxBRStart])), toString(asInt(surfResult[bFuncIdxReserveEnd])), toString(asInt(surfResult[bFuncIdxSupplyEnd])), toString(asInt(surfResult[bFuncIdxBREnd])), toString(asInt(surfResult[bFuncIdxRestWaves])), toString(asInt(surfResult[bFuncIdxRestUsdn]))], SEP))
226+
227+
228+@Callable(i)
229+func constructor (mathContractAddress,minWavesForNsbtBuy,minNsbtSell) = if ((i.caller != this))
230+ then throw("Permission denied")
231+ else [StringEntry(MathContractKey, mathContractAddress), IntegerEntry(MinNsbtSellKey, minNsbtSell), IntegerEntry(MinWavesForNsbtBuyKey, minWavesForNsbtBuy)]
232+
233+
234+
235+@Callable(i)
236+func constructorV2 (minWavesForSurfBuyKey,minUsdnForSurfBuyKey) = if ((i.caller != this))
237+ then throw("Permission denied")
238+ else {
239+ let issue = Issue("SURF", "Smart Utility Recapitalization Feature token", 0, 6, true, unit, 0)
240+ let assetId = calculateAssetId(issue)
241+[issue, StringEntry(SurfAssetIdKey, toBase58String(assetId)), IntegerEntry(MinWavesForSurfBuyKey, minWavesForSurfBuyKey), IntegerEntry(MinUsdnForSurfBuyKey, minUsdnForSurfBuyKey)]
242+ }
243+
185244
186245
187246 @Callable(i)
194253 else if (isDefined(pmt.assetId))
195254 then throw("can use waves only")
196255 else if ((minWavesAmountNsbtBuy > pmtAmount))
197- then throw((("min " + toString((minWavesAmountNsbtBuy / WAVELET))) + " waves expected"))
256+ then throw((("min " + toString((minWavesAmountNsbtBuy / MULT8))) + " waves expected"))
198257 else {
199258 let ownerAddress = i.caller
200259 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
225284 if ((pmt.assetId != nsbtAssetId))
226285 then throw("can use NSBT only")
227286 else if ((minNsbtSell > pmtAmount))
228- then throw((("min " + toString((minNsbtSell / PAULI))) + " nsbt expected"))
287+ then throw((("min " + toString((minNsbtSell / MULT6))) + " nsbt expected"))
229288 else {
230289 let newPrice = asInt(asAnyList(invoke(mathContract, "calcContractNsbtPriceSYSREADONLY", [-(pmtAmount)], nil))[0])
231- if ((PAULI > newPrice))
290+ if ((MULT6 > newPrice))
232291 then throw((("resulting nsbt price would be < 1 (" + toString(newPrice)) + " usdn)"))
233292 else {
234293 let transf = invoke(neutrinoContract, "transferUsdnToUser", [pmtAmount, toString(i.caller)], nil)
266325 func minNsbtAmountForSellSYSREADONLY () = $Tuple2(nil, minNsbtSell)
267326
268327
328+
329+@Callable(i)
330+func minWavesAmountSurfBuySYSREADONLY () = $Tuple2(nil, minWavesAmountSurfBuy)
331+
332+
333+
334+@Callable(i)
335+func minUsdnAmountSurfBuySYSREADONLY () = $Tuple2(nil, minUsdnAmountSurfBuy)
336+
337+
338+
339+@Callable(i)
340+func buySurf (noLessAmount,autoStake) = if ((size(i.payments) != 1))
341+ then throw("exactly 1 payment must be attached")
342+ else {
343+ let pmt = i.payments[0]
344+ let amt = pmt.amount
345+ let pmtAssetId = valueOrElse(pmt.assetId, WAVESID)
346+ if (if ((pmtAssetId != neutrinoAssetId))
347+ then (pmtAssetId != WAVESID)
348+ else false)
349+ then throw("Unsupported payment asset")
350+ else if (if ((pmtAssetId == neutrinoAssetId))
351+ then (minUsdnAmountSurfBuy > amt)
352+ else false)
353+ then throw((("min " + toString((minUsdnAmountSurfBuy / MULT6))) + " USDN expected"))
354+ else if (if ((pmtAssetId == WAVESID))
355+ then (minWavesAmountSurfBuy > amt)
356+ else false)
357+ then throw((("min " + toString((minWavesAmountSurfBuy / MULT8))) + " WAVES expected"))
358+ else {
359+ let surfResult = asAnyList(invoke(mathContract, "surfFunctionREADONLY", [amt, pmtAssetId], nil))
360+ let surfAmount = asInt(surfResult[bFuncIdxSurf])
361+ if ((noLessAmount > surfAmount))
362+ then throw(((("Requested no less than " + toString(noLessAmount)) + " SURF, but can buy only ") + toString(surfAmount)))
363+ else {
364+ let transfer = if ((pmtAssetId == WAVESID))
365+ then {
366+ let restWaves = asInt(surfResult[bFuncIdxRestWaves])
367+ let wavesAmt = invoke(neutrinoContract, "acceptWaves", nil, [AttachedPayment(unit, (amt - restWaves))])
368+ if ((wavesAmt == wavesAmt))
369+ then if ((restWaves > 0))
370+ then [ScriptTransfer(i.caller, restWaves, unit)]
371+ else nil
372+ else throw("Strict value is not equal to itself.")
373+ }
374+ else {
375+ let restUsdn = asInt(surfResult[bFuncIdxRestUsdn])
376+ if ((restUsdn > 0))
377+ then [ScriptTransfer(neutrinoContract, (amt - restUsdn), neutrinoAssetId), ScriptTransfer(i.caller, restUsdn, neutrinoAssetId)]
378+ else [ScriptTransfer(neutrinoContract, (amt - restUsdn), neutrinoAssetId)]
379+ }
380+ let surfAssetId = fromBase58String(getStringValue(SurfAssetIdKey))
381+ (transfer ++ [Reissue(surfAssetId, surfAmount, true), ScriptTransfer(i.caller, surfAmount, surfAssetId), surfData(surfResult)])
382+ }
383+ }
384+ }
385+
386+
269387 @Verifier(tx)
270388 func verify () = {
271- let pubKeyAdminsList = ["ExtEEK19nmKj9mCpnWyvEEJFYATLMcVEMvohhUHkyHNm", "Ev5py5FfBQX9cZpYKnfQrTB49Byf8QmpZWeDVRim4yV7", "DUuuLjXu98nBwZc7fqwCTjtA3nnRwgTbkMSr5SU2NmDR", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
389+ let pubKeyAdminsListStr = makeString(["ExtEEK19nmKj9mCpnWyvEEJFYATLMcVEMvohhUHkyHNm", "Ev5py5FfBQX9cZpYKnfQrTB49Byf8QmpZWeDVRim4yV7", "DUuuLjXu98nBwZc7fqwCTjtA3nnRwgTbkMSr5SU2NmDR", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"], SEP)
390+ let pubKeyAdminsList = split(valueOrElse(getString(controlContract, "%s__multisig"), pubKeyAdminsListStr), SEP)
272391 let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
273392 then 1
274393 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
55
66
77 func getStringByKey (key) = valueOrElse(getString(this, key), "")
88
99
1010 func getBoolByAddressAndKey (address,key) = valueOrElse(getBoolean(address, key), false)
1111
1212
1313 func getStringByAddressAndKey (address,key) = valueOrElse(getString(address, key), "")
1414
1515
1616 func getNumberByAddressAndKey (address,key) = valueOrElse(getInteger(address, key), 0)
1717
1818
1919 func asAnyList (val) = match val {
2020 case valAnyLyst: List[Any] =>
2121 valAnyLyst
2222 case _ =>
2323 throw("fail to cast into List[Any]")
2424 }
2525
2626
2727 func asString (val) = match val {
2828 case valStr: String =>
2929 valStr
3030 case _ =>
3131 throw("fail to cast into String")
3232 }
3333
3434
3535 func asInt (val) = match val {
3636 case valInt: Int =>
3737 valInt
3838 case _ =>
3939 throw("fail to cast into Int")
4040 }
4141
4242
43-let WAVELET = 100000000
43+let SEP = "__"
4444
45-let PAULI = 1000000
45+let MULT6 = 1000000
4646
47-let BIGPAULI = toBigInt(1000000)
47+let MULT8 = 100000000
4848
49-let PRICELET = 1000000
50-
51-let MULT = 100000000
52-
53-let BIGMULT16 = toBigInt(10000000000000000)
54-
55-let SCALE8 = 8
56-
57-let SCALE16 = 16
58-
59-let MINORDERTOTAL = (10 * WAVELET)
60-
61-let MAXROI = 95
49+let MULTX16 = toBigInt(10000000000000000)
6250
6351 let CANCELED = "canceled"
6452
6553 let NEW = "new"
6654
6755 let FILLED = "filled"
6856
57+let WAVESID = fromBase58String("WAVES")
58+
59+let nMetricIdxPrice = 0
60+
61+let nMetricIdxUsdnLockedBalance = 1
62+
63+let nMetricIdxWavesLockedBalance = 2
64+
65+let nMetricIdxReserve = 3
66+
67+let nMetricIdxReserveInUsdn = 4
68+
69+let nMetricIdxUsdnSupply = 5
70+
71+let nMetricIdxSurplus = 6
72+
73+let nMetricIdxSurplusPercent = 7
74+
75+let nMetricIdxBR = 8
76+
77+let nMetricIdxNsbtSupply = 9
78+
79+let nMetricIdxMaxNsbtSupply = 10
80+
81+let bFuncIdxSurf = 0
82+
83+let bFuncIdxWaves = 1
84+
85+let bFuncIdxUsdn = 2
86+
87+let bFuncIdxReserveStart = 3
88+
89+let bFuncIdxSupplyStart = 4
90+
91+let bFuncIdxBRStart = 5
92+
93+let bFuncIdxReserveEnd = 6
94+
95+let bFuncIdxSupplyEnd = 7
96+
97+let bFuncIdxBREnd = 8
98+
99+let bFuncIdxRestWaves = 9
100+
101+let bFuncIdxRestUsdn = 10
102+
69103 let PriceKey = "price"
70104
71105 let NsbtAssetIdKey = "bond_asset_id"
72106
73107 let NeutrinoAssetIdKey = "neutrino_asset_id"
108+
109+let SurfAssetIdKey = "surf_asset_id"
74110
75111 let BalanceLockedkKey = "balance_lock_"
76112
77113 let WavesLockedBalanceKey = (BalanceLockedkKey + "waves")
78114
79115 let NeutrinoLockedBalanceKey = (BalanceLockedkKey + "neutrino")
80116
81117 let FirstOrderKey = "order_first"
82118
83119 let MathContractKey = "math_contract"
84120
85121 let MinWavesForNsbtBuyKey = "min_waves_nsbt_buy"
86122
87123 let MinNsbtSellKey = "min_nsbt_sell"
124+
125+let MinWavesForSurfBuyKey = "min_waves_surf_buy"
126+
127+let MinUsdnForSurfBuyKey = "min_usdn_surf_buy"
88128
89129 func getRoiByOrderIdKey (orderId) = ("debug_order_roi_" + orderId)
90130
91131
92132 func getOrderPriceKey (orderId) = ("order_price_" + orderId)
93133
94134
95135 func getOrderTotalKey (orderId) = ("order_total_" + orderId)
96136
97137
98138 func getOrderOwnerKey (orderId) = ("order_owner_" + orderId)
99139
100140
101141 func getOrderHeightKey (orderId) = ("order_height_" + orderId)
102142
103143
104144 func getOrderStatusKey (orderId) = ("order_status_" + orderId)
105145
106146
107147 func getOrderFilledTotalKey (orderId) = ("order_filled_total_" + orderId)
108148
109149
110150 func getPrevOrderKey (orderId) = ("order_prev_" + orderId)
111151
112152
113153 func getNextOrderKey (orderId) = ("order_next_" + orderId)
114154
115155
116-func convertNeutrinoToWaves (amount,price) = fraction(fraction(amount, PRICELET, price), WAVELET, PAULI)
156+func convertNeutrinoToWaves (amount,price) = fraction(amount, MULT8, price)
117157
118158
119-func convertWavesToNeutrino (amount,price) = fraction(fraction(amount, price, PRICELET), PAULI, WAVELET)
159+func convertWavesToNeutrino (amount,price) = fraction(amount, price, MULT8)
120160
121161
122-func convertWavesToBond (amount,price) = convertWavesToNeutrino(amount, price)
162+func toX16 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULTX16, toBigInt(origScaleMult))
123163
124164
125-func convertBondToWaves (amount,price) = convertNeutrinoToWaves(amount, price)
126-
127-
128-func toX16 (origVal,origScaleMult) = fraction(toBigInt(origVal), BIGMULT16, toBigInt(origScaleMult))
129-
130-
131-func fromX16 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), BIGMULT16))
165+func fromX16 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULTX16))
132166
133167
134168 let neutrinoContract = Address(base58'3N9be2mwrA52WJho6DiesZkk4351GvpnWuj')
135169
136170 let controlContract = Address(base58'3MrwvfA9VRYwhHy4NuWPQGdxCtZdhH4LMMa')
137171
138172 let liquidationContract = Address(base58'3N24ZPUAMhFm76N3vbNiiDtFqfUnmBHTc5N')
139173
140174 let mathContract = addressFromStringValue(getStringByKey(MathContractKey))
141175
142176 let neutrinoAssetId = base58'HezsdQuRDtzksAYUy97gfhKy7Z1NW2uXYSHA3bgqenNZ'
143177
144178 let nsbtAssetId = base58'F3iaxzruFeKujfVfYSZEkejpjh67wmRfPCRHiNmWKp3Z'
145179
146180 let isBlocked = getBoolByAddressAndKey(controlContract, "is_blocked")
147181
148182 let minWavesAmountNsbtBuy = valueOrElse(getInteger(this, MinWavesForNsbtBuyKey), 1000000000)
149183
150184 let minNsbtSell = valueOrElse(getInteger(this, MinNsbtSellKey), 1000000)
185+
186+let minWavesAmountSurfBuy = valueOrElse(getInteger(this, MinWavesForSurfBuyKey), 100000000)
187+
188+let minUsdnAmountSurfBuy = valueOrElse(getInteger(this, MinUsdnForSurfBuyKey), 10000000)
151189
152190 let firstOrder = getStringByKey(FirstOrderKey)
153191
154192 func getOrderPrice (id) = getNumberByKey(getOrderPriceKey(id))
155193
156194
157195 func getOrderTotal (id) = getNumberByKey(getOrderTotalKey(id))
158196
159197
160198 func getOrderOwner (id) = getStringByKey(getOrderOwnerKey(id))
161199
162200
163201 func getOrderStatus (id) = getStringByKey(getOrderStatusKey(id))
164202
165203
166204 func getOrderFilledTotal (id) = getNumberByKey(getOrderFilledTotalKey(id))
167205
168206
169207 func getPrevOrder (id) = getStringByKey(getPrevOrderKey(id))
170208
171209
172210 func getNextOrder (id) = getStringByKey(getNextOrderKey(id))
173211
174212
175-func getReversePrice (price) = ((PRICELET * PRICELET) / price)
213+func getReversePrice (price) = ((MULT6 * MULT6) / price)
176214
177215
178-func calcNsbt2WavesPriceRaw (spentWavesRaw,receivedNsbtRaw) = fraction(toBigInt(spentWavesRaw), toBigInt((PAULI * PRICELET)), toBigInt(receivedNsbtRaw))
216+func calcNsbt2WavesPriceRaw (spentWavesRaw,receivedNsbtRaw) = fraction(toBigInt(spentWavesRaw), toBigInt((MULT6 * MULT6)), toBigInt(receivedNsbtRaw))
179217
180218
181219 func orderData (orderId,totalWavelets,filledWavelets,owner,status,roi,price,currentPrice) = [StringEntry(getOrderPriceKey(orderId), toString(price)), IntegerEntry(getOrderTotalKey(orderId), totalWavelets), IntegerEntry(getOrderFilledTotalKey(orderId), filledWavelets), StringEntry(getOrderOwnerKey(orderId), owner), IntegerEntry(getOrderHeightKey(orderId), height), StringEntry(getOrderStatusKey(orderId), status), IntegerEntry(("debug_order_currentPrice_" + orderId), currentPrice), IntegerEntry(getRoiByOrderIdKey(orderId), roi)]
182220
183221
184222 func toStr (name,curveResult) = (((((((((((((((((((((((((((((((((((name + "[nsbtAmountRaw=") + toString(asInt(curveResult[0]))) + " usdnPayment=") + toString(asInt(curveResult[1]))) + " wRaw=") + toString(asInt(curveResult[2]))) + " uRaw=") + toString(asInt(curveResult[3]))) + " mRaw=") + toString(asInt(curveResult[4]))) + " sRaw=") + toString(asInt(curveResult[5]))) + " nsbtCurveParam_a=") + toString(asInt(curveResult[6]))) + " nsbtCurveParam_b=") + toString(asInt(curveResult[7]))) + " wReservesInUsdn=") + toString(asInt(curveResult[8]))) + " price=") + toString(asInt(curveResult[9]))) + " multBR=") + toString(asInt(curveResult[10]))) + " multPower=") + toString(asInt(curveResult[11]))) + " multExpInPower=") + asString(curveResult[12])) + " multK=") + asString(curveResult[13])) + " step1=") + asString(curveResult[14])) + " step2=") + asString(curveResult[15])) + " step3=") + toString(asInt(curveResult[16]))) + "]")
223+
224+
225+func surfData (surfResult) = StringEntry("debug_surfResult", makeString(["%d%d%d%d%d%d%d%d%d%d%d", toString(asInt(surfResult[bFuncIdxSurf])), toString(asInt(surfResult[bFuncIdxWaves])), toString(asInt(surfResult[bFuncIdxUsdn])), toString(asInt(surfResult[bFuncIdxReserveStart])), toString(asInt(surfResult[bFuncIdxSupplyStart])), toString(asInt(surfResult[bFuncIdxBRStart])), toString(asInt(surfResult[bFuncIdxReserveEnd])), toString(asInt(surfResult[bFuncIdxSupplyEnd])), toString(asInt(surfResult[bFuncIdxBREnd])), toString(asInt(surfResult[bFuncIdxRestWaves])), toString(asInt(surfResult[bFuncIdxRestUsdn]))], SEP))
226+
227+
228+@Callable(i)
229+func constructor (mathContractAddress,minWavesForNsbtBuy,minNsbtSell) = if ((i.caller != this))
230+ then throw("Permission denied")
231+ else [StringEntry(MathContractKey, mathContractAddress), IntegerEntry(MinNsbtSellKey, minNsbtSell), IntegerEntry(MinWavesForNsbtBuyKey, minWavesForNsbtBuy)]
232+
233+
234+
235+@Callable(i)
236+func constructorV2 (minWavesForSurfBuyKey,minUsdnForSurfBuyKey) = if ((i.caller != this))
237+ then throw("Permission denied")
238+ else {
239+ let issue = Issue("SURF", "Smart Utility Recapitalization Feature token", 0, 6, true, unit, 0)
240+ let assetId = calculateAssetId(issue)
241+[issue, StringEntry(SurfAssetIdKey, toBase58String(assetId)), IntegerEntry(MinWavesForSurfBuyKey, minWavesForSurfBuyKey), IntegerEntry(MinUsdnForSurfBuyKey, minUsdnForSurfBuyKey)]
242+ }
243+
185244
186245
187246 @Callable(i)
188247 func buyNsbt () = {
189248 let pmt = value(i.payments[0])
190249 let pmtAmount = pmt.amount
191250 let wavesPay = pmtAmount
192251 if (isBlocked)
193252 then throw("contract is blocked by EMERGENCY SHUTDOWN actions until reactivation by emergency oracles")
194253 else if (isDefined(pmt.assetId))
195254 then throw("can use waves only")
196255 else if ((minWavesAmountNsbtBuy > pmtAmount))
197- then throw((("min " + toString((minWavesAmountNsbtBuy / WAVELET))) + " waves expected"))
256+ then throw((("min " + toString((minWavesAmountNsbtBuy / MULT8))) + " waves expected"))
198257 else {
199258 let ownerAddress = i.caller
200259 let neutrinoMetrics = asAnyList(invoke(mathContract, "calcNeutinoMetricsREADONLY", nil, nil))
201260 let currentPrice = asInt(neutrinoMetrics[0])
202261 let curveResult = asAnyList(invoke(mathContract, "curveFunctionREADONLY", [wavesPay], nil))
203262 let nsbtAmount = asInt(curveResult[0])
204263 if ((0 >= nsbtAmount))
205264 then throw("nsbtAmount <= 0")
206265 else {
207266 let nsbt2WavesPriceRaw = calcNsbt2WavesPriceRaw(wavesPay, nsbtAmount)
208267 let roi = 0
209268 let amountLeased = invoke(neutrinoContract, "acceptWaves", nil, i.payments)
210269 if ((amountLeased == amountLeased))
211270 then $Tuple2((orderData(toBase58String(i.transactionId), pmtAmount, pmtAmount, toString(ownerAddress), FILLED, roi, nsbt2WavesPriceRaw, currentPrice) ++ [ScriptTransfer(ownerAddress, nsbtAmount, nsbtAssetId), StringEntry("debug_curveResult", toStr("curveResult", curveResult))]), nsbtAmount)
212271 else throw("Strict value is not equal to itself.")
213272 }
214273 }
215274 }
216275
217276
218277
219278 @Callable(i)
220279 func sellNsbt () = if (isBlocked)
221280 then throw("contract is blocked by EMERGENCY SHUTDOWN actions until reactivation by emergency oracles")
222281 else {
223282 let pmt = value(i.payments[0])
224283 let pmtAmount = pmt.amount
225284 if ((pmt.assetId != nsbtAssetId))
226285 then throw("can use NSBT only")
227286 else if ((minNsbtSell > pmtAmount))
228- then throw((("min " + toString((minNsbtSell / PAULI))) + " nsbt expected"))
287+ then throw((("min " + toString((minNsbtSell / MULT6))) + " nsbt expected"))
229288 else {
230289 let newPrice = asInt(asAnyList(invoke(mathContract, "calcContractNsbtPriceSYSREADONLY", [-(pmtAmount)], nil))[0])
231- if ((PAULI > newPrice))
290+ if ((MULT6 > newPrice))
232291 then throw((("resulting nsbt price would be < 1 (" + toString(newPrice)) + " usdn)"))
233292 else {
234293 let transf = invoke(neutrinoContract, "transferUsdnToUser", [pmtAmount, toString(i.caller)], nil)
235294 if ((transf == transf))
236295 then $Tuple2(nil, newPrice)
237296 else throw("Strict value is not equal to itself.")
238297 }
239298 }
240299 }
241300
242301
243302
244303 @Callable(i)
245304 func cancelOrder (orderId) = {
246305 let owner = getOrderOwner(orderId)
247306 let amount = (getOrderTotal(orderId) - getOrderFilledTotal(orderId))
248307 let caller = toString(i.caller)
249308 let nextOrder = getNextOrder(orderId)
250309 let prevOrder = getPrevOrder(orderId)
251310 if ((getOrderStatus(orderId) != NEW))
252311 then throw("invalid order status")
253312 else [StringEntry(FirstOrderKey, if ((firstOrder == orderId))
254313 then nextOrder
255314 else firstOrder), StringEntry(getNextOrderKey(prevOrder), nextOrder), StringEntry(getPrevOrderKey(nextOrder), prevOrder), StringEntry(getOrderStatusKey(orderId), CANCELED), ScriptTransfer(i.caller, amount, unit)]
256315 }
257316
258317
259318
260319 @Callable(i)
261320 func minWavesAmountNsbtBuySYSREADONLY () = $Tuple2(nil, minWavesAmountNsbtBuy)
262321
263322
264323
265324 @Callable(i)
266325 func minNsbtAmountForSellSYSREADONLY () = $Tuple2(nil, minNsbtSell)
267326
268327
328+
329+@Callable(i)
330+func minWavesAmountSurfBuySYSREADONLY () = $Tuple2(nil, minWavesAmountSurfBuy)
331+
332+
333+
334+@Callable(i)
335+func minUsdnAmountSurfBuySYSREADONLY () = $Tuple2(nil, minUsdnAmountSurfBuy)
336+
337+
338+
339+@Callable(i)
340+func buySurf (noLessAmount,autoStake) = if ((size(i.payments) != 1))
341+ then throw("exactly 1 payment must be attached")
342+ else {
343+ let pmt = i.payments[0]
344+ let amt = pmt.amount
345+ let pmtAssetId = valueOrElse(pmt.assetId, WAVESID)
346+ if (if ((pmtAssetId != neutrinoAssetId))
347+ then (pmtAssetId != WAVESID)
348+ else false)
349+ then throw("Unsupported payment asset")
350+ else if (if ((pmtAssetId == neutrinoAssetId))
351+ then (minUsdnAmountSurfBuy > amt)
352+ else false)
353+ then throw((("min " + toString((minUsdnAmountSurfBuy / MULT6))) + " USDN expected"))
354+ else if (if ((pmtAssetId == WAVESID))
355+ then (minWavesAmountSurfBuy > amt)
356+ else false)
357+ then throw((("min " + toString((minWavesAmountSurfBuy / MULT8))) + " WAVES expected"))
358+ else {
359+ let surfResult = asAnyList(invoke(mathContract, "surfFunctionREADONLY", [amt, pmtAssetId], nil))
360+ let surfAmount = asInt(surfResult[bFuncIdxSurf])
361+ if ((noLessAmount > surfAmount))
362+ then throw(((("Requested no less than " + toString(noLessAmount)) + " SURF, but can buy only ") + toString(surfAmount)))
363+ else {
364+ let transfer = if ((pmtAssetId == WAVESID))
365+ then {
366+ let restWaves = asInt(surfResult[bFuncIdxRestWaves])
367+ let wavesAmt = invoke(neutrinoContract, "acceptWaves", nil, [AttachedPayment(unit, (amt - restWaves))])
368+ if ((wavesAmt == wavesAmt))
369+ then if ((restWaves > 0))
370+ then [ScriptTransfer(i.caller, restWaves, unit)]
371+ else nil
372+ else throw("Strict value is not equal to itself.")
373+ }
374+ else {
375+ let restUsdn = asInt(surfResult[bFuncIdxRestUsdn])
376+ if ((restUsdn > 0))
377+ then [ScriptTransfer(neutrinoContract, (amt - restUsdn), neutrinoAssetId), ScriptTransfer(i.caller, restUsdn, neutrinoAssetId)]
378+ else [ScriptTransfer(neutrinoContract, (amt - restUsdn), neutrinoAssetId)]
379+ }
380+ let surfAssetId = fromBase58String(getStringValue(SurfAssetIdKey))
381+ (transfer ++ [Reissue(surfAssetId, surfAmount, true), ScriptTransfer(i.caller, surfAmount, surfAssetId), surfData(surfResult)])
382+ }
383+ }
384+ }
385+
386+
269387 @Verifier(tx)
270388 func verify () = {
271- let pubKeyAdminsList = ["ExtEEK19nmKj9mCpnWyvEEJFYATLMcVEMvohhUHkyHNm", "Ev5py5FfBQX9cZpYKnfQrTB49Byf8QmpZWeDVRim4yV7", "DUuuLjXu98nBwZc7fqwCTjtA3nnRwgTbkMSr5SU2NmDR", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
389+ let pubKeyAdminsListStr = makeString(["ExtEEK19nmKj9mCpnWyvEEJFYATLMcVEMvohhUHkyHNm", "Ev5py5FfBQX9cZpYKnfQrTB49Byf8QmpZWeDVRim4yV7", "DUuuLjXu98nBwZc7fqwCTjtA3nnRwgTbkMSr5SU2NmDR", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"], SEP)
390+ let pubKeyAdminsList = split(valueOrElse(getString(controlContract, "%s__multisig"), pubKeyAdminsListStr), SEP)
272391 let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
273392 then 1
274393 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
275394 then 1
276395 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2])))
277396 then 1
278397 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[3], fromBase58String(pubKeyAdminsList[3])))
279398 then 2
280399 else 0))
281400 (count >= 3)
282401 }
283402

github/deemru/w8io/6500d08 
80.82 ms