tx · 46DPmddbLpB4A49QBtavuoCKVhNhYHnVxDsGbTr5RzBY

3P4uA5etnZi4AmBabKinq2bMiWU8KcnHZdH:  -0.04000000 Waves

2023.06.29 14:10 [3709517] smart account 3P4uA5etnZi4AmBabKinq2bMiWU8KcnHZdH > SELF 0.00000000 Waves

{ "type": 13, "id": "46DPmddbLpB4A49QBtavuoCKVhNhYHnVxDsGbTr5RzBY", "fee": 4000000, "feeAssetId": null, "timestamp": 1688037011702, "version": 2, "chainId": 87, "sender": "3P4uA5etnZi4AmBabKinq2bMiWU8KcnHZdH", "senderPublicKey": "8DxbUxhy23djr6kUEE1Jzp7oVJXBsHNaATLRiABpkSde", "proofs": [ "4Yk4GMT8YEkzPxMbAxtChaWjgodqwXKPM11RxMqqQyHiarDsaq5H2UPCZnqGGhCixopztusaKDFbzvt51bG7574f" ], "script": "base64:BgKPAQgCEgASBAoCCAESBAoCCAESABIDCgEIEgMKAQgSBAoCCAESBAoCCAESBAoCCAESABIGCgQICAgIEgYKBAgICAgSBAoCCAgSBAoCCAgSAwoBBBIDCgEIEgMKAQQSCAoGBAgBCAgIEgUKAwQICBIGCgQECAQIEgMKAQQSBAoCCAQSBAoCCAQSAwoBBBIDCgEEHwAScmVzZXJ2ZUZ1bmRBZGRyZXNzCQEHQWRkcmVzcwEBGgFXHuH7QDFrgebsS1YbBSxRoZNu3wmxPNLBAAtyZXNlcnZlRnVuZAAUABFhZ2dyZWdhdG9yQWRkcmVzcwkBB0FkZHJlc3MBARoBV50MqsYTUaluy4D3Y33BZHji73JNqAy60wAJb3JhY2xlU3RyAiMzUFBYVktqTjZuUk16WGVlZ2NZaGZpaWM5NnBkMmM5OEVrbQARc2h1dGRvd25XaGl0ZWxpc3QJAMwIAgEaAVfX4SNRjnyriFrV1yiXddiIddOPriMFpuEJAMwIAgEaAVdjDQOBpn9bVNIcueQoKvOngDTw2LWN1WUJAMwIAgEaAVez1ZJUSQmaKhD7xvifEHar7z8PcqWJFYwJAMwIAgEaAVf4+voCJsBRi+xqO0YzSdIccbB1i/mkypoJAMwIAgEaAVer3aoi85i5H0XYLNSn6vkSYq+JNmpQO3IJAMwIAgEaAVcwORzRpGYYO35/49jeov24Z5j/V00RJp0FA25pbAEWdmVyaWZ5TGlxdWlkYXRvclJpZ2h0cwEHYWRkcmVzcwkBASEBAwMJAQIhPQIFB2FkZHJlc3MJAQdBZGRyZXNzAQEaAVd3qs7ReFboqZ5eq5Xvv+nhcVh1XjKacYEJAQIhPQIFB2FkZHJlc3MJAQdBZGRyZXNzAQEaAVfX4SNRjnyriFrV1yiXddiIddOPriMFpuEHCQECIT0CBQdhZGRyZXNzCQEHQWRkcmVzcwEBGgFXq92qIvOYuR9F2CzUp+r5EmKviTZqUDtyBwEMZ2V0UmF0ZUN1cnZlAQphc3NldElkU3RyBAckbWF0Y2gwBQphc3NldElkU3RyAwkAAAICLDl3YzNMWE5BNFRFQnNYeUt0b0xFOW1yYkREN1dNSFh2WHJDalp2YWJMQXNpBQckbWF0Y2gwCQCWCgQAgIl6AMDw9QsAgOiSJgCAwtcvAwkAAAICLEhHZ2FiVHFVUzhXdFZGVUp6Zm1yVERNZ0VjY0p1WkxCUGhGZ1FGeHZuc29XBQckbWF0Y2gwCQCWCgQAgIl6AMDw9QsAgOiSJgCAwtcvAwkAAAICLDM0TjlZY0VFVExXbjkzcVlRNjRFc1AxeDg5dFNydUpVNDRSckVNU1hYRVBKBQckbWF0Y2gwCQCWCgQAgIl6AMDw9QsAgOiSJgCAwtcvAwkAAAICLDZYdEhqcFhiczlSUkpQMlNyOUdVeVZxekFDY2J5OVRrVGhIWG5qVkM1Q0RKBQckbWF0Y2gwCQCWCgQAgIl6AMDw9QsAgOiSJgCAwtcvAwkAAAICLERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwBQckbWF0Y2gwCQCWCgQAgIl6AMDw9QsAgOiSJgCAwtcvAwkAAAICLEFqc282blRUanB0dTJVSEx4NmhmU1hWdEhGdFJCSkNrS1lkNVNBeWo3emY1BQckbWF0Y2gwCQCWCgQAgIl6AIC0iRMAgOiSJgCAo8NHAwkAAAICLEhFQjhRYXc5eHJXcFdzOHRIc2lBVFlHQldEQnRQMlM3a2NQQUxyTXU0M0FTBQckbWF0Y2gwCQCWCgQAAACA4esXAIDokiYAgIjevgEDCQAAAgIFV0FWRVMFByRtYXRjaDAJAJYKBACAiXoAgIenDgCA6JImAIDh6xcDCQAAAgIsQXRxdjU5RVl6akZHdWl0S1ZuTVJrNkg4RnVram9WM2t0UG9yYkV5czI1b24FByRtYXRjaDAJAJYKBAAAAIDaxAkAgOiSJgCAtIkTAwkAAAICLERTYmJoTHNTVGVEZzVMc2l1ZmsyQW5laDNEalZxSnVQcjJNOXVVMWd3eTVwBQckbWF0Y2gwCQCWCgQAAACA2sQJAIDokiYAgMLXLwMJAAACAiw4dDREUFdUd1B6cGF0SEE5QWtUeFdBQjQ3VEhuWXpCc0Rub1k3ZlFxYkc5MQUHJG1hdGNoMAkAlgoEAAAAgIenDgCA6JImAIC0iRMDCQAAAgIsQXQ4RDZORkZwaGVDYnZLVm5qVm9lTEw4NEVvOE5abjZvdk1hbnhmTGFGV0wFByRtYXRjaDAJAJYKBAAAAMDw9QsAgOiSJgCAtIkTAwkAAAICLDhMUVc4ZjdQNWQ1UFpNN0d0WkVCZ2FxUlBHU3pTM0Rm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bgkAawMJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphc3NldElkU3RyAgZfc1JhdGUFB1NjYWxlMTYDCQAAAgUEZG93bgAAAAAJAGsDBQZTY2FsZTgJAGsDCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQphc3NldElkU3RyCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYXNzZXRJZFN0cgIGX2JSYXRlBQdTY2FsZTE2BQRkb3duAQtnZXRJbnRlcmVzdAEKYXNzZXRJZFN0cgQCdXIJAQ1nZXRPdXRkYXRlZFVyAQUKYXNzZXRJZFN0cgQFY3VydmUJAQxnZXRSYXRlQ3VydmUBBQphc3NldElkU3RyBARyYXRlCQBkAggFBWN1cnZlAl8xAwkAZwIIBQVjdXJ2ZQJfMwUCdXIJAGsDBQJ1cggFBWN1cnZlAl8yCAUFY3VydmUCXzMJAGQCCAUFY3VydmUCXzIJAGsDCQBlAgUCdXIIBQVjdXJ2ZQJfMwgFBWN1cnZlAl80CQBlAgCAwtcvCAUFY3VydmUCXzMJAJYDAQkAzAgCCQBrAwUEcmF0ZQUGU2NhbGU4CQBoAgUJZGF5QmxvY2tzAO0CCQDMCAIAAQUDbmlsARB0b2tlblJhdGVzUmVjYWxjAQphc3NldElkU3RyBAhpbnRlcmVzdAkBC2dldEludGVyZXN0AQUKYXNzZXRJZFN0cgQCdXIJAQ1nZXRPdXRkYXRlZFVyAQUKYXNzZXRJZFN0cgQQbGFzdFJlY2FsY0hlaWdodAkBDXRyeUdldEludGVnZXIBAg5sYXN0UmF0ZUhlaWdodAQJbGFzdEJSYXRlCQCWAwEJAMwIAgkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFzc2V0SWRTdHICBl9iUmF0ZQkAzAgCBQdTY2FsZTE2BQNuaWwECG5ld0JSYXRlCQBkAgUJbGFzdEJSYXRlCQBoAgkAZQIFBmhlaWdodAUQbGFzdFJlY2FsY0hlaWdodAUIaW50ZXJlc3QECWxhc3RTUmF0ZQkAlgMBCQDMCAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphc3NldElkU3RyAgZfc1JhdGUJAMwIAgUHU2NhbGUxNgUDbmlsBAhuZXdTUmF0ZQkAZAIFCWxhc3RTUmF0ZQkAaQIJAGgCCQBoAgkAZQIFBmhlaWdodAUQbGFzdFJlY2FsY0hlaWdodAkAawMFCGludGVyZXN0BQJ1cgUGU2NhbGU4CQBlAgBkBQtyZXNlcnZlRnVuZABkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFzc2V0SWRTdHICBl9zUmF0ZQUIbmV3U1JhdGUJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYXNzZXRJZFN0cgIGX2JSYXRlBQhuZXdCUmF0ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgIObGFzdFJhdGVIZWlnaHQFBmhlaWdodAUDbmlsAQ1nZXRBY3R1YWxSYXRlAgphc3NldElkU3RyCHJhdGVUeXBlCgEBZgIFYWNjdW0FdG9rZW4EBnJlY2FsYwkBEHRva2VuUmF0ZXNSZWNhbGMBBQV0b2tlbgkAlAoCAwkBAiE9AgUFdG9rZW4FCmFzc2V0SWRTdHIIBQVhY2N1bQJfMQMJAAACBQhyYXRlVHlwZQIFc1JhdGUICQCRAwIFBnJlY2FsYwAABXZhbHVlCAkAkQMCBQZyZWNhbGMAAQV2YWx1ZQkAzggCCAUFYWNjdW0CXzIFBnJlY2FsYwoAAiRsCQEPZ2V0TWFya2V0QXNzZXRzAAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgAABQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEyCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAQVnZXRVcgEKYXNzZXRJZFN0cgQFcmF0ZXMJARB0b2tlblJhdGVzUmVjYWxjAQUKYXNzZXRJZFN0cgQEZG93bgkAawMJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIICQCRAwIFBXJhdGVzAAAFdmFsdWUFB1NjYWxlMTYJAGsDBQZTY2FsZTgJAGsDCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQphc3NldElkU3RyCAkAkQMCBQVyYXRlcwABBXZhbHVlBQdTY2FsZTE2BQRkb3duAQtyYXRlc1JlY2FsYwAKAQFmAgVhY2N1bQV0b2tlbgkAzggCBQVhY2N1bQkBEHRva2VuUmF0ZXNSZWNhbGMBBQV0b2tlbgoAAiRsCQEPZ2V0TWFya2V0QXNzZXRzAAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEBZgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTIJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwBFWdldFRva2VuUHJpY2VXaXRoUmlzawIKYXNzZXRJZFN0cgxyaXNrQXZlcnNpdHkDAwkAAAIFCmFzc2V0SWRTdHICLDl3YzNMWE5BNFRFQnNYeUt0b0xFOW1yYkREN1dNSFh2WHJDalp2YWJMQXNpBgkAAAIFCmFzc2V0SWRTdHICLEhHZ2FiVHFVUzhXdFZGVUp6Zm1yVERNZ0VjY0p1WkxCUGhGZ1FGeHZuc29XCQCUCgIAwIQ9AMCEPQQFcHJpY2UJARFAZXh0ck5hdGl2ZSgxMDUwKQIJAQdBZGRyZXNzAQEaAVdJZtDL84r1V3qt/CFvccVbiYgr0IGzsX8JAKwCAgUKYXNzZXRJZFN0cgIHX3R3YXA1QgQJcmlza0xldmVsCQERQGV4dHJOYXRpdmUoMTA1MCkCCQEHQWRkcmVzcwEBGgFXSWbQy/OK9Vd6rfwhb3HFW4mIK9CBs7F/CQCsAgIFCmFzc2V0SWRTdHICCl9yaXNrTGV2ZWwDCQBnAgUMcmlza0F2ZXJzaXR5BQlyaXNrTGV2ZWwJAJQKAgUFcHJpY2UFBXByaWNlCQACAQkArAICCQCsAgICG29yYWNsZSBwcmljZXMgZG9uJ3QgbWF0Y2g6IAkApAMBBQVwcmljZQIjIGlzIHRoZSBwcmljZSwgYnV0IHJpc2sgaXMgdG9vIGhpZ2gBDWdldFRva2VuUHJpY2UBCmFzc2V0SWRTdHIJARVnZXRUb2tlblByaWNlV2l0aFJpc2sCBQphc3NldElkU3RyAAMBDmNhbGNBc3NldFNjYWxlAQphc3NldElkU3RyBAhkZWNpbWFscwMJAAACBQphc3NldElkU3RyAgVXQVZFUwAICAkBBXZhbHVlAQkA7AcBCQDZBAEFCmFzc2V0SWRTdHIIZGVjaW1hbHMJAGwGAAoAAAUIZGVjaW1hbHMAAAAABQRET1dOARJjYWxjVXNlckNvbGxhdGVyYWwBB2FkZHJlc3MEFHVzZXJDb2xsYXRlcmFsSW52b2tlCQD8BwQFBHRoaXMCEWdldFVzZXJDb2xsYXRlcmFsCQDMCAIHCQDMCAIFB2FkZHJlc3MJAMwIAgYJAMwIAgIABQNuaWwFA25pbAMJAAACBRR1c2VyQ29sbGF0ZXJhbEludm9rZQUUdXNlckNvbGxhdGVyYWxJbnZva2UEE3VzZXJDb2xsYXRlcmFsVmFsdWUEByRtYXRjaDAFFHVzZXJDb2xsYXRlcmFsSW52b2tlAwkAAQIFByRtYXRjaDACA0ludAQBeAUHJG1hdGNoMAUBeAkAAgECJGlzc3VlIHdoaWxlIGRvaW5nIGluLWRhcHAgaW52b2NhdGlvbgMJAAACBRN1c2VyQ29sbGF0ZXJhbFZhbHVlBRN1c2VyQ29sbGF0ZXJhbFZhbHVlBRN1c2VyQ29sbGF0ZXJhbFZhbHVlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuGQFpAQZzdXBwbHkAAwkBASEBCQENdHJ5R2V0Qm9vbGVhbgECDHNldHVwX2FjdGl2ZQkAAgECEW1hcmtldCBpcyBzdG9wcGVkAwMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQYJAAACCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAAACQACAQIcMSBwYXltZW50IGhhcyB0byBiZSBhdHRhY2hlZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBAthc3NldEFtb3VudAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQECyR0MDgxNjU4MjMyCQENZ2V0QWN0dWFsUmF0ZQIFCmFzc2V0SWRTdHICBXNSYXRlBAVzUmF0ZQgFCyR0MDgxNjU4MjMyAl8xBBFyYXRlc1JlY2FsY1Jlc3VsdAgFCyR0MDgxNjU4MjMyAl8yBAZhbW91bnQJAG4EBQthc3NldEFtb3VudAUHU2NhbGUxNgUFc1JhdGUFBERPV04EB2FkZHJlc3MJAKUIAQgFAWkGY2FsbGVyBAltYXhTdXBwbHkEByRtYXRjaDAJAKIIAQkArAICAhBzZXR1cF9tYXhTdXBwbHlfBQphc3NldElkU3RyAwkAAQIFByRtYXRjaDACBlN0cmluZwQBeAUHJG1hdGNoMAkBDXBhcnNlSW50VmFsdWUBBQF4CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIQc2V0dXBfbWF4U3VwcGx5XwUKYXNzZXRJZFN0cgQKYXNzZXRQcmljZQkBDWdldFRva2VuUHJpY2UBBQphc3NldElkU3RyBBBuZXdUb3RhbFN1cHBsaWVkCQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgUGYW1vdW50BARyYXRlCAkBDWdldEFjdHVhbFJhdGUCBQphc3NldElkU3RyAgVzUmF0ZQJfMQQKYXNzZXRTY2FsZQkBDmNhbGNBc3NldFNjYWxlAQUKYXNzZXRJZFN0cgQTbmV3VG90YWxTdXBwbGllZFVzZAkAawMJAGsDBRBuZXdUb3RhbFN1cHBsaWVkBQRyYXRlBQdTY2FsZTE2CAUKYXNzZXRQcmljZQJfMQUKYXNzZXRTY2FsZQMJAAACCQCzCQIJAQx0cnlHZXRTdHJpbmcBAgxzZXR1cF90b2tlbnMFCmFzc2V0SWRTdHIFBHVuaXQJAAIBAil0aGlzIGFzc2V0IGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIG1hcmtldAMDCQECIT0CBQltYXhTdXBwbHkAAAkAZgIFE25ld1RvdGFsU3VwcGxpZWRVc2QFCW1heFN1cHBseQcJAAIBAjNtYXggdG90YWwgc3VwcGx5IGZvciB0aGlzIHRva2VuIHJlYWNoZWQgaW4gdGhlIHBvb2wJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIFB2FkZHJlc3MCCl9zdXBwbGllZF8FCmFzc2V0SWRTdHIFEG5ld1RvdGFsU3VwcGxpZWQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyCQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgUGYW1vdW50BQNuaWwFEXJhdGVzUmVjYWxjUmVzdWx0AWkBCHdpdGhkcmF3Agphc3NldElkU3RyC2Fzc2V0QW1vdW50BAskdDA5NTM1OTYwMgkBDWdldEFjdHVhbFJhdGUCBQphc3NldElkU3RyAgVzUmF0ZQQFc1JhdGUIBQskdDA5NTM1OTYwMgJfMQQRcmF0ZXNSZWNhbGNSZXN1bHQIBQskdDA5NTM1OTYwMgJfMgQGYW1vdW50CQBuBAULYXNzZXRBbW91bnQFB1NjYWxlMTYFBXNSYXRlBQdDRUlMSU5HBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgQNYXNzZXRTdXBwbGllZAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgQNYXNzZXRCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgQRdXNlckFzc2V0U3VwcGxpZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9zdXBwbGllZF8FCmFzc2V0SWRTdHIEEXVzZXJBc3NldEJvcnJvd2VkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQphc3NldElkU3RyBBJjb2xsYXRlcmFsVmFsdWVJbnYJAPwHBAUEdGhpcwIRZ2V0VXNlckNvbGxhdGVyYWwJAMwIAgcJAMwIAgUHYWRkcmVzcwkAzAgCBgkAzAgCCQCsAgIJAKwCAgUKYXNzZXRJZFN0cgIKLHN1cHBsaWVkLAkApAMBCQEBLQEFBmFtb3VudAUDbmlsBQNuaWwDCQAAAgUSY29sbGF0ZXJhbFZhbHVlSW52BRJjb2xsYXRlcmFsVmFsdWVJbnYED2NvbGxhdGVyYWxWYWx1ZQQHJG1hdGNoMAUSY29sbGF0ZXJhbFZhbHVlSW52AwkAAQIFByRtYXRjaDACA0ludAQBeAUHJG1hdGNoMAUBeAkAAgECH2Nhbid0IGdldCB1c2VyIGNvbGxhdGVyYWwgdmFsdWUDCQEBIQEJAQ10cnlHZXRCb29sZWFuAQIMc2V0dXBfYWN0aXZlCQACAQIRbWFya2V0IGlzIHN0b3BwZWQDCQBmAgAABQ9jb2xsYXRlcmFsVmFsdWUJAAIBAjJ5b3UgZG9udCBoYXZlIGVub3VnaCBjb2xsYXRlcmFsIGZvciB0aGlzIG9wZXJhdGlvbgMJAGYCBQZhbW91bnQJAGUCBQ1hc3NldFN1cHBsaWVkBQ1hc3NldEJvcnJvd2VkCQACAQIqdGhpcyBhbW91bnQgaXMgbm90IGF2YWlsYWJsZSBvbiB0aGUgbWFya2V0AwkAZgIFBmFtb3VudAkAZQIFEXVzZXJBc3NldFN1cHBsaWVkBRF1c2VyQXNzZXRCb3Jyb3dlZAkAAgECKnRoaXMgYW1vdW50IGlzIG5vdCBhdmFpbGFibGUgZm9yIHRoaXMgdXNlcgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgkAZQIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9zdXBwbGllZF8FCmFzc2V0SWRTdHIFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIJAGUCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyBQZhbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQthc3NldEFtb3VudAkBDWdldEFzc2V0Qnl0ZXMBBQphc3NldElkU3RyBQNuaWwFEXJhdGVzUmVjYWxjUmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBmJvcnJvdwIKYXNzZXRJZFN0cgthc3NldEFtb3VudAQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEDSR0MDExMTc0MTEyNDEJAQ1nZXRBY3R1YWxSYXRlAgUKYXNzZXRJZFN0cgIFYlJhdGUEBWJSYXRlCAUNJHQwMTExNzQxMTI0MQJfMQQRcmF0ZXNSZWNhbGNSZXN1bHQIBQ0kdDAxMTE3NDExMjQxAl8yBAZhbW91bnQJAG4EBQthc3NldEFtb3VudAUHU2NhbGUxNgUFYlJhdGUFB0NFSUxJTkcEEmNvbGxhdGVyYWxWYWx1ZUludgkA/AcEBQR0aGlzAhFnZXRVc2VyQ29sbGF0ZXJhbAkAzAgCBwkAzAgCBQdhZGRyZXNzCQDMCAIGCQDMCAIJAKwCAgkArAICBQphc3NldElkU3RyAgosYm9ycm93ZWQsCQCkAwEFBmFtb3VudAUDbmlsBQNuaWwDCQAAAgUSY29sbGF0ZXJhbFZhbHVlSW52BRJjb2xsYXRlcmFsVmFsdWVJbnYED2NvbGxhdGVyYWxWYWx1ZQQHJG1hdGNoMAUSY29sbGF0ZXJhbFZhbHVlSW52AwkAAQIFByRtYXRjaDACA0ludAQBeAUHJG1hdGNoMAUBeAkAAgECH2Nhbid0IGdldCB1c2VyIGNvbGxhdGVyYWwgdmFsdWUDCQEBIQEJAQ10cnlHZXRCb29sZWFuAQIMc2V0dXBfYWN0aXZlCQACAQIRbWFya2V0IGlzIHN0b3BwZWQDCQBmAgAABQ9jb2xsYXRlcmFsVmFsdWUJAAIBAiF5b3UgaGF2ZSB0byBzdXBwbHkgbW9yZSB0byBib3Jyb3cEDWFzc2V0U3VwcGxpZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIEDWFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIEEXVzZXJBc3NldEJvcnJvd2VkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQphc3NldElkU3RyAwkAZgIFBmFtb3VudAkAZQIFDWFzc2V0U3VwcGxpZWQFDWFzc2V0Qm9ycm93ZWQJAAIBAhx0aGlzIGFtb3VudCBpcyBub3QgYXZhaWxhYmxlCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQphc3NldElkU3RyCQBkAgURdXNlckFzc2V0Qm9ycm93ZWQFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIJAGQCBQ1hc3NldEJvcnJvd2VkBQZhbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQthc3NldEFtb3VudAkBDWdldEFzc2V0Qnl0ZXMBBQphc3NldElkU3RyBQNuaWwFEXJhdGVzUmVjYWxjUmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBXJlcGF5AAMJAQEhAQkBDXRyeUdldEJvb2xlYW4BAgxzZXR1cF9hY3RpdmUJAAIBAhFtYXJrZXQgaXMgc3RvcHBlZAMDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEGCQAAAggJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQAAAkAAgECHDEgcGF5bWVudCBoYXMgdG8gYmUgYXR0YWNoZWQECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQLYXNzZXRBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BA0kdDAxMjgxNDEyODgxCQENZ2V0QWN0dWFsUmF0ZQIFCmFzc2V0SWRTdHICBWJSYXRlBAViUmF0ZQgFDSR0MDEyODE0MTI4ODECXzEEEXJhdGVzUmVjYWxjUmVzdWx0CAUNJHQwMTI4MTQxMjg4MQJfMgQGYW1vdW50CQBuBAULYXNzZXRBbW91bnQFB1NjYWxlMTYFBWJSYXRlBQdDRUlMSU5HBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgQNYXNzZXRTdXBwbGllZAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgQNYXNzZXRCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgQRdXNlckFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIECmFtb3VudExlZnQJAGUCBRF1c2VyQXNzZXRCb3Jyb3dlZAUGYW1vdW50BAtyZXBheUFtb3VudAMJAGcCBQphbW91bnRMZWZ0AAAFBmFtb3VudAURdXNlckFzc2V0Qm9ycm93ZWQDCQAAAgkAswkCCQEMdHJ5R2V0U3RyaW5nAQIMc2V0dXBfdG9rZW5zBQphc3NldElkU3RyBQR1bml0CQACAQIpdGhpcyBhc3NldCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBtYXJrZXQJAM4IAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgkAZQIFEXVzZXJBc3NldEJvcnJvd2VkBQtyZXBheUFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIJAGUCBQ1hc3NldEJvcnJvd2VkBQtyZXBheUFtb3VudAUDbmlsBRFyYXRlc1JlY2FsY1Jlc3VsdAMJAGcCBQphbW91bnRMZWZ0AAAFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJAQEtAQUKYW1vdW50TGVmdAgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBQNuaWwBaQEIcmVwYXlGb3IBB2FkZHJlc3MDCQEBIQEJAQ10cnlHZXRCb29sZWFuAQIMc2V0dXBfYWN0aXZlCQACAQIRbWFya2V0IGlzIHN0b3BwZWQDCQECIT0CCAUBaQZjYWxsZXIJAQdBZGRyZXNzAQEaAVce4ftAMWuB5uxLVhsFLFGhk27fCbE80sEJAAIBAidhdmFpbGFibGUgb25seSBmb3IgcmVzZXJ2ZSBmdW5kIGFkZHJlc3MDCQAAAgUHYWRkcmVzcwIGZ2xvYmFsCQACAQIgeW91IGNhbid0IHJlcGF5IGZvciBldmVyeW9uZSA6XykDAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABBgkAAAIICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50AAAJAAIBAhwxIHBheW1lbnQgaGFzIHRvIGJlIGF0dGFjaGVkBAphc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQEC2Fzc2V0QW1vdW50CAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQNJHQwMTQ0NzgxNDU0NQkBDWdldEFjdHVhbFJhdGUCBQphc3NldElkU3RyAgViUmF0ZQQFYlJhdGUIBQ0kdDAxNDQ3ODE0NTQ1Al8xBBFyYXRlc1JlY2FsY1Jlc3VsdAgFDSR0MDE0NDc4MTQ1NDUCXzIEBmFtb3VudAkAbgQFC2Fzc2V0QW1vdW50BQdTY2FsZTE2BQViUmF0ZQUHQ0VJTElORwQNYXNzZXRTdXBwbGllZAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgQNYXNzZXRCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgQRdXNlckFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIECmFtb3VudExlZnQJAGUCBRF1c2VyQXNzZXRCb3Jyb3dlZAUGYW1vdW50BAtyZXBheUFtb3VudAMJAGcCBQphbW91bnRMZWZ0AAAFBmFtb3VudAURdXNlckFzc2V0Qm9ycm93ZWQDCQAAAgkAswkCCQEMdHJ5R2V0U3RyaW5nAQIMc2V0dXBfdG9rZW5zBQphc3NldElkU3RyBQR1bml0CQACAQIpdGhpcyBhc3NldCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBtYXJrZXQJAM4IAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgkAZQIFEXVzZXJBc3NldEJvcnJvd2VkBQtyZXBheUFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIJAGUCBQ1hc3NldEJvcnJvd2VkBQtyZXBheUFtb3VudAUDbmlsBRFyYXRlc1JlY2FsY1Jlc3VsdAMJAGcCBQphbW91bnRMZWZ0AAAFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJAQEtAQUKYW1vdW50TGVmdAgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBQNuaWwBaQENc3Rha2VUb2tlbkFsbAEKYXNzZXRJZFN0cgMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECLG9ubHkgZm9yIGludGVybmFsIHNtYXJ0IGNvbnRyYWN0IGludm9jYXRpb25zBAZhbW91bnQJAQpnZXRCYWxhbmNlAQUKYXNzZXRJZFN0cgQDaW52CQD8BwQFBHRoaXMCCnN0YWtlVG9rZW4JAMwIAgUKYXNzZXRJZFN0cgkAzAgCBQZhbW91bnQFA25pbAUDbmlsAwkAAAIFA2ludgUDaW52BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKc3Rha2VUb2tlbgIKYXNzZXRJZFN0cgZhbW91bnQDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAixvbmx5IGZvciBpbnRlcm5hbCBzbWFydCBjb250cmFjdCBpbnZvY2F0aW9ucwMJAAACBQphc3NldElkU3RyAixERzJ4RmtQZER3S1VvQmt6R0FoUXRMcFNHemZYTGlDWVBFemVLSDJBZDI0cAQMYW1vdW50U3Rha2VkCQENdHJ5R2V0SW50ZWdlcgECPWF1dG9zdGFrZV9hbW91bnRfREcyeEZrUGREd0tVb0JrekdBaFF0THBTR3pmWExpQ1lQRXplS0gyQWQyNHAEA2ludgkA/AcECQEHQWRkcmVzcwEBGgFX5A6nNk+SC9eXz6QdPzUbz0Nq66o883GdAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCASC2JinDBPXOU5GkDkt1JC9kjFGx+t+vVCm9SNIdKrKq0QUGYW1vdW50BQNuaWwDCQAAAgUDaW52BQNpbnYJAMwIAgkBDEludGVnZXJFbnRyeQICPWF1dG9zdGFrZV9hbW91bnRfREcyeEZrUGREd0tVb0JrekdBaFF0THBTR3pmWExpQ1lQRXplS0gyQWQyNHAJAGQCBQxhbW91bnRTdGFrZWQFBmFtb3VudAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAwkAAAIFCmFzc2V0SWRTdHICLDh0NERQV1R3UHpwYXRIQTlBa1R4V0FCNDdUSG5ZekJzRG5vWTdmUXFiRzkxBAxhbW91bnRTdGFrZWQJAQ10cnlHZXRJbnRlZ2VyAQI9YXV0b3N0YWtlX2Ftb3VudF84dDREUFdUd1B6cGF0SEE5QWtUeFdBQjQ3VEhuWXpCc0Rub1k3ZlFxYkc5MQQDaW52CQD8BwQJAQdBZGRyZXNzAQEaAVf3FTURxe1yhVNUEPDdG03iajzTtGh3KVoCBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIBIHUWEDiAdg1VZX5J866x2+YZnGoQaB/JVWH6SkZadzAcBQZhbW91bnQFA25pbAMJAAACBQNpbnYFA2ludgkAzAgCCQEMSW50ZWdlckVudHJ5AgI9YXV0b3N0YWtlX2Ftb3VudF84dDREUFdUd1B6cGF0SEE5QWtUeFdBQjQ3VEhuWXpCc0Rub1k3ZlFxYkc5MQkAZAIFDGFtb3VudFN0YWtlZAUGYW1vdW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DCQAAAgUKYXNzZXRJZFN0cgIsQXQ4RDZORkZwaGVDYnZLVm5qVm9lTEw4NEVvOE5abjZvdk1hbnhmTGFGV0wEDGFtb3VudFN0YWtlZAkBDXRyeUdldEludGVnZXIBAj1hdXRvc3Rha2VfYW1vdW50X0F0OEQ2TkZGcGhlQ2J2S1ZualZvZUxMODRFbzhOWm42b3ZNYW54ZkxhRldMBANpbnYJAPwHBAkBB0FkZHJlc3MBARoBV2toOOED1JqMnxIbxiy8Iwc5C83tEtcKXwIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgEgktH0SuIRASv0fureIY49xfvJ8n3Oh7LtUhnwOk4kWPUFBmFtb3VudAUDbmlsAwkAAAIFA2ludgUDaW52CQDMCAIJAQxJbnRlZ2VyRW50cnkCAj1hdXRvc3Rha2VfYW1vdW50X0F0OEQ2TkZGcGhlQ2J2S1ZualZvZUxMODRFbzhOWm42b3ZNYW54ZkxhRldMCQBkAgUMYW1vdW50U3Rha2VkBQZhbW91bnQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsAWkBDHVuc3Rha2VUb2tlbgIKYXNzZXRJZFN0cgZhbW91bnQDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAixvbmx5IGZvciBpbnRlcm5hbCBzbWFydCBjb250cmFjdCBpbnZvY2F0aW9ucwMJAAACBQphc3NldElkU3RyAiw4dDREUFdUd1B6cGF0SEE5QWtUeFdBQjQ3VEhuWXpCc0Rub1k3ZlFxYkc5MQQMYW1vdW50U3Rha2VkCQENdHJ5R2V0SW50ZWdlcgECPWF1dG9zdGFrZV9hbW91bnRfOHQ0RFBXVHdQenBhdEhBOUFrVHhXQUI0N1RIbll6QnNEbm9ZN2ZRcWJHOTEEA2ludgkA/AcECQEHQWRkcmVzcwEBGgFX9xU1EcXtcoVTVBDw3RtN4mo807RodylaAgd1blN0YWtlCQDMCAIFBmFtb3VudAUDbmlsBQNuaWwDCQAAAgUDaW52BQNpbnYJAMwIAgkBDEludGVnZXJFbnRyeQICPWF1dG9zdGFrZV9hbW91bnRfOHQ0RFBXVHdQenBhdEhBOUFrVHhXQUI0N1RIbll6QnNEbm9ZN2ZRcWJHOTEJAGUCBQxhbW91bnRTdGFrZWQFBmFtb3VudAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAwkAAAIFCmFzc2V0SWRTdHICLEF0OEQ2TkZGcGhlQ2J2S1ZualZvZUxMODRFbzhOWm42b3ZNYW54ZkxhRldMBAxhbW91bnRTdGFrZWQJAQ10cnlHZXRJbnRlZ2VyAQI9YXV0b3N0YWtlX2Ftb3VudF9BdDhENk5GRnBoZUNidktWbmpWb2VMTDg0RW84TlpuNm92TWFueGZMYUZXTAQDaW52CQD8BwQJAQdBZGRyZXNzAQEaAVdraDjhA9SajJ8SG8YsvCMHOQvN7RLXCl8CB3Vuc3Rha2UJAMwIAgUGYW1vdW50BQNuaWwFA25pbAMJAAACBQNpbnYFA2ludgQEYmFsMAkBCmdldEJhbGFuY2UBAixBdDhENk5GRnBoZUNidktWbmpWb2VMTDg0RW84TlpuNm92TWFueGZMYUZXTAMJAAACBQRiYWwwBQRiYWwwBARpbnYyCQD8BwQJAQdBZGRyZXNzAQEaAVf7derrE/0ZwMsI3I9gs34DuhGOrY+30OsCF2duc2J0UmV3YXJkc1NZU1JFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQAAAgUEaW52MgUEaW52MgQMdG9wdXBSZXdhcmRzBAckbWF0Y2gwBQRpbnYyAwkAAQIFByRtYXRjaDACCUxpc3RbQW55XQQBeAUHJG1hdGNoMAQIc2Vjb25kRWwJAJEDAgUBeAABBAckbWF0Y2gxBQhzZWNvbmRFbAMJAAECBQckbWF0Y2gxAgZTdHJpbmcECHNlY29uZEVsBQckbWF0Y2gxBAl1c2RuVmFsdWUJAQ1wYXJzZUludFZhbHVlAQkAkQMCCQC1CQIJAJEDAgkAtQkCBQhzZWNvbmRFbAIBXwABAgE6AAEECndhdmVzVmFsdWUJAQ1wYXJzZUludFZhbHVlAQkAkQMCCQC1CQIJAJEDAgkAtQkCBQhzZWNvbmRFbAIBXwAAAgE6AAEDAwkBAiE9AgUJdXNkblZhbHVlAAAGCQECIT0CBQp3YXZlc1ZhbHVlAAAECHVzZG5CYWwwCQEKZ2V0QmFsYW5jZQECLERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwAwkAAAIFCHVzZG5CYWwwBQh1c2RuQmFsMAQJd2F2ZXNCYWwwCQEKZ2V0QmFsYW5jZQECBVdBVkVTAwkAAAIFCXdhdmVzQmFsMAUJd2F2ZXNCYWwwBARpbnYzCQD8BwQJAQdBZGRyZXNzAQEaAVdraDjhA9SajJ8SG8YsvCMHOQvN7RLXCl8CDGNsYWltUmV3YXJkcwUDbmlsBQNuaWwDCQAAAgUEaW52MwUEaW52MwQJd2F2ZXNCYWwxCQEKZ2V0QmFsYW5jZQECBVdBVkVTAwkAAAIFCXdhdmVzQmFsMQUJd2F2ZXNCYWwxBARpbnY0CQD8BwQJAQdBZGRyZXNzAQEaAVfOFBSdFlgD5ENMevWl7LKfrb/Ns4P5KaICBHN3YXAJAMwIAgIsREcyeEZrUGREd0tVb0JrekdBaFF0THBTR3pmWExpQ1lQRXplS0gyQWQyNHAJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFBHVuaXQJAGUCBQl3YXZlc0JhbDEFCXdhdmVzQmFsMAUDbmlsAwkAAAIFBGludjQFBGludjQECHVzZG5CYWwxCQEKZ2V0QmFsYW5jZQECLERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwAwkAAAIFCHVzZG5CYWwxBQh1c2RuQmFsMQQEaW52NQkA/AcECQEHQWRkcmVzcwEBGgFXQOqhXGWBKD10hFtXYJ7743krt9yKtJB3AgRzd2FwCQDMCAICLEF0OEQ2TkZGcGhlQ2J2S1ZualZvZUxMODRFbzhOWm42b3ZNYW54ZkxhRldMCQDMCAIAAAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCASC2JinDBPXOU5GkDkt1JC9kjFGx+t+vVCm9SNIdKrKq0QkAZQIFCHVzZG5CYWwxBQh1c2RuQmFsMAUDbmlsAwkAAAIFBGludjUFBGludjUEBGludjYJAPwHBAUEdGhpcwILYWRkSW50ZXJlc3QJAMwIAgIsQXQ4RDZORkZwaGVDYnZLVm5qVm9lTEw4NEVvOE5abjZvdk1hbnhmTGFGV0wJAMwIAgkAZQIJAQpnZXRCYWxhbmNlAQIsQXQ4RDZORkZwaGVDYnZLVm5qVm9lTEw4NEVvOE5abjZvdk1hbnhmTGFGV0wFBGJhbDAFA25pbAUDbmlsAwkAAAIFBGludjYFBGludjYAAgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgABAAEAAAMJAAACBQx0b3B1cFJld2FyZHMFDHRvcHVwUmV3YXJkcwkAzAgCCQEMSW50ZWdlckVudHJ5AgI9YXV0b3N0YWtlX2Ftb3VudF9BdDhENk5GRnBoZUNidktWbmpWb2VMTDg0RW84TlpuNm92TWFueGZMYUZXTAkAZQIFDGFtb3VudFN0YWtlZAUGYW1vdW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAFpAQthZGRJbnRlcmVzdAIKYXNzZXRJZFN0cgZhbW91bnQDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhhvbmx5IGZvciBzZWxmIGludm9jYXRpb24EBmVhcm5lZAkBDXRyeUdldEludGVnZXIBCQCsAgICFWF1dG9zdGFrZV9sYXN0RWFybmVkXwUKYXNzZXRJZFN0cgQKbGFzdEhlaWdodAkBDXRyeUdldEludGVnZXIBCQCsAgICFGF1dG9zdGFrZV9sYXN0QmxvY2tfBQphc3NldElkU3RyBAtjbGVhbkFtb3VudAkAawMFBmFtb3VudABQAGQEDHN0YXRlQ2hhbmdlcwMDCQAAAgUKbGFzdEhlaWdodAUGaGVpZ2h0BgkAAAIFBmFtb3VudAAABQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIYYXV0b3N0YWtlX3ByZUxhc3RFYXJuZWRfBQphc3NldElkU3RyBQZlYXJuZWQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIXYXV0b3N0YWtlX3ByZUxhc3RCbG9ja18FCmFzc2V0SWRTdHIFCmxhc3RIZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIVYXV0b3N0YWtlX2xhc3RFYXJuZWRfBQphc3NldElkU3RyCQBkAgUGZWFybmVkBQtjbGVhbkFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAhRhdXRvc3Rha2VfbGFzdEJsb2NrXwUKYXNzZXRJZFN0cgUGaGVpZ2h0BQNuaWwJAM4IAgUMc3RhdGVDaGFuZ2VzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFzc2V0SWRTdHICBl9zUmF0ZQkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphc3NldElkU3RyAgZfc1JhdGUJAGsDBQdTY2FsZTE2BQtjbGVhbkFtb3VudAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgUDbmlsAWkBE2FkZEludGVyZXN0RVhURVJOQUwABAZhbW91bnQJAGsDCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudABQAGQEB2Fzc2V0SWQICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAQGZWFybmVkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIVYXV0b3N0YWtlX2xhc3RFYXJuZWRfBQphc3NldElkU3RyBApsYXN0SGVpZ2h0CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIUYXV0b3N0YWtlX2xhc3RCbG9ja18FCmFzc2V0SWRTdHIEDHN0YXRlQ2hhbmdlcwMDCQAAAgUKbGFzdEhlaWdodAUGaGVpZ2h0BgkAAAIFBmFtb3VudAAABQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIYYXV0b3N0YWtlX3ByZUxhc3RFYXJuZWRfBQphc3NldElkU3RyBQZlYXJuZWQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIXYXV0b3N0YWtlX3ByZUxhc3RCbG9ja18FCmFzc2V0SWRTdHIFCmxhc3RIZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIVYXV0b3N0YWtlX2xhc3RFYXJuZWRfBQphc3NldElkU3RyCQBkAgUGZWFybmVkBQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIUYXV0b3N0YWtlX2xhc3RCbG9ja18FCmFzc2V0SWRTdHIFBmhlaWdodAUDbmlsCQDOCAIFDHN0YXRlQ2hhbmdlcwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQphc3NldElkU3RyAgZfc1JhdGUJAGQCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYXNzZXRJZFN0cgIGX3NSYXRlCQBrAwUHU2NhbGUxNgUGYW1vdW50CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyBQNuaWwBaQEHcHJlSW5pdAQGdG9rZW5zBGx0dnMDbHRzCXBlbmFsdGllcwoBAWYCBWFjY3VtBXRva2VuCQDOCAIFBWFjY3VtCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBXRva2VuAgZfYlJhdGUFB1NjYWxlMTYJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUFdG9rZW4CBl9zUmF0ZQUHU2NhbGUxNgUDbmlsAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIKYWRtaW4gb25seQQFcmF0ZXMKAAIkbAkAtQkCBQZ0b2tlbnMCASwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEyCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMCQDOCAIJAMwIAgkBC1N0cmluZ0VudHJ5AgIMc2V0dXBfdG9rZW5zBQZ0b2tlbnMJAMwIAgkBC1N0cmluZ0VudHJ5AgIKc2V0dXBfbHR2cwUEbHR2cwkAzAgCCQELU3RyaW5nRW50cnkCAglzZXR1cF9sdHMFA2x0cwkAzAgCCQELU3RyaW5nRW50cnkCAg9zZXR1cF9wZW5hbHRpZXMFCXBlbmFsdGllcwkAzAgCCQEMQm9vbGVhbkVudHJ5AgIMc2V0dXBfYWN0aXZlBgUDbmlsBQVyYXRlcwFpAQxpbml0TmV3VG9rZW4EBXRva2VuA2x0dgJsdAdwZW5hbHR5AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIKYWRtaW4gb25seQkAzAgCCQELU3RyaW5nRW50cnkCAgxzZXR1cF90b2tlbnMJAKwCAgkArAICCQEMdHJ5R2V0U3RyaW5nAQIMc2V0dXBfdG9rZW5zAgEsBQV0b2tlbgkAzAgCCQELU3RyaW5nRW50cnkCAgpzZXR1cF9sdHZzCQCsAgIJAKwCAgkBDHRyeUdldFN0cmluZwECCnNldHVwX2x0dnMCASwFA2x0dgkAzAgCCQELU3RyaW5nRW50cnkCAglzZXR1cF9sdHMJAKwCAgkArAICCQEMdHJ5R2V0U3RyaW5nAQIJc2V0dXBfbHRzAgEsBQJsdAkAzAgCCQELU3RyaW5nRW50cnkCAg9zZXR1cF9wZW5hbHRpZXMJAKwCAgkArAICCQEMdHJ5R2V0U3RyaW5nAQIPc2V0dXBfcGVuYWx0aWVzAgEsBQdwZW5hbHR5CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBXRva2VuAgZfYlJhdGUFB1NjYWxlMTYJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUFdG9rZW4CBl9zUmF0ZQUHU2NhbGUxNgUDbmlsAWkBD3VwZGF0ZVBhcmFtZXRlcgIDa2V5A3ZhbAMDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAQIhPQIIBQFpBmNhbGxlcgkBB0FkZHJlc3MBARoBVxR5WIXA+hpn5xQ0jQz3xPBtRe32HPk9QQcJAAIBAgphZG1pbiBvbmx5CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQNrZXkJAQ1wYXJzZUludFZhbHVlAQUDdmFsBQNuaWwBaQEMdXBkYXRlU3RyaW5nAgNrZXkDdmFsAwMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkBAiE9AggFAWkGY2FsbGVyCQEHQWRkcmVzcwEBGgFXFHlYhcD6GmfnFDSNDPfE8G1F7fYc+T1BBwkAAgECCmFkbWluIG9ubHkJAMwIAgkBC1N0cmluZ0VudHJ5AgUDa2V5BQN2YWwFA25pbAFpARJjbGFpbVRvUmVzZXJ2ZUZ1bmQBBWRlYnVnBAZhc3NldHMJAQ9nZXRNYXJrZXRBc3NldHMABAVyYXRlcwgJAQ1nZXRBY3R1YWxSYXRlAgkAkQMCBQZhc3NldHMAAAIFc1JhdGUCXzIEAmxpCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFCQDMCAIABgUDbmlsCgEBZgIFYWNjdW0BbgMJAGcCBQFuCQCQAwEFBmFzc2V0cwUFYWNjdW0ECmFzc2V0SWRTdHIJAJEDAgUGYXNzZXRzBQFuBA9hdXRvc3Rha2VBbW91bnQJAQx0cnlHZXRTdHJpbmcBCQCsAgICEWF1dG9zdGFrZV9hbW91bnRfBQphc3NldElkU3RyBAZhbW91bnQJAGUCCQBkAgkAZAIJAGQCCQEKZ2V0QmFsYW5jZQEFCmFzc2V0SWRTdHIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAhFhdXRvc3Rha2VfYW1vdW50XwUKYXNzZXRJZFN0cgMJAQIhPQIFD2F1dG9zdGFrZUFtb3VudAIACQENcGFyc2VJbnRWYWx1ZQEFD2F1dG9zdGFrZUFtb3VudAAACQBrAwkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cggJAJEDAgUFcmF0ZXMJAGQCCQBoAgUBbgADAAEFdmFsdWUFB1NjYWxlMTYJAGsDCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyCAkAkQMCBQVyYXRlcwkAaAIFAW4AAwV2YWx1ZQUHU2NhbGUxNgkAzggCBQVhY2N1bQkAzAgCBQZhbW91bnQFA25pbAQJcGFyYW1ldGVyCgACJGwFAmxpCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFmAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAoBAmYyAgVhY2N1bQFuAwkAZwIFAW4JAJADAQUGYXNzZXRzBQVhY2N1bQQKYXNzZXRJZFN0cgkAkQMCBQZhc3NldHMFAW4JAM4IAgUFYWNjdW0JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUScmVzZXJ2ZUZ1bmRBZGRyZXNzCQCWAwEJAMwIAgkAkQMCBQlwYXJhbWV0ZXIFAW4JAMwIAgAABQNuaWwJAQ1nZXRBc3NldEJ5dGVzAQUKYXNzZXRJZFN0cgUDbmlsAwUFZGVidWcJAAIBCQEKbGlJbnRUb1N0cgEFCXBhcmFtZXRlcgkAlAoCCgACJGwFAmxpCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYxXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQJmMgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMTIJAQUkZjFfMgIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIJAQUkZjFfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwFCXBhcmFtZXRlcgFpAQdyZVNldHVwAQphc3NldElkU3RyBAtsYXN0UmVzZXR1cAkBDXRyeUdldEludGVnZXIBAhJyZXNldHVwX2xhc3RVcGRhdGUDCQBmAgUJZGF5QmxvY2tzCQBlAgUGaGVpZ2h0BQtsYXN0UmVzZXR1cAkAAgECIGNhbiBiZSB1cGRhdGVkIG9ubHkgb25jZSBwZXIgZGF5BANsdHMJALUJAgkBDHRyeUdldFN0cmluZwECCXNldHVwX2x0cwIBLAQGYXNzZXRzCQEPZ2V0TWFya2V0QXNzZXRzAAQCdXIJAQVnZXRVcgEFCmFzc2V0SWRTdHIEBnRlbXBMVAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgIGc2V0dXBfBQphc3NldElkU3RyAgdfdGVtcExUBAJsdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBmFzc2V0cwkBBXZhbHVlAQkAzwgCBQZhc3NldHMFCmFzc2V0SWRTdHIDCQBmAgUCdXIAgJX1KgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICBnNldHVwXwUKYXNzZXRJZFN0cgIHX3RlbXBMVAkAawMFBnRlbXBMVAD3TQCQTgUDbmlsAwMJAGYCBQJsdAUGdGVtcExUCQBmAgCAlfUqBQJ1cgcJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICAgZzZXR1cF8FCmFzc2V0SWRTdHICB190ZW1wTFQJAGsDBQZ0ZW1wTFQAqU4AkE4FA25pbAUDbmlsAWkBCHNodXRkb3duAQhzaHV0ZG93bgMJAAACCQDPCAIFEXNodXRkb3duV2hpdGVsaXN0CAgFAWkGY2FsbGVyBWJ5dGVzBQR1bml0CQACAQIXdXNlciBub3QgaW4gYSB3aGl0ZWxpc3QJAMwIAgkBDEJvb2xlYW5FbnRyeQICDHNldHVwX2FjdGl2ZQkBASEBBQhzaHV0ZG93bgUDbmlsAWkBCWxpcXVpZGF0ZQYFZGVidWcHYWRkcmVzcwthc3NldEFtb3VudAtzQXNzZXRJZFN0cgtiQXNzZXRJZFN0cghyb3V0ZVN0cgMJAQEhAQkBFnZlcmlmeUxpcXVpZGF0b3JSaWdodHMBCAUBaQZjYWxsZXIJAAIBAih0ZW1wb3JhcmlseSBhdmFpbGFibGUgZm9yIHdoaXRlbGlzdCBvbmx5AwkBASEBCQENdHJ5R2V0Qm9vbGVhbgECDHNldHVwX2FjdGl2ZQkAAgECEW1hcmtldCBpcyBzdG9wcGVkBA51c2VyQ29sbGF0ZXJhbAkBEmNhbGNVc2VyQ29sbGF0ZXJhbAEFB2FkZHJlc3MDCQAAAgUOdXNlckNvbGxhdGVyYWwFDnVzZXJDb2xsYXRlcmFsBA0kdDAyODAyOTI4MDkxCQENZ2V0QWN0dWFsUmF0ZQIFC3NBc3NldElkU3RyAgVzUmF0ZQQFc1JhdGUIBQ0kdDAyODAyOTI4MDkxAl8xBAtyYXRlc1Jlc3VsdAgFDSR0MDI4MDI5MjgwOTECXzIEDSR0MDI4MDk2MjgxNjUJAQ1nZXRBY3R1YWxSYXRlAgULYkFzc2V0SWRTdHICBWJSYXRlBAViUmF0ZQgFDSR0MDI4MDk2MjgxNjUCXzEEEnJhdGVzUmVjYWxjUmVzdWx0MggFDSR0MDI4MDk2MjgxNjUCXzIEDHNBc3NldEFtb3VudAkAawMFC2Fzc2V0QW1vdW50BQdTY2FsZTE2BQVzUmF0ZQQQY3VycmVudFNQb3NpdGlvbgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwULc0Fzc2V0SWRTdHIEE2N1cnJlbnRCUG9zaXRpb25WYWwJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FC2JBc3NldElkU3RyBBBjdXJyZW50QlBvc2l0aW9uAwkAZgIFE2N1cnJlbnRCUG9zaXRpb25WYWwAAAUTY3VycmVudEJQb3NpdGlvblZhbAkAAgECIHVzZXIgaGFzIG5vIGJvcnJvdyBpbiB0aGlzIHRva2VuAwkAZgIFDnVzZXJDb2xsYXRlcmFsAAAJAAIBAhh1c2VyIGNhbid0IGJlIGxpcXVpZGF0ZWQDCQBmAgUMc0Fzc2V0QW1vdW50BRBjdXJyZW50U1Bvc2l0aW9uCQACAQIycG9zaXRpb24gdG8gbGlxdWlkYXRlIGlzIGJpZ2dlciB0aGFuIHVzZXIncyBzdXBwbHkEDmJhbGFuY2UwQmVmb3JlCQEKZ2V0QmFsYW5jZQEFC3NBc3NldElkU3RyAwkAAAIFDmJhbGFuY2UwQmVmb3JlBQ5iYWxhbmNlMEJlZm9yZQQOYmFsYW5jZTFCZWZvcmUJAQpnZXRCYWxhbmNlAQULYkFzc2V0SWRTdHIDCQAAAgUOYmFsYW5jZTFCZWZvcmUFDmJhbGFuY2UxQmVmb3JlBA5leGNoYW5nZUludm9rZQkA/AcEBRFhZ2dyZWdhdG9yQWRkcmVzcwIEc3dhcAkAzAgCBQhyb3V0ZVN0cgkAzAgCAAAFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBDWdldEFzc2V0Qnl0ZXMBBQtzQXNzZXRJZFN0cgULYXNzZXRBbW91bnQFA25pbAMJAAACBQ5leGNoYW5nZUludm9rZQUOZXhjaGFuZ2VJbnZva2UECmFzc2V0MFNvbGQJAGUCBQ5iYWxhbmNlMEJlZm9yZQkBCmdldEJhbGFuY2UBBQtzQXNzZXRJZFN0cgMJAAACBQphc3NldDBTb2xkBQphc3NldDBTb2xkBAxhc3NldDFCb3VnaHQJAGUCCQEKZ2V0QmFsYW5jZQEFC2JBc3NldElkU3RyBQ5iYWxhbmNlMUJlZm9yZQMJAAACBQxhc3NldDFCb3VnaHQFDGFzc2V0MUJvdWdodAQLYXNzZXQwUHJpY2UICQENZ2V0VG9rZW5QcmljZQEFC3NBc3NldElkU3RyAl8xBAthc3NldDBTY2FsZQkBDmNhbGNBc3NldFNjYWxlAQULc0Fzc2V0SWRTdHIECWFzc2V0MFVzZAkAawMFCmFzc2V0MFNvbGQFC2Fzc2V0MFByaWNlBQthc3NldDBTY2FsZQQLYXNzZXQxUHJpY2UICQENZ2V0VG9rZW5QcmljZQEFC2JBc3NldElkU3RyAl8yBAthc3NldDFTY2FsZQkBDmNhbGNBc3NldFNjYWxlAQULYkFzc2V0SWRTdHIECWFzc2V0MVVzZAkAawMFDGFzc2V0MUJvdWdodAULYXNzZXQxUHJpY2UFC2Fzc2V0MVNjYWxlBAdwZW5hbHR5CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgkAtQkCCQEMdHJ5R2V0U3RyaW5nAQIPc2V0dXBfcGVuYWx0aWVzAgEsCQEFdmFsdWUBCQDPCAIJAQ9nZXRNYXJrZXRBc3NldHMABQtiQXNzZXRJZFN0cgQRbGlxdWlkYXRpb25Qcm9maXQJAGUCBQlhc3NldDFVc2QJAGsDBQlhc3NldDBVc2QJAGUCBQZTY2FsZTgFB3BlbmFsdHkFBlNjYWxlOAQMc0Fzc2V0Q2hhbmdlCQBrAwUKYXNzZXQwU29sZAUHU2NhbGUxNgUFc1JhdGUEDGJBc3NldENoYW5nZQkAawMJAGsDBQxhc3NldDFCb3VnaHQFB1NjYWxlMTYFBWJSYXRlCQBlAgUGU2NhbGU4CQBrAwURbGlxdWlkYXRpb25Qcm9maXQFBlNjYWxlOAUJYXNzZXQxVXNkBQZTY2FsZTgDCQBmAgUKYXNzZXQwU29sZAULYXNzZXRBbW91bnQJAAIBAiNtb3JlIGFzc2V0cyBleGNoYW5nZWQgdGhhbiBleHBlY3RlZAMJAGYCAAAFEWxpcXVpZGF0aW9uUHJvZml0CQACAQIvcHJpY2UgaW1wYWN0IGlzIGJpZ2dlciB0aGFuIGxpcXVpZGF0aW9uIHBlbmFsdHkJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQtzQXNzZXRJZFN0cgkAZQIFEGN1cnJlbnRTUG9zaXRpb24FDHNBc3NldENoYW5nZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FC2JBc3NldElkU3RyCQBlAgUQY3VycmVudEJQb3NpdGlvbgUMYkFzc2V0Q2hhbmdlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICD3RvdGFsX3N1cHBsaWVkXwULc0Fzc2V0SWRTdHIJAGUCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQtzQXNzZXRJZFN0cgUMc0Fzc2V0Q2hhbmdlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICD3RvdGFsX2JvcnJvd2VkXwULYkFzc2V0SWRTdHIJAGUCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQtiQXNzZXRJZFN0cgUMYkFzc2V0Q2hhbmdlBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQELbGlxdWlkYXRlVjIDBWRlYnVnB2FkZHJlc3MLc0Fzc2V0SWRTdHIDCQEBIQEJARZ2ZXJpZnlMaXF1aWRhdG9yUmlnaHRzAQgFAWkGY2FsbGVyCQACAQIodGVtcG9yYXJpbHkgYXZhaWxhYmxlIGZvciB3aGl0ZWxpc3Qgb25seQMJAQEhAQkBDXRyeUdldEJvb2xlYW4BAgxzZXR1cF9hY3RpdmUJAAIBAhFtYXJrZXQgaXMgc3RvcHBlZAQIYkFzc2V0SWQICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQLYkFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEFCGJBc3NldElkBAxiQXNzZXRBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BA51c2VyQ29sbGF0ZXJhbAkBEmNhbGNVc2VyQ29sbGF0ZXJhbAEFB2FkZHJlc3MDCQAAAgUOdXNlckNvbGxhdGVyYWwFDnVzZXJDb2xsYXRlcmFsAwkAZgIFDnVzZXJDb2xsYXRlcmFsAAAJAAIBAhh1c2VyIGNhbid0IGJlIGxpcXVpZGF0ZWQEDG1hcmtldEFzc2V0cwkBD2dldE1hcmtldEFzc2V0cwAECWFzc2V0MU51bQkBBXZhbHVlAQkAzwgCBQxtYXJrZXRBc3NldHMFC2JBc3NldElkU3RyBAlhc3NldDBOdW0JAQV2YWx1ZQEJAM8IAgUMbWFya2V0QXNzZXRzBQtzQXNzZXRJZFN0cgQNJHQwMzEzMjAzMTM4MgkBDWdldEFjdHVhbFJhdGUCBQtiQXNzZXRJZFN0cgIFYlJhdGUEBWJSYXRlCAUNJHQwMzEzMjAzMTM4MgJfMQQLcmF0ZXNSZXN1bHQIBQ0kdDAzMTMyMDMxMzgyAl8yBAthc3NldDFQcmljZQgJAQ1nZXRUb2tlblByaWNlAQULYkFzc2V0SWRTdHICXzIEC2Fzc2V0MVNjYWxlCQEOY2FsY0Fzc2V0U2NhbGUBBQtiQXNzZXRJZFN0cgQKYkFtb3VudFVzZAkAawMFDGJBc3NldEFtb3VudAULYXNzZXQxUHJpY2UFC2Fzc2V0MVNjYWxlBAdwZW5hbHR5CQENcGFyc2VJbnRWYWx1ZQEJAQV2YWx1ZQEJAJEDAgkAtQkCCQEMdHJ5R2V0U3RyaW5nAQIPc2V0dXBfcGVuYWx0aWVzAgEsBQlhc3NldDFOdW0EC2Fzc2V0MFByaWNlCAkBDWdldFRva2VuUHJpY2UBBQtzQXNzZXRJZFN0cgJfMQQLYXNzZXQwU2NhbGUJAQ5jYWxjQXNzZXRTY2FsZQEFC3NBc3NldElkU3RyBApzQW1vdW50VXNkCQBrAwUKYkFtb3VudFVzZAkAZAIFBlNjYWxlOAUHcGVuYWx0eQUGU2NhbGU4BAxzQXNzZXRBbW91bnQJAGsDBQpzQW1vdW50VXNkBQthc3NldDBTY2FsZQULYXNzZXQwUHJpY2UEB2JBbW91bnQJAGsDBQxiQXNzZXRBbW91bnQFB1NjYWxlMTYFBWJSYXRlBAdzQW1vdW50CQBrAwUMc0Fzc2V0QW1vdW50BQdTY2FsZTE2CAkAkQMCBQtyYXRlc1Jlc3VsdAkAZAIJAGgCBQlhc3NldDBOdW0AAwABBXZhbHVlBBBjdXJyZW50U1Bvc2l0aW9uCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQtzQXNzZXRJZFN0cgQTY3VycmVudEJQb3NpdGlvblZhbAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwULYkFzc2V0SWRTdHIEEGN1cnJlbnRCUG9zaXRpb24DCQBmAgUTY3VycmVudEJQb3NpdGlvblZhbAAABRNjdXJyZW50QlBvc2l0aW9uVmFsCQACAQIgdXNlciBoYXMgbm8gYm9ycm93IGluIHRoaXMgdG9rZW4DCQBmAgUHc0Ftb3VudAUQY3VycmVudFNQb3NpdGlvbgkAAgECMnBvc2l0aW9uIHRvIGxpcXVpZGF0ZSBpcyBiaWdnZXIgdGhhbiB1c2VyJ3Mgc3VwcGx5AwUFZGVidWcJAAIBAhVsaXF1aWRhdGlvbiB3aWxsIHBhc3MJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFDHNBc3NldEFtb3VudAkBDWdldEFzc2V0Qnl0ZXMBBQtzQXNzZXRJZFN0cgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIFB2FkZHJlc3MCCl9zdXBwbGllZF8FC3NBc3NldElkU3RyCQBlAgUQY3VycmVudFNQb3NpdGlvbgUHc0Ftb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FC2JBc3NldElkU3RyCQBlAgUQY3VycmVudEJQb3NpdGlvbgUHYkFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9zdXBwbGllZF8FC3NBc3NldElkU3RyCQBlAgkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwULc0Fzc2V0SWRTdHIFB3NBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQtiQXNzZXRJZFN0cgkAZQIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9ib3Jyb3dlZF8FC2JBc3NldElkU3RyBQdiQW1vdW50BQNuaWwFC3JhdGVzUmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEWdldFVzZXJDb2xsYXRlcmFsBAVkZWJ1ZwdhZGRyZXNzDW1pbnVzQm9ycm93ZWQLYWZ0ZXJDaGFuZ2UEBmFzc2V0cwkBD2dldE1hcmtldEFzc2V0cwAEBGx0dnMJALUJAgkBDHRyeUdldFN0cmluZwECCnNldHVwX2x0dnMCASwEA2x0cwkAtQkCCQEMdHJ5R2V0U3RyaW5nAQIJc2V0dXBfbHRzAgEsBAVyYXRlcwgJAQ1nZXRBY3R1YWxSYXRlAgkAkQMCBQZhc3NldHMAAAIFc1JhdGUCXzIEDWNoYW5nZUhhbmRsZXIJALUJAgULYWZ0ZXJDaGFuZ2UCASwKAQFmAgVhY2N1bQRuZXh0AwkAZwIFBG5leHQJAJADAQUGYXNzZXRzBQVhY2N1bQQMdXNlclN1cHBsaWVkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfCQCRAwIFBmFzc2V0cwUEbmV4dAQMdXNlckJvcnJvd2VkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfCQCRAwIFBmFzc2V0cwUEbmV4dAQTbmVlZFRva2VuQWNjb3VudGluZwMJAAACBQthZnRlckNoYW5nZQIAAwMJAQIhPQIFDHVzZXJCb3Jyb3dlZAAABgkBAiE9AgUMdXNlclN1cHBsaWVkAAAGBwYDBRNuZWVkVG9rZW5BY2NvdW50aW5nBAphc3NldFNjYWxlCQEOY2FsY0Fzc2V0U2NhbGUBCQCRAwIFBmFzc2V0cwUEbmV4dAQKYXNzZXRQcmljZQkBDWdldFRva2VuUHJpY2UBCQCRAwIFBmFzc2V0cwUEbmV4dAkAZQIJAGQCBQVhY2N1bQkAawMJAGsDCQBrAwkAZAIFDHVzZXJTdXBwbGllZAMDAwkBAiE9AgULYWZ0ZXJDaGFuZ2UCAAkAAAIJAJEDAgUNY2hhbmdlSGFuZGxlcgAACQCRAwIFBmFzc2V0cwUEbmV4dAcJAAACCQCRAwIFDWNoYW5nZUhhbmRsZXIAAQIIc3VwcGxpZWQHCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUNY2hhbmdlSGFuZGxlcgACAAAICQCRAwIFBXJhdGVzCQBoAgUEbmV4dAADBXZhbHVlBQdTY2FsZTE2CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUEbHR2cwUEbmV4dAUGU2NhbGU4CAUKYXNzZXRQcmljZQJfMQUKYXNzZXRTY2FsZQMFDW1pbnVzQm9ycm93ZWQJAGsDCQBrAwkAawMJAGQCBQx1c2VyQm9ycm93ZWQDAwMJAQIhPQIFC2FmdGVyQ2hhbmdlAgAJAAACCQCRAwIFDWNoYW5nZUhhbmRsZXIAAAkAkQMCBQZhc3NldHMFBG5leHQHCQAAAgkAkQMCBQ1jaGFuZ2VIYW5kbGVyAAECCGJvcnJvd2VkBwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDWNoYW5nZUhhbmRsZXIAAgAACAkAkQMCBQVyYXRlcwkAZAIJ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", "height": 3709517, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: DrucwnTbKJJUf3Pv7mtHDomk9JiomSLZBVuSM4VnvpdX Next: AbMrsHqeXFhyfd9nDysqzVq7cFttQnFuTsKKDWvuk4FU Diff:
OldNewDifferences
3333 else if (("Ajso6nTTjptu2UHLx6hfSXVtHFtRBJCkKYd5SAyj7zf5" == $match0))
3434 then $Tuple4(2000000, 40000000, 80000000, 150000000)
3535 else if (("HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS" == $match0))
36- then $Tuple4(0, 20000000, 80000000, 40000000)
36+ then $Tuple4(0, 50000000, 80000000, 400000000)
3737 else if (("WAVES" == $match0))
3838 then $Tuple4(2000000, 30000000, 80000000, 50000000)
3939 else if (("Atqv59EYzjFGuitKVnMRk6H8FukjoV3ktPorbEys25on" == $match0))
5454 then $Tuple4(2000000, 40000000, 80000000, 100000000)
5555 else if (("YiNbofFzC17jEHHCMwrRcpy9MrrjabMMLZxg8g5xmf7" == $match0))
5656 then $Tuple4(2000000, 30000000, 80000000, 80000000)
57- else $Tuple4(0, 20000000, 80000000, 80000000)
57+ else if (("3VuV5WTmDz47Dmdn3QpcYjzbSdipjQE4JMdNe1xZpX13" == $match0))
58+ then $Tuple4(0, 100000000, 80000000, 400000000)
59+ else $Tuple4(0, 20000000, 80000000, 80000000)
5860 }
5961
6062
7880
7981 func $f0_2 ($a,$i) = if (($i >= $s))
8082 then $a
81- else throw("List size exceeds 8")
83+ else throw("List size exceeds 12")
8284
83- $f0_2($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)
85+ $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)
8486 }
8587
8688
194196
195197 func $f0_2 ($a,$i) = if (($i >= $s))
196198 then $a
197- else throw("List size exceeds 8")
199+ else throw("List size exceeds 12")
198200
199- $f0_2($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)
201+ $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)
200202 }
201203
202204
219221
220222 func $f0_2 ($a,$i) = if (($i >= $s))
221223 then $a
222- else throw("List size exceeds 8")
224+ else throw("List size exceeds 12")
223225
224- $f0_2($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)
226+ $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)
225227 }
226228
227229
238240 }
239241
240242
241-func getTokenPrice (assetIdStr) = if (if ((assetIdStr == "9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi"))
242- then true
243- else (assetIdStr == "HGgabTqUS8WtVFUJzfmrTDMgEccJuZLBPhFgQFxvnsoW"))
244- then $Tuple2(1000000, 1000000)
245- else {
246- let price = getIntegerValue(Address(base58'3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t'), (assetIdStr + "_twap5B"))
247- let riskLevel = getIntegerValue(Address(base58'3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t'), (assetIdStr + "_riskLevel"))
248- if ((1 >= riskLevel))
249- then $Tuple2(price, price)
250- else throw((("oracle prices don't match: " + toString(price)) + " is the price, but risk is too high"))
251- }
243+func getTokenPrice (assetIdStr) = getTokenPriceWithRisk(assetIdStr, 3)
252244
253245
254246 func calcAssetScale (assetIdStr) = {
287279 else {
288280 let assetIdStr = getAssetString(i.payments[0].assetId)
289281 let assetAmount = i.payments[0].amount
290- let $t085848651 = getActualRate(assetIdStr, "sRate")
291- let sRate = $t085848651._1
292- let ratesRecalcResult = $t085848651._2
282+ let $t081658232 = getActualRate(assetIdStr, "sRate")
283+ let sRate = $t081658232._1
284+ let ratesRecalcResult = $t081658232._2
293285 let amount = fraction(assetAmount, Scale16, sRate, DOWN)
294286 let address = toString(i.caller)
295287 let maxSupply = match getString(("setup_maxSupply_" + assetIdStr)) {
316308
317309 @Callable(i)
318310 func withdraw (assetIdStr,assetAmount) = {
319- let $t0995410021 = getActualRate(assetIdStr, "sRate")
320- let sRate = $t0995410021._1
321- let ratesRecalcResult = $t0995410021._2
311+ let $t095359602 = getActualRate(assetIdStr, "sRate")
312+ let sRate = $t095359602._1
313+ let ratesRecalcResult = $t095359602._2
322314 let amount = fraction(assetAmount, Scale16, sRate, CEILING)
323315 let address = toString(i.caller)
324316 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
352344 @Callable(i)
353345 func borrow (assetIdStr,assetAmount) = {
354346 let address = toString(i.caller)
355- let $t01159311660 = getActualRate(assetIdStr, "bRate")
356- let bRate = $t01159311660._1
357- let ratesRecalcResult = $t01159311660._2
347+ let $t01117411241 = getActualRate(assetIdStr, "bRate")
348+ let bRate = $t01117411241._1
349+ let ratesRecalcResult = $t01117411241._2
358350 let amount = fraction(assetAmount, Scale16, bRate, CEILING)
359351 let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",borrowed,") + toString(amount))], nil)
360352 if ((collateralValueInv == collateralValueInv))
393385 else {
394386 let assetIdStr = getAssetString(i.payments[0].assetId)
395387 let assetAmount = i.payments[0].amount
396- let $t01323313300 = getActualRate(assetIdStr, "bRate")
397- let bRate = $t01323313300._1
398- let ratesRecalcResult = $t01323313300._2
388+ let $t01281412881 = getActualRate(assetIdStr, "bRate")
389+ let bRate = $t01281412881._1
390+ let ratesRecalcResult = $t01281412881._2
399391 let amount = fraction(assetAmount, Scale16, bRate, CEILING)
400392 let address = toString(i.caller)
401393 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
419411 then throw("market is stopped")
420412 else if ((i.caller != Address(base58'3P4kBiU4wr2yV1S5gMfu3MdkVvy7kxXHsKe')))
421413 then throw("available only for reserve fund address")
422- else if (if ((size(i.payments) != 1))
423- then true
424- else (i.payments[0].amount == 0))
425- then throw("1 payment has to be attached")
426- else {
427- let assetIdStr = getAssetString(i.payments[0].assetId)
428- let assetAmount = i.payments[0].amount
429- let $t01481614883 = getActualRate(assetIdStr, "bRate")
430- let bRate = $t01481614883._1
431- let ratesRecalcResult = $t01481614883._2
432- let amount = fraction(assetAmount, Scale16, bRate, CEILING)
433- let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
434- let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
435- let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
436- let amountLeft = (userAssetBorrowed - amount)
437- let repayAmount = if ((amountLeft >= 0))
438- then amount
439- else userAssetBorrowed
440- if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
441- then throw("this asset is not supported by the market")
442- else (([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - repayAmount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - repayAmount))] ++ ratesRecalcResult) ++ (if ((amountLeft >= 0))
443- then nil
444- else [ScriptTransfer(i.caller, -(amountLeft), i.payments[0].assetId)]))
445- }
414+ else if ((address == "global"))
415+ then throw("you can't repay for everyone :_)")
416+ else if (if ((size(i.payments) != 1))
417+ then true
418+ else (i.payments[0].amount == 0))
419+ then throw("1 payment has to be attached")
420+ else {
421+ let assetIdStr = getAssetString(i.payments[0].assetId)
422+ let assetAmount = i.payments[0].amount
423+ let $t01447814545 = getActualRate(assetIdStr, "bRate")
424+ let bRate = $t01447814545._1
425+ let ratesRecalcResult = $t01447814545._2
426+ let amount = fraction(assetAmount, Scale16, bRate, CEILING)
427+ let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
428+ let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
429+ let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
430+ let amountLeft = (userAssetBorrowed - amount)
431+ let repayAmount = if ((amountLeft >= 0))
432+ then amount
433+ else userAssetBorrowed
434+ if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
435+ then throw("this asset is not supported by the market")
436+ else (([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - repayAmount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - repayAmount))] ++ ratesRecalcResult) ++ (if ((amountLeft >= 0))
437+ then nil
438+ else [ScriptTransfer(i.caller, -(amountLeft), i.payments[0].assetId)]))
439+ }
446440
447441
448442
636630
637631 func $f0_2 ($a,$i) = if (($i >= $s))
638632 then $a
639- else throw("List size exceeds 8")
633+ else throw("List size exceeds 12")
640634
641- $f0_2($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)
635+ $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)
642636 }
643637 ([StringEntry("setup_tokens", tokens), StringEntry("setup_ltvs", ltvs), StringEntry("setup_lts", lts), StringEntry("setup_penalties", penalties), BooleanEntry("setup_active", true)] ++ rates)
644638 }
697691
698692 func $f0_2 ($a,$i) = if (($i >= $s))
699693 then $a
700- else throw("List size exceeds 8")
694+ else throw("List size exceeds 12")
701695
702- $f0_2($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)
696+ $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)
703697 }
704698 func f2 (accum,n) = if ((n >= size(assets)))
705699 then accum
720714
721715 func $f1_2 ($a,$i) = if (($i >= $s))
722716 then $a
723- else throw("List size exceeds 8")
717+ else throw("List size exceeds 12")
724718
725- $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8)
719+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12)
726720 }, parameter)
727721 }
728722
767761 let userCollateral = calcUserCollateral(address)
768762 if ((userCollateral == userCollateral))
769763 then {
770- let $t02836428426 = getActualRate(sAssetIdStr, "sRate")
771- let sRate = $t02836428426._1
772- let ratesResult = $t02836428426._2
773- let $t02843128500 = getActualRate(bAssetIdStr, "bRate")
774- let bRate = $t02843128500._1
775- let ratesRecalcResult2 = $t02843128500._2
764+ let $t02802928091 = getActualRate(sAssetIdStr, "sRate")
765+ let sRate = $t02802928091._1
766+ let ratesResult = $t02802928091._2
767+ let $t02809628165 = getActualRate(bAssetIdStr, "bRate")
768+ let bRate = $t02809628165._1
769+ let ratesRecalcResult2 = $t02809628165._2
776770 let sAssetAmount = fraction(assetAmount, Scale16, sRate)
777771 let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
778772 let currentBPositionVal = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
848842 let marketAssets = getMarketAssets()
849843 let asset1Num = value(indexOf(marketAssets, bAssetIdStr))
850844 let asset0Num = value(indexOf(marketAssets, sAssetIdStr))
851- let $t03165531717 = getActualRate(bAssetIdStr, "bRate")
852- let bRate = $t03165531717._1
853- let ratesResult = $t03165531717._2
845+ let $t03132031382 = getActualRate(bAssetIdStr, "bRate")
846+ let bRate = $t03132031382._1
847+ let ratesResult = $t03132031382._2
854848 let asset1Price = getTokenPrice(bAssetIdStr)._2
855849 let asset1Scale = calcAssetScale(bAssetIdStr)
856850 let bAmountUsd = fraction(bAssetAmount, asset1Price, asset1Scale)
920914 }
921915
922916 let result = {
923- let $l = [0, 1, 2, 3, 4, 5, 6]
917+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
924918 let $s = size($l)
925919 let $acc0 = 0
926920 func $f0_1 ($a,$i) = if (($i >= $s))
929923
930924 func $f0_2 ($a,$i) = if (($i >= $s))
931925 then $a
932- else throw("List size exceeds 8")
926+ else throw("List size exceeds 12")
933927
934- $f0_2($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)
928+ $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)
935929 }
936930 if (debug)
937931 then throw(toString(result))
951945 }
952946
953947 let result = {
954- let $l = [0, 1, 2, 3, 4, 5, 6, 7]
948+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
955949 let $s = size($l)
956950 let $acc0 = ""
957951 func $f0_1 ($a,$i) = if (($i >= $s))
960954
961955 func $f0_2 ($a,$i) = if (($i >= $s))
962956 then $a
963- else throw("List size exceeds 8")
957+ else throw("List size exceeds 12")
964958
965- $f0_2($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)
959+ $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)
966960 }
967961 if (debug)
968962 then throw(result)
1002996
1003997 func $f0_2 ($a,$i) = if (($i >= $s))
1004998 then $a
1005- else throw("List size exceeds 8")
999+ else throw("List size exceeds 12")
10061000
1007- $f0_2($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)
1001+ $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)
10081002 }
10091003 if (debug)
10101004 then throw(parameter._1)
10301024
10311025 func $f0_2 ($a,$i) = if (($i >= $s))
10321026 then $a
1033- else throw("List size exceeds 8")
1027+ else throw("List size exceeds 12")
10341028
1035- $f0_2($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)
1029+ $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)
10361030 }
10371031 if (debug)
10381032 then throw(parameter)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let reserveFundAddress = Address(base58'3P4kBiU4wr2yV1S5gMfu3MdkVvy7kxXHsKe')
55
66 let reserveFund = 20
77
88 let aggregatorAddress = Address(base58'3PGFHzVGT4NTigwCKP1NcwoXkodVZwvBuuU')
99
1010 let oracleStr = "3PPXVKjN6nRMzXeegcYhfiic96pd2c98Ekm"
1111
1212 let shutdownWhitelist = [base58'3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL', base58'3PAxdDSmN758L5SHSGRC5apEtQE2aApZotG', base58'3PJKmXoHJvVeQXjSJdhtkUcFDtdiQqMbUTD', base58'3PQdNxynJy5mche2kxMVc5shXWzK8Gstq3o', base58'3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3', base58'3P6Ksahs71SiKQgQ4qaZuFAVhqncdi2nvJQ']
1313
1414 func verifyLiquidatorRights (address) = !(if (if ((address != Address(base58'3PCqdm1mAoQqR46oZotFanmqb5CLUvrKEo2')))
1515 then (address != Address(base58'3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL'))
1616 else false)
1717 then (address != Address(base58'3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3'))
1818 else false)
1919
2020
2121 func getRateCurve (assetIdStr) = match assetIdStr {
2222 case _ =>
2323 if (("9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi" == $match0))
2424 then $Tuple4(2000000, 25000000, 80000000, 100000000)
2525 else if (("HGgabTqUS8WtVFUJzfmrTDMgEccJuZLBPhFgQFxvnsoW" == $match0))
2626 then $Tuple4(2000000, 25000000, 80000000, 100000000)
2727 else if (("34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ" == $match0))
2828 then $Tuple4(2000000, 25000000, 80000000, 100000000)
2929 else if (("6XtHjpXbs9RRJP2Sr9GUyVqzACcby9TkThHXnjVC5CDJ" == $match0))
3030 then $Tuple4(2000000, 25000000, 80000000, 100000000)
3131 else if (("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p" == $match0))
3232 then $Tuple4(2000000, 25000000, 80000000, 100000000)
3333 else if (("Ajso6nTTjptu2UHLx6hfSXVtHFtRBJCkKYd5SAyj7zf5" == $match0))
3434 then $Tuple4(2000000, 40000000, 80000000, 150000000)
3535 else if (("HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS" == $match0))
36- then $Tuple4(0, 20000000, 80000000, 40000000)
36+ then $Tuple4(0, 50000000, 80000000, 400000000)
3737 else if (("WAVES" == $match0))
3838 then $Tuple4(2000000, 30000000, 80000000, 50000000)
3939 else if (("Atqv59EYzjFGuitKVnMRk6H8FukjoV3ktPorbEys25on" == $match0))
4040 then $Tuple4(0, 20000000, 80000000, 40000000)
4141 else if (("DSbbhLsSTeDg5Lsiufk2Aneh3DjVqJuPr2M9uU1gwy5p" == $match0))
4242 then $Tuple4(0, 20000000, 80000000, 100000000)
4343 else if (("8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91" == $match0))
4444 then $Tuple4(0, 30000000, 80000000, 40000000)
4545 else if (("At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL" == $match0))
4646 then $Tuple4(0, 25000000, 80000000, 40000000)
4747 else if (("8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS" == $match0))
4848 then $Tuple4(2000000, 30000000, 80000000, 50000000)
4949 else if (("474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu" == $match0))
5050 then $Tuple4(2000000, 30000000, 80000000, 50000000)
5151 else if (("5UYBPpq4WoU5n4MwpFkgJnW3Fq4B1u3ukpK33ik4QerR" == $match0))
5252 then $Tuple4(2000000, 30000000, 80000000, 50000000)
5353 else if (("2thsACuHmzDMuNezPM32wg9a3BwUzBWDeSKakgz3cw21" == $match0))
5454 then $Tuple4(2000000, 40000000, 80000000, 100000000)
5555 else if (("YiNbofFzC17jEHHCMwrRcpy9MrrjabMMLZxg8g5xmf7" == $match0))
5656 then $Tuple4(2000000, 30000000, 80000000, 80000000)
57- else $Tuple4(0, 20000000, 80000000, 80000000)
57+ else if (("3VuV5WTmDz47Dmdn3QpcYjzbSdipjQE4JMdNe1xZpX13" == $match0))
58+ then $Tuple4(0, 100000000, 80000000, 400000000)
59+ else $Tuple4(0, 20000000, 80000000, 80000000)
5860 }
5961
6062
6163 let Scale8 = 100000000
6264
6365 let Scale10 = 10000000000
6466
6567 let Scale16 = (Scale8 * Scale8)
6668
6769 let dayBlocks = 1440
6870
6971 func liIntToStr (li) = {
7072 func f (accum,next) = ((accum + toString(next)) + ",")
7173
7274 let $l = li
7375 let $s = size($l)
7476 let $acc0 = ""
7577 func $f0_1 ($a,$i) = if (($i >= $s))
7678 then $a
7779 else f($a, $l[$i])
7880
7981 func $f0_2 ($a,$i) = if (($i >= $s))
8082 then $a
81- else throw("List size exceeds 8")
83+ else throw("List size exceeds 12")
8284
83- $f0_2($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)
85+ $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)
8486 }
8587
8688
8789 func tryGetInteger (key) = match getInteger(this, key) {
8890 case b: Int =>
8991 b
9092 case _ =>
9193 0
9294 }
9395
9496
9597 func tryGetBoolean (key) = match getBoolean(this, key) {
9698 case b: Boolean =>
9799 b
98100 case _ =>
99101 false
100102 }
101103
102104
103105 func tryGetString (key) = match getString(this, key) {
104106 case b: String =>
105107 b
106108 case _ =>
107109 ""
108110 }
109111
110112
111113 func tryGetBinary (key) = match getBinary(this, key) {
112114 case b: ByteVector =>
113115 b
114116 case _ =>
115117 base58''
116118 }
117119
118120
119121 func getAssetString (assetId) = match assetId {
120122 case b: ByteVector =>
121123 toBase58String(b)
122124 case _ =>
123125 "WAVES"
124126 }
125127
126128
127129 func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES"))
128130 then unit
129131 else fromBase58String(assetIdStr)
130132
131133
132134 func getBalance (assetIdStr) = if ((assetIdStr == "WAVES"))
133135 then wavesBalance(this).available
134136 else assetBalance(this, fromBase58String(assetIdStr))
135137
136138
137139 func getMarketAssets () = split(tryGetString("setup_tokens"), ",")
138140
139141
140142 func getAssetsMaxSupply () = {
141143 let s = tryGetString("setup_maxSupply")
142144 if ((s == ""))
143145 then [-1, -1, -1, -1, -1, -1, -1]
144146 else split(s, ",")
145147 }
146148
147149
148150 func getOutdatedUr (assetIdStr) = {
149151 let down = fraction(tryGetInteger(("total_supplied_" + assetIdStr)), tryGetInteger((assetIdStr + "_sRate")), Scale16)
150152 if ((down == 0))
151153 then 0
152154 else fraction(Scale8, fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), tryGetInteger((assetIdStr + "_bRate")), Scale16), down)
153155 }
154156
155157
156158 func getInterest (assetIdStr) = {
157159 let ur = getOutdatedUr(assetIdStr)
158160 let curve = getRateCurve(assetIdStr)
159161 let rate = (curve._1 + (if ((curve._3 >= ur))
160162 then fraction(ur, curve._2, curve._3)
161163 else (curve._2 + fraction((ur - curve._3), curve._4, (100000000 - curve._3)))))
162164 max([fraction(rate, Scale8, (dayBlocks * 365)), 1])
163165 }
164166
165167
166168 func tokenRatesRecalc (assetIdStr) = {
167169 let interest = getInterest(assetIdStr)
168170 let ur = getOutdatedUr(assetIdStr)
169171 let lastRecalcHeight = tryGetInteger("lastRateHeight")
170172 let lastBRate = max([tryGetInteger((assetIdStr + "_bRate")), Scale16])
171173 let newBRate = (lastBRate + ((height - lastRecalcHeight) * interest))
172174 let lastSRate = max([tryGetInteger((assetIdStr + "_sRate")), Scale16])
173175 let newSRate = (lastSRate + ((((height - lastRecalcHeight) * fraction(interest, ur, Scale8)) * (100 - reserveFund)) / 100))
174176 [IntegerEntry((assetIdStr + "_sRate"), newSRate), IntegerEntry((assetIdStr + "_bRate"), newBRate), IntegerEntry("lastRateHeight", height)]
175177 }
176178
177179
178180 func getActualRate (assetIdStr,rateType) = {
179181 func f (accum,token) = {
180182 let recalc = tokenRatesRecalc(token)
181183 $Tuple2(if ((token != assetIdStr))
182184 then accum._1
183185 else if ((rateType == "sRate"))
184186 then recalc[0].value
185187 else recalc[1].value, (accum._2 ++ recalc))
186188 }
187189
188190 let $l = getMarketAssets()
189191 let $s = size($l)
190192 let $acc0 = $Tuple2(0, nil)
191193 func $f0_1 ($a,$i) = if (($i >= $s))
192194 then $a
193195 else f($a, $l[$i])
194196
195197 func $f0_2 ($a,$i) = if (($i >= $s))
196198 then $a
197- else throw("List size exceeds 8")
199+ else throw("List size exceeds 12")
198200
199- $f0_2($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)
201+ $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)
200202 }
201203
202204
203205 func getUr (assetIdStr) = {
204206 let rates = tokenRatesRecalc(assetIdStr)
205207 let down = fraction(tryGetInteger(("total_supplied_" + assetIdStr)), rates[0].value, Scale16)
206208 fraction(Scale8, fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), rates[1].value, Scale16), down)
207209 }
208210
209211
210212 func ratesRecalc () = {
211213 func f (accum,token) = (accum ++ tokenRatesRecalc(token))
212214
213215 let $l = getMarketAssets()
214216 let $s = size($l)
215217 let $acc0 = nil
216218 func $f0_1 ($a,$i) = if (($i >= $s))
217219 then $a
218220 else f($a, $l[$i])
219221
220222 func $f0_2 ($a,$i) = if (($i >= $s))
221223 then $a
222- else throw("List size exceeds 8")
224+ else throw("List size exceeds 12")
223225
224- $f0_2($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)
226+ $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)
225227 }
226228
227229
228230 func getTokenPriceWithRisk (assetIdStr,riskAversity) = if (if ((assetIdStr == "9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi"))
229231 then true
230232 else (assetIdStr == "HGgabTqUS8WtVFUJzfmrTDMgEccJuZLBPhFgQFxvnsoW"))
231233 then $Tuple2(1000000, 1000000)
232234 else {
233235 let price = getIntegerValue(Address(base58'3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t'), (assetIdStr + "_twap5B"))
234236 let riskLevel = getIntegerValue(Address(base58'3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t'), (assetIdStr + "_riskLevel"))
235237 if ((riskAversity >= riskLevel))
236238 then $Tuple2(price, price)
237239 else throw((("oracle prices don't match: " + toString(price)) + " is the price, but risk is too high"))
238240 }
239241
240242
241-func getTokenPrice (assetIdStr) = if (if ((assetIdStr == "9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi"))
242- then true
243- else (assetIdStr == "HGgabTqUS8WtVFUJzfmrTDMgEccJuZLBPhFgQFxvnsoW"))
244- then $Tuple2(1000000, 1000000)
245- else {
246- let price = getIntegerValue(Address(base58'3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t'), (assetIdStr + "_twap5B"))
247- let riskLevel = getIntegerValue(Address(base58'3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t'), (assetIdStr + "_riskLevel"))
248- if ((1 >= riskLevel))
249- then $Tuple2(price, price)
250- else throw((("oracle prices don't match: " + toString(price)) + " is the price, but risk is too high"))
251- }
243+func getTokenPrice (assetIdStr) = getTokenPriceWithRisk(assetIdStr, 3)
252244
253245
254246 func calcAssetScale (assetIdStr) = {
255247 let decimals = if ((assetIdStr == "WAVES"))
256248 then 8
257249 else value(assetInfo(fromBase58String(assetIdStr))).decimals
258250 pow(10, 0, decimals, 0, 0, DOWN)
259251 }
260252
261253
262254 func calcUserCollateral (address) = {
263255 let userCollateralInvoke = invoke(this, "getUserCollateral", [false, address, true, ""], nil)
264256 if ((userCollateralInvoke == userCollateralInvoke))
265257 then {
266258 let userCollateralValue = match userCollateralInvoke {
267259 case x: Int =>
268260 x
269261 case _ =>
270262 throw("issue while doing in-dapp invocation")
271263 }
272264 if ((userCollateralValue == userCollateralValue))
273265 then userCollateralValue
274266 else throw("Strict value is not equal to itself.")
275267 }
276268 else throw("Strict value is not equal to itself.")
277269 }
278270
279271
280272 @Callable(i)
281273 func supply () = if (!(tryGetBoolean("setup_active")))
282274 then throw("market is stopped")
283275 else if (if ((size(i.payments) != 1))
284276 then true
285277 else (i.payments[0].amount == 0))
286278 then throw("1 payment has to be attached")
287279 else {
288280 let assetIdStr = getAssetString(i.payments[0].assetId)
289281 let assetAmount = i.payments[0].amount
290- let $t085848651 = getActualRate(assetIdStr, "sRate")
291- let sRate = $t085848651._1
292- let ratesRecalcResult = $t085848651._2
282+ let $t081658232 = getActualRate(assetIdStr, "sRate")
283+ let sRate = $t081658232._1
284+ let ratesRecalcResult = $t081658232._2
293285 let amount = fraction(assetAmount, Scale16, sRate, DOWN)
294286 let address = toString(i.caller)
295287 let maxSupply = match getString(("setup_maxSupply_" + assetIdStr)) {
296288 case x: String =>
297289 parseIntValue(x)
298290 case _ =>
299291 tryGetInteger(("setup_maxSupply_" + assetIdStr))
300292 }
301293 let assetPrice = getTokenPrice(assetIdStr)
302294 let newTotalSupplied = (tryGetInteger(((address + "_supplied_") + assetIdStr)) + amount)
303295 let rate = getActualRate(assetIdStr, "sRate")._1
304296 let assetScale = calcAssetScale(assetIdStr)
305297 let newTotalSuppliedUsd = fraction(fraction(newTotalSupplied, rate, Scale16), assetPrice._1, assetScale)
306298 if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
307299 then throw("this asset is not supported by the market")
308300 else if (if ((maxSupply != 0))
309301 then (newTotalSuppliedUsd > maxSupply)
310302 else false)
311303 then throw("max total supply for this token reached in the pool")
312304 else ([IntegerEntry(((address + "_supplied_") + assetIdStr), newTotalSupplied), IntegerEntry(("total_supplied_" + assetIdStr), (tryGetInteger(("total_supplied_" + assetIdStr)) + amount))] ++ ratesRecalcResult)
313305 }
314306
315307
316308
317309 @Callable(i)
318310 func withdraw (assetIdStr,assetAmount) = {
319- let $t0995410021 = getActualRate(assetIdStr, "sRate")
320- let sRate = $t0995410021._1
321- let ratesRecalcResult = $t0995410021._2
311+ let $t095359602 = getActualRate(assetIdStr, "sRate")
312+ let sRate = $t095359602._1
313+ let ratesRecalcResult = $t095359602._2
322314 let amount = fraction(assetAmount, Scale16, sRate, CEILING)
323315 let address = toString(i.caller)
324316 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
325317 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
326318 let userAssetSupplied = tryGetInteger(((address + "_supplied_") + assetIdStr))
327319 let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
328320 let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",supplied,") + toString(-(amount)))], nil)
329321 if ((collateralValueInv == collateralValueInv))
330322 then {
331323 let collateralValue = match collateralValueInv {
332324 case x: Int =>
333325 x
334326 case _ =>
335327 throw("can't get user collateral value")
336328 }
337329 if (!(tryGetBoolean("setup_active")))
338330 then throw("market is stopped")
339331 else if ((0 > collateralValue))
340332 then throw("you dont have enough collateral for this operation")
341333 else if ((amount > (assetSupplied - assetBorrowed)))
342334 then throw("this amount is not available on the market")
343335 else if ((amount > (userAssetSupplied - userAssetBorrowed)))
344336 then throw("this amount is not available for this user")
345337 else ([IntegerEntry(((address + "_supplied_") + assetIdStr), (tryGetInteger(((address + "_supplied_") + assetIdStr)) - amount)), IntegerEntry(("total_supplied_" + assetIdStr), (tryGetInteger(("total_supplied_" + assetIdStr)) - amount)), ScriptTransfer(i.caller, assetAmount, getAssetBytes(assetIdStr))] ++ ratesRecalcResult)
346338 }
347339 else throw("Strict value is not equal to itself.")
348340 }
349341
350342
351343
352344 @Callable(i)
353345 func borrow (assetIdStr,assetAmount) = {
354346 let address = toString(i.caller)
355- let $t01159311660 = getActualRate(assetIdStr, "bRate")
356- let bRate = $t01159311660._1
357- let ratesRecalcResult = $t01159311660._2
347+ let $t01117411241 = getActualRate(assetIdStr, "bRate")
348+ let bRate = $t01117411241._1
349+ let ratesRecalcResult = $t01117411241._2
358350 let amount = fraction(assetAmount, Scale16, bRate, CEILING)
359351 let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",borrowed,") + toString(amount))], nil)
360352 if ((collateralValueInv == collateralValueInv))
361353 then {
362354 let collateralValue = match collateralValueInv {
363355 case x: Int =>
364356 x
365357 case _ =>
366358 throw("can't get user collateral value")
367359 }
368360 if (!(tryGetBoolean("setup_active")))
369361 then throw("market is stopped")
370362 else if ((0 > collateralValue))
371363 then throw("you have to supply more to borrow")
372364 else {
373365 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
374366 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
375367 let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
376368 if ((amount > (assetSupplied - assetBorrowed)))
377369 then throw("this amount is not available")
378370 else ([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed + amount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed + amount)), ScriptTransfer(i.caller, assetAmount, getAssetBytes(assetIdStr))] ++ ratesRecalcResult)
379371 }
380372 }
381373 else throw("Strict value is not equal to itself.")
382374 }
383375
384376
385377
386378 @Callable(i)
387379 func repay () = if (!(tryGetBoolean("setup_active")))
388380 then throw("market is stopped")
389381 else if (if ((size(i.payments) != 1))
390382 then true
391383 else (i.payments[0].amount == 0))
392384 then throw("1 payment has to be attached")
393385 else {
394386 let assetIdStr = getAssetString(i.payments[0].assetId)
395387 let assetAmount = i.payments[0].amount
396- let $t01323313300 = getActualRate(assetIdStr, "bRate")
397- let bRate = $t01323313300._1
398- let ratesRecalcResult = $t01323313300._2
388+ let $t01281412881 = getActualRate(assetIdStr, "bRate")
389+ let bRate = $t01281412881._1
390+ let ratesRecalcResult = $t01281412881._2
399391 let amount = fraction(assetAmount, Scale16, bRate, CEILING)
400392 let address = toString(i.caller)
401393 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
402394 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
403395 let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
404396 let amountLeft = (userAssetBorrowed - amount)
405397 let repayAmount = if ((amountLeft >= 0))
406398 then amount
407399 else userAssetBorrowed
408400 if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
409401 then throw("this asset is not supported by the market")
410402 else (([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - repayAmount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - repayAmount))] ++ ratesRecalcResult) ++ (if ((amountLeft >= 0))
411403 then nil
412404 else [ScriptTransfer(i.caller, -(amountLeft), i.payments[0].assetId)]))
413405 }
414406
415407
416408
417409 @Callable(i)
418410 func repayFor (address) = if (!(tryGetBoolean("setup_active")))
419411 then throw("market is stopped")
420412 else if ((i.caller != Address(base58'3P4kBiU4wr2yV1S5gMfu3MdkVvy7kxXHsKe')))
421413 then throw("available only for reserve fund address")
422- else if (if ((size(i.payments) != 1))
423- then true
424- else (i.payments[0].amount == 0))
425- then throw("1 payment has to be attached")
426- else {
427- let assetIdStr = getAssetString(i.payments[0].assetId)
428- let assetAmount = i.payments[0].amount
429- let $t01481614883 = getActualRate(assetIdStr, "bRate")
430- let bRate = $t01481614883._1
431- let ratesRecalcResult = $t01481614883._2
432- let amount = fraction(assetAmount, Scale16, bRate, CEILING)
433- let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
434- let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
435- let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
436- let amountLeft = (userAssetBorrowed - amount)
437- let repayAmount = if ((amountLeft >= 0))
438- then amount
439- else userAssetBorrowed
440- if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
441- then throw("this asset is not supported by the market")
442- else (([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - repayAmount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - repayAmount))] ++ ratesRecalcResult) ++ (if ((amountLeft >= 0))
443- then nil
444- else [ScriptTransfer(i.caller, -(amountLeft), i.payments[0].assetId)]))
445- }
414+ else if ((address == "global"))
415+ then throw("you can't repay for everyone :_)")
416+ else if (if ((size(i.payments) != 1))
417+ then true
418+ else (i.payments[0].amount == 0))
419+ then throw("1 payment has to be attached")
420+ else {
421+ let assetIdStr = getAssetString(i.payments[0].assetId)
422+ let assetAmount = i.payments[0].amount
423+ let $t01447814545 = getActualRate(assetIdStr, "bRate")
424+ let bRate = $t01447814545._1
425+ let ratesRecalcResult = $t01447814545._2
426+ let amount = fraction(assetAmount, Scale16, bRate, CEILING)
427+ let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
428+ let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
429+ let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
430+ let amountLeft = (userAssetBorrowed - amount)
431+ let repayAmount = if ((amountLeft >= 0))
432+ then amount
433+ else userAssetBorrowed
434+ if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
435+ then throw("this asset is not supported by the market")
436+ else (([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - repayAmount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - repayAmount))] ++ ratesRecalcResult) ++ (if ((amountLeft >= 0))
437+ then nil
438+ else [ScriptTransfer(i.caller, -(amountLeft), i.payments[0].assetId)]))
439+ }
446440
447441
448442
449443 @Callable(i)
450444 func stakeTokenAll (assetIdStr) = if ((i.caller != this))
451445 then throw("only for internal smart contract invocations")
452446 else {
453447 let amount = getBalance(assetIdStr)
454448 let inv = invoke(this, "stakeToken", [assetIdStr, amount], nil)
455449 if ((inv == inv))
456450 then nil
457451 else throw("Strict value is not equal to itself.")
458452 }
459453
460454
461455
462456 @Callable(i)
463457 func stakeToken (assetIdStr,amount) = if ((i.caller != this))
464458 then throw("only for internal smart contract invocations")
465459 else if ((assetIdStr == "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"))
466460 then {
467461 let amountStaked = tryGetInteger("autostake_amount_DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
468462 let inv = invoke(Address(base58'3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ'), "stake", nil, [AttachedPayment(base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p', amount)])
469463 if ((inv == inv))
470464 then [IntegerEntry("autostake_amount_DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p", (amountStaked + amount))]
471465 else throw("Strict value is not equal to itself.")
472466 }
473467 else if ((assetIdStr == "8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91"))
474468 then {
475469 let amountStaked = tryGetInteger("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91")
476470 let inv = invoke(Address(base58'3PQTM38wDmAY9vWonK6ha7QL3PAycLz5oPP'), "stake", nil, [AttachedPayment(base58'8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91', amount)])
477471 if ((inv == inv))
478472 then [IntegerEntry("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91", (amountStaked + amount))]
479473 else throw("Strict value is not equal to itself.")
480474 }
481475 else if ((assetIdStr == "At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL"))
482476 then {
483477 let amountStaked = tryGetInteger("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL")
484478 let inv = invoke(Address(base58'3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C'), "stake", nil, [AttachedPayment(base58'At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL', amount)])
485479 if ((inv == inv))
486480 then [IntegerEntry("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", (amountStaked + amount))]
487481 else throw("Strict value is not equal to itself.")
488482 }
489483 else nil
490484
491485
492486
493487 @Callable(i)
494488 func unstakeToken (assetIdStr,amount) = if ((i.caller != this))
495489 then throw("only for internal smart contract invocations")
496490 else if ((assetIdStr == "8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91"))
497491 then {
498492 let amountStaked = tryGetInteger("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91")
499493 let inv = invoke(Address(base58'3PQTM38wDmAY9vWonK6ha7QL3PAycLz5oPP'), "unStake", [amount], nil)
500494 if ((inv == inv))
501495 then [IntegerEntry("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91", (amountStaked - amount))]
502496 else throw("Strict value is not equal to itself.")
503497 }
504498 else if ((assetIdStr == "At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL"))
505499 then {
506500 let amountStaked = tryGetInteger("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL")
507501 let inv = invoke(Address(base58'3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C'), "unstake", [amount], nil)
508502 if ((inv == inv))
509503 then {
510504 let bal0 = getBalance("At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL")
511505 if ((bal0 == bal0))
512506 then {
513507 let inv2 = invoke(Address(base58'3PQrVbTVpqXHqpVKftkNdjy3zZAh4dsRzN6'), "gnsbtRewardsSYSREADONLY", [toString(this)], nil)
514508 if ((inv2 == inv2))
515509 then {
516510 let topupRewards = match inv2 {
517511 case x: List[Any] =>
518512 let secondEl = x[1]
519513 match secondEl {
520514 case secondEl: String =>
521515 let usdnValue = parseIntValue(split(split(secondEl, "_")[1], ":")[1])
522516 let wavesValue = parseIntValue(split(split(secondEl, "_")[0], ":")[1])
523517 if (if ((usdnValue != 0))
524518 then true
525519 else (wavesValue != 0))
526520 then {
527521 let usdnBal0 = getBalance("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
528522 if ((usdnBal0 == usdnBal0))
529523 then {
530524 let wavesBal0 = getBalance("WAVES")
531525 if ((wavesBal0 == wavesBal0))
532526 then {
533527 let inv3 = invoke(Address(base58'3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C'), "claimRewards", nil, nil)
534528 if ((inv3 == inv3))
535529 then {
536530 let wavesBal1 = getBalance("WAVES")
537531 if ((wavesBal1 == wavesBal1))
538532 then {
539533 let inv4 = invoke(Address(base58'3PLiXyywNThdvf3vVEUxwc7TJTucjZvuegh'), "swap", ["DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p", 0], [AttachedPayment(unit, (wavesBal1 - wavesBal0))])
540534 if ((inv4 == inv4))
541535 then {
542536 let usdnBal1 = getBalance("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
543537 if ((usdnBal1 == usdnBal1))
544538 then {
545539 let inv5 = invoke(Address(base58'3P7r93vXHuusageNJVGwzqaz3WMotAu49Yz'), "swap", ["At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", 0], [AttachedPayment(base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p', (usdnBal1 - usdnBal0))])
546540 if ((inv5 == inv5))
547541 then {
548542 let inv6 = invoke(this, "addInterest", ["At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", (getBalance("At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL") - bal0)], nil)
549543 if ((inv6 == inv6))
550544 then 2
551545 else throw("Strict value is not equal to itself.")
552546 }
553547 else throw("Strict value is not equal to itself.")
554548 }
555549 else throw("Strict value is not equal to itself.")
556550 }
557551 else throw("Strict value is not equal to itself.")
558552 }
559553 else throw("Strict value is not equal to itself.")
560554 }
561555 else throw("Strict value is not equal to itself.")
562556 }
563557 else throw("Strict value is not equal to itself.")
564558 }
565559 else throw("Strict value is not equal to itself.")
566560 }
567561 else 1
568562 case _ =>
569563 1
570564 }
571565 case _ =>
572566 0
573567 }
574568 if ((topupRewards == topupRewards))
575569 then [IntegerEntry("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", (amountStaked - amount))]
576570 else throw("Strict value is not equal to itself.")
577571 }
578572 else throw("Strict value is not equal to itself.")
579573 }
580574 else throw("Strict value is not equal to itself.")
581575 }
582576 else throw("Strict value is not equal to itself.")
583577 }
584578 else nil
585579
586580
587581
588582 @Callable(i)
589583 func addInterest (assetIdStr,amount) = if ((i.caller != this))
590584 then throw("only for self invocation")
591585 else {
592586 let earned = tryGetInteger(("autostake_lastEarned_" + assetIdStr))
593587 let lastHeight = tryGetInteger(("autostake_lastBlock_" + assetIdStr))
594588 let cleanAmount = fraction(amount, 80, 100)
595589 let stateChanges = if (if ((lastHeight == height))
596590 then true
597591 else (amount == 0))
598592 then nil
599593 else [IntegerEntry(("autostake_preLastEarned_" + assetIdStr), earned), IntegerEntry(("autostake_preLastBlock_" + assetIdStr), lastHeight), IntegerEntry(("autostake_lastEarned_" + assetIdStr), (earned + cleanAmount)), IntegerEntry(("autostake_lastBlock_" + assetIdStr), height)]
600594 (stateChanges ++ [IntegerEntry((assetIdStr + "_sRate"), (tryGetInteger((assetIdStr + "_sRate")) + fraction(Scale16, cleanAmount, tryGetInteger(("total_supplied_" + assetIdStr)))))])
601595 }
602596
603597
604598
605599 @Callable(i)
606600 func addInterestEXTERNAL () = {
607601 let amount = fraction(i.payments[0].amount, 80, 100)
608602 let assetId = i.payments[0].assetId
609603 let assetIdStr = getAssetString(assetId)
610604 let earned = tryGetInteger(("autostake_lastEarned_" + assetIdStr))
611605 let lastHeight = tryGetInteger(("autostake_lastBlock_" + assetIdStr))
612606 let stateChanges = if (if ((lastHeight == height))
613607 then true
614608 else (amount == 0))
615609 then nil
616610 else [IntegerEntry(("autostake_preLastEarned_" + assetIdStr), earned), IntegerEntry(("autostake_preLastBlock_" + assetIdStr), lastHeight), IntegerEntry(("autostake_lastEarned_" + assetIdStr), (earned + amount)), IntegerEntry(("autostake_lastBlock_" + assetIdStr), height)]
617611 (stateChanges ++ [IntegerEntry((assetIdStr + "_sRate"), (tryGetInteger((assetIdStr + "_sRate")) + fraction(Scale16, amount, tryGetInteger(("total_supplied_" + assetIdStr)))))])
618612 }
619613
620614
621615
622616 @Callable(i)
623617 func preInit (tokens,ltvs,lts,penalties) = {
624618 func f (accum,token) = (accum ++ [IntegerEntry((token + "_bRate"), Scale16), IntegerEntry((token + "_sRate"), Scale16)])
625619
626620 if ((i.caller != this))
627621 then throw("admin only")
628622 else {
629623 let rates = {
630624 let $l = split(tokens, ",")
631625 let $s = size($l)
632626 let $acc0 = nil
633627 func $f0_1 ($a,$i) = if (($i >= $s))
634628 then $a
635629 else f($a, $l[$i])
636630
637631 func $f0_2 ($a,$i) = if (($i >= $s))
638632 then $a
639- else throw("List size exceeds 8")
633+ else throw("List size exceeds 12")
640634
641- $f0_2($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)
635+ $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)
642636 }
643637 ([StringEntry("setup_tokens", tokens), StringEntry("setup_ltvs", ltvs), StringEntry("setup_lts", lts), StringEntry("setup_penalties", penalties), BooleanEntry("setup_active", true)] ++ rates)
644638 }
645639 }
646640
647641
648642
649643 @Callable(i)
650644 func initNewToken (token,ltv,lt,penalty) = if ((i.caller != this))
651645 then throw("admin only")
652646 else [StringEntry("setup_tokens", ((tryGetString("setup_tokens") + ",") + token)), StringEntry("setup_ltvs", ((tryGetString("setup_ltvs") + ",") + ltv)), StringEntry("setup_lts", ((tryGetString("setup_lts") + ",") + lt)), StringEntry("setup_penalties", ((tryGetString("setup_penalties") + ",") + penalty)), IntegerEntry((token + "_bRate"), Scale16), IntegerEntry((token + "_sRate"), Scale16)]
653647
654648
655649
656650 @Callable(i)
657651 func updateParameter (key,val) = if (if ((i.caller != this))
658652 then (i.caller != Address(base58'3P3o9cLTV2u9N4nYNKRYL6gy6cUEU9DwXW8'))
659653 else false)
660654 then throw("admin only")
661655 else [IntegerEntry(key, parseIntValue(val))]
662656
663657
664658
665659 @Callable(i)
666660 func updateString (key,val) = if (if ((i.caller != this))
667661 then (i.caller != Address(base58'3P3o9cLTV2u9N4nYNKRYL6gy6cUEU9DwXW8'))
668662 else false)
669663 then throw("admin only")
670664 else [StringEntry(key, val)]
671665
672666
673667
674668 @Callable(i)
675669 func claimToReserveFund (debug) = {
676670 let assets = getMarketAssets()
677671 let rates = getActualRate(assets[0], "sRate")._2
678672 let li = [0, 1, 2, 3, 4, 5, 6]
679673 func f (accum,n) = if ((n >= size(assets)))
680674 then accum
681675 else {
682676 let assetIdStr = assets[n]
683677 let autostakeAmount = tryGetString(("autostake_amount_" + assetIdStr))
684678 let amount = ((((getBalance(assetIdStr) + tryGetInteger(("autostake_amount_" + assetIdStr))) + (if ((autostakeAmount != ""))
685679 then parseIntValue(autostakeAmount)
686680 else 0)) + fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), rates[((n * 3) + 1)].value, Scale16)) - fraction(tryGetInteger(("total_supplied_" + assetIdStr)), rates[(n * 3)].value, Scale16))
687681 (accum ++ [amount])
688682 }
689683
690684 let parameter = {
691685 let $l = li
692686 let $s = size($l)
693687 let $acc0 = nil
694688 func $f0_1 ($a,$i) = if (($i >= $s))
695689 then $a
696690 else f($a, $l[$i])
697691
698692 func $f0_2 ($a,$i) = if (($i >= $s))
699693 then $a
700- else throw("List size exceeds 8")
694+ else throw("List size exceeds 12")
701695
702- $f0_2($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)
696+ $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)
703697 }
704698 func f2 (accum,n) = if ((n >= size(assets)))
705699 then accum
706700 else {
707701 let assetIdStr = assets[n]
708702 (accum ++ [ScriptTransfer(reserveFundAddress, max([parameter[n], 0]), getAssetBytes(assetIdStr))])
709703 }
710704
711705 if (debug)
712706 then throw(liIntToStr(parameter))
713707 else $Tuple2({
714708 let $l = li
715709 let $s = size($l)
716710 let $acc0 = nil
717711 func $f1_1 ($a,$i) = if (($i >= $s))
718712 then $a
719713 else f2($a, $l[$i])
720714
721715 func $f1_2 ($a,$i) = if (($i >= $s))
722716 then $a
723- else throw("List size exceeds 8")
717+ else throw("List size exceeds 12")
724718
725- $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8)
719+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12)
726720 }, parameter)
727721 }
728722
729723
730724
731725 @Callable(i)
732726 func reSetup (assetIdStr) = {
733727 let lastResetup = tryGetInteger("resetup_lastUpdate")
734728 if ((dayBlocks > (height - lastResetup)))
735729 then throw("can be updated only once per day")
736730 else {
737731 let lts = split(tryGetString("setup_lts"), ",")
738732 let assets = getMarketAssets()
739733 let ur = getUr(assetIdStr)
740734 let tempLT = tryGetInteger((("setup_" + assetIdStr) + "_tempLT"))
741735 let lt = parseIntValue(assets[value(indexOf(assets, assetIdStr))])
742736 if ((ur > 90000000))
743737 then [IntegerEntry((("setup_" + assetIdStr) + "_tempLT"), fraction(tempLT, 9975, 10000))]
744738 else if (if ((lt > tempLT))
745739 then (90000000 > ur)
746740 else false)
747741 then [IntegerEntry((("setup_" + assetIdStr) + "_tempLT"), fraction(tempLT, 10025, 10000))]
748742 else nil
749743 }
750744 }
751745
752746
753747
754748 @Callable(i)
755749 func shutdown (shutdown) = if ((indexOf(shutdownWhitelist, i.caller.bytes) == unit))
756750 then throw("user not in a whitelist")
757751 else [BooleanEntry("setup_active", !(shutdown))]
758752
759753
760754
761755 @Callable(i)
762756 func liquidate (debug,address,assetAmount,sAssetIdStr,bAssetIdStr,routeStr) = if (!(verifyLiquidatorRights(i.caller)))
763757 then throw("temporarily available for whitelist only")
764758 else if (!(tryGetBoolean("setup_active")))
765759 then throw("market is stopped")
766760 else {
767761 let userCollateral = calcUserCollateral(address)
768762 if ((userCollateral == userCollateral))
769763 then {
770- let $t02836428426 = getActualRate(sAssetIdStr, "sRate")
771- let sRate = $t02836428426._1
772- let ratesResult = $t02836428426._2
773- let $t02843128500 = getActualRate(bAssetIdStr, "bRate")
774- let bRate = $t02843128500._1
775- let ratesRecalcResult2 = $t02843128500._2
764+ let $t02802928091 = getActualRate(sAssetIdStr, "sRate")
765+ let sRate = $t02802928091._1
766+ let ratesResult = $t02802928091._2
767+ let $t02809628165 = getActualRate(bAssetIdStr, "bRate")
768+ let bRate = $t02809628165._1
769+ let ratesRecalcResult2 = $t02809628165._2
776770 let sAssetAmount = fraction(assetAmount, Scale16, sRate)
777771 let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
778772 let currentBPositionVal = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
779773 let currentBPosition = if ((currentBPositionVal > 0))
780774 then currentBPositionVal
781775 else throw("user has no borrow in this token")
782776 if ((userCollateral > 0))
783777 then throw("user can't be liquidated")
784778 else if ((sAssetAmount > currentSPosition))
785779 then throw("position to liquidate is bigger than user's supply")
786780 else {
787781 let balance0Before = getBalance(sAssetIdStr)
788782 if ((balance0Before == balance0Before))
789783 then {
790784 let balance1Before = getBalance(bAssetIdStr)
791785 if ((balance1Before == balance1Before))
792786 then {
793787 let exchangeInvoke = invoke(aggregatorAddress, "swap", [routeStr, 0], [AttachedPayment(getAssetBytes(sAssetIdStr), assetAmount)])
794788 if ((exchangeInvoke == exchangeInvoke))
795789 then {
796790 let asset0Sold = (balance0Before - getBalance(sAssetIdStr))
797791 if ((asset0Sold == asset0Sold))
798792 then {
799793 let asset1Bought = (getBalance(bAssetIdStr) - balance1Before)
800794 if ((asset1Bought == asset1Bought))
801795 then {
802796 let asset0Price = getTokenPrice(sAssetIdStr)._1
803797 let asset0Scale = calcAssetScale(sAssetIdStr)
804798 let asset0Usd = fraction(asset0Sold, asset0Price, asset0Scale)
805799 let asset1Price = getTokenPrice(bAssetIdStr)._2
806800 let asset1Scale = calcAssetScale(bAssetIdStr)
807801 let asset1Usd = fraction(asset1Bought, asset1Price, asset1Scale)
808802 let penalty = parseIntValue(split(tryGetString("setup_penalties"), ",")[value(indexOf(getMarketAssets(), bAssetIdStr))])
809803 let liquidationProfit = (asset1Usd - fraction(asset0Usd, (Scale8 - penalty), Scale8))
810804 let sAssetChange = fraction(asset0Sold, Scale16, sRate)
811805 let bAssetChange = fraction(fraction(asset1Bought, Scale16, bRate), (Scale8 - fraction(liquidationProfit, Scale8, asset1Usd)), Scale8)
812806 if ((asset0Sold > assetAmount))
813807 then throw("more assets exchanged than expected")
814808 else if ((0 > liquidationProfit))
815809 then throw("price impact is bigger than liquidation penalty")
816810 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))]
817811 }
818812 else throw("Strict value is not equal to itself.")
819813 }
820814 else throw("Strict value is not equal to itself.")
821815 }
822816 else throw("Strict value is not equal to itself.")
823817 }
824818 else throw("Strict value is not equal to itself.")
825819 }
826820 else throw("Strict value is not equal to itself.")
827821 }
828822 }
829823 else throw("Strict value is not equal to itself.")
830824 }
831825
832826
833827
834828 @Callable(i)
835829 func liquidateV2 (debug,address,sAssetIdStr) = if (!(verifyLiquidatorRights(i.caller)))
836830 then throw("temporarily available for whitelist only")
837831 else if (!(tryGetBoolean("setup_active")))
838832 then throw("market is stopped")
839833 else {
840834 let bAssetId = i.payments[0].assetId
841835 let bAssetIdStr = getAssetString(bAssetId)
842836 let bAssetAmount = i.payments[0].amount
843837 let userCollateral = calcUserCollateral(address)
844838 if ((userCollateral == userCollateral))
845839 then if ((userCollateral > 0))
846840 then throw("user can't be liquidated")
847841 else {
848842 let marketAssets = getMarketAssets()
849843 let asset1Num = value(indexOf(marketAssets, bAssetIdStr))
850844 let asset0Num = value(indexOf(marketAssets, sAssetIdStr))
851- let $t03165531717 = getActualRate(bAssetIdStr, "bRate")
852- let bRate = $t03165531717._1
853- let ratesResult = $t03165531717._2
845+ let $t03132031382 = getActualRate(bAssetIdStr, "bRate")
846+ let bRate = $t03132031382._1
847+ let ratesResult = $t03132031382._2
854848 let asset1Price = getTokenPrice(bAssetIdStr)._2
855849 let asset1Scale = calcAssetScale(bAssetIdStr)
856850 let bAmountUsd = fraction(bAssetAmount, asset1Price, asset1Scale)
857851 let penalty = parseIntValue(value(split(tryGetString("setup_penalties"), ",")[asset1Num]))
858852 let asset0Price = getTokenPrice(sAssetIdStr)._1
859853 let asset0Scale = calcAssetScale(sAssetIdStr)
860854 let sAmountUsd = fraction(bAmountUsd, (Scale8 + penalty), Scale8)
861855 let sAssetAmount = fraction(sAmountUsd, asset0Scale, asset0Price)
862856 let bAmount = fraction(bAssetAmount, Scale16, bRate)
863857 let sAmount = fraction(sAssetAmount, Scale16, ratesResult[((asset0Num * 3) + 1)].value)
864858 let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
865859 let currentBPositionVal = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
866860 let currentBPosition = if ((currentBPositionVal > 0))
867861 then currentBPositionVal
868862 else throw("user has no borrow in this token")
869863 if ((sAmount > currentSPosition))
870864 then throw("position to liquidate is bigger than user's supply")
871865 else if (debug)
872866 then throw("liquidation will pass")
873867 else ([ScriptTransfer(i.caller, sAssetAmount, getAssetBytes(sAssetIdStr)), IntegerEntry(((address + "_supplied_") + sAssetIdStr), (currentSPosition - sAmount)), IntegerEntry(((address + "_borrowed_") + bAssetIdStr), (currentBPosition - bAmount)), IntegerEntry(("total_supplied_" + sAssetIdStr), (tryGetInteger(("total_supplied_" + sAssetIdStr)) - sAmount)), IntegerEntry(("total_borrowed_" + bAssetIdStr), (tryGetInteger(("total_borrowed_" + bAssetIdStr)) - bAmount))] ++ ratesResult)
874868 }
875869 else throw("Strict value is not equal to itself.")
876870 }
877871
878872
879873
880874 @Callable(i)
881875 func getUserCollateral (debug,address,minusBorrowed,afterChange) = {
882876 let assets = getMarketAssets()
883877 let ltvs = split(tryGetString("setup_ltvs"), ",")
884878 let lts = split(tryGetString("setup_lts"), ",")
885879 let rates = getActualRate(assets[0], "sRate")._2
886880 let changeHandler = split(afterChange, ",")
887881 func f (accum,next) = if ((next >= size(assets)))
888882 then accum
889883 else {
890884 let userSupplied = tryGetInteger(((address + "_supplied_") + assets[next]))
891885 let userBorrowed = tryGetInteger(((address + "_borrowed_") + assets[next]))
892886 let needTokenAccounting = if ((afterChange == ""))
893887 then if (if ((userBorrowed != 0))
894888 then true
895889 else (userSupplied != 0))
896890 then true
897891 else false
898892 else true
899893 if (needTokenAccounting)
900894 then {
901895 let assetScale = calcAssetScale(assets[next])
902896 let assetPrice = getTokenPrice(assets[next])
903897 ((accum + fraction(fraction(fraction((userSupplied + (if (if (if ((afterChange != ""))
904898 then (changeHandler[0] == assets[next])
905899 else false)
906900 then (changeHandler[1] == "supplied")
907901 else false)
908902 then parseIntValue(changeHandler[2])
909903 else 0)), rates[(next * 3)].value, Scale16), parseIntValue(ltvs[next]), Scale8), assetPrice._1, assetScale)) - (if (minusBorrowed)
910904 then fraction(fraction(fraction((userBorrowed + (if (if (if ((afterChange != ""))
911905 then (changeHandler[0] == assets[next])
912906 else false)
913907 then (changeHandler[1] == "borrowed")
914908 else false)
915909 then parseIntValue(changeHandler[2])
916910 else 0)), rates[((next * 3) + 1)].value, Scale16), Scale8, parseIntValue(lts[next])), assetPrice._2, assetScale)
917911 else 0))
918912 }
919913 else accum
920914 }
921915
922916 let result = {
923- let $l = [0, 1, 2, 3, 4, 5, 6]
917+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
924918 let $s = size($l)
925919 let $acc0 = 0
926920 func $f0_1 ($a,$i) = if (($i >= $s))
927921 then $a
928922 else f($a, $l[$i])
929923
930924 func $f0_2 ($a,$i) = if (($i >= $s))
931925 then $a
932- else throw("List size exceeds 8")
926+ else throw("List size exceeds 12")
933927
934- $f0_2($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)
928+ $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)
935929 }
936930 if (debug)
937931 then throw(toString(result))
938932 else $Tuple2(rates, result)
939933 }
940934
941935
942936
943937 @Callable(i)
944938 func getPrices (debug) = {
945939 let assets = getMarketAssets()
946940 func f (accum,next) = if ((next >= size(assets)))
947941 then accum
948942 else {
949943 let assetPrice = getTokenPriceWithRisk(assets[next], 3)
950944 ((((accum + toString(assetPrice._1)) + ",") + toString(assetPrice._2)) + "|")
951945 }
952946
953947 let result = {
954- let $l = [0, 1, 2, 3, 4, 5, 6, 7]
948+ let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
955949 let $s = size($l)
956950 let $acc0 = ""
957951 func $f0_1 ($a,$i) = if (($i >= $s))
958952 then $a
959953 else f($a, $l[$i])
960954
961955 func $f0_2 ($a,$i) = if (($i >= $s))
962956 then $a
963- else throw("List size exceeds 8")
957+ else throw("List size exceeds 12")
964958
965- $f0_2($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)
959+ $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)
966960 }
967961 if (debug)
968962 then throw(result)
969963 else $Tuple2(nil, result)
970964 }
971965
972966
973967
974968 @Callable(i)
975969 func calculateUtilizationRatio (assetIdStr,debug) = if (debug)
976970 then throw(toString(getUr(assetIdStr)))
977971 else $Tuple2(nil, getUr(assetIdStr))
978972
979973
980974
981975 @Callable(i)
982976 func calculateOutdatedUR (assetIdStr,debug) = if (debug)
983977 then throw(toString(getOutdatedUr(assetIdStr)))
984978 else $Tuple2(nil, getOutdatedUr(assetIdStr))
985979
986980
987981
988982 @Callable(i)
989983 func calculateTokenRates (debug) = {
990984 func f (accum,assetIdStr) = {
991985 let rates = tokenRatesRecalc(assetIdStr)
992986 $Tuple2(((((accum._1 + toString(rates[1].value)) + "|") + toString(rates[0].value)) + ","), (accum._2 ++ rates))
993987 }
994988
995989 let parameter = {
996990 let $l = getMarketAssets()
997991 let $s = size($l)
998992 let $acc0 = $Tuple2("", nil)
999993 func $f0_1 ($a,$i) = if (($i >= $s))
1000994 then $a
1001995 else f($a, $l[$i])
1002996
1003997 func $f0_2 ($a,$i) = if (($i >= $s))
1004998 then $a
1005- else throw("List size exceeds 8")
999+ else throw("List size exceeds 12")
10061000
1007- $f0_2($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)
1001+ $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)
10081002 }
10091003 if (debug)
10101004 then throw(parameter._1)
10111005 else $Tuple2(parameter._2, parameter._1)
10121006 }
10131007
10141008
10151009
10161010 @Callable(i)
10171011 func calculateTokensInterest (debug) = {
10181012 func f (accum,assetIdStr) = {
10191013 let rate = fraction(getInterest(assetIdStr), dayBlocks, Scale8)
10201014 ((accum + toString(rate)) + ",")
10211015 }
10221016
10231017 let parameter = {
10241018 let $l = getMarketAssets()
10251019 let $s = size($l)
10261020 let $acc0 = ""
10271021 func $f0_1 ($a,$i) = if (($i >= $s))
10281022 then $a
10291023 else f($a, $l[$i])
10301024
10311025 func $f0_2 ($a,$i) = if (($i >= $s))
10321026 then $a
1033- else throw("List size exceeds 8")
1027+ else throw("List size exceeds 12")
10341028
1035- $f0_2($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)
1029+ $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)
10361030 }
10371031 if (debug)
10381032 then throw(parameter)
10391033 else $Tuple2(nil, parameter)
10401034 }
10411035
10421036
10431037 @Verifier(tx)
10441038 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
10451039

github/deemru/w8io/3ef1775 
163.66 ms