tx · 85ggpr5LTXF7NfizMY2FehVEuvKXzmxsmCc3N4BhoWnK 3P4uA5etnZi4AmBabKinq2bMiWU8KcnHZdH: -0.02000000 Waves 2022.10.08 21:06 [3329148] smart account 3P4uA5etnZi4AmBabKinq2bMiWU8KcnHZdH > SELF 0.00000000 Waves
{ "type": 13, "id": "85ggpr5LTXF7NfizMY2FehVEuvKXzmxsmCc3N4BhoWnK", "fee": 2000000, "feeAssetId": null, "timestamp": 1665252469310, "version": 2, "chainId": 87, "sender": "3P4uA5etnZi4AmBabKinq2bMiWU8KcnHZdH", "senderPublicKey": "8DxbUxhy23djr6kUEE1Jzp7oVJXBsHNaATLRiABpkSde", "proofs": [ "5u1vJFh3szPaAufjjCPTQJ2qyxe6WjzPeBYfFVPTweTkLhAgTY48UvAy3PA347hPvYGPT4j8qz26qSSRJMk5rGva" ], "script": "base64:BgJICAISBwoFCAgICAESABIECgIIARIECgIIARIAEggKBgQIAQgICBIGCgQECAQIEgMKAQQSBAoCCAQSBAoCCAQSAwoBBBIDCgEEFQAGU2NhbGU4AIDC1y8AB1NjYWxlMTAAgMivoCUAB1NjYWxlMTYJAGgCBQZTY2FsZTgFBlNjYWxlOAALcmVzZXJ2ZUZ1bmQAFAAJZGF5QmxvY2tzAKALAQ10cnlHZXRJbnRlZ2VyAQNrZXkEByRtYXRjaDAJAJoIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACA0ludAQBYgUHJG1hdGNoMAUBYgAAAQ10cnlHZXRCb29sZWFuAQNrZXkEByRtYXRjaDAJAJsIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACB0Jvb2xlYW4EAWIFByRtYXRjaDAFAWIHAQx0cnlHZXRTdHJpbmcBA2tleQQHJG1hdGNoMAkAnQgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFiBQckbWF0Y2gwBQFiAgABDmdldEFzc2V0U3RyaW5nAQdhc3NldElkBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAWIFByRtYXRjaDAJANgEAQUBYgIFV0FWRVMBDWdldEFzc2V0Qnl0ZXMBCmFzc2V0SWRTdHIDCQAAAgUKYXNzZXRJZFN0cgIFV0FWRVMFBHVuaXQJANkEAQUKYXNzZXRJZFN0cgEKZ2V0QmFsYW5jZQEKYXNzZXRJZFN0cgMJAAACBQphc3NldElkU3RyAgVXQVZFUwgJAO8HAQUEdGhpcwlhdmFpbGFibGUJAPAHAgUEdGhpcwkA2QQBBQphc3NldElkU3RyAQ9nZXRNYXJrZXRBc3NldHMACQC1CQIJAQx0cnlHZXRTdHJpbmcBAgxzZXR1cF90b2tlbnMCASwBDWdldE91dGRhdGVkVXIBCmFzc2V0SWRTdHIEBGRvd24JAGsDCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYXNzZXRJZFN0cgIGX3NSYXRlBQdTY2FsZTE2AwkAAAIFBGRvd24AAAAACQBrAwUGU2NhbGU4CQBrAwkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFzc2V0SWRTdHICBl9iUmF0ZQUHU2NhbGUxNgUEZG93bgELZ2V0SW50ZXJlc3QBCmFzc2V0SWRTdHIEAnVyCQENZ2V0T3V0ZGF0ZWRVcgEFCmFzc2V0SWRTdHIEDWRhaWx5SW50ZXJlc3QDCQBnAgCA6JImBQJ1cgkAawMFAnVyAIDxBACA6JImCQBkAgCA8QQJAGsDCQBlAgUCdXIAgOiSJgCA8QQAgNrECQkAlgMBCQDMCAIJAGsDBQ1kYWlseUludGVyZXN0BQZTY2FsZTgFCWRheUJsb2NrcwkAzAgCAAEFA25pbAEQdG9rZW5SYXRlc1JlY2FsYwEKYXNzZXRJZFN0cgQIaW50ZXJlc3QJAQtnZXRJbnRlcmVzdAEFCmFzc2V0SWRTdHIEAnVyCQENZ2V0T3V0ZGF0ZWRVcgEFCmFzc2V0SWRTdHIEEGxhc3RSZWNhbGNIZWlnaHQJAQ10cnlHZXRJbnRlZ2VyAQIObGFzdFJhdGVIZWlnaHQECWxhc3RCUmF0ZQkAlgMBCQDMCAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphc3NldElkU3RyAgZfYlJhdGUJAMwIAgUHU2NhbGUxNgUDbmlsBAhuZXdCUmF0ZQkAZAIFCWxhc3RCUmF0ZQkAaAIJAGUCBQZoZWlnaHQFEGxhc3RSZWNhbGNIZWlnaHQFCGludGVyZXN0BAlsYXN0U1JhdGUJAJYDAQkAzAgCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYXNzZXRJZFN0cgIGX3NSYXRlCQDMCAIFB1NjYWxlMTYFA25pbAQIbmV3U1JhdGUJAGQCBQlsYXN0U1JhdGUJAGkCCQBoAgkAaAIJAGUCBQZoZWlnaHQFEGxhc3RSZWNhbGNIZWlnaHQJAGsDBQhpbnRlcmVzdAUCdXIFBlNjYWxlOAkAZQIAZAULcmVzZXJ2ZUZ1bmQAZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQphc3NldElkU3RyAgZfc1JhdGUFCG5ld1NSYXRlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFzc2V0SWRTdHICBl9iUmF0ZQUIbmV3QlJhdGUJAMwIAgkBDEludGVnZXJFbnRyeQICDmxhc3RSYXRlSGVpZ2h0BQZoZWlnaHQFA25pbAEFZ2V0VXIBCmFzc2V0SWRTdHIEBXJhdGVzCQEQdG9rZW5SYXRlc1JlY2FsYwEFCmFzc2V0SWRTdHIEBGRvd24JAGsDCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyCAkAkQMCBQVyYXRlcwAABXZhbHVlBQdTY2FsZTE2CQBrAwUGU2NhbGU4CQBrAwkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cggJAJEDAgUFcmF0ZXMAAQV2YWx1ZQUHU2NhbGUxNgUEZG93bgENZ2V0QWN0dWFsUmF0ZQIKYXNzZXRJZFN0cghyYXRlVHlwZQoBAWYCBWFjY3VtBXRva2VuBAZyZWNhbGMJARB0b2tlblJhdGVzUmVjYWxjAQUFdG9rZW4JAJQKAgMJAQIhPQIFBXRva2VuBQphc3NldElkU3RyCAUFYWNjdW0CXzEDCQAAAgUIcmF0ZVR5cGUCBXNSYXRlCAkAkQMCBQZyZWNhbGMAAAV2YWx1ZQgJAJEDAgUGcmVjYWxjAAEFdmFsdWUJAM4IAggFBWFjY3VtAl8yBQZyZWNhbGMKAAIkbAkBD2dldE1hcmtldEFzc2V0cwAKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFmAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAQtyYXRlc1JlY2FsYwAKAQFmAgVhY2N1bQV0b2tlbgkAzggCBQVhY2N1bQkBEHRva2VuUmF0ZXNSZWNhbGMBBQV0b2tlbgoAAiRsCQEPZ2V0TWFya2V0QXNzZXRzAAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEBZgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgENZ2V0VG9rZW5QcmljZQEKYXNzZXRJZFN0cgQDaW52CQD8BwQJARFAZXh0ck5hdGl2ZSgxMDYyKQECIzNQNUJUdGRqMzJTZDFEeWgxTWR3MzN4UUFBY2tTZk1mbktmAglnZXRUV0FQNjAJAMwIAgUKYXNzZXRJZFN0cgkAzAgCBwUDbmlsBQNuaWwDCQAAAgUDaW52BQNpbnYEByRtYXRjaDAFA2ludgMJAAECBQckbWF0Y2gwAgooSW50LCBJbnQpBAF4BQckbWF0Y2gwBQF4CQACAQIVZXJyb3Igb2YgcHJpY2Ugb3JhY2xlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQ5jYWxjQXNzZXRTY2FsZQEKYXNzZXRJZFN0cgQIZGVjaW1hbHMDCQAAAgUKYXNzZXRJZFN0cgIFV0FWRVMACAgJAQV2YWx1ZQEJAOwHAQkA2QQBBQphc3NldElkU3RyCGRlY2ltYWxzCQBsBgAKAAAFCGRlY2ltYWxzAAAAAAUERE9XTgESY2FsY1VzZXJDb2xsYXRlcmFsAQdhZGRyZXNzBBR1c2VyQ29sbGF0ZXJhbEludm9rZQkA/AcEBQR0aGlzAhFnZXRVc2VyQ29sbGF0ZXJhbAkAzAgCBwkAzAgCBQdhZGRyZXNzCQDMCAIGCQDMCAICAAUDbmlsBQNuaWwDCQAAAgUUdXNlckNvbGxhdGVyYWxJbnZva2UFFHVzZXJDb2xsYXRlcmFsSW52b2tlBBN1c2VyQ29sbGF0ZXJhbFZhbHVlBAckbWF0Y2gwBRR1c2VyQ29sbGF0ZXJhbEludm9rZQMJAAECBQckbWF0Y2gwAgNJbnQEAXgFByRtYXRjaDAFAXgJAAIBAiRpc3N1ZSB3aGlsZSBkb2luZyBpbi1kYXBwIGludm9jYXRpb24DCQAAAgUTdXNlckNvbGxhdGVyYWxWYWx1ZQUTdXNlckNvbGxhdGVyYWxWYWx1ZQUTdXNlckNvbGxhdGVyYWxWYWx1ZQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgwBaQEHcHJlSW5pdAUGdG9rZW5zBGx0dnMDbHRzCXBlbmFsdGllcwxkYWlseVBlcmNlbnQKAQFmAgVhY2N1bQV0b2tlbgkAzggCBQVhY2N1bQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQV0b2tlbgIGX2JSYXRlBQdTY2FsZTE2CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBXRva2VuAgZfc1JhdGUFB1NjYWxlMTYFA25pbAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECCmFkbWluIG9ubHkEBXJhdGVzCgACJGwJALUJAgUGdG9rZW5zAgEsCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFmAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgIMc2V0dXBfdG9rZW5zBQZ0b2tlbnMJAMwIAgkBC1N0cmluZ0VudHJ5AgIKc2V0dXBfbHR2cwUEbHR2cwkAzAgCCQELU3RyaW5nRW50cnkCAglzZXR1cF9sdHMFA2x0cwkAzAgCCQELU3RyaW5nRW50cnkCAg9zZXR1cF9wZW5hbHRpZXMFCXBlbmFsdGllcwkAzAgCCQEMQm9vbGVhbkVudHJ5AgIMc2V0dXBfYWN0aXZlBgUDbmlsBQVyYXRlcwFpAQZzdXBwbHkAAwkBASEBCQENdHJ5R2V0Qm9vbGVhbgECDHNldHVwX2FjdGl2ZQkAAgECEW1hcmtldCBpcyBzdG9wcGVkAwMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQYJAAACCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAAACQACAQIcMSBwYXltZW50IGhhcyB0byBiZSBhdHRhY2hlZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBAthc3NldEFtb3VudAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQECyR0MDUwMjE1MDg4CQENZ2V0QWN0dWFsUmF0ZQIFCmFzc2V0SWRTdHICBXNSYXRlBAVzUmF0ZQgFCyR0MDUwMjE1MDg4Al8xBBFyYXRlc1JlY2FsY1Jlc3VsdAgFCyR0MDUwMjE1MDg4Al8yBAZhbW91bnQJAGsDBQthc3NldEFtb3VudAUHU2NhbGUxNgUFc1JhdGUEB2FkZHJlc3MJAKUIAQgFAWkGY2FsbGVyAwkAAAIJALMJAgkBDHRyeUdldFN0cmluZwECDHNldHVwX3Rva2VucwUKYXNzZXRJZFN0cgUEdW5pdAkAAgECKXRoaXMgYXNzZXQgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgbWFya2V0CQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQphc3NldElkU3RyCQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgUGYW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIFBmFtb3VudAUDbmlsBRFyYXRlc1JlY2FsY1Jlc3VsdAFpAQh3aXRoZHJhdwIKYXNzZXRJZFN0cgthc3NldEFtb3VudAQLJHQwNTY1MzU3MjAJAQ1nZXRBY3R1YWxSYXRlAgUKYXNzZXRJZFN0cgIFc1JhdGUEBXNSYXRlCAULJHQwNTY1MzU3MjACXzEEEXJhdGVzUmVjYWxjUmVzdWx0CAULJHQwNTY1MzU3MjACXzIEBmFtb3VudAkAawMFC2Fzc2V0QW1vdW50BQdTY2FsZTE2BQVzUmF0ZQQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEDWFzc2V0U3VwcGxpZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIEDWFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIEEXVzZXJBc3NldFN1cHBsaWVkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQphc3NldElkU3RyBBF1c2VyQXNzZXRCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgQSY29sbGF0ZXJhbFZhbHVlSW52CQD8BwQFBHRoaXMCEWdldFVzZXJDb2xsYXRlcmFsCQDMCAIHCQDMCAIFB2FkZHJlc3MJAMwIAgYJAMwIAgkArAICCQCsAgIFCmFzc2V0SWRTdHICCixzdXBwbGllZCwJAKQDAQkBAS0BBQZhbW91bnQFA25pbAUDbmlsAwkAAAIFEmNvbGxhdGVyYWxWYWx1ZUludgUSY29sbGF0ZXJhbFZhbHVlSW52BA9jb2xsYXRlcmFsVmFsdWUEByRtYXRjaDAFEmNvbGxhdGVyYWxWYWx1ZUludgMJAAECBQckbWF0Y2gwAgNJbnQEAXgFByRtYXRjaDAFAXgJAAIBAh9jYW4ndCBnZXQgdXNlciBjb2xsYXRlcmFsIHZhbHVlAwkBASEBCQENdHJ5R2V0Qm9vbGVhbgECDHNldHVwX2FjdGl2ZQkAAgECEW1hcmtldCBpcyBzdG9wcGVkAwkAZgIAAAUPY29sbGF0ZXJhbFZhbHVlCQACAQIyeW91IGRvbnQgaGF2ZSBlbm91Z2ggY29sbGF0ZXJhbCBmb3IgdGhpcyBvcGVyYXRpb24DCQBmAgUGYW1vdW50CQBlAgUNYXNzZXRTdXBwbGllZAUNYXNzZXRCb3Jyb3dlZAkAAgECKnRoaXMgYW1vdW50IGlzIG5vdCBhdmFpbGFibGUgb24gdGhlIG1hcmtldAMJAGYCBQZhbW91bnQJAGUCBRF1c2VyQXNzZXRTdXBwbGllZAURdXNlckFzc2V0Qm9ycm93ZWQJAAIBAip0aGlzIGFtb3VudCBpcyBub3QgYXZhaWxhYmxlIGZvciB0aGlzIHVzZXIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIFB2FkZHJlc3MCCl9zdXBwbGllZF8FCmFzc2V0SWRTdHIJAGUCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQphc3NldElkU3RyBQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyCQBlAgkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgUGYW1vdW50CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUGYW1vdW50CQENZ2V0QXNzZXRCeXRlcwEFCmFzc2V0SWRTdHIFA25pbAURcmF0ZXNSZWNhbGNSZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEGYm9ycm93Agphc3NldElkU3RyC2Fzc2V0QW1vdW50BAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgQLJHQwNzE5OTcyNjYJAQ1nZXRBY3R1YWxSYXRlAgUKYXNzZXRJZFN0cgIFYlJhdGUEBWJSYXRlCAULJHQwNzE5OTcyNjYCXzEEEXJhdGVzUmVjYWxjUmVzdWx0CAULJHQwNzE5OTcyNjYCXzIEBmFtb3VudAkAawMFC2Fzc2V0QW1vdW50BQdTY2FsZTE2BQViUmF0ZQQSY29sbGF0ZXJhbFZhbHVlSW52CQD8BwQFBHRoaXMCEWdldFVzZXJDb2xsYXRlcmFsCQDMCAIHCQDMCAIFB2FkZHJlc3MJAMwIAgYJAMwIAgkArAICCQCsAgIFCmFzc2V0SWRTdHICCixib3Jyb3dlZCwJAKQDAQUGYW1vdW50BQNuaWwFA25pbAMJAAACBRJjb2xsYXRlcmFsVmFsdWVJbnYFEmNvbGxhdGVyYWxWYWx1ZUludgQPY29sbGF0ZXJhbFZhbHVlBAckbWF0Y2gwBRJjb2xsYXRlcmFsVmFsdWVJbnYDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4CQACAQIfY2FuJ3QgZ2V0IHVzZXIgY29sbGF0ZXJhbCB2YWx1ZQMJAQEhAQkBDXRyeUdldEJvb2xlYW4BAgxzZXR1cF9hY3RpdmUJAAIBAhFtYXJrZXQgaXMgc3RvcHBlZAMJAGYCAAAFD2NvbGxhdGVyYWxWYWx1ZQkAAgECIXlvdSBoYXZlIHRvIHN1cHBseSBtb3JlIHRvIGJvcnJvdwQNYXNzZXRTdXBwbGllZAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgQNYXNzZXRCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgQRdXNlckFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIDCQBmAgUGYW1vdW50CQBlAgUNYXNzZXRTdXBwbGllZAUNYXNzZXRCb3Jyb3dlZAkAAgECHHRoaXMgYW1vdW50IGlzIG5vdCBhdmFpbGFibGUJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIJAGQCBRF1c2VyQXNzZXRCb3Jyb3dlZAUGYW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgkAZAIFDWFzc2V0Qm9ycm93ZWQFBmFtb3VudAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFBmFtb3VudAkBDWdldEFzc2V0Qnl0ZXMBBQphc3NldElkU3RyBQNuaWwFEXJhdGVzUmVjYWxjUmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBXJlcGF5AAMJAQEhAQkBDXRyeUdldEJvb2xlYW4BAgxzZXR1cF9hY3RpdmUJAAIBAhFtYXJrZXQgaXMgc3RvcHBlZAMDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEGCQAAAggJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQAAAkAAgECHDEgcGF5bWVudCBoYXMgdG8gYmUgYXR0YWNoZWQECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQLYXNzZXRBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BAskdDA4Njc2ODc0MwkBDWdldEFjdHVhbFJhdGUCBQphc3NldElkU3RyAgViUmF0ZQQFYlJhdGUIBQskdDA4Njc2ODc0MwJfMQQRcmF0ZXNSZWNhbGNSZXN1bHQIBQskdDA4Njc2ODc0MwJfMgQGYW1vdW50CQBrAwULYXNzZXRBbW91bnQFB1NjYWxlMTYFBWJSYXRlBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgQNYXNzZXRTdXBwbGllZAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgQNYXNzZXRCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgQRdXNlckFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIECmFtb3VudExlZnQJAGUCBRF1c2VyQXNzZXRCb3Jyb3dlZAUGYW1vdW50BAtyZXBheUFtb3VudAMJAGcCBQphbW91bnRMZWZ0AAAFBmFtb3VudAURdXNlckFzc2V0Qm9ycm93ZWQDCQAAAgkAswkCCQEMdHJ5R2V0U3RyaW5nAQIMc2V0dXBfdG9rZW5zBQphc3NldElkU3RyBQR1bml0CQACAQIpdGhpcyBhc3NldCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBtYXJrZXQJAM4IAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgkAZQIFEXVzZXJBc3NldEJvcnJvd2VkBQtyZXBheUFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIJAGUCBQ1hc3NldEJvcnJvd2VkBQtyZXBheUFtb3VudAUDbmlsBRFyYXRlc1JlY2FsY1Jlc3VsdAMJAGcCBQphbW91bnRMZWZ0AAAFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJAQEtAQUKYW1vdW50TGVmdAgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBQNuaWwBaQEJbGlxdWlkYXRlBgVkZWJ1ZwdhZGRyZXNzC2Fzc2V0QW1vdW50C3NBc3NldElkU3RyC2JBc3NldElkU3RyCHJvdXRlU3RyAwkBAiE9AggFAWkGY2FsbGVyCQEHQWRkcmVzcwEBAAkAAgECJXRlbXBvcmFyaWx5IGxpc3RlZCBmb3Igd2hpdGVsaXN0IG9ubHkEDnVzZXJDb2xsYXRlcmFsCQESY2FsY1VzZXJDb2xsYXRlcmFsAQUHYWRkcmVzcwMJAAACBQ51c2VyQ29sbGF0ZXJhbAUOdXNlckNvbGxhdGVyYWwEDCR0MDk5OTQxMDA2MwkBDWdldEFjdHVhbFJhdGUCBQtzQXNzZXRJZFN0cgIFc1JhdGUEBXNSYXRlCAUMJHQwOTk5NDEwMDYzAl8xBBJyYXRlc1JlY2FsY1Jlc3VsdDEIBQwkdDA5OTk0MTAwNjMCXzIEDSR0MDEwMDY4MTAxMzcJAQ1nZXRBY3R1YWxSYXRlAgULYkFzc2V0SWRTdHICBWJSYXRlBAViUmF0ZQgFDSR0MDEwMDY4MTAxMzcCXzEEEnJhdGVzUmVjYWxjUmVzdWx0MggFDSR0MDEwMDY4MTAxMzcCXzIEDHNBc3NldEFtb3VudAkAawMFC2Fzc2V0QW1vdW50BQdTY2FsZTE2BQVzUmF0ZQQQY3VycmVudFNQb3NpdGlvbgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwULc0Fzc2V0SWRTdHIEEGN1cnJlbnRCUG9zaXRpb24JAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FC2JBc3NldElkU3RyAwkAZgIFDnVzZXJDb2xsYXRlcmFsAAAJAAIBAhh1c2VyIGNhbid0IGJlIGxpcXVpZGF0ZWQDCQBmAgUMc0Fzc2V0QW1vdW50BRBjdXJyZW50U1Bvc2l0aW9uCQACAQIycG9zaXRpb24gdG8gbGlxdWlkYXRlIGlzIGJpZ2dlciB0aGFuIHVzZXIncyBzdXBwbHkEEWFnZ3JlZ2F0b3JBZGRyZXNzCQEHQWRkcmVzcwEBGgFXnQyqxhNRqW7LgPdjfcFkeOLvck2oDLrTBA5iYWxhbmNlMEJlZm9yZQkBCmdldEJhbGFuY2UBBQtzQXNzZXRJZFN0cgMJAAACBQ5iYWxhbmNlMEJlZm9yZQUOYmFsYW5jZTBCZWZvcmUEDmJhbGFuY2UxQmVmb3JlCQEKZ2V0QmFsYW5jZQEFC2JBc3NldElkU3RyAwkAAAIFDmJhbGFuY2UxQmVmb3JlBQ5iYWxhbmNlMUJlZm9yZQQOZXhjaGFuZ2VJbnZva2UJAPwHBAURYWdncmVnYXRvckFkZHJlc3MCBHN3YXAJAMwIAgUIcm91dGVTdHIJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQ1nZXRBc3NldEJ5dGVzAQULc0Fzc2V0SWRTdHIFC2Fzc2V0QW1vdW50BQNuaWwDCQAAAgUOZXhjaGFuZ2VJbnZva2UFDmV4Y2hhbmdlSW52b2tlBAphc3NldDBTb2xkCQBlAgUOYmFsYW5jZTBCZWZvcmUJAQpnZXRCYWxhbmNlAQULc0Fzc2V0SWRTdHIDCQAAAgUKYXNzZXQwU29sZAUKYXNzZXQwU29sZAQMYXNzZXQxQm91Z2h0CQBlAgkBCmdldEJhbGFuY2UBBQtiQXNzZXRJZFN0cgUOYmFsYW5jZTFCZWZvcmUDCQAAAgUMYXNzZXQxQm91Z2h0BQxhc3NldDFCb3VnaHQEC2Fzc2V0MFByaWNlCAkBDWdldFRva2VuUHJpY2UBBQtzQXNzZXRJZFN0cgJfMgQLYXNzZXQwU2NhbGUJAQ5jYWxjQXNzZXRTY2FsZQEFC3NBc3NldElkU3RyBAlhc3NldDBVc2QJAGsDBQphc3NldDBTb2xkBQthc3NldDBQcmljZQULYXNzZXQwU2NhbGUEC2Fzc2V0MVByaWNlCAkBDWdldFRva2VuUHJpY2UBBQtiQXNzZXRJZFN0cgJfMQQLYXNzZXQxU2NhbGUJAQ5jYWxjQXNzZXRTY2FsZQEFC2JBc3NldElkU3RyBAlhc3NldDFVc2QJAGsDBQxhc3NldDFCb3VnaHQFC2Fzc2V0MVByaWNlBQthc3NldDFTY2FsZQQHcGVuYWx0eQkBDXBhcnNlSW50VmFsdWUBCQCRAwIJALUJAgkBDHRyeUdldFN0cmluZwECD3NldHVwX3BlbmFsdGllcwIBLAkBBXZhbHVlAQkAzwgCCQEPZ2V0TWFya2V0QXNzZXRzAAULYkFzc2V0SWRTdHIEEWxpcXVpZGF0aW9uUHJvZml0CQBlAgUJYXNzZXQxVXNkCQBrAwUJYXNzZXQwVXNkCQBlAgUGU2NhbGU4BQdwZW5hbHR5BQZTY2FsZTgEDHNBc3NldENoYW5nZQkAawMFCmFzc2V0MFNvbGQFB1NjYWxlMTYFBXNSYXRlBAxiQXNzZXRDaGFuZ2UJAGsDBQxhc3NldDFCb3VnaHQFB1NjYWxlMTYFBWJSYXRlAwkAZgIFCmFzc2V0MFNvbGQFC2Fzc2V0QW1vdW50CQACAQIjbW9yZSBhc3NldHMgZXhjaGFuZ2VkIHRoYW4gZXhwZWN0ZWQDCQBmAgAABRFsaXF1aWRhdGlvblByb2ZpdAkAAgECL3ByaWNlIGltcGFjdCBpcyBiaWdnZXIgdGhhbiBsaXF1aWRhdGlvbiBwZW5hbHR5CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwULc0Fzc2V0SWRTdHIJAGUCBRBjdXJyZW50U1Bvc2l0aW9uBQxzQXNzZXRDaGFuZ2UJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQtiQXNzZXRJZFN0cgkAZQIFEGN1cnJlbnRCUG9zaXRpb24FDGJBc3NldENoYW5nZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9zdXBwbGllZF8FC3NBc3NldElkU3RyCQBlAgkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwULc0Fzc2V0SWRTdHIFDHNBc3NldENoYW5nZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9ib3Jyb3dlZF8FC2JBc3NldElkU3RyCQBlAgkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwULYkFzc2V0SWRTdHIFDGJBc3NldENoYW5nZQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFEWxpcXVpZGF0aW9uUHJvZml0CQENZ2V0QXNzZXRCeXRlcwEFC2JBc3NldElkU3RyBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQERZ2V0VXNlckNvbGxhdGVyYWwEBWRlYnVnB2FkZHJlc3MNbWludXNCb3Jyb3dlZAthZnRlckNoYW5nZQQGYXNzZXRzCQEPZ2V0TWFya2V0QXNzZXRzAAQEbHR2cwkAtQkCCQEMdHJ5R2V0U3RyaW5nAQIKc2V0dXBfbHR2cwIBLAQDbHRzCQC1CQIJAQx0cnlHZXRTdHJpbmcBAglzZXR1cF9sdHMCASwEBXJhdGVzCAkBDWdldEFjdHVhbFJhdGUCCQCRAwIFBmFzc2V0cwAAAgVzUmF0ZQJfMgQNY2hhbmdlSGFuZGxlcgkAtQkCBQthZnRlckNoYW5nZQIBLAoBAWYCBWFjY3VtBG5leHQDCQBnAgUEbmV4dAkAkAMBBQZhc3NldHMFBWFjY3VtBAhkZWNpbWFscwMJAAACCQCRAwIFBmFzc2V0cwUEbmV4dAIFV0FWRVMACAgJAQV2YWx1ZQEJAOwHAQkA2QQBCQCRAwIFBmFzc2V0cwUEbmV4dAhkZWNpbWFscwQKYXNzZXRTY2FsZQkAbAYACgAABQhkZWNpbWFscwAAAAAFBERPV04ECmFzc2V0UHJpY2UJAQ1nZXRUb2tlblByaWNlAQkAkQMCBQZhc3NldHMFBG5leHQJAGUCCQBkAgUFYWNjdW0JAGsDCQBrAwkAawMJAGQCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfCQCRAwIFBmFzc2V0cwUEbmV4dAMDAwkBAiE9AgULYWZ0ZXJDaGFuZ2UCAAkAAAIJAJEDAgUNY2hhbmdlSGFuZGxlcgAACQCRAwIFBmFzc2V0cwUEbmV4dAcJAAACCQCRAwIFDWNoYW5nZUhhbmRsZXIAAQIIc3VwcGxpZWQHCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUNY2hhbmdlSGFuZGxlcgACAAAICQCRAwIFBXJhdGVzCQBoAgUEbmV4dAADBXZhbHVlBQdTY2FsZTE2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbHR2cwUEbmV4dAUGU2NhbGU4CAUKYXNzZXRQcmljZQJfMQUKYXNzZXRTY2FsZQMFDW1pbnVzQm9ycm93ZWQJAGsDCQBrAwkAawMJAGQCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfCQCRAwIFBmFzc2V0cwUEbmV4dAMDAwkBAiE9AgULYWZ0ZXJDaGFuZ2UCAAkAAAIJAJEDAgUNY2hhbmdlSGFuZGxlcgAACQCRAwIFBmFzc2V0cwUEbmV4dAcJAAACCQCRAwIFDWNoYW5nZUhhbmRsZXIAAQIIYm9ycm93ZWQHCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUNY2hhbmdlSGFuZGxlcgACAAAICQCRAwIFBXJhdGVzCQBkAgkAaAIFBG5leHQAAwABBXZhbHVlBQdTY2FsZTE2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDbHRzBQRuZXh0BQZTY2FsZTgIBQphc3NldFByaWNlAl8yBQphc3NldFNjYWxlAAAEBnJlc3VsdAoAAiRsCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFBQNuaWwKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjBfMQICJGECJGkDCQBnAgUC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", "height": 3329148, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: BHhDxT77EG8EhtUZteGEw15RLq6D3BJCGAvL8SSKP8WE Full:
Old | New | Differences | |
---|---|---|---|
1 | - | # no script | |
1 | + | {-# STDLIB_VERSION 6 #-} | |
2 | + | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | + | {-# CONTENT_TYPE DAPP #-} | |
4 | + | let Scale8 = 100000000 | |
5 | + | ||
6 | + | let Scale10 = 10000000000 | |
7 | + | ||
8 | + | let Scale16 = (Scale8 * Scale8) | |
9 | + | ||
10 | + | let reserveFund = 20 | |
11 | + | ||
12 | + | let dayBlocks = 1440 | |
13 | + | ||
14 | + | func tryGetInteger (key) = match getInteger(this, key) { | |
15 | + | case b: Int => | |
16 | + | b | |
17 | + | case _ => | |
18 | + | 0 | |
19 | + | } | |
20 | + | ||
21 | + | ||
22 | + | func tryGetBoolean (key) = match getBoolean(this, key) { | |
23 | + | case b: Boolean => | |
24 | + | b | |
25 | + | case _ => | |
26 | + | false | |
27 | + | } | |
28 | + | ||
29 | + | ||
30 | + | func tryGetString (key) = match getString(this, key) { | |
31 | + | case b: String => | |
32 | + | b | |
33 | + | case _ => | |
34 | + | "" | |
35 | + | } | |
36 | + | ||
37 | + | ||
38 | + | func getAssetString (assetId) = match assetId { | |
39 | + | case b: ByteVector => | |
40 | + | toBase58String(b) | |
41 | + | case _ => | |
42 | + | "WAVES" | |
43 | + | } | |
44 | + | ||
45 | + | ||
46 | + | func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES")) | |
47 | + | then unit | |
48 | + | else fromBase58String(assetIdStr) | |
49 | + | ||
50 | + | ||
51 | + | func getBalance (assetIdStr) = if ((assetIdStr == "WAVES")) | |
52 | + | then wavesBalance(this).available | |
53 | + | else assetBalance(this, fromBase58String(assetIdStr)) | |
54 | + | ||
55 | + | ||
56 | + | func getMarketAssets () = split(tryGetString("setup_tokens"), ",") | |
57 | + | ||
58 | + | ||
59 | + | func getOutdatedUr (assetIdStr) = { | |
60 | + | let down = fraction(tryGetInteger(("total_supplied_" + assetIdStr)), tryGetInteger((assetIdStr + "_sRate")), Scale16) | |
61 | + | if ((down == 0)) | |
62 | + | then 0 | |
63 | + | else fraction(Scale8, fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), tryGetInteger((assetIdStr + "_bRate")), Scale16), down) | |
64 | + | } | |
65 | + | ||
66 | + | ||
67 | + | func getInterest (assetIdStr) = { | |
68 | + | let ur = getOutdatedUr(assetIdStr) | |
69 | + | let dailyInterest = if ((80000000 >= ur)) | |
70 | + | then fraction(ur, 80000, 80000000) | |
71 | + | else (80000 + fraction((ur - 80000000), 80000, 20000000)) | |
72 | + | max([fraction(dailyInterest, Scale8, dayBlocks), 1]) | |
73 | + | } | |
74 | + | ||
75 | + | ||
76 | + | func tokenRatesRecalc (assetIdStr) = { | |
77 | + | let interest = getInterest(assetIdStr) | |
78 | + | let ur = getOutdatedUr(assetIdStr) | |
79 | + | let lastRecalcHeight = tryGetInteger("lastRateHeight") | |
80 | + | let lastBRate = max([tryGetInteger((assetIdStr + "_bRate")), Scale16]) | |
81 | + | let newBRate = (lastBRate + ((height - lastRecalcHeight) * interest)) | |
82 | + | let lastSRate = max([tryGetInteger((assetIdStr + "_sRate")), Scale16]) | |
83 | + | let newSRate = (lastSRate + ((((height - lastRecalcHeight) * fraction(interest, ur, Scale8)) * (100 - reserveFund)) / 100)) | |
84 | + | [IntegerEntry((assetIdStr + "_sRate"), newSRate), IntegerEntry((assetIdStr + "_bRate"), newBRate), IntegerEntry("lastRateHeight", height)] | |
85 | + | } | |
86 | + | ||
87 | + | ||
88 | + | func getUr (assetIdStr) = { | |
89 | + | let rates = tokenRatesRecalc(assetIdStr) | |
90 | + | let down = fraction(tryGetInteger(("total_supplied_" + assetIdStr)), rates[0].value, Scale16) | |
91 | + | fraction(Scale8, fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), rates[1].value, Scale16), down) | |
92 | + | } | |
93 | + | ||
94 | + | ||
95 | + | func getActualRate (assetIdStr,rateType) = { | |
96 | + | func f (accum,token) = { | |
97 | + | let recalc = tokenRatesRecalc(token) | |
98 | + | $Tuple2(if ((token != assetIdStr)) | |
99 | + | then accum._1 | |
100 | + | else if ((rateType == "sRate")) | |
101 | + | then recalc[0].value | |
102 | + | else recalc[1].value, (accum._2 ++ recalc)) | |
103 | + | } | |
104 | + | ||
105 | + | let $l = getMarketAssets() | |
106 | + | let $s = size($l) | |
107 | + | let $acc0 = $Tuple2(0, nil) | |
108 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
109 | + | then $a | |
110 | + | else f($a, $l[$i]) | |
111 | + | ||
112 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
113 | + | then $a | |
114 | + | else throw("List size exceeds 6") | |
115 | + | ||
116 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
117 | + | } | |
118 | + | ||
119 | + | ||
120 | + | func ratesRecalc () = { | |
121 | + | func f (accum,token) = (accum ++ tokenRatesRecalc(token)) | |
122 | + | ||
123 | + | let $l = getMarketAssets() | |
124 | + | let $s = size($l) | |
125 | + | let $acc0 = nil | |
126 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
127 | + | then $a | |
128 | + | else f($a, $l[$i]) | |
129 | + | ||
130 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
131 | + | then $a | |
132 | + | else throw("List size exceeds 6") | |
133 | + | ||
134 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
135 | + | } | |
136 | + | ||
137 | + | ||
138 | + | func getTokenPrice (assetIdStr) = { | |
139 | + | let inv = invoke(addressFromStringValue("3P5BTtdj32Sd1Dyh1Mdw33xQAAckSfMfnKf"), "getTWAP60", [assetIdStr, false], nil) | |
140 | + | if ((inv == inv)) | |
141 | + | then match inv { | |
142 | + | case x: (Int, Int) => | |
143 | + | x | |
144 | + | case _ => | |
145 | + | throw("error of price oracle") | |
146 | + | } | |
147 | + | else throw("Strict value is not equal to itself.") | |
148 | + | } | |
149 | + | ||
150 | + | ||
151 | + | func calcAssetScale (assetIdStr) = { | |
152 | + | let decimals = if ((assetIdStr == "WAVES")) | |
153 | + | then 8 | |
154 | + | else value(assetInfo(fromBase58String(assetIdStr))).decimals | |
155 | + | pow(10, 0, decimals, 0, 0, DOWN) | |
156 | + | } | |
157 | + | ||
158 | + | ||
159 | + | func calcUserCollateral (address) = { | |
160 | + | let userCollateralInvoke = invoke(this, "getUserCollateral", [false, address, true, ""], nil) | |
161 | + | if ((userCollateralInvoke == userCollateralInvoke)) | |
162 | + | then { | |
163 | + | let userCollateralValue = match userCollateralInvoke { | |
164 | + | case x: Int => | |
165 | + | x | |
166 | + | case _ => | |
167 | + | throw("issue while doing in-dapp invocation") | |
168 | + | } | |
169 | + | if ((userCollateralValue == userCollateralValue)) | |
170 | + | then userCollateralValue | |
171 | + | else throw("Strict value is not equal to itself.") | |
172 | + | } | |
173 | + | else throw("Strict value is not equal to itself.") | |
174 | + | } | |
175 | + | ||
176 | + | ||
177 | + | @Callable(i) | |
178 | + | func preInit (tokens,ltvs,lts,penalties,dailyPercent) = { | |
179 | + | func f (accum,token) = (accum ++ [IntegerEntry((token + "_bRate"), Scale16), IntegerEntry((token + "_sRate"), Scale16)]) | |
180 | + | ||
181 | + | if ((i.caller != this)) | |
182 | + | then throw("admin only") | |
183 | + | else { | |
184 | + | let rates = { | |
185 | + | let $l = split(tokens, ",") | |
186 | + | let $s = size($l) | |
187 | + | let $acc0 = nil | |
188 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
189 | + | then $a | |
190 | + | else f($a, $l[$i]) | |
191 | + | ||
192 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
193 | + | then $a | |
194 | + | else throw("List size exceeds 6") | |
195 | + | ||
196 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
197 | + | } | |
198 | + | ([StringEntry("setup_tokens", tokens), StringEntry("setup_ltvs", ltvs), StringEntry("setup_lts", lts), StringEntry("setup_penalties", penalties), BooleanEntry("setup_active", true)] ++ rates) | |
199 | + | } | |
200 | + | } | |
201 | + | ||
202 | + | ||
203 | + | ||
204 | + | @Callable(i) | |
205 | + | func supply () = if (!(tryGetBoolean("setup_active"))) | |
206 | + | then throw("market is stopped") | |
207 | + | else if (if ((size(i.payments) != 1)) | |
208 | + | then true | |
209 | + | else (i.payments[0].amount == 0)) | |
210 | + | then throw("1 payment has to be attached") | |
211 | + | else { | |
212 | + | let assetIdStr = getAssetString(i.payments[0].assetId) | |
213 | + | let assetAmount = i.payments[0].amount | |
214 | + | let $t050215088 = getActualRate(assetIdStr, "sRate") | |
215 | + | let sRate = $t050215088._1 | |
216 | + | let ratesRecalcResult = $t050215088._2 | |
217 | + | let amount = fraction(assetAmount, Scale16, sRate) | |
218 | + | let address = toString(i.caller) | |
219 | + | if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit)) | |
220 | + | then throw("this asset is not supported by the market") | |
221 | + | else ([IntegerEntry(((address + "_supplied_") + assetIdStr), (tryGetInteger(((address + "_supplied_") + assetIdStr)) + amount)), IntegerEntry(("total_supplied_" + assetIdStr), (tryGetInteger(("total_supplied_" + assetIdStr)) + amount))] ++ ratesRecalcResult) | |
222 | + | } | |
223 | + | ||
224 | + | ||
225 | + | ||
226 | + | @Callable(i) | |
227 | + | func withdraw (assetIdStr,assetAmount) = { | |
228 | + | let $t056535720 = getActualRate(assetIdStr, "sRate") | |
229 | + | let sRate = $t056535720._1 | |
230 | + | let ratesRecalcResult = $t056535720._2 | |
231 | + | let amount = fraction(assetAmount, Scale16, sRate) | |
232 | + | let address = toString(i.caller) | |
233 | + | let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr)) | |
234 | + | let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr)) | |
235 | + | let userAssetSupplied = tryGetInteger(((address + "_supplied_") + assetIdStr)) | |
236 | + | let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr)) | |
237 | + | let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",supplied,") + toString(-(amount)))], nil) | |
238 | + | if ((collateralValueInv == collateralValueInv)) | |
239 | + | then { | |
240 | + | let collateralValue = match collateralValueInv { | |
241 | + | case x: Int => | |
242 | + | x | |
243 | + | case _ => | |
244 | + | throw("can't get user collateral value") | |
245 | + | } | |
246 | + | if (!(tryGetBoolean("setup_active"))) | |
247 | + | then throw("market is stopped") | |
248 | + | else if ((0 > collateralValue)) | |
249 | + | then throw("you dont have enough collateral for this operation") | |
250 | + | else if ((amount > (assetSupplied - assetBorrowed))) | |
251 | + | then throw("this amount is not available on the market") | |
252 | + | else if ((amount > (userAssetSupplied - userAssetBorrowed))) | |
253 | + | then throw("this amount is not available for this user") | |
254 | + | else ([IntegerEntry(((address + "_supplied_") + assetIdStr), (tryGetInteger(((address + "_supplied_") + assetIdStr)) - amount)), IntegerEntry(("total_supplied_" + assetIdStr), (tryGetInteger(("total_supplied_" + assetIdStr)) - amount)), ScriptTransfer(i.caller, amount, getAssetBytes(assetIdStr))] ++ ratesRecalcResult) | |
255 | + | } | |
256 | + | else throw("Strict value is not equal to itself.") | |
257 | + | } | |
258 | + | ||
259 | + | ||
260 | + | ||
261 | + | @Callable(i) | |
262 | + | func borrow (assetIdStr,assetAmount) = { | |
263 | + | let address = toString(i.caller) | |
264 | + | let $t071997266 = getActualRate(assetIdStr, "bRate") | |
265 | + | let bRate = $t071997266._1 | |
266 | + | let ratesRecalcResult = $t071997266._2 | |
267 | + | let amount = fraction(assetAmount, Scale16, bRate) | |
268 | + | let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",borrowed,") + toString(amount))], nil) | |
269 | + | if ((collateralValueInv == collateralValueInv)) | |
270 | + | then { | |
271 | + | let collateralValue = match collateralValueInv { | |
272 | + | case x: Int => | |
273 | + | x | |
274 | + | case _ => | |
275 | + | throw("can't get user collateral value") | |
276 | + | } | |
277 | + | if (!(tryGetBoolean("setup_active"))) | |
278 | + | then throw("market is stopped") | |
279 | + | else if ((0 > collateralValue)) | |
280 | + | then throw("you have to supply more to borrow") | |
281 | + | else { | |
282 | + | let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr)) | |
283 | + | let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr)) | |
284 | + | let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr)) | |
285 | + | if ((amount > (assetSupplied - assetBorrowed))) | |
286 | + | then throw("this amount is not available") | |
287 | + | else ([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed + amount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed + amount)), ScriptTransfer(i.caller, amount, getAssetBytes(assetIdStr))] ++ ratesRecalcResult) | |
288 | + | } | |
289 | + | } | |
290 | + | else throw("Strict value is not equal to itself.") | |
291 | + | } | |
292 | + | ||
293 | + | ||
294 | + | ||
295 | + | @Callable(i) | |
296 | + | func repay () = if (!(tryGetBoolean("setup_active"))) | |
297 | + | then throw("market is stopped") | |
298 | + | else if (if ((size(i.payments) != 1)) | |
299 | + | then true | |
300 | + | else (i.payments[0].amount == 0)) | |
301 | + | then throw("1 payment has to be attached") | |
302 | + | else { | |
303 | + | let assetIdStr = getAssetString(i.payments[0].assetId) | |
304 | + | let assetAmount = i.payments[0].amount | |
305 | + | let $t086768743 = getActualRate(assetIdStr, "bRate") | |
306 | + | let bRate = $t086768743._1 | |
307 | + | let ratesRecalcResult = $t086768743._2 | |
308 | + | let amount = fraction(assetAmount, Scale16, bRate) | |
309 | + | let address = toString(i.caller) | |
310 | + | let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr)) | |
311 | + | let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr)) | |
312 | + | let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr)) | |
313 | + | let amountLeft = (userAssetBorrowed - amount) | |
314 | + | let repayAmount = if ((amountLeft >= 0)) | |
315 | + | then amount | |
316 | + | else userAssetBorrowed | |
317 | + | if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit)) | |
318 | + | then throw("this asset is not supported by the market") | |
319 | + | else (([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - repayAmount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - repayAmount))] ++ ratesRecalcResult) ++ (if ((amountLeft >= 0)) | |
320 | + | then nil | |
321 | + | else [ScriptTransfer(i.caller, -(amountLeft), i.payments[0].assetId)])) | |
322 | + | } | |
323 | + | ||
324 | + | ||
325 | + | ||
326 | + | @Callable(i) | |
327 | + | func liquidate (debug,address,assetAmount,sAssetIdStr,bAssetIdStr,routeStr) = if ((i.caller != Address(base58''))) | |
328 | + | then throw("temporarily listed for whitelist only") | |
329 | + | else { | |
330 | + | let userCollateral = calcUserCollateral(address) | |
331 | + | if ((userCollateral == userCollateral)) | |
332 | + | then { | |
333 | + | let $t0999410063 = getActualRate(sAssetIdStr, "sRate") | |
334 | + | let sRate = $t0999410063._1 | |
335 | + | let ratesRecalcResult1 = $t0999410063._2 | |
336 | + | let $t01006810137 = getActualRate(bAssetIdStr, "bRate") | |
337 | + | let bRate = $t01006810137._1 | |
338 | + | let ratesRecalcResult2 = $t01006810137._2 | |
339 | + | let sAssetAmount = fraction(assetAmount, Scale16, sRate) | |
340 | + | let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr)) | |
341 | + | let currentBPosition = tryGetInteger(((address + "_borrowed_") + bAssetIdStr)) | |
342 | + | if ((userCollateral > 0)) | |
343 | + | then throw("user can't be liquidated") | |
344 | + | else if ((sAssetAmount > currentSPosition)) | |
345 | + | then throw("position to liquidate is bigger than user's supply") | |
346 | + | else { | |
347 | + | let aggregatorAddress = Address(base58'3PGFHzVGT4NTigwCKP1NcwoXkodVZwvBuuU') | |
348 | + | let balance0Before = getBalance(sAssetIdStr) | |
349 | + | if ((balance0Before == balance0Before)) | |
350 | + | then { | |
351 | + | let balance1Before = getBalance(bAssetIdStr) | |
352 | + | if ((balance1Before == balance1Before)) | |
353 | + | then { | |
354 | + | let exchangeInvoke = invoke(aggregatorAddress, "swap", [routeStr, 0], [AttachedPayment(getAssetBytes(sAssetIdStr), assetAmount)]) | |
355 | + | if ((exchangeInvoke == exchangeInvoke)) | |
356 | + | then { | |
357 | + | let asset0Sold = (balance0Before - getBalance(sAssetIdStr)) | |
358 | + | if ((asset0Sold == asset0Sold)) | |
359 | + | then { | |
360 | + | let asset1Bought = (getBalance(bAssetIdStr) - balance1Before) | |
361 | + | if ((asset1Bought == asset1Bought)) | |
362 | + | then { | |
363 | + | let asset0Price = getTokenPrice(sAssetIdStr)._2 | |
364 | + | let asset0Scale = calcAssetScale(sAssetIdStr) | |
365 | + | let asset0Usd = fraction(asset0Sold, asset0Price, asset0Scale) | |
366 | + | let asset1Price = getTokenPrice(bAssetIdStr)._1 | |
367 | + | let asset1Scale = calcAssetScale(bAssetIdStr) | |
368 | + | let asset1Usd = fraction(asset1Bought, asset1Price, asset1Scale) | |
369 | + | let penalty = parseIntValue(split(tryGetString("setup_penalties"), ",")[value(indexOf(getMarketAssets(), bAssetIdStr))]) | |
370 | + | let liquidationProfit = (asset1Usd - fraction(asset0Usd, (Scale8 - penalty), Scale8)) | |
371 | + | let sAssetChange = fraction(asset0Sold, Scale16, sRate) | |
372 | + | let bAssetChange = fraction(asset1Bought, Scale16, bRate) | |
373 | + | if ((asset0Sold > assetAmount)) | |
374 | + | then throw("more assets exchanged than expected") | |
375 | + | else if ((0 > liquidationProfit)) | |
376 | + | then throw("price impact is bigger than liquidation penalty") | |
377 | + | else [IntegerEntry(((address + "_supplied_") + sAssetIdStr), (currentSPosition - sAssetChange)), IntegerEntry(((address + "_borrowed_") + bAssetIdStr), (currentBPosition - bAssetChange)), IntegerEntry(("total_supplied_" + sAssetIdStr), (tryGetInteger(("total_supplied_" + sAssetIdStr)) - sAssetChange)), IntegerEntry(("total_borrowed_" + bAssetIdStr), (tryGetInteger(("total_borrowed_" + bAssetIdStr)) - bAssetChange)), ScriptTransfer(i.caller, liquidationProfit, getAssetBytes(bAssetIdStr))] | |
378 | + | } | |
379 | + | else throw("Strict value is not equal to itself.") | |
380 | + | } | |
381 | + | else throw("Strict value is not equal to itself.") | |
382 | + | } | |
383 | + | else throw("Strict value is not equal to itself.") | |
384 | + | } | |
385 | + | else throw("Strict value is not equal to itself.") | |
386 | + | } | |
387 | + | else throw("Strict value is not equal to itself.") | |
388 | + | } | |
389 | + | } | |
390 | + | else throw("Strict value is not equal to itself.") | |
391 | + | } | |
392 | + | ||
393 | + | ||
394 | + | ||
395 | + | @Callable(i) | |
396 | + | func getUserCollateral (debug,address,minusBorrowed,afterChange) = { | |
397 | + | let assets = getMarketAssets() | |
398 | + | let ltvs = split(tryGetString("setup_ltvs"), ",") | |
399 | + | let lts = split(tryGetString("setup_lts"), ",") | |
400 | + | let rates = getActualRate(assets[0], "sRate")._2 | |
401 | + | let changeHandler = split(afterChange, ",") | |
402 | + | func f (accum,next) = if ((next >= size(assets))) | |
403 | + | then accum | |
404 | + | else { | |
405 | + | let decimals = if ((assets[next] == "WAVES")) | |
406 | + | then 8 | |
407 | + | else value(assetInfo(fromBase58String(assets[next]))).decimals | |
408 | + | let assetScale = pow(10, 0, decimals, 0, 0, DOWN) | |
409 | + | let assetPrice = getTokenPrice(assets[next]) | |
410 | + | ((accum + fraction(fraction(fraction((tryGetInteger(((address + "_supplied_") + assets[next])) + (if (if (if ((afterChange != "")) | |
411 | + | then (changeHandler[0] == assets[next]) | |
412 | + | else false) | |
413 | + | then (changeHandler[1] == "supplied") | |
414 | + | else false) | |
415 | + | then parseIntValue(changeHandler[2]) | |
416 | + | else 0)), rates[(next * 3)].value, Scale16), parseIntValue(ltvs[next]), Scale8), assetPrice._1, assetScale)) - (if (minusBorrowed) | |
417 | + | then fraction(fraction(fraction((tryGetInteger(((address + "_borrowed_") + assets[next])) + (if (if (if ((afterChange != "")) | |
418 | + | then (changeHandler[0] == assets[next]) | |
419 | + | else false) | |
420 | + | then (changeHandler[1] == "borrowed") | |
421 | + | else false) | |
422 | + | then parseIntValue(changeHandler[2]) | |
423 | + | else 0)), rates[((next * 3) + 1)].value, Scale16), parseIntValue(lts[next]), Scale8), assetPrice._2, assetScale) | |
424 | + | else 0)) | |
425 | + | } | |
426 | + | ||
427 | + | let result = { | |
428 | + | let $l = [0, 1, 2, 3, 4, 5] | |
429 | + | let $s = size($l) | |
430 | + | let $acc0 = 0 | |
431 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
432 | + | then $a | |
433 | + | else f($a, $l[$i]) | |
434 | + | ||
435 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
436 | + | then $a | |
437 | + | else throw("List size exceeds 6") | |
438 | + | ||
439 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
440 | + | } | |
441 | + | if (debug) | |
442 | + | then throw(toString(result)) | |
443 | + | else $Tuple2(rates, result) | |
444 | + | } | |
445 | + | ||
446 | + | ||
447 | + | ||
448 | + | @Callable(i) | |
449 | + | func getPrices (debug) = { | |
450 | + | let assets = getMarketAssets() | |
451 | + | func f (accum,next) = if ((next >= size(assets))) | |
452 | + | then accum | |
453 | + | else { | |
454 | + | let assetPrice = getTokenPrice(assets[next]) | |
455 | + | ((((accum + toString(assetPrice._1)) + ",") + toString(assetPrice._2)) + "|") | |
456 | + | } | |
457 | + | ||
458 | + | let result = { | |
459 | + | let $l = [0, 1, 2, 3, 4, 5] | |
460 | + | let $s = size($l) | |
461 | + | let $acc0 = "" | |
462 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
463 | + | then $a | |
464 | + | else f($a, $l[$i]) | |
465 | + | ||
466 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
467 | + | then $a | |
468 | + | else throw("List size exceeds 6") | |
469 | + | ||
470 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
471 | + | } | |
472 | + | if (debug) | |
473 | + | then throw(result) | |
474 | + | else $Tuple2(nil, result) | |
475 | + | } | |
476 | + | ||
477 | + | ||
478 | + | ||
479 | + | @Callable(i) | |
480 | + | func calculateUtilizationRatio (assetIdStr,debug) = if (debug) | |
481 | + | then throw(toString(getUr(assetIdStr))) | |
482 | + | else $Tuple2(nil, getUr(assetIdStr)) | |
483 | + | ||
484 | + | ||
485 | + | ||
486 | + | @Callable(i) | |
487 | + | func calculateOutdatedUR (assetIdStr,debug) = if (debug) | |
488 | + | then throw(toString(getOutdatedUr(assetIdStr))) | |
489 | + | else $Tuple2(nil, getOutdatedUr(assetIdStr)) | |
490 | + | ||
491 | + | ||
492 | + | ||
493 | + | @Callable(i) | |
494 | + | func calculateTokenRates (debug) = { | |
495 | + | func f (accum,assetIdStr) = { | |
496 | + | let rates = tokenRatesRecalc(assetIdStr) | |
497 | + | $Tuple2(((((accum._1 + toString(rates[1].value)) + "|") + toString(rates[0].value)) + ","), (accum._2 ++ rates)) | |
498 | + | } | |
499 | + | ||
500 | + | let parameter = { | |
501 | + | let $l = getMarketAssets() | |
502 | + | let $s = size($l) | |
503 | + | let $acc0 = $Tuple2("", nil) | |
504 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
505 | + | then $a | |
506 | + | else f($a, $l[$i]) | |
507 | + | ||
508 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
509 | + | then $a | |
510 | + | else throw("List size exceeds 6") | |
511 | + | ||
512 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
513 | + | } | |
514 | + | if (debug) | |
515 | + | then throw(parameter._1) | |
516 | + | else $Tuple2(parameter._2, parameter._1) | |
517 | + | } | |
518 | + | ||
519 | + | ||
520 | + | ||
521 | + | @Callable(i) | |
522 | + | func calculateTokensInterest (debug) = { | |
523 | + | func f (accum,assetIdStr) = { | |
524 | + | let rate = fraction(getInterest(assetIdStr), dayBlocks, Scale8) | |
525 | + | ((accum + toString(rate)) + ",") | |
526 | + | } | |
527 | + | ||
528 | + | let parameter = { | |
529 | + | let $l = getMarketAssets() | |
530 | + | let $s = size($l) | |
531 | + | let $acc0 = "" | |
532 | + | func $f0_1 ($a,$i) = if (($i >= $s)) | |
533 | + | then $a | |
534 | + | else f($a, $l[$i]) | |
535 | + | ||
536 | + | func $f0_2 ($a,$i) = if (($i >= $s)) | |
537 | + | then $a | |
538 | + | else throw("List size exceeds 6") | |
539 | + | ||
540 | + | $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6) | |
541 | + | } | |
542 | + | if (debug) | |
543 | + | then throw(parameter) | |
544 | + | else $Tuple2(nil, parameter) | |
545 | + | } | |
546 | + | ||
547 | + | ||
548 | + | @Verifier(tx) | |
549 | + | func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
550 | + |
github/deemru/w8io/6500d08 37.15 ms ◑