tx · 8QuLefVAT8YVkZsUzukK5XbrBdgk9jLqffkNBNVC5cdE

3PF8ihzUXp9QqvtcnpSveENQHqLDYGvbRvZ:  -0.00600000 Waves

2023.03.10 17:00 [3549568] smart account 3PF8ihzUXp9QqvtcnpSveENQHqLDYGvbRvZ > SELF 0.00000000 Waves

{ "type": 13, "id": "8QuLefVAT8YVkZsUzukK5XbrBdgk9jLqffkNBNVC5cdE", "fee": 600000, "feeAssetId": null, "timestamp": 1678456854500, "version": 2, "chainId": 87, "sender": "3PF8ihzUXp9QqvtcnpSveENQHqLDYGvbRvZ", "senderPublicKey": "9kcEZHonGr2aoSBCDgKiB7nf7C6dYThx4YnvpDKNSD77", "proofs": [ "4RrYLsBkjMGY4qUXNV2hu3XP2yKjGSg1Z1qtYz2ZRt7nFguutWwWDEA1HBSCFjKJV24XGZmEKA49LGsM5voHiKYD" ], "script": "base64:AAIFAAAAAAAAABMIAhIECgIBCBIJCgcRGBgYAQEYAAAADAEAAAAQZ2V0U3RyaW5nT3JUaHJvdwAAAAIAAAAHYWRkcmVzcwAAAANrZXkJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAdhZGRyZXNzBQAAAANrZXkJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAADENhbid0IHJlYWQgJwUAAAADa2V5AgAAAA0nIGF0IGFkZHJlc3MgCQAEJQAAAAEFAAAAB2FkZHJlc3MBAAAAE3BhcnNlQWRkcmVzc09yVGhyb3cAAAABAAAADG1heWJlQWRkcmVzcwkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEFAAAADG1heWJlQWRkcmVzcwkAASwAAAACCQABLAAAAAICAAAAGkNhbid0IHBhcnNlIGFkZHJlc3MgZnJvbSAnBQAAAAxtYXliZUFkZHJlc3MCAAAAAScBAAAAGGtleV9sYXN0RmVlU3dhcFRpbWVzdGFtcAAAAAEAAAAHYXNzZXRJZAkAASwAAAACCQABLAAAAAICAAAABEZlZV8FAAAAB2Fzc2V0SWQCAAAAEl9sYXN0U3dhcFRpbWVzdGFtcAAAAAAMcHJveHlBZGRyZXNzCQEAAAATcGFyc2VBZGRyZXNzT3JUaHJvdwAAAAEJAQAAABBnZXRTdHJpbmdPclRocm93AAAAAgUAAAAEdGhpcwIAAAANcHJveHktYWRkcmVzcwEAAAAKZ2V0QXNzZXRJZAAAAAEAAAAFYXNzZXQDCQAAAAAAAAIFAAAABWFzc2V0AgAAAAVXQVZFUwUAAAAEdW5pdAgJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkAA+wAAAABCQACWQAAAAEFAAAABWFzc2V0CQABLAAAAAICAAAAEUNhbid0IGZpbmQgYXNzZXQgBQAAAAVhc3NldAAAAAJpZAAAAAASZmVlUHJpb3JpdHlBc3NldElkBAAAAAckbWF0Y2gwCQAEHQAAAAIFAAAABHRoaXMCAAAAEUZlZV9wcmlvcml0eUFzc2V0AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAAZTdHJpbmcEAAAAEHByaW9yaXR5QXNzZXRTdHIFAAAAByRtYXRjaDAJAAJZAAAAAQUAAAAQcHJpb3JpdHlBc3NldFN0cgkAAAIAAAABAgAAACBXQVZFUyBjYW5ub3QgYmUgYSBwcmlvcml0eSBhc3NldAAAAAAWZmVlUHJpb3JpdHlNaW5SZWNlaXZlZAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzAgAAABdGZWVfcHJpb3JpdHlNaW5SZWNlaXZlZAAAAAAAAAAAAAAAAAAKZmVlTWFuYWdlcgQAAAAHJG1hdGNoMAkABB0AAAACBQAAAAR0aGlzAgAAABRGZWVfbWFuYWdlclB1YmxpY0tleQMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAGU3RyaW5nBAAAAA9tYXliZUZlZU1hbmFnZXIFAAAAByRtYXRjaDAJAAJZAAAAAQUAAAAPbWF5YmVGZWVNYW5hZ2VyBQAAAAR1bml0AAAAAAxzd2FwRmVlTGltaXQJAAQaAAAAAgUAAAAEdGhpcwIAAAAQRmVlX3N3YXBGZWVMaW1pdAAAAAAUZmVlQXNzZXRTd2FwSW50ZXJ2YWwJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwIAAAAVRmVlX2Fzc2V0U3dhcEludGVydmFsAAAAAAAAAAAAAQAAABdnZXRMYXN0RmVlU3dhcFRpbWVzdGFtcAAAAAEAAAAHYXNzZXRJZAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAYa2V5X2xhc3RGZWVTd2FwVGltZXN0YW1wAAAAAQkAAlgAAAABBQAAAAdhc3NldElkAAAAAAAAAAAAAQAAABdzZXRMYXN0RmVlU3dhcFRpbWVzdGFtcAAAAAIAAAAHYXNzZXRJZAAAAAl0aW1lc3RhbXAJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABhrZXlfbGFzdEZlZVN3YXBUaW1lc3RhbXAAAAABCQACWAAAAAEFAAAAB2Fzc2V0SWQFAAAACXRpbWVzdGFtcAUAAAADbmlsAAAAAgAAAANpbnYBAAAAE2NsYWltUmVmZXJyZXJSZXdhcmQAAAACAAAABmFtb3VudAAAAAdhc3NldElkBAAAAAVhc3NldAkBAAAACmdldEFzc2V0SWQAAAABBQAAAAdh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aXMFAAAAEmZlZVByaW9yaXR5QXNzZXRJZAMJAAAAAAAAAgUAAAAMYmFsYW5jZUFmdGVyBQAAAAxiYWxhbmNlQWZ0ZXIEAAAACHJlY2VpdmVkCQAAZQAAAAIFAAAADGJhbGFuY2VBZnRlcgUAAAANYmFsYW5jZUJlZm9yZQMJAABnAAAAAgAAAAAAAAAAAAUAAAAIcmVjZWl2ZWQJAAACAAAAAQIAAAAqU3dhcCBpcyBvbmx5IGFsbG93ZWQgdG8gdGhlIHByaW9yaXR5IGFzc2V0AwkAAGYAAAACBQAAABZmZWVQcmlvcml0eU1pblJlY2VpdmVkBQAAAAhyZWNlaXZlZAkAAAIAAAABCQABLAAAAAICAAAAGVN3YXAgcmVzdWx0IGlzIGxlc3MgdGhhbiAJAAGkAAAAAQUAAAAWZmVlUHJpb3JpdHlNaW5SZWNlaXZlZAkBAAAAF3NldExhc3RGZWVTd2FwVGltZXN0YW1wAAAAAgUAAAAKcG10QXNzZXRJZAgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABAAAAAnR4AQAAAAZ2ZXJpZnkAAAAABAAAAAttYXliZU9yYWNsZQkABCYAAAABCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMCAAAABk9yYWNsZQIAAAAABAAAAA5tYXliZUFkbWluS2V5cwMJAQAAAAlpc0RlZmluZWQAAAABBQAAAAttYXliZU9yYWNsZQkABB0AAAACCQEAAAAFdmFsdWUAAAABBQAAAAttYXliZU9yYWNsZQIAAAAJQWRtaW5LZXlzBQAAAAR1bml0BAAAAA9pc0ZlZVN3YXBJbnZva2UEAAAAByRtYXRjaDAFAAAAAnR4AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAABdJbnZva2VTY3JpcHRUcmFuc2FjdGlvbgQAAAACdHgFAAAAByRtYXRjaDADCQAAAAAAAAIIBQAAAAJ0eAAAAARkQXBwBQAAAAR0aGlzCQAAAAAAAAIIBQAAAAJ0eAAAAAhmdW5jdGlvbgIAAAAMUFJJVkFURV9zd2FwBwcDAwkBAAAACWlzRGVmaW5lZAAAAAEFAAAACmZlZU1hbmFnZXIFAAAAD2lzRmVlU3dhcEludm9rZQcJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAACQEAAAAFdmFsdWUAAAABBQAAAApmZWVNYW5hZ2VyBAAAAAckbWF0Y2gwBQAAAA5tYXliZUFkbWluS2V5cwMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAGU3RyaW5nBAAAAAxhZG1pbktleXNTdHIFAAAAByRtYXRjaDAEAAAACWFkbWluS2V5cwQAAAAKc3RyaW5nS2V5cwkABLUAAAACBQAAAAxhZG1pbktleXNTdHICAAAAASwJAARMAAAAAgkAAlkAAAABCQABkQAAAAIFAAAACnN0cmluZ0tleXMAAAAAAAAAAAAJAARMAAAAAgkAAlkAAAABCQABkQAAAAIFAAAACnN0cmluZ0tleXMAAAAAAAAAAAEJAARMAAAAAgkAAlkAAAABCQABkQAAAAIFAAAACnN0cmluZ0tleXMAAAAAAAAAAAIFAAAAA25pbAoBAAAAD3ZlcmlmeUJ5QWxsS2V5cwAAAAEAAAAFcHJvb2YDCQAB9AAAAAMIBQAAAAJ0eAAAAAlib2R5Qnl0ZXMFAAAABXByb29mCQABkQAAAAIFAAAACWFkbWluS2V5cwAAAAAAAAAAAAAAAAAAAAAAAQMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwUAAAAFcHJvb2YJAAGRAAAAAgUAAAAJYWRtaW5LZXlzAAAAAAAAAAABAAAAAAAAAAAKAwkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzBQAAAAVwcm9vZgkAAZEAAAACBQAAAAlhZG1pbktleXMAAAAAAAAAAAIAAAAAAAAAAGQAAAAAAAAAAAAJAQAAAA9jb250YWluc0VsZW1lbnQAAAACCQAETAAAAAIAAAAAAAAAAG4JAARMAAAAAgAAAAAAAAAAZQkABEwAAAACAAAAAAAAAAALBQAAAANuaWwJAABkAAAAAgkBAAAAD3ZlcmlmeUJ5QWxsS2V5cwAAAAEJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAAkBAAAAD3ZlcmlmeUJ5QWxsS2V5cwAAAAEJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAQkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAIBQAAAAJ0eAAAAA9zZW5kZXJQdWJsaWNLZXlhdXmx", "height": 3549568, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: DTePGL71bZ8wVdjD6t9faSZndz4t8qNP9WAPQQeoQ4G9 Next: BcYFnD6sqhrjR6WKDdcJTuvbEvNZ8cCp6tUQVWLBgWcf Diff:
OldNewDifferences
44 func getStringOrThrow (address,key) = valueOrErrorMessage(getString(address, key), ((("Can't read '" + key) + "' at address ") + toString(address)))
55
66
7-func getIntegerOrThrow (address,key) = valueOrErrorMessage(getInteger(address, key), ((("Can't read '" + key) + "' at address ") + toString(address)))
8-
9-
107 func parseAddressOrThrow (maybeAddress) = valueOrErrorMessage(addressFromString(maybeAddress), (("Can't parse address from '" + maybeAddress) + "'"))
118
129
13-func parseIntOrDefault (maybeInt,default) = valueOrElse(parseInt(maybeInt), default)
10+func key_lastFeeSwapTimestamp (assetId) = (("Fee_" + assetId) + "_lastSwapTimestamp")
1411
1512
16-func parseIntOrThrow (maybeInt) = valueOrErrorMessage(parseInt(maybeInt), (("Can't parse integer from '" + maybeInt) + "'"))
17-
13+let proxyAddress = parseAddressOrThrow(getStringOrThrow(this, "proxy-address"))
1814
1915 func getAssetId (asset) = if ((asset == "WAVES"))
2016 then unit
21- else fromBase58String(asset)
17+ else valueOrErrorMessage(assetInfo(fromBase58String(asset)), ("Can't find asset " + asset)).id
2218
2319
24-let collector = parseAddressOrThrow(getStringOrThrow(this, "collector"))
25-
26-let feeRate = getIntegerOrThrow(this, "fee-rate")
27-
28-let oracle = parseAddressOrThrow(getStringOrThrow(this, "oracle"))
29-
30-let swopfiRouting = parseAddressOrThrow(getStringOrThrow(this, "swopfi-routing"))
31-
32-let puzzleRouting = parseAddressOrThrow(getStringOrThrow(this, "puzzle-routing"))
33-
34-let pools = split(getStringOrThrow(oracle, "pools"), ",")
35-
36-let percentRate = getIntegerOrThrow(this, "percent-rate")
37-
38-let refKey = "keeper"
39-
40-let puzzleRewardAssetStr = getStringOrThrow(this, "puzzle-reward-token")
41-
42-let puzzleRewardAssetId = getAssetId(puzzleRewardAssetStr)
43-
44-let pPools = split(getStringOrThrow(this, "p-pools"), ",")
45-
46-func assetIdToString (assetId) = match assetId {
47- case asset: ByteVector =>
48- toBase58String(asset)
49- case waves: Unit =>
50- "WAVES"
20+let feePriorityAssetId = match getString(this, "Fee_priorityAsset") {
21+ case priorityAssetStr: String =>
22+ fromBase58String(priorityAssetStr)
5123 case _ =>
52- throw("Match error")
24+ throw("WAVES cannot be a priority asset")
5325 }
5426
27+let feePriorityMinReceived = valueOrElse(getInteger(this, "Fee_priorityMinReceived"), 0)
5528
56-func getBalance (assetId) = match assetId {
57- case asset: ByteVector =>
58- assetBalance(this, asset)
59- case waves: Unit =>
60- wavesBalance(this).available
29+let feeManager = match getString(this, "Fee_managerPublicKey") {
30+ case maybeFeeManager: String =>
31+ fromBase58String(maybeFeeManager)
6132 case _ =>
62- throw("Match error")
33+ unit
6334 }
6435
36+let swapFeeLimit = getInteger(this, "Fee_swapFeeLimit")
6537
66-func getBalanceByAddress (address,assetId) = match assetId {
67- case asset: ByteVector =>
68- assetBalance(address, asset)
69- case waves: Unit =>
70- wavesBalance(address).available
71- case _ =>
72- throw("Match error")
73-}
38+let feeAssetSwapInterval = valueOrElse(getInteger(this, "Fee_assetSwapInterval"), 0)
39+
40+func getLastFeeSwapTimestamp (assetId) = valueOrElse(getInteger(this, key_lastFeeSwapTimestamp(toBase58String(assetId))), 0)
7441
7542
76-func deductFee (amount) = {
77- let fee = fraction(amount, 1, feeRate)
78- $Tuple2((amount - fee), fee)
79- }
80-
81-
82-func getReferrerDataOrThrow (referrerName) = if ((size(referrerName) == 0))
83- then $Tuple2(collector, 0)
84- else {
85- let refAddress = parseAddressOrThrow(valueOrErrorMessage(getString(this, (("referrer-" + referrerName) + "-address")), (("referrer with name " + referrerName) + " not found")))
86- let refPercent = valueOrElse(getInteger(this, (("referrer-" + referrerName) + "-percent")), percentRate)
87- if (if ((0 > refPercent))
88- then true
89- else (refPercent > 100))
90- then throw("Incorrect percent rate")
91- else $Tuple2(refAddress, refPercent)
92- }
93-
94-
95-func getSwapOptions (options) = {
96- func foldArguments (acc,index) = if ((index >= size(options)))
97- then (acc :+ "")
98- else (acc :+ options[index])
99-
100- let indices = [0, 1]
101- let arguments = {
102- let $l = indices
103- let $s = size($l)
104- let $acc0 = nil
105- func $f0_1 ($a,$i) = if (($i >= $s))
106- then $a
107- else foldArguments($a, $l[$i])
108-
109- func $f0_2 ($a,$i) = if (($i >= $s))
110- then $a
111- else throw("List size exceeds 2")
112-
113- $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
114- }
115- let deadline = parseIntOrDefault(arguments[0], 0)
116- let referrerName = arguments[1]
117- $Tuple2(deadline, referrerName)
118- }
119-
120-
121-func validateBlockTimestamp (deadline) = if (if ((deadline > 0))
122- then (lastBlock.timestamp > deadline)
123- else false)
124- then throw(((("This swap expired at timestamp " + toString(deadline)) + ". Current: ") + toString(lastBlock.timestamp)))
125- else true
126-
127-
128-func doSwap (pool,payment,assetReceived,estAmountToReceive,slippageTolerance) = {
129- let poolAddress = parseAddressOrThrow(pool)
130- let versionMajor = parseIntOrThrow(split(getStringOrThrow(poolAddress, "version"), ".")[0])
131- let assetReceivedId = getAssetId(assetReceived)
132- if ((0 > estAmountToReceive))
133- then throw("estAmountToReceive must be positive")
134- else if (containsElement(pools, pool))
135- then {
136- let poolAssetA = getStringOrThrow(poolAddress, "A_asset_id")
137- let poolAssetB = getStringOrThrow(poolAddress, "B_asset_id")
138- let poolAssetIdA = getAssetId(poolAssetA)
139- let poolAssetIdB = getAssetId(poolAssetB)
140- let $t042974641 = if (if ((payment.assetId == poolAssetIdA))
141- then (assetReceivedId == poolAssetIdB)
142- else false)
143- then $Tuple2(poolAssetIdA, poolAssetIdB)
144- else if (if ((assetReceivedId == poolAssetIdA))
145- then (payment.assetId == poolAssetIdB)
146- else false)
147- then $Tuple2(poolAssetIdB, poolAssetIdA)
148- else throw("Unsupported assets pair")
149- let assetIn = $t042974641._1
150- let assetOut = $t042974641._2
151- let args = if ((versionMajor == 1))
152- then [1]
153- else if ((versionMajor == 2))
154- then if ((0 >= estAmountToReceive))
155- then throw("estAmountToReceive must be positive")
156- else {
157- let minAmount = (estAmountToReceive - fraction(estAmountToReceive, slippageTolerance, 1000))
158-[estAmountToReceive, if ((minAmount > 0))
159- then minAmount
160- else 1]
161- }
162- else throw((("Unknown pool version '" + toString(versionMajor)) + "', but 1 or 2 expected"))
163- let balanceBefore = getBalance(assetReceivedId)
164- if ((balanceBefore == balanceBefore))
165- then {
166- let result = invoke(poolAddress, "exchange", args, [payment])
167- if ((result == result))
168- then {
169- let received = (getBalance(assetReceivedId) - balanceBefore)
170- if ((received == received))
171- then if ((0 >= received))
172- then throw("Received amount from pool must be positive")
173- else received
174- else throw("Strict value is not equal to itself.")
175- }
176- else throw("Strict value is not equal to itself.")
177- }
178- else throw("Strict value is not equal to itself.")
179- }
180- else if (containsElement(pPools, pool))
181- then {
182- let balanceBefore = getBalance(assetReceivedId)
183- if ((balanceBefore == balanceBefore))
184- then {
185- let result = invoke(poolAddress, "swap", [assetReceived, 0], [payment])
186- if ((result == result))
187- then {
188- let received = (getBalance(assetReceivedId) - balanceBefore)
189- if ((received == received))
190- then if ((0 >= received))
191- then throw("Received amount from pool must be positive")
192- else received
193- else throw("Strict value is not equal to itself.")
194- }
195- else throw("Strict value is not equal to itself.")
196- }
197- else throw("Strict value is not equal to itself.")
198- }
199- else throw((("There is no pool at address '" + pool) + "'"))
200- }
201-
202-
203-func swapSingleRoute (inv,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived) = {
204- let pmt = if ((size(inv.payments) > 0))
205- then inv.payments[0]
206- else throw("Payment required")
207- func foldSwap (previousReceived,index) = if ((index >= size(addresses)))
208- then previousReceived
209- else {
210- let assetReceived = assetsToReceive[index]
211- let assetReceivedId = getAssetId(assetReceived)
212- match doSwap(addresses[index], previousReceived, assetReceived, estReceived[index], slippageTolerance) {
213- case income: Int =>
214- AttachedPayment(assetReceivedId, income)
215- case _ =>
216- throw("Can't handle swap result")
217- }
218- }
219-
220- let received = if ((size(addresses) > 0))
221- then {
222- let $l = [0, 1, 2, 3, 4]
223- let $s = size($l)
224- let $acc0 = pmt
225- func $f0_1 ($a,$i) = if (($i >= $s))
226- then $a
227- else foldSwap($a, $l[$i])
228-
229- func $f0_2 ($a,$i) = if (($i >= $s))
230- then $a
231- else throw("List size exceeds 5")
232-
233- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
234- }
235- else throw("Path cannot be empty")
236- if ((0 >= received.amount))
237- then throw((("Swap result " + toString(received.amount)) + " must be positive"))
238- else received
239- }
240-
241-
242-func swapMultipleRoutes (inv,amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived) = {
243- let pmt = if ((size(inv.payments) > 0))
244- then inv.payments[0]
245- else throw("Payment required")
246- func foldSplit (splitResults,index) = if ((index >= size(addresses)))
247- then splitResults
248- else {
249- let splitInv = Invocation([AttachedPayment(pmt.assetId, amountsIn[index])], inv.caller, inv.callerPublicKey, inv.transactionId, inv.fee, inv.feeAssetId, inv.originCaller, inv.originCallerPublicKey)
250- let splitAddresses = split(addresses[index], "_")
251- let splitAssets = split(assetsToReceive[index], "_")
252- func mapIntOrThrow (result,maybeInt) = (result :+ parseIntOrThrow(maybeInt))
253-
254- let splitEstReceived = {
255- let $l = split(estReceived[index], "_")
256- let $s = size($l)
257- let $acc0 = nil
258- func $f0_1 ($a,$i) = if (($i >= $s))
259- then $a
260- else mapIntOrThrow($a, $l[$i])
261-
262- func $f0_2 ($a,$i) = if (($i >= $s))
263- then $a
264- else throw("List size exceeds 5")
265-
266- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
267- }
268- let result = swapSingleRoute(splitInv, splitAddresses, splitAssets, splitEstReceived, slippageTolerance, minReceived)
269- if ((result == result))
270- then (splitResults :+ result)
271- else throw("Strict value is not equal to itself.")
272- }
273-
274- let $l = [0, 1, 2]
275- let $s = size($l)
276- let $acc0 = nil
277- func $f0_1 ($a,$i) = if (($i >= $s))
278- then $a
279- else foldSplit($a, $l[$i])
280-
281- func $f0_2 ($a,$i) = if (($i >= $s))
282- then $a
283- else throw("List size exceeds 3")
284-
285- $f0_2($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3)
286- }
287-
288-
289-func wrapSwopfiSwap (inv,exchangers,exchangersType,args1,args2,routingAssetsKeys,minAmountToReceive) = {
290- let pmt = if ((size(inv.payments) > 0))
291- then inv.payments[0]
292- else throw("Payment required")
293- let lastExchanger = valueOrErrorMessage(addressFromString(exchangers[(size(exchangers) - 1)]), "Can't parse last exchanger swopfi address")
294- let lastAssetIdKey = (split(routingAssetsKeys[(size(routingAssetsKeys) - 1)], "_")[0] + "_asset_id")
295- let assetFinal = valueOrErrorMessage(getString(lastExchanger, lastAssetIdKey), ((("Can't read parameter '" + lastAssetIdKey) + "' for exchanger ") + toString(lastExchanger)))
296- let assetFinalId = getAssetId(assetFinal)
297- let balanceBefore = getBalance(assetFinalId)
298- if ((balanceBefore == balanceBefore))
299- then {
300- let result = invoke(swopfiRouting, "routingTrade", [exchangers, exchangersType, args1, args2, routingAssetsKeys, minAmountToReceive], [pmt])
301- if ((result == result))
302- then {
303- let balanceAfter = getBalance(assetFinalId)
304- if ((balanceAfter == balanceAfter))
305- then {
306- let delta = (balanceAfter - balanceBefore)
307- let $t01020310248 = deductFee(delta)
308- let resultAfterFee = $t01020310248._1
309- let fee = $t01020310248._2
310- if ((0 >= delta))
311- then throw((("Swap result " + toString(delta)) + " must be positive"))
312- else if ((minAmountToReceive > resultAfterFee))
313- then throw(((("Swap result " + toString(resultAfterFee)) + " is less then expected ") + toString(minAmountToReceive)))
314- else [ScriptTransfer(inv.caller, resultAfterFee, assetFinalId), ScriptTransfer(collector, fee, assetFinalId)]
315- }
316- else throw("Strict value is not equal to itself.")
317- }
318- else throw("Strict value is not equal to itself.")
319- }
320- else throw("Strict value is not equal to itself.")
321- }
322-
323-
324-func wrapPuzzleSwap (inv,routesStr,minToReceive) = {
325- let pmt = if ((size(inv.payments) > 0))
326- then inv.payments[0]
327- else throw("Payment required")
328- let assetIdFinal = split(routesStr, ",")[(size(split(routesStr, ",")) - 1)]
329- let assetId = getAssetId(assetIdFinal)
330- let balanceBefore = getBalance(assetId)
331- if ((balanceBefore == balanceBefore))
332- then {
333- let result = invoke(puzzleRouting, "swapWithReferral", [routesStr, minToReceive, refKey], [pmt])
334- if ((result == result))
335- then {
336- let balanceAfter = getBalance(assetId)
337- if ((balanceAfter == balanceAfter))
338- then {
339- let deltaProxy = (balanceAfter - balanceBefore)
340- if ((deltaProxy == deltaProxy))
341- then [ScriptTransfer(inv.caller, deltaProxy, assetId)]
342- else throw("Strict value is not equal to itself.")
343- }
344- else throw("Strict value is not equal to itself.")
345- }
346- else throw("Strict value is not equal to itself.")
347- }
348- else throw("Strict value is not equal to itself.")
349- }
43+func setLastFeeSwapTimestamp (assetId,timestamp) = [IntegerEntry(key_lastFeeSwapTimestamp(toBase58String(assetId)), timestamp)]
35044
35145
35246 @Callable(inv)
353-func swap (amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived,options) = {
354- let pmt = if ((size(inv.payments) > 0))
355- then inv.payments[0]
356- else throw("Payment required")
357- let $t01160311657 = getSwapOptions(options)
358- let deadline = $t01160311657._1
359- let referrerName = $t01160311657._2
360- let isValidTimestamp = validateBlockTimestamp(deadline)
361- if ((isValidTimestamp == isValidTimestamp))
362- then {
363- let $t01172511805 = getReferrerDataOrThrow(referrerName)
364- if (($t01172511805 == $t01172511805))
365- then {
366- let referrerPercent = $t01172511805._2
367- let referrerAddress = $t01172511805._1
368- let validAddresses = if (if ((0 > size(addresses)))
369- then true
370- else (size(addresses) > 3))
371- then throw("Supported swap of 1 to 3 splits")
372- else addresses
373- let validSlippageTolerance = if (if ((0 > slippageTolerance))
374- then true
375- else (slippageTolerance > 1000))
376- then throw("Slippage tolerance must be non-negative and less than or equal to 1000")
377- else slippageTolerance
378- func sumIn (accum,next) = (accum + next)
379-
380- let totalAmountIn = {
381- let $l = amountsIn
382- let $s = size($l)
383- let $acc0 = 0
384- func $f0_1 ($a,$i) = if (($i >= $s))
385- then $a
386- else sumIn($a, $l[$i])
387-
388- func $f0_2 ($a,$i) = if (($i >= $s))
389- then $a
390- else throw("List size exceeds 3")
391-
392- $f0_2($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3)
393- }
394- let amountsOut = if ((pmt.amount != totalAmountIn))
395- then throw(((("Total amount after split " + toString(totalAmountIn)) + " is not equal original payment amount ") + toString(pmt.amount)))
396- else swapMultipleRoutes(inv, amountsIn, validAddresses, assetsToReceive, estReceived, validSlippageTolerance, minReceived)
397- if ((amountsOut == amountsOut))
398- then {
399- func sumOut (total,next) = (total + next.amount)
400-
401- let totalAmountOut = {
402- let $l = amountsOut
403- let $s = size($l)
404- let $acc0 = 0
405- func $f1_1 ($a,$i) = if (($i >= $s))
406- then $a
407- else sumOut($a, $l[$i])
408-
409- func $f1_2 ($a,$i) = if (($i >= $s))
410- then $a
411- else throw("List size exceeds 3")
412-
413- $f1_2($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3)
414- }
415- let assetId = amountsOut[0].assetId
416- let $t01303213086 = deductFee(totalAmountOut)
417- let amountMinusFee = $t01303213086._1
418- let fee = $t01303213086._2
419- let referrerReward = fraction(fee, referrerPercent, 100)
420- let collectorReward = (fee - referrerReward)
421- let transfers = [ScriptTransfer(inv.caller, amountMinusFee, assetId), ScriptTransfer(collector, collectorReward, assetId)]
422- if ((referrerReward == 0))
423- then transfers
424- else (transfers :+ ScriptTransfer(referrerAddress, referrerReward, assetId))
425- }
426- else throw("Strict value is not equal to itself.")
427- }
428- else throw("Strict value is not equal to itself.")
429- }
430- else throw("Strict value is not equal to itself.")
47+func claimReferrerReward (amount,assetId) = {
48+ let asset = getAssetId(assetId)
49+ if ((proxyAddress != inv.caller))
50+ then throw("only self calls or by collector are allowed")
51+ else if ((0 >= amount))
52+ then throw("Incorrect reward amount")
53+ else [ScriptTransfer(proxyAddress, amount, asset)]
43154 }
43255
43356
43457
43558 @Callable(inv)
436-func swopfiSwap (exchangers,exchangersType,args1,args2,routingAssetsKeys,minAmountToReceive,options) = {
437- let $t01372813782 = getSwapOptions(options)
438- let deadline = $t01372813782._1
439- let referrerName = $t01372813782._2
440- let isValidTimestamp = validateBlockTimestamp(deadline)
441- if ((isValidTimestamp == isValidTimestamp))
442- then {
443- let $t01385013930 = getReferrerDataOrThrow(referrerName)
444- if (($t01385013930 == $t01385013930))
445- then {
446- let referrerPercent = $t01385013930._2
447- let referrerAddress = $t01385013930._1
448- let result = wrapSwopfiSwap(inv, exchangers, exchangersType, args1, args2, routingAssetsKeys, minAmountToReceive)
449- if ((result == result))
450- then if ((referrerPercent > 0))
59+func PRIVATE_swap (amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived,options) = {
60+ let pmt = if ((size(inv.payments) != 1))
61+ then throw("Single payment required")
62+ else if (if (!(isDefined(inv.payments[0].assetId)))
63+ then true
64+ else (inv.payments[0].assetId == feePriorityAssetId))
65+ then throw("Unable to swap WAVES or priority asset")
66+ else inv.payments[0]
67+ let pmtAssetId = value(pmt.assetId)
68+ if ((inv.caller != this))
69+ then throw("Only self calls are allowed")
70+ else if (isDefined(inv.feeAssetId))
71+ then throw("Only WAVES allowed for feeAssetId")
72+ else if (if (isDefined(swapFeeLimit))
73+ then (inv.fee > value(swapFeeLimit))
74+ else false)
75+ then throw((("Maximum fee (" + toString(value(swapFeeLimit))) + ") is exceeded"))
76+ else if ((feeAssetSwapInterval > (lastBlock.timestamp - getLastFeeSwapTimestamp(pmtAssetId))))
77+ then throw((("Swap is only possible once every " + toString((feeAssetSwapInterval / 3600000))) + " hours"))
78+ else {
79+ let balanceBefore = assetBalance(this, feePriorityAssetId)
80+ if ((balanceBefore == balanceBefore))
45181 then {
452- let lastExchanger = valueOrErrorMessage(addressFromString(exchangers[(size(exchangers) - 1)]), "Can't parse last exchanger swopfi address")
453- let lastAssetIdKey = (split(routingAssetsKeys[(size(routingAssetsKeys) - 1)], "_")[0] + "_asset_id")
454- let assetFinal = valueOrErrorMessage(getString(lastExchanger, lastAssetIdKey), ((("Can't read parameter '" + lastAssetIdKey) + "' for exchanger ") + toString(lastExchanger)))
455- let assetId = getAssetId(assetFinal)
456- let collectorFee = result[1].amount
457- let referrerReward = fraction(collectorFee, referrerPercent, 100)
458-[result[0], ScriptTransfer(collector, (collectorFee - referrerReward), assetId), ScriptTransfer(referrerAddress, referrerReward, assetId)]
459- }
460- else result
461- else throw("Strict value is not equal to itself.")
462- }
463- else throw("Strict value is not equal to itself.")
464- }
465- else throw("Strict value is not equal to itself.")
466- }
467-
468-
469-
470-@Callable(inv)
471-func puzzleSwap (routesStr,minToReceive,options) = {
472- let $t01500015054 = getSwapOptions(options)
473- let deadline = $t01500015054._1
474- let referrerName = $t01500015054._2
475- let isValidTimestamp = validateBlockTimestamp(deadline)
476- if ((isValidTimestamp == isValidTimestamp))
477- then {
478- let $t01512215202 = getReferrerDataOrThrow(referrerName)
479- if (($t01512215202 == $t01512215202))
480- then {
481- let referrerPercent = $t01512215202._2
482- let referrerAddress = $t01512215202._1
483- if ((size(routesStr) == 0))
484- then throw("Invalid routing")
485- else if ((0 >= minToReceive))
486- then throw("Sum to receive is to low")
487- else {
488- let balanceBefore = getBalanceByAddress(collector, puzzleRewardAssetId)
489- if ((balanceBefore == balanceBefore))
82+ let swap = invoke(proxyAddress, "swap", [amountsIn, addresses, assetsToReceive, estReceived, slippageTolerance, minReceived, options], [pmt])
83+ if ((swap == swap))
49084 then {
491- let result = wrapPuzzleSwap(inv, routesStr, minToReceive)
492- if ((result == result))
493- then if ((referrerPercent > 0))
494- then {
495- let assetIdFinal = split(routesStr, ",")[(size(split(routesStr, ",")) - 1)]
496- let assetId = getAssetId(assetIdFinal)
497- let balanceAfter = getBalanceByAddress(collector, puzzleRewardAssetId)
498- if ((balanceAfter == balanceAfter))
499- then {
500- let delta = (balanceAfter - balanceBefore)
501- if ((delta == delta))
502- then {
503- let reward = fraction(delta, referrerPercent, 100)
504- let res = invoke(collector, "claimReferrerReward", [reward, puzzleRewardAssetStr], nil)
505- if ((res == res))
506- then (result :+ ScriptTransfer(referrerAddress, reward, puzzleRewardAssetId))
507- else throw("Strict value is not equal to itself.")
508- }
509- else throw("Strict value is not equal to itself.")
510- }
511- else throw("Strict value is not equal to itself.")
512- }
513- else result
85+ let balanceAfter = assetBalance(this, feePriorityAssetId)
86+ if ((balanceAfter == balanceAfter))
87+ then {
88+ let received = (balanceAfter - balanceBefore)
89+ if ((0 >= received))
90+ then throw("Swap is only allowed to the priority asset")
91+ else if ((feePriorityMinReceived > received))
92+ then throw(("Swap result is less than " + toString(feePriorityMinReceived)))
93+ else setLastFeeSwapTimestamp(pmtAssetId, lastBlock.timestamp)
94+ }
51495 else throw("Strict value is not equal to itself.")
51596 }
51697 else throw("Strict value is not equal to itself.")
51798 }
518- }
519- else throw("Strict value is not equal to itself.")
520- }
521- else throw("Strict value is not equal to itself.")
99+ else throw("Strict value is not equal to itself.")
100+ }
522101 }
523102
524103
104+@Verifier(tx)
105+func verify () = {
106+ let maybeOracle = addressFromString(valueOrElse(getString(this, "Oracle"), ""))
107+ let maybeAdminKeys = if (isDefined(maybeOracle))
108+ then getString(value(maybeOracle), "AdminKeys")
109+ else unit
110+ let isFeeSwapInvoke = match tx {
111+ case tx: InvokeScriptTransaction =>
112+ if ((tx.dApp == this))
113+ then (tx.function == "PRIVATE_swap")
114+ else false
115+ case _ =>
116+ false
117+ }
118+ if (if (isDefined(feeManager))
119+ then isFeeSwapInvoke
120+ else false)
121+ then sigVerify(tx.bodyBytes, tx.proofs[0], value(feeManager))
122+ else match maybeAdminKeys {
123+ case adminKeysStr: String =>
124+ let adminKeys = {
125+ let stringKeys = split(adminKeysStr, ",")
126+[fromBase58String(stringKeys[0]), fromBase58String(stringKeys[1]), fromBase58String(stringKeys[2])]
127+ }
128+ func verifyByAllKeys (proof) = if (sigVerify(tx.bodyBytes, proof, adminKeys[0]))
129+ then 1
130+ else if (sigVerify(tx.bodyBytes, proof, adminKeys[1]))
131+ then 10
132+ else if (sigVerify(tx.bodyBytes, proof, adminKeys[2]))
133+ then 100
134+ else 0
525135
526-@Callable(inv)
527-func addPools (poolAddresses) = {
528- func addIfDoesNotExist (pools,pool) = if (containsElement(pools, pool))
529- then throw((("Pool '" + pool) + "' is already added"))
530- else (pools :+ toString(parseAddressOrThrow(pool)))
531-
532- if (!(containsElement([this, collector], inv.caller)))
533- then throw("only self calls or by collector are allowed")
534- else [StringEntry("p-pools", makeString({
535- let $l = poolAddresses
536- let $s = size($l)
537- let $acc0 = pPools
538- func $f0_1 ($a,$i) = if (($i >= $s))
539- then $a
540- else addIfDoesNotExist($a, $l[$i])
541-
542- func $f0_2 ($a,$i) = if (($i >= $s))
543- then $a
544- else throw("List size exceeds 10")
545-
546- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
547- }, ","))]
136+ containsElement([110, 101, 11], (verifyByAllKeys(tx.proofs[0]) + verifyByAllKeys(tx.proofs[1])))
137+ case _ =>
138+ sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
139+ }
548140 }
549-
550-
551-
552-@Callable(inv)
553-func addReferrer (referrerName,refererAddress,percent) = {
554- let address = parseAddressOrThrow(refererAddress)
555- if (if ((0 > percent))
556- then true
557- else (percent > 100))
558- then throw("Incorrect percent rate")
559- else if ((size(referrerName) == 0))
560- then throw("Referrer name invalid")
561- else if (!(containsElement([this, collector], inv.caller)))
562- then throw("only self calls or by collector are allowed")
563- else [StringEntry((("referrer-" + referrerName) + "-address"), refererAddress), IntegerEntry((("referrer-" + referrerName) + "-percent"), percent)]
564- }
565-
566141
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func getStringOrThrow (address,key) = valueOrErrorMessage(getString(address, key), ((("Can't read '" + key) + "' at address ") + toString(address)))
55
66
7-func getIntegerOrThrow (address,key) = valueOrErrorMessage(getInteger(address, key), ((("Can't read '" + key) + "' at address ") + toString(address)))
8-
9-
107 func parseAddressOrThrow (maybeAddress) = valueOrErrorMessage(addressFromString(maybeAddress), (("Can't parse address from '" + maybeAddress) + "'"))
118
129
13-func parseIntOrDefault (maybeInt,default) = valueOrElse(parseInt(maybeInt), default)
10+func key_lastFeeSwapTimestamp (assetId) = (("Fee_" + assetId) + "_lastSwapTimestamp")
1411
1512
16-func parseIntOrThrow (maybeInt) = valueOrErrorMessage(parseInt(maybeInt), (("Can't parse integer from '" + maybeInt) + "'"))
17-
13+let proxyAddress = parseAddressOrThrow(getStringOrThrow(this, "proxy-address"))
1814
1915 func getAssetId (asset) = if ((asset == "WAVES"))
2016 then unit
21- else fromBase58String(asset)
17+ else valueOrErrorMessage(assetInfo(fromBase58String(asset)), ("Can't find asset " + asset)).id
2218
2319
24-let collector = parseAddressOrThrow(getStringOrThrow(this, "collector"))
25-
26-let feeRate = getIntegerOrThrow(this, "fee-rate")
27-
28-let oracle = parseAddressOrThrow(getStringOrThrow(this, "oracle"))
29-
30-let swopfiRouting = parseAddressOrThrow(getStringOrThrow(this, "swopfi-routing"))
31-
32-let puzzleRouting = parseAddressOrThrow(getStringOrThrow(this, "puzzle-routing"))
33-
34-let pools = split(getStringOrThrow(oracle, "pools"), ",")
35-
36-let percentRate = getIntegerOrThrow(this, "percent-rate")
37-
38-let refKey = "keeper"
39-
40-let puzzleRewardAssetStr = getStringOrThrow(this, "puzzle-reward-token")
41-
42-let puzzleRewardAssetId = getAssetId(puzzleRewardAssetStr)
43-
44-let pPools = split(getStringOrThrow(this, "p-pools"), ",")
45-
46-func assetIdToString (assetId) = match assetId {
47- case asset: ByteVector =>
48- toBase58String(asset)
49- case waves: Unit =>
50- "WAVES"
20+let feePriorityAssetId = match getString(this, "Fee_priorityAsset") {
21+ case priorityAssetStr: String =>
22+ fromBase58String(priorityAssetStr)
5123 case _ =>
52- throw("Match error")
24+ throw("WAVES cannot be a priority asset")
5325 }
5426
27+let feePriorityMinReceived = valueOrElse(getInteger(this, "Fee_priorityMinReceived"), 0)
5528
56-func getBalance (assetId) = match assetId {
57- case asset: ByteVector =>
58- assetBalance(this, asset)
59- case waves: Unit =>
60- wavesBalance(this).available
29+let feeManager = match getString(this, "Fee_managerPublicKey") {
30+ case maybeFeeManager: String =>
31+ fromBase58String(maybeFeeManager)
6132 case _ =>
62- throw("Match error")
33+ unit
6334 }
6435
36+let swapFeeLimit = getInteger(this, "Fee_swapFeeLimit")
6537
66-func getBalanceByAddress (address,assetId) = match assetId {
67- case asset: ByteVector =>
68- assetBalance(address, asset)
69- case waves: Unit =>
70- wavesBalance(address).available
71- case _ =>
72- throw("Match error")
73-}
38+let feeAssetSwapInterval = valueOrElse(getInteger(this, "Fee_assetSwapInterval"), 0)
39+
40+func getLastFeeSwapTimestamp (assetId) = valueOrElse(getInteger(this, key_lastFeeSwapTimestamp(toBase58String(assetId))), 0)
7441
7542
76-func deductFee (amount) = {
77- let fee = fraction(amount, 1, feeRate)
78- $Tuple2((amount - fee), fee)
79- }
80-
81-
82-func getReferrerDataOrThrow (referrerName) = if ((size(referrerName) == 0))
83- then $Tuple2(collector, 0)
84- else {
85- let refAddress = parseAddressOrThrow(valueOrErrorMessage(getString(this, (("referrer-" + referrerName) + "-address")), (("referrer with name " + referrerName) + " not found")))
86- let refPercent = valueOrElse(getInteger(this, (("referrer-" + referrerName) + "-percent")), percentRate)
87- if (if ((0 > refPercent))
88- then true
89- else (refPercent > 100))
90- then throw("Incorrect percent rate")
91- else $Tuple2(refAddress, refPercent)
92- }
93-
94-
95-func getSwapOptions (options) = {
96- func foldArguments (acc,index) = if ((index >= size(options)))
97- then (acc :+ "")
98- else (acc :+ options[index])
99-
100- let indices = [0, 1]
101- let arguments = {
102- let $l = indices
103- let $s = size($l)
104- let $acc0 = nil
105- func $f0_1 ($a,$i) = if (($i >= $s))
106- then $a
107- else foldArguments($a, $l[$i])
108-
109- func $f0_2 ($a,$i) = if (($i >= $s))
110- then $a
111- else throw("List size exceeds 2")
112-
113- $f0_2($f0_1($f0_1($acc0, 0), 1), 2)
114- }
115- let deadline = parseIntOrDefault(arguments[0], 0)
116- let referrerName = arguments[1]
117- $Tuple2(deadline, referrerName)
118- }
119-
120-
121-func validateBlockTimestamp (deadline) = if (if ((deadline > 0))
122- then (lastBlock.timestamp > deadline)
123- else false)
124- then throw(((("This swap expired at timestamp " + toString(deadline)) + ". Current: ") + toString(lastBlock.timestamp)))
125- else true
126-
127-
128-func doSwap (pool,payment,assetReceived,estAmountToReceive,slippageTolerance) = {
129- let poolAddress = parseAddressOrThrow(pool)
130- let versionMajor = parseIntOrThrow(split(getStringOrThrow(poolAddress, "version"), ".")[0])
131- let assetReceivedId = getAssetId(assetReceived)
132- if ((0 > estAmountToReceive))
133- then throw("estAmountToReceive must be positive")
134- else if (containsElement(pools, pool))
135- then {
136- let poolAssetA = getStringOrThrow(poolAddress, "A_asset_id")
137- let poolAssetB = getStringOrThrow(poolAddress, "B_asset_id")
138- let poolAssetIdA = getAssetId(poolAssetA)
139- let poolAssetIdB = getAssetId(poolAssetB)
140- let $t042974641 = if (if ((payment.assetId == poolAssetIdA))
141- then (assetReceivedId == poolAssetIdB)
142- else false)
143- then $Tuple2(poolAssetIdA, poolAssetIdB)
144- else if (if ((assetReceivedId == poolAssetIdA))
145- then (payment.assetId == poolAssetIdB)
146- else false)
147- then $Tuple2(poolAssetIdB, poolAssetIdA)
148- else throw("Unsupported assets pair")
149- let assetIn = $t042974641._1
150- let assetOut = $t042974641._2
151- let args = if ((versionMajor == 1))
152- then [1]
153- else if ((versionMajor == 2))
154- then if ((0 >= estAmountToReceive))
155- then throw("estAmountToReceive must be positive")
156- else {
157- let minAmount = (estAmountToReceive - fraction(estAmountToReceive, slippageTolerance, 1000))
158-[estAmountToReceive, if ((minAmount > 0))
159- then minAmount
160- else 1]
161- }
162- else throw((("Unknown pool version '" + toString(versionMajor)) + "', but 1 or 2 expected"))
163- let balanceBefore = getBalance(assetReceivedId)
164- if ((balanceBefore == balanceBefore))
165- then {
166- let result = invoke(poolAddress, "exchange", args, [payment])
167- if ((result == result))
168- then {
169- let received = (getBalance(assetReceivedId) - balanceBefore)
170- if ((received == received))
171- then if ((0 >= received))
172- then throw("Received amount from pool must be positive")
173- else received
174- else throw("Strict value is not equal to itself.")
175- }
176- else throw("Strict value is not equal to itself.")
177- }
178- else throw("Strict value is not equal to itself.")
179- }
180- else if (containsElement(pPools, pool))
181- then {
182- let balanceBefore = getBalance(assetReceivedId)
183- if ((balanceBefore == balanceBefore))
184- then {
185- let result = invoke(poolAddress, "swap", [assetReceived, 0], [payment])
186- if ((result == result))
187- then {
188- let received = (getBalance(assetReceivedId) - balanceBefore)
189- if ((received == received))
190- then if ((0 >= received))
191- then throw("Received amount from pool must be positive")
192- else received
193- else throw("Strict value is not equal to itself.")
194- }
195- else throw("Strict value is not equal to itself.")
196- }
197- else throw("Strict value is not equal to itself.")
198- }
199- else throw((("There is no pool at address '" + pool) + "'"))
200- }
201-
202-
203-func swapSingleRoute (inv,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived) = {
204- let pmt = if ((size(inv.payments) > 0))
205- then inv.payments[0]
206- else throw("Payment required")
207- func foldSwap (previousReceived,index) = if ((index >= size(addresses)))
208- then previousReceived
209- else {
210- let assetReceived = assetsToReceive[index]
211- let assetReceivedId = getAssetId(assetReceived)
212- match doSwap(addresses[index], previousReceived, assetReceived, estReceived[index], slippageTolerance) {
213- case income: Int =>
214- AttachedPayment(assetReceivedId, income)
215- case _ =>
216- throw("Can't handle swap result")
217- }
218- }
219-
220- let received = if ((size(addresses) > 0))
221- then {
222- let $l = [0, 1, 2, 3, 4]
223- let $s = size($l)
224- let $acc0 = pmt
225- func $f0_1 ($a,$i) = if (($i >= $s))
226- then $a
227- else foldSwap($a, $l[$i])
228-
229- func $f0_2 ($a,$i) = if (($i >= $s))
230- then $a
231- else throw("List size exceeds 5")
232-
233- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
234- }
235- else throw("Path cannot be empty")
236- if ((0 >= received.amount))
237- then throw((("Swap result " + toString(received.amount)) + " must be positive"))
238- else received
239- }
240-
241-
242-func swapMultipleRoutes (inv,amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived) = {
243- let pmt = if ((size(inv.payments) > 0))
244- then inv.payments[0]
245- else throw("Payment required")
246- func foldSplit (splitResults,index) = if ((index >= size(addresses)))
247- then splitResults
248- else {
249- let splitInv = Invocation([AttachedPayment(pmt.assetId, amountsIn[index])], inv.caller, inv.callerPublicKey, inv.transactionId, inv.fee, inv.feeAssetId, inv.originCaller, inv.originCallerPublicKey)
250- let splitAddresses = split(addresses[index], "_")
251- let splitAssets = split(assetsToReceive[index], "_")
252- func mapIntOrThrow (result,maybeInt) = (result :+ parseIntOrThrow(maybeInt))
253-
254- let splitEstReceived = {
255- let $l = split(estReceived[index], "_")
256- let $s = size($l)
257- let $acc0 = nil
258- func $f0_1 ($a,$i) = if (($i >= $s))
259- then $a
260- else mapIntOrThrow($a, $l[$i])
261-
262- func $f0_2 ($a,$i) = if (($i >= $s))
263- then $a
264- else throw("List size exceeds 5")
265-
266- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
267- }
268- let result = swapSingleRoute(splitInv, splitAddresses, splitAssets, splitEstReceived, slippageTolerance, minReceived)
269- if ((result == result))
270- then (splitResults :+ result)
271- else throw("Strict value is not equal to itself.")
272- }
273-
274- let $l = [0, 1, 2]
275- let $s = size($l)
276- let $acc0 = nil
277- func $f0_1 ($a,$i) = if (($i >= $s))
278- then $a
279- else foldSplit($a, $l[$i])
280-
281- func $f0_2 ($a,$i) = if (($i >= $s))
282- then $a
283- else throw("List size exceeds 3")
284-
285- $f0_2($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3)
286- }
287-
288-
289-func wrapSwopfiSwap (inv,exchangers,exchangersType,args1,args2,routingAssetsKeys,minAmountToReceive) = {
290- let pmt = if ((size(inv.payments) > 0))
291- then inv.payments[0]
292- else throw("Payment required")
293- let lastExchanger = valueOrErrorMessage(addressFromString(exchangers[(size(exchangers) - 1)]), "Can't parse last exchanger swopfi address")
294- let lastAssetIdKey = (split(routingAssetsKeys[(size(routingAssetsKeys) - 1)], "_")[0] + "_asset_id")
295- let assetFinal = valueOrErrorMessage(getString(lastExchanger, lastAssetIdKey), ((("Can't read parameter '" + lastAssetIdKey) + "' for exchanger ") + toString(lastExchanger)))
296- let assetFinalId = getAssetId(assetFinal)
297- let balanceBefore = getBalance(assetFinalId)
298- if ((balanceBefore == balanceBefore))
299- then {
300- let result = invoke(swopfiRouting, "routingTrade", [exchangers, exchangersType, args1, args2, routingAssetsKeys, minAmountToReceive], [pmt])
301- if ((result == result))
302- then {
303- let balanceAfter = getBalance(assetFinalId)
304- if ((balanceAfter == balanceAfter))
305- then {
306- let delta = (balanceAfter - balanceBefore)
307- let $t01020310248 = deductFee(delta)
308- let resultAfterFee = $t01020310248._1
309- let fee = $t01020310248._2
310- if ((0 >= delta))
311- then throw((("Swap result " + toString(delta)) + " must be positive"))
312- else if ((minAmountToReceive > resultAfterFee))
313- then throw(((("Swap result " + toString(resultAfterFee)) + " is less then expected ") + toString(minAmountToReceive)))
314- else [ScriptTransfer(inv.caller, resultAfterFee, assetFinalId), ScriptTransfer(collector, fee, assetFinalId)]
315- }
316- else throw("Strict value is not equal to itself.")
317- }
318- else throw("Strict value is not equal to itself.")
319- }
320- else throw("Strict value is not equal to itself.")
321- }
322-
323-
324-func wrapPuzzleSwap (inv,routesStr,minToReceive) = {
325- let pmt = if ((size(inv.payments) > 0))
326- then inv.payments[0]
327- else throw("Payment required")
328- let assetIdFinal = split(routesStr, ",")[(size(split(routesStr, ",")) - 1)]
329- let assetId = getAssetId(assetIdFinal)
330- let balanceBefore = getBalance(assetId)
331- if ((balanceBefore == balanceBefore))
332- then {
333- let result = invoke(puzzleRouting, "swapWithReferral", [routesStr, minToReceive, refKey], [pmt])
334- if ((result == result))
335- then {
336- let balanceAfter = getBalance(assetId)
337- if ((balanceAfter == balanceAfter))
338- then {
339- let deltaProxy = (balanceAfter - balanceBefore)
340- if ((deltaProxy == deltaProxy))
341- then [ScriptTransfer(inv.caller, deltaProxy, assetId)]
342- else throw("Strict value is not equal to itself.")
343- }
344- else throw("Strict value is not equal to itself.")
345- }
346- else throw("Strict value is not equal to itself.")
347- }
348- else throw("Strict value is not equal to itself.")
349- }
43+func setLastFeeSwapTimestamp (assetId,timestamp) = [IntegerEntry(key_lastFeeSwapTimestamp(toBase58String(assetId)), timestamp)]
35044
35145
35246 @Callable(inv)
353-func swap (amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived,options) = {
354- let pmt = if ((size(inv.payments) > 0))
355- then inv.payments[0]
356- else throw("Payment required")
357- let $t01160311657 = getSwapOptions(options)
358- let deadline = $t01160311657._1
359- let referrerName = $t01160311657._2
360- let isValidTimestamp = validateBlockTimestamp(deadline)
361- if ((isValidTimestamp == isValidTimestamp))
362- then {
363- let $t01172511805 = getReferrerDataOrThrow(referrerName)
364- if (($t01172511805 == $t01172511805))
365- then {
366- let referrerPercent = $t01172511805._2
367- let referrerAddress = $t01172511805._1
368- let validAddresses = if (if ((0 > size(addresses)))
369- then true
370- else (size(addresses) > 3))
371- then throw("Supported swap of 1 to 3 splits")
372- else addresses
373- let validSlippageTolerance = if (if ((0 > slippageTolerance))
374- then true
375- else (slippageTolerance > 1000))
376- then throw("Slippage tolerance must be non-negative and less than or equal to 1000")
377- else slippageTolerance
378- func sumIn (accum,next) = (accum + next)
379-
380- let totalAmountIn = {
381- let $l = amountsIn
382- let $s = size($l)
383- let $acc0 = 0
384- func $f0_1 ($a,$i) = if (($i >= $s))
385- then $a
386- else sumIn($a, $l[$i])
387-
388- func $f0_2 ($a,$i) = if (($i >= $s))
389- then $a
390- else throw("List size exceeds 3")
391-
392- $f0_2($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3)
393- }
394- let amountsOut = if ((pmt.amount != totalAmountIn))
395- then throw(((("Total amount after split " + toString(totalAmountIn)) + " is not equal original payment amount ") + toString(pmt.amount)))
396- else swapMultipleRoutes(inv, amountsIn, validAddresses, assetsToReceive, estReceived, validSlippageTolerance, minReceived)
397- if ((amountsOut == amountsOut))
398- then {
399- func sumOut (total,next) = (total + next.amount)
400-
401- let totalAmountOut = {
402- let $l = amountsOut
403- let $s = size($l)
404- let $acc0 = 0
405- func $f1_1 ($a,$i) = if (($i >= $s))
406- then $a
407- else sumOut($a, $l[$i])
408-
409- func $f1_2 ($a,$i) = if (($i >= $s))
410- then $a
411- else throw("List size exceeds 3")
412-
413- $f1_2($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3)
414- }
415- let assetId = amountsOut[0].assetId
416- let $t01303213086 = deductFee(totalAmountOut)
417- let amountMinusFee = $t01303213086._1
418- let fee = $t01303213086._2
419- let referrerReward = fraction(fee, referrerPercent, 100)
420- let collectorReward = (fee - referrerReward)
421- let transfers = [ScriptTransfer(inv.caller, amountMinusFee, assetId), ScriptTransfer(collector, collectorReward, assetId)]
422- if ((referrerReward == 0))
423- then transfers
424- else (transfers :+ ScriptTransfer(referrerAddress, referrerReward, assetId))
425- }
426- else throw("Strict value is not equal to itself.")
427- }
428- else throw("Strict value is not equal to itself.")
429- }
430- else throw("Strict value is not equal to itself.")
47+func claimReferrerReward (amount,assetId) = {
48+ let asset = getAssetId(assetId)
49+ if ((proxyAddress != inv.caller))
50+ then throw("only self calls or by collector are allowed")
51+ else if ((0 >= amount))
52+ then throw("Incorrect reward amount")
53+ else [ScriptTransfer(proxyAddress, amount, asset)]
43154 }
43255
43356
43457
43558 @Callable(inv)
436-func swopfiSwap (exchangers,exchangersType,args1,args2,routingAssetsKeys,minAmountToReceive,options) = {
437- let $t01372813782 = getSwapOptions(options)
438- let deadline = $t01372813782._1
439- let referrerName = $t01372813782._2
440- let isValidTimestamp = validateBlockTimestamp(deadline)
441- if ((isValidTimestamp == isValidTimestamp))
442- then {
443- let $t01385013930 = getReferrerDataOrThrow(referrerName)
444- if (($t01385013930 == $t01385013930))
445- then {
446- let referrerPercent = $t01385013930._2
447- let referrerAddress = $t01385013930._1
448- let result = wrapSwopfiSwap(inv, exchangers, exchangersType, args1, args2, routingAssetsKeys, minAmountToReceive)
449- if ((result == result))
450- then if ((referrerPercent > 0))
59+func PRIVATE_swap (amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived,options) = {
60+ let pmt = if ((size(inv.payments) != 1))
61+ then throw("Single payment required")
62+ else if (if (!(isDefined(inv.payments[0].assetId)))
63+ then true
64+ else (inv.payments[0].assetId == feePriorityAssetId))
65+ then throw("Unable to swap WAVES or priority asset")
66+ else inv.payments[0]
67+ let pmtAssetId = value(pmt.assetId)
68+ if ((inv.caller != this))
69+ then throw("Only self calls are allowed")
70+ else if (isDefined(inv.feeAssetId))
71+ then throw("Only WAVES allowed for feeAssetId")
72+ else if (if (isDefined(swapFeeLimit))
73+ then (inv.fee > value(swapFeeLimit))
74+ else false)
75+ then throw((("Maximum fee (" + toString(value(swapFeeLimit))) + ") is exceeded"))
76+ else if ((feeAssetSwapInterval > (lastBlock.timestamp - getLastFeeSwapTimestamp(pmtAssetId))))
77+ then throw((("Swap is only possible once every " + toString((feeAssetSwapInterval / 3600000))) + " hours"))
78+ else {
79+ let balanceBefore = assetBalance(this, feePriorityAssetId)
80+ if ((balanceBefore == balanceBefore))
45181 then {
452- let lastExchanger = valueOrErrorMessage(addressFromString(exchangers[(size(exchangers) - 1)]), "Can't parse last exchanger swopfi address")
453- let lastAssetIdKey = (split(routingAssetsKeys[(size(routingAssetsKeys) - 1)], "_")[0] + "_asset_id")
454- let assetFinal = valueOrErrorMessage(getString(lastExchanger, lastAssetIdKey), ((("Can't read parameter '" + lastAssetIdKey) + "' for exchanger ") + toString(lastExchanger)))
455- let assetId = getAssetId(assetFinal)
456- let collectorFee = result[1].amount
457- let referrerReward = fraction(collectorFee, referrerPercent, 100)
458-[result[0], ScriptTransfer(collector, (collectorFee - referrerReward), assetId), ScriptTransfer(referrerAddress, referrerReward, assetId)]
459- }
460- else result
461- else throw("Strict value is not equal to itself.")
462- }
463- else throw("Strict value is not equal to itself.")
464- }
465- else throw("Strict value is not equal to itself.")
466- }
467-
468-
469-
470-@Callable(inv)
471-func puzzleSwap (routesStr,minToReceive,options) = {
472- let $t01500015054 = getSwapOptions(options)
473- let deadline = $t01500015054._1
474- let referrerName = $t01500015054._2
475- let isValidTimestamp = validateBlockTimestamp(deadline)
476- if ((isValidTimestamp == isValidTimestamp))
477- then {
478- let $t01512215202 = getReferrerDataOrThrow(referrerName)
479- if (($t01512215202 == $t01512215202))
480- then {
481- let referrerPercent = $t01512215202._2
482- let referrerAddress = $t01512215202._1
483- if ((size(routesStr) == 0))
484- then throw("Invalid routing")
485- else if ((0 >= minToReceive))
486- then throw("Sum to receive is to low")
487- else {
488- let balanceBefore = getBalanceByAddress(collector, puzzleRewardAssetId)
489- if ((balanceBefore == balanceBefore))
82+ let swap = invoke(proxyAddress, "swap", [amountsIn, addresses, assetsToReceive, estReceived, slippageTolerance, minReceived, options], [pmt])
83+ if ((swap == swap))
49084 then {
491- let result = wrapPuzzleSwap(inv, routesStr, minToReceive)
492- if ((result == result))
493- then if ((referrerPercent > 0))
494- then {
495- let assetIdFinal = split(routesStr, ",")[(size(split(routesStr, ",")) - 1)]
496- let assetId = getAssetId(assetIdFinal)
497- let balanceAfter = getBalanceByAddress(collector, puzzleRewardAssetId)
498- if ((balanceAfter == balanceAfter))
499- then {
500- let delta = (balanceAfter - balanceBefore)
501- if ((delta == delta))
502- then {
503- let reward = fraction(delta, referrerPercent, 100)
504- let res = invoke(collector, "claimReferrerReward", [reward, puzzleRewardAssetStr], nil)
505- if ((res == res))
506- then (result :+ ScriptTransfer(referrerAddress, reward, puzzleRewardAssetId))
507- else throw("Strict value is not equal to itself.")
508- }
509- else throw("Strict value is not equal to itself.")
510- }
511- else throw("Strict value is not equal to itself.")
512- }
513- else result
85+ let balanceAfter = assetBalance(this, feePriorityAssetId)
86+ if ((balanceAfter == balanceAfter))
87+ then {
88+ let received = (balanceAfter - balanceBefore)
89+ if ((0 >= received))
90+ then throw("Swap is only allowed to the priority asset")
91+ else if ((feePriorityMinReceived > received))
92+ then throw(("Swap result is less than " + toString(feePriorityMinReceived)))
93+ else setLastFeeSwapTimestamp(pmtAssetId, lastBlock.timestamp)
94+ }
51495 else throw("Strict value is not equal to itself.")
51596 }
51697 else throw("Strict value is not equal to itself.")
51798 }
518- }
519- else throw("Strict value is not equal to itself.")
520- }
521- else throw("Strict value is not equal to itself.")
99+ else throw("Strict value is not equal to itself.")
100+ }
522101 }
523102
524103
104+@Verifier(tx)
105+func verify () = {
106+ let maybeOracle = addressFromString(valueOrElse(getString(this, "Oracle"), ""))
107+ let maybeAdminKeys = if (isDefined(maybeOracle))
108+ then getString(value(maybeOracle), "AdminKeys")
109+ else unit
110+ let isFeeSwapInvoke = match tx {
111+ case tx: InvokeScriptTransaction =>
112+ if ((tx.dApp == this))
113+ then (tx.function == "PRIVATE_swap")
114+ else false
115+ case _ =>
116+ false
117+ }
118+ if (if (isDefined(feeManager))
119+ then isFeeSwapInvoke
120+ else false)
121+ then sigVerify(tx.bodyBytes, tx.proofs[0], value(feeManager))
122+ else match maybeAdminKeys {
123+ case adminKeysStr: String =>
124+ let adminKeys = {
125+ let stringKeys = split(adminKeysStr, ",")
126+[fromBase58String(stringKeys[0]), fromBase58String(stringKeys[1]), fromBase58String(stringKeys[2])]
127+ }
128+ func verifyByAllKeys (proof) = if (sigVerify(tx.bodyBytes, proof, adminKeys[0]))
129+ then 1
130+ else if (sigVerify(tx.bodyBytes, proof, adminKeys[1]))
131+ then 10
132+ else if (sigVerify(tx.bodyBytes, proof, adminKeys[2]))
133+ then 100
134+ else 0
525135
526-@Callable(inv)
527-func addPools (poolAddresses) = {
528- func addIfDoesNotExist (pools,pool) = if (containsElement(pools, pool))
529- then throw((("Pool '" + pool) + "' is already added"))
530- else (pools :+ toString(parseAddressOrThrow(pool)))
531-
532- if (!(containsElement([this, collector], inv.caller)))
533- then throw("only self calls or by collector are allowed")
534- else [StringEntry("p-pools", makeString({
535- let $l = poolAddresses
536- let $s = size($l)
537- let $acc0 = pPools
538- func $f0_1 ($a,$i) = if (($i >= $s))
539- then $a
540- else addIfDoesNotExist($a, $l[$i])
541-
542- func $f0_2 ($a,$i) = if (($i >= $s))
543- then $a
544- else throw("List size exceeds 10")
545-
546- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10)
547- }, ","))]
136+ containsElement([110, 101, 11], (verifyByAllKeys(tx.proofs[0]) + verifyByAllKeys(tx.proofs[1])))
137+ case _ =>
138+ sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
139+ }
548140 }
549-
550-
551-
552-@Callable(inv)
553-func addReferrer (referrerName,refererAddress,percent) = {
554- let address = parseAddressOrThrow(refererAddress)
555- if (if ((0 > percent))
556- then true
557- else (percent > 100))
558- then throw("Incorrect percent rate")
559- else if ((size(referrerName) == 0))
560- then throw("Referrer name invalid")
561- else if (!(containsElement([this, collector], inv.caller)))
562- then throw("only self calls or by collector are allowed")
563- else [StringEntry((("referrer-" + referrerName) + "-address"), refererAddress), IntegerEntry((("referrer-" + referrerName) + "-percent"), percent)]
564- }
565-
566141

github/deemru/w8io/3ef1775 
60.96 ms