tx · CWcXBfsTHzdjcJNPVSa3B9cRUtTmTmwWWs4aiRwnJVi6

3P4uA5etnZi4AmBabKinq2bMiWU8KcnHZdH:  -0.04000000 Waves

2023.07.06 17:27 [3719806] smart account 3P4uA5etnZi4AmBabKinq2bMiWU8KcnHZdH > SELF 0.00000000 Waves

{ "type": 13, "id": "CWcXBfsTHzdjcJNPVSa3B9cRUtTmTmwWWs4aiRwnJVi6", "fee": 4000000, "feeAssetId": null, "timestamp": 1688653653130, "version": 2, "chainId": 87, "sender": "3P4uA5etnZi4AmBabKinq2bMiWU8KcnHZdH", "senderPublicKey": "8DxbUxhy23djr6kUEE1Jzp7oVJXBsHNaATLRiABpkSde", "proofs": [ "5pffsKtWzT2iHi2Q8RDLZrCDjxvD6ocV2c4ThRNxTiRao2ycdiqwuKRMzabDXyNSF9mT6UAQXmzXjgmiirNM9WA6" ], "script": "base64:BgKPAQgCEgASBAoCCAESBAoCCAESABIDCgEIEgMKAQgSBAoCCAESBAoCCAESBAoCCAESABIGCgQICAgIEgYKBAgICAgSBAoCCAgSBAoCCAgSAwoBBBIDCgEIEgMKAQQSCAoGBAgBCAgIEgUKAwQICBIGCgQECAQIEgMKAQQSBAoCCAQSBAoCCAQSAwoBBBIDCgEEHwAScmVzZXJ2ZUZ1bmRBZGRyZXNzCQEHQWRkcmVzcwEBGgFXHuH7QDFrgebsS1YbBSxRoZNu3wmxPNLBAAtyZXNlcnZlRnVuZAAUABFhZ2dyZWdhdG9yQWRkcmVzcwkBB0FkZHJlc3MBARoBV50MqsYTUaluy4D3Y33BZHji73JNqAy60wAJb3JhY2xlU3RyAiMzUFBYVktqTjZuUk16WGVlZ2NZaGZpaWM5NnBkMmM5OEVrbQARc2h1dGRvd25XaGl0ZWxpc3QJAMwIAgEaAVfX4SNRjnyriFrV1yiXddiIddOPriMFpuEJAMwIAgEaAVdjDQOBpn9bVNIcueQoKvOngDTw2LWN1WUJAMwIAgEaAVez1ZJUSQmaKhD7xvifEHar7z8PcqWJFYwJAMwIAgEaAVf4+voCJsBRi+xqO0YzSdIccbB1i/mkypoJAMwIAgEaAVer3aoi85i5H0XYLNSn6vkSYq+JNmpQO3IJAMwIAgEaAVcwORzRpGYYO35/49jeov24Z5j/V00RJp0FA25pbAEWdmVyaWZ5TGlxdWlkYXRvclJpZ2h0cwEHYWRkcmVzcwkBASEBAwMJAQIhPQIFB2FkZHJlc3MJAQdBZGRyZXNzAQEaAVd3qs7ReFboqZ5eq5Xvv+nhcVh1XjKacYEJAQIhPQIFB2FkZHJlc3MJAQdBZGRyZXNzAQEaAVfX4SNRjnyriFrV1yiXddiIddOPriMFpuEHCQECIT0CBQdhZGRyZXNzCQEHQWRkcmVzcwEBGgFXq92qIvOYuR9F2CzUp+r5EmKviTZqUDtyBwEMZ2V0UmF0ZUN1cnZlAQphc3NldElkU3RyBAckbWF0Y2gwBQphc3NldElkU3RyAwkAAAICLDl3YzNMWE5BNFRFQnNYeUt0b0xFOW1yYkREN1dNSFh2WHJDalp2YWJMQXNpBQckbWF0Y2gwCQCWCgQAgIl6AMDw9QsAgOiSJgCAwtcvAwkAAAICLEhHZ2FiVHFVUzhXdFZGVUp6Zm1yVERNZ0VjY0p1WkxCUGhGZ1FGeHZuc29XBQckbWF0Y2gwCQCWCgQAgIl6AMDw9QsAgOiSJgCAwtcvAwkAAAICLDM0TjlZY0VFVExXbjkzcVlRNjRFc1AxeDg5dFNydUpVNDRSckVNU1hYRVBKBQckbWF0Y2gwCQCWCgQAgIl6AMDw9QsAgOiSJgCAwtcvAwkAAAICLDZYdEhqcFhiczlSUkpQMlNyOUdVeVZxekFDY2J5OVRrVGhIWG5qVkM1Q0RKBQckbWF0Y2gwCQCWCgQAgIl6AMDw9QsAgOiSJgCAwtcvAwkAAAICLERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwBQckbWF0Y2gwCQCWCgQAgIl6AMDw9QsAgOiSJgCAwtcvAwkAAAICLEFqc282blRUanB0dTJVSEx4NmhmU1hWdEhGdFJCSkNrS1lkNVNBeWo3emY1BQckbWF0Y2gwCQCWCgQAgIl6AIC0iRMAgOiSJgCAo8NHAwkAAAICLEhFQjhRYXc5eHJXcFdzOHRIc2lBVFlHQldEQnRQMlM3a2NQQUxyTXU0M0FTBQckbWF0Y2gwCQCWCgQAAACA4esXAIDokiYAgIjevgEDCQAAAgIFV0FWRVMFByRtYXRjaDAJAJYKBACAiXoAgIenDgCA6JImAIDokiYDCQAAAgIsQXRxdjU5RVl6akZHdWl0S1ZuTVJrNkg4RnVram9WM2t0UG9yYkV5czI1b24FByRtYXRjaDAJAJYKBAAAAIDaxAkAgOiSJgCAtIkTAwkAAAICLERTYmJoTHNTVGVEZzVMc2l1ZmsyQW5laDNEalZxSnVQcjJNOXVVMWd3eTVwBQckbWF0Y2gwCQCWCgQAAACA2sQJAIDokiYAgMLXLwMJAAACAiw4dDREUFdUd1B6cGF0SEE5QWtUeFdBQjQ3VEhuWXpCc0Rub1k3ZlFxYkc5MQUHJG1hdGNoMAkAlgoEAAAAgIenDgCA6JImAIC0iRMDCQAAAgIsQXQ4RDZORkZwaGVDYnZLVm5qVm9lTEw4NEVvOE5abjZvdk1hbnhmTGFGV0wFByRtYXRjaDAJAJYKBAAAAMDw9QsAgOiSJgCAtIkTAwkAAAICLDhMUVc4ZjdQNWQ1UFpNN0d0WkVCZ2FxUlBHU3pTM0RmUHVpWHJVUko0QUpTBQckbWF0Y2gwCQCWCgQAgIl6AICHpw4AgOiSJgCA4esXAwkAAAICLDQ3NGpUZVl4MnIyVmEzNTc5NHRDU2NBWFdKRzloVTJIY2d4ek1vd2FaVW51BQckbWF0Y2gwCQCWCgQAgIl6AICHpw4AgOiSJgCA4esXAwkAAAICLDVVWUJQcHE0V29VNW40TXdwRmtnSm5XM0ZxNEIxdTN1a3BLMzNpazRRZXJSBQckbWF0Y2gwCQCWCgQAgIl6AICHpw4AgOiSJgCA4esXAwkAAAICLDJ0aHNBQ3VIbXpETXVOZXpQTTMyd2c5YTNCd1V6QldEZVNLYWtnejNjdzIxBQckbWF0Y2gwCQCWCgQAgIl6AIC0iRMAgOiSJgCAwtcvAwkAAAICK1lpTmJvZkZ6QzE3akVISENNd3JSY3B5OU1ycmphYk1NTFp4ZzhnNXhtZjcFByRtYXRjaDAJAJYKBACAiXoAgIenDgCA6JImAIDokiYDCQAAAgIsOXdjM0xYTkE0VEVCc1h5S3RvTEU5bXJiREQ3V01IWHZYckNqWnZhYkxBc2kFByRtYXRjaDAJAJYKBAAAAIDh6xcAgOiSJgCAhK9fAwkAAAICLDNWdVY1V1RtRHo0N0RtZG4zUXBjWWp6YlNkaXBqUUU0Sk1kTmUxeFpwWDEzBQckbWF0Y2gwCQCWCgQAAACAwtcvAIDokiYAgIjevgEJAJYKBAAAAIDaxAkAgOiSJgCA6JImAAZTY2FsZTgAgMLXLwAHU2NhbGUxMACAyK+gJQAHU2NhbGUxNgkAaAIFBlNjYWxlOAUGU2NhbGU4AAlkYXlCbG9ja3MAoAsBCmxpSW50VG9TdHIBAmxpCgEBZgIFYWNjdW0EbmV4dAkArAICCQCsAgIFBWFjY3VtCQCkAwEFBG5leHQCASwKAAIkbAUCbGkKAAIkcwkAkAMBBQIkbAoABSRhY2MwAgAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEyCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAQ10cnlHZXRJbnRlZ2VyAQNrZXkEByRtYXRjaDAJAJoIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACA0ludAQBYgUHJG1hdGNoMAUBYgAAAQ10cnlHZXRCb29sZWFuAQNrZXkEByRtYXRjaDAJAJsIAgUEdGhpcwUDa2V5AwkAAQIFByRtYXRjaDACB0Jvb2xlYW4EAWIFByRtYXRjaDAFAWIHAQx0cnlHZXRTdHJpbmcBA2tleQQHJG1hdGNoMAkAnQgCBQR0aGlzBQNrZXkDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFiBQckbWF0Y2gwBQFiAgABDHRyeUdldEJpbmFyeQEDa2V5BAckbWF0Y2gwCQCcCAIFBHRoaXMFA2tleQMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAFiBQckbWF0Y2gwBQFiAQABDmdldEFzc2V0U3RyaW5nAQdhc3NldElkBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAWIFByRtYXRjaDAJANgEAQUBYgIFV0FWRVMBDWdldEFzc2V0Qnl0ZXMBCmFzc2V0SWRTdHIDCQAAAgUKYXNzZXRJZFN0cgIFV0FWRVMFBHVuaXQJANkEAQUKYXNzZXRJZFN0cgEKZ2V0QmFsYW5jZQEKYXNzZXRJZFN0cgMJAAACBQphc3NldElkU3RyAgVXQVZFUwgJAO8HAQUEdGhpcwlhdmFpbGFibGUJAPAHAgUEdGhpcwkA2QQBBQphc3NldElkU3RyAQ9nZXRNYXJrZXRBc3NldHMACQC1CQIJAQx0cnlHZXRTdHJpbmcBAgxzZXR1cF90b2tlbnMCASwBEmdldEFzc2V0c01heFN1cHBseQAEAXMJAQx0cnlHZXRTdHJpbmcBAg9zZXR1cF9tYXhTdXBwbHkDCQAAAgUBcwIACQDMCAIA////////////AQkAzAgCAP///////////wEJAMwIAgD///////////8BCQDMCAIA////////////AQkAzAgCAP///////////wEJAMwIAgD///////////8BCQDMCAIA////////////AQUDbmlsCQC1CQIFAXMCASwBDWdldE91dGRhdGVkVXIBCmFzc2V0SWRTdHIEBGRvd24JAGsDCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYXNzZXRJZFN0cgIGX3NSYXRlBQdTY2FsZTE2AwkAAAIFBGRvd24AAAAACQBrAwUGU2NhbGU4CQBrAwkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFzc2V0SWRTdHICBl9iUmF0ZQUHU2NhbGUxNgUEZG93bgELZ2V0SW50ZXJlc3QBCmFzc2V0SWRTdHIEAnVyCQENZ2V0T3V0ZGF0ZWRVcgEFCmFzc2V0SWRTdHIEBWN1cnZlCQEMZ2V0UmF0ZUN1cnZlAQUKYXNzZXRJZFN0cgQEcmF0ZQkAZAIIBQVjdXJ2ZQJfMQMJAGcCCAUFY3VydmUCXzMFAnVyCQBrAwUCdXIIBQVjdXJ2ZQJfMggFBWN1cnZlAl8zCQBkAggFBWN1cnZlAl8yCQBrAwkAZQIFAnVyCAUFY3VydmUCXzMIBQVjdXJ2ZQJfNAkAZQIAgMLXLwgFBWN1cnZlAl8zCQCWAwEJAMwIAgkAawMFBHJhdGUFBlNjYWxlOAkAaAIFCWRheUJsb2NrcwDtAgkAzAgCAAEFA25pbAEQdG9rZW5SYXRlc1JlY2FsYwEKYXNzZXRJZFN0cgQIaW50ZXJlc3QJAQtnZXRJbnRlcmVzdAEFCmFzc2V0SWRTdHIEAnVyCQENZ2V0T3V0ZGF0ZWRVcgEFCmFzc2V0SWRTdHIEEGxhc3RSZWNhbGNIZWlnaHQJAQ10cnlHZXRJbnRlZ2VyAQIObGFzdFJhdGVIZWlnaHQECWxhc3RCUmF0ZQkAlgMBCQDMCAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICBQphc3NldElkU3RyAgZfYlJhdGUJAMwIAgUHU2NhbGUxNgUDbmlsBAhuZXdCUmF0ZQkAZAIFCWxhc3RCUmF0ZQkAaAIJAGUCBQZoZWlnaHQFEGxhc3RSZWNhbGNIZWlnaHQFCGludGVyZXN0BAlsYXN0U1JhdGUJAJYDAQkAzAgCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYXNzZXRJZFN0cgIGX3NSYXRlCQDMCAIFB1NjYWxlMTYFA25pbAQIbmV3U1JhdGUJAGQCBQlsYXN0U1JhdGUJAGkCCQBoAgkAaAIJAGUCBQZoZWlnaHQFEGxhc3RSZWNhbGNIZWlnaHQJAGsDBQhpbnRlcmVzdAUCdXIFBlNjYWxlOAkAZQIAZAULcmVzZXJ2ZUZ1bmQAZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQphc3NldElkU3RyAgZfc1JhdGUFCG5ld1NSYXRlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCmFzc2V0SWRTdHICBl9iUmF0ZQUIbmV3QlJhdGUJAMwIAgkBDEludGVnZXJFbnRyeQICDmxhc3RSYXRlSGVpZ2h0BQZoZWlnaHQFA25pbAENZ2V0QWN0dWFsUmF0ZQIKYXNzZXRJZFN0cghyYXRlVHlwZQoBAWYCBWFjY3VtBXRva2VuBAZyZWNhbGMJARB0b2tlblJhdGVzUmVjYWxjAQUFdG9rZW4JAJQKAgMJAQIhPQIFBXRva2VuBQphc3NldElkU3RyCAUFYWNjdW0CXzEDCQAAAgUIcmF0ZVR5cGUCBXNSYXRlCAkAkQMCBQZyZWNhbGMAAAV2YWx1ZQgJAJEDAgUGcmVjYWxjAAEFdmFsdWUJAM4IAggFBWFjY3VtAl8yBQZyZWNhbGMKAAIkbAkBD2dldE1hcmtldEFzc2V0cwAKAAIkcwkAkAMBBQIkbAoABSRhY2MwCQCUCgIAAAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFmAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAEFZ2V0VXIBCmFzc2V0SWRTdHIEBXJhdGVzCQEQdG9rZW5SYXRlc1JlY2FsYwEFCmFzc2V0SWRTdHIEBGRvd24JAGsDCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyCAkAkQMCBQVyYXRlcwAABXZhbHVlBQdTY2FsZTE2CQBrAwUGU2NhbGU4CQBrAwkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX2JvcnJvd2VkXwUKYXNzZXRJZFN0cggJAJEDAgUFcmF0ZXMAAQV2YWx1ZQUHU2NhbGUxNgUEZG93bgELcmF0ZXNSZWNhbGMACgEBZgIFYWNjdW0FdG9rZW4JAM4IAgUFYWNjdW0JARB0b2tlblJhdGVzUmVjYWxjAQUFdG9rZW4KAAIkbAkBD2dldE1hcmtldEFzc2V0cwAKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBAWYCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDEyCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMARVnZXRUb2tlblByaWNlV2l0aFJpc2sCCmFzc2V0SWRTdHIMcmlza0F2ZXJzaXR5AwMJAAACBQphc3NldElkU3RyAiw5d2MzTFhOQTRURUJzWHlLdG9MRTltcmJERDdXTUhYdlhyQ2padmFiTEFzaQYJAAACBQphc3NldElkU3RyAixIR2dhYlRxVVM4V3RWRlVKemZtclRETWdFY2NKdVpMQlBoRmdRRnh2bnNvVwkAlAoCAMCEPQDAhD0EBXByaWNlCQERQGV4dHJOYXRpdmUoMTA1MCkCCQEHQWRkcmVzcwEBGgFXSWbQy/OK9Vd6rfwhb3HFW4mIK9CBs7F/CQCsAgIFCmFzc2V0SWRTdHICB190d2FwNUIECXJpc2tMZXZlbAkBEUBleHRyTmF0aXZlKDEwNTApAgkBB0FkZHJlc3MBARoBV0lm0MvzivVXeq38IW9xxVuJiCvQgbOxfwkArAICBQphc3NldElkU3RyAgpfcmlza0xldmVsAwkAZwIFDHJpc2tBdmVyc2l0eQUJcmlza0xldmVsCQCUCgIFBXByaWNlBQVwcmljZQkAAgEJAKwCAgkArAICAhtvcmFjbGUgcHJpY2VzIGRvbid0IG1hdGNoOiAJAKQDAQUFcHJpY2UCIyBpcyB0aGUgcHJpY2UsIGJ1dCByaXNrIGlzIHRvbyBoaWdoAQ1nZXRUb2tlblByaWNlAQphc3NldElkU3RyCQEVZ2V0VG9rZW5QcmljZVdpdGhSaXNrAgUKYXNzZXRJZFN0cgADAQ5jYWxjQXNzZXRTY2FsZQEKYXNzZXRJZFN0cgQIZGVjaW1hbHMDCQAAAgUKYXNzZXRJZFN0cgIFV0FWRVMACAgJAQV2YWx1ZQEJAOwHAQkA2QQBBQphc3NldElkU3RyCGRlY2ltYWxzCQBsBgAKAAAFCGRlY2ltYWxzAAAAAAUERE9XTgESY2FsY1VzZXJDb2xsYXRlcmFsAQdhZGRyZXNzBBR1c2VyQ29sbGF0ZXJhbEludm9rZQkA/AcEBQR0aGlzAhFnZXRVc2VyQ29sbGF0ZXJhbAkAzAgCBwkAzAgCBQdhZGRyZXNzCQDMCAIGCQDMCAICAAUDbmlsBQNuaWwDCQAAAgUUdXNlckNvbGxhdGVyYWxJbnZva2UFFHVzZXJDb2xsYXRlcmFsSW52b2tlBBN1c2VyQ29sbGF0ZXJhbFZhbHVlBAckbWF0Y2gwBRR1c2VyQ29sbGF0ZXJhbEludm9rZQMJAAECBQckbWF0Y2gwAgNJbnQEAXgFByRtYXRjaDAFAXgJAAIBAiRpc3N1ZSB3aGlsZSBkb2luZyBpbi1kYXBwIGludm9jYXRpb24DCQAAAgUTdXNlckNvbGxhdGVyYWxWYWx1ZQUTdXNlckNvbGxhdGVyYWxWYWx1ZQUTdXNlckNvbGxhdGVyYWxWYWx1ZQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLhkBaQEGc3VwcGx5AAMJAQEhAQkBDXRyeUdldEJvb2xlYW4BAgxzZXR1cF9hY3RpdmUJAAIBAhFtYXJrZXQgaXMgc3RvcHBlZAMDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEGCQAAAggJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQAAAkAAgECHDEgcGF5bWVudCBoYXMgdG8gYmUgYXR0YWNoZWQECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQLYXNzZXRBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BAskdDA4MjcwODMzNwkBDWdldEFjdHVhbFJhdGUCBQphc3NldElkU3RyAgVzUmF0ZQQFc1JhdGUIBQskdDA4MjcwODMzNwJfMQQRcmF0ZXNSZWNhbGNSZXN1bHQIBQskdDA4MjcwODMzNwJfMgQGYW1vdW50CQBuBAULYXNzZXRBbW91bnQFB1NjYWxlMTYFBXNSYXRlBQRET1dOBAdhZGRyZXNzCQClCAEIBQFpBmNhbGxlcgQJbWF4U3VwcGx5BAckbWF0Y2gwCQCiCAEJAKwCAgIQc2V0dXBfbWF4U3VwcGx5XwUKYXNzZXRJZFN0cgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXgFByRtYXRjaDAJAQ1wYXJzZUludFZhbHVlAQUBeAkBDXRyeUdldEludGVnZXIBCQCsAgICEHNldHVwX21heFN1cHBseV8FCmFzc2V0SWRTdHIECmFzc2V0UHJpY2UJAQ1nZXRUb2tlblByaWNlAQUKYXNzZXRJZFN0cgQQbmV3VG90YWxTdXBwbGllZAkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9zdXBwbGllZF8FCmFzc2V0SWRTdHIFBmFtb3VudAQEcmF0ZQgJAQ1nZXRBY3R1YWxSYXRlAgUKYXNzZXRJZFN0cgIFc1JhdGUCXzEECmFzc2V0U2NhbGUJAQ5jYWxjQXNzZXRTY2FsZQEFCmFzc2V0SWRTdHIEE25ld1RvdGFsU3VwcGxpZWRVc2QJAGsDCQBrAwUQbmV3VG90YWxTdXBwbGllZAUEcmF0ZQUHU2NhbGUxNggFCmFzc2V0UHJpY2UCXzEFCmFzc2V0U2NhbGUDCQAAAgkAswkCCQEMdHJ5R2V0U3RyaW5nAQIMc2V0dXBfdG9rZW5zBQphc3NldElkU3RyBQR1bml0CQACAQIpdGhpcyBhc3NldCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBtYXJrZXQDAwkBAiE9AgUJbWF4U3VwcGx5AAAJAGYCBRNuZXdUb3RhbFN1cHBsaWVkVXNkBQltYXhTdXBwbHkHCQACAQIzbWF4IHRvdGFsIHN1cHBseSBmb3IgdGhpcyB0b2tlbiByZWFjaGVkIGluIHRoZSBwb29sAwkAZgIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg1zZXR1cF9wYXVzZWRfBQphc3NldElkU3RyAAAJAAIBAih0aGlzIGFzc2V0IGNhbid0IGJlIHN1cHBsaWVkIG9yIGJvcnJvd2VkCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQphc3NldElkU3RyBRBuZXdUb3RhbFN1cHBsaWVkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgkAZAIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIFBmFtb3VudAUDbmlsBRFyYXRlc1JlY2FsY1Jlc3VsdAFpAQh3aXRoZHJhdwIKYXNzZXRJZFN0cgthc3NldEFtb3VudAQLJHQwOTc2MTk4MjgJAQ1nZXRBY3R1YWxSYXRlAgUKYXNzZXRJZFN0cgIFc1JhdGUEBXNSYXRlCAULJHQwOTc2MTk4MjgCXzEEEXJhdGVzUmVjYWxjUmVzdWx0CAULJHQwOTc2MTk4MjgCXzIEBmFtb3VudAkAbgQFC2Fzc2V0QW1vdW50BQdTY2FsZTE2BQVzUmF0ZQUHQ0VJTElORwQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEDWFzc2V0U3VwcGxpZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIEDWFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIEEXVzZXJBc3NldFN1cHBsaWVkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQphc3NldElkU3RyBBF1c2VyQXNzZXRCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgQSY29sbGF0ZXJhbFZhbHVlSW52CQD8BwQFBHRoaXMCEWdldFVzZXJDb2xsYXRlcmFsCQDMCAIHCQDMCAIFB2FkZHJlc3MJAMwIAgYJAMwIAgkArAICCQCsAgIFCmFzc2V0SWRTdHICCixzdXBwbGllZCwJAKQDAQkBAS0BBQZhbW91bnQFA25pbAUDbmlsAwkAAAIFEmNvbGxhdGVyYWxWYWx1ZUludgUSY29sbGF0ZXJhbFZhbHVlSW52BA9jb2xsYXRlcmFsVmFsdWUEByRtYXRjaDAFEmNvbGxhdGVyYWxWYWx1ZUludgMJAAECBQckbWF0Y2gwAgNJbnQEAXgFByRtYXRjaDAFAXgJAAIBAh9jYW4ndCBnZXQgdXNlciBjb2xsYXRlcmFsIHZhbHVlAwkBASEBCQENdHJ5R2V0Qm9vbGVhbgECDHNldHVwX2FjdGl2ZQkAAgECEW1hcmtldCBpcyBzdG9wcGVkAwkAZgIAAAUPY29sbGF0ZXJhbFZhbHVlCQACAQIyeW91IGRvbnQgaGF2ZSBlbm91Z2ggY29sbGF0ZXJhbCBmb3IgdGhpcyBvcGVyYXRpb24DCQBmAgUGYW1vdW50CQBlAgUNYXNzZXRTdXBwbGllZAUNYXNzZXRCb3Jyb3dlZAkAAgECKnRoaXMgYW1vdW50IGlzIG5vdCBhdmFpbGFibGUgb24gdGhlIG1hcmtldAMJAGYCBQZhbW91bnQJAGUCBRF1c2VyQXNzZXRTdXBwbGllZAURdXNlckFzc2V0Qm9ycm93ZWQJAAIBAip0aGlzIGFtb3VudCBpcyBub3QgYXZhaWxhYmxlIGZvciB0aGlzIHVzZXIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIFB2FkZHJlc3MCCl9zdXBwbGllZF8FCmFzc2V0SWRTdHIJAGUCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQphc3NldElkU3RyBQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyCQBlAgkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgUGYW1vdW50CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgULYXNzZXRBbW91bnQJAQ1nZXRBc3NldEJ5dGVzAQUKYXNzZXRJZFN0cgUDbmlsBRFyYXRlc1JlY2FsY1Jlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQZib3Jyb3cCCmFzc2V0SWRTdHILYXNzZXRBbW91bnQEB2FkZHJlc3MJAKUIAQgFAWkGY2FsbGVyBA0kdDAxMTQwMDExNDY3CQENZ2V0QWN0dWFsUmF0ZQIFCmFzc2V0SWRTdHICBWJSYXRlBAViUmF0ZQgFDSR0MDExNDAwMTE0NjcCXzEEEXJhdGVzUmVjYWxjUmVzdWx0CAUNJHQwMTE0MDAxMTQ2NwJfMgQGYW1vdW50CQBuBAULYXNzZXRBbW91bnQFB1NjYWxlMTYFBWJSYXRlBQdDRUlMSU5HBBJjb2xsYXRlcmFsVmFsdWVJbnYJAPwHBAUEdGhpcwIRZ2V0VXNlckNvbGxhdGVyYWwJAMwIAgcJAMwIAgUHYWRkcmVzcwkAzAgCBgkAzAgCCQCsAgIJAKwCAgUKYXNzZXRJZFN0cgIKLGJvcnJvd2VkLAkApAMBBQZhbW91bnQFA25pbAUDbmlsAwkAAAIFEmNvbGxhdGVyYWxWYWx1ZUludgUSY29sbGF0ZXJhbFZhbHVlSW52BA9jb2xsYXRlcmFsVmFsdWUEByRtYXRjaDAFEmNvbGxhdGVyYWxWYWx1ZUludgMJAAECBQckbWF0Y2gwAgNJbnQEAXgFByRtYXRjaDAFAXgJAAIBAh9jYW4ndCBnZXQgdXNlciBjb2xsYXRlcmFsIHZhbHVlAwkBASEBCQENdHJ5R2V0Qm9vbGVhbgECDHNldHVwX2FjdGl2ZQkAAgECEW1hcmtldCBpcyBzdG9wcGVkAwkAZgIAAAUPY29sbGF0ZXJhbFZhbHVlCQACAQIheW91IGhhdmUgdG8gc3VwcGx5IG1vcmUgdG8gYm9ycm93AwkAZgIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg1zZXR1cF9wYXVzZWRfBQphc3NldElkU3RyAAAJAAIBAih0aGlzIGFzc2V0IGNhbid0IGJlIHN1cHBsaWVkIG9yIGJvcnJvd2VkBA1hc3NldFN1cHBsaWVkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQphc3NldElkU3RyBA1hc3NldEJvcnJvd2VkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQphc3NldElkU3RyBBF1c2VyQXNzZXRCb3Jyb3dlZAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgMJAGYCBQZhbW91bnQJAGUCBQ1hc3NldFN1cHBsaWVkBQ1hc3NldEJvcnJvd2VkCQACAQIcdGhpcyBhbW91bnQgaXMgbm90IGF2YWlsYWJsZQkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwUKYXNzZXRJZFN0cgkAZAIFEXVzZXJBc3NldEJvcnJvd2VkBQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQphc3NldElkU3RyCQBkAgUNYXNzZXRCb3Jyb3dlZAUGYW1vdW50CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgULYXNzZXRBbW91bnQJAQ1nZXRBc3NldEJ5dGVzAQUKYXNzZXRJZFN0cgUDbmlsBRFyYXRlc1JlY2FsY1Jlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQVyZXBheQADCQEBIQEJAQ10cnlHZXRCb29sZWFuAQIMc2V0dXBfYWN0aXZlCQACAQIRbWFya2V0IGlzIHN0b3BwZWQDAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABBgkAAAIICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50AAAJAAIBAhwxIHBheW1lbnQgaGFzIHRvIGJlIGF0dGFjaGVkBAphc3NldElkU3RyCQEOZ2V0QXNzZXRTdHJpbmcBCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQEC2Fzc2V0QW1vdW50CAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQNJHQwMTMxNTUxMzIyMgkBDWdldEFjdHVhbFJhdGUCBQphc3NldElkU3RyAgViUmF0ZQQFYlJhdGUIBQ0kdDAxMzE1NTEzMjIyAl8xBBFyYXRlc1JlY2FsY1Jlc3VsdAgFDSR0MDEzMTU1MTMyMjICXzIEBmFtb3VudAkAbgQFC2Fzc2V0QW1vdW50BQdTY2FsZTE2BQViUmF0ZQUHQ0VJTElORwQHYWRkcmVzcwkApQgBCAUBaQZjYWxsZXIEDWFzc2V0U3VwcGxpZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIEDWFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIEEXVzZXJBc3NldEJvcnJvd2VkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQphc3NldElkU3RyBAphbW91bnRMZWZ0CQBlAgURdXNlckFzc2V0Qm9ycm93ZWQFBmFtb3VudAQLcmVwYXlBbW91bnQDCQBnAgUKYW1vdW50TGVmdAAABQZhbW91bnQFEXVzZXJBc3NldEJvcnJvd2VkAwkAAAIJALMJAgkBDHRyeUdldFN0cmluZwECDHNldHVwX3Rva2VucwUKYXNzZXRJZFN0cgUEdW5pdAkAAgECKXRoaXMgYXNzZXQgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgbWFya2V0CQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIJAGUCBRF1c2VyQXNzZXRCb3Jyb3dlZAULcmVwYXlBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQphc3NldElkU3RyCQBlAgUNYXNzZXRCb3Jyb3dlZAULcmVwYXlBbW91bnQFA25pbAURcmF0ZXNSZWNhbGNSZXN1bHQDCQBnAgUKYW1vdW50TGVmdAAABQNuaWwJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyCQEBLQEFCmFtb3VudExlZnQICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAUDbmlsAWkBCHJlcGF5Rm9yAQdhZGRyZXNzAwkBASEBCQENdHJ5R2V0Qm9vbGVhbgECDHNldHVwX2FjdGl2ZQkAAgECEW1hcmtldCBpcyBzdG9wcGVkAwkBAiE9AggFAWkGY2FsbGVyCQEHQWRkcmVzcwEBGgFXHuH7QDFrgebsS1YbBSxRoZNu3wmxPNLBCQACAQInYXZhaWxhYmxlIG9ubHkgZm9yIHJlc2VydmUgZnVuZCBhZGRyZXNzAwkAAAIFB2FkZHJlc3MCBmdsb2JhbAkAAgECIHlvdSBjYW4ndCByZXBheSBmb3IgZXZlcnlvbmUgOl8pAwMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQYJAAACCAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAAACQACAQIcMSBwYXltZW50IGhhcyB0byBiZSBhdHRhY2hlZAQKYXNzZXRJZFN0cgkBDmdldEFzc2V0U3RyaW5nAQgJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBAthc3NldEFtb3VudAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQEDSR0MDE0ODE5MTQ4ODYJAQ1nZXRBY3R1YWxSYXRlAgUKYXNzZXRJZFN0cgIFYlJhdGUEBWJSYXRlCAUNJHQwMTQ4MTkxNDg4NgJfMQQRcmF0ZXNSZWNhbGNSZXN1bHQIBQ0kdDAxNDgxOTE0ODg2Al8yBAZhbW91bnQJAG4EBQthc3NldEFtb3VudAUHU2NhbGUxNgUFYlJhdGUFB0NFSUxJTkcEDWFzc2V0U3VwcGxpZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIEDWFzc2V0Qm9ycm93ZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIEEXVzZXJBc3NldEJvcnJvd2VkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfBQphc3NldElkU3RyBAphbW91bnRMZWZ0CQBlAgURdXNlckFzc2V0Qm9ycm93ZWQFBmFtb3VudAQLcmVwYXlBbW91bnQDCQBnAgUKYW1vdW50TGVmdAAABQZhbW91bnQFEXVzZXJBc3NldEJvcnJvd2VkAwkAAAIJALMJAgkBDHRyeUdldFN0cmluZwECDHNldHVwX3Rva2VucwUKYXNzZXRJZFN0cgUEdW5pdAkAAgECKXRoaXMgYXNzZXQgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgbWFya2V0CQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FCmFzc2V0SWRTdHIJAGUCBRF1c2VyQXNzZXRCb3Jyb3dlZAULcmVwYXlBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQphc3NldElkU3RyCQBlAgUNYXNzZXRCb3Jyb3dlZAULcmVwYXlBbW91bnQFA25pbAURcmF0ZXNSZWNhbGNSZXN1bHQDCQBnAgUKYW1vdW50TGVmdAAABQNuaWwJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyCQEBLQEFCmFtb3VudExlZnQICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAUDbmlsAWkBDXN0YWtlVG9rZW5BbGwBCmFzc2V0SWRTdHIDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAAIBAixvbmx5IGZvciBpbnRlcm5hbCBzbWFydCBjb250cmFjdCBpbnZvY2F0aW9ucwQGYW1vdW50CQEKZ2V0QmFsYW5jZQEFCmFzc2V0SWRTdHIEA2ludgkA/AcEBQR0aGlzAgpzdGFrZVRva2VuCQDMCAIFCmFzc2V0SWRTdHIJAMwIAgUGYW1vdW50BQNuaWwFA25pbAMJAAACBQNpbnYFA2ludgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCnN0YWtlVG9rZW4CCmFzc2V0SWRTdHIGYW1vdW50AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIsb25seSBmb3IgaW50ZXJuYWwgc21hcnQgY29udHJhY3QgaW52b2NhdGlvbnMDCQAAAgUKYXNzZXRJZFN0cgIsREcyeEZrUGREd0tVb0JrekdBaFF0THBTR3pmWExpQ1lQRXplS0gyQWQyNHAEDGFtb3VudFN0YWtlZAkBDXRyeUdldEludGVnZXIBAj1hdXRvc3Rha2VfYW1vdW50X0RHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwBANpbnYJAPwHBAkBB0FkZHJlc3MBARoBV+QOpzZPkgvXl8+kHT81G89DauuqPPNxnQIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgEgtiYpwwT1zlORpA5LdSQvZIxRsfrfr1QpvUjSHSqyqtEFBmFtb3VudAUDbmlsAwkAAAIFA2ludgUDaW52CQDMCAIJAQxJbnRlZ2VyRW50cnkCAj1hdXRvc3Rha2VfYW1vdW50X0RHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwCQBkAgUMYW1vdW50U3Rha2VkBQZhbW91bnQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgMJAAACBQphc3NldElkU3RyAiw4dDREUFdUd1B6cGF0SEE5QWtUeFdBQjQ3VEhuWXpCc0Rub1k3ZlFxYkc5MQQMYW1vdW50U3Rha2VkCQENdHJ5R2V0SW50ZWdlcgECPWF1dG9zdGFrZV9hbW91bnRfOHQ0RFBXVHdQenBhdEhBOUFrVHhXQUI0N1RIbll6QnNEbm9ZN2ZRcWJHOTEEA2ludgkA/AcECQEHQWRkcmVzcwEBGgFX9xU1EcXtcoVTVBDw3RtN4mo807RodylaAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCASB1FhA4gHYNVWV+SfOusdvmGZxqEGgfyVVh+kpGWncwHAUGYW1vdW50BQNuaWwDCQAAAgUDaW52BQNpbnYJAMwIAgkBDEludGVnZXJFbnRyeQICPWF1dG9zdGFrZV9hbW91bnRfOHQ0RFBXVHdQenBhdEhBOUFrVHhXQUI0N1RIbll6QnNEbm9ZN2ZRcWJHOTEJAGQCBQxhbW91bnRTdGFrZWQFBmFtb3VudAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAwkAAAIFCmFzc2V0SWRTdHICLEF0OEQ2TkZGcGhlQ2J2S1ZualZvZUxMODRFbzhOWm42b3ZNYW54ZkxhRldMBAxhbW91bnRTdGFrZWQJAQ10cnlHZXRJbnRlZ2VyAQI9YXV0b3N0YWtlX2Ftb3VudF9BdDhENk5GRnBoZUNidktWbmpWb2VMTDg0RW84TlpuNm92TWFueGZMYUZXTAQDaW52CQD8BwQJAQdBZGRyZXNzAQEaAVdraDjhA9SajJ8SG8YsvCMHOQvN7RLXCl8CBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIBIJLR9EriEQEr9H7q3iGOPcX7yfJ9zoey7VIZ8DpOJFj1BQZhbW91bnQFA25pbAMJAAACBQNpbnYFA2ludgkAzAgCCQEMSW50ZWdlckVudHJ5AgI9YXV0b3N0YWtlX2Ftb3VudF9BdDhENk5GRnBoZUNidktWbmpWb2VMTDg0RW84TlpuNm92TWFueGZMYUZXTAkAZAIFDGFtb3VudFN0YWtlZAUGYW1vdW50BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAFpAQx1bnN0YWtlVG9rZW4CCmFzc2V0SWRTdHIGYW1vdW50AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIsb25seSBmb3IgaW50ZXJuYWwgc21hcnQgY29udHJhY3QgaW52b2NhdGlvbnMDCQAAAgUKYXNzZXRJZFN0cgIsOHQ0RFBXVHdQenBhdEhBOUFrVHhXQUI0N1RIbll6QnNEbm9ZN2ZRcWJHOTEEDGFtb3VudFN0YWtlZAkBDXRyeUdldEludGVnZXIBAj1hdXRvc3Rha2VfYW1vdW50Xzh0NERQV1R3UHpwYXRIQTlBa1R4V0FCNDdUSG5ZekJzRG5vWTdmUXFiRzkxBANpbnYJAPwHBAkBB0FkZHJlc3MBARoBV/cVNRHF7XKFU1QQ8N0bTeJqPNO0aHcpWgIHdW5TdGFrZQkAzAgCBQZhbW91bnQFA25pbAUDbmlsAwkAAAIFA2ludgUDaW52CQDMCAIJAQxJbnRlZ2VyRW50cnkCAj1hdXRvc3Rha2VfYW1vdW50Xzh0NERQV1R3UHpwYXRIQTlBa1R4V0FCNDdUSG5ZekJzRG5vWTdmUXFiRzkxCQBlAgUMYW1vdW50U3Rha2VkBQZhbW91bnQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgMJAAACBQphc3NldElkU3RyAixBdDhENk5GRnBoZUNidktWbmpWb2VMTDg0RW84TlpuNm92TWFueGZMYUZXTAQMYW1vdW50U3Rha2VkCQENdHJ5R2V0SW50ZWdlcgECPWF1dG9zdGFrZV9hbW91bnRfQXQ4RDZORkZwaGVDYnZLVm5qVm9lTEw4NEVvOE5abjZvdk1hbnhmTGFGV0wEA2ludgkA/AcECQEHQWRkcmVzcwEBGgFXa2g44QPUmoyfEhvGLLwjBzkLze0S1wpfAgd1bnN0YWtlCQDMCAIFBmFtb3VudAUDbmlsBQNuaWwDCQAAAgUDaW52BQNpbnYEBGJhbDAJAQpnZXRCYWxhbmNlAQIsQXQ4RDZORkZwaGVDYnZLVm5qVm9lTEw4NEVvOE5abjZvdk1hbnhmTGFGV0wDCQAAAgUEYmFsMAUEYmFsMAQEaW52MgkA/AcECQEHQWRkcmVzcwEBGgFX+3Xq6xP9GcDLCNyPYLN+A7oRjq2Pt9DrAhdnbnNidFJld2FyZHNTWVNSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAAIFBGludjIFBGludjIEDHRvcHVwUmV3YXJkcwQHJG1hdGNoMAUEaW52MgMJAAECBQckbWF0Y2gwAglMaXN0W0FueV0EAXgFByRtYXRjaDAECHNlY29uZEVsCQCRAwIFAXgAAQQHJG1hdGNoMQUIc2Vjb25kRWwDCQABAgUHJG1hdGNoMQIGU3RyaW5nBAhzZWNvbmRFbAUHJG1hdGNoMQQJdXNkblZhbHVlCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgkAtQkCCQCRAwIJALUJAgUIc2Vjb25kRWwCAV8AAQIBOgABBAp3YXZlc1ZhbHVlCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgkAtQkCCQCRAwIJALUJAgUIc2Vjb25kRWwCAV8AAAIBOgABAwMJAQIhPQIFCXVzZG5WYWx1ZQAABgkBAiE9AgUKd2F2ZXNWYWx1ZQAABAh1c2RuQmFsMAkBCmdldEJhbGFuY2UBAixERzJ4RmtQZER3S1VvQmt6R0FoUXRMcFNHemZYTGlDWVBFemVLSDJBZDI0cAMJAAACBQh1c2RuQmFsMAUIdXNkbkJhbDAECXdhdmVzQmFsMAkBCmdldEJhbGFuY2UBAgVXQVZFUwMJAAACBQl3YXZlc0JhbDAFCXdhdmVzQmFsMAQEaW52MwkA/AcECQEHQWRkcmVzcwEBGgFXa2g44QPUmoyfEhvGLLwjBzkLze0S1wpfAgxjbGFpbVJld2FyZHMFA25pbAUDbmlsAwkAAAIFBGludjMFBGludjMECXdhdmVzQmFsMQkBCmdldEJhbGFuY2UBAgVXQVZFUwMJAAACBQl3YXZlc0JhbDEFCXdhdmVzQmFsMQQEaW52NAkA/AcECQEHQWRkcmVzcwEBGgFXzhQUnRZYA+RDTHr1peyyn62/zbOD+SmiAgRzd2FwCQDMCAICLERHMnhGa1BkRHdLVW9Ca3pHQWhRdExwU0d6ZlhMaUNZUEV6ZUtIMkFkMjRwCQDMCAIAAAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQR1bml0CQBlAgUJd2F2ZXNCYWwxBQl3YXZlc0JhbDAFA25pbAMJAAACBQRpbnY0BQRpbnY0BAh1c2RuQmFsMQkBCmdldEJhbGFuY2UBAixERzJ4RmtQZER3S1VvQmt6R0FoUXRMcFNHemZYTGlDWVBFemVLSDJBZDI0cAMJAAACBQh1c2RuQmFsMQUIdXNkbkJhbDEEBGludjUJAPwHBAkBB0FkZHJlc3MBARoBV0DqoVxlgSg9dIRbV2Ce++N5K7fcirSQdwIEc3dhcAkAzAgCAixBdDhENk5GRnBoZUNidktWbmpWb2VMTDg0RW84TlpuNm92TWFueGZMYUZXTAkAzAgCAAAFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgEgtiYpwwT1zlORpA5LdSQvZIxRsfrfr1QpvUjSHSqyqtEJAGUCBQh1c2RuQmFsMQUIdXNkbkJhbDAFA25pbAMJAAACBQRpbnY1BQRpbnY1BARpbnY2CQD8BwQFBHRoaXMCC2FkZEludGVyZXN0CQDMCAICLEF0OEQ2TkZGcGhlQ2J2S1ZualZvZUxMODRFbzhOWm42b3ZNYW54ZkxhRldMCQDMCAIJAGUCCQEKZ2V0QmFsYW5jZQECLEF0OEQ2TkZGcGhlQ2J2S1ZualZvZUxMODRFbzhOWm42b3ZNYW54ZkxhRldMBQRiYWwwBQNuaWwFA25pbAMJAAACBQRpbnY2BQRpbnY2AAIJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAQABAAADCQAAAgUMdG9wdXBSZXdhcmRzBQx0b3B1cFJld2FyZHMJAMwIAgkBDEludGVnZXJFbnRyeQICPWF1dG9zdGFrZV9hbW91bnRfQXQ4RDZORkZwaGVDYnZLVm5qVm9lTEw4NEVvOE5abjZvdk1hbnhmTGFGV0wJAGUCBQxhbW91bnRTdGFrZWQFBmFtb3VudAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwBaQELYWRkSW50ZXJlc3QCCmFzc2V0SWRTdHIGYW1vdW50AwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQACAQIYb25seSBmb3Igc2VsZiBpbnZvY2F0aW9uBAZlYXJuZWQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAhVhdXRvc3Rha2VfbGFzdEVhcm5lZF8FCmFzc2V0SWRTdHIECmxhc3RIZWlnaHQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAhRhdXRvc3Rha2VfbGFzdEJsb2NrXwUKYXNzZXRJZFN0cgQLY2xlYW5BbW91bnQJAGsDBQZhbW91bnQAUABkBAxzdGF0ZUNoYW5nZXMDAwkAAAIFCmxhc3RIZWlnaHQFBmhlaWdodAYJAAACBQZhbW91bnQAAAUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICGGF1dG9zdGFrZV9wcmVMYXN0RWFybmVkXwUKYXNzZXRJZFN0cgUGZWFybmVkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICF2F1dG9zdGFrZV9wcmVMYXN0QmxvY2tfBQphc3NldElkU3RyBQpsYXN0SGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICFWF1dG9zdGFrZV9sYXN0RWFybmVkXwUKYXNzZXRJZFN0cgkAZAIFBmVhcm5lZAULY2xlYW5BbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIUYXV0b3N0YWtlX2xhc3RCbG9ja18FCmFzc2V0SWRTdHIFBmhlaWdodAUDbmlsCQDOCAIFDHN0YXRlQ2hhbmdlcwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQphc3NldElkU3RyAgZfc1JhdGUJAGQCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgUKYXNzZXRJZFN0cgIGX3NSYXRlCQBrAwUHU2NhbGUxNgULY2xlYW5BbW91bnQJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9zdXBwbGllZF8FCmFzc2V0SWRTdHIFA25pbAFpARNhZGRJbnRlcmVzdEVYVEVSTkFMAAQGYW1vdW50CQBrAwgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQAUABkBAdhc3NldElkCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQECmFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEFB2Fzc2V0SWQEBmVhcm5lZAkBDXRyeUdldEludGVnZXIBCQCsAgICFWF1dG9zdGFrZV9sYXN0RWFybmVkXwUKYXNzZXRJZFN0cgQKbGFzdEhlaWdodAkBDXRyeUdldEludGVnZXIBCQCsAgICFGF1dG9zdGFrZV9sYXN0QmxvY2tfBQphc3NldElkU3RyBAxzdGF0ZUNoYW5nZXMDAwkAAAIFCmxhc3RIZWlnaHQFBmhlaWdodAYJAAACBQZhbW91bnQAAAUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICGGF1dG9zdGFrZV9wcmVMYXN0RWFybmVkXwUKYXNzZXRJZFN0cgUGZWFybmVkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICF2F1dG9zdGFrZV9wcmVMYXN0QmxvY2tfBQphc3NldElkU3RyBQpsYXN0SGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICFWF1dG9zdGFrZV9sYXN0RWFybmVkXwUKYXNzZXRJZFN0cgkAZAIFBmVhcm5lZAUGYW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICFGF1dG9zdGFrZV9sYXN0QmxvY2tfBQphc3NldElkU3RyBQZoZWlnaHQFA25pbAkAzggCBQxzdGF0ZUNoYW5nZXMJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUKYXNzZXRJZFN0cgIGX3NSYXRlCQBkAgkBDXRyeUdldEludGVnZXIBCQCsAgIFCmFzc2V0SWRTdHICBl9zUmF0ZQkAawMFB1NjYWxlMTYFBmFtb3VudAkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwUKYXNzZXRJZFN0cgUDbmlsAWkBB3ByZUluaXQEBnRva2VucwRsdHZzA2x0cwlwZW5hbHRpZXMKAQFmAgVhY2N1bQV0b2tlbgkAzggCBQVhY2N1bQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQV0b2tlbgIGX2JSYXRlBQdTY2FsZTE2CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBXRva2VuAgZfc1JhdGUFB1NjYWxlMTYFA25pbAMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECCmFkbWluIG9ubHkEBXJhdGVzCgACJGwJALUJAgUGdG9rZW5zAgEsCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQFmAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxMgkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAkAzggCCQDMCAIJAQtTdHJpbmdFbnRyeQICDHNldHVwX3Rva2VucwUGdG9rZW5zCQDMCAIJAQtTdHJpbmdFbnRyeQICCnNldHVwX2x0dnMFBGx0dnMJAMwIAgkBC1N0cmluZ0VudHJ5AgIJc2V0dXBfbHRzBQNsdHMJAMwIAgkBC1N0cmluZ0VudHJ5AgIPc2V0dXBfcGVuYWx0aWVzBQlwZW5hbHRpZXMJAMwIAgkBDEJvb2xlYW5FbnRyeQICDHNldHVwX2FjdGl2ZQYFA25pbAUFcmF0ZXMBaQEMaW5pdE5ld1Rva2VuBAV0b2tlbgNsdHYCbHQHcGVuYWx0eQMJAQIhPQIIBQFpBmNhbGxlcgUEdGhpcwkAAgECCmFkbWluIG9ubHkJAMwIAgkBC1N0cmluZ0VudHJ5AgIMc2V0dXBfdG9rZW5zCQCsAgIJAKwCAgkBDHRyeUdldFN0cmluZwECDHNldHVwX3Rva2VucwIBLAUFdG9rZW4JAMwIAgkBC1N0cmluZ0VudHJ5AgIKc2V0dXBfbHR2cwkArAICCQCsAgIJAQx0cnlHZXRTdHJpbmcBAgpzZXR1cF9sdHZzAgEsBQNsdHYJAMwIAgkBC1N0cmluZ0VudHJ5AgIJc2V0dXBfbHRzCQCsAgIJAKwCAgkBDHRyeUdldFN0cmluZwECCXNldHVwX2x0cwIBLAUCbHQJAMwIAgkBC1N0cmluZ0VudHJ5AgIPc2V0dXBfcGVuYWx0aWVzCQCsAgIJAKwCAgkBDHRyeUdldFN0cmluZwECD3NldHVwX3BlbmFsdGllcwIBLAUHcGVuYWx0eQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQV0b2tlbgIGX2JSYXRlBQdTY2FsZTE2CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBXRva2VuAgZfc1JhdGUFB1NjYWxlMTYFA25pbAFpAQ91cGRhdGVQYXJhbWV0ZXICA2tleQN2YWwDAwkBAiE9AggFAWkGY2FsbGVyBQR0aGlzCQECIT0CCAUBaQZjYWxsZXIJAQdBZGRyZXNzAQEaAVcUeViFwPoaZ+cUNI0M98TwbUXt9hz5PUEHCQACAQIKYWRtaW4gb25seQkAzAgCCQEMSW50ZWdlckVudHJ5AgUDa2V5CQENcGFyc2VJbnRWYWx1ZQEFA3ZhbAUDbmlsAWkBDHVwZGF0ZVN0cmluZwIDa2V5A3ZhbAMDCQECIT0CCAUBaQZjYWxsZXIFBHRoaXMJAQIhPQIIBQFpBmNhbGxlcgkBB0FkZHJlc3MBARoBVxR5WIXA+hpn5xQ0jQz3xPBtRe32HPk9QQcJAAIBAgphZG1pbiBvbmx5CQDMCAIJAQtTdHJpbmdFbnRyeQIFA2tleQUDdmFsBQNuaWwBaQESY2xhaW1Ub1Jlc2VydmVGdW5kAQVkZWJ1ZwQGYXNzZXRzCQEPZ2V0TWFya2V0QXNzZXRzAAQFcmF0ZXMICQENZ2V0QWN0dWFsUmF0ZQIJAJEDAgUGYXNzZXRzAAACBXNSYXRlAl8yBAJsaQkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYJAMwIAgAHCQDMCAIACAkAzAgCAAkJAMwIAgAKCQDMCAIACwUDbmlsCgEBZgIFYWNjdW0BbgMJAGcCBQFuCQCQAwEFBmFzc2V0cwUFYWNjdW0ECmFzc2V0SWRTdHIJAJEDAgUGYXNzZXRzBQFuBA9hdXRvc3Rha2VBbW91bnQJAQx0cnlHZXRTdHJpbmcBCQCsAgICEWF1dG9zdGFrZV9hbW91bnRfBQphc3NldElkU3RyBAZhbW91bnQJAGUCCQBkAgkAZAIJAGQC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qU4AkE4FA25pbAUDbmlsAWkBCHNodXRkb3duAQhzaHV0ZG93bgMJAAACCQDPCAIFEXNodXRkb3duV2hpdGVsaXN0CAgFAWkGY2FsbGVyBWJ5dGVzBQR1bml0CQACAQIXdXNlciBub3QgaW4gYSB3aGl0ZWxpc3QJAMwIAgkBDEJvb2xlYW5FbnRyeQICDHNldHVwX2FjdGl2ZQkBASEBBQhzaHV0ZG93bgUDbmlsAWkBCWxpcXVpZGF0ZQYFZGVidWcHYWRkcmVzcwthc3NldEFtb3VudAtzQXNzZXRJZFN0cgtiQXNzZXRJZFN0cghyb3V0ZVN0cgMJAQEhAQkBFnZlcmlmeUxpcXVpZGF0b3JSaWdodHMBCAUBaQZjYWxsZXIJAAIBAih0ZW1wb3JhcmlseSBhdmFpbGFibGUgZm9yIHdoaXRlbGlzdCBvbmx5AwkBASEBCQENdHJ5R2V0Qm9vbGVhbgECDHNldHVwX2FjdGl2ZQkAAgECEW1hcmtldCBpcyBzdG9wcGVkBA51c2VyQ29sbGF0ZXJhbAkBEmNhbGNVc2VyQ29sbGF0ZXJhbAEFB2FkZHJlc3MDCQAAAgUOdXNlckNvbGxhdGVyYWwFDnVzZXJDb2xsYXRlcmFsBA0kdDAyODM4MjI4NDQ0CQENZ2V0QWN0dWFsUmF0ZQIFC3NBc3NldElkU3RyAgVzUmF0ZQQFc1JhdGUIBQ0kdDAyODM4MjI4NDQ0Al8xBAtyYXRlc1Jlc3VsdAgFDSR0MDI4MzgyMjg0NDQCXzIEDSR0MDI4NDQ5Mjg1MTgJAQ1nZXRBY3R1YWxSYXRlAgULYkFzc2V0SWRTdHICBWJSYXRlBAViUmF0ZQgFDSR0MDI4NDQ5Mjg1MTgCXzEEEnJhdGVzUmVjYWxjUmVzdWx0MggFDSR0MDI4NDQ5Mjg1MTgCXzIEDHNBc3NldEFtb3VudAkAawMFC2Fzc2V0QW1vdW50BQdTY2FsZTE2BQVzUmF0ZQQQY3VycmVudFNQb3NpdGlvbgkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX3N1cHBsaWVkXwULc0Fzc2V0SWRTdHIEE2N1cnJlbnRCUG9zaXRpb25WYWwJAQ10cnlHZXRJbnRlZ2VyAQkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FC2JBc3NldElkU3RyBBBjdXJyZW50QlBvc2l0aW9uAwkAZgIFE2N1cnJlbnRCUG9zaXRpb25WYWwAAAUTY3VycmVudEJQb3NpdGlvblZhbAkAAgECIHVzZXIgaGFzIG5vIGJvcnJvdyBpbiB0aGlzIHRva2VuAwkAZgIFDnVzZXJDb2xsYXRlcmFsAAAJAAIBAhh1c2VyIGNhbid0IGJlIGxpcXVpZGF0ZWQDCQBmAgUMc0Fzc2V0QW1vdW50BRBjdXJyZW50U1Bvc2l0aW9uCQACAQIycG9zaXRpb24gdG8gbGlxdWlkYXRlIGlzIGJpZ2dlciB0aGFuIHVzZXIncyBzdXBwbHkEDmJhbGFuY2UwQmVmb3JlCQEKZ2V0QmFsYW5jZQEFC3NBc3NldElkU3RyAwkAAAIFDmJhbGFuY2UwQmVmb3JlBQ5iYWxhbmNlMEJlZm9yZQQOYmFsYW5jZTFCZWZvcmUJAQpnZXRCYWxhbmNlAQULYkFzc2V0SWRTdHIDCQAAAgUOYmFsYW5jZTFCZWZvcmUFDmJhbGFuY2UxQmVmb3JlBA5leGNoYW5nZUludm9rZQkA/AcEBRFhZ2dyZWdhdG9yQWRkcmVzcwIEc3dhcAkAzAgCBQhyb3V0ZVN0cgkAzAgCAAAFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBDWdldEFzc2V0Qnl0ZXMBBQtzQXNzZXRJZFN0cgULYXNzZXRBbW91bnQFA25pbAMJAAACBQ5leGNoYW5nZUludm9rZQUOZXhjaGFuZ2VJbnZva2UECmFzc2V0MFNvbGQJAGUCBQ5iYWxhbmNlMEJlZm9yZQkBCmdldEJhbGFuY2UBBQtzQXNzZXRJZFN0cgMJAAACBQphc3NldDBTb2xkBQphc3NldDBTb2xkBAxhc3NldDFCb3VnaHQJAGUCCQEKZ2V0QmFsYW5jZQEFC2JBc3NldElkU3RyBQ5iYWxhbmNlMUJlZm9yZQMJAAACBQxhc3NldDFCb3VnaHQFDGFzc2V0MUJvdWdodAQLYXNzZXQwUHJpY2UICQENZ2V0VG9rZW5QcmljZQEFC3NBc3NldElkU3RyAl8xBAthc3NldDBTY2FsZQkBDmNhbGNBc3NldFNjYWxlAQULc0Fzc2V0SWRTdHIECWFzc2V0MFVzZAkAawMFCmFzc2V0MFNvbGQFC2Fzc2V0MFByaWNlBQthc3NldDBTY2FsZQQLYXNzZXQxUHJpY2UICQENZ2V0VG9rZW5QcmljZQEFC2JBc3NldElkU3RyAl8yBAthc3NldDFTY2FsZQkBDmNhbGNBc3NldFNjYWxlAQULYkFzc2V0SWRTdHIECWFzc2V0MVVzZAkAawMFDGFzc2V0MUJvdWdodAULYXNzZXQxUHJpY2UFC2Fzc2V0MVNjYWxlBAdwZW5hbHR5CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgkAtQkCCQEMdHJ5R2V0U3RyaW5nAQIPc2V0dXBfcGVuYWx0aWVzAgEsCQEFdmFsdWUBCQDPCAIJAQ9nZXRNYXJrZXRBc3NldHMABQtiQXNzZXRJZFN0cgQRbGlxdWlkYXRpb25Qcm9maXQJAGUCBQlhc3NldDFVc2QJAGsDBQlhc3NldDBVc2QJAGUCBQZTY2FsZTgFB3BlbmFsdHkFBlNjYWxlOAQMc0Fzc2V0Q2hhbmdlCQBrAwUKYXNzZXQwU29sZAUHU2NhbGUxNgUFc1JhdGUEDGJBc3NldENoYW5nZQkAawMJAGsDBQxhc3NldDFCb3VnaHQFB1NjYWxlMTYFBWJSYXRlCQBlAgUGU2NhbGU4CQBrAwURbGlxdWlkYXRpb25Qcm9maXQFBlNjYWxlOAUJYXNzZXQxVXNkBQZTY2FsZTgDCQBmAgUKYXNzZXQwU29sZAULYXNzZXRBbW91bnQJAAIBAiNtb3JlIGFzc2V0cyBleGNoYW5nZWQgdGhhbiBleHBlY3RlZAMJAGYCAAAFEWxpcXVpZGF0aW9uUHJvZml0CQACAQIvcHJpY2UgaW1wYWN0IGlzIGJpZ2dlciB0aGFuIGxpcXVpZGF0aW9uIHBlbmFsdHkJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQtzQXNzZXRJZFN0cgkAZQIFEGN1cnJlbnRTUG9zaXRpb24FDHNBc3NldENoYW5nZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FC2JBc3NldElkU3RyCQBlAgUQY3VycmVudEJQb3NpdGlvbgUMYkFzc2V0Q2hhbmdlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICD3RvdGFsX3N1cHBsaWVkXwULc0Fzc2V0SWRTdHIJAGUCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfc3VwcGxpZWRfBQtzQXNzZXRJZFN0cgUMc0Fzc2V0Q2hhbmdlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgICD3RvdGFsX2JvcnJvd2VkXwULYkFzc2V0SWRTdHIJAGUCCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQtiQXNzZXRJZFN0cgUMYkFzc2V0Q2hhbmdlBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQELbGlxdWlkYXRlVjIDBWRlYnVnB2FkZHJlc3MLc0Fzc2V0SWRTdHIDCQEBIQEJARZ2ZXJpZnlMaXF1aWRhdG9yUmlnaHRzAQgFAWkGY2FsbGVyCQACAQIodGVtcG9yYXJpbHkgYXZhaWxhYmxlIGZvciB3aGl0ZWxpc3Qgb25seQMJAQEhAQkBDXRyeUdldEJvb2xlYW4BAgxzZXR1cF9hY3RpdmUJAAIBAhFtYXJrZXQgaXMgc3RvcHBlZAQIYkFzc2V0SWQICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAQLYkFzc2V0SWRTdHIJAQ5nZXRBc3NldFN0cmluZwEFCGJBc3NldElkBAxiQXNzZXRBbW91bnQICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BA51c2VyQ29sbGF0ZXJhbAkBEmNhbGNVc2VyQ29sbGF0ZXJhbAEFB2FkZHJlc3MDCQAAAgUOdXNlckNvbGxhdGVyYWwFDnVzZXJDb2xsYXRlcmFsAwkAZgIFDnVzZXJDb2xsYXRlcmFsAAAJAAIBAhh1c2VyIGNhbid0IGJlIGxpcXVpZGF0ZWQEDG1hcmtldEFzc2V0cwkBD2dldE1hcmtldEFzc2V0cwAECWFzc2V0MU51bQkBBXZhbHVlAQkAzwgCBQxtYXJrZXRBc3NldHMFC2JBc3NldElkU3RyBAlhc3NldDBOdW0JAQV2YWx1ZQEJAM8IAgUMbWFya2V0QXNzZXRzBQtzQXNzZXRJZFN0cgQNJHQwMzE2NzMzMTczNQkBDWdldEFjdHVhbFJhdGUCBQtiQXNzZXRJZFN0cgIFYlJhdGUEBWJSYXRlCAUNJHQwMzE2NzMzMTczNQJfMQQLcmF0ZXNSZXN1bHQIBQ0kdDAzMTY3MzMxNzM1Al8yBAthc3NldDFQcmljZQgJAQ1nZXRUb2tlblByaWNlAQULYkFzc2V0SWRTdHICXzIEC2Fzc2V0MVNjYWxlCQEOY2FsY0Fzc2V0U2NhbGUBBQtiQXNzZXRJZFN0cgQKYkFtb3VudFVzZAkAawMFDGJBc3NldEFtb3VudAULYXNzZXQxUHJpY2UFC2Fzc2V0MVNjYWxlBAdwZW5hbHR5CQENcGFyc2VJbnRWYWx1ZQEJAQV2YWx1ZQEJAJEDAgkAtQkCCQEMdHJ5R2V0U3RyaW5nAQIPc2V0dXBfcGVuYWx0aWVzAgEsBQlhc3NldDFOdW0EC2Fzc2V0MFByaWNlCAkBDWdldFRva2VuUHJpY2UBBQtzQXNzZXRJZFN0cgJfMQQLYXNzZXQwU2NhbGUJAQ5jYWxjQXNzZXRTY2FsZQEFC3NBc3NldElkU3RyBApzQW1vdW50VXNkCQBrAwUKYkFtb3VudFVzZAkAZAIFBlNjYWxlOAUHcGVuYWx0eQUGU2NhbGU4BAxzQXNzZXRBbW91bnQJAGsDBQpzQW1vdW50VXNkBQthc3NldDBTY2FsZQULYXNzZXQwUHJpY2UEB2JBbW91bnQJAGsDBQxiQXNzZXRBbW91bnQFB1NjYWxlMTYFBWJSYXRlBAdzQW1vdW50CQBrAwUMc0Fzc2V0QW1vdW50BQdTY2FsZTE2CAkAkQMCBQtyYXRlc1Jlc3VsdAkAZAIJAGgCBQlhc3NldDBOdW0AAwABBXZhbHVlBBBjdXJyZW50U1Bvc2l0aW9uCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfBQtzQXNzZXRJZFN0cgQTY3VycmVudEJQb3NpdGlvblZhbAkBDXRyeUdldEludGVnZXIBCQCsAgIJAKwCAgUHYWRkcmVzcwIKX2JvcnJvd2VkXwULYkFzc2V0SWRTdHIEEGN1cnJlbnRCUG9zaXRpb24DCQBmAgUTY3VycmVudEJQb3NpdGlvblZhbAAABRNjdXJyZW50QlBvc2l0aW9uVmFsCQACAQIgdXNlciBoYXMgbm8gYm9ycm93IGluIHRoaXMgdG9rZW4DCQBmAgUHc0Ftb3VudAUQY3VycmVudFNQb3NpdGlvbgkAAgECMnBvc2l0aW9uIHRvIGxpcXVpZGF0ZSBpcyBiaWdnZXIgdGhhbiB1c2VyJ3Mgc3VwcGx5AwUFZGVidWcJAAIBAhVsaXF1aWRhdGlvbiB3aWxsIHBhc3MJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFDHNBc3NldEFtb3VudAkBDWdldEFzc2V0Qnl0ZXMBBQtzQXNzZXRJZFN0cgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIFB2FkZHJlc3MCCl9zdXBwbGllZF8FC3NBc3NldElkU3RyCQBlAgUQY3VycmVudFNQb3NpdGlvbgUHc0Ftb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIFB2FkZHJlc3MCCl9ib3Jyb3dlZF8FC2JBc3NldElkU3RyCQBlAgUQY3VycmVudEJQb3NpdGlvbgUHYkFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICAg90b3RhbF9zdXBwbGllZF8FC3NBc3NldElkU3RyCQBlAgkBDXRyeUdldEludGVnZXIBCQCsAgICD3RvdGFsX3N1cHBsaWVkXwULc0Fzc2V0SWRTdHIFB3NBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgIPdG90YWxfYm9ycm93ZWRfBQtiQXNzZXRJZFN0cgkAZQIJAQ10cnlHZXRJbnRlZ2VyAQkArAICAg90b3RhbF9ib3Jyb3dlZF8FC2JBc3NldElkU3RyBQdiQW1vdW50BQNuaWwFC3JhdGVzUmVzdWx0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEWdldFVzZXJDb2xsYXRlcmFsBAVkZWJ1ZwdhZGRyZXNzDW1pbnVzQm9ycm93ZWQLYWZ0ZXJDaGFuZ2UEBmFzc2V0cwkBD2dldE1hcmtldEFzc2V0cwAEBGx0dnMJALUJAgkBDHRyeUdldFN0cmluZwECCnNldHVwX2x0dnMCASwEA2x0cwkAtQkCCQEMdHJ5R2V0U3RyaW5nAQIJc2V0dXBfbHRzAgEsBAVyYXRlcwgJAQ1nZXRBY3R1YWxSYXRlAgkAkQMCBQZhc3NldHMAAAIFc1JhdGUCXzIEDWNoYW5nZUhhbmRsZXIJALUJAgULYWZ0ZXJDaGFuZ2UCASwKAQFmAgVhY2N1bQRuZXh0AwkAZwIFBG5leHQJAJADAQUGYXNzZXRzBQVhY2N1bQQMdXNlclN1cHBsaWVkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfc3VwcGxpZWRfCQCRAwIFBmFzc2V0cwUEbmV4dAQMdXNlckJvcnJvd2VkCQENdHJ5R2V0SW50ZWdlcgEJAKwCAgkArAICBQdhZGRyZXNzAgpfYm9ycm93ZWRfCQCRAwIFBmFzc2V0cwUEbmV4dAQTbmVlZFRva2VuQWNjb3VudGluZwMJAAACBQthZnRlckNoYW5nZQIAAwMJAQIhPQIFDHVzZXJCb3Jyb3dlZAAABgkBAiE9AgUMdXNlclN1cHBsaWVkAAAGBwYDBRNuZWVkVG9rZW5BY2NvdW50aW5nBAphc3NldFNjYWxlCQEOY2FsY0Fzc2V0U2NhbGUBCQCRAwIFBmFzc2V0cwUEbmV4dAQKYXNzZXRQcmljZQkBDWdldFRva2VuUHJpY2UBCQCRAwIFBmFzc2V0cwUEbmV4dAkAZQIJAGQCBQVhY2N1bQkAawMJAGsDCQBrAwkAZAIFDHVzZXJTdXBwbGllZAMDAwkBAiE9AgULYWZ0ZXJDaGFuZ2UCAAkAAAIJAJEDAgUNY2hhbmdlSGFuZGxlcgAACQCRAwIFBmFzc2V0cwUEbmV4dAcJAAACCQCRAwIFDWNoYW5nZUhhbmRsZXIAAQIIc3VwcGxpZWQHCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUNY2hhbmdlSGFuZGxlcgACAAAI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", "height": 3719806, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: Ch7R1KpxfZt7hWh3DrWrBgjXMkAdbbZSoQWdsKLhHJh7 Next: 9ZLneEys5zXjNynoVz4z3JZMLQtgYuv9vbCY5tdsH51W Diff:
OldNewDifferences
286286 let ratesRecalcResult = $t082708337._2
287287 let amount = fraction(assetAmount, Scale16, sRate, DOWN)
288288 let address = toString(i.caller)
289- let maxSupply = tryGetInteger(("setup_maxSupply_" + assetIdStr))
289+ let maxSupply = match getString(("setup_maxSupply_" + assetIdStr)) {
290+ case x: String =>
291+ parseIntValue(x)
292+ case _ =>
293+ tryGetInteger(("setup_maxSupply_" + assetIdStr))
294+ }
290295 let assetPrice = getTokenPrice(assetIdStr)
291- let newTotalSupplied = (tryGetInteger(("total_supplied_" + assetIdStr)) + amount)
296+ let newTotalSupplied = (tryGetInteger(((address + "_supplied_") + assetIdStr)) + amount)
292297 let rate = getActualRate(assetIdStr, "sRate")._1
293298 let assetScale = calcAssetScale(assetIdStr)
294299 let newTotalSuppliedUsd = fraction(fraction(newTotalSupplied, rate, Scale16), assetPrice._1, assetScale)
307312
308313 @Callable(i)
309314 func withdraw (assetIdStr,assetAmount) = {
310- let $t096419708 = getActualRate(assetIdStr, "sRate")
311- let sRate = $t096419708._1
312- let ratesRecalcResult = $t096419708._2
315+ let $t097619828 = getActualRate(assetIdStr, "sRate")
316+ let sRate = $t097619828._1
317+ let ratesRecalcResult = $t097619828._2
313318 let amount = fraction(assetAmount, Scale16, sRate, CEILING)
314319 let address = toString(i.caller)
315320 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
343348 @Callable(i)
344349 func borrow (assetIdStr,assetAmount) = {
345350 let address = toString(i.caller)
346- let $t01128011347 = getActualRate(assetIdStr, "bRate")
347- let bRate = $t01128011347._1
348- let ratesRecalcResult = $t01128011347._2
351+ let $t01140011467 = getActualRate(assetIdStr, "bRate")
352+ let bRate = $t01140011467._1
353+ let ratesRecalcResult = $t01140011467._2
349354 let amount = fraction(assetAmount, Scale16, bRate, CEILING)
350355 let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",borrowed,") + toString(amount))], nil)
351356 if ((collateralValueInv == collateralValueInv))
386391 else {
387392 let assetIdStr = getAssetString(i.payments[0].assetId)
388393 let assetAmount = i.payments[0].amount
389- let $t01303513102 = getActualRate(assetIdStr, "bRate")
390- let bRate = $t01303513102._1
391- let ratesRecalcResult = $t01303513102._2
394+ let $t01315513222 = getActualRate(assetIdStr, "bRate")
395+ let bRate = $t01315513222._1
396+ let ratesRecalcResult = $t01315513222._2
392397 let amount = fraction(assetAmount, Scale16, bRate, CEILING)
393398 let address = toString(i.caller)
394399 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
421426 else {
422427 let assetIdStr = getAssetString(i.payments[0].assetId)
423428 let assetAmount = i.payments[0].amount
424- let $t01469914766 = getActualRate(assetIdStr, "bRate")
425- let bRate = $t01469914766._1
426- let ratesRecalcResult = $t01469914766._2
429+ let $t01481914886 = getActualRate(assetIdStr, "bRate")
430+ let bRate = $t01481914886._1
431+ let ratesRecalcResult = $t01481914886._2
427432 let amount = fraction(assetAmount, Scale16, bRate, CEILING)
428433 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
429434 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
762767 let userCollateral = calcUserCollateral(address)
763768 if ((userCollateral == userCollateral))
764769 then {
765- let $t02826228324 = getActualRate(sAssetIdStr, "sRate")
766- let sRate = $t02826228324._1
767- let ratesResult = $t02826228324._2
768- let $t02832928398 = getActualRate(bAssetIdStr, "bRate")
769- let bRate = $t02832928398._1
770- let ratesRecalcResult2 = $t02832928398._2
770+ let $t02838228444 = getActualRate(sAssetIdStr, "sRate")
771+ let sRate = $t02838228444._1
772+ let ratesResult = $t02838228444._2
773+ let $t02844928518 = getActualRate(bAssetIdStr, "bRate")
774+ let bRate = $t02844928518._1
775+ let ratesRecalcResult2 = $t02844928518._2
771776 let sAssetAmount = fraction(assetAmount, Scale16, sRate)
772777 let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
773778 let currentBPositionVal = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
843848 let marketAssets = getMarketAssets()
844849 let asset1Num = value(indexOf(marketAssets, bAssetIdStr))
845850 let asset0Num = value(indexOf(marketAssets, sAssetIdStr))
846- let $t03155331615 = getActualRate(bAssetIdStr, "bRate")
847- let bRate = $t03155331615._1
848- let ratesResult = $t03155331615._2
851+ let $t03167331735 = getActualRate(bAssetIdStr, "bRate")
852+ let bRate = $t03167331735._1
853+ let ratesResult = $t03167331735._2
849854 let asset1Price = getTokenPrice(bAssetIdStr)._2
850855 let asset1Scale = calcAssetScale(bAssetIdStr)
851856 let bAmountUsd = fraction(bAssetAmount, asset1Price, asset1Scale)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let reserveFundAddress = Address(base58'3P4kBiU4wr2yV1S5gMfu3MdkVvy7kxXHsKe')
55
66 let reserveFund = 20
77
88 let aggregatorAddress = Address(base58'3PGFHzVGT4NTigwCKP1NcwoXkodVZwvBuuU')
99
1010 let oracleStr = "3PPXVKjN6nRMzXeegcYhfiic96pd2c98Ekm"
1111
1212 let shutdownWhitelist = [base58'3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL', base58'3PAxdDSmN758L5SHSGRC5apEtQE2aApZotG', base58'3PJKmXoHJvVeQXjSJdhtkUcFDtdiQqMbUTD', base58'3PQdNxynJy5mche2kxMVc5shXWzK8Gstq3o', base58'3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3', base58'3P6Ksahs71SiKQgQ4qaZuFAVhqncdi2nvJQ']
1313
1414 func verifyLiquidatorRights (address) = !(if (if ((address != Address(base58'3PCqdm1mAoQqR46oZotFanmqb5CLUvrKEo2')))
1515 then (address != Address(base58'3PMcMiMEs6w56NRGacksXtFG5zS7doE9fpL'))
1616 else false)
1717 then (address != Address(base58'3PHbdpaKzz8EiAngGHaFu2hVuNCdsC67qh3'))
1818 else false)
1919
2020
2121 func getRateCurve (assetIdStr) = match assetIdStr {
2222 case _ =>
2323 if (("9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi" == $match0))
2424 then $Tuple4(2000000, 25000000, 80000000, 100000000)
2525 else if (("HGgabTqUS8WtVFUJzfmrTDMgEccJuZLBPhFgQFxvnsoW" == $match0))
2626 then $Tuple4(2000000, 25000000, 80000000, 100000000)
2727 else if (("34N9YcEETLWn93qYQ64EsP1x89tSruJU44RrEMSXXEPJ" == $match0))
2828 then $Tuple4(2000000, 25000000, 80000000, 100000000)
2929 else if (("6XtHjpXbs9RRJP2Sr9GUyVqzACcby9TkThHXnjVC5CDJ" == $match0))
3030 then $Tuple4(2000000, 25000000, 80000000, 100000000)
3131 else if (("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p" == $match0))
3232 then $Tuple4(2000000, 25000000, 80000000, 100000000)
3333 else if (("Ajso6nTTjptu2UHLx6hfSXVtHFtRBJCkKYd5SAyj7zf5" == $match0))
3434 then $Tuple4(2000000, 40000000, 80000000, 150000000)
3535 else if (("HEB8Qaw9xrWpWs8tHsiATYGBWDBtP2S7kcPALrMu43AS" == $match0))
3636 then $Tuple4(0, 50000000, 80000000, 400000000)
3737 else if (("WAVES" == $match0))
3838 then $Tuple4(2000000, 30000000, 80000000, 80000000)
3939 else if (("Atqv59EYzjFGuitKVnMRk6H8FukjoV3ktPorbEys25on" == $match0))
4040 then $Tuple4(0, 20000000, 80000000, 40000000)
4141 else if (("DSbbhLsSTeDg5Lsiufk2Aneh3DjVqJuPr2M9uU1gwy5p" == $match0))
4242 then $Tuple4(0, 20000000, 80000000, 100000000)
4343 else if (("8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91" == $match0))
4444 then $Tuple4(0, 30000000, 80000000, 40000000)
4545 else if (("At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL" == $match0))
4646 then $Tuple4(0, 25000000, 80000000, 40000000)
4747 else if (("8LQW8f7P5d5PZM7GtZEBgaqRPGSzS3DfPuiXrURJ4AJS" == $match0))
4848 then $Tuple4(2000000, 30000000, 80000000, 50000000)
4949 else if (("474jTeYx2r2Va35794tCScAXWJG9hU2HcgxzMowaZUnu" == $match0))
5050 then $Tuple4(2000000, 30000000, 80000000, 50000000)
5151 else if (("5UYBPpq4WoU5n4MwpFkgJnW3Fq4B1u3ukpK33ik4QerR" == $match0))
5252 then $Tuple4(2000000, 30000000, 80000000, 50000000)
5353 else if (("2thsACuHmzDMuNezPM32wg9a3BwUzBWDeSKakgz3cw21" == $match0))
5454 then $Tuple4(2000000, 40000000, 80000000, 100000000)
5555 else if (("YiNbofFzC17jEHHCMwrRcpy9MrrjabMMLZxg8g5xmf7" == $match0))
5656 then $Tuple4(2000000, 30000000, 80000000, 80000000)
5757 else if (("9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi" == $match0))
5858 then $Tuple4(0, 50000000, 80000000, 200000000)
5959 else if (("3VuV5WTmDz47Dmdn3QpcYjzbSdipjQE4JMdNe1xZpX13" == $match0))
6060 then $Tuple4(0, 100000000, 80000000, 400000000)
6161 else $Tuple4(0, 20000000, 80000000, 80000000)
6262 }
6363
6464
6565 let Scale8 = 100000000
6666
6767 let Scale10 = 10000000000
6868
6969 let Scale16 = (Scale8 * Scale8)
7070
7171 let dayBlocks = 1440
7272
7373 func liIntToStr (li) = {
7474 func f (accum,next) = ((accum + toString(next)) + ",")
7575
7676 let $l = li
7777 let $s = size($l)
7878 let $acc0 = ""
7979 func $f0_1 ($a,$i) = if (($i >= $s))
8080 then $a
8181 else f($a, $l[$i])
8282
8383 func $f0_2 ($a,$i) = if (($i >= $s))
8484 then $a
8585 else throw("List size exceeds 12")
8686
8787 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12)
8888 }
8989
9090
9191 func tryGetInteger (key) = match getInteger(this, key) {
9292 case b: Int =>
9393 b
9494 case _ =>
9595 0
9696 }
9797
9898
9999 func tryGetBoolean (key) = match getBoolean(this, key) {
100100 case b: Boolean =>
101101 b
102102 case _ =>
103103 false
104104 }
105105
106106
107107 func tryGetString (key) = match getString(this, key) {
108108 case b: String =>
109109 b
110110 case _ =>
111111 ""
112112 }
113113
114114
115115 func tryGetBinary (key) = match getBinary(this, key) {
116116 case b: ByteVector =>
117117 b
118118 case _ =>
119119 base58''
120120 }
121121
122122
123123 func getAssetString (assetId) = match assetId {
124124 case b: ByteVector =>
125125 toBase58String(b)
126126 case _ =>
127127 "WAVES"
128128 }
129129
130130
131131 func getAssetBytes (assetIdStr) = if ((assetIdStr == "WAVES"))
132132 then unit
133133 else fromBase58String(assetIdStr)
134134
135135
136136 func getBalance (assetIdStr) = if ((assetIdStr == "WAVES"))
137137 then wavesBalance(this).available
138138 else assetBalance(this, fromBase58String(assetIdStr))
139139
140140
141141 func getMarketAssets () = split(tryGetString("setup_tokens"), ",")
142142
143143
144144 func getAssetsMaxSupply () = {
145145 let s = tryGetString("setup_maxSupply")
146146 if ((s == ""))
147147 then [-1, -1, -1, -1, -1, -1, -1]
148148 else split(s, ",")
149149 }
150150
151151
152152 func getOutdatedUr (assetIdStr) = {
153153 let down = fraction(tryGetInteger(("total_supplied_" + assetIdStr)), tryGetInteger((assetIdStr + "_sRate")), Scale16)
154154 if ((down == 0))
155155 then 0
156156 else fraction(Scale8, fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), tryGetInteger((assetIdStr + "_bRate")), Scale16), down)
157157 }
158158
159159
160160 func getInterest (assetIdStr) = {
161161 let ur = getOutdatedUr(assetIdStr)
162162 let curve = getRateCurve(assetIdStr)
163163 let rate = (curve._1 + (if ((curve._3 >= ur))
164164 then fraction(ur, curve._2, curve._3)
165165 else (curve._2 + fraction((ur - curve._3), curve._4, (100000000 - curve._3)))))
166166 max([fraction(rate, Scale8, (dayBlocks * 365)), 1])
167167 }
168168
169169
170170 func tokenRatesRecalc (assetIdStr) = {
171171 let interest = getInterest(assetIdStr)
172172 let ur = getOutdatedUr(assetIdStr)
173173 let lastRecalcHeight = tryGetInteger("lastRateHeight")
174174 let lastBRate = max([tryGetInteger((assetIdStr + "_bRate")), Scale16])
175175 let newBRate = (lastBRate + ((height - lastRecalcHeight) * interest))
176176 let lastSRate = max([tryGetInteger((assetIdStr + "_sRate")), Scale16])
177177 let newSRate = (lastSRate + ((((height - lastRecalcHeight) * fraction(interest, ur, Scale8)) * (100 - reserveFund)) / 100))
178178 [IntegerEntry((assetIdStr + "_sRate"), newSRate), IntegerEntry((assetIdStr + "_bRate"), newBRate), IntegerEntry("lastRateHeight", height)]
179179 }
180180
181181
182182 func getActualRate (assetIdStr,rateType) = {
183183 func f (accum,token) = {
184184 let recalc = tokenRatesRecalc(token)
185185 $Tuple2(if ((token != assetIdStr))
186186 then accum._1
187187 else if ((rateType == "sRate"))
188188 then recalc[0].value
189189 else recalc[1].value, (accum._2 ++ recalc))
190190 }
191191
192192 let $l = getMarketAssets()
193193 let $s = size($l)
194194 let $acc0 = $Tuple2(0, nil)
195195 func $f0_1 ($a,$i) = if (($i >= $s))
196196 then $a
197197 else f($a, $l[$i])
198198
199199 func $f0_2 ($a,$i) = if (($i >= $s))
200200 then $a
201201 else throw("List size exceeds 12")
202202
203203 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12)
204204 }
205205
206206
207207 func getUr (assetIdStr) = {
208208 let rates = tokenRatesRecalc(assetIdStr)
209209 let down = fraction(tryGetInteger(("total_supplied_" + assetIdStr)), rates[0].value, Scale16)
210210 fraction(Scale8, fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), rates[1].value, Scale16), down)
211211 }
212212
213213
214214 func ratesRecalc () = {
215215 func f (accum,token) = (accum ++ tokenRatesRecalc(token))
216216
217217 let $l = getMarketAssets()
218218 let $s = size($l)
219219 let $acc0 = nil
220220 func $f0_1 ($a,$i) = if (($i >= $s))
221221 then $a
222222 else f($a, $l[$i])
223223
224224 func $f0_2 ($a,$i) = if (($i >= $s))
225225 then $a
226226 else throw("List size exceeds 12")
227227
228228 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12)
229229 }
230230
231231
232232 func getTokenPriceWithRisk (assetIdStr,riskAversity) = if (if ((assetIdStr == "9wc3LXNA4TEBsXyKtoLE9mrbDD7WMHXvXrCjZvabLAsi"))
233233 then true
234234 else (assetIdStr == "HGgabTqUS8WtVFUJzfmrTDMgEccJuZLBPhFgQFxvnsoW"))
235235 then $Tuple2(1000000, 1000000)
236236 else {
237237 let price = getIntegerValue(Address(base58'3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t'), (assetIdStr + "_twap5B"))
238238 let riskLevel = getIntegerValue(Address(base58'3P8d1E1BLKoD52y3bQJ1bDTd2TD1gpaLn9t'), (assetIdStr + "_riskLevel"))
239239 if ((riskAversity >= riskLevel))
240240 then $Tuple2(price, price)
241241 else throw((("oracle prices don't match: " + toString(price)) + " is the price, but risk is too high"))
242242 }
243243
244244
245245 func getTokenPrice (assetIdStr) = getTokenPriceWithRisk(assetIdStr, 3)
246246
247247
248248 func calcAssetScale (assetIdStr) = {
249249 let decimals = if ((assetIdStr == "WAVES"))
250250 then 8
251251 else value(assetInfo(fromBase58String(assetIdStr))).decimals
252252 pow(10, 0, decimals, 0, 0, DOWN)
253253 }
254254
255255
256256 func calcUserCollateral (address) = {
257257 let userCollateralInvoke = invoke(this, "getUserCollateral", [false, address, true, ""], nil)
258258 if ((userCollateralInvoke == userCollateralInvoke))
259259 then {
260260 let userCollateralValue = match userCollateralInvoke {
261261 case x: Int =>
262262 x
263263 case _ =>
264264 throw("issue while doing in-dapp invocation")
265265 }
266266 if ((userCollateralValue == userCollateralValue))
267267 then userCollateralValue
268268 else throw("Strict value is not equal to itself.")
269269 }
270270 else throw("Strict value is not equal to itself.")
271271 }
272272
273273
274274 @Callable(i)
275275 func supply () = if (!(tryGetBoolean("setup_active")))
276276 then throw("market is stopped")
277277 else if (if ((size(i.payments) != 1))
278278 then true
279279 else (i.payments[0].amount == 0))
280280 then throw("1 payment has to be attached")
281281 else {
282282 let assetIdStr = getAssetString(i.payments[0].assetId)
283283 let assetAmount = i.payments[0].amount
284284 let $t082708337 = getActualRate(assetIdStr, "sRate")
285285 let sRate = $t082708337._1
286286 let ratesRecalcResult = $t082708337._2
287287 let amount = fraction(assetAmount, Scale16, sRate, DOWN)
288288 let address = toString(i.caller)
289- let maxSupply = tryGetInteger(("setup_maxSupply_" + assetIdStr))
289+ let maxSupply = match getString(("setup_maxSupply_" + assetIdStr)) {
290+ case x: String =>
291+ parseIntValue(x)
292+ case _ =>
293+ tryGetInteger(("setup_maxSupply_" + assetIdStr))
294+ }
290295 let assetPrice = getTokenPrice(assetIdStr)
291- let newTotalSupplied = (tryGetInteger(("total_supplied_" + assetIdStr)) + amount)
296+ let newTotalSupplied = (tryGetInteger(((address + "_supplied_") + assetIdStr)) + amount)
292297 let rate = getActualRate(assetIdStr, "sRate")._1
293298 let assetScale = calcAssetScale(assetIdStr)
294299 let newTotalSuppliedUsd = fraction(fraction(newTotalSupplied, rate, Scale16), assetPrice._1, assetScale)
295300 if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
296301 then throw("this asset is not supported by the market")
297302 else if (if ((maxSupply != 0))
298303 then (newTotalSuppliedUsd > maxSupply)
299304 else false)
300305 then throw("max total supply for this token reached in the pool")
301306 else if ((tryGetInteger(("setup_paused_" + assetIdStr)) > 0))
302307 then throw("this asset can't be supplied or borrowed")
303308 else ([IntegerEntry(((address + "_supplied_") + assetIdStr), newTotalSupplied), IntegerEntry(("total_supplied_" + assetIdStr), (tryGetInteger(("total_supplied_" + assetIdStr)) + amount))] ++ ratesRecalcResult)
304309 }
305310
306311
307312
308313 @Callable(i)
309314 func withdraw (assetIdStr,assetAmount) = {
310- let $t096419708 = getActualRate(assetIdStr, "sRate")
311- let sRate = $t096419708._1
312- let ratesRecalcResult = $t096419708._2
315+ let $t097619828 = getActualRate(assetIdStr, "sRate")
316+ let sRate = $t097619828._1
317+ let ratesRecalcResult = $t097619828._2
313318 let amount = fraction(assetAmount, Scale16, sRate, CEILING)
314319 let address = toString(i.caller)
315320 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
316321 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
317322 let userAssetSupplied = tryGetInteger(((address + "_supplied_") + assetIdStr))
318323 let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
319324 let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",supplied,") + toString(-(amount)))], nil)
320325 if ((collateralValueInv == collateralValueInv))
321326 then {
322327 let collateralValue = match collateralValueInv {
323328 case x: Int =>
324329 x
325330 case _ =>
326331 throw("can't get user collateral value")
327332 }
328333 if (!(tryGetBoolean("setup_active")))
329334 then throw("market is stopped")
330335 else if ((0 > collateralValue))
331336 then throw("you dont have enough collateral for this operation")
332337 else if ((amount > (assetSupplied - assetBorrowed)))
333338 then throw("this amount is not available on the market")
334339 else if ((amount > (userAssetSupplied - userAssetBorrowed)))
335340 then throw("this amount is not available for this user")
336341 else ([IntegerEntry(((address + "_supplied_") + assetIdStr), (tryGetInteger(((address + "_supplied_") + assetIdStr)) - amount)), IntegerEntry(("total_supplied_" + assetIdStr), (tryGetInteger(("total_supplied_" + assetIdStr)) - amount)), ScriptTransfer(i.caller, assetAmount, getAssetBytes(assetIdStr))] ++ ratesRecalcResult)
337342 }
338343 else throw("Strict value is not equal to itself.")
339344 }
340345
341346
342347
343348 @Callable(i)
344349 func borrow (assetIdStr,assetAmount) = {
345350 let address = toString(i.caller)
346- let $t01128011347 = getActualRate(assetIdStr, "bRate")
347- let bRate = $t01128011347._1
348- let ratesRecalcResult = $t01128011347._2
351+ let $t01140011467 = getActualRate(assetIdStr, "bRate")
352+ let bRate = $t01140011467._1
353+ let ratesRecalcResult = $t01140011467._2
349354 let amount = fraction(assetAmount, Scale16, bRate, CEILING)
350355 let collateralValueInv = invoke(this, "getUserCollateral", [false, address, true, ((assetIdStr + ",borrowed,") + toString(amount))], nil)
351356 if ((collateralValueInv == collateralValueInv))
352357 then {
353358 let collateralValue = match collateralValueInv {
354359 case x: Int =>
355360 x
356361 case _ =>
357362 throw("can't get user collateral value")
358363 }
359364 if (!(tryGetBoolean("setup_active")))
360365 then throw("market is stopped")
361366 else if ((0 > collateralValue))
362367 then throw("you have to supply more to borrow")
363368 else if ((tryGetInteger(("setup_paused_" + assetIdStr)) > 0))
364369 then throw("this asset can't be supplied or borrowed")
365370 else {
366371 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
367372 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
368373 let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
369374 if ((amount > (assetSupplied - assetBorrowed)))
370375 then throw("this amount is not available")
371376 else ([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed + amount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed + amount)), ScriptTransfer(i.caller, assetAmount, getAssetBytes(assetIdStr))] ++ ratesRecalcResult)
372377 }
373378 }
374379 else throw("Strict value is not equal to itself.")
375380 }
376381
377382
378383
379384 @Callable(i)
380385 func repay () = if (!(tryGetBoolean("setup_active")))
381386 then throw("market is stopped")
382387 else if (if ((size(i.payments) != 1))
383388 then true
384389 else (i.payments[0].amount == 0))
385390 then throw("1 payment has to be attached")
386391 else {
387392 let assetIdStr = getAssetString(i.payments[0].assetId)
388393 let assetAmount = i.payments[0].amount
389- let $t01303513102 = getActualRate(assetIdStr, "bRate")
390- let bRate = $t01303513102._1
391- let ratesRecalcResult = $t01303513102._2
394+ let $t01315513222 = getActualRate(assetIdStr, "bRate")
395+ let bRate = $t01315513222._1
396+ let ratesRecalcResult = $t01315513222._2
392397 let amount = fraction(assetAmount, Scale16, bRate, CEILING)
393398 let address = toString(i.caller)
394399 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
395400 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
396401 let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
397402 let amountLeft = (userAssetBorrowed - amount)
398403 let repayAmount = if ((amountLeft >= 0))
399404 then amount
400405 else userAssetBorrowed
401406 if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
402407 then throw("this asset is not supported by the market")
403408 else (([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - repayAmount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - repayAmount))] ++ ratesRecalcResult) ++ (if ((amountLeft >= 0))
404409 then nil
405410 else [ScriptTransfer(i.caller, -(amountLeft), i.payments[0].assetId)]))
406411 }
407412
408413
409414
410415 @Callable(i)
411416 func repayFor (address) = if (!(tryGetBoolean("setup_active")))
412417 then throw("market is stopped")
413418 else if ((i.caller != Address(base58'3P4kBiU4wr2yV1S5gMfu3MdkVvy7kxXHsKe')))
414419 then throw("available only for reserve fund address")
415420 else if ((address == "global"))
416421 then throw("you can't repay for everyone :_)")
417422 else if (if ((size(i.payments) != 1))
418423 then true
419424 else (i.payments[0].amount == 0))
420425 then throw("1 payment has to be attached")
421426 else {
422427 let assetIdStr = getAssetString(i.payments[0].assetId)
423428 let assetAmount = i.payments[0].amount
424- let $t01469914766 = getActualRate(assetIdStr, "bRate")
425- let bRate = $t01469914766._1
426- let ratesRecalcResult = $t01469914766._2
429+ let $t01481914886 = getActualRate(assetIdStr, "bRate")
430+ let bRate = $t01481914886._1
431+ let ratesRecalcResult = $t01481914886._2
427432 let amount = fraction(assetAmount, Scale16, bRate, CEILING)
428433 let assetSupplied = tryGetInteger(("total_supplied_" + assetIdStr))
429434 let assetBorrowed = tryGetInteger(("total_borrowed_" + assetIdStr))
430435 let userAssetBorrowed = tryGetInteger(((address + "_borrowed_") + assetIdStr))
431436 let amountLeft = (userAssetBorrowed - amount)
432437 let repayAmount = if ((amountLeft >= 0))
433438 then amount
434439 else userAssetBorrowed
435440 if ((indexOf(tryGetString("setup_tokens"), assetIdStr) == unit))
436441 then throw("this asset is not supported by the market")
437442 else (([IntegerEntry(((address + "_borrowed_") + assetIdStr), (userAssetBorrowed - repayAmount)), IntegerEntry(("total_borrowed_" + assetIdStr), (assetBorrowed - repayAmount))] ++ ratesRecalcResult) ++ (if ((amountLeft >= 0))
438443 then nil
439444 else [ScriptTransfer(i.caller, -(amountLeft), i.payments[0].assetId)]))
440445 }
441446
442447
443448
444449 @Callable(i)
445450 func stakeTokenAll (assetIdStr) = if ((i.caller != this))
446451 then throw("only for internal smart contract invocations")
447452 else {
448453 let amount = getBalance(assetIdStr)
449454 let inv = invoke(this, "stakeToken", [assetIdStr, amount], nil)
450455 if ((inv == inv))
451456 then nil
452457 else throw("Strict value is not equal to itself.")
453458 }
454459
455460
456461
457462 @Callable(i)
458463 func stakeToken (assetIdStr,amount) = if ((i.caller != this))
459464 then throw("only for internal smart contract invocations")
460465 else if ((assetIdStr == "DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p"))
461466 then {
462467 let amountStaked = tryGetInteger("autostake_amount_DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
463468 let inv = invoke(Address(base58'3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ'), "stake", nil, [AttachedPayment(base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p', amount)])
464469 if ((inv == inv))
465470 then [IntegerEntry("autostake_amount_DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p", (amountStaked + amount))]
466471 else throw("Strict value is not equal to itself.")
467472 }
468473 else if ((assetIdStr == "8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91"))
469474 then {
470475 let amountStaked = tryGetInteger("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91")
471476 let inv = invoke(Address(base58'3PQTM38wDmAY9vWonK6ha7QL3PAycLz5oPP'), "stake", nil, [AttachedPayment(base58'8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91', amount)])
472477 if ((inv == inv))
473478 then [IntegerEntry("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91", (amountStaked + amount))]
474479 else throw("Strict value is not equal to itself.")
475480 }
476481 else if ((assetIdStr == "At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL"))
477482 then {
478483 let amountStaked = tryGetInteger("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL")
479484 let inv = invoke(Address(base58'3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C'), "stake", nil, [AttachedPayment(base58'At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL', amount)])
480485 if ((inv == inv))
481486 then [IntegerEntry("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", (amountStaked + amount))]
482487 else throw("Strict value is not equal to itself.")
483488 }
484489 else nil
485490
486491
487492
488493 @Callable(i)
489494 func unstakeToken (assetIdStr,amount) = if ((i.caller != this))
490495 then throw("only for internal smart contract invocations")
491496 else if ((assetIdStr == "8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91"))
492497 then {
493498 let amountStaked = tryGetInteger("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91")
494499 let inv = invoke(Address(base58'3PQTM38wDmAY9vWonK6ha7QL3PAycLz5oPP'), "unStake", [amount], nil)
495500 if ((inv == inv))
496501 then [IntegerEntry("autostake_amount_8t4DPWTwPzpatHA9AkTxWAB47THnYzBsDnoY7fQqbG91", (amountStaked - amount))]
497502 else throw("Strict value is not equal to itself.")
498503 }
499504 else if ((assetIdStr == "At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL"))
500505 then {
501506 let amountStaked = tryGetInteger("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL")
502507 let inv = invoke(Address(base58'3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C'), "unstake", [amount], nil)
503508 if ((inv == inv))
504509 then {
505510 let bal0 = getBalance("At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL")
506511 if ((bal0 == bal0))
507512 then {
508513 let inv2 = invoke(Address(base58'3PQrVbTVpqXHqpVKftkNdjy3zZAh4dsRzN6'), "gnsbtRewardsSYSREADONLY", [toString(this)], nil)
509514 if ((inv2 == inv2))
510515 then {
511516 let topupRewards = match inv2 {
512517 case x: List[Any] =>
513518 let secondEl = x[1]
514519 match secondEl {
515520 case secondEl: String =>
516521 let usdnValue = parseIntValue(split(split(secondEl, "_")[1], ":")[1])
517522 let wavesValue = parseIntValue(split(split(secondEl, "_")[0], ":")[1])
518523 if (if ((usdnValue != 0))
519524 then true
520525 else (wavesValue != 0))
521526 then {
522527 let usdnBal0 = getBalance("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
523528 if ((usdnBal0 == usdnBal0))
524529 then {
525530 let wavesBal0 = getBalance("WAVES")
526531 if ((wavesBal0 == wavesBal0))
527532 then {
528533 let inv3 = invoke(Address(base58'3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C'), "claimRewards", nil, nil)
529534 if ((inv3 == inv3))
530535 then {
531536 let wavesBal1 = getBalance("WAVES")
532537 if ((wavesBal1 == wavesBal1))
533538 then {
534539 let inv4 = invoke(Address(base58'3PLiXyywNThdvf3vVEUxwc7TJTucjZvuegh'), "swap", ["DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p", 0], [AttachedPayment(unit, (wavesBal1 - wavesBal0))])
535540 if ((inv4 == inv4))
536541 then {
537542 let usdnBal1 = getBalance("DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p")
538543 if ((usdnBal1 == usdnBal1))
539544 then {
540545 let inv5 = invoke(Address(base58'3P7r93vXHuusageNJVGwzqaz3WMotAu49Yz'), "swap", ["At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", 0], [AttachedPayment(base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p', (usdnBal1 - usdnBal0))])
541546 if ((inv5 == inv5))
542547 then {
543548 let inv6 = invoke(this, "addInterest", ["At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", (getBalance("At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL") - bal0)], nil)
544549 if ((inv6 == inv6))
545550 then 2
546551 else throw("Strict value is not equal to itself.")
547552 }
548553 else throw("Strict value is not equal to itself.")
549554 }
550555 else throw("Strict value is not equal to itself.")
551556 }
552557 else throw("Strict value is not equal to itself.")
553558 }
554559 else throw("Strict value is not equal to itself.")
555560 }
556561 else throw("Strict value is not equal to itself.")
557562 }
558563 else throw("Strict value is not equal to itself.")
559564 }
560565 else throw("Strict value is not equal to itself.")
561566 }
562567 else 1
563568 case _ =>
564569 1
565570 }
566571 case _ =>
567572 0
568573 }
569574 if ((topupRewards == topupRewards))
570575 then [IntegerEntry("autostake_amount_At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL", (amountStaked - amount))]
571576 else throw("Strict value is not equal to itself.")
572577 }
573578 else throw("Strict value is not equal to itself.")
574579 }
575580 else throw("Strict value is not equal to itself.")
576581 }
577582 else throw("Strict value is not equal to itself.")
578583 }
579584 else nil
580585
581586
582587
583588 @Callable(i)
584589 func addInterest (assetIdStr,amount) = if ((i.caller != this))
585590 then throw("only for self invocation")
586591 else {
587592 let earned = tryGetInteger(("autostake_lastEarned_" + assetIdStr))
588593 let lastHeight = tryGetInteger(("autostake_lastBlock_" + assetIdStr))
589594 let cleanAmount = fraction(amount, 80, 100)
590595 let stateChanges = if (if ((lastHeight == height))
591596 then true
592597 else (amount == 0))
593598 then nil
594599 else [IntegerEntry(("autostake_preLastEarned_" + assetIdStr), earned), IntegerEntry(("autostake_preLastBlock_" + assetIdStr), lastHeight), IntegerEntry(("autostake_lastEarned_" + assetIdStr), (earned + cleanAmount)), IntegerEntry(("autostake_lastBlock_" + assetIdStr), height)]
595600 (stateChanges ++ [IntegerEntry((assetIdStr + "_sRate"), (tryGetInteger((assetIdStr + "_sRate")) + fraction(Scale16, cleanAmount, tryGetInteger(("total_supplied_" + assetIdStr)))))])
596601 }
597602
598603
599604
600605 @Callable(i)
601606 func addInterestEXTERNAL () = {
602607 let amount = fraction(i.payments[0].amount, 80, 100)
603608 let assetId = i.payments[0].assetId
604609 let assetIdStr = getAssetString(assetId)
605610 let earned = tryGetInteger(("autostake_lastEarned_" + assetIdStr))
606611 let lastHeight = tryGetInteger(("autostake_lastBlock_" + assetIdStr))
607612 let stateChanges = if (if ((lastHeight == height))
608613 then true
609614 else (amount == 0))
610615 then nil
611616 else [IntegerEntry(("autostake_preLastEarned_" + assetIdStr), earned), IntegerEntry(("autostake_preLastBlock_" + assetIdStr), lastHeight), IntegerEntry(("autostake_lastEarned_" + assetIdStr), (earned + amount)), IntegerEntry(("autostake_lastBlock_" + assetIdStr), height)]
612617 (stateChanges ++ [IntegerEntry((assetIdStr + "_sRate"), (tryGetInteger((assetIdStr + "_sRate")) + fraction(Scale16, amount, tryGetInteger(("total_supplied_" + assetIdStr)))))])
613618 }
614619
615620
616621
617622 @Callable(i)
618623 func preInit (tokens,ltvs,lts,penalties) = {
619624 func f (accum,token) = (accum ++ [IntegerEntry((token + "_bRate"), Scale16), IntegerEntry((token + "_sRate"), Scale16)])
620625
621626 if ((i.caller != this))
622627 then throw("admin only")
623628 else {
624629 let rates = {
625630 let $l = split(tokens, ",")
626631 let $s = size($l)
627632 let $acc0 = nil
628633 func $f0_1 ($a,$i) = if (($i >= $s))
629634 then $a
630635 else f($a, $l[$i])
631636
632637 func $f0_2 ($a,$i) = if (($i >= $s))
633638 then $a
634639 else throw("List size exceeds 12")
635640
636641 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12)
637642 }
638643 ([StringEntry("setup_tokens", tokens), StringEntry("setup_ltvs", ltvs), StringEntry("setup_lts", lts), StringEntry("setup_penalties", penalties), BooleanEntry("setup_active", true)] ++ rates)
639644 }
640645 }
641646
642647
643648
644649 @Callable(i)
645650 func initNewToken (token,ltv,lt,penalty) = if ((i.caller != this))
646651 then throw("admin only")
647652 else [StringEntry("setup_tokens", ((tryGetString("setup_tokens") + ",") + token)), StringEntry("setup_ltvs", ((tryGetString("setup_ltvs") + ",") + ltv)), StringEntry("setup_lts", ((tryGetString("setup_lts") + ",") + lt)), StringEntry("setup_penalties", ((tryGetString("setup_penalties") + ",") + penalty)), IntegerEntry((token + "_bRate"), Scale16), IntegerEntry((token + "_sRate"), Scale16)]
648653
649654
650655
651656 @Callable(i)
652657 func updateParameter (key,val) = if (if ((i.caller != this))
653658 then (i.caller != Address(base58'3P3o9cLTV2u9N4nYNKRYL6gy6cUEU9DwXW8'))
654659 else false)
655660 then throw("admin only")
656661 else [IntegerEntry(key, parseIntValue(val))]
657662
658663
659664
660665 @Callable(i)
661666 func updateString (key,val) = if (if ((i.caller != this))
662667 then (i.caller != Address(base58'3P3o9cLTV2u9N4nYNKRYL6gy6cUEU9DwXW8'))
663668 else false)
664669 then throw("admin only")
665670 else [StringEntry(key, val)]
666671
667672
668673
669674 @Callable(i)
670675 func claimToReserveFund (debug) = {
671676 let assets = getMarketAssets()
672677 let rates = getActualRate(assets[0], "sRate")._2
673678 let li = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
674679 func f (accum,n) = if ((n >= size(assets)))
675680 then accum
676681 else {
677682 let assetIdStr = assets[n]
678683 let autostakeAmount = tryGetString(("autostake_amount_" + assetIdStr))
679684 let amount = ((((getBalance(assetIdStr) + tryGetInteger(("autostake_amount_" + assetIdStr))) + (if ((autostakeAmount != ""))
680685 then parseIntValue(autostakeAmount)
681686 else 0)) + fraction(tryGetInteger(("total_borrowed_" + assetIdStr)), rates[((n * 3) + 1)].value, Scale16)) - fraction(tryGetInteger(("total_supplied_" + assetIdStr)), rates[(n * 3)].value, Scale16))
682687 (accum ++ [amount])
683688 }
684689
685690 let parameter = {
686691 let $l = li
687692 let $s = size($l)
688693 let $acc0 = nil
689694 func $f0_1 ($a,$i) = if (($i >= $s))
690695 then $a
691696 else f($a, $l[$i])
692697
693698 func $f0_2 ($a,$i) = if (($i >= $s))
694699 then $a
695700 else throw("List size exceeds 12")
696701
697702 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12)
698703 }
699704 func f2 (accum,n) = if ((n >= size(assets)))
700705 then accum
701706 else {
702707 let assetIdStr = assets[n]
703708 (accum ++ [ScriptTransfer(reserveFundAddress, max([parameter[n], 0]), getAssetBytes(assetIdStr))])
704709 }
705710
706711 if (debug)
707712 then throw(liIntToStr(parameter))
708713 else $Tuple2({
709714 let $l = li
710715 let $s = size($l)
711716 let $acc0 = nil
712717 func $f1_1 ($a,$i) = if (($i >= $s))
713718 then $a
714719 else f2($a, $l[$i])
715720
716721 func $f1_2 ($a,$i) = if (($i >= $s))
717722 then $a
718723 else throw("List size exceeds 12")
719724
720725 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12)
721726 }, parameter)
722727 }
723728
724729
725730
726731 @Callable(i)
727732 func reSetup (assetIdStr) = {
728733 let lastResetup = tryGetInteger("resetup_lastUpdate")
729734 if ((dayBlocks > (height - lastResetup)))
730735 then throw("can be updated only once per day")
731736 else {
732737 let lts = split(tryGetString("setup_lts"), ",")
733738 let assets = getMarketAssets()
734739 let ur = getUr(assetIdStr)
735740 let tempLT = tryGetInteger((("setup_" + assetIdStr) + "_tempLT"))
736741 let lt = parseIntValue(assets[value(indexOf(assets, assetIdStr))])
737742 if ((ur > 90000000))
738743 then [IntegerEntry((("setup_" + assetIdStr) + "_tempLT"), fraction(tempLT, 9975, 10000))]
739744 else if (if ((lt > tempLT))
740745 then (90000000 > ur)
741746 else false)
742747 then [IntegerEntry((("setup_" + assetIdStr) + "_tempLT"), fraction(tempLT, 10025, 10000))]
743748 else nil
744749 }
745750 }
746751
747752
748753
749754 @Callable(i)
750755 func shutdown (shutdown) = if ((indexOf(shutdownWhitelist, i.caller.bytes) == unit))
751756 then throw("user not in a whitelist")
752757 else [BooleanEntry("setup_active", !(shutdown))]
753758
754759
755760
756761 @Callable(i)
757762 func liquidate (debug,address,assetAmount,sAssetIdStr,bAssetIdStr,routeStr) = if (!(verifyLiquidatorRights(i.caller)))
758763 then throw("temporarily available for whitelist only")
759764 else if (!(tryGetBoolean("setup_active")))
760765 then throw("market is stopped")
761766 else {
762767 let userCollateral = calcUserCollateral(address)
763768 if ((userCollateral == userCollateral))
764769 then {
765- let $t02826228324 = getActualRate(sAssetIdStr, "sRate")
766- let sRate = $t02826228324._1
767- let ratesResult = $t02826228324._2
768- let $t02832928398 = getActualRate(bAssetIdStr, "bRate")
769- let bRate = $t02832928398._1
770- let ratesRecalcResult2 = $t02832928398._2
770+ let $t02838228444 = getActualRate(sAssetIdStr, "sRate")
771+ let sRate = $t02838228444._1
772+ let ratesResult = $t02838228444._2
773+ let $t02844928518 = getActualRate(bAssetIdStr, "bRate")
774+ let bRate = $t02844928518._1
775+ let ratesRecalcResult2 = $t02844928518._2
771776 let sAssetAmount = fraction(assetAmount, Scale16, sRate)
772777 let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
773778 let currentBPositionVal = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
774779 let currentBPosition = if ((currentBPositionVal > 0))
775780 then currentBPositionVal
776781 else throw("user has no borrow in this token")
777782 if ((userCollateral > 0))
778783 then throw("user can't be liquidated")
779784 else if ((sAssetAmount > currentSPosition))
780785 then throw("position to liquidate is bigger than user's supply")
781786 else {
782787 let balance0Before = getBalance(sAssetIdStr)
783788 if ((balance0Before == balance0Before))
784789 then {
785790 let balance1Before = getBalance(bAssetIdStr)
786791 if ((balance1Before == balance1Before))
787792 then {
788793 let exchangeInvoke = invoke(aggregatorAddress, "swap", [routeStr, 0], [AttachedPayment(getAssetBytes(sAssetIdStr), assetAmount)])
789794 if ((exchangeInvoke == exchangeInvoke))
790795 then {
791796 let asset0Sold = (balance0Before - getBalance(sAssetIdStr))
792797 if ((asset0Sold == asset0Sold))
793798 then {
794799 let asset1Bought = (getBalance(bAssetIdStr) - balance1Before)
795800 if ((asset1Bought == asset1Bought))
796801 then {
797802 let asset0Price = getTokenPrice(sAssetIdStr)._1
798803 let asset0Scale = calcAssetScale(sAssetIdStr)
799804 let asset0Usd = fraction(asset0Sold, asset0Price, asset0Scale)
800805 let asset1Price = getTokenPrice(bAssetIdStr)._2
801806 let asset1Scale = calcAssetScale(bAssetIdStr)
802807 let asset1Usd = fraction(asset1Bought, asset1Price, asset1Scale)
803808 let penalty = parseIntValue(split(tryGetString("setup_penalties"), ",")[value(indexOf(getMarketAssets(), bAssetIdStr))])
804809 let liquidationProfit = (asset1Usd - fraction(asset0Usd, (Scale8 - penalty), Scale8))
805810 let sAssetChange = fraction(asset0Sold, Scale16, sRate)
806811 let bAssetChange = fraction(fraction(asset1Bought, Scale16, bRate), (Scale8 - fraction(liquidationProfit, Scale8, asset1Usd)), Scale8)
807812 if ((asset0Sold > assetAmount))
808813 then throw("more assets exchanged than expected")
809814 else if ((0 > liquidationProfit))
810815 then throw("price impact is bigger than liquidation penalty")
811816 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))]
812817 }
813818 else throw("Strict value is not equal to itself.")
814819 }
815820 else throw("Strict value is not equal to itself.")
816821 }
817822 else throw("Strict value is not equal to itself.")
818823 }
819824 else throw("Strict value is not equal to itself.")
820825 }
821826 else throw("Strict value is not equal to itself.")
822827 }
823828 }
824829 else throw("Strict value is not equal to itself.")
825830 }
826831
827832
828833
829834 @Callable(i)
830835 func liquidateV2 (debug,address,sAssetIdStr) = if (!(verifyLiquidatorRights(i.caller)))
831836 then throw("temporarily available for whitelist only")
832837 else if (!(tryGetBoolean("setup_active")))
833838 then throw("market is stopped")
834839 else {
835840 let bAssetId = i.payments[0].assetId
836841 let bAssetIdStr = getAssetString(bAssetId)
837842 let bAssetAmount = i.payments[0].amount
838843 let userCollateral = calcUserCollateral(address)
839844 if ((userCollateral == userCollateral))
840845 then if ((userCollateral > 0))
841846 then throw("user can't be liquidated")
842847 else {
843848 let marketAssets = getMarketAssets()
844849 let asset1Num = value(indexOf(marketAssets, bAssetIdStr))
845850 let asset0Num = value(indexOf(marketAssets, sAssetIdStr))
846- let $t03155331615 = getActualRate(bAssetIdStr, "bRate")
847- let bRate = $t03155331615._1
848- let ratesResult = $t03155331615._2
851+ let $t03167331735 = getActualRate(bAssetIdStr, "bRate")
852+ let bRate = $t03167331735._1
853+ let ratesResult = $t03167331735._2
849854 let asset1Price = getTokenPrice(bAssetIdStr)._2
850855 let asset1Scale = calcAssetScale(bAssetIdStr)
851856 let bAmountUsd = fraction(bAssetAmount, asset1Price, asset1Scale)
852857 let penalty = parseIntValue(value(split(tryGetString("setup_penalties"), ",")[asset1Num]))
853858 let asset0Price = getTokenPrice(sAssetIdStr)._1
854859 let asset0Scale = calcAssetScale(sAssetIdStr)
855860 let sAmountUsd = fraction(bAmountUsd, (Scale8 + penalty), Scale8)
856861 let sAssetAmount = fraction(sAmountUsd, asset0Scale, asset0Price)
857862 let bAmount = fraction(bAssetAmount, Scale16, bRate)
858863 let sAmount = fraction(sAssetAmount, Scale16, ratesResult[((asset0Num * 3) + 1)].value)
859864 let currentSPosition = tryGetInteger(((address + "_supplied_") + sAssetIdStr))
860865 let currentBPositionVal = tryGetInteger(((address + "_borrowed_") + bAssetIdStr))
861866 let currentBPosition = if ((currentBPositionVal > 0))
862867 then currentBPositionVal
863868 else throw("user has no borrow in this token")
864869 if ((sAmount > currentSPosition))
865870 then throw("position to liquidate is bigger than user's supply")
866871 else if (debug)
867872 then throw("liquidation will pass")
868873 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)
869874 }
870875 else throw("Strict value is not equal to itself.")
871876 }
872877
873878
874879
875880 @Callable(i)
876881 func getUserCollateral (debug,address,minusBorrowed,afterChange) = {
877882 let assets = getMarketAssets()
878883 let ltvs = split(tryGetString("setup_ltvs"), ",")
879884 let lts = split(tryGetString("setup_lts"), ",")
880885 let rates = getActualRate(assets[0], "sRate")._2
881886 let changeHandler = split(afterChange, ",")
882887 func f (accum,next) = if ((next >= size(assets)))
883888 then accum
884889 else {
885890 let userSupplied = tryGetInteger(((address + "_supplied_") + assets[next]))
886891 let userBorrowed = tryGetInteger(((address + "_borrowed_") + assets[next]))
887892 let needTokenAccounting = if ((afterChange == ""))
888893 then if (if ((userBorrowed != 0))
889894 then true
890895 else (userSupplied != 0))
891896 then true
892897 else false
893898 else true
894899 if (needTokenAccounting)
895900 then {
896901 let assetScale = calcAssetScale(assets[next])
897902 let assetPrice = getTokenPrice(assets[next])
898903 ((accum + fraction(fraction(fraction((userSupplied + (if (if (if ((afterChange != ""))
899904 then (changeHandler[0] == assets[next])
900905 else false)
901906 then (changeHandler[1] == "supplied")
902907 else false)
903908 then parseIntValue(changeHandler[2])
904909 else 0)), rates[(next * 3)].value, Scale16), parseIntValue(ltvs[next]), Scale8), assetPrice._1, assetScale)) - (if (minusBorrowed)
905910 then fraction(fraction(fraction((userBorrowed + (if (if (if ((afterChange != ""))
906911 then (changeHandler[0] == assets[next])
907912 else false)
908913 then (changeHandler[1] == "borrowed")
909914 else false)
910915 then parseIntValue(changeHandler[2])
911916 else 0)), rates[((next * 3) + 1)].value, Scale16), Scale8, parseIntValue(lts[next])), assetPrice._2, assetScale)
912917 else 0))
913918 }
914919 else accum
915920 }
916921
917922 let result = {
918923 let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
919924 let $s = size($l)
920925 let $acc0 = 0
921926 func $f0_1 ($a,$i) = if (($i >= $s))
922927 then $a
923928 else f($a, $l[$i])
924929
925930 func $f0_2 ($a,$i) = if (($i >= $s))
926931 then $a
927932 else throw("List size exceeds 12")
928933
929934 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12)
930935 }
931936 if (debug)
932937 then throw(toString(result))
933938 else $Tuple2(rates, result)
934939 }
935940
936941
937942
938943 @Callable(i)
939944 func getPrices (debug) = {
940945 let assets = getMarketAssets()
941946 func f (accum,next) = if ((next >= size(assets)))
942947 then accum
943948 else {
944949 let assetPrice = getTokenPriceWithRisk(assets[next], 3)
945950 ((((accum + toString(assetPrice._1)) + ",") + toString(assetPrice._2)) + "|")
946951 }
947952
948953 let result = {
949954 let $l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
950955 let $s = size($l)
951956 let $acc0 = ""
952957 func $f0_1 ($a,$i) = if (($i >= $s))
953958 then $a
954959 else f($a, $l[$i])
955960
956961 func $f0_2 ($a,$i) = if (($i >= $s))
957962 then $a
958963 else throw("List size exceeds 12")
959964
960965 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12)
961966 }
962967 if (debug)
963968 then throw(result)
964969 else $Tuple2(nil, result)
965970 }
966971
967972
968973
969974 @Callable(i)
970975 func calculateUtilizationRatio (assetIdStr,debug) = if (debug)
971976 then throw(toString(getUr(assetIdStr)))
972977 else $Tuple2(nil, getUr(assetIdStr))
973978
974979
975980
976981 @Callable(i)
977982 func calculateOutdatedUR (assetIdStr,debug) = if (debug)
978983 then throw(toString(getOutdatedUr(assetIdStr)))
979984 else $Tuple2(nil, getOutdatedUr(assetIdStr))
980985
981986
982987
983988 @Callable(i)
984989 func calculateTokenRates (debug) = {
985990 func f (accum,assetIdStr) = {
986991 let rates = tokenRatesRecalc(assetIdStr)
987992 $Tuple2(((((accum._1 + toString(rates[1].value)) + "|") + toString(rates[0].value)) + ","), (accum._2 ++ rates))
988993 }
989994
990995 let parameter = {
991996 let $l = getMarketAssets()
992997 let $s = size($l)
993998 let $acc0 = $Tuple2("", nil)
994999 func $f0_1 ($a,$i) = if (($i >= $s))
9951000 then $a
9961001 else f($a, $l[$i])
9971002
9981003 func $f0_2 ($a,$i) = if (($i >= $s))
9991004 then $a
10001005 else throw("List size exceeds 12")
10011006
10021007 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12)
10031008 }
10041009 if (debug)
10051010 then throw(parameter._1)
10061011 else $Tuple2(parameter._2, parameter._1)
10071012 }
10081013
10091014
10101015
10111016 @Callable(i)
10121017 func calculateTokensInterest (debug) = {
10131018 func f (accum,assetIdStr) = {
10141019 let rate = fraction(getInterest(assetIdStr), dayBlocks, Scale8)
10151020 ((accum + toString(rate)) + ",")
10161021 }
10171022
10181023 let parameter = {
10191024 let $l = getMarketAssets()
10201025 let $s = size($l)
10211026 let $acc0 = ""
10221027 func $f0_1 ($a,$i) = if (($i >= $s))
10231028 then $a
10241029 else f($a, $l[$i])
10251030
10261031 func $f0_2 ($a,$i) = if (($i >= $s))
10271032 then $a
10281033 else throw("List size exceeds 12")
10291034
10301035 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12)
10311036 }
10321037 if (debug)
10331038 then throw(parameter)
10341039 else $Tuple2(nil, parameter)
10351040 }
10361041
10371042
10381043 @Verifier(tx)
10391044 func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
10401045

github/deemru/w8io/3ef1775 
127.30 ms