tx · CfefnKVKqYaiD2NhjymfAWA9ceujCuZsHh2u3a3hUqWM

3MrULQRLc52GWrJF1tMcAm4M78fPe57o9Kt:  -0.04200000 Waves

2023.04.13 15:39 [2532780] smart account 3MrULQRLc52GWrJF1tMcAm4M78fPe57o9Kt > SELF 0.00000000 Waves

{ "type": 13, "id": "CfefnKVKqYaiD2NhjymfAWA9ceujCuZsHh2u3a3hUqWM", "fee": 4200000, "feeAssetId": null, "timestamp": 1681389595278, "version": 2, "chainId": 84, "sender": "3MrULQRLc52GWrJF1tMcAm4M78fPe57o9Kt", "senderPublicKey": "Aig94J3pRT3J41eXw33rJrs67gTCECiMVRZrbtuoARit", "proofs": [ "3oyst9mvNfkH6bUibbXNVbKTJHDG29QYEG9ywLRYdvNgUJB91XKXB4TUTuYNirGQiTR774Jf2aoSAAWBbu4CsFpJ" ], "script": "base64:BgK9NwgCEgASBQoDAQQBEgcKBQEEAQgBEgMKAQgSABIECgIBBBIDCgEBEgQKAgEEEgQKAggBEgQKAggBEgQKAggBEgUKAwEIARIAEgQKAgEBEgMKAQESBQoDAQEBEgQKAggIEgASABIDCgEIEgUKAwEBARIECgIBARIECgIIARIECgIICBILCgkIAQECAQIIBAQSBgoECAgBCBIAEgMKAQESAwoBARIECgIIASIKbFBkZWNpbWFscyIGc2NhbGU4IgxzY2FsZThCaWdJbnQiB3NjYWxlMTgiCnplcm9CaWdJbnQiBGJpZzAiBGJpZzEiBGJpZzIiC3dhdmVzU3RyaW5nIgNTRVAiClBvb2xBY3RpdmUiD1Bvb2xQdXREaXNhYmxlZCITUG9vbE1hdGNoZXJEaXNhYmxlZCIMUG9vbFNodXRkb3duIg5pZHhQb29sQWRkcmVzcyINaWR4UG9vbFN0YXR1cyIQaWR4UG9vbExQQXNzZXRJZCINaWR4QW10QXNzZXRJZCIPaWR4UHJpY2VBc3NldElkIg5pZHhBbXRBc3NldERjbSIQaWR4UHJpY2VBc3NldERjbSIOaWR4SUFtdEFzc2V0SWQiEGlkeElQcmljZUFzc2V0SWQiDWlkeExQQXNzZXREY20iEmlkeFBvb2xBbXRBc3NldEFtdCIUaWR4UG9vbFByaWNlQXNzZXRBbXQiEWlkeFBvb2xMUEFzc2V0QW10IhlpZHhGYWN0b3J5U3Rha2luZ0NvbnRyYWN0IhppZHhGYWN0b3J5U2xpcHBhZ2VDb250cmFjdCIFdG9YMTgiB29yaWdWYWwiDW9yaWdTY2FsZU11bHQiC3RvWDE4QmlnSW50Igdmcm9tWDE4IgN2YWwiD3Jlc3VsdFNjYWxlTXVsdCIMZnJvbVgxOFJvdW5kIgVyb3VuZCIHdG9TY2FsZSIDYW10IghyZXNTY2FsZSIIY3VyU2NhbGUiA2FicyIJYWJzQmlnSW50Igxzd2FwQ29udHJhY3QiAmZjIgNtcGsiBHBtcGsiAnBsIgJwaCIBaCIJdGltZXN0YW1wIgNwYXUiC3VzZXJBZGRyZXNzIgR0eElkIgNnYXUiAmFhIgJwYSIGa2V5RmVlIgpmZWVEZWZhdWx0IgNmZWUiBmtleUtMcCIVa2V5S0xwUmVmcmVzaGVkSGVpZ2h0IhJrZXlLTHBSZWZyZXNoRGVsYXkiFmtMcFJlZnJlc2hEZWxheURlZmF1bHQiD2tMcFJlZnJlc2hEZWxheSIUa2V5QWRkaXRpb25hbEJhbGFuY2UiB2Fzc2V0SWQiFmtleVN0YWtpbmdBc3NldEJhbGFuY2UiGmdldEFkZGl0aW9uYWxCYWxhbmNlT3JaZXJvIhxnZXRTdGFraW5nQXNzZXRCYWxhbmNlT3JaZXJvIhBrZXlGYWN0b3J5Q29uZmlnIg1rZXlNYXRjaGVyUHViIilrZXlNYXBwaW5nUG9vbENvbnRyYWN0QWRkcmVzc1RvUG9vbEFzc2V0cyITcG9vbENvbnRyYWN0QWRkcmVzcyINa2V5UG9vbENvbmZpZyIJaUFtdEFzc2V0IgtpUHJpY2VBc3NldCIfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZCIMYmFzZUFzc2V0U3RyIhNrZXlBbGxQb29sc1NodXRkb3duIg1rZXlQb29sV2VpZ2h0Ig9jb250cmFjdEFkZHJlc3MiFmtleUFsbG93ZWRMcFNjcmlwdEhhc2giFmtleUZlZUNvbGxlY3RvckFkZHJlc3MiD3Rocm93T3JkZXJFcnJvciIKb3JkZXJWYWxpZCIOb3JkZXJWYWxpZEluZm8iC3NlbmRlclZhbGlkIgxtYXRjaGVyVmFsaWQiD2dldFN0cmluZ09yRmFpbCIHYWRkcmVzcyIDa2V5IgxnZXRJbnRPckZhaWwiCHRocm93RXJyIgNtc2ciBmZtdEVyciIPZmFjdG9yeUNvbnRyYWN0IhNmZWVDb2xsZWN0b3JBZGRyZXNzIgVpbkZlZSIBQCIGb3V0RmVlIhBpc0dsb2JhbFNodXRkb3duIhNnZXRNYXRjaGVyUHViT3JGYWlsIg1nZXRQb29sQ29uZmlnIghhbXRBc3NldCIKcHJpY2VBc3NldCIMcGFyc2VBc3NldElkIgVpbnB1dCIPYXNzZXRJZFRvU3RyaW5nIg9wYXJzZVBvb2xDb25maWciCnBvb2xDb25maWciEHBvb2xDb25maWdQYXJzZWQiCyR0MDg5NjI5MTI4Ig5jZmdQb29sQWRkcmVzcyINY2ZnUG9vbFN0YXR1cyIMY2ZnTHBBc3NldElkIhBjZmdBbW91bnRBc3NldElkIg9jZmdQcmljZUFzc2V0SWQiFmNmZ0Ftb3VudEFzc2V0RGVjaW1hbHMiFWNmZ1ByaWNlQXNzZXREZWNpbWFscyIQZ2V0RmFjdG9yeUNvbmZpZyIPc3Rha2luZ0NvbnRyYWN0IhBzbGlwcGFnZUNvbnRyYWN0IhFkYXRhUHV0QWN0aW9uSW5mbyINaW5BbXRBc3NldEFtdCIPaW5QcmljZUFzc2V0QW10IghvdXRMcEFtdCIFcHJpY2UiHXNsaXBwYWdlVG9sZXJhbmNlUGFzc2VkQnlVc2VyIhVzbGlwcGFnZVRvbGVyYW5jZVJlYWwiCHR4SGVpZ2h0Igt0eFRpbWVzdGFtcCISc2xpcGFnZUFtdEFzc2V0QW10IhRzbGlwYWdlUHJpY2VBc3NldEFtdCIRZGF0YUdldEFjdGlvbkluZm8iDm91dEFtdEFzc2V0QW10IhBvdXRQcmljZUFzc2V0QW10IgdpbkxwQW10Ig1nZXRBY2NCYWxhbmNlIg1iYWxhbmNlT25Qb29sIgx0b3RhbEJhbGFuY2UiD2NhbGNQcmljZUJpZ0ludCIIcHJBbXRYMTgiCGFtQW10WDE4IhRjYWxjUHJpY2VCaWdJbnRSb3VuZCIHZ2V0UmF0ZSIFcHJveHkiA2ludiIHJG1hdGNoMCIBciIHZGVwb3NpdCIGYW1vdW50Ig5zdGFraW5nQXNzZXRJZCIYY3VycmVudEFkZGl0aW9uYWxCYWxhbmNlIhpjdXJyZW50U3Rha2luZ0Fzc2V0QmFsYW5jZSIFYXNzZXQiDWRlcG9zaXRJbnZva2UiFHJlY2VpdmVkU3Rha2luZ0Fzc2V0IhRuZXdBZGRpdGlvbmFsQmFsYW5jZSIWbmV3U3Rha2luZ0Fzc2V0QmFsYW5jZSIId2l0aGRyYXciDHByb3h5UmF0ZU11bCINcHJvZml0QWRkcmVzcyIQY3VycmVudFByb3h5UmF0ZSIHb2xkUmF0ZSIMc3Rha2luZ0Fzc2V0IhRvbGRTZW5kU3Rha2luZ0Ftb3VudCIWc2VuZFN0YWtpbmdBc3NldEFtb3VudCIMcHJvZml0QW1vdW50Ig53aXRoZHJhd0ludm9rZSIOcmVjZWl2ZWRBc3NldHMiE2dldExlYXNlUHJveHlDb25maWciAWEiEXJlYmFsYW5jZUludGVybmFsIgt0YXJnZXRSYXRpbyIKbWluQmFsYW5jZSIUbGVhc2FibGVUb3RhbEJhbGFuY2UiF3RhcmdldEFkZGl0aW9uYWxCYWxhbmNlIgRkaWZmIg9zZW5kQXNzZXRBbW91bnQiDmdldEFzc2V0QW1vdW50Ig5yZWJhbGFuY2VBc3NldCINJHQwMTUzNjQxNTUwMCIKaXNMZWFzYWJsZSILbGVhc2VkUmF0aW8iDHByb3h5QWRkcmVzcyIMcHJveHlBc3NldElkIhRzdGFraW5nUHJvZml0QWRkcmVzcyIZd2l0aGRyYXdBbmRSZWJhbGFuY2VBc3NldCIJZ2V0QW1vdW50Ig0kdDAxNTg5OTE2MDM1IhduZXdUb3RhbExlYXNhYmxlQmFsYW5jZSIOd2l0aGRyYXdBbW91bnQiF3dpdGhkcmF3QW5kUmViYWxhbmNlQWxsIhRhbW91bnRBc3NldE91dEFtb3VudCITcHJpY2VBc3NldE91dEFtb3VudCISQW1BbXRXaXRoZHJhd1N0YXRlIhJQckFtdFdpdGhkcmF3U3RhdGUiEHByaXZhdGVDYWxjUHJpY2UiCmFtQXNzZXREY20iCnByQXNzZXREY20iBWFtQW10IgVwckFtdCIOYW10QXNzZXRBbXRYMTgiEHByaWNlQXNzZXRBbXRYMTgiCmNhbGNQcmljZXMiBWxwQW10IgNjZmciC2FtdEFzc2V0RGNtIg1wcmljZUFzc2V0RGNtIghwcmljZVgxOCIIbHBBbXRYMTgiE2xwUHJpY2VJbkFtQXNzZXRYMTgiE2xwUHJpY2VJblByQXNzZXRYMTgiD2NhbGN1bGF0ZVByaWNlcyIGcHJpY2VzIhRlc3RpbWF0ZUdldE9wZXJhdGlvbiIGdHhJZDU4IgpwbXRBc3NldElkIghwbXRMcEFtdCIJbHBBc3NldElkIglhbUFzc2V0SWQiCXByQXNzZXRJZCIKcG9vbFN0YXR1cyIKbHBFbWlzc2lvbiIJYW1CYWxhbmNlIgxhbUJhbGFuY2VYMTgiCXByQmFsYW5jZSIMcHJCYWxhbmNlWDE4IgtjdXJQcmljZVgxOCIIY3VyUHJpY2UiC3BtdExwQW10WDE4Ig1scEVtaXNzaW9uWDE4IgtvdXRBbUFtdFgxOCILb3V0UHJBbXRYMTgiCG91dEFtQW10IghvdXRQckFtdCIFc3RhdGUiFGVzdGltYXRlUHV0T3BlcmF0aW9uIhFzbGlwcGFnZVRvbGVyYW5jZSIMaW5BbUFzc2V0QW10IgtpbkFtQXNzZXRJZCIMaW5QckFzc2V0QW10IgtpblByQXNzZXRJZCIKaXNFdmFsdWF0ZSIGZW1pdExwIgxhbUFzc2V0SWRTdHIiDHByQXNzZXRJZFN0ciILaUFtdEFzc2V0SWQiDWlQcmljZUFzc2V0SWQiDmluQW1Bc3NldElkU3RyIg5pblByQXNzZXRJZFN0ciIPaW5BbUFzc2V0QW10WDE4Ig9pblByQXNzZXRBbXRYMTgiDHVzZXJQcmljZVgxOCIDcmVzIgtzbGlwcGFnZVgxOCIUc2xpcHBhZ2VUb2xlcmFuY2VYMTgiCnByVmlhQW1YMTgiCmFtVmlhUHJYMTgiDGV4cGVjdGVkQW10cyIRZXhwQW10QXNzZXRBbXRYMTgiE2V4cFByaWNlQXNzZXRBbXRYMTgiCWNhbGNMcEFtdCIOY2FsY0FtQXNzZXRQbXQiDmNhbGNQckFzc2V0UG10IgxzbGlwcGFnZUNhbGMiCWVtaXRMcEFtdCIGYW1EaWZmIgZwckRpZmYiC2NvbW1vblN0YXRlIgdjYWxjS0xwIg1hbW91bnRCYWxhbmNlIgxwcmljZUJhbGFuY2UiEGFtb3VudEJhbGFuY2VYMTgiD3ByaWNlQmFsYW5jZVgxOCIKdXBkYXRlZEtMcCIOY2FsY0N1cnJlbnRLTHAiEGFtb3VudEFzc2V0RGVsdGEiD3ByaWNlQXNzZXREZWx0YSIUbHBBc3NldEVtaXNzaW9uRGVsdGEiEmFtb3VudEFzc2V0QmFsYW5jZSIRcHJpY2VBc3NldEJhbGFuY2UiD2xwQXNzZXRFbWlzc2lvbiIKY3VycmVudEtMcCIScmVmcmVzaEtMcEludGVybmFsIhdhbW91bnRBc3NldEJhbGFuY2VEZWx0YSIWcHJpY2VBc3NldEJhbGFuY2VEZWx0YSIHYWN0aW9ucyISdmFsaWRhdGVVcGRhdGVkS0xwIgZvbGRLTHAiG3ZhbGlkYXRlTWF0Y2hlck9yZGVyQWxsb3dlZCIFb3JkZXIiEWFtb3VudEFzc2V0QW1vdW50IhBwcmljZUFzc2V0QW1vdW50Ig0kdDAyODMwMTI4NTEzIgNrTHAiDSR0MDI4OTUzMjkwNTMiDXVudXNlZEFjdGlvbnMiBmtMcE5ldyIMaXNPcmRlclZhbGlkIgRpbmZvIgljb21tb25HZXQiAWkiA3BtdCIGcG10QW10Igljb21tb25QdXQiCmFtQXNzZXRQbXQiCnByQXNzZXRQbXQiBmVzdFB1dCIEZW1pdCIHZW1pdEludiINZW1pdEludkxlZ2FjeSIVbGVnYWN5RmFjdG9yeUNvbnRyYWN0Igd0YWtlRmVlIglmZWVBbW91bnQiD2NhbGNQdXRPbmVUb2tlbiIQcGF5bWVudEFtb3VudFJhdyIOcGF5bWVudEFzc2V0SWQiBmlzRXZhbCIQYW1vdW50QmFsYW5jZVJhdyIPcHJpY2VCYWxhbmNlUmF3IhRwYXltZW50SW5BbW91bnRBc3NldCINJHQwMzIxNjYzMjQ1OSIQYW1vdW50QmFsYW5jZU9sZCIPcHJpY2VCYWxhbmNlT2xkIg0kdDAzMjQ2MzMyNjEyIhRhbW91bnRBc3NldEFtb3VudFJhdyITcHJpY2VBc3NldEFtb3VudFJhdyINJHQwMzI3NDQzMjgwOCINcGF5bWVudEFtb3VudCIQYW1vdW50QmFsYW5jZU5ldyIPcHJpY2VCYWxhbmNlTmV3IgtwcmljZU5ld1gxOCIIcHJpY2VOZXciDnBheW1lbnRCYWxhbmNlIhRwYXltZW50QmFsYW5jZUJpZ0ludCIMc3VwcGx5QmlnSW50IgtjaGVjaFN1cHBseSINZGVwb3NpdEJpZ0ludCILaXNzdWVBbW91bnQiC3ByaWNlT2xkWDE4IghwcmljZU9sZCIEbG9zcyINJHQwMzQ0ODkzNDY1NiIHYmFsYW5jZSIPaXNzdWVBbW91bnRCb3RoIg9jYWxjR2V0T25lVG9rZW4iCm91dEFzc2V0SWQiBmNoZWNrcyIQb3V0SW5BbW91bnRBc3NldCINYmFsYW5jZUJpZ0ludCIYb3V0SW5BbW91bnRBc3NldERlY2ltYWxzIgxhbUJhbGFuY2VPbGQiDHByQmFsYW5jZU9sZCIKb3V0QmFsYW5jZSIQb3V0QmFsYW5jZUJpZ0ludCIOcmVkZWVtZWRCaWdJbnQiCWFtb3VudFJhdyINJHQwMzY3MzQzNjc5MCILdG90YWxBbW91bnQiDSR0MDM2Nzk0MzcwMjAiC291dEFtQW1vdW50IgtvdXRQckFtb3VudCIMYW1CYWxhbmNlTmV3IgxwckJhbGFuY2VOZXciGGFtb3VudEJvdGhJblBheW1lbnRBc3NldCIWbWFuYWdlclB1YmxpY0tleU9yVW5pdCIBcyIdcGVuZGluZ01hbmFnZXJQdWJsaWNLZXlPclVuaXQiCWlzTWFuYWdlciICcGsiC211c3RNYW5hZ2VyIgJwZCINY2xlYW5BbW91bnRJbiIJaXNSZXZlcnNlIg1mZWVQb29sQW1vdW50Ig0kdDAzODkwNjM5MjExIghhc3NldE91dCIHYXNzZXRJbiIScG9vbEFzc2V0SW5CYWxhbmNlIhNwb29sQXNzZXRPdXRCYWxhbmNlIglhbW91bnRPdXQiBG9sZEsiBG5ld0siBmNoZWNrSyIMYW1vdW50T3V0TWluIglhZGRyZXNzVG8iC3N3YXBDb250YWN0IghjaGVja01pbiIOcmViYWxhbmNlU3RhdGUiDXdpdGhkcmF3U3RhdGUiF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5IgtjaGVja0NhbGxlciIVY2hlY2tNYW5hZ2VyUHVibGljS2V5IgJwbSIFaGFzUE0iB2NoZWNrUE0iD3Nob3VsZEF1dG9TdGFrZSIEYW1JZCIEcHJJZCIMc2xpcHBhZ2VBSW52IgxzbGlwcGFnZVBJbnYiCmxwVHJhbnNmZXIiC3NscFN0YWtlSW52Ig0kdDA0NDI1NzQ0NzE5IhFyZWZyZXNoS0xwQWN0aW9ucyIRaXNVcGRhdGVkS0xwVmFsaWQiA3JlYiILbWF4U2xpcHBhZ2UiDSR0MDQ1MzMxNDUzOTYiDG1pbk91dEFtb3VudCIJYXV0b1N0YWtlIiBpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZCINaXNQdXREaXNhYmxlZCIHcGF5bWVudCINJHQwNDY1ODQ0NjczNiIFYm9udXMiE2VtaXRBbW91bnRFc3RpbWF0ZWQiCmVtaXRBbW91bnQiCHN0YWtlSW52IgdzZW5kRmVlIg0kdDA0NzMyMjQ3NTE5Ig0kdDA0NzUyMjQ3NjMwIg0kdDA0Nzk4NTQ4MTQyIg1vdXRBc3NldElkU3RyIg1pc0dldERpc2FibGVkIg0kdDA0OTAyNzQ5MTgwIg9hbW91bnRFc3RpbWF0ZWQiB2J1cm5JbnYiDWFzc2V0VHJhbnNmZXIiDSR0MDQ5ODQ0NTAwOTEiEGZlZUFtb3VudEZvckNhbGMiDSR0MDUwMDk0NTAyMDIiDSR0MDUwNDgwNTA2MzYiDXVuc3Rha2VBbW91bnQiCnVuc3Rha2VJbnYiDSR0MDUxNTQxNTE2OTIiDSR0MDUyMzUxNTI1OTgiDSR0MDUyNjAxNTI3MDkiFGJ1cm5MUEFzc2V0T25GYWN0b3J5Ig0kdDA1MzgwNDUzODg1IhJub0xlc3NUaGVuQW10QXNzZXQiFG5vTGVzc1RoZW5QcmljZUFzc2V0Ig0kdDA1NDk4MDU1MDYxIg1jaGVja1BheW1lbnRzIg9jaGVja1Bvb2xTdGF0dXMiDSR0MDU2MzMzNTY0MTQiFW5vTGVzc1RoZW5BbW91bnRBc3NldCIMY2hlY2tBbW91bnRzIg0kdDA1Nzg1NTU3OTM2IgthbXRBc3NldFN0ciINcHJpY2VBc3NldFN0ciIYbGFzdFJlZnJlc2hlZEJsb2NrSGVpZ2h0Ih1jaGVja0xhc3RSZWZyZXNoZWRCbG9ja0hlaWdodCINJHQwNTkxNDA1OTIwNCIQa0xwVXBkYXRlQWN0aW9ucyIKYW10QXNzZXRJZCIMcHJpY2VBc3NldElkIg1wb29sTFBCYWxhbmNlIhJhY2NBbXRBc3NldEJhbGFuY2UiFGFjY1ByaWNlQXNzZXRCYWxhbmNlIgpwcmljZXNMaXN0Ig9scEFtdEFzc2V0U2hhcmUiEWxwUHJpY2VBc3NldFNoYXJlIgpwb29sV2VpZ2h0IgxjdXJQcmljZUNhbGMiDGFtQmFsYW5jZVJhdyIMcHJCYWxhbmNlUmF3Ig9hbUJhbGFuY2VSYXdYMTgiD3ByQmFsYW5jZVJhd1gxOCIQcGF5bWVudExwQXNzZXRJZCIMcGF5bWVudExwQW10IgJ0eCIGdmVyaWZ5Ig90YXJnZXRQdWJsaWNLZXkiCm1hdGNoZXJQdWIiDSR0MDY3ODY2Njc5MzUiB25ld0hhc2giC2FsbG93ZWRIYXNoIgtjdXJyZW50SGFzaH8AAWEACAABYgCAwtcvAAFjCQC2AgEAgMLXLwABZAkAtgIBAICAkLu61q3wDQABZQkAtgIBAAAAAWYJALYCAQAAAAFnCQC2AgEAAQABaAkAtgIBAAIAAWkCBVdBVkVTAAFqAgJfXwABawABAAFsAAIAAW0AAwABbgAEAAFvAAEAAXAAAgABcQADAAFyAAQAAXMABQABdAAGAAF1AAcAAXYACAABdwAJAAF4AAoAAXkAAQABegACAAFBAAMAAUIAAQABQwAHAQFEAgFFAUYJALwCAwkAtgIBBQFFBQFkCQC2AgEFAUYBAUcCAUUBRgkAvAIDBQFFBQFkBQFGAQFIAgFJAUoJAKADAQkAvAIDBQFJCQC2AgEFAUoFAWQBAUsDAUkBSgFMCQCgAwEJAL0CBAUBSQkAtgIBBQFKBQFkBQFMAQFNAwFOAU8BUAkAawMFAU4FAU8FAVABAVEBAUkDCQBmAgAABQFJCQEBLQEFAUkFAUkBAVIBAUkDCQC/AgIFAWUFAUkJAL4CAQUBSQUBSQEBUwACECVzX19zd2FwQ29udHJhY3QBAVQAAhMlc19fZmFjdG9yeUNvbnRyYWN0AQFVAAIUJXNfX21hbmFnZXJQdWJsaWNLZXkBAVYAAhslc19fcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkBAVcAAhElcyVzX19wcmljZV9fbGFzdAEBWAIBWQFaCQC5CQIJAMwIAgIYJXMlcyVkJWRfX3ByaWNlX19oaXN0b3J5CQDMCAIJAKQDAQUBWQkAzAgCCQCkAwEFAVoFA25pbAUBagECYWECAmFiAmFjCQCsAgIJAKwCAgkArAICAgslcyVzJXNfX1BfXwUCYWICAl9fBQJhYwECYWQCAmFiAmFjCQCsAgIJAKwCAgkArAICAgslcyVzJXNfX0dfXwUCYWICAl9fBQJhYwECYWUAAg8lc19fYW1vdW50QXNzZXQBAmFmAAIOJXNfX3ByaWNlQXNzZXQAAmFnAgclc19fZmVlAAJhaAkAawMACgUBYgCQTgACYWkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUCYWcFAmFoAAJhagkAuQkCCQDMCAICAiVzCQDMCAICA2tMcAUDbmlsBQFqAAJhawkAuQkCCQDMCAICAiVzCQDMCAICEmtMcFJlZnJlc2hlZEhlaWdodAUDbmlsBQFqAAJhbAkAuQkCCQDMCAICAiVzCQDMCAICD3JlZnJlc2hLTHBEZWxheQUDbmlsBQFqAAJhbQAeAAJhbgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQJhbAUCYW0BAmFvAQJhcAkAuQkCCQDMCAICBCVzJXMJAMwIAgINc3Rha2VkQmFsYW5jZQkAzAgCBQJhcAUDbmlsBQFqAQJhcQECYXAJALkJAgkAzAgCAgQlcyVzCQDMCAICEXNoYXJlQXNzZXRCYWxhbmNlCQDMCAIFAmFwBQNuaWwFAWoBAmFyAQJhcAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYW8BBQJhcAAAAQJhcwECYXAJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmFxAQUCYXAAAAECYXQAAhElc19fZmFjdG9yeUNvbmZpZwECYXUAAhglcyVzX19tYXRjaGVyX19wdWJsaWNLZXkBAmF2AQJhdwkArAICCQCsAgICCCVzJXMlc19fBQJhdwIgX19tYXBwaW5nc19fcG9vbENvbnRyYWN0MkxwQXNzZXQBAmF4AgJheQJhegkArAICCQCsAgIJAKwCAgkArAICAgglZCVkJXNfXwUCYXkCAl9fBQJhegIIX19jb25maWcBAmFBAQJhQgkArAICAiglcyVzJXNfX21hcHBpbmdzX19iYXNlQXNzZXQyaW50ZXJuYWxJZF9fBQJhQgECYUMAAgwlc19fc2h1dGRvd24BAmFEAQJhRQkArAICAhIlcyVzX19wb29sV2VpZ2h0X18FAmFFAQJhRgACFyVzX19hbGxvd2VkTHBTY3JpcHRIYXNoAAJhRwIXJXNfX2ZlZUNvbGxlY3RvckFkZHJlc3MBAmFIBAJhSQJhSgJhSwJhTAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAiRvcmRlciB2YWxpZGF0aW9uIGZhaWxlZDogb3JkZXJWYWxpZD0JAKUDAQUCYUkCAiAoBQJhSgIBKQINIHNlbmRlclZhbGlkPQkApQMBBQJhSwIOIG1hdGNoZXJWYWxpZD0JAKUDAQUCYUwBAmFNAgJhTgJhTwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFAmFOBQJhTwkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQJhTgkAzAgCAgEuCQDMCAIFAmFPCQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABAmFQAgJhTgJhTwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFAmFOBQJhTwkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQJhTgkAzAgCAgEuCQDMCAIFAmFPCQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABAmFRAQJhUgkAAgEJALkJAgkAzAgCAghscC5yaWRlOgkAzAgCBQJhUgUDbmlsAgEgAQJhUwECYVIJALkJAgkAzAgCAghscC5yaWRlOgkAzAgCBQJhUgUDbmlsAgEgAAJhVAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFNAgUEdGhpcwkBAVQAAAJhVQkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFNAgUCYVQFAmFHAAJhVgoAAmFXCQD8BwQFAmFUAhBnZXRJbkZlZVJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYVcCA0ludAUCYVcJAAIBCQCsAgIJAAMBBQJhVwIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AAJhWAoAAmFXCQD8BwQFAmFUAhFnZXRPdXRGZWVSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFXAgNJbnQFAmFXCQACAQkArAICCQADAQUCYVcCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAECYVkACQELdmFsdWVPckVsc2UCCQCbCAIFAmFUCQECYUMABwECYVoACQDZBAEJAQJhTQIFAmFUCQECYXUAAQJiYQAEAmJiCQECYU0CBQR0aGlzCQECYWUABAJiYwkBAmFNAgUEdGhpcwkBAmFmAAQCYXoJAQJhUAIFAmFUCQECYUEBBQJiYwQCYXkJAQJhUAIFAmFUCQECYUEBBQJiYgkAtQkCCQECYU0CBQJhVAkBAmF4AgkApAMBBQJheQkApAMBBQJhegUBagECYmQBAmJlAwkAAAIFAmJlBQFpBQR1bml0CQDZBAEFAmJlAQJiZgECYmUDCQAAAgUCYmUFBHVuaXQFAWkJANgEAQkBBXZhbHVlAQUCYmUBAmJnAQJiaAkAmQoHCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFAmJoBQFvCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYmgFAXAJANkEAQkAkQMCBQJiaAUBcQkBAmJkAQkAkQMCBQJiaAUBcgkBAmJkAQkAkQMCBQJiaAUBcwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJoBQF0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYmgFAXUAAmJpCQECYmcBCQECYmEAAAJiagUCYmkAAmJrCAUCYmoCXzEAAmJsCAUCYmoCXzIAAmJtCAUCYmoCXzMAAmJuCAUCYmoCXzQAAmJvCAUCYmoCXzUAAmJwCAUCYmoCXzYAAmJxCAUCYmoCXzcBAmJyAAkAtQkCCQECYU0CBQJhVAkBAmF0AAUBagACYnMJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIJAQJicgAFAUICGWluY29ycmVjdCBzdGFraW5nIGFkZHJlc3MAAmJ0CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCCQECYnIABQFDAhlpbmNvcnJlY3Qgc3Rha2luZyBhZGRyZXNzAQJidQoCYnYCYncCYngCYnkCYnoCYkECYkICYkMCYkQCYkUJALkJAgkAzAgCAhQlZCVkJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmJ2CQDMCAIJAKQDAQUCYncJAMwIAgkApAMBBQJieAkAzAgCCQCkAwEFAmJ5CQDMCAIJAKQDAQUCYnoJAMwIAgkApAMBBQJiQQkAzAgCCQCkAwEFAmJCCQDMCAIJAKQDAQUCYkMJAMwIAgkApAMBBQJiRAkAzAgCCQCkAwEFAmJFBQNuaWwFAWoBAmJGBgJiRwJiSAJiSQJieQJiQgJiQwkAuQkCCQDMCAICDCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmJHCQDMCAIJAKQDAQUCYkgJAMwIAgkApAMBBQJiSQkAzAgCCQCkAwEFAmJ5CQDMCAIJAKQDAQUCYkIJAMwIAgkApAMBBQJiQwUDbmlsBQFqAQJiSgECYXAEAmJLAwkAAAIFAmFwAgVXQVZFUwgJAO8HAQUEdGhpcwlhdmFpbGFibGUJAPAHAgUEdGhpcwkA2QQBBQJhcAQCYkwJAGUCCQBkAgUCYksJAQJhcgEFAmFwCQECYXMBBQJhcAkAlgMBCQDMCAIAAAkAzAgCBQJiTAUDbmlsAQJiTQICYk4CYk8JALwCAwUCYk4FAWQFAmJPAQJiUAMCYk4CYk8BTAkAvQIEBQJiTgUBZAUCYk8FAUwBAmJRAQJiUgQCYlMJAPwHBAUCYlICB2dldFJhdGUFA25pbAUDbmlsAwkAAAIFAmJTBQJiUwQCYlQFAmJTAwkAAQIFAmJUAgNJbnQEAmJVBQJiVAUCYlUJAQJhUQECIHByb3h5LmdldFJhdGUoKSB1bmV4cGVjdGVkIHZhbHVlCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJiVgQCYXACYlcCYlgCYlIEAmJZCQECYXIBBQJhcAMJAAACBQJiWQUCYlkEAmJaCQECYXMBBQJiWAMJAAACBQJiWgUCYloEAmNhCQECYmQBBQJhcAMJAGYCBQJiVwAABAJjYgkA/AcEBQJiUgIHZGVwb3NpdAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJjYQUCYlcFA25pbAMJAAACBQJjYgUCY2IEAmJUBQJjYgMJAAECBQJiVAIDSW50BAJjYwUCYlQEAmNkCQBkAgUCYlkFAmJXBAJjZQkAZAIFAmJaBQJjYwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFvAQUCYXAFAmNkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXEBBQJiWAUCY2UFA25pbAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmNmBgJhcAJiVwJiWAJiUgJjZwJjaAQCYlkJAQJhcgEFAmFwAwkAAAIFAmJZBQJiWQQCYloJAQJhcwEFAmJYAwkAAAIFAmJaBQJiWgQCY2kJAQJiUQEFAmJSAwkAAAIFAmNpBQJjaQQCY2oJAGsDBQJjZwUCYlkFAmJaBAJjawkBAmJkAQUCYlgEAmNsCQBrAwUCY2cFAmJXBQJjagQCY20JAGsDBQJjZwUCYlcFAmNpBAJjbgkAlgMBCQDMCAIAAAkAzAgCCQBlAgUCY2wFAmNtBQNuaWwDCQBmAgUCY20AAAQCY28JAPwHBAUCYlICCHdpdGhkcmF3BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmNrBQJjbQUDbmlsAwkAAAIFAmNvBQJjbwQCYlQFAmNvAwkAAQIFAmJUAgNJbnQEAmNwBQJiVAQCY2QJAGUCBQJiWQUCY3AEAmNlCQBlAgkAZQIFAmJaBQJjbQUCY24JAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhbwEFAmFwBQJjZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFxAQUCYlgFAmNlCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmNoBQJjbgkBAmJkAQUCYlgFA25pbAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmNxAQJhcAQCYlQJAPwHBAUCYVQCGmdldFBvb2xMZWFzZUNvbmZpZ1JFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwkAzAgCBQJhcAUDbmlsBQNuaWwDCQABAgUCYlQCMChCb29sZWFuLCBJbnQsIEludCwgU3RyaW5nLCBTdHJpbmcsIEludCwgU3RyaW5nKQQCY3IFAmJUBQJjcgkBAmFRAQkArAICCQCsAgICAVsFAmFwAh1dIGdldExlYXNlUHJveHlDb25maWcoKSBlcnJvcgECY3MHAmN0AmFwAmJYAmN1AmJSAmNnAmNoBAJiWQkBAmFyAQUCYXADCQAAAgUCYlkFAmJZBAJiWgkBAmFzAQUCYlgDCQAAAgUCYloFAmJaBAJjdgkAlgMBCQDMCAIAAAkAzAgCCQBlAgkBAmJKAQUCYXAFAmN1BQNuaWwEAmN3CQBrAwUCY3QFAmN2AGQEAmN4CQBlAgUCYlkFAmN3AwkAAAIFAmN4AAAFA25pbAMJAGYCAAAFAmN4BAJjeQkBAS0BBQJjeAkBAmJWBAUCYXAFAmN5BQJiWAUCYlIEAmN6BQJjeAkBAmNmBgUCYXAFAmN6BQJiWAUCYlIFAmNnBQJjaAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY0EBAmFwBAJjQgkBAmNxAQUCYXAEAmNDCAUCY0ICXzEEAmNECAUCY0ICXzIEAmN1CAUCY0ICXzMEAmNFCAUCY0ICXzQEAmNGCAUCY0ICXzUEAmNnCAUCY0ICXzYEAmNHCAUCY0ICXzcDBQJjQwkBAmNzBwUCY0QFAmFwBQJjRgUCY3UJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmNFBQJjZwkBEUBleHRyTmF0aXZlKDEwNjIpAQUCY0cFA25pbAECY0gCAmFwAmNJBAJjSgkBAmNxAQUCYXAEAmNDCAUCY0oCXzEEAmNECAUCY0oCXzIEAmN1CAUCY0oCXzMEAmNFCAUCY0oCXzQEAmNGCAUCY0oCXzUEAmNnCAUCY0oCXzYEAmNHCAUCY0oCXzcDBQJjQwQCY0sJAJYDAQkAzAgCAAAJAMwIAgkAZQIJAGUCCQECYkoBBQJhcAUCY0kFAmN1BQNuaWwDCQAAAgUCY0sFAmNLBAJjZAkAawMFAmNEBQJjSwBkAwkAAAIFAmNkBQJjZAQCY0wJAGUCCQECYXIBBQJhcAUCY2QDCQAAAgUCY0wFAmNMAwkAZgIAAAUCY0wJAQJiVgQFAmFwCQEBLQEFAmNMBQJjRgkBEUBleHRyTmF0aXZlKDEwNjIpAQUCY0UJAQJjZgYFAmFwBQJjTAUCY0YJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmNFBQJjZwkBEUBleHRyTmF0aXZlKDEwNjIpAQUCY0cJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAECY00CAmNOAmNPBAJjUAkBAmNIAgkBAmFNAgUEdGhpcwkBAmFlAAUCY04EAmNRCQECY0gCCQECYU0CBQR0aGlzCQECYWYABQJjTwkAzggCBQJjUAUCY1EBAmNSBAJjUwJjVAJjVQJjVgQCY1cJAQFEAgUCY1UFAmNTBAJjWAkBAUQCBQJjVgUCY1QJAQJiTQIFAmNYBQJjVwECY1kDAmNVAmNWAmNaBAJkYQkBAmJhAAQCZGIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkYQUBdAQCZGMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkYQUBdQQCZGQJAQJjUgQFAmRiBQJkYwUCY1UFAmNWBAJiTwkBAUQCBQJjVQUCZGIEAmJOCQEBRAIFAmNWBQJkYwQCZGUJAQFEAgUCY1oFAWIEAmRmCQECYk0CBQJiTwUCZGUEAmRnCQECYk0CBQJiTgUCZGUJAMwIAgUCZGQJAMwIAgUCZGYJAMwIAgUCZGcFA25pbAECZGgDAmNVAmNWAmNaBAJkaQkBAmNZAwUCY1UFAmNWBQJjWgkAzAgCCQEBSAIJAJEDAgUCZGkAAAUBYgkAzAgCCQEBSAIJAJEDAgUCZGkAAQUBYgkAzAgCCQEBSAIJAJEDAgUCZGkAAgUBYgUDbmlsAQJkagQCZGsCZGwCZG0CYWIEAmRhCQECYmEABAJkbgkAkQMCBQJkYQUBcQQCZG8JAJEDAgUCZGEFAXIEAmRwCQCRAwIFAmRhBQFzBAJjUwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRhBQF0BAJjVAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRhBQF1BAJkcQkAkQMCBQJkYQUBcAQCZHIICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQkA2QQBBQJkbgkArAICCQCsAgICBkFzc2V0IAUCZG4CDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5AwkBAiE9AgUCZG4FAmRsCQACAQIVSW52YWxpZCBhc3NldCBwYXNzZWQuBAJkcwkBAmJKAQUCZG8EAmR0CQEBRAIFAmRzBQJjUwQCZHUJAQJiSgEFAmRwBAJkdgkBAUQCBQJkdQUCY1QEAmR3CQECYk0CBQJkdgUCZHQEAmR4CQEBSAIFAmR3BQFiBAJkeQkBAUQCBQJkbQUBYgQCZHoJAQFEAgUCZHIFAWIEAmRBCQC8AgMFAmR0BQJkeQUCZHoEAmRCCQC8AgMFAmR2BQJkeQUCZHoEAmRDCQEBSwMFAmRBBQJjUwUFRkxPT1IEAmRECQEBSwMFAmRCBQJjVAUFRkxPT1IEAmRFAwkAAAIFAmRrAgAFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhYgUCZEMDCQAAAgUCZG8CBVdBVkVTBQR1bml0CQDZBAEFAmRvCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFiBQJkRAMJAAACBQJkcAIFV0FWRVMFBHVuaXQJANkEAQUCZHAJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFkAgkApQgBBQJhYgUCZGsJAQJiRgYFAmRDBQJkRAUCZG0FAmR4BQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVwAFAmR4CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBWAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmR4BQNuaWwJAJwKCgUCZEMFAmREBQJkbwUCZHAFAmRzBQJkdQUCZHIFAmR3BQJkcQUCZEUBAmRGCQJkawJkRwJkSAJkSQJkSgJkSwJhYgJkTAJkTQQCZGEJAQJiYQAEAmRuCQDZBAEJAJEDAgUCZGEFAXEEAmROCQCRAwIFAmRhBQFyBAJkTwkAkQMCBQJkYQUBcwQCZFAJAJEDAgUCZGEFAXYEAmRRCQCRAwIFAmRhBQF3BAJkYgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRhBQF0BAJkYwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRhBQF1BAJkcQkAkQMCBQJkYQUBcAQCZHIICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCZG4JAKwCAgkArAICAgZBc3NldCAJANgEAQUCZG4CDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJkUgkA2AQBCQELdmFsdWVPckVsc2UCBQJkSQkA2QQBAgVXQVZFUwQCZFMJANgEAQkBC3ZhbHVlT3JFbHNlAgUCZEsJANkEAQIFV0FWRVMDAwkBAiE9AgUCZE4FAmRSBgkBAiE9AgUCZE8FAmRTCQACAQIiSW52YWxpZCBhbXQgb3IgcHJpY2UgYXNzZXQgcGFzc2VkLgQCZHMDBQJkTAkBAmJKAQUCZE4JAGUCCQECYkoBBQJkTgUCZEgEAmR1AwUCZEwJAQJiSgEFAmRPCQBlAgkBAmJKAQUCZE8FAmRKBAJkVAkBAUQCBQJkSAUCZGIEAmRVCQEBRAIFAmRKBQJkYwQCZFYJAQJiTQIFAmRVBQJkVAQCZHQJAQFEAgUCZHMFAmRiBAJkdgkBAUQCBQJkdQUCZGMEAmRXAwkAAAIFAmRyAAAEAmR3BQFlBAJkWAUBZQQCZGUJAHYGCQC5AgIFAmRUBQJkVQAACQC2AgEABQABAAAFBERPV04JAJcKBQkBAUgCBQJkZQUBYgkBAUgCBQJkVAUCZGIJAQFIAgUCZFUFAmRjCQECYk0CCQC3AgIFAmR2BQJkVQkAtwICBQJkdAUCZFQFAmRYBAJkdwkBAmJNAgUCZHYFAmR0BAJkWAkAvAIDCQEBUgEJALgCAgUCZHcFAmRWBQFkBQJkdwQCZFkJAQFEAgUCZEcFAWIDAwkBAiE9AgUCZHcFAWUJAL8CAgUCZFgFAmRZBwkAAgEJAKwCAgkArAICCQCsAgICD1ByaWNlIHNsaXBwYWdlIAkApgMBBQJkWAIeIGV4Y2VlZGVkIHRoZSBwYXNzZWQgbGltaXQgb2YgCQCmAwEFAmRZBAJkegkBAUQCBQJkcgUBYgQCZFoJAL0CBAUCZFQJAQJiUAMFAmR2BQJkdAUHQ0VJTElORwUBZAUHQ0VJTElORwQCZWEJAL0CBAUCZFUFAWQJAQJiUAMFAmR2BQJkdAUFRkxPT1IFB0NFSUxJTkcEAmViAwkAvwICBQJkWgUCZFUJAJQKAgUCZWEFAmRVCQCUCgIFAmRUBQJkWgQCZWMIBQJlYgJfMQQCZWQIBQJlYgJfMgQCZGUJAL0CBAUCZHoFAmVkBQJkdgUFRkxPT1IJAJcKBQkBAUsDBQJkZQUBYgUFRkxPT1IJAQFLAwUCZWMFAmRiBQdDRUlMSU5HCQEBSwMFAmVkBQJkYwUHQ0VJTElORwUCZHcFAmRYBAJlZQgFAmRXAl8xBAJlZggFAmRXAl8yBAJlZwgFAmRXAl8zBAJkeAkBAUgCCAUCZFcCXzQFAWIEAmVoCQEBSAIIBQJkVwJfNQUBYgMJAGcCAAAFAmVlCQACAQI2SW52YWxpZCBjYWxjdWxhdGlvbnMuIExQIGNhbGN1bGF0ZWQgaXMgbGVzcyB0aGFuIHplcm8uBAJlaQMJAQEhAQUCZE0AAAUCZWUEAmVqCQBlAgUCZEgFAmVmBAJlawkAZQIFAmRKBQJlZwQCZWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZHgJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZHgJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFhAgUCYWIFAmRrCQECYnUKBQJlZgUCZWcFAmVpBQJkeAUCZEcFAmVoBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJlagUCZWsFA25pbAkAnwoNBQJlZQUCZWkFAmR4BQJkcwUCZHUFAmRyBQJkbgUCZHEFAmVsBQJlagUCZWsFAmRJBQJkSwECZW0DAmVuAmVvAmRyBAJlcAkBAUcCBQJlbgkAtgIBBQJicAQCZXEJAQFHAgUCZW8JALYCAQUCYnEEAmVyCQC8AgMJAHYGCQC5AgIFAmVwBQJlcQAACQC2AgEABQABABIFBERPV04FAWcFAmRyAwkAAAIFAmRyBQFmBQFmBQJlcgECZXMDAmV0AmV1AmV2BAJldwkAuAICCQC2AgEJAQJiSgEJAQJiZgEFAmJuBQJldAQCZXgJALgCAgkAtgIBCQECYkoBCQECYmYBBQJibwUCZXUEAmV5CQC4AgIJALYCAQgJAQV2YWx1ZQEJAOwHAQUCYm0IcXVhbnRpdHkFAmV2BAJlegkBAmVtAwUCZXcFAmV4BQJleQUCZXoBAmVBAwJlQgJlQwJldgQCZXcJAGQCCQECYkoBCQECYmYBBQJibgUCZUIEAmV4CQBkAgkBAmJKAQkBAmJmAQUCYm8FAmVDBAJleQkAZAIICQEFdmFsdWUBCQDsBwEFAmJtCHF1YW50aXR5BQJldgQCZXIJAQJlbQMJALYCAQUCZXcJALYCAQUCZXgJALYCAQUCZXkEAmVECQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJhawUGaGVpZ2h0CQDMCAIJAQtTdHJpbmdFbnRyeQIFAmFqCQCmAwEFAmVyBQNuaWwJAJQKAgUCZUQFAmVyAQJlRQICZUYCZXIDCQDAAgIFAmVyBQJlRgYJAQJhUQEJALkJAgkAzAgCAiJ1cGRhdGVkIEtMcCBsb3dlciB0aGFuIGN1cnJlbnQgS0xwCQDMCAIJAKYDAQUCZUYJAMwIAgkApgMBBQJlcgUDbmlsAgEgAQJlRwECZUgEAmV3CQECYkoBCQECYmYBBQJibgQCZXgJAQJiSgEJAQJiZgEFAmJvBAJlSQgFAmVIBmFtb3VudAQCZUoJAG4ECAUCZUgGYW1vdW50CAUCZUgFcHJpY2UFAWIFBUZMT09SBAJlSwMJAAACCAUCZUgJb3JkZXJUeXBlBQNCdXkJAJQKAgUCZUkJAQEtAQUCZUoJAJQKAgkBAS0BBQJlSQUCZUoEAmVCCAUCZUsCXzEEAmVDCAUCZUsCXzIDAwMJAQJhWQAGCQAAAgUCYmwFAW0GCQAAAgUCYmwFAW4JAAIBAhxFeGNoYW5nZSBvcGVyYXRpb25zIGRpc2FibGVkAwMJAQIhPQIICAUCZUgJYXNzZXRQYWlyC2Ftb3VudEFzc2V0BQJibgYJAQIhPQIICAUCZUgJYXNzZXRQYWlyCnByaWNlQXNzZXQFAmJvCQACAQITV3Jvbmcgb3JkZXIgYXNzZXRzLgQCZUwJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAqAMBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAmFqAgEwCQECYVMBAgtpbnZhbGlkIGtMcAQCZU0JAQJlQQMFAmVCBQJlQwAABAJlTggFAmVNAl8xBAJlTwgFAmVNAl8yBAJlUAkAwAICBQJlTwUCZUwEAmVRCQC5CQIJAMwIAgIEa0xwPQkAzAgCCQCmAwEFAmVMCQDMCAICCCBrTHBOZXc9CQDMCAIJAKYDAQUCZU8JAMwIAgIUIGFtb3VudEFzc2V0QmFsYW5jZT0JAMwIAgkApAMBBQJldwkAzAgCAhMgcHJpY2VBc3NldEJhbGFuY2U9CQDMCAIJAKQDAQUCZXgJAMwIAgIZIGFtb3VudEFzc2V0QmFsYW5jZURlbHRhPQkAzAgCCQCkAwEFAmVCCQDMCAICGCBwcmljZUFzc2V0QmFsYW5jZURlbHRhPQkAzAgCCQCkAwEFAmVDCQDMCAICCCBoZWlnaHQ9CQDMCAIJAKQDAQUGaGVpZ2h0BQNuaWwCAAkAlAoCBQJlUAUCZVEBAmVSAQJlUwMJAQIhPQIJAJADAQgFAmVTCHBheW1lbnRzAAEJAAIBAh1leGFjdGx5IDEgcGF5bWVudCBpcyBleHBlY3RlZAQCZVQJAQV2YWx1ZQEJAJEDAggFAmVTCHBheW1lbnRzAAAEAmRsCQEFdmFsdWUBCAUCZVQHYXNzZXRJZAQCZVUIBQJlVAZhbW91bnQEAmRXCQECZGoECQDYBAEIBQJlUw10cmFuc2FjdGlvbklkCQDYBAEFAmRsBQJlVQgFAmVTBmNhbGxlcgQCZEMIBQJkVwJfMQQCZEQIBQJkVwJfMgQCZHEJAQ1wYXJzZUludFZhbHVlAQgFAmRXAl85BAJkRQgFAmRXA18xMAMDCQECYVkABgkAAAIFAmRxBQFuCQACAQkArAICAixHZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4uIFN0YXR1cyA9IAkApAMBBQJkcQkAlwoFBQJkQwUCZEQFAmVVBQJkbAUCZEUBAmVWAwJlUwJkRwJkTQMJAQIhPQIJAJADAQgFAmVTCHBheW1lbnRzAAIJAAIBAh9leGFjdGx5IDIgcGF5bWVudHMgYXJlIGV4cGVjdGVkBAJlVwkBBXZhbHVlAQkAkQMCCAUCZVMIcGF5bWVudHMAAAQCZVgJAQV2YWx1ZQEJAJEDAggFAmVTCHBheW1lbnRzAAEEAmVZCQECZEYJCQDYBAEIBQJlUw10cmFuc2FjdGlvbklkBQJkRwgFAmVXBmFtb3VudAgFAmVXB2Fzc2V0SWQIBQJlWAZhbW91bnQIBQJlWAdhc3NldElkCQClCAEIBQJlUwZjYWxsZXIHBQJkTQQCZHEJAQ1wYXJzZUludFZhbHVlAQgFAmVZAl84AwMDCQECYVkABgkAAAIFAmRxBQFsBgkAAAIFAmRxBQFuCQACAQkArAICAixQdXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4uIFN0YXR1cyA9IAkApAMBBQJkcQUCZVkBAmVaAQJiVwQCZmEJAPwHBAUCYVQCBGVtaXQJAMwIAgUCYlcFA25pbAUDbmlsAwkAAAIFAmZhBQJmYQQCZmIEAmJUBQJmYQMJAAECBQJiVAIHQWRkcmVzcwQCZmMFAmJUCQD8BwQFAmZjAgRlbWl0CQDMCAIFAmJXBQNuaWwFA25pbAUEdW5pdAMJAAACBQJmYgUCZmIFAmJXCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJmZAICYlcCYWkEAmZlAwkAAAIFAmFpAAAAAAkAawMFAmJXBQJhaQUBYgkAlAoCCQBlAgUCYlcFAmZlBQJmZQECZmYEAmZnAmZoAmFiAmFjBAJmaQkAAAIFAmFjBQR1bml0BAJmagkBAmJKAQkBAmJmAQUCYm4EAmZrCQECYkoBCQECYmYBBQJibwQCZmwDCQAAAgUCZmgFAmJuBgMJAAACBQJmaAUCYm8HCQECYVEBAg1pbnZhbGlkIGFzc2V0BAJmbQMFAmZpCQCUCgIFAmZqBQJmawMFAmZsCQCUCgIJAGUCBQJmagUCZmcFAmZrCQCUCgIFAmZqCQBlAgUCZmsFAmZnBAJmbggFAmZtAl8xBAJmbwgFAmZtAl8yBAJmcAMFAmZsCQCUCgIFAmZnAAAJAJQKAgAABQJmZwQCZnEIBQJmcAJfMQQCZnIIBQJmcAJfMgQCZUkICQECZmQCBQJmcQUCYVYCXzEEAmVKCAkBAmZkAgUCZnIFAmFWAl8xBAJmcwkBAmZkAgUCZmcFAmFWBAJmdAgFAmZzAl8xBAJmZQgFAmZzAl8yBAJmdQkAZAIFAmZuBQJlSQQCZnYJAGQCBQJmbwUCZUoEAmZ3CQECYk0CCQEBRAIFAmZ2BQJicQkBAUQCBQJmdQUCYnAEAmZ4CQEBSAIFAmZ3BQFiBAJmeQMFAmZsBQJmbgUCZm8EAmZ6CQC2AgEFAmZ5BAJmQQkAtgIBCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmJtCQCsAgIJAKwCAgIGYXNzZXQgCQDYBAEFAmJtAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCZkIDCQC/AgIFAmZBBQFmBgkBAmFRAQIiaW5pdGlhbCBkZXBvc2l0IHJlcXVpcmVzIGFsbCBjb2lucwMJAAACBQJmQgUCZkIEAmZDCQC2AgEFAmZ0BAJmRAkAlgMBCQDMCAIAAAkAzAgCCQCgAwEJALoCAgkAuQICBQJmQQkAuAICCQEKc3FydEJpZ0ludAQJALcCAgUBZAkAugICCQC5AgIFAmZDBQFkBQJmegASABIFBERPV04FAWQFAWQFA25pbAQCZWwDBQJmaQUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVwAFAmZ4CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBWAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmZ4CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhYQIJAKUIAQkBBXZhbHVlAQUCYWIJANgEAQkBBXZhbHVlAQUCYWMJAQJidQoFAmZxBQJmcgUCZkQFAmZ4AAAAAAUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAAAAAAFA25pbAQCZkUJAQJiTQIJAQFEAgUCZm8FAmJxCQEBRAIFAmZuBQJicAQCZkYJAQFIAgUCZkUFAWIEAmZHBAJmSAMFAmZsCQCUCgIFAmZxBQJmbgkAlAoCBQJmcgUCZm8EAmJXCAUCZkgCXzEEAmZJCAUCZkgCXzIEAmZKCQCgAwEJALwCAwUCZkEJALYCAQkAaQIFAmJXAAIJALYCAQUCZkkJAGsDCQBlAgUCZkQFAmZKBQFiBQJmSgkAlwoFBQJmRAUCZWwFAmZlBQJmRwUCZmwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmZLBQJmTAJmdAJmaAJhYgJhYwQCZmkJAAACBQJhYwUEdW5pdAQCZGEJAQJiYQAEAmRiCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGEFAXQEAmRjCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGEFAXUEAmZNCQDMCAIDCQAAAgUCZmgFAmJtBgkBAmFRAQIQaW52YWxpZCBscCBhc3NldAUDbmlsAwkAAAIFAmZNBQJmTQQCZk4DCQAAAgUCZkwFAmJuBgMJAAACBQJmTAUCYm8HCQECYVEBAg1pbnZhbGlkIGFzc2V0BAJmTwMFAmZOCQC2AgEJAQJiSgEJAQJiZgEFAmJuCQC2AgEJAQJiSgEJAQJiZgEFAmJvBAJmUAMFAmZOBQJkYgUCZGMEAmZRCQECYkoBCQECYmYBBQJibgQCZlIJAQJiSgEJAQJiZgEFAmJvBAJmUwMFAmZOBQJmUQUCZlIEAmZUCQC2AgEFAmZTBAJmQQkAtgIBCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmJtCQCsAgIJAKwCAgIGYXNzZXQgCQDYBAEFAmJtAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCZlUJALYCAQUCZnQEAmZWCQCWAwEJAMwIAgAACQDMCAIJAKADAQkAugICCQC5AgIFAmZPCQC4AgIFAWQJAHYGCQC4AgIFAWQJALoCAgkAuQICBQJmVQUBZAUCZkEAEgUBaAAAABIFBERPV04FAWQFA25pbAQCZlcJAQJmZAIFAmZWBQJhWAQCZlgIBQJmVwJfMQQCZmUIBQJmVwJfMgQCZlkDBQJmTgkAlgoEBQJmWAAACQBlAgUCZlEFAmZWBQJmUgkAlgoEAAAFAmZYBQJmUQkAZQIFAmZSBQJmVgQCZloIBQJmWQJfMQQCZ2EIBQJmWQJfMgQCZ2IIBQJmWQJfMwQCZ2MIBQJmWQJfNAQCZncJAQJiTQIJAQFEAgUCZ2MFAmJxCQEBRAIFAmdiBQJicAQCZngJAQFIAgUCZncFAWIEAmVsAwUCZmkFA25pbAkAzAgCCQELU3RyaW5nRW50cnkCCQECYWQCCQClCAEJAQV2YWx1ZQEFAmFiCQDYBAEJAQV2YWx1ZQEFAmFjCQECYkYGBQJmWgUCZ2EFAmZ0BQJmeAUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVcABQJmeAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVgCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJmeAUDbmlsBAJmRQkBAmJNAgkBAUQCBQJmUgUCYnEJAQFEAgUCZlEFAmJwBAJmRgkBAUgCBQJmRQUBYgQCZkcEAmdkCQBoAgkAoAMBCQC8AgMFAmZPBQJmVQUCZkEAAgkAawMJAGUCBQJmWAUCZ2QFAWIFAmdkCQCXCgUFAmZYBQJlbAUCZmUFAmZHBQJmTgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZ2UABAJiVAkAoggBCQEBVQADCQABAgUCYlQCBlN0cmluZwQCZ2YFAmJUCQDZBAEFAmdmAwkAAQIFAmJUAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmdnAAQCYlQJAKIIAQkBAVYAAwkAAQIFAmJUAgZTdHJpbmcEAmdmBQJiVAkA2QQBBQJnZgMJAAECBQJiVAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJnaAECZVMEAmJUCQECZ2UAAwkAAQIFAmJUAgpCeXRlVmVjdG9yBAJnaQUCYlQJAAACCAUCZVMPY2FsbGVyUHVibGljS2V5BQJnaQMJAAECBQJiVAIEVW5pdAkAAAIIBQJlUwZjYWxsZXIFBHRoaXMJAAIBAgtNYXRjaCBlcnJvcgECZ2oBAmVTBAJnawkAAgECEVBlcm1pc3Npb24gZGVuaWVkBAJiVAkBAmdlAAMJAAECBQJiVAIKQnl0ZVZlY3RvcgQCZ2kFAmJUAwkAAAIIBQJlUw9jYWxsZXJQdWJsaWNLZXkFAmdpBgUCZ2sDCQABAgUCYlQCBFVuaXQDCQAAAggFAmVTBmNhbGxlcgUEdGhpcwYFAmdrCQACAQILTWF0Y2ggZXJyb3IeAmVTAQlyZWJhbGFuY2UACQDOCAIJAQJjQQEJAQJhTQIFBHRoaXMJAQJhZQAJAQJjQQEJAQJhTQIFBHRoaXMJAQJhZgACZVMBIWNhbGN1bGF0ZUFtb3VudE91dEZvclN3YXBSRUFET05MWQMCZ2wCZ20CZ24EAmdvAwkAAAIFAmdtBwQCZ3AJAQJhTQIFBHRoaXMJAQJhZgAEAmdxCQECYU0CBQR0aGlzCQECYWUACQCUCgIFAmdwBQJncQQCZ3AJAQJhTQIFBHRoaXMJAQJhZQAEAmdxCQECYU0CBQR0aGlzCQECYWYACQCUCgIFAmdwBQJncQQCZ3AIBQJnbwJfMQQCZ3EIBQJnbwJfMgQCZ3IJAQJiSgEFAmdxBAJncwkBAmJKAQUCZ3AEAmd0CQBrAwUCZ3MFAmdsCQBkAgUCZ3IFAmdsBAJndQkAuQICCQC2AgEFAmdyCQC2AgEFAmdzBAJndgkAuQICCQC3AgIJALcCAgkAtgIBCQECYkoBBQJncQkAtgIBBQJnbAkAtgIBBQJnbgkAuAICCQC2AgEJAQJiSgEFAmdwCQC2AgEFAmd0BAJndwMJAMACAgUCZ3YFAmd1BgkAAgECFG5ldyBLIGlzIGZld2VyIGVycm9yAwkAAAIFAmd3BQJndwkAlAoCBQNuaWwFAmd0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmVTASZjYWxjdWxhdGVBbW91bnRPdXRGb3JTd2FwQW5kU2VuZFRva2VucwUCZ2wCZ20CZ3gCZ3kCZ24EAmd6CgACYVcJAPwHBAUCYVQCF2dldFN3YXBDb250cmFjdFJFQURPTkxZBQNuaWwFA25pbAMJAAECBQJhVwIGU3RyaW5nBQJhVwkAAgEJAKwCAgkAAwEFAmFXAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcEAmZNCQDMCAIDCQBnAggJAQV2YWx1ZQEJAJEDAggFAmVTCHBheW1lbnRzAAAGYW1vdW50BQJnbAYJAQJhUQECDFdyb25nIGFtb3VudAkAzAgCAwkAAAIIBQJlUwZjYWxsZXIJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmd6BgkBAmFRAQIRUGVybWlzc2lvbiBkZW5pZWQFA25pbAMJAAACBQJmTQUCZk0EAmVUCQEFdmFsdWUBCQCRAwIIBQJlUwhwYXltZW50cwAABAJncQkBAmJmAQgFAmVUB2Fzc2V0SWQEAmdwAwkAAAIFAmdtBwkBAmFNAgUEdGhpcwkBAmFmAAkBAmFNAgUEdGhpcwkBAmFlAAQCZ3IJAGUCCQECYkoBBQJncQgJAQV2YWx1ZQEJAJEDAggFAmVTCHBheW1lbnRzAAAGYW1vdW50BAJncwkBAmJKAQUCZ3AEAmd0CQBrAwUCZ3MFAmdsCQBkAgUCZ3IFAmdsBAJndQkAuQICCQC2AgEFAmdyCQC2AgEFAmdzBAJndgkAuQICCQC3AgIJALYCAQkBAmJKAQUCZ3EJALYCAQUCZ24JALgCAgkAtgIBCQECYkoBBQJncAkAtgIBBQJndAQCZ3cDCQDAAgIFAmd2BQJndQYJAAIBAhRuZXcgSyBpcyBmZXdlciBlcnJvcgMJAAACBQJndwUCZ3cEAmdBAwkAZwIFAmd0BQJneAYJAAIBAixFeGNoYW5nZSByZXN1bHQgaXMgZmV3ZXIgY29pbnMgdGhhbiBleHBlY3RlZAMJAAACBQJnQQUCZ0EEAmdCCQECY0EBBQJncQMJAAACBQJnQgUCZ0IEAmdDCQECY0gCBQJncAUCZ3QDCQAAAgUCZ0MFAmdDCQCUCgIJAM4IAgkAzggCBQJnQwUCZ0IJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQUCZ3kFAmd0CQECYmQBBQJncAUDbmlsBQJndAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJlUwEKc2V0TWFuYWdlcgECZ0QEAmdFCQECZ2oBBQJlUwMJAAACBQJnRQUCZ0UEAmdGCQDZBAEFAmdEAwkAAAIFAmdGBQJnRgkAzAgCCQELU3RyaW5nRW50cnkCCQEBVgAFAmdEBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZVMBDmNvbmZpcm1NYW5hZ2VyAAQCZ0cJAQJnZwAEAmdIAwkBCWlzRGVmaW5lZAEFAmdHBgkAAgECEk5vIHBlbmRpbmcgbWFuYWdlcgMJAAACBQJnSAUCZ0gEAmdJAwkAAAIIBQJlUw9jYWxsZXJQdWJsaWNLZXkJAQV2YWx1ZQEFAmdHBgkAAgECG1lvdSBhcmUgbm90IHBlbmRpbmcgbWFuYWdlcgMJAAACBQJnSQUCZ0kJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAVUACQDYBAEJAQV2YWx1ZQEFAmdHCQDMCAIJAQtEZWxldGVFbnRyeQEJAQFWAAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmVTAQNwdXQCAmRHAmdKAwkAZgIAAAUCZEcJAAIBAiBJbnZhbGlkIHNsaXBwYWdlVG9sZXJhbmNlIHBhc3NlZAQCZVkJAQJlVgMFAmVTBQJkRwYEAmVpCAUCZVkCXzIEAmRuCAUCZVkCXzcEAmRFCAUCZVkCXzkEAmVqCAUCZVkDXzEwBAJlawgFAmVZA18xMQQCZ0sIBQJlWQNfMTIEAmdMCAUCZVkDXzEzBAJlVwkAtgIBCAkBBXZhbHVlAQkAkQMCCAUCZVMIcGF5bWVudHMAAAZhbW91bnQEAmVYCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJlUwhwYXltZW50cwABBmFtb3VudAQCZXoJAQJlcwMFAmVXBQJlWAkAtgIBAAADCQAAAgUCZXoFAmV6BAJmYQkA/AcEBQJhVAIEZW1pdAkAzAgCBQJlaQUDbmlsBQNuaWwDCQAAAgUCZmEFAmZhBAJmYgQCYlQFAmZhAwkAAQIFAmJUAgdBZGRyZXNzBAJmYwUCYlQJAPwHBAUCZmMCBGVtaXQJAMwIAgUCZWkFA25pbAUDbmlsBQR1bml0AwkAAAIFAmZiBQJmYgQCZ00DCQBmAgUCZWoAAAkA/AcEBQJidAIDcHV0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmdLBQJlagUDbmlsBQNuaWwDCQAAAgUCZ00FAmdNBAJnTgMJAGYCBQJlawAACQD8BwQFAmJ0AgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZ0wFAmVrBQNuaWwFA25pbAMJAAACBQJnTgUCZ04EAmdPAwUCZ0oEAmdQCQD8BwQFAmJzAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJkbgUCZWkFA25pbAMJAAACBQJnUAUCZ1AFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZVMGY2FsbGVyBQJlaQUCZG4FA25pbAQCZ1EJAQJlQQMAAAAAAAADCQAAAgUCZ1EFAmdRBAJlcggFAmdRAl8yBAJnUggFAmdRAl8xBAJnUwkBAmVFAgUCZXoFAmVyAwkAAAIFAmdTBQJnUwQCZ1QJAPwHBAUEdGhpcwIJcmViYWxhbmNlBQNuaWwFA25pbAMJAAACBQJnVAUCZ1QJAM4IAgkAzggCBQJkRQUCZ08FAmdSCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmVTAQpwdXRGb3JGcmVlAQJnVQMJAGYCAAAFAmdVCQACAQIUSW52YWxpZCB2YWx1ZSBwYXNzZWQEAmVZCQECZVYDBQJlUwUCZ1UHBAJkRQgFAmVZAl85BAJlVwkAtgIBCAkBBXZhbHVlAQkAkQMCCAUCZVMIcGF5bWVudHMAAAZhbW91bnQEAmVYCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJlUwhwYXltZW50cwABBmFtb3VudAQCZXoJAQJlcwMFAmVXBQJlWAkAtgIBAAADCQAAAgUCZXoFAmV6BAJnVgkBAmVBAwAAAAAAAAQCZ1IIBQJnVgJfMQQCZXIIBQJnVgJfMgQCZ1MJAQJlRQIFAmV6BQJlcgMJAAACBQJnUwUCZ1MJAM4IAgUCZEUFAmdSCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmVTAQlwdXRPbmVUa24CAmdXAmdYBAJnWQoAAmFXCQD8BwQFAmFUAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYVcCB0Jvb2xlYW4FAmFXCQACAQkArAICCQADAQUCYVcCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmdaAwMDCQECYVkABgkAAAIFAmJsBQFsBgkAAAIFAmJsBQFuBgUCZ1kEAmZNCQDMCAIDAwkBASEBBQJnWgYJAQJnaAEFAmVTBgkBAmFRAQIhcHV0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCZVMIcGF5bWVudHMAAQYJAQJhUQECHmV4YWN0bHkgMSBwYXltZW50IGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmZNBQJmTQQCaGEJAJEDAggFAmVTCHBheW1lbnRzAAAEAmZoCAUCaGEHYXNzZXRJZAQCZmcIBQJoYQZhbW91bnQEAmV6AwkAAAIFAmZoBQJibgkBAmVzAwkAtgIBBQJmZwkAtgIBAAAJALYCAQAAAwkAAAIFAmZoBQJibwkBAmVzAwkAtgIBAAAJALYCAQUCZmcJALYCAQAACQECYVEBAh5wYXltZW50IGFzc2V0IGlzIG5vdCBzdXBwb3J0ZWQDCQAAAgUCZXoFAmV6BAJhYggFAmVTBmNhbGxlcgQCYWMIBQJlUw10cmFuc2FjdGlvbklkBAJoYgkBAmZmBAUCZmcFAmZoBQJhYgUCYWMDCQAAAgUCaGIFAmhiBAJmbAgFAmhiAl81BAJoYwgFAmhiAl80BAJmZQgFAmhiAl8zBAJlbAgFAmhiAl8yBAJoZAgFAmhiAl8xBAJoZQMDCQBmAgUCZ1cAAAkAZgIFAmdXBQJoZAcJAQJhUQEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZ1cFA25pbAIABQJoZAQCZmEJAQJlWgEFAmhlAwkAAAIFAmZhBQJmYQQCZ08DBQJnWAQCaGYJAPwHBAUCYnMCBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJtBQJoZQUDbmlsAwkAAAIFAmhmBQJoZgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJlUwZjYWxsZXIFAmhlBQJibQUDbmlsBAJoZwMJAGYCBQJmZQAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFVBQJmZQUCZmgFA25pbAUDbmlsBAJoaAMJAAACBQR0aGlzBQJhVQkAlAoCAAAAAAMFAmZsCQCUCgIJAQEtAQUCZmUAAAkAlAoCAAAJAQEtAQUCZmUEAmVCCAUCaGgCXzEEAmVDCAUCaGgCXzIEAmhpCQECZUEDBQJlQgUCZUMAAAQCZ1IIBQJoaQJfMQQCZXIIBQJoaQJfMgQCZUwJAQV2YWx1ZQEJAKIIAQUCYWoEAmdTCQECZUUCBQJlegUCZXIDCQAAAgUCZ1MFAmdTBAJnVAkA/AcEBQR0aGlzAglyZWJhbGFuY2UFA25pbAUDbmlsAwkAAAIFAmdUBQJnVAkAlAoCCQDOCAIJAM4IAgkAzggCBQJlbAUCZ08FAmhnBQJnUgUCaGUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZVMBEXB1dE9uZVRrblJFQURPTkxZAgJmaAJmZwQCaGoJAQJmZgQFAmZnCQECYmQBBQJmaAUEdW5pdAUEdW5pdAQCaGQIBQJoagJfMQQCZWwIBQJoagJfMgQCZmUIBQJoagJfMwQCaGMIBQJoagJfNAQCZmwIBQJoagJfNQkAlAoCBQNuaWwJAJUKAwUCaGQFAmZlBQJoYwJlUwEJZ2V0T25lVGtuAgJoawJnVwQCZ1kKAAJhVwkA/AcEBQJhVAIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFXAgdCb29sZWFuBQJhVwkAAgEJAKwCAgkAAwEFAmFXAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJobAMDCQECYVkABgkAAAIFAmJsBQFuBgUCZ1kEAmZNCQDMCAIDAwkBASEBBQJobAYJAQJnaAEFAmVTBgkBAmFRAQIhZ2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCZVMIcGF5bWVudHMAAQYJAQJhUQECHmV4YWN0bHkgMSBwYXltZW50IGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmZNBQJmTQQCZkwJAQJiZAEFAmhrBAJoYQkAkQMCCAUCZVMIcGF5bWVudHMAAAQCZmgIBQJoYQdhc3NldElkBAJmdAgFAmhhBmFtb3VudAQCZXoJAQJlcwMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZXoFAmV6BAJhYggFAmVTBmNhbGxlcgQCYWMIBQJlUw10cmFuc2FjdGlvbklkBAJobQkBAmZLBQUCZkwFAmZ0BQJmaAUCYWIFAmFjAwkAAAIFAmhtBQJobQQCZk4IBQJobQJfNQQCaGMIBQJobQJfNAQCZmUIBQJobQJfMwQCZWwIBQJobQJfMgQCaG4IBQJobQJfMQQCYlcDAwkAZgIFAmdXAAAJAGYCBQJnVwUCaG4HCQECYVEBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmdXBQNuaWwCAAUCaG4EAmhvCQD8BwQFAmFUAgRidXJuCQDMCAIFAmZ0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmZoBQJmdAUDbmlsAwkAAAIFAmhvBQJobwQCZ0MJAQJjSAIFAmhrCQBkAgUCYlcJAJYDAQkAzAgCAAAJAMwIAgUCZmUFA25pbAQCaHAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYWIFAmJXBQJmTAUDbmlsBAJoZwMJAGYCBQJmZQAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFVBQJmZQUCZkwFA25pbAUDbmlsBAJocQQCaHIDCQAAAgUEdGhpcwUCYVUAAAUCZmUDBQJmTgkAlAoCCQEBLQEJAGQCBQJiVwUCaHIAAAkAlAoCAAAJAQEtAQkAZAIFAmJXBQJocgQCZUIIBQJocQJfMQQCZUMIBQJocQJfMgQCaHMJAQJlQQMFAmVCBQJlQwAABAJnUggFAmhzAl8xBAJlcggFAmhzAl8yBAJnUwkBAmVFAgUCZXoFAmVyAwkAAAIFAmdTBQJnUwkAlAoCCQDOCAIJAM4IAgkAzggCCQDOCAIFAmVsBQJnQwUCaHAFAmhnBQJnUgUCYlcJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZVMBEWdldE9uZVRrblJFQURPTkxZAgJmTAJmdAQCaHQJAQJmSwUJAQJiZAEFAmZMBQJmdAUCYm0FBHVuaXQFBHVuaXQEAmhuCAUCaHQCXzEEAmVsCAUCaHQCXzIEAmZlCAUCaHQCXzMEAmhjCAUCaHQCXzQEAmZOCAUCaHQCXzUJAJQKAgUDbmlsCQCVCgMFAmhuBQJmZQUCaGMCZVMBE3Vuc3Rha2VBbmRHZXRPbmVUa24DAmh1AmhrAmdXBAJnWQoAAmFXCQD8BwQFAmFUAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYVcCB0Jvb2xlYW4FAmFXCQACAQkArAICCQADAQUCYVcCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmhsAwMJAQJhWQAGCQAAAgUCYmwFAW4GBQJnWQQCZk0JAMwIAgMDCQEBIQEFAmhsBgkBAmdoAQUCZVMGCQECYVEBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJlUwhwYXltZW50cwAABgkBAmFRAQIYbm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZk0FAmZNBAJmTAkBAmJkAQUCaGsEAmFiCAUCZVMGY2FsbGVyBAJhYwgFAmVTDXRyYW5zYWN0aW9uSWQEAmV6CQECZXMDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmV6BQJlegQCaHYJAPwHBAUCYnMCB3Vuc3Rha2UJAMwIAgkA2AQBBQJibQkAzAgCBQJodQUDbmlsBQNuaWwDCQAAAgUCaHYFAmh2BAJodwkBAmZLBQUCZkwFAmh1BQJibQUCYWIFAmFjAwkAAAIFAmh3BQJodwQCZk4IBQJodwJfNQQCaGMIBQJodwJfNAQCZmUIBQJodwJfMwQCZWwIBQJodwJfMgQCaG4IBQJodwJfMQQCYlcDAwkAZgIFAmdXAAAJAGYCBQJnVwUCaG4HCQECYVEBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmdXBQNuaWwCAAUCaG4EAmhvCQD8BwQFAmFUAgRidXJuCQDMCAIFAmh1BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJtBQJodQUDbmlsAwkAAAIFAmhvBQJobwQCZ0MJAQJjSAIFAmhrCQBkAgUCYlcJAJYDAQkAzAgCAAAJAMwIAgUCZmUFA25pbAQCaHAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmVTBmNhbGxlcgUCYlcFAmZMBQNuaWwEAmhnAwkAZgIFAmZlAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYVUFAmZlBQJmTAUDbmlsBQNuaWwEAmh4BAJocgMJAAACBQR0aGlzBQJhVQAABQJmZQMFAmZOCQCUCgIJAQEtAQkAZAIFAmJXBQJocgAACQCUCgIAAAkBAS0BCQBkAgUCYlcFAmhyBAJlQggFAmh4Al8xBAJlQwgFAmh4Al8yBAJoeQkBAmVBAwUCZUIFAmVDAAAEAmdSCAUCaHkCXzEEAmVyCAUCaHkCXzIEAmdTCQECZUUCBQJlegUCZXIDCQAAAgUCZ1MFAmdTCQCUCgIJAM4IAgkAzggCCQDOCAIJAM4IAgUCZWwFAmdDBQJocAUCaGcFAmdSBQJiVwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJlUwEDZ2V0AAQCZFcJAQJlUgEFAmVTBAJkQwgFAmRXAl8xBAJkRAgFAmRXAl8yBAJlVQgFAmRXAl8zBAJkbAgFAmRXAl80BAJkRQgFAmRXAl81BAJnQwkBAmNNAgUCZEMFAmREBAJlegkBAmVzAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJlegUCZXoEAmh6CQD8BwQFAmFUAgRidXJuCQDMCAIFAmVVBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmRsBQJlVQUDbmlsAwkAAAIFAmh6BQJoegQCaEEJAQJlQQMJAQEtAQUCZEMJAQEtAQUCZEQAAAQCZ1IIBQJoQQJfMQQCZXIIBQJoQQJfMgQCZ1MJAQJlRQIFAmV6BQJlcgMJAAACBQJnUwUCZ1MJAM4IAgkAzggCBQJnQwUCZEUFAmdSCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmVTAQlnZXROb0xlc3MCAmhCAmhDBAJkVwkBAmVSAQUCZVMEAmRDCAUCZFcCXzEEAmRECAUCZFcCXzIEAmVVCAUCZFcCXzMEAmRsCAUCZFcCXzQEAmRFCAUCZFcCXzUDCQBmAgUCaEIFAmRDCQACAQkArAICCQCsAgIJAKwCAgIcbm9MZXNzVGhlbkFtdEFzc2V0IGZhaWxlZDogIAkApAMBBQJkQwIDIDwgCQCkAwEFAmhCAwkAZgIFAmhDBQJkRAkAAgEJAKwCAgkArAICCQCsAgICHW5vTGVzc1RoZW5QcmljZUFzc2V0IGZhaWxlZDogCQCkAwEFAmREAgMgPCAJAKQDAQUCaEMEAmdDCQECY00CBQJkQwUCZEQEAmV6CQECZXMDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmV6BQJlegQCaHoJAPwHBAUCYVQCBGJ1cm4JAMwIAgUCZVUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZGwFAmVVBQNuaWwDCQAAAgUCaHoFAmh6BAJoRAkBAmVBAwkBAS0BBQJkQwkBAS0BBQJkRAAABAJnUggFAmhEAl8xBAJlcggFAmhEAl8yBAJnUwkBAmVFAgUCZXoFAmVyAwkAAAIFAmdTBQJnUwkAzggCCQDOCAIFAmdDBQJkRQUCZ1IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZVMBDXVuc3Rha2VBbmRHZXQBAmJXBAJoRQMJAQIhPQIJAJADAQgFAmVTCHBheW1lbnRzAAAJAAIBAhhObyBwYXltZW50cyBhcmUgZXhwZWN0ZWQGAwkAAAIFAmhFBQJoRQQCZGEJAQJiYQAEAmRuCQDZBAEJAJEDAgUCZGEFAXEEAmV6CQECZXMDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmV6BQJlegQCaHYJAPwHBAUCYnMCB3Vuc3Rha2UJAMwIAgkA2AQBBQJkbgkAzAgCBQJiVwUDbmlsBQNuaWwDCQAAAgUCaHYFAmh2BAJkVwkBAmRqBAkA2AQBCAUCZVMNdHJhbnNhY3Rpb25JZAkA2AQBBQJkbgUCYlcIBQJlUwZjYWxsZXIEAmRDCAUCZFcCXzEEAmRECAUCZFcCXzIEAmRxCQENcGFyc2VJbnRWYWx1ZQEIBQJkVwJfOQQCZEUIBQJkVwNfMTAEAmdDCQECY00CBQJkQwUCZEQEAmhGAwMJAQJhWQAGCQAAAgUCZHEFAW4JAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmRxBgMJAAACBQJoRgUCaEYEAmh6CQD8BwQFAmFUAgRidXJuCQDMCAIFAmJXBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmRuBQJiVwUDbmlsAwkAAAIFAmh6BQJoegQCaEcJAQJlQQMJAQEtAQUCZEMJAQEtAQUCZEQAAAQCZ1IIBQJoRwJfMQQCZXIIBQJoRwJfMgQCZ1MJAQJlRQIFAmV6BQJlcgMJAAACBQJnUwUCZ1MJAM4IAgkAzggCBQJnQwUCZEUFAmdSCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmVTARN1bnN0YWtlQW5kR2V0Tm9MZXNzAwJodQJoSAJoQwQCaGwDCQECYVkABgkAAAIFAmJsBQFuBAJmTQkAzAgCAwkBASEBBQJobAYJAAIBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJlUwhwYXltZW50cwAABgkAAgECGG5vIHBheW1lbnRzIGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmZNBQJmTQQCZXoJAQJlcwMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZXoFAmV6BAJodgkA/AcEBQJicwIHdW5zdGFrZQkAzAgCCQDYBAEFAmJtCQDMCAIFAmh1BQNuaWwFA25pbAMJAAACBQJodgUCaHYEAmRXCQECZGoECQDYBAEIBQJlUw10cmFuc2FjdGlvbklkCQDYBAEFAmJtBQJodQgFAmVTBmNhbGxlcgQCZEMIBQJkVwJfMQQCZEQIBQJkVwJfMgQCZEUIBQJkVwNfMTAEAmdDCQECY00CBQJkQwUCZEQEAmhJCQDMCAIDCQBnAgUCZEMFAmhIBgkAAgEJALkJAgkAzAgCAixhbW91bnQgYXNzZXQgYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmhIBQNuaWwCAAkAzAgCAwkAZwIFAmREBQJoQwYJAAIBCQC5CQIJAMwIAgIrcHJpY2UgYXNzZXQgYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmhDBQNuaWwCAAUDbmlsAwkAAAIFAmhJBQJoSQQCaHoJAPwHBAUCYVQCBGJ1cm4JAMwIAgUCaHUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYm0FAmh1BQNuaWwDCQAAAgUCaHoFAmh6BAJoSgkBAmVBAwkBAS0BBQJkQwkBAS0BBQJkRAAABAJnUggFAmhKAl8xBAJlcggFAmhKAl8yBAJnUwkBAmVFAgUCZXoFAmVyAwkAAAIFAmdTBQJnUwkAzggCCQDOCAIFAmdDBQJkRQUCZ1IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZVMBCGFjdGl2YXRlAgJoSwJoTAMJAQIhPQIJAKUIAQgFAmVTBmNhbGxlcgkApQgBBQJhVAkAAgECEnBlcm1pc3Npb25zIGRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZQAFAmhLCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZgAFAmhMBQNuaWwCB3N1Y2Nlc3MCZVMBCnJlZnJlc2hLTHAABAJoTQkBC3ZhbHVlT3JFbHNlAgkAnwgBBQJhawAABAJoTgMJAGcCCQBlAgUGaGVpZ2h0BQJoTQUCYW4FBHVuaXQJAQJhUQEJALkJAgkAzAgCCQCkAwEFAmFuCQDMCAICLyBibG9ja3MgaGF2ZSBub3QgcGFzc2VkIHNpbmNlIHRoZSBwcmV2aW91cyBjYWxsBQNuaWwCAAMJAAACBQJoTgUCaE4EAmVMCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKgDAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQJhagIBMAkBAmFTAQILaW52YWxpZCBrTHAEAmhPCQECZUEDAAAAAAAABAJoUAgFAmhPAl8xBAJlcggFAmhPAl8yBAJlRAMJAQIhPQIFAmVMBQJlcgUCaFAJAQJhUQECEm5vdGhpbmcgdG8gcmVmcmVzaAkAlAoCBQJlRAkApgMBBQJlcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJlUwEcZ2V0UG9vbENvbmZpZ1dyYXBwZXJSRUFET05MWQAJAJQKAgUDbmlsCQECYmEAAmVTARxnZXRBY2NCYWxhbmNlV3JhcHBlclJFQURPTkxZAQJhcAkAlAoCBQNuaWwJAQJiSgEFAmFwAmVTARljYWxjUHJpY2VzV3JhcHBlclJFQURPTkxZAwJjVQJjVgJjWgQCZGkJAQJjWQMFAmNVBQJjVgUCY1oJAJQKAgUDbmlsCQDMCAIJAKYDAQkAkQMCBQJkaQAACQDMCAIJAKYDAQkAkQMCBQJkaQABCQDMCAIJAKYDAQkAkQMCBQJkaQACBQNuaWwCZVMBFHRvWDE4V3JhcHBlclJFQURPTkxZAgFFAUYJAJQKAgUDbmlsCQCmAwEJAQFEAgUBRQUBRgJlUwEWZnJvbVgxOFdyYXBwZXJSRUFET05MWQIBSQFKCQCUCgIFA25pbAkBAUgCCQCnAwEFAUkFAUoCZVMBHmNhbGNQcmljZUJpZ0ludFdyYXBwZXJSRUFET05MWQICYk4CYk8JAJQKAgUDbmlsCQCmAwEJAQJiTQIJAKcDAQUCYk4JAKcDAQUCYk8CZVMBI2VzdGltYXRlUHV0T3BlcmF0aW9uV3JhcHBlclJFQURPTkxZCQJkawJkRwJkSAJkSQJkSgJkSwJhYgJkTAJkTQkAlAoCBQNuaWwJAQJkRgkFAmRrBQJkRwUCZEgFAmRJBQJkSgUCZEsFAmFiBQJkTAUCZE0CZVMBI2VzdGltYXRlR2V0T3BlcmF0aW9uV3JhcHBlclJFQURPTkxZBAJkawJkbAJkbQJhYgQCZFcJAQJkagQFAmRrBQJkbAUCZG0JARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmFiCQCUCgIFA25pbAkAnAoKCAUCZFcCXzEIBQJkVwJfMggFAmRXAl8zCAUCZFcCXzQIBQJkVwJfNQgFAmRXAl82CAUCZFcCXzcJAKYDAQgFAmRXAl84CAUCZFcCXzkIBQJkVwNfMTACZVMBDXN0YXRzUkVBRE9OTFkABAJkYQkBAmJhAAQCZG4JANkEAQkAkQMCBQJkYQUBcQQCaFEJAJEDAgUCZGEFAXIEAmhSCQCRAwIFAmRhBQFzBAJkUAkAkQMCBQJkYQUBdgQCZFEJAJEDAgUCZGEFAXcEAmRiCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGEFAXQEAmRjCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGEFAXUEAmhTCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmRuCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmRuAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCaFQJAQJiSgEFAmhRBAJoVQkBAmJKAQUCaFIEAmhWAwkAAAIFAmhTAAAJAMwIAgUBZQkAzAgCBQFlCQDMCAIFAWUFA25pbAkBAmNZAwUCaFQFAmhVBQJoUwQCZHgAAAQCaFcJAQFIAgkAkQMCBQJoVgABBQFiBAJoWAkBAUgCCQCRAwIFAmhWAAIFAWIEAmhZCQEFdmFsdWUBCQCaCAIFAmFUCQECYUQBCQClCAEFBHRoaXMJAJQKAgUDbmlsCQC5CQIJAMwIAgIOJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJoVAkAzAgCCQCkAwEFAmhVCQDMCAIJAKQDAQUCaFMJAMwIAgkApAMBBQJkeAkAzAgCCQCkAwEFAmhXCQDMCAIJAKQDAQUCaFgJAMwIAgkApAMBBQJoWQUDbmlsBQFqAmVTASBldmFsdWF0ZVB1dEJ5QW1vdW50QXNzZXRSRUFET05MWQECZEgEAmRhCQECYmEABAJkbgkA2QQBCQCRAwIFAmRhBQFxBAJkTgkAkQMCBQJkYQUBcgQCZG8JANkEAQUCZE4EAmRPCQCRAwIFAmRhBQFzBAJkcAkA2QQBBQJkTwQCZGIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkYQUBdAQCZGMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkYQUBdQQCZHEJAJEDAgUCZGEFAXAEAmhTCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmRuCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmRuAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCaFQJAQJiSgEFAmROBAJoVQkBAmJKAQUCZE8EAmNXCQEBRAIFAmhUBQJkYgQCY1gJAQFEAgUCaFUFAmRjBAJkdwMJAAACBQJoUwAABQFlCQECYk0CBQJjWAUCY1cEAmRUCQEBRAIFAmRIBQJkYgQCZFUJALwCAwUCZFQFAmR3BQFkBAJkSgkBAUgCBQJkVQUCZGMEAmVZCQECZEYJAgAAoMIeBQJkSAUCZG8FAmRKBQJkcAIABgcEAmVlCAUCZVkCXzEEAmhaCAUCZVkCXzMEAmRzCAUCZVkCXzQEAmR1CAUCZVkCXzUEAmRyCAUCZVkCXzYJAJQKAgUDbmlsCQC5CQIJAMwIAgIQJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmVlCQDMCAIJAKQDAQkBAUgCBQJkdwUBYgkAzAgCCQCkAwEFAmRzCQDMCAIJAKQDAQUCZHUJAMwIAgkApAMBBQJkcgkAzAgCBQJkcQkAzAgCCQCkAwEFAmRICQDMCAIJAKQDAQUCZEoFA25pbAUBagJlUwEfZXZhbHVhdGVQdXRCeVByaWNlQXNzZXRSRUFET05MWQECZEoEAmRhCQECYmEABAJkbgkA2QQBCQCRAwIFAmRhBQFxBAJkTgkAkQMCBQJkYQUBcgQCZG8JANkEAQUCZE4EAmRPCQCRAwIFAmRhBQFzBAJkcAkA2QQBBQJkTwQCZGIJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkYQUBdAQCZGMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkYQUBdQQCZHEJAJEDAgUCZGEFAXAEAmhTCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmRuCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmRuAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCaWEJAQJiSgEFAmROBAJpYgkBAmJKAQUCZE8EAmljCQEBRAIFAmlhBQJkYgQCaWQJAQFEAgUCaWIFAmRjBAJkdwMJAAACBQJoUwAABQFlCQECYk0CBQJpZAUCaWMEAmRVCQEBRAIFAmRKBQJkYwQCZFQJALwCAwUCZFUFAWQFAmR3BAJkSAkBAUgCBQJkVAUCZGIEAmVZCQECZEYJAgAAoMIeBQJkSAUCZG8FAmRKBQJkcAIABgcEAmVlCAUCZVkCXzEEAmhaCAUCZVkCXzMEAmRzCAUCZVkCXzQEAmR1CAUCZVkCXzUEAmRyCAUCZVkCXzYJAJQKAgUDbmlsCQC5CQIJAMwIAgIQJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmVlCQDMCAIJAKQDAQkBAUgCBQJkdwUBYgkAzAgCCQCkAwEFAmRzCQDMCAIJAKQDAQUCZHUJAMwIAgkApAMBBQJkcgkAzAgCBQJkcQkAzAgCCQCkAwEFAmRICQDMCAIJAKQDAQUCZEoFA25pbAUBagJlUwETZXZhbHVhdGVHZXRSRUFET05MWQICaWUCaWYEAmRXCQECZGoEAgAFAmllBQJpZgUEdGhpcwQCZEMIBQJkVwJfMQQCZEQIBQJkVwJfMgQCZHMIBQJkVwJfNQQCZHUIBQJkVwJfNgQCZHIIBQJkVwJfNwQCZHgIBQJkVwJfOAQCZHEJAQ1wYXJzZUludFZhbHVlAQgFAmRXAl85CQCUCgIFA25pbAkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCZEMJAMwIAgkApAMBBQJkRAkAzAgCCQCkAwEFAmRzCQDMCAIJAKQDAQUCZHUJAMwIAgkApAMBBQJkcgkAzAgCCQCmAwEFAmR4CQDMCAIJAKQDAQUCZHEFA25pbAUBagECaWcBAmloAAQCaWkEAmJUCQECZ2UAAwkAAQIFAmJUAgpCeXRlVmVjdG9yBAJnaQUCYlQFAmdpAwkAAQIFAmJUAgRVbml0CAUCaWcPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IEAmJUBQJpZwMJAAECBQJiVAIFT3JkZXIEAmVIBQJiVAQCaWoJAQJhWgAEAmlrCQECZUcBBQJlSAQCYUkIBQJpawJfMQQCYUoIBQJpawJfMgQCYUsJAPQDAwgFAmVICWJvZHlCeXRlcwkAkQMCCAUCZUgGcHJvb2ZzAAAIBQJlSA9zZW5kZXJQdWJsaWNLZXkEAmFMCQD0AwMIBQJlSAlib2R5Qnl0ZXMJAJEDAggFAmVIBnByb29mcwABBQJpagMDAwUCYUkFAmFLBwUCYUwHBgkBAmFIBAUCYUkFAmFKBQJhSwUCYUwDCQABAgUCYlQCFFNldFNjcmlwdFRyYW5zYWN0aW9uBAJnZgUCYlQDCQD0AwMIBQJpZwlib2R5Qnl0ZXMJAJEDAggFAmlnBnByb29mcwAABQJpaQYEAmlsCQD2AwEJAQV2YWx1ZQEIBQJnZgZzY3JpcHQEAmltCQDbBAEJAQV2YWx1ZQEJAJ0IAgUCYVQJAQJhRgAEAmluCQDxBwEFBHRoaXMDCQAAAgUCaW0FAmlsCQECIT0CBQJpbgUCaWwHCQD0AwMIBQJpZwlib2R5Qnl0ZXMJAJEDAggFAmlnBnByb29mcwAABQJpaQh2GPI=", "height": 2532780, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: JDZgrHsVDs67gZXMqnrACy78DNTyNbsWFT7XvBAsmxm9 Next: 8emu6oz3EztpFydtpXg7kZ2HtDuxMeukJzdio1muv39e Diff:
OldNewDifferences
409409
410410
411411 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
412+ let $t01589916035 = getLeaseProxyConfig(assetId)
413+ let isLeasable = $t01589916035._1
414+ let leasedRatio = $t01589916035._2
415+ let minBalance = $t01589916035._3
416+ let proxyAddress = $t01589916035._4
417+ let proxyAssetId = $t01589916035._5
418+ let proxyRateMul = $t01589916035._6
419+ let stakingProfitAddress = $t01589916035._7
420420 if (isLeasable)
421421 then {
422422 let newTotalLeasableBalance = max([0, ((getAccBalance(assetId) - getAmount) - minBalance)])
425425 let newAdditionalBalance = fraction(leasedRatio, newTotalLeasableBalance, 100)
426426 if ((newAdditionalBalance == newAdditionalBalance))
427427 then {
428- let withdrawAmount = max([0, (getAdditionalBalanceOrZero(assetId) - newAdditionalBalance)])
428+ let withdrawAmount = (getAdditionalBalanceOrZero(assetId) - newAdditionalBalance)
429429 if ((withdrawAmount == withdrawAmount))
430- then withdraw(assetId, withdrawAmount, proxyAssetId, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
430+ then if ((0 > withdrawAmount))
431+ then deposit(assetId, -(withdrawAmount), proxyAssetId, addressFromStringValue(proxyAddress))
432+ else withdraw(assetId, withdrawAmount, proxyAssetId, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
431433 else throw("Strict value is not equal to itself.")
432434 }
433435 else throw("Strict value is not equal to itself.")
624626 let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
625627 let amountAssetAmount = order.amount
626628 let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
627- let $t02815528367 = if ((order.orderType == Buy))
629+ let $t02830128513 = if ((order.orderType == Buy))
628630 then $Tuple2(amountAssetAmount, -(priceAssetAmount))
629631 else $Tuple2(-(amountAssetAmount), priceAssetAmount)
630- let amountAssetBalanceDelta = $t02815528367._1
631- let priceAssetBalanceDelta = $t02815528367._2
632+ let amountAssetBalanceDelta = $t02830128513._1
633+ let priceAssetBalanceDelta = $t02830128513._2
632634 if (if (if (isGlobalShutdown())
633635 then true
634636 else (cfgPoolStatus == PoolMatcherDisabled))
641643 then throw("Wrong order assets.")
642644 else {
643645 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
644- let $t02880728907 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
645- let unusedActions = $t02880728907._1
646- let kLpNew = $t02880728907._2
646+ let $t02895329053 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
647+ let unusedActions = $t02895329053._1
648+ let kLpNew = $t02895329053._2
647649 let isOrderValid = (kLpNew >= kLp)
648650 let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
649651 $Tuple2(isOrderValid, info)
722724 else if ((paymentAssetId == cfgPriceAssetId))
723725 then false
724726 else throwErr("invalid asset")
725- let $t03202032313 = if (isEval)
727+ let $t03216632459 = if (isEval)
726728 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
727729 else if (paymentInAmountAsset)
728730 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
729731 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
730- let amountBalanceOld = $t03202032313._1
731- let priceBalanceOld = $t03202032313._2
732- let $t03231732466 = if (paymentInAmountAsset)
732+ let amountBalanceOld = $t03216632459._1
733+ let priceBalanceOld = $t03216632459._2
734+ let $t03246332612 = if (paymentInAmountAsset)
733735 then $Tuple2(paymentAmountRaw, 0)
734736 else $Tuple2(0, paymentAmountRaw)
735- let amountAssetAmountRaw = $t03231732466._1
736- let priceAssetAmountRaw = $t03231732466._2
737+ let amountAssetAmountRaw = $t03246332612._1
738+ let priceAssetAmountRaw = $t03246332612._2
737739 let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
738740 let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
739- let $t03259832662 = takeFee(paymentAmountRaw, inFee)
740- let paymentAmount = $t03259832662._1
741- let feeAmount = $t03259832662._2
741+ let $t03274432808 = takeFee(paymentAmountRaw, inFee)
742+ let paymentAmount = $t03274432808._1
743+ let feeAmount = $t03274432808._2
742744 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
743745 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
744746 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
761763 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
762764 let priceOld = fromX18(priceOldX18, scale8)
763765 let loss = {
764- let $t03434334510 = if (paymentInAmountAsset)
766+ let $t03448934656 = if (paymentInAmountAsset)
765767 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
766768 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
767- let amount = $t03434334510._1
768- let balance = $t03434334510._2
769+ let amount = $t03448934656._1
770+ let balance = $t03448934656._2
769771 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
770772 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
771773 }
805807 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
806808 let redeemedBigInt = toBigInt(paymentAmount)
807809 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
808- let $t03658836644 = takeFee(amountRaw, outFee)
809- let totalAmount = $t03658836644._1
810- let feeAmount = $t03658836644._2
811- let $t03664836874 = if (outInAmountAsset)
810+ let $t03673436790 = takeFee(amountRaw, outFee)
811+ let totalAmount = $t03673436790._1
812+ let feeAmount = $t03673436790._2
813+ let $t03679437020 = if (outInAmountAsset)
812814 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
813815 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
814- let outAmAmount = $t03664836874._1
815- let outPrAmount = $t03664836874._2
816- let amBalanceNew = $t03664836874._3
817- let prBalanceNew = $t03664836874._4
816+ let outAmAmount = $t03679437020._1
817+ let outPrAmount = $t03679437020._2
818+ let amBalanceNew = $t03679437020._3
819+ let prBalanceNew = $t03679437020._4
818820 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
819821 let priceNew = fromX18(priceNewX18, scale8)
820822 let commonState = if (isEval)
886888
887889 @Callable(i)
888890 func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse,feePoolAmount) = {
889- let $t03876039065 = if ((isReverse == false))
891+ let $t03890639211 = if ((isReverse == false))
890892 then {
891893 let assetOut = getStringOrFail(this, pa())
892894 let assetIn = getStringOrFail(this, aa())
897899 let assetIn = getStringOrFail(this, pa())
898900 $Tuple2(assetOut, assetIn)
899901 }
900- let assetOut = $t03876039065._1
901- let assetIn = $t03876039065._2
902+ let assetOut = $t03890639211._1
903+ let assetIn = $t03890639211._2
902904 let poolAssetInBalance = getAccBalance(assetIn)
903905 let poolAssetOutBalance = getAccBalance(assetOut)
904906 let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
10491051 else throw("Strict value is not equal to itself.")
10501052 }
10511053 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1052- let $t04411144573 = refreshKLpInternal(0, 0, 0)
1053- if (($t04411144573 == $t04411144573))
1054+ let $t04425744719 = refreshKLpInternal(0, 0, 0)
1055+ if (($t04425744719 == $t04425744719))
10541056 then {
1055- let updatedKLp = $t04411144573._2
1056- let refreshKLpActions = $t04411144573._1
1057+ let updatedKLp = $t04425744719._2
1058+ let refreshKLpActions = $t04425744719._1
10571059 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
10581060 if ((isUpdatedKLpValid == isUpdatedKLpValid))
10591061 then {
10901092 let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
10911093 if ((currentKLp == currentKLp))
10921094 then {
1093- let $t04518545250 = refreshKLpInternal(0, 0, 0)
1094- let refreshKLpActions = $t04518545250._1
1095- let updatedKLp = $t04518545250._2
1095+ let $t04533145396 = refreshKLpInternal(0, 0, 0)
1096+ let refreshKLpActions = $t04533145396._1
1097+ let updatedKLp = $t04533145396._2
10961098 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
10971099 if ((isUpdatedKLpValid == isUpdatedKLpValid))
10981100 then (state ++ refreshKLpActions)
11391141 then {
11401142 let userAddress = i.caller
11411143 let txId = i.transactionId
1142- let $t04643846590 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
1143- if (($t04643846590 == $t04643846590))
1144+ let $t04658446736 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
1145+ if (($t04658446736 == $t04658446736))
11441146 then {
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
1147+ let paymentInAmountAsset = $t04658446736._5
1148+ let bonus = $t04658446736._4
1149+ let feeAmount = $t04658446736._3
1150+ let commonState = $t04658446736._2
1151+ let emitAmountEstimated = $t04658446736._1
11501152 let emitAmount = if (if ((minOutAmount > 0))
11511153 then (minOutAmount > emitAmountEstimated)
11521154 else false)
11661168 let sendFee = if ((feeAmount > 0))
11671169 then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
11681170 else nil
1169- let $t04717647373 = if ((this == feeCollectorAddress))
1171+ let $t04732247519 = if ((this == feeCollectorAddress))
11701172 then $Tuple2(0, 0)
11711173 else if (paymentInAmountAsset)
11721174 then $Tuple2(-(feeAmount), 0)
11731175 else $Tuple2(0, -(feeAmount))
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
1176+ let amountAssetBalanceDelta = $t04732247519._1
1177+ let priceAssetBalanceDelta = $t04732247519._2
1178+ let $t04752247630 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1179+ let refreshKLpActions = $t04752247630._1
1180+ let updatedKLp = $t04752247630._2
11791181 let kLp = value(getString(keyKLp))
11801182 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11811183 if ((isUpdatedKLpValid == isUpdatedKLpValid))
12001202
12011203 @Callable(i)
12021204 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
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
1205+ let $t04798548142 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
1206+ let emitAmountEstimated = $t04798548142._1
1207+ let commonState = $t04798548142._2
1208+ let feeAmount = $t04798548142._3
1209+ let bonus = $t04798548142._4
1210+ let paymentInAmountAsset = $t04798548142._5
12091211 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
12101212 }
12111213
12421244 then {
12431245 let userAddress = i.caller
12441246 let txId = i.transactionId
1245- let $t04888149034 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1246- if (($t04888149034 == $t04888149034))
1247+ let $t04902749180 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1248+ if (($t04902749180 == $t04902749180))
12471249 then {
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
1250+ let outInAmountAsset = $t04902749180._5
1251+ let bonus = $t04902749180._4
1252+ let feeAmount = $t04902749180._3
1253+ let commonState = $t04902749180._2
1254+ let amountEstimated = $t04902749180._1
12531255 let amount = if (if ((minOutAmount > 0))
12541256 then (minOutAmount > amountEstimated)
12551257 else false)
12631265 let sendFee = if ((feeAmount > 0))
12641266 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
12651267 else nil
1266- let $t04969849945 = {
1268+ let $t04984450091 = {
12671269 let feeAmountForCalc = if ((this == feeCollectorAddress))
12681270 then 0
12691271 else feeAmount
12711273 then $Tuple2(-((amount + feeAmountForCalc)), 0)
12721274 else $Tuple2(0, -((amount + feeAmountForCalc)))
12731275 }
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
1276+ let amountAssetBalanceDelta = $t04984450091._1
1277+ let priceAssetBalanceDelta = $t04984450091._2
1278+ let $t05009450202 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1279+ let refreshKLpActions = $t05009450202._1
1280+ let updatedKLp = $t05009450202._2
12791281 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
12801282 if ((isUpdatedKLpValid == isUpdatedKLpValid))
12811283 then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
12941296
12951297 @Callable(i)
12961298 func getOneTknREADONLY (outAssetId,paymentAmount) = {
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
1299+ let $t05048050636 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1300+ let amountEstimated = $t05048050636._1
1301+ let commonState = $t05048050636._2
1302+ let feeAmount = $t05048050636._3
1303+ let bonus = $t05048050636._4
1304+ let outInAmountAsset = $t05048050636._5
13031305 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
13041306 }
13051307
13361338 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
13371339 if ((unstakeInv == unstakeInv))
13381340 then {
1339- let $t05139551546 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1340- if (($t05139551546 == $t05139551546))
1341+ let $t05154151692 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1342+ if (($t05154151692 == $t05154151692))
13411343 then {
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
1344+ let outInAmountAsset = $t05154151692._5
1345+ let bonus = $t05154151692._4
1346+ let feeAmount = $t05154151692._3
1347+ let commonState = $t05154151692._2
1348+ let amountEstimated = $t05154151692._1
13471349 let amount = if (if ((minOutAmount > 0))
13481350 then (minOutAmount > amountEstimated)
13491351 else false)
13571359 let sendFee = if ((feeAmount > 0))
13581360 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
13591361 else nil
1360- let $t05220552452 = {
1362+ let $t05235152598 = {
13611363 let feeAmountForCalc = if ((this == feeCollectorAddress))
13621364 then 0
13631365 else feeAmount
13651367 then $Tuple2(-((amount + feeAmountForCalc)), 0)
13661368 else $Tuple2(0, -((amount + feeAmountForCalc)))
13671369 }
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
1370+ let amountAssetBalanceDelta = $t05235152598._1
1371+ let priceAssetBalanceDelta = $t05235152598._2
1372+ let $t05260152709 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1373+ let refreshKLpActions = $t05260152709._1
1374+ let updatedKLp = $t05260152709._2
13731375 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
13741376 if ((isUpdatedKLpValid == isUpdatedKLpValid))
13751377 then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
14031405 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
14041406 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
14051407 then {
1406- let $t05365853739 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1407- let refreshKLpActions = $t05365853739._1
1408- let updatedKLp = $t05365853739._2
1408+ let $t05380453885 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1409+ let refreshKLpActions = $t05380453885._1
1410+ let updatedKLp = $t05380453885._2
14091411 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
14101412 if ((isUpdatedKLpValid == isUpdatedKLpValid))
14111413 then ((withdrawState ++ state) ++ refreshKLpActions)
14381440 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
14391441 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
14401442 then {
1441- let $t05483454915 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1442- let refreshKLpActions = $t05483454915._1
1443- let updatedKLp = $t05483454915._2
1443+ let $t05498055061 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1444+ let refreshKLpActions = $t05498055061._1
1445+ let updatedKLp = $t05498055061._2
14441446 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
14451447 if ((isUpdatedKLpValid == isUpdatedKLpValid))
14461448 then ((withdrawState ++ state) ++ refreshKLpActions)
14851487 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
14861488 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
14871489 then {
1488- let $t05618756268 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1489- let refreshKLpActions = $t05618756268._1
1490- let updatedKLp = $t05618756268._2
1490+ let $t05633356414 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1491+ let refreshKLpActions = $t05633356414._1
1492+ let updatedKLp = $t05633356414._2
14911493 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
14921494 if ((isUpdatedKLpValid == isUpdatedKLpValid))
14931495 then ((withdrawState ++ state) ++ refreshKLpActions)
15391541 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
15401542 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
15411543 then {
1542- let $t05770957790 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1543- let refreshKLpActions = $t05770957790._1
1544- let updatedKLp = $t05770957790._2
1544+ let $t05785557936 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1545+ let refreshKLpActions = $t05785557936._1
1546+ let updatedKLp = $t05785557936._2
15451547 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
15461548 if ((isUpdatedKLpValid == isUpdatedKLpValid))
15471549 then ((withdrawState ++ state) ++ refreshKLpActions)
15761578 if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
15771579 then {
15781580 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1579- let $t05899459058 = refreshKLpInternal(0, 0, 0)
1580- let kLpUpdateActions = $t05899459058._1
1581- let updatedKLp = $t05899459058._2
1581+ let $t05914059204 = refreshKLpInternal(0, 0, 0)
1582+ let kLpUpdateActions = $t05914059204._1
1583+ let updatedKLp = $t05914059204._2
15821584 let actions = if ((kLp != updatedKLp))
15831585 then kLpUpdateActions
15841586 else throwErr("nothing to refresh")
17531755 match tx {
17541756 case order: Order =>
17551757 let matcherPub = getMatcherPubOrFail()
1756- let $t06772067789 = validateMatcherOrderAllowed(order)
1757- let orderValid = $t06772067789._1
1758- let orderValidInfo = $t06772067789._2
1758+ let $t06786667935 = validateMatcherOrderAllowed(order)
1759+ let orderValid = $t06786667935._1
1760+ let orderValidInfo = $t06786667935._2
17591761 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
17601762 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
17611763 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
133133 func keyAdditionalBalance (assetId) = makeString(["%s%s", "stakedBalance", assetId], SEP)
134134
135135
136136 func keyStakingAssetBalance (assetId) = makeString(["%s%s", "shareAssetBalance", assetId], SEP)
137137
138138
139139 func getAdditionalBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyAdditionalBalance(assetId)), 0)
140140
141141
142142 func getStakingAssetBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyStakingAssetBalance(assetId)), 0)
143143
144144
145145 func keyFactoryConfig () = "%s__factoryConfig"
146146
147147
148148 func keyMatcherPub () = "%s%s__matcher__publicKey"
149149
150150
151151 func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
152152
153153
154154 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
155155
156156
157157 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
158158
159159
160160 func keyAllPoolsShutdown () = "%s__shutdown"
161161
162162
163163 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
164164
165165
166166 func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
167167
168168
169169 let keyFeeCollectorAddress = "%s__feeCollectorAddress"
170170
171171 func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
172172
173173
174174 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
175175
176176
177177 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
178178
179179
180180 func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
181181
182182
183183 func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
184184
185185
186186 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
187187
188188 let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
189189
190190 let inFee = {
191191 let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
192192 if ($isInstanceOf(@, "Int"))
193193 then @
194194 else throw(($getType(@) + " couldn't be cast to Int"))
195195 }
196196
197197 let outFee = {
198198 let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
199199 if ($isInstanceOf(@, "Int"))
200200 then @
201201 else throw(($getType(@) + " couldn't be cast to Int"))
202202 }
203203
204204 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
205205
206206
207207 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
208208
209209
210210 func getPoolConfig () = {
211211 let amtAsset = getStringOrFail(this, aa())
212212 let priceAsset = getStringOrFail(this, pa())
213213 let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
214214 let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
215215 split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
216216 }
217217
218218
219219 func parseAssetId (input) = if ((input == wavesString))
220220 then unit
221221 else fromBase58String(input)
222222
223223
224224 func assetIdToString (input) = if ((input == unit))
225225 then wavesString
226226 else toBase58String(value(input))
227227
228228
229229 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]))
230230
231231
232232 let poolConfigParsed = parsePoolConfig(getPoolConfig())
233233
234234 let $t089629128 = poolConfigParsed
235235
236236 let cfgPoolAddress = $t089629128._1
237237
238238 let cfgPoolStatus = $t089629128._2
239239
240240 let cfgLpAssetId = $t089629128._3
241241
242242 let cfgAmountAssetId = $t089629128._4
243243
244244 let cfgPriceAssetId = $t089629128._5
245245
246246 let cfgAmountAssetDecimals = $t089629128._6
247247
248248 let cfgPriceAssetDecimals = $t089629128._7
249249
250250 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
251251
252252
253253 let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
254254
255255 let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
256256
257257 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)
258258
259259
260260 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)
261261
262262
263263 func getAccBalance (assetId) = {
264264 let balanceOnPool = if ((assetId == "WAVES"))
265265 then wavesBalance(this).available
266266 else assetBalance(this, fromBase58String(assetId))
267267 let totalBalance = ((balanceOnPool + getAdditionalBalanceOrZero(assetId)) - getStakingAssetBalanceOrZero(assetId))
268268 max([0, totalBalance])
269269 }
270270
271271
272272 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
273273
274274
275275 func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
276276
277277
278278 func getRate (proxy) = {
279279 let inv = invoke(proxy, "getRate", nil, nil)
280280 if ((inv == inv))
281281 then match inv {
282282 case r: Int =>
283283 r
284284 case _ =>
285285 throwErr("proxy.getRate() unexpected value")
286286 }
287287 else throw("Strict value is not equal to itself.")
288288 }
289289
290290
291291 func deposit (assetId,amount,stakingAssetId,proxy) = {
292292 let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
293293 if ((currentAdditionalBalance == currentAdditionalBalance))
294294 then {
295295 let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
296296 if ((currentStakingAssetBalance == currentStakingAssetBalance))
297297 then {
298298 let asset = parseAssetId(assetId)
299299 if ((amount > 0))
300300 then {
301301 let depositInvoke = invoke(proxy, "deposit", nil, [AttachedPayment(asset, amount)])
302302 if ((depositInvoke == depositInvoke))
303303 then match depositInvoke {
304304 case receivedStakingAsset: Int =>
305305 let newAdditionalBalance = (currentAdditionalBalance + amount)
306306 let newStakingAssetBalance = (currentStakingAssetBalance + receivedStakingAsset)
307307 [IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance)]
308308 case _ =>
309309 nil
310310 }
311311 else throw("Strict value is not equal to itself.")
312312 }
313313 else nil
314314 }
315315 else throw("Strict value is not equal to itself.")
316316 }
317317 else throw("Strict value is not equal to itself.")
318318 }
319319
320320
321321 func withdraw (assetId,amount,stakingAssetId,proxy,proxyRateMul,profitAddress) = {
322322 let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
323323 if ((currentAdditionalBalance == currentAdditionalBalance))
324324 then {
325325 let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
326326 if ((currentStakingAssetBalance == currentStakingAssetBalance))
327327 then {
328328 let currentProxyRate = getRate(proxy)
329329 if ((currentProxyRate == currentProxyRate))
330330 then {
331331 let oldRate = fraction(proxyRateMul, currentAdditionalBalance, currentStakingAssetBalance)
332332 let stakingAsset = parseAssetId(stakingAssetId)
333333 let oldSendStakingAmount = fraction(proxyRateMul, amount, oldRate)
334334 let sendStakingAssetAmount = fraction(proxyRateMul, amount, currentProxyRate)
335335 let profitAmount = max([0, (oldSendStakingAmount - sendStakingAssetAmount)])
336336 if ((sendStakingAssetAmount > 0))
337337 then {
338338 let withdrawInvoke = invoke(proxy, "withdraw", nil, [AttachedPayment(stakingAsset, sendStakingAssetAmount)])
339339 if ((withdrawInvoke == withdrawInvoke))
340340 then match withdrawInvoke {
341341 case receivedAssets: Int =>
342342 let newAdditionalBalance = (currentAdditionalBalance - receivedAssets)
343343 let newStakingAssetBalance = ((currentStakingAssetBalance - sendStakingAssetAmount) - profitAmount)
344344 [IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance), ScriptTransfer(profitAddress, profitAmount, parseAssetId(stakingAssetId))]
345345 case _ =>
346346 nil
347347 }
348348 else throw("Strict value is not equal to itself.")
349349 }
350350 else nil
351351 }
352352 else throw("Strict value is not equal to itself.")
353353 }
354354 else throw("Strict value is not equal to itself.")
355355 }
356356 else throw("Strict value is not equal to itself.")
357357 }
358358
359359
360360 func getLeaseProxyConfig (assetId) = match invoke(factoryContract, "getPoolLeaseConfigREADONLY", [toString(this), assetId], nil) {
361361 case a: (Boolean, Int, Int, String, String, Int, String) =>
362362 a
363363 case _ =>
364364 throwErr((("[" + assetId) + "] getLeaseProxyConfig() error"))
365365 }
366366
367367
368368 func rebalanceInternal (targetRatio,assetId,stakingAssetId,minBalance,proxy,proxyRateMul,profitAddress) = {
369369 let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
370370 if ((currentAdditionalBalance == currentAdditionalBalance))
371371 then {
372372 let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
373373 if ((currentStakingAssetBalance == currentStakingAssetBalance))
374374 then {
375375 let leasableTotalBalance = max([0, (getAccBalance(assetId) - minBalance)])
376376 let targetAdditionalBalance = fraction(targetRatio, leasableTotalBalance, 100)
377377 let diff = (currentAdditionalBalance - targetAdditionalBalance)
378378 if ((diff == 0))
379379 then nil
380380 else if ((0 > diff))
381381 then {
382382 let sendAssetAmount = -(diff)
383383 deposit(assetId, sendAssetAmount, stakingAssetId, proxy)
384384 }
385385 else {
386386 let getAssetAmount = diff
387387 withdraw(assetId, getAssetAmount, stakingAssetId, proxy, proxyRateMul, profitAddress)
388388 }
389389 }
390390 else throw("Strict value is not equal to itself.")
391391 }
392392 else throw("Strict value is not equal to itself.")
393393 }
394394
395395
396396 func rebalanceAsset (assetId) = {
397397 let $t01536415500 = getLeaseProxyConfig(assetId)
398398 let isLeasable = $t01536415500._1
399399 let leasedRatio = $t01536415500._2
400400 let minBalance = $t01536415500._3
401401 let proxyAddress = $t01536415500._4
402402 let proxyAssetId = $t01536415500._5
403403 let proxyRateMul = $t01536415500._6
404404 let stakingProfitAddress = $t01536415500._7
405405 if (isLeasable)
406406 then rebalanceInternal(leasedRatio, assetId, proxyAssetId, minBalance, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
407407 else nil
408408 }
409409
410410
411411 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
412+ let $t01589916035 = getLeaseProxyConfig(assetId)
413+ let isLeasable = $t01589916035._1
414+ let leasedRatio = $t01589916035._2
415+ let minBalance = $t01589916035._3
416+ let proxyAddress = $t01589916035._4
417+ let proxyAssetId = $t01589916035._5
418+ let proxyRateMul = $t01589916035._6
419+ let stakingProfitAddress = $t01589916035._7
420420 if (isLeasable)
421421 then {
422422 let newTotalLeasableBalance = max([0, ((getAccBalance(assetId) - getAmount) - minBalance)])
423423 if ((newTotalLeasableBalance == newTotalLeasableBalance))
424424 then {
425425 let newAdditionalBalance = fraction(leasedRatio, newTotalLeasableBalance, 100)
426426 if ((newAdditionalBalance == newAdditionalBalance))
427427 then {
428- let withdrawAmount = max([0, (getAdditionalBalanceOrZero(assetId) - newAdditionalBalance)])
428+ let withdrawAmount = (getAdditionalBalanceOrZero(assetId) - newAdditionalBalance)
429429 if ((withdrawAmount == withdrawAmount))
430- then withdraw(assetId, withdrawAmount, proxyAssetId, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
430+ then if ((0 > withdrawAmount))
431+ then deposit(assetId, -(withdrawAmount), proxyAssetId, addressFromStringValue(proxyAddress))
432+ else withdraw(assetId, withdrawAmount, proxyAssetId, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
431433 else throw("Strict value is not equal to itself.")
432434 }
433435 else throw("Strict value is not equal to itself.")
434436 }
435437 else throw("Strict value is not equal to itself.")
436438 }
437439 else nil
438440 }
439441
440442
441443 func withdrawAndRebalanceAll (amountAssetOutAmount,priceAssetOutAmount) = {
442444 let AmAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, aa()), amountAssetOutAmount)
443445 let PrAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, pa()), priceAssetOutAmount)
444446 (AmAmtWithdrawState ++ PrAmtWithdrawState)
445447 }
446448
447449
448450 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
449451 let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
450452 let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
451453 calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
452454 }
453455
454456
455457 func calcPrices (amAmt,prAmt,lpAmt) = {
456458 let cfg = getPoolConfig()
457459 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
458460 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
459461 let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
460462 let amAmtX18 = toX18(amAmt, amtAssetDcm)
461463 let prAmtX18 = toX18(prAmt, priceAssetDcm)
462464 let lpAmtX18 = toX18(lpAmt, scale8)
463465 let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
464466 let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
465467 [priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
466468 }
467469
468470
469471 func calculatePrices (amAmt,prAmt,lpAmt) = {
470472 let prices = calcPrices(amAmt, prAmt, lpAmt)
471473 [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
472474 }
473475
474476
475477 func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
476478 let cfg = getPoolConfig()
477479 let lpAssetId = cfg[idxPoolLPAssetId]
478480 let amAssetId = cfg[idxAmtAssetId]
479481 let prAssetId = cfg[idxPriceAssetId]
480482 let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
481483 let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
482484 let poolStatus = cfg[idxPoolStatus]
483485 let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
484486 if ((lpAssetId != pmtAssetId))
485487 then throw("Invalid asset passed.")
486488 else {
487489 let amBalance = getAccBalance(amAssetId)
488490 let amBalanceX18 = toX18(amBalance, amAssetDcm)
489491 let prBalance = getAccBalance(prAssetId)
490492 let prBalanceX18 = toX18(prBalance, prAssetDcm)
491493 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
492494 let curPrice = fromX18(curPriceX18, scale8)
493495 let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
494496 let lpEmissionX18 = toX18(lpEmission, scale8)
495497 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
496498 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
497499 let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
498500 let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
499501 let state = if ((txId58 == ""))
500502 then nil
501503 else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
502504 then unit
503505 else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
504506 then unit
505507 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)]
506508 $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
507509 }
508510 }
509511
510512
511513 func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
512514 let cfg = getPoolConfig()
513515 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
514516 let amAssetIdStr = cfg[idxAmtAssetId]
515517 let prAssetIdStr = cfg[idxPriceAssetId]
516518 let iAmtAssetId = cfg[idxIAmtAssetId]
517519 let iPriceAssetId = cfg[idxIPriceAssetId]
518520 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
519521 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
520522 let poolStatus = cfg[idxPoolStatus]
521523 let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
522524 let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
523525 let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
524526 if (if ((amAssetIdStr != inAmAssetIdStr))
525527 then true
526528 else (prAssetIdStr != inPrAssetIdStr))
527529 then throw("Invalid amt or price asset passed.")
528530 else {
529531 let amBalance = if (isEvaluate)
530532 then getAccBalance(amAssetIdStr)
531533 else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
532534 let prBalance = if (isEvaluate)
533535 then getAccBalance(prAssetIdStr)
534536 else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
535537 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
536538 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
537539 let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
538540 let amBalanceX18 = toX18(amBalance, amtAssetDcm)
539541 let prBalanceX18 = toX18(prBalance, priceAssetDcm)
540542 let res = if ((lpEmission == 0))
541543 then {
542544 let curPriceX18 = zeroBigInt
543545 let slippageX18 = zeroBigInt
544546 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
545547 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
546548 }
547549 else {
548550 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
549551 let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
550552 let slippageToleranceX18 = toX18(slippageTolerance, scale8)
551553 if (if ((curPriceX18 != zeroBigInt))
552554 then (slippageX18 > slippageToleranceX18)
553555 else false)
554556 then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
555557 else {
556558 let lpEmissionX18 = toX18(lpEmission, scale8)
557559 let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
558560 let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
559561 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
560562 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
561563 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
562564 let expAmtAssetAmtX18 = expectedAmts._1
563565 let expPriceAssetAmtX18 = expectedAmts._2
564566 let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
565567 $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
566568 }
567569 }
568570 let calcLpAmt = res._1
569571 let calcAmAssetPmt = res._2
570572 let calcPrAssetPmt = res._3
571573 let curPrice = fromX18(res._4, scale8)
572574 let slippageCalc = fromX18(res._5, scale8)
573575 if ((0 >= calcLpAmt))
574576 then throw("Invalid calculations. LP calculated is less than zero.")
575577 else {
576578 let emitLpAmt = if (!(emitLp))
577579 then 0
578580 else calcLpAmt
579581 let amDiff = (inAmAssetAmt - calcAmAssetPmt)
580582 let prDiff = (inPrAssetAmt - calcPrAssetPmt)
581583 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))]
582584 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
583585 }
584586 }
585587 }
586588
587589
588590 func calcKLp (amountBalance,priceBalance,lpEmission) = {
589591 let amountBalanceX18 = toX18BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals))
590592 let priceBalanceX18 = toX18BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))
591593 let updatedKLp = fraction(pow((amountBalanceX18 * priceBalanceX18), 0, toBigInt(5), 1, 18, DOWN), big1, lpEmission)
592594 if ((lpEmission == big0))
593595 then big0
594596 else updatedKLp
595597 }
596598
597599
598600 func calcCurrentKLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
599601 let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
600602 let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
601603 let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
602604 let currentKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
603605 currentKLp
604606 }
605607
606608
607609 func refreshKLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
608610 let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
609611 let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
610612 let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
611613 let updatedKLp = calcKLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
612614 let actions = [IntegerEntry(keyKLpRefreshedHeight, height), StringEntry(keyKLp, toString(updatedKLp))]
613615 $Tuple2(actions, updatedKLp)
614616 }
615617
616618
617619 func validateUpdatedKLp (oldKLp,updatedKLp) = if ((updatedKLp >= oldKLp))
618620 then true
619621 else throwErr(makeString(["updated KLp lower than current KLp", toString(oldKLp), toString(updatedKLp)], " "))
620622
621623
622624 func validateMatcherOrderAllowed (order) = {
623625 let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
624626 let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
625627 let amountAssetAmount = order.amount
626628 let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
627- let $t02815528367 = if ((order.orderType == Buy))
629+ let $t02830128513 = if ((order.orderType == Buy))
628630 then $Tuple2(amountAssetAmount, -(priceAssetAmount))
629631 else $Tuple2(-(amountAssetAmount), priceAssetAmount)
630- let amountAssetBalanceDelta = $t02815528367._1
631- let priceAssetBalanceDelta = $t02815528367._2
632+ let amountAssetBalanceDelta = $t02830128513._1
633+ let priceAssetBalanceDelta = $t02830128513._2
632634 if (if (if (isGlobalShutdown())
633635 then true
634636 else (cfgPoolStatus == PoolMatcherDisabled))
635637 then true
636638 else (cfgPoolStatus == PoolShutdown))
637639 then throw("Exchange operations disabled")
638640 else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
639641 then true
640642 else (order.assetPair.priceAsset != cfgPriceAssetId))
641643 then throw("Wrong order assets.")
642644 else {
643645 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
644- let $t02880728907 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
645- let unusedActions = $t02880728907._1
646- let kLpNew = $t02880728907._2
646+ let $t02895329053 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
647+ let unusedActions = $t02895329053._1
648+ let kLpNew = $t02895329053._2
647649 let isOrderValid = (kLpNew >= kLp)
648650 let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
649651 $Tuple2(isOrderValid, info)
650652 }
651653 }
652654
653655
654656 func commonGet (i) = if ((size(i.payments) != 1))
655657 then throw("exactly 1 payment is expected")
656658 else {
657659 let pmt = value(i.payments[0])
658660 let pmtAssetId = value(pmt.assetId)
659661 let pmtAmt = pmt.amount
660662 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
661663 let outAmAmt = res._1
662664 let outPrAmt = res._2
663665 let poolStatus = parseIntValue(res._9)
664666 let state = res._10
665667 if (if (isGlobalShutdown())
666668 then true
667669 else (poolStatus == PoolShutdown))
668670 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
669671 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
670672 }
671673
672674
673675 func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
674676 then throw("exactly 2 payments are expected")
675677 else {
676678 let amAssetPmt = value(i.payments[0])
677679 let prAssetPmt = value(i.payments[1])
678680 let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
679681 let poolStatus = parseIntValue(estPut._8)
680682 if (if (if (isGlobalShutdown())
681683 then true
682684 else (poolStatus == PoolPutDisabled))
683685 then true
684686 else (poolStatus == PoolShutdown))
685687 then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
686688 else estPut
687689 }
688690
689691
690692 func emit (amount) = {
691693 let emitInv = invoke(factoryContract, "emit", [amount], nil)
692694 if ((emitInv == emitInv))
693695 then {
694696 let emitInvLegacy = match emitInv {
695697 case legacyFactoryContract: Address =>
696698 invoke(legacyFactoryContract, "emit", [amount], nil)
697699 case _ =>
698700 unit
699701 }
700702 if ((emitInvLegacy == emitInvLegacy))
701703 then amount
702704 else throw("Strict value is not equal to itself.")
703705 }
704706 else throw("Strict value is not equal to itself.")
705707 }
706708
707709
708710 func takeFee (amount,fee) = {
709711 let feeAmount = if ((fee == 0))
710712 then 0
711713 else fraction(amount, fee, scale8)
712714 $Tuple2((amount - feeAmount), feeAmount)
713715 }
714716
715717
716718 func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
717719 let isEval = (txId == unit)
718720 let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
719721 let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
720722 let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
721723 then true
722724 else if ((paymentAssetId == cfgPriceAssetId))
723725 then false
724726 else throwErr("invalid asset")
725- let $t03202032313 = if (isEval)
727+ let $t03216632459 = if (isEval)
726728 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
727729 else if (paymentInAmountAsset)
728730 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
729731 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
730- let amountBalanceOld = $t03202032313._1
731- let priceBalanceOld = $t03202032313._2
732- let $t03231732466 = if (paymentInAmountAsset)
732+ let amountBalanceOld = $t03216632459._1
733+ let priceBalanceOld = $t03216632459._2
734+ let $t03246332612 = if (paymentInAmountAsset)
733735 then $Tuple2(paymentAmountRaw, 0)
734736 else $Tuple2(0, paymentAmountRaw)
735- let amountAssetAmountRaw = $t03231732466._1
736- let priceAssetAmountRaw = $t03231732466._2
737+ let amountAssetAmountRaw = $t03246332612._1
738+ let priceAssetAmountRaw = $t03246332612._2
737739 let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
738740 let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
739- let $t03259832662 = takeFee(paymentAmountRaw, inFee)
740- let paymentAmount = $t03259832662._1
741- let feeAmount = $t03259832662._2
741+ let $t03274432808 = takeFee(paymentAmountRaw, inFee)
742+ let paymentAmount = $t03274432808._1
743+ let feeAmount = $t03274432808._2
742744 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
743745 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
744746 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
745747 let priceNew = fromX18(priceNewX18, scale8)
746748 let paymentBalance = if (paymentInAmountAsset)
747749 then amountBalanceOld
748750 else priceBalanceOld
749751 let paymentBalanceBigInt = toBigInt(paymentBalance)
750752 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
751753 let chechSupply = if ((supplyBigInt > big0))
752754 then true
753755 else throwErr("initial deposit requires all coins")
754756 if ((chechSupply == chechSupply))
755757 then {
756758 let depositBigInt = toBigInt(paymentAmount)
757759 let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
758760 let commonState = if (isEval)
759761 then nil
760762 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))]
761763 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
762764 let priceOld = fromX18(priceOldX18, scale8)
763765 let loss = {
764- let $t03434334510 = if (paymentInAmountAsset)
766+ let $t03448934656 = if (paymentInAmountAsset)
765767 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
766768 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
767- let amount = $t03434334510._1
768- let balance = $t03434334510._2
769+ let amount = $t03448934656._1
770+ let balance = $t03448934656._2
769771 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
770772 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
771773 }
772774 $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
773775 }
774776 else throw("Strict value is not equal to itself.")
775777 }
776778
777779
778780 func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
779781 let isEval = (txId == unit)
780782 let cfg = getPoolConfig()
781783 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
782784 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
783785 let checks = [if ((paymentAssetId == cfgLpAssetId))
784786 then true
785787 else throwErr("invalid lp asset")]
786788 if ((checks == checks))
787789 then {
788790 let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
789791 then true
790792 else if ((outAssetId == cfgPriceAssetId))
791793 then false
792794 else throwErr("invalid asset")
793795 let balanceBigInt = if (outInAmountAsset)
794796 then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
795797 else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
796798 let outInAmountAssetDecimals = if (outInAmountAsset)
797799 then amtAssetDcm
798800 else priceAssetDcm
799801 let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
800802 let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
801803 let outBalance = if (outInAmountAsset)
802804 then amBalanceOld
803805 else prBalanceOld
804806 let outBalanceBigInt = toBigInt(outBalance)
805807 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
806808 let redeemedBigInt = toBigInt(paymentAmount)
807809 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
808- let $t03658836644 = takeFee(amountRaw, outFee)
809- let totalAmount = $t03658836644._1
810- let feeAmount = $t03658836644._2
811- let $t03664836874 = if (outInAmountAsset)
810+ let $t03673436790 = takeFee(amountRaw, outFee)
811+ let totalAmount = $t03673436790._1
812+ let feeAmount = $t03673436790._2
813+ let $t03679437020 = if (outInAmountAsset)
812814 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
813815 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
814- let outAmAmount = $t03664836874._1
815- let outPrAmount = $t03664836874._2
816- let amBalanceNew = $t03664836874._3
817- let prBalanceNew = $t03664836874._4
816+ let outAmAmount = $t03679437020._1
817+ let outPrAmount = $t03679437020._2
818+ let amBalanceNew = $t03679437020._3
819+ let prBalanceNew = $t03679437020._4
818820 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
819821 let priceNew = fromX18(priceNewX18, scale8)
820822 let commonState = if (isEval)
821823 then nil
822824 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)]
823825 let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
824826 let priceOld = fromX18(priceOldX18, scale8)
825827 let loss = {
826828 let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
827829 fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
828830 }
829831 $Tuple5(totalAmount, commonState, feeAmount, loss, outInAmountAsset)
830832 }
831833 else throw("Strict value is not equal to itself.")
832834 }
833835
834836
835837 func managerPublicKeyOrUnit () = match getString(mpk()) {
836838 case s: String =>
837839 fromBase58String(s)
838840 case _: Unit =>
839841 unit
840842 case _ =>
841843 throw("Match error")
842844 }
843845
844846
845847 func pendingManagerPublicKeyOrUnit () = match getString(pmpk()) {
846848 case s: String =>
847849 fromBase58String(s)
848850 case _: Unit =>
849851 unit
850852 case _ =>
851853 throw("Match error")
852854 }
853855
854856
855857 func isManager (i) = match managerPublicKeyOrUnit() {
856858 case pk: ByteVector =>
857859 (i.callerPublicKey == pk)
858860 case _: Unit =>
859861 (i.caller == this)
860862 case _ =>
861863 throw("Match error")
862864 }
863865
864866
865867 func mustManager (i) = {
866868 let pd = throw("Permission denied")
867869 match managerPublicKeyOrUnit() {
868870 case pk: ByteVector =>
869871 if ((i.callerPublicKey == pk))
870872 then true
871873 else pd
872874 case _: Unit =>
873875 if ((i.caller == this))
874876 then true
875877 else pd
876878 case _ =>
877879 throw("Match error")
878880 }
879881 }
880882
881883
882884 @Callable(i)
883885 func rebalance () = (rebalanceAsset(getStringOrFail(this, aa())) ++ rebalanceAsset(getStringOrFail(this, pa())))
884886
885887
886888
887889 @Callable(i)
888890 func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse,feePoolAmount) = {
889- let $t03876039065 = if ((isReverse == false))
891+ let $t03890639211 = if ((isReverse == false))
890892 then {
891893 let assetOut = getStringOrFail(this, pa())
892894 let assetIn = getStringOrFail(this, aa())
893895 $Tuple2(assetOut, assetIn)
894896 }
895897 else {
896898 let assetOut = getStringOrFail(this, aa())
897899 let assetIn = getStringOrFail(this, pa())
898900 $Tuple2(assetOut, assetIn)
899901 }
900- let assetOut = $t03876039065._1
901- let assetIn = $t03876039065._2
902+ let assetOut = $t03890639211._1
903+ let assetIn = $t03890639211._2
902904 let poolAssetInBalance = getAccBalance(assetIn)
903905 let poolAssetOutBalance = getAccBalance(assetOut)
904906 let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
905907 let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
906908 let newK = (((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
907909 let checkK = if ((newK >= oldK))
908910 then true
909911 else throw("new K is fewer error")
910912 if ((checkK == checkK))
911913 then $Tuple2(nil, amountOut)
912914 else throw("Strict value is not equal to itself.")
913915 }
914916
915917
916918
917919 @Callable(i)
918920 func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo,feePoolAmount) = {
919921 let swapContact = {
920922 let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil)
921923 if ($isInstanceOf(@, "String"))
922924 then @
923925 else throw(($getType(@) + " couldn't be cast to String"))
924926 }
925927 let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
926928 then true
927929 else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
928930 then true
929931 else throwErr("Permission denied")]
930932 if ((checks == checks))
931933 then {
932934 let pmt = value(i.payments[0])
933935 let assetIn = assetIdToString(pmt.assetId)
934936 let assetOut = if ((isReverse == false))
935937 then getStringOrFail(this, pa())
936938 else getStringOrFail(this, aa())
937939 let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
938940 let poolAssetOutBalance = getAccBalance(assetOut)
939941 let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
940942 let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
941943 let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
942944 let checkK = if ((newK >= oldK))
943945 then true
944946 else throw("new K is fewer error")
945947 if ((checkK == checkK))
946948 then {
947949 let checkMin = if ((amountOut >= amountOutMin))
948950 then true
949951 else throw("Exchange result is fewer coins than expected")
950952 if ((checkMin == checkMin))
951953 then {
952954 let rebalanceState = rebalanceAsset(assetIn)
953955 if ((rebalanceState == rebalanceState))
954956 then {
955957 let withdrawState = withdrawAndRebalanceAsset(assetOut, amountOut)
956958 if ((withdrawState == withdrawState))
957959 then $Tuple2(((withdrawState ++ rebalanceState) ++ [ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))]), amountOut)
958960 else throw("Strict value is not equal to itself.")
959961 }
960962 else throw("Strict value is not equal to itself.")
961963 }
962964 else throw("Strict value is not equal to itself.")
963965 }
964966 else throw("Strict value is not equal to itself.")
965967 }
966968 else throw("Strict value is not equal to itself.")
967969 }
968970
969971
970972
971973 @Callable(i)
972974 func setManager (pendingManagerPublicKey) = {
973975 let checkCaller = mustManager(i)
974976 if ((checkCaller == checkCaller))
975977 then {
976978 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
977979 if ((checkManagerPublicKey == checkManagerPublicKey))
978980 then [StringEntry(pmpk(), pendingManagerPublicKey)]
979981 else throw("Strict value is not equal to itself.")
980982 }
981983 else throw("Strict value is not equal to itself.")
982984 }
983985
984986
985987
986988 @Callable(i)
987989 func confirmManager () = {
988990 let pm = pendingManagerPublicKeyOrUnit()
989991 let hasPM = if (isDefined(pm))
990992 then true
991993 else throw("No pending manager")
992994 if ((hasPM == hasPM))
993995 then {
994996 let checkPM = if ((i.callerPublicKey == value(pm)))
995997 then true
996998 else throw("You are not pending manager")
997999 if ((checkPM == checkPM))
9981000 then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())]
9991001 else throw("Strict value is not equal to itself.")
10001002 }
10011003 else throw("Strict value is not equal to itself.")
10021004 }
10031005
10041006
10051007
10061008 @Callable(i)
10071009 func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
10081010 then throw("Invalid slippageTolerance passed")
10091011 else {
10101012 let estPut = commonPut(i, slippageTolerance, true)
10111013 let emitLpAmt = estPut._2
10121014 let lpAssetId = estPut._7
10131015 let state = estPut._9
10141016 let amDiff = estPut._10
10151017 let prDiff = estPut._11
10161018 let amId = estPut._12
10171019 let prId = estPut._13
10181020 let amAssetPmt = toBigInt(value(i.payments[0]).amount)
10191021 let prAssetPmt = toBigInt(value(i.payments[1]).amount)
10201022 let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
10211023 if ((currentKLp == currentKLp))
10221024 then {
10231025 let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
10241026 if ((emitInv == emitInv))
10251027 then {
10261028 let emitInvLegacy = match emitInv {
10271029 case legacyFactoryContract: Address =>
10281030 invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
10291031 case _ =>
10301032 unit
10311033 }
10321034 if ((emitInvLegacy == emitInvLegacy))
10331035 then {
10341036 let slippageAInv = if ((amDiff > 0))
10351037 then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
10361038 else nil
10371039 if ((slippageAInv == slippageAInv))
10381040 then {
10391041 let slippagePInv = if ((prDiff > 0))
10401042 then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
10411043 else nil
10421044 if ((slippagePInv == slippagePInv))
10431045 then {
10441046 let lpTransfer = if (shouldAutoStake)
10451047 then {
10461048 let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
10471049 if ((slpStakeInv == slpStakeInv))
10481050 then nil
10491051 else throw("Strict value is not equal to itself.")
10501052 }
10511053 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1052- let $t04411144573 = refreshKLpInternal(0, 0, 0)
1053- if (($t04411144573 == $t04411144573))
1054+ let $t04425744719 = refreshKLpInternal(0, 0, 0)
1055+ if (($t04425744719 == $t04425744719))
10541056 then {
1055- let updatedKLp = $t04411144573._2
1056- let refreshKLpActions = $t04411144573._1
1057+ let updatedKLp = $t04425744719._2
1058+ let refreshKLpActions = $t04425744719._1
10571059 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
10581060 if ((isUpdatedKLpValid == isUpdatedKLpValid))
10591061 then {
10601062 let reb = invoke(this, "rebalance", nil, nil)
10611063 if ((reb == reb))
10621064 then ((state ++ lpTransfer) ++ refreshKLpActions)
10631065 else throw("Strict value is not equal to itself.")
10641066 }
10651067 else throw("Strict value is not equal to itself.")
10661068 }
10671069 else throw("Strict value is not equal to itself.")
10681070 }
10691071 else throw("Strict value is not equal to itself.")
10701072 }
10711073 else throw("Strict value is not equal to itself.")
10721074 }
10731075 else throw("Strict value is not equal to itself.")
10741076 }
10751077 else throw("Strict value is not equal to itself.")
10761078 }
10771079 else throw("Strict value is not equal to itself.")
10781080 }
10791081
10801082
10811083
10821084 @Callable(i)
10831085 func putForFree (maxSlippage) = if ((0 > maxSlippage))
10841086 then throw("Invalid value passed")
10851087 else {
10861088 let estPut = commonPut(i, maxSlippage, false)
10871089 let state = estPut._9
10881090 let amAssetPmt = toBigInt(value(i.payments[0]).amount)
10891091 let prAssetPmt = toBigInt(value(i.payments[1]).amount)
10901092 let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
10911093 if ((currentKLp == currentKLp))
10921094 then {
1093- let $t04518545250 = refreshKLpInternal(0, 0, 0)
1094- let refreshKLpActions = $t04518545250._1
1095- let updatedKLp = $t04518545250._2
1095+ let $t04533145396 = refreshKLpInternal(0, 0, 0)
1096+ let refreshKLpActions = $t04533145396._1
1097+ let updatedKLp = $t04533145396._2
10961098 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
10971099 if ((isUpdatedKLpValid == isUpdatedKLpValid))
10981100 then (state ++ refreshKLpActions)
10991101 else throw("Strict value is not equal to itself.")
11001102 }
11011103 else throw("Strict value is not equal to itself.")
11021104 }
11031105
11041106
11051107
11061108 @Callable(i)
11071109 func putOneTkn (minOutAmount,autoStake) = {
11081110 let isPoolOneTokenOperationsDisabled = {
11091111 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
11101112 if ($isInstanceOf(@, "Boolean"))
11111113 then @
11121114 else throw(($getType(@) + " couldn't be cast to Boolean"))
11131115 }
11141116 let isPutDisabled = if (if (if (isGlobalShutdown())
11151117 then true
11161118 else (cfgPoolStatus == PoolPutDisabled))
11171119 then true
11181120 else (cfgPoolStatus == PoolShutdown))
11191121 then true
11201122 else isPoolOneTokenOperationsDisabled
11211123 let checks = [if (if (!(isPutDisabled))
11221124 then true
11231125 else isManager(i))
11241126 then true
11251127 else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
11261128 then true
11271129 else throwErr("exactly 1 payment are expected")]
11281130 if ((checks == checks))
11291131 then {
11301132 let payment = i.payments[0]
11311133 let paymentAssetId = payment.assetId
11321134 let paymentAmountRaw = payment.amount
11331135 let currentKLp = if ((paymentAssetId == cfgAmountAssetId))
11341136 then calcCurrentKLp(toBigInt(paymentAmountRaw), toBigInt(0), toBigInt(0))
11351137 else if ((paymentAssetId == cfgPriceAssetId))
11361138 then calcCurrentKLp(toBigInt(0), toBigInt(paymentAmountRaw), toBigInt(0))
11371139 else throwErr("payment asset is not supported")
11381140 if ((currentKLp == currentKLp))
11391141 then {
11401142 let userAddress = i.caller
11411143 let txId = i.transactionId
1142- let $t04643846590 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
1143- if (($t04643846590 == $t04643846590))
1144+ let $t04658446736 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
1145+ if (($t04658446736 == $t04658446736))
11441146 then {
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
1147+ let paymentInAmountAsset = $t04658446736._5
1148+ let bonus = $t04658446736._4
1149+ let feeAmount = $t04658446736._3
1150+ let commonState = $t04658446736._2
1151+ let emitAmountEstimated = $t04658446736._1
11501152 let emitAmount = if (if ((minOutAmount > 0))
11511153 then (minOutAmount > emitAmountEstimated)
11521154 else false)
11531155 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
11541156 else emitAmountEstimated
11551157 let emitInv = emit(emitAmount)
11561158 if ((emitInv == emitInv))
11571159 then {
11581160 let lpTransfer = if (autoStake)
11591161 then {
11601162 let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
11611163 if ((stakeInv == stakeInv))
11621164 then nil
11631165 else throw("Strict value is not equal to itself.")
11641166 }
11651167 else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
11661168 let sendFee = if ((feeAmount > 0))
11671169 then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
11681170 else nil
1169- let $t04717647373 = if ((this == feeCollectorAddress))
1171+ let $t04732247519 = if ((this == feeCollectorAddress))
11701172 then $Tuple2(0, 0)
11711173 else if (paymentInAmountAsset)
11721174 then $Tuple2(-(feeAmount), 0)
11731175 else $Tuple2(0, -(feeAmount))
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
1176+ let amountAssetBalanceDelta = $t04732247519._1
1177+ let priceAssetBalanceDelta = $t04732247519._2
1178+ let $t04752247630 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1179+ let refreshKLpActions = $t04752247630._1
1180+ let updatedKLp = $t04752247630._2
11791181 let kLp = value(getString(keyKLp))
11801182 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11811183 if ((isUpdatedKLpValid == isUpdatedKLpValid))
11821184 then {
11831185 let reb = invoke(this, "rebalance", nil, nil)
11841186 if ((reb == reb))
11851187 then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
11861188 else throw("Strict value is not equal to itself.")
11871189 }
11881190 else throw("Strict value is not equal to itself.")
11891191 }
11901192 else throw("Strict value is not equal to itself.")
11911193 }
11921194 else throw("Strict value is not equal to itself.")
11931195 }
11941196 else throw("Strict value is not equal to itself.")
11951197 }
11961198 else throw("Strict value is not equal to itself.")
11971199 }
11981200
11991201
12001202
12011203 @Callable(i)
12021204 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
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
1205+ let $t04798548142 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
1206+ let emitAmountEstimated = $t04798548142._1
1207+ let commonState = $t04798548142._2
1208+ let feeAmount = $t04798548142._3
1209+ let bonus = $t04798548142._4
1210+ let paymentInAmountAsset = $t04798548142._5
12091211 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
12101212 }
12111213
12121214
12131215
12141216 @Callable(i)
12151217 func getOneTkn (outAssetIdStr,minOutAmount) = {
12161218 let isPoolOneTokenOperationsDisabled = {
12171219 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
12181220 if ($isInstanceOf(@, "Boolean"))
12191221 then @
12201222 else throw(($getType(@) + " couldn't be cast to Boolean"))
12211223 }
12221224 let isGetDisabled = if (if (isGlobalShutdown())
12231225 then true
12241226 else (cfgPoolStatus == PoolShutdown))
12251227 then true
12261228 else isPoolOneTokenOperationsDisabled
12271229 let checks = [if (if (!(isGetDisabled))
12281230 then true
12291231 else isManager(i))
12301232 then true
12311233 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
12321234 then true
12331235 else throwErr("exactly 1 payment are expected")]
12341236 if ((checks == checks))
12351237 then {
12361238 let outAssetId = parseAssetId(outAssetIdStr)
12371239 let payment = i.payments[0]
12381240 let paymentAssetId = payment.assetId
12391241 let paymentAmount = payment.amount
12401242 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
12411243 if ((currentKLp == currentKLp))
12421244 then {
12431245 let userAddress = i.caller
12441246 let txId = i.transactionId
1245- let $t04888149034 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1246- if (($t04888149034 == $t04888149034))
1247+ let $t04902749180 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1248+ if (($t04902749180 == $t04902749180))
12471249 then {
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
1250+ let outInAmountAsset = $t04902749180._5
1251+ let bonus = $t04902749180._4
1252+ let feeAmount = $t04902749180._3
1253+ let commonState = $t04902749180._2
1254+ let amountEstimated = $t04902749180._1
12531255 let amount = if (if ((minOutAmount > 0))
12541256 then (minOutAmount > amountEstimated)
12551257 else false)
12561258 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
12571259 else amountEstimated
12581260 let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
12591261 if ((burnInv == burnInv))
12601262 then {
12611263 let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
12621264 let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
12631265 let sendFee = if ((feeAmount > 0))
12641266 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
12651267 else nil
1266- let $t04969849945 = {
1268+ let $t04984450091 = {
12671269 let feeAmountForCalc = if ((this == feeCollectorAddress))
12681270 then 0
12691271 else feeAmount
12701272 if (outInAmountAsset)
12711273 then $Tuple2(-((amount + feeAmountForCalc)), 0)
12721274 else $Tuple2(0, -((amount + feeAmountForCalc)))
12731275 }
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
1276+ let amountAssetBalanceDelta = $t04984450091._1
1277+ let priceAssetBalanceDelta = $t04984450091._2
1278+ let $t05009450202 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1279+ let refreshKLpActions = $t05009450202._1
1280+ let updatedKLp = $t05009450202._2
12791281 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
12801282 if ((isUpdatedKLpValid == isUpdatedKLpValid))
12811283 then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
12821284 else throw("Strict value is not equal to itself.")
12831285 }
12841286 else throw("Strict value is not equal to itself.")
12851287 }
12861288 else throw("Strict value is not equal to itself.")
12871289 }
12881290 else throw("Strict value is not equal to itself.")
12891291 }
12901292 else throw("Strict value is not equal to itself.")
12911293 }
12921294
12931295
12941296
12951297 @Callable(i)
12961298 func getOneTknREADONLY (outAssetId,paymentAmount) = {
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
1299+ let $t05048050636 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1300+ let amountEstimated = $t05048050636._1
1301+ let commonState = $t05048050636._2
1302+ let feeAmount = $t05048050636._3
1303+ let bonus = $t05048050636._4
1304+ let outInAmountAsset = $t05048050636._5
13031305 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
13041306 }
13051307
13061308
13071309
13081310 @Callable(i)
13091311 func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
13101312 let isPoolOneTokenOperationsDisabled = {
13111313 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
13121314 if ($isInstanceOf(@, "Boolean"))
13131315 then @
13141316 else throw(($getType(@) + " couldn't be cast to Boolean"))
13151317 }
13161318 let isGetDisabled = if (if (isGlobalShutdown())
13171319 then true
13181320 else (cfgPoolStatus == PoolShutdown))
13191321 then true
13201322 else isPoolOneTokenOperationsDisabled
13211323 let checks = [if (if (!(isGetDisabled))
13221324 then true
13231325 else isManager(i))
13241326 then true
13251327 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
13261328 then true
13271329 else throwErr("no payments are expected")]
13281330 if ((checks == checks))
13291331 then {
13301332 let outAssetId = parseAssetId(outAssetIdStr)
13311333 let userAddress = i.caller
13321334 let txId = i.transactionId
13331335 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
13341336 if ((currentKLp == currentKLp))
13351337 then {
13361338 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
13371339 if ((unstakeInv == unstakeInv))
13381340 then {
1339- let $t05139551546 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1340- if (($t05139551546 == $t05139551546))
1341+ let $t05154151692 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1342+ if (($t05154151692 == $t05154151692))
13411343 then {
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
1344+ let outInAmountAsset = $t05154151692._5
1345+ let bonus = $t05154151692._4
1346+ let feeAmount = $t05154151692._3
1347+ let commonState = $t05154151692._2
1348+ let amountEstimated = $t05154151692._1
13471349 let amount = if (if ((minOutAmount > 0))
13481350 then (minOutAmount > amountEstimated)
13491351 else false)
13501352 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
13511353 else amountEstimated
13521354 let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
13531355 if ((burnInv == burnInv))
13541356 then {
13551357 let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
13561358 let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
13571359 let sendFee = if ((feeAmount > 0))
13581360 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
13591361 else nil
1360- let $t05220552452 = {
1362+ let $t05235152598 = {
13611363 let feeAmountForCalc = if ((this == feeCollectorAddress))
13621364 then 0
13631365 else feeAmount
13641366 if (outInAmountAsset)
13651367 then $Tuple2(-((amount + feeAmountForCalc)), 0)
13661368 else $Tuple2(0, -((amount + feeAmountForCalc)))
13671369 }
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
1370+ let amountAssetBalanceDelta = $t05235152598._1
1371+ let priceAssetBalanceDelta = $t05235152598._2
1372+ let $t05260152709 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1373+ let refreshKLpActions = $t05260152709._1
1374+ let updatedKLp = $t05260152709._2
13731375 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
13741376 if ((isUpdatedKLpValid == isUpdatedKLpValid))
13751377 then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
13761378 else throw("Strict value is not equal to itself.")
13771379 }
13781380 else throw("Strict value is not equal to itself.")
13791381 }
13801382 else throw("Strict value is not equal to itself.")
13811383 }
13821384 else throw("Strict value is not equal to itself.")
13831385 }
13841386 else throw("Strict value is not equal to itself.")
13851387 }
13861388 else throw("Strict value is not equal to itself.")
13871389 }
13881390
13891391
13901392
13911393 @Callable(i)
13921394 func get () = {
13931395 let res = commonGet(i)
13941396 let outAmAmt = res._1
13951397 let outPrAmt = res._2
13961398 let pmtAmt = res._3
13971399 let pmtAssetId = res._4
13981400 let state = res._5
13991401 let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
14001402 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
14011403 if ((currentKLp == currentKLp))
14021404 then {
14031405 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
14041406 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
14051407 then {
1406- let $t05365853739 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1407- let refreshKLpActions = $t05365853739._1
1408- let updatedKLp = $t05365853739._2
1408+ let $t05380453885 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1409+ let refreshKLpActions = $t05380453885._1
1410+ let updatedKLp = $t05380453885._2
14091411 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
14101412 if ((isUpdatedKLpValid == isUpdatedKLpValid))
14111413 then ((withdrawState ++ state) ++ refreshKLpActions)
14121414 else throw("Strict value is not equal to itself.")
14131415 }
14141416 else throw("Strict value is not equal to itself.")
14151417 }
14161418 else throw("Strict value is not equal to itself.")
14171419 }
14181420
14191421
14201422
14211423 @Callable(i)
14221424 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
14231425 let res = commonGet(i)
14241426 let outAmAmt = res._1
14251427 let outPrAmt = res._2
14261428 let pmtAmt = res._3
14271429 let pmtAssetId = res._4
14281430 let state = res._5
14291431 if ((noLessThenAmtAsset > outAmAmt))
14301432 then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
14311433 else if ((noLessThenPriceAsset > outPrAmt))
14321434 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
14331435 else {
14341436 let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
14351437 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
14361438 if ((currentKLp == currentKLp))
14371439 then {
14381440 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
14391441 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
14401442 then {
1441- let $t05483454915 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1442- let refreshKLpActions = $t05483454915._1
1443- let updatedKLp = $t05483454915._2
1443+ let $t05498055061 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1444+ let refreshKLpActions = $t05498055061._1
1445+ let updatedKLp = $t05498055061._2
14441446 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
14451447 if ((isUpdatedKLpValid == isUpdatedKLpValid))
14461448 then ((withdrawState ++ state) ++ refreshKLpActions)
14471449 else throw("Strict value is not equal to itself.")
14481450 }
14491451 else throw("Strict value is not equal to itself.")
14501452 }
14511453 else throw("Strict value is not equal to itself.")
14521454 }
14531455 }
14541456
14551457
14561458
14571459 @Callable(i)
14581460 func unstakeAndGet (amount) = {
14591461 let checkPayments = if ((size(i.payments) != 0))
14601462 then throw("No payments are expected")
14611463 else true
14621464 if ((checkPayments == checkPayments))
14631465 then {
14641466 let cfg = getPoolConfig()
14651467 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
14661468 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
14671469 if ((currentKLp == currentKLp))
14681470 then {
14691471 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
14701472 if ((unstakeInv == unstakeInv))
14711473 then {
14721474 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
14731475 let outAmAmt = res._1
14741476 let outPrAmt = res._2
14751477 let poolStatus = parseIntValue(res._9)
14761478 let state = res._10
14771479 let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
14781480 let checkPoolStatus = if (if (isGlobalShutdown())
14791481 then true
14801482 else (poolStatus == PoolShutdown))
14811483 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
14821484 else true
14831485 if ((checkPoolStatus == checkPoolStatus))
14841486 then {
14851487 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
14861488 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
14871489 then {
1488- let $t05618756268 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1489- let refreshKLpActions = $t05618756268._1
1490- let updatedKLp = $t05618756268._2
1490+ let $t05633356414 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1491+ let refreshKLpActions = $t05633356414._1
1492+ let updatedKLp = $t05633356414._2
14911493 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
14921494 if ((isUpdatedKLpValid == isUpdatedKLpValid))
14931495 then ((withdrawState ++ state) ++ refreshKLpActions)
14941496 else throw("Strict value is not equal to itself.")
14951497 }
14961498 else throw("Strict value is not equal to itself.")
14971499 }
14981500 else throw("Strict value is not equal to itself.")
14991501 }
15001502 else throw("Strict value is not equal to itself.")
15011503 }
15021504 else throw("Strict value is not equal to itself.")
15031505 }
15041506 else throw("Strict value is not equal to itself.")
15051507 }
15061508
15071509
15081510
15091511 @Callable(i)
15101512 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
15111513 let isGetDisabled = if (isGlobalShutdown())
15121514 then true
15131515 else (cfgPoolStatus == PoolShutdown)
15141516 let checks = [if (!(isGetDisabled))
15151517 then true
15161518 else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
15171519 then true
15181520 else throw("no payments are expected")]
15191521 if ((checks == checks))
15201522 then {
15211523 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
15221524 if ((currentKLp == currentKLp))
15231525 then {
15241526 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
15251527 if ((unstakeInv == unstakeInv))
15261528 then {
15271529 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
15281530 let outAmAmt = res._1
15291531 let outPrAmt = res._2
15301532 let state = res._10
15311533 let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
15321534 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
15331535 then true
15341536 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
15351537 then true
15361538 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
15371539 if ((checkAmounts == checkAmounts))
15381540 then {
15391541 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
15401542 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
15411543 then {
1542- let $t05770957790 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1543- let refreshKLpActions = $t05770957790._1
1544- let updatedKLp = $t05770957790._2
1544+ let $t05785557936 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1545+ let refreshKLpActions = $t05785557936._1
1546+ let updatedKLp = $t05785557936._2
15451547 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
15461548 if ((isUpdatedKLpValid == isUpdatedKLpValid))
15471549 then ((withdrawState ++ state) ++ refreshKLpActions)
15481550 else throw("Strict value is not equal to itself.")
15491551 }
15501552 else throw("Strict value is not equal to itself.")
15511553 }
15521554 else throw("Strict value is not equal to itself.")
15531555 }
15541556 else throw("Strict value is not equal to itself.")
15551557 }
15561558 else throw("Strict value is not equal to itself.")
15571559 }
15581560 else throw("Strict value is not equal to itself.")
15591561 }
15601562
15611563
15621564
15631565 @Callable(i)
15641566 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
15651567 then throw("permissions denied")
15661568 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
15671569
15681570
15691571
15701572 @Callable(i)
15711573 func refreshKLp () = {
15721574 let lastRefreshedBlockHeight = valueOrElse(getInteger(keyKLpRefreshedHeight), 0)
15731575 let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= kLpRefreshDelay))
15741576 then unit
15751577 else throwErr(makeString([toString(kLpRefreshDelay), " blocks have not passed since the previous call"], ""))
15761578 if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
15771579 then {
15781580 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1579- let $t05899459058 = refreshKLpInternal(0, 0, 0)
1580- let kLpUpdateActions = $t05899459058._1
1581- let updatedKLp = $t05899459058._2
1581+ let $t05914059204 = refreshKLpInternal(0, 0, 0)
1582+ let kLpUpdateActions = $t05914059204._1
1583+ let updatedKLp = $t05914059204._2
15821584 let actions = if ((kLp != updatedKLp))
15831585 then kLpUpdateActions
15841586 else throwErr("nothing to refresh")
15851587 $Tuple2(actions, toString(updatedKLp))
15861588 }
15871589 else throw("Strict value is not equal to itself.")
15881590 }
15891591
15901592
15911593
15921594 @Callable(i)
15931595 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
15941596
15951597
15961598
15971599 @Callable(i)
15981600 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
15991601
16001602
16011603
16021604 @Callable(i)
16031605 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
16041606 let prices = calcPrices(amAmt, prAmt, lpAmt)
16051607 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
16061608 }
16071609
16081610
16091611
16101612 @Callable(i)
16111613 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
16121614
16131615
16141616
16151617 @Callable(i)
16161618 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
16171619
16181620
16191621
16201622 @Callable(i)
16211623 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
16221624
16231625
16241626
16251627 @Callable(i)
16261628 func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
16271629
16281630
16291631
16301632 @Callable(i)
16311633 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
16321634 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
16331635 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
16341636 }
16351637
16361638
16371639
16381640 @Callable(i)
16391641 func statsREADONLY () = {
16401642 let cfg = getPoolConfig()
16411643 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
16421644 let amtAssetId = cfg[idxAmtAssetId]
16431645 let priceAssetId = cfg[idxPriceAssetId]
16441646 let iAmtAssetId = cfg[idxIAmtAssetId]
16451647 let iPriceAssetId = cfg[idxIPriceAssetId]
16461648 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
16471649 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
16481650 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
16491651 let accAmtAssetBalance = getAccBalance(amtAssetId)
16501652 let accPriceAssetBalance = getAccBalance(priceAssetId)
16511653 let pricesList = if ((poolLPBalance == 0))
16521654 then [zeroBigInt, zeroBigInt, zeroBigInt]
16531655 else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
16541656 let curPrice = 0
16551657 let lpAmtAssetShare = fromX18(pricesList[1], scale8)
16561658 let lpPriceAssetShare = fromX18(pricesList[2], scale8)
16571659 let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
16581660 $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))
16591661 }
16601662
16611663
16621664
16631665 @Callable(i)
16641666 func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
16651667 let cfg = getPoolConfig()
16661668 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
16671669 let amAssetIdStr = cfg[idxAmtAssetId]
16681670 let amAssetId = fromBase58String(amAssetIdStr)
16691671 let prAssetIdStr = cfg[idxPriceAssetId]
16701672 let prAssetId = fromBase58String(prAssetIdStr)
16711673 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
16721674 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
16731675 let poolStatus = cfg[idxPoolStatus]
16741676 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
16751677 let accAmtAssetBalance = getAccBalance(amAssetIdStr)
16761678 let accPriceAssetBalance = getAccBalance(prAssetIdStr)
16771679 let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
16781680 let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
16791681 let curPriceX18 = if ((poolLPBalance == 0))
16801682 then zeroBigInt
16811683 else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
16821684 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
16831685 let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
16841686 let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
16851687 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
16861688 let calcLpAmt = estPut._1
16871689 let curPriceCalc = estPut._3
16881690 let amBalance = estPut._4
16891691 let prBalance = estPut._5
16901692 let lpEmission = estPut._6
16911693 $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))
16921694 }
16931695
16941696
16951697
16961698 @Callable(i)
16971699 func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
16981700 let cfg = getPoolConfig()
16991701 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
17001702 let amAssetIdStr = cfg[idxAmtAssetId]
17011703 let amAssetId = fromBase58String(amAssetIdStr)
17021704 let prAssetIdStr = cfg[idxPriceAssetId]
17031705 let prAssetId = fromBase58String(prAssetIdStr)
17041706 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
17051707 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
17061708 let poolStatus = cfg[idxPoolStatus]
17071709 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
17081710 let amBalanceRaw = getAccBalance(amAssetIdStr)
17091711 let prBalanceRaw = getAccBalance(prAssetIdStr)
17101712 let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
17111713 let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
17121714 let curPriceX18 = if ((poolLPBalance == 0))
17131715 then zeroBigInt
17141716 else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
17151717 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
17161718 let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
17171719 let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
17181720 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
17191721 let calcLpAmt = estPut._1
17201722 let curPriceCalc = estPut._3
17211723 let amBalance = estPut._4
17221724 let prBalance = estPut._5
17231725 let lpEmission = estPut._6
17241726 $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))
17251727 }
17261728
17271729
17281730
17291731 @Callable(i)
17301732 func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
17311733 let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
17321734 let outAmAmt = res._1
17331735 let outPrAmt = res._2
17341736 let amBalance = res._5
17351737 let prBalance = res._6
17361738 let lpEmission = res._7
17371739 let curPrice = res._8
17381740 let poolStatus = parseIntValue(res._9)
17391741 $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))
17401742 }
17411743
17421744
17431745 @Verifier(tx)
17441746 func verify () = {
17451747 let targetPublicKey = match managerPublicKeyOrUnit() {
17461748 case pk: ByteVector =>
17471749 pk
17481750 case _: Unit =>
17491751 tx.senderPublicKey
17501752 case _ =>
17511753 throw("Match error")
17521754 }
17531755 match tx {
17541756 case order: Order =>
17551757 let matcherPub = getMatcherPubOrFail()
1756- let $t06772067789 = validateMatcherOrderAllowed(order)
1757- let orderValid = $t06772067789._1
1758- let orderValidInfo = $t06772067789._2
1758+ let $t06786667935 = validateMatcherOrderAllowed(order)
1759+ let orderValid = $t06786667935._1
1760+ let orderValidInfo = $t06786667935._2
17591761 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
17601762 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
17611763 if (if (if (orderValid)
17621764 then senderValid
17631765 else false)
17641766 then matcherValid
17651767 else false)
17661768 then true
17671769 else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
17681770 case s: SetScriptTransaction =>
17691771 if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
17701772 then true
17711773 else {
17721774 let newHash = blake2b256(value(s.script))
17731775 let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
17741776 let currentHash = scriptHash(this)
17751777 if ((allowedHash == newHash))
17761778 then (currentHash != newHash)
17771779 else false
17781780 }
17791781 case _ =>
17801782 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
17811783 }
17821784 }
17831785

github/deemru/w8io/169f3d6 
245.08 ms