tx · 7uoXZJpD1H7Ypdc8G8tWiNbMYNbsnkFmjTuV1TUw7SkC

3M5rfKcU1WopgFv3Gjp8AM3rWks34jpAsax:  -0.03000000 Waves

2025.12.03 07:43 [783696] smart account 3M5rfKcU1WopgFv3Gjp8AM3rWks34jpAsax > SELF 0.00000000 Waves

{ "type": 13, "id": "7uoXZJpD1H7Ypdc8G8tWiNbMYNbsnkFmjTuV1TUw7SkC", "fee": 3000000, "feeAssetId": null, "timestamp": 1764737031604, "version": 2, "chainId": 82, "sender": "3M5rfKcU1WopgFv3Gjp8AM3rWks34jpAsax", "senderPublicKey": "FbWJzZsTsu1KcqiM4ePJDHwDGkCLrgWq5uUXLax3AHz", "proofs": [ "3VvawxUd2d9CUzWKbTrHztwrLtJcbVdpFe4KFN4Ve3uR1GE4yLjyxU9VmMAGxWqteK3rxKBZY2xrN2sYH7TwPo9n" ], "script": "base64:BgIgCAISBAoCCAESBQoDCAEIEgQKAggIEgQKAggIEgMKAQQeAAljb25maWdTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwINY29uZmlnQWRkcmVzcwIjM1BNb0VpYmRMZVdxY1VSUTgzNTFYaGFXd3lhY0RjN0c0ZTUADkNPTkZJR19BRERSRVNTAwkAAAIFCWNvbmZpZ1N0cgIABQR0aGlzCQEHQWRkcmVzcwEJANkEAQUJY29uZmlnU3RyAAhhZG1pblN0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIFQURNSU4CIzNQTWNNaU1FczZ3NTZOUkdhY2tzWHRGRzV6Uzdkb0U5ZnBMAAVhZG1pbgkA2QQBBQhhZG1pblN0cgAJdXNkbklkU3RyCQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAg51c2RuQXNzZXRJZFN0cgIsREcyeEZrUGREd0tVb0JrekdBaFF0THBTR3pmWExpQ1lQRXplS0gyQWQyNHAABnVzZG5JZAkA2QQBBQl1c2RuSWRTdHIADWxpbWl0Q29udHJhY3QJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDkxJTUlUX0NPTlRSQUNUAiMzUEZCNkxKeVNoc0NLRUExQVUxVTFXTGJEYXpxeWo2Wkw5YgALdHNuQ29udHJhY3QJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCDFRTTl9DT05UUkFDVAIjM1BLejVqbkpMb2hGMkdqU2hRN2JHNUg0QmViZG9BOTh6WjIAEWxlbmRQcm94eUNvbnRyYWN0CQELdmFsdWVPckVsc2UCCQCdCAIFDkNPTkZJR19BRERSRVNTAhNMRU5EX1BST1hZX0NPTlRSQUNUAiMzUEd4TVp0TW5OVDlwSkN2WHhYVjRMektxWHNqdlE5WHBmUgAQcHpQb29sc0wyV3JhcHBlcgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwITUFpfUE9PTFNfTDJfV1JBUFBFUgIjM1BRb0JmVUtIa0pBZUdXaG9vTFA3V1M4b3ZiNTRhdjlKcDIADHd4U3dhcHBlclN0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwIKV1hfU1dBUFBFUgIjM1A2OHpOaXVmc3UxdmlacHUxYVkzY2RhaFJSS2N2VjVOOTMACXd4U3dhcHBlcgkA2QQBBQx3eFN3YXBwZXJTdHIAFXVsdHJhc3Rha2VDb250cmFjdFN0cgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQ5DT05GSUdfQUREUkVTUwITVUxUUkFTVEFLRV9DT05UUkFDVAIjM1BLVXhiWmFTWWZzUjd3dTJIYUFnaWlySFl3QU11cERyWVcAEnVsdHJhc3Rha2VDb250cmFjdAkA2QQBBRV1bHRyYXN0YWtlQ29udHJhY3RTdHIAFnJlc2VydmVGdW5kQ29udHJhY3RTdHIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUOQ09ORklHX0FERFJFU1MCFVJFU0VSVkVfRlVORF9DT05UUkFDVAIjM1A0a0JpVTR3cjJ5VjFTNWdNZnUzTWRrVnZ5N2t4WEhzS2UAE3Jlc2VydmVGdW5kQ29udHJhY3QJANkEAQUWcmVzZXJ2ZUZ1bmRDb250cmFjdFN0cgAHbXVuYVJlZgkA2QQBCQELdmFsdWVPckVsc2UCCQCiCAECB211bmFSZWYCIzNQR0ZIelZHVDROVGlnd0NLUDFOY3dvWGtvZFZad3ZCdXVVAAZ0Y2lSZWYJANkEAQkBC3ZhbHVlT3JFbHNlAgkAoggBAgZ0Y2lSZWYCIzNQOTNSMkdCa1RHVmVoUlBoeXRIcjdzZHhZd3c5M2prYmhtAAlrZWVwZXJSZWYJANkEAQkBC3ZhbHVlT3JFbHNlAgkAoggBAglrZWVwZXJSZWYCIzNQTmd3NkRiMlRHVVFiam5WN2VrdmU2cTEyNnhCQzFlN2VNAApkZWZhdWx0UmVmCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAKIIAQIKZGVmYXVsdFJlZgIjM1BReFhYaVFYcFdzakR3UUxZeHl1b1BpYUxuVkhqSmd1Rm8BDHRyeUdldFN0cmluZwEDa2V5BAckbWF0Y2gwCQCdCAIFBHRoaXMFA2tleQMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAWIFByRtYXRjaDAFAWICAAERdHJ5R2V0U3RyaW5nT3RoZXICA2tleQdhZGRyZXNzBAckbWF0Y2gwCQCdCAIFB2FkZHJlc3MFA2tleQMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAWIFByRtYXRjaDAFAWICAAEOZ2V0QXNzZXRTdHJpbmcBB2Fzc2V0SWQEByRtYXRjaDAFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBYgUHJG1hdGNoMAkA2AQBBQFiAgVXQVZFUwENZ2V0QXNzZXRCeXRlcwEKYXNzZXRJZFN0cgMJAAACBQphc3NldElkU3RyAgVXQVZFUwUEdW5pdAkA2QQBBQphc3NldElkU3RyAQpnZXRCYWxhbmNlAQdhc3NldElkBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACBFVuaXQEAXgFByRtYXRjaDAICQDvBwEFBHRoaXMJYXZhaWxhYmxlCQDwBwIFBHRoaXMJAQV2YWx1ZQEFB2Fzc2V0SWQBBnN3YXBXWAMGYXNzZXQwBmFzc2V0MQdhbW91bnQwBBNhc3NldDFCYWxhbmNlQmVmb3JlCQEKZ2V0QmFsYW5jZQEJAQ1nZXRBc3NldEJ5dGVzAQUGYXNzZXQxAwkAAAIFE2Fzc2V0MUJhbGFuY2VCZWZvcmUFE2Fzc2V0MUJhbGFuY2VCZWZvcmUEBGludjEJAPwHBAkBB0FkZHJlc3MBBQl3eFN3YXBwZXICBHN3YXAJAMwIAgABCQDMCAIFBmFzc2V0MQkAzAgCCQClCAEFBHRoaXMFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBDWdldEFzc2V0Qnl0ZXMBBQZhc3NldDAFB2Ftb3VudDAFA25pbAMJAAACBQRpbnYxBQRpbnYxBAdhbW91bnQxCQBlAgkBCmdldEJhbGFuY2UBCQENZ2V0QXNzZXRCeXRlcwEFBmFzc2V0MQUTYXNzZXQxQmFsYW5jZUJlZm9yZQMJAAACBQdhbW91bnQxBQdhbW91bnQxBQdhbW91bnQxCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQlzd2FwTGltaXQDBnBhcmFtcwV0MFN0cgV0MVN0cgoBB2RvTGltaXQCBWFzc2V0C29yZGVyUGFyYW1zBANvcmQJALUJAgULb3JkZXJQYXJhbXMCAT4ECyR0MDMyODQzMzMyCQCUCgIJAJEDAgUDb3JkAAAJAJEDAgUDb3JkAAEEB29yZGVySWQIBQskdDAzMjg0MzMzMgJfMQQOb3JkZXJBbW91bnRTdHIIBQskdDAzMjg0MzMzMgJfMgQMX29yZGVyQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEFDm9yZGVyQW1vdW50U3RyBAhhc3NldEJhbAkBCmdldEJhbGFuY2UBBQVhc3NldAMJAAACBQhhc3NldEJhbAUIYXNzZXRCYWwEC29yZGVyQW1vdW50AwkAZgIFDF9vcmRlckFtb3VudAUIYXNzZXRCYWwFCGFzc2V0QmFsBQxfb3JkZXJBbW91bnQEA2ludgkA/AcECQEHQWRkcmVzcwEJANkEAQUNbGltaXRDb250cmFjdAIMZnVsZmlsbE9yZGVyCQDMCAIFB29yZGVySWQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUFYXNzZXQFC29yZGVyQW1vdW50BQNuaWwDCQAAAgUDaW52BQNpbnYFBWFzc2V0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAhvcmRlcnNMaQkAtQkCBQZwYXJhbXMCAToEAnQwCQENZ2V0QXNzZXRCeXRlcwEFBXQwU3RyBAZyZXN1bHQKAAIkbAUIb3JkZXJzTGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQJ0MAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHZG9MaW1pdAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgMJAAACBQZyZXN1bHQFBnJlc3VsdAAACQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQhzd2FwTGVuZAQGcGFyYW1zBXQwU3RyBXQxU3RyBmFtb3VudAQDYXJyCQC1CQIFBnBhcmFtcwIBLQQLJHQwMzkyMjM5NzkJAJUKAwkAkQMCBQNhcnIAAAkAkQMCBQNhcnIAAQkAkQMCBQNhcnIAAgQMcG9vbF9hZGRyZXNzCAULJHQwMzkyMjM5NzkCXzEEBWFzc2V0CAULJHQwMzkyMjM5NzkCXzIEA2RpcggFCyR0MDM5MjIzOTc5Al8zBAhwcm94eUFkcgkBB0FkZHJlc3MBCQDZBAEFEWxlbmRQcm94eUNvbnRyYWN0BAxmdW5jdGlvbk5hbWUDCQAAAgUDZGlyAgEwAgZtaW50UEwCCHJlZGVlbVBMCQD8BwQFCHByb3h5QWRyBQxmdW5jdGlvbk5hbWUJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQ1nZXRBc3NldEJ5dGVzAQUFdDBTdHIFBmFtb3VudAUDbmlsAQhzd2FwUGVwZQQGcGFyYW1zBXQwU3RyBXQxU3RyBmFtb3VudAQDYXJyCQC1CQIFBnBhcmFtcwIBLQQLJHQwNDM0NzQzOTcJAJQKAgkAkQMCBQNhcnIAAAkAkQMCBQNhcnIAAQQMcG9vbF9hZGRyZXNzCAULJHQwNDM0NzQzOTcCXzEEC2Z1bmN0aW9uVGFnCAULJHQwNDM0NzQzOTcCXzIEC3N3YXBBZGRyZXNzCQEHQWRkcmVzcwEJANkEAQUMcG9vbF9hZGRyZXNzAwkAAAIFC2Z1bmN0aW9uVGFnAgFkCQD8BwQFC3N3YXBBZGRyZXNzAgdkZXBvc2l0CQDMCAIAAAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQENZ2V0QXNzZXRCeXRlcwEFBXQwU3RyBQZhbW91bnQFA25pbAMJAAACBQtmdW5jdGlvblRhZwIBdwkA/AcEBQtzd2FwQWRkcmVzcwIId2l0aGRyYXcJAMwIAgUFdDFTdHIJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQ1nZXRBc3NldEJ5dGVzAQUFdDBTdHIFBmFtb3VudAUDbmlsAwkAAAIFC2Z1bmN0aW9uVGFnAgFzCQD8BwQFC3N3YXBBZGRyZXNzAgRzd2FwCQDMCAIFBXQxU3RyCQDMCAIAAAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQENZ2V0QXNzZXRCeXRlcwEFBXQwU3RyBQZhbW91bnQFA25pbAkAAgECIlVua25vd24gZnVuY3Rpb24gdGFnIGZvciBwZXBlIHN3YXABDHN3YXBJbnRlcm5hbAQBaQlyb3V0ZXNTdHIMbWluVG9SZWNlaXZlBnJlZktleQQIc2h1dGRvd24JAQt2YWx1ZU9yRWxzZQIJAKAIAQIIc2h1dGRvd24HAwUIc2h1dGRvd24JAAIBAghzaHV0ZG93bgoBBmRvU3dhcAIGYW1vdW50BHN3YXAEBnN3YXBMaQkAtQkCBQRzd2FwAgEsBAskdDA1MjAxNTI4MgkAlgoECQCRAwIFBnN3YXBMaQAACQCRAwIFBnN3YXBMaQABCQCRAwIFBnN3YXBMaQACCQCRAwIFBnN3YXBMaQADBARkQXBwCAULJHQwNTIwMTUyODICXzEECGRBcHBUeXBlCAULJHQwNTIwMTUyODICXzIEBXQwU3RyCAULJHQwNTIwMTUyODICXzMEBXQxU3RyCAULJHQwNTIwMTUyODICXzQEAnQwCQENZ2V0QXNzZXRCeXRlcwEFBXQwU3RyBAdhbW91bnQwAwkBAiE9AgUGYW1vdW50AAAFBmFtb3VudAkBCmdldEJhbGFuY2UBBQJ0MAQCaTEDCQAAAgUIZEFwcFR5cGUCBnN3b3BmaQkA/AcECQEHQWRkcmVzcwEJANkEAQUEZEFwcAIIZXhjaGFuZ2UJAMwIAgABBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAnQwBQdhbW91bnQwBQNuaWwDCQAAAgUIZEFwcFR5cGUCBnB1enpsZQQEcG9vbAkBB0FkZHJlc3MBCQDZBAEFBGRBcHAEEXBvb2xUb2tlbklkQmluYXJ5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJwIAgUEcG9vbAITZ2xvYmFsX3Bvb2xUb2tlbl9pZAkArAICAhZObyBwb29sVG9rZW4gZW50cnkgaW4gBQRkQXBwBA5wb29sVG9rZW5JZFN0cgkBDmdldEFzc2V0U3RyaW5nAQURcG9vbFRva2VuSWRCaW5hcnkDCQAAAgUFdDBTdHIFDnBvb2xUb2tlbklkU3RyCQD8BwQJAQdBZGRyZXNzAQkA2QQBBRBwelBvb2xzTDJXcmFwcGVyAhJyZWRlZW1XaXRoT25lVG9rZW4JAMwIAgUEZEFwcAkAzAgCBQV0MVN0cgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJ0MAUHYW1vdW50MAUDbmlsAwkAAAIFBXQxU3RyBQ5wb29sVG9rZW5JZFN0cgkA/AcECQEHQWRkcmVzcwEJANkEAQUQcHpQb29sc0wyV3JhcHBlcgIUZ2VuZXJhdGVXaXRoT25lVG9rZW4JAMwIAgUEZEFwcAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJ0MAUHYW1vdW50MAUDbmlsCQD8BwQFBHBvb2wCBHN3YXAJAMwIAgUFdDFTdHIJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAnQwBQdhbW91bnQwBQNuaWwDCQAAAgUIZEFwcFR5cGUCAnd4CQEGc3dhcFdYAwUFdDBTdHIFBXQxU3RyBQdhbW91bnQwAwkAAAIFCGRBcHBUeXBlAgVsaW1pdAkBCXN3YXBMaW1pdAMFBGRBcHAFBXQwU3RyBQV0MVN0cgMJAAACBQhkQXBwVHlwZQIHdHN1bmFtaQkA/AcECQEHQWRkcmVzcwEJANkEAQULdHNuQ29udHJhY3QCBHN3YXAJAMwIAgUFdDFTdHIJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAnQwBQdhbW91bnQwBQNuaWwDCQAAAgUIZEFwcFR5cGUCBGxlbmQJAQhzd2FwTGVuZAQFBGRBcHAFBXQwU3RyBQV0MVN0cgUHYW1vdW50MAMJAAACBQhkQXBwVHlwZQIEcGVwZQkBCHN3YXBQZXBlBAUEZEFwcAUFdDBTdHIFBXQxU3RyBQdhbW91bnQwCQACAQIraW50ZXJuYWwgYWdncmVnYXRvciBpc3N1ZTogdW5rbm93IHBvb2wgdHlwZQMJAAACBQJpMQUCaTEAAAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgoBB2RvUm91dGUCBWFjY3VtBXJvdXRlBAhhbW91bnRJbgkBDXBhcnNlSW50VmFsdWUBCQCRAwIJALUJAgUFcm91dGUCAS8AAAQFc3dhcHMJALUJAgkAkQMCCQC1CQIFBXJvdXRlAgEvAAECATsEC3N3YXBzUmVzdWx0CgACJGwFBXN3YXBzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUIYW1vdW50SW4KAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBBmRvU3dhcAIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgMwkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwMJAAACBQtzd2Fwc1Jlc3VsdAULc3dhcHNSZXN1bHQJAGQCBQVhY2N1bQULc3dhcHNSZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EDXNwbGl0dGVkUm91dGUJALUJAgkAsgICBQlyb3V0ZXNTdHIAMgIBLAQJYXNzZXQxU3RyCQCRAwIFDXNwbGl0dGVkUm91dGUJAGUCCQCQAwEFDXNwbGl0dGVkUm91dGUAAQQGYXNzZXQxCQENZ2V0QXNzZXRCeXRlcwEFCWFzc2V0MVN0cgQGcm91dGVzCQC8CQIFCXJvdXRlc1N0cgIBfAQFc3dhcHMKAAIkbAUGcm91dGVzCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQdkb1JvdXRlAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA0CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQDCQAAAgUFc3dhcHMFBXN3YXBzBAh0b3RhbE91dAkBCmdldEJhbGFuY2UBBQZhc3NldDEECWZlZUFtb3VudAkAawMFCHRvdGFsT3V0AB0AkE4EEGNsZWFuVG90YWxBbW91bnQJAGUCBQh0b3RhbE91dAUJZmVlQW1vdW50AwkAZgIFDG1pblRvUmVjZWl2ZQUQY2xlYW5Ub3RhbEFtb3VudAkAAgEJAKwCAgkArAICCQCsAgICX2Ftb3VudCB0byByZWNlaXZlIGlzIHRvbyBsb3cuIHBsZWFzZSB0cnkgYWdhaW4gd2l0aCBhbm90aGVyIGFtb3VudCBvciB3YWl0IDEgbWludXRlLiBleHBlY3RlZDogCQCkAwEFDG1pblRvUmVjZWl2ZQIHLCByZWFsIAkApAMBBRBjbGVhblRvdGFsQW1vdW50BAd1c2RuRmVlAwkAAAIFBmFzc2V0MQUGdXNkbklkBQlmZWVBbW91bnQEDnBvb2xBZGRyZXNzU3RyCQEMdHJ5R2V0U3RyaW5nAQkArAICCQCsAgICDXN0YXRpY19hc3NldF8FCWFzc2V0MVN0cgILX3B1enpsZVBvb2wDCQAAAgUOcG9vbEFkZHJlc3NTdHICAAAABBF1c2RuQmFsYW5jZUJlZm9yZQkBCmdldEJhbGFuY2UBBQZ1c2RuSWQDCQAAAgURdXNkbkJhbGFuY2VCZWZvcmUFEXVzZG5CYWxhbmNlQmVmb3JlBAxjb252ZXJ0ZWRGZWUJAPwHBAkBEUBleHRyTmF0aXZlKDEwNjIpAQUOcG9vbEFkZHJlc3NTdHICBHN3YXAJAMwIAgUJdXNkbklkU3RyCQDMCAIAAAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQZhc3NldDEFCWZlZUFtb3VudAUDbmlsAwkAAAIFDGNvbnZlcnRlZEZlZQUMY29udmVydGVkRmVlBBB1c2RuQmFsYW5jZUFmdGVyCQEKZ2V0QmFsYW5jZQEFBnVzZG5JZAMJAAACBRB1c2RuQmFsYW5jZUFmdGVyBRB1c2RuQmFsYW5jZUFmdGVyCQBlAgUQdXNkbkJhbGFuY2VBZnRlcgURdXNkbkJhbGFuY2VCZWZvcmUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DCQAAAgUHdXNkbkZlZQUHdXNkbkZlZQQPcmVmZXJyYWxBZGRyZXNzAwkAAAIFBnJlZktleQIEbXVuYQkBB0FkZHJlc3MBBQdtdW5hUmVmAwkAAAIFBnJlZktleQIGa2VlcGVyCQEHQWRkcmVzcwEFCWtlZXBlclJlZgMJAAACBQZyZWZLZXkCA3RjaQkBB0FkZHJlc3MBBQZ0Y2lSZWYDCQECIT0CCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJAKwCAgIEcmVmXwUGcmVmS2V5AgACAAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwkArAICAgRyZWZfBQZyZWZLZXkJAQdBZGRyZXNzAQUKZGVmYXVsdFJlZgQMcmVmVXNkblNoYXJlAwkAAAIFBnJlZktleQIFbm9yZWYAAAkAawMFB3VzZG5GZWUAAgAKBAV0b3BVcAMJAQIhPQIFB3VzZG5GZWUAAAkA/AcECQEHQWRkcmVzcwEFEnVsdHJhc3Rha2VDb250cmFjdAILdG9wVXBSZXdhcmQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUGdXNkbklkCQBlAgUHdXNkbkZlZQUMcmVmVXNkblNoYXJlBQNuaWwFBHVuaXQDCQAAAgUFdG9wVXAFBXRvcFVwBAZhc3NldDAICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQHYW1vdW50MAkAZQIJAQpnZXRCYWxhbmNlAQUGYXNzZXQwAwkAAAIFBmFzc2V0MAUGdXNkbklkBQxyZWZVc2RuU2hhcmUAAAQHYW1vdW50MQkAZQIFEGNsZWFuVG90YWxBbW91bnQDCQAAAgUGYXNzZXQxBQZ1c2RuSWQFDHJlZlVzZG5TaGFyZQAACQDOCAIJAM4IAgkAzggCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUHYW1vdW50MQUGYXNzZXQxBQNuaWwDCQECIT0CBQxyZWZVc2RuU2hhcmUAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQ9yZWZlcnJhbEFkZHJlc3MFDHJlZlVzZG5TaGFyZQUGdXNkbklkBQNuaWwFA25pbAMJAQIhPQIFB2Ftb3VudDAAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFB2Ftb3VudDAFBmFzc2V0MAUDbmlsBQNuaWwDCQAAAgUHdXNkbkZlZQAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJAQdBZGRyZXNzAQUTcmVzZXJ2ZUZ1bmRDb250cmFjdAUJZmVlQW1vdW50BQZhc3NldDEFA25pbAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQFpAQRzd2FwAglyb3V0ZXNTdHIMbWluVG9SZWNlaXZlCQEMc3dhcEludGVybmFsBAUBaQUJcm91dGVzU3RyBQxtaW5Ub1JlY2VpdmUCBW5vcmVmAWkBEHN3YXBXaXRoUmVmZXJyYWwDCXJvdXRlc1N0cgxtaW5Ub1JlY2VpdmUGcmVmS2V5CQEMc3dhcEludGVybmFsBAUBaQUJcm91dGVzU3RyBQxtaW5Ub1JlY2VpdmUFBnJlZktleQFpARJhZGRUb2tlblB1enpsZVBvb2wCCmFzc2V0SWRTdHIOcG9vbEFkZHJlc3NTdHIDCQECIT0CCAUBaQZjYWxsZXIJAQdBZGRyZXNzAQUFYWRtaW4JAAIBAgphZG1pbiBvbmx5CQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICAg1zdGF0aWNfYXNzZXRfBQphc3NldElkU3RyAgtfcHV6emxlUG9vbAUOcG9vbEFkZHJlc3NTdHIFA25pbAFpAQ5hZGRSZWZlcnJhbEtleQIGcmVmS2V5CmFkZHJlc3NTdHIDCQECIT0CCAUBaQZjYWxsZXIJAQdBZGRyZXNzAQUFYWRtaW4JAAIBAgphZG1pbiBvbmx5CQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgIEcmVmXwUGcmVmS2V5BQphZGRyZXNzU3RyBQNuaWwBaQEIc2h1dGRvd24BA3ZhbAMJAQIhPQIIBQFpBmNhbGxlcgkBB0FkZHJlc3MBBQVhZG1pbgkAAgECB3dsIG9ubHkJAMwIAgkBDEJvb2xlYW5FbnRyeQICCHNodXRkb3duBQN2YWwFA25pbAECdHgBBnZlcmlmeQAJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAIBQJ0eA9zZW5kZXJQdWJsaWNLZXlbpd2U", "height": 783696, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
OldNewDifferences
1-# no script
1+{-# STDLIB_VERSION 6 #-}
2+{-# SCRIPT_TYPE ACCOUNT #-}
3+{-# CONTENT_TYPE DAPP #-}
4+let configStr = valueOrElse(getString(this, "configAddress"), "3PMoEibdLeWqcURQ8351XhaWwyacDc7G4e5")
5+
6+let CONFIG_ADDRESS = if ((configStr == ""))
7+ then this
8+ else Address(fromBase58String(configStr))
9+
10+let adminStr = valueOrElse(getString(CONFIG_ADDRESS, "ADMIN"), "3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL")
11+
12+let admin = fromBase58String(adminStr)
13+
14+let usdnIdStr = valueOrElse(getString(CONFIG_ADDRESS, "usdnAssetIdStr"), "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
15+
16+let usdnId = fromBase58String(usdnIdStr)
17+
18+let limitContract = valueOrElse(getString(CONFIG_ADDRESS, "LIMIT_CONTRACT"), "3PFB6LJyShsCKEA1AU1U1WLbDazqyj6ZL9b")
19+
20+let tsnContract = valueOrElse(getString(CONFIG_ADDRESS, "TSN_CONTRACT"), "3PKz5jnJLohF2GjShQ7bG5H4BebdoA98zZ2")
21+
22+let lendProxyContract = valueOrElse(getString(CONFIG_ADDRESS, "LEND_PROXY_CONTRACT"), "3PGxMZtMnNT9pJCvXxXV4LzKqXsjvQ9XpfR")
23+
24+let pzPoolsL2Wrapper = valueOrElse(getString(CONFIG_ADDRESS, "PZ_POOLS_L2_WRAPPER"), "3PQoBfUKHkJAeGWhooLP7WS8ovb54av9Jp2")
25+
26+let wxSwapperStr = valueOrElse(getString(CONFIG_ADDRESS, "WX_SWAPPER"), "3P68zNiufsu1viZpu1aY3cdahRRKcvV5N93")
27+
28+let wxSwapper = fromBase58String(wxSwapperStr)
29+
30+let ultrastakeContractStr = valueOrElse(getString(CONFIG_ADDRESS, "ULTRASTAKE_CONTRACT"), "3PKUxbZaSYfsR7wu2HaAgiirHYwAMupDrYW")
31+
32+let ultrastakeContract = fromBase58String(ultrastakeContractStr)
33+
34+let reserveFundContractStr = valueOrElse(getString(CONFIG_ADDRESS, "RESERVE_FUND_CONTRACT"), "3P4kBiU4wr2yV1S5gMfu3MdkVvy7kxXHsKe")
35+
36+let reserveFundContract = fromBase58String(reserveFundContractStr)
37+
38+let munaRef = fromBase58String(valueOrElse(getString("munaRef"), "3PGFHzVGT4NTigwCKP1NcwoXkodVZwvBuuU"))
39+
40+let tciRef = fromBase58String(valueOrElse(getString("tciRef"), "3P93R2GBkTGVehRPhytHr7sdxYww93jkbhm"))
41+
42+let keeperRef = fromBase58String(valueOrElse(getString("keeperRef"), "3PNgw6Db2TGUQbjnV7ekve6q126xBC1e7eM"))
43+
44+let defaultRef = fromBase58String(valueOrElse(getString("defaultRef"), "3PQxXXiQXpWsjDwQLYxyuoPiaLnVHjJguFo"))
45+
46+func tryGetString (key) = match getString(this, key) {
47+ case b: String =>
48+ b
49+ case _ =>
50+ ""
51+}
52+
53+
54+func tryGetStringOther (key,address) = match getString(address, key) {
55+ case b: String =>
56+ b
57+ case _ =>
58+ ""
59+}
60+
61+
62+func getAssetString (assetId) = match assetId {
63+ case b: ByteVector =>
64+ toBase58String(b)
65+ case _ =>
66+ "WAVES"
67+}
68+
69+
70+func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES"))
71+ then unit
72+ else fromBase58String(assetIdStr)
73+
74+
75+func getBalance (assetId) = match assetId {
76+ case x: Unit =>
77+ wavesBalance(this).available
78+ case _ =>
79+ assetBalance(this, value(assetId))
80+}
81+
82+
83+func swapWX (asset0,asset1,amount0) = {
84+ let asset1BalanceBefore = getBalance(getAssetBytes(asset1))
85+ if ((asset1BalanceBefore == asset1BalanceBefore))
86+ then {
87+ let inv1 = invoke(Address(wxSwapper), "swap", [1, asset1, toString(this)], [AttachedPayment(getAssetBytes(asset0), amount0)])
88+ if ((inv1 == inv1))
89+ then {
90+ let amount1 = (getBalance(getAssetBytes(asset1)) - asset1BalanceBefore)
91+ if ((amount1 == amount1))
92+ then amount1
93+ else throw("Strict value is not equal to itself.")
94+ }
95+ else throw("Strict value is not equal to itself.")
96+ }
97+ else throw("Strict value is not equal to itself.")
98+ }
99+
100+
101+func swapLimit (params,t0Str,t1Str) = {
102+ func doLimit (asset,orderParams) = {
103+ let ord = split(orderParams, ">")
104+ let $t032843332 = $Tuple2(ord[0], ord[1])
105+ let orderId = $t032843332._1
106+ let orderAmountStr = $t032843332._2
107+ let _orderAmount = parseIntValue(orderAmountStr)
108+ let assetBal = getBalance(asset)
109+ if ((assetBal == assetBal))
110+ then {
111+ let orderAmount = if ((_orderAmount > assetBal))
112+ then assetBal
113+ else _orderAmount
114+ let inv = invoke(Address(fromBase58String(limitContract)), "fulfillOrder", [orderId], [AttachedPayment(asset, orderAmount)])
115+ if ((inv == inv))
116+ then asset
117+ else throw("Strict value is not equal to itself.")
118+ }
119+ else throw("Strict value is not equal to itself.")
120+ }
121+
122+ let ordersLi = split(params, ":")
123+ let t0 = getAssetBytes(t0Str)
124+ let result = {
125+ let $l = ordersLi
126+ let $s = size($l)
127+ let $acc0 = t0
128+ func $f0_1 ($a,$i) = if (($i >= $s))
129+ then $a
130+ else doLimit($a, $l[$i])
131+
132+ func $f0_2 ($a,$i) = if (($i >= $s))
133+ then $a
134+ else throw("List size exceeds 10")
135+
136+ $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)
137+ }
138+ if ((result == result))
139+ then 0
140+ else throw("Strict value is not equal to itself.")
141+ }
142+
143+
144+func swapLend (params,t0Str,t1Str,amount) = {
145+ let arr = split(params, "-")
146+ let $t039223979 = $Tuple3(arr[0], arr[1], arr[2])
147+ let pool_address = $t039223979._1
148+ let asset = $t039223979._2
149+ let dir = $t039223979._3
150+ let proxyAdr = Address(fromBase58String(lendProxyContract))
151+ let functionName = if ((dir == "0"))
152+ then "mintPL"
153+ else "redeemPL"
154+ invoke(proxyAdr, functionName, [0], [AttachedPayment(getAssetBytes(t0Str), amount)])
155+ }
156+
157+
158+func swapPepe (params,t0Str,t1Str,amount) = {
159+ let arr = split(params, "-")
160+ let $t043474397 = $Tuple2(arr[0], arr[1])
161+ let pool_address = $t043474397._1
162+ let functionTag = $t043474397._2
163+ let swapAddress = Address(fromBase58String(pool_address))
164+ if ((functionTag == "d"))
165+ then invoke(swapAddress, "deposit", [0], [AttachedPayment(getAssetBytes(t0Str), amount)])
166+ else if ((functionTag == "w"))
167+ then invoke(swapAddress, "withdraw", [t1Str, 0], [AttachedPayment(getAssetBytes(t0Str), amount)])
168+ else if ((functionTag == "s"))
169+ then invoke(swapAddress, "swap", [t1Str, 0], [AttachedPayment(getAssetBytes(t0Str), amount)])
170+ else throw("Unknown function tag for pepe swap")
171+ }
172+
173+
174+func swapInternal (i,routesStr,minToReceive,refKey) = {
175+ let shutdown = valueOrElse(getBoolean("shutdown"), false)
176+ if (shutdown)
177+ then throw("shutdown")
178+ else {
179+ func doSwap (amount,swap) = {
180+ let swapLi = split(swap, ",")
181+ let $t052015282 = $Tuple4(swapLi[0], swapLi[1], swapLi[2], swapLi[3])
182+ let dApp = $t052015282._1
183+ let dAppType = $t052015282._2
184+ let t0Str = $t052015282._3
185+ let t1Str = $t052015282._4
186+ let t0 = getAssetBytes(t0Str)
187+ let amount0 = if ((amount != 0))
188+ then amount
189+ else getBalance(t0)
190+ let i1 = if ((dAppType == "swopfi"))
191+ then invoke(Address(fromBase58String(dApp)), "exchange", [1], [AttachedPayment(t0, amount0)])
192+ else if ((dAppType == "puzzle"))
193+ then {
194+ let pool = Address(fromBase58String(dApp))
195+ let poolTokenIdBinary = valueOrErrorMessage(getBinary(pool, "global_poolToken_id"), ("No poolToken entry in " + dApp))
196+ let poolTokenIdStr = getAssetString(poolTokenIdBinary)
197+ if ((t0Str == poolTokenIdStr))
198+ then invoke(Address(fromBase58String(pzPoolsL2Wrapper)), "redeemWithOneToken", [dApp, t1Str], [AttachedPayment(t0, amount0)])
199+ else if ((t1Str == poolTokenIdStr))
200+ then invoke(Address(fromBase58String(pzPoolsL2Wrapper)), "generateWithOneToken", [dApp], [AttachedPayment(t0, amount0)])
201+ else invoke(pool, "swap", [t1Str, 0], [AttachedPayment(t0, amount0)])
202+ }
203+ else if ((dAppType == "wx"))
204+ then swapWX(t0Str, t1Str, amount0)
205+ else if ((dAppType == "limit"))
206+ then swapLimit(dApp, t0Str, t1Str)
207+ else if ((dAppType == "tsunami"))
208+ then invoke(Address(fromBase58String(tsnContract)), "swap", [t1Str, 0], [AttachedPayment(t0, amount0)])
209+ else if ((dAppType == "lend"))
210+ then swapLend(dApp, t0Str, t1Str, amount0)
211+ else if ((dAppType == "pepe"))
212+ then swapPepe(dApp, t0Str, t1Str, amount0)
213+ else throw("internal aggregator issue: unknow pool type")
214+ if ((i1 == i1))
215+ then 0
216+ else throw("Strict value is not equal to itself.")
217+ }
218+
219+ func doRoute (accum,route) = {
220+ let amountIn = parseIntValue(split(route, "/")[0])
221+ let swaps = split(split(route, "/")[1], ";")
222+ let swapsResult = {
223+ let $l = swaps
224+ let $s = size($l)
225+ let $acc0 = amountIn
226+ func $f0_1 ($a,$i) = if (($i >= $s))
227+ then $a
228+ else doSwap($a, $l[$i])
229+
230+ func $f0_2 ($a,$i) = if (($i >= $s))
231+ then $a
232+ else throw("List size exceeds 3")
233+
234+ $f0_2($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3)
235+ }
236+ if ((swapsResult == swapsResult))
237+ then (accum + swapsResult)
238+ else throw("Strict value is not equal to itself.")
239+ }
240+
241+ let splittedRoute = split(takeRight(routesStr, 50), ",")
242+ let asset1Str = splittedRoute[(size(splittedRoute) - 1)]
243+ let asset1 = getAssetBytes(asset1Str)
244+ let routes = split_4C(routesStr, "|")
245+ let swaps = {
246+ let $l = routes
247+ let $s = size($l)
248+ let $acc0 = 0
249+ func $f0_1 ($a,$i) = if (($i >= $s))
250+ then $a
251+ else doRoute($a, $l[$i])
252+
253+ func $f0_2 ($a,$i) = if (($i >= $s))
254+ then $a
255+ else throw("List size exceeds 4")
256+
257+ $f0_2($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4)
258+ }
259+ if ((swaps == swaps))
260+ then {
261+ let totalOut = getBalance(asset1)
262+ let feeAmount = fraction(totalOut, 29, 10000)
263+ let cleanTotalAmount = (totalOut - feeAmount)
264+ if ((minToReceive > cleanTotalAmount))
265+ then throw(((("amount to receive is too low. please try again with another amount or wait 1 minute. expected: " + toString(minToReceive)) + ", real ") + toString(cleanTotalAmount)))
266+ else {
267+ let usdnFee = if ((asset1 == usdnId))
268+ then feeAmount
269+ else {
270+ let poolAddressStr = tryGetString((("static_asset_" + asset1Str) + "_puzzlePool"))
271+ if ((poolAddressStr == ""))
272+ then 0
273+ else {
274+ let usdnBalanceBefore = getBalance(usdnId)
275+ if ((usdnBalanceBefore == usdnBalanceBefore))
276+ then {
277+ let convertedFee = invoke(addressFromStringValue(poolAddressStr), "swap", [usdnIdStr, 0], [AttachedPayment(asset1, feeAmount)])
278+ if ((convertedFee == convertedFee))
279+ then {
280+ let usdnBalanceAfter = getBalance(usdnId)
281+ if ((usdnBalanceAfter == usdnBalanceAfter))
282+ then (usdnBalanceAfter - usdnBalanceBefore)
283+ else throw("Strict value is not equal to itself.")
284+ }
285+ else throw("Strict value is not equal to itself.")
286+ }
287+ else throw("Strict value is not equal to itself.")
288+ }
289+ }
290+ if ((usdnFee == usdnFee))
291+ then {
292+ let referralAddress = if ((refKey == "muna"))
293+ then Address(munaRef)
294+ else if ((refKey == "keeper"))
295+ then Address(keeperRef)
296+ else if ((refKey == "tci"))
297+ then Address(tciRef)
298+ else if ((valueOrElse(getString(this, ("ref_" + refKey)), "") != ""))
299+ then addressFromStringValue(getStringValue(this, ("ref_" + refKey)))
300+ else Address(defaultRef)
301+ let refUsdnShare = if ((refKey == "noref"))
302+ then 0
303+ else fraction(usdnFee, 2, 10)
304+ let topUp = if ((usdnFee != 0))
305+ then invoke(Address(ultrastakeContract), "topUpReward", nil, [AttachedPayment(usdnId, (usdnFee - refUsdnShare))])
306+ else unit
307+ if ((topUp == topUp))
308+ then {
309+ let asset0 = i.payments[0].assetId
310+ let amount0 = (getBalance(asset0) - (if ((asset0 == usdnId))
311+ then refUsdnShare
312+ else 0))
313+ let amount1 = (cleanTotalAmount - (if ((asset1 == usdnId))
314+ then refUsdnShare
315+ else 0))
316+ ((([ScriptTransfer(i.caller, amount1, asset1)] ++ (if ((refUsdnShare != 0))
317+ then [ScriptTransfer(referralAddress, refUsdnShare, usdnId)]
318+ else nil)) ++ (if ((amount0 != 0))
319+ then [ScriptTransfer(i.caller, amount0, asset0)]
320+ else nil)) ++ (if ((usdnFee == 0))
321+ then [ScriptTransfer(Address(reserveFundContract), feeAmount, asset1)]
322+ else nil))
323+ }
324+ else throw("Strict value is not equal to itself.")
325+ }
326+ else throw("Strict value is not equal to itself.")
327+ }
328+ }
329+ else throw("Strict value is not equal to itself.")
330+ }
331+ }
332+
333+
334+@Callable(i)
335+func swap (routesStr,minToReceive) = swapInternal(i, routesStr, minToReceive, "noref")
336+
337+
338+
339+@Callable(i)
340+func swapWithReferral (routesStr,minToReceive,refKey) = swapInternal(i, routesStr, minToReceive, refKey)
341+
342+
343+
344+@Callable(i)
345+func addTokenPuzzlePool (assetIdStr,poolAddressStr) = if ((i.caller != Address(admin)))
346+ then throw("admin only")
347+ else [StringEntry((("static_asset_" + assetIdStr) + "_puzzlePool"), poolAddressStr)]
348+
349+
350+
351+@Callable(i)
352+func addReferralKey (refKey,addressStr) = if ((i.caller != Address(admin)))
353+ then throw("admin only")
354+ else [StringEntry(("ref_" + refKey), addressStr)]
355+
356+
357+
358+@Callable(i)
359+func shutdown (val) = if ((i.caller != Address(admin)))
360+ then throw("wl only")
361+ else [BooleanEntry("shutdown", val)]
362+
363+
364+@Verifier(tx)
365+func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
366+

github/deemru/w8io
30.61 ms