tx · 4opCmweNFJvfGjV1kBC5K5Kgyr2up5W19rX3J8B4rERv

3MvRWw2FPEimFCTGtK7qY9uAJbM7XJ4ZfJS:  -0.05300000 Waves

2023.08.09 17:08 [2703161] smart account 3MvRWw2FPEimFCTGtK7qY9uAJbM7XJ4ZfJS > SELF 0.00000000 Waves

{ "type": 13, "id": "4opCmweNFJvfGjV1kBC5K5Kgyr2up5W19rX3J8B4rERv", "fee": 5300000, "feeAssetId": null, "timestamp": 1691590100823, "version": 2, "chainId": 84, "sender": "3MvRWw2FPEimFCTGtK7qY9uAJbM7XJ4ZfJS", "senderPublicKey": "HP8sssVq1866F7CaPQJwgFrt6fsqhQjKwM84cL1wjD2a", "proofs": [ "3AsxcpMtHTYLd5mZj1buyThT4jzxALjKiM4nUkU8k87gpMx8xhV1NVsmfp2kvc4kcAt8ZwuU7z9dZ5e1NDMxyPHU" ], "script": "base64:BgLBAQgCEgMKAQgSAwoBCBIECgIICBIFCgMIGBgSBQoDCAEIEgQKAggBEgYKBAEICAESBQoDAQgIEg8KDQgICAgICAgICAgICAgSAwoBCBIDCgEIEgUKAwgIARIGCgQIAQgIEg0KCwgIAQQRGBgYAQEYEgkKBwgIAQQIARgSDQoLCAgBBBgYGBgYARgSBQoDCAQBEgsKCQgIAQEBAQEBBBIJCgcIAQEBAQEBEgASABIAEgASABIAEgASABIDCgEIEgMKAQiBAQAHU0ZfUE9PTAICU0YAB1dYX1BPT0wCAldYAA9DQVBfRkVFX05PX0xPQU4CCWNhcE5vTG9hbgAMQ0FQX0ZFRV9MT0FOAgdjYXBMb2FuABRTVE9QTE9TU19GRUVfTk9fTE9BTgIOc3RvcExvc3NOb0xvYW4ADVNUT1BMT1NTX0xPQU4CDHN0b3BMb3NzTG9hbgAITE9BTl9GRUUCBGxvYW4AC05PX0xPQU5fRkVFAgZub0xvYW4ABk5PX0ZFRQIFbm9GZWUABlNDQUxFOACAwtcvAAdTQ0FMRTEwAIDIr6AlAAdTQ0FMRTE2CQC2AgEAgICE/qbe4REACkZFRV9TQ0FMRTYAwIQ9ABRrU0ZQb29sQUFzc2V0QmFsYW5jZQIPQV9hc3NldF9iYWxhbmNlABRrU0ZQb29sQkFzc2V0QmFsYW5jZQIPQl9hc3NldF9iYWxhbmNlAA9rU0ZQb29sQUFzc2V0SWQCCkFfYXNzZXRfaWQAD2tTRlBvb2xCQXNzZXRJZAIKQl9hc3NldF9pZAAOa1NGUG9vbFNoYXJlSWQCDnNoYXJlX2Fzc2V0X2lkABJrU0ZQb29sU2hhcmVTdXBwbHkCEnNoYXJlX2Fzc2V0X3N1cHBseQAKa1NGUG9vbEZlZQIKY29tbWlzc2lvbgANa1VzZXJQb3NpdGlvbgINX3VzZXJQb3NpdGlvbgARa1VzZXJQb3NpdGlvblBvb2wCEV91c2VyUG9zaXRpb25Qb29sABFrVXNlckJvcnJvd0Ftb3VudAIZX3VzZXJQb3NpdGlvbkJvcnJvd0Ftb3VudAASa1VzZXJCb3Jyb3dBc3NldElkAhpfdXNlclBvc2l0aW9uQm9ycm93QXNzZXRJZAAQa1VzZXJQb3NpdGlvbk51bQITX3VzZXJQb3NpdGlvbk51bWJlcgAVa1VzZXJQb3NpdGlvbkludGVyZXN0AhVfdXNlclBvc2l0aW9uSW50ZXJlc3QACmtQb29sVG90YWwCCl9wb29sVG90YWwADmtQb29sVG90YWxMb2FuAg5fcG9vbFRvdGFsTG9hbgARa1Bvb2xJbnRlcmVzdExvYW4CEV9wb29sSW50ZXJlc3RMb2FuABNrUG9vbEludGVyZXN0Tm9Mb2FuAhNfcG9vbEludGVyZXN0Tm9Mb2FuAA5rUG9vbENhbkJvcnJvdwIOX3Bvb2xDYW5Cb3Jyb3cAFWtBeGx5SW5GZWVXaXRob3V0TG9hbgIOX2F4bHlGZWVOb0xvYW4AEmtBeGx5SW5GZWVXaXRoTG9hbgIQX2F4bHlGZWVXaXRoTG9hbgARa0F4bHlOb0xvYW5DYXBGZWUCEV9heGx5RmVlQ2FwTm9Mb2FuABNrQXhseVdpdGhMb2FuQ2FwRmVlAhNfYXhseUZlZUNhcFdpdGhMb2FuABZrQXhseVN0b3BMb3NzTm9Mb2FuRmVlAhhfYXhseUZlZVN0b3Bsb3NzV2l0aExvYW4AFGtBeGx5U3RvcExvc3NMb2FuRmVlAhZfYXhseUZlZVN0b3Bsb3NzTm9Mb2FuAAprUmVxdWVzdElkAgtfcmVxdWVzdF9pZAAMa1JlcXVlc3RJdGVyAg1yZXF1ZXN0c19pdGVyAAVrUG9vbAIFcG9vbF8ACmtTaGFyZVBvb2wCDF9wb29sU2hhcmVJZAAOa1Bvb2xDYXBDaGFuZ2UCDl9wb29sQ2FwQ2hhbmdlAA9rVG9rZW5MYXN0UHJpY2UCCmxhc3RfcHJpY2UADmtQcmljZUluT3JhY2xlAgdfdHdhcDVCAAdrQWN0aXZlAgZhY3RpdmUADGtBY3RpdmVVc2VycwILYWN0aXZlVXNlcnMAC2tBY3RpdmVTRldYAgdfYWN0aXZlAAtrUG9vbEFjdGl2ZQILX2FjdGl2ZVBvb2wADWtVc2VyU3RvcExvc3MCCV9zdG9wTG9zcwAJa01vbmV5Qm94Ag5heGx5X21vbmV5X2JveAAOa1NGRmFybWluZ0FkZHICE3N3b3BmaV9mYXJtaW5nX2FkZHIADGtMZW5kU2VydmljZQIRbGVuZF9zZXJ2aWNlX2FkZHIAD2tPcGVyYXRvckNhbGxQSwISYWRtaW5fY2FsbF9wdWJfa2V5AAxrUHJpY2VPcmFjbGUCDHByaWNlX29yYWNsZQALa0V4Q29udHJhY3QCEWV4Y2hhbmdlX2NvbnRyYWN0AA9rV3hTd2FwQ29udHJhY3QCEHd4X3N3YXBfY29udHJhY3QAB2tTd29wSWQCB3N3b3BfaWQABWtXeElkAgV3eF9pZAAPa0dyb3VwMUFkbWluMVBLAhVncm91cDFfYWRtaW4xX3B1Yl9rZXkAD2tHcm91cDFBZG1pbjJQSwIVZ3JvdXAxX2FkbWluMl9wdWJfa2V5AA9rR3JvdXAyQWRtaW4xUEsCFWdyb3VwMl9hZG1pbjFfcHViX2tleQAPa0dyb3VwMkFkbWluMlBLAhVncm91cDJfYWRtaW4yX3B1Yl9rZXkACG1vbmV5Qm94CQEHQWRkcmVzcwEJANkEAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMFCWtNb25leUJveAIYTm8gYXhseSBtb25leUJveCBhZGRyZXNzAApleENvbnRyYWN0CQEHQWRkcmVzcwEJANkEAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMFC2tFeENvbnRyYWN0AhxObyBleGNoYW5nZSBjb250cmFjdCBhZGRyZXNzAA9wcmljZU9yYWNsZUFkZHIJAQdBZGRyZXNzAQkA2QQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwUMa1ByaWNlT3JhY2xlAhdObyBwcmljZSBvcmFjbGUgYWRkcmVzcwAOd3hTd2FwQ29udHJhY3QJAQdBZGRyZXNzAQkA2QQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwUPa1d4U3dhcENvbnRyYWN0AhJObyB3eCBzd2FwIGFkZHJlc3MABlNXT1BJRAkA2QQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwUHa1N3b3BJZAIKTm8gc3dvcCBpZAAEV1hJRAkA2QQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwUFa1d4SWQCCE5vIHd4IGlkAA5ncm91cDFBZG1pbjFQSwkA2QQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwUPa0dyb3VwMUFkbWluMVBLAhlDYW4ndCBnZXQga0dyb3VwMUFkbWluMVBLAA5ncm91cDFBZG1pbjJQSwkA2QQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwUPa0dyb3VwMUFkbWluMlBLAhlDYW4ndCBnZXQga0dyb3VwMUFkbWluMlBLAA5ncm91cDJBZG1pbjFQSwkA2QQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwUPa0dyb3VwMkFkbWluMVBLAhlDYW4ndCBnZXQga0dyb3VwMkFkbWluMVBLAA5ncm91cDJBZG1pbjJQSwkA2QQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwUPa0dyb3VwMkFkbWluMlBLAhlDYW4ndCBnZXQga0dyb3VwMkFkbWluMVBLAApvcGVyYXRvclBLCQDZBAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzBQ9rT3BlcmF0b3JDYWxsUEsCFENhbid0IGdldCBvcGVyYXRvclBLAQ91bmtub3duUG9vbFR5cGUACQACAQIPV3JvbmcgcG9vbCB0eXBlAQ5nZXRMZW5kU3J2QWRkcgAJAQdBZGRyZXNzAQkA2QQBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwUMa0xlbmRTZXJ2aWNlAhtDYW4ndCBnZXQgbGVuZCBzZXJ2aWNlIGFkZHIBDmlzT3BlcmF0b3JDYWxsAQFpAwkAAAIIBQFpD2NhbGxlclB1YmxpY0tleQgFAWkPY2FsbGVyUHVibGljS2V5BQR1bml0CQACAQIkT25seSBvcGVyYXRvciBjYW4gY2FsbCB0aGlzIGZ1bmN0aW9uAQtpc0FkbWluQ2FsbAEBaQMDCQAAAggFAWkPY2FsbGVyUHVibGljS2V5CAUBaQ9jYWxsZXJQdWJsaWNLZXkGCQAAAggFAWkPY2FsbGVyUHVibGljS2V5CAUBaQ9jYWxsZXJQdWJsaWNLZXkFBHVuaXQJAAIBAihPbmx5IGFkbWluIGdyb3VwMSBjYW4gY2FsbCB0aGlzIGZ1bmN0aW9uAQppc1NlbGZDYWxsAQFpAwkAAAIIBQFpBmNhbGxlcgUEdGhpcwUEdW5pdAkAAgECK09ubHkgY29udHJhY3QgaXRzZWxmIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24BCmlzTGFuZENhbGwBAWkDCQAAAggFAWkGY2FsbGVyCQEOZ2V0TGVuZFNydkFkZHIABQR1bml0CQACAQIpT25seSBsYW5kIGNvbnRyYWN0IGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24BCGlzQWN0aXZlAAMJAAACCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMFB2tBY3RpdmUGBgUEdW5pdAkAAgECH0RBcHAgaXMgaW5hY3RpdmUgYXQgdGhpcyBtb21lbnQBEGlzQWN0aXZlRm9yVXNlcnMAAwMJAQt2YWx1ZU9yRWxzZQIJAJsIAgUEdGhpcwUHa0FjdGl2ZQYJAAACCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMFDGtBY3RpdmVVc2VycwYGBwUEdW5pdAkAAgECKURBcHAgaXMgaW5hY3RpdmUgZm9yIHVzZXJzIGF0IHRoaXMgbW9tZW50AQxpc1Bvb2xBY3RpdmUCBHBvb2wEdHlwZQQKV1hTRkFjdGl2ZQkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzCQCsAgIFBHR5cGUFC2tBY3RpdmVTRldYBgQKcG9vbEFjdGl2ZQkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzCQCsAgIFBHBvb2wFC2tQb29sQWN0aXZlBgMDBQpXWFNGQWN0aXZlBQpwb29sQWN0aXZlBwYHAQ5hY2NvdW50QmFsYW5jZQEHYXNzZXRJZAQHJG1hdGNoMAUHYXNzZXRJZAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJpZAUHJG1hdGNoMAkA8AcCBQR0aGlzBQJpZAMJAAECBQckbWF0Y2gwAgRVbml0BAV3YXZlcwUHJG1hdGNoMAgJAO8HAQUEdGhpcwlhdmFpbGFibGUJAAIBAgtNYXRjaCBlcnJvcgERZ2V0U0ZQb29sQmFsYW5jZXMBCHBvb2xBZGRyCQCUCgIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQhwb29sQWRkcgUUa1NGUG9vbEFBc3NldEJhbGFuY2UCHkNhbid0IGdldCBwb29sIEEgYXNzZXQgYmFsYW5jZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFCHBvb2xBZGRyBRRrU0ZQb29sQkFzc2V0QmFsYW5jZQIeQ2FuJ3QgZ2V0IHBvb2wgQiBhc3NldCBiYWxhbmNlARFnZXRXWFBvb2xCYWxhbmNlcwMIcG9vbEFkZHIDYUlkA2JJZAkAlAoCCgABQAkA/AcEBQhwb29sQWRkcgIcZ2V0QWNjQmFsYW5jZVdyYXBwZXJSRUFET05MWQkAzAgCBQNhSWQFA25pbAUDbmlsAwkAAQIFAUACA0ludAUBQAkAAgEJAKwCAgkAAwEFAUACGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAoAAUAJAPwHBAUIcG9vbEFkZHICHGdldEFjY0JhbGFuY2VXcmFwcGVyUkVBRE9OTFkJAMwIAgUDYklkBQNuaWwFA25pbAMJAAECBQFAAgNJbnQFAUAJAAIBCQCsAgIJAAMBBQFAAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQBD2dldFBvb2xCYWxhbmNlcwQIcG9vbEFkZHIEdHlwZQNhSWQDYklkAwkAAAIFBHR5cGUFB1NGX1BPT0wJARFnZXRTRlBvb2xCYWxhbmNlcwEFCHBvb2xBZGRyAwkAAAIFBHR5cGUFB1dYX1BPT0wJARFnZXRXWFBvb2xCYWxhbmNlcwMFCHBvb2xBZGRyBQNhSWQFA2JJZAkBD3Vua25vd25Qb29sVHlwZQABDWdldFNGUG9vbERhdGEBCHBvb2xBZGRyBAskdDA3OTEyNzk2MQkBEWdldFNGUG9vbEJhbGFuY2VzAQUIcG9vbEFkZHIDCQAAAgULJHQwNzkxMjc5NjEFCyR0MDc5MTI3OTYxBARiYWxCCAULJHQwNzkxMjc5NjECXzIEBGJhbEEIBQskdDA3OTEyNzk2MQJfMQkAlwoFCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUIcG9vbEFkZHIFD2tTRlBvb2xBQXNzZXRJZAIZQ2FuJ3QgZ2V0IHBvb2wgQSBhc3NldCBpZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFCHBvb2xBZGRyBQ9rU0ZQb29sQkFzc2V0SWQCGUNhbid0IGdldCBwb29sIEIgYXNzZXQgaWQFBGJhbEEFBGJhbEIJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQhwb29sQWRkcgUOa1NGUG9vbFNoYXJlSWQCGENhbid0IGdldCBzaGFyZSBhc3NldCBpZAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgENZ2V0V1hQb29sRGF0YQEIcG9vbEFkZHIEA2NmZwoAAUAJAPwHBAUIcG9vbEFkZHICHGdldFBvb2xDb25maWdXcmFwcGVyUkVBRE9OTFkFA25pbAUDbmlsAwkAAQIFAUACCUxpc3RbQW55XQUBQAkAAgEJAKwCAgkAAwEFAUACHiBjb3VsZG4ndCBiZSBjYXN0IHRvIExpc3RbQW55XQMJAAACBQNjZmcFA2NmZwQDYUlkCQETdmFsdWVPckVycm9yTWVzc2FnZQIKAAFACQCRAwIFA2NmZwAEAwkAAQIFAUACBlN0cmluZwUBQAUEdW5pdAIZQ2FuJ3QgZ2V0IHBvb2wgQSBhc3NldCBpZAQDYklkCQETdmFsdWVPckVycm9yTWVzc2FnZQIKAAFACQCRAwIFA2NmZwAFAwkAAQIFAUACBlN0cmluZwUBQAUEdW5pdAIZQ2FuJ3QgZ2V0IHBvb2wgQiBhc3NldCBpZAQHc2hhcmVJZAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCgABQAkAkQMCBQNjZmcAAwMJAAECBQFAAgZTdHJpbmcFAUAFBHVuaXQCGkNhbid0IGdldCBwb29sIExQIGFzc2V0IGlkBAskdDA4NjU4ODcxNwkBEWdldFdYUG9vbEJhbGFuY2VzAwUIcG9vbEFkZHIFA2FJZAUDYklkAwkAAAIFCyR0MDg2NTg4NzE3BQskdDA4NjU4ODcxNwQEYmFsQggFCyR0MDg2NTg4NzE3Al8yBARiYWxBCAULJHQwODY1ODg3MTcCXzEJAJcKBQUDYUlkBQNiSWQFBGJhbEEFBGJhbEIFB3NoYXJlSWQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BC2dldFBvb2xEYXRhAghwb29sQWRkcgR0eXBlAwkAAAIFBHR5cGUFB1NGX1BPT0wJAQ1nZXRTRlBvb2xEYXRhAQUIcG9vbEFkZHIDCQAAAgUEdHlwZQUHV1hfUE9PTAkBDWdldFdYUG9vbERhdGEBBQhwb29sQWRkcgkBD3Vua25vd25Qb29sVHlwZQABDmdldFNoYXJlU3VwcGx5Awhwb29sQWRkcgR0eXBlB3NoYXJlSWQDCQAAAgUEdHlwZQUHU0ZfUE9PTAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFCHBvb2xBZGRyBRJrU0ZQb29sU2hhcmVTdXBwbHkCHENhbid0IGdldCBzaGFyZSBhc3NldCBzdXBwbHkDCQAAAgUEdHlwZQUHV1hfUE9PTAgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFB3NoYXJlSWQCDVdyb25nIFNoYXJlSWQIcXVhbnRpdHkJAQ91bmtub3duUG9vbFR5cGUAARFnZXRQb29sVG90YWxTaGFyZQEEcG9vbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIFBHBvb2wFCmtQb29sVG90YWwAAAEZZ2V0UG9vbFRvdGFsU2hhcmVXaXRoTG9hbgEEcG9vbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIFBHBvb2wFDmtQb29sVG90YWxMb2FuAAABGGdldE5ld1VzZXJQb3NpdGlvbk51bWJlcgEEdXNlcgkAZAIJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICBQR1c2VyBRBrVXNlclBvc2l0aW9uTnVtAAAAAQEKZ2V0QXhseUZlZQIEcG9vbAdmZWVUeXBlAwkAAAIFB2ZlZVR5cGUFDENBUF9GRUVfTE9BTgkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkArAICBQRwb29sBRNrQXhseVdpdGhMb2FuQ2FwRmVlAwkAAAIFB2ZlZVR5cGUFD0NBUF9GRUVfTk9fTE9BTgkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkArAICBQRwb29sBRFrQXhseU5vTG9hbkNhcEZlZQMJAAACBQdmZWVUeXBlBQhMT0FOX0ZFRQkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkArAICBQRwb29sBRJrQXhseUluRmVlV2l0aExvYW4DCQAAAgUHZmVlVHlwZQULTk9fTE9BTl9GRUUJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAKwCAgUEcG9vbAUVa0F4bHlJbkZlZVdpdGhvdXRMb2FuAwkAAAIFB2ZlZVR5cGUFBk5PX0ZFRQAACQACAQIOV3JvbmcgZmVlIHR5cGUBEGdldFNGRmFybWluZ0FkZHIACQEHQWRkcmVzcwEJANkEAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMFDmtTRkZhcm1pbmdBZGRyAh1DYW4ndCBnZXQgc3dvcGZpIGZhcm1pbmcgYWRkcgEQZ2V0V1hGYXJtaW5nQWRkcgEIcG9vbEFkZHIECWZDb250cmFjdAkBB0FkZHJlc3MBCQDZBAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQhwb29sQWRkcgITJXNfX2ZhY3RvcnlDb250cmFjdAIiQ2FuJ3QgZ2V0IFdYIGZhY3RvcnkgY29udHJhY3QgYWRkcgQKZmFjdHJveUNmZwkAtQkCCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUJZkNvbnRyYWN0AhElc19fZmFjdG9yeUNvbmZpZwIYQ2FuJ3QgZ2V0IFdYIGZhY3RvcnkgY2ZnAgJfXwkBB0FkZHJlc3MBCQDZBAEJAJEDAgUKZmFjdHJveUNmZwABAQxhc3NldElkVG9TdHIBB2Fzc2V0SWQEByRtYXRjaDAFB2Fzc2V0SWQDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCaWQFByRtYXRjaDAJANgEAQUCaWQDCQABAgUHJG1hdGNoMAIEVW5pdAQFd2F2ZXMFByRtYXRjaDACBVdBVkVTCQACAQIMTm90IEFzc2V0IGlkAQ5hc3NldElkRnJvbVN0cgEHYXNzZXRJZAMJAAACBQdhc3NldElkAgVXQVZFUwUEdW5pdAkA2QQBBQdhc3NldElkARBnZXRBc3NldERlY2ltYWxzAQdhc3NldElkAwkAAAIFB2Fzc2V0SWQCBVdBVkVTAAgEByRtYXRjaDAJAOwHAQkA2QQBBQdhc3NldElkAwkAAQIFByRtYXRjaDACBUFzc2V0BAVhc3NldAUHJG1hdGNoMAgFBWFzc2V0CGRlY2ltYWxzCQACAQIQQ2FuJ3QgZmluZCBhc3NldAERZ2V0QXNzZXRQcmVjaXRpb24BB2Fzc2V0SWQJAGwGAAoAAAkBEGdldEFzc2V0RGVjaW1hbHMBBQdhc3NldElkAAAAAAUERE9XTgEOZ2V0QXNzZXRzUHJpY2UBCGFzc2V0SWRzCgEJZ2V0UHJpY2VzAgFhB2Fzc2V0SWQECmFzc2V0UHJpY2UJAQt2YWx1ZU9yRWxzZQIJAJoIAgUPcHJpY2VPcmFjbGVBZGRyCQCsAgIFB2Fzc2V0SWQFDmtQcmljZUluT3JhY2xlAP///////////wEJAM0IAgUBYQUKYXNzZXRQcmljZQoAAiRsBQhhc3NldElkcwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAFA25pbAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEJZ2V0UHJpY2VzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyA1MAkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIBDWdldFNoYXJlUHJpY2UBB3NoYXJlSWQEBHBvb2wJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzCQCsAgIFB3NoYXJlSWQFCmtTaGFyZVBvb2wCIENhbid0IGZpbmQgcG9vbCBhZGRyIGJ5IHNoYXJlIGlkBAhwb29sQWRkcgkBB0FkZHJlc3MBCQDZBAEFBHBvb2wEBXBUeXBlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwkArAICBQVrUG9vbAUEcG9vbAISUG9vbCBpcyBub3QgaW5pdGVkBA0kdDAxMTcwNjExNzcxCQELZ2V0UG9vbERhdGECBQhwb29sQWRkcgUFcFR5cGUEA2FJZAgFDSR0MDExNzA2MTE3NzECXzEEA2JJZAgFDSR0MDExNzA2MTE3NzECXzIECGFCYWxhbmNlCAUNJHQwMTE3MDYxMTc3MQJfMwQIYkJhbGFuY2UIBQ0kdDAxMTcwNjExNzcxAl80BAZwcmljZXMJAQ5nZXRBc3NldHNQcmljZQEJAMwIAgUDYUlkCQDMCAIFA2JJZAUDbmlsBAdkUHJpY2VBCQCRAwIFBnByaWNlcwAABAdkUHJpY2VCCQCRAwIFBnByaWNlcwABAwMJAGYCAAAFB2RQcmljZUEGCQBmAgAABQdkUHJpY2VCAP///////////wEEC3NoYXJlU3VwcGx5CQEOZ2V0U2hhcmVTdXBwbHkDBQhwb29sQWRkcgUFcFR5cGUFB3NoYXJlSWQECkFQcmVjaXNpb24JAGwGAAoAAAkBEGdldEFzc2V0RGVjaW1hbHMBBQNhSWQAAAAABQRET1dOBApCUHJlY2lzaW9uCQBsBgAKAAAJARBnZXRBc3NldERlY2ltYWxzAQUDYklkAAAAAAUERE9XTgQOc2hhcmVQcmVjaXNpb24JAGwGAAoAAAkBEGdldEFzc2V0RGVjaW1hbHMBBQdzaGFyZUlkAAAAAAUERE9XTgQDc3VtCQBkAgkAawMFCGFCYWxhbmNlBQdkUHJpY2VBBQpBUHJlY2lzaW9uCQBrAwUIYkJhbGFuY2UFB2RQcmljZUIFCkJQcmVjaXNpb24JAGsDBQNzdW0FDnNoYXJlUHJlY2lzaW9uBQtzaGFyZVN1cHBseQEOZ2V0U2hhcmVQcmljZXMBCHNoYXJlSWRzCgEJZ2V0UHJpY2VzAgFhB3NoYXJlSWQJAM0IAgUBYQkBDWdldFNoYXJlUHJpY2UBBQdzaGFyZUlkCgACJGwFCHNoYXJlSWRzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAQlnZXRQcmljZXMCBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDIwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAEOZ2V0Q3Vyc0VudHJpZXMEA2FJZANiSWQHc2hhcmVJZAh3QW1vdW50cwQMYXNzZXRzUHJpY2VzCQEOZ2V0QXNzZXRzUHJpY2UBCQDMCAIFA2FJZAkAzAgCBQNiSWQFA25pbAQKc2hhcmVQcmljZQkBDWdldFNoYXJlUHJpY2UBBQdzaGFyZUlkBAZwcmljZXMJAM4IAgkAzAgCCQCkAwEJAJEDAgUMYXNzZXRzUHJpY2VzAAAJAMwIAgkApAMBCQCRAwIFDGFzc2V0c1ByaWNlcwABCQDMCAIJAKQDAQUKc2hhcmVQcmljZQUDbmlsBQh3QW1vdW50cwkAzAgCCQELU3RyaW5nRW50cnkCBQ9rVG9rZW5MYXN0UHJpY2UJALkJAgUGcHJpY2VzAgEsBQNuaWwBGGNhbGNSZXBsZW5pc2hCeVR3b1Rva2VucwgFcFR5cGUIcG9vbEFkZHIEcG10QQNhSWQEcG10QgNiSWQEYmFsQQRiYWxCAwkAAAIFBXBUeXBlBQdTRl9QT09MBARyZXBsCgABQAkA/AcEBQhwb29sQWRkcgIMY2FsbEZ1bmN0aW9uCQDMCAICIGNhbGNMUFJlcGxlbmlzaFR3b1Rva2Vuc1JFQURPTkxZCQDMCAIJAMwIAgkApAMBBQRwbXRBCQDMCAIJAKQDAQUEcG10QgUDbmlsBQNuaWwFA25pbAMJAAECBQFAAglMaXN0W0FueV0FAUAJAAIBCQCsAgIJAAMBBQFAAh4gY291bGRuJ3QgYmUgY2FzdCB0byBMaXN0W0FueV0DCQAAAgUEcmVwbAUEcmVwbAkAlwoFCgABQAkAkQMCBQRyZXBsAAMDCQABAgUBQAIDSW50BQFACQACAQkArAICCQADAQUBQAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50CgABQAkAkQMCBQRyZXBsAAQDCQABAgUBQAIDSW50BQFACQACAQkArAICCQADAQUBQAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50CgABQAkAkQMCBQRyZXBsAAEDCQABAgUBQAIDSW50BQFACQACAQkArAICCQADAQUBQAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50CQEMYXNzZXRJZFRvU3RyAQkAkQMCBQRyZXBsAAIKAAFACQCRAwIFBHJlcGwAAAMJAAECBQFAAgNJbnQFAUAJAAIBCQCsAgIJAAMBBQFAAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DCQAAAgUFcFR5cGUFB1dYX1BPT0wEDSR0MDEzMzE1MTM1NjUJAJQKAgkAtQkCCgABQAkA/AcEBQhwb29sQWRkcgIgZXZhbHVhdGVQdXRCeUFtb3VudEFzc2V0UkVBRE9OTFkJAMwIAgUEcG10QQUDbmlsBQNuaWwDCQABAgUBQAIGU3RyaW5nBQFACQACAQkArAICCQADAQUBQAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nAgJfXwkAtQkCCgABQAkA/AcEBQhwb29sQWRkcgIfZXZhbHVhdGVQdXRCeVByaWNlQXNzZXRSRUFET05MWQkAzAgCBQRwbXRCBQNuaWwFA25pbAMJAAECBQFAAgZTdHJpbmcFAUAJAAIBCQCsAgIJAAMBBQFAAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcCAl9fAwkAAAIFDSR0MDEzMzE1MTM1NjUFDSR0MDEzMzE1MTM1NjUECmV2YWxQdXRJbkIIBQ0kdDAxMzMxNTEzNTY1Al8yBApldmFsUHV0SW5BCAUNJHQwMTMzMTUxMzU2NQJfMQQFbHBJbkEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQpldmFsUHV0SW5BAAEEBWxwSW5CCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKZXZhbFB1dEluQgABAwkAZgIFBWxwSW5CBQVscEluQQQDcG10CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKZXZhbFB1dEluQQAICQCXCgUFBHBtdEEFA3BtdAkAZQIFBHBtdEIFA3BtdAUDYklkBQVscEluQgQDcG10CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUKZXZhbFB1dEluQgAHCQCXCgUFA3BtdAUEcG10QgkAZQIFBHBtdEEFA3BtdAUDYUlkBQVscEluQQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkBD3Vua25vd25Qb29sVHlwZQABGHJlcGxlbmlzaFR3b1Rva2Vuc0J5VHlwZQYIcG9vbEFkZHIFcFR5cGUEcG10QQNhSWQEcG10QgNiSWQECHBheW1lbnRzCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEOYXNzZXRJZEZyb21TdHIBBQNhSWQFBHBtdEEJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQ5hc3NldElkRnJvbVN0cgEFA2JJZAUEcG10QgUDbmlsAwkAAAIFBXBUeXBlBQdTRl9QT09MCQD8BwQFCHBvb2xBZGRyAgxjYWxsRnVuY3Rpb24JAMwIAgIWcmVwbGVuaXNoV2l0aFR3b1Rva2VucwkAzAgCCQDMCAICBWZhbHNlCQDMCAICATAFA25pbAUDbmlsBQhwYXltZW50cwMJAAACBQVwVHlwZQUHV1hfUE9PTAkA/AcEBQhwb29sQWRkcgIDcHV0CQDMCAIAwIQ9CQDMCAIHBQNuaWwFCHBheW1lbnRzCQEPdW5rbm93blBvb2xUeXBlAAEXcmVwbGVuaXNoT25lVG9rZW5CeVR5cGUECHBvb2xBZGRyBXBUeXBlA3BtdAVwbXRJZAQIcGF5bWVudHMJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJAQ5hc3NldElkRnJvbVN0cgEFBXBtdElkBQNwbXQFA25pbAMJAAACBQVwVHlwZQUHU0ZfUE9PTAkA/AcEBQhwb29sQWRkcgIMY2FsbEZ1bmN0aW9uCQDMCAICFXJlcGxlbmlzaFdpdGhPbmVUb2tlbgkAzAgCCQDMCAICATAJAMwIAgIFZmFsc2UJAMwIAgIBMAUDbmlsBQNuaWwFCHBheW1lbnRzAwkAAAIFBXBUeXBlBQdXWF9QT09MCQD8BwQFCHBvb2xBZGRyAglwdXRPbmVUa24JAMwIAgAACQDMCAIHBQNuaWwFCHBheW1lbnRzCQEPdW5rbm93blBvb2xUeXBlAAEHc3Rha2VMUAQEcG9vbAVwVHlwZQdzaGFyZUlkBmFtb3VudAQIcGF5bWVudHMJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIJANkEAQUHc2hhcmVJZAUGYW1vdW50BQNuaWwDCQAAAgUFcFR5cGUFB1NGX1BPT0wJAPwHBAkBEGdldFNGRmFybWluZ0FkZHIAAg9sb2NrU2hhcmVUb2tlbnMJAMwIAgUEcG9vbAkAzAgCAAAFA25pbAUIcGF5bWVudHMDCQAAAgUFcFR5cGUFB1dYX1BPT0wJAPwHBAkBEGdldFdYRmFybWluZ0FkZHIBCQERQGV4dHJOYXRpdmUoMTA2MikBBQRwb29sAgVzdGFrZQUDbmlsBQhwYXltZW50cwkBD3Vua25vd25Qb29sVHlwZQABCXVuc3Rha2VMUAQEcG9vbAVwVHlwZQdzaGFyZUlkBmFtb3VudAQNJHQwMTUyMjQxNTU3NAMJAAACBQVwVHlwZQUHU0ZfUE9PTAkAlQoDCQEQZ2V0U0ZGYXJtaW5nQWRkcgACE3dpdGhkcmF3U2hhcmVUb2tlbnMJAMwIAgUEcG9vbAkAzAgCBQZhbW91bnQFA25pbAMJAAACBQVwVHlwZQUHV1hfUE9PTAkAlQoDCQEQZ2V0V1hGYXJtaW5nQWRkcgEJAQdBZGRyZXNzAQkA2QQBBQRwb29sAgd1bnN0YWtlCQDMCAIFB3NoYXJlSWQJAMwIAgUGYW1vdW50BQNuaWwJAQ91bmtub3duUG9vbFR5cGUABAhmYXJtQWRkcggFDSR0MDE1MjI0MTU1NzQCXzEEBWZOYW1lCAUNJHQwMTUyMjQxNTU3NAJfMgQGcGFyYW1zCAUNJHQwMTUyMjQxNTU3NAJfMwQDaW52CQD8BwQFCGZhcm1BZGRyBQVmTmFtZQUGcGFyYW1zBQNuaWwDCQAAAgUDaW52BQNpbnYFBmFtb3VudAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgERY2FsY0Ftb3VudFRvUGF5U0YHBHBvb2wIYXNzZXRJZEEIYXNzZXRJZEIEYmFsQQRiYWxCEGFtb3VudFRva2VuVG9HZXQPYXNzZXRUb2tlblRvR2V0BAhwb29sQWRkcgkBB0FkZHJlc3MBCQDZBAEFBHBvb2wECWZlZVNjYWxlNgDAhD0EA2ZlZQkBEUBleHRyTmF0aXZlKDEwNTApAgUIcG9vbEFkZHIFCmtTRlBvb2xGZWUEDGFtbnRHZXROb0ZlZQkAbgQFEGFtb3VudFRva2VuVG9HZXQFCWZlZVNjYWxlNgkAZQIFCWZlZVNjYWxlNgUDZmVlBQdDRUlMSU5HBA0kdDAxNTk5NjE2MzAyAwkAAAIFD2Fzc2V0VG9rZW5Ub0dldAUIYXNzZXRJZEEEC2Ftb3VudFRvUGF5CQBuBAUMYW1udEdldE5vRmVlBQRiYWxCCQBlAgUEYmFsQQUMYW1udEdldE5vRmVlBQdDRUlMSU5HCQCUCgIFC2Ftb3VudFRvUGF5BQhhc3NldElkQgQLYW1vdW50VG9QYXkJAG4EBQxhbW50R2V0Tm9GZWUFBGJhbEEJAGUCBQRiYWxCBQxhbW50R2V0Tm9GZWUFB0NFSUxJTkcJAJQKAgULYW1vdW50VG9QYXkFCGFzc2V0SWRBBAthbW91bnRUb1BheQgFDSR0MDE1OTk2MTYzMDICXzEECmFzc2V0VG9QYXkIBQ0kdDAxNTk5NjE2MzAyAl8yCQCUCgIFCmFzc2V0VG9QYXkFC2Ftb3VudFRvUGF5AQ1nZXRXWFN3YXBGZWVzAQRwb29sBAhwb29sQWRkcgkBEUBleHRyTmF0aXZlKDEwNjIpAQUEcG9vbAQJZkNvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUIcG9vbEFkZHICEyVzX19mYWN0b3J5Q29udHJhY3QCIkNhbid0IGdldCBXWCBmYWN0b3J5IGNvbnRyYWN0IGFkZHIEDnBvb2xGZWVEZWZhdWx0CQEFdmFsdWUBCQCaCAIFDnd4U3dhcENvbnRyYWN0Agslc19fcG9vbEZlZQQScHJvdG9jb2xGZWVEZWZhdWx0CQEFdmFsdWUBCQCaCAIFDnd4U3dhcENvbnRyYWN0Ag8lc19fcHJvdG9jb2xGZWUEByRtYXRjaDAJAPwHBAUJZkNvbnRyYWN0AhJnZXRTd2FwRmVlUkVBRE9OTFkJAMwIAgkApQgBBQhwb29sQWRkcgUDbmlsBQNuaWwDCQABAgUHJG1hdGNoMAIKKEludCwgSW50KQQEZmVlcwUHJG1hdGNoMAkAlAoCCAUEZmVlcwJfMQgFBGZlZXMCXzIJAJQKAgUOcG9vbEZlZURlZmF1bHQFEnByb3RvY29sRmVlRGVmYXVsdAERY2FsY0Ftb3VudFRvUGF5V1gHBHBvb2wIYXNzZXRJZEEIYXNzZXRJZEIEYmFsQQRiYWxCEGFtb3VudFRva2VuVG9HZXQPYXNzZXRUb2tlblRvR2V0BA0kdDAxNzA0MjE3MDgxCQENZ2V0V1hTd2FwRmVlcwEFBHBvb2wEBHBGZWUIBQ0kdDAxNzA0MjE3MDgxAl8xBAVwckZlZQgFDSR0MDE3MDQyMTcwODECXzIECGZlZVNjYWxlCQC2AgEAgMLXLwQNJHQwMTcxMjExNzQyOQMJAAACBQ9hc3NldFRva2VuVG9HZXQFCGFzc2V0SWRBBAthbW91bnRUb1BheQkAawMFEGFtb3VudFRva2VuVG9HZXQFBGJhbEIJAGUCBQRiYWxBBRBhbW91bnRUb2tlblRvR2V0CQCUCgIFC2Ftb3VudFRvUGF5BQhhc3NldElkQgQLYW1vdW50VG9QYXkJAGsDBRBhbW91bnRUb2tlblRvR2V0BQRiYWxBCQBlAgUEYmFsQgUQYW1vdW50VG9rZW5Ub0dldAkAlAoCBQthbW91bnRUb1BheQUIYXNzZXRJZEEEC2Ftb3VudFRvUGF5CAUNJHQwMTcxMjExNzQyOQJfMQQKYXNzZXRUb1BheQgFDSR0MDE3MTIxMTc0MjkCXzIEEmFtb3VudFRvUGF5V2l0aEZlZQkAoAMBCQC9AgQJALYCAQULYW1vdW50VG9QYXkFCGZlZVNjYWxlCQC4AgIFCGZlZVNjYWxlCQC2AgEJAGQCBQVwckZlZQUEcEZlZQUHQ0VJTElORwkAlAoCBQphc3NldFRvUGF5BRJhbW91bnRUb1BheVdpdGhGZWUBEGV4Y2hhbmdlRGlyZWN0bHkIBXBUeXBlBHBvb2wIYXNzZXRJZEEIYXNzZXRJZEIEYmFsQQRiYWxCEGFtb3VudFRva2VuVG9HZXQPYXNzZXRUb2tlblRvR2V0AwkAAAIFBXBUeXBlBQdTRl9QT09MBA0kdDAxNzc3NjE3ODk4CQERY2FsY0Ftb3VudFRvUGF5U0YHBQRwb29sBQhhc3NldElkQQUIYXNzZXRJZEIFBGJhbEEFBGJhbEIFEGFtb3VudFRva2VuVG9HZXQFD2Fzc2V0VG9rZW5Ub0dldAQKYXNzZXRUb1BheQgFDSR0MDE3Nzc2MTc4OTgCXzEEC2Ftb3VudFRvUGF5CAUNJHQwMTc3NzYxNzg5OAJfMgkA/AcECQERQGV4dHJOYXRpdmUoMTA2MikBBQRwb29sAgxjYWxsRnVuY3Rpb24JAMwIAgIIZXhjaGFuZ2UJAMwIAgkAzAgCCQCkAwEFEGFtb3VudFRva2VuVG9HZXQFA25pbAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEOYXNzZXRJZEZyb21TdHIBBQphc3NldFRvUGF5BQthbW91bnRUb1BheQUDbmlsAwkAAAIFBXBUeXBlBQdXWF9QT09MBA0kdDAxODA5ODE4MjIwCQERY2FsY0Ftb3VudFRvUGF5V1gHBQRwb29sBQhhc3NldElkQQUIYXNzZXRJZEIFBGJhbEEFBGJhbEIFEGFtb3VudFRva2VuVG9HZXQFD2Fzc2V0VG9rZW5Ub0dldAQKYXNzZXRUb1BheQgFDSR0MDE4MDk4MTgyMjACXzEEC2Ftb3VudFRvUGF5CAUNJHQwMTgwOTgxODIyMAJfMgkA/AcEBQ53eFN3YXBDb250cmFjdAIEc3dhcAkAzAgCBRBhbW91bnRUb2tlblRvR2V0CQDMCAIFD2Fzc2V0VG9rZW5Ub0dldAkAzAgCCQClCAEFBHRoaXMFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBDmFzc2V0SWRGcm9tU3RyAQUKYXNzZXRUb1BheQULYW1vdW50VG9QYXkFA25pbAkBD3Vua25vd25Qb29sVHlwZQABGmNhbGNXaXRoZHJhd0xQRnJvbVBvb2xWaXJ0BAhwb29sQWRkcgVwVHlwZQdzaGFyZUlkD3VzZXJDYW5XaXRoZHJhdwQNJHQwMTg1MDcxODk3MQMJAAACBQVwVHlwZQUHU0ZfUE9PTAQDaW52CgABQAkA/AcEBQhwb29sQWRkcgIMY2FsbEZ1bmN0aW9uCQDMCAICEHdpdGhkcmF3UkVBRE9OTFkJAMwIAgkAzAgCCQCkAwEFD3VzZXJDYW5XaXRoZHJhdwUDbmlsBQNuaWwFA25pbAMJAAECBQFAAglMaXN0W0FueV0FAUAJAAIBCQCsAgIJAAMBBQFAAh4gY291bGRuJ3QgYmUgY2FzdCB0byBMaXN0W0FueV0DCQAAAgUDaW52BQNpbnYJAJQKAgoAAUAJAJEDAgUDaW52AAADCQABAgUBQAIDSW50BQFACQACAQkArAICCQADAQUBQAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50CgABQAkAkQMCBQNpbnYAAQMJAAECBQFAAgNJbnQFAUAJAAIBCQCsAgIJAAMBBQFAAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DCQAAAgUFcFR5cGUFB1dYX1BPT0wEA2ludgkAtQkCCgABQAkA/AcEBQhwb29sQWRkcgITZXZhbHVhdGVHZXRSRUFET05MWQkAzAgCBQdzaGFyZUlkCQDMCAIFD3VzZXJDYW5XaXRoZHJhdwUDbmlsBQNuaWwDCQABAgUBQAIGU3RyaW5nBQFACQACAQkArAICCQADAQUBQAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nAgJfXwMJAAACBQNpbnYFA2ludgkAlAoCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUDaW52AAEJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQNpbnYAAgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkBD3Vua25vd25Qb29sVHlwZQAEB2Ftb3VudEEIBQ0kdDAxODUwNzE4OTcxAl8xBAdhbW91bnRCCAUNJHQwMTg1MDcxODk3MQJfMgkAlAoCBQdhbW91bnRBBQdhbW91bnRCAQtjbGFpbUZhcm1lZAIFcFR5cGUEcG9vbAMJAAACBQVwVHlwZQUHU0ZfUE9PTAQJYmFsQmVmb3JlCQEOYWNjb3VudEJhbGFuY2UBBQZTV09QSUQDCQAAAgUJYmFsQmVmb3JlBQliYWxCZWZvcmUEA2ludgkA/AcECQEQZ2V0U0ZGYXJtaW5nQWRkcgACBWNsYWltCQDMCAIFBHBvb2wFA25pbAUDbmlsAwkAAAIFA2ludgUDaW52BAhiYWxBZnRlcgkBDmFjY291bnRCYWxhbmNlAQUGU1dPUElECQCUCgIJAGUCBQhiYWxBZnRlcgUJYmFsQmVmb3JlBQZTV09QSUQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DCQAAAgUFcFR5cGUFB1dYX1BPT0wEDSR0MDE5MzM5MTk0MTgJAQ1nZXRXWFBvb2xEYXRhAQkBEUBleHRyTmF0aXZlKDEwNjIpAQUEcG9vbAQDYUlkCAUNJHQwMTkzMzkxOTQxOAJfMQQDYklkCAUNJHQwMTkzMzkxOTQxOAJfMgQEYUJhbAgFDSR0MDE5MzM5MTk0MTgCXzMEBGJCYWwIBQ0kdDAxOTMzOTE5NDE4Al80BARscElkCAUNJHQwMTkzMzkxOTQxOAJfNQQJYmFsQmVmb3JlCQEOYWNjb3VudEJhbGFuY2UBBQRXWElEAwkAAAIFCWJhbEJlZm9yZQUJYmFsQmVmb3JlBANpbnYJAPwHBAkBEGdldFdYRmFybWluZ0FkZHIBCQERQGV4dHJOYXRpdmUoMTA2MikBBQRwb29sAgdjbGFpbVd4CQDMCAIFBGxwSWQFA25pbAUDbmlsAwkAAAIFA2ludgUDaW52BAhiYWxBZnRlcgkBDmFjY291bnRCYWxhbmNlAQUEV1hJRAkAlAoCCQBlAgUIYmFsQWZ0ZXIFCWJhbEJlZm9yZQUEV1hJRAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkBD3Vua25vd25Qb29sVHlwZQABD3JlcGxlbmlzaEJ5VHlwZQoFcFR5cGUEcG9vbAdmZWVUeXBlBHBtdEEDYUlkBHBtdEIDYklkBGJhbEEEYmFsQgRMUElkBA9scEJhbGFuY2VCZWZvcmUJAQ5hY2NvdW50QmFsYW5jZQEJANkEAQUETFBJZAMJAAACBQ9scEJhbGFuY2VCZWZvcmUFD2xwQmFsYW5jZUJlZm9yZQQIcG9vbEFkZHIJARFAZXh0ck5hdGl2ZSgxMDYyKQEFBHBvb2wEDSR0MDIwMDE2MjA0MzIDAwkAZgIFBHBtdEEAAAkAZgIFBHBtdEIAAAcEDSR0MDIwMDgyMjAxOTgJARhjYWxjUmVwbGVuaXNoQnlUd29Ub2tlbnMIBQVwVHlwZQUIcG9vbEFkZHIFBHBtdEEFA2FJZAUEcG10QgUDYklkBQRiYWxBBQRiYWxCBAZwbXRJbkEIBQ0kdDAyMDA4MjIwMTk4Al8xBAZwbXRJbkIIBQ0kdDAyMDA4MjIwMTk4Al8yBAZjaGFuZ2UIBQ0kdDAyMDA4MjIwMTk4Al8zBAhjaGFuZ2VJZAgFDSR0MDIwMDgyMjAxOTgCXzQEA2ludgkBGHJlcGxlbmlzaFR3b1Rva2Vuc0J5VHlwZQYFCHBvb2xBZGRyBQVwVHlwZQUGcG10SW5BBQNhSWQFBnBtdEluQgUDYklkAwkAAAIFA2ludgUDaW52CQCUCgIFBmNoYW5nZQUIY2hhbmdlSWQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DCQBmAgUEcG10QQAACQCUCgIFBHBtdEEFA2FJZAMJAGYCBQRwbXRCAAAJAJQKAgUEcG10QgUDYklkCQACAQIQcG10cyBtdXN0IGJlID4gMAQGY2hhbmdlCAUNJHQwMjAwMTYyMDQzMgJfMQQIY2hhbmdlSWQIBQ0kdDAyMDAxNjIwNDMyAl8yBANpbnYDCQBmAgUGY2hhbmdlAAAJARdyZXBsZW5pc2hPbmVUb2tlbkJ5VHlwZQQFCHBvb2xBZGRyBQVwVHlwZQUGY2hhbmdlBQhjaGFuZ2VJZAUDbmlsAwkAAAIFA2ludgUDaW52BA5scEJhbGFuY2VBZnRlcgkBDmFjY291bnRCYWxhbmNlAQkA2QQBBQRMUElkBAt0b3RhbFN0YWtlZAkAZQIFDmxwQmFsYW5jZUFmdGVyBQ9scEJhbGFuY2VCZWZvcmUEDWF4bHlGZWVBbW91bnQJAGsDBQt0b3RhbFN0YWtlZAkBCmdldEF4bHlGZWUCBQRwb29sBQdmZWVUeXBlBQpGRUVfU0NBTEU2BBF1c2VyU2hhcmVGb3JTdGFrZQkAZQIFC3RvdGFsU3Rha2VkBQ1heGx5RmVlQW1vdW50AwkAZwIAAAURdXNlclNoYXJlRm9yU3Rha2UJAAIBAihhbW91bnQgb2Ygc3Rha2VkIHNoYXJldG9rZW5zIG11c3QgYmUgPiAwBAVpbnZMUAkBB3N0YWtlTFAEBQRwb29sBQVwVHlwZQUETFBJZAURdXNlclNoYXJlRm9yU3Rha2UDCQAAAgUFaW52TFAFBWludkxQCQCUCgIFEXVzZXJTaGFyZUZvclN0YWtlBQ1heGx5RmVlQW1vdW50CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuARByZXBsZW5pc2hFbnRyaWVzCARwb29sBHVzZXIMc3Rha2VkQW1vdW50DWF4bHlGZWVBbW91bnQGcG9zTnVtB3NoYXJlSWQEdHlwZQh3aXRoTG9hbgQLdG90YWxBbW91bnQJARFnZXRQb29sVG90YWxTaGFyZQEFBHBvb2wED3RvdGFsQW1vdW50TG9hbgkBGWdldFBvb2xUb3RhbFNoYXJlV2l0aExvYW4BBQRwb29sBA0kdDAyMTI4OTIxNTI3AwUId2l0aExvYW4JAJQKAgkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkArAICBQRwb29sBRFrUG9vbEludGVyZXN0TG9hbgkAZAIFD3RvdGFsQW1vdW50TG9hbgUMc3Rha2VkQW1vdW50CQCUCgIJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAKwCAgUEcG9vbAUTa1Bvb2xJbnRlcmVzdE5vTG9hbgUPdG90YWxBbW91bnRMb2FuBA9jdXJQb29sSW50ZXJlc3QIBQ0kdDAyMTI4OTIxNTI3Al8xBBN0b3RhbFN0YWtlZFdpdGhMb2FuCAUNJHQwMjEyODkyMTUyNwJfMgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBQprUG9vbFRvdGFsCQBkAgULdG90YWxBbW91bnQFDHN0YWtlZEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBQ5rUG9vbFRvdGFsTG9hbgUTdG90YWxTdGFrZWRXaXRoTG9hbgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8JAKQDAQUGcG9zTnVtBQ1rVXNlclBvc2l0aW9uBQxzdGFrZWRBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyAgFfCQCkAwEFBnBvc051bQUVa1VzZXJQb3NpdGlvbkludGVyZXN0BQ9jdXJQb29sSW50ZXJlc3QJAMwIAgkBC1N0cmluZ0VudHJ5AgkArAICCQCsAgIJAKwCAgUEdXNlcgIBXwkApAMBBQZwb3NOdW0FEWtVc2VyUG9zaXRpb25Qb29sBQRwb29sCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHVzZXIFEGtVc2VyUG9zaXRpb25OdW0FBnBvc051bQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQhtb25leUJveAUNYXhseUZlZUFtb3VudAkA2QQBBQdzaGFyZUlkBQNuaWwBDmV4Y2hhbmdlS2VlcGVyCgd0b1Rva2VuCXBtdEFtb3VudAhwbXRBc3NldAlhbW91bnRzSW4JYWRkcmVzc2VzD2Fzc2V0c1RvUmVjZWl2ZQtlc3RSZWNlaXZlZBFzbGlwcGFnZVRvbGVyYW5jZQttaW5SZWNlaXZlZAdvcHRpb25zBBJ0b2tlbkJhbGFuY2VCZWZvcmUJAQ5hY2NvdW50QmFsYW5jZQEJAQ5hc3NldElkRnJvbVN0cgEFB3RvVG9rZW4DCQAAAgUSdG9rZW5CYWxhbmNlQmVmb3JlBRJ0b2tlbkJhbGFuY2VCZWZvcmUEA2ludgkA/AcEBQpleENvbnRyYWN0AgRzd2FwCQDMCAIFCWFtb3VudHNJbgkAzAgCBQlhZGRyZXNzZXMJAMwIAgUPYXNzZXRzVG9SZWNlaXZlCQDMCAIFC2VzdFJlY2VpdmVkCQDMCAIFEXNsaXBwYWdlVG9sZXJhbmNlCQDMCAIFC21pblJlY2VpdmVkCQDMCAIFB29wdGlvbnMFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUIcG10QXNzZXQFCXBtdEFtb3VudAUDbmlsAwkAAAIFA2ludgUDaW52CQBlAgkBDmFjY291bnRCYWxhbmNlAQkBDmFzc2V0SWRGcm9tU3RyAQUHdG9Ub2tlbgUSdG9rZW5CYWxhbmNlQmVmb3JlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQ5leGNoYW5nZVB1enpsZQYHdG9Ub2tlbglwbXRBbW91bnQIcG10QXNzZXQJcm91dGVzU3RyDG1pblRvUmVjZWl2ZQdvcHRpb25zBBJ0b2tlbkJhbGFuY2VCZWZvcmUJAQ5hY2NvdW50QmFsYW5jZQEJAQ5hc3NldElkRnJvbVN0cgEFB3RvVG9rZW4DCQAAAgUSdG9rZW5CYWxhbmNlQmVmb3JlBRJ0b2tlbkJhbGFuY2VCZWZvcmUEA2ludgkA/AcEBQpleENvbnRyYWN0AgpwdXp6bGVTd2FwCQDMCAIFCXJvdXRlc1N0cgkAzAgCBQxtaW5Ub1JlY2VpdmUJAMwIAgUHb3B0aW9ucwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQhwbXRBc3NldAUJcG10QW1vdW50BQNuaWwDCQAAAgUDaW52BQNpbnYJAGUCCQEOYWNjb3VudEJhbGFuY2UBCQEOYXNzZXRJZEZyb21TdHIBBQd0b1Rva2VuBRJ0b2tlbkJhbGFuY2VCZWZvcmUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BDmV4Y2hhbmdlU3dvcEZpCgd0b1Rva2VuCXBtdEFtb3VudAhwbXRBc3NldApleGNoYW5nZXJzDmV4Y2hhbmdlcnNUeXBlBWFyZ3MxBWFyZ3MyEXJvdXRpbmdBc3NldHNLZXlzEm1pbkFtb3VudFRvUmVjZWl2ZQdvcHRpb25zBBJ0b2tlbkJhbGFuY2VCZWZvcmUJAQ5hY2NvdW50QmFsYW5jZQEJAQ5hc3NldElkRnJvbVN0cgEFB3RvVG9rZW4DCQAAAgUSdG9rZW5CYWxhbmNlQmVmb3JlBRJ0b2tlbkJhbGFuY2VCZWZvcmUEA2ludgkA/AcEBQpleENvbnRyYWN0Agpzd29wZmlTd2FwCQDMCAIFCmV4Y2hhbmdlcnMJAMwIAgUOZXhjaGFuZ2Vyc1R5cGUJAMwIAgUFYXJnczEJAMwIAgUFYXJnczIJAMwIAgURcm91dGluZ0Fzc2V0c0tleXMJAMwIAgUSbWluQW1vdW50VG9SZWNlaXZlCQDMCAIFB29wdGlvbnMFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUIcG10QXNzZXQFCXBtdEFtb3VudAUDbmlsAwkAAAIFA2ludgUDaW52CQBlAgkBDmFjY291bnRCYWxhbmNlAQkBDmFzc2V0SWRGcm9tU3RyAQUHdG9Ub2tlbgUSdG9rZW5CYWxhbmNlQmVmb3JlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQpjYXBpdGFsaXplBARwb29sBXBUeXBlB3Rva2VuSWQLdG9rZW5BbW91bnQECHBvb2xBZGRyCQEHQWRkcmVzcwEJANkEAQUEcG9vbAQNJHQwMjM4ODEyMzk0NwkBC2dldFBvb2xEYXRhAgUIcG9vbEFkZHIFBXBUeXBlBANBSWQIBQ0kdDAyMzg4MTIzOTQ3Al8xBANCSWQIBQ0kdDAyMzg4MTIzOTQ3Al8yBARiYWxBCAUNJHQwMjM4ODEyMzk0NwJfMwQEYmFsQggFDSR0MDIzODgxMjM5NDcCXzQEB3NoYXJlSWQIBQ0kdDAyMzg4MTIzOTQ3Al81AwMJAQIhPQIFB3Rva2VuSWQFA0FJZAkBAiE9AgUHdG9rZW5JZAUDQklkBwkAAgECC1dyb25nIGFzc2V0BBB0b3RhbFNoYXJlQW1vdW50CQERZ2V0UG9vbFRvdGFsU2hhcmUBBQRwb29sBBh0b3RhbFNoYXJlQW1vdW50V2l0aExvYW4JARlnZXRQb29sVG90YWxTaGFyZVdpdGhMb2FuAQUEcG9vbAQLbG9hblBlcmNlbnQJAGsDBRh0b3RhbFNoYXJlQW1vdW50V2l0aExvYW4FBlNDQUxFOAUQdG90YWxTaGFyZUFtb3VudAQQdG9rZW5zRm9yRmVlTG9hbgkAawMFC3Rva2VuQW1vdW50BQtsb2FuUGVyY2VudAUGU0NBTEU4BBJ0b2tlbnNGb3JGZWVOb0xvYW4JAGUCBQt0b2tlbkFtb3VudAUQdG9rZW5zRm9yRmVlTG9hbgQLYXhseUZlZUxvYW4JAGsDBRB0b2tlbnNGb3JGZWVMb2FuCQEKZ2V0QXhseUZlZQIFBHBvb2wFDENBUF9GRUVfTE9BTgUKRkVFX1NDQUxFNgQNYXhseUZlZU5vTG9hbgkAawMFEnRva2Vuc0ZvckZlZU5vTG9hbgkBCmdldEF4bHlGZWUCBQRwb29sBQ9DQVBfRkVFX05PX0xPQU4FCkZFRV9TQ0FMRTYEB2F4bHlGZWUJAGQCBQtheGx5RmVlTG9hbgUNYXhseUZlZU5vTG9hbgQNJHQwMjQ1ODcyNDY4NwMJAAACBQd0b2tlbklkBQNBSWQJAJQKAgkAZQIFC3Rva2VuQW1vdW50BQdheGx5RmVlAAAJAJQKAgAACQBlAgULdG9rZW5BbW91bnQFB2F4bHlGZWUEBHBtdEEIBQ0kdDAyNDU4NzI0Njg3Al8xBARwbXRCCAUNJHQwMjQ1ODcyNDY4NwJfMgQNJHQwMjQ2OTAyNDc5NAkBD3JlcGxlbmlzaEJ5VHlwZQoFBXBUeXBlBQRwb29sBQZOT19GRUUFBHBtdEEFA0FJZAUEcG10QgUDQklkBQRiYWxBBQRiYWxCBQdzaGFyZUlkBAxzdGFrZWRBbW91bnQIBQ0kdDAyNDY5MDI0Nzk0Al8xBAJuZggFDSR0MDI0NjkwMjQ3OTQCXzIEE2N1clBvb2xJbnRlcmVzdExvYW4JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICBQRwb29sBRFrUG9vbEludGVyZXN0TG9hbgAABBVjdXJQb29sSW50ZXJlc3ROb0xvYW4JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICBQRwb29sBRNrUG9vbEludGVyZXN0Tm9Mb2FuAAAECnN0YWtlZExvYW4JAGsDBQxzdGFrZWRBbW91bnQFC2xvYW5QZXJjZW50BQZTQ0FMRTgEDHN0YWtlZE5vTG9hbgkAZQIFDHN0YWtlZEFtb3VudAUKc3Rha2VkTG9hbgQPbmV3SW50ZXJlc3RMb2FuAwkAZgIFGHRvdGFsU2hhcmVBbW91bnRXaXRoTG9hbgAACQBkAgUTY3VyUG9vbEludGVyZXN0TG9hbgkAawMFCnN0YWtlZExvYW4FB1NDQUxFMTAFGHRvdGFsU2hhcmVBbW91bnRXaXRoTG9hbgAABBFuZXdJbnRlcmVzdE5vTG9hbgMJAGYCCQBlAgUQdG90YWxTaGFyZUFtb3VudAUYdG90YWxTaGFyZUFtb3VudFdpdGhMb2FuAAAJAGQCBRVjdXJQb29sSW50ZXJlc3ROb0xvYW4JAGsDBQxzdGFrZWROb0xvYW4FB1NDQUxFMTAJAGUCBRB0b3RhbFNoYXJlQW1vdW50BRh0b3RhbFNoYXJlQW1vdW50V2l0aExvYW4AAAkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFBHBvb2wFEWtQb29sSW50ZXJlc3RMb2FuBQ9uZXdJbnRlcmVzdExvYW4JAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUTa1Bvb2xJbnRlcmVzdE5vTG9hbgURbmV3SW50ZXJlc3ROb0xvYW4JAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUKa1Bvb2xUb3RhbAkAZAIFEHRvdGFsU2hhcmVBbW91bnQFDHN0YWtlZEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBQ5rUG9vbFRvdGFsTG9hbgkAZAIFGHRvdGFsU2hhcmVBbW91bnRXaXRoTG9hbgUKc3Rha2VkTG9hbgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQhtb25leUJveAUHYXhseUZlZQkA2QQBBQd0b2tlbklkBQNuaWwJAQ5nZXRDdXJzRW50cmllcwQFA0FJZAUDQklkBQdzaGFyZUlkBQNuaWwBGHVzZXJDYW5XaXRoZHJhd1NoYXJlQ2FsYwQEdXNlcgRwb29sBXBvc0lkCGJvcnJvd2VkBAdwQW1vdW50CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8FBXBvc0lkBQ1rVXNlclBvc2l0aW9uAhBVbmtub3duIHBvc2l0aW9uBAx1c2VySW50ZXJlc3QJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyAgFfBQVwb3NJZAUVa1VzZXJQb3NpdGlvbkludGVyZXN0BAxwb29sSW50ZXJlc3QDBQhib3Jyb3dlZAkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkArAICBQRwb29sBRFrUG9vbEludGVyZXN0TG9hbgkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkArAICBQRwb29sBRNrUG9vbEludGVyZXN0Tm9Mb2FuCQBkAgUHcEFtb3VudAkAawMFB3BBbW91bnQJAGUCBQxwb29sSW50ZXJlc3QFDHVzZXJJbnRlcmVzdAUHU0NBTEUxMAEPY2FsY1N0b3BMb3NzRmVlBARwb29sCmlzQm9ycm93ZWQIc3RvcExvc3MKbHBXaXRoZHJhdwQHZmVlVHlwZQMFCmlzQm9ycm93ZWQFDVNUT1BMT1NTX0xPQU4FFFNUT1BMT1NTX0ZFRV9OT19MT0FOAwUIc3RvcExvc3MJAGsDBQpscFdpdGhkcmF3CQEKZ2V0QXhseUZlZQIFBHBvb2wFB2ZlZVR5cGUFCkZFRV9TQ0FMRTYAAAEOd2l0aGRyYXdUb1VzZXIEBHVzZXIEcG9vbAVwb3NJZAhzdG9wTG9zcwQHcEFtb3VudAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFBHRoaXMJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyAgFfBQVwb3NJZAUNa1VzZXJQb3NpdGlvbgIQVW5rbm93biBwb3NpdGlvbgQKaXNCb3Jyb3dlZAkAZgIJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8FBXBvc0lkBRFrVXNlckJvcnJvd0Ftb3VudAAAAAAED3VzZXJDYW5XaXRoZHJhdwkBGHVzZXJDYW5XaXRoZHJhd1NoYXJlQ2FsYwQFBHVzZXIFBHBvb2wFBXBvc0lkBQppc0JvcnJvd2VkBA5wb29sVG90YWxTaGFyZQkBEWdldFBvb2xUb3RhbFNoYXJlAQUEcG9vbAQScG9vbFRvdGFsU2hhcmVMb2FuCQEZZ2V0UG9vbFRvdGFsU2hhcmVXaXRoTG9hbgEFBHBvb2wECHVzZXJBZGRyCQEHQWRkcmVzcwEJANkEAQUEdXNlcgQIcG9vbEFkZHIJAQdBZGRyZXNzAQkA2QQBBQRwb29sBAVwVHlwZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMJAKwCAgUFa1Bvb2wFBHBvb2wCDFVua25vd24gcG9vbAQNJHQwMjczMjUyNzM5NwkBC2dldFBvb2xEYXRhAgUIcG9vbEFkZHIFBXBUeXBlBAZpZEFTdHIIBQ0kdDAyNzMyNTI3Mzk3Al8xBAZpZEJTdHIIBQ0kdDAyNzMyNTI3Mzk3Al8yBARiYWxBCAUNJHQwMjczMjUyNzM5NwJfMwQEYmFsQggFDSR0MDI3MzI1MjczOTcCXzQEB3NoYXJlSWQIBQ0kdDAyNzMyNTI3Mzk3Al81BA0kdDAyNzQwMDI3NDY3CQCUCgIJAQ5hc3NldElkRnJvbVN0cgEFBmlkQVN0cgkBDmFzc2V0SWRGcm9tU3RyAQUGaWRCU3RyBANpZEEIBQ0kdDAyNzQwMDI3NDY3Al8xBANpZEIIBQ0kdDAyNzQwMDI3NDY3Al8yBAtzdG9wTG9zc0ZlZQkBD2NhbGNTdG9wTG9zc0ZlZQQFBHBvb2wFCmlzQm9ycm93ZWQFCHN0b3BMb3NzBQ91c2VyQ2FuV2l0aGRyYXcEC2NCYWxBQmVmb3JlCQEOYWNjb3VudEJhbGFuY2UBBQNpZEEDCQAAAgULY0JhbEFCZWZvcmUFC2NCYWxBQmVmb3JlBAtjQmFsQkJlZm9yZQkBDmFjY291bnRCYWxhbmNlAQUDaWRCAwkAAAIFC2NCYWxCQmVmb3JlBQtjQmFsQkJlZm9yZQQDaW52AwkAAAIFBXBUeXBlBQdTRl9QT09MBANpbnYJAQl1bnN0YWtlTFAEBQRwb29sBQVwVHlwZQUHc2hhcmVJZAULc3RvcExvc3NGZWUDCQAAAgUDaW52BQNpbnYJAPwHBAUIcG9vbEFkZHICDGNhbGxGdW5jdGlvbgkAzAgCAgh3aXRoZHJhdwkAzAgCCQDMCAIJAKQDAQUPdXNlckNhbldpdGhkcmF3BQNuaWwFA25pbAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAwkAAAIFBXBUeXBlBQdXWF9QT09MBANpbnYJAQl1bnN0YWtlTFAEBQRwb29sBQVwVHlwZQUHc2hhcmVJZAkAZAIFD3VzZXJDYW5XaXRoZHJhdwULc3RvcExvc3NGZWUDCQAAAgUDaW52BQNpbnYJAPwHBAUIcG9vbEFkZHICA2dldAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQEOYXNzZXRJZEZyb21TdHIBBQdzaGFyZUlkBQ91c2VyQ2FuV2l0aGRyYXcFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkBD3Vua25vd25Qb29sVHlwZQADCQAAAgUDaW52BQNpbnYECmNCYWxBQWZ0ZXIJAQ5hY2NvdW50QmFsYW5jZQEFA2lkQQMJAAACBQpjQmFsQUFmdGVyBQpjQmFsQUFmdGVyBApjQmFsQkFmdGVyCQEOYWNjb3VudEJhbGFuY2UBBQNpZEIDCQAAAgUKY0JhbEJBZnRlcgUKY0JhbEJBZnRlcgQNJHQwMjgxNjIyODI1MQkAlAoCCQBlAgUKY0JhbEFBZnRlcgULY0JhbEFCZWZvcmUJAGUCBQpjQmFsQkFmdGVyBQtjQmFsQkJlZm9yZQQNdG9rZW5zQW1vdW50QQgFDSR0MDI4MTYyMjgyNTECXzEEDXRva2Vuc0Ftb3VudEIIBQ0kdDAyODE2MjI4MjUxAl8yBA0kdDAyODI1NDI5NDkwAwUKaXNCb3Jyb3dlZAQLYm9ycm93QXNzZXQJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBHRoaXMJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyAgFfBQVwb3NJZAUSa1VzZXJCb3Jyb3dBc3NldElkBARkZWJ0CgABQAkA/AcECQEOZ2V0TGVuZFNydkFkZHIAAgxnZXRBc3NldERlYnQJAMwIAgcJAMwIAgkArAICCQCsAgIFBHVzZXICAV8FBXBvc0lkCQDMCAIFC2JvcnJvd0Fzc2V0BQNuaWwFA25pbAMJAAECBQFAAgNJbnQFAUAJAAIBCQCsAgIJAAMBBQFAAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQDCQAAAgUEZGVidAUEZGVidAQNYW1vdW50VG9HZXRFeAMDCQAAAgULYm9ycm93QXNzZXQFBmlkQVN0cgkAZgIFBGRlYnQFDXRva2Vuc0Ftb3VudEEHCQBlAgUEZGVidAUNdG9rZW5zQW1vdW50QQMDCQAAAgULYm9ycm93QXNzZXQFBmlkQlN0cgkAZgIFBGRlYnQFDXRva2Vuc0Ftb3VudEIHCQBlAgUEZGVidAUNdG9rZW5zQW1vdW50QgAABAVleEludgMJAGYCBQ1hbW91bnRUb0dldEV4AAAJARBleGNoYW5nZURpcmVjdGx5CAUFcFR5cGUFBHBvb2wFBmlkQVN0cgUGaWRCU3RyCQBlAgUEYmFsQQUNdG9rZW5zQW1vdW50QQkAZQIFBGJhbEIFDXRva2Vuc0Ftb3VudEIFDWFtb3VudFRvR2V0RXgFC2JvcnJvd0Fzc2V0BQNuaWwDCQAAAgUFZXhJbnYFBWV4SW52BA9jQmFsQUFmdGVyUmVwYXkJAQ5hY2NvdW50QmFsYW5jZQEFA2lkQQMJAAACBQ9jQmFsQUFmdGVyUmVwYXkFD2NCYWxBQWZ0ZXJSZXBheQQPY0JhbEJBZnRlclJlcGF5CQEOYWNjb3VudEJhbGFuY2UBBQNpZEIDCQAAAgUPY0JhbEJBZnRlclJlcGF5BQ9jQmFsQkFmdGVyUmVwYXkEC2Nsb3NlRGJ0SW52AwkAZgIFBGRlYnQAAAkA/AcECQEOZ2V0TGVuZFNydkFkZHIAAghyZXBheUZvcgkAzAgCCQCsAgIJAKwCAgUEdXNlcgIBXwUFcG9zSWQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkBDmFzc2V0SWRGcm9tU3RyAQULYm9ycm93QXNzZXQFBGRlYnQFA25pbAAAAwkAAAIFC2Nsb3NlRGJ0SW52BQtjbG9zZURidEludgMJAAACBQtib3Jyb3dBc3NldAUGaWRBU3RyCQCUCgIJAGUCCQBlAgUPY0JhbEFBZnRlclJlcGF5BQtjQmFsQUJlZm9yZQUEZGVidAkAZQIFD2NCYWxCQWZ0ZXJSZXBheQULY0JhbEJCZWZvcmUJAJQKAgkAZQIFD2NCYWxBQWZ0ZXJSZXBheQULY0JhbEFCZWZvcmUJAGUCCQBlAgUPY0JhbEJBZnRlclJlcGF5BQtjQmFsQkJlZm9yZQUEZGVidAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAlAoCBQ10b2tlbnNBbW91bnRBBQ10b2tlbnNBbW91bnRCBAd0b1VzZXJBCAUNJHQwMjgyNTQyOTQ5MAJfMQQHdG9Vc2VyQggFDSR0MDI4MjU0Mjk0OTACXzIEFHBvb2xUb3RhbExvYW5FbnRyaWVzAwUKaXNCb3Jyb3dlZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBQ5rUG9vbFRvdGFsTG9hbgkAZQIJAGUCBRJwb29sVG90YWxTaGFyZUxvYW4FD3VzZXJDYW5XaXRoZHJhdwULc3RvcExvc3NGZWUFA25pbAUDbmlsBAdlbnRyaWVzCQDOCAIJAM4IAgkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgIBXwUFcG9zSWQFDWtVc2VyUG9zaXRpb24JAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgIJAKwCAgUEdXNlcgIBXwUFcG9zSWQFEWtVc2VyUG9zaXRpb25Qb29sCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyAgFfBQVwb3NJZAURa1VzZXJCb3Jyb3dBbW91bnQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8FBXBvc0lkBRJrVXNlckJvcnJvd0Fzc2V0SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8FBXBvc0lkBRVrVXNlclBvc2l0aW9uSW50ZXJlc3QJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUKa1Bvb2xUb3RhbAkAZQIJAGUCBQ5wb29sVG90YWxTaGFyZQUPdXNlckNhbldpdGhkcmF3BQtzdG9wTG9zc0ZlZQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQh1c2VyQWRkcgUHdG9Vc2VyQQUDaWRBCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFCHVzZXJBZGRyBQd0b1VzZXJCBQNpZEIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUIbW9uZXlCb3gFC3N0b3BMb3NzRmVlCQDZBAEFB3NoYXJlSWQFA25pbAUUcG9vbFRvdGFsTG9hbkVudHJpZXMJAQ5nZXRDdXJzRW50cmllcwQFBmlkQVN0cgUGaWRCU3RyBQdzaGFyZUlkBQNuaWwJAJQKAgUHZW50cmllcwkAzAgCBQd0b1VzZXJBCQDMCAIFB3RvVXNlckIFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEMcGFyc2VSZXF1ZXN0AQlyZXF1ZXN0SWQEB3JlcXVlc3QJALUJAgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMJAKwCAgUJcmVxdWVzdElkBQprUmVxdWVzdElkCQCsAgICE05vIHJlcXVlc3Qgd2l0aCBpZCAFCXJlcXVlc3RJZAIBLAQEdXNlcgkAkQMCBQdyZXF1ZXN0AAAEBHBvb2wJAJEDAgUHcmVxdWVzdAABBARwbXRBCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHcmVxdWVzdAACBANBSWQJAJEDAgUHcmVxdWVzdAADBARwbXRCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHcmVxdWVzdAAEBANCSWQJAJEDAgUHcmVxdWVzdAAFBARiYWxBCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHcmVxdWVzdAAGBARiYWxCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHcmVxdWVzdAAHBAdzaGFyZUlkCQCRAwIFB3JlcXVlc3QACAQHYndBc3NldAkAkQMCBQdyZXF1ZXN0AAkECGJ3QW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUHcmVxdWVzdAAKCQCdCgsFBHVzZXIFBHBvb2wFBHBtdEEFA0FJZAUEcG10QgUDQklkBQRiYWxBBQRiYWxCBQdzaGFyZUlkBQdid0Fzc2V0BQhid0Ftb3VudAEQY2FsY0JvcnJvd0Ftb3VudAYEcG10QQRwbXRCA2FJZANiSWQIbGV2ZXJhZ2UIYm9ycm93SWQDAwkBAiE9AgUIYm9ycm93SWQFA2FJZAkBAiE9AgUIYm9ycm93SWQFA2JJZAcJAAIBAhJXcm9uZyBib3Jyb3cgYXNzZXQEB2RQcmljZUEJARFAZXh0ck5hdGl2ZSgxMDUwKQIFD3ByaWNlT3JhY2xlQWRkcgkArAICBQNhSWQFDmtQcmljZUluT3JhY2xlBAdkUHJpY2VCCQERQGV4dHJOYXRpdmUoMTA1MCkCBQ9wcmljZU9yYWNsZUFkZHIJAKwCAgUDYklkBQ5rUHJpY2VJbk9yYWNsZQQGZGVjUHJBCQBsBgAKAAAJARBnZXRBc3NldERlY2ltYWxzAQUDYUlkAAAAAAUERE9XTgQGZGVjUHJCCQBsBgAKAAAJARBnZXRBc3NldERlY2ltYWxzAQUDYklkAAAAAAUERE9XTgQMcGF5ZEluRG9sbGFyCQBkAgkAawMFB2RQcmljZUEFBHBtdEEFBmRlY1ByQQkAawMFB2RQcmljZUIFBHBtdEIFBmRlY1ByQgQNJHQwMzE0NzIzMTU2OQMJAAACBQhib3Jyb3dJZAUDYUlkCQCUCgIFB2RQcmljZUEFBmRlY1ByQQkAlAoCBQdkUHJpY2VCBQZkZWNQckIEC2JvcnJvd1ByaWNlCAUNJHQwMzE0NzIzMTU2OQJfMQQLYm9ycm93RGVjUHIIBQ0kdDAzMTQ3MjMxNTY5Al8yCQBrAwkAawMFDHBheWRJbkRvbGxhcgkAZQIFCGxldmVyYWdlAGQAZAULYm9ycm93RGVjUHIFC2JvcnJvd1ByaWNlARJwYXJzZVJlcGxlbmlzaFBtdHMDBHBtdHMDQUlkA0JJZAMJAAACCQCQAwEFBHBtdHMAAgMJAQIhPQIJAQxhc3NldElkVG9TdHIBCAkAkQMCBQRwbXRzAAAHYXNzZXRJZAUDQUlkCQACAQIVV3JvbmcgcGF5bWVudCBhc3NldCBBAwkBAiE9AgkBDGFzc2V0SWRUb1N0cgEICQCRAwIFBHBtdHMAAQdhc3NldElkBQNCSWQJAAIBAhVXcm9uZyBwYXltZW50IGFzc2V0IEIJAJQKAggJAJEDAgUEcG10cwAABmFtb3VudAgJAJEDAgUEcG10cwABBmFtb3VudAMJAAACCQCQAwEFBHBtdHMAAQMJAAACCQEMYXNzZXRJZFRvU3RyAQgJAJEDAgUEcG10cwAAB2Fzc2V0SWQFA0FJZAkAlAoCCAkAkQMCBQRwbXRzAAAGYW1vdW50AAADCQAAAgkBDGFzc2V0SWRUb1N0cgEICQCRAwIFBHBtdHMAAAdhc3NldElkBQNCSWQJAJQKAgAACAkAkQMCBQRwbXRzAAAGYW1vdW50CQACAQINV3JvbmcgcGF5bWVudAkAAgECHE9uZSBvciB0d28gcGF5bWVudHMgZXhwZWN0ZWQBD2NhbGNQcmljZUltcGFjdAQEYmFsQQRiYWxCB25ld0JhbEEHbmV3QmFsQgQDcHJpCQBoAgkAZQIFBlNDQUxFOAkAawMJAGsDBQRiYWxCBQZTQ0FMRTgFBGJhbEEFBlNDQUxFOAkAawMFB25ld0JhbEIFBlNDQUxFOAUHbmV3QmFsQQBkAwkAZgIAAAUDcHJpCQBoAgUDcHJpAP///////////wEFA3ByaQERY2xhaW1BbmRDaGVja0FtbnQFBHBvb2wFcFR5cGUFY2xhaW0GYW1vdW50BmNoYW5nZQQNJHQwMzI1NjkzMjgyOAMFBWNsYWltCQELY2xhaW1GYXJtZWQCBQVwVHlwZQUEcG9vbAQMY2xhaW1lZEFzc2V0AwkAAAIFBXBUeXBlBQdTRl9QT09MBQZTV09QSUQDCQAAAgUFcFR5cGUFB1dYX1BPT0wFBFdYSUQJAQ91bmtub3duUG9vbFR5cGUACQCUCgIFBmFtb3VudAUMY2xhaW1lZEFzc2V0BAtjbGFpbUFtb3VudAgFDSR0MDMyNTY5MzI4MjgCXzEECmNsYWltQXNzZXQIBQ0kdDAzMjU2OTMyODI4Al8yBANiYWwJAQ5hY2NvdW50QmFsYW5jZQEFCmNsYWltQXNzZXQDAwkAZgIFBmFtb3VudAkAZAIFC2NsYWltQW1vdW50BQZjaGFuZ2UGCQBmAgUGYW1vdW50BQNiYWwJAAIBAhlUbyBiaWcgYW1vdW50IHRvIGV4Y2hhbmdlCQCUCgIFC2NsYWltQW1vdW50BQpjbGFpbUFzc2V0HQFpARNnZXRQb29sSW5mb1JFQURPTkxZAQRwb29sBAhwb29sQWRkcgkBEUBleHRyTmF0aXZlKDEwNjIpAQUEcG9vbAQFcFR5cGUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzCQCsAgIFBWtQb29sBQRwb29sAhJQb29sIGlzIG5vdCBpbml0ZWQEDSR0MDMzMjI1MzMzMTUJAQtnZXRQb29sRGF0YQIJAQdBZGRyZXNzAQkA2QQBBQRwb29sBQVwVHlwZQQDQUlkCAUNJHQwMzMyMjUzMzMxNQJfMQQDQklkCAUNJHQwMzMyMjUzMzMxNQJfMgQEYmFsQQgFDSR0MDMzMjI1MzMzMTUCXzMEBGJhbEIIBQ0kdDAzMzIyNTMzMzE1Al80BAdzaGFyZUlkCAUNJHQwMzMyMjUzMzMxNQJfNQQLc2hhcmVTdXBwbHkJAQ5nZXRTaGFyZVN1cHBseQMFCHBvb2xBZGRyBQVwVHlwZQUHc2hhcmVJZAkAlAoCBQNuaWwJAJgKBgUDQUlkBQNCSWQFB3NoYXJlSWQFBGJhbEEFBGJhbEIFC3NoYXJlU3VwcGx5AWkBGmdldFNoYXJlQXNzZXRQcmljZVJFQURPTkxZAQdzaGFyZUlkBAtzaGFyZVByaWNlcwkBDWdldFNoYXJlUHJpY2UBBQdzaGFyZUlkCQCUCgIFA25pbAULc2hhcmVQcmljZXMBaQEiZ2V0VXNlclBvc2l0aW9uU2hhcmVBbW91bnRSRUFET05MWQIEdXNlcgZwb3NOdW0EBHBvb2wJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzCQCsAgIJAKwCAgkArAICBQR1c2VyAgFfBQZwb3NOdW0FEWtVc2VyUG9zaXRpb25Qb29sAhBVbmtub3duIHBvc2l0aW9uBAxib3Jyb3dBbW91bnQJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyAgFfBQZwb3NOdW0FEWtVc2VyQm9ycm93QW1vdW50BA91c2VyQ2FuV2l0aGRyYXcJARh1c2VyQ2FuV2l0aGRyYXdTaGFyZUNhbGMEBQR1c2VyBQRwb29sBQZwb3NOdW0JAGYCBQxib3Jyb3dBbW91bnQAAAkAlAoCBQNuaWwFD3VzZXJDYW5XaXRoZHJhdwFpARdnZXRVc2VyUG9zaXRpb25SRUFET05MWQMEdXNlcgVwb29scwZwb3NOdW0KAQd1c2VyUG9zAgFhBHBvb2wEDSR0MDM0MTg4MzQyNTgFAWEECXdBbW91bnRzQQgFDSR0MDM0MTg4MzQyNTgCXzEECXdBbW91bnRzQggFDSR0MDM0MTg4MzQyNTgCXzIEBWRlYnRzCAUNJHQwMzQxODgzNDI1OAJfMwQLZXFXQW1vdW50c0EIBQ0kdDAzNDE4ODM0MjU4Al80BAtlcVdBbW91bnRzQggFDSR0MDM0MTg4MzQyNTgCXzUEBWluZGV4CAUNJHQwMzQxODgzNDI1OAJfNgMJAQEhAQkBCWlzRGVmaW5lZAEJAJoIAgUEdGhpcwkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8JAJEDAgUGcG9zTnVtBQVpbmRleAUNa1VzZXJQb3NpdGlvbgkAmAoGCQDNCAIFCXdBbW91bnRzQQAACQDNCAIFCXdBbW91bnRzQgAACQDNCAIFBWRlYnRzAAAJAM0IAgULZXFXQW1vdW50c0EAAAkAzQgCBQtlcVdBbW91bnRzQgAACQBkAgUFaW5kZXgAAQQFcFR5cGUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzCQCsAgIFBWtQb29sBQRwb29sAhJQb29sIGlzIG5vdCBpbml0ZWQEDSR0MDM0NTM3MzQ2MjcJAQtnZXRQb29sRGF0YQIJAQdBZGRyZXNzAQkA2QQBBQRwb29sBQVwVHlwZQQDQUlkCAUNJHQwMzQ1MzczNDYyNwJfMQQDQklkCAUNJHQwMzQ1MzczNDYyNwJfMgQEYmFsQQgFDSR0MDM0NTM3MzQ2MjcCXzMEBGJhbEIIBQ0kdDAzNDUzNzM0NjI3Al80BAdzaGFyZUlkCAUNJHQwMzQ1MzczNDYyNwJfNQQMYm9ycm93QW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyAgFfCQCRAwIFBnBvc051bQUFaW5kZXgFEWtVc2VyQm9ycm93QW1vdW50AAAED3VzZXJDYW5XaXRoZHJhdwkBGHVzZXJDYW5XaXRoZHJhd1NoYXJlQ2FsYwQFBHVzZXIFBHBvb2wJAJEDAgUGcG9zTnVtBQVpbmRleAkAZgIFDGJvcnJvd0Ftb3VudAAABA0kdDAzNDg0MzM0OTYzCQEaY2FsY1dpdGhkcmF3TFBGcm9tUG9vbFZpcnQECQEHQWRkcmVzcwEJANkEAQUEcG9vbAUFcFR5cGUFB3NoYXJlSWQFD3VzZXJDYW5XaXRoZHJhdwQId0Ftb3VudEEIBQ0kdDAzNDg0MzM0OTYzAl8xBAh3QW1vdW50QggFDSR0MDM0ODQzMzQ5NjMCXzIDCQBmAgUMYm9ycm93QW1vdW50AAAEC2JvcnJvd0Fzc2V0CQERQGV4dHJOYXRpdmUoMTA1MykCBQR0aGlzCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgIBXwkAkQMCBQZwb3NOdW0FBWluZGV4BRJrVXNlckJvcnJvd0Fzc2V0SWQEBGRlYnQKAAFACQD8BwQJAQ5nZXRMZW5kU3J2QWRkcgACDGdldEFzc2V0RGVidAkAzAgCBwkAzAgCCQCsAgIJAKwCAgUEdXNlcgIBXwkAkQMCBQZwb3NOdW0FBWluZGV4CQDMCAIFC2JvcnJvd0Fzc2V0BQNuaWwFA25pbAMJAAECBQFAAgNJbnQFAUAJAAIBCQCsAgIJAAMBBQFAAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQDCQAAAgUEZGVidAUEZGVidAQNYW1vdW50VG9HZXRFeAMDCQAAAgULYm9ycm93QXNzZXQFA0FJZAkAZgIFBGRlYnQFCHdBbW91bnRBBwkAZQIFBGRlYnQFCHdBbW91bnRBAwMJAAACBQtib3Jyb3dBc3NldAUDQklkCQBmAgUEZGVidAUId0Ftb3VudEIHCQBlAgUEZGVidAUId0Ftb3VudEIAAAQLYW1vdW50VG9QYXkDCQBmAgUNYW1vdW50VG9HZXRFeAAAAwkAAAIFBXBUeXBlBQdTRl9QT09MBAJleAkBEWNhbGNBbW91bnRUb1BheVNGBwUEcG9vbAUDQUlkBQNCSWQFBGJhbEEFBGJhbEIFDWFtb3VudFRvR2V0RXgFC2JvcnJvd0Fzc2V0CAUCZXgCXzIDCQAAAgUFcFR5cGUFB1dYX1BPT0wEAmV4CQERY2FsY0Ftb3VudFRvUGF5V1gHBQRwb29sBQNBSWQFA0JJZAUEYmFsQQUEYmFsQgUNYW1vdW50VG9HZXRFeAULYm9ycm93QXNzZXQIBQJleAJfMgkBD3Vua25vd25Qb29sVHlwZQAAAAQNJHQwMzU4NzUzNjA5NAMJAAACBQtib3Jyb3dBc3NldAUDQUlkCQCUCgIJAGUCCQBkAgUId0Ftb3VudEEFDWFtb3VudFRvR2V0RXgFBGRlYnQJAGUCBQh3QW1vdW50QgULYW1vdW50VG9QYXkJAJQKAgkAZQIFCHdBbW91bnRBBQthbW91bnRUb1BheQkAZQIJAGQCBQh3QW1vdW50QgUNYW1vdW50VG9HZXRFeAUEZGVidAQKZXFXQW1vdW50QQgFDSR0MDM1ODc1MzYwOTQCXzEECmVxV0Ftb3VudEIIBQ0kdDAzNTg3NTM2MDk0Al8yCQCYCgYJAM0IAgUJd0Ftb3VudHNBBQh3QW1vdW50QQkAzQgCBQl3QW1vdW50c0IFCHdBbW91bnRCCQDNCAIFBWRlYnRzBQRkZWJ0CQDNCAIFC2VxV0Ftb3VudHNBBQplcVdBbW91bnRBCQDNCAIFC2VxV0Ftb3VudHNCBQplcVdBbW91bnRCCQBkAgUFaW5kZXgAAQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAmAoGCQDNCAIFCXdBbW91bnRzQQUId0Ftb3VudEEJAM0IAgUJd0Ftb3VudHNCBQh3QW1vdW50QgUFZGVidHMJAM0IAgUJd0Ftb3VudHNBBQh3QW1vdW50QQkAzQgCBQl3QW1vdW50c0IFCHdBbW91bnRCCQBkAgUFaW5kZXgAAQQNJHQwMzYzNDkzNjQ2MAoAAiRsBQVwb29scwoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJgKBgUDbmlsBQNuaWwFA25pbAUDbmlsBQNuaWwAAAoBBSRmMF8xAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQEHdXNlclBvcwIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQIUTGlzdCBzaXplIGV4Y2VlZHMgMjAJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUBAl3QW1vdW50c0EIBQ0kdDAzNjM0OTM2NDYwAl8xBAl3QW1vdW50c0IIBQ0kdDAzNjM0OTM2NDYwAl8yBAVkZWJ0cwgFDSR0MDM2MzQ5MzY0NjACXzMEC2VxV0Ftb3VudHNBCAUNJHQwMzYzNDkzNjQ2MAJfNAQLZXFXQW1vdW50c0IIBQ0kdDAzNjM0OTM2NDYwAl81CQCUCgIFA25pbAkAlwoFBQl3QW1vdW50c0EFCXdBbW91bnRzQgUFZGVidHMFC2VxV0Ftb3VudHNBBQtlcVdBbW91bnRzQgFpAQlyZXBsZW5pc2gDBHBvb2wIbGV2ZXJhZ2UIYm9ycm93SWQJAQt2YWx1ZU9yRWxzZQIJARBpc0FjdGl2ZUZvclVzZXJzAAQFcFR5cGUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzCQCsAgIFBWtQb29sBQRwb29sAhJQb29sIGlzIG5vdCBpbml0ZWQDCQEBIQEJAQxpc1Bvb2xBY3RpdmUCBQRwb29sBQVwVHlwZQkAAgECHlBvb2wgbm90IGFjdGl2ZSBhdCB0aGlzIG1vbWVudAMDCQBmAgBkBQhsZXZlcmFnZQYJAGYCBQhsZXZlcmFnZQCsAgkAAgECH0xldmVyYWdlIGNhbid0IGJlIDwxMDAgYW5kID4zMDADAwkBASEBCQERQGV4dHJOYXRpdmUoMTA1MSkCBQR0aGlzCQCsAgIFBHBvb2wFDmtQb29sQ2FuQm9ycm93CQBmAgUIbGV2ZXJhZ2UAZAcJAAIBAh1Zb3UgY2FuJ3QgYm9ycm93IGluIHRoaXMgcG9vbAQNJHQwMzcwNTgzNzE0OAkBC2dldFBvb2xEYXRhAgkBB0FkZHJlc3MBCQDZBAEFBHBvb2wFBXBUeXBlBANBSWQIBQ0kdDAzNzA1ODM3MTQ4Al8xBANCSWQIBQ0kdDAzNzA1ODM3MTQ4Al8yBARiYWxBCAUNJHQwMzcwNTgzNzE0OAJfMwQEYmFsQggFDSR0MDM3MDU4MzcxNDgCXzQEB3NoYXJlSWQIBQ0kdDAzNzA1ODM3MTQ4Al81AwMJAQIhPQIFCGJvcnJvd0lkBQNBSWQJAQIhPQIFCGJvcnJvd0lkBQNCSWQHCQACAQISV3JvbmcgYm9ycm93IGFzc2V0BA0kdDAzNzIyOTM3Mjg4CQEScGFyc2VSZXBsZW5pc2hQbXRzAwgFAWkIcGF5bWVudHMFA0FJZAUDQklkBARwbXRBCAUNJHQwMzcyMjkzNzI4OAJfMQQEcG10QggFDSR0MDM3MjI5MzcyODgCXzIEBHVzZXIJAKUIAQgFAWkGY2FsbGVyBAluZXdQb3NOdW0JARhnZXROZXdVc2VyUG9zaXRpb25OdW1iZXIBBQR1c2VyAwkAZgIFCGxldmVyYWdlAGQEDGJvcnJvd0Ftb3VudAkBEGNhbGNCb3Jyb3dBbW91bnQGBQRwbXRBBQRwbXRCBQNBSWQFA0JJZAUIbGV2ZXJhZ2UFCGJvcnJvd0lkBAdyZXF1ZXN0CQC5CQIJAMwIAgUEdXNlcgkAzAgCBQRwb29sCQDMCAIJAKQDAQUEcG10QQkAzAgCBQNBSWQJAMwIAgkApAMBBQRwbXRCCQDMCAIFA0JJZAkAzAgCCQCkAwEFBGJhbEEJAMwIAgkApAMBBQRiYWxCCQDMCAIFB3NoYXJlSWQJAMwIAgUIYm9ycm93SWQJAMwIAgkApAMBBQxib3Jyb3dBbW91bnQFA25pbAIBLAQMbmV3UmVxdWVzdElkCgABQAkA/AcEBQR0aGlzAhBjcmVhdGVOZXdSZXF1ZXN0CQDMCAIFB3JlcXVlc3QFA25pbAUDbmlsAwkAAQIFAUACA0ludAUBQAkAAgEJAKwCAgkAAwEFAUACGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAMJAAACBQxuZXdSZXF1ZXN0SWQFDG5ld1JlcXVlc3RJZAQEYXJncwkAzAgCCQCsAgIJAKwCAgUEdXNlcgIBXwkApAMBBQluZXdQb3NOdW0JAMwIAgUHc2hhcmVJZAkAzAgCBQhib3Jyb3dJZAkAzAgCBQxib3Jyb3dBbW91bnQJAMwIAgkApQgBBQR0aGlzCQDMCAICEXJlcGxlbmlzaEZyb21MYW5kCQDMCAIJAKQDAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBQxuZXdSZXF1ZXN0SWQCGENhbid0IGNyZWF0ZSBuZXcgcmVxdWVzdAUDbmlsBANpbnYJAP0HBAkBDmdldExlbmRTcnZBZGRyAAINZmxhc2hQb3NpdGlvbgUEYXJncwUDbmlsAwkAAAIFA2ludgUDaW52BAp1c2VyU3Rha2VkCQERQGV4dHJOYXRpdmUoMTA1MCkCBQR0aGlzCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgIBXwkApAMBBQluZXdQb3NOdW0FDWtVc2VyUG9zaXRpb24EDSR0MDM4Mjc3MzgzNzEJAQ9nZXRQb29sQmFsYW5jZXMECQEHQWRkcmVzcwEJANkEAQUEcG9vbAUFcFR5cGUFA0FJZAUDQklkAwkAAAIFDSR0MDM4Mjc3MzgzNzEFDSR0MDM4Mjc3MzgzNzEEB25ld0JhbEIIBQ0kdDAzODI3NzM4MzcxAl8yBAduZXdCYWxBCAUNJHQwMzgyNzczODM3MQJfMQQIcHJJbXBhY3QJAQ9jYWxjUHJpY2VJbXBhY3QEBQRiYWxBBQRiYWxCBQduZXdCYWxBBQduZXdCYWxCBA0kdDAzODQ0MTM4NTU2CQEaY2FsY1dpdGhkcmF3TFBGcm9tUG9vbFZpcnQECQEHQWRkcmVzcwEJANkEAQUEcG9vbAUFcFR5cGUFB3NoYXJlSWQFCnVzZXJTdGFrZWQECHdBbW91bnRBCAUNJHQwMzg0NDEzODU1NgJfMQQId0Ftb3VudEIIBQ0kdDAzODQ0MTM4NTU2Al8yCQCUCgIFA25pbAkAzAgCBQhwckltcGFjdAkAzAgCBQh3QW1vdW50QQkAzAgCBQh3QW1vdW50QgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBA0kdDAzODYwOTM4NzI0CQEPcmVwbGVuaXNoQnlUeXBlCgUFcFR5cGUFBHBvb2wFC05PX0xPQU5fRkVFBQRwbXRBBQNBSWQFBHBtdEIFA0JJZAUEYmFsQQUEYmFsQgUHc2hhcmVJZAMJAAACBQ0kdDAzODYwOTM4NzI0BQ0kdDAzODYwOTM4NzI0BAdheGx5RmVlCAUNJHQwMzg2MDkzODcyNAJfMgQKdXNlclN0YWtlZAgFDSR0MDM4NjA5Mzg3MjQCXzEEDSR0MDM4NzMwMzg4MjQJAQ9nZXRQb29sQmFsYW5jZXMECQEHQWRkcmVzcwEJANkEAQUEcG9vbAUFcFR5cGUFA0FJZAUDQklkAwkAAAIFDSR0MDM4NzMwMzg4MjQFDSR0MDM4NzMwMzg4MjQEB25ld0JhbEIIBQ0kdDAzODczMDM4ODI0Al8yBAduZXdCYWxBCAUNJHQwMzg3MzAzODgyNAJfMQQIcHJJbXBhY3QJAQ9jYWxjUHJpY2VJbXBhY3QEBQRiYWxBBQRiYWxCBQduZXdCYWxBBQduZXdCYWxCBA0kdDAzODg5NDM5MDA5CQEaY2FsY1dpdGhkcmF3TFBGcm9tUG9vbFZpcnQECQEHQWRkcmVzcwEJANkEAQUEcG9vbAUFcFR5cGUFB3NoYXJlSWQFCnVzZXJTdGFrZWQECHdBbW91bnRBCAUNJHQwMzg4OTQzOTAwOQJfMQQId0Ftb3VudEIIBQ0kdDAzODg5NDM5MDA5Al8yCQCUCgIJAM4IAgkBEHJlcGxlbmlzaEVudHJpZXMIBQRwb29sBQR1c2VyBQp1c2VyU3Rha2VkBQdheGx5RmVlBQluZXdQb3NOdW0FB3NoYXJlSWQFBXBUeXBlBwkBDmdldEN1cnNFbnRyaWVzBAUDQUlkBQNCSWQFB3NoYXJlSWQJAMwIAgkApAMBBQh3QW1vdW50QQkAzAgCCQCkAwEFCHdBbW91bnRCBQNuaWwJAMwIAgUIcHJJbXBhY3QJAMwIAgUId0Ftb3VudEEJAMwIAgUId0Ftb3VudEIFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQh3aXRoZHJhdwIEcG9vbAVwb3NJZAkBC3ZhbHVlT3JFbHNlAgkBEGlzQWN0aXZlRm9yVXNlcnMABAVwVHlwZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMJAKwCAgUFa1Bvb2wFBHBvb2wCElBvb2wgaXMgbm90IGluaXRlZAMJAQEhAQkBDGlzUG9vbEFjdGl2ZQIFBHBvb2wFBXBUeXBlCQACAQIeUG9vbCBub3QgYWN0aXZlIGF0IHRoaXMgbW9tZW50CQEOd2l0aGRyYXdUb1VzZXIECQClCAEIBQFpBmNhbGxlcgUEcG9vbAkApAMBBQVwb3NJZAcBaQEUY3JlYXRlVXBkYXRlU3RvcExvc3MEBXBvc0lkBnBvb2xJZAdhc3NldElkBXByaWNlCQELdmFsdWVPckVsc2UCCQEQaXNBY3RpdmVGb3JVc2VycwAEEHRva2VuT3JhY2xlUHJpY2UJARFAZXh0ck5hdGl2ZSgxMDUwKQIFD3ByaWNlT3JhY2xlQWRkcgkArAICBQdhc3NldElkBQ5rUHJpY2VJbk9yYWNsZQQFcFR5cGUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzCQCsAgIFBWtQb29sBQZwb29sSWQCElBvb2wgaXMgbm90IGluaXRlZAMJAQEhAQkBDGlzUG9vbEFjdGl2ZQIFBnBvb2xJZAUFcFR5cGUJAAIBAh5Qb29sIG5vdCBhY3RpdmUgYXQgdGhpcyBtb21lbnQDCQEBIQEJAQlpc0RlZmluZWQBCQCaCAIFBHRoaXMJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBQZwb29sSWQCAV8JAKUIAQgFAWkGY2FsbGVyAgFfCQCkAwEFBXBvc0lkBQ1rVXNlclBvc2l0aW9uCQACAQIaVGhlcmUgYXJlIG5vIHVzZXIgcG9zaXRpb24DCQBnAgAABQVwcmljZQkAAgECHFByaWNlIG11c3QgYmUgZ3JlYXRlciB0aGFuIDADCQBmAgUFcHJpY2UFEHRva2VuT3JhY2xlUHJpY2UJAAIBAitQcmljZSBtdXN0IGJlIGxlc3MgdGhhbiBjdXJyZW50IHRva2VuIHByaWNlCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgFfCQCkAwEFBXBvc0lkAgFfBQZwb29sSWQCAV8FB2Fzc2V0SWQFDWtVc2VyU3RvcExvc3MFBXByaWNlBQNuaWwBaQEOZGVsZXRlU3RvcExvc3MDBXBvc0lkBnBvb2xJZAdhc3NldElkCQELdmFsdWVPckVsc2UCCQEQaXNBY3RpdmVGb3JVc2VycwAEBXBUeXBlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwkArAICBQVrUG9vbAUGcG9vbElkAhJQb29sIGlzIG5vdCBpbml0ZWQDCQEBIQEJAQxpc1Bvb2xBY3RpdmUCBQZwb29sSWQFBXBUeXBlCQACAQIeUG9vbCBub3QgYWN0aXZlIGF0IHRoaXMgbW9tZW50AwkBASEBCQEJaXNEZWZpbmVkAQkAmggCBQR0aGlzCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgFfCQCkAwEFBXBvc0lkAgFfBQZwb29sSWQCAV8FB2Fzc2V0SWQFDWtVc2VyU3RvcExvc3MJAAIBAghObyBlbnRyeQkAzAgCCQELRGVsZXRlRW50cnkBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKUIAQgFAWkGY2FsbGVyAgFfCQCkAwEFBXBvc0lkAgFfBQZwb29sSWQCAV8FB2Fzc2V0SWQFDWtVc2VyU3RvcExvc3MFA25pbAFpAQRpbml0DQxtb25leUJveEFkZHINc2ZGYXJtaW5nQWRkcghsZW5kQWRkcg9wcmljZU9yYWNsZUFkZHIQa2VlcGVyRXhDb250cmFjdA53eFN3YXBDb250cmFjdAtzd29wQXNzZXRJZAl3eEFzc2V0SWQOb3BlcmF0b3JQdWJLZXkSZ3JvdXAxQWRtaW4xUHViS2V5Emdyb3VwMUFkbWluMlB1YktleRJncm91cDJBZG1pbjFQdWJLZXkSZ3JvdXAyQWRtaW4yUHViS2V5CQELdmFsdWVPckVsc2UCCQEKaXNTZWxmQ2FsbAEFAWkDCQEJaXNEZWZpbmVkAQkAoggBBQ9rT3BlcmF0b3JDYWxsUEsJAAIBAg5BbHJlYWR5IGluaXRlZAMJAQEhAQkBCWlzRGVmaW5lZAEJAKYIAQUMbW9uZXlCb3hBZGRyCQACAQIjbW9uZXlCb3hBZGRyIGlzIG5vdCBjb3JyZWN0IGFkZHJlc3MDCQEBIQEJAQlpc0RlZmluZWQBCQCmCAEFDXNmRmFybWluZ0FkZHIJAAIBAiRzZkZhcm1pbmdBZGRyIGlzIG5vdCBjb3JyZWN0IGFkZHJlc3MDCQEBIQEJAQlpc0RlZmluZWQBCQCmCAEFCGxlbmRBZGRyCQACAQIfbGVuZEFkZHIgaXMgbm90IGNvcnJlY3QgYWRkcmVzcwMJAQEhAQkBCWlzRGVmaW5lZAEJAKYIAQUPcHJpY2VPcmFjbGVBZGRyCQACAQImcHJpY2VPcmFjbGVBZGRyIGlzIG5vdCBjb3JyZWN0IGFkZHJlc3MDCQEBIQEJAQlpc0RlZmluZWQBCQCmCAEFEGtlZXBlckV4Q29udHJhY3QJAAIBAidrZWVwZXJFeENvbnRyYWN0IGlzIG5vdCBjb3JyZWN0IGFkZHJlc3MDCQEBIQEJAQlpc0RlZmluZWQBCQDsBwEJANkEAQULc3dvcEFzc2V0SWQJAAIBAiNzd29wQXNzZXRJZCBpcyBub3QgY29ycmVjdCBhc3NldCBpZAMJAQEhAQkBCWlzRGVmaW5lZAEJAOwHAQkA2QQBBQl3eEFzc2V0SWQJAAIBAiNzd29wQXNzZXRJZCBpcyBub3QgY29ycmVjdCBhc3NldCBpZAMJAQIhPQIJAMgBAQkA2QQBBQ5vcGVyYXRvclB1YktleQAgCQACAQIdb3BlcmF0b3JQdWJLZXkgaXMgbm90IGNvcnJlY3QDCQECIT0CCQDIAQEJANkEAQUSZ3JvdXAxQWRtaW4xUHViS2V5ACAJAAIBAiFncm91cDFBZG1pbjFQdWJLZXkgaXMgbm90IGNvcnJlY3QDCQECIT0CCQDIAQEJANkEAQUSZ3JvdXAxQWRtaW4yUHViS2V5ACAJAAIBAiFncm91cDFBZG1pbjJQdWJLZXkgaXMgbm90IGNvcnJlY3QDCQECIT0CCQDIAQEJANkEAQUSZ3JvdXAyQWRtaW4xUHViS2V5ACAJAAIBAiFncm91cDJBZG1pbjFQdWJLZXkgaXMgbm90IGNvcnJlY3QDCQECIT0CCQDIAQEJANkEAQUSZ3JvdXAyQWRtaW4yUHViS2V5ACAJAAIBAiFncm91cDJBZG1pbjJQdWJLZXkgaXMgbm90IGNvcnJlY3QJAMwIAgkBC1N0cmluZ0VudHJ5AgUJa01vbmV5Qm94BQxtb25leUJveEFkZHIJAMwIAgkBC1N0cmluZ0VudHJ5AgUOa1NGRmFybWluZ0FkZHIFDXNmRmFybWluZ0FkZHIJAMwIAgkBC1N0cmluZ0VudHJ5AgUMa0xlbmRTZXJ2aWNlBQhsZW5kQWRkcgkAzAgCCQELU3RyaW5nRW50cnkCBQxrUHJpY2VPcmFjbGUFD3ByaWNlT3JhY2xlQWRkcgkAzAgCCQELU3RyaW5nRW50cnkCBQtrRXhDb250cmFjdAUQa2VlcGVyRXhDb250cmFjdAkAzAgCCQELU3RyaW5nRW50cnkCBQ9rV3hTd2FwQ29udHJhY3QFDnd4U3dhcENvbnRyYWN0CQDMCAIJAQtTdHJpbmdFbnRyeQIFB2tTd29wSWQFC3N3b3BBc3NldElkCQDMCAIJAQtTdHJpbmdFbnRyeQIFBWtXeElkBQl3eEFzc2V0SWQJAMwIAgkBC1N0cmluZ0VudHJ5AgUPa09wZXJhdG9yQ2FsbFBLBQ5vcGVyYXRvclB1YktleQkAzAgCCQELU3RyaW5nRW50cnkCBQ9rR3JvdXAxQWRtaW4xUEsFEmdyb3VwMUFkbWluMVB1YktleQkAzAgCCQELU3RyaW5nRW50cnkCBQ9rR3JvdXAxQWRtaW4yUEsFEmdyb3VwMUFkbWluMlB1YktleQkAzAgCCQELU3RyaW5nRW50cnkCBQ9rR3JvdXAyQWRtaW4xUEsFEmdyb3VwMkFkbWluMVB1YktleQkAzAgCCQELU3RyaW5nRW50cnkCBQ9rR3JvdXAyQWRtaW4yUEsFEmdyb3VwMkFkbWluMlB1YktleQUDbmlsAWkBEGNyZWF0ZU5ld1JlcXVlc3QBBnBhcmFtcwkBC3ZhbHVlT3JFbHNlAgkBCmlzU2VsZkNhbGwBBQFpBAxuZXdSZXF1ZXN0SWQJAGQCCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFDGtSZXF1ZXN0SXRlcgAAAAEJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQCsAgIJAKQDAQUMbmV3UmVxdWVzdElkBQprUmVxdWVzdElkBQZwYXJhbXMJAMwIAgkBDEludGVnZXJFbnRyeQIFDGtSZXF1ZXN0SXRlcgUMbmV3UmVxdWVzdElkBQNuaWwFDG5ld1JlcXVlc3RJZAFpARFyZXBsZW5pc2hGcm9tTGFuZAEJcmVxdWVzdElkCQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUACQELdmFsdWVPckVsc2UCCQEKaXNMYW5kQ2FsbAEFAWkEDSR0MDQzODQ4NDM5NTIJAQxwYXJzZVJlcXVlc3QBBQlyZXF1ZXN0SWQEBHVzZXIIBQ0kdDA0Mzg0ODQzOTUyAl8xBARwb29sCAUNJHQwNDM4NDg0Mzk1MgJfMgQEcG10QQgFDSR0MDQzODQ4NDM5NTICXzMEA0FJZAgFDSR0MDQzODQ4NDM5NTICXzQEBHBtdEIIBQ0kdDA0Mzg0ODQzOTUyAl81BANCSWQIBQ0kdDA0Mzg0ODQzOTUyAl82BARiYWxBCAUNJHQwNDM4NDg0Mzk1MgJfNwQEYmFsQggFDSR0MDQzODQ4NDM5NTICXzgEB3NoYXJlSWQIBQ0kdDA0Mzg0ODQzOTUyAl85BAdid0Fzc2V0CAUNJHQwNDM4NDg0Mzk1MgNfMTAECGJ3QW1vdW50CAUNJHQwNDM4NDg0Mzk1MgNfMTEDCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAhJXcm9uZyBwYXltZW50IHNpemUDAwkBAiE9AgkBDGFzc2V0SWRUb1N0cgEICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAUHYndBc3NldAYJAQIhPQIICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BQhid0Ftb3VudAkAAgECDVdyb25nIHBheW1lbnQEDSR0MDQ0MTQyNDQyNDIDCQAAAgUDQUlkBQdid0Fzc2V0CQCUCgIJAGQCBQRwbXRBBQhid0Ftb3VudAUEcG10QgkAlAoCBQRwbXRBCQBkAgUEcG10QgUIYndBbW91bnQEB3BtdEFsbEEIBQ0kdDA0NDE0MjQ0MjQyAl8xBAdwbXRBbGxCCAUNJHQwNDQxNDI0NDI0MgJfMgQFcFR5cGUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQR0aGlzCQCsAgIFBWtQb29sBQRwb29sAgxVbmtub3duIHBvb2wEDSR0MDQ0MzI0NDQ0MzkJAQ9yZXBsZW5pc2hCeVR5cGUKBQVwVHlwZQUEcG9vbAUITE9BTl9GRUUFB3BtdEFsbEEFA0FJZAUHcG10QWxsQgUDQklkBQRiYWxBBQRiYWxCBQdzaGFyZUlkBAp1c2VyU3Rha2VkCAUNJHQwNDQzMjQ0NDQzOQJfMQQHYXhseUZlZQgFDSR0MDQ0MzI0NDQ0MzkCXzIEBnBvc051bQkBGGdldE5ld1VzZXJQb3NpdGlvbk51bWJlcgEFBHVzZXIEDWJvcnJvd0VudHJpZXMJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyAgFfCQCkAwEFBnBvc051bQURa1VzZXJCb3Jyb3dBbW91bnQFCGJ3QW1vdW50CQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyAgFfCQCkAwEFBnBvc051bQUSa1VzZXJCb3Jyb3dBc3NldElkBQdid0Fzc2V0BQNuaWwEB2VudHJpZXMJARByZXBsZW5pc2hFbnRyaWVzCAUEcG9vbAUEdXNlcgUKdXNlclN0YWtlZAUHYXhseUZlZQUGcG9zTnVtBQdzaGFyZUlkBQVwVHlwZQYEDSR0MDQ0Nzk5NDQ5MTQJARpjYWxjV2l0aGRyYXdMUEZyb21Qb29sVmlydAQJAQdBZGRyZXNzAQkA2QQBBQRwb29sBQVwVHlwZQUHc2hhcmVJZAUKdXNlclN0YWtlZAQId0Ftb3VudEEIBQ0kdDA0NDc5OTQ0OTE0Al8xBAh3QW1vdW50QggFDSR0MDQ0Nzk5NDQ5MTQCXzIJAJQKAgkAzQgCCQDOCAIJAM4IAgUHZW50cmllcwkBDmdldEN1cnNFbnRyaWVzBAUDQUlkBQNCSWQFB3NoYXJlSWQJAMwIAgkApAMBBQh3QW1vdW50QQkAzAgCCQCkAwEFCHdBbW91bnRCBQNuaWwFDWJvcnJvd0VudHJpZXMJAQtEZWxldGVFbnRyeQEJAKwCAgUJcmVxdWVzdElkBQprUmVxdWVzdElkBQp1c2VyU3Rha2VkAWkBCWxpcXVpZGF0ZQMEdXNlcgVwb3NJZA9saXF1aWRhdGVBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAQhpc0FjdGl2ZQAJAQt2YWx1ZU9yRWxzZQIJAQppc0xhbmRDYWxsAQUBaQQEcG9vbAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFBHRoaXMJAKwCAgkArAICCQCsAgIFBHVzZXICAV8FBXBvc0lkBRFrVXNlclBvc2l0aW9uUG9vbAILbm8gcG9zaXRpb24EBXBUeXBlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUEdGhpcwkArAICBQVrUG9vbAUEcG9vbAISUG9vbCBpcyBub3QgaW5pdGVkBA0kdDA0NTQzNTQ1NTI1CQELZ2V0UG9vbERhdGECCQEHQWRkcmVzcwEJANkEAQUEcG9vbAUFcFR5cGUEA0FJZAgFDSR0MDQ1NDM1NDU1MjUCXzEEA0JJZAgFDSR0MDQ1NDM1NDU1MjUCXzIEBGJhbEEIBQ0kdDA0NTQzNTQ1NTI1Al8zBARiYWxCCAUNJHQwNDU0MzU0NTUyNQJfNAQHc2hhcmVJZAgFDSR0MDQ1NDM1NDU1MjUCXzUEBmFtb3VudAkBCXVuc3Rha2VMUAQFBHBvb2wFBXBUeXBlBQdzaGFyZUlkBQ9saXF1aWRhdGVBbW91bnQEDGJvcnJvd0Ftb3VudAkBEUBleHRyTmF0aXZlKDEwNTApAgUEdGhpcwkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8FBXBvc0lkBRFrVXNlckJvcnJvd0Ftb3VudAQLYm9ycm93QXNzZXQJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBHRoaXMJAKwCAgkArAICCQCsAgIJAKwCAgkArAICBQRwb29sAgFfBQR1c2VyAgFfBQVwb3NJZAUSa1VzZXJCb3Jyb3dBc3NldElkBA91c2VyQ2FuV2l0aGRyYXcJARh1c2VyQ2FuV2l0aGRyYXdTaGFyZUNhbGMEBQR1c2VyBQRwb29sBQVwb3NJZAkAZgIFDGJvcnJvd0Ftb3VudAAAAwkAZgIFD2xpcXVpZGF0ZUFtb3VudAUPdXNlckNhbldpdGhkcmF3CQACAQInWW91IGNhbid0IGxpcXVpZGF0ZSBtb3JlIHRoYW4gdXNlciBoYXZlAwkAAAIFDGJvcnJvd0Ftb3VudAAACQACAQIrWW91IGNhbid0IGxpcXVpZGF0ZSBwb3NpdGlvbiB3aXRob3V0IGJvcnJvdwkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHBvb2wCAV8FBHVzZXICAV8FBXBvc0lkBRVrVXNlclBvc2l0aW9uSW50ZXJlc3QJARFAZXh0ck5hdGl2ZSgxMDUwKQIFBHRoaXMJAKwCAgUEcG9vbAURa1Bvb2xJbnRlcmVzdExvYW4JAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUOa1Bvb2xUb3RhbExvYW4JAGUCCQEZZ2V0UG9vbFRvdGFsU2hhcmVXaXRoTG9hbgEFBHBvb2wFD2xpcXVpZGF0ZUFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBQprUG9vbFRvdGFsCQBlAgkBEWdldFBvb2xUb3RhbFNoYXJlAQUEcG9vbAUPbGlxdWlkYXRlQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgUEcG9vbAIBXwUEdXNlcgIBXwUFcG9zSWQFDWtVc2VyUG9zaXRpb24JAGUCBQ91c2VyQ2FuV2l0aGRyYXcFD2xpcXVpZGF0ZUFtb3VudAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFBmFtb3VudAkA2QQBBQdzaGFyZUlkBQNuaWwBaQEIc3RvcExvc3MEBHVzZXIFcG9zSWQEcG9vbAdhc3NldElkCQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUACQELdmFsdWVPckVsc2UCCQEOaXNPcGVyYXRvckNhbGwBBQFpBBB0b2tlbk9yYWNsZVByaWNlCQERQGV4dHJOYXRpdmUoMTA1MCkCBQ9wcmljZU9yYWNsZUFkZHIJAKwCAgUHYXNzZXRJZAUOa1ByaWNlSW5PcmFjbGUEDXN0b3BMb3NzUHJpY2UJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQR0aGlzCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIFBHVzZXICAV8JAKQDAQUFcG9zSWQCAV8FBHBvb2wCAV8FB2Fzc2V0SWQFDWtVc2VyU3RvcExvc3MCCE5vIGVudHJ5AwkAZgIFEHRva2VuT3JhY2xlUHJpY2UFDXN0b3BMb3NzUHJpY2UJAAIBAiNUb2tlbiBwcmljZSBncmVhdGVyIHN0b3AgbG9zcyBwcmljZQQDcmVzCQEOd2l0aGRyYXdUb1VzZXIEBQR1c2VyBQRwb29sCQCkAwEFBXBvc0lkBgkAlAoCCQDNCAIIBQNyZXMCXzEJAQtEZWxldGVFbnRyeQEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgUEdXNlcgIBXwkApAMBBQVwb3NJZAIBXwUEcG9vbAIBXwUHYXNzZXRJZAUNa1VzZXJTdG9wTG9zcwgFA3JlcwJfMgFpARJjYXBpdGFsaXplRXhLZWVwZXILBHBvb2wJdG9rZW5Ub0lkEGFtb3VudFRvRXhjaGFuZ2UFY2xhaW0JYW1vdW50c0luCWFkZHJlc3Nlcw9hc3NldHNUb1JlY2VpdmULZXN0UmVjZWl2ZWQRc2xpcHBhZ2VUb2xlcmFuY2ULbWluUmVjZWl2ZWQHb3B0aW9ucwkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAkBC3ZhbHVlT3JFbHNlAgkBDmlzT3BlcmF0b3JDYWxsAQUBaQQFcFR5cGUJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBHRoaXMJAKwCAgUFa1Bvb2wFBHBvb2wEBmNoYW5nZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQCsAgIFBHBvb2wFDmtQb29sQ2FwQ2hhbmdlAAAEDSR0MDQ3Njc0NDc3NzMJARFjbGFpbUFuZENoZWNrQW1udAUFBHBvb2wFBXBUeXBlBQVjbGFpbQUQYW1vdW50VG9FeGNoYW5nZQUGY2hhbmdlBA1jbGFpbWVkQW1vdW50CAUNJHQwNDc2NzQ0Nzc3MwJfMQQMY2xhaW1lZEFzc2V0CAUNJHQwNDc2NzQ0Nzc3MwJfMgQPZXhjaGFuZ2VkQW1vdW50CQEOZXhjaGFuZ2VLZWVwZXIKBQl0b2tlblRvSWQFEGFtb3VudFRvRXhjaGFuZ2UFDGNsYWltZWRBc3NldAUJYW1vdW50c0luBQlhZGRyZXNzZXMFD2Fzc2V0c1RvUmVjZWl2ZQULZXN0UmVjZWl2ZWQFEXNsaXBwYWdlVG9sZXJhbmNlBQttaW5SZWNlaXZlZAUHb3B0aW9ucwQJbmV3Q2hhbmdlCQBlAgkAZAIFDWNsYWltZWRBbW91bnQFBmNoYW5nZQUQYW1vdW50VG9FeGNoYW5nZQQLY2hhbmdlRW50cnkDCQBnAgUJbmV3Q2hhbmdlAAAJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUOa1Bvb2xDYXBDaGFuZ2UFCW5ld0NoYW5nZQUDbmlsCQACAQIPTmVnYXRpdmUgY2hhbmdlCQDOCAIJAQpjYXBpdGFsaXplBAUEcG9vbAUFcFR5cGUFCXRva2VuVG9JZAUPZXhjaGFuZ2VkQW1vdW50BQtjaGFuZ2VFbnRyeQFpARJjYXBpdGFsaXplRXhQdXp6bGUHBHBvb2wJdG9rZW5Ub0lkEGFtb3VudFRvRXhjaGFuZ2UFY2xhaW0Jcm91dGVzU3RyDG1pblRvUmVjZWl2ZQdvcHRpb25zCQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUACQELdmFsdWVPckVsc2UCCQEOaXNPcGVyYXRvckNhbGwBBQFpBAVwVHlwZQkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwkArAICBQVrUG9vbAUEcG9vbAQGY2hhbmdlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgUEcG9vbAUOa1Bvb2xDYXBDaGFuZ2UAAAQNJHQwNDg1NzM0ODY3MgkBEWNsYWltQW5kQ2hlY2tBbW50BQUEcG9vbAUFcFR5cGUFBWNsYWltBRBhbW91bnRUb0V4Y2hhbmdlBQZjaGFuZ2UEDWNsYWltZWRBbW91bnQIBQ0kdDA0ODU3MzQ4NjcyAl8xBAxjbGFpbWVkQXNzZXQIBQ0kdDA0ODU3MzQ4NjcyAl8yBA9leGNoYW5nZWRBbW91bnQJAQ5leGNoYW5nZVB1enpsZQYFCXRva2VuVG9JZAUQYW1vdW50VG9FeGNoYW5nZQUMY2xhaW1lZEFzc2V0BQlyb3V0ZXNTdHIFDG1pblRvUmVjZWl2ZQUHb3B0aW9ucwQJbmV3Q2hhbmdlCQBlAgkAZAIFDWNsYWltZWRBbW91bnQFBmNoYW5nZQUQYW1vdW50VG9FeGNoYW5nZQQLY2hhbmdlRW50cnkDCQBnAgUJbmV3Q2hhbmdlAAAJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUEcG9vbAUOa1Bvb2xDYXBDaGFuZ2UFCW5ld0NoYW5nZQUDbmlsBQNuaWwJAM4IAgkBCmNhcGl0YWxpemUEBQRwb29sBQVwVHlwZQUJdG9rZW5Ub0lkBQ9leGNoYW5nZWRBbW91bnQFC2NoYW5nZUVudHJ5AWkBEmNhcGl0YWxpemVFeFN3b3BGaQsEcG9vbAl0b2tlblRvSWQQYW1vdW50VG9FeGNoYW5nZQVjbGFpbQpleGNoYW5nZXJzDmV4Y2hhbmdlcnNUeXBlBWFyZ3MxBWFyZ3MyEXJvdXRpbmdBc3NldHNLZXlzEm1pbkFtb3VudFRvUmVjZWl2ZQdvcHRpb25zCQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUACQELdmFsdWVPckVsc2UCCQEOaXNPcGVyYXRvckNhbGwBBQFpBAVwVHlwZQkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwkArAICBQVrUG9vbAUEcG9vbAQGY2hhbmdlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAKwCAgUEcG9vbAUOa1Bvb2xDYXBDaGFuZ2UAAAQNJHQwNDk1MTc0OTYxNgkBEWNsYWltQW5kQ2hlY2tBbW50BQUEcG9vbAUFcFR5cGUFBWNsYWltBRBhbW91bnRUb0V4Y2hhbmdlBQZjaGFuZ2UEDWNsYWltZWRBbW91bnQIBQ0kdDA0OTUxNzQ5NjE2Al8xBAxjbGFpbWVkQXNzZXQIBQ0kdDA0OTUxNzQ5NjE2Al8yBA9leGNoYW5nZWRBbW91bnQJAQ5leGNoYW5nZVN3b3BGaQoFCXRva2VuVG9JZAUQYW1vdW50VG9FeGNoYW5nZQUMY2xhaW1lZEFzc2V0BQpleGNoYW5nZXJzBQ5leGNoYW5nZXJzVHlwZQUFYXJnczEFBWFyZ3MyBRFyb3V0aW5nQXNzZXRzS2V5cwUSbWluQW1vdW50VG9SZWNlaXZlBQdvcHRpb25zBAluZXdDaGFuZ2UJAGUCCQBkAgUNY2xhaW1lZEFtb3VudAUGY2hhbmdlBRBhbW91bnRUb0V4Y2hhbmdlBAtjaGFuZ2VFbnRyeQMJAGcCBQluZXdDaGFuZ2UAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQRwb29sBQ5rUG9vbENhcENoYW5nZQUJbmV3Q2hhbmdlBQNuaWwFA25pbAkAzggCCQEKY2FwaXRhbGl6ZQQFBHBvb2wFBXBUeXBlBQl0b2tlblRvSWQFD2V4Y2hhbmdlZEFtb3VudAULY2hhbmdlRW50cnkBaQEOY2FwaXRhbGl6ZU5vRXgDBHBvb2wFY2xhaW0RYW1vdW50RnJvbUJhbGFuY2UJAQt2YWx1ZU9yRWxzZQIJAQhpc0FjdGl2ZQAJAQt2YWx1ZU9yRWxzZQIJAQ5pc09wZXJhdG9yQ2FsbAEFAWkEBXBUeXBlCQERQGV4dHJOYXRpdmUoMTA1MykCBQR0aGlzCQCsAgIFBWtQb29sBQRwb29sBA0kdDA1MDIxMzUwMzA4CQERY2xhaW1BbmRDaGVja0FtbnQFBQRwb29sBQVwVHlwZQUFY2xhaW0FEWFtb3VudEZyb21CYWxhbmNlAAAEDWNsYWltZWRBbW91bnQIBQ0kdDA1MDIxMzUwMzA4Al8xBAxjbGFpbWVkQXNzZXQIBQ0kdDA1MDIxMzUwMzA4Al8yCQEKY2FwaXRhbGl6ZQQFBHBvb2wFBXBUeXBlCQEMYXNzZXRJZFRvU3RyAQUMY2xhaW1lZEFzc2V0CQBkAgUNY2xhaW1lZEFtb3VudAURYW1vdW50RnJvbUJhbGFuY2UBaQELaW5pdE5ld1Bvb2wJBHR5cGUIcG9vbEFkZHILaW5GZWVOb0xvYW4JaW5GZWVMb2FuDGNhcEZlZU5vTG9hbg5jYXBGZWVXaXRoTG9hbhFzdG9wbG9zc0ZlZU5vTG9hbhNzdG9wbG9zc0ZlZVdpdGhMb2FuCWNhbkJvcnJvdwkBC3ZhbHVlT3JFbHNlAgkBCGlzQWN0aXZlAAkBC3ZhbHVlT3JFbHNlAgkBC2lzQWRtaW5DYWxsAQUBaQMDCQECIT0CBQR0eXBlBQdTRl9QT09MCQECIT0CBQR0eXBlBQdXWF9QT09MBwkAAgECCldyb25nIHR5cGUEDSR0MDUwNzM0NTA4MjgJAQtnZXRQb29sRGF0YQIJAQdBZGRyZXNzAQkA2QQBBQhwb29sQWRkcgUEdHlwZQQDYUlkCAUNJHQwNTA3MzQ1MDgyOAJfMQQDYklkCAUNJHQwNTA3MzQ1MDgyOAJfMgQEYUJhbAgFDSR0MDUwNzM0NTA4MjgCXzMEBGJCYWwIBQ0kdDA1MDczNDUwODI4Al80BAdzaGFyZUlkCAUNJHQwNTA3MzQ1MDgyOAJfNQMJAGYCAAAFC2luRmVlTm9Mb2FuCQACAQIiaW5GZWVOb0xvYW4gbXVzdCBiZSBncmVhdGVyIHRoYW4gMAMJAGYCAAAFCWluRmVlTG9hbgkAAgECIGluRmVlTG9hbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwAwkAZgIAAAUMY2FwRmVlTm9Mb2FuCQACAQIjY2FwRmVlTm9Mb2FuIG11c3QgYmUgZ3JlYXRlciB0aGFuIDADCQBmAgAABQ5jYXBGZWVXaXRoTG9hbgkAAgECJWNhcEZlZVdpdGhMb2FuIG11c3QgYmUgZ3JlYXRlciB0aGFuIDADCQBmAgAABRFzdG9wbG9zc0ZlZU5vTG9hbgkAAgECKHN0b3Bsb3NzRmVlTm9Mb2FuIG11c3QgYmUgZ3JlYXRlciB0aGFuIDADCQBmAgAABRNzdG9wbG9zc0ZlZVdpdGhMb2FuCQACAQIqc3RvcGxvc3NGZWVXaXRoTG9hbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCHBvb2xBZGRyBRVrQXhseUluRmVlV2l0aG91dExvYW4FC2luRmVlTm9Mb2FuCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCHBvb2xBZGRyBRJrQXhseUluRmVlV2l0aExvYW4FCWluRmVlTG9hbgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQhwb29sQWRkcgURa0F4bHlOb0xvYW5DYXBGZWUFDGNhcEZlZU5vTG9hbgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQhwb29sQWRkcgUTa0F4bHlXaXRoTG9hbkNhcEZlZQUOY2FwRmVlV2l0aExvYW4JAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUIcG9vbEFkZHIFFmtBeGx5U3RvcExvc3NOb0xvYW5GZWUFEXN0b3Bsb3NzRmVlTm9Mb2FuCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCHBvb2xBZGRyBRRrQXhseVN0b3BMb3NzTG9hbkZlZQUTc3RvcGxvc3NGZWVXaXRoTG9hbgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQhwb29sQWRkcgURa1Bvb2xJbnRlcmVzdExvYW4AAAkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQhwb29sQWRkcgUTa1Bvb2xJbnRlcmVzdE5vTG9hbgAACQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUFa1Bvb2wFCHBvb2xBZGRyBQR0eXBlCQDMCAIJAQtTdHJpbmdFbnRyeQIJAKwCAgUHc2hhcmVJZAUKa1NoYXJlUG9vbAUIcG9vbEFkZHIJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAKwCAgUIcG9vbEFkZHIFDmtQb29sQ2FuQm9ycm93BQljYW5Cb3Jyb3cFA25pbAFpAQ51cGRhdGVQb29sRmVlcwcIcG9vbEFkZHILaW5GZWVOb0xvYW4JaW5GZWVMb2FuDGNhcEZlZU5vTG9hbg5jYXBGZWVXaXRoTG9hbhFzdG9wbG9zc0ZlZU5vTG9hbhNzdG9wbG9zc0ZlZVdpdGhMb2FuCQELdmFsdWVPckVsc2UCCQEIaXNBY3RpdmUACQELdmFsdWVPckVsc2UCCQELaXNBZG1pbkNhbGwBBQFpAwkBASEBCQEJaXNEZWZpbmVkAQkAnQgCBQR0aGlzCQCsAgIFBWtQb29sBQhwb29sQWRkcgkAAgEJAKwCAgIaQ2FuJ3QgZmluZCBwb29sIHdpdGggYWRkciAFCHBvb2xBZGRyAwkAZgIAAAULaW5GZWVOb0xvYW4JAAIBAiJpbkZlZU5vTG9hbiBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwAwkAZgIAAAUJaW5GZWVMb2FuCQACAQIgaW5GZWVMb2FuIG11c3QgYmUgZ3JlYXRlciB0aGFuIDADCQBmAgAABQxjYXBGZWVOb0xvYW4JAAIBAiNjYXBGZWVOb0xvYW4gbXVzdCBiZSBncmVhdGVyIHRoYW4gMAMJAGYCAAAFDmNhcEZlZVdpdGhMb2FuCQACAQIlY2FwRmVlV2l0aExvYW4gbXVzdCBiZSBncmVhdGVyIHRoYW4gMAMJAGYCAAAFEXN0b3Bsb3NzRmVlTm9Mb2FuCQACAQIoc3RvcGxvc3NGZWVOb0xvYW4gbXVzdCBiZSBncmVhdGVyIHRoYW4gMAMJAGYCAAAFE3N0b3Bsb3NzRmVlV2l0aExvYW4JAAIBAipzdG9wbG9zc0ZlZVdpdGhMb2FuIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAJAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUIcG9vbEFkZHIFFWtBeGx5SW5GZWVXaXRob3V0TG9hbgULaW5GZWVOb0xvYW4JAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUIcG9vbEFkZHIFEmtBeGx5SW5GZWVXaXRoTG9hbgUJaW5GZWVMb2FuCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCHBvb2xBZGRyBRFrQXhseU5vTG9hbkNhcEZlZQUMY2FwRmVlTm9Mb2FuCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQCsAgIFCHBvb2xBZGRyBRNrQXhseVdpdGhMb2FuQ2FwRmVlBQ5jYXBGZWVXaXRoTG9hbgkAzAgCCQEMSW50ZWdlckVudHJ5AgkArAICBQhwb29sQWRkcgUWa0F4bHlTdG9wTG9zc05vTG9hbkZlZQURc3RvcGxvc3NGZWVOb0xvYW4JAMwIAgkBDEludGVnZXJFbnRyeQIJAKwCAgUIcG9vbEFkZHIFFGtBeGx5U3RvcExvc3NMb2FuRmVlBRNzdG9wbG9zc0ZlZVdpdGhMb2FuBQNuaWwBaQEIYWN0aXZhdGUACQELdmFsdWVPckVsc2UCCQELaXNBZG1pbkNhbGwBBQFpAwkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzBQdrQWN0aXZlBgkAAgECE2RBcHAgYWxyZWFkeSBhY3RpdmUJAMwIAgkBDEJvb2xlYW5FbnRyeQIFB2tBY3RpdmUGBQNuaWwBaQEIc2h1dGRvd24ACQELdmFsdWVPckVsc2UCCQELaXNBZG1pbkNhbGwBBQFpAwkBASEBCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMFB2tBY3RpdmUGCQACAQIVZEFwcCBhbHJlYWR5IHNodXRkb3duCQDMCAIJAQxCb29sZWFuRW50cnkCBQdrQWN0aXZlBwUDbmlsAWkBEGFjdGl2YXRlRm9yVXNlcnMACQELdmFsdWVPckVsc2UCCQELaXNBZG1pbkNhbGwBBQFpAwkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzBQxrQWN0aXZlVXNlcnMGCQACAQIdZEFwcCBhbHJlYWR5IGFjdGl2ZSBmb3IgdXNlcnMJAMwIAgkBDEJvb2xlYW5FbnRyeQIFDGtBY3RpdmVVc2VycwYFA25pbAFpARBzaHV0ZG93bkZvclVzZXJzAAkBC3ZhbHVlT3JFbHNlAgkBC2lzQWRtaW5DYWxsAQUBaQMJAQEhAQkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzBQxrQWN0aXZlVXNlcnMGCQACAQIfZEFwcCBhbHJlYWR5IHNodXRkb3duIGZvciB1c2VycwkAzAgCCQEMQm9vbGVhbkVudHJ5AgUMa0FjdGl2ZVVzZXJzBwUDbmlsAWkBCmFjdGl2YXRlU0YACQELdmFsdWVPckVsc2UCCQELaXNBZG1pbkNhbGwBBQFpAwkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzCQCsAgIFB1NGX1BPT0wFC2tBY3RpdmVTRldYBgkAAgECFVNXT1BGSSBhbHJlYWR5IGFjdGl2ZQkAzAgCCQEMQm9vbGVhbkVudHJ5AgkArAICBQdTRl9QT09MBQtrQWN0aXZlU0ZXWAYFA25pbAFpAQpzaHV0ZG93blNGAAkBC3ZhbHVlT3JFbHNlAgkBC2lzQWRtaW5DYWxsAQUBaQMJAQEhAQkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzCQCsAgIFB1NGX1BPT0wFC2tBY3RpdmVTRldYBgkAAgECF1NXT1BGSSBhbHJlYWR5IHNodXRkb3duCQDMCAIJAQxCb29sZWFuRW50cnkCCQCsAgIFB1NGX1BPT0wFC2tBY3RpdmVTRldYBwUDbmlsAWkBCmFjdGl2YXRlV1gACQELdmFsdWVPckVsc2UCCQELaXNBZG1pbkNhbGwBBQFpAwkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzCQCsAgIFB1dYX1BPT0wFC2tBY3RpdmVTRldYBgkAAgECEVdYIGFscmVhZHkgYWN0aXZlCQDMCAIJAQxCb29sZWFuRW50cnkCCQCsAgIFB1dYX1BPT0wFC2tBY3RpdmVTRldYBgUDbmlsAWkBCnNodXRkb3duV1gACQELdmFsdWVPckVsc2UCCQELaXNBZG1pbkNhbGwBBQFpAwkBASEBCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMJAKwCAgUHV1hfUE9PTAULa0FjdGl2ZVNGV1gGCQACAQITV1ggYWxyZWFkeSBzaHV0ZG93bgkAzAgCCQEMQm9vbGVhbkVudHJ5AgkArAICBQdXWF9QT09MBQtrQWN0aXZlU0ZXWAcFA25pbAFpAQxhY3RpdmF0ZVBvb2wBBHBvb2wJAQt2YWx1ZU9yRWxzZQIJAQtpc0FkbWluQ2FsbAEFAWkDCQEBIQEJAQlpc0RlZmluZWQBCQCdCAIFBHRoaXMJAKwCAgUFa1Bvb2wFBHBvb2wJAAIBAgxVbmtub3duIHBvb2wDCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMJAKwCAgUEcG9vbAULa1Bvb2xBY3RpdmUGCQACAQITUG9vbCBhbHJlYWR5IGFjdGl2ZQkAzAgCCQEMQm9vbGVhbkVudHJ5AgkArAICBQRwb29sBQtrUG9vbEFjdGl2ZQYFA25pbAFpAQxzaHV0ZG93blBvb2wBBHBvb2wJAQt2YWx1ZU9yRWxzZQIJAQtpc0FkbWluQ2FsbAEFAWkDCQEBIQEJAQlpc0RlZmluZWQBCQCdCAIFBHRoaXMJAKwCAgUFa1Bvb2wFBHBvb2wJAAIBAgxVbmtub3duIHBvb2wDCQEBIQEJAQt2YWx1ZU9yRWxzZQIJAJsIAgUEdGhpcwkArAICBQRwb29sBQtrUG9vbEFjdGl2ZQYJAAIBAhVQb29sIGFscmVhZHkgc2h1dGRvd24JAMwIAgkBDEJvb2xlYW5FbnRyeQIJAKwCAgUEcG9vbAULa1Bvb2xBY3RpdmUHBQNuaWwAu303DA==", "height": 2703161, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: FxVCrpoJFb2gwrAJBhMAeUvSjuGMv8pTNvFKARVw2ixj Next: 5W8me79ju9vr22gKggeGKTHUvDDc2gnGH7wsLsZTbiku Diff:
OldNewDifferences
6767
6868 let kAxlyInFeeWithLoan = "_axlyFeeWithLoan"
6969
70-let kAxlyNoLoanCapFee = "_axlyFeeCapWithLoan"
70+let kAxlyNoLoanCapFee = "_axlyFeeCapNoLoan"
7171
72-let kAxlyWithLoanCapFee = "_axlyFeeCapNoLoan"
72+let kAxlyWithLoanCapFee = "_axlyFeeCapWithLoan"
7373
7474 let kAxlyStopLossNoLoanFee = "_axlyFeeStoplossWithLoan"
7575
105105
106106 let kLendService = "lend_service_addr"
107107
108-let kAdminCallPK = "admin_call_pub_key"
108+let kOperatorCallPK = "admin_call_pub_key"
109109
110110 let kPriceOracle = "price_oracle"
111111
116116 let kSwopId = "swop_id"
117117
118118 let kWxId = "wx_id"
119+
120+let kGroup1Admin1PK = "group1_admin1_pub_key"
121+
122+let kGroup1Admin2PK = "group1_admin2_pub_key"
123+
124+let kGroup2Admin1PK = "group2_admin1_pub_key"
125+
126+let kGroup2Admin2PK = "group2_admin2_pub_key"
119127
120128 let moneyBox = Address(fromBase58String(valueOrErrorMessage(getString(this, kMoneyBox), "No axly moneyBox address")))
121129
129137
130138 let WXID = fromBase58String(valueOrErrorMessage(getString(this, kWxId), "No wx id"))
131139
140+let group1Admin1PK = fromBase58String(valueOrErrorMessage(getString(this, kGroup1Admin1PK), "Can't get kGroup1Admin1PK"))
141+
142+let group1Admin2PK = fromBase58String(valueOrErrorMessage(getString(this, kGroup1Admin2PK), "Can't get kGroup1Admin2PK"))
143+
144+let group2Admin1PK = fromBase58String(valueOrErrorMessage(getString(this, kGroup2Admin1PK), "Can't get kGroup2Admin1PK"))
145+
146+let group2Admin2PK = fromBase58String(valueOrErrorMessage(getString(this, kGroup2Admin2PK), "Can't get kGroup2Admin1PK"))
147+
148+let operatorPK = fromBase58String(valueOrErrorMessage(getString(this, kOperatorCallPK), "Can't get operatorPK"))
149+
132150 func unknownPoolType () = throw("Wrong pool type")
133151
134152
135153 func getLendSrvAddr () = Address(fromBase58String(valueOrErrorMessage(getString(this, kLendService), "Can't get lend service addr")))
136154
137155
138-func getAdminCallAddr () = addressFromPublicKey(fromBase58String(valueOrErrorMessage(getString(this, kAdminCallPK), "Can't get admin addr")))
156+func isOperatorCall (i) = if ((i.callerPublicKey == i.callerPublicKey))
157+ then unit
158+ else throw("Only operator can call this function")
139159
140160
141-func isAdminCall (i) = if ((i.caller == getAdminCallAddr()))
161+func isAdminCall (i) = if (if ((i.callerPublicKey == i.callerPublicKey))
162+ then true
163+ else (i.callerPublicKey == i.callerPublicKey))
142164 then unit
143- else throw("Only admin can call this function")
165+ else throw("Only admin group1 can call this function")
144166
145167
146168 func isSelfCall (i) = if ((i.caller == this))
210232
211233
212234 func getSFPoolData (poolAddr) = {
213- let $t070647113 = getSFPoolBalances(poolAddr)
214- if (($t070647113 == $t070647113))
235+ let $t079127961 = getSFPoolBalances(poolAddr)
236+ if (($t079127961 == $t079127961))
215237 then {
216- let balB = $t070647113._2
217- let balA = $t070647113._1
238+ let balB = $t079127961._2
239+ let balA = $t079127961._1
218240 $Tuple5(valueOrErrorMessage(getString(poolAddr, kSFPoolAAssetId), "Can't get pool A asset id"), valueOrErrorMessage(getString(poolAddr, kSFPoolBAssetId), "Can't get pool B asset id"), balA, balB, valueOrErrorMessage(getString(poolAddr, kSFPoolShareId), "Can't get share asset id"))
219241 }
220242 else throw("Strict value is not equal to itself.")
248270 then @
249271 else unit
250272 }, "Can't get pool LP asset id")
251- let $t078107869 = getWXPoolBalances(poolAddr, aId, bId)
252- if (($t078107869 == $t078107869))
273+ let $t086588717 = getWXPoolBalances(poolAddr, aId, bId)
274+ if (($t086588717 == $t086588717))
253275 then {
254- let balB = $t078107869._2
255- let balA = $t078107869._1
276+ let balB = $t086588717._2
277+ let balA = $t086588717._1
256278 $Tuple5(aId, bId, balA, balB, shareId)
257279 }
258280 else throw("Strict value is not equal to itself.")
337359
338360 func getAssetsPrice (assetIds) = {
339361 func getPrices (a,assetId) = {
340- let assetPrice = getIntegerValue(priceOracleAddr, (assetId + kPriceInOracle))
362+ let assetPrice = valueOrElse(getInteger(priceOracleAddr, (assetId + kPriceInOracle)), -1)
341363 (a :+ assetPrice)
342364 }
343365
360382 let pool = valueOrErrorMessage(getString(this, (shareId + kSharePool)), "Can't find pool addr by share id")
361383 let poolAddr = Address(fromBase58String(pool))
362384 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
363- let $t01084710912 = getPoolData(poolAddr, pType)
364- let aId = $t01084710912._1
365- let bId = $t01084710912._2
366- let aBalance = $t01084710912._3
367- let bBalance = $t01084710912._4
368- let dPriceA = getIntegerValue(priceOracleAddr, (aId + kPriceInOracle))
369- let dPriceB = getIntegerValue(priceOracleAddr, (bId + kPriceInOracle))
370- let shareSupply = getShareSupply(poolAddr, pType, shareId)
371- let APrecision = pow(10, 0, getAssetDecimals(aId), 0, 0, DOWN)
372- let BPrecision = pow(10, 0, getAssetDecimals(bId), 0, 0, DOWN)
373- let sharePrecision = pow(10, 0, getAssetDecimals(shareId), 0, 0, DOWN)
374- let sum = (fraction(aBalance, dPriceA, APrecision) + fraction(bBalance, dPriceB, BPrecision))
375- fraction(sum, sharePrecision, shareSupply)
385+ let $t01170611771 = getPoolData(poolAddr, pType)
386+ let aId = $t01170611771._1
387+ let bId = $t01170611771._2
388+ let aBalance = $t01170611771._3
389+ let bBalance = $t01170611771._4
390+ let prices = getAssetsPrice([aId, bId])
391+ let dPriceA = prices[0]
392+ let dPriceB = prices[1]
393+ if (if ((0 > dPriceA))
394+ then true
395+ else (0 > dPriceB))
396+ then -1
397+ else {
398+ let shareSupply = getShareSupply(poolAddr, pType, shareId)
399+ let APrecision = pow(10, 0, getAssetDecimals(aId), 0, 0, DOWN)
400+ let BPrecision = pow(10, 0, getAssetDecimals(bId), 0, 0, DOWN)
401+ let sharePrecision = pow(10, 0, getAssetDecimals(shareId), 0, 0, DOWN)
402+ let sum = (fraction(aBalance, dPriceA, APrecision) + fraction(bBalance, dPriceB, BPrecision))
403+ fraction(sum, sharePrecision, shareSupply)
404+ }
376405 }
377406
378407
436465 }
437466 else if ((pType == WX_POOL))
438467 then {
439- let $t01245712707 = $Tuple2(split({
468+ let $t01331513565 = $Tuple2(split({
440469 let @ = invoke(poolAddr, "evaluatePutByAmountAssetREADONLY", [pmtA], nil)
441470 if ($isInstanceOf(@, "String"))
442471 then @
447476 then @
448477 else throw(($getType(@) + " couldn't be cast to String"))
449478 }, "__"))
450- if (($t01245712707 == $t01245712707))
479+ if (($t01331513565 == $t01331513565))
451480 then {
452- let evalPutInB = $t01245712707._2
453- let evalPutInA = $t01245712707._1
481+ let evalPutInB = $t01331513565._2
482+ let evalPutInA = $t01331513565._1
454483 let lpInA = parseIntValue(evalPutInA[1])
455484 let lpInB = parseIntValue(evalPutInB[1])
456485 if ((lpInB > lpInA))
499528
500529
501530 func unstakeLP (pool,pType,shareId,amount) = {
502- let $t01436614716 = if ((pType == SF_POOL))
531+ let $t01522415574 = if ((pType == SF_POOL))
503532 then $Tuple3(getSFFarmingAddr(), "withdrawShareTokens", [pool, amount])
504533 else if ((pType == WX_POOL))
505534 then $Tuple3(getWXFarmingAddr(Address(fromBase58String(pool))), "unstake", [shareId, amount])
506535 else unknownPoolType()
507- let farmAddr = $t01436614716._1
508- let fName = $t01436614716._2
509- let params = $t01436614716._3
536+ let farmAddr = $t01522415574._1
537+ let fName = $t01522415574._2
538+ let params = $t01522415574._3
510539 let inv = invoke(farmAddr, fName, params, nil)
511540 if ((inv == inv))
512541 then amount
519548 let feeScale6 = 1000000
520549 let fee = getIntegerValue(poolAddr, kSFPoolFee)
521550 let amntGetNoFee = fraction(amountTokenToGet, feeScale6, (feeScale6 - fee), CEILING)
522- let $t01513815444 = if ((assetTokenToGet == assetIdA))
551+ let $t01599616302 = if ((assetTokenToGet == assetIdA))
523552 then {
524553 let amountToPay = fraction(amntGetNoFee, balB, (balA - amntGetNoFee), CEILING)
525554 $Tuple2(amountToPay, assetIdB)
528557 let amountToPay = fraction(amntGetNoFee, balA, (balB - amntGetNoFee), CEILING)
529558 $Tuple2(amountToPay, assetIdA)
530559 }
531- let amountToPay = $t01513815444._1
532- let assetToPay = $t01513815444._2
560+ let amountToPay = $t01599616302._1
561+ let assetToPay = $t01599616302._2
533562 $Tuple2(assetToPay, amountToPay)
534563 }
535564
549578
550579
551580 func calcAmountToPayWX (pool,assetIdA,assetIdB,balA,balB,amountTokenToGet,assetTokenToGet) = {
552- let $t01618416223 = getWXSwapFees(pool)
553- let pFee = $t01618416223._1
554- let prFee = $t01618416223._2
581+ let $t01704217081 = getWXSwapFees(pool)
582+ let pFee = $t01704217081._1
583+ let prFee = $t01704217081._2
555584 let feeScale = toBigInt(100000000)
556- let $t01626316571 = if ((assetTokenToGet == assetIdA))
585+ let $t01712117429 = if ((assetTokenToGet == assetIdA))
557586 then {
558587 let amountToPay = fraction(amountTokenToGet, balB, (balA - amountTokenToGet))
559588 $Tuple2(amountToPay, assetIdB)
562591 let amountToPay = fraction(amountTokenToGet, balA, (balB - amountTokenToGet))
563592 $Tuple2(amountToPay, assetIdA)
564593 }
565- let amountToPay = $t01626316571._1
566- let assetToPay = $t01626316571._2
594+ let amountToPay = $t01712117429._1
595+ let assetToPay = $t01712117429._2
567596 let amountToPayWithFee = toInt(fraction(toBigInt(amountToPay), feeScale, (feeScale - toBigInt((prFee + pFee))), CEILING))
568597 $Tuple2(assetToPay, amountToPayWithFee)
569598 }
571600
572601 func exchangeDirectly (pType,pool,assetIdA,assetIdB,balA,balB,amountTokenToGet,assetTokenToGet) = if ((pType == SF_POOL))
573602 then {
574- let $t01691817040 = calcAmountToPaySF(pool, assetIdA, assetIdB, balA, balB, amountTokenToGet, assetTokenToGet)
575- let assetToPay = $t01691817040._1
576- let amountToPay = $t01691817040._2
603+ let $t01777617898 = calcAmountToPaySF(pool, assetIdA, assetIdB, balA, balB, amountTokenToGet, assetTokenToGet)
604+ let assetToPay = $t01777617898._1
605+ let amountToPay = $t01777617898._2
577606 invoke(addressFromStringValue(pool), "callFunction", ["exchange", [toString(amountTokenToGet)]], [AttachedPayment(assetIdFromStr(assetToPay), amountToPay)])
578607 }
579608 else if ((pType == WX_POOL))
580609 then {
581- let $t01724017362 = calcAmountToPayWX(pool, assetIdA, assetIdB, balA, balB, amountTokenToGet, assetTokenToGet)
582- let assetToPay = $t01724017362._1
583- let amountToPay = $t01724017362._2
610+ let $t01809818220 = calcAmountToPayWX(pool, assetIdA, assetIdB, balA, balB, amountTokenToGet, assetTokenToGet)
611+ let assetToPay = $t01809818220._1
612+ let amountToPay = $t01809818220._2
584613 invoke(wxSwapContract, "swap", [amountTokenToGet, assetTokenToGet, toString(this)], [AttachedPayment(assetIdFromStr(assetToPay), amountToPay)])
585614 }
586615 else unknownPoolType()
587616
588617
589618 func calcWithdrawLPFromPoolVirt (poolAddr,pType,shareId,userCanWithdraw) = {
590- let $t01764918113 = if ((pType == SF_POOL))
619+ let $t01850718971 = if ((pType == SF_POOL))
591620 then {
592621 let inv = {
593622 let @ = invoke(poolAddr, "callFunction", ["withdrawREADONLY", [toString(userCanWithdraw)]], nil)
622651 else throw("Strict value is not equal to itself.")
623652 }
624653 else unknownPoolType()
625- let amountA = $t01764918113._1
626- let amountB = $t01764918113._2
654+ let amountA = $t01850718971._1
655+ let amountB = $t01850718971._2
627656 $Tuple2(amountA, amountB)
628657 }
629658
645674 }
646675 else if ((pType == WX_POOL))
647676 then {
677+ let $t01933919418 = getWXPoolData(addressFromStringValue(pool))
678+ let aId = $t01933919418._1
679+ let bId = $t01933919418._2
680+ let aBal = $t01933919418._3
681+ let bBal = $t01933919418._4
682+ let lpId = $t01933919418._5
648683 let balBefore = accountBalance(WXID)
649684 if ((balBefore == balBefore))
650685 then {
651- let inv = invoke(getWXFarmingAddr(Address(fromBase58String(pool))), "claimWX", [pool], nil)
686+ let inv = invoke(getWXFarmingAddr(addressFromStringValue(pool)), "claimWx", [lpId], nil)
652687 if ((inv == inv))
653688 then {
654689 let balAfter = accountBalance(WXID)
666701 if ((lpBalanceBefore == lpBalanceBefore))
667702 then {
668703 let poolAddr = addressFromStringValue(pool)
669- let $t01907819494 = if (if ((pmtA > 0))
704+ let $t02001620432 = if (if ((pmtA > 0))
670705 then (pmtB > 0)
671706 else false)
672707 then {
673- let $t01914419260 = calcReplenishByTwoTokens(pType, poolAddr, pmtA, aId, pmtB, bId, balA, balB)
674- let pmtInA = $t01914419260._1
675- let pmtInB = $t01914419260._2
676- let change = $t01914419260._3
677- let changeId = $t01914419260._4
708+ let $t02008220198 = calcReplenishByTwoTokens(pType, poolAddr, pmtA, aId, pmtB, bId, balA, balB)
709+ let pmtInA = $t02008220198._1
710+ let pmtInB = $t02008220198._2
711+ let change = $t02008220198._3
712+ let changeId = $t02008220198._4
678713 let inv = replenishTwoTokensByType(poolAddr, pType, pmtInA, aId, pmtInB, bId)
679714 if ((inv == inv))
680715 then $Tuple2(change, changeId)
685720 else if ((pmtB > 0))
686721 then $Tuple2(pmtB, bId)
687722 else throw("pmts must be > 0")
688- let change = $t01907819494._1
689- let changeId = $t01907819494._2
723+ let change = $t02001620432._1
724+ let changeId = $t02001620432._2
690725 let inv = if ((change > 0))
691726 then replenishOneTokenByType(poolAddr, pType, change, changeId)
692727 else nil
714749 func replenishEntries (pool,user,stakedAmount,axlyFeeAmount,posNum,shareId,type,withLoan) = {
715750 let totalAmount = getPoolTotalShare(pool)
716751 let totalAmountLoan = getPoolTotalShareWithLoan(pool)
717- let $t02035220590 = if (withLoan)
752+ let $t02128921527 = if (withLoan)
718753 then $Tuple2(getIntegerValue(this, (pool + kPoolInterestLoan)), (totalAmountLoan + stakedAmount))
719754 else $Tuple2(getIntegerValue(this, (pool + kPoolInterestNoLoan)), totalAmountLoan)
720- let curPoolInterest = $t02035220590._1
721- let totalStakedWithLoan = $t02035220590._2
755+ let curPoolInterest = $t02128921527._1
756+ let totalStakedWithLoan = $t02128921527._2
722757 [IntegerEntry((pool + kPoolTotal), (totalAmount + stakedAmount)), IntegerEntry((pool + kPoolTotalLoan), totalStakedWithLoan), IntegerEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserPosition), stakedAmount), IntegerEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserPositionInterest), curPoolInterest), StringEntry((((user + "_") + toString(posNum)) + kUserPositionPool), pool), IntegerEntry((user + kUserPositionNum), posNum), ScriptTransfer(moneyBox, axlyFeeAmount, fromBase58String(shareId))]
723758 }
724759
764799
765800 func capitalize (pool,pType,tokenId,tokenAmount) = {
766801 let poolAddr = Address(fromBase58String(pool))
767- let $t02294123007 = getPoolData(poolAddr, pType)
768- let AId = $t02294123007._1
769- let BId = $t02294123007._2
770- let balA = $t02294123007._3
771- let balB = $t02294123007._4
772- let shareId = $t02294123007._5
802+ let $t02388123947 = getPoolData(poolAddr, pType)
803+ let AId = $t02388123947._1
804+ let BId = $t02388123947._2
805+ let balA = $t02388123947._3
806+ let balB = $t02388123947._4
807+ let shareId = $t02388123947._5
773808 if (if ((tokenId != AId))
774809 then (tokenId != BId)
775810 else false)
776811 then throw("Wrong asset")
777812 else {
778- let $t02309223172 = if ((tokenId == AId))
779- then $Tuple2(tokenAmount, 0)
780- else $Tuple2(0, tokenAmount)
781- let pmtA = $t02309223172._1
782- let pmtB = $t02309223172._2
783- let $t02317523279 = replenishByType(pType, pool, NO_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
784- let stakedAmount = $t02317523279._1
785- let nf = $t02317523279._2
786- let curPoolInterestLoan = valueOrElse(getInteger(this, (pool + kPoolInterestLoan)), 0)
787- let curPoolInterestNoLoan = valueOrElse(getInteger(this, (pool + kPoolInterestNoLoan)), 0)
788813 let totalShareAmount = getPoolTotalShare(pool)
789814 let totalShareAmountWithLoan = getPoolTotalShareWithLoan(pool)
790815 let loanPercent = fraction(totalShareAmountWithLoan, SCALE8, totalShareAmount)
816+ let tokensForFeeLoan = fraction(tokenAmount, loanPercent, SCALE8)
817+ let tokensForFeeNoLoan = (tokenAmount - tokensForFeeLoan)
818+ let axlyFeeLoan = fraction(tokensForFeeLoan, getAxlyFee(pool, CAP_FEE_LOAN), FEE_SCALE6)
819+ let axlyFeeNoLoan = fraction(tokensForFeeNoLoan, getAxlyFee(pool, CAP_FEE_NO_LOAN), FEE_SCALE6)
820+ let axlyFee = (axlyFeeLoan + axlyFeeNoLoan)
821+ let $t02458724687 = if ((tokenId == AId))
822+ then $Tuple2((tokenAmount - axlyFee), 0)
823+ else $Tuple2(0, (tokenAmount - axlyFee))
824+ let pmtA = $t02458724687._1
825+ let pmtB = $t02458724687._2
826+ let $t02469024794 = replenishByType(pType, pool, NO_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
827+ let stakedAmount = $t02469024794._1
828+ let nf = $t02469024794._2
829+ let curPoolInterestLoan = valueOrElse(getInteger(this, (pool + kPoolInterestLoan)), 0)
830+ let curPoolInterestNoLoan = valueOrElse(getInteger(this, (pool + kPoolInterestNoLoan)), 0)
791831 let stakedLoan = fraction(stakedAmount, loanPercent, SCALE8)
792832 let stakedNoLoan = (stakedAmount - stakedLoan)
793833 let newInterestLoan = if ((totalShareAmountWithLoan > 0))
796836 let newInterestNoLoan = if (((totalShareAmount - totalShareAmountWithLoan) > 0))
797837 then (curPoolInterestNoLoan + fraction(stakedNoLoan, SCALE10, (totalShareAmount - totalShareAmountWithLoan)))
798838 else 0
799- let axlyFeeLoan = fraction(stakedLoan, getAxlyFee(pool, CAP_FEE_LOAN), FEE_SCALE6)
800- let axlyFeeNoLoan = fraction(stakedNoLoan, getAxlyFee(pool, CAP_FEE_NO_LOAN), FEE_SCALE6)
801- let axlyFee = unstakeLP(pool, pType, shareId, (axlyFeeLoan + axlyFeeNoLoan))
802- if ((axlyFee == axlyFee))
803- then ([IntegerEntry((pool + kPoolInterestLoan), newInterestLoan), IntegerEntry((pool + kPoolInterestNoLoan), newInterestNoLoan), IntegerEntry((pool + kPoolTotal), ((totalShareAmount + stakedAmount) - axlyFee)), IntegerEntry((pool + kPoolTotalLoan), ((totalShareAmountWithLoan + stakedLoan) - axlyFeeLoan)), ScriptTransfer(moneyBox, (axlyFeeLoan + axlyFeeNoLoan), fromBase58String(shareId))] ++ getCursEntries(AId, BId, shareId, nil))
804- else throw("Strict value is not equal to itself.")
839+ ([IntegerEntry((pool + kPoolInterestLoan), newInterestLoan), IntegerEntry((pool + kPoolInterestNoLoan), newInterestNoLoan), IntegerEntry((pool + kPoolTotal), (totalShareAmount + stakedAmount)), IntegerEntry((pool + kPoolTotalLoan), (totalShareAmountWithLoan + stakedLoan)), ScriptTransfer(moneyBox, axlyFee, fromBase58String(tokenId))] ++ getCursEntries(AId, BId, shareId, nil))
805840 }
806841 }
807842
808843
809-func withdrawAmountCalc (pool,userCanWithdraw,debt,borrowAsset,stopLossFee) = {
844+func userCanWithdrawShareCalc (user,pool,posId,borrowed) = {
845+ let pAmount = valueOrErrorMessage(getInteger(this, (((((pool + "_") + user) + "_") + posId) + kUserPosition)), "Unknown position")
846+ let userInterest = getIntegerValue(this, (((((pool + "_") + user) + "_") + posId) + kUserPositionInterest))
847+ let poolInterest = if (borrowed)
848+ then getIntegerValue(this, (pool + kPoolInterestLoan))
849+ else getIntegerValue(this, (pool + kPoolInterestNoLoan))
850+ (pAmount + fraction(pAmount, (poolInterest - userInterest), SCALE10))
851+ }
852+
853+
854+func calcStopLossFee (pool,isBorrowed,stopLoss,lpWithdraw) = {
855+ let feeType = if (isBorrowed)
856+ then STOPLOSS_LOAN
857+ else STOPLOSS_FEE_NO_LOAN
858+ if (stopLoss)
859+ then fraction(lpWithdraw, getAxlyFee(pool, feeType), FEE_SCALE6)
860+ else 0
861+ }
862+
863+
864+func withdrawToUser (user,pool,posId,stopLoss) = {
865+ let pAmount = valueOrErrorMessage(getInteger(this, (((((pool + "_") + user) + "_") + posId) + kUserPosition)), "Unknown position")
866+ let isBorrowed = (valueOrElse(getInteger(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAmount)), 0) > 0)
867+ let userCanWithdraw = userCanWithdrawShareCalc(user, pool, posId, isBorrowed)
868+ let poolTotalShare = getPoolTotalShare(pool)
869+ let poolTotalShareLoan = getPoolTotalShareWithLoan(pool)
870+ let userAddr = Address(fromBase58String(user))
810871 let poolAddr = Address(fromBase58String(pool))
811872 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Unknown pool")
812- let $t02506925145 = getPoolData(poolAddr, pType)
813- let assetIdA = $t02506925145._1
814- let assetIdB = $t02506925145._2
815- let balA = $t02506925145._3
816- let balB = $t02506925145._4
817- let shareId = $t02506925145._5
818- let cBalABefore = accountBalance(assetIdFromStr(assetIdA))
873+ let $t02732527397 = getPoolData(poolAddr, pType)
874+ let idAStr = $t02732527397._1
875+ let idBStr = $t02732527397._2
876+ let balA = $t02732527397._3
877+ let balB = $t02732527397._4
878+ let shareId = $t02732527397._5
879+ let $t02740027467 = $Tuple2(assetIdFromStr(idAStr), assetIdFromStr(idBStr))
880+ let idA = $t02740027467._1
881+ let idB = $t02740027467._2
882+ let stopLossFee = calcStopLossFee(pool, isBorrowed, stopLoss, userCanWithdraw)
883+ let cBalABefore = accountBalance(idA)
819884 if ((cBalABefore == cBalABefore))
820885 then {
821- let cBalBBefore = accountBalance(assetIdFromStr(assetIdB))
886+ let cBalBBefore = accountBalance(idB)
822887 if ((cBalBBefore == cBalBBefore))
823888 then {
824889 let inv = if ((pType == SF_POOL))
838903 else unknownPoolType()
839904 if ((inv == inv))
840905 then {
841- let cBalAAfter = accountBalance(assetIdFromStr(assetIdA))
842- let cBalBAfter = accountBalance(assetIdFromStr(assetIdB))
843- let $t02583825927 = $Tuple2((cBalAAfter - cBalABefore), (cBalBAfter - cBalBBefore))
844- let tokensAmountA = $t02583825927._1
845- let tokensAmountB = $t02583825927._2
846- let $t02593026784 = if ((debt > 0))
906+ let cBalAAfter = accountBalance(idA)
907+ if ((cBalAAfter == cBalAAfter))
847908 then {
848- let amountToGetEx = if (if ((borrowAsset == assetIdA))
849- then (debt > tokensAmountA)
850- else false)
851- then (debt - tokensAmountA)
852- else if (if ((borrowAsset == assetIdB))
853- then (debt > tokensAmountB)
854- else false)
855- then (debt - tokensAmountB)
856- else 0
857- let exInv = if ((amountToGetEx > 0))
858- then exchangeDirectly(pType, pool, assetIdA, assetIdB, (balA - tokensAmountA), (balB - tokensAmountB), amountToGetEx, borrowAsset)
859- else nil
860- if ((exInv == exInv))
909+ let cBalBAfter = accountBalance(idB)
910+ if ((cBalBAfter == cBalBAfter))
861911 then {
862- let cBalAAfterRepay = accountBalance(assetIdFromStr(assetIdA))
863- let cBalBAfterRepay = accountBalance(assetIdFromStr(assetIdB))
864- if ((borrowAsset == assetIdA))
865- then $Tuple2(((cBalAAfterRepay - cBalABefore) - debt), (cBalBAfterRepay - cBalBBefore))
866- else $Tuple2((cBalAAfterRepay - cBalABefore), ((cBalBAfterRepay - cBalBBefore) - debt))
912+ let $t02816228251 = $Tuple2((cBalAAfter - cBalABefore), (cBalBAfter - cBalBBefore))
913+ let tokensAmountA = $t02816228251._1
914+ let tokensAmountB = $t02816228251._2
915+ let $t02825429490 = if (isBorrowed)
916+ then {
917+ let borrowAsset = getStringValue(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAssetId))
918+ let debt = {
919+ let @ = invoke(getLendSrvAddr(), "getAssetDebt", [false, ((user + "_") + posId), borrowAsset], nil)
920+ if ($isInstanceOf(@, "Int"))
921+ then @
922+ else throw(($getType(@) + " couldn't be cast to Int"))
923+ }
924+ if ((debt == debt))
925+ then {
926+ let amountToGetEx = if (if ((borrowAsset == idAStr))
927+ then (debt > tokensAmountA)
928+ else false)
929+ then (debt - tokensAmountA)
930+ else if (if ((borrowAsset == idBStr))
931+ then (debt > tokensAmountB)
932+ else false)
933+ then (debt - tokensAmountB)
934+ else 0
935+ let exInv = if ((amountToGetEx > 0))
936+ then exchangeDirectly(pType, pool, idAStr, idBStr, (balA - tokensAmountA), (balB - tokensAmountB), amountToGetEx, borrowAsset)
937+ else nil
938+ if ((exInv == exInv))
939+ then {
940+ let cBalAAfterRepay = accountBalance(idA)
941+ if ((cBalAAfterRepay == cBalAAfterRepay))
942+ then {
943+ let cBalBAfterRepay = accountBalance(idB)
944+ if ((cBalBAfterRepay == cBalBAfterRepay))
945+ then {
946+ let closeDbtInv = if ((debt > 0))
947+ then invoke(getLendSrvAddr(), "repayFor", [((user + "_") + posId)], [AttachedPayment(assetIdFromStr(borrowAsset), debt)])
948+ else 0
949+ if ((closeDbtInv == closeDbtInv))
950+ then if ((borrowAsset == idAStr))
951+ then $Tuple2(((cBalAAfterRepay - cBalABefore) - debt), (cBalBAfterRepay - cBalBBefore))
952+ else $Tuple2((cBalAAfterRepay - cBalABefore), ((cBalBAfterRepay - cBalBBefore) - debt))
953+ else throw("Strict value is not equal to itself.")
954+ }
955+ else throw("Strict value is not equal to itself.")
956+ }
957+ else throw("Strict value is not equal to itself.")
958+ }
959+ else throw("Strict value is not equal to itself.")
960+ }
961+ else throw("Strict value is not equal to itself.")
962+ }
963+ else $Tuple2(tokensAmountA, tokensAmountB)
964+ let toUserA = $t02825429490._1
965+ let toUserB = $t02825429490._2
966+ let poolTotalLoanEntries = if (isBorrowed)
967+ then [IntegerEntry((pool + kPoolTotalLoan), ((poolTotalShareLoan - userCanWithdraw) - stopLossFee))]
968+ else nil
969+ let entries = (([DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserPosition)), DeleteEntry((((user + "_") + posId) + kUserPositionPool)), DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserBorrowAmount)), DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserBorrowAssetId)), DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserPositionInterest)), IntegerEntry((pool + kPoolTotal), ((poolTotalShare - userCanWithdraw) - stopLossFee)), ScriptTransfer(userAddr, toUserA, idA), ScriptTransfer(userAddr, toUserB, idB), ScriptTransfer(moneyBox, stopLossFee, fromBase58String(shareId))] ++ poolTotalLoanEntries) ++ getCursEntries(idAStr, idBStr, shareId, nil))
970+ $Tuple2(entries, [toUserA, toUserB])
867971 }
868972 else throw("Strict value is not equal to itself.")
869973 }
870- else $Tuple2(tokensAmountA, tokensAmountB)
871- let toUserA = $t02593026784._1
872- let toUserB = $t02593026784._2
873- $Tuple5(toUserA, assetIdA, toUserB, assetIdB, shareId)
974+ else throw("Strict value is not equal to itself.")
874975 }
875976 else throw("Strict value is not equal to itself.")
876- }
877- else throw("Strict value is not equal to itself.")
878- }
879- else throw("Strict value is not equal to itself.")
880- }
881-
882-
883-func userCanWithdrawShareCalc (user,pool,posId,borrowed) = {
884- let pAmount = valueOrErrorMessage(getInteger(this, (((((pool + "_") + user) + "_") + posId) + kUserPosition)), "Unknown position")
885- let userInterest = getIntegerValue(this, (((((pool + "_") + user) + "_") + posId) + kUserPositionInterest))
886- let poolInterest = if (borrowed)
887- then getIntegerValue(this, (pool + kPoolInterestLoan))
888- else getIntegerValue(this, (pool + kPoolInterestNoLoan))
889- (pAmount + fraction(pAmount, (poolInterest - userInterest), SCALE10))
890- }
891-
892-
893-func withdrawToUser (user,pool,posId,stopLoss) = {
894- let pAmount = valueOrErrorMessage(getInteger(this, (((((pool + "_") + user) + "_") + posId) + kUserPosition)), "Unknown position")
895- let borrowAmount = valueOrElse(getInteger(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAmount)), 0)
896- let userCanWithdraw = userCanWithdrawShareCalc(user, pool, posId, (borrowAmount > 0))
897- let poolTotalShare = getPoolTotalShare(pool)
898- let userAddr = Address(fromBase58String(user))
899- let borrowAsset = valueOrElse(getString(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAssetId)), "")
900- let $t02798228216 = if ((borrowAmount > 0))
901- then $Tuple2({
902- let @ = invoke(getLendSrvAddr(), "getAssetDebt", [false, ((user + "_") + posId), borrowAsset], nil)
903- if ($isInstanceOf(@, "Int"))
904- then @
905- else throw(($getType(@) + " couldn't be cast to Int"))
906- }, STOPLOSS_LOAN)
907- else $Tuple2(0, STOPLOSS_FEE_NO_LOAN)
908- let debt = $t02798228216._1
909- let feeType = $t02798228216._2
910- let stopLossFee = if (stopLoss)
911- then fraction(userCanWithdraw, getAxlyFee(pool, feeType), FEE_SCALE6)
912- else 0
913- let $t02833328489 = withdrawAmountCalc(pool, (userCanWithdraw - stopLossFee), debt, borrowAsset, stopLossFee)
914- if (($t02833328489 == $t02833328489))
915- then {
916- let shareId = $t02833328489._5
917- let assetIdB = $t02833328489._4
918- let toUserAmountB = $t02833328489._3
919- let assetIdA = $t02833328489._2
920- let toUserAmountA = $t02833328489._1
921- let closeDbtInv = if ((debt > 0))
922- then invoke(getLendSrvAddr(), "repayFor", [((user + "_") + posId)], [AttachedPayment(assetIdFromStr(borrowAsset), debt)])
923- else 0
924- if ((closeDbtInv == closeDbtInv))
925- then {
926- let entries = ([DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserPosition)), DeleteEntry((((user + "_") + posId) + kUserPositionPool)), DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserBorrowAmount)), DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserBorrowAssetId)), DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserPositionInterest)), IntegerEntry((pool + kPoolTotal), ((poolTotalShare - userCanWithdraw) - stopLossFee)), ScriptTransfer(userAddr, toUserAmountA, assetIdFromStr(assetIdA)), ScriptTransfer(userAddr, toUserAmountB, assetIdFromStr(assetIdB)), ScriptTransfer(moneyBox, stopLossFee, fromBase58String(shareId))] ++ getCursEntries(assetIdA, assetIdB, shareId, nil))
927- $Tuple2(entries, [toUserAmountA, toUserAmountB])
928977 }
929978 else throw("Strict value is not equal to itself.")
930979 }
9591008 let decPrA = pow(10, 0, getAssetDecimals(aId), 0, 0, DOWN)
9601009 let decPrB = pow(10, 0, getAssetDecimals(bId), 0, 0, DOWN)
9611010 let paydInDollar = (fraction(dPriceA, pmtA, decPrA) + fraction(dPriceB, pmtB, decPrB))
962- let $t03055230649 = if ((borrowId == aId))
1011+ let $t03147231569 = if ((borrowId == aId))
9631012 then $Tuple2(dPriceA, decPrA)
9641013 else $Tuple2(dPriceB, decPrB)
965- let borrowPrice = $t03055230649._1
966- let borrowDecPr = $t03055230649._2
1014+ let borrowPrice = $t03147231569._1
1015+ let borrowDecPr = $t03147231569._2
9671016 fraction(fraction(paydInDollar, (leverage - 100), 100), borrowDecPr, borrowPrice)
9681017 }
9691018
9911040 }
9921041
9931042
994-func claimAndCheckAmntEx (pool,pType,claim,amountToExchange,change) = {
995- let $t03166331950 = if (claim)
1043+func claimAndCheckAmnt (pool,pType,claim,amount,change) = {
1044+ let $t03256932828 = if (claim)
9961045 then claimFarmed(pType, pool)
9971046 else {
9981047 let claimedAsset = if ((pType == SF_POOL))
10001049 else if ((pType == WX_POOL))
10011050 then WXID
10021051 else unknownPoolType()
1003- $Tuple2(amountToExchange, claimedAsset)
1052+ $Tuple2(amount, claimedAsset)
10041053 }
1005- let claimAmount = $t03166331950._1
1006- let claimAsset = $t03166331950._2
1054+ let claimAmount = $t03256932828._1
1055+ let claimAsset = $t03256932828._2
10071056 let bal = accountBalance(claimAsset)
1008- if (if ((amountToExchange > (claimAmount + change)))
1057+ if (if ((amount > (claimAmount + change)))
10091058 then true
1010- else (amountToExchange > bal))
1059+ else (amount > bal))
10111060 then throw("To big amount to exchange")
10121061 else $Tuple2(claimAmount, claimAsset)
10131062 }
1063+
1064+
1065+@Callable(i)
1066+func getPoolInfoREADONLY (pool) = {
1067+ let poolAddr = addressFromStringValue(pool)
1068+ let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
1069+ let $t03322533315 = getPoolData(Address(fromBase58String(pool)), pType)
1070+ let AId = $t03322533315._1
1071+ let BId = $t03322533315._2
1072+ let balA = $t03322533315._3
1073+ let balB = $t03322533315._4
1074+ let shareId = $t03322533315._5
1075+ let shareSupply = getShareSupply(poolAddr, pType, shareId)
1076+ $Tuple2(nil, $Tuple6(AId, BId, shareId, balA, balB, shareSupply))
1077+ }
1078+
10141079
10151080
10161081 @Callable(i)
10341099 @Callable(i)
10351100 func getUserPositionREADONLY (user,pools,posNum) = {
10361101 func userPos (a,pool) = {
1037- let $t03293833008 = a
1038- let wAmountsA = $t03293833008._1
1039- let wAmountsB = $t03293833008._2
1040- let debts = $t03293833008._3
1041- let eqWAmountsA = $t03293833008._4
1042- let eqWAmountsB = $t03293833008._5
1043- let index = $t03293833008._6
1102+ let $t03418834258 = a
1103+ let wAmountsA = $t03418834258._1
1104+ let wAmountsB = $t03418834258._2
1105+ let debts = $t03418834258._3
1106+ let eqWAmountsA = $t03418834258._4
1107+ let eqWAmountsB = $t03418834258._5
1108+ let index = $t03418834258._6
10441109 if (!(isDefined(getInteger(this, (((((pool + "_") + user) + "_") + posNum[index]) + kUserPosition)))))
10451110 then $Tuple6((wAmountsA :+ 0), (wAmountsB :+ 0), (debts :+ 0), (eqWAmountsA :+ 0), (eqWAmountsB :+ 0), (index + 1))
10461111 else {
10471112 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
1048- let $t03328733377 = getPoolData(Address(fromBase58String(pool)), pType)
1049- let AId = $t03328733377._1
1050- let BId = $t03328733377._2
1051- let balA = $t03328733377._3
1052- let balB = $t03328733377._4
1053- let shareId = $t03328733377._5
1113+ let $t03453734627 = getPoolData(Address(fromBase58String(pool)), pType)
1114+ let AId = $t03453734627._1
1115+ let BId = $t03453734627._2
1116+ let balA = $t03453734627._3
1117+ let balB = $t03453734627._4
1118+ let shareId = $t03453734627._5
10541119 let borrowAmount = valueOrElse(getInteger(this, (((((pool + "_") + user) + "_") + posNum[index]) + kUserBorrowAmount)), 0)
10551120 let userCanWithdraw = userCanWithdrawShareCalc(user, pool, posNum[index], (borrowAmount > 0))
1056- let $t03359333713 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userCanWithdraw)
1057- let wAmountA = $t03359333713._1
1058- let wAmountB = $t03359333713._2
1121+ let $t03484334963 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userCanWithdraw)
1122+ let wAmountA = $t03484334963._1
1123+ let wAmountB = $t03484334963._2
10591124 if ((borrowAmount > 0))
10601125 then {
10611126 let borrowAsset = getStringValue(this, (((((pool + "_") + user) + "_") + posNum[index]) + kUserBorrowAssetId))
10671132 }
10681133 if ((debt == debt))
10691134 then {
1070- let $t03399734281 = if ((pType == SF_POOL))
1071- then calcAmountToPaySF(pool, AId, BId, balA, balB, debt, borrowAsset)
1072- else if ((pType == WX_POOL))
1073- then calcAmountToPayWX(pool, AId, BId, balA, balB, debt, borrowAsset)
1074- else unknownPoolType()
1075- let assetToPay = $t03399734281._1
1076- let amountToPay = $t03399734281._2
1077- let $t03428834434 = if ((assetToPay == BId))
1078- then $Tuple2((wAmountA - debt), (wAmountB - amountToPay))
1079- else $Tuple2((wAmountA - amountToPay), (wAmountB - debt))
1080- let eqWAmountA = $t03428834434._1
1081- let eqWAmountB = $t03428834434._2
1135+ let amountToGetEx = if (if ((borrowAsset == AId))
1136+ then (debt > wAmountA)
1137+ else false)
1138+ then (debt - wAmountA)
1139+ else if (if ((borrowAsset == BId))
1140+ then (debt > wAmountB)
1141+ else false)
1142+ then (debt - wAmountB)
1143+ else 0
1144+ let amountToPay = if ((amountToGetEx > 0))
1145+ then if ((pType == SF_POOL))
1146+ then {
1147+ let ex = calcAmountToPaySF(pool, AId, BId, balA, balB, amountToGetEx, borrowAsset)
1148+ ex._2
1149+ }
1150+ else if ((pType == WX_POOL))
1151+ then {
1152+ let ex = calcAmountToPayWX(pool, AId, BId, balA, balB, amountToGetEx, borrowAsset)
1153+ ex._2
1154+ }
1155+ else unknownPoolType()
1156+ else 0
1157+ let $t03587536094 = if ((borrowAsset == AId))
1158+ then $Tuple2(((wAmountA + amountToGetEx) - debt), (wAmountB - amountToPay))
1159+ else $Tuple2((wAmountA - amountToPay), ((wAmountB + amountToGetEx) - debt))
1160+ let eqWAmountA = $t03587536094._1
1161+ let eqWAmountB = $t03587536094._2
10821162 $Tuple6((wAmountsA :+ wAmountA), (wAmountsB :+ wAmountB), (debts :+ debt), (eqWAmountsA :+ eqWAmountA), (eqWAmountsB :+ eqWAmountB), (index + 1))
10831163 }
10841164 else throw("Strict value is not equal to itself.")
10871167 }
10881168 }
10891169
1090- let $t03468934800 = {
1170+ let $t03634936460 = {
10911171 let $l = pools
10921172 let $s = size($l)
10931173 let $acc0 = $Tuple6(nil, nil, nil, nil, nil, 0)
11011181
11021182 $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($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), 13), 14), 15), 16), 17), 18), 19), 20)
11031183 }
1104- let wAmountsA = $t03468934800._1
1105- let wAmountsB = $t03468934800._2
1106- let debts = $t03468934800._3
1107- let eqWAmountsA = $t03468934800._4
1108- let eqWAmountsB = $t03468934800._5
1184+ let wAmountsA = $t03634936460._1
1185+ let wAmountsB = $t03634936460._2
1186+ let debts = $t03634936460._3
1187+ let eqWAmountsA = $t03634936460._4
1188+ let eqWAmountsB = $t03634936460._5
11091189 $Tuple2(nil, $Tuple5(wAmountsA, wAmountsB, debts, eqWAmountsA, eqWAmountsB))
11101190 }
11111191
11251205 else false)
11261206 then throw("You can't borrow in this pool")
11271207 else {
1128- let $t03539835488 = getPoolData(Address(fromBase58String(pool)), pType)
1129- let AId = $t03539835488._1
1130- let BId = $t03539835488._2
1131- let balA = $t03539835488._3
1132- let balB = $t03539835488._4
1133- let shareId = $t03539835488._5
1208+ let $t03705837148 = getPoolData(Address(fromBase58String(pool)), pType)
1209+ let AId = $t03705837148._1
1210+ let BId = $t03705837148._2
1211+ let balA = $t03705837148._3
1212+ let balB = $t03705837148._4
1213+ let shareId = $t03705837148._5
11341214 if (if ((borrowId != AId))
11351215 then (borrowId != BId)
11361216 else false)
11371217 then throw("Wrong borrow asset")
11381218 else {
1139- let $t03556935628 = parseReplenishPmts(i.payments, AId, BId)
1140- let pmtA = $t03556935628._1
1141- let pmtB = $t03556935628._2
1219+ let $t03722937288 = parseReplenishPmts(i.payments, AId, BId)
1220+ let pmtA = $t03722937288._1
1221+ let pmtB = $t03722937288._2
11421222 let user = toString(i.caller)
11431223 let newPosNum = getNewUserPositionNumber(user)
11441224 if ((leverage > 100))
11581238 if ((inv == inv))
11591239 then {
11601240 let userStaked = getIntegerValue(this, (((((pool + "_") + user) + "_") + toString(newPosNum)) + kUserPosition))
1161- let $t03661736711 = getPoolBalances(Address(fromBase58String(pool)), pType, AId, BId)
1162- if (($t03661736711 == $t03661736711))
1241+ let $t03827738371 = getPoolBalances(Address(fromBase58String(pool)), pType, AId, BId)
1242+ if (($t03827738371 == $t03827738371))
11631243 then {
1164- let newBalB = $t03661736711._2
1165- let newBalA = $t03661736711._1
1244+ let newBalB = $t03827738371._2
1245+ let newBalA = $t03827738371._1
11661246 let prImpact = calcPriceImpact(balA, balB, newBalA, newBalB)
1167- let $t03678136896 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userStaked)
1168- let wAmountA = $t03678136896._1
1169- let wAmountB = $t03678136896._2
1247+ let $t03844138556 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userStaked)
1248+ let wAmountA = $t03844138556._1
1249+ let wAmountB = $t03844138556._2
11701250 $Tuple2(nil, [prImpact, wAmountA, wAmountB])
11711251 }
11721252 else throw("Strict value is not equal to itself.")
11761256 else throw("Strict value is not equal to itself.")
11771257 }
11781258 else {
1179- let $t03694937064 = replenishByType(pType, pool, NO_LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
1180- if (($t03694937064 == $t03694937064))
1259+ let $t03860938724 = replenishByType(pType, pool, NO_LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
1260+ if (($t03860938724 == $t03860938724))
11811261 then {
1182- let axlyFee = $t03694937064._2
1183- let userStaked = $t03694937064._1
1184- let $t03707037164 = getPoolBalances(Address(fromBase58String(pool)), pType, AId, BId)
1185- if (($t03707037164 == $t03707037164))
1262+ let axlyFee = $t03860938724._2
1263+ let userStaked = $t03860938724._1
1264+ let $t03873038824 = getPoolBalances(Address(fromBase58String(pool)), pType, AId, BId)
1265+ if (($t03873038824 == $t03873038824))
11861266 then {
1187- let newBalB = $t03707037164._2
1188- let newBalA = $t03707037164._1
1267+ let newBalB = $t03873038824._2
1268+ let newBalA = $t03873038824._1
11891269 let prImpact = calcPriceImpact(balA, balB, newBalA, newBalB)
1190- let $t03723437349 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userStaked)
1191- let wAmountA = $t03723437349._1
1192- let wAmountB = $t03723437349._2
1270+ let $t03889439009 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userStaked)
1271+ let wAmountA = $t03889439009._1
1272+ let wAmountB = $t03889439009._2
11931273 $Tuple2((replenishEntries(pool, user, userStaked, axlyFee, newPosNum, shareId, pType, false) ++ getCursEntries(AId, BId, shareId, [toString(wAmountA), toString(wAmountB)])), [prImpact, wAmountA, wAmountB])
11941274 }
11951275 else throw("Strict value is not equal to itself.")
12421322
12431323
12441324 @Callable(i)
1245-func init (moneyBoxAddr,sfFarmingAddr,lendAddr,priceOracleAddr,keeperExContract,wxSwapContract,swopAssetId,wxAssetId,adminPubKey) = valueOrElse(isSelfCall(i), if (isDefined(getString(kAdminCallPK)))
1325+func init (moneyBoxAddr,sfFarmingAddr,lendAddr,priceOracleAddr,keeperExContract,wxSwapContract,swopAssetId,wxAssetId,operatorPubKey,group1Admin1PubKey,group1Admin2PubKey,group2Admin1PubKey,group2Admin2PubKey) = valueOrElse(isSelfCall(i), if (isDefined(getString(kOperatorCallPK)))
12461326 then throw("Already inited")
12471327 else if (!(isDefined(addressFromString(moneyBoxAddr))))
12481328 then throw("moneyBoxAddr is not correct address")
12581338 then throw("swopAssetId is not correct asset id")
12591339 else if (!(isDefined(assetInfo(fromBase58String(wxAssetId)))))
12601340 then throw("swopAssetId is not correct asset id")
1261- else if ((size(fromBase58String(adminPubKey)) != 32))
1262- then throw("adminPubKey is not correct")
1263- else [StringEntry(kMoneyBox, moneyBoxAddr), StringEntry(kSFFarmingAddr, sfFarmingAddr), StringEntry(kLendService, lendAddr), StringEntry(kPriceOracle, priceOracleAddr), StringEntry(kExContract, keeperExContract), StringEntry(kWxSwapContract, wxSwapContract), StringEntry(kSwopId, swopAssetId), StringEntry(kWxId, wxAssetId), StringEntry(kAdminCallPK, adminPubKey)])
1341+ else if ((size(fromBase58String(operatorPubKey)) != 32))
1342+ then throw("operatorPubKey is not correct")
1343+ else if ((size(fromBase58String(group1Admin1PubKey)) != 32))
1344+ then throw("group1Admin1PubKey is not correct")
1345+ else if ((size(fromBase58String(group1Admin2PubKey)) != 32))
1346+ then throw("group1Admin2PubKey is not correct")
1347+ else if ((size(fromBase58String(group2Admin1PubKey)) != 32))
1348+ then throw("group2Admin1PubKey is not correct")
1349+ else if ((size(fromBase58String(group2Admin2PubKey)) != 32))
1350+ then throw("group2Admin2PubKey is not correct")
1351+ else [StringEntry(kMoneyBox, moneyBoxAddr), StringEntry(kSFFarmingAddr, sfFarmingAddr), StringEntry(kLendService, lendAddr), StringEntry(kPriceOracle, priceOracleAddr), StringEntry(kExContract, keeperExContract), StringEntry(kWxSwapContract, wxSwapContract), StringEntry(kSwopId, swopAssetId), StringEntry(kWxId, wxAssetId), StringEntry(kOperatorCallPK, operatorPubKey), StringEntry(kGroup1Admin1PK, group1Admin1PubKey), StringEntry(kGroup1Admin2PK, group1Admin2PubKey), StringEntry(kGroup2Admin1PK, group2Admin1PubKey), StringEntry(kGroup2Admin2PK, group2Admin2PubKey)])
12641352
12651353
12661354
12741362
12751363 @Callable(i)
12761364 func replenishFromLand (requestId) = valueOrElse(isActive(), valueOrElse(isLandCall(i), {
1277- let $t04139841502 = parseRequest(requestId)
1278- let user = $t04139841502._1
1279- let pool = $t04139841502._2
1280- let pmtA = $t04139841502._3
1281- let AId = $t04139841502._4
1282- let pmtB = $t04139841502._5
1283- let BId = $t04139841502._6
1284- let balA = $t04139841502._7
1285- let balB = $t04139841502._8
1286- let shareId = $t04139841502._9
1287- let bwAsset = $t04139841502._10
1288- let bwAmount = $t04139841502._11
1365+ let $t04384843952 = parseRequest(requestId)
1366+ let user = $t04384843952._1
1367+ let pool = $t04384843952._2
1368+ let pmtA = $t04384843952._3
1369+ let AId = $t04384843952._4
1370+ let pmtB = $t04384843952._5
1371+ let BId = $t04384843952._6
1372+ let balA = $t04384843952._7
1373+ let balB = $t04384843952._8
1374+ let shareId = $t04384843952._9
1375+ let bwAsset = $t04384843952._10
1376+ let bwAmount = $t04384843952._11
12891377 if ((size(i.payments) != 1))
12901378 then throw("Wrong payment size")
12911379 else if (if ((assetIdToStr(i.payments[0].assetId) != bwAsset))
12931381 else (i.payments[0].amount != bwAmount))
12941382 then throw("Wrong payment")
12951383 else {
1296- let $t04169241792 = if ((AId == bwAsset))
1384+ let $t04414244242 = if ((AId == bwAsset))
12971385 then $Tuple2((pmtA + bwAmount), pmtB)
12981386 else $Tuple2(pmtA, (pmtB + bwAmount))
1299- let pmtAllA = $t04169241792._1
1300- let pmtAllB = $t04169241792._2
1387+ let pmtAllA = $t04414244242._1
1388+ let pmtAllB = $t04414244242._2
13011389 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Unknown pool")
1302- let $t04187441989 = replenishByType(pType, pool, LOAN_FEE, pmtAllA, AId, pmtAllB, BId, balA, balB, shareId)
1303- let userStaked = $t04187441989._1
1304- let axlyFee = $t04187441989._2
1390+ let $t04432444439 = replenishByType(pType, pool, LOAN_FEE, pmtAllA, AId, pmtAllB, BId, balA, balB, shareId)
1391+ let userStaked = $t04432444439._1
1392+ let axlyFee = $t04432444439._2
13051393 let posNum = getNewUserPositionNumber(user)
13061394 let borrowEntries = [IntegerEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserBorrowAmount), bwAmount), StringEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserBorrowAssetId), bwAsset)]
13071395 let entries = replenishEntries(pool, user, userStaked, axlyFee, posNum, shareId, pType, true)
1308- let $t04234942464 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userStaked)
1309- let wAmountA = $t04234942464._1
1310- let wAmountB = $t04234942464._2
1396+ let $t04479944914 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userStaked)
1397+ let wAmountA = $t04479944914._1
1398+ let wAmountB = $t04479944914._2
13111399 $Tuple2((((entries ++ getCursEntries(AId, BId, shareId, [toString(wAmountA), toString(wAmountB)])) ++ borrowEntries) :+ DeleteEntry((requestId + kRequestId))), userStaked)
13121400 }
13131401 }))
13181406 func liquidate (user,posId,liquidateAmount) = valueOrElse(isActive(), valueOrElse(isLandCall(i), {
13191407 let pool = valueOrErrorMessage(getString(this, (((user + "_") + posId) + kUserPositionPool)), "no position")
13201408 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
1321- let $t04298543075 = getPoolData(Address(fromBase58String(pool)), pType)
1322- let AId = $t04298543075._1
1323- let BId = $t04298543075._2
1324- let balA = $t04298543075._3
1325- let balB = $t04298543075._4
1326- let shareId = $t04298543075._5
1409+ let $t04543545525 = getPoolData(Address(fromBase58String(pool)), pType)
1410+ let AId = $t04543545525._1
1411+ let BId = $t04543545525._2
1412+ let balA = $t04543545525._3
1413+ let balB = $t04543545525._4
1414+ let shareId = $t04543545525._5
13271415 let amount = unstakeLP(pool, pType, shareId, liquidateAmount)
13281416 let borrowAmount = getIntegerValue(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAmount))
13291417 let borrowAsset = getStringValue(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAssetId))
13381426
13391427
13401428 @Callable(i)
1341-func stopLoss (user,posId,pool,assetId) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
1429+func stopLoss (user,posId,pool,assetId) = valueOrElse(isActive(), valueOrElse(isOperatorCall(i), {
13421430 let tokenOraclePrice = getIntegerValue(priceOracleAddr, (assetId + kPriceInOracle))
13431431 let stopLossPrice = valueOrErrorMessage(getInteger(this, (((((((user + "_") + toString(posId)) + "_") + pool) + "_") + assetId) + kUserStopLoss)), "No entry")
13441432 if ((tokenOraclePrice > stopLossPrice))
13521440
13531441
13541442 @Callable(i)
1355-func capitalizeExKeeper (pool,tokenToId,amountToExchange,claim,amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived,options) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
1443+func capitalizeExKeeper (pool,tokenToId,amountToExchange,claim,amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived,options) = valueOrElse(isActive(), valueOrElse(isOperatorCall(i), {
13561444 let pType = getStringValue(this, (kPool + pool))
13571445 let change = valueOrElse(getInteger(this, (pool + kPoolCapChange)), 0)
1358- let $t04521845319 = claimAndCheckAmntEx(pool, pType, claim, amountToExchange, change)
1359- let claimedAmount = $t04521845319._1
1360- let claimedAsset = $t04521845319._2
1446+ let $t04767447773 = claimAndCheckAmnt(pool, pType, claim, amountToExchange, change)
1447+ let claimedAmount = $t04767447773._1
1448+ let claimedAsset = $t04767447773._2
13611449 let exchangedAmount = exchangeKeeper(tokenToId, amountToExchange, claimedAsset, amountsIn, addresses, assetsToReceive, estReceived, slippageTolerance, minReceived, options)
13621450 let newChange = ((claimedAmount + change) - amountToExchange)
13631451 let changeEntry = if ((newChange >= 0))
13641452 then [IntegerEntry((pool + kPoolCapChange), newChange)]
1365- else nil
1453+ else throw("Negative change")
13661454 (capitalize(pool, pType, tokenToId, exchangedAmount) ++ changeEntry)
13671455 }))
13681456
13691457
13701458
13711459 @Callable(i)
1372-func capitalizeExPuzzle (pool,tokenToId,amountToExchange,claim,routesStr,minToReceive,options) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
1460+func capitalizeExPuzzle (pool,tokenToId,amountToExchange,claim,routesStr,minToReceive,options) = valueOrElse(isActive(), valueOrElse(isOperatorCall(i), {
13731461 let pType = getStringValue(this, (kPool + pool))
13741462 let change = valueOrElse(getInteger(this, (pool + kPoolCapChange)), 0)
1375- let $t04609446195 = claimAndCheckAmntEx(pool, pType, claim, amountToExchange, change)
1376- let claimedAmount = $t04609446195._1
1377- let claimedAsset = $t04609446195._2
1463+ let $t04857348672 = claimAndCheckAmnt(pool, pType, claim, amountToExchange, change)
1464+ let claimedAmount = $t04857348672._1
1465+ let claimedAsset = $t04857348672._2
13781466 let exchangedAmount = exchangePuzzle(tokenToId, amountToExchange, claimedAsset, routesStr, minToReceive, options)
13791467 let newChange = ((claimedAmount + change) - amountToExchange)
13801468 let changeEntry = if ((newChange >= 0))
13861474
13871475
13881476 @Callable(i)
1389-func capitalizeExSwopFi (pool,tokenToId,amountToExchange,claim,exchangers,exchangersType,args1,args2,routingAssetsKeys,minAmountToReceive,options) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
1477+func capitalizeExSwopFi (pool,tokenToId,amountToExchange,claim,exchangers,exchangersType,args1,args2,routingAssetsKeys,minAmountToReceive,options) = valueOrElse(isActive(), valueOrElse(isOperatorCall(i), {
13901478 let pType = getStringValue(this, (kPool + pool))
13911479 let change = valueOrElse(getInteger(this, (pool + kPoolCapChange)), 0)
1392- let $t04703747138 = claimAndCheckAmntEx(pool, pType, claim, amountToExchange, change)
1393- let claimedAmount = $t04703747138._1
1394- let claimedAsset = $t04703747138._2
1480+ let $t04951749616 = claimAndCheckAmnt(pool, pType, claim, amountToExchange, change)
1481+ let claimedAmount = $t04951749616._1
1482+ let claimedAsset = $t04951749616._2
13951483 let exchangedAmount = exchangeSwopFi(tokenToId, amountToExchange, claimedAsset, exchangers, exchangersType, args1, args2, routingAssetsKeys, minAmountToReceive, options)
13961484 let newChange = ((claimedAmount + change) - amountToExchange)
13971485 let changeEntry = if ((newChange >= 0))
14031491
14041492
14051493 @Callable(i)
1494+func capitalizeNoEx (pool,claim,amountFromBalance) = valueOrElse(isActive(), valueOrElse(isOperatorCall(i), {
1495+ let pType = getStringValue(this, (kPool + pool))
1496+ let $t05021350308 = claimAndCheckAmnt(pool, pType, claim, amountFromBalance, 0)
1497+ let claimedAmount = $t05021350308._1
1498+ let claimedAsset = $t05021350308._2
1499+ capitalize(pool, pType, assetIdToStr(claimedAsset), (claimedAmount + amountFromBalance))
1500+ }))
1501+
1502+
1503+
1504+@Callable(i)
14061505 func initNewPool (type,poolAddr,inFeeNoLoan,inFeeLoan,capFeeNoLoan,capFeeWithLoan,stoplossFeeNoLoan,stoplossFeeWithLoan,canBorrow) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), if (if ((type != SF_POOL))
14071506 then (type != WX_POOL)
14081507 else false)
14091508 then throw("Wrong type")
14101509 else {
1411- let $t04786947963 = getPoolData(Address(fromBase58String(poolAddr)), type)
1412- let aId = $t04786947963._1
1413- let bId = $t04786947963._2
1414- let aBal = $t04786947963._3
1415- let bBal = $t04786947963._4
1416- let shareId = $t04786947963._5
1510+ let $t05073450828 = getPoolData(Address(fromBase58String(poolAddr)), type)
1511+ let aId = $t05073450828._1
1512+ let bId = $t05073450828._2
1513+ let aBal = $t05073450828._3
1514+ let bBal = $t05073450828._4
1515+ let shareId = $t05073450828._5
14171516 if ((0 > inFeeNoLoan))
14181517 then throw("inFeeNoLoan must be greater than 0")
14191518 else if ((0 > inFeeLoan))
14281527 then throw("stoplossFeeWithLoan must be greater than 0")
14291528 else [IntegerEntry((poolAddr + kAxlyInFeeWithoutLoan), inFeeNoLoan), IntegerEntry((poolAddr + kAxlyInFeeWithLoan), inFeeLoan), IntegerEntry((poolAddr + kAxlyNoLoanCapFee), capFeeNoLoan), IntegerEntry((poolAddr + kAxlyWithLoanCapFee), capFeeWithLoan), IntegerEntry((poolAddr + kAxlyStopLossNoLoanFee), stoplossFeeNoLoan), IntegerEntry((poolAddr + kAxlyStopLossLoanFee), stoplossFeeWithLoan), IntegerEntry((poolAddr + kPoolInterestLoan), 0), IntegerEntry((poolAddr + kPoolInterestNoLoan), 0), StringEntry((kPool + poolAddr), type), StringEntry((shareId + kSharePool), poolAddr), BooleanEntry((poolAddr + kPoolCanBorrow), canBorrow)]
14301529 }))
1530+
1531+
1532+
1533+@Callable(i)
1534+func updatePoolFees (poolAddr,inFeeNoLoan,inFeeLoan,capFeeNoLoan,capFeeWithLoan,stoplossFeeNoLoan,stoplossFeeWithLoan) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), if (!(isDefined(getString(this, (kPool + poolAddr)))))
1535+ then throw(("Can't find pool with addr " + poolAddr))
1536+ else if ((0 > inFeeNoLoan))
1537+ then throw("inFeeNoLoan must be greater than 0")
1538+ else if ((0 > inFeeLoan))
1539+ then throw("inFeeLoan must be greater than 0")
1540+ else if ((0 > capFeeNoLoan))
1541+ then throw("capFeeNoLoan must be greater than 0")
1542+ else if ((0 > capFeeWithLoan))
1543+ then throw("capFeeWithLoan must be greater than 0")
1544+ else if ((0 > stoplossFeeNoLoan))
1545+ then throw("stoplossFeeNoLoan must be greater than 0")
1546+ else if ((0 > stoplossFeeWithLoan))
1547+ then throw("stoplossFeeWithLoan must be greater than 0")
1548+ else [IntegerEntry((poolAddr + kAxlyInFeeWithoutLoan), inFeeNoLoan), IntegerEntry((poolAddr + kAxlyInFeeWithLoan), inFeeLoan), IntegerEntry((poolAddr + kAxlyNoLoanCapFee), capFeeNoLoan), IntegerEntry((poolAddr + kAxlyWithLoanCapFee), capFeeWithLoan), IntegerEntry((poolAddr + kAxlyStopLossNoLoanFee), stoplossFeeNoLoan), IntegerEntry((poolAddr + kAxlyStopLossLoanFee), stoplossFeeWithLoan)]))
14311549
14321550
14331551
15041622 else [BooleanEntry((pool + kPoolActive), false)])
15051623
15061624
1507-@Verifier(tx)
1508-func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
1509-
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SF_POOL = "SF"
55
66 let WX_POOL = "WX"
77
88 let CAP_FEE_NO_LOAN = "capNoLoan"
99
1010 let CAP_FEE_LOAN = "capLoan"
1111
1212 let STOPLOSS_FEE_NO_LOAN = "stopLossNoLoan"
1313
1414 let STOPLOSS_LOAN = "stopLossLoan"
1515
1616 let LOAN_FEE = "loan"
1717
1818 let NO_LOAN_FEE = "noLoan"
1919
2020 let NO_FEE = "noFee"
2121
2222 let SCALE8 = 100000000
2323
2424 let SCALE10 = 10000000000
2525
2626 let SCALE16 = toBigInt(10000000000000000)
2727
2828 let FEE_SCALE6 = 1000000
2929
3030 let kSFPoolAAssetBalance = "A_asset_balance"
3131
3232 let kSFPoolBAssetBalance = "B_asset_balance"
3333
3434 let kSFPoolAAssetId = "A_asset_id"
3535
3636 let kSFPoolBAssetId = "B_asset_id"
3737
3838 let kSFPoolShareId = "share_asset_id"
3939
4040 let kSFPoolShareSupply = "share_asset_supply"
4141
4242 let kSFPoolFee = "commission"
4343
4444 let kUserPosition = "_userPosition"
4545
4646 let kUserPositionPool = "_userPositionPool"
4747
4848 let kUserBorrowAmount = "_userPositionBorrowAmount"
4949
5050 let kUserBorrowAssetId = "_userPositionBorrowAssetId"
5151
5252 let kUserPositionNum = "_userPositionNumber"
5353
5454 let kUserPositionInterest = "_userPositionInterest"
5555
5656 let kPoolTotal = "_poolTotal"
5757
5858 let kPoolTotalLoan = "_poolTotalLoan"
5959
6060 let kPoolInterestLoan = "_poolInterestLoan"
6161
6262 let kPoolInterestNoLoan = "_poolInterestNoLoan"
6363
6464 let kPoolCanBorrow = "_poolCanBorrow"
6565
6666 let kAxlyInFeeWithoutLoan = "_axlyFeeNoLoan"
6767
6868 let kAxlyInFeeWithLoan = "_axlyFeeWithLoan"
6969
70-let kAxlyNoLoanCapFee = "_axlyFeeCapWithLoan"
70+let kAxlyNoLoanCapFee = "_axlyFeeCapNoLoan"
7171
72-let kAxlyWithLoanCapFee = "_axlyFeeCapNoLoan"
72+let kAxlyWithLoanCapFee = "_axlyFeeCapWithLoan"
7373
7474 let kAxlyStopLossNoLoanFee = "_axlyFeeStoplossWithLoan"
7575
7676 let kAxlyStopLossLoanFee = "_axlyFeeStoplossNoLoan"
7777
7878 let kRequestId = "_request_id"
7979
8080 let kRequestIter = "requests_iter"
8181
8282 let kPool = "pool_"
8383
8484 let kSharePool = "_poolShareId"
8585
8686 let kPoolCapChange = "_poolCapChange"
8787
8888 let kTokenLastPrice = "last_price"
8989
9090 let kPriceInOracle = "_twap5B"
9191
9292 let kActive = "active"
9393
9494 let kActiveUsers = "activeUsers"
9595
9696 let kActiveSFWX = "_active"
9797
9898 let kPoolActive = "_activePool"
9999
100100 let kUserStopLoss = "_stopLoss"
101101
102102 let kMoneyBox = "axly_money_box"
103103
104104 let kSFFarmingAddr = "swopfi_farming_addr"
105105
106106 let kLendService = "lend_service_addr"
107107
108-let kAdminCallPK = "admin_call_pub_key"
108+let kOperatorCallPK = "admin_call_pub_key"
109109
110110 let kPriceOracle = "price_oracle"
111111
112112 let kExContract = "exchange_contract"
113113
114114 let kWxSwapContract = "wx_swap_contract"
115115
116116 let kSwopId = "swop_id"
117117
118118 let kWxId = "wx_id"
119+
120+let kGroup1Admin1PK = "group1_admin1_pub_key"
121+
122+let kGroup1Admin2PK = "group1_admin2_pub_key"
123+
124+let kGroup2Admin1PK = "group2_admin1_pub_key"
125+
126+let kGroup2Admin2PK = "group2_admin2_pub_key"
119127
120128 let moneyBox = Address(fromBase58String(valueOrErrorMessage(getString(this, kMoneyBox), "No axly moneyBox address")))
121129
122130 let exContract = Address(fromBase58String(valueOrErrorMessage(getString(this, kExContract), "No exchange contract address")))
123131
124132 let priceOracleAddr = Address(fromBase58String(valueOrErrorMessage(getString(this, kPriceOracle), "No price oracle address")))
125133
126134 let wxSwapContract = Address(fromBase58String(valueOrErrorMessage(getString(this, kWxSwapContract), "No wx swap address")))
127135
128136 let SWOPID = fromBase58String(valueOrErrorMessage(getString(this, kSwopId), "No swop id"))
129137
130138 let WXID = fromBase58String(valueOrErrorMessage(getString(this, kWxId), "No wx id"))
131139
140+let group1Admin1PK = fromBase58String(valueOrErrorMessage(getString(this, kGroup1Admin1PK), "Can't get kGroup1Admin1PK"))
141+
142+let group1Admin2PK = fromBase58String(valueOrErrorMessage(getString(this, kGroup1Admin2PK), "Can't get kGroup1Admin2PK"))
143+
144+let group2Admin1PK = fromBase58String(valueOrErrorMessage(getString(this, kGroup2Admin1PK), "Can't get kGroup2Admin1PK"))
145+
146+let group2Admin2PK = fromBase58String(valueOrErrorMessage(getString(this, kGroup2Admin2PK), "Can't get kGroup2Admin1PK"))
147+
148+let operatorPK = fromBase58String(valueOrErrorMessage(getString(this, kOperatorCallPK), "Can't get operatorPK"))
149+
132150 func unknownPoolType () = throw("Wrong pool type")
133151
134152
135153 func getLendSrvAddr () = Address(fromBase58String(valueOrErrorMessage(getString(this, kLendService), "Can't get lend service addr")))
136154
137155
138-func getAdminCallAddr () = addressFromPublicKey(fromBase58String(valueOrErrorMessage(getString(this, kAdminCallPK), "Can't get admin addr")))
156+func isOperatorCall (i) = if ((i.callerPublicKey == i.callerPublicKey))
157+ then unit
158+ else throw("Only operator can call this function")
139159
140160
141-func isAdminCall (i) = if ((i.caller == getAdminCallAddr()))
161+func isAdminCall (i) = if (if ((i.callerPublicKey == i.callerPublicKey))
162+ then true
163+ else (i.callerPublicKey == i.callerPublicKey))
142164 then unit
143- else throw("Only admin can call this function")
165+ else throw("Only admin group1 can call this function")
144166
145167
146168 func isSelfCall (i) = if ((i.caller == this))
147169 then unit
148170 else throw("Only contract itself can call this function")
149171
150172
151173 func isLandCall (i) = if ((i.caller == getLendSrvAddr()))
152174 then unit
153175 else throw("Only land contract can call this function")
154176
155177
156178 func isActive () = if ((valueOrElse(getBoolean(this, kActive), true) == true))
157179 then unit
158180 else throw("DApp is inactive at this moment")
159181
160182
161183 func isActiveForUsers () = if (if (valueOrElse(getBoolean(this, kActive), true))
162184 then (valueOrElse(getBoolean(this, kActiveUsers), true) == true)
163185 else false)
164186 then unit
165187 else throw("DApp is inactive for users at this moment")
166188
167189
168190 func isPoolActive (pool,type) = {
169191 let WXSFActive = valueOrElse(getBoolean(this, (type + kActiveSFWX)), true)
170192 let poolActive = valueOrElse(getBoolean(this, (pool + kPoolActive)), true)
171193 if (if (WXSFActive)
172194 then poolActive
173195 else false)
174196 then true
175197 else false
176198 }
177199
178200
179201 func accountBalance (assetId) = match assetId {
180202 case id: ByteVector =>
181203 assetBalance(this, id)
182204 case waves: Unit =>
183205 wavesBalance(this).available
184206 case _ =>
185207 throw("Match error")
186208 }
187209
188210
189211 func getSFPoolBalances (poolAddr) = $Tuple2(valueOrErrorMessage(getInteger(poolAddr, kSFPoolAAssetBalance), "Can't get pool A asset balance"), valueOrErrorMessage(getInteger(poolAddr, kSFPoolBAssetBalance), "Can't get pool B asset balance"))
190212
191213
192214 func getWXPoolBalances (poolAddr,aId,bId) = $Tuple2({
193215 let @ = invoke(poolAddr, "getAccBalanceWrapperREADONLY", [aId], nil)
194216 if ($isInstanceOf(@, "Int"))
195217 then @
196218 else throw(($getType(@) + " couldn't be cast to Int"))
197219 }, {
198220 let @ = invoke(poolAddr, "getAccBalanceWrapperREADONLY", [bId], nil)
199221 if ($isInstanceOf(@, "Int"))
200222 then @
201223 else throw(($getType(@) + " couldn't be cast to Int"))
202224 })
203225
204226
205227 func getPoolBalances (poolAddr,type,aId,bId) = if ((type == SF_POOL))
206228 then getSFPoolBalances(poolAddr)
207229 else if ((type == WX_POOL))
208230 then getWXPoolBalances(poolAddr, aId, bId)
209231 else unknownPoolType()
210232
211233
212234 func getSFPoolData (poolAddr) = {
213- let $t070647113 = getSFPoolBalances(poolAddr)
214- if (($t070647113 == $t070647113))
235+ let $t079127961 = getSFPoolBalances(poolAddr)
236+ if (($t079127961 == $t079127961))
215237 then {
216- let balB = $t070647113._2
217- let balA = $t070647113._1
238+ let balB = $t079127961._2
239+ let balA = $t079127961._1
218240 $Tuple5(valueOrErrorMessage(getString(poolAddr, kSFPoolAAssetId), "Can't get pool A asset id"), valueOrErrorMessage(getString(poolAddr, kSFPoolBAssetId), "Can't get pool B asset id"), balA, balB, valueOrErrorMessage(getString(poolAddr, kSFPoolShareId), "Can't get share asset id"))
219241 }
220242 else throw("Strict value is not equal to itself.")
221243 }
222244
223245
224246 func getWXPoolData (poolAddr) = {
225247 let cfg = {
226248 let @ = invoke(poolAddr, "getPoolConfigWrapperREADONLY", nil, nil)
227249 if ($isInstanceOf(@, "List[Any]"))
228250 then @
229251 else throw(($getType(@) + " couldn't be cast to List[Any]"))
230252 }
231253 if ((cfg == cfg))
232254 then {
233255 let aId = valueOrErrorMessage({
234256 let @ = cfg[4]
235257 if ($isInstanceOf(@, "String"))
236258 then @
237259 else unit
238260 }, "Can't get pool A asset id")
239261 let bId = valueOrErrorMessage({
240262 let @ = cfg[5]
241263 if ($isInstanceOf(@, "String"))
242264 then @
243265 else unit
244266 }, "Can't get pool B asset id")
245267 let shareId = valueOrErrorMessage({
246268 let @ = cfg[3]
247269 if ($isInstanceOf(@, "String"))
248270 then @
249271 else unit
250272 }, "Can't get pool LP asset id")
251- let $t078107869 = getWXPoolBalances(poolAddr, aId, bId)
252- if (($t078107869 == $t078107869))
273+ let $t086588717 = getWXPoolBalances(poolAddr, aId, bId)
274+ if (($t086588717 == $t086588717))
253275 then {
254- let balB = $t078107869._2
255- let balA = $t078107869._1
276+ let balB = $t086588717._2
277+ let balA = $t086588717._1
256278 $Tuple5(aId, bId, balA, balB, shareId)
257279 }
258280 else throw("Strict value is not equal to itself.")
259281 }
260282 else throw("Strict value is not equal to itself.")
261283 }
262284
263285
264286 func getPoolData (poolAddr,type) = if ((type == SF_POOL))
265287 then getSFPoolData(poolAddr)
266288 else if ((type == WX_POOL))
267289 then getWXPoolData(poolAddr)
268290 else unknownPoolType()
269291
270292
271293 func getShareSupply (poolAddr,type,shareId) = if ((type == SF_POOL))
272294 then valueOrErrorMessage(getInteger(poolAddr, kSFPoolShareSupply), "Can't get share asset supply")
273295 else if ((type == WX_POOL))
274296 then valueOrErrorMessage(assetInfo(fromBase58String(shareId)), "Wrong ShareId").quantity
275297 else unknownPoolType()
276298
277299
278300 func getPoolTotalShare (pool) = valueOrElse(getInteger(this, (pool + kPoolTotal)), 0)
279301
280302
281303 func getPoolTotalShareWithLoan (pool) = valueOrElse(getInteger(this, (pool + kPoolTotalLoan)), 0)
282304
283305
284306 func getNewUserPositionNumber (user) = (valueOrElse(getInteger(this, (user + kUserPositionNum)), 0) + 1)
285307
286308
287309 func getAxlyFee (pool,feeType) = if ((feeType == CAP_FEE_LOAN))
288310 then getIntegerValue(this, (pool + kAxlyWithLoanCapFee))
289311 else if ((feeType == CAP_FEE_NO_LOAN))
290312 then getIntegerValue(this, (pool + kAxlyNoLoanCapFee))
291313 else if ((feeType == LOAN_FEE))
292314 then getIntegerValue(this, (pool + kAxlyInFeeWithLoan))
293315 else if ((feeType == NO_LOAN_FEE))
294316 then getIntegerValue(this, (pool + kAxlyInFeeWithoutLoan))
295317 else if ((feeType == NO_FEE))
296318 then 0
297319 else throw("Wrong fee type")
298320
299321
300322 func getSFFarmingAddr () = Address(fromBase58String(valueOrErrorMessage(getString(this, kSFFarmingAddr), "Can't get swopfi farming addr")))
301323
302324
303325 func getWXFarmingAddr (poolAddr) = {
304326 let fContract = Address(fromBase58String(valueOrErrorMessage(getString(poolAddr, "%s__factoryContract"), "Can't get WX factory contract addr")))
305327 let factroyCfg = split(valueOrErrorMessage(getString(fContract, "%s__factoryConfig"), "Can't get WX factory cfg"), "__")
306328 Address(fromBase58String(factroyCfg[1]))
307329 }
308330
309331
310332 func assetIdToStr (assetId) = match assetId {
311333 case id: ByteVector =>
312334 toBase58String(id)
313335 case waves: Unit =>
314336 "WAVES"
315337 case _ =>
316338 throw("Not Asset id")
317339 }
318340
319341
320342 func assetIdFromStr (assetId) = if ((assetId == "WAVES"))
321343 then unit
322344 else fromBase58String(assetId)
323345
324346
325347 func getAssetDecimals (assetId) = if ((assetId == "WAVES"))
326348 then 8
327349 else match assetInfo(fromBase58String(assetId)) {
328350 case asset: Asset =>
329351 asset.decimals
330352 case _ =>
331353 throw("Can't find asset")
332354 }
333355
334356
335357 func getAssetPrecition (assetId) = pow(10, 0, getAssetDecimals(assetId), 0, 0, DOWN)
336358
337359
338360 func getAssetsPrice (assetIds) = {
339361 func getPrices (a,assetId) = {
340- let assetPrice = getIntegerValue(priceOracleAddr, (assetId + kPriceInOracle))
362+ let assetPrice = valueOrElse(getInteger(priceOracleAddr, (assetId + kPriceInOracle)), -1)
341363 (a :+ assetPrice)
342364 }
343365
344366 let $l = assetIds
345367 let $s = size($l)
346368 let $acc0 = nil
347369 func $f0_1 ($a,$i) = if (($i >= $s))
348370 then $a
349371 else getPrices($a, $l[$i])
350372
351373 func $f0_2 ($a,$i) = if (($i >= $s))
352374 then $a
353375 else throw("List size exceeds 50")
354376
355377 $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($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($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), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50)
356378 }
357379
358380
359381 func getSharePrice (shareId) = {
360382 let pool = valueOrErrorMessage(getString(this, (shareId + kSharePool)), "Can't find pool addr by share id")
361383 let poolAddr = Address(fromBase58String(pool))
362384 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
363- let $t01084710912 = getPoolData(poolAddr, pType)
364- let aId = $t01084710912._1
365- let bId = $t01084710912._2
366- let aBalance = $t01084710912._3
367- let bBalance = $t01084710912._4
368- let dPriceA = getIntegerValue(priceOracleAddr, (aId + kPriceInOracle))
369- let dPriceB = getIntegerValue(priceOracleAddr, (bId + kPriceInOracle))
370- let shareSupply = getShareSupply(poolAddr, pType, shareId)
371- let APrecision = pow(10, 0, getAssetDecimals(aId), 0, 0, DOWN)
372- let BPrecision = pow(10, 0, getAssetDecimals(bId), 0, 0, DOWN)
373- let sharePrecision = pow(10, 0, getAssetDecimals(shareId), 0, 0, DOWN)
374- let sum = (fraction(aBalance, dPriceA, APrecision) + fraction(bBalance, dPriceB, BPrecision))
375- fraction(sum, sharePrecision, shareSupply)
385+ let $t01170611771 = getPoolData(poolAddr, pType)
386+ let aId = $t01170611771._1
387+ let bId = $t01170611771._2
388+ let aBalance = $t01170611771._3
389+ let bBalance = $t01170611771._4
390+ let prices = getAssetsPrice([aId, bId])
391+ let dPriceA = prices[0]
392+ let dPriceB = prices[1]
393+ if (if ((0 > dPriceA))
394+ then true
395+ else (0 > dPriceB))
396+ then -1
397+ else {
398+ let shareSupply = getShareSupply(poolAddr, pType, shareId)
399+ let APrecision = pow(10, 0, getAssetDecimals(aId), 0, 0, DOWN)
400+ let BPrecision = pow(10, 0, getAssetDecimals(bId), 0, 0, DOWN)
401+ let sharePrecision = pow(10, 0, getAssetDecimals(shareId), 0, 0, DOWN)
402+ let sum = (fraction(aBalance, dPriceA, APrecision) + fraction(bBalance, dPriceB, BPrecision))
403+ fraction(sum, sharePrecision, shareSupply)
404+ }
376405 }
377406
378407
379408 func getSharePrices (shareIds) = {
380409 func getPrices (a,shareId) = (a :+ getSharePrice(shareId))
381410
382411 let $l = shareIds
383412 let $s = size($l)
384413 let $acc0 = nil
385414 func $f0_1 ($a,$i) = if (($i >= $s))
386415 then $a
387416 else getPrices($a, $l[$i])
388417
389418 func $f0_2 ($a,$i) = if (($i >= $s))
390419 then $a
391420 else throw("List size exceeds 20")
392421
393422 $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($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), 13), 14), 15), 16), 17), 18), 19), 20)
394423 }
395424
396425
397426 func getCursEntries (aId,bId,shareId,wAmounts) = {
398427 let assetsPrices = getAssetsPrice([aId, bId])
399428 let sharePrice = getSharePrice(shareId)
400429 let prices = ([toString(assetsPrices[0]), toString(assetsPrices[1]), toString(sharePrice)] ++ wAmounts)
401430 [StringEntry(kTokenLastPrice, makeString(prices, ","))]
402431 }
403432
404433
405434 func calcReplenishByTwoTokens (pType,poolAddr,pmtA,aId,pmtB,bId,balA,balB) = if ((pType == SF_POOL))
406435 then {
407436 let repl = {
408437 let @ = invoke(poolAddr, "callFunction", ["calcLPReplenishTwoTokensREADONLY", [toString(pmtA), toString(pmtB)]], nil)
409438 if ($isInstanceOf(@, "List[Any]"))
410439 then @
411440 else throw(($getType(@) + " couldn't be cast to List[Any]"))
412441 }
413442 if ((repl == repl))
414443 then $Tuple5({
415444 let @ = repl[3]
416445 if ($isInstanceOf(@, "Int"))
417446 then @
418447 else throw(($getType(@) + " couldn't be cast to Int"))
419448 }, {
420449 let @ = repl[4]
421450 if ($isInstanceOf(@, "Int"))
422451 then @
423452 else throw(($getType(@) + " couldn't be cast to Int"))
424453 }, {
425454 let @ = repl[1]
426455 if ($isInstanceOf(@, "Int"))
427456 then @
428457 else throw(($getType(@) + " couldn't be cast to Int"))
429458 }, assetIdToStr(repl[2]), {
430459 let @ = repl[0]
431460 if ($isInstanceOf(@, "Int"))
432461 then @
433462 else throw(($getType(@) + " couldn't be cast to Int"))
434463 })
435464 else throw("Strict value is not equal to itself.")
436465 }
437466 else if ((pType == WX_POOL))
438467 then {
439- let $t01245712707 = $Tuple2(split({
468+ let $t01331513565 = $Tuple2(split({
440469 let @ = invoke(poolAddr, "evaluatePutByAmountAssetREADONLY", [pmtA], nil)
441470 if ($isInstanceOf(@, "String"))
442471 then @
443472 else throw(($getType(@) + " couldn't be cast to String"))
444473 }, "__"), split({
445474 let @ = invoke(poolAddr, "evaluatePutByPriceAssetREADONLY", [pmtB], nil)
446475 if ($isInstanceOf(@, "String"))
447476 then @
448477 else throw(($getType(@) + " couldn't be cast to String"))
449478 }, "__"))
450- if (($t01245712707 == $t01245712707))
479+ if (($t01331513565 == $t01331513565))
451480 then {
452- let evalPutInB = $t01245712707._2
453- let evalPutInA = $t01245712707._1
481+ let evalPutInB = $t01331513565._2
482+ let evalPutInA = $t01331513565._1
454483 let lpInA = parseIntValue(evalPutInA[1])
455484 let lpInB = parseIntValue(evalPutInB[1])
456485 if ((lpInB > lpInA))
457486 then {
458487 let pmt = parseIntValue(evalPutInA[8])
459488 $Tuple5(pmtA, pmt, (pmtB - pmt), bId, lpInB)
460489 }
461490 else {
462491 let pmt = parseIntValue(evalPutInB[7])
463492 $Tuple5(pmt, pmtB, (pmtA - pmt), aId, lpInA)
464493 }
465494 }
466495 else throw("Strict value is not equal to itself.")
467496 }
468497 else unknownPoolType()
469498
470499
471500 func replenishTwoTokensByType (poolAddr,pType,pmtA,aId,pmtB,bId) = {
472501 let payments = [AttachedPayment(assetIdFromStr(aId), pmtA), AttachedPayment(assetIdFromStr(bId), pmtB)]
473502 if ((pType == SF_POOL))
474503 then invoke(poolAddr, "callFunction", ["replenishWithTwoTokens", ["false", "0"]], payments)
475504 else if ((pType == WX_POOL))
476505 then invoke(poolAddr, "put", [1000000, false], payments)
477506 else unknownPoolType()
478507 }
479508
480509
481510 func replenishOneTokenByType (poolAddr,pType,pmt,pmtId) = {
482511 let payments = [AttachedPayment(assetIdFromStr(pmtId), pmt)]
483512 if ((pType == SF_POOL))
484513 then invoke(poolAddr, "callFunction", ["replenishWithOneToken", ["0", "false", "0"]], payments)
485514 else if ((pType == WX_POOL))
486515 then invoke(poolAddr, "putOneTkn", [0, false], payments)
487516 else unknownPoolType()
488517 }
489518
490519
491520 func stakeLP (pool,pType,shareId,amount) = {
492521 let payments = [AttachedPayment(fromBase58String(shareId), amount)]
493522 if ((pType == SF_POOL))
494523 then invoke(getSFFarmingAddr(), "lockShareTokens", [pool, 0], payments)
495524 else if ((pType == WX_POOL))
496525 then invoke(getWXFarmingAddr(addressFromStringValue(pool)), "stake", nil, payments)
497526 else unknownPoolType()
498527 }
499528
500529
501530 func unstakeLP (pool,pType,shareId,amount) = {
502- let $t01436614716 = if ((pType == SF_POOL))
531+ let $t01522415574 = if ((pType == SF_POOL))
503532 then $Tuple3(getSFFarmingAddr(), "withdrawShareTokens", [pool, amount])
504533 else if ((pType == WX_POOL))
505534 then $Tuple3(getWXFarmingAddr(Address(fromBase58String(pool))), "unstake", [shareId, amount])
506535 else unknownPoolType()
507- let farmAddr = $t01436614716._1
508- let fName = $t01436614716._2
509- let params = $t01436614716._3
536+ let farmAddr = $t01522415574._1
537+ let fName = $t01522415574._2
538+ let params = $t01522415574._3
510539 let inv = invoke(farmAddr, fName, params, nil)
511540 if ((inv == inv))
512541 then amount
513542 else throw("Strict value is not equal to itself.")
514543 }
515544
516545
517546 func calcAmountToPaySF (pool,assetIdA,assetIdB,balA,balB,amountTokenToGet,assetTokenToGet) = {
518547 let poolAddr = Address(fromBase58String(pool))
519548 let feeScale6 = 1000000
520549 let fee = getIntegerValue(poolAddr, kSFPoolFee)
521550 let amntGetNoFee = fraction(amountTokenToGet, feeScale6, (feeScale6 - fee), CEILING)
522- let $t01513815444 = if ((assetTokenToGet == assetIdA))
551+ let $t01599616302 = if ((assetTokenToGet == assetIdA))
523552 then {
524553 let amountToPay = fraction(amntGetNoFee, balB, (balA - amntGetNoFee), CEILING)
525554 $Tuple2(amountToPay, assetIdB)
526555 }
527556 else {
528557 let amountToPay = fraction(amntGetNoFee, balA, (balB - amntGetNoFee), CEILING)
529558 $Tuple2(amountToPay, assetIdA)
530559 }
531- let amountToPay = $t01513815444._1
532- let assetToPay = $t01513815444._2
560+ let amountToPay = $t01599616302._1
561+ let assetToPay = $t01599616302._2
533562 $Tuple2(assetToPay, amountToPay)
534563 }
535564
536565
537566 func getWXSwapFees (pool) = {
538567 let poolAddr = addressFromStringValue(pool)
539568 let fContract = addressFromStringValue(valueOrErrorMessage(getString(poolAddr, "%s__factoryContract"), "Can't get WX factory contract addr"))
540569 let poolFeeDefault = value(getInteger(wxSwapContract, "%s__poolFee"))
541570 let protocolFeeDefault = value(getInteger(wxSwapContract, "%s__protocolFee"))
542571 match invoke(fContract, "getSwapFeeREADONLY", [toString(poolAddr)], nil) {
543572 case fees: (Int, Int) =>
544573 $Tuple2(fees._1, fees._2)
545574 case _ =>
546575 $Tuple2(poolFeeDefault, protocolFeeDefault)
547576 }
548577 }
549578
550579
551580 func calcAmountToPayWX (pool,assetIdA,assetIdB,balA,balB,amountTokenToGet,assetTokenToGet) = {
552- let $t01618416223 = getWXSwapFees(pool)
553- let pFee = $t01618416223._1
554- let prFee = $t01618416223._2
581+ let $t01704217081 = getWXSwapFees(pool)
582+ let pFee = $t01704217081._1
583+ let prFee = $t01704217081._2
555584 let feeScale = toBigInt(100000000)
556- let $t01626316571 = if ((assetTokenToGet == assetIdA))
585+ let $t01712117429 = if ((assetTokenToGet == assetIdA))
557586 then {
558587 let amountToPay = fraction(amountTokenToGet, balB, (balA - amountTokenToGet))
559588 $Tuple2(amountToPay, assetIdB)
560589 }
561590 else {
562591 let amountToPay = fraction(amountTokenToGet, balA, (balB - amountTokenToGet))
563592 $Tuple2(amountToPay, assetIdA)
564593 }
565- let amountToPay = $t01626316571._1
566- let assetToPay = $t01626316571._2
594+ let amountToPay = $t01712117429._1
595+ let assetToPay = $t01712117429._2
567596 let amountToPayWithFee = toInt(fraction(toBigInt(amountToPay), feeScale, (feeScale - toBigInt((prFee + pFee))), CEILING))
568597 $Tuple2(assetToPay, amountToPayWithFee)
569598 }
570599
571600
572601 func exchangeDirectly (pType,pool,assetIdA,assetIdB,balA,balB,amountTokenToGet,assetTokenToGet) = if ((pType == SF_POOL))
573602 then {
574- let $t01691817040 = calcAmountToPaySF(pool, assetIdA, assetIdB, balA, balB, amountTokenToGet, assetTokenToGet)
575- let assetToPay = $t01691817040._1
576- let amountToPay = $t01691817040._2
603+ let $t01777617898 = calcAmountToPaySF(pool, assetIdA, assetIdB, balA, balB, amountTokenToGet, assetTokenToGet)
604+ let assetToPay = $t01777617898._1
605+ let amountToPay = $t01777617898._2
577606 invoke(addressFromStringValue(pool), "callFunction", ["exchange", [toString(amountTokenToGet)]], [AttachedPayment(assetIdFromStr(assetToPay), amountToPay)])
578607 }
579608 else if ((pType == WX_POOL))
580609 then {
581- let $t01724017362 = calcAmountToPayWX(pool, assetIdA, assetIdB, balA, balB, amountTokenToGet, assetTokenToGet)
582- let assetToPay = $t01724017362._1
583- let amountToPay = $t01724017362._2
610+ let $t01809818220 = calcAmountToPayWX(pool, assetIdA, assetIdB, balA, balB, amountTokenToGet, assetTokenToGet)
611+ let assetToPay = $t01809818220._1
612+ let amountToPay = $t01809818220._2
584613 invoke(wxSwapContract, "swap", [amountTokenToGet, assetTokenToGet, toString(this)], [AttachedPayment(assetIdFromStr(assetToPay), amountToPay)])
585614 }
586615 else unknownPoolType()
587616
588617
589618 func calcWithdrawLPFromPoolVirt (poolAddr,pType,shareId,userCanWithdraw) = {
590- let $t01764918113 = if ((pType == SF_POOL))
619+ let $t01850718971 = if ((pType == SF_POOL))
591620 then {
592621 let inv = {
593622 let @ = invoke(poolAddr, "callFunction", ["withdrawREADONLY", [toString(userCanWithdraw)]], nil)
594623 if ($isInstanceOf(@, "List[Any]"))
595624 then @
596625 else throw(($getType(@) + " couldn't be cast to List[Any]"))
597626 }
598627 if ((inv == inv))
599628 then $Tuple2({
600629 let @ = inv[0]
601630 if ($isInstanceOf(@, "Int"))
602631 then @
603632 else throw(($getType(@) + " couldn't be cast to Int"))
604633 }, {
605634 let @ = inv[1]
606635 if ($isInstanceOf(@, "Int"))
607636 then @
608637 else throw(($getType(@) + " couldn't be cast to Int"))
609638 })
610639 else throw("Strict value is not equal to itself.")
611640 }
612641 else if ((pType == WX_POOL))
613642 then {
614643 let inv = split({
615644 let @ = invoke(poolAddr, "evaluateGetREADONLY", [shareId, userCanWithdraw], nil)
616645 if ($isInstanceOf(@, "String"))
617646 then @
618647 else throw(($getType(@) + " couldn't be cast to String"))
619648 }, "__")
620649 if ((inv == inv))
621650 then $Tuple2(parseIntValue(inv[1]), parseIntValue(inv[2]))
622651 else throw("Strict value is not equal to itself.")
623652 }
624653 else unknownPoolType()
625- let amountA = $t01764918113._1
626- let amountB = $t01764918113._2
654+ let amountA = $t01850718971._1
655+ let amountB = $t01850718971._2
627656 $Tuple2(amountA, amountB)
628657 }
629658
630659
631660 func claimFarmed (pType,pool) = if ((pType == SF_POOL))
632661 then {
633662 let balBefore = accountBalance(SWOPID)
634663 if ((balBefore == balBefore))
635664 then {
636665 let inv = invoke(getSFFarmingAddr(), "claim", [pool], nil)
637666 if ((inv == inv))
638667 then {
639668 let balAfter = accountBalance(SWOPID)
640669 $Tuple2((balAfter - balBefore), SWOPID)
641670 }
642671 else throw("Strict value is not equal to itself.")
643672 }
644673 else throw("Strict value is not equal to itself.")
645674 }
646675 else if ((pType == WX_POOL))
647676 then {
677+ let $t01933919418 = getWXPoolData(addressFromStringValue(pool))
678+ let aId = $t01933919418._1
679+ let bId = $t01933919418._2
680+ let aBal = $t01933919418._3
681+ let bBal = $t01933919418._4
682+ let lpId = $t01933919418._5
648683 let balBefore = accountBalance(WXID)
649684 if ((balBefore == balBefore))
650685 then {
651- let inv = invoke(getWXFarmingAddr(Address(fromBase58String(pool))), "claimWX", [pool], nil)
686+ let inv = invoke(getWXFarmingAddr(addressFromStringValue(pool)), "claimWx", [lpId], nil)
652687 if ((inv == inv))
653688 then {
654689 let balAfter = accountBalance(WXID)
655690 $Tuple2((balAfter - balBefore), WXID)
656691 }
657692 else throw("Strict value is not equal to itself.")
658693 }
659694 else throw("Strict value is not equal to itself.")
660695 }
661696 else unknownPoolType()
662697
663698
664699 func replenishByType (pType,pool,feeType,pmtA,aId,pmtB,bId,balA,balB,LPId) = {
665700 let lpBalanceBefore = accountBalance(fromBase58String(LPId))
666701 if ((lpBalanceBefore == lpBalanceBefore))
667702 then {
668703 let poolAddr = addressFromStringValue(pool)
669- let $t01907819494 = if (if ((pmtA > 0))
704+ let $t02001620432 = if (if ((pmtA > 0))
670705 then (pmtB > 0)
671706 else false)
672707 then {
673- let $t01914419260 = calcReplenishByTwoTokens(pType, poolAddr, pmtA, aId, pmtB, bId, balA, balB)
674- let pmtInA = $t01914419260._1
675- let pmtInB = $t01914419260._2
676- let change = $t01914419260._3
677- let changeId = $t01914419260._4
708+ let $t02008220198 = calcReplenishByTwoTokens(pType, poolAddr, pmtA, aId, pmtB, bId, balA, balB)
709+ let pmtInA = $t02008220198._1
710+ let pmtInB = $t02008220198._2
711+ let change = $t02008220198._3
712+ let changeId = $t02008220198._4
678713 let inv = replenishTwoTokensByType(poolAddr, pType, pmtInA, aId, pmtInB, bId)
679714 if ((inv == inv))
680715 then $Tuple2(change, changeId)
681716 else throw("Strict value is not equal to itself.")
682717 }
683718 else if ((pmtA > 0))
684719 then $Tuple2(pmtA, aId)
685720 else if ((pmtB > 0))
686721 then $Tuple2(pmtB, bId)
687722 else throw("pmts must be > 0")
688- let change = $t01907819494._1
689- let changeId = $t01907819494._2
723+ let change = $t02001620432._1
724+ let changeId = $t02001620432._2
690725 let inv = if ((change > 0))
691726 then replenishOneTokenByType(poolAddr, pType, change, changeId)
692727 else nil
693728 if ((inv == inv))
694729 then {
695730 let lpBalanceAfter = accountBalance(fromBase58String(LPId))
696731 let totalStaked = (lpBalanceAfter - lpBalanceBefore)
697732 let axlyFeeAmount = fraction(totalStaked, getAxlyFee(pool, feeType), FEE_SCALE6)
698733 let userShareForStake = (totalStaked - axlyFeeAmount)
699734 if ((0 >= userShareForStake))
700735 then throw("amount of staked sharetokens must be > 0")
701736 else {
702737 let invLP = stakeLP(pool, pType, LPId, userShareForStake)
703738 if ((invLP == invLP))
704739 then $Tuple2(userShareForStake, axlyFeeAmount)
705740 else throw("Strict value is not equal to itself.")
706741 }
707742 }
708743 else throw("Strict value is not equal to itself.")
709744 }
710745 else throw("Strict value is not equal to itself.")
711746 }
712747
713748
714749 func replenishEntries (pool,user,stakedAmount,axlyFeeAmount,posNum,shareId,type,withLoan) = {
715750 let totalAmount = getPoolTotalShare(pool)
716751 let totalAmountLoan = getPoolTotalShareWithLoan(pool)
717- let $t02035220590 = if (withLoan)
752+ let $t02128921527 = if (withLoan)
718753 then $Tuple2(getIntegerValue(this, (pool + kPoolInterestLoan)), (totalAmountLoan + stakedAmount))
719754 else $Tuple2(getIntegerValue(this, (pool + kPoolInterestNoLoan)), totalAmountLoan)
720- let curPoolInterest = $t02035220590._1
721- let totalStakedWithLoan = $t02035220590._2
755+ let curPoolInterest = $t02128921527._1
756+ let totalStakedWithLoan = $t02128921527._2
722757 [IntegerEntry((pool + kPoolTotal), (totalAmount + stakedAmount)), IntegerEntry((pool + kPoolTotalLoan), totalStakedWithLoan), IntegerEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserPosition), stakedAmount), IntegerEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserPositionInterest), curPoolInterest), StringEntry((((user + "_") + toString(posNum)) + kUserPositionPool), pool), IntegerEntry((user + kUserPositionNum), posNum), ScriptTransfer(moneyBox, axlyFeeAmount, fromBase58String(shareId))]
723758 }
724759
725760
726761 func exchangeKeeper (toToken,pmtAmount,pmtAsset,amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived,options) = {
727762 let tokenBalanceBefore = accountBalance(assetIdFromStr(toToken))
728763 if ((tokenBalanceBefore == tokenBalanceBefore))
729764 then {
730765 let inv = invoke(exContract, "swap", [amountsIn, addresses, assetsToReceive, estReceived, slippageTolerance, minReceived, options], [AttachedPayment(pmtAsset, pmtAmount)])
731766 if ((inv == inv))
732767 then (accountBalance(assetIdFromStr(toToken)) - tokenBalanceBefore)
733768 else throw("Strict value is not equal to itself.")
734769 }
735770 else throw("Strict value is not equal to itself.")
736771 }
737772
738773
739774 func exchangePuzzle (toToken,pmtAmount,pmtAsset,routesStr,minToReceive,options) = {
740775 let tokenBalanceBefore = accountBalance(assetIdFromStr(toToken))
741776 if ((tokenBalanceBefore == tokenBalanceBefore))
742777 then {
743778 let inv = invoke(exContract, "puzzleSwap", [routesStr, minToReceive, options], [AttachedPayment(pmtAsset, pmtAmount)])
744779 if ((inv == inv))
745780 then (accountBalance(assetIdFromStr(toToken)) - tokenBalanceBefore)
746781 else throw("Strict value is not equal to itself.")
747782 }
748783 else throw("Strict value is not equal to itself.")
749784 }
750785
751786
752787 func exchangeSwopFi (toToken,pmtAmount,pmtAsset,exchangers,exchangersType,args1,args2,routingAssetsKeys,minAmountToReceive,options) = {
753788 let tokenBalanceBefore = accountBalance(assetIdFromStr(toToken))
754789 if ((tokenBalanceBefore == tokenBalanceBefore))
755790 then {
756791 let inv = invoke(exContract, "swopfiSwap", [exchangers, exchangersType, args1, args2, routingAssetsKeys, minAmountToReceive, options], [AttachedPayment(pmtAsset, pmtAmount)])
757792 if ((inv == inv))
758793 then (accountBalance(assetIdFromStr(toToken)) - tokenBalanceBefore)
759794 else throw("Strict value is not equal to itself.")
760795 }
761796 else throw("Strict value is not equal to itself.")
762797 }
763798
764799
765800 func capitalize (pool,pType,tokenId,tokenAmount) = {
766801 let poolAddr = Address(fromBase58String(pool))
767- let $t02294123007 = getPoolData(poolAddr, pType)
768- let AId = $t02294123007._1
769- let BId = $t02294123007._2
770- let balA = $t02294123007._3
771- let balB = $t02294123007._4
772- let shareId = $t02294123007._5
802+ let $t02388123947 = getPoolData(poolAddr, pType)
803+ let AId = $t02388123947._1
804+ let BId = $t02388123947._2
805+ let balA = $t02388123947._3
806+ let balB = $t02388123947._4
807+ let shareId = $t02388123947._5
773808 if (if ((tokenId != AId))
774809 then (tokenId != BId)
775810 else false)
776811 then throw("Wrong asset")
777812 else {
778- let $t02309223172 = if ((tokenId == AId))
779- then $Tuple2(tokenAmount, 0)
780- else $Tuple2(0, tokenAmount)
781- let pmtA = $t02309223172._1
782- let pmtB = $t02309223172._2
783- let $t02317523279 = replenishByType(pType, pool, NO_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
784- let stakedAmount = $t02317523279._1
785- let nf = $t02317523279._2
786- let curPoolInterestLoan = valueOrElse(getInteger(this, (pool + kPoolInterestLoan)), 0)
787- let curPoolInterestNoLoan = valueOrElse(getInteger(this, (pool + kPoolInterestNoLoan)), 0)
788813 let totalShareAmount = getPoolTotalShare(pool)
789814 let totalShareAmountWithLoan = getPoolTotalShareWithLoan(pool)
790815 let loanPercent = fraction(totalShareAmountWithLoan, SCALE8, totalShareAmount)
816+ let tokensForFeeLoan = fraction(tokenAmount, loanPercent, SCALE8)
817+ let tokensForFeeNoLoan = (tokenAmount - tokensForFeeLoan)
818+ let axlyFeeLoan = fraction(tokensForFeeLoan, getAxlyFee(pool, CAP_FEE_LOAN), FEE_SCALE6)
819+ let axlyFeeNoLoan = fraction(tokensForFeeNoLoan, getAxlyFee(pool, CAP_FEE_NO_LOAN), FEE_SCALE6)
820+ let axlyFee = (axlyFeeLoan + axlyFeeNoLoan)
821+ let $t02458724687 = if ((tokenId == AId))
822+ then $Tuple2((tokenAmount - axlyFee), 0)
823+ else $Tuple2(0, (tokenAmount - axlyFee))
824+ let pmtA = $t02458724687._1
825+ let pmtB = $t02458724687._2
826+ let $t02469024794 = replenishByType(pType, pool, NO_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
827+ let stakedAmount = $t02469024794._1
828+ let nf = $t02469024794._2
829+ let curPoolInterestLoan = valueOrElse(getInteger(this, (pool + kPoolInterestLoan)), 0)
830+ let curPoolInterestNoLoan = valueOrElse(getInteger(this, (pool + kPoolInterestNoLoan)), 0)
791831 let stakedLoan = fraction(stakedAmount, loanPercent, SCALE8)
792832 let stakedNoLoan = (stakedAmount - stakedLoan)
793833 let newInterestLoan = if ((totalShareAmountWithLoan > 0))
794834 then (curPoolInterestLoan + fraction(stakedLoan, SCALE10, totalShareAmountWithLoan))
795835 else 0
796836 let newInterestNoLoan = if (((totalShareAmount - totalShareAmountWithLoan) > 0))
797837 then (curPoolInterestNoLoan + fraction(stakedNoLoan, SCALE10, (totalShareAmount - totalShareAmountWithLoan)))
798838 else 0
799- let axlyFeeLoan = fraction(stakedLoan, getAxlyFee(pool, CAP_FEE_LOAN), FEE_SCALE6)
800- let axlyFeeNoLoan = fraction(stakedNoLoan, getAxlyFee(pool, CAP_FEE_NO_LOAN), FEE_SCALE6)
801- let axlyFee = unstakeLP(pool, pType, shareId, (axlyFeeLoan + axlyFeeNoLoan))
802- if ((axlyFee == axlyFee))
803- then ([IntegerEntry((pool + kPoolInterestLoan), newInterestLoan), IntegerEntry((pool + kPoolInterestNoLoan), newInterestNoLoan), IntegerEntry((pool + kPoolTotal), ((totalShareAmount + stakedAmount) - axlyFee)), IntegerEntry((pool + kPoolTotalLoan), ((totalShareAmountWithLoan + stakedLoan) - axlyFeeLoan)), ScriptTransfer(moneyBox, (axlyFeeLoan + axlyFeeNoLoan), fromBase58String(shareId))] ++ getCursEntries(AId, BId, shareId, nil))
804- else throw("Strict value is not equal to itself.")
839+ ([IntegerEntry((pool + kPoolInterestLoan), newInterestLoan), IntegerEntry((pool + kPoolInterestNoLoan), newInterestNoLoan), IntegerEntry((pool + kPoolTotal), (totalShareAmount + stakedAmount)), IntegerEntry((pool + kPoolTotalLoan), (totalShareAmountWithLoan + stakedLoan)), ScriptTransfer(moneyBox, axlyFee, fromBase58String(tokenId))] ++ getCursEntries(AId, BId, shareId, nil))
805840 }
806841 }
807842
808843
809-func withdrawAmountCalc (pool,userCanWithdraw,debt,borrowAsset,stopLossFee) = {
844+func userCanWithdrawShareCalc (user,pool,posId,borrowed) = {
845+ let pAmount = valueOrErrorMessage(getInteger(this, (((((pool + "_") + user) + "_") + posId) + kUserPosition)), "Unknown position")
846+ let userInterest = getIntegerValue(this, (((((pool + "_") + user) + "_") + posId) + kUserPositionInterest))
847+ let poolInterest = if (borrowed)
848+ then getIntegerValue(this, (pool + kPoolInterestLoan))
849+ else getIntegerValue(this, (pool + kPoolInterestNoLoan))
850+ (pAmount + fraction(pAmount, (poolInterest - userInterest), SCALE10))
851+ }
852+
853+
854+func calcStopLossFee (pool,isBorrowed,stopLoss,lpWithdraw) = {
855+ let feeType = if (isBorrowed)
856+ then STOPLOSS_LOAN
857+ else STOPLOSS_FEE_NO_LOAN
858+ if (stopLoss)
859+ then fraction(lpWithdraw, getAxlyFee(pool, feeType), FEE_SCALE6)
860+ else 0
861+ }
862+
863+
864+func withdrawToUser (user,pool,posId,stopLoss) = {
865+ let pAmount = valueOrErrorMessage(getInteger(this, (((((pool + "_") + user) + "_") + posId) + kUserPosition)), "Unknown position")
866+ let isBorrowed = (valueOrElse(getInteger(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAmount)), 0) > 0)
867+ let userCanWithdraw = userCanWithdrawShareCalc(user, pool, posId, isBorrowed)
868+ let poolTotalShare = getPoolTotalShare(pool)
869+ let poolTotalShareLoan = getPoolTotalShareWithLoan(pool)
870+ let userAddr = Address(fromBase58String(user))
810871 let poolAddr = Address(fromBase58String(pool))
811872 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Unknown pool")
812- let $t02506925145 = getPoolData(poolAddr, pType)
813- let assetIdA = $t02506925145._1
814- let assetIdB = $t02506925145._2
815- let balA = $t02506925145._3
816- let balB = $t02506925145._4
817- let shareId = $t02506925145._5
818- let cBalABefore = accountBalance(assetIdFromStr(assetIdA))
873+ let $t02732527397 = getPoolData(poolAddr, pType)
874+ let idAStr = $t02732527397._1
875+ let idBStr = $t02732527397._2
876+ let balA = $t02732527397._3
877+ let balB = $t02732527397._4
878+ let shareId = $t02732527397._5
879+ let $t02740027467 = $Tuple2(assetIdFromStr(idAStr), assetIdFromStr(idBStr))
880+ let idA = $t02740027467._1
881+ let idB = $t02740027467._2
882+ let stopLossFee = calcStopLossFee(pool, isBorrowed, stopLoss, userCanWithdraw)
883+ let cBalABefore = accountBalance(idA)
819884 if ((cBalABefore == cBalABefore))
820885 then {
821- let cBalBBefore = accountBalance(assetIdFromStr(assetIdB))
886+ let cBalBBefore = accountBalance(idB)
822887 if ((cBalBBefore == cBalBBefore))
823888 then {
824889 let inv = if ((pType == SF_POOL))
825890 then {
826891 let inv = unstakeLP(pool, pType, shareId, stopLossFee)
827892 if ((inv == inv))
828893 then invoke(poolAddr, "callFunction", ["withdraw", [toString(userCanWithdraw)]], nil)
829894 else throw("Strict value is not equal to itself.")
830895 }
831896 else if ((pType == WX_POOL))
832897 then {
833898 let inv = unstakeLP(pool, pType, shareId, (userCanWithdraw + stopLossFee))
834899 if ((inv == inv))
835900 then invoke(poolAddr, "get", nil, [AttachedPayment(assetIdFromStr(shareId), userCanWithdraw)])
836901 else throw("Strict value is not equal to itself.")
837902 }
838903 else unknownPoolType()
839904 if ((inv == inv))
840905 then {
841- let cBalAAfter = accountBalance(assetIdFromStr(assetIdA))
842- let cBalBAfter = accountBalance(assetIdFromStr(assetIdB))
843- let $t02583825927 = $Tuple2((cBalAAfter - cBalABefore), (cBalBAfter - cBalBBefore))
844- let tokensAmountA = $t02583825927._1
845- let tokensAmountB = $t02583825927._2
846- let $t02593026784 = if ((debt > 0))
906+ let cBalAAfter = accountBalance(idA)
907+ if ((cBalAAfter == cBalAAfter))
847908 then {
848- let amountToGetEx = if (if ((borrowAsset == assetIdA))
849- then (debt > tokensAmountA)
850- else false)
851- then (debt - tokensAmountA)
852- else if (if ((borrowAsset == assetIdB))
853- then (debt > tokensAmountB)
854- else false)
855- then (debt - tokensAmountB)
856- else 0
857- let exInv = if ((amountToGetEx > 0))
858- then exchangeDirectly(pType, pool, assetIdA, assetIdB, (balA - tokensAmountA), (balB - tokensAmountB), amountToGetEx, borrowAsset)
859- else nil
860- if ((exInv == exInv))
909+ let cBalBAfter = accountBalance(idB)
910+ if ((cBalBAfter == cBalBAfter))
861911 then {
862- let cBalAAfterRepay = accountBalance(assetIdFromStr(assetIdA))
863- let cBalBAfterRepay = accountBalance(assetIdFromStr(assetIdB))
864- if ((borrowAsset == assetIdA))
865- then $Tuple2(((cBalAAfterRepay - cBalABefore) - debt), (cBalBAfterRepay - cBalBBefore))
866- else $Tuple2((cBalAAfterRepay - cBalABefore), ((cBalBAfterRepay - cBalBBefore) - debt))
912+ let $t02816228251 = $Tuple2((cBalAAfter - cBalABefore), (cBalBAfter - cBalBBefore))
913+ let tokensAmountA = $t02816228251._1
914+ let tokensAmountB = $t02816228251._2
915+ let $t02825429490 = if (isBorrowed)
916+ then {
917+ let borrowAsset = getStringValue(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAssetId))
918+ let debt = {
919+ let @ = invoke(getLendSrvAddr(), "getAssetDebt", [false, ((user + "_") + posId), borrowAsset], nil)
920+ if ($isInstanceOf(@, "Int"))
921+ then @
922+ else throw(($getType(@) + " couldn't be cast to Int"))
923+ }
924+ if ((debt == debt))
925+ then {
926+ let amountToGetEx = if (if ((borrowAsset == idAStr))
927+ then (debt > tokensAmountA)
928+ else false)
929+ then (debt - tokensAmountA)
930+ else if (if ((borrowAsset == idBStr))
931+ then (debt > tokensAmountB)
932+ else false)
933+ then (debt - tokensAmountB)
934+ else 0
935+ let exInv = if ((amountToGetEx > 0))
936+ then exchangeDirectly(pType, pool, idAStr, idBStr, (balA - tokensAmountA), (balB - tokensAmountB), amountToGetEx, borrowAsset)
937+ else nil
938+ if ((exInv == exInv))
939+ then {
940+ let cBalAAfterRepay = accountBalance(idA)
941+ if ((cBalAAfterRepay == cBalAAfterRepay))
942+ then {
943+ let cBalBAfterRepay = accountBalance(idB)
944+ if ((cBalBAfterRepay == cBalBAfterRepay))
945+ then {
946+ let closeDbtInv = if ((debt > 0))
947+ then invoke(getLendSrvAddr(), "repayFor", [((user + "_") + posId)], [AttachedPayment(assetIdFromStr(borrowAsset), debt)])
948+ else 0
949+ if ((closeDbtInv == closeDbtInv))
950+ then if ((borrowAsset == idAStr))
951+ then $Tuple2(((cBalAAfterRepay - cBalABefore) - debt), (cBalBAfterRepay - cBalBBefore))
952+ else $Tuple2((cBalAAfterRepay - cBalABefore), ((cBalBAfterRepay - cBalBBefore) - debt))
953+ else throw("Strict value is not equal to itself.")
954+ }
955+ else throw("Strict value is not equal to itself.")
956+ }
957+ else throw("Strict value is not equal to itself.")
958+ }
959+ else throw("Strict value is not equal to itself.")
960+ }
961+ else throw("Strict value is not equal to itself.")
962+ }
963+ else $Tuple2(tokensAmountA, tokensAmountB)
964+ let toUserA = $t02825429490._1
965+ let toUserB = $t02825429490._2
966+ let poolTotalLoanEntries = if (isBorrowed)
967+ then [IntegerEntry((pool + kPoolTotalLoan), ((poolTotalShareLoan - userCanWithdraw) - stopLossFee))]
968+ else nil
969+ let entries = (([DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserPosition)), DeleteEntry((((user + "_") + posId) + kUserPositionPool)), DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserBorrowAmount)), DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserBorrowAssetId)), DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserPositionInterest)), IntegerEntry((pool + kPoolTotal), ((poolTotalShare - userCanWithdraw) - stopLossFee)), ScriptTransfer(userAddr, toUserA, idA), ScriptTransfer(userAddr, toUserB, idB), ScriptTransfer(moneyBox, stopLossFee, fromBase58String(shareId))] ++ poolTotalLoanEntries) ++ getCursEntries(idAStr, idBStr, shareId, nil))
970+ $Tuple2(entries, [toUserA, toUserB])
867971 }
868972 else throw("Strict value is not equal to itself.")
869973 }
870- else $Tuple2(tokensAmountA, tokensAmountB)
871- let toUserA = $t02593026784._1
872- let toUserB = $t02593026784._2
873- $Tuple5(toUserA, assetIdA, toUserB, assetIdB, shareId)
974+ else throw("Strict value is not equal to itself.")
874975 }
875976 else throw("Strict value is not equal to itself.")
876- }
877- else throw("Strict value is not equal to itself.")
878- }
879- else throw("Strict value is not equal to itself.")
880- }
881-
882-
883-func userCanWithdrawShareCalc (user,pool,posId,borrowed) = {
884- let pAmount = valueOrErrorMessage(getInteger(this, (((((pool + "_") + user) + "_") + posId) + kUserPosition)), "Unknown position")
885- let userInterest = getIntegerValue(this, (((((pool + "_") + user) + "_") + posId) + kUserPositionInterest))
886- let poolInterest = if (borrowed)
887- then getIntegerValue(this, (pool + kPoolInterestLoan))
888- else getIntegerValue(this, (pool + kPoolInterestNoLoan))
889- (pAmount + fraction(pAmount, (poolInterest - userInterest), SCALE10))
890- }
891-
892-
893-func withdrawToUser (user,pool,posId,stopLoss) = {
894- let pAmount = valueOrErrorMessage(getInteger(this, (((((pool + "_") + user) + "_") + posId) + kUserPosition)), "Unknown position")
895- let borrowAmount = valueOrElse(getInteger(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAmount)), 0)
896- let userCanWithdraw = userCanWithdrawShareCalc(user, pool, posId, (borrowAmount > 0))
897- let poolTotalShare = getPoolTotalShare(pool)
898- let userAddr = Address(fromBase58String(user))
899- let borrowAsset = valueOrElse(getString(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAssetId)), "")
900- let $t02798228216 = if ((borrowAmount > 0))
901- then $Tuple2({
902- let @ = invoke(getLendSrvAddr(), "getAssetDebt", [false, ((user + "_") + posId), borrowAsset], nil)
903- if ($isInstanceOf(@, "Int"))
904- then @
905- else throw(($getType(@) + " couldn't be cast to Int"))
906- }, STOPLOSS_LOAN)
907- else $Tuple2(0, STOPLOSS_FEE_NO_LOAN)
908- let debt = $t02798228216._1
909- let feeType = $t02798228216._2
910- let stopLossFee = if (stopLoss)
911- then fraction(userCanWithdraw, getAxlyFee(pool, feeType), FEE_SCALE6)
912- else 0
913- let $t02833328489 = withdrawAmountCalc(pool, (userCanWithdraw - stopLossFee), debt, borrowAsset, stopLossFee)
914- if (($t02833328489 == $t02833328489))
915- then {
916- let shareId = $t02833328489._5
917- let assetIdB = $t02833328489._4
918- let toUserAmountB = $t02833328489._3
919- let assetIdA = $t02833328489._2
920- let toUserAmountA = $t02833328489._1
921- let closeDbtInv = if ((debt > 0))
922- then invoke(getLendSrvAddr(), "repayFor", [((user + "_") + posId)], [AttachedPayment(assetIdFromStr(borrowAsset), debt)])
923- else 0
924- if ((closeDbtInv == closeDbtInv))
925- then {
926- let entries = ([DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserPosition)), DeleteEntry((((user + "_") + posId) + kUserPositionPool)), DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserBorrowAmount)), DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserBorrowAssetId)), DeleteEntry((((((pool + "_") + user) + "_") + posId) + kUserPositionInterest)), IntegerEntry((pool + kPoolTotal), ((poolTotalShare - userCanWithdraw) - stopLossFee)), ScriptTransfer(userAddr, toUserAmountA, assetIdFromStr(assetIdA)), ScriptTransfer(userAddr, toUserAmountB, assetIdFromStr(assetIdB)), ScriptTransfer(moneyBox, stopLossFee, fromBase58String(shareId))] ++ getCursEntries(assetIdA, assetIdB, shareId, nil))
927- $Tuple2(entries, [toUserAmountA, toUserAmountB])
928977 }
929978 else throw("Strict value is not equal to itself.")
930979 }
931980 else throw("Strict value is not equal to itself.")
932981 }
933982
934983
935984 func parseRequest (requestId) = {
936985 let request = split(valueOrErrorMessage(getString(this, (requestId + kRequestId)), ("No request with id " + requestId)), ",")
937986 let user = request[0]
938987 let pool = request[1]
939988 let pmtA = parseIntValue(request[2])
940989 let AId = request[3]
941990 let pmtB = parseIntValue(request[4])
942991 let BId = request[5]
943992 let balA = parseIntValue(request[6])
944993 let balB = parseIntValue(request[7])
945994 let shareId = request[8]
946995 let bwAsset = request[9]
947996 let bwAmount = parseIntValue(request[10])
948997 $Tuple11(user, pool, pmtA, AId, pmtB, BId, balA, balB, shareId, bwAsset, bwAmount)
949998 }
950999
9511000
9521001 func calcBorrowAmount (pmtA,pmtB,aId,bId,leverage,borrowId) = if (if ((borrowId != aId))
9531002 then (borrowId != bId)
9541003 else false)
9551004 then throw("Wrong borrow asset")
9561005 else {
9571006 let dPriceA = getIntegerValue(priceOracleAddr, (aId + kPriceInOracle))
9581007 let dPriceB = getIntegerValue(priceOracleAddr, (bId + kPriceInOracle))
9591008 let decPrA = pow(10, 0, getAssetDecimals(aId), 0, 0, DOWN)
9601009 let decPrB = pow(10, 0, getAssetDecimals(bId), 0, 0, DOWN)
9611010 let paydInDollar = (fraction(dPriceA, pmtA, decPrA) + fraction(dPriceB, pmtB, decPrB))
962- let $t03055230649 = if ((borrowId == aId))
1011+ let $t03147231569 = if ((borrowId == aId))
9631012 then $Tuple2(dPriceA, decPrA)
9641013 else $Tuple2(dPriceB, decPrB)
965- let borrowPrice = $t03055230649._1
966- let borrowDecPr = $t03055230649._2
1014+ let borrowPrice = $t03147231569._1
1015+ let borrowDecPr = $t03147231569._2
9671016 fraction(fraction(paydInDollar, (leverage - 100), 100), borrowDecPr, borrowPrice)
9681017 }
9691018
9701019
9711020 func parseReplenishPmts (pmts,AId,BId) = if ((size(pmts) == 2))
9721021 then if ((assetIdToStr(pmts[0].assetId) != AId))
9731022 then throw("Wrong payment asset A")
9741023 else if ((assetIdToStr(pmts[1].assetId) != BId))
9751024 then throw("Wrong payment asset B")
9761025 else $Tuple2(pmts[0].amount, pmts[1].amount)
9771026 else if ((size(pmts) == 1))
9781027 then if ((assetIdToStr(pmts[0].assetId) == AId))
9791028 then $Tuple2(pmts[0].amount, 0)
9801029 else if ((assetIdToStr(pmts[0].assetId) == BId))
9811030 then $Tuple2(0, pmts[0].amount)
9821031 else throw("Wrong payment")
9831032 else throw("One or two payments expected")
9841033
9851034
9861035 func calcPriceImpact (balA,balB,newBalA,newBalB) = {
9871036 let pri = ((SCALE8 - fraction(fraction(balB, SCALE8, balA), SCALE8, fraction(newBalB, SCALE8, newBalA))) * 100)
9881037 if ((0 > pri))
9891038 then (pri * -1)
9901039 else pri
9911040 }
9921041
9931042
994-func claimAndCheckAmntEx (pool,pType,claim,amountToExchange,change) = {
995- let $t03166331950 = if (claim)
1043+func claimAndCheckAmnt (pool,pType,claim,amount,change) = {
1044+ let $t03256932828 = if (claim)
9961045 then claimFarmed(pType, pool)
9971046 else {
9981047 let claimedAsset = if ((pType == SF_POOL))
9991048 then SWOPID
10001049 else if ((pType == WX_POOL))
10011050 then WXID
10021051 else unknownPoolType()
1003- $Tuple2(amountToExchange, claimedAsset)
1052+ $Tuple2(amount, claimedAsset)
10041053 }
1005- let claimAmount = $t03166331950._1
1006- let claimAsset = $t03166331950._2
1054+ let claimAmount = $t03256932828._1
1055+ let claimAsset = $t03256932828._2
10071056 let bal = accountBalance(claimAsset)
1008- if (if ((amountToExchange > (claimAmount + change)))
1057+ if (if ((amount > (claimAmount + change)))
10091058 then true
1010- else (amountToExchange > bal))
1059+ else (amount > bal))
10111060 then throw("To big amount to exchange")
10121061 else $Tuple2(claimAmount, claimAsset)
10131062 }
1063+
1064+
1065+@Callable(i)
1066+func getPoolInfoREADONLY (pool) = {
1067+ let poolAddr = addressFromStringValue(pool)
1068+ let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
1069+ let $t03322533315 = getPoolData(Address(fromBase58String(pool)), pType)
1070+ let AId = $t03322533315._1
1071+ let BId = $t03322533315._2
1072+ let balA = $t03322533315._3
1073+ let balB = $t03322533315._4
1074+ let shareId = $t03322533315._5
1075+ let shareSupply = getShareSupply(poolAddr, pType, shareId)
1076+ $Tuple2(nil, $Tuple6(AId, BId, shareId, balA, balB, shareSupply))
1077+ }
1078+
10141079
10151080
10161081 @Callable(i)
10171082 func getShareAssetPriceREADONLY (shareId) = {
10181083 let sharePrices = getSharePrice(shareId)
10191084 $Tuple2(nil, sharePrices)
10201085 }
10211086
10221087
10231088
10241089 @Callable(i)
10251090 func getUserPositionShareAmountREADONLY (user,posNum) = {
10261091 let pool = valueOrErrorMessage(getString(this, (((user + "_") + posNum) + kUserPositionPool)), "Unknown position")
10271092 let borrowAmount = getIntegerValue(this, (((((pool + "_") + user) + "_") + posNum) + kUserBorrowAmount))
10281093 let userCanWithdraw = userCanWithdrawShareCalc(user, pool, posNum, (borrowAmount > 0))
10291094 $Tuple2(nil, userCanWithdraw)
10301095 }
10311096
10321097
10331098
10341099 @Callable(i)
10351100 func getUserPositionREADONLY (user,pools,posNum) = {
10361101 func userPos (a,pool) = {
1037- let $t03293833008 = a
1038- let wAmountsA = $t03293833008._1
1039- let wAmountsB = $t03293833008._2
1040- let debts = $t03293833008._3
1041- let eqWAmountsA = $t03293833008._4
1042- let eqWAmountsB = $t03293833008._5
1043- let index = $t03293833008._6
1102+ let $t03418834258 = a
1103+ let wAmountsA = $t03418834258._1
1104+ let wAmountsB = $t03418834258._2
1105+ let debts = $t03418834258._3
1106+ let eqWAmountsA = $t03418834258._4
1107+ let eqWAmountsB = $t03418834258._5
1108+ let index = $t03418834258._6
10441109 if (!(isDefined(getInteger(this, (((((pool + "_") + user) + "_") + posNum[index]) + kUserPosition)))))
10451110 then $Tuple6((wAmountsA :+ 0), (wAmountsB :+ 0), (debts :+ 0), (eqWAmountsA :+ 0), (eqWAmountsB :+ 0), (index + 1))
10461111 else {
10471112 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
1048- let $t03328733377 = getPoolData(Address(fromBase58String(pool)), pType)
1049- let AId = $t03328733377._1
1050- let BId = $t03328733377._2
1051- let balA = $t03328733377._3
1052- let balB = $t03328733377._4
1053- let shareId = $t03328733377._5
1113+ let $t03453734627 = getPoolData(Address(fromBase58String(pool)), pType)
1114+ let AId = $t03453734627._1
1115+ let BId = $t03453734627._2
1116+ let balA = $t03453734627._3
1117+ let balB = $t03453734627._4
1118+ let shareId = $t03453734627._5
10541119 let borrowAmount = valueOrElse(getInteger(this, (((((pool + "_") + user) + "_") + posNum[index]) + kUserBorrowAmount)), 0)
10551120 let userCanWithdraw = userCanWithdrawShareCalc(user, pool, posNum[index], (borrowAmount > 0))
1056- let $t03359333713 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userCanWithdraw)
1057- let wAmountA = $t03359333713._1
1058- let wAmountB = $t03359333713._2
1121+ let $t03484334963 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userCanWithdraw)
1122+ let wAmountA = $t03484334963._1
1123+ let wAmountB = $t03484334963._2
10591124 if ((borrowAmount > 0))
10601125 then {
10611126 let borrowAsset = getStringValue(this, (((((pool + "_") + user) + "_") + posNum[index]) + kUserBorrowAssetId))
10621127 let debt = {
10631128 let @ = invoke(getLendSrvAddr(), "getAssetDebt", [false, ((user + "_") + posNum[index]), borrowAsset], nil)
10641129 if ($isInstanceOf(@, "Int"))
10651130 then @
10661131 else throw(($getType(@) + " couldn't be cast to Int"))
10671132 }
10681133 if ((debt == debt))
10691134 then {
1070- let $t03399734281 = if ((pType == SF_POOL))
1071- then calcAmountToPaySF(pool, AId, BId, balA, balB, debt, borrowAsset)
1072- else if ((pType == WX_POOL))
1073- then calcAmountToPayWX(pool, AId, BId, balA, balB, debt, borrowAsset)
1074- else unknownPoolType()
1075- let assetToPay = $t03399734281._1
1076- let amountToPay = $t03399734281._2
1077- let $t03428834434 = if ((assetToPay == BId))
1078- then $Tuple2((wAmountA - debt), (wAmountB - amountToPay))
1079- else $Tuple2((wAmountA - amountToPay), (wAmountB - debt))
1080- let eqWAmountA = $t03428834434._1
1081- let eqWAmountB = $t03428834434._2
1135+ let amountToGetEx = if (if ((borrowAsset == AId))
1136+ then (debt > wAmountA)
1137+ else false)
1138+ then (debt - wAmountA)
1139+ else if (if ((borrowAsset == BId))
1140+ then (debt > wAmountB)
1141+ else false)
1142+ then (debt - wAmountB)
1143+ else 0
1144+ let amountToPay = if ((amountToGetEx > 0))
1145+ then if ((pType == SF_POOL))
1146+ then {
1147+ let ex = calcAmountToPaySF(pool, AId, BId, balA, balB, amountToGetEx, borrowAsset)
1148+ ex._2
1149+ }
1150+ else if ((pType == WX_POOL))
1151+ then {
1152+ let ex = calcAmountToPayWX(pool, AId, BId, balA, balB, amountToGetEx, borrowAsset)
1153+ ex._2
1154+ }
1155+ else unknownPoolType()
1156+ else 0
1157+ let $t03587536094 = if ((borrowAsset == AId))
1158+ then $Tuple2(((wAmountA + amountToGetEx) - debt), (wAmountB - amountToPay))
1159+ else $Tuple2((wAmountA - amountToPay), ((wAmountB + amountToGetEx) - debt))
1160+ let eqWAmountA = $t03587536094._1
1161+ let eqWAmountB = $t03587536094._2
10821162 $Tuple6((wAmountsA :+ wAmountA), (wAmountsB :+ wAmountB), (debts :+ debt), (eqWAmountsA :+ eqWAmountA), (eqWAmountsB :+ eqWAmountB), (index + 1))
10831163 }
10841164 else throw("Strict value is not equal to itself.")
10851165 }
10861166 else $Tuple6((wAmountsA :+ wAmountA), (wAmountsB :+ wAmountB), debts, (wAmountsA :+ wAmountA), (wAmountsB :+ wAmountB), (index + 1))
10871167 }
10881168 }
10891169
1090- let $t03468934800 = {
1170+ let $t03634936460 = {
10911171 let $l = pools
10921172 let $s = size($l)
10931173 let $acc0 = $Tuple6(nil, nil, nil, nil, nil, 0)
10941174 func $f0_1 ($a,$i) = if (($i >= $s))
10951175 then $a
10961176 else userPos($a, $l[$i])
10971177
10981178 func $f0_2 ($a,$i) = if (($i >= $s))
10991179 then $a
11001180 else throw("List size exceeds 20")
11011181
11021182 $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($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), 13), 14), 15), 16), 17), 18), 19), 20)
11031183 }
1104- let wAmountsA = $t03468934800._1
1105- let wAmountsB = $t03468934800._2
1106- let debts = $t03468934800._3
1107- let eqWAmountsA = $t03468934800._4
1108- let eqWAmountsB = $t03468934800._5
1184+ let wAmountsA = $t03634936460._1
1185+ let wAmountsB = $t03634936460._2
1186+ let debts = $t03634936460._3
1187+ let eqWAmountsA = $t03634936460._4
1188+ let eqWAmountsB = $t03634936460._5
11091189 $Tuple2(nil, $Tuple5(wAmountsA, wAmountsB, debts, eqWAmountsA, eqWAmountsB))
11101190 }
11111191
11121192
11131193
11141194 @Callable(i)
11151195 func replenish (pool,leverage,borrowId) = valueOrElse(isActiveForUsers(), {
11161196 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
11171197 if (!(isPoolActive(pool, pType)))
11181198 then throw("Pool not active at this moment")
11191199 else if (if ((100 > leverage))
11201200 then true
11211201 else (leverage > 300))
11221202 then throw("Leverage can't be <100 and >300")
11231203 else if (if (!(getBooleanValue(this, (pool + kPoolCanBorrow))))
11241204 then (leverage > 100)
11251205 else false)
11261206 then throw("You can't borrow in this pool")
11271207 else {
1128- let $t03539835488 = getPoolData(Address(fromBase58String(pool)), pType)
1129- let AId = $t03539835488._1
1130- let BId = $t03539835488._2
1131- let balA = $t03539835488._3
1132- let balB = $t03539835488._4
1133- let shareId = $t03539835488._5
1208+ let $t03705837148 = getPoolData(Address(fromBase58String(pool)), pType)
1209+ let AId = $t03705837148._1
1210+ let BId = $t03705837148._2
1211+ let balA = $t03705837148._3
1212+ let balB = $t03705837148._4
1213+ let shareId = $t03705837148._5
11341214 if (if ((borrowId != AId))
11351215 then (borrowId != BId)
11361216 else false)
11371217 then throw("Wrong borrow asset")
11381218 else {
1139- let $t03556935628 = parseReplenishPmts(i.payments, AId, BId)
1140- let pmtA = $t03556935628._1
1141- let pmtB = $t03556935628._2
1219+ let $t03722937288 = parseReplenishPmts(i.payments, AId, BId)
1220+ let pmtA = $t03722937288._1
1221+ let pmtB = $t03722937288._2
11421222 let user = toString(i.caller)
11431223 let newPosNum = getNewUserPositionNumber(user)
11441224 if ((leverage > 100))
11451225 then {
11461226 let borrowAmount = calcBorrowAmount(pmtA, pmtB, AId, BId, leverage, borrowId)
11471227 let request = makeString([user, pool, toString(pmtA), AId, toString(pmtB), BId, toString(balA), toString(balB), shareId, borrowId, toString(borrowAmount)], ",")
11481228 let newRequestId = {
11491229 let @ = invoke(this, "createNewRequest", [request], nil)
11501230 if ($isInstanceOf(@, "Int"))
11511231 then @
11521232 else throw(($getType(@) + " couldn't be cast to Int"))
11531233 }
11541234 if ((newRequestId == newRequestId))
11551235 then {
11561236 let args = [((user + "_") + toString(newPosNum)), shareId, borrowId, borrowAmount, toString(this), "replenishFromLand", toString(valueOrErrorMessage(newRequestId, "Can't create new request"))]
11571237 let inv = reentrantInvoke(getLendSrvAddr(), "flashPosition", args, nil)
11581238 if ((inv == inv))
11591239 then {
11601240 let userStaked = getIntegerValue(this, (((((pool + "_") + user) + "_") + toString(newPosNum)) + kUserPosition))
1161- let $t03661736711 = getPoolBalances(Address(fromBase58String(pool)), pType, AId, BId)
1162- if (($t03661736711 == $t03661736711))
1241+ let $t03827738371 = getPoolBalances(Address(fromBase58String(pool)), pType, AId, BId)
1242+ if (($t03827738371 == $t03827738371))
11631243 then {
1164- let newBalB = $t03661736711._2
1165- let newBalA = $t03661736711._1
1244+ let newBalB = $t03827738371._2
1245+ let newBalA = $t03827738371._1
11661246 let prImpact = calcPriceImpact(balA, balB, newBalA, newBalB)
1167- let $t03678136896 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userStaked)
1168- let wAmountA = $t03678136896._1
1169- let wAmountB = $t03678136896._2
1247+ let $t03844138556 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userStaked)
1248+ let wAmountA = $t03844138556._1
1249+ let wAmountB = $t03844138556._2
11701250 $Tuple2(nil, [prImpact, wAmountA, wAmountB])
11711251 }
11721252 else throw("Strict value is not equal to itself.")
11731253 }
11741254 else throw("Strict value is not equal to itself.")
11751255 }
11761256 else throw("Strict value is not equal to itself.")
11771257 }
11781258 else {
1179- let $t03694937064 = replenishByType(pType, pool, NO_LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
1180- if (($t03694937064 == $t03694937064))
1259+ let $t03860938724 = replenishByType(pType, pool, NO_LOAN_FEE, pmtA, AId, pmtB, BId, balA, balB, shareId)
1260+ if (($t03860938724 == $t03860938724))
11811261 then {
1182- let axlyFee = $t03694937064._2
1183- let userStaked = $t03694937064._1
1184- let $t03707037164 = getPoolBalances(Address(fromBase58String(pool)), pType, AId, BId)
1185- if (($t03707037164 == $t03707037164))
1262+ let axlyFee = $t03860938724._2
1263+ let userStaked = $t03860938724._1
1264+ let $t03873038824 = getPoolBalances(Address(fromBase58String(pool)), pType, AId, BId)
1265+ if (($t03873038824 == $t03873038824))
11861266 then {
1187- let newBalB = $t03707037164._2
1188- let newBalA = $t03707037164._1
1267+ let newBalB = $t03873038824._2
1268+ let newBalA = $t03873038824._1
11891269 let prImpact = calcPriceImpact(balA, balB, newBalA, newBalB)
1190- let $t03723437349 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userStaked)
1191- let wAmountA = $t03723437349._1
1192- let wAmountB = $t03723437349._2
1270+ let $t03889439009 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userStaked)
1271+ let wAmountA = $t03889439009._1
1272+ let wAmountB = $t03889439009._2
11931273 $Tuple2((replenishEntries(pool, user, userStaked, axlyFee, newPosNum, shareId, pType, false) ++ getCursEntries(AId, BId, shareId, [toString(wAmountA), toString(wAmountB)])), [prImpact, wAmountA, wAmountB])
11941274 }
11951275 else throw("Strict value is not equal to itself.")
11961276 }
11971277 else throw("Strict value is not equal to itself.")
11981278 }
11991279 }
12001280 }
12011281 })
12021282
12031283
12041284
12051285 @Callable(i)
12061286 func withdraw (pool,posId) = valueOrElse(isActiveForUsers(), {
12071287 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
12081288 if (!(isPoolActive(pool, pType)))
12091289 then throw("Pool not active at this moment")
12101290 else withdrawToUser(toString(i.caller), pool, toString(posId), false)
12111291 })
12121292
12131293
12141294
12151295 @Callable(i)
12161296 func createUpdateStopLoss (posId,poolId,assetId,price) = valueOrElse(isActiveForUsers(), {
12171297 let tokenOraclePrice = getIntegerValue(priceOracleAddr, (assetId + kPriceInOracle))
12181298 let pType = valueOrErrorMessage(getString(this, (kPool + poolId)), "Pool is not inited")
12191299 if (!(isPoolActive(poolId, pType)))
12201300 then throw("Pool not active at this moment")
12211301 else if (!(isDefined(getInteger(this, (((((poolId + "_") + toString(i.caller)) + "_") + toString(posId)) + kUserPosition)))))
12221302 then throw("There are no user position")
12231303 else if ((0 >= price))
12241304 then throw("Price must be greater than 0")
12251305 else if ((price > tokenOraclePrice))
12261306 then throw("Price must be less than current token price")
12271307 else [IntegerEntry((((((((toString(i.caller) + "_") + toString(posId)) + "_") + poolId) + "_") + assetId) + kUserStopLoss), price)]
12281308 })
12291309
12301310
12311311
12321312 @Callable(i)
12331313 func deleteStopLoss (posId,poolId,assetId) = valueOrElse(isActiveForUsers(), {
12341314 let pType = valueOrErrorMessage(getString(this, (kPool + poolId)), "Pool is not inited")
12351315 if (!(isPoolActive(poolId, pType)))
12361316 then throw("Pool not active at this moment")
12371317 else if (!(isDefined(getInteger(this, (((((((toString(i.caller) + "_") + toString(posId)) + "_") + poolId) + "_") + assetId) + kUserStopLoss)))))
12381318 then throw("No entry")
12391319 else [DeleteEntry((((((((toString(i.caller) + "_") + toString(posId)) + "_") + poolId) + "_") + assetId) + kUserStopLoss))]
12401320 })
12411321
12421322
12431323
12441324 @Callable(i)
1245-func init (moneyBoxAddr,sfFarmingAddr,lendAddr,priceOracleAddr,keeperExContract,wxSwapContract,swopAssetId,wxAssetId,adminPubKey) = valueOrElse(isSelfCall(i), if (isDefined(getString(kAdminCallPK)))
1325+func init (moneyBoxAddr,sfFarmingAddr,lendAddr,priceOracleAddr,keeperExContract,wxSwapContract,swopAssetId,wxAssetId,operatorPubKey,group1Admin1PubKey,group1Admin2PubKey,group2Admin1PubKey,group2Admin2PubKey) = valueOrElse(isSelfCall(i), if (isDefined(getString(kOperatorCallPK)))
12461326 then throw("Already inited")
12471327 else if (!(isDefined(addressFromString(moneyBoxAddr))))
12481328 then throw("moneyBoxAddr is not correct address")
12491329 else if (!(isDefined(addressFromString(sfFarmingAddr))))
12501330 then throw("sfFarmingAddr is not correct address")
12511331 else if (!(isDefined(addressFromString(lendAddr))))
12521332 then throw("lendAddr is not correct address")
12531333 else if (!(isDefined(addressFromString(priceOracleAddr))))
12541334 then throw("priceOracleAddr is not correct address")
12551335 else if (!(isDefined(addressFromString(keeperExContract))))
12561336 then throw("keeperExContract is not correct address")
12571337 else if (!(isDefined(assetInfo(fromBase58String(swopAssetId)))))
12581338 then throw("swopAssetId is not correct asset id")
12591339 else if (!(isDefined(assetInfo(fromBase58String(wxAssetId)))))
12601340 then throw("swopAssetId is not correct asset id")
1261- else if ((size(fromBase58String(adminPubKey)) != 32))
1262- then throw("adminPubKey is not correct")
1263- else [StringEntry(kMoneyBox, moneyBoxAddr), StringEntry(kSFFarmingAddr, sfFarmingAddr), StringEntry(kLendService, lendAddr), StringEntry(kPriceOracle, priceOracleAddr), StringEntry(kExContract, keeperExContract), StringEntry(kWxSwapContract, wxSwapContract), StringEntry(kSwopId, swopAssetId), StringEntry(kWxId, wxAssetId), StringEntry(kAdminCallPK, adminPubKey)])
1341+ else if ((size(fromBase58String(operatorPubKey)) != 32))
1342+ then throw("operatorPubKey is not correct")
1343+ else if ((size(fromBase58String(group1Admin1PubKey)) != 32))
1344+ then throw("group1Admin1PubKey is not correct")
1345+ else if ((size(fromBase58String(group1Admin2PubKey)) != 32))
1346+ then throw("group1Admin2PubKey is not correct")
1347+ else if ((size(fromBase58String(group2Admin1PubKey)) != 32))
1348+ then throw("group2Admin1PubKey is not correct")
1349+ else if ((size(fromBase58String(group2Admin2PubKey)) != 32))
1350+ then throw("group2Admin2PubKey is not correct")
1351+ else [StringEntry(kMoneyBox, moneyBoxAddr), StringEntry(kSFFarmingAddr, sfFarmingAddr), StringEntry(kLendService, lendAddr), StringEntry(kPriceOracle, priceOracleAddr), StringEntry(kExContract, keeperExContract), StringEntry(kWxSwapContract, wxSwapContract), StringEntry(kSwopId, swopAssetId), StringEntry(kWxId, wxAssetId), StringEntry(kOperatorCallPK, operatorPubKey), StringEntry(kGroup1Admin1PK, group1Admin1PubKey), StringEntry(kGroup1Admin2PK, group1Admin2PubKey), StringEntry(kGroup2Admin1PK, group2Admin1PubKey), StringEntry(kGroup2Admin2PK, group2Admin2PubKey)])
12641352
12651353
12661354
12671355 @Callable(i)
12681356 func createNewRequest (params) = valueOrElse(isSelfCall(i), {
12691357 let newRequestId = (valueOrElse(getInteger(this, kRequestIter), 0) + 1)
12701358 $Tuple2([StringEntry((toString(newRequestId) + kRequestId), params), IntegerEntry(kRequestIter, newRequestId)], newRequestId)
12711359 })
12721360
12731361
12741362
12751363 @Callable(i)
12761364 func replenishFromLand (requestId) = valueOrElse(isActive(), valueOrElse(isLandCall(i), {
1277- let $t04139841502 = parseRequest(requestId)
1278- let user = $t04139841502._1
1279- let pool = $t04139841502._2
1280- let pmtA = $t04139841502._3
1281- let AId = $t04139841502._4
1282- let pmtB = $t04139841502._5
1283- let BId = $t04139841502._6
1284- let balA = $t04139841502._7
1285- let balB = $t04139841502._8
1286- let shareId = $t04139841502._9
1287- let bwAsset = $t04139841502._10
1288- let bwAmount = $t04139841502._11
1365+ let $t04384843952 = parseRequest(requestId)
1366+ let user = $t04384843952._1
1367+ let pool = $t04384843952._2
1368+ let pmtA = $t04384843952._3
1369+ let AId = $t04384843952._4
1370+ let pmtB = $t04384843952._5
1371+ let BId = $t04384843952._6
1372+ let balA = $t04384843952._7
1373+ let balB = $t04384843952._8
1374+ let shareId = $t04384843952._9
1375+ let bwAsset = $t04384843952._10
1376+ let bwAmount = $t04384843952._11
12891377 if ((size(i.payments) != 1))
12901378 then throw("Wrong payment size")
12911379 else if (if ((assetIdToStr(i.payments[0].assetId) != bwAsset))
12921380 then true
12931381 else (i.payments[0].amount != bwAmount))
12941382 then throw("Wrong payment")
12951383 else {
1296- let $t04169241792 = if ((AId == bwAsset))
1384+ let $t04414244242 = if ((AId == bwAsset))
12971385 then $Tuple2((pmtA + bwAmount), pmtB)
12981386 else $Tuple2(pmtA, (pmtB + bwAmount))
1299- let pmtAllA = $t04169241792._1
1300- let pmtAllB = $t04169241792._2
1387+ let pmtAllA = $t04414244242._1
1388+ let pmtAllB = $t04414244242._2
13011389 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Unknown pool")
1302- let $t04187441989 = replenishByType(pType, pool, LOAN_FEE, pmtAllA, AId, pmtAllB, BId, balA, balB, shareId)
1303- let userStaked = $t04187441989._1
1304- let axlyFee = $t04187441989._2
1390+ let $t04432444439 = replenishByType(pType, pool, LOAN_FEE, pmtAllA, AId, pmtAllB, BId, balA, balB, shareId)
1391+ let userStaked = $t04432444439._1
1392+ let axlyFee = $t04432444439._2
13051393 let posNum = getNewUserPositionNumber(user)
13061394 let borrowEntries = [IntegerEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserBorrowAmount), bwAmount), StringEntry((((((pool + "_") + user) + "_") + toString(posNum)) + kUserBorrowAssetId), bwAsset)]
13071395 let entries = replenishEntries(pool, user, userStaked, axlyFee, posNum, shareId, pType, true)
1308- let $t04234942464 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userStaked)
1309- let wAmountA = $t04234942464._1
1310- let wAmountB = $t04234942464._2
1396+ let $t04479944914 = calcWithdrawLPFromPoolVirt(Address(fromBase58String(pool)), pType, shareId, userStaked)
1397+ let wAmountA = $t04479944914._1
1398+ let wAmountB = $t04479944914._2
13111399 $Tuple2((((entries ++ getCursEntries(AId, BId, shareId, [toString(wAmountA), toString(wAmountB)])) ++ borrowEntries) :+ DeleteEntry((requestId + kRequestId))), userStaked)
13121400 }
13131401 }))
13141402
13151403
13161404
13171405 @Callable(i)
13181406 func liquidate (user,posId,liquidateAmount) = valueOrElse(isActive(), valueOrElse(isLandCall(i), {
13191407 let pool = valueOrErrorMessage(getString(this, (((user + "_") + posId) + kUserPositionPool)), "no position")
13201408 let pType = valueOrErrorMessage(getString(this, (kPool + pool)), "Pool is not inited")
1321- let $t04298543075 = getPoolData(Address(fromBase58String(pool)), pType)
1322- let AId = $t04298543075._1
1323- let BId = $t04298543075._2
1324- let balA = $t04298543075._3
1325- let balB = $t04298543075._4
1326- let shareId = $t04298543075._5
1409+ let $t04543545525 = getPoolData(Address(fromBase58String(pool)), pType)
1410+ let AId = $t04543545525._1
1411+ let BId = $t04543545525._2
1412+ let balA = $t04543545525._3
1413+ let balB = $t04543545525._4
1414+ let shareId = $t04543545525._5
13271415 let amount = unstakeLP(pool, pType, shareId, liquidateAmount)
13281416 let borrowAmount = getIntegerValue(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAmount))
13291417 let borrowAsset = getStringValue(this, (((((pool + "_") + user) + "_") + posId) + kUserBorrowAssetId))
13301418 let userCanWithdraw = userCanWithdrawShareCalc(user, pool, posId, (borrowAmount > 0))
13311419 if ((liquidateAmount > userCanWithdraw))
13321420 then throw("You can't liquidate more than user have")
13331421 else if ((borrowAmount == 0))
13341422 then throw("You can't liquidate position without borrow")
13351423 else [IntegerEntry((((((pool + "_") + user) + "_") + posId) + kUserPositionInterest), getIntegerValue(this, (pool + kPoolInterestLoan))), IntegerEntry((pool + kPoolTotalLoan), (getPoolTotalShareWithLoan(pool) - liquidateAmount)), IntegerEntry((pool + kPoolTotal), (getPoolTotalShare(pool) - liquidateAmount)), IntegerEntry((((((pool + "_") + user) + "_") + posId) + kUserPosition), (userCanWithdraw - liquidateAmount)), ScriptTransfer(i.caller, amount, fromBase58String(shareId))]
13361424 }))
13371425
13381426
13391427
13401428 @Callable(i)
1341-func stopLoss (user,posId,pool,assetId) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
1429+func stopLoss (user,posId,pool,assetId) = valueOrElse(isActive(), valueOrElse(isOperatorCall(i), {
13421430 let tokenOraclePrice = getIntegerValue(priceOracleAddr, (assetId + kPriceInOracle))
13431431 let stopLossPrice = valueOrErrorMessage(getInteger(this, (((((((user + "_") + toString(posId)) + "_") + pool) + "_") + assetId) + kUserStopLoss)), "No entry")
13441432 if ((tokenOraclePrice > stopLossPrice))
13451433 then throw("Token price greater stop loss price")
13461434 else {
13471435 let res = withdrawToUser(user, pool, toString(posId), true)
13481436 $Tuple2((res._1 :+ DeleteEntry((((((((user + "_") + toString(posId)) + "_") + pool) + "_") + assetId) + kUserStopLoss))), res._2)
13491437 }
13501438 }))
13511439
13521440
13531441
13541442 @Callable(i)
1355-func capitalizeExKeeper (pool,tokenToId,amountToExchange,claim,amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived,options) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
1443+func capitalizeExKeeper (pool,tokenToId,amountToExchange,claim,amountsIn,addresses,assetsToReceive,estReceived,slippageTolerance,minReceived,options) = valueOrElse(isActive(), valueOrElse(isOperatorCall(i), {
13561444 let pType = getStringValue(this, (kPool + pool))
13571445 let change = valueOrElse(getInteger(this, (pool + kPoolCapChange)), 0)
1358- let $t04521845319 = claimAndCheckAmntEx(pool, pType, claim, amountToExchange, change)
1359- let claimedAmount = $t04521845319._1
1360- let claimedAsset = $t04521845319._2
1446+ let $t04767447773 = claimAndCheckAmnt(pool, pType, claim, amountToExchange, change)
1447+ let claimedAmount = $t04767447773._1
1448+ let claimedAsset = $t04767447773._2
13611449 let exchangedAmount = exchangeKeeper(tokenToId, amountToExchange, claimedAsset, amountsIn, addresses, assetsToReceive, estReceived, slippageTolerance, minReceived, options)
13621450 let newChange = ((claimedAmount + change) - amountToExchange)
13631451 let changeEntry = if ((newChange >= 0))
13641452 then [IntegerEntry((pool + kPoolCapChange), newChange)]
1365- else nil
1453+ else throw("Negative change")
13661454 (capitalize(pool, pType, tokenToId, exchangedAmount) ++ changeEntry)
13671455 }))
13681456
13691457
13701458
13711459 @Callable(i)
1372-func capitalizeExPuzzle (pool,tokenToId,amountToExchange,claim,routesStr,minToReceive,options) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
1460+func capitalizeExPuzzle (pool,tokenToId,amountToExchange,claim,routesStr,minToReceive,options) = valueOrElse(isActive(), valueOrElse(isOperatorCall(i), {
13731461 let pType = getStringValue(this, (kPool + pool))
13741462 let change = valueOrElse(getInteger(this, (pool + kPoolCapChange)), 0)
1375- let $t04609446195 = claimAndCheckAmntEx(pool, pType, claim, amountToExchange, change)
1376- let claimedAmount = $t04609446195._1
1377- let claimedAsset = $t04609446195._2
1463+ let $t04857348672 = claimAndCheckAmnt(pool, pType, claim, amountToExchange, change)
1464+ let claimedAmount = $t04857348672._1
1465+ let claimedAsset = $t04857348672._2
13781466 let exchangedAmount = exchangePuzzle(tokenToId, amountToExchange, claimedAsset, routesStr, minToReceive, options)
13791467 let newChange = ((claimedAmount + change) - amountToExchange)
13801468 let changeEntry = if ((newChange >= 0))
13811469 then [IntegerEntry((pool + kPoolCapChange), newChange)]
13821470 else nil
13831471 (capitalize(pool, pType, tokenToId, exchangedAmount) ++ changeEntry)
13841472 }))
13851473
13861474
13871475
13881476 @Callable(i)
1389-func capitalizeExSwopFi (pool,tokenToId,amountToExchange,claim,exchangers,exchangersType,args1,args2,routingAssetsKeys,minAmountToReceive,options) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), {
1477+func capitalizeExSwopFi (pool,tokenToId,amountToExchange,claim,exchangers,exchangersType,args1,args2,routingAssetsKeys,minAmountToReceive,options) = valueOrElse(isActive(), valueOrElse(isOperatorCall(i), {
13901478 let pType = getStringValue(this, (kPool + pool))
13911479 let change = valueOrElse(getInteger(this, (pool + kPoolCapChange)), 0)
1392- let $t04703747138 = claimAndCheckAmntEx(pool, pType, claim, amountToExchange, change)
1393- let claimedAmount = $t04703747138._1
1394- let claimedAsset = $t04703747138._2
1480+ let $t04951749616 = claimAndCheckAmnt(pool, pType, claim, amountToExchange, change)
1481+ let claimedAmount = $t04951749616._1
1482+ let claimedAsset = $t04951749616._2
13951483 let exchangedAmount = exchangeSwopFi(tokenToId, amountToExchange, claimedAsset, exchangers, exchangersType, args1, args2, routingAssetsKeys, minAmountToReceive, options)
13961484 let newChange = ((claimedAmount + change) - amountToExchange)
13971485 let changeEntry = if ((newChange >= 0))
13981486 then [IntegerEntry((pool + kPoolCapChange), newChange)]
13991487 else nil
14001488 (capitalize(pool, pType, tokenToId, exchangedAmount) ++ changeEntry)
14011489 }))
14021490
14031491
14041492
14051493 @Callable(i)
1494+func capitalizeNoEx (pool,claim,amountFromBalance) = valueOrElse(isActive(), valueOrElse(isOperatorCall(i), {
1495+ let pType = getStringValue(this, (kPool + pool))
1496+ let $t05021350308 = claimAndCheckAmnt(pool, pType, claim, amountFromBalance, 0)
1497+ let claimedAmount = $t05021350308._1
1498+ let claimedAsset = $t05021350308._2
1499+ capitalize(pool, pType, assetIdToStr(claimedAsset), (claimedAmount + amountFromBalance))
1500+ }))
1501+
1502+
1503+
1504+@Callable(i)
14061505 func initNewPool (type,poolAddr,inFeeNoLoan,inFeeLoan,capFeeNoLoan,capFeeWithLoan,stoplossFeeNoLoan,stoplossFeeWithLoan,canBorrow) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), if (if ((type != SF_POOL))
14071506 then (type != WX_POOL)
14081507 else false)
14091508 then throw("Wrong type")
14101509 else {
1411- let $t04786947963 = getPoolData(Address(fromBase58String(poolAddr)), type)
1412- let aId = $t04786947963._1
1413- let bId = $t04786947963._2
1414- let aBal = $t04786947963._3
1415- let bBal = $t04786947963._4
1416- let shareId = $t04786947963._5
1510+ let $t05073450828 = getPoolData(Address(fromBase58String(poolAddr)), type)
1511+ let aId = $t05073450828._1
1512+ let bId = $t05073450828._2
1513+ let aBal = $t05073450828._3
1514+ let bBal = $t05073450828._4
1515+ let shareId = $t05073450828._5
14171516 if ((0 > inFeeNoLoan))
14181517 then throw("inFeeNoLoan must be greater than 0")
14191518 else if ((0 > inFeeLoan))
14201519 then throw("inFeeLoan must be greater than 0")
14211520 else if ((0 > capFeeNoLoan))
14221521 then throw("capFeeNoLoan must be greater than 0")
14231522 else if ((0 > capFeeWithLoan))
14241523 then throw("capFeeWithLoan must be greater than 0")
14251524 else if ((0 > stoplossFeeNoLoan))
14261525 then throw("stoplossFeeNoLoan must be greater than 0")
14271526 else if ((0 > stoplossFeeWithLoan))
14281527 then throw("stoplossFeeWithLoan must be greater than 0")
14291528 else [IntegerEntry((poolAddr + kAxlyInFeeWithoutLoan), inFeeNoLoan), IntegerEntry((poolAddr + kAxlyInFeeWithLoan), inFeeLoan), IntegerEntry((poolAddr + kAxlyNoLoanCapFee), capFeeNoLoan), IntegerEntry((poolAddr + kAxlyWithLoanCapFee), capFeeWithLoan), IntegerEntry((poolAddr + kAxlyStopLossNoLoanFee), stoplossFeeNoLoan), IntegerEntry((poolAddr + kAxlyStopLossLoanFee), stoplossFeeWithLoan), IntegerEntry((poolAddr + kPoolInterestLoan), 0), IntegerEntry((poolAddr + kPoolInterestNoLoan), 0), StringEntry((kPool + poolAddr), type), StringEntry((shareId + kSharePool), poolAddr), BooleanEntry((poolAddr + kPoolCanBorrow), canBorrow)]
14301529 }))
1530+
1531+
1532+
1533+@Callable(i)
1534+func updatePoolFees (poolAddr,inFeeNoLoan,inFeeLoan,capFeeNoLoan,capFeeWithLoan,stoplossFeeNoLoan,stoplossFeeWithLoan) = valueOrElse(isActive(), valueOrElse(isAdminCall(i), if (!(isDefined(getString(this, (kPool + poolAddr)))))
1535+ then throw(("Can't find pool with addr " + poolAddr))
1536+ else if ((0 > inFeeNoLoan))
1537+ then throw("inFeeNoLoan must be greater than 0")
1538+ else if ((0 > inFeeLoan))
1539+ then throw("inFeeLoan must be greater than 0")
1540+ else if ((0 > capFeeNoLoan))
1541+ then throw("capFeeNoLoan must be greater than 0")
1542+ else if ((0 > capFeeWithLoan))
1543+ then throw("capFeeWithLoan must be greater than 0")
1544+ else if ((0 > stoplossFeeNoLoan))
1545+ then throw("stoplossFeeNoLoan must be greater than 0")
1546+ else if ((0 > stoplossFeeWithLoan))
1547+ then throw("stoplossFeeWithLoan must be greater than 0")
1548+ else [IntegerEntry((poolAddr + kAxlyInFeeWithoutLoan), inFeeNoLoan), IntegerEntry((poolAddr + kAxlyInFeeWithLoan), inFeeLoan), IntegerEntry((poolAddr + kAxlyNoLoanCapFee), capFeeNoLoan), IntegerEntry((poolAddr + kAxlyWithLoanCapFee), capFeeWithLoan), IntegerEntry((poolAddr + kAxlyStopLossNoLoanFee), stoplossFeeNoLoan), IntegerEntry((poolAddr + kAxlyStopLossLoanFee), stoplossFeeWithLoan)]))
14311549
14321550
14331551
14341552 @Callable(i)
14351553 func activate () = valueOrElse(isAdminCall(i), if (valueOrElse(getBoolean(this, kActive), true))
14361554 then throw("dApp already active")
14371555 else [BooleanEntry(kActive, true)])
14381556
14391557
14401558
14411559 @Callable(i)
14421560 func shutdown () = valueOrElse(isAdminCall(i), if (!(valueOrElse(getBoolean(this, kActive), true)))
14431561 then throw("dApp already shutdown")
14441562 else [BooleanEntry(kActive, false)])
14451563
14461564
14471565
14481566 @Callable(i)
14491567 func activateForUsers () = valueOrElse(isAdminCall(i), if (valueOrElse(getBoolean(this, kActiveUsers), true))
14501568 then throw("dApp already active for users")
14511569 else [BooleanEntry(kActiveUsers, true)])
14521570
14531571
14541572
14551573 @Callable(i)
14561574 func shutdownForUsers () = valueOrElse(isAdminCall(i), if (!(valueOrElse(getBoolean(this, kActiveUsers), true)))
14571575 then throw("dApp already shutdown for users")
14581576 else [BooleanEntry(kActiveUsers, false)])
14591577
14601578
14611579
14621580 @Callable(i)
14631581 func activateSF () = valueOrElse(isAdminCall(i), if (valueOrElse(getBoolean(this, (SF_POOL + kActiveSFWX)), true))
14641582 then throw("SWOPFI already active")
14651583 else [BooleanEntry((SF_POOL + kActiveSFWX), true)])
14661584
14671585
14681586
14691587 @Callable(i)
14701588 func shutdownSF () = valueOrElse(isAdminCall(i), if (!(valueOrElse(getBoolean(this, (SF_POOL + kActiveSFWX)), true)))
14711589 then throw("SWOPFI already shutdown")
14721590 else [BooleanEntry((SF_POOL + kActiveSFWX), false)])
14731591
14741592
14751593
14761594 @Callable(i)
14771595 func activateWX () = valueOrElse(isAdminCall(i), if (valueOrElse(getBoolean(this, (WX_POOL + kActiveSFWX)), true))
14781596 then throw("WX already active")
14791597 else [BooleanEntry((WX_POOL + kActiveSFWX), true)])
14801598
14811599
14821600
14831601 @Callable(i)
14841602 func shutdownWX () = valueOrElse(isAdminCall(i), if (!(valueOrElse(getBoolean(this, (WX_POOL + kActiveSFWX)), true)))
14851603 then throw("WX already shutdown")
14861604 else [BooleanEntry((WX_POOL + kActiveSFWX), false)])
14871605
14881606
14891607
14901608 @Callable(i)
14911609 func activatePool (pool) = valueOrElse(isAdminCall(i), if (!(isDefined(getString(this, (kPool + pool)))))
14921610 then throw("Unknown pool")
14931611 else if (valueOrElse(getBoolean(this, (pool + kPoolActive)), true))
14941612 then throw("Pool already active")
14951613 else [BooleanEntry((pool + kPoolActive), true)])
14961614
14971615
14981616
14991617 @Callable(i)
15001618 func shutdownPool (pool) = valueOrElse(isAdminCall(i), if (!(isDefined(getString(this, (kPool + pool)))))
15011619 then throw("Unknown pool")
15021620 else if (!(valueOrElse(getBoolean(this, (pool + kPoolActive)), true)))
15031621 then throw("Pool already shutdown")
15041622 else [BooleanEntry((pool + kPoolActive), false)])
15051623
15061624
1507-@Verifier(tx)
1508-func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
1509-

github/deemru/w8io/3ef1775 
355.93 ms