tx · DZPmtE6cH18nti7LYb6BM8VGvLRQbrSTZynamHXep1kH 3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3: -0.02600000 Waves 2024.02.08 13:17 [4032922] smart account 3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3 > SELF 0.00000000 Waves
{ "type": 13, "id": "DZPmtE6cH18nti7LYb6BM8VGvLRQbrSTZynamHXep1kH", "fee": 2600000, "feeAssetId": null, "timestamp": 1707387431548, "version": 2, "chainId": 87, "sender": "3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3", "senderPublicKey": "4XuPpm7Pz97L5yDuLYiKbCSuXvtGjxCPsUBUUzmgokhP", "proofs": [ "43D12iLTzP9FVPwEypUbBABjPxqaHFEoy9XACSjESPFnZVXmPUjhPfHwvB7C6twpYGxwrai2UPfpoLVp17yS1PBQ" ], "script": "base64:BgIuCAISBwoFCAgICAESCAoGCAgICAEIEgQKAggIEgQKAggIEgQKAggBEgUKAwQICAwAB1ZFUlNJT04CC1BMTGlxLTEuMC4yAAZTY2FsZTgAgMLXLwAHU2NhbGUxNgCAgIT+pt7hEQENZ2V0QXNzZXRCeXRlcwEKYXNzZXRJZFN0cgMJAAACBQphc3NldElkU3RyAgVXQVZFUwUEdW5pdAkA2QQBBQphc3NldElkU3RyARZ2ZXJpZnlMaXF1aWRhdG9yQWNjZXNzAQdhZGRyZXNzCQECIT0CCQCzCQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwIRc2V0dXBfbGlxdWlkYXRvcnMCAAkApQgBBQdhZGRyZXNzBQR1bml0ABNNYXhTaGFyZVRvTGlxdWlkYXRlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMCGXNldHVwX21heFNoYXJlVG9MaXF1aWRhdGUAZAAQTGlxdWlkYXRpb25EZWxheQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzAhZzZXR1cF9saXF1aWRhdGlvbkRlbGF5AAoAEExpcXVpZGF0b3JSZXdhcmQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwIWc2V0dXBfbGlxdWlkYXRvclJld2FyZAAKABFCYWREZWJ0TGlxQWxsb3dlZAkAZgIJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwIXc2V0dXBfYmFkRGVidExpcUFsbG93ZWQAAAAAAA1PcmFjbGVBZGRyZXNzCQELdmFsdWVPckVsc2UCCQCmCAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwIUc2V0dXBfYWRkcmVzc19vcmFjbGUCAAkBB0FkZHJlc3MBARoBV0lm0MvzivVXeq38IW9xxVuJiCvQgbOxfwAHbWFya2V0cwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzAg1zZXR1cF9tYXJrZXRzCQC5CQIJAMwIAgIjM1BIcHVRVVBWVW9SM0FZekZlSnplV0pmWUxzTFRtV3NzVkgFA25pbAIBLAEWZ2V0VXNlckJhbGFuY2VJTlRFUk5BTAMGbWFya2V0B2FkZHJlc3MNbWludXNCb3Jyb3dlZAoBDHRyeUdldFN0cmluZwEDa2V5BAckbWF0Y2gwCQCdCAIFBm1hcmtldAUDa2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQBYgUHJG1hdGNoMAUBYgIACgENdHJ5R2V0SW50ZWdlcgEDa2V5BAckbWF0Y2gwCQCaCAIFBm1hcmtldAUDa2V5AwkAAQIFByRtYXRjaDACA0ludAQBYgUHJG1hdGNoMAUBYgAACgENZ2V0VG9rZW5QcmljZQEKYXNzZXRJZFN0cgMDAwkAAAIFCmFzc2V0SWRTdHICLEFQNENiNXhMWUdINlppZ0hyZUNaSG9YcFFUV0RrUHNHMkJIcWZEVXg2dGFKBgkAAAIFCmFzc2V0SWRTdHICLDl3YzNMWE5BNFRFQnNYeUt0b0xFOW1yYkREN1dNSFh2WHJDalp2YWJMQXNpBgkAAAIFCmFzc2V0SWRTdHICLEhHZ2FiVHFVUzhXdFZGVUp6Zm1yVERNZ0VjY0p1WkxCUGhGZ1FGeHZuc29XCQCUCgIAwIQ9AMCEPQQFcHJpY2UJARFAZXh0ck5hdGl2ZSgxMDUwKQIFDU9yYWNsZUFkZHJlc3MJAKwCAgUKYXNzZXRJZFN0cgIHX3R3YXA1QgkAlAoCBQVwcmljZQUFcHJpY2UKAQ5jYWxjQXNzZXRTY2FsZQEKYXNzZXRJZFN0cgQIZGVjaW1hbHMDCQAAAgUKYXNzZXRJZFN0cgIFV0FWRVMACAgJAQV2YWx1ZQEJAOwHAQkA2QQBBQphc3NldElkU3RyCGRlY2ltYWxzCQBsBgAKAAAFCGRlY2ltYWxzAAAAAAUERE9XTgQGYXNzZXRzCQC1CQIJAQx0cnlHZXRTdHJpbmcBAgxzZXR1cF90b2tlbnMCASwEBGx0dnMJALUJAgkBDHRyeUdldFN0cmluZwECCnNldHVwX2x0dnMCASwEA2x0cwkAtQkCCQEMdHJ5R2V0U3RyaW5nAQIJc2V0dXBfbHRzAgEsCgEBZgIFYWNjdW0EbmV4dAMJAGcCBQRuZXh0CQCQAwEFBmFzc2V0cwUFYWNjdW0EDHVzZXJTdXBwbGllZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwkAkQMCBQZhc3NldHMFBG5leHQEDHVzZXJCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwkAkQMCBQZhc3NldHMFBG5leHQEE25lZWRUb2tlbkFjY291bnRpbmcDAwkBAiE9AgUMdXNlckJvcnJvd2VkAAAGCQECIT0CBQx1c2VyU3VwcGxpZWQAAAYHAwUTbmVlZFRva2VuQWNjb3VudGluZwQKYXNzZXRTY2FsZQkBDmNhbGNBc3NldFNjYWxlAQkAkQMCBQZhc3NldHMFBG5leHQECmFzc2V0UHJpY2UJAQ1nZXRUb2tlblByaWNlAQkAkQMCBQZhc3NldHMFBG5leHQJAGUCCQBkAgUFYWNjdW0JAGsDCQBrAwUMdXNlclN1cHBsaWVkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkAkQMCBQZhc3NldHMFBG5leHQCBl9zUmF0ZQUHU2NhbGUxNggFCmFzc2V0UHJpY2UCXzEFCmFzc2V0U2NhbGUDBQ1taW51c0JvcnJvd2VkCQBrAwkAawMFDHVzZXJCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAJEDAgUGYXNzZXRzBQRuZXh0AgZfYlJhdGUFB1NjYWxlMTYIBQphc3NldFByaWNlAl8xBQphc3NldFNjYWxlAAAFBWFjY3VtBAZyZXN1bHQKAAIkbAkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYJAMwIAgAHCQDMCAIACAkAzAgCAAkJAMwIAgAKCQDMCAIACwUDbmlsCgACJHMJAJADAQUCJGwKAAUkYWNjMAAACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFmAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAUGcmVzdWx0BgFpARBwcm94eUxpcXVpZGF0ZVYyBQZtYXJrZXQLdXNlckFkZHJlc3MOZGVidEFzc2V0SWRTdHISc3VwcGxpZWRBc3NldElkU3RyBmFtb3VudAMJAAACCQCzCQIFB21hcmtldHMFBm1hcmtldAUEdW5pdAkAAgECIGdpdmVuIHBvb2wgYWRkcmVzcyBpcyBub3QgYSBwb29sAwkBASEBCQEWdmVyaWZ5TGlxdWlkYXRvckFjY2VzcwEIBQFpBmNhbGxlcgkAAgECJG5vIHBlcm1pc3Npb24gdG8gcGVyZm9ybSBsaXF1aWRhdGlvbgQDaW52CQD8BwQJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBm1hcmtldAILbGlxdWlkYXRlVjIJAMwIAgcJAMwIAgULdXNlckFkZHJlc3MJAMwIAgUSc3VwcGxpZWRBc3NldElkU3RyBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQ1nZXRBc3NldEJ5dGVzAQUOZGVidEFzc2V0SWRTdHIFBmFtb3VudAUDbmlsAwkAAAIFA2ludgUDaW52BBJ1c2VyQm9ycm93ZWRBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgkBEUBleHRyTmF0aXZlKDEwNjIpAQUGbWFya2V0CQCsAgIJAKwCAgULdXNlckFkZHJlc3MCCl9ib3Jyb3dlZF8FDmRlYnRBc3NldElkU3RyAAADCQBmAgAABRJ1c2VyQm9ycm93ZWRBbW91bnQJAAIBAi90cmFuc2FjdGlvbiBsZWFkcyB0byBhIG5lZ2F0aXZlIGJvcnJvd2VkIGFtb3VudAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEHByb3h5TGlxdWlkYXRlVjMGBm1hcmtldAt1c2VyQWRkcmVzcw5kZWJ0QXNzZXRJZFN0chJzdXBwbGllZEFzc2V0SWRTdHIGYW1vdW50CHJvdXRlU3RyAwkAAAIJALMJAgUHbWFya2V0cwUGbWFya2V0BQR1bml0CQACAQIkZ2l2ZW4gbWFya2V0IGFkZHJlc3MgaXMgbm90IGEgbWFya2V0AwkBASEBCQEWdmVyaWZ5TGlxdWlkYXRvckFjY2VzcwEIBQFpBmNhbGxlcgkAAgECJG5vIHBlcm1pc3Npb24gdG8gcGVyZm9ybSBsaXF1aWRhdGlvbgQNbWFya2V0QWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQUGbWFya2V0BAVzUmF0ZQkBEUBleHRyTmF0aXZlKDEwNTApAgUNbWFya2V0QWRkcmVzcwkArAICBRJzdXBwbGllZEFzc2V0SWRTdHICBl9zUmF0ZQQHc0Ftb3VudAkBEUBleHRyTmF0aXZlKDEwNTApAgUNbWFya2V0QWRkcmVzcwkArAICCQCsAgIFC3VzZXJBZGRyZXNzAgpfc3VwcGxpZWRfBRJzdXBwbGllZEFzc2V0SWRTdHIEDnN1cHBsaWVkQW1vdW50CQBrAwUHc0Ftb3VudAUFc1JhdGUFB1NjYWxlMTYEFmxhc3RMaXFGb3JNYXJrZXRLZXlTdHIJAKwCAgkArAICAg9oaXN0b3J5X21hcmtldF8FBm1hcmtldAIQX2xhc3RMaXF1aWRhdGlvbgQVbGFzdExpcXVpZGF0aW9uS2V5U3RyCQCsAgIJAKwCAgINaGlzdG9yeV91c2VyXwULdXNlckFkZHJlc3MCEF9sYXN0TGlxdWlkYXRpb24ED2xhc3RMaXF1aWRhdGlvbgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRVsYXN0TGlxdWlkYXRpb25LZXlTdHIAAAMJAGYCBQZhbW91bnQJAGsDBRNNYXhTaGFyZVRvTGlxdWlkYXRlBQ5zdXBwbGllZEFtb3VudACQTgkAAgECJnNob3VsZCBsaXF1aWRhdGUgc21hbGxlciBwYXJ0IHBlciB0aW1lAwkAZgIJAGQCBQ9sYXN0TGlxdWlkYXRpb24FEExpcXVpZGF0aW9uRGVsYXkFBmhlaWdodAkAAgECFGNhbm5vdCBsaXF1aWRhdGUgeWV0BANpbnYJAPwHBAUNbWFya2V0QWRkcmVzcwIJbGlxdWlkYXRlCQDMCAIHCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIFBmFtb3VudAkAzAgCBRJzdXBwbGllZEFzc2V0SWRTdHIJAMwIAgUOZGVidEFzc2V0SWRTdHIJAMwIAgUIcm91dGVTdHIFA25pbAUDbmlsAwkAAAIFA2ludgUDaW52BBJ1c2VyQm9ycm93ZWRBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUNbWFya2V0QWRkcmVzcwkArAICCQCsAgIFC3VzZXJBZGRyZXNzAgpfYm9ycm93ZWRfBQ5kZWJ0QXNzZXRJZFN0cgAABA51c2VyVXNkQmFsYW5jZQkBFmdldFVzZXJCYWxhbmNlSU5URVJOQUwDBQ1tYXJrZXRBZGRyZXNzBQt1c2VyQWRkcmVzcwYDCQBmAgAABRJ1c2VyQm9ycm93ZWRBbW91bnQJAAIBAi90cmFuc2FjdGlvbiBsZWFkcyB0byBhIG5lZ2F0aXZlIGJvcnJvd2VkIGFtb3VudAMDCQEBIQEFEUJhZERlYnRMaXFBbGxvd2VkCQBnAgAABQ51c2VyVXNkQmFsYW5jZQcJAAIBAh90cmFuc2FjdGlvbiBsZWFkcyB0byBhIGJhZCBkZWJ0BBBsaXF1aWRhdG9yUmV3YXJkCQBrAwUGYW1vdW50BRBMaXF1aWRhdG9yUmV3YXJkAJBOBAtzdGF0c0tleVN0cgkArAICCQCsAgIJAKwCAgIHcmV3YXJkXwkApQgBCAUBaQZjYWxsZXICAV8FEnN1cHBsaWVkQXNzZXRJZFN0cgkAzAgCCQEMSW50ZWdlckVudHJ5AgULc3RhdHNLZXlTdHIJAGQCCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFC3N0YXRzS2V5U3RyAAAFEGxpcXVpZGF0b3JSZXdhcmQJAMwIAgkBDEludGVnZXJFbnRyeQIFFWxhc3RMaXF1aWRhdGlvbktleVN0cgUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRZsYXN0TGlxRm9yTWFya2V0S2V5U3RyBQZoZWlnaHQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQxwYXlvdXRSZXdhcmQCCmFkZHJlc3NTdHIKYXNzZXRJZFN0cgMJAQIhPQIJAKUIAQgFAWkGY2FsbGVyAiMzUE1jTWlNRXM2dzU2TlJHYWNrc1h0Rkc1elM3ZG9FOWZwTAkAAgECGG5vIGFjY2VzcyB0byB0aGlzIG1ldGhvZAQLc3RhdHNLZXlTdHIJAKwCAgkArAICCQCsAgICB3Jld2FyZF8FCmFkZHJlc3NTdHICAV8FCmFzc2V0SWRTdHIED3Jld2FyZEF2YWlsYWJsZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQtzdGF0c0tleVN0cgAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFCmFkZHJlc3NTdHIFD3Jld2FyZEF2YWlsYWJsZQkBDWdldEFzc2V0Qnl0ZXMBBQphc3NldElkU3RyCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQtzdGF0c0tleVN0cgAABQNuaWwBaQEMdXBkYXRlU3RyaW5nAgNrZXkDdmFsAwMJAQIhPQIJAKUIAQgFAWkGY2FsbGVyAiMzUE1jTWlNRXM2dzU2TlJHYWNrc1h0Rkc1elM3ZG9FOWZwTAkBAiE9AgkApQgBCAUBaQZjYWxsZXICIzNQSGJkcGFLeno4RWlBbmdHSGFGdTJoVnVOQ2RzQzY3cWgzBwkAAgECGG5vIGFjY2VzcyB0byB0aGlzIG1ldGhvZAkAzAgCCQELU3RyaW5nRW50cnkCBQNrZXkFA3ZhbAUDbmlsAWkBDXVwZGF0ZUludGVnZXICA2tleQN2YWwDAwkBAiE9AgkApQgBCAUBaQZjYWxsZXICIzNQTWNNaU1FczZ3NTZOUkdhY2tzWHRGRzV6Uzdkb0U5ZnBMCQECIT0CCQClCAEIBQFpBmNhbGxlcgIjM1BIYmRwYUt6ejhFaUFuZ0dIYUZ1MmhWdU5DZHNDNjdxaDMHCQACAQIYbm8gYWNjZXNzIHRvIHRoaXMgbWV0aG9kCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQNrZXkFA3ZhbAUDbmlsAWkBFmdldFVzZXJCYWxhbmNlUkVBRE9OTFkDBWRlYnVnCW1hcmtldFN0cgdhZGRyZXNzBANyZXMJARZnZXRVc2VyQmFsYW5jZUlOVEVSTkFMAwkBEUBleHRyTmF0aXZlKDEwNjIpAQUJbWFya2V0U3RyBQdhZGRyZXNzBgMJAAACBQVkZWJ1ZwYJAAIBCQCkAwEFA3JlcwkAlAoCBQNuaWwFA3JlcwBwhriW", "height": 4032922, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: tJfYezoWRQHALRdTQT13jZTRZwirE2SgxdFSXsKPgoR Next: none Diff:
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 6 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | - | let VERSION = "PLLiq-1.0. | |
4 | + | let VERSION = "PLLiq-1.0.2" | |
5 | 5 | ||
6 | 6 | let Scale8 = 100000000 | |
7 | 7 | ||
25 | 25 | ||
26 | 26 | let OracleAddress = valueOrElse(addressFromString(valueOrElse(getString(this, "setup_address_oracle"), "")), Address(base58'3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t')) | |
27 | 27 | ||
28 | - | let markets = valueOrElse(getString(this, "setup_markets"), makeString([" | |
28 | + | let markets = valueOrElse(getString(this, "setup_markets"), makeString(["3PHpuQUPVUoR3AYzFeJzeWJfYLsLTmWssVH"], ",")) | |
29 | 29 | ||
30 | 30 | func getUserBalanceINTERNAL (market,address,minusBorrowed) = { | |
31 | 31 | func tryGetString (key) = match getString(market, key) { | |
105 | 105 | @Callable(i) | |
106 | 106 | func proxyLiquidateV2 (market,userAddress,debtAssetIdStr,suppliedAssetIdStr,amount) = if ((indexOf(markets, market) == unit)) | |
107 | 107 | then throw("given pool address is not a pool") | |
108 | - | else { | |
109 | - | let inv = invoke(addressFromStringValue(market), "liquidateV2", [false, userAddress, suppliedAssetIdStr], [AttachedPayment(getAssetBytes(debtAssetIdStr), amount)]) | |
110 | - | if ((inv == inv)) | |
111 | - | then nil | |
112 | - | else throw("Strict value is not equal to itself.") | |
113 | - | } | |
108 | + | else if (!(verifyLiquidatorAccess(i.caller))) | |
109 | + | then throw("no permission to perform liquidation") | |
110 | + | else { | |
111 | + | let inv = invoke(addressFromStringValue(market), "liquidateV2", [false, userAddress, suppliedAssetIdStr], [AttachedPayment(getAssetBytes(debtAssetIdStr), amount)]) | |
112 | + | if ((inv == inv)) | |
113 | + | then { | |
114 | + | let userBorrowedAmount = valueOrElse(getInteger(addressFromStringValue(market), ((userAddress + "_borrowed_") + debtAssetIdStr)), 0) | |
115 | + | if ((0 > userBorrowedAmount)) | |
116 | + | then throw("transaction leads to a negative borrowed amount") | |
117 | + | else nil | |
118 | + | } | |
119 | + | else throw("Strict value is not equal to itself.") | |
120 | + | } | |
114 | 121 | ||
115 | 122 | ||
116 | 123 |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 6 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | - | let VERSION = "PLLiq-1.0. | |
4 | + | let VERSION = "PLLiq-1.0.2" | |
5 | 5 | ||
6 | 6 | let Scale8 = 100000000 | |
7 | 7 | ||
8 | 8 | let Scale16 = 10000000000000000 | |
9 | 9 | ||
10 | 10 | func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES")) | |
11 | 11 | then unit | |
12 | 12 | else fromBase58String(assetIdStr) | |
13 | 13 | ||
14 | 14 | ||
15 | 15 | func verifyLiquidatorAccess (address) = (indexOf(valueOrElse(getString(this, "setup_liquidators"), ""), toString(address)) != unit) | |
16 | 16 | ||
17 | 17 | ||
18 | 18 | let MaxShareToLiquidate = valueOrElse(getInteger(this, "setup_maxShareToLiquidate"), 100) | |
19 | 19 | ||
20 | 20 | let LiquidationDelay = valueOrElse(getInteger(this, "setup_liquidationDelay"), 10) | |
21 | 21 | ||
22 | 22 | let LiquidatorReward = valueOrElse(getInteger(this, "setup_liquidatorReward"), 10) | |
23 | 23 | ||
24 | 24 | let BadDebtLiqAllowed = (valueOrElse(getInteger(this, "setup_badDebtLiqAllowed"), 0) > 0) | |
25 | 25 | ||
26 | 26 | let OracleAddress = valueOrElse(addressFromString(valueOrElse(getString(this, "setup_address_oracle"), "")), Address(base58'3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t')) | |
27 | 27 | ||
28 | - | let markets = valueOrElse(getString(this, "setup_markets"), makeString([" | |
28 | + | let markets = valueOrElse(getString(this, "setup_markets"), makeString(["3PHpuQUPVUoR3AYzFeJzeWJfYLsLTmWssVH"], ",")) | |
29 | 29 | ||
30 | 30 | func getUserBalanceINTERNAL (market,address,minusBorrowed) = { | |
31 | 31 | func tryGetString (key) = match getString(market, key) { | |
32 | 32 | case b: String => | |
33 | 33 | b | |
34 | 34 | case _ => | |
35 | 35 | "" | |
36 | 36 | } | |
37 | 37 | ||
38 | 38 | func tryGetInteger (key) = match getInteger(market, key) { | |
39 | 39 | case b: Int => | |
40 | 40 | b | |
41 | 41 | case _ => | |
42 | 42 | 0 | |
43 | 43 | } | |
44 | 44 | ||
45 | 45 | func getTokenPrice (assetIdStr) = if (if (if ((assetIdStr == "AP4Cb5xLYGH6ZigHreCZHoXpQTWDkPsG2BHqfDUx6taJ")) | |
46 | 46 | then true | |
47 | 47 | else (assetIdStr == "9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi")) | |
48 | 48 | then true | |
49 | 49 | else (assetIdStr == "HGgabTqUS8WtVFUJzfmrTDMgEccJuZLBPhFgQFxvnsoW")) | |
50 | 50 | then $Tuple2(1000000, 1000000) | |
51 | 51 | else { | |
52 | 52 | let price = getIntegerValue(OracleAddress, (assetIdStr + "_twap5B")) | |
53 | 53 | $Tuple2(price, price) | |
54 | 54 | } | |
55 | 55 | ||
56 | 56 | func calcAssetScale (assetIdStr) = { | |
57 | 57 | let decimals = if ((assetIdStr == "WAVES")) | |
58 | 58 | then 8 | |
59 | 59 | else value(assetInfo(fromBase58String(assetIdStr))).decimals | |
60 | 60 | pow(10, 0, decimals, 0, 0, DOWN) | |
61 | 61 | } | |
62 | 62 | ||
63 | 63 | let assets = split(tryGetString("setup_tokens"), ",") | |
64 | 64 | let ltvs = split(tryGetString("setup_ltvs"), ",") | |
65 | 65 | let lts = split(tryGetString("setup_lts"), ",") | |
66 | 66 | func f (accum,next) = if ((next >= size(assets))) | |
67 | 67 | then accum | |
68 | 68 | else { | |
69 | 69 | let userSupplied = tryGetInteger(((address + "_supplied_") + assets[next])) | |
70 | 70 | let userBorrowed = tryGetInteger(((address + "_borrowed_") + assets[next])) | |
71 | 71 | let needTokenAccounting = if (if ((userBorrowed != 0)) | |
72 | 72 | then true | |
73 | 73 | else (userSupplied != 0)) | |
74 | 74 | then true | |
75 | 75 | else false | |
76 | 76 | if (needTokenAccounting) | |
77 | 77 | then { | |
78 | 78 | let assetScale = calcAssetScale(assets[next]) | |
79 | 79 | let assetPrice = getTokenPrice(assets[next]) | |
80 | 80 | ((accum + fraction(fraction(userSupplied, tryGetInteger((assets[next] + "_sRate")), Scale16), assetPrice._1, assetScale)) - (if (minusBorrowed) | |
81 | 81 | then fraction(fraction(userBorrowed, tryGetInteger((assets[next] + "_bRate")), Scale16), assetPrice._1, assetScale) | |
82 | 82 | else 0)) | |
83 | 83 | } | |
84 | 84 | else accum | |
85 | 85 | } | |
86 | 86 | ||
87 | 87 | let result = { | |
88 | 88 | let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] | |
89 | 89 | let $s = size($l) | |
90 | 90 | let $acc0 = 0 | |
91 | 91 | func $f0_1 ($a,$i) = if (($i >= $s)) | |
92 | 92 | then $a | |
93 | 93 | else f($a, $l[$i]) | |
94 | 94 | ||
95 | 95 | func $f0_2 ($a,$i) = if (($i >= $s)) | |
96 | 96 | then $a | |
97 | 97 | else throw("List size exceeds 12") | |
98 | 98 | ||
99 | 99 | $f0_2($f0_1($f0_1($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), 11), 12) | |
100 | 100 | } | |
101 | 101 | result | |
102 | 102 | } | |
103 | 103 | ||
104 | 104 | ||
105 | 105 | @Callable(i) | |
106 | 106 | func proxyLiquidateV2 (market,userAddress,debtAssetIdStr,suppliedAssetIdStr,amount) = if ((indexOf(markets, market) == unit)) | |
107 | 107 | then throw("given pool address is not a pool") | |
108 | - | else { | |
109 | - | let inv = invoke(addressFromStringValue(market), "liquidateV2", [false, userAddress, suppliedAssetIdStr], [AttachedPayment(getAssetBytes(debtAssetIdStr), amount)]) | |
110 | - | if ((inv == inv)) | |
111 | - | then nil | |
112 | - | else throw("Strict value is not equal to itself.") | |
113 | - | } | |
108 | + | else if (!(verifyLiquidatorAccess(i.caller))) | |
109 | + | then throw("no permission to perform liquidation") | |
110 | + | else { | |
111 | + | let inv = invoke(addressFromStringValue(market), "liquidateV2", [false, userAddress, suppliedAssetIdStr], [AttachedPayment(getAssetBytes(debtAssetIdStr), amount)]) | |
112 | + | if ((inv == inv)) | |
113 | + | then { | |
114 | + | let userBorrowedAmount = valueOrElse(getInteger(addressFromStringValue(market), ((userAddress + "_borrowed_") + debtAssetIdStr)), 0) | |
115 | + | if ((0 > userBorrowedAmount)) | |
116 | + | then throw("transaction leads to a negative borrowed amount") | |
117 | + | else nil | |
118 | + | } | |
119 | + | else throw("Strict value is not equal to itself.") | |
120 | + | } | |
114 | 121 | ||
115 | 122 | ||
116 | 123 | ||
117 | 124 | @Callable(i) | |
118 | 125 | func proxyLiquidateV3 (market,userAddress,debtAssetIdStr,suppliedAssetIdStr,amount,routeStr) = if ((indexOf(markets, market) == unit)) | |
119 | 126 | then throw("given market address is not a market") | |
120 | 127 | else if (!(verifyLiquidatorAccess(i.caller))) | |
121 | 128 | then throw("no permission to perform liquidation") | |
122 | 129 | else { | |
123 | 130 | let marketAddress = addressFromStringValue(market) | |
124 | 131 | let sRate = getIntegerValue(marketAddress, (suppliedAssetIdStr + "_sRate")) | |
125 | 132 | let sAmount = getIntegerValue(marketAddress, ((userAddress + "_supplied_") + suppliedAssetIdStr)) | |
126 | 133 | let suppliedAmount = fraction(sAmount, sRate, Scale16) | |
127 | 134 | let lastLiqForMarketKeyStr = (("history_market_" + market) + "_lastLiquidation") | |
128 | 135 | let lastLiquidationKeyStr = (("history_user_" + userAddress) + "_lastLiquidation") | |
129 | 136 | let lastLiquidation = valueOrElse(getInteger(this, lastLiquidationKeyStr), 0) | |
130 | 137 | if ((amount > fraction(MaxShareToLiquidate, suppliedAmount, 10000))) | |
131 | 138 | then throw("should liquidate smaller part per time") | |
132 | 139 | else if (((lastLiquidation + LiquidationDelay) > height)) | |
133 | 140 | then throw("cannot liquidate yet") | |
134 | 141 | else { | |
135 | 142 | let inv = invoke(marketAddress, "liquidate", [false, userAddress, amount, suppliedAssetIdStr, debtAssetIdStr, routeStr], nil) | |
136 | 143 | if ((inv == inv)) | |
137 | 144 | then { | |
138 | 145 | let userBorrowedAmount = valueOrElse(getInteger(marketAddress, ((userAddress + "_borrowed_") + debtAssetIdStr)), 0) | |
139 | 146 | let userUsdBalance = getUserBalanceINTERNAL(marketAddress, userAddress, true) | |
140 | 147 | if ((0 > userBorrowedAmount)) | |
141 | 148 | then throw("transaction leads to a negative borrowed amount") | |
142 | 149 | else if (if (!(BadDebtLiqAllowed)) | |
143 | 150 | then (0 >= userUsdBalance) | |
144 | 151 | else false) | |
145 | 152 | then throw("transaction leads to a bad debt") | |
146 | 153 | else { | |
147 | 154 | let liquidatorReward = fraction(amount, LiquidatorReward, 10000) | |
148 | 155 | let statsKeyStr = ((("reward_" + toString(i.caller)) + "_") + suppliedAssetIdStr) | |
149 | 156 | [IntegerEntry(statsKeyStr, (valueOrElse(getInteger(this, statsKeyStr), 0) + liquidatorReward)), IntegerEntry(lastLiquidationKeyStr, height), IntegerEntry(lastLiqForMarketKeyStr, height)] | |
150 | 157 | } | |
151 | 158 | } | |
152 | 159 | else throw("Strict value is not equal to itself.") | |
153 | 160 | } | |
154 | 161 | } | |
155 | 162 | ||
156 | 163 | ||
157 | 164 | ||
158 | 165 | @Callable(i) | |
159 | 166 | func payoutReward (addressStr,assetIdStr) = if ((toString(i.caller) != "3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL")) | |
160 | 167 | then throw("no access to this method") | |
161 | 168 | else { | |
162 | 169 | let statsKeyStr = ((("reward_" + addressStr) + "_") + assetIdStr) | |
163 | 170 | let rewardAvailable = valueOrElse(getInteger(this, statsKeyStr), 0) | |
164 | 171 | [ScriptTransfer(addressFromStringValue(addressStr), rewardAvailable, getAssetBytes(assetIdStr)), IntegerEntry(statsKeyStr, 0)] | |
165 | 172 | } | |
166 | 173 | ||
167 | 174 | ||
168 | 175 | ||
169 | 176 | @Callable(i) | |
170 | 177 | func updateString (key,val) = if (if ((toString(i.caller) != "3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL")) | |
171 | 178 | then (toString(i.caller) != "3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3") | |
172 | 179 | else false) | |
173 | 180 | then throw("no access to this method") | |
174 | 181 | else [StringEntry(key, val)] | |
175 | 182 | ||
176 | 183 | ||
177 | 184 | ||
178 | 185 | @Callable(i) | |
179 | 186 | func updateInteger (key,val) = if (if ((toString(i.caller) != "3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL")) | |
180 | 187 | then (toString(i.caller) != "3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3") | |
181 | 188 | else false) | |
182 | 189 | then throw("no access to this method") | |
183 | 190 | else [IntegerEntry(key, val)] | |
184 | 191 | ||
185 | 192 | ||
186 | 193 | ||
187 | 194 | @Callable(i) | |
188 | 195 | func getUserBalanceREADONLY (debug,marketStr,address) = { | |
189 | 196 | let res = getUserBalanceINTERNAL(addressFromStringValue(marketStr), address, true) | |
190 | 197 | if ((debug == true)) | |
191 | 198 | then throw(toString(res)) | |
192 | 199 | else $Tuple2(nil, res) | |
193 | 200 | } | |
194 | 201 | ||
195 | 202 |
github/deemru/w8io/3ef1775 40.05 ms ◑