tx · AQaRenXR23AbtBozQWAFmp6hJs3HCxdLYKsG67bq4qQM 3MHrtN61qab1ntynJZi94kyQjnqWXmQHjZR: -0.06000000 Waves 2026.06.24 04:14 [824680] smart account 3MHrtN61qab1ntynJZi94kyQjnqWXmQHjZR > SELF 0.00000000 Waves
{ "type": 13, "id": "AQaRenXR23AbtBozQWAFmp6hJs3HCxdLYKsG67bq4qQM", "fee": 6000000, "feeAssetId": null, "timestamp": 1782263685306, "version": 2, "chainId": 82, "sender": "3MHrtN61qab1ntynJZi94kyQjnqWXmQHjZR", "senderPublicKey": "GMjhhbZyRz6noRpKsa8vsQ7SEs8XTzfdhnaS1th1H72G", "proofs": [ "3GDuU9d7KEnZSAdNh8sQQcGYvU1CDwjRLZFQjwKdfe1QAzEpyn7j68Usme523hP4L9vqLxQcrt8gFWjFapdsb6me" ], "script": "base64:BgInCAISBgoECAEBARIFCgMIAQgSAwoBBBIECgIICBIECgIIARIDCgEIDgANQ09OVFJBQ1RfVFlQRQIRTEVORF9GRUVDT0xMRUNUT1IAB1ZFUlNJT04CCUxGQy0wLjAuMQAIa19hY3RpdmUCDHNldHVwX2FjdGl2ZQAJa19tYXJrZXRzAg1zZXR1cF9tYXJrZXRzABNrX3NodXRkb3duQWRkcmVzc2VzAhdzZXR1cF9zaHV0ZG93bkFkZHJlc3NlcwALc2h1dGRvd25lcnMJAMwIAgIjM1BNY01pTUVzNnc1Nk5SR2Fja3NYdEZHNXpTN2RvRTlmcEwJAMwIAgIjM1BKdTNwYjdCU1Q1WFY3cVVpSFdES21yekFrRXBEU0Nld2EFA25pbAAHbWFya2V0cwkAzAgCAiMzUDR1QTVldG5aaTRBbUJhYktpbnEyYk1pV1U4S2NuSFpkSAkAzAgCAiMzUDRESzVWekR3TDN2ZmM1YWhVRWh0b2U1QnlaTnlhY0ozWAkAzAgCAiMzUEhwdVFVUFZVb1IzQVl6RmVKemVXSmZZTHNMVG1Xc3NWSAkAzAgCAiMzUDhEZjJiN3l3SHRMQkhCZThQQlZRWWQzQTVNZEVFSkFvdQkAzAgCAiMzUEFkOUFxZzNjUVN6dTI2TUZZV1FZY2pTWFBWQ0p0dWY1VgUDbmlsAQ10cnlHZXRJbnRlZ2VyAQNrZXkEByRtYXRjaDAJAJoIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACA0ludAQBYgUHJG1hdGNoMAUBYgAAAQ1nZXRBc3NldEJ5dGVzAQphc3NldElkU3RyAwkAAAIFCmFzc2V0SWRTdHICBVdBVkVTBQR1bml0CQDZBAEFCmFzc2V0SWRTdHIBDmdldEFzc2V0U3RyaW5nAQdhc3NldElkBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAWIFByRtYXRjaDAJANgEAQUBYgIFV0FWRVMBCGlzUGF1c2VkAAkBASEBCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMFCGtfYWN0aXZlBgEOZ2V0QWRkcmVzc0xpc3QCA2tleQdkZWZhdWx0BAckbWF0Y2gwCQCdCAIFBHRoaXMFA2tleQMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJALwJAgUBcwIBLAUHZGVmYXVsdAEMaXNTaHV0ZG93bmVyAQRhZGRyCQECIT0CCQDPCAIJAQ5nZXRBZGRyZXNzTGlzdAIFE2tfc2h1dGRvd25BZGRyZXNzZXMFC3NodXRkb3duZXJzCQClCAEFBGFkZHIFBHVuaXQBCGlzTWFya2V0AQRhZGRyCQECIT0CCQDPCAIJAQ5nZXRBZGRyZXNzTGlzdAIFCWtfbWFya2V0cwUHbWFya2V0cwkApQgBBQRhZGRyBQR1bml0BgFpAQtwcm9jZXNzRmVlcwQKYXNzZXRJZFN0cghpbnRlcmVzdAdzdGFraW5nC2xpcXVpZGF0aW9uBAV0b3RhbAkAZAIJAGQCBQhpbnRlcmVzdAUHc3Rha2luZwULbGlxdWlkYXRpb24EB19hY3RpdmUDCQEBIQEJAQhpc1BhdXNlZAAGCQACAQISY29udHJhY3QgaXMgcGF1c2VkAwkAAAIFB19hY3RpdmUFB19hY3RpdmUEB19tYXJrZXQDCQEIaXNNYXJrZXQBCAUBaQZjYWxsZXIGCQACAQIiY2FsbGVyIGlzIG5vdCBhIHdoaXRlbGlzdGVkIG1hcmtldAMJAAACBQdfbWFya2V0BQdfbWFya2V0BAdfbm9ubmVnAwMDCQBnAgUIaW50ZXJlc3QAAAkAZwIFB3N0YWtpbmcAAAcJAGcCBQtsaXF1aWRhdGlvbgAABwYJAAIBAhxhbW91bnRzIG11c3QgYmUgbm9uLW5lZ2F0aXZlAwkAAAIFB19ub25uZWcFB19ub25uZWcEBF9wbXQDCQAAAgkAkAMBCAUBaQhwYXltZW50cwABBgkAAgECHDEgcGF5bWVudCBoYXMgdG8gYmUgYXR0YWNoZWQDCQAAAgUEX3BtdAUEX3BtdAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAEBl9hc3NldAMJAAACCQEOZ2V0QXNzZXRTdHJpbmcBCAUDcG10B2Fzc2V0SWQFCmFzc2V0SWRTdHIGCQACAQIWcGF5bWVudCBhc3NldCBtaXNtYXRjaAMJAAACBQZfYXNzZXQFBl9hc3NldAQEX3N1bQMJAAACCAUDcG10BmFtb3VudAUFdG90YWwGCQACAQIocGF5bWVudCBhbW91bnQgbXVzdCBlcXVhbCBzdW0gb2Ygc291cmNlcwMJAAACBQRfc3VtBQRfc3VtBAFtCQClCAEIBQFpBmNhbGxlcgQHbVByZWZpeAkArAICCQCsAgIJAKwCAgkArAICAgpjb2xsZWN0ZWRfBQFtAgFfBQphc3NldElkU3RyAgFfBAd0UHJlZml4CQCsAgIJAKwCAgIGdG90YWxfBQphc3NldElkU3RyAgFfCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFB21QcmVmaXgCCGludGVyZXN0CQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgIFB21QcmVmaXgCCGludGVyZXN0BQhpbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQdtUHJlZml4AgdzdGFraW5nCQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgIFB21QcmVmaXgCB3N0YWtpbmcFB3N0YWtpbmcJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUHbVByZWZpeAILbGlxdWlkYXRpb24JAGQCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUHbVByZWZpeAILbGlxdWlkYXRpb24FC2xpcXVpZGF0aW9uCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFB3RQcmVmaXgCCGludGVyZXN0CQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgIFB3RQcmVmaXgCCGludGVyZXN0BQhpbnRlcmVzdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQd0UHJlZml4AgdzdGFraW5nCQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgIFB3RQcmVmaXgCB3N0YWtpbmcFB3N0YWtpbmcJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUHdFByZWZpeAILbGlxdWlkYXRpb24JAGQCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUHdFByZWZpeAILbGlxdWlkYXRpb24FC2xpcXVpZGF0aW9uBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEId2l0aGRyYXcDCmFzc2V0SWRTdHIGYW1vdW50CXJlY2lwaWVudAQHX2FjdGl2ZQMJAQEhAQkBCGlzUGF1c2VkAAYJAAIBAhJjb250cmFjdCBpcyBwYXVzZWQDCQAAAgUHX2FjdGl2ZQUHX2FjdGl2ZQQGaXNTZWxmAwkAAAIIBQFpBmNhbGxlcgUEdGhpcwYJAAIBAhhPbmx5IHNlbGYtaW52b2tlIGFsbG93ZWQDCQAAAgUGaXNTZWxmBQZpc1NlbGYEB19hbW91bnQDCQBmAgUGYW1vdW50AAAGCQACAQIXYW1vdW50IG11c3QgYmUgcG9zaXRpdmUDCQAAAgUHX2Ftb3VudAUHX2Ftb3VudAQEYWRkcgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEFCXJlY2lwaWVudAIRaW52YWxpZCByZWNpcGllbnQDCQAAAgUEYWRkcgUEYWRkcgQEd0tleQkArAICAgp3aXRoZHJhd25fBQphc3NldElkU3RyCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFBGFkZHIFBmFtb3VudAkBDWdldEFzc2V0Qnl0ZXMBBQphc3NldElkU3RyCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQR3S2V5CQBkAgkBDXRyeUdldEludGVnZXIBBQR3S2V5BQZhbW91bnQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQhzaHV0ZG93bgEIc2h1dGRvd24DCQEBIQEJAQxpc1NodXRkb3duZXIBCAUBaQZjYWxsZXIJAAIBAhd1c2VyIG5vdCBpbiBhIHdoaXRlbGlzdAkAzAgCCQEMQm9vbGVhbkVudHJ5AgUIa19hY3RpdmUJAQEhAQUIc2h1dGRvd24FA25pbAFpAQx1cGRhdGVTdHJpbmcCA2tleQN2YWwEBmlzU2VsZgMJAAACCAUBaQZjYWxsZXIFBHRoaXMGCQACAQIYT25seSBzZWxmLWludm9rZSBhbGxvd2VkAwkAAAIFBmlzU2VsZgUGaXNTZWxmCQDMCAIJAQtTdHJpbmdFbnRyeQIFA2tleQUDdmFsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQENdXBkYXRlSW50ZWdlcgIDa2V5A3ZhbAQGaXNTZWxmAwkAAAIIBQFpBmNhbGxlcgUEdGhpcwYJAAIBAhhPbmx5IHNlbGYtaW52b2tlIGFsbG93ZWQDCQAAAgUGaXNTZWxmBQZpc1NlbGYJAMwIAgkBDEludGVnZXJFbnRyeQIFA2tleQUDdmFsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQESc2V0QXBwcm92ZXJBZGRyZXNzAQ9hcHByb3ZlckFkZHJlc3MEBmlzU2VsZgMJAAACCAUBaQZjYWxsZXIFBHRoaXMGCQACAQIQT25seSBzZWxmIGludm9rZQMJAAACBQZpc1NlbGYFBmlzU2VsZgQQX2FwcHJvdmVyQWRkcmVzcwkApggBBQ9hcHByb3ZlckFkZHJlc3MECmFwcHJvdmVyT2sEByRtYXRjaDAFEF9hcHByb3ZlckFkZHJlc3MDCQABAgUHJG1hdGNoMAIHQWRkcmVzcwQBdAUHJG1hdGNoMAYHBA5jYW5TZXRBcHByb3ZlcgMDBQphcHByb3Zlck9rBgkAAAIFD2FwcHJvdmVyQWRkcmVzcwIABgkAAgECFldyb25nIGFwcHJvdmVyIGFkZHJlc3MDCQAAAgUOY2FuU2V0QXBwcm92ZXIFDmNhblNldEFwcHJvdmVyBAhpc0luaXRlZAkBC3ZhbHVlT3JFbHNlAgkAmwgCCQEFdmFsdWUBBRBfYXBwcm92ZXJBZGRyZXNzAgZJTklURUQHBAloYXNBZG1pbnMJAQIhPQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgkBBXZhbHVlAQUQX2FwcHJvdmVyQWRkcmVzcwILQURNSU5TX1BCS1MCAAIABBJpc0FwcHJvdmVyQ29udHJhY3QDAwkAAAIFD2FwcHJvdmVyQWRkcmVzcwIABgMFCGlzSW5pdGVkBQloYXNBZG1pbnMHBgkAAgECIEFkZHJlc3MgaXMgbm90IGFwcHJvdmVyIGNvbnRyYWN0AwkAAAIFEmlzQXBwcm92ZXJDb250cmFjdAUSaXNBcHByb3ZlckNvbnRyYWN0CQDMCAIJAQtTdHJpbmdFbnRyeQICEEFQUFJPVkVSX0FERFJFU1MFD2FwcHJvdmVyQWRkcmVzcwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJ0eAEGdmVyaWZ5AAQLbXVsdGlzaWdTdHIJAQt2YWx1ZU9yRWxzZQIJAKIIAQIQQVBQUk9WRVJfQUREUkVTUwIABA9tdWx0aXNpZ0FkZHJlc3MJAKYIAQULbXVsdGlzaWdTdHIECm11bHRpc2lnT2sEByRtYXRjaDAFD211bHRpc2lnQWRkcmVzcwMJAAECBQckbWF0Y2gwAgdBZGRyZXNzBAF0BQckbWF0Y2gwBgcECGlzSW5pdGVkAwUKbXVsdGlzaWdPawkBC3ZhbHVlT3JFbHNlAgkAmwgCCQEFdmFsdWUBBQ9tdWx0aXNpZ0FkZHJlc3MCBklOSVRFRAcHBAloYXNBZG1pbnMDBQptdWx0aXNpZ09rCQECIT0CCQELdmFsdWVPckVsc2UCCQCdCAIJAQV2YWx1ZQEFD211bHRpc2lnQWRkcmVzcwILQURNSU5TX1BCS1MCAAIABwMDAwUKbXVsdGlzaWdPawUIaXNJbml0ZWQHBQloYXNBZG1pbnMHBAckbWF0Y2gwBQJ0eAMJAAECBQckbWF0Y2gwAhRTZXRTY3JpcHRUcmFuc2FjdGlvbgQDdHR4BQckbWF0Y2gwBAckbWF0Y2gxCAUDdHR4BnNjcmlwdAMJAAECBQckbWF0Y2gxAgpCeXRlVmVjdG9yBAZzY3JpcHQFByRtYXRjaDEEC3NjcmlwdEhhc2hhCQDYBAEJAPYDAQUGc2NyaXB0BAl2YWxpZEZyb20JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCCQEFdmFsdWUBBQ9tdWx0aXNpZ0FkZHJlc3MJAKwCAgkArAICCQCsAgIJAKwCAgIIc2NyaXB0JSUFDUNPTlRSQUNUX1RZUEUCAiUlBQtzY3JpcHRIYXNoYQILJSV2YWxpZEZyb20CEXZhbGlkRnJvbSBub3Qgc2V0BAd2YWxpZFRvCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgkBBXZhbHVlAQUPbXVsdGlzaWdBZGRyZXNzCQCsAgIJAKwCAgkArAICCQCsAgICCHNjcmlwdCUlBQ1DT05UUkFDVF9UWVBFAgIlJQULc2NyaXB0SGFzaGECCSUldmFsaWRUbwIPdmFsaWRUbyBub3Qgc2V0AwMDCQBnAgUGaGVpZ2h0BQl2YWxpZEZyb20JAGcCBQd2YWxpZFRvBQZoZWlnaHQHCQBnAgCAttwFCAUDdHR4A2ZlZQcJAQIhPQIJAPEHAQUEdGhpcwkA9gMBBQZzY3JpcHQHBwQDb3R4BQckbWF0Y2gwBAZ0YXNrSWQJAKwCAgkArAICCQCsAgICA3R4XwkApQgBBQR0aGlzAgFfCQDYBAEIBQNvdHgCaWQECmlzQXBwcm92ZWQJAQt2YWx1ZU9yRWxzZQIJAJsIAgkBBXZhbHVlAQUPbXVsdGlzaWdBZGRyZXNzCQCsAgIJAKwCAgkArAICCQClCAEFBHRoaXMCAV8JANgEAQgFA290eAJpZAIKX19hcHByb3ZlZAcEDGFwcHJvdmVkRnJvbQkBC3ZhbHVlT3JFbHNlAgkAmggCCQEFdmFsdWUBBQ9tdWx0aXNpZ0FkZHJlc3MJAKwCAgUGdGFza0lkAg5fX2FwcHJvdmVkRnJvbQAAAwUKaXNBcHByb3ZlZAkAZwIFBmhlaWdodAUMYXBwcm92ZWRGcm9tBwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAgFAnR4D3NlbmRlclB1YmxpY0tleZcD06Q=", "height": 824680, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
| Old | New | Differences | |
|---|---|---|---|
| 1 | - | # no script | |
| 1 | + | {-# STDLIB_VERSION 6 #-} | |
| 2 | + | {-# SCRIPT_TYPE ACCOUNT #-} | |
| 3 | + | {-# CONTENT_TYPE DAPP #-} | |
| 4 | + | let CONTRACT_TYPE = "LEND_FEECOLLECTOR" | |
| 5 | + | ||
| 6 | + | let VERSION = "LFC-0.0.1" | |
| 7 | + | ||
| 8 | + | let k_active = "setup_active" | |
| 9 | + | ||
| 10 | + | let k_markets = "setup_markets" | |
| 11 | + | ||
| 12 | + | let k_shutdownAddresses = "setup_shutdownAddresses" | |
| 13 | + | ||
| 14 | + | let shutdowners = ["3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL", "3PJu3pb7BST5XV7qUiHWDKmrzAkEpDSCewa"] | |
| 15 | + | ||
| 16 | + | let markets = ["3P4uA5etnZi4AmBabKinq2bMiWU8KcnHZdH", "3P4DK5VzDwL3vfc5ahUEhtoe5ByZNyacJ3X", "3PHpuQUPVUoR3AYzFeJzeWJfYLsLTmWssVH", "3P8Df2b7ywHtLBHBe8PBVQYd3A5MdEEJAou", "3PAd9Aqg3cQSzu26MFYWQYcjSXPVCJtuf5V"] | |
| 17 | + | ||
| 18 | + | func tryGetInteger (key) = match getInteger(this, key) { | |
| 19 | + | case b: Int => | |
| 20 | + | b | |
| 21 | + | case _ => | |
| 22 | + | 0 | |
| 23 | + | } | |
| 24 | + | ||
| 25 | + | ||
| 26 | + | func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES")) | |
| 27 | + | then unit | |
| 28 | + | else fromBase58String(assetIdStr) | |
| 29 | + | ||
| 30 | + | ||
| 31 | + | func getAssetString (assetId) = match assetId { | |
| 32 | + | case b: ByteVector => | |
| 33 | + | toBase58String(b) | |
| 34 | + | case _ => | |
| 35 | + | "WAVES" | |
| 36 | + | } | |
| 37 | + | ||
| 38 | + | ||
| 39 | + | func isPaused () = !(valueOrElse(getBoolean(this, k_active), true)) | |
| 40 | + | ||
| 41 | + | ||
| 42 | + | func getAddressList (key,default) = match getString(this, key) { | |
| 43 | + | case s: String => | |
| 44 | + | split_4C(s, ",") | |
| 45 | + | case _ => | |
| 46 | + | default | |
| 47 | + | } | |
| 48 | + | ||
| 49 | + | ||
| 50 | + | func isShutdowner (addr) = (indexOf(getAddressList(k_shutdownAddresses, shutdowners), toString(addr)) != unit) | |
| 51 | + | ||
| 52 | + | ||
| 53 | + | func isMarket (addr) = (indexOf(getAddressList(k_markets, markets), toString(addr)) != unit) | |
| 54 | + | ||
| 55 | + | ||
| 56 | + | @Callable(i) | |
| 57 | + | func processFees (assetIdStr,interest,staking,liquidation) = { | |
| 58 | + | let total = ((interest + staking) + liquidation) | |
| 59 | + | let _active = if (!(isPaused())) | |
| 60 | + | then true | |
| 61 | + | else throw("contract is paused") | |
| 62 | + | if ((_active == _active)) | |
| 63 | + | then { | |
| 64 | + | let _market = if (isMarket(i.caller)) | |
| 65 | + | then true | |
| 66 | + | else throw("caller is not a whitelisted market") | |
| 67 | + | if ((_market == _market)) | |
| 68 | + | then { | |
| 69 | + | let _nonneg = if (if (if ((interest >= 0)) | |
| 70 | + | then (staking >= 0) | |
| 71 | + | else false) | |
| 72 | + | then (liquidation >= 0) | |
| 73 | + | else false) | |
| 74 | + | then true | |
| 75 | + | else throw("amounts must be non-negative") | |
| 76 | + | if ((_nonneg == _nonneg)) | |
| 77 | + | then { | |
| 78 | + | let _pmt = if ((size(i.payments) == 1)) | |
| 79 | + | then true | |
| 80 | + | else throw("1 payment has to be attached") | |
| 81 | + | if ((_pmt == _pmt)) | |
| 82 | + | then { | |
| 83 | + | let pmt = i.payments[0] | |
| 84 | + | let _asset = if ((getAssetString(pmt.assetId) == assetIdStr)) | |
| 85 | + | then true | |
| 86 | + | else throw("payment asset mismatch") | |
| 87 | + | if ((_asset == _asset)) | |
| 88 | + | then { | |
| 89 | + | let _sum = if ((pmt.amount == total)) | |
| 90 | + | then true | |
| 91 | + | else throw("payment amount must equal sum of sources") | |
| 92 | + | if ((_sum == _sum)) | |
| 93 | + | then { | |
| 94 | + | let m = toString(i.caller) | |
| 95 | + | let mPrefix = (((("collected_" + m) + "_") + assetIdStr) + "_") | |
| 96 | + | let tPrefix = (("total_" + assetIdStr) + "_") | |
| 97 | + | [IntegerEntry((mPrefix + "interest"), (tryGetInteger((mPrefix + "interest")) + interest)), IntegerEntry((mPrefix + "staking"), (tryGetInteger((mPrefix + "staking")) + staking)), IntegerEntry((mPrefix + "liquidation"), (tryGetInteger((mPrefix + "liquidation")) + liquidation)), IntegerEntry((tPrefix + "interest"), (tryGetInteger((tPrefix + "interest")) + interest)), IntegerEntry((tPrefix + "staking"), (tryGetInteger((tPrefix + "staking")) + staking)), IntegerEntry((tPrefix + "liquidation"), (tryGetInteger((tPrefix + "liquidation")) + liquidation))] | |
| 98 | + | } | |
| 99 | + | else throw("Strict value is not equal to itself.") | |
| 100 | + | } | |
| 101 | + | else throw("Strict value is not equal to itself.") | |
| 102 | + | } | |
| 103 | + | else throw("Strict value is not equal to itself.") | |
| 104 | + | } | |
| 105 | + | else throw("Strict value is not equal to itself.") | |
| 106 | + | } | |
| 107 | + | else throw("Strict value is not equal to itself.") | |
| 108 | + | } | |
| 109 | + | else throw("Strict value is not equal to itself.") | |
| 110 | + | } | |
| 111 | + | ||
| 112 | + | ||
| 113 | + | ||
| 114 | + | @Callable(i) | |
| 115 | + | func withdraw (assetIdStr,amount,recipient) = { | |
| 116 | + | let _active = if (!(isPaused())) | |
| 117 | + | then true | |
| 118 | + | else throw("contract is paused") | |
| 119 | + | if ((_active == _active)) | |
| 120 | + | then { | |
| 121 | + | let isSelf = if ((i.caller == this)) | |
| 122 | + | then true | |
| 123 | + | else throw("Only self-invoke allowed") | |
| 124 | + | if ((isSelf == isSelf)) | |
| 125 | + | then { | |
| 126 | + | let _amount = if ((amount > 0)) | |
| 127 | + | then true | |
| 128 | + | else throw("amount must be positive") | |
| 129 | + | if ((_amount == _amount)) | |
| 130 | + | then { | |
| 131 | + | let addr = valueOrErrorMessage(addressFromString(recipient), "invalid recipient") | |
| 132 | + | if ((addr == addr)) | |
| 133 | + | then { | |
| 134 | + | let wKey = ("withdrawn_" + assetIdStr) | |
| 135 | + | [ScriptTransfer(addr, amount, getAssetBytes(assetIdStr)), IntegerEntry(wKey, (tryGetInteger(wKey) + amount))] | |
| 136 | + | } | |
| 137 | + | else throw("Strict value is not equal to itself.") | |
| 138 | + | } | |
| 139 | + | else throw("Strict value is not equal to itself.") | |
| 140 | + | } | |
| 141 | + | else throw("Strict value is not equal to itself.") | |
| 142 | + | } | |
| 143 | + | else throw("Strict value is not equal to itself.") | |
| 144 | + | } | |
| 145 | + | ||
| 146 | + | ||
| 147 | + | ||
| 148 | + | @Callable(i) | |
| 149 | + | func shutdown (shutdown) = if (!(isShutdowner(i.caller))) | |
| 150 | + | then throw("user not in a whitelist") | |
| 151 | + | else [BooleanEntry(k_active, !(shutdown))] | |
| 152 | + | ||
| 153 | + | ||
| 154 | + | ||
| 155 | + | @Callable(i) | |
| 156 | + | func updateString (key,val) = { | |
| 157 | + | let isSelf = if ((i.caller == this)) | |
| 158 | + | then true | |
| 159 | + | else throw("Only self-invoke allowed") | |
| 160 | + | if ((isSelf == isSelf)) | |
| 161 | + | then [StringEntry(key, val)] | |
| 162 | + | else throw("Strict value is not equal to itself.") | |
| 163 | + | } | |
| 164 | + | ||
| 165 | + | ||
| 166 | + | ||
| 167 | + | @Callable(i) | |
| 168 | + | func updateInteger (key,val) = { | |
| 169 | + | let isSelf = if ((i.caller == this)) | |
| 170 | + | then true | |
| 171 | + | else throw("Only self-invoke allowed") | |
| 172 | + | if ((isSelf == isSelf)) | |
| 173 | + | then [IntegerEntry(key, val)] | |
| 174 | + | else throw("Strict value is not equal to itself.") | |
| 175 | + | } | |
| 176 | + | ||
| 177 | + | ||
| 178 | + | ||
| 179 | + | @Callable(i) | |
| 180 | + | func setApproverAddress (approverAddress) = { | |
| 181 | + | let isSelf = if ((i.caller == this)) | |
| 182 | + | then true | |
| 183 | + | else throw("Only self invoke") | |
| 184 | + | if ((isSelf == isSelf)) | |
| 185 | + | then { | |
| 186 | + | let _approverAddress = addressFromString(approverAddress) | |
| 187 | + | let approverOk = match _approverAddress { | |
| 188 | + | case t: Address => | |
| 189 | + | true | |
| 190 | + | case _ => | |
| 191 | + | false | |
| 192 | + | } | |
| 193 | + | let canSetApprover = if (if (approverOk) | |
| 194 | + | then true | |
| 195 | + | else (approverAddress == "")) | |
| 196 | + | then true | |
| 197 | + | else throw("Wrong approver address") | |
| 198 | + | if ((canSetApprover == canSetApprover)) | |
| 199 | + | then { | |
| 200 | + | let isInited = valueOrElse(getBoolean(value(_approverAddress), "INITED"), false) | |
| 201 | + | let hasAdmins = (valueOrElse(getString(value(_approverAddress), "ADMINS_PBKS"), "") != "") | |
| 202 | + | let isApproverContract = if (if ((approverAddress == "")) | |
| 203 | + | then true | |
| 204 | + | else if (isInited) | |
| 205 | + | then hasAdmins | |
| 206 | + | else false) | |
| 207 | + | then true | |
| 208 | + | else throw("Address is not approver contract") | |
| 209 | + | if ((isApproverContract == isApproverContract)) | |
| 210 | + | then [StringEntry("APPROVER_ADDRESS", approverAddress)] | |
| 211 | + | else throw("Strict value is not equal to itself.") | |
| 212 | + | } | |
| 213 | + | else throw("Strict value is not equal to itself.") | |
| 214 | + | } | |
| 215 | + | else throw("Strict value is not equal to itself.") | |
| 216 | + | } | |
| 217 | + | ||
| 218 | + | ||
| 219 | + | @Verifier(tx) | |
| 220 | + | func verify () = { | |
| 221 | + | let multisigStr = valueOrElse(getString("APPROVER_ADDRESS"), "") | |
| 222 | + | let multisigAddress = addressFromString(multisigStr) | |
| 223 | + | let multisigOk = match multisigAddress { | |
| 224 | + | case t: Address => | |
| 225 | + | true | |
| 226 | + | case _ => | |
| 227 | + | false | |
| 228 | + | } | |
| 229 | + | let isInited = if (multisigOk) | |
| 230 | + | then valueOrElse(getBoolean(value(multisigAddress), "INITED"), false) | |
| 231 | + | else false | |
| 232 | + | let hasAdmins = if (multisigOk) | |
| 233 | + | then (valueOrElse(getString(value(multisigAddress), "ADMINS_PBKS"), "") != "") | |
| 234 | + | else false | |
| 235 | + | if (if (if (multisigOk) | |
| 236 | + | then isInited | |
| 237 | + | else false) | |
| 238 | + | then hasAdmins | |
| 239 | + | else false) | |
| 240 | + | then match tx { | |
| 241 | + | case ttx: SetScriptTransaction => | |
| 242 | + | match ttx.script { | |
| 243 | + | case script: ByteVector => | |
| 244 | + | let scriptHasha = toBase58String(blake2b256(script)) | |
| 245 | + | let validFrom = valueOrErrorMessage(getInteger(value(multisigAddress), (((("script%%" + CONTRACT_TYPE) + "%%") + scriptHasha) + "%%validFrom")), "validFrom not set") | |
| 246 | + | let validTo = valueOrErrorMessage(getInteger(value(multisigAddress), (((("script%%" + CONTRACT_TYPE) + "%%") + scriptHasha) + "%%validTo")), "validTo not set") | |
| 247 | + | if (if (if ((height >= validFrom)) | |
| 248 | + | then (validTo >= height) | |
| 249 | + | else false) | |
| 250 | + | then (12000000 >= ttx.fee) | |
| 251 | + | else false) | |
| 252 | + | then (scriptHash(this) != blake2b256(script)) | |
| 253 | + | else false | |
| 254 | + | case _ => | |
| 255 | + | false | |
| 256 | + | } | |
| 257 | + | case otx => | |
| 258 | + | let taskId = ((("tx_" + toString(this)) + "_") + toBase58String(otx.id)) | |
| 259 | + | let isApproved = valueOrElse(getBoolean(value(multisigAddress), (((toString(this) + "_") + toBase58String(otx.id)) + "__approved")), false) | |
| 260 | + | let approvedFrom = valueOrElse(getInteger(value(multisigAddress), (taskId + "__approvedFrom")), 0) | |
| 261 | + | if (isApproved) | |
| 262 | + | then (height >= approvedFrom) | |
| 263 | + | else false | |
| 264 | + | } | |
| 265 | + | else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
| 266 | + | } | |
| 267 | + |
github/deemru/w8io 15.82 ms ◑