tx · 8FCFvsr8UZyqUS7XH1L6sfv7Svey2UCCus3HoaX8HUqh

3N8yRV8Q8ZhGdZ18MLnah4VeHPNtZidcK85:  -0.04200000 Waves

2023.04.13 12:33 [2532597] smart account 3N8yRV8Q8ZhGdZ18MLnah4VeHPNtZidcK85 > SELF 0.00000000 Waves

{ "type": 13, "id": "8FCFvsr8UZyqUS7XH1L6sfv7Svey2UCCus3HoaX8HUqh", "fee": 4200000, "feeAssetId": null, "timestamp": 1681378412591, "version": 2, "chainId": 84, "sender": "3N8yRV8Q8ZhGdZ18MLnah4VeHPNtZidcK85", "senderPublicKey": "AiJf67HX3s9my1e4STFj2yEKxvzrRZZTdDaHQy1XBoy3", "proofs": [ "4S47fNMEsANPF5iq9PQFF2yd93k3vp27tYvSkUULwFN3Y21upYo8msu5s45GBvi8rZE4jQGu8AqdHXbZQ5J5coSH" ], "script": "base64:BgK9NwgCEgASBQoDAQQBEgcKBQEEAQgBEgMKAQgSABIECgIBBBIDCgEBEgQKAgEEEgQKAggBEgQKAggBEgQKAggBEgUKAwEIARIAEgQKAgEBEgMKAQESBQoDAQEBEgQKAggIEgASABIDCgEIEgUKAwEBARIECgIBARIECgIIARIECgIICBILCgkIAQECAQIIBAQSBgoECAgBCBIAEgMKAQESAwoBARIECgIIASIKbFBkZWNpbWFscyIGc2NhbGU4IgxzY2FsZThCaWdJbnQiB3NjYWxlMTgiCnplcm9CaWdJbnQiBGJpZzAiBGJpZzEiBGJpZzIiC3dhdmVzU3RyaW5nIgNTRVAiClBvb2xBY3RpdmUiD1Bvb2xQdXREaXNhYmxlZCITUG9vbE1hdGNoZXJEaXNhYmxlZCIMUG9vbFNodXRkb3duIg5pZHhQb29sQWRkcmVzcyINaWR4UG9vbFN0YXR1cyIQaWR4UG9vbExQQXNzZXRJZCINaWR4QW10QXNzZXRJZCIPaWR4UHJpY2VBc3NldElkIg5pZHhBbXRBc3NldERjbSIQaWR4UHJpY2VBc3NldERjbSIOaWR4SUFtdEFzc2V0SWQiEGlkeElQcmljZUFzc2V0SWQiDWlkeExQQXNzZXREY20iEmlkeFBvb2xBbXRBc3NldEFtdCIUaWR4UG9vbFByaWNlQXNzZXRBbXQiEWlkeFBvb2xMUEFzc2V0QW10IhlpZHhGYWN0b3J5U3Rha2luZ0NvbnRyYWN0IhppZHhGYWN0b3J5U2xpcHBhZ2VDb250cmFjdCIFdG9YMTgiB29yaWdWYWwiDW9yaWdTY2FsZU11bHQiC3RvWDE4QmlnSW50Igdmcm9tWDE4IgN2YWwiD3Jlc3VsdFNjYWxlTXVsdCIMZnJvbVgxOFJvdW5kIgVyb3VuZCIHdG9TY2FsZSIDYW10IghyZXNTY2FsZSIIY3VyU2NhbGUiA2FicyIJYWJzQmlnSW50Igxzd2FwQ29udHJhY3QiAmZjIgNtcGsiBHBtcGsiAnBsIgJwaCIBaCIJdGltZXN0YW1wIgNwYXUiC3VzZXJBZGRyZXNzIgR0eElkIgNnYXUiAmFhIgJwYSIGa2V5RmVlIgpmZWVEZWZhdWx0IgNmZWUiBmtleUtMcCIVa2V5S0xwUmVmcmVzaGVkSGVpZ2h0IhJrZXlLTHBSZWZyZXNoRGVsYXkiFmtMcFJlZnJlc2hEZWxheURlZmF1bHQiD2tMcFJlZnJlc2hEZWxheSIUa2V5QWRkaXRpb25hbEJhbGFuY2UiB2Fzc2V0SWQiFmtleVN0YWtpbmdBc3NldEJhbGFuY2UiGmdldEFkZGl0aW9uYWxCYWxhbmNlT3JaZXJvIhxnZXRTdGFraW5nQXNzZXRCYWxhbmNlT3JaZXJvIhBrZXlGYWN0b3J5Q29uZmlnIg1rZXlNYXRjaGVyUHViIilrZXlNYXBwaW5nUG9vbENvbnRyYWN0QWRkcmVzc1RvUG9vbEFzc2V0cyITcG9vbENvbnRyYWN0QWRkcmVzcyINa2V5UG9vbENvbmZpZyIJaUFtdEFzc2V0IgtpUHJpY2VBc3NldCIfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZCIMYmFzZUFzc2V0U3RyIhNrZXlBbGxQb29sc1NodXRkb3duIg1rZXlQb29sV2VpZ2h0Ig9jb250cmFjdEFkZHJlc3MiFmtleUFsbG93ZWRMcFNjcmlwdEhhc2giFmtleUZlZUNvbGxlY3RvckFkZHJlc3MiD3Rocm93T3JkZXJFcnJvciIKb3JkZXJWYWxpZCIOb3JkZXJWYWxpZEluZm8iC3NlbmRlclZhbGlkIgxtYXRjaGVyVmFsaWQiD2dldFN0cmluZ09yRmFpbCIHYWRkcmVzcyIDa2V5IgxnZXRJbnRPckZhaWwiCHRocm93RXJyIgNtc2ciBmZtdEVyciIPZmFjdG9yeUNvbnRyYWN0IhNmZWVDb2xsZWN0b3JBZGRyZXNzIgVpbkZlZSIBQCIGb3V0RmVlIhBpc0dsb2JhbFNodXRkb3duIhNnZXRNYXRjaGVyUHViT3JGYWlsIg1nZXRQb29sQ29uZmlnIghhbXRBc3NldCIKcHJpY2VBc3NldCIMcGFyc2VBc3NldElkIgVpbnB1dCIPYXNzZXRJZFRvU3RyaW5nIg9wYXJzZVBvb2xDb25maWciCnBvb2xDb25maWciEHBvb2xDb25maWdQYXJzZWQiCyR0MDg5NjI5MTI4Ig5jZmdQb29sQWRkcmVzcyINY2ZnUG9vbFN0YXR1cyIMY2ZnTHBBc3NldElkIhBjZmdBbW91bnRBc3NldElkIg9jZmdQcmljZUFzc2V0SWQiFmNmZ0Ftb3VudEFzc2V0RGVjaW1hbHMiFWNmZ1ByaWNlQXNzZXREZWNpbWFscyIQZ2V0RmFjdG9yeUNvbmZpZyIPc3Rha2luZ0NvbnRyYWN0IhBzbGlwcGFnZUNvbnRyYWN0IhFkYXRhUHV0QWN0aW9uSW5mbyINaW5BbXRBc3NldEFtdCIPaW5QcmljZUFzc2V0QW10IghvdXRMcEFtdCIFcHJpY2UiHXNsaXBwYWdlVG9sZXJhbmNlUGFzc2VkQnlVc2VyIhVzbGlwcGFnZVRvbGVyYW5jZVJlYWwiCHR4SGVpZ2h0Igt0eFRpbWVzdGFtcCISc2xpcGFnZUFtdEFzc2V0QW10IhRzbGlwYWdlUHJpY2VBc3NldEFtdCIRZGF0YUdldEFjdGlvbkluZm8iDm91dEFtdEFzc2V0QW10IhBvdXRQcmljZUFzc2V0QW10IgdpbkxwQW10Ig1nZXRBY2NCYWxhbmNlIg1iYWxhbmNlT25Qb29sIgx0b3RhbEJhbGFuY2UiD2NhbGNQcmljZUJpZ0ludCIIcHJBbXRYMTgiCGFtQW10WDE4IhRjYWxjUHJpY2VCaWdJbnRSb3VuZCIHZ2V0UmF0ZSIFcHJveHkiA2ludiIHJG1hdGNoMCIBciIHZGVwb3NpdCIGYW1vdW50Ig5zdGFraW5nQXNzZXRJZCIYY3VycmVudEFkZGl0aW9uYWxCYWxhbmNlIhpjdXJyZW50U3Rha2luZ0Fzc2V0QmFsYW5jZSIFYXNzZXQiDWRlcG9zaXRJbnZva2UiFHJlY2VpdmVkU3Rha2luZ0Fzc2V0IhRuZXdBZGRpdGlvbmFsQmFsYW5jZSIWbmV3U3Rha2luZ0Fzc2V0QmFsYW5jZSIId2l0aGRyYXciDHByb3h5UmF0ZU11bCINcHJvZml0QWRkcmVzcyIQY3VycmVudFByb3h5UmF0ZSIHb2xkUmF0ZSIMc3Rha2luZ0Fzc2V0IhRvbGRTZW5kU3Rha2luZ0Ftb3VudCIWc2VuZFN0YWtpbmdBc3NldEFtb3VudCIMcHJvZml0QW1vdW50Ig53aXRoZHJhd0ludm9rZSIOcmVjZWl2ZWRBc3NldHMiE2dldExlYXNlUHJveHlDb25maWciAWEiEXJlYmFsYW5jZUludGVybmFsIgt0YXJnZXRSYXRpbyIKbWluQmFsYW5jZSIUbGVhc2FibGVUb3RhbEJhbGFuY2UiF3RhcmdldEFkZGl0aW9uYWxCYWxhbmNlIgRkaWZmIg9zZW5kQXNzZXRBbW91bnQiDmdldEFzc2V0QW1vdW50Ig5yZWJhbGFuY2VBc3NldCINJHQwMTUzNjQxNTUwMCIKaXNMZWFzYWJsZSILbGVhc2VkUmF0aW8iDHByb3h5QWRkcmVzcyIMcHJveHlBc3NldElkIhRzdGFraW5nUHJvZml0QWRkcmVzcyIZd2l0aGRyYXdBbmRSZWJhbGFuY2VBc3NldCIJZ2V0QW1vdW50Ig0kdDAxNTg5MTE2MDI3IhduZXdUb3RhbExlYXNhYmxlQmFsYW5jZSIOd2l0aGRyYXdBbW91bnQiF3dpdGhkcmF3QW5kUmViYWxhbmNlQWxsIhRhbW91bnRBc3NldE91dEFtb3VudCITcHJpY2VBc3NldE91dEFtb3VudCISQW1BbXRXaXRoZHJhd1N0YXRlIhJQckFtdFdpdGhkcmF3U3RhdGUiEHByaXZhdGVDYWxjUHJpY2UiCmFtQXNzZXREY20iCnByQXNzZXREY20iBWFtQW10IgVwckFtdCIOYW10QXNzZXRBbXRYMTgiEHByaWNlQXNzZXRBbXRYMTgiCmNhbGNQcmljZXMiBWxwQW10IgNjZmciC2FtdEFzc2V0RGNtIg1wcmljZUFzc2V0RGNtIghwcmljZVgxOCIIbHBBbXRYMTgiE2xwUHJpY2VJbkFtQXNzZXRYMTgiE2xwUHJpY2VJblByQXNzZXRYMTgiD2NhbGN1bGF0ZVByaWNlcyIGcHJpY2VzIhRlc3RpbWF0ZUdldE9wZXJhdGlvbiIGdHhJZDU4IgpwbXRBc3NldElkIghwbXRMcEFtdCIJbHBBc3NldElkIglhbUFzc2V0SWQiCXByQXNzZXRJZCIKcG9vbFN0YXR1cyIKbHBFbWlzc2lvbiIJYW1CYWxhbmNlIgxhbUJhbGFuY2VYMTgiCXByQmFsYW5jZSIMcHJCYWxhbmNlWDE4IgtjdXJQcmljZVgxOCIIY3VyUHJpY2UiC3BtdExwQW10WDE4Ig1scEVtaXNzaW9uWDE4IgtvdXRBbUFtdFgxOCILb3V0UHJBbXRYMTgiCG91dEFtQW10IghvdXRQckFtdCIFc3RhdGUiFGVzdGltYXRlUHV0T3BlcmF0aW9uIhFzbGlwcGFnZVRvbGVyYW5jZSIMaW5BbUFzc2V0QW10IgtpbkFtQXNzZXRJZCIMaW5QckFzc2V0QW10IgtpblByQXNzZXRJZCIKaXNFdmFsdWF0ZSIGZW1pdExwIgxhbUFzc2V0SWRTdHIiDHByQXNzZXRJZFN0ciILaUFtdEFzc2V0SWQiDWlQcmljZUFzc2V0SWQiDmluQW1Bc3NldElkU3RyIg5pblByQXNzZXRJZFN0ciIPaW5BbUFzc2V0QW10WDE4Ig9pblByQXNzZXRBbXRYMTgiDHVzZXJQcmljZVgxOCIDcmVzIgtzbGlwcGFnZVgxOCIUc2xpcHBhZ2VUb2xlcmFuY2VYMTgiCnByVmlhQW1YMTgiCmFtVmlhUHJYMTgiDGV4cGVjdGVkQW10cyIRZXhwQW10QXNzZXRBbXRYMTgiE2V4cFByaWNlQXNzZXRBbXRYMTgiCWNhbGNMcEFtdCIOY2FsY0FtQXNzZXRQbXQiDmNhbGNQckFzc2V0UG10IgxzbGlwcGFnZUNhbGMiCWVtaXRMcEFtdCIGYW1EaWZmIgZwckRpZmYiC2NvbW1vblN0YXRlIgdjYWxjS0xwIg1hbW91bnRCYWxhbmNlIgxwcmljZUJhbGFuY2UiEGFtb3VudEJhbGFuY2VYMTgiD3ByaWNlQmFsYW5jZVgxOCIKdXBkYXRlZEtMcCIOY2FsY0N1cnJlbnRLTHAiEGFtb3VudEFzc2V0RGVsdGEiD3ByaWNlQXNzZXREZWx0YSIUbHBBc3NldEVtaXNzaW9uRGVsdGEiEmFtb3VudEFzc2V0QmFsYW5jZSIRcHJpY2VBc3NldEJhbGFuY2UiD2xwQXNzZXRFbWlzc2lvbiIKY3VycmVudEtMcCIScmVmcmVzaEtMcEludGVybmFsIhdhbW91bnRBc3NldEJhbGFuY2VEZWx0YSIWcHJpY2VBc3NldEJhbGFuY2VEZWx0YSIHYWN0aW9ucyISdmFsaWRhdGVVcGRhdGVkS0xwIgZvbGRLTHAiG3ZhbGlkYXRlTWF0Y2hlck9yZGVyQWxsb3dlZCIFb3JkZXIiEWFtb3VudEFzc2V0QW1vdW50IhBwcmljZUFzc2V0QW1vdW50Ig0kdDAyODE1NTI4MzY3IgNrTHAiDSR0MDI4ODA3Mjg5MDciDXVudXNlZEFjdGlvbnMiBmtMcE5ldyIMaXNPcmRlclZhbGlkIgRpbmZvIgljb21tb25HZXQiAWkiA3BtdCIGcG10QW10Igljb21tb25QdXQiCmFtQXNzZXRQbXQiCnByQXNzZXRQbXQiBmVzdFB1dCIEZW1pdCIHZW1pdEludiINZW1pdEludkxlZ2FjeSIVbGVnYWN5RmFjdG9yeUNvbnRyYWN0Igd0YWtlRmVlIglmZWVBbW91bnQiD2NhbGNQdXRPbmVUb2tlbiIQcGF5bWVudEFtb3VudFJhdyIOcGF5bWVudEFzc2V0SWQiBmlzRXZhbCIQYW1vdW50QmFsYW5jZVJhdyIPcHJpY2VCYWxhbmNlUmF3IhRwYXltZW50SW5BbW91bnRBc3NldCINJHQwMzIwMjAzMjMxMyIQYW1vdW50QmFsYW5jZU9sZCIPcHJpY2VCYWxhbmNlT2xkIg0kdDAzMjMxNzMyNDY2IhRhbW91bnRBc3NldEFtb3VudFJhdyITcHJpY2VBc3NldEFtb3VudFJhdyINJHQwMzI1OTgzMjY2MiINcGF5bWVudEFtb3VudCIQYW1vdW50QmFsYW5jZU5ldyIPcHJpY2VCYWxhbmNlTmV3IgtwcmljZU5ld1gxOCIIcHJpY2VOZXciDnBheW1lbnRCYWxhbmNlIhRwYXltZW50QmFsYW5jZUJpZ0ludCIMc3VwcGx5QmlnSW50IgtjaGVjaFN1cHBseSINZGVwb3NpdEJpZ0ludCILaXNzdWVBbW91bnQiC3ByaWNlT2xkWDE4IghwcmljZU9sZCIEbG9zcyINJHQwMzQzNDMzNDUxMCIHYmFsYW5jZSIPaXNzdWVBbW91bnRCb3RoIg9jYWxjR2V0T25lVG9rZW4iCm91dEFzc2V0SWQiBmNoZWNrcyIQb3V0SW5BbW91bnRBc3NldCINYmFsYW5jZUJpZ0ludCIYb3V0SW5BbW91bnRBc3NldERlY2ltYWxzIgxhbUJhbGFuY2VPbGQiDHByQmFsYW5jZU9sZCIKb3V0QmFsYW5jZSIQb3V0QmFsYW5jZUJpZ0ludCIOcmVkZWVtZWRCaWdJbnQiCWFtb3VudFJhdyINJHQwMzY1ODgzNjY0NCILdG90YWxBbW91bnQiDSR0MDM2NjQ4MzY4NzQiC291dEFtQW1vdW50IgtvdXRQckFtb3VudCIMYW1CYWxhbmNlTmV3IgxwckJhbGFuY2VOZXciGGFtb3VudEJvdGhJblBheW1lbnRBc3NldCIWbWFuYWdlclB1YmxpY0tleU9yVW5pdCIBcyIdcGVuZGluZ01hbmFnZXJQdWJsaWNLZXlPclVuaXQiCWlzTWFuYWdlciICcGsiC211c3RNYW5hZ2VyIgJwZCINY2xlYW5BbW91bnRJbiIJaXNSZXZlcnNlIg1mZWVQb29sQW1vdW50Ig0kdDAzODc2MDM5MDY1Ighhc3NldE91dCIHYXNzZXRJbiIScG9vbEFzc2V0SW5CYWxhbmNlIhNwb29sQXNzZXRPdXRCYWxhbmNlIglhbW91bnRPdXQiBG9sZEsiBG5ld0siBmNoZWNrSyIMYW1vdW50T3V0TWluIglhZGRyZXNzVG8iC3N3YXBDb250YWN0IghjaGVja01pbiIOcmViYWxhbmNlU3RhdGUiDXdpdGhkcmF3U3RhdGUiF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5IgtjaGVja0NhbGxlciIVY2hlY2tNYW5hZ2VyUHVibGljS2V5IgJwbSIFaGFzUE0iB2NoZWNrUE0iD3Nob3VsZEF1dG9TdGFrZSIEYW1JZCIEcHJJZCIMc2xpcHBhZ2VBSW52IgxzbGlwcGFnZVBJbnYiCmxwVHJhbnNmZXIiC3NscFN0YWtlSW52Ig0kdDA0NDExMTQ0NTczIhFyZWZyZXNoS0xwQWN0aW9ucyIRaXNVcGRhdGVkS0xwVmFsaWQiA3JlYiILbWF4U2xpcHBhZ2UiDSR0MDQ1MTg1NDUyNTAiDG1pbk91dEFtb3VudCIJYXV0b1N0YWtlIiBpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZCINaXNQdXREaXNhYmxlZCIHcGF5bWVudCINJHQwNDY0Mzg0NjU5MCIFYm9udXMiE2VtaXRBbW91bnRFc3RpbWF0ZWQiCmVtaXRBbW91bnQiCHN0YWtlSW52IgdzZW5kRmVlIg0kdDA0NzE3NjQ3MzczIg0kdDA0NzM3NjQ3NDg0Ig0kdDA0NzgzOTQ3OTk2Ig1vdXRBc3NldElkU3RyIg1pc0dldERpc2FibGVkIg0kdDA0ODg4MTQ5MDM0Ig9hbW91bnRFc3RpbWF0ZWQiB2J1cm5JbnYiDWFzc2V0VHJhbnNmZXIiDSR0MDQ5Njk4NDk5NDUiEGZlZUFtb3VudEZvckNhbGMiDSR0MDQ5OTQ4NTAwNTYiDSR0MDUwMzM0NTA0OTAiDXVuc3Rha2VBbW91bnQiCnVuc3Rha2VJbnYiDSR0MDUxMzk1NTE1NDYiDSR0MDUyMjA1NTI0NTIiDSR0MDUyNDU1NTI1NjMiFGJ1cm5MUEFzc2V0T25GYWN0b3J5Ig0kdDA1MzY1ODUzNzM5IhJub0xlc3NUaGVuQW10QXNzZXQiFG5vTGVzc1RoZW5QcmljZUFzc2V0Ig0kdDA1NDgzNDU0OTE1Ig1jaGVja1BheW1lbnRzIg9jaGVja1Bvb2xTdGF0dXMiDSR0MDU2MTg3NTYyNjgiFW5vTGVzc1RoZW5BbW91bnRBc3NldCIMY2hlY2tBbW91bnRzIg0kdDA1NzcwOTU3NzkwIgthbXRBc3NldFN0ciINcHJpY2VBc3NldFN0ciIYbGFzdFJlZnJlc2hlZEJsb2NrSGVpZ2h0Ih1jaGVja0xhc3RSZWZyZXNoZWRCbG9ja0hlaWdodCINJHQwNTg5OTQ1OTA1OCIQa0xwVXBkYXRlQWN0aW9ucyIKYW10QXNzZXRJZCIMcHJpY2VBc3NldElkIg1wb29sTFBCYWxhbmNlIhJhY2NBbXRBc3NldEJhbGFuY2UiFGFjY1ByaWNlQXNzZXRCYWxhbmNlIgpwcmljZXNMaXN0Ig9scEFtdEFzc2V0U2hhcmUiEWxwUHJpY2VBc3NldFNoYXJlIgpwb29sV2VpZ2h0IgxjdXJQcmljZUNhbGMiDGFtQmFsYW5jZVJhdyIMcHJCYWxhbmNlUmF3Ig9hbUJhbGFuY2VSYXdYMTgiD3ByQmFsYW5jZVJhd1gxOCIQcGF5bWVudExwQXNzZXRJZCIMcGF5bWVudExwQW10IgJ0eCIGdmVyaWZ5Ig90YXJnZXRQdWJsaWNLZXkiCm1hdGNoZXJQdWIiDSR0MDY3NzIwNjc3ODkiB25ld0hhc2giC2FsbG93ZWRIYXNoIgtjdXJyZW50SGFzaH8AAWEACAABYgCAwtcvAAFjCQC2AgEAgMLXLwABZAkAtgIBAICAkLu61q3wDQABZQkAtgIBAAAAAWYJALYCAQAAAAFnCQC2AgEAAQABaAkAtgIBAAIAAWkCBVdBVkVTAAFqAgJfXwABawABAAFsAAIAAW0AAwABbgAEAAFvAAEAAXAAAgABcQADAAFyAAQAAXMABQABdAAGAAF1AAcAAXYACAABdwAJAAF4AAoAAXkAAQABegACAAFBAAMAAUIAAQABQwAHAQFEAgFFAUYJALwCAwkAtgIBBQFFBQFkCQC2AgEFAUYBAUcCAUUBRgkAvAIDBQFFBQFkBQFGAQFIAgFJAUoJAKADAQkAvAIDBQFJCQC2AgEFAUoFAWQBAUsDAUkBSgFMCQCgAwEJAL0CBAUBSQkAtgIBBQFKBQFkBQFMAQFNAwFOAU8BUAkAawMFAU4FAU8FAVABAVEBAUkDCQBmAgAABQFJCQEBLQEFAUkFAUkBAVIBAUkDCQC/AgIFAWUFAUkJAL4CAQUBSQUBSQEBUwACECVzX19zd2FwQ29udHJhY3QBAVQAAhMlc19fZmFjdG9yeUNvbnRyYWN0AQFVAAIUJXNfX21hbmFnZXJQdWJsaWNLZXkBAVYAAhslc19fcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkBAVcAAhElcyVzX19wcmljZV9fbGFzdAEBWAIBWQFaCQC5CQIJAMwIAgIYJXMlcyVkJWRfX3ByaWNlX19oaXN0b3J5CQDMCAIJAKQDAQUBWQkAzAgCCQCkAwEFAVoFA25pbAUBagECYWECAmFiAmFjCQCsAgIJAKwCAgkArAICAgslcyVzJXNfX1BfXwUCYWICAl9fBQJhYwECYWQCAmFiAmFjCQCsAgIJAKwCAgkArAICAgslcyVzJXNfX0dfXwUCYWICAl9fBQJhYwECYWUAAg8lc19fYW1vdW50QXNzZXQBAmFmAAIOJXNfX3ByaWNlQXNzZXQAAmFnAgclc19fZmVlAAJhaAkAawMACgUBYgCQTgACYWkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUCYWcFAmFoAAJhagkAuQkCCQDMCAICAiVzCQDMCAICA2tMcAUDbmlsBQFqAAJhawkAuQkCCQDMCAICAiVzCQDMCAICEmtMcFJlZnJlc2hlZEhlaWdodAUDbmlsBQFqAAJhbAkAuQkCCQDMCAICAiVzCQDMCAICD3JlZnJlc2hLTHBEZWxheQUDbmlsBQFqAAJhbQAeAAJhbgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQJhbAUCYW0BAmFvAQJhcAkAuQkCCQDMCAICBCVzJXMJAMwIAgINc3Rha2VkQmFsYW5jZQkAzAgCBQJhcAUDbmlsBQFqAQJhcQECYXAJALkJAgkAzAgCAgQlcyVzCQDMCAICEXNoYXJlQXNzZXRCYWxhbmNlCQDMCAIFAmFwBQNuaWwFAWoBAmFyAQJhcAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYW8BBQJhcAAAAQJhcwECYXAJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmFxAQUCYXAAAAECYXQAAhElc19fZmFjdG9yeUNvbmZpZwECYXUAAhglcyVzX19tYXRjaGVyX19wdWJsaWNLZXkBAmF2AQJhdwkArAICCQCsAgICCCVzJXMlc19fBQJhdwIgX19tYXBwaW5nc19fcG9vbENvbnRyYWN0MkxwQXNzZXQBAmF4AgJheQJhegkArAICCQCsAgIJAKwCAgkArAICAgglZCVkJXNfXwUCYXkCAl9fBQJhegIIX19jb25maWcBAmFBAQJhQgkArAICAiglcyVzJXNfX21hcHBpbmdzX19iYXNlQXNzZXQyaW50ZXJuYWxJZF9fBQJhQgECYUMAAgwlc19fc2h1dGRvd24BAmFEAQJhRQkArAICAhIlcyVzX19wb29sV2VpZ2h0X18FAmFFAQJhRgACFyVzX19hbGxvd2VkTHBTY3JpcHRIYXNoAAJhRwIXJXNfX2ZlZUNvbGxlY3RvckFkZHJlc3MBAmFIBAJhSQJhSgJhSwJhTAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAiRvcmRlciB2YWxpZGF0aW9uIGZhaWxlZDogb3JkZXJWYWxpZD0JAKUDAQUCYUkCAiAoBQJhSgIBKQINIHNlbmRlclZhbGlkPQkApQMBBQJhSwIOIG1hdGNoZXJWYWxpZD0JAKUDAQUCYUwBAmFNAgJhTgJhTwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFAmFOBQJhTwkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQJhTgkAzAgCAgEuCQDMCAIFAmFPCQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABAmFQAgJhTgJhTwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFAmFOBQJhTwkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQJhTgkAzAgCAgEuCQDMCAIFAmFPCQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABAmFRAQJhUgkAAgEJALkJAgkAzAgCAghscC5yaWRlOgkAzAgCBQJhUgUDbmlsAgEgAQJhUwECYVIJALkJAgkAzAgCAghscC5yaWRlOgkAzAgCBQJhUgUDbmlsAgEgAAJhVAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFNAgUEdGhpcwkBAVQAAAJhVQkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFNAgUCYVQFAmFHAAJhVgoAAmFXCQD8BwQFAmFUAhBnZXRJbkZlZVJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYVcCA0ludAUCYVcJAAIBCQCsAgIJAAMBBQJhVwIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AAJhWAoAAmFXCQD8BwQFAmFUAhFnZXRPdXRGZWVSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFXAgNJbnQFAmFXCQACAQkArAICCQADAQUCYVcCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAECYVkACQELdmFsdWVPckVsc2UCCQCbCAIFAmFUCQECYUMABwECYVoACQDZBAEJAQJhTQIFAmFUCQECYXUAAQJiYQAEAmJiCQECYU0CBQR0aGlzCQECYWUABAJiYwkBAmFNAgUEdGhpcwkBAmFmAAQCYXoJAQJhUAIFAmFUCQECYUEBBQJiYwQCYXkJAQJhUAIFAmFUCQECYUEBBQJiYgkAtQkCCQECYU0CBQJhVAkBAmF4AgkApAMBBQJheQkApAMBBQJhegUBagECYmQBAmJlAwkAAAIFAmJlBQFpBQR1bml0CQDZBAEFAmJlAQJiZgECYmUDCQAAAgUCYmUFBHVuaXQFAWkJANgEAQkBBXZhbHVlAQUCYmUBAmJnAQJiaAkAmQoHCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFAmJoBQFvCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYmgFAXAJANkEAQkAkQMCBQJiaAUBcQkBAmJkAQkAkQMCBQJiaAUBcgkBAmJkAQkAkQMCBQJiaAUBcwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJoBQF0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYmgFAXUAAmJpCQECYmcBCQECYmEAAAJiagUCYmkAAmJrCAUCYmoCXzEAAmJsCAUCYmoCXzIAAmJtCAUCYmoCXzMAAmJuCAUCYmoCXzQAAmJvCAUCYmoCXzUAAmJwCAUCYmoCXzYAAmJxCAUCYmoCXzcBAmJyAAkAtQkCCQECYU0CBQJhVAkBAmF0AAUBagACYnMJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIJAQJicgAFAUICGWluY29ycmVjdCBzdGFraW5nIGFkZHJlc3MAAmJ0CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCCQECYnIABQFDAhlpbmNvcnJlY3Qgc3Rha2luZyBhZGRyZXNzAQJidQoCYnYCYncCYngCYnkCYnoCYkECYkICYkMCYkQCYkUJALkJAgkAzAgCAhQlZCVkJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmJ2CQDMCAIJAKQDAQUCYncJAMwIAgkApAMBBQJieAkAzAgCCQCkAwEFAmJ5CQDMCAIJAKQDAQUCYnoJAMwIAgkApAMBBQJiQQkAzAgCCQCkAwEFAmJCCQDMCAIJAKQDAQUCYkMJAMwIAgkApAMBBQJiRAkAzAgCCQCkAwEFAmJFBQNuaWwFAWoBAmJGBgJiRwJiSAJiSQJieQJiQgJiQwkAuQkCCQDMCAICDCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmJHCQDMCAIJAKQDAQUCYkgJAMwIAgkApAMBBQJiSQkAzAgCCQCkAwEFAmJ5CQDMCAIJAKQDAQUCYkIJAMwIAgkApAMBBQJiQwUDbmlsBQFqAQJiSgECYXAEAmJLAwkAAAIFAmFwAgVXQVZFUwgJAO8HAQUEdGhpcwlhdmFpbGFibGUJAPAHAgUEdGhpcwkA2QQBBQJhcAQCYkwJAGUCCQBkAgUCYksJAQJhcgEFAmFwCQECYXMBBQJhcAkAlgMBCQDMCAIAAAkAzAgCBQJiTAUDbmlsAQJiTQICYk4CYk8JALwCAwUCYk4FAWQFAmJPAQJiUAMCYk4CYk8BTAkAvQIEBQJiTgUBZAUCYk8FAUwBAmJRAQJiUgQCYlMJAPwHBAUCYlICB2dldFJhdGUFA25pbAUDbmlsAwkAAAIFAmJTBQJiUwQCYlQFAmJTAwkAAQIFAmJUAgNJbnQEAmJVBQJiVAUCYlUJAQJhUQECIHByb3h5LmdldFJhdGUoKSB1bmV4cGVjdGVkIHZhbHVlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJiVgQCYXACYlcCYlgCYlIEAmJZCQECYXIBBQJhcAMJAAACBQJiWQUCYlkEAmJaCQECYXMBBQJiWAMJAAACBQJiWgUCYloEAmNhCQECYmQBBQJhcAMJAGYCBQJiVwAABAJjYgkA/AcEBQJiUgIHZGVwb3NpdAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJjYQUCYlcFA25pbAMJAAACBQJjYgUCY2IEAmJUBQJjYgMJAAECBQJiVAIDSW50BAJjYwUCYlQEAmNkCQBkAgUCYlkFAmJXBAJjZQkAZAIFAmJaBQJjYwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFvAQUCYXAFAmNkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXEBBQJiWAUCY2UFA25pbAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmNmBgJhcAJiVwJiWAJiUgJjZwJjaAQCYlkJAQJhcgEFAmFwAwkAAAIFAmJZBQJiWQQCYloJAQJhcwEFAmJYAwkAAAIFAmJaBQJiWgQCY2kJAQJiUQEFAmJSAwkAAAIFAmNpBQJjaQQCY2oJAGsDBQJjZwUCYlkFAmJaBAJjawkBAmJkAQUCYlgEAmNsCQBrAwUCY2cFAmJXBQJjagQCY20JAGsDBQJjZwUCYlcFAmNpBAJjbgkAlgMBCQDMCAIAAAkAzAgCCQBlAgUCY2wFAmNtBQNuaWwDCQBmAgUCY20AAAQCY28JAPwHBAUCYlICCHdpdGhkcmF3BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmNrBQJjbQUDbmlsAwkAAAIFAmNvBQJjbwQCYlQFAmNvAwkAAQIFAmJUAgNJbnQEAmNwBQJiVAQCY2QJAGUCBQJiWQUCY3AEAmNlCQBlAgkAZQIFAmJaBQJjbQUCY24JAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhbwEFAmFwBQJjZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFxAQUCYlgFAmNlCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmNoBQJjbgkBAmJkAQUCYlgFA25pbAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmNxAQJhcAQCYlQJAPwHBAUCYVQCGmdldFBvb2xMZWFzZUNvbmZpZ1JFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwkAzAgCBQJhcAUDbmlsBQNuaWwDCQABAgUCYlQCMChCb29sZWFuLCBJbnQsIEludCwgU3RyaW5nLCBTdHJpbmcsIEludCwgU3RyaW5nKQQCY3IFAmJUBQJjcgkBAmFRAQkArAICCQCsAgICAVsFAmFwAh1dIGdldExlYXNlUHJveHlDb25maWcoKSBlcnJvcgECY3MHAmN0AmFwAmJYAmN1AmJSAmNnAmNoBAJiWQkBAmFyAQUCYXADCQAAAgUCYlkFAmJZBAJiWgkBAmFzAQUCYlgDCQAAAgUCYloFAmJaBAJjdgkAlgMBCQDMCAIAAAkAzAgCCQBlAgkBAmJKAQUCYXAFAmN1BQNuaWwEAmN3CQBrAwUCY3QFAmN2AGQEAmN4CQBlAgUCYlkFAmN3AwkAAAIFAmN4AAAFA25pbAMJAGYCAAAFAmN4BAJjeQkBAS0BBQJjeAkBAmJWBAUCYXAFAmN5BQJiWAUCYlIEAmN6BQJjeAkBAmNmBgUCYXAFAmN6BQJiWAUCYlIFAmNnBQJjaAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY0EBAmFwBAJjQgkBAmNxAQUCYXAEAmNDCAUCY0ICXzEEAmNECAUCY0ICXzIEAmN1CAUCY0ICXzMEAmNFCAUCY0ICXzQEAmNGCAUCY0ICXzUEAmNnCAUCY0ICXzYEAmNHCAUCY0ICXzcDBQJjQwkBAmNzBwUCY0QFAmFwBQJjRgUCY3UJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmNFBQJjZwkBEUBleHRyTmF0aXZlKDEwNjIpAQUCY0cFA25pbAECY0gCAmFwAmNJBAJjSgkBAmNxAQUCYXAEAmNDCAUCY0oCXzEEAmNECAUCY0oCXzIEAmN1CAUCY0oCXzMEAmNFCAUCY0oCXzQEAmNGCAUCY0oCXzUEAmNnCAUCY0oCXzYEAmNHCAUCY0oCXzcDBQJjQwQCY0sJAJYDAQkAzAgCAAAJAMwIAgkAZQIJAGUCCQECYkoBBQJhcAUCY0kFAmN1BQNuaWwDCQAAAgUCY0sFAmNLBAJjZAkAawMFAmNEBQJjSwBkAwkAAAIFAmNkBQJjZAQCY0wJAJYDAQkAzAgCAAAJAMwIAgkAZQIJAQJhcgEFAmFwBQJjZAUDbmlsAwkAAAIFAmNMBQJjTAkBAmNmBgUCYXAFAmNMBQJjRgkBEUBleHRyTmF0aXZlKDEwNjIpAQUCY0UFAmNnCQERQGV4dHJOYXRpdmUoMTA2MikBBQJjRwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsAQJjTQICY04CY08EAmNQCQECY0gCCQECYU0CBQR0aGlzCQECYWUABQJjTgQCY1EJAQJjSAIJAQJhTQIFBHRoaXMJAQJhZgAFAmNPCQDOCAIFAmNQBQJjUQECY1IEAmNTAmNUAmNVAmNWBAJjVwkBAUQCBQJjVQUCY1MEAmNYCQEBRAIFAmNWBQJjVAkBAmJNAgUCY1gFAmNXAQJjWQMCY1UCY1YCY1oEAmRhCQECYmEABAJkYgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRhBQF0BAJkYwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRhBQF1BAJkZAkBAmNSBAUCZGIFAmRjBQJjVQUCY1YEAmJPCQEBRAIFAmNVBQJkYgQCYk4JAQFEAgUCY1YFAmRjBAJkZQkBAUQCBQJjWgUBYgQCZGYJAQJiTQIFAmJPBQJkZQQCZGcJAQJiTQIFAmJOBQJkZQkAzAgCBQJkZAkAzAgCBQJkZgkAzAgCBQJkZwUDbmlsAQJkaAMCY1UCY1YCY1oEAmRpCQECY1kDBQJjVQUCY1YFAmNaCQDMCAIJAQFIAgkAkQMCBQJkaQAABQFiCQDMCAIJAQFIAgkAkQMCBQJkaQABBQFiCQDMCAIJAQFIAgkAkQMCBQJkaQACBQFiBQNuaWwBAmRqBAJkawJkbAJkbQJhYgQCZGEJAQJiYQAEAmRuCQCRAwIFAmRhBQFxBAJkbwkAkQMCBQJkYQUBcgQCZHAJAJEDAgUCZGEFAXMEAmNTCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGEFAXQEAmNUCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGEFAXUEAmRxCQCRAwIFAmRhBQFwBAJkcggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFAmRuCQCsAgIJAKwCAgIGQXNzZXQgBQJkbgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkDCQECIT0CBQJkbgUCZGwJAAIBAhVJbnZhbGlkIGFzc2V0IHBhc3NlZC4EAmRzCQECYkoBBQJkbwQCZHQJAQFEAgUCZHMFAmNTBAJkdQkBAmJKAQUCZHAEAmR2CQEBRAIFAmR1BQJjVAQCZHcJAQJiTQIFAmR2BQJkdAQCZHgJAQFIAgUCZHcFAWIEAmR5CQEBRAIFAmRtBQFiBAJkegkBAUQCBQJkcgUBYgQCZEEJALwCAwUCZHQFAmR5BQJkegQCZEIJALwCAwUCZHYFAmR5BQJkegQCZEMJAQFLAwUCZEEFAmNTBQVGTE9PUgQCZEQJAQFLAwUCZEIFAmNUBQVGTE9PUgQCZEUDCQAAAgUCZGsCAAUDbmlsCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFiBQJkQwMJAAACBQJkbwIFV0FWRVMFBHVuaXQJANkEAQUCZG8JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYWIFAmREAwkAAAIFAmRwAgVXQVZFUwUEdW5pdAkA2QQBBQJkcAkAzAgCCQELU3RyaW5nRW50cnkCCQECYWQCCQClCAEFAmFiBQJkawkBAmJGBgUCZEMFAmREBQJkbQUCZHgFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZHgJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZHgFA25pbAkAnAoKBQJkQwUCZEQFAmRvBQJkcAUCZHMFAmR1BQJkcgUCZHcFAmRxBQJkRQECZEYJAmRrAmRHAmRIAmRJAmRKAmRLAmFiAmRMAmRNBAJkYQkBAmJhAAQCZG4JANkEAQkAkQMCBQJkYQUBcQQCZE4JAJEDAgUCZGEFAXIEAmRPCQCRAwIFAmRhBQFzBAJkUAkAkQMCBQJkYQUBdgQCZFEJAJEDAgUCZGEFAXcEAmRiCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGEFAXQEAmRjCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGEFAXUEAmRxCQCRAwIFAmRhBQFwBAJkcggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJkbgkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJkbgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmRSCQDYBAEJAQt2YWx1ZU9yRWxzZQIFAmRJCQDZBAECBVdBVkVTBAJkUwkA2AQBCQELdmFsdWVPckVsc2UCBQJkSwkA2QQBAgVXQVZFUwMDCQECIT0CBQJkTgUCZFIGCQECIT0CBQJkTwUCZFMJAAIBAiJJbnZhbGlkIGFtdCBvciBwcmljZSBhc3NldCBwYXNzZWQuBAJkcwMFAmRMCQECYkoBBQJkTgkAZQIJAQJiSgEFAmROBQJkSAQCZHUDBQJkTAkBAmJKAQUCZE8JAGUCCQECYkoBBQJkTwUCZEoEAmRUCQEBRAIFAmRIBQJkYgQCZFUJAQFEAgUCZEoFAmRjBAJkVgkBAmJNAgUCZFUFAmRUBAJkdAkBAUQCBQJkcwUCZGIEAmR2CQEBRAIFAmR1BQJkYwQCZFcDCQAAAgUCZHIAAAQCZHcFAWUEAmRYBQFlBAJkZQkAdgYJALkCAgUCZFQFAmRVAAAJALYCAQAFAAEAAAUERE9XTgkAlwoFCQEBSAIFAmRlBQFiCQEBSAIFAmRUBQJkYgkBAUgCBQJkVQUCZGMJAQJiTQIJALcCAgUCZHYFAmRVCQC3AgIFAmR0BQJkVAUCZFgEAmR3CQECYk0CBQJkdgUCZHQEAmRYCQC8AgMJAQFSAQkAuAICBQJkdwUCZFYFAWQFAmR3BAJkWQkBAUQCBQJkRwUBYgMDCQECIT0CBQJkdwUBZQkAvwICBQJkWAUCZFkHCQACAQkArAICCQCsAgIJAKwCAgIPUHJpY2Ugc2xpcHBhZ2UgCQCmAwEFAmRYAh4gZXhjZWVkZWQgdGhlIHBhc3NlZCBsaW1pdCBvZiAJAKYDAQUCZFkEAmR6CQEBRAIFAmRyBQFiBAJkWgkAvQIEBQJkVAkBAmJQAwUCZHYFAmR0BQdDRUlMSU5HBQFkBQdDRUlMSU5HBAJlYQkAvQIEBQJkVQUBZAkBAmJQAwUCZHYFAmR0BQVGTE9PUgUHQ0VJTElORwQCZWIDCQC/AgIFAmRaBQJkVQkAlAoCBQJlYQUCZFUJAJQKAgUCZFQFAmRaBAJlYwgFAmViAl8xBAJlZAgFAmViAl8yBAJkZQkAvQIEBQJkegUCZWQFAmR2BQVGTE9PUgkAlwoFCQEBSwMFAmRlBQFiBQVGTE9PUgkBAUsDBQJlYwUCZGIFB0NFSUxJTkcJAQFLAwUCZWQFAmRjBQdDRUlMSU5HBQJkdwUCZFgEAmVlCAUCZFcCXzEEAmVmCAUCZFcCXzIEAmVnCAUCZFcCXzMEAmR4CQEBSAIIBQJkVwJfNAUBYgQCZWgJAQFIAggFAmRXAl81BQFiAwkAZwIAAAUCZWUJAAIBAjZJbnZhbGlkIGNhbGN1bGF0aW9ucy4gTFAgY2FsY3VsYXRlZCBpcyBsZXNzIHRoYW4gemVyby4EAmVpAwkBASEBBQJkTQAABQJlZQQCZWoJAGUCBQJkSAUCZWYEAmVrCQBlAgUCZEoFAmVnBAJlbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVcABQJkeAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVgCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJkeAkAzAgCCQELU3RyaW5nRW50cnkCCQECYWECBQJhYgUCZGsJAQJidQoFAmVmBQJlZwUCZWkFAmR4BQJkRwUCZWgFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmVqBQJlawUDbmlsCQCfCg0FAmVlBQJlaQUCZHgFAmRzBQJkdQUCZHIFAmRuBQJkcQUCZWwFAmVqBQJlawUCZEkFAmRLAQJlbQMCZW4CZW8CZHIEAmVwCQEBRwIFAmVuCQC2AgEFAmJwBAJlcQkBAUcCBQJlbwkAtgIBBQJicQQCZXIJALwCAwkAdgYJALkCAgUCZXAFAmVxAAAJALYCAQAFAAEAEgUERE9XTgUBZwUCZHIDCQAAAgUCZHIFAWYFAWYFAmVyAQJlcwMCZXQCZXUCZXYEAmV3CQC4AgIJALYCAQkBAmJKAQkBAmJmAQUCYm4FAmV0BAJleAkAuAICCQC2AgEJAQJiSgEJAQJiZgEFAmJvBQJldQQCZXkJALgCAgkAtgIBCAkBBXZhbHVlAQkA7AcBBQJibQhxdWFudGl0eQUCZXYEAmV6CQECZW0DBQJldwUCZXgFAmV5BQJlegECZUEDAmVCAmVDAmV2BAJldwkAZAIJAQJiSgEJAQJiZgEFAmJuBQJlQgQCZXgJAGQCCQECYkoBCQECYmYBBQJibwUCZUMEAmV5CQBkAggJAQV2YWx1ZQEJAOwHAQUCYm0IcXVhbnRpdHkFAmV2BAJlcgkBAmVtAwkAtgIBBQJldwkAtgIBBQJleAkAtgIBBQJleQQCZUQJAMwIAgkBDEludGVnZXJFbnRyeQIFAmFrBQZoZWlnaHQJAMwIAgkBC1N0cmluZ0VudHJ5AgUCYWoJAKYDAQUCZXIFA25pbAkAlAoCBQJlRAUCZXIBAmVFAgJlRgJlcgMJAMACAgUCZXIFAmVGBgkBAmFRAQkAuQkCCQDMCAICInVwZGF0ZWQgS0xwIGxvd2VyIHRoYW4gY3VycmVudCBLTHAJAMwIAgkApgMBBQJlRgkAzAgCCQCmAwEFAmVyBQNuaWwCASABAmVHAQJlSAQCZXcJAQJiSgEJAQJiZgEFAmJuBAJleAkBAmJKAQkBAmJmAQUCYm8EAmVJCAUCZUgGYW1vdW50BAJlSgkAbgQIBQJlSAZhbW91bnQIBQJlSAVwcmljZQUBYgUFRkxPT1IEAmVLAwkAAAIIBQJlSAlvcmRlclR5cGUFA0J1eQkAlAoCBQJlSQkBAS0BBQJlSgkAlAoCCQEBLQEFAmVJBQJlSgQCZUIIBQJlSwJfMQQCZUMIBQJlSwJfMgMDAwkBAmFZAAYJAAACBQJibAUBbQYJAAACBQJibAUBbgkAAgECHEV4Y2hhbmdlIG9wZXJhdGlvbnMgZGlzYWJsZWQDAwkBAiE9AggIBQJlSAlhc3NldFBhaXILYW1vdW50QXNzZXQFAmJuBgkBAiE9AggIBQJlSAlhc3NldFBhaXIKcHJpY2VBc3NldAUCYm8JAAIBAhNXcm9uZyBvcmRlciBhc3NldHMuBAJlTAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCoAwEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUCYWoCATAJAQJhUwECC2ludmFsaWQga0xwBAJlTQkBAmVBAwUCZUIFAmVDAAAEAmVOCAUCZU0CXzEEAmVPCAUCZU0CXzIEAmVQCQDAAgIFAmVPBQJlTAQCZVEJALkJAgkAzAgCAgRrTHA9CQDMCAIJAKYDAQUCZUwJAMwIAgIIIGtMcE5ldz0JAMwIAgkApgMBBQJlTwkAzAgCAhQgYW1vdW50QXNzZXRCYWxhbmNlPQkAzAgCCQCkAwEFAmV3CQDMCAICEyBwcmljZUFzc2V0QmFsYW5jZT0JAMwIAgkApAMBBQJleAkAzAgCAhkgYW1vdW50QXNzZXRCYWxhbmNlRGVsdGE9CQDMCAIJAKQDAQUCZUIJAMwIAgIYIHByaWNlQXNzZXRCYWxhbmNlRGVsdGE9CQDMCAIJAKQDAQUCZUMJAMwIAgIIIGhlaWdodD0JAMwIAgkApAMBBQZoZWlnaHQFA25pbAIACQCUCgIFAmVQBQJlUQECZVIBAmVTAwkBAiE9AgkAkAMBCAUCZVMIcGF5bWVudHMAAQkAAgECHWV4YWN0bHkgMSBwYXltZW50IGlzIGV4cGVjdGVkBAJlVAkBBXZhbHVlAQkAkQMCCAUCZVMIcGF5bWVudHMAAAQCZGwJAQV2YWx1ZQEIBQJlVAdhc3NldElkBAJlVQgFAmVUBmFtb3VudAQCZFcJAQJkagQJANgEAQgFAmVTDXRyYW5zYWN0aW9uSWQJANgEAQUCZGwFAmVVCAUCZVMGY2FsbGVyBAJkQwgFAmRXAl8xBAJkRAgFAmRXAl8yBAJkcQkBDXBhcnNlSW50VmFsdWUBCAUCZFcCXzkEAmRFCAUCZFcDXzEwAwMJAQJhWQAGCQAAAgUCZHEFAW4JAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmRxCQCXCgUFAmRDBQJkRAUCZVUFAmRsBQJkRQECZVYDAmVTAmRHAmRNAwkBAiE9AgkAkAMBCAUCZVMIcGF5bWVudHMAAgkAAgECH2V4YWN0bHkgMiBwYXltZW50cyBhcmUgZXhwZWN0ZWQEAmVXCQEFdmFsdWUBCQCRAwIIBQJlUwhwYXltZW50cwAABAJlWAkBBXZhbHVlAQkAkQMCCAUCZVMIcGF5bWVudHMAAQQCZVkJAQJkRgkJANgEAQgFAmVTDXRyYW5zYWN0aW9uSWQFAmRHCAUCZVcGYW1vdW50CAUCZVcHYXNzZXRJZAgFAmVYBmFtb3VudAgFAmVYB2Fzc2V0SWQJAKUIAQgFAmVTBmNhbGxlcgcFAmRNBAJkcQkBDXBhcnNlSW50VmFsdWUBCAUCZVkCXzgDAwMJAQJhWQAGCQAAAgUCZHEFAWwGCQAAAgUCZHEFAW4JAAIBCQCsAgICLFB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmRxBQJlWQECZVoBAmJXBAJmYQkA/AcEBQJhVAIEZW1pdAkAzAgCBQJiVwUDbmlsBQNuaWwDCQAAAgUCZmEFAmZhBAJmYgQCYlQFAmZhAwkAAQIFAmJUAgdBZGRyZXNzBAJmYwUCYlQJAPwHBAUCZmMCBGVtaXQJAMwIAgUCYlcFA25pbAUDbmlsBQR1bml0AwkAAAIFAmZiBQJmYgUCYlcJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmZkAgJiVwJhaQQCZmUDCQAAAgUCYWkAAAAACQBrAwUCYlcFAmFpBQFiCQCUCgIJAGUCBQJiVwUCZmUFAmZlAQJmZgQCZmcCZmgCYWICYWMEAmZpCQAAAgUCYWMFBHVuaXQEAmZqCQECYkoBCQECYmYBBQJibgQCZmsJAQJiSgEJAQJiZgEFAmJvBAJmbAMJAAACBQJmaAUCYm4GAwkAAAIFAmZoBQJibwcJAQJhUQECDWludmFsaWQgYXNzZXQEAmZtAwUCZmkJAJQKAgUCZmoFAmZrAwUCZmwJAJQKAgkAZQIFAmZqBQJmZwUCZmsJAJQKAgUCZmoJAGUCBQJmawUCZmcEAmZuCAUCZm0CXzEEAmZvCAUCZm0CXzIEAmZwAwUCZmwJAJQKAgUCZmcAAAkAlAoCAAAFAmZnBAJmcQgFAmZwAl8xBAJmcggFAmZwAl8yBAJlSQgJAQJmZAIFAmZxBQJhVgJfMQQCZUoICQECZmQCBQJmcgUCYVYCXzEEAmZzCQECZmQCBQJmZwUCYVYEAmZ0CAUCZnMCXzEEAmZlCAUCZnMCXzIEAmZ1CQBkAgUCZm4FAmVJBAJmdgkAZAIFAmZvBQJlSgQCZncJAQJiTQIJAQFEAgUCZnYFAmJxCQEBRAIFAmZ1BQJicAQCZngJAQFIAgUCZncFAWIEAmZ5AwUCZmwFAmZuBQJmbwQCZnoJALYCAQUCZnkEAmZBCQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYm0JAKwCAgkArAICAgZhc3NldCAJANgEAQUCYm0CDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJmQgMJAL8CAgUCZkEFAWYGCQECYVEBAiJpbml0aWFsIGRlcG9zaXQgcmVxdWlyZXMgYWxsIGNvaW5zAwkAAAIFAmZCBQJmQgQCZkMJALYCAQUCZnQEAmZECQCWAwEJAMwIAgAACQDMCAIJAKADAQkAugICCQC5AgIFAmZBCQC4AgIJAQpzcXJ0QmlnSW50BAkAtwICBQFkCQC6AgIJALkCAgUCZkMFAWQFAmZ6ABIAEgUERE9XTgUBZAUBZAUDbmlsBAJlbAMFAmZpBQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZngJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZngJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFhAgkApQgBCQEFdmFsdWUBBQJhYgkA2AQBCQEFdmFsdWUBBQJhYwkBAmJ1CgUCZnEFAmZyBQJmRAUCZngAAAAABQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wAAAAAAUDbmlsBAJmRQkBAmJNAgkBAUQCBQJmbwUCYnEJAQFEAgUCZm4FAmJwBAJmRgkBAUgCBQJmRQUBYgQCZkcEAmZIAwUCZmwJAJQKAgUCZnEFAmZuCQCUCgIFAmZyBQJmbwQCYlcIBQJmSAJfMQQCZkkIBQJmSAJfMgQCZkoJAKADAQkAvAIDBQJmQQkAtgIBCQBpAgUCYlcAAgkAtgIBBQJmSQkAawMJAGUCBQJmRAUCZkoFAWIFAmZKCQCXCgUFAmZEBQJlbAUCZmUFAmZHBQJmbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZksFAmZMAmZ0AmZoAmFiAmFjBAJmaQkAAAIFAmFjBQR1bml0BAJkYQkBAmJhAAQCZGIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkYQUBdAQCZGMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkYQUBdQQCZk0JAMwIAgMJAAACBQJmaAUCYm0GCQECYVEBAhBpbnZhbGlkIGxwIGFzc2V0BQNuaWwDCQAAAgUCZk0FAmZNBAJmTgMJAAACBQJmTAUCYm4GAwkAAAIFAmZMBQJibwcJAQJhUQECDWludmFsaWQgYXNzZXQEAmZPAwUCZk4JALYCAQkBAmJKAQkBAmJmAQUCYm4JALYCAQkBAmJKAQkBAmJmAQUCYm8EAmZQAwUCZk4FAmRiBQJkYwQCZlEJAQJiSgEJAQJiZgEFAmJuBAJmUgkBAmJKAQkBAmJmAQUCYm8EAmZTAwUCZk4FAmZRBQJmUgQCZlQJALYCAQUCZlMEAmZBCQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYm0JAKwCAgkArAICAgZhc3NldCAJANgEAQUCYm0CDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJmVQkAtgIBBQJmdAQCZlYJAJYDAQkAzAgCAAAJAMwIAgkAoAMBCQC6AgIJALkCAgUCZk8JALgCAgUBZAkAdgYJALgCAgUBZAkAugICCQC5AgIFAmZVBQFkBQJmQQASBQFoAAAAEgUERE9XTgUBZAUDbmlsBAJmVwkBAmZkAgUCZlYFAmFYBAJmWAgFAmZXAl8xBAJmZQgFAmZXAl8yBAJmWQMFAmZOCQCWCgQFAmZYAAAJAGUCBQJmUQUCZlYFAmZSCQCWCgQAAAUCZlgFAmZRCQBlAgUCZlIFAmZWBAJmWggFAmZZAl8xBAJnYQgFAmZZAl8yBAJnYggFAmZZAl8zBAJnYwgFAmZZAl80BAJmdwkBAmJNAgkBAUQCBQJnYwUCYnEJAQFEAgUCZ2IFAmJwBAJmeAkBAUgCBQJmdwUBYgQCZWwDBQJmaQUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZAIJAKUIAQkBBXZhbHVlAQUCYWIJANgEAQkBBXZhbHVlAQUCYWMJAQJiRgYFAmZaBQJnYQUCZnQFAmZ4BQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVwAFAmZ4CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBWAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmZ4BQNuaWwEAmZFCQECYk0CCQEBRAIFAmZSBQJicQkBAUQCBQJmUQUCYnAEAmZGCQEBSAIFAmZFBQFiBAJmRwQCZ2QJAGgCCQCgAwEJALwCAwUCZk8FAmZVBQJmQQACCQBrAwkAZQIFAmZYBQJnZAUBYgUCZ2QJAJcKBQUCZlgFAmVsBQJmZQUCZkcFAmZOCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJnZQAEAmJUCQCiCAEJAQFVAAMJAAECBQJiVAIGU3RyaW5nBAJnZgUCYlQJANkEAQUCZ2YDCQABAgUCYlQCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgECZ2cABAJiVAkAoggBCQEBVgADCQABAgUCYlQCBlN0cmluZwQCZ2YFAmJUCQDZBAEFAmdmAwkAAQIFAmJUAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmdoAQJlUwQCYlQJAQJnZQADCQABAgUCYlQCCkJ5dGVWZWN0b3IEAmdpBQJiVAkAAAIIBQJlUw9jYWxsZXJQdWJsaWNLZXkFAmdpAwkAAQIFAmJUAgRVbml0CQAAAggFAmVTBmNhbGxlcgUEdGhpcwkAAgECC01hdGNoIGVycm9yAQJnagECZVMEAmdrCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEAmJUCQECZ2UAAwkAAQIFAmJUAgpCeXRlVmVjdG9yBAJnaQUCYlQDCQAAAggFAmVTD2NhbGxlclB1YmxpY0tleQUCZ2kGBQJnawMJAAECBQJiVAIEVW5pdAMJAAACCAUCZVMGY2FsbGVyBQR0aGlzBgUCZ2sJAAIBAgtNYXRjaCBlcnJvch4CZVMBCXJlYmFsYW5jZQAJAM4IAgkBAmNBAQkBAmFNAgUEdGhpcwkBAmFlAAkBAmNBAQkBAmFNAgUEdGhpcwkBAmFmAAJlUwEhY2FsY3VsYXRlQW1vdW50T3V0Rm9yU3dhcFJFQURPTkxZAwJnbAJnbQJnbgQCZ28DCQAAAgUCZ20HBAJncAkBAmFNAgUEdGhpcwkBAmFmAAQCZ3EJAQJhTQIFBHRoaXMJAQJhZQAJAJQKAgUCZ3AFAmdxBAJncAkBAmFNAgUEdGhpcwkBAmFlAAQCZ3EJAQJhTQIFBHRoaXMJAQJhZgAJAJQKAgUCZ3AFAmdxBAJncAgFAmdvAl8xBAJncQgFAmdvAl8yBAJncgkBAmJKAQUCZ3EEAmdzCQECYkoBBQJncAQCZ3QJAGsDBQJncwUCZ2wJAGQCBQJncgUCZ2wEAmd1CQC5AgIJALYCAQUCZ3IJALYCAQUCZ3MEAmd2CQC5AgIJALcCAgkAtwICCQC2AgEJAQJiSgEFAmdxCQC2AgEFAmdsCQC2AgEFAmduCQC4AgIJALYCAQkBAmJKAQUCZ3AJALYCAQUCZ3QEAmd3AwkAwAICBQJndgUCZ3UGCQACAQIUbmV3IEsgaXMgZmV3ZXIgZXJyb3IDCQAAAgUCZ3cFAmd3CQCUCgIFA25pbAUCZ3QJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZVMBJmNhbGN1bGF0ZUFtb3VudE91dEZvclN3YXBBbmRTZW5kVG9rZW5zBQJnbAJnbQJneAJneQJnbgQCZ3oKAAJhVwkA/AcEBQJhVAIXZ2V0U3dhcENvbnRyYWN0UkVBRE9OTFkFA25pbAUDbmlsAwkAAQIFAmFXAgZTdHJpbmcFAmFXCQACAQkArAICCQADAQUCYVcCGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwQCZk0JAMwIAgMJAGcCCAkBBXZhbHVlAQkAkQMCCAUCZVMIcGF5bWVudHMAAAZhbW91bnQFAmdsBgkBAmFRAQIMV3JvbmcgYW1vdW50CQDMCAIDCQAAAggFAmVTBmNhbGxlcgkBEUBleHRyTmF0aXZlKDEwNjIpAQUCZ3oGCQECYVEBAhFQZXJtaXNzaW9uIGRlbmllZAUDbmlsAwkAAAIFAmZNBQJmTQQCZVQJAQV2YWx1ZQEJAJEDAggFAmVTCHBheW1lbnRzAAAEAmdxCQECYmYBCAUCZVQHYXNzZXRJZAQCZ3ADCQAAAgUCZ20HCQECYU0CBQR0aGlzCQECYWYACQECYU0CBQR0aGlzCQECYWUABAJncgkAZQIJAQJiSgEFAmdxCAkBBXZhbHVlAQkAkQMCCAUCZVMIcGF5bWVudHMAAAZhbW91bnQEAmdzCQECYkoBBQJncAQCZ3QJAGsDBQJncwUCZ2wJAGQCBQJncgUCZ2wEAmd1CQC5AgIJALYCAQUCZ3IJALYCAQUCZ3MEAmd2CQC5AgIJALcCAgkAtgIBCQECYkoBBQJncQkAtgIBBQJnbgkAuAICCQC2AgEJAQJiSgEFAmdwCQC2AgEFAmd0BAJndwMJAMACAgUCZ3YFAmd1BgkAAgECFG5ldyBLIGlzIGZld2VyIGVycm9yAwkAAAIFAmd3BQJndwQCZ0EDCQBnAgUCZ3QFAmd4BgkAAgECLEV4Y2hhbmdlIHJlc3VsdCBpcyBmZXdlciBjb2lucyB0aGFuIGV4cGVjdGVkAwkAAAIFAmdBBQJnQQQCZ0IJAQJjQQEFAmdxAwkAAAIFAmdCBQJnQgQCZ0MJAQJjSAIFAmdwBQJndAMJAAACBQJnQwUCZ0MJAJQKAgkAzggCCQDOCAIFAmdDBQJnQgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQJneQUCZ3QJAQJiZAEFAmdwBQNuaWwFAmd0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmVTAQpzZXRNYW5hZ2VyAQJnRAQCZ0UJAQJnagEFAmVTAwkAAAIFAmdFBQJnRQQCZ0YJANkEAQUCZ0QDCQAAAgUCZ0YFAmdGCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFWAAUCZ0QFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJlUwEOY29uZmlybU1hbmFnZXIABAJnRwkBAmdnAAQCZ0gDCQEJaXNEZWZpbmVkAQUCZ0cGCQACAQISTm8gcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmdIBQJnSAQCZ0kDCQAAAggFAmVTD2NhbGxlclB1YmxpY0tleQkBBXZhbHVlAQUCZ0cGCQACAQIbWW91IGFyZSBub3QgcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmdJBQJnSQkAzAgCCQELU3RyaW5nRW50cnkCCQEBVQAJANgEAQkBBXZhbHVlAQUCZ0cJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAVYABQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZVMBA3B1dAICZEcCZ0oDCQBmAgAABQJkRwkAAgECIEludmFsaWQgc2xpcHBhZ2VUb2xlcmFuY2UgcGFzc2VkBAJlWQkBAmVWAwUCZVMFAmRHBgQCZWkIBQJlWQJfMgQCZG4IBQJlWQJfNwQCZEUIBQJlWQJfOQQCZWoIBQJlWQNfMTAEAmVrCAUCZVkDXzExBAJnSwgFAmVZA18xMgQCZ0wIBQJlWQNfMTMEAmVXCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJlUwhwYXltZW50cwAABmFtb3VudAQCZVgJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmVTCHBheW1lbnRzAAEGYW1vdW50BAJlegkBAmVzAwUCZVcFAmVYCQC2AgEAAAMJAAACBQJlegUCZXoEAmZhCQD8BwQFAmFUAgRlbWl0CQDMCAIFAmVpBQNuaWwFA25pbAMJAAACBQJmYQUCZmEEAmZiBAJiVAUCZmEDCQABAgUCYlQCB0FkZHJlc3MEAmZjBQJiVAkA/AcEBQJmYwIEZW1pdAkAzAgCBQJlaQUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZmIFAmZiBAJnTQMJAGYCBQJlagAACQD8BwQFAmJ0AgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZ0sFAmVqBQNuaWwFA25pbAMJAAACBQJnTQUCZ00EAmdOAwkAZgIFAmVrAAAJAPwHBAUCYnQCA3B1dAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJnTAUCZWsFA25pbAUDbmlsAwkAAAIFAmdOBQJnTgQCZ08DBQJnSgQCZ1AJAPwHBAUCYnMCBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmRuBQJlaQUDbmlsAwkAAAIFAmdQBQJnUAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJlUwZjYWxsZXIFAmVpBQJkbgUDbmlsBAJnUQkBAmVBAwAAAAAAAAMJAAACBQJnUQUCZ1EEAmVyCAUCZ1ECXzIEAmdSCAUCZ1ECXzEEAmdTCQECZUUCBQJlegUCZXIDCQAAAgUCZ1MFAmdTBAJnVAkA/AcEBQR0aGlzAglyZWJhbGFuY2UFA25pbAUDbmlsAwkAAAIFAmdUBQJnVAkAzggCCQDOCAIFAmRFBQJnTwUCZ1IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZVMBCnB1dEZvckZyZWUBAmdVAwkAZgIAAAUCZ1UJAAIBAhRJbnZhbGlkIHZhbHVlIHBhc3NlZAQCZVkJAQJlVgMFAmVTBQJnVQcEAmRFCAUCZVkCXzkEAmVXCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJlUwhwYXltZW50cwAABmFtb3VudAQCZVgJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmVTCHBheW1lbnRzAAEGYW1vdW50BAJlegkBAmVzAwUCZVcFAmVYCQC2AgEAAAMJAAACBQJlegUCZXoEAmdWCQECZUEDAAAAAAAABAJnUggFAmdWAl8xBAJlcggFAmdWAl8yBAJnUwkBAmVFAgUCZXoFAmVyAwkAAAIFAmdTBQJnUwkAzggCBQJkRQUCZ1IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZVMBCXB1dE9uZVRrbgICZ1cCZ1gEAmdZCgACYVcJAPwHBAUCYVQCKGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJhVwIHQm9vbGVhbgUCYVcJAAIBCQCsAgIJAAMBBQJhVwIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCZ1oDAwMJAQJhWQAGCQAAAgUCYmwFAWwGCQAAAgUCYmwFAW4GBQJnWQQCZk0JAMwIAgMDCQEBIQEFAmdaBgkBAmdoAQUCZVMGCQECYVEBAiFwdXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJlUwhwYXltZW50cwABBgkBAmFRAQIeZXhhY3RseSAxIHBheW1lbnQgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZk0FAmZNBAJoYQkAkQMCCAUCZVMIcGF5bWVudHMAAAQCZmgIBQJoYQdhc3NldElkBAJmZwgFAmhhBmFtb3VudAQCZXoDCQAAAgUCZmgFAmJuCQECZXMDCQC2AgEFAmZnCQC2AgEAAAkAtgIBAAADCQAAAgUCZmgFAmJvCQECZXMDCQC2AgEAAAkAtgIBBQJmZwkAtgIBAAAJAQJhUQECHnBheW1lbnQgYXNzZXQgaXMgbm90IHN1cHBvcnRlZAMJAAACBQJlegUCZXoEAmFiCAUCZVMGY2FsbGVyBAJhYwgFAmVTDXRyYW5zYWN0aW9uSWQEAmhiCQECZmYEBQJmZwUCZmgFAmFiBQJhYwMJAAACBQJoYgUCaGIEAmZsCAUCaGICXzUEAmhjCAUCaGICXzQEAmZlCAUCaGICXzMEAmVsCAUCaGICXzIEAmhkCAUCaGICXzEEAmhlAwMJAGYCBQJnVwAACQBmAgUCZ1cFAmhkBwkBAmFRAQkAuQkCCQDMCAICH2Ftb3VudCB0byByZWNlaXZlIGlzIGxlc3MgdGhhbiAJAMwIAgkApAMBBQJnVwUDbmlsAgAFAmhkBAJmYQkBAmVaAQUCaGUDCQAAAgUCZmEFAmZhBAJnTwMFAmdYBAJoZgkA/AcEBQJicwIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYm0FAmhlBQNuaWwDCQAAAgUCaGYFAmhmBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmVTBmNhbGxlcgUCaGUFAmJtBQNuaWwEAmhnAwkAZgIFAmZlAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYVUFAmZlBQJmaAUDbmlsBQNuaWwEAmhoAwkAAAIFBHRoaXMFAmFVCQCUCgIAAAAAAwUCZmwJAJQKAgkBAS0BBQJmZQAACQCUCgIAAAkBAS0BBQJmZQQCZUIIBQJoaAJfMQQCZUMIBQJoaAJfMgQCaGkJAQJlQQMFAmVCBQJlQwAABAJnUggFAmhpAl8xBAJlcggFAmhpAl8yBAJlTAkBBXZhbHVlAQkAoggBBQJhagQCZ1MJAQJlRQIFAmV6BQJlcgMJAAACBQJnUwUCZ1MEAmdUCQD8BwQFBHRoaXMCCXJlYmFsYW5jZQUDbmlsBQNuaWwDCQAAAgUCZ1QFAmdUCQCUCgIJAM4IAgkAzggCCQDOCAIFAmVsBQJnTwUCaGcFAmdSBQJoZQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJlUwERcHV0T25lVGtuUkVBRE9OTFkCAmZoAmZnBAJoagkBAmZmBAUCZmcJAQJiZAEFAmZoBQR1bml0BQR1bml0BAJoZAgFAmhqAl8xBAJlbAgFAmhqAl8yBAJmZQgFAmhqAl8zBAJoYwgFAmhqAl80BAJmbAgFAmhqAl81CQCUCgIFA25pbAkAlQoDBQJoZAUCZmUFAmhjAmVTAQlnZXRPbmVUa24CAmhrAmdXBAJnWQoAAmFXCQD8BwQFAmFUAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYVcCB0Jvb2xlYW4FAmFXCQACAQkArAICCQADAQUCYVcCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmhsAwMJAQJhWQAGCQAAAgUCYmwFAW4GBQJnWQQCZk0JAMwIAgMDCQEBIQEFAmhsBgkBAmdoAQUCZVMGCQECYVEBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJlUwhwYXltZW50cwABBgkBAmFRAQIeZXhhY3RseSAxIHBheW1lbnQgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZk0FAmZNBAJmTAkBAmJkAQUCaGsEAmhhCQCRAwIIBQJlUwhwYXltZW50cwAABAJmaAgFAmhhB2Fzc2V0SWQEAmZ0CAUCaGEGYW1vdW50BAJlegkBAmVzAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJlegUCZXoEAmFiCAUCZVMGY2FsbGVyBAJhYwgFAmVTDXRyYW5zYWN0aW9uSWQEAmhtCQECZksFBQJmTAUCZnQFAmZoBQJhYgUCYWMDCQAAAgUCaG0FAmhtBAJmTggFAmhtAl81BAJoYwgFAmhtAl80BAJmZQgFAmhtAl8zBAJlbAgFAmhtAl8yBAJobggFAmhtAl8xBAJiVwMDCQBmAgUCZ1cAAAkAZgIFAmdXBQJobgcJAQJhUQEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZ1cFA25pbAIABQJobgQCaG8JAPwHBAUCYVQCBGJ1cm4JAMwIAgUCZnQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZmgFAmZ0BQNuaWwDCQAAAgUCaG8FAmhvBAJnQwkBAmNIAgUCaGsJAGQCBQJiVwkAlgMBCQDMCAIAAAkAzAgCBQJmZQUDbmlsBAJocAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhYgUCYlcFAmZMBQNuaWwEAmhnAwkAZgIFAmZlAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYVUFAmZlBQJmTAUDbmlsBQNuaWwEAmhxBAJocgMJAAACBQR0aGlzBQJhVQAABQJmZQMFAmZOCQCUCgIJAQEtAQkAZAIFAmJXBQJocgAACQCUCgIAAAkBAS0BCQBkAgUCYlcFAmhyBAJlQggFAmhxAl8xBAJlQwgFAmhxAl8yBAJocwkBAmVBAwUCZUIFAmVDAAAEAmdSCAUCaHMCXzEEAmVyCAUCaHMCXzIEAmdTCQECZUUCBQJlegUCZXIDCQAAAgUCZ1MFAmdTCQCUCgIJAM4IAgkAzggCCQDOCAIJAM4IAgUCZWwFAmdDBQJocAUCaGcFAmdSBQJiVwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJlUwERZ2V0T25lVGtuUkVBRE9OTFkCAmZMAmZ0BAJodAkBAmZLBQkBAmJkAQUCZkwFAmZ0BQJibQUEdW5pdAUEdW5pdAQCaG4IBQJodAJfMQQCZWwIBQJodAJfMgQCZmUIBQJodAJfMwQCaGMIBQJodAJfNAQCZk4IBQJodAJfNQkAlAoCBQNuaWwJAJUKAwUCaG4FAmZlBQJoYwJlUwETdW5zdGFrZUFuZEdldE9uZVRrbgMCaHUCaGsCZ1cEAmdZCgACYVcJAPwHBAUCYVQCKGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJhVwIHQm9vbGVhbgUCYVcJAAIBCQCsAgIJAAMBBQJhVwIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCaGwDAwkBAmFZAAYJAAACBQJibAUBbgYFAmdZBAJmTQkAzAgCAwMJAQEhAQUCaGwGCQECZ2gBBQJlUwYJAQJhUQECIWdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmVTCHBheW1lbnRzAAAGCQECYVEBAhhubyBwYXltZW50cyBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJmTQUCZk0EAmZMCQECYmQBBQJoawQCYWIIBQJlUwZjYWxsZXIEAmFjCAUCZVMNdHJhbnNhY3Rpb25JZAQCZXoJAQJlcwMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZXoFAmV6BAJodgkA/AcEBQJicwIHdW5zdGFrZQkAzAgCCQDYBAEFAmJtCQDMCAIFAmh1BQNuaWwFA25pbAMJAAACBQJodgUCaHYEAmh3CQECZksFBQJmTAUCaHUFAmJtBQJhYgUCYWMDCQAAAgUCaHcFAmh3BAJmTggFAmh3Al81BAJoYwgFAmh3Al80BAJmZQgFAmh3Al8zBAJlbAgFAmh3Al8yBAJobggFAmh3Al8xBAJiVwMDCQBmAgUCZ1cAAAkAZgIFAmdXBQJobgcJAQJhUQEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZ1cFA25pbAIABQJobgQCaG8JAPwHBAUCYVQCBGJ1cm4JAMwIAgUCaHUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYm0FAmh1BQNuaWwDCQAAAgUCaG8FAmhvBAJnQwkBAmNIAgUCaGsJAGQCBQJiVwkAlgMBCQDMCAIAAAkAzAgCBQJmZQUDbmlsBAJocAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZVMGY2FsbGVyBQJiVwUCZkwFA25pbAQCaGcDCQBmAgUCZmUAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhVQUCZmUFAmZMBQNuaWwFA25pbAQCaHgEAmhyAwkAAAIFBHRoaXMFAmFVAAAFAmZlAwUCZk4JAJQKAgkBAS0BCQBkAgUCYlcFAmhyAAAJAJQKAgAACQEBLQEJAGQCBQJiVwUCaHIEAmVCCAUCaHgCXzEEAmVDCAUCaHgCXzIEAmh5CQECZUEDBQJlQgUCZUMAAAQCZ1IIBQJoeQJfMQQCZXIIBQJoeQJfMgQCZ1MJAQJlRQIFAmV6BQJlcgMJAAACBQJnUwUCZ1MJAJQKAgkAzggCCQDOCAIJAM4IAgkAzggCBQJlbAUCZ0MFAmhwBQJoZwUCZ1IFAmJXCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmVTAQNnZXQABAJkVwkBAmVSAQUCZVMEAmRDCAUCZFcCXzEEAmRECAUCZFcCXzIEAmVVCAUCZFcCXzMEAmRsCAUCZFcCXzQEAmRFCAUCZFcCXzUEAmdDCQECY00CBQJkQwUCZEQEAmV6CQECZXMDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmV6BQJlegQCaHoJAPwHBAUCYVQCBGJ1cm4JAMwIAgUCZVUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZGwFAmVVBQNuaWwDCQAAAgUCaHoFAmh6BAJoQQkBAmVBAwkBAS0BBQJkQwkBAS0BBQJkRAAABAJnUggFAmhBAl8xBAJlcggFAmhBAl8yBAJnUwkBAmVFAgUCZXoFAmVyAwkAAAIFAmdTBQJnUwkAzggCCQDOCAIFAmdDBQJkRQUCZ1IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZVMBCWdldE5vTGVzcwICaEICaEMEAmRXCQECZVIBBQJlUwQCZEMIBQJkVwJfMQQCZEQIBQJkVwJfMgQCZVUIBQJkVwJfMwQCZGwIBQJkVwJfNAQCZEUIBQJkVwJfNQMJAGYCBQJoQgUCZEMJAAIBCQCsAgIJAKwCAgkArAICAhxub0xlc3NUaGVuQW10QXNzZXQgZmFpbGVkOiAgCQCkAwEFAmRDAgMgPCAJAKQDAQUCaEIDCQBmAgUCaEMFAmRECQACAQkArAICCQCsAgIJAKwCAgIdbm9MZXNzVGhlblByaWNlQXNzZXQgZmFpbGVkOiAJAKQDAQUCZEQCAyA8IAkApAMBBQJoQwQCZ0MJAQJjTQIFAmRDBQJkRAQCZXoJAQJlcwMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZXoFAmV6BAJoegkA/AcEBQJhVAIEYnVybgkAzAgCBQJlVQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJkbAUCZVUFA25pbAMJAAACBQJoegUCaHoEAmhECQECZUEDCQEBLQEFAmRDCQEBLQEFAmREAAAEAmdSCAUCaEQCXzEEAmVyCAUCaEQCXzIEAmdTCQECZUUCBQJlegUCZXIDCQAAAgUCZ1MFAmdTCQDOCAIJAM4IAgUCZ0MFAmRFBQJnUgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJlUwENdW5zdGFrZUFuZEdldAECYlcEAmhFAwkBAiE9AgkAkAMBCAUCZVMIcGF5bWVudHMAAAkAAgECGE5vIHBheW1lbnRzIGFyZSBleHBlY3RlZAYDCQAAAgUCaEUFAmhFBAJkYQkBAmJhAAQCZG4JANkEAQkAkQMCBQJkYQUBcQQCZXoJAQJlcwMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZXoFAmV6BAJodgkA/AcEBQJicwIHdW5zdGFrZQkAzAgCCQDYBAEFAmRuCQDMCAIFAmJXBQNuaWwFA25pbAMJAAACBQJodgUCaHYEAmRXCQECZGoECQDYBAEIBQJlUw10cmFuc2FjdGlvbklkCQDYBAEFAmRuBQJiVwgFAmVTBmNhbGxlcgQCZEMIBQJkVwJfMQQCZEQIBQJkVwJfMgQCZHEJAQ1wYXJzZUludFZhbHVlAQgFAmRXAl85BAJkRQgFAmRXA18xMAQCZ0MJAQJjTQIFAmRDBQJkRAQCaEYDAwkBAmFZAAYJAAACBQJkcQUBbgkAAgEJAKwCAgIsR2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCZHEGAwkAAAIFAmhGBQJoRgQCaHoJAPwHBAUCYVQCBGJ1cm4JAMwIAgUCYlcFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZG4FAmJXBQNuaWwDCQAAAgUCaHoFAmh6BAJoRwkBAmVBAwkBAS0BBQJkQwkBAS0BBQJkRAAABAJnUggFAmhHAl8xBAJlcggFAmhHAl8yBAJnUwkBAmVFAgUCZXoFAmVyAwkAAAIFAmdTBQJnUwkAzggCCQDOCAIFAmdDBQJkRQUCZ1IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZVMBE3Vuc3Rha2VBbmRHZXROb0xlc3MDAmh1AmhIAmhDBAJobAMJAQJhWQAGCQAAAgUCYmwFAW4EAmZNCQDMCAIDCQEBIQEFAmhsBgkAAgECIWdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmVTCHBheW1lbnRzAAAGCQACAQIYbm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZk0FAmZNBAJlegkBAmVzAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJlegUCZXoEAmh2CQD8BwQFAmJzAgd1bnN0YWtlCQDMCAIJANgEAQUCYm0JAMwIAgUCaHUFA25pbAUDbmlsAwkAAAIFAmh2BQJodgQCZFcJAQJkagQJANgEAQgFAmVTDXRyYW5zYWN0aW9uSWQJANgEAQUCYm0FAmh1CAUCZVMGY2FsbGVyBAJkQwgFAmRXAl8xBAJkRAgFAmRXAl8yBAJkRQgFAmRXA18xMAQCZ0MJAQJjTQIFAmRDBQJkRAQCaEkJAMwIAgMJAGcCBQJkQwUCaEgGCQACAQkAuQkCCQDMCAICLGFtb3VudCBhc3NldCBhbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCaEgFA25pbAIACQDMCAIDCQBnAgUCZEQFAmhDBgkAAgEJALkJAgkAzAgCAitwcmljZSBhc3NldCBhbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCaEMFA25pbAIABQNuaWwDCQAAAgUCaEkFAmhJBAJoegkA/AcEBQJhVAIEYnVybgkAzAgCBQJodQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJibQUCaHUFA25pbAMJAAACBQJoegUCaHoEAmhKCQECZUEDCQEBLQEFAmRDCQEBLQEFAmREAAAEAmdSCAUCaEoCXzEEAmVyCAUCaEoCXzIEAmdTCQECZUUCBQJlegUCZXIDCQAAAgUCZ1MFAmdTCQDOCAIJAM4IAgUCZ0MFAmRFBQJnUgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJlUwEIYWN0aXZhdGUCAmhLAmhMAwkBAiE9AgkApQgBCAUCZVMGY2FsbGVyCQClCAEFAmFUCQACAQIScGVybWlzc2lvbnMgZGVuaWVkCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFlAAUCaEsJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFmAAUCaEwFA25pbAIHc3VjY2VzcwJlUwEKcmVmcmVzaEtMcAAEAmhNCQELdmFsdWVPckVsc2UCCQCfCAEFAmFrAAAEAmhOAwkAZwIJAGUCBQZoZWlnaHQFAmhNBQJhbgUEdW5pdAkBAmFRAQkAuQkCCQDMCAIJAKQDAQUCYW4JAMwIAgIvIGJsb2NrcyBoYXZlIG5vdCBwYXNzZWQgc2luY2UgdGhlIHByZXZpb3VzIGNhbGwFA25pbAIAAwkAAAIFAmhOBQJoTgQCZUwJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAqAMBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAmFqAgEwCQECYVMBAgtpbnZhbGlkIGtMcAQCaE8JAQJlQQMAAAAAAAAEAmhQCAUCaE8CXzEEAmVyCAUCaE8CXzIEAmVEAwkBAiE9AgUCZUwFAmVyBQJoUAkBAmFRAQISbm90aGluZyB0byByZWZyZXNoCQCUCgIFAmVECQCmAwEFAmVyCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmVTARxnZXRQb29sQ29uZmlnV3JhcHBlclJFQURPTkxZAAkAlAoCBQNuaWwJAQJiYQACZVMBHGdldEFjY0JhbGFuY2VXcmFwcGVyUkVBRE9OTFkBAmFwCQCUCgIFA25pbAkBAmJKAQUCYXACZVMBGWNhbGNQcmljZXNXcmFwcGVyUkVBRE9OTFkDAmNVAmNWAmNaBAJkaQkBAmNZAwUCY1UFAmNWBQJjWgkAlAoCBQNuaWwJAMwIAgkApgMBCQCRAwIFAmRpAAAJAMwIAgkApgMBCQCRAwIFAmRpAAEJAMwIAgkApgMBCQCRAwIFAmRpAAIFA25pbAJlUwEUdG9YMThXcmFwcGVyUkVBRE9OTFkCAUUBRgkAlAoCBQNuaWwJAKYDAQkBAUQCBQFFBQFGAmVTARZmcm9tWDE4V3JhcHBlclJFQURPTkxZAgFJAUoJAJQKAgUDbmlsCQEBSAIJAKcDAQUBSQUBSgJlUwEeY2FsY1ByaWNlQmlnSW50V3JhcHBlclJFQURPTkxZAgJiTgJiTwkAlAoCBQNuaWwJAKYDAQkBAmJNAgkApwMBBQJiTgkApwMBBQJiTwJlUwEjZXN0aW1hdGVQdXRPcGVyYXRpb25XcmFwcGVyUkVBRE9OTFkJAmRrAmRHAmRIAmRJAmRKAmRLAmFiAmRMAmRNCQCUCgIFA25pbAkBAmRGCQUCZGsFAmRHBQJkSAUCZEkFAmRKBQJkSwUCYWIFAmRMBQJkTQJlUwEjZXN0aW1hdGVHZXRPcGVyYXRpb25XcmFwcGVyUkVBRE9OTFkEAmRrAmRsAmRtAmFiBAJkVwkBAmRqBAUCZGsFAmRsBQJkbQkBEUBleHRyTmF0aXZlKDEwNjIpAQUCYWIJAJQKAgUDbmlsCQCcCgoIBQJkVwJfMQgFAmRXAl8yCAUCZFcCXzMIBQJkVwJfNAgFAmRXAl81CAUCZFcCXzYIBQJkVwJfNwkApgMBCAUCZFcCXzgIBQJkVwJfOQgFAmRXA18xMAJlUwENc3RhdHNSRUFET05MWQAEAmRhCQECYmEABAJkbgkA2QQBCQCRAwIFAmRhBQFxBAJoUQkAkQMCBQJkYQUBcgQCaFIJAJEDAgUCZGEFAXMEAmRQCQCRAwIFAmRhBQF2BAJkUQkAkQMCBQJkYQUBdwQCZGIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkYQUBdAQCZGMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkYQUBdQQCaFMICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCZG4JAKwCAgkArAICAgZBc3NldCAJANgEAQUCZG4CDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJoVAkBAmJKAQUCaFEEAmhVCQECYkoBBQJoUgQCaFYDCQAAAgUCaFMAAAkAzAgCBQFlCQDMCAIFAWUJAMwIAgUBZQUDbmlsCQECY1kDBQJoVAUCaFUFAmhTBAJkeAAABAJoVwkBAUgCCQCRAwIFAmhWAAEFAWIEAmhYCQEBSAIJAJEDAgUCaFYAAgUBYgQCaFkJAQV2YWx1ZQEJAJoIAgUCYVQJAQJhRAEJAKUIAQUEdGhpcwkAlAoCBQNuaWwJALkJAgkAzAgCAg4lZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmhUCQDMCAIJAKQDAQUCaFUJAMwIAgkApAMBBQJoUwkAzAgCCQCkAwEFAmR4CQDMCAIJAKQDAQUCaFcJAMwIAgkApAMBBQJoWAkAzAgCCQCkAwEFAmhZBQNuaWwFAWoCZVMBIGV2YWx1YXRlUHV0QnlBbW91bnRBc3NldFJFQURPTkxZAQJkSAQCZGEJAQJiYQAEAmRuCQDZBAEJAJEDAgUCZGEFAXEEAmROCQCRAwIFAmRhBQFyBAJkbwkA2QQBBQJkTgQCZE8JAJEDAgUCZGEFAXMEAmRwCQDZBAEFAmRPBAJkYgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRhBQF0BAJkYwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRhBQF1BAJkcQkAkQMCBQJkYQUBcAQCaFMICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCZG4JAKwCAgkArAICAgZBc3NldCAJANgEAQUCZG4CDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJoVAkBAmJKAQUCZE4EAmhVCQECYkoBBQJkTwQCY1cJAQFEAgUCaFQFAmRiBAJjWAkBAUQCBQJoVQUCZGMEAmR3AwkAAAIFAmhTAAAFAWUJAQJiTQIFAmNYBQJjVwQCZFQJAQFEAgUCZEgFAmRiBAJkVQkAvAIDBQJkVAUCZHcFAWQEAmRKCQEBSAIFAmRVBQJkYwQCZVkJAQJkRgkCAACgwh4FAmRIBQJkbwUCZEoFAmRwAgAGBwQCZWUIBQJlWQJfMQQCaFoIBQJlWQJfMwQCZHMIBQJlWQJfNAQCZHUIBQJlWQJfNQQCZHIIBQJlWQJfNgkAlAoCBQNuaWwJALkJAgkAzAgCAhAlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCZWUJAMwIAgkApAMBCQEBSAIFAmR3BQFiCQDMCAIJAKQDAQUCZHMJAMwIAgkApAMBBQJkdQkAzAgCCQCkAwEFAmRyCQDMCAIFAmRxCQDMCAIJAKQDAQUCZEgJAMwIAgkApAMBBQJkSgUDbmlsBQFqAmVTAR9ldmFsdWF0ZVB1dEJ5UHJpY2VBc3NldFJFQURPTkxZAQJkSgQCZGEJAQJiYQAEAmRuCQDZBAEJAJEDAgUCZGEFAXEEAmROCQCRAwIFAmRhBQFyBAJkbwkA2QQBBQJkTgQCZE8JAJEDAgUCZGEFAXMEAmRwCQDZBAEFAmRPBAJkYgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRhBQF0BAJkYwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRhBQF1BAJkcQkAkQMCBQJkYQUBcAQCaFMICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCZG4JAKwCAgkArAICAgZBc3NldCAJANgEAQUCZG4CDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJpYQkBAmJKAQUCZE4EAmliCQECYkoBBQJkTwQCaWMJAQFEAgUCaWEFAmRiBAJpZAkBAUQCBQJpYgUCZGMEAmR3AwkAAAIFAmhTAAAFAWUJAQJiTQIFAmlkBQJpYwQCZFUJAQFEAgUCZEoFAmRjBAJkVAkAvAIDBQJkVQUBZAUCZHcEAmRICQEBSAIFAmRUBQJkYgQCZVkJAQJkRgkCAACgwh4FAmRIBQJkbwUCZEoFAmRwAgAGBwQCZWUIBQJlWQJfMQQCaFoIBQJlWQJfMwQCZHMIBQJlWQJfNAQCZHUIBQJlWQJfNQQCZHIIBQJlWQJfNgkAlAoCBQNuaWwJALkJAgkAzAgCAhAlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCZWUJAMwIAgkApAMBCQEBSAIFAmR3BQFiCQDMCAIJAKQDAQUCZHMJAMwIAgkApAMBBQJkdQkAzAgCCQCkAwEFAmRyCQDMCAIFAmRxCQDMCAIJAKQDAQUCZEgJAMwIAgkApAMBBQJkSgUDbmlsBQFqAmVTARNldmFsdWF0ZUdldFJFQURPTkxZAgJpZQJpZgQCZFcJAQJkagQCAAUCaWUFAmlmBQR0aGlzBAJkQwgFAmRXAl8xBAJkRAgFAmRXAl8yBAJkcwgFAmRXAl81BAJkdQgFAmRXAl82BAJkcggFAmRXAl83BAJkeAgFAmRXAl84BAJkcQkBDXBhcnNlSW50VmFsdWUBCAUCZFcCXzkJAJQKAgUDbmlsCQC5CQIJAMwIAgIOJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJkQwkAzAgCCQCkAwEFAmRECQDMCAIJAKQDAQUCZHMJAMwIAgkApAMBBQJkdQkAzAgCCQCkAwEFAmRyCQDMCAIJAKYDAQUCZHgJAMwIAgkApAMBBQJkcQUDbmlsBQFqAQJpZwECaWgABAJpaQQCYlQJAQJnZQADCQABAgUCYlQCCkJ5dGVWZWN0b3IEAmdpBQJiVAUCZ2kDCQABAgUCYlQCBFVuaXQIBQJpZw9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgQCYlQFAmlnAwkAAQIFAmJUAgVPcmRlcgQCZUgFAmJUBAJpagkBAmFaAAQCaWsJAQJlRwEFAmVIBAJhSQgFAmlrAl8xBAJhSggFAmlrAl8yBAJhSwkA9AMDCAUCZUgJYm9keUJ5dGVzCQCRAwIIBQJlSAZwcm9vZnMAAAgFAmVID3NlbmRlclB1YmxpY0tleQQCYUwJAPQDAwgFAmVICWJvZHlCeXRlcwkAkQMCCAUCZUgGcHJvb2ZzAAEFAmlqAwMDBQJhSQUCYUsHBQJhTAcGCQECYUgEBQJhSQUCYUoFAmFLBQJhTAMJAAECBQJiVAIUU2V0U2NyaXB0VHJhbnNhY3Rpb24EAmdmBQJiVAMJAPQDAwgFAmlnCWJvZHlCeXRlcwkAkQMCCAUCaWcGcHJvb2ZzAAAFAmlpBgQCaWwJAPYDAQkBBXZhbHVlAQgFAmdmBnNjcmlwdAQCaW0JANsEAQkBBXZhbHVlAQkAnQgCBQJhVAkBAmFGAAQCaW4JAPEHAQUEdGhpcwMJAAACBQJpbQUCaWwJAQIhPQIFAmluBQJpbAcJAPQDAwgFAmlnCWJvZHlCeXRlcwkAkQMCCAUCaWcGcHJvb2ZzAAAFAmlpjGbQ+w==", "height": 2532597, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: J7mTx3X91UE6wmHWuidw5nfwaXUQrdhXqF54XTD3zXpV Next: AqqgYF9sjbJ9NXDQEoine9C41MkEL6BbfN1bwNDdqtQS Diff:
OldNewDifferences
130130
131131 let kLpRefreshDelay = valueOrElse(getInteger(this, keyKLpRefreshDelay), kLpRefreshDelayDefault)
132132
133+func keyAdditionalBalance (assetId) = makeString(["%s%s", "stakedBalance", assetId], SEP)
134+
135+
136+func keyStakingAssetBalance (assetId) = makeString(["%s%s", "shareAssetBalance", assetId], SEP)
137+
138+
139+func getAdditionalBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyAdditionalBalance(assetId)), 0)
140+
141+
142+func getStakingAssetBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyStakingAssetBalance(assetId)), 0)
143+
144+
133145 func keyFactoryConfig () = "%s__factoryConfig"
134146
135147
219231
220232 let poolConfigParsed = parsePoolConfig(getPoolConfig())
221233
222-let $t084698635 = poolConfigParsed
234+let $t089629128 = poolConfigParsed
223235
224-let cfgPoolAddress = $t084698635._1
236+let cfgPoolAddress = $t089629128._1
225237
226-let cfgPoolStatus = $t084698635._2
238+let cfgPoolStatus = $t089629128._2
227239
228-let cfgLpAssetId = $t084698635._3
240+let cfgLpAssetId = $t089629128._3
229241
230-let cfgAmountAssetId = $t084698635._4
242+let cfgAmountAssetId = $t089629128._4
231243
232-let cfgPriceAssetId = $t084698635._5
244+let cfgPriceAssetId = $t089629128._5
233245
234-let cfgAmountAssetDecimals = $t084698635._6
246+let cfgAmountAssetDecimals = $t089629128._6
235247
236-let cfgPriceAssetDecimals = $t084698635._7
248+let cfgPriceAssetDecimals = $t089629128._7
237249
238250 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
239251
248260 func dataGetActionInfo (outAmtAssetAmt,outPriceAssetAmt,inLpAmt,price,txHeight,txTimestamp) = makeString(["%d%d%d%d%d%d", toString(outAmtAssetAmt), toString(outPriceAssetAmt), toString(inLpAmt), toString(price), toString(txHeight), toString(txTimestamp)], SEP)
249261
250262
251-func getAccBalance (assetId) = if ((assetId == "WAVES"))
252- then wavesBalance(this).available
253- else assetBalance(this, fromBase58String(assetId))
263+func getAccBalance (assetId) = {
264+ let balanceOnPool = if ((assetId == "WAVES"))
265+ then wavesBalance(this).available
266+ else assetBalance(this, fromBase58String(assetId))
267+ let totalBalance = ((balanceOnPool + getAdditionalBalanceOrZero(assetId)) - getStakingAssetBalanceOrZero(assetId))
268+ max([0, totalBalance])
269+ }
254270
255271
256272 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
257273
258274
259275 func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
276+
277+
278+func getRate (proxy) = {
279+ let inv = invoke(proxy, "getRate", nil, nil)
280+ if ((inv == inv))
281+ then match inv {
282+ case r: Int =>
283+ r
284+ case _ =>
285+ throwErr("proxy.getRate() unexpected value")
286+ }
287+ else throw("Strict value is not equal to itself.")
288+ }
289+
290+
291+func deposit (assetId,amount,stakingAssetId,proxy) = {
292+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
293+ if ((currentAdditionalBalance == currentAdditionalBalance))
294+ then {
295+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
296+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
297+ then {
298+ let asset = parseAssetId(assetId)
299+ if ((amount > 0))
300+ then {
301+ let depositInvoke = invoke(proxy, "deposit", nil, [AttachedPayment(asset, amount)])
302+ if ((depositInvoke == depositInvoke))
303+ then match depositInvoke {
304+ case receivedStakingAsset: Int =>
305+ let newAdditionalBalance = (currentAdditionalBalance + amount)
306+ let newStakingAssetBalance = (currentStakingAssetBalance + receivedStakingAsset)
307+[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance)]
308+ case _ =>
309+ nil
310+ }
311+ else throw("Strict value is not equal to itself.")
312+ }
313+ else nil
314+ }
315+ else throw("Strict value is not equal to itself.")
316+ }
317+ else throw("Strict value is not equal to itself.")
318+ }
319+
320+
321+func withdraw (assetId,amount,stakingAssetId,proxy,proxyRateMul,profitAddress) = {
322+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
323+ if ((currentAdditionalBalance == currentAdditionalBalance))
324+ then {
325+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
326+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
327+ then {
328+ let currentProxyRate = getRate(proxy)
329+ if ((currentProxyRate == currentProxyRate))
330+ then {
331+ let oldRate = fraction(proxyRateMul, currentAdditionalBalance, currentStakingAssetBalance)
332+ let stakingAsset = parseAssetId(stakingAssetId)
333+ let oldSendStakingAmount = fraction(proxyRateMul, amount, oldRate)
334+ let sendStakingAssetAmount = fraction(proxyRateMul, amount, currentProxyRate)
335+ let profitAmount = max([0, (oldSendStakingAmount - sendStakingAssetAmount)])
336+ if ((sendStakingAssetAmount > 0))
337+ then {
338+ let withdrawInvoke = invoke(proxy, "withdraw", nil, [AttachedPayment(stakingAsset, sendStakingAssetAmount)])
339+ if ((withdrawInvoke == withdrawInvoke))
340+ then match withdrawInvoke {
341+ case receivedAssets: Int =>
342+ let newAdditionalBalance = (currentAdditionalBalance - receivedAssets)
343+ let newStakingAssetBalance = ((currentStakingAssetBalance - sendStakingAssetAmount) - profitAmount)
344+[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance), ScriptTransfer(profitAddress, profitAmount, parseAssetId(stakingAssetId))]
345+ case _ =>
346+ nil
347+ }
348+ else throw("Strict value is not equal to itself.")
349+ }
350+ else nil
351+ }
352+ else throw("Strict value is not equal to itself.")
353+ }
354+ else throw("Strict value is not equal to itself.")
355+ }
356+ else throw("Strict value is not equal to itself.")
357+ }
358+
359+
360+func getLeaseProxyConfig (assetId) = match invoke(factoryContract, "getPoolLeaseConfigREADONLY", [toString(this), assetId], nil) {
361+ case a: (Boolean, Int, Int, String, String, Int, String) =>
362+ a
363+ case _ =>
364+ throwErr((("[" + assetId) + "] getLeaseProxyConfig() error"))
365+}
366+
367+
368+func rebalanceInternal (targetRatio,assetId,stakingAssetId,minBalance,proxy,proxyRateMul,profitAddress) = {
369+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
370+ if ((currentAdditionalBalance == currentAdditionalBalance))
371+ then {
372+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
373+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
374+ then {
375+ let leasableTotalBalance = max([0, (getAccBalance(assetId) - minBalance)])
376+ let targetAdditionalBalance = fraction(targetRatio, leasableTotalBalance, 100)
377+ let diff = (currentAdditionalBalance - targetAdditionalBalance)
378+ if ((diff == 0))
379+ then nil
380+ else if ((0 > diff))
381+ then {
382+ let sendAssetAmount = -(diff)
383+ deposit(assetId, sendAssetAmount, stakingAssetId, proxy)
384+ }
385+ else {
386+ let getAssetAmount = diff
387+ withdraw(assetId, getAssetAmount, stakingAssetId, proxy, proxyRateMul, profitAddress)
388+ }
389+ }
390+ else throw("Strict value is not equal to itself.")
391+ }
392+ else throw("Strict value is not equal to itself.")
393+ }
394+
395+
396+func rebalanceAsset (assetId) = {
397+ let $t01536415500 = getLeaseProxyConfig(assetId)
398+ let isLeasable = $t01536415500._1
399+ let leasedRatio = $t01536415500._2
400+ let minBalance = $t01536415500._3
401+ let proxyAddress = $t01536415500._4
402+ let proxyAssetId = $t01536415500._5
403+ let proxyRateMul = $t01536415500._6
404+ let stakingProfitAddress = $t01536415500._7
405+ if (isLeasable)
406+ then rebalanceInternal(leasedRatio, assetId, proxyAssetId, minBalance, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
407+ else nil
408+ }
409+
410+
411+func withdrawAndRebalanceAsset (assetId,getAmount) = {
412+ let $t01589116027 = getLeaseProxyConfig(assetId)
413+ let isLeasable = $t01589116027._1
414+ let leasedRatio = $t01589116027._2
415+ let minBalance = $t01589116027._3
416+ let proxyAddress = $t01589116027._4
417+ let proxyAssetId = $t01589116027._5
418+ let proxyRateMul = $t01589116027._6
419+ let stakingProfitAddress = $t01589116027._7
420+ if (isLeasable)
421+ then {
422+ let newTotalLeasableBalance = max([0, ((getAccBalance(assetId) - getAmount) - minBalance)])
423+ if ((newTotalLeasableBalance == newTotalLeasableBalance))
424+ then {
425+ let newAdditionalBalance = fraction(leasedRatio, newTotalLeasableBalance, 100)
426+ if ((newAdditionalBalance == newAdditionalBalance))
427+ then {
428+ let withdrawAmount = max([0, (getAdditionalBalanceOrZero(assetId) - newAdditionalBalance)])
429+ if ((withdrawAmount == withdrawAmount))
430+ then withdraw(assetId, withdrawAmount, proxyAssetId, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
431+ else throw("Strict value is not equal to itself.")
432+ }
433+ else throw("Strict value is not equal to itself.")
434+ }
435+ else throw("Strict value is not equal to itself.")
436+ }
437+ else nil
438+ }
439+
440+
441+func withdrawAndRebalanceAll (amountAssetOutAmount,priceAssetOutAmount) = {
442+ let AmAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, aa()), amountAssetOutAmount)
443+ let PrAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, pa()), priceAssetOutAmount)
444+ (AmAmtWithdrawState ++ PrAmtWithdrawState)
445+ }
260446
261447
262448 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
438624 let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
439625 let amountAssetAmount = order.amount
440626 let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
441- let $t02154121753 = if ((order.orderType == Buy))
627+ let $t02815528367 = if ((order.orderType == Buy))
442628 then $Tuple2(amountAssetAmount, -(priceAssetAmount))
443629 else $Tuple2(-(amountAssetAmount), priceAssetAmount)
444- let amountAssetBalanceDelta = $t02154121753._1
445- let priceAssetBalanceDelta = $t02154121753._2
630+ let amountAssetBalanceDelta = $t02815528367._1
631+ let priceAssetBalanceDelta = $t02815528367._2
446632 if (if (if (isGlobalShutdown())
447633 then true
448634 else (cfgPoolStatus == PoolMatcherDisabled))
455641 then throw("Wrong order assets.")
456642 else {
457643 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
458- let $t02219322293 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
459- let unusedActions = $t02219322293._1
460- let kLpNew = $t02219322293._2
644+ let $t02880728907 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
645+ let unusedActions = $t02880728907._1
646+ let kLpNew = $t02880728907._2
461647 let isOrderValid = (kLpNew >= kLp)
462648 let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
463649 $Tuple2(isOrderValid, info)
536722 else if ((paymentAssetId == cfgPriceAssetId))
537723 then false
538724 else throwErr("invalid asset")
539- let $t02540625699 = if (isEval)
725+ let $t03202032313 = if (isEval)
540726 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
541727 else if (paymentInAmountAsset)
542728 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
543729 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
544- let amountBalanceOld = $t02540625699._1
545- let priceBalanceOld = $t02540625699._2
546- let $t02570325852 = if (paymentInAmountAsset)
730+ let amountBalanceOld = $t03202032313._1
731+ let priceBalanceOld = $t03202032313._2
732+ let $t03231732466 = if (paymentInAmountAsset)
547733 then $Tuple2(paymentAmountRaw, 0)
548734 else $Tuple2(0, paymentAmountRaw)
549- let amountAssetAmountRaw = $t02570325852._1
550- let priceAssetAmountRaw = $t02570325852._2
735+ let amountAssetAmountRaw = $t03231732466._1
736+ let priceAssetAmountRaw = $t03231732466._2
551737 let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
552738 let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
553- let $t02598426048 = takeFee(paymentAmountRaw, inFee)
554- let paymentAmount = $t02598426048._1
555- let feeAmount = $t02598426048._2
739+ let $t03259832662 = takeFee(paymentAmountRaw, inFee)
740+ let paymentAmount = $t03259832662._1
741+ let feeAmount = $t03259832662._2
556742 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
557743 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
558744 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
575761 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
576762 let priceOld = fromX18(priceOldX18, scale8)
577763 let loss = {
578- let $t02772927896 = if (paymentInAmountAsset)
764+ let $t03434334510 = if (paymentInAmountAsset)
579765 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
580766 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
581- let amount = $t02772927896._1
582- let balance = $t02772927896._2
767+ let amount = $t03434334510._1
768+ let balance = $t03434334510._2
583769 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
584770 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
585771 }
619805 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
620806 let redeemedBigInt = toBigInt(paymentAmount)
621807 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
622- let $t02997430030 = takeFee(amountRaw, outFee)
623- let totalAmount = $t02997430030._1
624- let feeAmount = $t02997430030._2
625- let $t03003430260 = if (outInAmountAsset)
808+ let $t03658836644 = takeFee(amountRaw, outFee)
809+ let totalAmount = $t03658836644._1
810+ let feeAmount = $t03658836644._2
811+ let $t03664836874 = if (outInAmountAsset)
626812 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
627813 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
628- let outAmAmount = $t03003430260._1
629- let outPrAmount = $t03003430260._2
630- let amBalanceNew = $t03003430260._3
631- let prBalanceNew = $t03003430260._4
814+ let outAmAmount = $t03664836874._1
815+ let outPrAmount = $t03664836874._2
816+ let amBalanceNew = $t03664836874._3
817+ let prBalanceNew = $t03664836874._4
632818 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
633819 let priceNew = fromX18(priceNewX18, scale8)
634820 let commonState = if (isEval)
694880
695881
696882 @Callable(i)
883+func rebalance () = (rebalanceAsset(getStringOrFail(this, aa())) ++ rebalanceAsset(getStringOrFail(this, pa())))
884+
885+
886+
887+@Callable(i)
697888 func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse,feePoolAmount) = {
698- let $t03197732282 = if ((isReverse == false))
889+ let $t03876039065 = if ((isReverse == false))
699890 then {
700891 let assetOut = getStringOrFail(this, pa())
701892 let assetIn = getStringOrFail(this, aa())
706897 let assetIn = getStringOrFail(this, pa())
707898 $Tuple2(assetOut, assetIn)
708899 }
709- let assetOut = $t03197732282._1
710- let assetIn = $t03197732282._2
900+ let assetOut = $t03876039065._1
901+ let assetIn = $t03876039065._2
711902 let poolAssetInBalance = getAccBalance(assetIn)
712903 let poolAssetOutBalance = getAccBalance(assetOut)
713904 let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
757948 then true
758949 else throw("Exchange result is fewer coins than expected")
759950 if ((checkMin == checkMin))
760- then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))], amountOut)
951+ then {
952+ let rebalanceState = rebalanceAsset(assetIn)
953+ if ((rebalanceState == rebalanceState))
954+ then {
955+ let withdrawState = withdrawAndRebalanceAsset(assetOut, amountOut)
956+ if ((withdrawState == withdrawState))
957+ then $Tuple2(((withdrawState ++ rebalanceState) ++ [ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))]), amountOut)
958+ else throw("Strict value is not equal to itself.")
959+ }
960+ else throw("Strict value is not equal to itself.")
961+ }
761962 else throw("Strict value is not equal to itself.")
762963 }
763964 else throw("Strict value is not equal to itself.")
8481049 else throw("Strict value is not equal to itself.")
8491050 }
8501051 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
851- let $t03716637628 = refreshKLpInternal(0, 0, 0)
852- if (($t03716637628 == $t03716637628))
1052+ let $t04411144573 = refreshKLpInternal(0, 0, 0)
1053+ if (($t04411144573 == $t04411144573))
8531054 then {
854- let updatedKLp = $t03716637628._2
855- let refreshKLpActions = $t03716637628._1
1055+ let updatedKLp = $t04411144573._2
1056+ let refreshKLpActions = $t04411144573._1
8561057 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
8571058 if ((isUpdatedKLpValid == isUpdatedKLpValid))
858- then ((state ++ lpTransfer) ++ refreshKLpActions)
1059+ then {
1060+ let reb = invoke(this, "rebalance", nil, nil)
1061+ if ((reb == reb))
1062+ then ((state ++ lpTransfer) ++ refreshKLpActions)
1063+ else throw("Strict value is not equal to itself.")
1064+ }
8591065 else throw("Strict value is not equal to itself.")
8601066 }
8611067 else throw("Strict value is not equal to itself.")
8841090 let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
8851091 if ((currentKLp == currentKLp))
8861092 then {
887- let $t03819038255 = refreshKLpInternal(0, 0, 0)
888- let refreshKLpActions = $t03819038255._1
889- let updatedKLp = $t03819038255._2
1093+ let $t04518545250 = refreshKLpInternal(0, 0, 0)
1094+ let refreshKLpActions = $t04518545250._1
1095+ let updatedKLp = $t04518545250._2
8901096 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
8911097 if ((isUpdatedKLpValid == isUpdatedKLpValid))
8921098 then (state ++ refreshKLpActions)
9331139 then {
9341140 let userAddress = i.caller
9351141 let txId = i.transactionId
936- let $t03944339595 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
937- if (($t03944339595 == $t03944339595))
1142+ let $t04643846590 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
1143+ if (($t04643846590 == $t04643846590))
9381144 then {
939- let paymentInAmountAsset = $t03944339595._5
940- let bonus = $t03944339595._4
941- let feeAmount = $t03944339595._3
942- let commonState = $t03944339595._2
943- let emitAmountEstimated = $t03944339595._1
1145+ let paymentInAmountAsset = $t04643846590._5
1146+ let bonus = $t04643846590._4
1147+ let feeAmount = $t04643846590._3
1148+ let commonState = $t04643846590._2
1149+ let emitAmountEstimated = $t04643846590._1
9441150 let emitAmount = if (if ((minOutAmount > 0))
9451151 then (minOutAmount > emitAmountEstimated)
9461152 else false)
9601166 let sendFee = if ((feeAmount > 0))
9611167 then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
9621168 else nil
963- let $t04018140378 = if ((this == feeCollectorAddress))
1169+ let $t04717647373 = if ((this == feeCollectorAddress))
9641170 then $Tuple2(0, 0)
9651171 else if (paymentInAmountAsset)
9661172 then $Tuple2(-(feeAmount), 0)
9671173 else $Tuple2(0, -(feeAmount))
968- let amountAssetBalanceDelta = $t04018140378._1
969- let priceAssetBalanceDelta = $t04018140378._2
970- let $t04038140489 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
971- let refreshKLpActions = $t04038140489._1
972- let updatedKLp = $t04038140489._2
1174+ let amountAssetBalanceDelta = $t04717647373._1
1175+ let priceAssetBalanceDelta = $t04717647373._2
1176+ let $t04737647484 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1177+ let refreshKLpActions = $t04737647484._1
1178+ let updatedKLp = $t04737647484._2
9731179 let kLp = value(getString(keyKLp))
9741180 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
9751181 if ((isUpdatedKLpValid == isUpdatedKLpValid))
976- then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
1182+ then {
1183+ let reb = invoke(this, "rebalance", nil, nil)
1184+ if ((reb == reb))
1185+ then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
1186+ else throw("Strict value is not equal to itself.")
1187+ }
9771188 else throw("Strict value is not equal to itself.")
9781189 }
9791190 else throw("Strict value is not equal to itself.")
9891200
9901201 @Callable(i)
9911202 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
992- let $t04079540952 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
993- let emitAmountEstimated = $t04079540952._1
994- let commonState = $t04079540952._2
995- let feeAmount = $t04079540952._3
996- let bonus = $t04079540952._4
997- let paymentInAmountAsset = $t04079540952._5
1203+ let $t04783947996 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
1204+ let emitAmountEstimated = $t04783947996._1
1205+ let commonState = $t04783947996._2
1206+ let feeAmount = $t04783947996._3
1207+ let bonus = $t04783947996._4
1208+ let paymentInAmountAsset = $t04783947996._5
9981209 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
9991210 }
10001211
10311242 then {
10321243 let userAddress = i.caller
10331244 let txId = i.transactionId
1034- let $t04183741990 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1035- if (($t04183741990 == $t04183741990))
1245+ let $t04888149034 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1246+ if (($t04888149034 == $t04888149034))
10361247 then {
1037- let outInAmountAsset = $t04183741990._5
1038- let bonus = $t04183741990._4
1039- let feeAmount = $t04183741990._3
1040- let commonState = $t04183741990._2
1041- let amountEstimated = $t04183741990._1
1248+ let outInAmountAsset = $t04888149034._5
1249+ let bonus = $t04888149034._4
1250+ let feeAmount = $t04888149034._3
1251+ let commonState = $t04888149034._2
1252+ let amountEstimated = $t04888149034._1
10421253 let amount = if (if ((minOutAmount > 0))
10431254 then (minOutAmount > amountEstimated)
10441255 else false)
10471258 let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
10481259 if ((burnInv == burnInv))
10491260 then {
1261+ let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
10501262 let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
10511263 let sendFee = if ((feeAmount > 0))
10521264 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
10531265 else nil
1054- let $t04249042737 = {
1266+ let $t04969849945 = {
10551267 let feeAmountForCalc = if ((this == feeCollectorAddress))
10561268 then 0
10571269 else feeAmount
10591271 then $Tuple2(-((amount + feeAmountForCalc)), 0)
10601272 else $Tuple2(0, -((amount + feeAmountForCalc)))
10611273 }
1062- let amountAssetBalanceDelta = $t04249042737._1
1063- let priceAssetBalanceDelta = $t04249042737._2
1064- let $t04274042848 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1065- let refreshKLpActions = $t04274042848._1
1066- let updatedKLp = $t04274042848._2
1274+ let amountAssetBalanceDelta = $t04969849945._1
1275+ let priceAssetBalanceDelta = $t04969849945._2
1276+ let $t04994850056 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1277+ let refreshKLpActions = $t04994850056._1
1278+ let updatedKLp = $t04994850056._2
10671279 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
10681280 if ((isUpdatedKLpValid == isUpdatedKLpValid))
1069- then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1281+ then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
10701282 else throw("Strict value is not equal to itself.")
10711283 }
10721284 else throw("Strict value is not equal to itself.")
10821294
10831295 @Callable(i)
10841296 func getOneTknREADONLY (outAssetId,paymentAmount) = {
1085- let $t04310543261 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1086- let amountEstimated = $t04310543261._1
1087- let commonState = $t04310543261._2
1088- let feeAmount = $t04310543261._3
1089- let bonus = $t04310543261._4
1090- let outInAmountAsset = $t04310543261._5
1297+ let $t05033450490 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1298+ let amountEstimated = $t05033450490._1
1299+ let commonState = $t05033450490._2
1300+ let feeAmount = $t05033450490._3
1301+ let bonus = $t05033450490._4
1302+ let outInAmountAsset = $t05033450490._5
10911303 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
10921304 }
10931305
11241336 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
11251337 if ((unstakeInv == unstakeInv))
11261338 then {
1127- let $t04416644317 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1128- if (($t04416644317 == $t04416644317))
1339+ let $t05139551546 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1340+ if (($t05139551546 == $t05139551546))
11291341 then {
1130- let outInAmountAsset = $t04416644317._5
1131- let bonus = $t04416644317._4
1132- let feeAmount = $t04416644317._3
1133- let commonState = $t04416644317._2
1134- let amountEstimated = $t04416644317._1
1342+ let outInAmountAsset = $t05139551546._5
1343+ let bonus = $t05139551546._4
1344+ let feeAmount = $t05139551546._3
1345+ let commonState = $t05139551546._2
1346+ let amountEstimated = $t05139551546._1
11351347 let amount = if (if ((minOutAmount > 0))
11361348 then (minOutAmount > amountEstimated)
11371349 else false)
11401352 let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
11411353 if ((burnInv == burnInv))
11421354 then {
1355+ let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
11431356 let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
11441357 let sendFee = if ((feeAmount > 0))
11451358 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
11461359 else nil
1147- let $t04481245059 = {
1360+ let $t05220552452 = {
11481361 let feeAmountForCalc = if ((this == feeCollectorAddress))
11491362 then 0
11501363 else feeAmount
11521365 then $Tuple2(-((amount + feeAmountForCalc)), 0)
11531366 else $Tuple2(0, -((amount + feeAmountForCalc)))
11541367 }
1155- let amountAssetBalanceDelta = $t04481245059._1
1156- let priceAssetBalanceDelta = $t04481245059._2
1157- let $t04506245170 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1158- let refreshKLpActions = $t04506245170._1
1159- let updatedKLp = $t04506245170._2
1368+ let amountAssetBalanceDelta = $t05220552452._1
1369+ let priceAssetBalanceDelta = $t05220552452._2
1370+ let $t05245552563 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1371+ let refreshKLpActions = $t05245552563._1
1372+ let updatedKLp = $t05245552563._2
11601373 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11611374 if ((isUpdatedKLpValid == isUpdatedKLpValid))
1162- then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1375+ then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
11631376 else throw("Strict value is not equal to itself.")
11641377 }
11651378 else throw("Strict value is not equal to itself.")
11781391 @Callable(i)
11791392 func get () = {
11801393 let res = commonGet(i)
1181- let outAmtAmt = res._1
1394+ let outAmAmt = res._1
11821395 let outPrAmt = res._2
11831396 let pmtAmt = res._3
11841397 let pmtAssetId = res._4
11851398 let state = res._5
1399+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
11861400 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
11871401 if ((currentKLp == currentKLp))
11881402 then {
11891403 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
11901404 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11911405 then {
1192- let $t04611646198 = refreshKLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1193- let refreshKLpActions = $t04611646198._1
1194- let updatedKLp = $t04611646198._2
1406+ let $t05365853739 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1407+ let refreshKLpActions = $t05365853739._1
1408+ let updatedKLp = $t05365853739._2
11951409 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11961410 if ((isUpdatedKLpValid == isUpdatedKLpValid))
1197- then (state ++ refreshKLpActions)
1411+ then ((withdrawState ++ state) ++ refreshKLpActions)
11981412 else throw("Strict value is not equal to itself.")
11991413 }
12001414 else throw("Strict value is not equal to itself.")
12171431 else if ((noLessThenPriceAsset > outPrAmt))
12181432 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
12191433 else {
1434+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
12201435 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
12211436 if ((currentKLp == currentKLp))
12221437 then {
12231438 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
12241439 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
12251440 then {
1226- let $t04714747228 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1227- let refreshKLpActions = $t04714747228._1
1228- let updatedKLp = $t04714747228._2
1441+ let $t05483454915 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1442+ let refreshKLpActions = $t05483454915._1
1443+ let updatedKLp = $t05483454915._2
12291444 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
12301445 if ((isUpdatedKLpValid == isUpdatedKLpValid))
1231- then (state ++ refreshKLpActions)
1446+ then ((withdrawState ++ state) ++ refreshKLpActions)
12321447 else throw("Strict value is not equal to itself.")
12331448 }
12341449 else throw("Strict value is not equal to itself.")
12591474 let outPrAmt = res._2
12601475 let poolStatus = parseIntValue(res._9)
12611476 let state = res._10
1477+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
12621478 let checkPoolStatus = if (if (isGlobalShutdown())
12631479 then true
12641480 else (poolStatus == PoolShutdown))
12691485 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
12701486 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
12711487 then {
1272- let $t04835448435 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1273- let refreshKLpActions = $t04835448435._1
1274- let updatedKLp = $t04835448435._2
1488+ let $t05618756268 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1489+ let refreshKLpActions = $t05618756268._1
1490+ let updatedKLp = $t05618756268._2
12751491 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
12761492 if ((isUpdatedKLpValid == isUpdatedKLpValid))
1277- then (state ++ refreshKLpActions)
1493+ then ((withdrawState ++ state) ++ refreshKLpActions)
12781494 else throw("Strict value is not equal to itself.")
12791495 }
12801496 else throw("Strict value is not equal to itself.")
13121528 let outAmAmt = res._1
13131529 let outPrAmt = res._2
13141530 let state = res._10
1531+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
13151532 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
13161533 then true
13171534 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
13221539 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
13231540 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
13241541 then {
1325- let $t04973049811 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1326- let refreshKLpActions = $t04973049811._1
1327- let updatedKLp = $t04973049811._2
1542+ let $t05770957790 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1543+ let refreshKLpActions = $t05770957790._1
1544+ let updatedKLp = $t05770957790._2
13281545 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
13291546 if ((isUpdatedKLpValid == isUpdatedKLpValid))
1330- then (state ++ refreshKLpActions)
1547+ then ((withdrawState ++ state) ++ refreshKLpActions)
13311548 else throw("Strict value is not equal to itself.")
13321549 }
13331550 else throw("Strict value is not equal to itself.")
13591576 if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
13601577 then {
13611578 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1362- let $t05099851062 = refreshKLpInternal(0, 0, 0)
1363- let kLpUpdateActions = $t05099851062._1
1364- let updatedKLp = $t05099851062._2
1579+ let $t05899459058 = refreshKLpInternal(0, 0, 0)
1580+ let kLpUpdateActions = $t05899459058._1
1581+ let updatedKLp = $t05899459058._2
13651582 let actions = if ((kLp != updatedKLp))
13661583 then kLpUpdateActions
13671584 else throwErr("nothing to refresh")
15361753 match tx {
15371754 case order: Order =>
15381755 let matcherPub = getMatcherPubOrFail()
1539- let $t05972459793 = validateMatcherOrderAllowed(order)
1540- let orderValid = $t05972459793._1
1541- let orderValidInfo = $t05972459793._2
1756+ let $t06772067789 = validateMatcherOrderAllowed(order)
1757+ let orderValid = $t06772067789._1
1758+ let orderValidInfo = $t06772067789._2
15421759 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
15431760 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
15441761 if (if (if (orderValid)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let lPdecimals = 8
55
66 let scale8 = 100000000
77
88 let scale8BigInt = toBigInt(100000000)
99
1010 let scale18 = toBigInt(1000000000000000000)
1111
1212 let zeroBigInt = toBigInt(0)
1313
1414 let big0 = toBigInt(0)
1515
1616 let big1 = toBigInt(1)
1717
1818 let big2 = toBigInt(2)
1919
2020 let wavesString = "WAVES"
2121
2222 let SEP = "__"
2323
2424 let PoolActive = 1
2525
2626 let PoolPutDisabled = 2
2727
2828 let PoolMatcherDisabled = 3
2929
3030 let PoolShutdown = 4
3131
3232 let idxPoolAddress = 1
3333
3434 let idxPoolStatus = 2
3535
3636 let idxPoolLPAssetId = 3
3737
3838 let idxAmtAssetId = 4
3939
4040 let idxPriceAssetId = 5
4141
4242 let idxAmtAssetDcm = 6
4343
4444 let idxPriceAssetDcm = 7
4545
4646 let idxIAmtAssetId = 8
4747
4848 let idxIPriceAssetId = 9
4949
5050 let idxLPAssetDcm = 10
5151
5252 let idxPoolAmtAssetAmt = 1
5353
5454 let idxPoolPriceAssetAmt = 2
5555
5656 let idxPoolLPAssetAmt = 3
5757
5858 let idxFactoryStakingContract = 1
5959
6060 let idxFactorySlippageContract = 7
6161
6262 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
6363
6464
6565 func toX18BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
6666
6767
6868 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
6969
7070
7171 func fromX18Round (val,resultScaleMult,round) = toInt(fraction(val, toBigInt(resultScaleMult), scale18, round))
7272
7373
7474 func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
7575
7676
7777 func abs (val) = if ((0 > val))
7878 then -(val)
7979 else val
8080
8181
8282 func absBigInt (val) = if ((zeroBigInt > val))
8383 then -(val)
8484 else val
8585
8686
8787 func swapContract () = "%s__swapContract"
8888
8989
9090 func fc () = "%s__factoryContract"
9191
9292
9393 func mpk () = "%s__managerPublicKey"
9494
9595
9696 func pmpk () = "%s__pendingManagerPublicKey"
9797
9898
9999 func pl () = "%s%s__price__last"
100100
101101
102102 func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
103103
104104
105105 func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
106106
107107
108108 func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
109109
110110
111111 func aa () = "%s__amountAsset"
112112
113113
114114 func pa () = "%s__priceAsset"
115115
116116
117117 let keyFee = "%s__fee"
118118
119119 let feeDefault = fraction(10, scale8, 10000)
120120
121121 let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
122122
123123 let keyKLp = makeString(["%s", "kLp"], SEP)
124124
125125 let keyKLpRefreshedHeight = makeString(["%s", "kLpRefreshedHeight"], SEP)
126126
127127 let keyKLpRefreshDelay = makeString(["%s", "refreshKLpDelay"], SEP)
128128
129129 let kLpRefreshDelayDefault = 30
130130
131131 let kLpRefreshDelay = valueOrElse(getInteger(this, keyKLpRefreshDelay), kLpRefreshDelayDefault)
132132
133+func keyAdditionalBalance (assetId) = makeString(["%s%s", "stakedBalance", assetId], SEP)
134+
135+
136+func keyStakingAssetBalance (assetId) = makeString(["%s%s", "shareAssetBalance", assetId], SEP)
137+
138+
139+func getAdditionalBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyAdditionalBalance(assetId)), 0)
140+
141+
142+func getStakingAssetBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyStakingAssetBalance(assetId)), 0)
143+
144+
133145 func keyFactoryConfig () = "%s__factoryConfig"
134146
135147
136148 func keyMatcherPub () = "%s%s__matcher__publicKey"
137149
138150
139151 func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
140152
141153
142154 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
143155
144156
145157 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
146158
147159
148160 func keyAllPoolsShutdown () = "%s__shutdown"
149161
150162
151163 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
152164
153165
154166 func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
155167
156168
157169 let keyFeeCollectorAddress = "%s__feeCollectorAddress"
158170
159171 func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
160172
161173
162174 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
163175
164176
165177 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
166178
167179
168180 func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
169181
170182
171183 func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
172184
173185
174186 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
175187
176188 let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
177189
178190 let inFee = {
179191 let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
180192 if ($isInstanceOf(@, "Int"))
181193 then @
182194 else throw(($getType(@) + " couldn't be cast to Int"))
183195 }
184196
185197 let outFee = {
186198 let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
187199 if ($isInstanceOf(@, "Int"))
188200 then @
189201 else throw(($getType(@) + " couldn't be cast to Int"))
190202 }
191203
192204 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
193205
194206
195207 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
196208
197209
198210 func getPoolConfig () = {
199211 let amtAsset = getStringOrFail(this, aa())
200212 let priceAsset = getStringOrFail(this, pa())
201213 let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
202214 let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
203215 split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
204216 }
205217
206218
207219 func parseAssetId (input) = if ((input == wavesString))
208220 then unit
209221 else fromBase58String(input)
210222
211223
212224 func assetIdToString (input) = if ((input == unit))
213225 then wavesString
214226 else toBase58String(value(input))
215227
216228
217229 func parsePoolConfig (poolConfig) = $Tuple7(addressFromStringValue(poolConfig[idxPoolAddress]), parseIntValue(poolConfig[idxPoolStatus]), fromBase58String(poolConfig[idxPoolLPAssetId]), parseAssetId(poolConfig[idxAmtAssetId]), parseAssetId(poolConfig[idxPriceAssetId]), parseIntValue(poolConfig[idxAmtAssetDcm]), parseIntValue(poolConfig[idxPriceAssetDcm]))
218230
219231
220232 let poolConfigParsed = parsePoolConfig(getPoolConfig())
221233
222-let $t084698635 = poolConfigParsed
234+let $t089629128 = poolConfigParsed
223235
224-let cfgPoolAddress = $t084698635._1
236+let cfgPoolAddress = $t089629128._1
225237
226-let cfgPoolStatus = $t084698635._2
238+let cfgPoolStatus = $t089629128._2
227239
228-let cfgLpAssetId = $t084698635._3
240+let cfgLpAssetId = $t089629128._3
229241
230-let cfgAmountAssetId = $t084698635._4
242+let cfgAmountAssetId = $t089629128._4
231243
232-let cfgPriceAssetId = $t084698635._5
244+let cfgPriceAssetId = $t089629128._5
233245
234-let cfgAmountAssetDecimals = $t084698635._6
246+let cfgAmountAssetDecimals = $t089629128._6
235247
236-let cfgPriceAssetDecimals = $t084698635._7
248+let cfgPriceAssetDecimals = $t089629128._7
237249
238250 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
239251
240252
241253 let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
242254
243255 let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
244256
245257 func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slippageTolerancePassedByUser,slippageToleranceReal,txHeight,txTimestamp,slipageAmtAssetAmt,slipagePriceAssetAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slippageTolerancePassedByUser), toString(slippageToleranceReal), toString(txHeight), toString(txTimestamp), toString(slipageAmtAssetAmt), toString(slipagePriceAssetAmt)], SEP)
246258
247259
248260 func dataGetActionInfo (outAmtAssetAmt,outPriceAssetAmt,inLpAmt,price,txHeight,txTimestamp) = makeString(["%d%d%d%d%d%d", toString(outAmtAssetAmt), toString(outPriceAssetAmt), toString(inLpAmt), toString(price), toString(txHeight), toString(txTimestamp)], SEP)
249261
250262
251-func getAccBalance (assetId) = if ((assetId == "WAVES"))
252- then wavesBalance(this).available
253- else assetBalance(this, fromBase58String(assetId))
263+func getAccBalance (assetId) = {
264+ let balanceOnPool = if ((assetId == "WAVES"))
265+ then wavesBalance(this).available
266+ else assetBalance(this, fromBase58String(assetId))
267+ let totalBalance = ((balanceOnPool + getAdditionalBalanceOrZero(assetId)) - getStakingAssetBalanceOrZero(assetId))
268+ max([0, totalBalance])
269+ }
254270
255271
256272 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
257273
258274
259275 func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
276+
277+
278+func getRate (proxy) = {
279+ let inv = invoke(proxy, "getRate", nil, nil)
280+ if ((inv == inv))
281+ then match inv {
282+ case r: Int =>
283+ r
284+ case _ =>
285+ throwErr("proxy.getRate() unexpected value")
286+ }
287+ else throw("Strict value is not equal to itself.")
288+ }
289+
290+
291+func deposit (assetId,amount,stakingAssetId,proxy) = {
292+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
293+ if ((currentAdditionalBalance == currentAdditionalBalance))
294+ then {
295+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
296+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
297+ then {
298+ let asset = parseAssetId(assetId)
299+ if ((amount > 0))
300+ then {
301+ let depositInvoke = invoke(proxy, "deposit", nil, [AttachedPayment(asset, amount)])
302+ if ((depositInvoke == depositInvoke))
303+ then match depositInvoke {
304+ case receivedStakingAsset: Int =>
305+ let newAdditionalBalance = (currentAdditionalBalance + amount)
306+ let newStakingAssetBalance = (currentStakingAssetBalance + receivedStakingAsset)
307+[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance)]
308+ case _ =>
309+ nil
310+ }
311+ else throw("Strict value is not equal to itself.")
312+ }
313+ else nil
314+ }
315+ else throw("Strict value is not equal to itself.")
316+ }
317+ else throw("Strict value is not equal to itself.")
318+ }
319+
320+
321+func withdraw (assetId,amount,stakingAssetId,proxy,proxyRateMul,profitAddress) = {
322+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
323+ if ((currentAdditionalBalance == currentAdditionalBalance))
324+ then {
325+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
326+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
327+ then {
328+ let currentProxyRate = getRate(proxy)
329+ if ((currentProxyRate == currentProxyRate))
330+ then {
331+ let oldRate = fraction(proxyRateMul, currentAdditionalBalance, currentStakingAssetBalance)
332+ let stakingAsset = parseAssetId(stakingAssetId)
333+ let oldSendStakingAmount = fraction(proxyRateMul, amount, oldRate)
334+ let sendStakingAssetAmount = fraction(proxyRateMul, amount, currentProxyRate)
335+ let profitAmount = max([0, (oldSendStakingAmount - sendStakingAssetAmount)])
336+ if ((sendStakingAssetAmount > 0))
337+ then {
338+ let withdrawInvoke = invoke(proxy, "withdraw", nil, [AttachedPayment(stakingAsset, sendStakingAssetAmount)])
339+ if ((withdrawInvoke == withdrawInvoke))
340+ then match withdrawInvoke {
341+ case receivedAssets: Int =>
342+ let newAdditionalBalance = (currentAdditionalBalance - receivedAssets)
343+ let newStakingAssetBalance = ((currentStakingAssetBalance - sendStakingAssetAmount) - profitAmount)
344+[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance), ScriptTransfer(profitAddress, profitAmount, parseAssetId(stakingAssetId))]
345+ case _ =>
346+ nil
347+ }
348+ else throw("Strict value is not equal to itself.")
349+ }
350+ else nil
351+ }
352+ else throw("Strict value is not equal to itself.")
353+ }
354+ else throw("Strict value is not equal to itself.")
355+ }
356+ else throw("Strict value is not equal to itself.")
357+ }
358+
359+
360+func getLeaseProxyConfig (assetId) = match invoke(factoryContract, "getPoolLeaseConfigREADONLY", [toString(this), assetId], nil) {
361+ case a: (Boolean, Int, Int, String, String, Int, String) =>
362+ a
363+ case _ =>
364+ throwErr((("[" + assetId) + "] getLeaseProxyConfig() error"))
365+}
366+
367+
368+func rebalanceInternal (targetRatio,assetId,stakingAssetId,minBalance,proxy,proxyRateMul,profitAddress) = {
369+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
370+ if ((currentAdditionalBalance == currentAdditionalBalance))
371+ then {
372+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
373+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
374+ then {
375+ let leasableTotalBalance = max([0, (getAccBalance(assetId) - minBalance)])
376+ let targetAdditionalBalance = fraction(targetRatio, leasableTotalBalance, 100)
377+ let diff = (currentAdditionalBalance - targetAdditionalBalance)
378+ if ((diff == 0))
379+ then nil
380+ else if ((0 > diff))
381+ then {
382+ let sendAssetAmount = -(diff)
383+ deposit(assetId, sendAssetAmount, stakingAssetId, proxy)
384+ }
385+ else {
386+ let getAssetAmount = diff
387+ withdraw(assetId, getAssetAmount, stakingAssetId, proxy, proxyRateMul, profitAddress)
388+ }
389+ }
390+ else throw("Strict value is not equal to itself.")
391+ }
392+ else throw("Strict value is not equal to itself.")
393+ }
394+
395+
396+func rebalanceAsset (assetId) = {
397+ let $t01536415500 = getLeaseProxyConfig(assetId)
398+ let isLeasable = $t01536415500._1
399+ let leasedRatio = $t01536415500._2
400+ let minBalance = $t01536415500._3
401+ let proxyAddress = $t01536415500._4
402+ let proxyAssetId = $t01536415500._5
403+ let proxyRateMul = $t01536415500._6
404+ let stakingProfitAddress = $t01536415500._7
405+ if (isLeasable)
406+ then rebalanceInternal(leasedRatio, assetId, proxyAssetId, minBalance, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
407+ else nil
408+ }
409+
410+
411+func withdrawAndRebalanceAsset (assetId,getAmount) = {
412+ let $t01589116027 = getLeaseProxyConfig(assetId)
413+ let isLeasable = $t01589116027._1
414+ let leasedRatio = $t01589116027._2
415+ let minBalance = $t01589116027._3
416+ let proxyAddress = $t01589116027._4
417+ let proxyAssetId = $t01589116027._5
418+ let proxyRateMul = $t01589116027._6
419+ let stakingProfitAddress = $t01589116027._7
420+ if (isLeasable)
421+ then {
422+ let newTotalLeasableBalance = max([0, ((getAccBalance(assetId) - getAmount) - minBalance)])
423+ if ((newTotalLeasableBalance == newTotalLeasableBalance))
424+ then {
425+ let newAdditionalBalance = fraction(leasedRatio, newTotalLeasableBalance, 100)
426+ if ((newAdditionalBalance == newAdditionalBalance))
427+ then {
428+ let withdrawAmount = max([0, (getAdditionalBalanceOrZero(assetId) - newAdditionalBalance)])
429+ if ((withdrawAmount == withdrawAmount))
430+ then withdraw(assetId, withdrawAmount, proxyAssetId, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
431+ else throw("Strict value is not equal to itself.")
432+ }
433+ else throw("Strict value is not equal to itself.")
434+ }
435+ else throw("Strict value is not equal to itself.")
436+ }
437+ else nil
438+ }
439+
440+
441+func withdrawAndRebalanceAll (amountAssetOutAmount,priceAssetOutAmount) = {
442+ let AmAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, aa()), amountAssetOutAmount)
443+ let PrAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, pa()), priceAssetOutAmount)
444+ (AmAmtWithdrawState ++ PrAmtWithdrawState)
445+ }
260446
261447
262448 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
263449 let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
264450 let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
265451 calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
266452 }
267453
268454
269455 func calcPrices (amAmt,prAmt,lpAmt) = {
270456 let cfg = getPoolConfig()
271457 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
272458 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
273459 let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
274460 let amAmtX18 = toX18(amAmt, amtAssetDcm)
275461 let prAmtX18 = toX18(prAmt, priceAssetDcm)
276462 let lpAmtX18 = toX18(lpAmt, scale8)
277463 let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
278464 let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
279465 [priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
280466 }
281467
282468
283469 func calculatePrices (amAmt,prAmt,lpAmt) = {
284470 let prices = calcPrices(amAmt, prAmt, lpAmt)
285471 [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
286472 }
287473
288474
289475 func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
290476 let cfg = getPoolConfig()
291477 let lpAssetId = cfg[idxPoolLPAssetId]
292478 let amAssetId = cfg[idxAmtAssetId]
293479 let prAssetId = cfg[idxPriceAssetId]
294480 let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
295481 let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
296482 let poolStatus = cfg[idxPoolStatus]
297483 let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
298484 if ((lpAssetId != pmtAssetId))
299485 then throw("Invalid asset passed.")
300486 else {
301487 let amBalance = getAccBalance(amAssetId)
302488 let amBalanceX18 = toX18(amBalance, amAssetDcm)
303489 let prBalance = getAccBalance(prAssetId)
304490 let prBalanceX18 = toX18(prBalance, prAssetDcm)
305491 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
306492 let curPrice = fromX18(curPriceX18, scale8)
307493 let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
308494 let lpEmissionX18 = toX18(lpEmission, scale8)
309495 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
310496 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
311497 let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
312498 let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
313499 let state = if ((txId58 == ""))
314500 then nil
315501 else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
316502 then unit
317503 else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
318504 then unit
319505 else fromBase58String(prAssetId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
320506 $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
321507 }
322508 }
323509
324510
325511 func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
326512 let cfg = getPoolConfig()
327513 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
328514 let amAssetIdStr = cfg[idxAmtAssetId]
329515 let prAssetIdStr = cfg[idxPriceAssetId]
330516 let iAmtAssetId = cfg[idxIAmtAssetId]
331517 let iPriceAssetId = cfg[idxIPriceAssetId]
332518 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
333519 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
334520 let poolStatus = cfg[idxPoolStatus]
335521 let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
336522 let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
337523 let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
338524 if (if ((amAssetIdStr != inAmAssetIdStr))
339525 then true
340526 else (prAssetIdStr != inPrAssetIdStr))
341527 then throw("Invalid amt or price asset passed.")
342528 else {
343529 let amBalance = if (isEvaluate)
344530 then getAccBalance(amAssetIdStr)
345531 else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
346532 let prBalance = if (isEvaluate)
347533 then getAccBalance(prAssetIdStr)
348534 else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
349535 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
350536 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
351537 let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
352538 let amBalanceX18 = toX18(amBalance, amtAssetDcm)
353539 let prBalanceX18 = toX18(prBalance, priceAssetDcm)
354540 let res = if ((lpEmission == 0))
355541 then {
356542 let curPriceX18 = zeroBigInt
357543 let slippageX18 = zeroBigInt
358544 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
359545 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
360546 }
361547 else {
362548 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
363549 let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
364550 let slippageToleranceX18 = toX18(slippageTolerance, scale8)
365551 if (if ((curPriceX18 != zeroBigInt))
366552 then (slippageX18 > slippageToleranceX18)
367553 else false)
368554 then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
369555 else {
370556 let lpEmissionX18 = toX18(lpEmission, scale8)
371557 let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
372558 let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
373559 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
374560 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
375561 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
376562 let expAmtAssetAmtX18 = expectedAmts._1
377563 let expPriceAssetAmtX18 = expectedAmts._2
378564 let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
379565 $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
380566 }
381567 }
382568 let calcLpAmt = res._1
383569 let calcAmAssetPmt = res._2
384570 let calcPrAssetPmt = res._3
385571 let curPrice = fromX18(res._4, scale8)
386572 let slippageCalc = fromX18(res._5, scale8)
387573 if ((0 >= calcLpAmt))
388574 then throw("Invalid calculations. LP calculated is less than zero.")
389575 else {
390576 let emitLpAmt = if (!(emitLp))
391577 then 0
392578 else calcLpAmt
393579 let amDiff = (inAmAssetAmt - calcAmAssetPmt)
394580 let prDiff = (inPrAssetAmt - calcPrAssetPmt)
395581 let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(calcAmAssetPmt, calcPrAssetPmt, emitLpAmt, curPrice, slippageTolerance, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
396582 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
397583 }
398584 }
399585 }
400586
401587
402588 func calcKLp (amountBalance,priceBalance,lpEmission) = {
403589 let amountBalanceX18 = toX18BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals))
404590 let priceBalanceX18 = toX18BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))
405591 let updatedKLp = fraction(pow((amountBalanceX18 * priceBalanceX18), 0, toBigInt(5), 1, 18, DOWN), big1, lpEmission)
406592 if ((lpEmission == big0))
407593 then big0
408594 else updatedKLp
409595 }
410596
411597
412598 func calcCurrentKLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
413599 let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
414600 let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
415601 let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
416602 let currentKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
417603 currentKLp
418604 }
419605
420606
421607 func refreshKLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
422608 let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
423609 let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
424610 let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
425611 let updatedKLp = calcKLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
426612 let actions = [IntegerEntry(keyKLpRefreshedHeight, height), StringEntry(keyKLp, toString(updatedKLp))]
427613 $Tuple2(actions, updatedKLp)
428614 }
429615
430616
431617 func validateUpdatedKLp (oldKLp,updatedKLp) = if ((updatedKLp >= oldKLp))
432618 then true
433619 else throwErr(makeString(["updated KLp lower than current KLp", toString(oldKLp), toString(updatedKLp)], " "))
434620
435621
436622 func validateMatcherOrderAllowed (order) = {
437623 let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
438624 let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
439625 let amountAssetAmount = order.amount
440626 let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
441- let $t02154121753 = if ((order.orderType == Buy))
627+ let $t02815528367 = if ((order.orderType == Buy))
442628 then $Tuple2(amountAssetAmount, -(priceAssetAmount))
443629 else $Tuple2(-(amountAssetAmount), priceAssetAmount)
444- let amountAssetBalanceDelta = $t02154121753._1
445- let priceAssetBalanceDelta = $t02154121753._2
630+ let amountAssetBalanceDelta = $t02815528367._1
631+ let priceAssetBalanceDelta = $t02815528367._2
446632 if (if (if (isGlobalShutdown())
447633 then true
448634 else (cfgPoolStatus == PoolMatcherDisabled))
449635 then true
450636 else (cfgPoolStatus == PoolShutdown))
451637 then throw("Exchange operations disabled")
452638 else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
453639 then true
454640 else (order.assetPair.priceAsset != cfgPriceAssetId))
455641 then throw("Wrong order assets.")
456642 else {
457643 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
458- let $t02219322293 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
459- let unusedActions = $t02219322293._1
460- let kLpNew = $t02219322293._2
644+ let $t02880728907 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
645+ let unusedActions = $t02880728907._1
646+ let kLpNew = $t02880728907._2
461647 let isOrderValid = (kLpNew >= kLp)
462648 let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
463649 $Tuple2(isOrderValid, info)
464650 }
465651 }
466652
467653
468654 func commonGet (i) = if ((size(i.payments) != 1))
469655 then throw("exactly 1 payment is expected")
470656 else {
471657 let pmt = value(i.payments[0])
472658 let pmtAssetId = value(pmt.assetId)
473659 let pmtAmt = pmt.amount
474660 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
475661 let outAmAmt = res._1
476662 let outPrAmt = res._2
477663 let poolStatus = parseIntValue(res._9)
478664 let state = res._10
479665 if (if (isGlobalShutdown())
480666 then true
481667 else (poolStatus == PoolShutdown))
482668 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
483669 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
484670 }
485671
486672
487673 func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
488674 then throw("exactly 2 payments are expected")
489675 else {
490676 let amAssetPmt = value(i.payments[0])
491677 let prAssetPmt = value(i.payments[1])
492678 let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
493679 let poolStatus = parseIntValue(estPut._8)
494680 if (if (if (isGlobalShutdown())
495681 then true
496682 else (poolStatus == PoolPutDisabled))
497683 then true
498684 else (poolStatus == PoolShutdown))
499685 then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
500686 else estPut
501687 }
502688
503689
504690 func emit (amount) = {
505691 let emitInv = invoke(factoryContract, "emit", [amount], nil)
506692 if ((emitInv == emitInv))
507693 then {
508694 let emitInvLegacy = match emitInv {
509695 case legacyFactoryContract: Address =>
510696 invoke(legacyFactoryContract, "emit", [amount], nil)
511697 case _ =>
512698 unit
513699 }
514700 if ((emitInvLegacy == emitInvLegacy))
515701 then amount
516702 else throw("Strict value is not equal to itself.")
517703 }
518704 else throw("Strict value is not equal to itself.")
519705 }
520706
521707
522708 func takeFee (amount,fee) = {
523709 let feeAmount = if ((fee == 0))
524710 then 0
525711 else fraction(amount, fee, scale8)
526712 $Tuple2((amount - feeAmount), feeAmount)
527713 }
528714
529715
530716 func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
531717 let isEval = (txId == unit)
532718 let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
533719 let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
534720 let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
535721 then true
536722 else if ((paymentAssetId == cfgPriceAssetId))
537723 then false
538724 else throwErr("invalid asset")
539- let $t02540625699 = if (isEval)
725+ let $t03202032313 = if (isEval)
540726 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
541727 else if (paymentInAmountAsset)
542728 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
543729 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
544- let amountBalanceOld = $t02540625699._1
545- let priceBalanceOld = $t02540625699._2
546- let $t02570325852 = if (paymentInAmountAsset)
730+ let amountBalanceOld = $t03202032313._1
731+ let priceBalanceOld = $t03202032313._2
732+ let $t03231732466 = if (paymentInAmountAsset)
547733 then $Tuple2(paymentAmountRaw, 0)
548734 else $Tuple2(0, paymentAmountRaw)
549- let amountAssetAmountRaw = $t02570325852._1
550- let priceAssetAmountRaw = $t02570325852._2
735+ let amountAssetAmountRaw = $t03231732466._1
736+ let priceAssetAmountRaw = $t03231732466._2
551737 let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
552738 let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
553- let $t02598426048 = takeFee(paymentAmountRaw, inFee)
554- let paymentAmount = $t02598426048._1
555- let feeAmount = $t02598426048._2
739+ let $t03259832662 = takeFee(paymentAmountRaw, inFee)
740+ let paymentAmount = $t03259832662._1
741+ let feeAmount = $t03259832662._2
556742 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
557743 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
558744 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
559745 let priceNew = fromX18(priceNewX18, scale8)
560746 let paymentBalance = if (paymentInAmountAsset)
561747 then amountBalanceOld
562748 else priceBalanceOld
563749 let paymentBalanceBigInt = toBigInt(paymentBalance)
564750 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
565751 let chechSupply = if ((supplyBigInt > big0))
566752 then true
567753 else throwErr("initial deposit requires all coins")
568754 if ((chechSupply == chechSupply))
569755 then {
570756 let depositBigInt = toBigInt(paymentAmount)
571757 let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
572758 let commonState = if (isEval)
573759 then nil
574760 else [IntegerEntry(pl(), priceNew), IntegerEntry(ph(height, lastBlock.timestamp), priceNew), StringEntry(pau(toString(value(userAddress)), toBase58String(value(txId))), dataPutActionInfo(amountAssetAmountRaw, priceAssetAmountRaw, issueAmount, priceNew, 0, 0, height, lastBlock.timestamp, 0, 0))]
575761 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
576762 let priceOld = fromX18(priceOldX18, scale8)
577763 let loss = {
578- let $t02772927896 = if (paymentInAmountAsset)
764+ let $t03434334510 = if (paymentInAmountAsset)
579765 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
580766 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
581- let amount = $t02772927896._1
582- let balance = $t02772927896._2
767+ let amount = $t03434334510._1
768+ let balance = $t03434334510._2
583769 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
584770 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
585771 }
586772 $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
587773 }
588774 else throw("Strict value is not equal to itself.")
589775 }
590776
591777
592778 func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
593779 let isEval = (txId == unit)
594780 let cfg = getPoolConfig()
595781 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
596782 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
597783 let checks = [if ((paymentAssetId == cfgLpAssetId))
598784 then true
599785 else throwErr("invalid lp asset")]
600786 if ((checks == checks))
601787 then {
602788 let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
603789 then true
604790 else if ((outAssetId == cfgPriceAssetId))
605791 then false
606792 else throwErr("invalid asset")
607793 let balanceBigInt = if (outInAmountAsset)
608794 then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
609795 else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
610796 let outInAmountAssetDecimals = if (outInAmountAsset)
611797 then amtAssetDcm
612798 else priceAssetDcm
613799 let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
614800 let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
615801 let outBalance = if (outInAmountAsset)
616802 then amBalanceOld
617803 else prBalanceOld
618804 let outBalanceBigInt = toBigInt(outBalance)
619805 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
620806 let redeemedBigInt = toBigInt(paymentAmount)
621807 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
622- let $t02997430030 = takeFee(amountRaw, outFee)
623- let totalAmount = $t02997430030._1
624- let feeAmount = $t02997430030._2
625- let $t03003430260 = if (outInAmountAsset)
808+ let $t03658836644 = takeFee(amountRaw, outFee)
809+ let totalAmount = $t03658836644._1
810+ let feeAmount = $t03658836644._2
811+ let $t03664836874 = if (outInAmountAsset)
626812 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
627813 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
628- let outAmAmount = $t03003430260._1
629- let outPrAmount = $t03003430260._2
630- let amBalanceNew = $t03003430260._3
631- let prBalanceNew = $t03003430260._4
814+ let outAmAmount = $t03664836874._1
815+ let outPrAmount = $t03664836874._2
816+ let amBalanceNew = $t03664836874._3
817+ let prBalanceNew = $t03664836874._4
632818 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
633819 let priceNew = fromX18(priceNewX18, scale8)
634820 let commonState = if (isEval)
635821 then nil
636822 else [StringEntry(gau(toString(value(userAddress)), toBase58String(value(txId))), dataGetActionInfo(outAmAmount, outPrAmount, paymentAmount, priceNew, height, lastBlock.timestamp)), IntegerEntry(pl(), priceNew), IntegerEntry(ph(height, lastBlock.timestamp), priceNew)]
637823 let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
638824 let priceOld = fromX18(priceOldX18, scale8)
639825 let loss = {
640826 let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
641827 fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
642828 }
643829 $Tuple5(totalAmount, commonState, feeAmount, loss, outInAmountAsset)
644830 }
645831 else throw("Strict value is not equal to itself.")
646832 }
647833
648834
649835 func managerPublicKeyOrUnit () = match getString(mpk()) {
650836 case s: String =>
651837 fromBase58String(s)
652838 case _: Unit =>
653839 unit
654840 case _ =>
655841 throw("Match error")
656842 }
657843
658844
659845 func pendingManagerPublicKeyOrUnit () = match getString(pmpk()) {
660846 case s: String =>
661847 fromBase58String(s)
662848 case _: Unit =>
663849 unit
664850 case _ =>
665851 throw("Match error")
666852 }
667853
668854
669855 func isManager (i) = match managerPublicKeyOrUnit() {
670856 case pk: ByteVector =>
671857 (i.callerPublicKey == pk)
672858 case _: Unit =>
673859 (i.caller == this)
674860 case _ =>
675861 throw("Match error")
676862 }
677863
678864
679865 func mustManager (i) = {
680866 let pd = throw("Permission denied")
681867 match managerPublicKeyOrUnit() {
682868 case pk: ByteVector =>
683869 if ((i.callerPublicKey == pk))
684870 then true
685871 else pd
686872 case _: Unit =>
687873 if ((i.caller == this))
688874 then true
689875 else pd
690876 case _ =>
691877 throw("Match error")
692878 }
693879 }
694880
695881
696882 @Callable(i)
883+func rebalance () = (rebalanceAsset(getStringOrFail(this, aa())) ++ rebalanceAsset(getStringOrFail(this, pa())))
884+
885+
886+
887+@Callable(i)
697888 func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse,feePoolAmount) = {
698- let $t03197732282 = if ((isReverse == false))
889+ let $t03876039065 = if ((isReverse == false))
699890 then {
700891 let assetOut = getStringOrFail(this, pa())
701892 let assetIn = getStringOrFail(this, aa())
702893 $Tuple2(assetOut, assetIn)
703894 }
704895 else {
705896 let assetOut = getStringOrFail(this, aa())
706897 let assetIn = getStringOrFail(this, pa())
707898 $Tuple2(assetOut, assetIn)
708899 }
709- let assetOut = $t03197732282._1
710- let assetIn = $t03197732282._2
900+ let assetOut = $t03876039065._1
901+ let assetIn = $t03876039065._2
711902 let poolAssetInBalance = getAccBalance(assetIn)
712903 let poolAssetOutBalance = getAccBalance(assetOut)
713904 let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
714905 let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
715906 let newK = (((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
716907 let checkK = if ((newK >= oldK))
717908 then true
718909 else throw("new K is fewer error")
719910 if ((checkK == checkK))
720911 then $Tuple2(nil, amountOut)
721912 else throw("Strict value is not equal to itself.")
722913 }
723914
724915
725916
726917 @Callable(i)
727918 func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo,feePoolAmount) = {
728919 let swapContact = {
729920 let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil)
730921 if ($isInstanceOf(@, "String"))
731922 then @
732923 else throw(($getType(@) + " couldn't be cast to String"))
733924 }
734925 let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
735926 then true
736927 else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
737928 then true
738929 else throwErr("Permission denied")]
739930 if ((checks == checks))
740931 then {
741932 let pmt = value(i.payments[0])
742933 let assetIn = assetIdToString(pmt.assetId)
743934 let assetOut = if ((isReverse == false))
744935 then getStringOrFail(this, pa())
745936 else getStringOrFail(this, aa())
746937 let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
747938 let poolAssetOutBalance = getAccBalance(assetOut)
748939 let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
749940 let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
750941 let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
751942 let checkK = if ((newK >= oldK))
752943 then true
753944 else throw("new K is fewer error")
754945 if ((checkK == checkK))
755946 then {
756947 let checkMin = if ((amountOut >= amountOutMin))
757948 then true
758949 else throw("Exchange result is fewer coins than expected")
759950 if ((checkMin == checkMin))
760- then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))], amountOut)
951+ then {
952+ let rebalanceState = rebalanceAsset(assetIn)
953+ if ((rebalanceState == rebalanceState))
954+ then {
955+ let withdrawState = withdrawAndRebalanceAsset(assetOut, amountOut)
956+ if ((withdrawState == withdrawState))
957+ then $Tuple2(((withdrawState ++ rebalanceState) ++ [ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))]), amountOut)
958+ else throw("Strict value is not equal to itself.")
959+ }
960+ else throw("Strict value is not equal to itself.")
961+ }
761962 else throw("Strict value is not equal to itself.")
762963 }
763964 else throw("Strict value is not equal to itself.")
764965 }
765966 else throw("Strict value is not equal to itself.")
766967 }
767968
768969
769970
770971 @Callable(i)
771972 func setManager (pendingManagerPublicKey) = {
772973 let checkCaller = mustManager(i)
773974 if ((checkCaller == checkCaller))
774975 then {
775976 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
776977 if ((checkManagerPublicKey == checkManagerPublicKey))
777978 then [StringEntry(pmpk(), pendingManagerPublicKey)]
778979 else throw("Strict value is not equal to itself.")
779980 }
780981 else throw("Strict value is not equal to itself.")
781982 }
782983
783984
784985
785986 @Callable(i)
786987 func confirmManager () = {
787988 let pm = pendingManagerPublicKeyOrUnit()
788989 let hasPM = if (isDefined(pm))
789990 then true
790991 else throw("No pending manager")
791992 if ((hasPM == hasPM))
792993 then {
793994 let checkPM = if ((i.callerPublicKey == value(pm)))
794995 then true
795996 else throw("You are not pending manager")
796997 if ((checkPM == checkPM))
797998 then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())]
798999 else throw("Strict value is not equal to itself.")
7991000 }
8001001 else throw("Strict value is not equal to itself.")
8011002 }
8021003
8031004
8041005
8051006 @Callable(i)
8061007 func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
8071008 then throw("Invalid slippageTolerance passed")
8081009 else {
8091010 let estPut = commonPut(i, slippageTolerance, true)
8101011 let emitLpAmt = estPut._2
8111012 let lpAssetId = estPut._7
8121013 let state = estPut._9
8131014 let amDiff = estPut._10
8141015 let prDiff = estPut._11
8151016 let amId = estPut._12
8161017 let prId = estPut._13
8171018 let amAssetPmt = toBigInt(value(i.payments[0]).amount)
8181019 let prAssetPmt = toBigInt(value(i.payments[1]).amount)
8191020 let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
8201021 if ((currentKLp == currentKLp))
8211022 then {
8221023 let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
8231024 if ((emitInv == emitInv))
8241025 then {
8251026 let emitInvLegacy = match emitInv {
8261027 case legacyFactoryContract: Address =>
8271028 invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
8281029 case _ =>
8291030 unit
8301031 }
8311032 if ((emitInvLegacy == emitInvLegacy))
8321033 then {
8331034 let slippageAInv = if ((amDiff > 0))
8341035 then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
8351036 else nil
8361037 if ((slippageAInv == slippageAInv))
8371038 then {
8381039 let slippagePInv = if ((prDiff > 0))
8391040 then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
8401041 else nil
8411042 if ((slippagePInv == slippagePInv))
8421043 then {
8431044 let lpTransfer = if (shouldAutoStake)
8441045 then {
8451046 let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
8461047 if ((slpStakeInv == slpStakeInv))
8471048 then nil
8481049 else throw("Strict value is not equal to itself.")
8491050 }
8501051 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
851- let $t03716637628 = refreshKLpInternal(0, 0, 0)
852- if (($t03716637628 == $t03716637628))
1052+ let $t04411144573 = refreshKLpInternal(0, 0, 0)
1053+ if (($t04411144573 == $t04411144573))
8531054 then {
854- let updatedKLp = $t03716637628._2
855- let refreshKLpActions = $t03716637628._1
1055+ let updatedKLp = $t04411144573._2
1056+ let refreshKLpActions = $t04411144573._1
8561057 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
8571058 if ((isUpdatedKLpValid == isUpdatedKLpValid))
858- then ((state ++ lpTransfer) ++ refreshKLpActions)
1059+ then {
1060+ let reb = invoke(this, "rebalance", nil, nil)
1061+ if ((reb == reb))
1062+ then ((state ++ lpTransfer) ++ refreshKLpActions)
1063+ else throw("Strict value is not equal to itself.")
1064+ }
8591065 else throw("Strict value is not equal to itself.")
8601066 }
8611067 else throw("Strict value is not equal to itself.")
8621068 }
8631069 else throw("Strict value is not equal to itself.")
8641070 }
8651071 else throw("Strict value is not equal to itself.")
8661072 }
8671073 else throw("Strict value is not equal to itself.")
8681074 }
8691075 else throw("Strict value is not equal to itself.")
8701076 }
8711077 else throw("Strict value is not equal to itself.")
8721078 }
8731079
8741080
8751081
8761082 @Callable(i)
8771083 func putForFree (maxSlippage) = if ((0 > maxSlippage))
8781084 then throw("Invalid value passed")
8791085 else {
8801086 let estPut = commonPut(i, maxSlippage, false)
8811087 let state = estPut._9
8821088 let amAssetPmt = toBigInt(value(i.payments[0]).amount)
8831089 let prAssetPmt = toBigInt(value(i.payments[1]).amount)
8841090 let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
8851091 if ((currentKLp == currentKLp))
8861092 then {
887- let $t03819038255 = refreshKLpInternal(0, 0, 0)
888- let refreshKLpActions = $t03819038255._1
889- let updatedKLp = $t03819038255._2
1093+ let $t04518545250 = refreshKLpInternal(0, 0, 0)
1094+ let refreshKLpActions = $t04518545250._1
1095+ let updatedKLp = $t04518545250._2
8901096 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
8911097 if ((isUpdatedKLpValid == isUpdatedKLpValid))
8921098 then (state ++ refreshKLpActions)
8931099 else throw("Strict value is not equal to itself.")
8941100 }
8951101 else throw("Strict value is not equal to itself.")
8961102 }
8971103
8981104
8991105
9001106 @Callable(i)
9011107 func putOneTkn (minOutAmount,autoStake) = {
9021108 let isPoolOneTokenOperationsDisabled = {
9031109 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
9041110 if ($isInstanceOf(@, "Boolean"))
9051111 then @
9061112 else throw(($getType(@) + " couldn't be cast to Boolean"))
9071113 }
9081114 let isPutDisabled = if (if (if (isGlobalShutdown())
9091115 then true
9101116 else (cfgPoolStatus == PoolPutDisabled))
9111117 then true
9121118 else (cfgPoolStatus == PoolShutdown))
9131119 then true
9141120 else isPoolOneTokenOperationsDisabled
9151121 let checks = [if (if (!(isPutDisabled))
9161122 then true
9171123 else isManager(i))
9181124 then true
9191125 else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
9201126 then true
9211127 else throwErr("exactly 1 payment are expected")]
9221128 if ((checks == checks))
9231129 then {
9241130 let payment = i.payments[0]
9251131 let paymentAssetId = payment.assetId
9261132 let paymentAmountRaw = payment.amount
9271133 let currentKLp = if ((paymentAssetId == cfgAmountAssetId))
9281134 then calcCurrentKLp(toBigInt(paymentAmountRaw), toBigInt(0), toBigInt(0))
9291135 else if ((paymentAssetId == cfgPriceAssetId))
9301136 then calcCurrentKLp(toBigInt(0), toBigInt(paymentAmountRaw), toBigInt(0))
9311137 else throwErr("payment asset is not supported")
9321138 if ((currentKLp == currentKLp))
9331139 then {
9341140 let userAddress = i.caller
9351141 let txId = i.transactionId
936- let $t03944339595 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
937- if (($t03944339595 == $t03944339595))
1142+ let $t04643846590 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
1143+ if (($t04643846590 == $t04643846590))
9381144 then {
939- let paymentInAmountAsset = $t03944339595._5
940- let bonus = $t03944339595._4
941- let feeAmount = $t03944339595._3
942- let commonState = $t03944339595._2
943- let emitAmountEstimated = $t03944339595._1
1145+ let paymentInAmountAsset = $t04643846590._5
1146+ let bonus = $t04643846590._4
1147+ let feeAmount = $t04643846590._3
1148+ let commonState = $t04643846590._2
1149+ let emitAmountEstimated = $t04643846590._1
9441150 let emitAmount = if (if ((minOutAmount > 0))
9451151 then (minOutAmount > emitAmountEstimated)
9461152 else false)
9471153 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
9481154 else emitAmountEstimated
9491155 let emitInv = emit(emitAmount)
9501156 if ((emitInv == emitInv))
9511157 then {
9521158 let lpTransfer = if (autoStake)
9531159 then {
9541160 let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
9551161 if ((stakeInv == stakeInv))
9561162 then nil
9571163 else throw("Strict value is not equal to itself.")
9581164 }
9591165 else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
9601166 let sendFee = if ((feeAmount > 0))
9611167 then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
9621168 else nil
963- let $t04018140378 = if ((this == feeCollectorAddress))
1169+ let $t04717647373 = if ((this == feeCollectorAddress))
9641170 then $Tuple2(0, 0)
9651171 else if (paymentInAmountAsset)
9661172 then $Tuple2(-(feeAmount), 0)
9671173 else $Tuple2(0, -(feeAmount))
968- let amountAssetBalanceDelta = $t04018140378._1
969- let priceAssetBalanceDelta = $t04018140378._2
970- let $t04038140489 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
971- let refreshKLpActions = $t04038140489._1
972- let updatedKLp = $t04038140489._2
1174+ let amountAssetBalanceDelta = $t04717647373._1
1175+ let priceAssetBalanceDelta = $t04717647373._2
1176+ let $t04737647484 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1177+ let refreshKLpActions = $t04737647484._1
1178+ let updatedKLp = $t04737647484._2
9731179 let kLp = value(getString(keyKLp))
9741180 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
9751181 if ((isUpdatedKLpValid == isUpdatedKLpValid))
976- then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
1182+ then {
1183+ let reb = invoke(this, "rebalance", nil, nil)
1184+ if ((reb == reb))
1185+ then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
1186+ else throw("Strict value is not equal to itself.")
1187+ }
9771188 else throw("Strict value is not equal to itself.")
9781189 }
9791190 else throw("Strict value is not equal to itself.")
9801191 }
9811192 else throw("Strict value is not equal to itself.")
9821193 }
9831194 else throw("Strict value is not equal to itself.")
9841195 }
9851196 else throw("Strict value is not equal to itself.")
9861197 }
9871198
9881199
9891200
9901201 @Callable(i)
9911202 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
992- let $t04079540952 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
993- let emitAmountEstimated = $t04079540952._1
994- let commonState = $t04079540952._2
995- let feeAmount = $t04079540952._3
996- let bonus = $t04079540952._4
997- let paymentInAmountAsset = $t04079540952._5
1203+ let $t04783947996 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
1204+ let emitAmountEstimated = $t04783947996._1
1205+ let commonState = $t04783947996._2
1206+ let feeAmount = $t04783947996._3
1207+ let bonus = $t04783947996._4
1208+ let paymentInAmountAsset = $t04783947996._5
9981209 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
9991210 }
10001211
10011212
10021213
10031214 @Callable(i)
10041215 func getOneTkn (outAssetIdStr,minOutAmount) = {
10051216 let isPoolOneTokenOperationsDisabled = {
10061217 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
10071218 if ($isInstanceOf(@, "Boolean"))
10081219 then @
10091220 else throw(($getType(@) + " couldn't be cast to Boolean"))
10101221 }
10111222 let isGetDisabled = if (if (isGlobalShutdown())
10121223 then true
10131224 else (cfgPoolStatus == PoolShutdown))
10141225 then true
10151226 else isPoolOneTokenOperationsDisabled
10161227 let checks = [if (if (!(isGetDisabled))
10171228 then true
10181229 else isManager(i))
10191230 then true
10201231 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
10211232 then true
10221233 else throwErr("exactly 1 payment are expected")]
10231234 if ((checks == checks))
10241235 then {
10251236 let outAssetId = parseAssetId(outAssetIdStr)
10261237 let payment = i.payments[0]
10271238 let paymentAssetId = payment.assetId
10281239 let paymentAmount = payment.amount
10291240 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
10301241 if ((currentKLp == currentKLp))
10311242 then {
10321243 let userAddress = i.caller
10331244 let txId = i.transactionId
1034- let $t04183741990 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1035- if (($t04183741990 == $t04183741990))
1245+ let $t04888149034 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1246+ if (($t04888149034 == $t04888149034))
10361247 then {
1037- let outInAmountAsset = $t04183741990._5
1038- let bonus = $t04183741990._4
1039- let feeAmount = $t04183741990._3
1040- let commonState = $t04183741990._2
1041- let amountEstimated = $t04183741990._1
1248+ let outInAmountAsset = $t04888149034._5
1249+ let bonus = $t04888149034._4
1250+ let feeAmount = $t04888149034._3
1251+ let commonState = $t04888149034._2
1252+ let amountEstimated = $t04888149034._1
10421253 let amount = if (if ((minOutAmount > 0))
10431254 then (minOutAmount > amountEstimated)
10441255 else false)
10451256 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
10461257 else amountEstimated
10471258 let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
10481259 if ((burnInv == burnInv))
10491260 then {
1261+ let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
10501262 let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
10511263 let sendFee = if ((feeAmount > 0))
10521264 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
10531265 else nil
1054- let $t04249042737 = {
1266+ let $t04969849945 = {
10551267 let feeAmountForCalc = if ((this == feeCollectorAddress))
10561268 then 0
10571269 else feeAmount
10581270 if (outInAmountAsset)
10591271 then $Tuple2(-((amount + feeAmountForCalc)), 0)
10601272 else $Tuple2(0, -((amount + feeAmountForCalc)))
10611273 }
1062- let amountAssetBalanceDelta = $t04249042737._1
1063- let priceAssetBalanceDelta = $t04249042737._2
1064- let $t04274042848 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1065- let refreshKLpActions = $t04274042848._1
1066- let updatedKLp = $t04274042848._2
1274+ let amountAssetBalanceDelta = $t04969849945._1
1275+ let priceAssetBalanceDelta = $t04969849945._2
1276+ let $t04994850056 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1277+ let refreshKLpActions = $t04994850056._1
1278+ let updatedKLp = $t04994850056._2
10671279 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
10681280 if ((isUpdatedKLpValid == isUpdatedKLpValid))
1069- then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1281+ then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
10701282 else throw("Strict value is not equal to itself.")
10711283 }
10721284 else throw("Strict value is not equal to itself.")
10731285 }
10741286 else throw("Strict value is not equal to itself.")
10751287 }
10761288 else throw("Strict value is not equal to itself.")
10771289 }
10781290 else throw("Strict value is not equal to itself.")
10791291 }
10801292
10811293
10821294
10831295 @Callable(i)
10841296 func getOneTknREADONLY (outAssetId,paymentAmount) = {
1085- let $t04310543261 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1086- let amountEstimated = $t04310543261._1
1087- let commonState = $t04310543261._2
1088- let feeAmount = $t04310543261._3
1089- let bonus = $t04310543261._4
1090- let outInAmountAsset = $t04310543261._5
1297+ let $t05033450490 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1298+ let amountEstimated = $t05033450490._1
1299+ let commonState = $t05033450490._2
1300+ let feeAmount = $t05033450490._3
1301+ let bonus = $t05033450490._4
1302+ let outInAmountAsset = $t05033450490._5
10911303 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
10921304 }
10931305
10941306
10951307
10961308 @Callable(i)
10971309 func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
10981310 let isPoolOneTokenOperationsDisabled = {
10991311 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
11001312 if ($isInstanceOf(@, "Boolean"))
11011313 then @
11021314 else throw(($getType(@) + " couldn't be cast to Boolean"))
11031315 }
11041316 let isGetDisabled = if (if (isGlobalShutdown())
11051317 then true
11061318 else (cfgPoolStatus == PoolShutdown))
11071319 then true
11081320 else isPoolOneTokenOperationsDisabled
11091321 let checks = [if (if (!(isGetDisabled))
11101322 then true
11111323 else isManager(i))
11121324 then true
11131325 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
11141326 then true
11151327 else throwErr("no payments are expected")]
11161328 if ((checks == checks))
11171329 then {
11181330 let outAssetId = parseAssetId(outAssetIdStr)
11191331 let userAddress = i.caller
11201332 let txId = i.transactionId
11211333 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
11221334 if ((currentKLp == currentKLp))
11231335 then {
11241336 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
11251337 if ((unstakeInv == unstakeInv))
11261338 then {
1127- let $t04416644317 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1128- if (($t04416644317 == $t04416644317))
1339+ let $t05139551546 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1340+ if (($t05139551546 == $t05139551546))
11291341 then {
1130- let outInAmountAsset = $t04416644317._5
1131- let bonus = $t04416644317._4
1132- let feeAmount = $t04416644317._3
1133- let commonState = $t04416644317._2
1134- let amountEstimated = $t04416644317._1
1342+ let outInAmountAsset = $t05139551546._5
1343+ let bonus = $t05139551546._4
1344+ let feeAmount = $t05139551546._3
1345+ let commonState = $t05139551546._2
1346+ let amountEstimated = $t05139551546._1
11351347 let amount = if (if ((minOutAmount > 0))
11361348 then (minOutAmount > amountEstimated)
11371349 else false)
11381350 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
11391351 else amountEstimated
11401352 let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
11411353 if ((burnInv == burnInv))
11421354 then {
1355+ let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
11431356 let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
11441357 let sendFee = if ((feeAmount > 0))
11451358 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
11461359 else nil
1147- let $t04481245059 = {
1360+ let $t05220552452 = {
11481361 let feeAmountForCalc = if ((this == feeCollectorAddress))
11491362 then 0
11501363 else feeAmount
11511364 if (outInAmountAsset)
11521365 then $Tuple2(-((amount + feeAmountForCalc)), 0)
11531366 else $Tuple2(0, -((amount + feeAmountForCalc)))
11541367 }
1155- let amountAssetBalanceDelta = $t04481245059._1
1156- let priceAssetBalanceDelta = $t04481245059._2
1157- let $t04506245170 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1158- let refreshKLpActions = $t04506245170._1
1159- let updatedKLp = $t04506245170._2
1368+ let amountAssetBalanceDelta = $t05220552452._1
1369+ let priceAssetBalanceDelta = $t05220552452._2
1370+ let $t05245552563 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1371+ let refreshKLpActions = $t05245552563._1
1372+ let updatedKLp = $t05245552563._2
11601373 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11611374 if ((isUpdatedKLpValid == isUpdatedKLpValid))
1162- then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1375+ then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
11631376 else throw("Strict value is not equal to itself.")
11641377 }
11651378 else throw("Strict value is not equal to itself.")
11661379 }
11671380 else throw("Strict value is not equal to itself.")
11681381 }
11691382 else throw("Strict value is not equal to itself.")
11701383 }
11711384 else throw("Strict value is not equal to itself.")
11721385 }
11731386 else throw("Strict value is not equal to itself.")
11741387 }
11751388
11761389
11771390
11781391 @Callable(i)
11791392 func get () = {
11801393 let res = commonGet(i)
1181- let outAmtAmt = res._1
1394+ let outAmAmt = res._1
11821395 let outPrAmt = res._2
11831396 let pmtAmt = res._3
11841397 let pmtAssetId = res._4
11851398 let state = res._5
1399+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
11861400 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
11871401 if ((currentKLp == currentKLp))
11881402 then {
11891403 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
11901404 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11911405 then {
1192- let $t04611646198 = refreshKLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1193- let refreshKLpActions = $t04611646198._1
1194- let updatedKLp = $t04611646198._2
1406+ let $t05365853739 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1407+ let refreshKLpActions = $t05365853739._1
1408+ let updatedKLp = $t05365853739._2
11951409 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11961410 if ((isUpdatedKLpValid == isUpdatedKLpValid))
1197- then (state ++ refreshKLpActions)
1411+ then ((withdrawState ++ state) ++ refreshKLpActions)
11981412 else throw("Strict value is not equal to itself.")
11991413 }
12001414 else throw("Strict value is not equal to itself.")
12011415 }
12021416 else throw("Strict value is not equal to itself.")
12031417 }
12041418
12051419
12061420
12071421 @Callable(i)
12081422 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
12091423 let res = commonGet(i)
12101424 let outAmAmt = res._1
12111425 let outPrAmt = res._2
12121426 let pmtAmt = res._3
12131427 let pmtAssetId = res._4
12141428 let state = res._5
12151429 if ((noLessThenAmtAsset > outAmAmt))
12161430 then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
12171431 else if ((noLessThenPriceAsset > outPrAmt))
12181432 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
12191433 else {
1434+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
12201435 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
12211436 if ((currentKLp == currentKLp))
12221437 then {
12231438 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
12241439 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
12251440 then {
1226- let $t04714747228 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1227- let refreshKLpActions = $t04714747228._1
1228- let updatedKLp = $t04714747228._2
1441+ let $t05483454915 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1442+ let refreshKLpActions = $t05483454915._1
1443+ let updatedKLp = $t05483454915._2
12291444 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
12301445 if ((isUpdatedKLpValid == isUpdatedKLpValid))
1231- then (state ++ refreshKLpActions)
1446+ then ((withdrawState ++ state) ++ refreshKLpActions)
12321447 else throw("Strict value is not equal to itself.")
12331448 }
12341449 else throw("Strict value is not equal to itself.")
12351450 }
12361451 else throw("Strict value is not equal to itself.")
12371452 }
12381453 }
12391454
12401455
12411456
12421457 @Callable(i)
12431458 func unstakeAndGet (amount) = {
12441459 let checkPayments = if ((size(i.payments) != 0))
12451460 then throw("No payments are expected")
12461461 else true
12471462 if ((checkPayments == checkPayments))
12481463 then {
12491464 let cfg = getPoolConfig()
12501465 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
12511466 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
12521467 if ((currentKLp == currentKLp))
12531468 then {
12541469 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
12551470 if ((unstakeInv == unstakeInv))
12561471 then {
12571472 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
12581473 let outAmAmt = res._1
12591474 let outPrAmt = res._2
12601475 let poolStatus = parseIntValue(res._9)
12611476 let state = res._10
1477+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
12621478 let checkPoolStatus = if (if (isGlobalShutdown())
12631479 then true
12641480 else (poolStatus == PoolShutdown))
12651481 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
12661482 else true
12671483 if ((checkPoolStatus == checkPoolStatus))
12681484 then {
12691485 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
12701486 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
12711487 then {
1272- let $t04835448435 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1273- let refreshKLpActions = $t04835448435._1
1274- let updatedKLp = $t04835448435._2
1488+ let $t05618756268 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1489+ let refreshKLpActions = $t05618756268._1
1490+ let updatedKLp = $t05618756268._2
12751491 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
12761492 if ((isUpdatedKLpValid == isUpdatedKLpValid))
1277- then (state ++ refreshKLpActions)
1493+ then ((withdrawState ++ state) ++ refreshKLpActions)
12781494 else throw("Strict value is not equal to itself.")
12791495 }
12801496 else throw("Strict value is not equal to itself.")
12811497 }
12821498 else throw("Strict value is not equal to itself.")
12831499 }
12841500 else throw("Strict value is not equal to itself.")
12851501 }
12861502 else throw("Strict value is not equal to itself.")
12871503 }
12881504 else throw("Strict value is not equal to itself.")
12891505 }
12901506
12911507
12921508
12931509 @Callable(i)
12941510 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
12951511 let isGetDisabled = if (isGlobalShutdown())
12961512 then true
12971513 else (cfgPoolStatus == PoolShutdown)
12981514 let checks = [if (!(isGetDisabled))
12991515 then true
13001516 else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
13011517 then true
13021518 else throw("no payments are expected")]
13031519 if ((checks == checks))
13041520 then {
13051521 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
13061522 if ((currentKLp == currentKLp))
13071523 then {
13081524 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
13091525 if ((unstakeInv == unstakeInv))
13101526 then {
13111527 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
13121528 let outAmAmt = res._1
13131529 let outPrAmt = res._2
13141530 let state = res._10
1531+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
13151532 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
13161533 then true
13171534 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
13181535 then true
13191536 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
13201537 if ((checkAmounts == checkAmounts))
13211538 then {
13221539 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
13231540 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
13241541 then {
1325- let $t04973049811 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1326- let refreshKLpActions = $t04973049811._1
1327- let updatedKLp = $t04973049811._2
1542+ let $t05770957790 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1543+ let refreshKLpActions = $t05770957790._1
1544+ let updatedKLp = $t05770957790._2
13281545 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
13291546 if ((isUpdatedKLpValid == isUpdatedKLpValid))
1330- then (state ++ refreshKLpActions)
1547+ then ((withdrawState ++ state) ++ refreshKLpActions)
13311548 else throw("Strict value is not equal to itself.")
13321549 }
13331550 else throw("Strict value is not equal to itself.")
13341551 }
13351552 else throw("Strict value is not equal to itself.")
13361553 }
13371554 else throw("Strict value is not equal to itself.")
13381555 }
13391556 else throw("Strict value is not equal to itself.")
13401557 }
13411558 else throw("Strict value is not equal to itself.")
13421559 }
13431560
13441561
13451562
13461563 @Callable(i)
13471564 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
13481565 then throw("permissions denied")
13491566 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
13501567
13511568
13521569
13531570 @Callable(i)
13541571 func refreshKLp () = {
13551572 let lastRefreshedBlockHeight = valueOrElse(getInteger(keyKLpRefreshedHeight), 0)
13561573 let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= kLpRefreshDelay))
13571574 then unit
13581575 else throwErr(makeString([toString(kLpRefreshDelay), " blocks have not passed since the previous call"], ""))
13591576 if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
13601577 then {
13611578 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1362- let $t05099851062 = refreshKLpInternal(0, 0, 0)
1363- let kLpUpdateActions = $t05099851062._1
1364- let updatedKLp = $t05099851062._2
1579+ let $t05899459058 = refreshKLpInternal(0, 0, 0)
1580+ let kLpUpdateActions = $t05899459058._1
1581+ let updatedKLp = $t05899459058._2
13651582 let actions = if ((kLp != updatedKLp))
13661583 then kLpUpdateActions
13671584 else throwErr("nothing to refresh")
13681585 $Tuple2(actions, toString(updatedKLp))
13691586 }
13701587 else throw("Strict value is not equal to itself.")
13711588 }
13721589
13731590
13741591
13751592 @Callable(i)
13761593 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
13771594
13781595
13791596
13801597 @Callable(i)
13811598 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
13821599
13831600
13841601
13851602 @Callable(i)
13861603 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
13871604 let prices = calcPrices(amAmt, prAmt, lpAmt)
13881605 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
13891606 }
13901607
13911608
13921609
13931610 @Callable(i)
13941611 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
13951612
13961613
13971614
13981615 @Callable(i)
13991616 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
14001617
14011618
14021619
14031620 @Callable(i)
14041621 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
14051622
14061623
14071624
14081625 @Callable(i)
14091626 func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
14101627
14111628
14121629
14131630 @Callable(i)
14141631 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
14151632 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
14161633 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
14171634 }
14181635
14191636
14201637
14211638 @Callable(i)
14221639 func statsREADONLY () = {
14231640 let cfg = getPoolConfig()
14241641 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
14251642 let amtAssetId = cfg[idxAmtAssetId]
14261643 let priceAssetId = cfg[idxPriceAssetId]
14271644 let iAmtAssetId = cfg[idxIAmtAssetId]
14281645 let iPriceAssetId = cfg[idxIPriceAssetId]
14291646 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
14301647 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
14311648 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
14321649 let accAmtAssetBalance = getAccBalance(amtAssetId)
14331650 let accPriceAssetBalance = getAccBalance(priceAssetId)
14341651 let pricesList = if ((poolLPBalance == 0))
14351652 then [zeroBigInt, zeroBigInt, zeroBigInt]
14361653 else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
14371654 let curPrice = 0
14381655 let lpAmtAssetShare = fromX18(pricesList[1], scale8)
14391656 let lpPriceAssetShare = fromX18(pricesList[2], scale8)
14401657 let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
14411658 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(accAmtAssetBalance), toString(accPriceAssetBalance), toString(poolLPBalance), toString(curPrice), toString(lpAmtAssetShare), toString(lpPriceAssetShare), toString(poolWeight)], SEP))
14421659 }
14431660
14441661
14451662
14461663 @Callable(i)
14471664 func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
14481665 let cfg = getPoolConfig()
14491666 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
14501667 let amAssetIdStr = cfg[idxAmtAssetId]
14511668 let amAssetId = fromBase58String(amAssetIdStr)
14521669 let prAssetIdStr = cfg[idxPriceAssetId]
14531670 let prAssetId = fromBase58String(prAssetIdStr)
14541671 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
14551672 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
14561673 let poolStatus = cfg[idxPoolStatus]
14571674 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
14581675 let accAmtAssetBalance = getAccBalance(amAssetIdStr)
14591676 let accPriceAssetBalance = getAccBalance(prAssetIdStr)
14601677 let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
14611678 let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
14621679 let curPriceX18 = if ((poolLPBalance == 0))
14631680 then zeroBigInt
14641681 else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
14651682 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
14661683 let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
14671684 let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
14681685 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
14691686 let calcLpAmt = estPut._1
14701687 let curPriceCalc = estPut._3
14711688 let amBalance = estPut._4
14721689 let prBalance = estPut._5
14731690 let lpEmission = estPut._6
14741691 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(calcLpAmt), toString(fromX18(curPriceX18, scale8)), toString(amBalance), toString(prBalance), toString(lpEmission), poolStatus, toString(inAmAssetAmt), toString(inPrAssetAmt)], SEP))
14751692 }
14761693
14771694
14781695
14791696 @Callable(i)
14801697 func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
14811698 let cfg = getPoolConfig()
14821699 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
14831700 let amAssetIdStr = cfg[idxAmtAssetId]
14841701 let amAssetId = fromBase58String(amAssetIdStr)
14851702 let prAssetIdStr = cfg[idxPriceAssetId]
14861703 let prAssetId = fromBase58String(prAssetIdStr)
14871704 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
14881705 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
14891706 let poolStatus = cfg[idxPoolStatus]
14901707 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
14911708 let amBalanceRaw = getAccBalance(amAssetIdStr)
14921709 let prBalanceRaw = getAccBalance(prAssetIdStr)
14931710 let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
14941711 let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
14951712 let curPriceX18 = if ((poolLPBalance == 0))
14961713 then zeroBigInt
14971714 else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
14981715 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
14991716 let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
15001717 let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
15011718 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
15021719 let calcLpAmt = estPut._1
15031720 let curPriceCalc = estPut._3
15041721 let amBalance = estPut._4
15051722 let prBalance = estPut._5
15061723 let lpEmission = estPut._6
15071724 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(calcLpAmt), toString(fromX18(curPriceX18, scale8)), toString(amBalance), toString(prBalance), toString(lpEmission), poolStatus, toString(inAmAssetAmt), toString(inPrAssetAmt)], SEP))
15081725 }
15091726
15101727
15111728
15121729 @Callable(i)
15131730 func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
15141731 let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
15151732 let outAmAmt = res._1
15161733 let outPrAmt = res._2
15171734 let amBalance = res._5
15181735 let prBalance = res._6
15191736 let lpEmission = res._7
15201737 let curPrice = res._8
15211738 let poolStatus = parseIntValue(res._9)
15221739 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(outAmAmt), toString(outPrAmt), toString(amBalance), toString(prBalance), toString(lpEmission), toString(curPrice), toString(poolStatus)], SEP))
15231740 }
15241741
15251742
15261743 @Verifier(tx)
15271744 func verify () = {
15281745 let targetPublicKey = match managerPublicKeyOrUnit() {
15291746 case pk: ByteVector =>
15301747 pk
15311748 case _: Unit =>
15321749 tx.senderPublicKey
15331750 case _ =>
15341751 throw("Match error")
15351752 }
15361753 match tx {
15371754 case order: Order =>
15381755 let matcherPub = getMatcherPubOrFail()
1539- let $t05972459793 = validateMatcherOrderAllowed(order)
1540- let orderValid = $t05972459793._1
1541- let orderValidInfo = $t05972459793._2
1756+ let $t06772067789 = validateMatcherOrderAllowed(order)
1757+ let orderValid = $t06772067789._1
1758+ let orderValidInfo = $t06772067789._2
15421759 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
15431760 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
15441761 if (if (if (orderValid)
15451762 then senderValid
15461763 else false)
15471764 then matcherValid
15481765 else false)
15491766 then true
15501767 else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
15511768 case s: SetScriptTransaction =>
15521769 if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
15531770 then true
15541771 else {
15551772 let newHash = blake2b256(value(s.script))
15561773 let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
15571774 let currentHash = scriptHash(this)
15581775 if ((allowedHash == newHash))
15591776 then (currentHash != newHash)
15601777 else false
15611778 }
15621779 case _ =>
15631780 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
15641781 }
15651782 }
15661783

github/deemru/w8io/fabc49c 
222.30 ms