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