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