tx · 6aL82FeuZ43Njgjn8uFnXpVTHDnWnqJTLVv6Mf7a1fVp

3P4uA5etnZi4AmBabKinq2bMiWU8KcnHZdH:  -0.03100000 Waves

2022.12.05 14:50 [3412475] smart account 3P4uA5etnZi4AmBabKinq2bMiWU8KcnHZdH > SELF 0.00000000 Waves

{ "type": 13, "id": "6aL82FeuZ43Njgjn8uFnXpVTHDnWnqJTLVv6Mf7a1fVp", "fee": 3100000, "feeAssetId": null, "timestamp": 1670241019911, "version": 2, "chainId": 87, "sender": "3P4uA5etnZi4AmBabKinq2bMiWU8KcnHZdH", "senderPublicKey": "8DxbUxhy23djr6kUEE1Jzp7oVJXBsHNaATLRiABpkSde", "proofs": [ "ZuhNy8BYBBw7NfexhP5q8GgB2QqansR5SHBP3K5k12b8eCUq6nXbLaHoJgyobX7n6fUSjcANdd6ZmrPXFf2i6PU" ], "script": "base64:BgJ8CAISABIECgIIARIECgIIARIAEgMKAQgSBAoCCAESBAoCCAESBAoCCAESABIGCgQICAgIEgQKAggIEgMKAQQSAwoBCBIDCgEEEggKBgQIAQgICBIFCgMECAgSBgoEBAgECBIDCgEEEgQKAggEEgQKAggEEgMKAQQSAwoBBBoABlNjYWxlOACAwtcvAAdTY2FsZTEwAIDIr6AlAAdTY2FsZTE2CQBoAgUGU2NhbGU4BQZTY2FsZTgACWRheUJsb2NrcwCgCwEKbGlJbnRUb1N0cgECbGkKAQFmAgVhY2N1bQRuZXh0CQCsAgIJAKwCAgUFYWNjdW0JAKQDAQUEbmV4dAIBLAoAAiRsBQJsaQoAAiRzCQCQAwEFAiRsCgAFJGFjYzACAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEBZgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgENdHJ5R2V0SW50ZWdlcgEDa2V5BAckbWF0Y2gwCQCaCAIFBHRoaXMFA2tleQMJAAECBQckbWF0Y2gwAgNJbnQEAWIFByRtYXRjaDAFAWIAAAENdHJ5R2V0Qm9vbGVhbgEDa2V5BAckbWF0Y2gwCQCbCAIFBHRoaXMFA2tleQMJAAECBQckbWF0Y2gwAgdCb29sZWFuBAFiBQckbWF0Y2gwBQFiBwEMdHJ5R2V0U3RyaW5nAQNrZXkEByRtYXRjaDAJAJ0IAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACBlN0cmluZwQBYgUHJG1hdGNoMAUBYgIAAQx0cnlHZXRCaW5hcnkBA2tleQQHJG1hdGNoMAkAnAgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBYgUHJG1hdGNoMAUBYgEAAQ5nZXRBc3NldFN0cmluZwEHYXNzZXRJZAQHJG1hdGNoMAUHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAFiBQckbWF0Y2gwCQDYBAEFAWICBVdBVkVTAQ1nZXRBc3NldEJ5dGVzAQphc3NldElkU3RyAwkAAAIFCmFzc2V0SWRTdHICBVdBVkVTBQR1bml0CQDZBAEFCmFzc2V0SWRTdHIBCmdldEJhbGFuY2UBCmFzc2V0SWRTdHIDCQAAAgUKYXNzZXRJZFN0cgIFV0FWRVMICQDvBwEFBHRoaXMJYXZhaWxhYmxlCQDwBwIFBHRoaXMJANkEAQUKYXNzZXRJZFN0cgAScmVzZXJ2ZUZ1bmRBZGRyZXNzCQEHQWRkcmVzcwEBGgFXHuH7QDFrgebsS1YbBSxRoZNu3wmxPNLBAAtyZXNlcnZlRnVuZAAUAQ9nZXRNYXJrZXRBc3NldHMACQC1CQIJAQx0cnlHZXRTdHJpbmcBAgxzZXR1cF90b2tlbnMCASwBEmdldEFzc2V0c01heFN1cHBseQAEAXMJAQx0cnlHZXRTdHJpbmcBAg9zZXR1cF9tYXhzdXBwbHkDCQAAAgUBcwIACQDMCAIA////////////AQkAzAgCAP///////////wEJAMwIAgD///////////8BCQDMCAIA////////////AQkAzAgCAP///////////wEJAMwIAgD///////////8BCQDMCAIA////////////AQUDbmlsCQC1CQIFAXMCASwBDWdldE91dGRhdGVkVXIBCmFzc2V0SWRTdHIEBGRvd24JAGsDCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYXNzZXRJZFN0cgIGX3NSYXRlBQdTY2FsZTE2AwkAAAIFBGRvd24AAAAACQBrAwUGU2NhbGU4CQBrAwkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFzc2V0SWRTdHICBl9iUmF0ZQUHU2NhbGUxNgUEZG93bgEMZ2V0UmF0ZUN1cnZlAQphc3NldElkU3RyBAckbWF0Y2gwBQphc3NldElkU3RyAwkAAAICLDM0TjlZY0VFVExXbjkzcVlRNjRFc1AxeDg5dFNydUpVNDRSckVNU1hYRVBKBQckbWF0Y2gwCQCWCgQAgIl6AMDw9QsAgOiSJgCAwtcvAwkAAAICLDZYdEhqcFhiczlSUkpQMlNyOUdVeVZxekFDY2J5OVRrVGhIWG5qVkM1Q0RKBQckbWF0Y2gwCQCWCgQAgIl6AMDw9QsAgOiSJgCAwtcvAwkAAAICLERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwBQckbWF0Y2gwCQCWCgQAgIl6AMDw9QsAgOiSJgCAwtcvAwkAAAICLEFqc282blRUanB0dTJVSEx4NmhmU1hWdEhGdFJCSkNrS1lkNVNBeWo3emY1BQckbWF0Y2gwCQCWCgQAgIl6AIC0iRMAgOiSJgCAo8NHAwkAAAICLEhFQjhRYXc5eHJXcFdzOHRIc2lBVFlHQldEQnRQMlM3a2NQQUxyTXU0M0FTBQckbWF0Y2gwCQCWCgQAAACA2sQJAIDokiYAgLSJEwMJAAACAgVXQVZFUwUHJG1hdGNoMAkAlgoEAICJegCAh6cOAIDokiYAgOHrFwMJAAACAixBdHF2NTlFWXpqRkd1aXRLVm5NUms2SDhGdWtqb1Yza3RQb3JiRXlzMjVvbgUHJG1hdGNoMAkAlgoEAAAAgNrECQCA6JImAIC0iRMDCQAAAgIsRFNiYmhMc1NUZURnNUxzaXVmazJBbmVoM0RqVnFKdVByMk05dVUxZ3d5NXAFByRtYXRjaDAJAJYKBAAAAIDaxAkAgOiSJgCAwtcvAwkAAAICLDh0NERQV1R3UHpwYXRIQTlBa1R4V0FCNDdUSG5ZekJzRG5vWTdmUXFiRzkxBQckbWF0Y2gwCQCWCgQAAACAh6cOAIDokiYAgLSJEwMJAAACAixBdDhENk5GRnBoZUNidktWbmpWb2VMTDg0RW84TlpuNm92TWFueGZMYUZXTAUHJG1hdGNoMAkAlgoEAAAAwPD1CwCA6JImAIC0iRMDCQAAAgIsOExRVzhmN1A1ZDVQWk03R3RaRUJnYXFSUEdTelMzRGZQdWlYclVSSjRBSlMFByRtYXRjaDAJAJYKBACAiXoAgIenDgCA6JImAIDh6xcDCQAAAgIsNDc0alRlWXgycjJWYTM1Nzk0dENTY0FYV0pHOWhVMkhjZ3h6TW93YVpVbnUFByRtYXRjaDAJAJYKBACAiXoAgIenDgCA6JImAIDh6xcDCQAAAgIsNVVZQlBwcTRXb1U1bjRNd3BGa2dKblczRnE0QjF1M3VrcEszM2lrNFFlclIFByRtYXRjaDAJAJYKBACAiXoAgIenDgCA6JImAIDh6xcJAJYKBAAAAIDaxAkAgOiSJgCA6JImAQtnZXRJbnRlcmVzdAEKYXNzZXRJZFN0cgQCdXIJAQ1nZXRPdXRkYXRlZFVyAQUKYXNzZXRJZFN0cgQFY3VydmUJAQxnZXRSYXRlQ3VydmUBBQphc3NldElkU3RyBARyYXRlCQBkAggFBWN1cnZlAl8xAwkAZwIIBQVjdXJ2ZQJfMwUCdXIJAGsDBQJ1cggFBWN1cnZlAl8yCAUFY3VydmUCXzMJAGQCCAUFY3VydmUCXzIJAGsDCQBlAgUCdXIIBQVjdXJ2ZQJfMwkAZQIIBQVjdXJ2ZQJfNAgFBWN1cnZlAl8yCQBlAgCAwtcvCAUFY3VydmUCXzMJAJYDAQkAzAgCCQBrAwUEcmF0ZQUGU2NhbGU4CQBoAgUJZGF5QmxvY2tzAO0CCQDMCAIAAQUDbmlsARB0b2tlblJhdGVzUmVjYWxjAQphc3NldElkU3RyBAhpbnRlcmVzdAkBC2dldEludGVyZXN0AQUKYXNzZXRJZFN0cgQCdXIJAQ1nZXRPdXRkYXRlZFVyAQUKYXNzZXRJZFN0cgQQbGFzdFJlY2FsY0hlaWdodAkBDXRyeUdldEludGVnZXIBAg5sYXN0UmF0ZUhlaWdodAQJbGFzdEJSYXRlCQCWAwEJAMwIAgkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFzc2V0SWRTdHICBl9iUmF0ZQkAzAgCBQdTY2FsZTE2BQNuaWwECG5ld0JSYXRlCQBkAgUJbGFzdEJSYXRlCQBoAgkAZQIFBmhlaWdodAUQbGFzdFJlY2FsY0hlaWdodAUIaW50ZXJlc3QECWxhc3RTUmF0ZQkAlgMBCQDMCAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphc3NldElkU3RyAgZfc1JhdGUJAMwIAgUHU2NhbGUxNgUDbmlsBAhuZXdTUmF0ZQkAZAIFCWxhc3RTUmF0ZQkAaQIJAGgCCQBoAgkAZQIFBmhlaWdodAUQbGFzdFJlY2FsY0hlaWdodAkAawMFCGludGVyZXN0BQJ1cgUGU2NhbGU4CQBlAgBkBQtyZXNlcnZlRnVuZABkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFzc2V0SWRTdHICBl9zUmF0ZQUIbmV3U1JhdGUJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYXNzZXRJZFN0cgIGX2JSYXRlBQhuZXdCUmF0ZQkAzAgCCQEMSW50ZWdlckVudHJ5AgIObGFzdFJhdGVIZWlnaHQFBmhlaWdodAUDbmlsAQ1nZXRBY3R1YWxSYXRlAgphc3NldElkU3RyCHJhdGVUeXBlCgEBZgIFYWNjdW0FdG9rZW4EBnJlY2FsYwkBEHRva2VuUmF0ZXNSZWNhbGMBBQV0b2tlbgkAlAoCAwkBAiE9AgUFdG9rZW4FCmFzc2V0SWRTdHIIBQVhY2N1bQJfMQMJAAACBQhyYXRlVHlwZQIFc1JhdGUICQCRAwIFBnJlY2FsYwAABXZhbHVlCAkAkQMCBQZyZWNhbGMAAQV2YWx1ZQkAzggCCAUFYWNjdW0CXzIFBnJlY2FsYwoAAiRsCQEPZ2V0TWFya2V0QXNzZXRzAAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgAABQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYBBWdldFVyAQphc3NldElkU3RyBAVyYXRlcwkBEHRva2VuUmF0ZXNSZWNhbGMBBQphc3NldElkU3RyBARkb3duCQBrAwkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cggJAJEDAgUFcmF0ZXMAAAV2YWx1ZQUHU2NhbGUxNgkAawMFBlNjYWxlOAkAawMJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIICQCRAwIFBXJhdGVzAAEFdmFsdWUFB1NjYWxlMTYFBGRvd24BC3JhdGVzUmVjYWxjAAoBAWYCBWFjY3VtBXRva2VuCQDOCAIFBWFjY3VtCQEQdG9rZW5SYXRlc1JlY2FsYwEFBXRva2VuCgACJGwJAQ9nZXRNYXJrZXRBc3NldHMACgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFmAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAQ1nZXRUb2tlblByaWNlAQphc3NldElkU3RyAwkAAAIFCmFzc2V0SWRTdHICLDZYdEhqcFhiczlSUkpQMlNyOUdVeVZxekFDY2J5OVRrVGhIWG5qVkM1Q0RKCQCUCgIAwIQ9AMCEPQQEaW52MQkA/AcECQERQGV4dHJOYXRpdmUoMTA2MikBAiMzUDVCVHRkajMyU2QxRHloMU1kdzMzeFFBQWNrU2ZNZm5LZgIJZ2V0VFdBUDYwCQDMCAIFCmFzc2V0SWRTdHIJAMwIAgcFA25pbAUDbmlsAwkAAAIFBGludjEFBGludjEEBGludjIJAPwHBAkBEUBleHRyTmF0aXZlKDEwNjIpAQIjM1A4cHZtY0JpOUplQnJuUGdXRFRhUFdyV21HenhpRGtwVHUCCWdldFRXQVA2MAkAzAgCBQphc3NldElkU3RyCQDMCAIHBQNuaWwFA25pbAMJAAACBQRpbnYyBQRpbnYyBAVkYXRhMQQHJG1hdGNoMAUEaW52MQMJAAECBQckbWF0Y2gwAgooSW50LCBJbnQpBAF4BQckbWF0Y2gwBQF4CQACAQIVZXJyb3Igb2YgcHJpY2Ugb3JhY2xlAwkAAAIFBWRhdGExBQVkYXRhMQQFZGF0YTIEByRtYXRjaDAFBGludjIDCQABAgUHJG1hdGNoMAIKKEludCwgSW50KQQBeAUHJG1hdGNoMAUBeAkAAgECFWVycm9yIG9mIHByaWNlIG9yYWNsZQMJAAACBQVkYXRhMgUFZGF0YTIJAJQKAgkAlwMBCQDMCAIIBQVkYXRhMQJfMQkAzAgCCAUFZGF0YTICXzEFA25pbAkAlgMBCQDMCAIIBQVkYXRhMQJfMgkAzAgCCAUFZGF0YTICXzIFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEOY2FsY0Fzc2V0U2NhbGUBCmFzc2V0SWRTdHIECGRlY2ltYWxzAwkAAAIFCmFzc2V0SWRTdHICBVdBVkVTAAgICQEFdmFsdWUBCQDsBwEJANkEAQUKYXNzZXRJZFN0cghkZWNpbWFscwkAbAYACgAABQhkZWNpbWFscwAAAAAFBERPV04BEmNhbGNVc2VyQ29sbGF0ZXJhbAEHYWRkcmVzcwQUdXNlckNvbGxhdGVyYWxJbnZva2UJAPwHBAUEdGhpcwIRZ2V0VXNlckNvbGxhdGVyYWwJAMwIAgcJAMwIAgUHYWRkcmVzcwkAzAgCBgkAzAgCAgAFA25pbAUDbmlsAwkAAAIFFHVzZXJDb2xsYXRlcmFsSW52b2tlBRR1c2VyQ29sbGF0ZXJhbEludm9rZQQTdXNlckNvbGxhdGVyYWxWYWx1ZQQHJG1hdGNoMAUUdXNlckNvbGxhdGVyYWxJbnZva2UDCQABAgUHJG1hdGNoMAIDSW50BAF4BQckbWF0Y2gwBQF4CQACAQIkaXNzdWUgd2hpbGUgZG9pbmcgaW4tZGFwcCBpbnZvY2F0aW9uAwkAAAIFE3VzZXJDb2xsYXRlcmFsVmFsdWUFE3VzZXJDb2xsYXRlcmFsVmFsdWUFE3VzZXJDb2xsYXRlcmFsVmFsdWUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4WAWkBBnN1cHBseQADCQEBIQEJAQ10cnlHZXRCb29sZWFuAQIMc2V0dXBfYWN0aXZlCQACAQIRbWFya2V0IGlzIHN0b3BwZWQDAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABBgkAAAIICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50AAAJAAIBAhwxIHBheW1lbnQgaGFzIHRvIGJlIGF0dGFjaGVkBAphc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQEC2Fzc2V0QW1vdW50CAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQLJHQwNjg5MDY5NTcJAQ1nZXRBY3R1YWxSYXRlAgUKYXNzZXRJZFN0cgIFc1JhdGUEBXNSYXRlCAULJHQwNjg5MDY5NTcCXzEEEXJhdGVzUmVjYWxjUmVzdWx0CAULJHQwNjg5MDY5NTcCXzIEBmFtb3VudAkAbgQFC2Fzc2V0QW1vdW50BQdTY2FsZTE2BQVzUmF0ZQUERE9XTgQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIECW1heFN1cHBseQQHJG1hdGNoMAkAoggBCQCsAgICEHNldHVwX21heFN1cHBseV8FCmFzc2V0SWRTdHIDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAF4BQckbWF0Y2gwCQENcGFyc2VJbnRWYWx1ZQEFAXgAAAQKYXNzZXRQcmljZQkBDWdldFRva2VuUHJpY2UBBQphc3NldElkU3RyBBBuZXdUb3RhbFN1cHBsaWVkCQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgUGYW1vdW50BARyYXRlCAkBDWdldEFjdHVhbFJhdGUCBQphc3NldElkU3RyAgVzUmF0ZQJfMQQKYXNzZXRTY2FsZQkBDmNhbGNBc3NldFNjYWxlAQUKYXNzZXRJZFN0cgQTbmV3VG90YWxTdXBwbGllZFVzZAkAawMJAGsDBRBuZXdUb3RhbFN1cHBsaWVkBQRyYXRlBQdTY2FsZTE2CAUKYXNzZXRQcmljZQJfMQUKYXNzZXRTY2FsZQMJAAACCQCzCQIJAQx0cnlHZXRTdHJpbmcBAgxzZXR1cF90b2tlbnMFCmFzc2V0SWRTdHIFBHVuaXQJAAIBAil0aGlzIGFzc2V0IGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIG1hcmtldAMDCQECIT0CBQltYXhTdXBwbHkAAAkAZgIFE25ld1RvdGFsU3VwcGxpZWRVc2QFCW1heFN1cHBseQcJAAIBAjNtYXggdG90YWwgc3VwcGx5IGZvciB0aGlzIHRva2VuIHJlYWNoZWQgaW4gdGhlIHBvb2wEA2ludgkA/AcEBQR0aGlzAgpzdGFrZVRva2VuCQDMCAIFCmFzc2V0SWRTdHIJAMwIAgULYXNzZXRBbW91bnQFA25pbAUDbmlsAwkAAAIFA2ludgUDaW52CQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQphc3NldElkU3RyBRBuZXdUb3RhbFN1cHBsaWVkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIFBmFtb3VudAUDbmlsBRFyYXRlc1JlY2FsY1Jlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQh3aXRoZHJhdwIKYXNzZXRJZFN0cgthc3NldEFtb3VudAQLJHQwODIxNTgyODIJAQ1nZXRBY3R1YWxSYXRlAgUKYXNzZXRJZFN0cgIFc1JhdGUEBXNSYXRlCAULJHQwODIxNTgyODICXzEEEXJhdGVzUmVjYWxjUmVzdWx0CAULJHQwODIxNTgyODICXzIEBmFtb3VudAkAbgQFC2Fzc2V0QW1vdW50BQdTY2FsZTE2BQVzUmF0ZQUHQ0VJTElORwQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEDWFzc2V0U3VwcGxpZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIEDWFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIEEXVzZXJBc3NldFN1cHBsaWVkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQphc3NldElkU3RyBBF1c2VyQXNzZXRCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgQSY29sbGF0ZXJhbFZhbHVlSW52CQD8BwQFBHRoaXMCEWdldFVzZXJDb2xsYXRlcmFsCQDMCAIHCQDMCAIFB2FkZHJlc3MJAMwIAgYJAMwIAgkArAICCQCsAgIFCmFzc2V0SWRTdHICCixzdXBwbGllZCwJAKQDAQkBAS0BBQZhbW91bnQFA25pbAUDbmlsAwkAAAIFEmNvbGxhdGVyYWxWYWx1ZUludgUSY29sbGF0ZXJhbFZhbHVlSW52BA9jb2xsYXRlcmFsVmFsdWUEByRtYXRjaDAFEmNvbGxhdGVyYWxWYWx1ZUludgMJAAECBQckbWF0Y2gwAgNJbnQEAXgFByRtYXRjaDAFAXgJAAIBAh9jYW4ndCBnZXQgdXNlciBjb2xsYXRlcmFsIHZhbHVlAwkBASEBCQENdHJ5R2V0Qm9vbGVhbgECDHNldHVwX2FjdGl2ZQkAAgECEW1hcmtldCBpcyBzdG9wcGVkAwkAZgIAAAUPY29sbGF0ZXJhbFZhbHVlCQACAQIyeW91IGRvbnQgaGF2ZSBlbm91Z2ggY29sbGF0ZXJhbCBmb3IgdGhpcyBvcGVyYXRpb24DCQBmAgUGYW1vdW50CQBlAgUNYXNzZXRTdXBwbGllZAUNYXNzZXRCb3Jyb3dlZAkAAgECKnRoaXMgYW1vdW50IGlzIG5vdCBhdmFpbGFibGUgb24gdGhlIG1hcmtldAQDaW52CQD8BwQFBHRoaXMCDHVuc3Rha2VUb2tlbgkAzAgCBQphc3NldElkU3RyCQDMCAIFC2Fzc2V0QW1vdW50BQNuaWwFA25pbAMJAAACBQNpbnYFA2ludgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgkAZQIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9zdXBwbGllZF8FCmFzc2V0SWRTdHIFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIJAGUCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyBQZhbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQthc3NldEFtb3VudAkBDWdldEFzc2V0Qnl0ZXMBBQphc3NldElkU3RyBQNuaWwFEXJhdGVzUmVjYWxjUmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBmJvcnJvdwIKYXNzZXRJZFN0cgthc3NldEFtb3VudAQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIECyR0MDk4NTQ5OTIxCQENZ2V0QWN0dWFsUmF0ZQIFCmFzc2V0SWRTdHICBWJSYXRlBAViUmF0ZQgFCyR0MDk4NTQ5OTIxAl8xBBFyYXRlc1JlY2FsY1Jlc3VsdAgFCyR0MDk4NTQ5OTIxAl8yBAZhbW91bnQJAG4EBQthc3NldEFtb3VudAUHU2NhbGUxNgUFYlJhdGUFB0NFSUxJTkcEEmNvbGxhdGVyYWxWYWx1ZUludgkA/AcEBQR0aGlzAhFnZXRVc2VyQ29sbGF0ZXJhbAkAzAgCBwkAzAgCBQdhZGRyZXNzCQDMCAIGCQDMCAIJAKwCAgkArAICBQphc3NldElkU3RyAgosYm9ycm93ZWQsCQCkAwEFBmFtb3VudAUDbmlsBQNuaWwDCQAAAgUSY29sbGF0ZXJhbFZhbHVlSW52BRJjb2xsYXRlcmFsVmFsdWVJbnYED2NvbGxhdGVyYWxWYWx1ZQQHJG1hdGNoMAUSY29sbGF0ZXJhbFZhbHVlSW52AwkAAQIFByRtYXRjaDACA0ludAQBeAUHJG1hdGNoMAUBeAkAAgECH2Nhbid0IGdldCB1c2VyIGNvbGxhdGVyYWwgdmFsdWUDCQEBIQEJAQ10cnlHZXRCb29sZWFuAQIMc2V0dXBfYWN0aXZlCQACAQIRbWFya2V0IGlzIHN0b3BwZWQDCQBmAgAABQ9jb2xsYXRlcmFsVmFsdWUJAAIBAiF5b3UgaGF2ZSB0byBzdXBwbHkgbW9yZSB0byBib3Jyb3cEDWFzc2V0U3VwcGxpZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIEDWFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIEEXVzZXJBc3NldEJvcnJvd2VkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQphc3NldElkU3RyAwkAZgIFBmFtb3VudAkAZQIFDWFzc2V0U3VwcGxpZWQFDWFzc2V0Qm9ycm93ZWQJAAIBAhx0aGlzIGFtb3VudCBpcyBub3QgYXZhaWxhYmxlBANpbnYJAPwHBAUEdGhpcwIMdW5zdGFrZVRva2VuCQDMCAIFCmFzc2V0SWRTdHIJAMwIAgULYXNzZXRBbW91bnQFA25pbAUDbmlsAwkAAAIFA2ludgUDaW52CQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQphc3NldElkU3RyCQBkAgURdXNlckFzc2V0Qm9ycm93ZWQFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIJAGQCBQ1hc3NldEJvcnJvd2VkBQZhbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQthc3NldEFtb3VudAkBDWdldEFzc2V0Qnl0ZXMBBQphc3NldElkU3RyBQNuaWwFEXJhdGVzUmVjYWxjUmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBBXJlcGF5AAMJAQEhAQkBDXRyeUdldEJvb2xlYW4BAgxzZXR1cF9hY3RpdmUJAAIBAhFtYXJrZXQgaXMgc3RvcHBlZAMDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEGCQAAAggJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQAAAkAAgECHDEgcGF5bWVudCBoYXMgdG8gYmUgYXR0YWNoZWQECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQLYXNzZXRBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BA0kdDAxMTQyNDExNDkxCQENZ2V0QWN0dWFsUmF0ZQIFCmFzc2V0SWRTdHICBWJSYXRlBAViUmF0ZQgFDSR0MDExNDI0MTE0OTECXzEEEXJhdGVzUmVjYWxjUmVzdWx0CAUNJHQwMTE0MjQxMTQ5MQJfMgQGYW1vdW50CQBuBAULYXNzZXRBbW91bnQFB1NjYWxlMTYFBWJSYXRlBQdDRUlMSU5HBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgQNYXNzZXRTdXBwbGllZAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgQNYXNzZXRCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgQRdXNlckFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIECmFtb3VudExlZnQJAGUCBRF1c2VyQXNzZXRCb3Jyb3dlZAUGYW1vdW50BAtyZXBheUFtb3VudAMJAGcCBQphbW91bnRMZWZ0AAAFBmFtb3VudAURdXNlckFzc2V0Qm9ycm93ZWQDCQAAAgkAswkCCQEMdHJ5R2V0U3RyaW5nAQIMc2V0dXBfdG9rZW5zBQphc3NldElkU3RyBQR1bml0CQACAQIpdGhpcyBhc3NldCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBtYXJrZXQEA2ludgkA/AcEBQR0aGlzAgpzdGFrZVRva2VuCQDMCAIFCmFzc2V0SWRTdHIJAMwIAgULYXNzZXRBbW91bnQFA25pbAUDbmlsAwkAAAIFA2ludgUDaW52CQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIJAGUCBRF1c2VyQXNzZXRCb3Jyb3dlZAULcmVwYXlBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQphc3NldElkU3RyCQBlAgUNYXNzZXRCb3Jyb3dlZAULcmVwYXlBbW91bnQFA25pbAURcmF0ZXNSZWNhbGNSZXN1bHQDCQBnAgUKYW1vdW50TGVmdAAABQNuaWwJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyCQEBLQEFCmFtb3VudExlZnQICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDXN0YWtlVG9rZW5BbGwBCmFzc2V0SWRTdHIDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAixvbmx5IGZvciBpbnRlcm5hbCBzbWFydCBjb250cmFjdCBpbnZvY2F0aW9ucwQGYW1vdW50CQEKZ2V0QmFsYW5jZQEFCmFzc2V0SWRTdHIEA2ludgkA/AcEBQR0aGlzAgpzdGFrZVRva2VuCQDMCAIFCmFzc2V0SWRTdHIJAMwIAgUGYW1vdW50BQNuaWwFA25pbAMJAAACBQNpbnYFA2ludgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCnN0YWtlVG9rZW4CCmFzc2V0SWRTdHIGYW1vdW50AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIsb25seSBmb3IgaW50ZXJuYWwgc21hcnQgY29udHJhY3QgaW52b2NhdGlvbnMDCQAAAgUKYXNzZXRJZFN0cgIsREcyeEZrUGREd0tVb0JrekdBaFF0THBTR3pmWExpQ1lQRXplS0gyQWQyNHAEDGFtb3VudFN0YWtlZAkBDXRyeUdldEludGVnZXIBAj1hdXRvc3Rha2VfYW1vdW50X0RHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwBANpbnYJAPwHBAkBB0FkZHJlc3MBARoBV+QOpzZPkgvXl8+kHT81G89DauuqPPNxnQIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgEgtiYpwwT1zlORpA5LdSQvZIxRsfrfr1QpvUjSHSqyqtEFBmFtb3VudAUDbmlsAwkAAAIFA2ludgUDaW52CQDMCAIJAQxJbnRlZ2VyRW50cnkCAj1hdXRvc3Rha2VfYW1vdW50X0RHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwCQBkAgUMYW1vdW50U3Rha2VkBQZhbW91bnQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgMJAAACBQphc3NldElkU3RyAiw4dDREUFdUd1B6cGF0SEE5QWtUeFdBQjQ3VEhuWXpCc0Rub1k3ZlFxYkc5MQQMYW1vdW50U3Rha2VkCQENdHJ5R2V0SW50ZWdlcgECPWF1dG9zdGFrZV9hbW91bnRfOHQ0RFBXVHdQenBhdEhBOUFrVHhXQUI0N1RIbll6QnNEbm9ZN2ZRcWJHOTEEA2ludgkA/AcECQEHQWRkcmVzcwEBGgFX9xU1EcXtcoVTVBDw3RtN4mo807RodylaAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCASB1FhA4gHYNVWV+SfOusdvmGZxqEGgfyVVh+kpGWncwHAUGYW1vdW50BQNuaWwDCQAAAgUDaW52BQNpbnYJAMwIAgkBDEludGVnZXJFbnRyeQICPWF1dG9zdGFrZV9hbW91bnRfOHQ0RFBXVHdQenBhdEhBOUFrVHhXQUI0N1RIbll6QnNEbm9ZN2ZRcWJHOTEJAGQCBQxhbW91bnRTdGFrZWQFBmFtb3VudAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAwkAAAIFCmFzc2V0SWRTdHICLEF0OEQ2TkZGcGhlQ2J2S1ZualZvZUxMODRFbzhOWm42b3ZNYW54ZkxhRldMBAxhbW91bnRTdGFrZWQJAQ10cnlHZXRJbnRlZ2VyAQI9YXV0b3N0YWtlX2Ftb3VudF9BdDhENk5GRnBoZUNidktWbmpWb2VMTDg0RW84TlpuNm92TWFueGZMYUZXTAQDaW52CQD8BwQJAQdBZGRyZXNzAQEaAVdraDjhA9SajJ8SG8YsvCMHOQvN7RLXCl8CBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIBIJLR9EriEQEr9H7q3iGOPcX7yfJ9zoey7VIZ8DpOJFj1BQZhbW91bnQFA25pbAMJAAACBQNpbnYFA2ludgkAzAgCCQEMSW50ZWdlckVudHJ5AgI9YXV0b3N0YWtlX2Ftb3VudF9BdDhENk5GRnBoZUNidktWbmpWb2VMTDg0RW84TlpuNm92TWFueGZMYUZXTAkAZAIFDGFtb3VudFN0YWtlZAUGYW1vdW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAFpAQx1bnN0YWtlVG9rZW4CCmFzc2V0SWRTdHIGYW1vdW50AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIsb25seSBmb3IgaW50ZXJuYWwgc21hcnQgY29udHJhY3QgaW52b2NhdGlvbnMDCQAAAgUKYXNzZXRJZFN0cgIsREcyeEZrUGREd0tVb0JrekdBaFF0THBTR3pmWExpQ1lQRXplS0gyQWQyNHAEDGFtb3VudFN0YWtlZAkBDXRyeUdldEludGVnZXIBAj1hdXRvc3Rha2VfYW1vdW50X0RHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwBANpbnYJAPwHBAkBB0FkZHJlc3MBARoBV+QOpzZPkgvXl8+kHT81G89DauuqPPNxnQIHdW5zdGFrZQkAzAgCBQZhbW91bnQFA25pbAUDbmlsAwkAAAIFA2ludgUDaW52BARiYWwwCQEKZ2V0QmFsYW5jZQECLERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwAwkAAAIFBGJhbDAFBGJhbDAEBGludjIJAPwHBAkBB0FkZHJlc3MBARoBV+QOpzZPkgvXl8+kHT81G89DauuqPPNxnQIMY2xhaW1SZXdhcmRzBQNuaWwFA25pbAMJAAACBQRpbnYyBQRpbnYyBARpbnYzCQD8BwQFBHRoaXMCC2FkZEludGVyZXN0CQDMCAICLERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwCQDMCAIJAGUCCQEKZ2V0QmFsYW5jZQECLERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwBQRiYWwwBQNuaWwFA25pbAMJAAACBQRpbnYzBQRpbnYzCQDMCAIJAQxJbnRlZ2VyRW50cnkCAj1hdXRvc3Rha2VfYW1vdW50X0RHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwCQBlAgUMYW1vdW50U3Rha2VkBQZhbW91bnQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgMJAAACBQphc3NldElkU3RyAiw4dDREUFdUd1B6cGF0SEE5QWtUeFdBQjQ3VEhuWXpCc0Rub1k3ZlFxYkc5MQQMYW1vdW50U3Rha2VkCQENdHJ5R2V0SW50ZWdlcgECPWF1dG9zdGFrZV9hbW91bnRfOHQ0RFBXVHdQenBhdEhBOUFrVHhXQUI0N1RIbll6QnNEbm9ZN2ZRcWJHOTEEA2ludgkA/AcECQEHQWRkcmVzcwEBGgFX9xU1EcXtcoVTVBDw3RtN4mo807RodylaAgd1blN0YWtlCQDMCAIFBmFtb3VudAUDbmlsBQNuaWwDCQAAAgUDaW52BQNpbnYJAMwIAgkBDEludGVnZXJFbnRyeQICPWF1dG9zdGFrZV9hbW91bnRfOHQ0RFBXVHdQenBhdEhBOUFrVHhXQUI0N1RIbll6QnNEbm9ZN2ZRcWJHOTEJAGUCBQxhbW91bnRTdGFrZWQFBmFtb3VudAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAwkAAAIFCmFzc2V0SWRTdHICLEF0OEQ2TkZGcGhlQ2J2S1ZualZvZUxMODRFbzhOWm42b3ZNYW54ZkxhRldMBAxhbW91bnRTdGFrZWQJAQ10cnlHZXRJbnRlZ2VyAQI9YXV0b3N0YWtlX2Ftb3VudF9BdDhENk5GRnBoZUNidktWbmpWb2VMTDg0RW84TlpuNm92TWFueGZMYUZXTAQDaW52CQD8BwQJAQdBZGRyZXNzAQEaAVdraDjhA9SajJ8SG8YsvCMHOQvN7RLXCl8CB3Vuc3Rha2UJAMwIAgUGYW1vdW50BQNuaWwFA25pbAMJAAACBQNpbnYFA2ludgQEYmFsMAkBCmdldEJhbGFuY2UBAixBdDhENk5GRnBoZUNidktWbmpWb2VMTDg0RW84TlpuNm92TWFueGZMYUZXTAMJAAACBQRiYWwwBQRiYWwwBARpbnYyCQD8BwQJAQdBZGRyZXNzAQEaAVf7derrE/0ZwMsI3I9gs34DuhGOrY+30OsCF2duc2J0UmV3YXJkc1NZU1JFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQAAAgUEaW52MgUEaW52MgQMdG9wdXBSZXdhcmRzBAckbWF0Y2gwBQRpbnYyAwkAAQIFByRtYXRjaDACCUxpc3RbQW55XQQBeAUHJG1hdGNoMAQIc2Vjb25kRWwJAJEDAgUBeAABBAckbWF0Y2gxBQhzZWNvbmRFbAMJAAECBQckbWF0Y2gxAgZTdHJpbmcECHNlY29uZEVsBQckbWF0Y2gxBAl1c2RuVmFsdWUJAQ1wYXJzZUludFZhbHVlAQkAkQMCCQC1CQIJAJEDAgkAtQkCBQhzZWNvbmRFbAIBXwABAgE6AAEECndhdmVzVmFsdWUJAQ1wYXJzZUludFZhbHVlAQkAkQMCCQC1CQIJAJEDAgkAtQkCBQhzZWNvbmRFbAIBXwAAAgE6AAEDAwkBAiE9AgUJdXNkblZhbHVlAAAGCQECIT0CBQp3YXZlc1ZhbHVlAAAECHVzZG5CYWwwCQEKZ2V0QmFsYW5jZQECLERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwAwkAAAIFCHVzZG5CYWwwBQh1c2RuQmFsMAQJd2F2ZXNCYWwwCQEKZ2V0QmFsYW5jZQECBVdBVkVTAwkAAAIFCXdhdmVzQmFsMAUJd2F2ZXNCYWwwBARpbnYzCQD8BwQJAQdBZGRyZXNzAQEaAVdraDjhA9SajJ8SG8YsvCMHOQvN7RLXCl8CDGNsYWltUmV3YXJkcwUDbmlsBQNuaWwDCQAAAgUEaW52MwUEaW52MwQJd2F2ZXNCYWwxCQEKZ2V0QmFsYW5jZQECBVdBVkVTAwkAAAIFCXdhdmVzQmFsMQUJd2F2ZXNCYWwxBARpbnY0CQD8BwQJAQdBZGRyZXNzAQEaAVfOFBSdFlgD5ENMevWl7LKfrb/Ns4P5KaICBHN3YXAJAMwIAgIsREcyeEZrUGREd0tVb0JrekdBaFF0THBTR3pmWExpQ1lQRXplS0gyQWQyNHAJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFBHVuaXQJAGUCBQl3YXZlc0JhbDEFCXdhdmVzQmFsMAUDbmlsAwkAAAIFBGludjQFBGludjQECHVzZG5CYWwxCQEKZ2V0QmFsYW5jZQECLERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwAwkAAAIFCHVzZG5CYWwxBQh1c2RuQmFsMQQEaW52NQkA/AcECQEHQWRkcmVzcwEBGgFXQOqhXGWBKD10hFtXYJ7743krt9yKtJB3AgRzd2FwCQDMCAICLEF0OEQ2TkZGcGhlQ2J2S1ZualZvZUxMODRFbzhOWm42b3ZNYW54ZkxhRldMCQDMCAIAAAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCASC2JinDBPXOU5GkDkt1JC9kjFGx+t+vVCm9SNIdKrKq0QkAZQIFCHVzZG5CYWwxBQh1c2RuQmFsMAUDbmlsAwkAAAIFBGludjUFBGludjUEBGludjYJAPwHBAUEdGhpcwILYWRkSW50ZXJlc3QJAMwIAgIsQXQ4RDZORkZwaGVDYnZLVm5qVm9lTEw4NEVvOE5abjZvdk1hbnhmTGFGV0wJAMwIAgkAZQIJAQpnZXRCYWxhbmNlAQIsQXQ4RDZORkZwaGVDYnZLVm5qVm9lTEw4NEVvOE5abjZvdk1hbnhmTGFGV0wFBGJhbDAFA25pbAUDbmlsAwkAAAIFBGludjYFBGludjYAAgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgABAAEAAAMJAAACBQx0b3B1cFJld2FyZHMFDHRvcHVwUmV3YXJkcwkAzAgCCQEMSW50ZWdlckVudHJ5AgI9YXV0b3N0YWtlX2Ftb3VudF9BdDhENk5GRnBoZUNidktWbmpWb2VMTDg0RW84TlpuNm92TWFueGZMYUZXTAkAZQIFDGFtb3VudFN0YWtlZAUGYW1vdW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAFpAQthZGRJbnRlcmVzdAIKYXNzZXRJZFN0cgZhbW91bnQDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAhhvbmx5IGZvciBzZWxmIGludm9jYXRpb24EBmVhcm5lZAkBDXRyeUdldEludGVnZXIBCQCsAgICFWF1dG9zdGFrZV9sYXN0RWFybmVkXwUKYXNzZXRJZFN0cgQKbGFzdEhlaWdodAkBDXRyeUdldEludGVnZXIBCQCsAgICFGF1dG9zdGFrZV9sYXN0QmxvY2tfBQphc3NldElkU3RyBAxzdGF0ZUNoYW5nZXMDAwkAAAIFCmxhc3RIZWlnaHQFBmhlaWdodAYJAAACBQZhbW91bnQAAAUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICGGF1dG9zdGFrZV9wcmVMYXN0RWFybmVkXwUKYXNzZXRJZFN0cgUGZWFybmVkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICF2F1dG9zdGFrZV9wcmVMYXN0QmxvY2tfBQphc3NldElkU3RyBQpsYXN0SGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICFWF1dG9zdGFrZV9sYXN0RWFybmVkXwUKYXNzZXRJZFN0cgkAZAIFBmVhcm5lZAUGYW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICFGF1dG9zdGFrZV9sYXN0QmxvY2tfBQphc3NldElkU3RyBQZoZWlnaHQFA25pbAkAzggCBQxzdGF0ZUNoYW5nZXMJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYXNzZXRJZFN0cgIGX3NSYXRlCQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFzc2V0SWRTdHICBl9zUmF0ZQkAawMFB1NjYWxlMTYFBmFtb3VudAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgUDbmlsAWkBE2FkZEludGVyZXN0RVhURVJOQUwABAZhbW91bnQJAGsDCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudABQAGQEB2Fzc2V0SWQICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUHYXNzZXRJZAQGZWFybmVkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIVYXV0b3N0YWtlX2xhc3RFYXJuZWRfBQphc3NldElkU3RyBApsYXN0SGVpZ2h0CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIUYXV0b3N0YWtlX2xhc3RCbG9ja18FCmFzc2V0SWRTdHIEDHN0YXRlQ2hhbmdlcwMDCQAAAgUKbGFzdEhlaWdodAUGaGVpZ2h0BgkAAAIFBmFtb3VudAAABQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIYYXV0b3N0YWtlX3ByZUxhc3RFYXJuZWRfBQphc3NldElkU3RyBQZlYXJuZWQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIXYXV0b3N0YWtlX3ByZUxhc3RCbG9ja18FCmFzc2V0SWRTdHIFCmxhc3RIZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIVYXV0b3N0YWtlX2xhc3RFYXJuZWRfBQphc3NldElkU3RyCQBkAgUGZWFybmVkBQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIUYXV0b3N0YWtlX2xhc3RCbG9ja18FCmFzc2V0SWRTdHIFBmhlaWdodAUDbmlsCQDOCAIFDHN0YXRlQ2hhbmdlcwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQphc3NldElkU3RyAgZfc1JhdGUJAGQCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYXNzZXRJZFN0cgIGX3NSYXRlCQBrAwUHU2NhbGUxNgUGYW1vdW50CQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyBQNuaWwBaQEHcHJlSW5pdAQGdG9rZW5zBGx0dnMDbHRzCXBlbmFsdGllcwoBAWYCBWFjY3VtBXRva2VuCQDOCAIFBWFjY3VtCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBXRva2VuAgZfYlJhdGUFB1NjYWxlMTYJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUFdG9rZW4CBl9zUmF0ZQUHU2NhbGUxNgUDbmlsAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIKYWRtaW4gb25seQQFcmF0ZXMKAAIkbAkAtQkCBQZ0b2tlbnMCASwKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYJAM4IAgkAzAgCCQELU3RyaW5nRW50cnkCAgxzZXR1cF90b2tlbnMFBnRva2VucwkAzAgCCQELU3RyaW5nRW50cnkCAgpzZXR1cF9sdHZzBQRsdHZzCQDMCAIJAQtTdHJpbmdFbnRyeQICCXNldHVwX2x0cwUDbHRzCQDMCAIJAQtTdHJpbmdFbnRyeQICD3NldHVwX3BlbmFsdGllcwUJcGVuYWx0aWVzCQDMCAIJAQxCb29sZWFuRW50cnkCAgxzZXR1cF9hY3RpdmUGBQNuaWwFBXJhdGVzAWkBD3VwZGF0ZVBhcmFtZXRlcgIDa2V5A3ZhbAMDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAQIhPQIIBQFpBmNhbGxlcgkBB0FkZHJlc3MBARoBVxR5WIXA+hpn5xQ0jQz3xPBtRe32HPk9QQcJAAIBAgphZG1pbiBvbmx5CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQNrZXkJAQ1wYXJzZUludFZhbHVlAQUDdmFsBQNuaWwBaQESY2xhaW1Ub1Jlc2VydmVGdW5kAQVkZWJ1ZwQGYXNzZXRzCQEPZ2V0TWFya2V0QXNzZXRzAAQFcmF0ZXMICQENZ2V0QWN0dWFsUmF0ZQIJAJEDAgUGYXNzZXRzAAACBXNSYXRlAl8yBAJsaQkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQUDbmlsCgEBZgIFYWNjdW0BbgMJAGcCBQFuCQCQAwEFBmFzc2V0cwUFYWNjdW0ECmFzc2V0SWRTdHIJAJEDAgUGYXNzZXRzBQFuBA9hdXRvc3Rha2VBbW91bnQJAQx0cnlHZXRTdHJpbmcBCQCsAgICEWF1dG9zdGFrZV9hbW91bnRfBQphc3NldElkU3RyBAZhbW91bnQJAGUCCQBkAgkAZAIJAGQCCQEKZ2V0QmFsYW5jZQEFCmFzc2V0SWRTdHIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAhFhdXRvc3Rha2VfYW1vdW50XwUKYXNzZXRJZFN0cgMJAQIhPQIFD2F1dG9zdGFrZUFtb3VudAIACQENcGFyc2VJbnRWYWx1ZQEFD2F1dG9zdGFrZUFtb3VudAAACQBrAwkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cggJAJEDAgUFcmF0ZXMJAGQCCQBoAgUBbgADAAEFdmFsdWUFB1NjYWxlMTYJAGsDCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyCAkAkQMCBQVyYXRlcwkAaAIFAW4AAwV2YWx1ZQUHU2NhbGUxNgQDaW52AwkAZgIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAhFhdXRvc3Rha2VfYW1vdW50XwUKYXNzZXRJZFN0cgAACQD8BwQFBHRoaXMCDHVuc3Rha2VUb2tlbgkAzAgCBQphc3NldElkU3RyCQDMCAIJAJYDAQkAzAgCBQZhbW91bnQJAMwIAgAABQNuaWwFA25pbAUDbmlsAAADCQAAAgUDaW52BQNpbnYJAM4IAgUFYWNjdW0JAMwIAgUGYW1vdW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4ECXBhcmFtZXRlcgoAAiRsBQJsaQoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEBZgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgoBAmYyAgVhY2N1bQFuAwkAZwIFAW4JAJADAQUGYXNzZXRzBQVhY2N1bQQKYXNzZXRJZFN0cgkAkQMCBQZhc3NldHMFAW4JAM4IAgUFYWNjdW0JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUScmVzZXJ2ZUZ1bmRBZGRyZXNzCQCWAwEJAMwIAgkAkQMCBQlwYXJhbWV0ZXIFAW4JAMwIAgAABQNuaWwJAQ1nZXRBc3NldEJ5dGVzAQUKYXNzZXRJZFN0cgUDbmlsAwUFZGVidWcJAAIBCQEKbGlJbnRUb1N0cgEFCXBhcmFtZXRlcgkAlAoCCgACJGwFAmxpCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYxXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQJmMgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMV8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNgkBBSRmMV8yAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgUJcGFyYW1ldGVyAWkBB3JlU2V0dXABCmFzc2V0SWRTdHIEC2xhc3RSZXNldHVwCQENdHJ5R2V0SW50ZWdlcgECEnJlc2V0dXBfbGFzdFVwZGF0ZQMJAGYCBQlkYXlCbG9ja3MJAGUCBQZoZWlnaHQFC2xhc3RSZXNldHVwCQACAQIgY2FuIGJlIHVwZGF0ZWQgb25seSBvbmNlIHBlciBkYXkEA2x0cwkAtQkCCQEMdHJ5R2V0U3RyaW5nAQIJc2V0dXBfbHRzAgEsBAZhc3NldHMJAQ9nZXRNYXJrZXRBc3NldHMABAJ1cgkBBWdldFVyAQUKYXNzZXRJZFN0cgQGdGVtcExUCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICAgZzZXR1cF8FCmFzc2V0SWRTdHICB190ZW1wTFQEAmx0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGYXNzZXRzCQEFdmFsdWUBCQDPCAIFBmFzc2V0cwUKYXNzZXRJZFN0cgMJAGYCBQJ1cgCAlfUqCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgIGc2V0dXBfBQphc3NldElkU3RyAgdfdGVtcExUCQBrAwUGdGVtcExUAPdNAJBOBQNuaWwDAwkAZgIFAmx0BQZ0ZW1wTFQJAGYCAICV9SoFAnVyBwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgICBnNldHVwXwUKYXNzZXRJZFN0cgIHX3RlbXBMVAkAawMFBnRlbXBMVACpTgCQTgUDbmlsBQNuaWwBaQEIc2h1dGRvd24BCHNodXRkb3duBAl3aGl0ZWxpc3QJAMwIAgEaAVfX4SNRjnyriFrV1yiXddiIddOPriMFpuEJAMwIAgEaAVdjDQOBpn9bVNIcueQoKvOngDTw2LWN1WUJAMwIAgEaAVez1ZJUSQmaKhD7xvifEHar7z8PcqWJFYwJAMwIAgEaAVf4+voCJsBRi+xqO0YzSdIccbB1i/mkypoJAMwIAgEaAVer3aoi85i5H0XYLNSn6vkSYq+JNmpQO3IJAMwIAgEaAVcwORzRpGYYO35/49jeov24Z5j/V00RJp0FA25pbAMJAAACCQDPCAIFCXdoaXRlbGlzdAgIBQFpBmNhbGxlcgVieXRlcwUEdW5pdAkAAgECF3VzZXIgbm90IGluIGEgd2hpdGVsaXN0CQDMCAIJAQxCb29sZWFuRW50cnkCAgxzZXR1cF9hY3RpdmUJAQEhAQUIc2h1dGRvd24FA25pbAFpAQlsaXF1aWRhdGUGBWRlYnVnB2FkZHJlc3MLYXNzZXRBbW91bnQLc0Fzc2V0SWRTdHILYkFzc2V0SWRTdHIIcm91dGVTdHIDAwkBAiE9AggFAWkGY2FsbGVyCQEHQWRkcmVzcwEBGgFXd6rO0XhW6KmeXquV77/p4XFYdV4ymnGBCQECIT0CCAUBaQZjYWxsZXIJAQdBZGRyZXNzAQEaAVer3aoi85i5H0XYLNSn6vkSYq+JNmpQO3IHCQACAQIldGVtcG9yYXJpbHkgbGlzdGVkIGZvciB3aGl0ZWxpc3Qgb25seQMJAQEhAQkBDXRyeUdldEJvb2xlYW4BAgxzZXR1cF9hY3RpdmUJAAIBAhFtYXJrZXQgaXMgc3RvcHBlZAQOdXNlckNvbGxhdGVyYWwJARJjYWxjVXNlckNvbGxhdGVyYWwBBQdhZGRyZXNzAwkAAAIFDnVzZXJDb2xsYXRlcmFsBQ51c2VyQ29sbGF0ZXJhbAQNJHQwMjQ0ODIyNDU0NAkBDWdldEFjdHVhbFJhdGUCBQtzQXNzZXRJZFN0cgIFc1JhdGUEBXNSYXRlCAUNJHQwMjQ0ODIyNDU0NAJfMQQLcmF0ZXNSZXN1bHQIBQ0kdDAyNDQ4MjI0NTQ0Al8yBA0kdDAyNDU0OTI0NjE4CQENZ2V0QWN0dWFsUmF0ZQIFC2JBc3NldElkU3RyAgViUmF0ZQQFYlJhdGUIBQ0kdDAyNDU0OTI0NjE4Al8xBBJyYXRlc1JlY2FsY1Jlc3VsdDIIBQ0kdDAyNDU0OTI0NjE4Al8yBAxzQXNzZXRBbW91bnQJAGsDBQthc3NldEFtb3VudAUHU2NhbGUxNgUFc1JhdGUEEGN1cnJlbnRTUG9zaXRpb24JAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9zdXBwbGllZF8FC3NBc3NldElkU3RyBBNjdXJyZW50QlBvc2l0aW9uVmFsCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQtiQXNzZXRJZFN0cgQQY3VycmVudEJQb3NpdGlvbgMJAQIhPQIFE2N1cnJlbnRCUG9zaXRpb25WYWwAAAUTY3VycmVudEJQb3NpdGlvblZhbAkAAgECIHVzZXIgaGFzIG5vIGJvcnJvdyBpbiB0aGlzIHRva2VuAwkAZgIFDnVzZXJDb2xsYXRlcmFsAAAJAAIBAhh1c2VyIGNhbid0IGJlIGxpcXVpZGF0ZWQDCQBmAgUMc0Fzc2V0QW1vdW50BRBjdXJyZW50U1Bvc2l0aW9uCQACAQIycG9zaXRpb24gdG8gbGlxdWlkYXRlIGlzIGJpZ2dlciB0aGFuIHVzZXIncyBzdXBwbHkEEWFnZ3JlZ2F0b3JBZGRyZXNzCQEHQWRkcmVzcwEBGgFXnQyqxhNRqW7LgPdjfcFkeOLvck2oDLrTBA5iYWxhbmNlMEJlZm9yZQkBCmdldEJhbGFuY2UBBQtzQXNzZXRJZFN0cgMJAAACBQ5iYWxhbmNlMEJlZm9yZQUOYmFsYW5jZTBCZWZvcmUEDmJhbGFuY2UxQmVmb3JlCQEKZ2V0QmFsYW5jZQEFC2JBc3NldElkU3RyAwkAAAIFDmJhbGFuY2UxQmVmb3JlBQ5iYWxhbmNlMUJlZm9yZQQOZXhjaGFuZ2VJbnZva2UJAPwHBAURYWdncmVnYXRvckFkZHJlc3MCBHN3YXAJAMwIAgUIcm91dGVTdHIJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQ1nZXRBc3NldEJ5dGVzAQULc0Fzc2V0SWRTdHIFC2Fzc2V0QW1vdW50BQNuaWwDCQAAAgUOZXhjaGFuZ2VJbnZva2UFDmV4Y2hhbmdlSW52b2tlBAphc3NldDBTb2xkCQBlAgUOYmFsYW5jZTBCZWZvcmUJAQpnZXRCYWxhbmNlAQULc0Fzc2V0SWRTdHIDCQAAAgUKYXNzZXQwU29sZAUKYXNzZXQwU29sZAQMYXNzZXQxQm91Z2h0CQBlAgkBCmdldEJhbGFuY2UBBQtiQXNzZXRJZFN0cgUOYmFsYW5jZTFCZWZvcmUDCQAAAgUMYXNzZXQxQm91Z2h0BQxhc3NldDFCb3VnaHQEC2Fzc2V0MFByaWNlCAkBDWdldFRva2VuUHJpY2UBBQtzQXNzZXRJZFN0cgJfMgQLYXNzZXQwU2NhbGUJAQ5jYWxjQXNzZXRTY2FsZQEFC3NBc3NldElkU3RyBAlhc3NldDBVc2QJAGsDBQphc3NldDBTb2xkBQthc3NldDBQcmljZQULYXNzZXQwU2NhbGUEC2Fzc2V0MVByaWNlCAkBDWdldFRva2VuUHJpY2UBBQtiQXNzZXRJZFN0cgJfMQQLYXNzZXQxU2NhbGUJAQ5jYWxjQXNzZXRTY2FsZQEFC2JBc3NldElkU3RyBAlhc3NldDFVc2QJAGsDBQxhc3NldDFCb3VnaHQFC2Fzc2V0MVByaWNlBQthc3NldDFTY2FsZQQHcGVuYWx0eQkBDXBhcnNlSW50VmFsdWUBCQCRAwIJALUJAgkBDHRyeUdldFN0cmluZwECD3NldHVwX3BlbmFsdGllcwIBLAkBBXZhbHVlAQkAzwgCCQEPZ2V0TWFya2V0QXNzZXRzAAULYkFzc2V0SWRTdHIEEWxpcXVpZGF0aW9uUHJvZml0CQBlAgUJYXNzZXQxVXNkCQBrAwUJYXNzZXQwVXNkCQBlAgUGU2NhbGU4BQdwZW5hbHR5BQZTY2FsZTgEDHNBc3NldENoYW5nZQkAawMFCmFzc2V0MFNvbGQFB1NjYWxlMTYFBXNSYXRlBAxiQXNzZXRDaGFuZ2UJAGsDBQxhc3NldDFCb3VnaHQFB1NjYWxlMTYFBWJSYXRlAwkAZgIFCmFzc2V0MFNvbGQFC2Fzc2V0QW1vdW50CQACAQIjbW9yZSBhc3NldHMgZXhjaGFuZ2VkIHRoYW4gZXhwZWN0ZWQDCQBmAgAABRFsaXF1aWRhdGlvblByb2ZpdAkAAgECL3ByaWNlIGltcGFjdCBpcyBiaWdnZXIgdGhhbiBsaXF1aWRhdGlvbiBwZW5hbHR5CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwULc0Fzc2V0SWRTdHIJAGUCBRBjdXJyZW50U1Bvc2l0aW9uBQxzQXNzZXRDaGFuZ2UJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQtiQXNzZXRJZFN0cgkAZQIFEGN1cnJlbnRCUG9zaXRpb24FDGJBc3NldENoYW5nZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9zdXBwbGllZF8FC3NBc3NldElkU3RyCQBlAgkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwULc0Fzc2V0SWRTdHIFDHNBc3NldENoYW5nZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9ib3Jyb3dlZF8FC2JBc3NldElkU3RyCQBlAgkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwULYkFzc2V0SWRTdHIFDGJBc3NldENoYW5nZQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBC2xpcXVpZGF0ZVYyAwVkZWJ1ZwdhZGRyZXNzC3NBc3NldElkU3RyAwMDCQECIT0CCAUBaQZjYWxsZXIJAQdBZGRyZXNzAQEaAVd3qs7ReFboqZ5eq5Xvv+nhcVh1XjKacYEJAQIhPQIIBQFpBmNhbGxlcgkBB0FkZHJlc3MBARoBV9fhI1GOfKuIWtXXKJd12Ih104+uIwWm4QcJAQIhPQIIBQFpBmNhbGxlcgkBB0FkZHJlc3MBARoBV6vdqiLzmLkfRdgs1Kfq+RJir4k2alA7cgcJAAIBAih0ZW1wb3JhcmlseSBhdmFpbGFibGUgZm9yIHdoaXRlbGlzdCBvbmx5AwkBASEBCQENdHJ5R2V0Qm9vbGVhbgECDHNldHVwX2FjdGl2ZQkAAgECEW1hcmtldCBpcyBzdG9wcGVkBAhiQXNzZXRJZAgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBAtiQXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQUIYkFzc2V0SWQEDGJBc3NldEFtb3VudAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQEDnVzZXJDb2xsYXRlcmFsCQESY2FsY1VzZXJDb2xsYXRlcmFsAQUHYWRkcmVzcwMJAAACBQ51c2VyQ29sbGF0ZXJhbAUOdXNlckNvbGxhdGVyYWwDCQBmAgUOdXNlckNvbGxhdGVyYWwAAAkAAgECGHVzZXIgY2FuJ3QgYmUgbGlxdWlkYXRlZAQMbWFya2V0QXNzZXRzCQEPZ2V0TWFya2V0QXNzZXRzAAQJYXNzZXQxTnVtCQEFdmFsdWUBCQDPCAIFDG1hcmtldEFzc2V0cwULYkFzc2V0SWRTdHIECWFzc2V0ME51bQkBBXZhbHVlAQkAzwgCBQxtYXJrZXRBc3NldHMFC3NBc3NldElkU3RyBA0kdDAyNzk1MDI4MDEyCQENZ2V0QWN0dWFsUmF0ZQIFC2JBc3NldElkU3RyAgViUmF0ZQQFYlJhdGUIBQ0kdDAyNzk1MDI4MDEyAl8xBAtyYXRlc1Jlc3VsdAgFDSR0MDI3OTUwMjgwMTICXzIEC2Fzc2V0MVByaWNlCAkBDWdldFRva2VuUHJpY2UBBQtiQXNzZXRJZFN0cgJfMgQLYXNzZXQxU2NhbGUJAQ5jYWxjQXNzZXRTY2FsZQEFC2JBc3NldElkU3RyBApiQW1vdW50VXNkCQBrAwUMYkFzc2V0QW1vdW50BQthc3NldDFQcmljZQULYXNzZXQxU2NhbGUEB3BlbmFsdHkJAQ1wYXJzZUludFZhbHVlAQkBBXZhbHVlAQkAkQMCCQC1CQIJAQx0cnlHZXRTdHJpbmcBAg9zZXR1cF9wZW5hbHRpZXMCASwFCWFzc2V0MU51bQQLYXNzZXQwUHJpY2UICQENZ2V0VG9rZW5QcmljZQEFC3NBc3NldElkU3RyAl8xBAthc3NldDBTY2FsZQkBDmNhbGNBc3NldFNjYWxlAQULc0Fzc2V0SWRTdHIECnNBbW91bnRVc2QJAGsDBQpiQW1vdW50VXNkCQBkAgUGU2NhbGU4BQdwZW5hbHR5BQZTY2FsZTgEDHNBc3NldEFtb3VudAkAawMFCnNBbW91bnRVc2QFC2Fzc2V0MFNjYWxlBQthc3NldDBQcmljZQQHYkFtb3VudAkAawMFDGJBc3NldEFtb3VudAUHU2NhbGUxNgUFYlJhdGUEB3NBbW91bnQJAGsDBQxzQXNzZXRBbW91bnQFB1NjYWxlMTYICQCRAwIFC3JhdGVzUmVzdWx0CQBkAgkAaAIFCWFzc2V0ME51bQADAAEFdmFsdWUEEGN1cnJlbnRTUG9zaXRpb24JAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9zdXBwbGllZF8FC3NBc3NldElkU3RyBBNjdXJyZW50QlBvc2l0aW9uVmFsCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQtiQXNzZXRJZFN0cgQQY3VycmVudEJQb3NpdGlvbgMJAQIhPQIFE2N1cnJlbnRCUG9zaXRpb25WYWwAAAUTY3VycmVudEJQb3NpdGlvblZhbAkAAgECIHVzZXIgaGFzIG5vIGJvcnJvdyBpbiB0aGlzIHRva2VuAwkAZgIFB3NBbW91bnQFEGN1cnJlbnRTUG9zaXRpb24JAAIBAjJwb3NpdGlvbiB0byBsaXF1aWRhdGUgaXMgYmlnZ2VyIHRoYW4gdXNlcidzIHN1cHBseQMFBWRlYnVnCQACAQIVbGlxdWlkYXRpb24gd2lsbCBwYXNzCQDOCAIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQxzQXNzZXRBbW91bnQJAQ1nZXRBc3NldEJ5dGVzAQULc0Fzc2V0SWRTdHIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQtzQXNzZXRJZFN0cgkAZQIFEGN1cnJlbnRTUG9zaXRpb24FB3NBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQtiQXNzZXRJZFN0cgkAZQIFEGN1cnJlbnRCUG9zaXRpb24FB2JBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQtzQXNzZXRJZFN0cgkAZQIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FC3NBc3NldElkU3RyBQdzQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICD3RvdGFsX2JvcnJvd2VkXwULYkFzc2V0SWRTdHIJAGUCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQtiQXNzZXRJZFN0cgUHYkFtb3VudAUDbmlsBQtyYXRlc1Jlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpARFnZXRVc2VyQ29sbGF0ZXJhbAQFZGVidWcHYWRkcmVzcw1taW51c0JvcnJvd2VkC2FmdGVyQ2hhbmdlBAZhc3NldHMJAQ9nZXRNYXJrZXRBc3NldHMABARsdHZzCQC1CQIJAQx0cnlHZXRTdHJpbmcBAgpzZXR1cF9sdHZzAgEsBANsdHMJALUJAgkBDHRyeUdldFN0cmluZwECCXNldHVwX2x0cwIBLAQFcmF0ZXMICQENZ2V0QWN0dWFsUmF0ZQIJAJEDAgUGYXNzZXRzAAACBXNSYXRlAl8yBA1jaGFuZ2VIYW5kbGVyCQC1CQIFC2FmdGVyQ2hhbmdlAgEsCgEBZgIFYWNjdW0EbmV4dAMJAGcCBQRuZXh0CQCQAwEFBmFzc2V0cwUFYWNjdW0EDHVzZXJTdXBwbGllZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwkAkQMCBQZhc3NldHMFBG5leHQEDHVzZXJCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwkAkQMCBQZhc3NldHMFBG5leHQDAwkBAiE9AgUMdXNlckJvcnJvd2VkAAAGCQECIT0CBQx1c2VyU3VwcGxpZWQAAAQKYXNzZXRTY2FsZQkBDmNhbGNBc3NldFNjYWxlAQkAkQMCBQZhc3NldHMFBG5leHQECmFzc2V0UHJpY2UJAQ1nZXRUb2tlblByaWNlAQkAkQMCBQZhc3NldHMFBG5leHQJAGUCCQBkAgUFYWNjdW0JAGsDCQBrAwkAawMJAGQCBQx1c2VyU3VwcGxpZWQDAwMJAQIhPQIFC2FmdGVyQ2hhbmdlAgAJAAACCQCRAwIFDWNoYW5nZUhhbmRsZXIAAAkAkQMCBQZhc3NldHMFBG5leHQHCQAAAgkAkQMCBQ1jaGFuZ2VIYW5kbGVyAAECCHN1cHBsaWVkBwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFDWNoYW5nZUhhbmRsZXIAAgAACAkAkQMCBQVyYXRlcwkAaAIFBG5leHQAAwV2YWx1ZQUHU2NhbGUxNgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFBGx0dnMFBG5leHQFBlNjYWxlOAgFCmFzc2V0UHJpY2UCXzEFCmFzc2V0U2NhbGUDBQ1taW51c0JvcnJvd2VkCQBrAwkAawMJAGsDCQBkAgUMdXNlckJvcnJvd2VkAwMDCQECIT0CBQthZnRlckNoYW5nZQIACQAAAgkAkQMCBQ1jaGFuZ2VIYW5kbGVyAAAJAJEDAgUGYXNzZXRzBQRuZXh0BwkAAAIJAJEDAgUNY2hhbmdlSGFuZGxlcgABAghib3Jyb3dlZAcJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ1jaGFuZ2VIYW5kbGVyAAIAAAgJAJEDAgUFcmF0ZXMJAGQCCQBoAgUEbmV4dAADAAEFdmFsdWUFB1NjYWxlMTYFBlNjYWxlOAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFA2x0cwUEbmV4dAgFCmFzc2V0UHJpY2UCXzIFCmFzc2V0U2NhbGUAAAUFYWNjdW0EBnJlc3VsdAoAAiRsCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFBQNuaWwKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYDBQVkZWJ1ZwkAAgEJAKQDAQUGcmVzdWx0CQCUCgIFBXJhdGVzBQZyZXN1bHQBaQEJZ2V0UHJpY2VzAQVkZWJ1ZwQGYXNzZXRzCQEPZ2V0TWFya2V0QXNzZXRzAAoBAWYCBWFjY3VtBG5leHQDCQBnAgUEbmV4dAkAkAMBBQZhc3NldHMFBWFjY3VtBAphc3NldFByaWNlCQENZ2V0VG9rZW5QcmljZQEJAJEDAgUGYXNzZXRzBQRuZXh0CQCsAgIJAKwCAgkArAICCQCsAgIFBWFjY3VtCQCkAwEIBQphc3NldFByaWNlAl8xAgEsCQCkAwEIBQphc3NldFByaWNlAl8yAgF8BAZyZXN1bHQKAAIkbAkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQUDbmlsCgACJHMJAJADAQUCJGwKAAUkYWNjMAIACgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFmAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA2CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAwUFZGVidWcJAAIBBQZyZXN1bHQJAJQKAgUDbmlsBQZyZXN1bHQBaQEZY2FsY3VsYXRlVXRpbGl6YXRpb25SYXRpbwIKYXNzZXRJZFN0cgVkZWJ1ZwMFBWRlYnVnCQACAQkApAMBCQEFZ2V0VXIBBQphc3NldElkU3RyCQCUCgIFA25pbAkBBWdldFVyAQUKYXNzZXRJZFN0cgFpARNjYWxjdWxhdGVPdXRkYXRlZFVSAgphc3NldElkU3RyBWRlYnVnAwUFZGVidWcJAAIBCQCkAwEJAQ1nZXRPdXRkYXRlZFVyAQUKYXNzZXRJZFN0cgkAlAoCBQNuaWwJAQ1nZXRPdXRkYXRlZFVyAQUKYXNzZXRJZFN0cgFpARNjYWxjdWxhdGVUb2tlblJhdGVzAQVkZWJ1ZwoBAWYCBWFjY3VtCmFzc2V0SWRTdHIEBXJhdGVzCQEQdG9rZW5SYXRlc1JlY2FsYwEFCmFzc2V0SWRTdHIJAJQKAgkArAICCQCsAgIJAKwCAgkArAICCAUFYWNjdW0CXzEJAKQDAQgJAJEDAgUFcmF0ZXMAAQV2YWx1ZQIBfAkApAMBCAkAkQMCBQVyYXRlcwAABXZhbHVlAgEsCQDOCAIIBQVhY2N1bQJfMgUFcmF0ZXMECXBhcmFtZXRlcgoAAiRsCQEPZ2V0TWFya2V0QXNzZXRzAAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgIABQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYDBQVkZWJ1ZwkAAgEIBQlwYXJhbWV0ZXICXzEJAJQKAggFCXBhcmFtZXRlcgJfMggFCXBhcmFtZXRlcgJfMQFpARdjYWxjdWxhdGVUb2tlbnNJbnRlcmVzdAEFZGVidWcKAQFmAgVhY2N1bQphc3NldElkU3RyBARyYXRlCQBrAwkBC2dldEludGVyZXN0AQUKYXNzZXRJZFN0cgUJZGF5QmxvY2tzBQZTY2FsZTgJAKwCAgkArAICBQVhY2N1bQkApAMBBQRyYXRlAgEsBAlwYXJhbWV0ZXIKAAIkbAkBD2dldE1hcmtldEFzc2V0cwAKAAIkcwkAkAMBBQIkbAoABSRhY2MwAgAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDYJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYDBQVkZWJ1ZwkAAgEFCXBhcmFtZXRlcgkAlAoCBQNuaWwFCXBhcmFtZXRlcgECdHgBBnZlcmlmeQAJAPQDAwgFAnR4CWJvZHlCeXRlcwkAkQMCCAUCdHgGcHJvb2ZzAAAIBQJ0eA9zZW5kZXJQdWJsaWNLZXnmWCcs", "height": 3412475, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: HE9gQtpvSfikkRPC6QXzHu6WeN6ZuQWGvyVUPMWabcdz Next: 4tvWVjvwjXSqDo2Qs43ggqNT9FQKwK2ukv4sgz2uFA5c Diff:
OldNewDifferences
77
88 let Scale16 = (Scale8 * Scale8)
99
10-let reserveFund = 20
11-
1210 let dayBlocks = 1440
13-
14-let reserveFundAddress = Address(base58'3P4kBiU4wr2yV1S5gMfu3MdkVvy7kxXHsKe')
1511
1612 func liIntToStr (li) = {
1713 func f (accum,next) = ((accum + toString(next)) + ",")
8177 else assetBalance(this, fromBase58String(assetIdStr))
8278
8379
80+let reserveFundAddress = Address(base58'3P4kBiU4wr2yV1S5gMfu3MdkVvy7kxXHsKe')
81+
82+let reserveFund = 20
83+
8484 func getMarketAssets () = split(tryGetString("setup_tokens"), ",")
8585
8686
122122 then $Tuple4(0, 30000000, 80000000, 40000000)
123123 else if (("At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL" == $match0))
124124 then $Tuple4(0, 25000000, 80000000, 40000000)
125- else $Tuple4(0, 20000000, 80000000, 80000000)
125+ else if (("8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS" == $match0))
126+ then $Tuple4(2000000, 30000000, 80000000, 50000000)
127+ else if (("474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu" == $match0))
128+ then $Tuple4(2000000, 30000000, 80000000, 50000000)
129+ else if (("5UYBPpq4WoU5n4MwpFkgJnW3Fq4B1u3ukpK33ik4QerR" == $match0))
130+ then $Tuple4(2000000, 30000000, 80000000, 50000000)
131+ else $Tuple4(0, 20000000, 80000000, 80000000)
126132 }
127133
128134
260266
261267
262268 @Callable(i)
269+func supply () = if (!(tryGetBoolean("setup_active")))
270+ then throw("market is stopped")
271+ else if (if ((size(i.payments) != 1))
272+ then true
273+ else (i.payments[0].amount == 0))
274+ then throw("1 payment has to be attached")
275+ else {
276+ let assetIdStr = getAssetString(i.payments[0].assetId)
277+ let assetAmount = i.payments[0].amount
278+ let $t068906957 = getActualRate(assetIdStr, "sRate")
279+ let sRate = $t068906957._1
280+ let ratesRecalcResult = $t068906957._2
281+ let amount = fraction(assetAmount, Scale16, sRate, DOWN)
282+ let address = toString(i.caller)
283+ let maxSupply = match getString(("setup_maxSupply_" + assetIdStr)) {
284+ case x: String =>
285+ parseIntValue(x)
286+ case _ =>
287+ 0
288+ }
289+ let assetPrice = getTokenPrice(assetIdStr)
290+ let newTotalSupplied = (tryGetInteger(((address + "_supplied_") + assetIdStr)) + amount)
291+ let rate = getActualRate(assetIdStr, "sRate")._1
292+ let assetScale = calcAssetScale(assetIdStr)
293+ let newTotalSuppliedUsd = fraction(fraction(newTotalSupplied, rate, Scale16), assetPrice._1, assetScale)
294+ if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
295+ then throw("this asset is not supported by the market")
296+ else if (if ((maxSupply != 0))
297+ then (newTotalSuppliedUsd > maxSupply)
298+ else false)
299+ then throw("max total supply for this token reached in the pool")
300+ else {
301+ let inv = invoke(this, "stakeToken", [assetIdStr, assetAmount], nil)
302+ if ((inv == inv))
303+ then ([IntegerEntry(((address + "_supplied_") + assetIdStr), newTotalSupplied), IntegerEntry(("total_supplied_" + assetIdStr), (tryGetInteger(("total_supplied_" + assetIdStr)) + amount))] ++ ratesRecalcResult)
304+ else throw("Strict value is not equal to itself.")
305+ }
306+ }
307+
308+
309+
310+@Callable(i)
311+func withdraw (assetIdStr,assetAmount) = {
312+ let $t082158282 = getActualRate(assetIdStr, "sRate")
313+ let sRate = $t082158282._1
314+ let ratesRecalcResult = $t082158282._2
315+ let amount = fraction(assetAmount, Scale16, sRate, CEILING)
316+ let address = toString(i.caller)
317+ let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
318+ let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
319+ let userAssetSupplied = tryGetInteger(((address + "_supplied_") + assetIdStr))
320+ let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
321+ let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",supplied,") + toString(-(amount)))], nil)
322+ if ((collateralValueInv == collateralValueInv))
323+ then {
324+ let collateralValue = match collateralValueInv {
325+ case x: Int =>
326+ x
327+ case _ =>
328+ throw("can't get user collateral value")
329+ }
330+ if (!(tryGetBoolean("setup_active")))
331+ then throw("market is stopped")
332+ else if ((0 > collateralValue))
333+ then throw("you dont have enough collateral for this operation")
334+ else if ((amount > (assetSupplied - assetBorrowed)))
335+ then throw("this amount is not available on the market")
336+ else {
337+ let inv = invoke(this, "unstakeToken", [assetIdStr, assetAmount], nil)
338+ if ((inv == inv))
339+ then ([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)
340+ else throw("Strict value is not equal to itself.")
341+ }
342+ }
343+ else throw("Strict value is not equal to itself.")
344+ }
345+
346+
347+
348+@Callable(i)
349+func borrow (assetIdStr,assetAmount) = {
350+ let address = toString(i.caller)
351+ let $t098549921 = getActualRate(assetIdStr, "bRate")
352+ let bRate = $t098549921._1
353+ let ratesRecalcResult = $t098549921._2
354+ let amount = fraction(assetAmount, Scale16, bRate, CEILING)
355+ let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",borrowed,") + toString(amount))], nil)
356+ if ((collateralValueInv == collateralValueInv))
357+ then {
358+ let collateralValue = match collateralValueInv {
359+ case x: Int =>
360+ x
361+ case _ =>
362+ throw("can't get user collateral value")
363+ }
364+ if (!(tryGetBoolean("setup_active")))
365+ then throw("market is stopped")
366+ else if ((0 > collateralValue))
367+ then throw("you have to supply more to borrow")
368+ else {
369+ let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
370+ let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
371+ let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
372+ if ((amount > (assetSupplied - assetBorrowed)))
373+ then throw("this amount is not available")
374+ else {
375+ let inv = invoke(this, "unstakeToken", [assetIdStr, assetAmount], nil)
376+ if ((inv == inv))
377+ then ([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed + amount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed + amount)), ScriptTransfer(i.caller, assetAmount, getAssetBytes(assetIdStr))] ++ ratesRecalcResult)
378+ else throw("Strict value is not equal to itself.")
379+ }
380+ }
381+ }
382+ else throw("Strict value is not equal to itself.")
383+ }
384+
385+
386+
387+@Callable(i)
388+func repay () = if (!(tryGetBoolean("setup_active")))
389+ then throw("market is stopped")
390+ else if (if ((size(i.payments) != 1))
391+ then true
392+ else (i.payments[0].amount == 0))
393+ then throw("1 payment has to be attached")
394+ else {
395+ let assetIdStr = getAssetString(i.payments[0].assetId)
396+ let assetAmount = i.payments[0].amount
397+ let $t01142411491 = getActualRate(assetIdStr, "bRate")
398+ let bRate = $t01142411491._1
399+ let ratesRecalcResult = $t01142411491._2
400+ let amount = fraction(assetAmount, Scale16, bRate, CEILING)
401+ let address = toString(i.caller)
402+ let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
403+ let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
404+ let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
405+ let amountLeft = (userAssetBorrowed - amount)
406+ let repayAmount = if ((amountLeft >= 0))
407+ then amount
408+ else userAssetBorrowed
409+ if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
410+ then throw("this asset is not supported by the market")
411+ else {
412+ let inv = invoke(this, "stakeToken", [assetIdStr, assetAmount], nil)
413+ if ((inv == inv))
414+ then (([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - repayAmount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - repayAmount))] ++ ratesRecalcResult) ++ (if ((amountLeft >= 0))
415+ then nil
416+ else [ScriptTransfer(i.caller, -(amountLeft), i.payments[0].assetId)]))
417+ else throw("Strict value is not equal to itself.")
418+ }
419+ }
420+
421+
422+
423+@Callable(i)
263424 func stakeTokenAll (assetIdStr) = if ((i.caller != this))
264425 then throw("only for internal smart contract invocations")
265426 else {
266- let amount = getBalance("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
427+ let amount = getBalance(assetIdStr)
267428 let inv = invoke(this, "stakeToken", [assetIdStr, amount], nil)
268429 if ((inv == inv))
269430 then nil
283444 then [IntegerEntry("autostake_amount_DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p", (amountStaked + amount))]
284445 else throw("Strict value is not equal to itself.")
285446 }
286- else nil
447+ else if ((assetIdStr == "8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91"))
448+ then {
449+ let amountStaked = tryGetInteger("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91")
450+ let inv = invoke(Address(base58'3PQTM38wDmAY9vWonK6ha7QL3PAycLz5oPP'), "stake", nil, [AttachedPayment(base58'8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91', amount)])
451+ if ((inv == inv))
452+ then [IntegerEntry("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91", (amountStaked + amount))]
453+ else throw("Strict value is not equal to itself.")
454+ }
455+ else if ((assetIdStr == "At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL"))
456+ then {
457+ let amountStaked = tryGetInteger("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL")
458+ let inv = invoke(Address(base58'3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C'), "stake", nil, [AttachedPayment(base58'At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL', amount)])
459+ if ((inv == inv))
460+ then [IntegerEntry("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", (amountStaked + amount))]
461+ else throw("Strict value is not equal to itself.")
462+ }
463+ else nil
287464
288465
289466
313490 }
314491 else throw("Strict value is not equal to itself.")
315492 }
316- else nil
493+ else if ((assetIdStr == "8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91"))
494+ then {
495+ let amountStaked = tryGetInteger("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91")
496+ let inv = invoke(Address(base58'3PQTM38wDmAY9vWonK6ha7QL3PAycLz5oPP'), "unStake", [amount], nil)
497+ if ((inv == inv))
498+ then [IntegerEntry("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91", (amountStaked - amount))]
499+ else throw("Strict value is not equal to itself.")
500+ }
501+ else if ((assetIdStr == "At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL"))
502+ then {
503+ let amountStaked = tryGetInteger("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL")
504+ let inv = invoke(Address(base58'3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C'), "unstake", [amount], nil)
505+ if ((inv == inv))
506+ then {
507+ let bal0 = getBalance("At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL")
508+ if ((bal0 == bal0))
509+ then {
510+ let inv2 = invoke(Address(base58'3PQrVbTVpqXHqpVKftkNdjy3zZAh4dsRzN6'), "gnsbtRewardsSYSREADONLY", [toString(this)], nil)
511+ if ((inv2 == inv2))
512+ then {
513+ let topupRewards = match inv2 {
514+ case x: List[Any] =>
515+ let secondEl = x[1]
516+ match secondEl {
517+ case secondEl: String =>
518+ let usdnValue = parseIntValue(split(split(secondEl, "_")[1], ":")[1])
519+ let wavesValue = parseIntValue(split(split(secondEl, "_")[0], ":")[1])
520+ if (if ((usdnValue != 0))
521+ then true
522+ else (wavesValue != 0))
523+ then {
524+ let usdnBal0 = getBalance("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
525+ if ((usdnBal0 == usdnBal0))
526+ then {
527+ let wavesBal0 = getBalance("WAVES")
528+ if ((wavesBal0 == wavesBal0))
529+ then {
530+ let inv3 = invoke(Address(base58'3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C'), "claimRewards", nil, nil)
531+ if ((inv3 == inv3))
532+ then {
533+ let wavesBal1 = getBalance("WAVES")
534+ if ((wavesBal1 == wavesBal1))
535+ then {
536+ let inv4 = invoke(Address(base58'3PLiXyywNThdvf3vVEUxwc7TJTucjZvuegh'), "swap", ["DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p", 0], [AttachedPayment(unit, (wavesBal1 - wavesBal0))])
537+ if ((inv4 == inv4))
538+ then {
539+ let usdnBal1 = getBalance("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
540+ if ((usdnBal1 == usdnBal1))
541+ then {
542+ let inv5 = invoke(Address(base58'3P7r93vXHuusageNJVGwzqaz3WMotAu49Yz'), "swap", ["At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", 0], [AttachedPayment(base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p', (usdnBal1 - usdnBal0))])
543+ if ((inv5 == inv5))
544+ then {
545+ let inv6 = invoke(this, "addInterest", ["At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", (getBalance("At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL") - bal0)], nil)
546+ if ((inv6 == inv6))
547+ then 2
548+ else throw("Strict value is not equal to itself.")
549+ }
550+ else throw("Strict value is not equal to itself.")
551+ }
552+ else throw("Strict value is not equal to itself.")
553+ }
554+ else throw("Strict value is not equal to itself.")
555+ }
556+ else throw("Strict value is not equal to itself.")
557+ }
558+ else throw("Strict value is not equal to itself.")
559+ }
560+ else throw("Strict value is not equal to itself.")
561+ }
562+ else throw("Strict value is not equal to itself.")
563+ }
564+ else 1
565+ case _ =>
566+ 1
567+ }
568+ case _ =>
569+ 0
570+ }
571+ if ((topupRewards == topupRewards))
572+ then [IntegerEntry("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", (amountStaked - amount))]
573+ else throw("Strict value is not equal to itself.")
574+ }
575+ else throw("Strict value is not equal to itself.")
576+ }
577+ else throw("Strict value is not equal to itself.")
578+ }
579+ else throw("Strict value is not equal to itself.")
580+ }
581+ else nil
317582
318583
319584
378643
379644
380645 @Callable(i)
381-func updateParameter (key,val) = if ((i.caller != this))
646+func updateParameter (key,val) = if (if ((i.caller != this))
647+ then (i.caller != Address(base58'3P3o9cLTV2u9N4nYNKRYL6gy6cUEU9DwXW8'))
648+ else false)
382649 then throw("admin only")
383650 else [IntegerEntry(key, parseIntValue(val))]
384651
385652
386653
387654 @Callable(i)
388-func supply () = if (!(tryGetBoolean("setup_active")))
389- then throw("market is stopped")
390- else if (if ((size(i.payments) != 1))
391- then true
392- else (i.payments[0].amount == 0))
393- then throw("1 payment has to be attached")
655+func claimToReserveFund (debug) = {
656+ let assets = getMarketAssets()
657+ let rates = getActualRate(assets[0], "sRate")._2
658+ let li = [0, 1, 2, 3, 4, 5]
659+ func f (accum,n) = if ((n >= size(assets)))
660+ then accum
394661 else {
395- let assetIdStr = getAssetString(i.payments[0].assetId)
396- let assetAmount = i.payments[0].amount
397- let $t01160411671 = getActualRate(assetIdStr, "sRate")
398- let sRate = $t01160411671._1
399- let ratesRecalcResult = $t01160411671._2
400- let amount = fraction(assetAmount, Scale16, sRate, DOWN)
401- let address = toString(i.caller)
402- let maxSupply = match getString(("setup_maxSupply_" + assetIdStr)) {
403- case x: String =>
404- parseIntValue(x)
405- case _ =>
406- 0
407- }
408- let assetPrice = getTokenPrice(assetIdStr)
409- let newTotalSupplied = (tryGetInteger(((address + "_supplied_") + assetIdStr)) + amount)
410- let rate = getActualRate(assetIdStr, "sRate")._1
411- let assetScale = calcAssetScale(assetIdStr)
412- let newTotalSuppliedUsd = fraction(fraction(newTotalSupplied, rate, Scale16), assetPrice._1, assetScale)
413- if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
414- then throw("this asset is not supported by the market")
415- else if (if ((maxSupply != 0))
416- then (newTotalSuppliedUsd > maxSupply)
417- else false)
418- then throw("max total supply for this token reached in the pool")
419- else {
420- let inv = invoke(this, "stakeToken", [assetIdStr, assetAmount], nil)
421- if ((inv == inv))
422- then ([IntegerEntry(((address + "_supplied_") + assetIdStr), newTotalSupplied), IntegerEntry(("total_supplied_" + assetIdStr), (tryGetInteger(("total_supplied_" + assetIdStr)) + amount))] ++ ratesRecalcResult)
423- else throw("Strict value is not equal to itself.")
424- }
662+ let assetIdStr = assets[n]
663+ let autostakeAmount = tryGetString(("autostake_amount_" + assetIdStr))
664+ let amount = ((((getBalance(assetIdStr) + tryGetInteger(("autostake_amount_" + assetIdStr))) + (if ((autostakeAmount != ""))
665+ then parseIntValue(autostakeAmount)
666+ else 0)) + fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), rates[((n * 3) + 1)].value, Scale16)) - fraction(tryGetInteger(("total_supplied_" + assetIdStr)), rates[(n * 3)].value, Scale16))
667+ let inv = if ((tryGetInteger(("autostake_amount_" + assetIdStr)) > 0))
668+ then invoke(this, "unstakeToken", [assetIdStr, max([amount, 0])], nil)
669+ else 0
670+ if ((inv == inv))
671+ then (accum ++ [amount])
672+ else throw("Strict value is not equal to itself.")
425673 }
426674
675+ let parameter = {
676+ let $l = li
677+ let $s = size($l)
678+ let $acc0 = nil
679+ func $f0_1 ($a,$i) = if (($i >= $s))
680+ then $a
681+ else f($a, $l[$i])
427682
683+ func $f0_2 ($a,$i) = if (($i >= $s))
684+ then $a
685+ else throw("List size exceeds 6")
428686
429-@Callable(i)
430-func withdraw (assetIdStr,assetAmount) = {
431- let $t01293012997 = getActualRate(assetIdStr, "sRate")
432- let sRate = $t01293012997._1
433- let ratesRecalcResult = $t01293012997._2
434- let amount = fraction(assetAmount, Scale16, sRate, CEILING)
435- let address = toString(i.caller)
436- let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
437- let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
438- let userAssetSupplied = tryGetInteger(((address + "_supplied_") + assetIdStr))
439- let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
440- let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",supplied,") + toString(-(amount)))], nil)
441- if ((collateralValueInv == collateralValueInv))
442- then {
443- let collateralValue = match collateralValueInv {
444- case x: Int =>
445- x
446- case _ =>
447- throw("can't get user collateral value")
687+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
688+ }
689+ func f2 (accum,n) = if ((n >= size(assets)))
690+ then accum
691+ else {
692+ let assetIdStr = assets[n]
693+ (accum ++ [ScriptTransfer(reserveFundAddress, max([parameter[n], 0]), getAssetBytes(assetIdStr))])
448694 }
449- if (!(tryGetBoolean("setup_active")))
450- then throw("market is stopped")
451- else if ((0 > collateralValue))
452- then throw("you dont have enough collateral for this operation")
453- else if ((amount > (assetSupplied - assetBorrowed)))
454- then throw("this amount is not available on the market")
455- else {
456- let inv = invoke(this, "unstakeToken", [assetIdStr, assetAmount], nil)
457- if ((inv == inv))
458- then ([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)
459- else throw("Strict value is not equal to itself.")
460- }
461- }
462- else throw("Strict value is not equal to itself.")
695+
696+ if (debug)
697+ then throw(liIntToStr(parameter))
698+ else $Tuple2({
699+ let $l = li
700+ let $s = size($l)
701+ let $acc0 = nil
702+ func $f1_1 ($a,$i) = if (($i >= $s))
703+ then $a
704+ else f2($a, $l[$i])
705+
706+ func $f1_2 ($a,$i) = if (($i >= $s))
707+ then $a
708+ else throw("List size exceeds 6")
709+
710+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
711+ }, parameter)
463712 }
464713
465714
466715
467716 @Callable(i)
468-func borrow (assetIdStr,assetAmount) = {
469- let address = toString(i.caller)
470- let $t01457014637 = getActualRate(assetIdStr, "bRate")
471- let bRate = $t01457014637._1
472- let ratesRecalcResult = $t01457014637._2
473- let amount = fraction(assetAmount, Scale16, bRate, CEILING)
474- let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",borrowed,") + toString(amount))], nil)
475- if ((collateralValueInv == collateralValueInv))
476- then {
477- let collateralValue = match collateralValueInv {
478- case x: Int =>
479- x
480- case _ =>
481- throw("can't get user collateral value")
717+func reSetup (assetIdStr) = {
718+ let lastResetup = tryGetInteger("resetup_lastUpdate")
719+ if ((dayBlocks > (height - lastResetup)))
720+ then throw("can be updated only once per day")
721+ else {
722+ let lts = split(tryGetString("setup_lts"), ",")
723+ let assets = getMarketAssets()
724+ let ur = getUr(assetIdStr)
725+ let tempLT = tryGetInteger((("setup_" + assetIdStr) + "_tempLT"))
726+ let lt = parseIntValue(assets[value(indexOf(assets, assetIdStr))])
727+ if ((ur > 90000000))
728+ then [IntegerEntry((("setup_" + assetIdStr) + "_tempLT"), fraction(tempLT, 9975, 10000))]
729+ else if (if ((lt > tempLT))
730+ then (90000000 > ur)
731+ else false)
732+ then [IntegerEntry((("setup_" + assetIdStr) + "_tempLT"), fraction(tempLT, 10025, 10000))]
733+ else nil
482734 }
483- if (!(tryGetBoolean("setup_active")))
484- then throw("market is stopped")
485- else if ((0 > collateralValue))
486- then throw("you have to supply more to borrow")
487- else {
488- let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
489- let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
490- let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
491- if ((amount > (assetSupplied - assetBorrowed)))
492- then throw("this amount is not available")
493- else {
494- let inv = invoke(this, "unstakeToken", [assetIdStr, assetAmount], nil)
495- if ((inv == inv))
496- then ([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed + amount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed + amount)), ScriptTransfer(i.caller, assetAmount, getAssetBytes(assetIdStr))] ++ ratesRecalcResult)
497- else throw("Strict value is not equal to itself.")
498- }
499- }
500- }
501- else throw("Strict value is not equal to itself.")
502735 }
503736
504737
505738
506739 @Callable(i)
507-func repay () = if (!(tryGetBoolean("setup_active")))
508- then throw("market is stopped")
509- else if (if ((size(i.payments) != 1))
510- then true
511- else (i.payments[0].amount == 0))
512- then throw("1 payment has to be attached")
513- else {
514- let assetIdStr = getAssetString(i.payments[0].assetId)
515- let assetAmount = i.payments[0].amount
516- let $t01614016207 = getActualRate(assetIdStr, "bRate")
517- let bRate = $t01614016207._1
518- let ratesRecalcResult = $t01614016207._2
519- let amount = fraction(assetAmount, Scale16, bRate, CEILING)
520- let address = toString(i.caller)
521- let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
522- let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
523- let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
524- let amountLeft = (userAssetBorrowed - amount)
525- let repayAmount = if ((amountLeft >= 0))
526- then amount
527- else userAssetBorrowed
528- if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
529- then throw("this asset is not supported by the market")
530- else {
531- let inv = invoke(this, "stakeToken", [assetIdStr, assetAmount], nil)
532- if ((inv == inv))
533- then (([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - repayAmount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - repayAmount))] ++ ratesRecalcResult) ++ (if ((amountLeft >= 0))
534- then nil
535- else [ScriptTransfer(i.caller, -(amountLeft), i.payments[0].assetId)]))
536- else throw("Strict value is not equal to itself.")
537- }
538- }
740+func shutdown (shutdown) = {
741+ let whitelist = [base58'3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL', base58'3PAxdDSmN758L5SHSGRC5apEtQE2aApZotG', base58'3PJKmXoHJvVeQXjSJdhtkUcFDtdiQqMbUTD', base58'3PQdNxynJy5mche2kxMVc5shXWzK8Gstq3o', base58'3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3', base58'3P6Ksahs71SiKQgQ4qaZuFAVhqncdi2nvJQ']
742+ if ((indexOf(whitelist, i.caller.bytes) == unit))
743+ then throw("user not in a whitelist")
744+ else [BooleanEntry("setup_active", !(shutdown))]
745+ }
539746
540747
541748
550757 let userCollateral = calcUserCollateral(address)
551758 if ((userCollateral == userCollateral))
552759 then {
553- let $t01772617795 = getActualRate(sAssetIdStr, "sRate")
554- let sRate = $t01772617795._1
555- let ratesRecalcResult1 = $t01772617795._2
556- let $t01780017869 = getActualRate(bAssetIdStr, "bRate")
557- let bRate = $t01780017869._1
558- let ratesRecalcResult2 = $t01780017869._2
760+ let $t02448224544 = getActualRate(sAssetIdStr, "sRate")
761+ let sRate = $t02448224544._1
762+ let ratesResult = $t02448224544._2
763+ let $t02454924618 = getActualRate(bAssetIdStr, "bRate")
764+ let bRate = $t02454924618._1
765+ let ratesRecalcResult2 = $t02454924618._2
559766 let sAssetAmount = fraction(assetAmount, Scale16, sRate)
560767 let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
561768 let currentBPositionVal = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
597804 then throw("more assets exchanged than expected")
598805 else if ((0 > liquidationProfit))
599806 then throw("price impact is bigger than liquidation penalty")
600- 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)), ScriptTransfer(i.caller, liquidationProfit, getAssetBytes(bAssetIdStr))]
807+ 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))]
601808 }
602809 else throw("Strict value is not equal to itself.")
603810 }
616823
617824
618825 @Callable(i)
826+func liquidateV2 (debug,address,sAssetIdStr) = if (if (if ((i.caller != Address(base58'3PCqdm1mAoQqR46oZotFanmqb5CLUvrKEo2')))
827+ then (i.caller != Address(base58'3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL'))
828+ else false)
829+ then (i.caller != Address(base58'3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3'))
830+ else false)
831+ then throw("temporarily available for whitelist only")
832+ else if (!(tryGetBoolean("setup_active")))
833+ then throw("market is stopped")
834+ else {
835+ let bAssetId = i.payments[0].assetId
836+ let bAssetIdStr = getAssetString(bAssetId)
837+ let bAssetAmount = i.payments[0].amount
838+ let userCollateral = calcUserCollateral(address)
839+ if ((userCollateral == userCollateral))
840+ then if ((userCollateral > 0))
841+ then throw("user can't be liquidated")
842+ else {
843+ let marketAssets = getMarketAssets()
844+ let asset1Num = value(indexOf(marketAssets, bAssetIdStr))
845+ let asset0Num = value(indexOf(marketAssets, sAssetIdStr))
846+ let $t02795028012 = getActualRate(bAssetIdStr, "bRate")
847+ let bRate = $t02795028012._1
848+ let ratesResult = $t02795028012._2
849+ let asset1Price = getTokenPrice(bAssetIdStr)._2
850+ let asset1Scale = calcAssetScale(bAssetIdStr)
851+ let bAmountUsd = fraction(bAssetAmount, asset1Price, asset1Scale)
852+ let penalty = parseIntValue(value(split(tryGetString("setup_penalties"), ",")[asset1Num]))
853+ let asset0Price = getTokenPrice(sAssetIdStr)._1
854+ let asset0Scale = calcAssetScale(sAssetIdStr)
855+ let sAmountUsd = fraction(bAmountUsd, (Scale8 + penalty), Scale8)
856+ let sAssetAmount = fraction(sAmountUsd, asset0Scale, asset0Price)
857+ let bAmount = fraction(bAssetAmount, Scale16, bRate)
858+ let sAmount = fraction(sAssetAmount, Scale16, ratesResult[((asset0Num * 3) + 1)].value)
859+ let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
860+ let currentBPositionVal = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
861+ let currentBPosition = if ((currentBPositionVal != 0))
862+ then currentBPositionVal
863+ else throw("user has no borrow in this token")
864+ if ((sAmount > currentSPosition))
865+ then throw("position to liquidate is bigger than user's supply")
866+ else if (debug)
867+ then throw("liquidation will pass")
868+ 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)
869+ }
870+ else throw("Strict value is not equal to itself.")
871+ }
872+
873+
874+
875+@Callable(i)
619876 func getUserCollateral (debug,address,minusBorrowed,afterChange) = {
620877 let assets = getMarketAssets()
621878 let ltvs = split(tryGetString("setup_ltvs"), ",")
625882 func f (accum,next) = if ((next >= size(assets)))
626883 then accum
627884 else {
628- let assetScale = calcAssetScale(assets[next])
629- let assetPrice = getTokenPrice(assets[next])
630- ((accum + fraction(fraction(fraction((tryGetInteger(((address + "_supplied_") + assets[next])) + (if (if (if ((afterChange != ""))
631- then (changeHandler[0] == assets[next])
632- else false)
633- then (changeHandler[1] == "supplied")
634- else false)
635- then parseIntValue(changeHandler[2])
636- else 0)), rates[(next * 3)].value, Scale16), parseIntValue(ltvs[next]), Scale8), assetPrice._1, assetScale)) - (if (minusBorrowed)
637- then fraction(fraction(fraction((tryGetInteger(((address + "_borrowed_") + assets[next])) + (if (if (if ((afterChange != ""))
638- then (changeHandler[0] == assets[next])
639- else false)
640- then (changeHandler[1] == "borrowed")
641- else false)
642- then parseIntValue(changeHandler[2])
643- else 0)), rates[((next * 3) + 1)].value, Scale16), Scale8, parseIntValue(lts[next])), assetPrice._2, assetScale)
644- else 0))
885+ let userSupplied = tryGetInteger(((address + "_supplied_") + assets[next]))
886+ let userBorrowed = tryGetInteger(((address + "_borrowed_") + assets[next]))
887+ if (if ((userBorrowed != 0))
888+ then true
889+ else (userSupplied != 0))
890+ then {
891+ let assetScale = calcAssetScale(assets[next])
892+ let assetPrice = getTokenPrice(assets[next])
893+ ((accum + fraction(fraction(fraction((userSupplied + (if (if (if ((afterChange != ""))
894+ then (changeHandler[0] == assets[next])
895+ else false)
896+ then (changeHandler[1] == "supplied")
897+ else false)
898+ then parseIntValue(changeHandler[2])
899+ else 0)), rates[(next * 3)].value, Scale16), parseIntValue(ltvs[next]), Scale8), assetPrice._1, assetScale)) - (if (minusBorrowed)
900+ then fraction(fraction(fraction((userBorrowed + (if (if (if ((afterChange != ""))
901+ then (changeHandler[0] == assets[next])
902+ else false)
903+ then (changeHandler[1] == "borrowed")
904+ else false)
905+ then parseIntValue(changeHandler[2])
906+ else 0)), rates[((next * 3) + 1)].value, Scale16), Scale8, parseIntValue(lts[next])), assetPrice._2, assetScale)
907+ else 0))
908+ }
909+ else accum
645910 }
646911
647912 let result = {
7651030 }
7661031
7671032
768-
769-@Callable(i)
770-func claimToReserveFund (debug) = {
771- let assets = getMarketAssets()
772- let rates = getActualRate(assets[0], "sRate")._2
773- let li = [0, 1, 2, 3, 4, 5]
774- func f (accum,n) = if ((n >= size(assets)))
775- then accum
776- else {
777- let assetIdStr = assets[n]
778- let autostakeAmount = tryGetString(("autostake_amount_" + assetIdStr))
779- let amount = ((((getBalance(assetIdStr) + tryGetInteger(("autostake_amount_" + assetIdStr))) + (if ((autostakeAmount != ""))
780- then parseIntValue(autostakeAmount)
781- else 0)) + fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), rates[((n * 3) + 1)].value, Scale16)) - fraction(tryGetInteger(("total_supplied_" + assetIdStr)), rates[(n * 3)].value, Scale16))
782- let inv = if ((tryGetInteger(("autostake_amount_" + assetIdStr)) > 0))
783- then invoke(this, "unstakeToken", [assetIdStr, amount], nil)
784- else 0
785- if ((inv == inv))
786- then (accum ++ [amount])
787- else throw("Strict value is not equal to itself.")
788- }
789-
790- let parameter = {
791- let $l = li
792- let $s = size($l)
793- let $acc0 = nil
794- func $f0_1 ($a,$i) = if (($i >= $s))
795- then $a
796- else f($a, $l[$i])
797-
798- func $f0_2 ($a,$i) = if (($i >= $s))
799- then $a
800- else throw("List size exceeds 6")
801-
802- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
803- }
804- func f2 (accum,n) = if ((n >= size(assets)))
805- then accum
806- else {
807- let assetIdStr = assets[n]
808- (accum ++ [ScriptTransfer(reserveFundAddress, max([parameter[n], 0]), getAssetBytes(assetIdStr))])
809- }
810-
811- if (debug)
812- then throw(liIntToStr(parameter))
813- else $Tuple2({
814- let $l = li
815- let $s = size($l)
816- let $acc0 = nil
817- func $f1_1 ($a,$i) = if (($i >= $s))
818- then $a
819- else f2($a, $l[$i])
820-
821- func $f1_2 ($a,$i) = if (($i >= $s))
822- then $a
823- else throw("List size exceeds 6")
824-
825- $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
826- }, parameter)
827- }
828-
829-
830-
831-@Callable(i)
832-func reSetup (assetIdStr) = {
833- let lastResetup = tryGetInteger("resetup_lastUpdate")
834- if ((dayBlocks > (height - lastResetup)))
835- then throw("can be updated only once per day")
836- else {
837- let lts = split(tryGetString("setup_lts"), ",")
838- let assets = getMarketAssets()
839- let ur = getUr(assetIdStr)
840- let tempLT = tryGetInteger((("setup_" + assetIdStr) + "_tempLT"))
841- let lt = parseIntValue(assets[value(indexOf(assets, assetIdStr))])
842- if ((ur > 90000000))
843- then [IntegerEntry((("setup_" + assetIdStr) + "_tempLT"), fraction(tempLT, 9975, 10000))]
844- else if (if ((lt > tempLT))
845- then (90000000 > ur)
846- else false)
847- then [IntegerEntry((("setup_" + assetIdStr) + "_tempLT"), fraction(tempLT, 10025, 10000))]
848- else nil
849- }
850- }
851-
852-
853-
854-@Callable(i)
855-func shutdown (shutdown) = {
856- let whitelist = [base58'3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL', base58'3PAxdDSmN758L5SHSGRC5apEtQE2aApZotG', base58'3PJKmXoHJvVeQXjSJdhtkUcFDtdiQqMbUTD', base58'3PQdNxynJy5mche2kxMVc5shXWzK8Gstq3o', base58'3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3', base58'3P6Ksahs71SiKQgQ4qaZuFAVhqncdi2nvJQ']
857- if ((indexOf(whitelist, i.caller.bytes) == unit))
858- then throw("user not in a whitelist")
859- else [BooleanEntry("setup_active", !(shutdown))]
860- }
861-
862-
8631033 @Verifier(tx)
8641034 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
8651035
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let Scale8 = 100000000
55
66 let Scale10 = 10000000000
77
88 let Scale16 = (Scale8 * Scale8)
99
10-let reserveFund = 20
11-
1210 let dayBlocks = 1440
13-
14-let reserveFundAddress = Address(base58'3P4kBiU4wr2yV1S5gMfu3MdkVvy7kxXHsKe')
1511
1612 func liIntToStr (li) = {
1713 func f (accum,next) = ((accum + toString(next)) + ",")
1814
1915 let $l = li
2016 let $s = size($l)
2117 let $acc0 = ""
2218 func $f0_1 ($a,$i) = if (($i >= $s))
2319 then $a
2420 else f($a, $l[$i])
2521
2622 func $f0_2 ($a,$i) = if (($i >= $s))
2723 then $a
2824 else throw("List size exceeds 6")
2925
3026 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
3127 }
3228
3329
3430 func tryGetInteger (key) = match getInteger(this, key) {
3531 case b: Int =>
3632 b
3733 case _ =>
3834 0
3935 }
4036
4137
4238 func tryGetBoolean (key) = match getBoolean(this, key) {
4339 case b: Boolean =>
4440 b
4541 case _ =>
4642 false
4743 }
4844
4945
5046 func tryGetString (key) = match getString(this, key) {
5147 case b: String =>
5248 b
5349 case _ =>
5450 ""
5551 }
5652
5753
5854 func tryGetBinary (key) = match getBinary(this, key) {
5955 case b: ByteVector =>
6056 b
6157 case _ =>
6258 base58''
6359 }
6460
6561
6662 func getAssetString (assetId) = match assetId {
6763 case b: ByteVector =>
6864 toBase58String(b)
6965 case _ =>
7066 "WAVES"
7167 }
7268
7369
7470 func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES"))
7571 then unit
7672 else fromBase58String(assetIdStr)
7773
7874
7975 func getBalance (assetIdStr) = if ((assetIdStr == "WAVES"))
8076 then wavesBalance(this).available
8177 else assetBalance(this, fromBase58String(assetIdStr))
8278
8379
80+let reserveFundAddress = Address(base58'3P4kBiU4wr2yV1S5gMfu3MdkVvy7kxXHsKe')
81+
82+let reserveFund = 20
83+
8484 func getMarketAssets () = split(tryGetString("setup_tokens"), ",")
8585
8686
8787 func getAssetsMaxSupply () = {
8888 let s = tryGetString("setup_maxsupply")
8989 if ((s == ""))
9090 then [-1, -1, -1, -1, -1, -1, -1]
9191 else split(s, ",")
9292 }
9393
9494
9595 func getOutdatedUr (assetIdStr) = {
9696 let down = fraction(tryGetInteger(("total_supplied_" + assetIdStr)), tryGetInteger((assetIdStr + "_sRate")), Scale16)
9797 if ((down == 0))
9898 then 0
9999 else fraction(Scale8, fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), tryGetInteger((assetIdStr + "_bRate")), Scale16), down)
100100 }
101101
102102
103103 func getRateCurve (assetIdStr) = match assetIdStr {
104104 case _ =>
105105 if (("34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ" == $match0))
106106 then $Tuple4(2000000, 25000000, 80000000, 100000000)
107107 else if (("6XtHjpXbs9RRJP2Sr9GUyVqzACcby9TkThHXnjVC5CDJ" == $match0))
108108 then $Tuple4(2000000, 25000000, 80000000, 100000000)
109109 else if (("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p" == $match0))
110110 then $Tuple4(2000000, 25000000, 80000000, 100000000)
111111 else if (("Ajso6nTTjptu2UHLx6hfSXVtHFtRBJCkKYd5SAyj7zf5" == $match0))
112112 then $Tuple4(2000000, 40000000, 80000000, 150000000)
113113 else if (("HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS" == $match0))
114114 then $Tuple4(0, 20000000, 80000000, 40000000)
115115 else if (("WAVES" == $match0))
116116 then $Tuple4(2000000, 30000000, 80000000, 50000000)
117117 else if (("Atqv59EYzjFGuitKVnMRk6H8FukjoV3ktPorbEys25on" == $match0))
118118 then $Tuple4(0, 20000000, 80000000, 40000000)
119119 else if (("DSbbhLsSTeDg5Lsiufk2Aneh3DjVqJuPr2M9uU1gwy5p" == $match0))
120120 then $Tuple4(0, 20000000, 80000000, 100000000)
121121 else if (("8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91" == $match0))
122122 then $Tuple4(0, 30000000, 80000000, 40000000)
123123 else if (("At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL" == $match0))
124124 then $Tuple4(0, 25000000, 80000000, 40000000)
125- else $Tuple4(0, 20000000, 80000000, 80000000)
125+ else if (("8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS" == $match0))
126+ then $Tuple4(2000000, 30000000, 80000000, 50000000)
127+ else if (("474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu" == $match0))
128+ then $Tuple4(2000000, 30000000, 80000000, 50000000)
129+ else if (("5UYBPpq4WoU5n4MwpFkgJnW3Fq4B1u3ukpK33ik4QerR" == $match0))
130+ then $Tuple4(2000000, 30000000, 80000000, 50000000)
131+ else $Tuple4(0, 20000000, 80000000, 80000000)
126132 }
127133
128134
129135 func getInterest (assetIdStr) = {
130136 let ur = getOutdatedUr(assetIdStr)
131137 let curve = getRateCurve(assetIdStr)
132138 let rate = (curve._1 + (if ((curve._3 >= ur))
133139 then fraction(ur, curve._2, curve._3)
134140 else (curve._2 + fraction((ur - curve._3), (curve._4 - curve._2), (100000000 - curve._3)))))
135141 max([fraction(rate, Scale8, (dayBlocks * 365)), 1])
136142 }
137143
138144
139145 func tokenRatesRecalc (assetIdStr) = {
140146 let interest = getInterest(assetIdStr)
141147 let ur = getOutdatedUr(assetIdStr)
142148 let lastRecalcHeight = tryGetInteger("lastRateHeight")
143149 let lastBRate = max([tryGetInteger((assetIdStr + "_bRate")), Scale16])
144150 let newBRate = (lastBRate + ((height - lastRecalcHeight) * interest))
145151 let lastSRate = max([tryGetInteger((assetIdStr + "_sRate")), Scale16])
146152 let newSRate = (lastSRate + ((((height - lastRecalcHeight) * fraction(interest, ur, Scale8)) * (100 - reserveFund)) / 100))
147153 [IntegerEntry((assetIdStr + "_sRate"), newSRate), IntegerEntry((assetIdStr + "_bRate"), newBRate), IntegerEntry("lastRateHeight", height)]
148154 }
149155
150156
151157 func getActualRate (assetIdStr,rateType) = {
152158 func f (accum,token) = {
153159 let recalc = tokenRatesRecalc(token)
154160 $Tuple2(if ((token != assetIdStr))
155161 then accum._1
156162 else if ((rateType == "sRate"))
157163 then recalc[0].value
158164 else recalc[1].value, (accum._2 ++ recalc))
159165 }
160166
161167 let $l = getMarketAssets()
162168 let $s = size($l)
163169 let $acc0 = $Tuple2(0, nil)
164170 func $f0_1 ($a,$i) = if (($i >= $s))
165171 then $a
166172 else f($a, $l[$i])
167173
168174 func $f0_2 ($a,$i) = if (($i >= $s))
169175 then $a
170176 else throw("List size exceeds 6")
171177
172178 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
173179 }
174180
175181
176182 func getUr (assetIdStr) = {
177183 let rates = tokenRatesRecalc(assetIdStr)
178184 let down = fraction(tryGetInteger(("total_supplied_" + assetIdStr)), rates[0].value, Scale16)
179185 fraction(Scale8, fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), rates[1].value, Scale16), down)
180186 }
181187
182188
183189 func ratesRecalc () = {
184190 func f (accum,token) = (accum ++ tokenRatesRecalc(token))
185191
186192 let $l = getMarketAssets()
187193 let $s = size($l)
188194 let $acc0 = nil
189195 func $f0_1 ($a,$i) = if (($i >= $s))
190196 then $a
191197 else f($a, $l[$i])
192198
193199 func $f0_2 ($a,$i) = if (($i >= $s))
194200 then $a
195201 else throw("List size exceeds 6")
196202
197203 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
198204 }
199205
200206
201207 func getTokenPrice (assetIdStr) = if ((assetIdStr == "6XtHjpXbs9RRJP2Sr9GUyVqzACcby9TkThHXnjVC5CDJ"))
202208 then $Tuple2(1000000, 1000000)
203209 else {
204210 let inv1 = invoke(addressFromStringValue("3P5BTtdj32Sd1Dyh1Mdw33xQAAckSfMfnKf"), "getTWAP60", [assetIdStr, false], nil)
205211 if ((inv1 == inv1))
206212 then {
207213 let inv2 = invoke(addressFromStringValue("3P8pvmcBi9JeBrnPgWDTaPWrWmGzxiDkpTu"), "getTWAP60", [assetIdStr, false], nil)
208214 if ((inv2 == inv2))
209215 then {
210216 let data1 = match inv1 {
211217 case x: (Int, Int) =>
212218 x
213219 case _ =>
214220 throw("error of price oracle")
215221 }
216222 if ((data1 == data1))
217223 then {
218224 let data2 = match inv2 {
219225 case x: (Int, Int) =>
220226 x
221227 case _ =>
222228 throw("error of price oracle")
223229 }
224230 if ((data2 == data2))
225231 then $Tuple2(min([data1._1, data2._1]), max([data1._2, data2._2]))
226232 else throw("Strict value is not equal to itself.")
227233 }
228234 else throw("Strict value is not equal to itself.")
229235 }
230236 else throw("Strict value is not equal to itself.")
231237 }
232238 else throw("Strict value is not equal to itself.")
233239 }
234240
235241
236242 func calcAssetScale (assetIdStr) = {
237243 let decimals = if ((assetIdStr == "WAVES"))
238244 then 8
239245 else value(assetInfo(fromBase58String(assetIdStr))).decimals
240246 pow(10, 0, decimals, 0, 0, DOWN)
241247 }
242248
243249
244250 func calcUserCollateral (address) = {
245251 let userCollateralInvoke = invoke(this, "getUserCollateral", [false, address, true, ""], nil)
246252 if ((userCollateralInvoke == userCollateralInvoke))
247253 then {
248254 let userCollateralValue = match userCollateralInvoke {
249255 case x: Int =>
250256 x
251257 case _ =>
252258 throw("issue while doing in-dapp invocation")
253259 }
254260 if ((userCollateralValue == userCollateralValue))
255261 then userCollateralValue
256262 else throw("Strict value is not equal to itself.")
257263 }
258264 else throw("Strict value is not equal to itself.")
259265 }
260266
261267
262268 @Callable(i)
269+func supply () = if (!(tryGetBoolean("setup_active")))
270+ then throw("market is stopped")
271+ else if (if ((size(i.payments) != 1))
272+ then true
273+ else (i.payments[0].amount == 0))
274+ then throw("1 payment has to be attached")
275+ else {
276+ let assetIdStr = getAssetString(i.payments[0].assetId)
277+ let assetAmount = i.payments[0].amount
278+ let $t068906957 = getActualRate(assetIdStr, "sRate")
279+ let sRate = $t068906957._1
280+ let ratesRecalcResult = $t068906957._2
281+ let amount = fraction(assetAmount, Scale16, sRate, DOWN)
282+ let address = toString(i.caller)
283+ let maxSupply = match getString(("setup_maxSupply_" + assetIdStr)) {
284+ case x: String =>
285+ parseIntValue(x)
286+ case _ =>
287+ 0
288+ }
289+ let assetPrice = getTokenPrice(assetIdStr)
290+ let newTotalSupplied = (tryGetInteger(((address + "_supplied_") + assetIdStr)) + amount)
291+ let rate = getActualRate(assetIdStr, "sRate")._1
292+ let assetScale = calcAssetScale(assetIdStr)
293+ let newTotalSuppliedUsd = fraction(fraction(newTotalSupplied, rate, Scale16), assetPrice._1, assetScale)
294+ if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
295+ then throw("this asset is not supported by the market")
296+ else if (if ((maxSupply != 0))
297+ then (newTotalSuppliedUsd > maxSupply)
298+ else false)
299+ then throw("max total supply for this token reached in the pool")
300+ else {
301+ let inv = invoke(this, "stakeToken", [assetIdStr, assetAmount], nil)
302+ if ((inv == inv))
303+ then ([IntegerEntry(((address + "_supplied_") + assetIdStr), newTotalSupplied), IntegerEntry(("total_supplied_" + assetIdStr), (tryGetInteger(("total_supplied_" + assetIdStr)) + amount))] ++ ratesRecalcResult)
304+ else throw("Strict value is not equal to itself.")
305+ }
306+ }
307+
308+
309+
310+@Callable(i)
311+func withdraw (assetIdStr,assetAmount) = {
312+ let $t082158282 = getActualRate(assetIdStr, "sRate")
313+ let sRate = $t082158282._1
314+ let ratesRecalcResult = $t082158282._2
315+ let amount = fraction(assetAmount, Scale16, sRate, CEILING)
316+ let address = toString(i.caller)
317+ let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
318+ let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
319+ let userAssetSupplied = tryGetInteger(((address + "_supplied_") + assetIdStr))
320+ let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
321+ let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",supplied,") + toString(-(amount)))], nil)
322+ if ((collateralValueInv == collateralValueInv))
323+ then {
324+ let collateralValue = match collateralValueInv {
325+ case x: Int =>
326+ x
327+ case _ =>
328+ throw("can't get user collateral value")
329+ }
330+ if (!(tryGetBoolean("setup_active")))
331+ then throw("market is stopped")
332+ else if ((0 > collateralValue))
333+ then throw("you dont have enough collateral for this operation")
334+ else if ((amount > (assetSupplied - assetBorrowed)))
335+ then throw("this amount is not available on the market")
336+ else {
337+ let inv = invoke(this, "unstakeToken", [assetIdStr, assetAmount], nil)
338+ if ((inv == inv))
339+ then ([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)
340+ else throw("Strict value is not equal to itself.")
341+ }
342+ }
343+ else throw("Strict value is not equal to itself.")
344+ }
345+
346+
347+
348+@Callable(i)
349+func borrow (assetIdStr,assetAmount) = {
350+ let address = toString(i.caller)
351+ let $t098549921 = getActualRate(assetIdStr, "bRate")
352+ let bRate = $t098549921._1
353+ let ratesRecalcResult = $t098549921._2
354+ let amount = fraction(assetAmount, Scale16, bRate, CEILING)
355+ let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",borrowed,") + toString(amount))], nil)
356+ if ((collateralValueInv == collateralValueInv))
357+ then {
358+ let collateralValue = match collateralValueInv {
359+ case x: Int =>
360+ x
361+ case _ =>
362+ throw("can't get user collateral value")
363+ }
364+ if (!(tryGetBoolean("setup_active")))
365+ then throw("market is stopped")
366+ else if ((0 > collateralValue))
367+ then throw("you have to supply more to borrow")
368+ else {
369+ let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
370+ let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
371+ let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
372+ if ((amount > (assetSupplied - assetBorrowed)))
373+ then throw("this amount is not available")
374+ else {
375+ let inv = invoke(this, "unstakeToken", [assetIdStr, assetAmount], nil)
376+ if ((inv == inv))
377+ then ([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed + amount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed + amount)), ScriptTransfer(i.caller, assetAmount, getAssetBytes(assetIdStr))] ++ ratesRecalcResult)
378+ else throw("Strict value is not equal to itself.")
379+ }
380+ }
381+ }
382+ else throw("Strict value is not equal to itself.")
383+ }
384+
385+
386+
387+@Callable(i)
388+func repay () = if (!(tryGetBoolean("setup_active")))
389+ then throw("market is stopped")
390+ else if (if ((size(i.payments) != 1))
391+ then true
392+ else (i.payments[0].amount == 0))
393+ then throw("1 payment has to be attached")
394+ else {
395+ let assetIdStr = getAssetString(i.payments[0].assetId)
396+ let assetAmount = i.payments[0].amount
397+ let $t01142411491 = getActualRate(assetIdStr, "bRate")
398+ let bRate = $t01142411491._1
399+ let ratesRecalcResult = $t01142411491._2
400+ let amount = fraction(assetAmount, Scale16, bRate, CEILING)
401+ let address = toString(i.caller)
402+ let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
403+ let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
404+ let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
405+ let amountLeft = (userAssetBorrowed - amount)
406+ let repayAmount = if ((amountLeft >= 0))
407+ then amount
408+ else userAssetBorrowed
409+ if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
410+ then throw("this asset is not supported by the market")
411+ else {
412+ let inv = invoke(this, "stakeToken", [assetIdStr, assetAmount], nil)
413+ if ((inv == inv))
414+ then (([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - repayAmount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - repayAmount))] ++ ratesRecalcResult) ++ (if ((amountLeft >= 0))
415+ then nil
416+ else [ScriptTransfer(i.caller, -(amountLeft), i.payments[0].assetId)]))
417+ else throw("Strict value is not equal to itself.")
418+ }
419+ }
420+
421+
422+
423+@Callable(i)
263424 func stakeTokenAll (assetIdStr) = if ((i.caller != this))
264425 then throw("only for internal smart contract invocations")
265426 else {
266- let amount = getBalance("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
427+ let amount = getBalance(assetIdStr)
267428 let inv = invoke(this, "stakeToken", [assetIdStr, amount], nil)
268429 if ((inv == inv))
269430 then nil
270431 else throw("Strict value is not equal to itself.")
271432 }
272433
273434
274435
275436 @Callable(i)
276437 func stakeToken (assetIdStr,amount) = if ((i.caller != this))
277438 then throw("only for internal smart contract invocations")
278439 else if ((assetIdStr == "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"))
279440 then {
280441 let amountStaked = tryGetInteger("autostake_amount_DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
281442 let inv = invoke(Address(base58'3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ'), "stake", nil, [AttachedPayment(base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p', amount)])
282443 if ((inv == inv))
283444 then [IntegerEntry("autostake_amount_DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p", (amountStaked + amount))]
284445 else throw("Strict value is not equal to itself.")
285446 }
286- else nil
447+ else if ((assetIdStr == "8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91"))
448+ then {
449+ let amountStaked = tryGetInteger("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91")
450+ let inv = invoke(Address(base58'3PQTM38wDmAY9vWonK6ha7QL3PAycLz5oPP'), "stake", nil, [AttachedPayment(base58'8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91', amount)])
451+ if ((inv == inv))
452+ then [IntegerEntry("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91", (amountStaked + amount))]
453+ else throw("Strict value is not equal to itself.")
454+ }
455+ else if ((assetIdStr == "At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL"))
456+ then {
457+ let amountStaked = tryGetInteger("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL")
458+ let inv = invoke(Address(base58'3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C'), "stake", nil, [AttachedPayment(base58'At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL', amount)])
459+ if ((inv == inv))
460+ then [IntegerEntry("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", (amountStaked + amount))]
461+ else throw("Strict value is not equal to itself.")
462+ }
463+ else nil
287464
288465
289466
290467 @Callable(i)
291468 func unstakeToken (assetIdStr,amount) = if ((i.caller != this))
292469 then throw("only for internal smart contract invocations")
293470 else if ((assetIdStr == "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"))
294471 then {
295472 let amountStaked = tryGetInteger("autostake_amount_DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
296473 let inv = invoke(Address(base58'3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ'), "unstake", [amount], nil)
297474 if ((inv == inv))
298475 then {
299476 let bal0 = getBalance("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
300477 if ((bal0 == bal0))
301478 then {
302479 let inv2 = invoke(Address(base58'3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ'), "claimRewards", nil, nil)
303480 if ((inv2 == inv2))
304481 then {
305482 let inv3 = invoke(this, "addInterest", ["DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p", (getBalance("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p") - bal0)], nil)
306483 if ((inv3 == inv3))
307484 then [IntegerEntry("autostake_amount_DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p", (amountStaked - amount))]
308485 else throw("Strict value is not equal to itself.")
309486 }
310487 else throw("Strict value is not equal to itself.")
311488 }
312489 else throw("Strict value is not equal to itself.")
313490 }
314491 else throw("Strict value is not equal to itself.")
315492 }
316- else nil
493+ else if ((assetIdStr == "8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91"))
494+ then {
495+ let amountStaked = tryGetInteger("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91")
496+ let inv = invoke(Address(base58'3PQTM38wDmAY9vWonK6ha7QL3PAycLz5oPP'), "unStake", [amount], nil)
497+ if ((inv == inv))
498+ then [IntegerEntry("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91", (amountStaked - amount))]
499+ else throw("Strict value is not equal to itself.")
500+ }
501+ else if ((assetIdStr == "At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL"))
502+ then {
503+ let amountStaked = tryGetInteger("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL")
504+ let inv = invoke(Address(base58'3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C'), "unstake", [amount], nil)
505+ if ((inv == inv))
506+ then {
507+ let bal0 = getBalance("At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL")
508+ if ((bal0 == bal0))
509+ then {
510+ let inv2 = invoke(Address(base58'3PQrVbTVpqXHqpVKftkNdjy3zZAh4dsRzN6'), "gnsbtRewardsSYSREADONLY", [toString(this)], nil)
511+ if ((inv2 == inv2))
512+ then {
513+ let topupRewards = match inv2 {
514+ case x: List[Any] =>
515+ let secondEl = x[1]
516+ match secondEl {
517+ case secondEl: String =>
518+ let usdnValue = parseIntValue(split(split(secondEl, "_")[1], ":")[1])
519+ let wavesValue = parseIntValue(split(split(secondEl, "_")[0], ":")[1])
520+ if (if ((usdnValue != 0))
521+ then true
522+ else (wavesValue != 0))
523+ then {
524+ let usdnBal0 = getBalance("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
525+ if ((usdnBal0 == usdnBal0))
526+ then {
527+ let wavesBal0 = getBalance("WAVES")
528+ if ((wavesBal0 == wavesBal0))
529+ then {
530+ let inv3 = invoke(Address(base58'3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C'), "claimRewards", nil, nil)
531+ if ((inv3 == inv3))
532+ then {
533+ let wavesBal1 = getBalance("WAVES")
534+ if ((wavesBal1 == wavesBal1))
535+ then {
536+ let inv4 = invoke(Address(base58'3PLiXyywNThdvf3vVEUxwc7TJTucjZvuegh'), "swap", ["DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p", 0], [AttachedPayment(unit, (wavesBal1 - wavesBal0))])
537+ if ((inv4 == inv4))
538+ then {
539+ let usdnBal1 = getBalance("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
540+ if ((usdnBal1 == usdnBal1))
541+ then {
542+ let inv5 = invoke(Address(base58'3P7r93vXHuusageNJVGwzqaz3WMotAu49Yz'), "swap", ["At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", 0], [AttachedPayment(base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p', (usdnBal1 - usdnBal0))])
543+ if ((inv5 == inv5))
544+ then {
545+ let inv6 = invoke(this, "addInterest", ["At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", (getBalance("At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL") - bal0)], nil)
546+ if ((inv6 == inv6))
547+ then 2
548+ else throw("Strict value is not equal to itself.")
549+ }
550+ else throw("Strict value is not equal to itself.")
551+ }
552+ else throw("Strict value is not equal to itself.")
553+ }
554+ else throw("Strict value is not equal to itself.")
555+ }
556+ else throw("Strict value is not equal to itself.")
557+ }
558+ else throw("Strict value is not equal to itself.")
559+ }
560+ else throw("Strict value is not equal to itself.")
561+ }
562+ else throw("Strict value is not equal to itself.")
563+ }
564+ else 1
565+ case _ =>
566+ 1
567+ }
568+ case _ =>
569+ 0
570+ }
571+ if ((topupRewards == topupRewards))
572+ then [IntegerEntry("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", (amountStaked - amount))]
573+ else throw("Strict value is not equal to itself.")
574+ }
575+ else throw("Strict value is not equal to itself.")
576+ }
577+ else throw("Strict value is not equal to itself.")
578+ }
579+ else throw("Strict value is not equal to itself.")
580+ }
581+ else nil
317582
318583
319584
320585 @Callable(i)
321586 func addInterest (assetIdStr,amount) = if ((i.caller != this))
322587 then throw("only for self invocation")
323588 else {
324589 let earned = tryGetInteger(("autostake_lastEarned_" + assetIdStr))
325590 let lastHeight = tryGetInteger(("autostake_lastBlock_" + assetIdStr))
326591 let stateChanges = if (if ((lastHeight == height))
327592 then true
328593 else (amount == 0))
329594 then nil
330595 else [IntegerEntry(("autostake_preLastEarned_" + assetIdStr), earned), IntegerEntry(("autostake_preLastBlock_" + assetIdStr), lastHeight), IntegerEntry(("autostake_lastEarned_" + assetIdStr), (earned + amount)), IntegerEntry(("autostake_lastBlock_" + assetIdStr), height)]
331596 (stateChanges ++ [IntegerEntry((assetIdStr + "_sRate"), (tryGetInteger((assetIdStr + "_sRate")) + fraction(Scale16, amount, tryGetInteger(("total_supplied_" + assetIdStr)))))])
332597 }
333598
334599
335600
336601 @Callable(i)
337602 func addInterestEXTERNAL () = {
338603 let amount = fraction(i.payments[0].amount, 80, 100)
339604 let assetId = i.payments[0].assetId
340605 let assetIdStr = getAssetString(assetId)
341606 let earned = tryGetInteger(("autostake_lastEarned_" + assetIdStr))
342607 let lastHeight = tryGetInteger(("autostake_lastBlock_" + assetIdStr))
343608 let stateChanges = if (if ((lastHeight == height))
344609 then true
345610 else (amount == 0))
346611 then nil
347612 else [IntegerEntry(("autostake_preLastEarned_" + assetIdStr), earned), IntegerEntry(("autostake_preLastBlock_" + assetIdStr), lastHeight), IntegerEntry(("autostake_lastEarned_" + assetIdStr), (earned + amount)), IntegerEntry(("autostake_lastBlock_" + assetIdStr), height)]
348613 (stateChanges ++ [IntegerEntry((assetIdStr + "_sRate"), (tryGetInteger((assetIdStr + "_sRate")) + fraction(Scale16, amount, tryGetInteger(("total_supplied_" + assetIdStr)))))])
349614 }
350615
351616
352617
353618 @Callable(i)
354619 func preInit (tokens,ltvs,lts,penalties) = {
355620 func f (accum,token) = (accum ++ [IntegerEntry((token + "_bRate"), Scale16), IntegerEntry((token + "_sRate"), Scale16)])
356621
357622 if ((i.caller != this))
358623 then throw("admin only")
359624 else {
360625 let rates = {
361626 let $l = split(tokens, ",")
362627 let $s = size($l)
363628 let $acc0 = nil
364629 func $f0_1 ($a,$i) = if (($i >= $s))
365630 then $a
366631 else f($a, $l[$i])
367632
368633 func $f0_2 ($a,$i) = if (($i >= $s))
369634 then $a
370635 else throw("List size exceeds 6")
371636
372637 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
373638 }
374639 ([StringEntry("setup_tokens", tokens), StringEntry("setup_ltvs", ltvs), StringEntry("setup_lts", lts), StringEntry("setup_penalties", penalties), BooleanEntry("setup_active", true)] ++ rates)
375640 }
376641 }
377642
378643
379644
380645 @Callable(i)
381-func updateParameter (key,val) = if ((i.caller != this))
646+func updateParameter (key,val) = if (if ((i.caller != this))
647+ then (i.caller != Address(base58'3P3o9cLTV2u9N4nYNKRYL6gy6cUEU9DwXW8'))
648+ else false)
382649 then throw("admin only")
383650 else [IntegerEntry(key, parseIntValue(val))]
384651
385652
386653
387654 @Callable(i)
388-func supply () = if (!(tryGetBoolean("setup_active")))
389- then throw("market is stopped")
390- else if (if ((size(i.payments) != 1))
391- then true
392- else (i.payments[0].amount == 0))
393- then throw("1 payment has to be attached")
655+func claimToReserveFund (debug) = {
656+ let assets = getMarketAssets()
657+ let rates = getActualRate(assets[0], "sRate")._2
658+ let li = [0, 1, 2, 3, 4, 5]
659+ func f (accum,n) = if ((n >= size(assets)))
660+ then accum
394661 else {
395- let assetIdStr = getAssetString(i.payments[0].assetId)
396- let assetAmount = i.payments[0].amount
397- let $t01160411671 = getActualRate(assetIdStr, "sRate")
398- let sRate = $t01160411671._1
399- let ratesRecalcResult = $t01160411671._2
400- let amount = fraction(assetAmount, Scale16, sRate, DOWN)
401- let address = toString(i.caller)
402- let maxSupply = match getString(("setup_maxSupply_" + assetIdStr)) {
403- case x: String =>
404- parseIntValue(x)
405- case _ =>
406- 0
407- }
408- let assetPrice = getTokenPrice(assetIdStr)
409- let newTotalSupplied = (tryGetInteger(((address + "_supplied_") + assetIdStr)) + amount)
410- let rate = getActualRate(assetIdStr, "sRate")._1
411- let assetScale = calcAssetScale(assetIdStr)
412- let newTotalSuppliedUsd = fraction(fraction(newTotalSupplied, rate, Scale16), assetPrice._1, assetScale)
413- if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
414- then throw("this asset is not supported by the market")
415- else if (if ((maxSupply != 0))
416- then (newTotalSuppliedUsd > maxSupply)
417- else false)
418- then throw("max total supply for this token reached in the pool")
419- else {
420- let inv = invoke(this, "stakeToken", [assetIdStr, assetAmount], nil)
421- if ((inv == inv))
422- then ([IntegerEntry(((address + "_supplied_") + assetIdStr), newTotalSupplied), IntegerEntry(("total_supplied_" + assetIdStr), (tryGetInteger(("total_supplied_" + assetIdStr)) + amount))] ++ ratesRecalcResult)
423- else throw("Strict value is not equal to itself.")
424- }
662+ let assetIdStr = assets[n]
663+ let autostakeAmount = tryGetString(("autostake_amount_" + assetIdStr))
664+ let amount = ((((getBalance(assetIdStr) + tryGetInteger(("autostake_amount_" + assetIdStr))) + (if ((autostakeAmount != ""))
665+ then parseIntValue(autostakeAmount)
666+ else 0)) + fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), rates[((n * 3) + 1)].value, Scale16)) - fraction(tryGetInteger(("total_supplied_" + assetIdStr)), rates[(n * 3)].value, Scale16))
667+ let inv = if ((tryGetInteger(("autostake_amount_" + assetIdStr)) > 0))
668+ then invoke(this, "unstakeToken", [assetIdStr, max([amount, 0])], nil)
669+ else 0
670+ if ((inv == inv))
671+ then (accum ++ [amount])
672+ else throw("Strict value is not equal to itself.")
425673 }
426674
675+ let parameter = {
676+ let $l = li
677+ let $s = size($l)
678+ let $acc0 = nil
679+ func $f0_1 ($a,$i) = if (($i >= $s))
680+ then $a
681+ else f($a, $l[$i])
427682
683+ func $f0_2 ($a,$i) = if (($i >= $s))
684+ then $a
685+ else throw("List size exceeds 6")
428686
429-@Callable(i)
430-func withdraw (assetIdStr,assetAmount) = {
431- let $t01293012997 = getActualRate(assetIdStr, "sRate")
432- let sRate = $t01293012997._1
433- let ratesRecalcResult = $t01293012997._2
434- let amount = fraction(assetAmount, Scale16, sRate, CEILING)
435- let address = toString(i.caller)
436- let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
437- let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
438- let userAssetSupplied = tryGetInteger(((address + "_supplied_") + assetIdStr))
439- let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
440- let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",supplied,") + toString(-(amount)))], nil)
441- if ((collateralValueInv == collateralValueInv))
442- then {
443- let collateralValue = match collateralValueInv {
444- case x: Int =>
445- x
446- case _ =>
447- throw("can't get user collateral value")
687+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
688+ }
689+ func f2 (accum,n) = if ((n >= size(assets)))
690+ then accum
691+ else {
692+ let assetIdStr = assets[n]
693+ (accum ++ [ScriptTransfer(reserveFundAddress, max([parameter[n], 0]), getAssetBytes(assetIdStr))])
448694 }
449- if (!(tryGetBoolean("setup_active")))
450- then throw("market is stopped")
451- else if ((0 > collateralValue))
452- then throw("you dont have enough collateral for this operation")
453- else if ((amount > (assetSupplied - assetBorrowed)))
454- then throw("this amount is not available on the market")
455- else {
456- let inv = invoke(this, "unstakeToken", [assetIdStr, assetAmount], nil)
457- if ((inv == inv))
458- then ([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)
459- else throw("Strict value is not equal to itself.")
460- }
461- }
462- else throw("Strict value is not equal to itself.")
695+
696+ if (debug)
697+ then throw(liIntToStr(parameter))
698+ else $Tuple2({
699+ let $l = li
700+ let $s = size($l)
701+ let $acc0 = nil
702+ func $f1_1 ($a,$i) = if (($i >= $s))
703+ then $a
704+ else f2($a, $l[$i])
705+
706+ func $f1_2 ($a,$i) = if (($i >= $s))
707+ then $a
708+ else throw("List size exceeds 6")
709+
710+ $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
711+ }, parameter)
463712 }
464713
465714
466715
467716 @Callable(i)
468-func borrow (assetIdStr,assetAmount) = {
469- let address = toString(i.caller)
470- let $t01457014637 = getActualRate(assetIdStr, "bRate")
471- let bRate = $t01457014637._1
472- let ratesRecalcResult = $t01457014637._2
473- let amount = fraction(assetAmount, Scale16, bRate, CEILING)
474- let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",borrowed,") + toString(amount))], nil)
475- if ((collateralValueInv == collateralValueInv))
476- then {
477- let collateralValue = match collateralValueInv {
478- case x: Int =>
479- x
480- case _ =>
481- throw("can't get user collateral value")
717+func reSetup (assetIdStr) = {
718+ let lastResetup = tryGetInteger("resetup_lastUpdate")
719+ if ((dayBlocks > (height - lastResetup)))
720+ then throw("can be updated only once per day")
721+ else {
722+ let lts = split(tryGetString("setup_lts"), ",")
723+ let assets = getMarketAssets()
724+ let ur = getUr(assetIdStr)
725+ let tempLT = tryGetInteger((("setup_" + assetIdStr) + "_tempLT"))
726+ let lt = parseIntValue(assets[value(indexOf(assets, assetIdStr))])
727+ if ((ur > 90000000))
728+ then [IntegerEntry((("setup_" + assetIdStr) + "_tempLT"), fraction(tempLT, 9975, 10000))]
729+ else if (if ((lt > tempLT))
730+ then (90000000 > ur)
731+ else false)
732+ then [IntegerEntry((("setup_" + assetIdStr) + "_tempLT"), fraction(tempLT, 10025, 10000))]
733+ else nil
482734 }
483- if (!(tryGetBoolean("setup_active")))
484- then throw("market is stopped")
485- else if ((0 > collateralValue))
486- then throw("you have to supply more to borrow")
487- else {
488- let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
489- let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
490- let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
491- if ((amount > (assetSupplied - assetBorrowed)))
492- then throw("this amount is not available")
493- else {
494- let inv = invoke(this, "unstakeToken", [assetIdStr, assetAmount], nil)
495- if ((inv == inv))
496- then ([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed + amount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed + amount)), ScriptTransfer(i.caller, assetAmount, getAssetBytes(assetIdStr))] ++ ratesRecalcResult)
497- else throw("Strict value is not equal to itself.")
498- }
499- }
500- }
501- else throw("Strict value is not equal to itself.")
502735 }
503736
504737
505738
506739 @Callable(i)
507-func repay () = if (!(tryGetBoolean("setup_active")))
508- then throw("market is stopped")
509- else if (if ((size(i.payments) != 1))
510- then true
511- else (i.payments[0].amount == 0))
512- then throw("1 payment has to be attached")
513- else {
514- let assetIdStr = getAssetString(i.payments[0].assetId)
515- let assetAmount = i.payments[0].amount
516- let $t01614016207 = getActualRate(assetIdStr, "bRate")
517- let bRate = $t01614016207._1
518- let ratesRecalcResult = $t01614016207._2
519- let amount = fraction(assetAmount, Scale16, bRate, CEILING)
520- let address = toString(i.caller)
521- let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
522- let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
523- let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
524- let amountLeft = (userAssetBorrowed - amount)
525- let repayAmount = if ((amountLeft >= 0))
526- then amount
527- else userAssetBorrowed
528- if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
529- then throw("this asset is not supported by the market")
530- else {
531- let inv = invoke(this, "stakeToken", [assetIdStr, assetAmount], nil)
532- if ((inv == inv))
533- then (([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - repayAmount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - repayAmount))] ++ ratesRecalcResult) ++ (if ((amountLeft >= 0))
534- then nil
535- else [ScriptTransfer(i.caller, -(amountLeft), i.payments[0].assetId)]))
536- else throw("Strict value is not equal to itself.")
537- }
538- }
740+func shutdown (shutdown) = {
741+ let whitelist = [base58'3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL', base58'3PAxdDSmN758L5SHSGRC5apEtQE2aApZotG', base58'3PJKmXoHJvVeQXjSJdhtkUcFDtdiQqMbUTD', base58'3PQdNxynJy5mche2kxMVc5shXWzK8Gstq3o', base58'3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3', base58'3P6Ksahs71SiKQgQ4qaZuFAVhqncdi2nvJQ']
742+ if ((indexOf(whitelist, i.caller.bytes) == unit))
743+ then throw("user not in a whitelist")
744+ else [BooleanEntry("setup_active", !(shutdown))]
745+ }
539746
540747
541748
542749 @Callable(i)
543750 func liquidate (debug,address,assetAmount,sAssetIdStr,bAssetIdStr,routeStr) = if (if ((i.caller != Address(base58'3PCqdm1mAoQqR46oZotFanmqb5CLUvrKEo2')))
544751 then (i.caller != Address(base58'3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3'))
545752 else false)
546753 then throw("temporarily listed for whitelist only")
547754 else if (!(tryGetBoolean("setup_active")))
548755 then throw("market is stopped")
549756 else {
550757 let userCollateral = calcUserCollateral(address)
551758 if ((userCollateral == userCollateral))
552759 then {
553- let $t01772617795 = getActualRate(sAssetIdStr, "sRate")
554- let sRate = $t01772617795._1
555- let ratesRecalcResult1 = $t01772617795._2
556- let $t01780017869 = getActualRate(bAssetIdStr, "bRate")
557- let bRate = $t01780017869._1
558- let ratesRecalcResult2 = $t01780017869._2
760+ let $t02448224544 = getActualRate(sAssetIdStr, "sRate")
761+ let sRate = $t02448224544._1
762+ let ratesResult = $t02448224544._2
763+ let $t02454924618 = getActualRate(bAssetIdStr, "bRate")
764+ let bRate = $t02454924618._1
765+ let ratesRecalcResult2 = $t02454924618._2
559766 let sAssetAmount = fraction(assetAmount, Scale16, sRate)
560767 let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
561768 let currentBPositionVal = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
562769 let currentBPosition = if ((currentBPositionVal != 0))
563770 then currentBPositionVal
564771 else throw("user has no borrow in this token")
565772 if ((userCollateral > 0))
566773 then throw("user can't be liquidated")
567774 else if ((sAssetAmount > currentSPosition))
568775 then throw("position to liquidate is bigger than user's supply")
569776 else {
570777 let aggregatorAddress = Address(base58'3PGFHzVGT4NTigwCKP1NcwoXkodVZwvBuuU')
571778 let balance0Before = getBalance(sAssetIdStr)
572779 if ((balance0Before == balance0Before))
573780 then {
574781 let balance1Before = getBalance(bAssetIdStr)
575782 if ((balance1Before == balance1Before))
576783 then {
577784 let exchangeInvoke = invoke(aggregatorAddress, "swap", [routeStr, 0], [AttachedPayment(getAssetBytes(sAssetIdStr), assetAmount)])
578785 if ((exchangeInvoke == exchangeInvoke))
579786 then {
580787 let asset0Sold = (balance0Before - getBalance(sAssetIdStr))
581788 if ((asset0Sold == asset0Sold))
582789 then {
583790 let asset1Bought = (getBalance(bAssetIdStr) - balance1Before)
584791 if ((asset1Bought == asset1Bought))
585792 then {
586793 let asset0Price = getTokenPrice(sAssetIdStr)._2
587794 let asset0Scale = calcAssetScale(sAssetIdStr)
588795 let asset0Usd = fraction(asset0Sold, asset0Price, asset0Scale)
589796 let asset1Price = getTokenPrice(bAssetIdStr)._1
590797 let asset1Scale = calcAssetScale(bAssetIdStr)
591798 let asset1Usd = fraction(asset1Bought, asset1Price, asset1Scale)
592799 let penalty = parseIntValue(split(tryGetString("setup_penalties"), ",")[value(indexOf(getMarketAssets(), bAssetIdStr))])
593800 let liquidationProfit = (asset1Usd - fraction(asset0Usd, (Scale8 - penalty), Scale8))
594801 let sAssetChange = fraction(asset0Sold, Scale16, sRate)
595802 let bAssetChange = fraction(asset1Bought, Scale16, bRate)
596803 if ((asset0Sold > assetAmount))
597804 then throw("more assets exchanged than expected")
598805 else if ((0 > liquidationProfit))
599806 then throw("price impact is bigger than liquidation penalty")
600- 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)), ScriptTransfer(i.caller, liquidationProfit, getAssetBytes(bAssetIdStr))]
807+ 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))]
601808 }
602809 else throw("Strict value is not equal to itself.")
603810 }
604811 else throw("Strict value is not equal to itself.")
605812 }
606813 else throw("Strict value is not equal to itself.")
607814 }
608815 else throw("Strict value is not equal to itself.")
609816 }
610817 else throw("Strict value is not equal to itself.")
611818 }
612819 }
613820 else throw("Strict value is not equal to itself.")
614821 }
615822
616823
617824
618825 @Callable(i)
826+func liquidateV2 (debug,address,sAssetIdStr) = if (if (if ((i.caller != Address(base58'3PCqdm1mAoQqR46oZotFanmqb5CLUvrKEo2')))
827+ then (i.caller != Address(base58'3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL'))
828+ else false)
829+ then (i.caller != Address(base58'3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3'))
830+ else false)
831+ then throw("temporarily available for whitelist only")
832+ else if (!(tryGetBoolean("setup_active")))
833+ then throw("market is stopped")
834+ else {
835+ let bAssetId = i.payments[0].assetId
836+ let bAssetIdStr = getAssetString(bAssetId)
837+ let bAssetAmount = i.payments[0].amount
838+ let userCollateral = calcUserCollateral(address)
839+ if ((userCollateral == userCollateral))
840+ then if ((userCollateral > 0))
841+ then throw("user can't be liquidated")
842+ else {
843+ let marketAssets = getMarketAssets()
844+ let asset1Num = value(indexOf(marketAssets, bAssetIdStr))
845+ let asset0Num = value(indexOf(marketAssets, sAssetIdStr))
846+ let $t02795028012 = getActualRate(bAssetIdStr, "bRate")
847+ let bRate = $t02795028012._1
848+ let ratesResult = $t02795028012._2
849+ let asset1Price = getTokenPrice(bAssetIdStr)._2
850+ let asset1Scale = calcAssetScale(bAssetIdStr)
851+ let bAmountUsd = fraction(bAssetAmount, asset1Price, asset1Scale)
852+ let penalty = parseIntValue(value(split(tryGetString("setup_penalties"), ",")[asset1Num]))
853+ let asset0Price = getTokenPrice(sAssetIdStr)._1
854+ let asset0Scale = calcAssetScale(sAssetIdStr)
855+ let sAmountUsd = fraction(bAmountUsd, (Scale8 + penalty), Scale8)
856+ let sAssetAmount = fraction(sAmountUsd, asset0Scale, asset0Price)
857+ let bAmount = fraction(bAssetAmount, Scale16, bRate)
858+ let sAmount = fraction(sAssetAmount, Scale16, ratesResult[((asset0Num * 3) + 1)].value)
859+ let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
860+ let currentBPositionVal = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
861+ let currentBPosition = if ((currentBPositionVal != 0))
862+ then currentBPositionVal
863+ else throw("user has no borrow in this token")
864+ if ((sAmount > currentSPosition))
865+ then throw("position to liquidate is bigger than user's supply")
866+ else if (debug)
867+ then throw("liquidation will pass")
868+ 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)
869+ }
870+ else throw("Strict value is not equal to itself.")
871+ }
872+
873+
874+
875+@Callable(i)
619876 func getUserCollateral (debug,address,minusBorrowed,afterChange) = {
620877 let assets = getMarketAssets()
621878 let ltvs = split(tryGetString("setup_ltvs"), ",")
622879 let lts = split(tryGetString("setup_lts"), ",")
623880 let rates = getActualRate(assets[0], "sRate")._2
624881 let changeHandler = split(afterChange, ",")
625882 func f (accum,next) = if ((next >= size(assets)))
626883 then accum
627884 else {
628- let assetScale = calcAssetScale(assets[next])
629- let assetPrice = getTokenPrice(assets[next])
630- ((accum + fraction(fraction(fraction((tryGetInteger(((address + "_supplied_") + assets[next])) + (if (if (if ((afterChange != ""))
631- then (changeHandler[0] == assets[next])
632- else false)
633- then (changeHandler[1] == "supplied")
634- else false)
635- then parseIntValue(changeHandler[2])
636- else 0)), rates[(next * 3)].value, Scale16), parseIntValue(ltvs[next]), Scale8), assetPrice._1, assetScale)) - (if (minusBorrowed)
637- then fraction(fraction(fraction((tryGetInteger(((address + "_borrowed_") + assets[next])) + (if (if (if ((afterChange != ""))
638- then (changeHandler[0] == assets[next])
639- else false)
640- then (changeHandler[1] == "borrowed")
641- else false)
642- then parseIntValue(changeHandler[2])
643- else 0)), rates[((next * 3) + 1)].value, Scale16), Scale8, parseIntValue(lts[next])), assetPrice._2, assetScale)
644- else 0))
885+ let userSupplied = tryGetInteger(((address + "_supplied_") + assets[next]))
886+ let userBorrowed = tryGetInteger(((address + "_borrowed_") + assets[next]))
887+ if (if ((userBorrowed != 0))
888+ then true
889+ else (userSupplied != 0))
890+ then {
891+ let assetScale = calcAssetScale(assets[next])
892+ let assetPrice = getTokenPrice(assets[next])
893+ ((accum + fraction(fraction(fraction((userSupplied + (if (if (if ((afterChange != ""))
894+ then (changeHandler[0] == assets[next])
895+ else false)
896+ then (changeHandler[1] == "supplied")
897+ else false)
898+ then parseIntValue(changeHandler[2])
899+ else 0)), rates[(next * 3)].value, Scale16), parseIntValue(ltvs[next]), Scale8), assetPrice._1, assetScale)) - (if (minusBorrowed)
900+ then fraction(fraction(fraction((userBorrowed + (if (if (if ((afterChange != ""))
901+ then (changeHandler[0] == assets[next])
902+ else false)
903+ then (changeHandler[1] == "borrowed")
904+ else false)
905+ then parseIntValue(changeHandler[2])
906+ else 0)), rates[((next * 3) + 1)].value, Scale16), Scale8, parseIntValue(lts[next])), assetPrice._2, assetScale)
907+ else 0))
908+ }
909+ else accum
645910 }
646911
647912 let result = {
648913 let $l = [0, 1, 2, 3, 4, 5]
649914 let $s = size($l)
650915 let $acc0 = 0
651916 func $f0_1 ($a,$i) = if (($i >= $s))
652917 then $a
653918 else f($a, $l[$i])
654919
655920 func $f0_2 ($a,$i) = if (($i >= $s))
656921 then $a
657922 else throw("List size exceeds 6")
658923
659924 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
660925 }
661926 if (debug)
662927 then throw(toString(result))
663928 else $Tuple2(rates, result)
664929 }
665930
666931
667932
668933 @Callable(i)
669934 func getPrices (debug) = {
670935 let assets = getMarketAssets()
671936 func f (accum,next) = if ((next >= size(assets)))
672937 then accum
673938 else {
674939 let assetPrice = getTokenPrice(assets[next])
675940 ((((accum + toString(assetPrice._1)) + ",") + toString(assetPrice._2)) + "|")
676941 }
677942
678943 let result = {
679944 let $l = [0, 1, 2, 3, 4, 5]
680945 let $s = size($l)
681946 let $acc0 = ""
682947 func $f0_1 ($a,$i) = if (($i >= $s))
683948 then $a
684949 else f($a, $l[$i])
685950
686951 func $f0_2 ($a,$i) = if (($i >= $s))
687952 then $a
688953 else throw("List size exceeds 6")
689954
690955 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
691956 }
692957 if (debug)
693958 then throw(result)
694959 else $Tuple2(nil, result)
695960 }
696961
697962
698963
699964 @Callable(i)
700965 func calculateUtilizationRatio (assetIdStr,debug) = if (debug)
701966 then throw(toString(getUr(assetIdStr)))
702967 else $Tuple2(nil, getUr(assetIdStr))
703968
704969
705970
706971 @Callable(i)
707972 func calculateOutdatedUR (assetIdStr,debug) = if (debug)
708973 then throw(toString(getOutdatedUr(assetIdStr)))
709974 else $Tuple2(nil, getOutdatedUr(assetIdStr))
710975
711976
712977
713978 @Callable(i)
714979 func calculateTokenRates (debug) = {
715980 func f (accum,assetIdStr) = {
716981 let rates = tokenRatesRecalc(assetIdStr)
717982 $Tuple2(((((accum._1 + toString(rates[1].value)) + "|") + toString(rates[0].value)) + ","), (accum._2 ++ rates))
718983 }
719984
720985 let parameter = {
721986 let $l = getMarketAssets()
722987 let $s = size($l)
723988 let $acc0 = $Tuple2("", nil)
724989 func $f0_1 ($a,$i) = if (($i >= $s))
725990 then $a
726991 else f($a, $l[$i])
727992
728993 func $f0_2 ($a,$i) = if (($i >= $s))
729994 then $a
730995 else throw("List size exceeds 6")
731996
732997 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
733998 }
734999 if (debug)
7351000 then throw(parameter._1)
7361001 else $Tuple2(parameter._2, parameter._1)
7371002 }
7381003
7391004
7401005
7411006 @Callable(i)
7421007 func calculateTokensInterest (debug) = {
7431008 func f (accum,assetIdStr) = {
7441009 let rate = fraction(getInterest(assetIdStr), dayBlocks, Scale8)
7451010 ((accum + toString(rate)) + ",")
7461011 }
7471012
7481013 let parameter = {
7491014 let $l = getMarketAssets()
7501015 let $s = size($l)
7511016 let $acc0 = ""
7521017 func $f0_1 ($a,$i) = if (($i >= $s))
7531018 then $a
7541019 else f($a, $l[$i])
7551020
7561021 func $f0_2 ($a,$i) = if (($i >= $s))
7571022 then $a
7581023 else throw("List size exceeds 6")
7591024
7601025 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
7611026 }
7621027 if (debug)
7631028 then throw(parameter)
7641029 else $Tuple2(nil, parameter)
7651030 }
7661031
7671032
768-
769-@Callable(i)
770-func claimToReserveFund (debug) = {
771- let assets = getMarketAssets()
772- let rates = getActualRate(assets[0], "sRate")._2
773- let li = [0, 1, 2, 3, 4, 5]
774- func f (accum,n) = if ((n >= size(assets)))
775- then accum
776- else {
777- let assetIdStr = assets[n]
778- let autostakeAmount = tryGetString(("autostake_amount_" + assetIdStr))
779- let amount = ((((getBalance(assetIdStr) + tryGetInteger(("autostake_amount_" + assetIdStr))) + (if ((autostakeAmount != ""))
780- then parseIntValue(autostakeAmount)
781- else 0)) + fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), rates[((n * 3) + 1)].value, Scale16)) - fraction(tryGetInteger(("total_supplied_" + assetIdStr)), rates[(n * 3)].value, Scale16))
782- let inv = if ((tryGetInteger(("autostake_amount_" + assetIdStr)) > 0))
783- then invoke(this, "unstakeToken", [assetIdStr, amount], nil)
784- else 0
785- if ((inv == inv))
786- then (accum ++ [amount])
787- else throw("Strict value is not equal to itself.")
788- }
789-
790- let parameter = {
791- let $l = li
792- let $s = size($l)
793- let $acc0 = nil
794- func $f0_1 ($a,$i) = if (($i >= $s))
795- then $a
796- else f($a, $l[$i])
797-
798- func $f0_2 ($a,$i) = if (($i >= $s))
799- then $a
800- else throw("List size exceeds 6")
801-
802- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6)
803- }
804- func f2 (accum,n) = if ((n >= size(assets)))
805- then accum
806- else {
807- let assetIdStr = assets[n]
808- (accum ++ [ScriptTransfer(reserveFundAddress, max([parameter[n], 0]), getAssetBytes(assetIdStr))])
809- }
810-
811- if (debug)
812- then throw(liIntToStr(parameter))
813- else $Tuple2({
814- let $l = li
815- let $s = size($l)
816- let $acc0 = nil
817- func $f1_1 ($a,$i) = if (($i >= $s))
818- then $a
819- else f2($a, $l[$i])
820-
821- func $f1_2 ($a,$i) = if (($i >= $s))
822- then $a
823- else throw("List size exceeds 6")
824-
825- $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6)
826- }, parameter)
827- }
828-
829-
830-
831-@Callable(i)
832-func reSetup (assetIdStr) = {
833- let lastResetup = tryGetInteger("resetup_lastUpdate")
834- if ((dayBlocks > (height - lastResetup)))
835- then throw("can be updated only once per day")
836- else {
837- let lts = split(tryGetString("setup_lts"), ",")
838- let assets = getMarketAssets()
839- let ur = getUr(assetIdStr)
840- let tempLT = tryGetInteger((("setup_" + assetIdStr) + "_tempLT"))
841- let lt = parseIntValue(assets[value(indexOf(assets, assetIdStr))])
842- if ((ur > 90000000))
843- then [IntegerEntry((("setup_" + assetIdStr) + "_tempLT"), fraction(tempLT, 9975, 10000))]
844- else if (if ((lt > tempLT))
845- then (90000000 > ur)
846- else false)
847- then [IntegerEntry((("setup_" + assetIdStr) + "_tempLT"), fraction(tempLT, 10025, 10000))]
848- else nil
849- }
850- }
851-
852-
853-
854-@Callable(i)
855-func shutdown (shutdown) = {
856- let whitelist = [base58'3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL', base58'3PAxdDSmN758L5SHSGRC5apEtQE2aApZotG', base58'3PJKmXoHJvVeQXjSJdhtkUcFDtdiQqMbUTD', base58'3PQdNxynJy5mche2kxMVc5shXWzK8Gstq3o', base58'3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3', base58'3P6Ksahs71SiKQgQ4qaZuFAVhqncdi2nvJQ']
857- if ((indexOf(whitelist, i.caller.bytes) == unit))
858- then throw("user not in a whitelist")
859- else [BooleanEntry("setup_active", !(shutdown))]
860- }
861-
862-
8631033 @Verifier(tx)
8641034 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
8651035

github/deemru/w8io/3ef1775 
137.84 ms