2023.04.18 12:39 [3605379] smart account 3PNgw6Db2TGUQbjnV7ekve6q126xBC1e7eM > SELF 0.00000000 Waves
{ "type": 13, "id": "ESaNpPaG5AfzNky8nxZGoKHrskcSM8n31px5ndSczeuw", "fee": 900000, "feeAssetId": null, "timestamp": 1681810582571, "version": 2, "chainId": 87, "sender": "3PNgw6Db2TGUQbjnV7ekve6q126xBC1e7eM", "senderPublicKey": "ERDjJaWKWwVUSyXxLyG38P3wMqKt2Eutwy5q6iJj1uhP", "proofs": [ "2M82rqtFQNdzkPKkvZ8zVhXaWoVF7ns5j3e3mMiyLVi55J2E4yrvHrhkQ21Zbh5wSfq1me4ZwwsAQvrjNTiP2mjs", "4h7LQ2eypB65tDc9ZiFX87qzxq4e3jVLmPPQiP82oQcrMfgMhDwWt8i1CP5ENobkisxr2VrHWEXRHubQFk1tWxHm" ], "script": "base64:BgIVCAISBAoCAQgSCwoJERgYGAEBGAEIDwEQZ2V0U3RyaW5nT3JUaHJvdwIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJAKwCAgkArAICCQCsAgICDENhbid0IHJlYWQgJwUDa2V5Ag0nIGF0IGFkZHJlc3MgCQClCAEFB2FkZHJlc3MBE3BhcnNlQWRkcmVzc09yVGhyb3cBDG1heWJlQWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEFDG1heWJlQWRkcmVzcwkArAICCQCsAgICGkNhbid0IHBhcnNlIGFkZHJlc3MgZnJvbSAnBQxtYXliZUFkZHJlc3MCAScBGGtleV9sYXN0RmVlU3dhcFRpbWVzdGFtcAEHYXNzZXRJZAkArAICCQCsAgICBEZlZV8FB2Fzc2V0SWQCEl9sYXN0U3dhcFRpbWVzdGFtcAAMcHJveHlBZGRyZXNzCQETcGFyc2VBZGRyZXNzT3JUaHJvdwEJARBnZXRTdHJpbmdPclRocm93AgUEdGhpcwINcHJveHktYWRkcmVzcwEKZ2V0QXNzZXRJZAEFYXNzZXQDCQAAAgUFYXNzZXQCBVdBVkVTBQR1bml0CAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEJANkEAQUFYXNzZXQJAKwCAgIRQ2FuJ3QgZmluZCBhc3NldCAFBWFzc2V0AmlkAQ9nZXRBc3NldEJhbGFuY2UBB2Fzc2V0SWQEByRtYXRjaDAFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCaWQFByRtYXRjaDAJAPAHAgUEdGhpcwUCaWQICQDvBwEFBHRoaXMJYXZhaWxhYmxlABJmZWVQcmlvcml0eUFzc2V0SWQJAQpnZXRBc3NldElkAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMCEUZlZV9wcmlvcml0eUFzc2V0Ah1GZWUgcHJpb3JpdHkgYXNzZXQgaXMgbm90IHNldAATZmVlRXhjbHVkZWRBc3NldElkcwkAzQgCBAckbWF0Y2gwCQCdCAIFBHRoaXMCEkZlZV9leGNsdWRlZEFzc2V0cwMJAAECBQckbWF0Y2gwAgZTdHJpbmcEC2V4Y2x1ZGVkU3RyBQckbWF0Y2gwCgEGYXBwZW5kAgNhY2MLbmV4dEFzc2V0SWQJAM0IAgUDYWNjCQEKZ2V0QXNzZXRJZAEFC25leHRBc3NldElkCgACJGwJALwJAgULZXhjbHVkZWRTdHICASwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBmFwcGVuZAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgUDbmlsBRJmZWVQcmlvcml0eUFzc2V0SWQAFmZlZVByaW9yaXR5TWluUmVjZWl2ZWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwIXRmVlX3ByaW9yaXR5TWluUmVjZWl2ZWQAAAAKZmVlTWFuYWdlcgQHJG1hdGNoMAkAnQgCBQR0aGlzAhRGZWVfbWFuYWdlclB1YmxpY0tleQMJAAECBQckbWF0Y2gwAgZTdHJpbmcED21heWJlRmVlTWFuYWdlcgUHJG1hdGNoMAkA2QQBBQ9tYXliZUZlZU1hbmFnZXIFBHVuaXQACnR4RmVlTGltaXQJAJoIAgUEdGhpcwIORmVlX3R4RmVlTGltaXQAD2ZlZVN3YXBJbnRlcnZhbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzAhBGZWVfc3dhcEludGVydmFsAAABFGdldFByaW9yaXR5QXNzZXRJbmZvAAMJAQEhAQkBCWlzRGVmaW5lZAEFEmZlZVByaW9yaXR5QXNzZXRJZAkAlgoEAgVXQVZFUwIFV0FWRVMAgMLXLwUWZmVlUHJpb3JpdHlNaW5SZWNlaXZlZAQHJG1hdGNoMAkA7AcBCQEFdmFsdWUBBRJmZWVQcmlvcml0eUFzc2V0SWQDCQABAgUHJG1hdGNoMAIFQXNzZXQEEGZlZVByaW9yaXR5QXNzZXQFByRtYXRjaDAJAJYKBAkA2AQBCAUQZmVlUHJpb3JpdHlBc3NldAJpZAgFEGZlZVByaW9yaXR5QXNzZXQEbmFtZQkAbAYACgAACAUQZmVlUHJpb3JpdHlBc3NldAhkZWNpbWFscwAAAAAFBERPV04FFmZlZVByaW9yaXR5TWluUmVjZWl2ZWQJAAIBAhRVbmV4cGVjdGVkIGJlaGF2aW91cgEXZ2V0TGFzdEZlZVN3YXBUaW1lc3RhbXABB2Fzc2V0SWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBGGtleV9sYXN0RmVlU3dhcFRpbWVzdGFtcAEJANgEAQkBC3ZhbHVlT3JFbHNlAgUHYXNzZXRJZAEEE6vZMwAAARdzZXRMYXN0RmVlU3dhcFRpbWVzdGFtcAIHYXNzZXRJZAl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJARhrZXlfbGFzdEZlZVN3YXBUaW1lc3RhbXABCQDYBAEJAQt2YWx1ZU9yRWxzZQIFB2Fzc2V0SWQBBBOr2TMFCXRpbWVzdGFtcAUDbmlsAgNpbnYBE2NsYWltUmVmZXJyZXJSZXdhcmQCBmFtb3VudAdhc3NldElkBAVhc3NldAkBCmdldEFzc2V0SWQBBQdhc3NldElkAwkBAiE9AgUMcHJveHlBZGRyZXNzCAUDaW52BmNhbGxlcgkAAgECK29ubHkgc2VsZiBjYWxscyBvciBieSBjb2xsZWN0b3IgYXJlIGFsbG93ZWQDCQBnAgAABQZhbW91bnQJAAIBAhdJbmNvcnJlY3QgcmV3YXJkIGFtb3VudAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQxwcm94eUFkZHJlc3MFBmFtb3VudAUFYXNzZXQFA25pbANpbnYBDFBSSVZBVEVfc3dhcAkJYW1vdW50c0luCWFkZHJlc3Nlcw9hc3NldHNUb1JlY2VpdmULZXN0UmVjZWl2ZWQRc2xpcHBhZ2VUb2xlcmFuY2ULbWluUmVjZWl2ZWQHb3B0aW9ucwlwbXRBbW91bnQLcG10QXNzZXRTdHIECnBtdEFzc2V0SWQJAQpnZXRBc3NldElkAQULcG10QXNzZXRTdHIEA3BtdAMJAQ9jb250YWluc0VsZW1lbnQCBRNmZWVFeGNsdWRlZEFzc2V0SWRzBQpwbXRBc3NldElkCQACAQkArAICCQCsAgICB0Fzc2V0IGAFC3BtdEFzc2V0U3RyAh9gIGlzIGV4Y2x1ZGVkIGZyb20gUFJJVkFURV9zd2FwAwkAZwIAAAUJcG10QW1vdW50CQACAQIfUGF5bWVudCBhbW91bnQgbXVzdCBiZSBwb3NpdGl2ZQkBD0F0dGFjaGVkUGF5bWVudAIFCnBtdEFzc2V0SWQFCXBtdEFtb3VudAMJAQIhPQIIBQNpbnYGY2FsbGVyBQR0aGlzCQACAQIbT25seSBzZWxmIGNhbGxzIGFyZSBhbGxvd2VkAwkBCWlzRGVmaW5lZAEIBQNpbnYKZmVlQXNzZXRJZAkAAgECIU9ubHkgV0FWRVMgYWxsb3dlZCBmb3IgZmVlQXNzZXRJZAMDCQEJaXNEZWZpbmVkAQUKdHhGZWVMaW1pdAkAZgIIBQNpbnYDZmVlCQEFdmFsdWUBBQp0eEZlZUxpbWl0BwkAAgEJAKwCAgkArAICAg1NYXhpbXVtIGZlZSAoCQCkAwEJAQV2YWx1ZQEFCnR4RmVlTGltaXQCDSkgaXMgZXhjZWVkZWQDCQBmAgUPZmVlU3dhcEludGVydmFsCQBlAggFCWxhc3RCbG9jawl0aW1lc3RhbXAJARdnZXRMYXN0RmVlU3dhcFRpbWVzdGFtcAEFCnBtdEFzc2V0SWQJAAIBCQCsAgIJAKwCAgIhU3dhcCBpcyBvbmx5IHBvc3NpYmxlIG9uY2UgZXZlcnkgCQCkAwEJAGkCBQ9mZWVTd2FwSW50ZXJ2YWwAgN3bAQIGIGhvdXJzBA1iYWxhbmNlQmVmb3JlCQEPZ2V0QXNzZXRCYWxhbmNlAQUSZmVlUHJpb3JpdHlBc3NldElkAwkAAAIFDWJhbGFuY2VCZWZvcmUFDWJhbGFuY2VCZWZvcmUEBHN3YXAJAPwHBAUMcHJveHlBZGRyZXNzAgRzd2FwCQDMCAIFCWFtb3VudHNJbgkAzAgCBQlhZGRyZXNzZXMJAMwIAgUPYXNzZXRzVG9SZWNlaXZlCQDMCAIFC2VzdFJlY2VpdmVkCQDMCAIFEXNsaXBwYWdlVG9sZXJhbmNlCQDMCAIFC21pblJlY2VpdmVkCQDMCAIFB29wdGlvbnMFA25pbAkAzAgCBQNwbXQFA25pbAMJAAACBQRzd2FwBQRzd2FwBAxiYWxhbmNlQWZ0ZXIJAQ9nZXRBc3NldEJhbGFuY2UBBRJmZWVQcmlvcml0eUFzc2V0SWQDCQAAAgUMYmFsYW5jZUFmdGVyBQxiYWxhbmNlQWZ0ZXIECHJlY2VpdmVkCQBlAgUMYmFsYW5jZUFmdGVyBQ1iYWxhbmNlQmVmb3JlAwkAZwIAAAUIcmVjZWl2ZWQJAAIBAipTd2FwIGlzIG9ubHkgYWxsb3dlZCB0byB0aGUgcHJpb3JpdHkgYXNzZXQDCQBmAgUWZmVlUHJpb3JpdHlNaW5SZWNlaXZlZAUIcmVjZWl2ZWQJAAIBCQCsAgICGVN3YXAgcmVzdWx0IGlzIGxlc3MgdGhhbiAJAKQDAQUWZmVlUHJpb3JpdHlNaW5SZWNlaXZlZAkBF3NldExhc3RGZWVTd2FwVGltZXN0YW1wAgUKcG10QXNzZXRJZAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAnR4AQZ2ZXJpZnkABAttYXliZU9yYWNsZQkApggBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMCBk9yYWNsZQIABA5tYXliZUFkbWluS2V5cwMJAQlpc0RlZmluZWQBBQttYXliZU9yYWNsZQkAnQgCCQEFdmFsdWUBBQttYXliZU9yYWNsZQIJQWRtaW5LZXlzBQR1bml0BA9pc0ZlZVN3YXBJbnZva2UEByRtYXRjaDAFAnR4AwkAAQIFByRtYXRjaDACF0ludm9rZVNjcmlwdFRyYW5zYWN0aW9uBAJ0eAUHJG1hdGNoMAMJAAACCAUCdHgEZEFwcAUEdGhpcwkAAAIIBQJ0eAhmdW5jdGlvbgIMUFJJVkFURV9zd2FwBwcDAwkBCWlzRGVmaW5lZAEFCmZlZU1hbmFnZXIFD2lzRmVlU3dhcEludm9rZQcJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAJAQV2YWx1ZQEFCmZlZU1hbmFnZXIEByRtYXRjaDAFDm1heWJlQWRtaW5LZXlzAwkAAQIFByRtYXRjaDACBlN0cmluZwQMYWRtaW5LZXlzU3RyBQckbWF0Y2gwBAlhZG1pbktleXMECnN0cmluZ0tleXMJALUJAgUMYWRtaW5LZXlzU3RyAgEsCQDMCAIJANkEAQkAkQMCBQpzdHJpbmdLZXlzAAAJAMwIAgkA2QQBCQCRAwIFCnN0cmluZ0tleXMAAQkAzAgCCQDZBAEJAJEDAgUKc3RyaW5nS2V5cwACBQNuaWwKAQ92ZXJpZnlCeUFsbEtleXMBBXByb29mAwkA9AMDCAUCdHgJYm9keUJ5dGVzBQVwcm9vZgkAkQMCBQlhZG1pbktleXMAAAABAwkA9AMDCAUCdHgJYm9keUJ5dGVzBQVwcm9vZgkAkQMCBQlhZG1pbktleXMAAQAKAwkA9AMDCAUCdHgJYm9keUJ5dGVzBQVwcm9vZgkAkQMCBQlhZG1pbktleXMAAgBkAAAJAQ9jb250YWluc0VsZW1lbnQCCQDMCAIAbgkAzAgCAGUJAMwIAgALBQNuaWwJAGQCCQEPdmVyaWZ5QnlBbGxLZXlzAQkAkQMCCAUCdHgGcHJvb2ZzAAAJAQ92ZXJpZnlCeUFsbEtleXMBCQCRAwIIBQJ0eAZwcm9vZnMAAQkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAgFAnR4D3NlbmRlclB1YmxpY0tled3qmAk=", "height": 3605379, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 47o22YuaJEETcXtfASAC7HiBpfcPxP1iKbhV5g6Z4ZPS Next: FdctyhtzZfeybU3znkeo7u9aAxgDpQqWjdBSwGtY7s5z Diff:
Old | New | Differences | |
---|---|---|---|
1 | - | {-# STDLIB_VERSION | |
1 | + | {-# STDLIB_VERSION 6 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | func getStringOrThrow (address,key) = valueOrErrorMessage(getString(address, key), ((("Can't read '" + key) + "' at address ") + toString(address))) | |
17 | 17 | else valueOrErrorMessage(assetInfo(fromBase58String(asset)), ("Can't find asset " + asset)).id | |
18 | 18 | ||
19 | 19 | ||
20 | - | ||
21 | - | case | |
22 | - | | |
20 | + | func getAssetBalance (assetId) = match assetId { | |
21 | + | case id: ByteVector => | |
22 | + | assetBalance(this, id) | |
23 | 23 | case _ => | |
24 | - | | |
24 | + | wavesBalance(this).available | |
25 | 25 | } | |
26 | + | ||
27 | + | ||
28 | + | let feePriorityAssetId = getAssetId(valueOrErrorMessage(getString(this, "Fee_priorityAsset"), "Fee priority asset is not set")) | |
29 | + | ||
30 | + | let feeExcludedAssetIds = (match getString(this, "Fee_excludedAssets") { | |
31 | + | case excludedStr: String => | |
32 | + | func append (acc,nextAssetId) = (acc :+ getAssetId(nextAssetId)) | |
33 | + | ||
34 | + | let $l = split_4C(excludedStr, ",") | |
35 | + | let $s = size($l) | |
36 | + | let $acc0 = nil | |
37 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
38 | + | then $a | |
39 | + | else append($a, $l[$i]) | |
40 | + | ||
41 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
42 | + | then $a | |
43 | + | else throw("List size exceeds 10") | |
44 | + | ||
45 | + | $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) | |
46 | + | case _ => | |
47 | + | nil | |
48 | + | } :+ feePriorityAssetId) | |
26 | 49 | ||
27 | 50 | let feePriorityMinReceived = valueOrElse(getInteger(this, "Fee_priorityMinReceived"), 0) | |
28 | 51 | ||
37 | 60 | ||
38 | 61 | let feeSwapInterval = valueOrElse(getInteger(this, "Fee_swapInterval"), 0) | |
39 | 62 | ||
40 | - | func getPriorityAssetInfo () = match assetInfo(feePriorityAssetId) { | |
41 | - | case feePriorityAsset: Asset => | |
42 | - | $Tuple4(toBase58String(feePriorityAsset.id), feePriorityAsset.name, pow(10, 0, feePriorityAsset.decimals, 0, 0, DOWN), feePriorityMinReceived) | |
43 | - | case _ => | |
44 | - | throw("Unexpected behaviour") | |
45 | - | } | |
63 | + | func getPriorityAssetInfo () = if (!(isDefined(feePriorityAssetId))) | |
64 | + | then $Tuple4("WAVES", "WAVES", 100000000, feePriorityMinReceived) | |
65 | + | else match assetInfo(value(feePriorityAssetId)) { | |
66 | + | case feePriorityAsset: Asset => | |
67 | + | $Tuple4(toBase58String(feePriorityAsset.id), feePriorityAsset.name, pow(10, 0, feePriorityAsset.decimals, 0, 0, DOWN), feePriorityMinReceived) | |
68 | + | case _ => | |
69 | + | throw("Unexpected behaviour") | |
70 | + | } | |
46 | 71 | ||
47 | 72 | ||
48 | - | func getLastFeeSwapTimestamp (assetId) = valueOrElse(getInteger(this, key_lastFeeSwapTimestamp(toBase58String(assetId))), 0) | |
73 | + | func getLastFeeSwapTimestamp (assetId) = valueOrElse(getInteger(this, key_lastFeeSwapTimestamp(toBase58String(valueOrElse(assetId, base58'WAVES')))), 0) | |
49 | 74 | ||
50 | 75 | ||
51 | - | func setLastFeeSwapTimestamp (assetId,timestamp) = [IntegerEntry(key_lastFeeSwapTimestamp(toBase58String(assetId)), timestamp)] | |
76 | + | func setLastFeeSwapTimestamp (assetId,timestamp) = [IntegerEntry(key_lastFeeSwapTimestamp(toBase58String(valueOrElse(assetId, base58'WAVES'))), timestamp)] | |
52 | 77 | ||
53 | 78 | ||
54 | 79 | @Callable(inv) | |
65 | 90 | ||
66 | 91 | @Callable(inv) | |
67 | 92 | func PRIVATE_swap (amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived,options,pmtAmount,pmtAssetStr) = { | |
68 | - | let pmtAssetId = fromBase58String(pmtAssetStr) | |
69 | - | let pmt = if (if ((pmtAssetStr == "WAVES")) | |
70 | - | then true | |
71 | - | else (pmtAssetId == feePriorityAssetId)) | |
72 | - | then throw("Unable to swap WAVES or priority asset") | |
93 | + | let pmtAssetId = getAssetId(pmtAssetStr) | |
94 | + | let pmt = if (containsElement(feeExcludedAssetIds, pmtAssetId)) | |
95 | + | then throw((("Asset `" + pmtAssetStr) + "` is excluded from PRIVATE_swap")) | |
73 | 96 | else if ((0 >= pmtAmount)) | |
74 | 97 | then throw("Payment amount must be positive") | |
75 | 98 | else AttachedPayment(pmtAssetId, pmtAmount) | |
84 | 107 | else if ((feeSwapInterval > (lastBlock.timestamp - getLastFeeSwapTimestamp(pmtAssetId)))) | |
85 | 108 | then throw((("Swap is only possible once every " + toString((feeSwapInterval / 3600000))) + " hours")) | |
86 | 109 | else { | |
87 | - | let balanceBefore = | |
110 | + | let balanceBefore = getAssetBalance(feePriorityAssetId) | |
88 | 111 | if ((balanceBefore == balanceBefore)) | |
89 | 112 | then { | |
90 | 113 | let swap = invoke(proxyAddress, "swap", [amountsIn, addresses, assetsToReceive, estReceived, slippageTolerance, minReceived, options], [pmt]) | |
91 | 114 | if ((swap == swap)) | |
92 | 115 | then { | |
93 | - | let balanceAfter = | |
116 | + | let balanceAfter = getAssetBalance(feePriorityAssetId) | |
94 | 117 | if ((balanceAfter == balanceAfter)) | |
95 | 118 | then { | |
96 | 119 | let received = (balanceAfter - balanceBefore) |
Old | New | Differences | |
---|---|---|---|
1 | - | {-# STDLIB_VERSION | |
1 | + | {-# STDLIB_VERSION 6 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | func getStringOrThrow (address,key) = valueOrErrorMessage(getString(address, key), ((("Can't read '" + key) + "' at address ") + toString(address))) | |
5 | 5 | ||
6 | 6 | ||
7 | 7 | func parseAddressOrThrow (maybeAddress) = valueOrErrorMessage(addressFromString(maybeAddress), (("Can't parse address from '" + maybeAddress) + "'")) | |
8 | 8 | ||
9 | 9 | ||
10 | 10 | func key_lastFeeSwapTimestamp (assetId) = (("Fee_" + assetId) + "_lastSwapTimestamp") | |
11 | 11 | ||
12 | 12 | ||
13 | 13 | let proxyAddress = parseAddressOrThrow(getStringOrThrow(this, "proxy-address")) | |
14 | 14 | ||
15 | 15 | func getAssetId (asset) = if ((asset == "WAVES")) | |
16 | 16 | then unit | |
17 | 17 | else valueOrErrorMessage(assetInfo(fromBase58String(asset)), ("Can't find asset " + asset)).id | |
18 | 18 | ||
19 | 19 | ||
20 | - | ||
21 | - | case | |
22 | - | | |
20 | + | func getAssetBalance (assetId) = match assetId { | |
21 | + | case id: ByteVector => | |
22 | + | assetBalance(this, id) | |
23 | 23 | case _ => | |
24 | - | | |
24 | + | wavesBalance(this).available | |
25 | 25 | } | |
26 | + | ||
27 | + | ||
28 | + | let feePriorityAssetId = getAssetId(valueOrErrorMessage(getString(this, "Fee_priorityAsset"), "Fee priority asset is not set")) | |
29 | + | ||
30 | + | let feeExcludedAssetIds = (match getString(this, "Fee_excludedAssets") { | |
31 | + | case excludedStr: String => | |
32 | + | func append (acc,nextAssetId) = (acc :+ getAssetId(nextAssetId)) | |
33 | + | ||
34 | + | let $l = split_4C(excludedStr, ",") | |
35 | + | let $s = size($l) | |
36 | + | let $acc0 = nil | |
37 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
38 | + | then $a | |
39 | + | else append($a, $l[$i]) | |
40 | + | ||
41 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
42 | + | then $a | |
43 | + | else throw("List size exceeds 10") | |
44 | + | ||
45 | + | $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) | |
46 | + | case _ => | |
47 | + | nil | |
48 | + | } :+ feePriorityAssetId) | |
26 | 49 | ||
27 | 50 | let feePriorityMinReceived = valueOrElse(getInteger(this, "Fee_priorityMinReceived"), 0) | |
28 | 51 | ||
29 | 52 | let feeManager = match getString(this, "Fee_managerPublicKey") { | |
30 | 53 | case maybeFeeManager: String => | |
31 | 54 | fromBase58String(maybeFeeManager) | |
32 | 55 | case _ => | |
33 | 56 | unit | |
34 | 57 | } | |
35 | 58 | ||
36 | 59 | let txFeeLimit = getInteger(this, "Fee_txFeeLimit") | |
37 | 60 | ||
38 | 61 | let feeSwapInterval = valueOrElse(getInteger(this, "Fee_swapInterval"), 0) | |
39 | 62 | ||
40 | - | func getPriorityAssetInfo () = match assetInfo(feePriorityAssetId) { | |
41 | - | case feePriorityAsset: Asset => | |
42 | - | $Tuple4(toBase58String(feePriorityAsset.id), feePriorityAsset.name, pow(10, 0, feePriorityAsset.decimals, 0, 0, DOWN), feePriorityMinReceived) | |
43 | - | case _ => | |
44 | - | throw("Unexpected behaviour") | |
45 | - | } | |
63 | + | func getPriorityAssetInfo () = if (!(isDefined(feePriorityAssetId))) | |
64 | + | then $Tuple4("WAVES", "WAVES", 100000000, feePriorityMinReceived) | |
65 | + | else match assetInfo(value(feePriorityAssetId)) { | |
66 | + | case feePriorityAsset: Asset => | |
67 | + | $Tuple4(toBase58String(feePriorityAsset.id), feePriorityAsset.name, pow(10, 0, feePriorityAsset.decimals, 0, 0, DOWN), feePriorityMinReceived) | |
68 | + | case _ => | |
69 | + | throw("Unexpected behaviour") | |
70 | + | } | |
46 | 71 | ||
47 | 72 | ||
48 | - | func getLastFeeSwapTimestamp (assetId) = valueOrElse(getInteger(this, key_lastFeeSwapTimestamp(toBase58String(assetId))), 0) | |
73 | + | func getLastFeeSwapTimestamp (assetId) = valueOrElse(getInteger(this, key_lastFeeSwapTimestamp(toBase58String(valueOrElse(assetId, base58'WAVES')))), 0) | |
49 | 74 | ||
50 | 75 | ||
51 | - | func setLastFeeSwapTimestamp (assetId,timestamp) = [IntegerEntry(key_lastFeeSwapTimestamp(toBase58String(assetId)), timestamp)] | |
76 | + | func setLastFeeSwapTimestamp (assetId,timestamp) = [IntegerEntry(key_lastFeeSwapTimestamp(toBase58String(valueOrElse(assetId, base58'WAVES'))), timestamp)] | |
52 | 77 | ||
53 | 78 | ||
54 | 79 | @Callable(inv) | |
55 | 80 | func claimReferrerReward (amount,assetId) = { | |
56 | 81 | let asset = getAssetId(assetId) | |
57 | 82 | if ((proxyAddress != inv.caller)) | |
58 | 83 | then throw("only self calls or by collector are allowed") | |
59 | 84 | else if ((0 >= amount)) | |
60 | 85 | then throw("Incorrect reward amount") | |
61 | 86 | else [ScriptTransfer(proxyAddress, amount, asset)] | |
62 | 87 | } | |
63 | 88 | ||
64 | 89 | ||
65 | 90 | ||
66 | 91 | @Callable(inv) | |
67 | 92 | func PRIVATE_swap (amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived,options,pmtAmount,pmtAssetStr) = { | |
68 | - | let pmtAssetId = fromBase58String(pmtAssetStr) | |
69 | - | let pmt = if (if ((pmtAssetStr == "WAVES")) | |
70 | - | then true | |
71 | - | else (pmtAssetId == feePriorityAssetId)) | |
72 | - | then throw("Unable to swap WAVES or priority asset") | |
93 | + | let pmtAssetId = getAssetId(pmtAssetStr) | |
94 | + | let pmt = if (containsElement(feeExcludedAssetIds, pmtAssetId)) | |
95 | + | then throw((("Asset `" + pmtAssetStr) + "` is excluded from PRIVATE_swap")) | |
73 | 96 | else if ((0 >= pmtAmount)) | |
74 | 97 | then throw("Payment amount must be positive") | |
75 | 98 | else AttachedPayment(pmtAssetId, pmtAmount) | |
76 | 99 | if ((inv.caller != this)) | |
77 | 100 | then throw("Only self calls are allowed") | |
78 | 101 | else if (isDefined(inv.feeAssetId)) | |
79 | 102 | then throw("Only WAVES allowed for feeAssetId") | |
80 | 103 | else if (if (isDefined(txFeeLimit)) | |
81 | 104 | then (inv.fee > value(txFeeLimit)) | |
82 | 105 | else false) | |
83 | 106 | then throw((("Maximum fee (" + toString(value(txFeeLimit))) + ") is exceeded")) | |
84 | 107 | else if ((feeSwapInterval > (lastBlock.timestamp - getLastFeeSwapTimestamp(pmtAssetId)))) | |
85 | 108 | then throw((("Swap is only possible once every " + toString((feeSwapInterval / 3600000))) + " hours")) | |
86 | 109 | else { | |
87 | - | let balanceBefore = | |
110 | + | let balanceBefore = getAssetBalance(feePriorityAssetId) | |
88 | 111 | if ((balanceBefore == balanceBefore)) | |
89 | 112 | then { | |
90 | 113 | let swap = invoke(proxyAddress, "swap", [amountsIn, addresses, assetsToReceive, estReceived, slippageTolerance, minReceived, options], [pmt]) | |
91 | 114 | if ((swap == swap)) | |
92 | 115 | then { | |
93 | - | let balanceAfter = | |
116 | + | let balanceAfter = getAssetBalance(feePriorityAssetId) | |
94 | 117 | if ((balanceAfter == balanceAfter)) | |
95 | 118 | then { | |
96 | 119 | let received = (balanceAfter - balanceBefore) | |
97 | 120 | if ((0 >= received)) | |
98 | 121 | then throw("Swap is only allowed to the priority asset") | |
99 | 122 | else if ((feePriorityMinReceived > received)) | |
100 | 123 | then throw(("Swap result is less than " + toString(feePriorityMinReceived))) | |
101 | 124 | else setLastFeeSwapTimestamp(pmtAssetId, lastBlock.timestamp) | |
102 | 125 | } | |
103 | 126 | else throw("Strict value is not equal to itself.") | |
104 | 127 | } | |
105 | 128 | else throw("Strict value is not equal to itself.") | |
106 | 129 | } | |
107 | 130 | else throw("Strict value is not equal to itself.") | |
108 | 131 | } | |
109 | 132 | } | |
110 | 133 | ||
111 | 134 | ||
112 | 135 | @Verifier(tx) | |
113 | 136 | func verify () = { | |
114 | 137 | let maybeOracle = addressFromString(valueOrElse(getString(this, "Oracle"), "")) | |
115 | 138 | let maybeAdminKeys = if (isDefined(maybeOracle)) | |
116 | 139 | then getString(value(maybeOracle), "AdminKeys") | |
117 | 140 | else unit | |
118 | 141 | let isFeeSwapInvoke = match tx { | |
119 | 142 | case tx: InvokeScriptTransaction => | |
120 | 143 | if ((tx.dApp == this)) | |
121 | 144 | then (tx.function == "PRIVATE_swap") | |
122 | 145 | else false | |
123 | 146 | case _ => | |
124 | 147 | false | |
125 | 148 | } | |
126 | 149 | if (if (isDefined(feeManager)) | |
127 | 150 | then isFeeSwapInvoke | |
128 | 151 | else false) | |
129 | 152 | then sigVerify(tx.bodyBytes, tx.proofs[0], value(feeManager)) | |
130 | 153 | else match maybeAdminKeys { | |
131 | 154 | case adminKeysStr: String => | |
132 | 155 | let adminKeys = { | |
133 | 156 | let stringKeys = split(adminKeysStr, ",") | |
134 | 157 | [fromBase58String(stringKeys[0]), fromBase58String(stringKeys[1]), fromBase58String(stringKeys[2])] | |
135 | 158 | } | |
136 | 159 | func verifyByAllKeys (proof) = if (sigVerify(tx.bodyBytes, proof, adminKeys[0])) | |
137 | 160 | then 1 | |
138 | 161 | else if (sigVerify(tx.bodyBytes, proof, adminKeys[1])) | |
139 | 162 | then 10 | |
140 | 163 | else if (sigVerify(tx.bodyBytes, proof, adminKeys[2])) | |
141 | 164 | then 100 | |
142 | 165 | else 0 | |
143 | 166 | ||
144 | 167 | containsElement([110, 101, 11], (verifyByAllKeys(tx.proofs[0]) + verifyByAllKeys(tx.proofs[1]))) | |
145 | 168 | case _ => | |
146 | 169 | sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
147 | 170 | } | |
148 | 171 | } | |
149 | 172 |
github/deemru/w8io/786bc32 37.18 ms ◑