2023.02.14 13:44 [3514775] smart account 3PEMqetsaJDbYMw1XGovmE37FB8VUhGnX9A > SELF 0.00000000 Waves

{ "type": 13, "id": "AZvaCTVLgUg4nLpdhsAi6g26BcddFhWmFQvK8qWNoSfj", "fee": 3800000, "feeAssetId": null, "timestamp": 1676371477774, "version": 2, "chainId": 87, "sender": "3PEMqetsaJDbYMw1XGovmE37FB8VUhGnX9A", "senderPublicKey": "9qgdsmC729MergDJsKAPxR8Pf2t8bTaTMqnRc7gj3r28", "proofs": [ "raFzymJNLRjqBsKtujEthjojT78CMDpMy6xc8H9CDKM8XWCPQJZCynnX155ntbrx2fAS4Kye4LgPTLnyZYTGcSW" ], "script": "base64:BgLRLwgCEgQKAgEEEgYKBAEEAQgSAwoBCBIAEgQKAgEEEgMKAQESBAoCAQQSBAoCCAESBAoCCAESBAoCCAESBQoDAQgBEgASBAoCAQESAwoBARIFCgMBAQESBAoCCAgSABIAEgMKAQgSBQoDAQEBEgQKAgEBEgQKAggBEgQKAggIEgsKCQgBAQIBAggEBBIGCgQICAEIEgASAwoBARIDCgEBEgQKAggBIgpsUGRlY2ltYWxzIgZzY2FsZTgiDHNjYWxlOEJpZ0ludCIHc2NhbGUxOCIKemVyb0JpZ0ludCIEYmlnMCIEYmlnMSIEYmlnMiILd2F2ZXNTdHJpbmciA1NFUCIKUG9vbEFjdGl2ZSIPUG9vbFB1dERpc2FibGVkIhNQb29sTWF0Y2hlckRpc2FibGVkIgxQb29sU2h1dGRvd24iDmlkeFBvb2xBZGRyZXNzIg1pZHhQb29sU3RhdHVzIhBpZHhQb29sTFBBc3NldElkIg1pZHhBbXRBc3NldElkIg9pZHhQcmljZUFzc2V0SWQiDmlkeEFtdEFzc2V0RGNtIhBpZHhQcmljZUFzc2V0RGNtIg5pZHhJQW10QXNzZXRJZCIQaWR4SVByaWNlQXNzZXRJZCINaWR4TFBBc3NldERjbSISaWR4UG9vbEFtdEFzc2V0QW10IhRpZHhQb29sUHJpY2VBc3NldEFtdCIRaWR4UG9vbExQQXNzZXRBbXQiGWlkeEZhY3RvcnlTdGFraW5nQ29udHJhY3QiGmlkeEZhY3RvcnlTbGlwcGFnZUNvbnRyYWN0IgV0b1gxOCIHb3JpZ1ZhbCINb3JpZ1NjYWxlTXVsdCILdG9YMThCaWdJbnQiB2Zyb21YMTgiA3ZhbCIPcmVzdWx0U2NhbGVNdWx0Igxmcm9tWDE4Um91bmQiBXJvdW5kIgd0b1NjYWxlIgNhbXQiCHJlc1NjYWxlIghjdXJTY2FsZSIDYWJzIglhYnNCaWdJbnQiDHN3YXBDb250cmFjdCICZmMiA21wayIEcG1wayICcGwiAnBoIgFoIgl0aW1lc3RhbXAiA3BhdSILdXNlckFkZHJlc3MiBHR4SWQiA2dhdSICYWEiAnBhIgZrZXlGZWUiCmZlZURlZmF1bHQiA2ZlZSIGa2V5S0xwIhVrZXlLTHBSZWZyZXNoZWRIZWlnaHQiEmtleUtMcFJlZnJlc2hEZWxheSIWa0xwUmVmcmVzaERlbGF5RGVmYXVsdCIPa0xwUmVmcmVzaERlbGF5IhBrZXlGYWN0b3J5Q29uZmlnIg1rZXlNYXRjaGVyUHViIilrZXlNYXBwaW5nUG9vbENvbnRyYWN0QWRkcmVzc1RvUG9vbEFzc2V0cyITcG9vbENvbnRyYWN0QWRkcmVzcyINa2V5UG9vbENvbmZpZyIJaUFtdEFzc2V0IgtpUHJpY2VBc3NldCIfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZCIMYmFzZUFzc2V0U3RyIhNrZXlBbGxQb29sc1NodXRkb3duIg1rZXlQb29sV2VpZ2h0Ig9jb250cmFjdEFkZHJlc3MiFmtleUFsbG93ZWRMcFNjcmlwdEhhc2giFmtleUZlZUNvbGxlY3RvckFkZHJlc3MiD3Rocm93T3JkZXJFcnJvciIKb3JkZXJWYWxpZCIOb3JkZXJWYWxpZEluZm8iC3NlbmRlclZhbGlkIgxtYXRjaGVyVmFsaWQiD2dldFN0cmluZ09yRmFpbCIHYWRkcmVzcyIDa2V5IgxnZXRJbnRPckZhaWwiCHRocm93RXJyIgNtc2ciBmZtdEVyciIPZmFjdG9yeUNvbnRyYWN0IhNmZWVDb2xsZWN0b3JBZGRyZXNzIgVpbkZlZSIBQCIGb3V0RmVlIhBpc0dsb2JhbFNodXRkb3duIhNnZXRNYXRjaGVyUHViT3JGYWlsIg1nZXRQb29sQ29uZmlnIghhbXRBc3NldCIKcHJpY2VBc3NldCIMcGFyc2VBc3NldElkIgVpbnB1dCIPYXNzZXRJZFRvU3RyaW5nIg9wYXJzZVBvb2xDb25maWciCnBvb2xDb25maWciEHBvb2xDb25maWdQYXJzZWQiCyR0MDg0Njk4NjM1Ig5jZmdQb29sQWRkcmVzcyINY2ZnUG9vbFN0YXR1cyIMY2ZnTHBBc3NldElkIhBjZmdBbW91bnRBc3NldElkIg9jZmdQcmljZUFzc2V0SWQiFmNmZ0Ftb3VudEFzc2V0RGVjaW1hbHMiFWNmZ1ByaWNlQXNzZXREZWNpbWFscyIQZ2V0RmFjdG9yeUNvbmZpZyIPc3Rha2luZ0NvbnRyYWN0IhBzbGlwcGFnZUNvbnRyYWN0IhFkYXRhUHV0QWN0aW9uSW5mbyINaW5BbXRBc3NldEFtdCIPaW5QcmljZUFzc2V0QW10IghvdXRMcEFtdCIFcHJpY2UiHXNsaXBwYWdlVG9sZXJhbmNlUGFzc2VkQnlVc2VyIhVzbGlwcGFnZVRvbGVyYW5jZVJlYWwiCHR4SGVpZ2h0Igt0eFRpbWVzdGFtcCISc2xpcGFnZUFtdEFzc2V0QW10IhRzbGlwYWdlUHJpY2VBc3NldEFtdCIRZGF0YUdldEFjdGlvbkluZm8iDm91dEFtdEFzc2V0QW10IhBvdXRQcmljZUFzc2V0QW10IgdpbkxwQW10Ig1nZXRBY2NCYWxhbmNlIgdhc3NldElkIg9jYWxjUHJpY2VCaWdJbnQiCHByQW10WDE4IghhbUFtdFgxOCIUY2FsY1ByaWNlQmlnSW50Um91bmQiEHByaXZhdGVDYWxjUHJpY2UiCmFtQXNzZXREY20iCnByQXNzZXREY20iBWFtQW10IgVwckFtdCIOYW10QXNzZXRBbXRYMTgiEHByaWNlQXNzZXRBbXRYMTgiCmNhbGNQcmljZXMiBWxwQW10IgNjZmciC2FtdEFzc2V0RGNtIg1wcmljZUFzc2V0RGNtIghwcmljZVgxOCIIbHBBbXRYMTgiE2xwUHJpY2VJbkFtQXNzZXRYMTgiE2xwUHJpY2VJblByQXNzZXRYMTgiD2NhbGN1bGF0ZVByaWNlcyIGcHJpY2VzIhRlc3RpbWF0ZUdldE9wZXJhdGlvbiIGdHhJZDU4IgpwbXRBc3NldElkIghwbXRMcEFtdCIJbHBBc3NldElkIglhbUFzc2V0SWQiCXByQXNzZXRJZCIKcG9vbFN0YXR1cyIKbHBFbWlzc2lvbiIJYW1CYWxhbmNlIgxhbUJhbGFuY2VYMTgiCXByQmFsYW5jZSIMcHJCYWxhbmNlWDE4IgtjdXJQcmljZVgxOCIIY3VyUHJpY2UiC3BtdExwQW10WDE4Ig1scEVtaXNzaW9uWDE4IgtvdXRBbUFtdFgxOCILb3V0UHJBbXRYMTgiCG91dEFtQW10IghvdXRQckFtdCIFc3RhdGUiFGVzdGltYXRlUHV0T3BlcmF0aW9uIhFzbGlwcGFnZVRvbGVyYW5jZSIMaW5BbUFzc2V0QW10IgtpbkFtQXNzZXRJZCIMaW5QckFzc2V0QW10IgtpblByQXNzZXRJZCIKaXNFdmFsdWF0ZSIGZW1pdExwIgxhbUFzc2V0SWRTdHIiDHByQXNzZXRJZFN0ciILaUFtdEFzc2V0SWQiDWlQcmljZUFzc2V0SWQiDmluQW1Bc3NldElkU3RyIg5pblByQXNzZXRJZFN0ciIPaW5BbUFzc2V0QW10WDE4Ig9pblByQXNzZXRBbXRYMTgiDHVzZXJQcmljZVgxOCIDcmVzIgtzbGlwcGFnZVgxOCIUc2xpcHBhZ2VUb2xlcmFuY2VYMTgiCnByVmlhQW1YMTgiCmFtVmlhUHJYMTgiDGV4cGVjdGVkQW10cyIRZXhwQW10QXNzZXRBbXRYMTgiE2V4cFByaWNlQXNzZXRBbXRYMTgiCWNhbGNMcEFtdCIOY2FsY0FtQXNzZXRQbXQiDmNhbGNQckFzc2V0UG10IgxzbGlwcGFnZUNhbGMiCWVtaXRMcEFtdCIGYW1EaWZmIgZwckRpZmYiC2NvbW1vblN0YXRlIgdjYWxjS0xwIg1hbW91bnRCYWxhbmNlIgxwcmljZUJhbGFuY2UiEGFtb3VudEJhbGFuY2VYMTgiD3ByaWNlQmFsYW5jZVgxOCIKdXBkYXRlZEtMcCIOY2FsY0N1cnJlbnRLTHAiEGFtb3VudEFzc2V0RGVsdGEiD3ByaWNlQXNzZXREZWx0YSIUbHBBc3NldEVtaXNzaW9uRGVsdGEiEmFtb3VudEFzc2V0QmFsYW5jZSIRcHJpY2VBc3NldEJhbGFuY2UiD2xwQXNzZXRFbWlzc2lvbiIKY3VycmVudEtMcCIScmVmcmVzaEtMcEludGVybmFsIhdhbW91bnRBc3NldEJhbGFuY2VEZWx0YSIWcHJpY2VBc3NldEJhbGFuY2VEZWx0YSIHYWN0aW9ucyISdmFsaWRhdGVVcGRhdGVkS0xwIgZvbGRLTHAiG3ZhbGlkYXRlTWF0Y2hlck9yZGVyQWxsb3dlZCIFb3JkZXIiEWFtb3VudEFzc2V0QW1vdW50IhBwcmljZUFzc2V0QW1vdW50Ig0kdDAyMTU0MTIxNzUzIgNrTHAiDSR0MDIyMTkzMjIyOTMiDXVudXNlZEFjdGlvbnMiBmtMcE5ldyIMaXNPcmRlclZhbGlkIgRpbmZvIgljb21tb25HZXQiAWkiA3BtdCIGcG10QW10Igljb21tb25QdXQiCmFtQXNzZXRQbXQiCnByQXNzZXRQbXQiBmVzdFB1dCIEZW1pdCIGYW1vdW50IgdlbWl0SW52Ig1lbWl0SW52TGVnYWN5IgckbWF0Y2gwIhVsZWdhY3lGYWN0b3J5Q29udHJhY3QiB3Rha2VGZWUiCWZlZUFtb3VudCIPY2FsY1B1dE9uZVRva2VuIhBwYXltZW50QW1vdW50UmF3Ig5wYXltZW50QXNzZXRJZCIGaXNFdmFsIhBhbW91bnRCYWxhbmNlUmF3Ig9wcmljZUJhbGFuY2VSYXciFHBheW1lbnRJbkFtb3VudEFzc2V0Ig0kdDAyNTQwNjI1Njk5IhBhbW91bnRCYWxhbmNlT2xkIg9wcmljZUJhbGFuY2VPbGQiDSR0MDI1NzAzMjU4NTIiFGFtb3VudEFzc2V0QW1vdW50UmF3IhNwcmljZUFzc2V0QW1vdW50UmF3Ig0kdDAyNTk4NDI2MDQ4Ig1wYXltZW50QW1vdW50IhBhbW91bnRCYWxhbmNlTmV3Ig9wcmljZUJhbGFuY2VOZXciC3ByaWNlTmV3WDE4IghwcmljZU5ldyIOcGF5bWVudEJhbGFuY2UiFHBheW1lbnRCYWxhbmNlQmlnSW50IgxzdXBwbHlCaWdJbnQiC2NoZWNoU3VwcGx5Ig1kZXBvc2l0QmlnSW50Igtpc3N1ZUFtb3VudCILcHJpY2VPbGRYMTgiCHByaWNlT2xkIgRsb3NzIg0kdDAyNzcyOTI3ODk2IgdiYWxhbmNlIg9pc3N1ZUFtb3VudEJvdGgiD2NhbGNHZXRPbmVUb2tlbiIKb3V0QXNzZXRJZCIGY2hlY2tzIhBvdXRJbkFtb3VudEFzc2V0Ig1iYWxhbmNlQmlnSW50IhhvdXRJbkFtb3VudEFzc2V0RGVjaW1hbHMiDGFtQmFsYW5jZU9sZCIMcHJCYWxhbmNlT2xkIgpvdXRCYWxhbmNlIhBvdXRCYWxhbmNlQmlnSW50Ig5yZWRlZW1lZEJpZ0ludCIJYW1vdW50UmF3Ig0kdDAyOTk3NDMwMDMwIgt0b3RhbEFtb3VudCINJHQwMzAwMzQzMDI2MCILb3V0QW1BbW91bnQiC291dFByQW1vdW50IgxhbUJhbGFuY2VOZXciDHByQmFsYW5jZU5ldyIYYW1vdW50Qm90aEluUGF5bWVudEFzc2V0IhZtYW5hZ2VyUHVibGljS2V5T3JVbml0IgFzIh1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdCIJaXNNYW5hZ2VyIgJwayILbXVzdE1hbmFnZXIiAnBkIg1jbGVhbkFtb3VudEluIglpc1JldmVyc2UiDSR0MDMxOTU3MzIyNjIiCGFzc2V0T3V0Igdhc3NldEluIhJwb29sQXNzZXRJbkJhbGFuY2UiE3Bvb2xBc3NldE91dEJhbGFuY2UiCWFtb3VudE91dCIEb2xkSyIEbmV3SyIGY2hlY2tLIgxhbW91bnRPdXRNaW4iCWFkZHJlc3NUbyILc3dhcENvbnRhY3QiCGNoZWNrTWluIhdwZW5kaW5nTWFuYWdlclB1YmxpY0tleSILY2hlY2tDYWxsZXIiFWNoZWNrTWFuYWdlclB1YmxpY0tleSICcG0iBWhhc1BNIgdjaGVja1BNIg9zaG91bGRBdXRvU3Rha2UiBGFtSWQiBHBySWQiDHNsaXBwYWdlQUludiIMc2xpcHBhZ2VQSW52IgpscFRyYW5zZmVyIgtzbHBTdGFrZUludiINJHQwMzcwNzEzNzUzMyIRcmVmcmVzaEtMcEFjdGlvbnMiEWlzVXBkYXRlZEtMcFZhbGlkIgttYXhTbGlwcGFnZSINJHQwMzgwOTUzODE2MCIMbWluT3V0QW1vdW50IglhdXRvU3Rha2UiIGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkIg1pc1B1dERpc2FibGVkIgdwYXltZW50Ig0kdDAzOTM0ODM5NTAwIgVib251cyITZW1pdEFtb3VudEVzdGltYXRlZCIKZW1pdEFtb3VudCIIc3Rha2VJbnYiB3NlbmRGZWUiDSR0MDQwMDg2NDAyODMiDSR0MDQwMjg2NDAzOTQiDSR0MDQwNzAwNDA4NTciDW91dEFzc2V0SWRTdHIiDWlzR2V0RGlzYWJsZWQiDSR0MDQxNzQyNDE4OTUiD2Ftb3VudEVzdGltYXRlZCIHYnVybkludiINYXNzZXRUcmFuc2ZlciINJHQwNDIzOTU0MjY0MiIQZmVlQW1vdW50Rm9yQ2FsYyINJHQwNDI2NDU0Mjc1MyINJHQwNDMwMTA0MzE2NiINdW5zdGFrZUFtb3VudCIKdW5zdGFrZUludiINJHQwNDQwNzE0NDIyMiINJHQwNDQ3MTc0NDk2NCINJHQwNDQ5Njc0NTA3NSIJb3V0QW10QW10IhRidXJuTFBBc3NldE9uRmFjdG9yeSINJHQwNDYwMjE0NjEwMyISbm9MZXNzVGhlbkFtdEFzc2V0IhRub0xlc3NUaGVuUHJpY2VBc3NldCINJHQwNDcwNTI0NzEzMyINY2hlY2tQYXltZW50cyIPY2hlY2tQb29sU3RhdHVzIg0kdDA0ODI1OTQ4MzQwIhVub0xlc3NUaGVuQW1vdW50QXNzZXQiDGNoZWNrQW1vdW50cyINJHQwNDk2MzU0OTcxNiILYW10QXNzZXRTdHIiDXByaWNlQXNzZXRTdHIiGGxhc3RSZWZyZXNoZWRCbG9ja0hlaWdodCIdY2hlY2tMYXN0UmVmcmVzaGVkQmxvY2tIZWlnaHQiDSR0MDUwOTAzNTA5NjciEGtMcFVwZGF0ZUFjdGlvbnMiCmFtdEFzc2V0SWQiDHByaWNlQXNzZXRJZCINcG9vbExQQmFsYW5jZSISYWNjQW10QXNzZXRCYWxhbmNlIhRhY2NQcmljZUFzc2V0QmFsYW5jZSIKcHJpY2VzTGlzdCIPbHBBbXRBc3NldFNoYXJlIhFscFByaWNlQXNzZXRTaGFyZSIKcG9vbFdlaWdodCIMY3VyUHJpY2VDYWxjIgxhbUJhbGFuY2VSYXciDHByQmFsYW5jZVJhdyIPYW1CYWxhbmNlUmF3WDE4Ig9wckJhbGFuY2VSYXdYMTgiEHBheW1lbnRMcEFzc2V0SWQiDHBheW1lbnRMcEFtdCICdHgiBnZlcmlmeSIPdGFyZ2V0UHVibGljS2V5IgptYXRjaGVyUHViIg0kdDA1OTYyOTU5Njk4IgduZXdIYXNoIgthbGxvd2VkSGFzaCILY3VycmVudEhhc2hzAAFhAAgAAWIAgMLXLwABYwkAtgIBAIDC1y8AAWQJALYCAQCAgJC7utat8A0AAWUJALYCAQAAAAFmCQC2AgEAAAABZwkAtgIBAAEAAWgJALYCAQACAAFpAgVXQVZFUwABagICX18AAWsAAQABbAACAAFtAAMAAW4ABAABbwABAAFwAAIAAXEAAwABcgAEAAFzAAUAAXQABgABdQAHAAF2AAgAAXcACQABeAAKAAF5AAEAAXoAAgABQQADAAFCAAEAAUMABwEBRAIBRQFGCQC8AgMJALYCAQUBRQUBZAkAtgIBBQFGAQFHAgFFAUYJALwCAwUBRQUBZAUBRgEBSAIBSQFKCQCgAwEJALwCAwUBSQkAtgIBBQFKBQFkAQFLAwFJAUoBTAkAoAMBCQC9AgQFAUkJALYCAQUBSgUBZAUBTAEBTQMBTgFPAVAJAGsDBQFOBQFPBQFQAQFRAQFJAwkAZgIAAAUBSQkBAS0BBQFJBQFJAQFSAQFJAwkAvwICBQFlBQFJCQC+AgEFAUkFAUkBAVMAAhAlc19fc3dhcENvbnRyYWN0AQFUAAITJXNfX2ZhY3RvcnlDb250cmFjdAEBVQACFCVzX19tYW5hZ2VyUHVibGljS2V5AQFWAAIbJXNfX3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AQFXAAIRJXMlc19fcHJpY2VfX2xhc3QBAVgCAVkBWgkAuQkCCQDMCAICGCVzJXMlZCVkX19wcmljZV9faGlzdG9yeQkAzAgCCQCkAwEFAVkJAMwIAgkApAMBBQFaBQNuaWwFAWoBAmFhAgJhYgJhYwkArAICCQCsAgIJAKwCAgILJXMlcyVzX19QX18FAmFiAgJfXwUCYWMBAmFkAgJhYgJhYwkArAICCQCsAgIJAKwCAgILJXMlcyVzX19HX18FAmFiAgJfXwUCYWMBAmFlAAIPJXNfX2Ftb3VudEFzc2V0AQJhZgACDiVzX19wcmljZUFzc2V0AAJhZwIHJXNfX2ZlZQACYWgJAGsDAAoFAWIAkE4AAmFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAmFnBQJhaAACYWoJALkJAgkAzAgCAgIlcwkAzAgCAgNrTHAFA25pbAUBagACYWsJALkJAgkAzAgCAgIlcwkAzAgCAhJrTHBSZWZyZXNoZWRIZWlnaHQFA25pbAUBagACYWwJALkJAgkAzAgCAgIlcwkAzAgCAg9yZWZyZXNoS0xwRGVsYXkFA25pbAUBagACYW0AHgACYW4JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUCYWwFAmFtAQJhbwACESVzX19mYWN0b3J5Q29uZmlnAQJhcAACGCVzJXNfX21hdGNoZXJfX3B1YmxpY0tleQECYXEBAmFyCQCsAgIJAKwCAgIIJXMlcyVzX18FAmFyAiBfX21hcHBpbmdzX19wb29sQ29udHJhY3QyTHBBc3NldAECYXMCAmF0AmF1CQCsAgIJAKwCAgkArAICCQCsAgICCCVkJWQlc19fBQJhdAICX18FAmF1AghfX2NvbmZpZwECYXYBAmF3CQCsAgICKCVzJXMlc19fbWFwcGluZ3NfX2Jhc2VBc3NldDJpbnRlcm5hbElkX18FAmF3AQJheAACDCVzX19zaHV0ZG93bgECYXkBAmF6CQCsAgICEiVzJXNfX3Bvb2xXZWlnaHRfXwUCYXoBAmFBAAIXJXNfX2FsbG93ZWRMcFNjcmlwdEhhc2gAAmFCAhclc19fZmVlQ29sbGVjdG9yQWRkcmVzcwECYUMEAmFEAmFFAmFGAmFHCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICJG9yZGVyIHZhbGlkYXRpb24gZmFpbGVkOiBvcmRlclZhbGlkPQkApQMBBQJhRAICICgFAmFFAgEpAg0gc2VuZGVyVmFsaWQ9CQClAwEFAmFGAg4gbWF0Y2hlclZhbGlkPQkApQMBBQJhRwECYUgCAmFJAmFKCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUCYUkFAmFKCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmFJCQDMCAICAS4JAMwIAgUCYUoJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAECYUsCAmFJAmFKCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUCYUkFAmFKCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmFJCQDMCAICAS4JAMwIAgUCYUoJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAECYUwBAmFNCQACAQkAuQkCCQDMCAICCGxwLnJpZGU6CQDMCAIFAmFNBQNuaWwCASABAmFOAQJhTQkAuQkCCQDMCAICCGxwLnJpZGU6CQDMCAIFAmFNBQNuaWwCASAAAmFPCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYUgCBQR0aGlzCQEBVAAAAmFQCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYUgCBQJhTwUCYUIAAmFRCgACYVIJAPwHBAUCYU8CEGdldEluRmVlUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJhUgIDSW50BQJhUgkAAgEJAKwCAgkAAwEFAmFSAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQAAmFTCgACYVIJAPwHBAUCYU8CEWdldE91dEZlZVJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYVICA0ludAUCYVIJAAIBCQCsAgIJAAMBBQJhUgIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AQJhVAAJAQt2YWx1ZU9yRWxzZQIJAJsIAgUCYU8JAQJheAAHAQJhVQAJANkEAQkBAmFIAgUCYU8JAQJhcAABAmFWAAQCYVcJAQJhSAIFBHRoaXMJAQJhZQAEAmFYCQECYUgCBQR0aGlzCQECYWYABAJhdQkBAmFLAgUCYU8JAQJhdgEFAmFYBAJhdAkBAmFLAgUCYU8JAQJhdgEFAmFXCQC1CQIJAQJhSAIFAmFPCQECYXMCCQCkAwEFAmF0CQCkAwEFAmF1BQFqAQJhWQECYVoDCQAAAgUCYVoFAWkFBHVuaXQJANkEAQUCYVoBAmJhAQJhWgMJAAACBQJhWgUEdW5pdAUBaQkA2AQBCQEFdmFsdWUBBQJhWgECYmIBAmJjCQCZCgcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYmMFAW8JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiYwUBcAkA2QQBCQCRAwIFAmJjBQFxCQECYVkBCQCRAwIFAmJjBQFyCQECYVkBCQCRAwIFAmJjBQFzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYmMFAXQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiYwUBdQACYmQJAQJiYgEJAQJhVgAAAmJlBQJiZAACYmYIBQJiZQJfMQACYmcIBQJiZQJfMgACYmgIBQJiZQJfMwACYmkIBQJiZQJfNAACYmoIBQJiZQJfNQACYmsIBQJiZQJfNgACYmwIBQJiZQJfNwECYm0ACQC1CQIJAQJhSAIFAmFPCQECYW8ABQFqAAJibgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgkBAmJtAAUBQgIZaW5jb3JyZWN0IHN0YWtpbmcgYWRkcmVzcwACYm8JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIJAQJibQAFAUMCGWluY29ycmVjdCBzdGFraW5nIGFkZHJlc3MBAmJwCgJicQJicgJicwJidAJidQJidgJidwJieAJieQJiegkAuQkCCQDMCAICFCVkJWQlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYnEJAMwIAgkApAMBBQJicgkAzAgCCQCkAwEFAmJzCQDMCAIJAKQDAQUCYnQJAMwIAgkApAMBBQJidQkAzAgCCQCkAwEFAmJ2CQDMCAIJAKQDAQUCYncJAMwIAgkApAMBBQJieAkAzAgCCQCkAwEFAmJ5CQDMCAIJAKQDAQUCYnoFA25pbAUBagECYkEGAmJCAmJDAmJEAmJ0AmJ3AmJ4CQC5CQIJAMwIAgIMJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYkIJAMwIAgkApAMBBQJiQwkAzAgCCQCkAwEFAmJECQDMCAIJAKQDAQUCYnQJAMwIAgkApAMBBQJidwkAzAgCCQCkAwEFAmJ4BQNuaWwFAWoBAmJFAQJiRgMJAAACBQJiRgIFV0FWRVMICQDvBwEFBHRoaXMJYXZhaWxhYmxlCQDwBwIFBHRoaXMJANkEAQUCYkYBAmJHAgJiSAJiSQkAvAIDBQJiSAUBZAUCYkkBAmJKAwJiSAJiSQFMCQC9AgQFAmJIBQFkBQJiSQUBTAECYksEAmJMAmJNAmJOAmJPBAJiUAkBAUQCBQJiTgUCYkwEAmJRCQEBRAIFAmJPBQJiTQkBAmJHAgUCYlEFAmJQAQJiUgMCYk4CYk8CYlMEAmJUCQECYVYABAJiVQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJUBQF0BAJiVgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJUBQF1BAJiVwkBAmJLBAUCYlUFAmJWBQJiTgUCYk8EAmJJCQEBRAIFAmJOBQJiVQQCYkgJAQFEAgUCYk8FAmJWBAJiWAkBAUQCBQJiUwUBYgQCYlkJAQJiRwIFAmJJBQJiWAQCYloJAQJiRwIFAmJIBQJiWAkAzAgCBQJiVwkAzAgCBQJiWQkAzAgCBQJiWgUDbmlsAQJjYQMCYk4CYk8CYlMEAmNiCQECYlIDBQJiTgUCYk8FAmJTCQDMCAIJAQFIAgkAkQMCBQJjYgAABQFiCQDMCAIJAQFIAgkAkQMCBQJjYgABBQFiCQDMCAIJAQFIAgkAkQMCBQJjYgACBQFiBQNuaWwBAmNjBAJjZAJjZQJjZgJhYgQCYlQJAQJhVgAEAmNnCQCRAwIFAmJUBQFxBAJjaAkAkQMCBQJiVAUBcgQCY2kJAJEDAgUCYlQFAXMEAmJMCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlQFAXQEAmJNCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlQFAXUEAmNqCQCRAwIFAmJUBQFwBAJjawgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFAmNnCQCsAgIJAKwCAgIGQXNzZXQgBQJjZwIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkDCQECIT0CBQJjZwUCY2UJAAIBAhVJbnZhbGlkIGFzc2V0IHBhc3NlZC4EAmNsCQECYkUBBQJjaAQCY20JAQFEAgUCY2wFAmJMBAJjbgkBAmJFAQUCY2kEAmNvCQEBRAIFAmNuBQJiTQQCY3AJAQJiRwIFAmNvBQJjbQQCY3EJAQFIAgUCY3AFAWIEAmNyCQEBRAIFAmNmBQFiBAJjcwkBAUQCBQJjawUBYgQCY3QJALwCAwUCY20FAmNyBQJjcwQCY3UJALwCAwUCY28FAmNyBQJjcwQCY3YJAQFLAwUCY3QFAmJMBQVGTE9PUgQCY3cJAQFLAwUCY3UFAmJNBQVGTE9PUgQCY3gDCQAAAgUCY2QCAAUDbmlsCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFiBQJjdgMJAAACBQJjaAIFV0FWRVMFBHVuaXQJANkEAQUCY2gJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYWIFAmN3AwkAAAIFAmNpAgVXQVZFUwUEdW5pdAkA2QQBBQJjaQkAzAgCCQELU3RyaW5nRW50cnkCCQECYWQCCQClCAEFAmFiBQJjZAkBAmJBBgUCY3YFAmN3BQJjZgUCY3EFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCY3EJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCY3EFA25pbAkAnAoKBQJjdgUCY3cFAmNoBQJjaQUCY2wFAmNuBQJjawUCY3AFAmNqBQJjeAECY3kJAmNkAmN6AmNBAmNCAmNDAmNEAmFiAmNFAmNGBAJiVAkBAmFWAAQCY2cJANkEAQkAkQMCBQJiVAUBcQQCY0cJAJEDAgUCYlQFAXIEAmNICQCRAwIFAmJUBQFzBAJjSQkAkQMCBQJiVAUBdgQCY0oJAJEDAgUCYlQFAXcEAmJVCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlQFAXQEAmJWCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlQFAXUEAmNqCQCRAwIFAmJUBQFwBAJjawgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJjZwkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJjZwIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmNLCQDYBAEJAQt2YWx1ZU9yRWxzZQIFAmNCCQDZBAECBVdBVkVTBAJjTAkA2AQBCQELdmFsdWVPckVsc2UCBQJjRAkA2QQBAgVXQVZFUwMDCQECIT0CBQJjRwUCY0sGCQECIT0CBQJjSAUCY0wJAAIBAiJJbnZhbGlkIGFtdCBvciBwcmljZSBhc3NldCBwYXNzZWQuBAJjbAMFAmNFCQECYkUBBQJjRwkAZQIJAQJiRQEFAmNHBQJjQQQCY24DBQJjRQkBAmJFAQUCY0gJAGUCCQECYkUBBQJjSAUCY0MEAmNNCQEBRAIFAmNBBQJiVQQCY04JAQFEAgUCY0MFAmJWBAJjTwkBAmJHAgUCY04FAmNNBAJjbQkBAUQCBQJjbAUCYlUEAmNvCQEBRAIFAmNuBQJiVgQCY1ADCQAAAgUCY2sAAAQCY3AFAWUEAmNRBQFlBAJiWAkAdgYJALkCAgUCY00FAmNOAAAJALYCAQAFAAEAAAUERE9XTgkAlwoFCQEBSAIFAmJYBQFiCQEBSAIFAmNNBQJiVQkBAUgCBQJjTgUCYlYJAQJiRwIJALcCAgUCY28FAmNOCQC3AgIFAmNtBQJjTQUCY1EEAmNwCQECYkcCBQJjbwUCY20EAmNRCQC8AgMJAQFSAQkAuAICBQJjcAUCY08FAWQFAmNwBAJjUgkBAUQCBQJjegUBYgMDCQECIT0CBQJjcAUBZQkAvwICBQJjUQUCY1IHCQACAQkArAICCQCsAgIJAKwCAgIPUHJpY2Ugc2xpcHBhZ2UgCQCmAwEFAmNRAh4gZXhjZWVkZWQgdGhlIHBhc3NlZCBsaW1pdCBvZiAJAKYDAQUCY1IEAmNzCQEBRAIFAmNrBQFiBAJjUwkAvQIEBQJjTQkBAmJKAwUCY28FAmNtBQdDRUlMSU5HBQFkBQdDRUlMSU5HBAJjVAkAvQIEBQJjTgUBZAkBAmJKAwUCY28FAmNtBQVGTE9PUgUHQ0VJTElORwQCY1UDCQC/AgIFAmNTBQJjTgkAlAoCBQJjVAUCY04JAJQKAgUCY00FAmNTBAJjVggFAmNVAl8xBAJjVwgFAmNVAl8yBAJiWAkAvQIEBQJjcwUCY1cFAmNvBQVGTE9PUgkAlwoFCQEBSwMFAmJYBQFiBQVGTE9PUgkBAUsDBQJjVgUCYlUFB0NFSUxJTkcJAQFLAwUCY1cFAmJWBQdDRUlMSU5HBQJjcAUCY1EEAmNYCAUCY1ACXzEEAmNZCAUCY1ACXzIEAmNaCAUCY1ACXzMEAmNxCQEBSAIIBQJjUAJfNAUBYgQCZGEJAQFIAggFAmNQAl81BQFiAwkAZwIAAAUCY1gJAAIBAjZJbnZhbGlkIGNhbGN1bGF0aW9ucy4gTFAgY2FsY3VsYXRlZCBpcyBsZXNzIHRoYW4gemVyby4EAmRiAwkBASEBBQJjRgAABQJjWAQCZGMJAGUCBQJjQQUCY1kEAmRkCQBlAgUCY0MFAmNaBAJkZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVcABQJjcQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVgCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJjcQkAzAgCCQELU3RyaW5nRW50cnkCCQECYWECBQJhYgUCY2QJAQJicAoFAmNZBQJjWgUCZGIFAmNxBQJjegUCZGEFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmRjBQJkZAUDbmlsCQCfCg0FAmNYBQJkYgUCY3EFAmNsBQJjbgUCY2sFAmNnBQJjagUCZGUFAmRjBQJkZAUCY0IFAmNEAQJkZgMCZGcCZGgCY2sEAmRpCQEBRwIFAmRnCQC2AgEFAmJrBAJkagkBAUcCBQJkaAkAtgIBBQJibAQCZGsJALwCAwkAdgYJALkCAgUCZGkFAmRqAAAJALYCAQAFAAEAEgUERE9XTgUBZwUCY2sDCQAAAgUCY2sFAWYFAWYFAmRrAQJkbAMCZG0CZG4CZG8EAmRwCQC4AgIJALYCAQkBAmJFAQkBAmJhAQUCYmkFAmRtBAJkcQkAuAICCQC2AgEJAQJiRQEJAQJiYQEFAmJqBQJkbgQCZHIJALgCAgkAtgIBCAkBBXZhbHVlAQkA7AcBBQJiaAhxdWFudGl0eQUCZG8EAmRzCQECZGYDBQJkcAUCZHEFAmRyBQJkcwECZHQDAmR1AmR2AmRvBAJkcAkAZAIJAQJiRQEJAQJiYQEFAmJpBQJkdQQCZHEJAGQCCQECYkUBCQECYmEBBQJiagUCZHYEAmRyCQBkAggJAQV2YWx1ZQEJAOwHAQUCYmgIcXVhbnRpdHkFAmRvBAJkawkBAmRmAwkAtgIBBQJkcAkAtgIBBQJkcQkAtgIBBQJkcgQCZHcJAMwIAgkBDEludGVnZXJFbnRyeQIFAmFrBQZoZWlnaHQJAMwIAgkBC1N0cmluZ0VudHJ5AgUCYWoJAKYDAQUCZGsFA25pbAkAlAoCBQJkdwUCZGsBAmR4AgJkeQJkawMJAMACAgUCZGsFAmR5BgkBAmFMAQkAuQkCCQDMCAICInVwZGF0ZWQgS0xwIGxvd2VyIHRoYW4gY3VycmVudCBLTHAJAMwIAgkApgMBBQJkeQkAzAgCCQCmAwEFAmRrBQNuaWwCASABAmR6AQJkQQQCZHAJAQJiRQEJAQJiYQEFAmJpBAJkcQkBAmJFAQkBAmJhAQUCYmoEAmRCCAUCZEEGYW1vdW50BAJkQwkAbgQIBQJkQQZhbW91bnQIBQJkQQVwcmljZQUBYgUFRkxPT1IEAmREAwkAAAIIBQJkQQlvcmRlclR5cGUFA0J1eQkAlAoCBQJkQgkBAS0BBQJkQwkAlAoCCQEBLQEFAmRCBQJkQwQCZHUIBQJkRAJfMQQCZHYIBQJkRAJfMgMDAwkBAmFUAAYJAAACBQJiZwUBbQYJAAACBQJiZwUBbgkAAgECHEV4Y2hhbmdlIG9wZXJhdGlvbnMgZGlzYWJsZWQDAwkBAiE9AggIBQJkQQlhc3NldFBhaXILYW1vdW50QXNzZXQFAmJpBgkBAiE9AggIBQJkQQlhc3NldFBhaXIKcHJpY2VBc3NldAUCYmoJAAIBAhNXcm9uZyBvcmRlciBhc3NldHMuBAJkRQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCoAwEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUCYWoCATAJAQJhTgECC2ludmFsaWQga0xwBAJkRgkBAmR0AwUCZHUFAmR2AAAEAmRHCAUCZEYCXzEEAmRICAUCZEYCXzIEAmRJCQDAAgIFAmRIBQJkRQQCZEoJALkJAgkAzAgCAgRrTHA9CQDMCAIJAKYDAQUCZEUJAMwIAgIIIGtMcE5ldz0JAMwIAgkApgMBBQJkSAkAzAgCAhQgYW1vdW50QXNzZXRCYWxhbmNlPQkAzAgCCQCkAwEFAmRwCQDMCAICEyBwcmljZUFzc2V0QmFsYW5jZT0JAMwIAgkApAMBBQJkcQkAzAgCAhkgYW1vdW50QXNzZXRCYWxhbmNlRGVsdGE9CQDMCAIJAKQDAQUCZHUJAMwIAgIYIHByaWNlQXNzZXRCYWxhbmNlRGVsdGE9CQDMCAIJAKQDAQUCZHYJAMwIAgIIIGhlaWdodD0JAMwIAgkApAMBBQZoZWlnaHQFA25pbAIACQCUCgIFAmRJBQJkSgECZEsBAmRMAwkBAiE9AgkAkAMBCAUCZEwIcGF5bWVudHMAAQkAAgECHWV4YWN0bHkgMSBwYXltZW50IGlzIGV4cGVjdGVkBAJkTQkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAAQCY2UJAQV2YWx1ZQEIBQJkTQdhc3NldElkBAJkTggFAmRNBmFtb3VudAQCY1AJAQJjYwQJANgEAQgFAmRMDXRyYW5zYWN0aW9uSWQJANgEAQUCY2UFAmROCAUCZEwGY2FsbGVyBAJjdggFAmNQAl8xBAJjdwgFAmNQAl8yBAJjagkBDXBhcnNlSW50VmFsdWUBCAUCY1ACXzkEAmN4CAUCY1ADXzEwAwMJAQJhVAAGCQAAAgUCY2oFAW4JAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmNqCQCXCgUFAmN2BQJjdwUCZE4FAmNlBQJjeAECZE8DAmRMAmN6AmNGAwkBAiE9AgkAkAMBCAUCZEwIcGF5bWVudHMAAgkAAgECH2V4YWN0bHkgMiBwYXltZW50cyBhcmUgZXhwZWN0ZWQEAmRQCQEFdmFsdWUBCQCRAwIIBQJkTAhwYXltZW50cwAABAJkUQkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAQQCZFIJAQJjeQkJANgEAQgFAmRMDXRyYW5zYWN0aW9uSWQFAmN6CAUCZFAGYW1vdW50CAUCZFAHYXNzZXRJZAgFAmRRBmFtb3VudAgFAmRRB2Fzc2V0SWQJAKUIAQgFAmRMBmNhbGxlcgcFAmNGBAJjagkBDXBhcnNlSW50VmFsdWUBCAUCZFICXzgDAwMJAQJhVAAGCQAAAgUCY2oFAWwGCQAAAgUCY2oFAW4JAAIBCQCsAgICLFB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmNqBQJkUgECZFMBAmRUBAJkVQkA/AcEBQJhTwIEZW1pdAkAzAgCBQJkVAUDbmlsBQNuaWwDCQAAAgUCZFUFAmRVBAJkVgQCZFcFAmRVAwkAAQIFAmRXAgdBZGRyZXNzBAJkWAUCZFcJAPwHBAUCZFgCBGVtaXQJAMwIAgUCZFQFA25pbAUDbmlsBQR1bml0AwkAAAIFAmRWBQJkVgUCZFQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmRZAgJkVAJhaQQCZFoDCQAAAgUCYWkAAAAACQBrAwUCZFQFAmFpBQFiCQCUCgIJAGUCBQJkVAUCZFoFAmRaAQJlYQQCZWICZWMCYWICYWMEAmVkCQAAAgUCYWMFBHVuaXQEAmVlCQECYkUBCQECYmEBBQJiaQQCZWYJAQJiRQEJAQJiYQEFAmJqBAJlZwMJAAACBQJlYwUCYmkGAwkAAAIFAmVjBQJiagcJAQJhTAECDWludmFsaWQgYXNzZXQEAmVoAwUCZWQJAJQKAgUCZWUFAmVmAwUCZWcJAJQKAgkAZQIFAmVlBQJlYgUCZWYJAJQKAgUCZWUJAGUCBQJlZgUCZWIEAmVpCAUCZWgCXzEEAmVqCAUCZWgCXzIEAmVrAwUCZWcJAJQKAgUCZWIAAAkAlAoCAAAFAmViBAJlbAgFAmVrAl8xBAJlbQgFAmVrAl8yBAJkQggJAQJkWQIFAmVsBQJhUQJfMQQCZEMICQECZFkCBQJlbQUCYVECXzEEAmVuCQECZFkCBQJlYgUCYVEEAmVvCAUCZW4CXzEEAmRaCAUCZW4CXzIEAmVwCQBkAgUCZWkFAmRCBAJlcQkAZAIFAmVqBQJkQwQCZXIJAQJiRwIJAQFEAgUCZXEFAmJsCQEBRAIFAmVwBQJiawQCZXMJAQFIAgUCZXIFAWIEAmV0AwUCZWcFAmVpBQJlagQCZXUJALYCAQUCZXQEAmV2CQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYmgJAKwCAgkArAICAgZhc3NldCAJANgEAQUCYmgCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJldwMJAL8CAgUCZXYFAWYGCQECYUwBAiJpbml0aWFsIGRlcG9zaXQgcmVxdWlyZXMgYWxsIGNvaW5zAwkAAAIFAmV3BQJldwQCZXgJALYCAQUCZW8EAmV5CQCWAwEJAMwIAgAACQDMCAIJAKADAQkAugICCQC5AgIFAmV2CQC4AgIJAQpzcXJ0QmlnSW50BAkAtwICBQFkCQC6AgIJALkCAgUCZXgFAWQFAmV1ABIAEgUERE9XTgUBZAUBZAUDbmlsBAJkZQMFAmVkBQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZXMJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZXMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFhAgkApQgBCQEFdmFsdWUBBQJhYgkA2AQBCQEFdmFsdWUBBQJhYwkBAmJwCgUCZWwFAmVtBQJleQUCZXMAAAAABQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wAAAAAAUDbmlsBAJlegkBAmJHAgkBAUQCBQJlagUCYmwJAQFEAgUCZWkFAmJrBAJlQQkBAUgCBQJlegUBYgQCZUIEAmVDAwUCZWcJAJQKAgUCZWwFAmVpCQCUCgIFAmVtBQJlagQCZFQIBQJlQwJfMQQCZUQIBQJlQwJfMgQCZUUJAKADAQkAvAIDBQJldgkAtgIBCQBpAgUCZFQAAgkAtgIBBQJlRAkAawMJAGUCBQJleQUCZUUFAWIFAmVFCQCXCgUFAmV5BQJkZQUCZFoFAmVCBQJlZwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZUYFAmVHAmVvAmVjAmFiAmFjBAJlZAkAAAIFAmFjBQR1bml0BAJiVAkBAmFWAAQCYlUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiVAUBdAQCYlYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiVAUBdQQCZUgJAMwIAgMJAAACBQJlYwUCYmgGCQECYUwBAhBpbnZhbGlkIGxwIGFzc2V0BQNuaWwDCQAAAgUCZUgFAmVIBAJlSQMJAAACBQJlRwUCYmkGAwkAAAIFAmVHBQJiagcJAQJhTAECDWludmFsaWQgYXNzZXQEAmVKAwUCZUkJALYCAQkBAmJFAQkBAmJhAQUCYmkJALYCAQkBAmJFAQkBAmJhAQUCYmoEAmVLAwUCZUkFAmJVBQJiVgQCZUwJAQJiRQEJAQJiYQEFAmJpBAJlTQkBAmJFAQkBAmJhAQUCYmoEAmVOAwUCZUkFAmVMBQJlTQQCZU8JALYCAQUCZU4EAmV2CQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYmgJAKwCAgkArAICAgZhc3NldCAJANgEAQUCYmgCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJlUAkAtgIBBQJlbwQCZVEJAJYDAQkAzAgCAAAJAMwIAgkAoAMBCQC6AgIJALkCAgUCZUoJALgCAgUBZAkAdgYJALgCAgUBZAkAugICCQC5AgIFAmVQBQFkBQJldgASBQFoAAAAEgUERE9XTgUBZAUDbmlsBAJlUgkBAmRZAgUCZVEFAmFTBAJlUwgFAmVSAl8xBAJkWggFAmVSAl8yBAJlVAMFAmVJCQCWCgQFAmVTAAAJAGUCBQJlTAUCZVEFAmVNCQCWCgQAAAUCZVMFAmVMCQBlAgUCZU0FAmVRBAJlVQgFAmVUAl8xBAJlVggFAmVUAl8yBAJlVwgFAmVUAl8zBAJlWAgFAmVUAl80BAJlcgkBAmJHAgkBAUQCBQJlWAUCYmwJAQFEAgUCZVcFAmJrBAJlcwkBAUgCBQJlcgUBYgQCZGUDBQJlZAUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZAIJAKUIAQkBBXZhbHVlAQUCYWIJANgEAQkBBXZhbHVlAQUCYWMJAQJiQQYFAmVVBQJlVgUCZW8FAmVzBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVwAFAmVzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBWAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmVzBQNuaWwEAmV6CQECYkcCCQEBRAIFAmVNBQJibAkBAUQCBQJlTAUCYmsEAmVBCQEBSAIFAmV6BQFiBAJlQgQCZVkJAGgCCQCgAwEJALwCAwUCZUoFAmVQBQJldgACCQBrAwkAZQIFAmVTBQJlWQUBYgUCZVkJAJcKBQUCZVMFAmRlBQJkWgUCZUIFAmVJCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJlWgAEAmRXCQCiCAEJAQFVAAMJAAECBQJkVwIGU3RyaW5nBAJmYQUCZFcJANkEAQUCZmEDCQABAgUCZFcCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgECZmIABAJkVwkAoggBCQEBVgADCQABAgUCZFcCBlN0cmluZwQCZmEFAmRXCQDZBAEFAmZhAwkAAQIFAmRXAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmZjAQJkTAQCZFcJAQJlWgADCQABAgUCZFcCCkJ5dGVWZWN0b3IEAmZkBQJkVwkAAAIIBQJkTA9jYWxsZXJQdWJsaWNLZXkFAmZkAwkAAQIFAmRXAgRVbml0CQAAAggFAmRMBmNhbGxlcgUEdGhpcwkAAgECC01hdGNoIGVycm9yAQJmZQECZEwEAmZmCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEAmRXCQECZVoAAwkAAQIFAmRXAgpCeXRlVmVjdG9yBAJmZAUCZFcDCQAAAggFAmRMD2NhbGxlclB1YmxpY0tleQUCZmQGBQJmZgMJAAECBQJkVwIEVW5pdAMJAAACCAUCZEwGY2FsbGVyBQR0aGlzBgUCZmYJAAIBAgtNYXRjaCBlcnJvch0CZEwBIWNhbGN1bGF0ZUFtb3VudE91dEZvclN3YXBSRUFET05MWQICZmcCZmgEAmZpAwkAAAIFAmZoBwQCZmoJAQJhSAIFBHRoaXMJAQJhZgAEAmZrCQECYUgCBQR0aGlzCQECYWUACQCUCgIFAmZqBQJmawQCZmoJAQJhSAIFBHRoaXMJAQJhZQAEAmZrCQECYUgCBQR0aGlzCQECYWYACQCUCgIFAmZqBQJmawQCZmoIBQJmaQJfMQQCZmsIBQJmaQJfMgQCZmwJAQJiRQEFAmZrBAJmbQkBAmJFAQUCZmoEAmZuCQBrAwUCZm0FAmZnCQBkAgUCZmwFAmZnBAJmbwkAuQICCQC2AgEFAmZsCQC2AgEFAmZtBAJmcAkAuQICCQC3AgIJALYCAQkBAmJFAQUCZmsJALYCAQUCZmcJALgCAgkAtgIBCQECYkUBBQJmagkAtgIBBQJmbgQCZnEDCQDAAgIFAmZwBQJmbwYJAAIBAhRuZXcgSyBpcyBmZXdlciBlcnJvcgMJAAACBQJmcQUCZnEJAJQKAgUDbmlsBQJmbgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEmY2FsY3VsYXRlQW1vdW50T3V0Rm9yU3dhcEFuZFNlbmRUb2tlbnMEAmZnAmZoAmZyAmZzBAJmdAoAAmFSCQD8BwQFAmFPAhdnZXRTd2FwQ29udHJhY3RSRUFET05MWQUDbmlsBQNuaWwDCQABAgUCYVICBlN0cmluZwUCYVIJAAIBCQCsAgIJAAMBBQJhUgIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nBAJlSAkAzAgCAwkAZwIICQEFdmFsdWUBCQCRAwIIBQJkTAhwYXltZW50cwAABmFtb3VudAUCZmcGCQECYUwBAgxXcm9uZyBhbW91bnQJAMwIAgMJAAACCAUCZEwGY2FsbGVyCQERQGV4dHJOYXRpdmUoMTA2MikBBQJmdAYJAQJhTAECEVBlcm1pc3Npb24gZGVuaWVkBQNuaWwDCQAAAgUCZUgFAmVIBAJkTQkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAAQCZmsJAQJiYQEIBQJkTQdhc3NldElkBAJmagMJAAACBQJmaAcJAQJhSAIFBHRoaXMJAQJhZgAJAQJhSAIFBHRoaXMJAQJhZQAEAmZsCQBlAgkBAmJFAQUCZmsICQEFdmFsdWUBCQCRAwIIBQJkTAhwYXltZW50cwAABmFtb3VudAQCZm0JAQJiRQEFAmZqBAJmbgkAawMFAmZtBQJmZwkAZAIFAmZsBQJmZwQCZm8JALkCAgkAtgIBBQJmbAkAtgIBBQJmbQQCZnAJALkCAgkAtgIBCQECYkUBBQJmawkAuAICCQC2AgEJAQJiRQEFAmZqCQC2AgEFAmZuBAJmcQMJAMACAgUCZnAFAmZvBgkAAgECFG5ldyBLIGlzIGZld2VyIGVycm9yAwkAAAIFAmZxBQJmcQQCZnUDCQBnAgUCZm4FAmZyBgkAAgECLEV4Y2hhbmdlIHJlc3VsdCBpcyBmZXdlciBjb2lucyB0aGFuIGV4cGVjdGVkAwkAAAIFAmZ1BQJmdQkAlAoCCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmZzBQJmbgkBAmFZAQUCZmoFA25pbAUCZm4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEwBCnNldE1hbmFnZXIBAmZ2BAJmdwkBAmZlAQUCZEwDCQAAAgUCZncFAmZ3BAJmeAkA2QQBBQJmdgMJAAACBQJmeAUCZngJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAVYABQJmdgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRMAQ5jb25maXJtTWFuYWdlcgAEAmZ5CQECZmIABAJmegMJAQlpc0RlZmluZWQBBQJmeQYJAAIBAhJObyBwZW5kaW5nIG1hbmFnZXIDCQAAAgUCZnoFAmZ6BAJmQQMJAAACCAUCZEwPY2FsbGVyUHVibGljS2V5CQEFdmFsdWUBBQJmeQYJAAIBAhtZb3UgYXJlIG5vdCBwZW5kaW5nIG1hbmFnZXIDCQAAAgUCZkEFAmZBCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFVAAkA2AQBCQEFdmFsdWUBBQJmeQkAzAgCCQELRGVsZXRlRW50cnkBCQEBVgAFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEDcHV0AgJjegJmQgMJAGYCAAAFAmN6CQACAQIgSW52YWxpZCBzbGlwcGFnZVRvbGVyYW5jZSBwYXNzZWQEAmRSCQECZE8DBQJkTAUCY3oGBAJkYggFAmRSAl8yBAJjZwgFAmRSAl83BAJjeAgFAmRSAl85BAJkYwgFAmRSA18xMAQCZGQIBQJkUgNfMTEEAmZDCAUCZFIDXzEyBAJmRAgFAmRSA18xMwQCZFAJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmRMCHBheW1lbnRzAAAGYW1vdW50BAJkUQkAtgIBCAkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAQZhbW91bnQEAmRzCQECZGwDBQJkUAUCZFEJALYCAQAAAwkAAAIFAmRzBQJkcwQCZFUJAPwHBAUCYU8CBGVtaXQJAMwIAgUCZGIFA25pbAUDbmlsAwkAAAIFAmRVBQJkVQQCZFYEAmRXBQJkVQMJAAECBQJkVwIHQWRkcmVzcwQCZFgFAmRXCQD8BwQFAmRYAgRlbWl0CQDMCAIFAmRiBQNuaWwFA25pbAUEdW5pdAMJAAACBQJkVgUCZFYEAmZFAwkAZgIFAmRjAAAJAPwHBAUCYm8CA3B1dAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJmQwUCZGMFA25pbAUDbmlsAwkAAAIFAmZFBQJmRQQCZkYDCQBmAgUCZGQAAAkA/AcEBQJibwIDcHV0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmZEBQJkZAUDbmlsBQNuaWwDCQAAAgUCZkYFAmZGBAJmRwMFAmZCBAJmSAkA/AcEBQJibgIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCY2cFAmRiBQNuaWwDCQAAAgUCZkgFAmZIBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmRMBmNhbGxlcgUCZGIFAmNnBQNuaWwEAmZJCQECZHQDAAAAAAAAAwkAAAIFAmZJBQJmSQQCZGsIBQJmSQJfMgQCZkoIBQJmSQJfMQQCZksJAQJkeAIFAmRzBQJkawMJAAACBQJmSwUCZksJAM4IAgkAzggCBQJjeAUCZkcFAmZKCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRMAQpwdXRGb3JGcmVlAQJmTAMJAGYCAAAFAmZMCQACAQIUSW52YWxpZCB2YWx1ZSBwYXNzZWQEAmRSCQECZE8DBQJkTAUCZkwHBAJjeAgFAmRSAl85BAJkUAkAtgIBCAkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAAZhbW91bnQEAmRRCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJkTAhwYXltZW50cwABBmFtb3VudAQCZHMJAQJkbAMFAmRQBQJkUQkAtgIBAAADCQAAAgUCZHMFAmRzBAJmTQkBAmR0AwAAAAAAAAQCZkoIBQJmTQJfMQQCZGsIBQJmTQJfMgQCZksJAQJkeAIFAmRzBQJkawMJAAACBQJmSwUCZksJAM4IAgUCY3gFAmZKCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRMAQlwdXRPbmVUa24CAmZOAmZPBAJmUAoAAmFSCQD8BwQFAmFPAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYVICB0Jvb2xlYW4FAmFSCQACAQkArAICCQADAQUCYVICHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmZRAwMDCQECYVQABgkAAAIFAmJnBQFsBgkAAAIFAmJnBQFuBgUCZlAEAmVICQDMCAIDAwkBASEBBQJmUQYJAQJmYwEFAmRMBgkBAmFMAQIhcHV0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCZEwIcGF5bWVudHMAAQYJAQJhTAECHmV4YWN0bHkgMSBwYXltZW50IGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmVIBQJlSAQCZlIJAJEDAggFAmRMCHBheW1lbnRzAAAEAmVjCAUCZlIHYXNzZXRJZAQCZWIIBQJmUgZhbW91bnQEAmRzAwkAAAIFAmVjBQJiaQkBAmRsAwkAtgIBBQJlYgkAtgIBAAAJALYCAQAAAwkAAAIFAmVjBQJiagkBAmRsAwkAtgIBAAAJALYCAQUCZWIJALYCAQAACQECYUwBAh5wYXltZW50IGFzc2V0IGlzIG5vdCBzdXBwb3J0ZWQDCQAAAgUCZHMFAmRzBAJhYggFAmRMBmNhbGxlcgQCYWMIBQJkTA10cmFuc2FjdGlvbklkBAJmUwkBAmVhBAUCZWIFAmVjBQJhYgUCYWMDCQAAAgUCZlMFAmZTBAJlZwgFAmZTAl81BAJmVAgFAmZTAl80BAJkWggFAmZTAl8zBAJkZQgFAmZTAl8yBAJmVQgFAmZTAl8xBAJmVgMDCQBmAgUCZk4AAAkAZgIFAmZOBQJmVQcJAQJhTAEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZk4FA25pbAIABQJmVQQCZFUJAQJkUwEFAmZWAwkAAAIFAmRVBQJkVQQCZkcDBQJmTwQCZlcJAPwHBAUCYm4CBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJoBQJmVgUDbmlsAwkAAAIFAmZXBQJmVwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJkTAZjYWxsZXIFAmZWBQJiaAUDbmlsBAJmWAMJAGYCBQJkWgAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFQBQJkWgUCZWMFA25pbAUDbmlsBAJmWQMJAAACBQR0aGlzBQJhUAkAlAoCAAAAAAMFAmVnCQCUCgIJAQEtAQUCZFoAAAkAlAoCAAAJAQEtAQUCZFoEAmR1CAUCZlkCXzEEAmR2CAUCZlkCXzIEAmZaCQECZHQDBQJkdQUCZHYAAAQCZkoIBQJmWgJfMQQCZGsIBQJmWgJfMgQCZEUJAQV2YWx1ZQEJAKIIAQUCYWoEAmZLCQECZHgCBQJkcwUCZGsDCQAAAgUCZksFAmZLCQCUCgIJAM4IAgkAzggCCQDOCAIFAmRlBQJmRwUCZlgFAmZKBQJmVgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAERcHV0T25lVGtuUkVBRE9OTFkCAmVjAmViBAJnYQkBAmVhBAUCZWIJAQJhWQEFAmVjBQR1bml0BQR1bml0BAJmVQgFAmdhAl8xBAJkZQgFAmdhAl8yBAJkWggFAmdhAl8zBAJmVAgFAmdhAl80BAJlZwgFAmdhAl81CQCUCgIFA25pbAkAlQoDBQJmVQUCZFoFAmZUAmRMAQlnZXRPbmVUa24CAmdiAmZOBAJmUAoAAmFSCQD8BwQFAmFPAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYVICB0Jvb2xlYW4FAmFSCQACAQkArAICCQADAQUCYVICHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmdjAwMJAQJhVAAGCQAAAgUCYmcFAW4GBQJmUAQCZUgJAMwIAgMDCQEBIQEFAmdjBgkBAmZjAQUCZEwGCQECYUwBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJkTAhwYXltZW50cwABBgkBAmFMAQIeZXhhY3RseSAxIHBheW1lbnQgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZUgFAmVIBAJlRwkBAmFZAQUCZ2IEAmZSCQCRAwIIBQJkTAhwYXltZW50cwAABAJlYwgFAmZSB2Fzc2V0SWQEAmVvCAUCZlIGYW1vdW50BAJkcwkBAmRsAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJkcwUCZHMEAmFiCAUCZEwGY2FsbGVyBAJhYwgFAmRMDXRyYW5zYWN0aW9uSWQEAmdkCQECZUYFBQJlRwUCZW8FAmVjBQJhYgUCYWMDCQAAAgUCZ2QFAmdkBAJlSQgFAmdkAl81BAJmVAgFAmdkAl80BAJkWggFAmdkAl8zBAJkZQgFAmdkAl8yBAJnZQgFAmdkAl8xBAJkVAMDCQBmAgUCZk4AAAkAZgIFAmZOBQJnZQcJAQJhTAEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZk4FA25pbAIABQJnZQQCZ2YJAPwHBAUCYU8CBGJ1cm4JAMwIAgUCZW8FA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZWMFAmVvBQNuaWwDCQAAAgUCZ2YFAmdmBAJnZwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhYgUCZFQFAmVHBQNuaWwEAmZYAwkAZgIFAmRaAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYVAFAmRaBQJlRwUDbmlsBQNuaWwEAmdoBAJnaQMJAAACBQR0aGlzBQJhUAAABQJkWgMFAmVJCQCUCgIJAQEtAQkAZAIFAmRUBQJnaQAACQCUCgIAAAkBAS0BCQBkAgUCZFQFAmdpBAJkdQgFAmdoAl8xBAJkdggFAmdoAl8yBAJnagkBAmR0AwUCZHUFAmR2AAAEAmZKCAUCZ2oCXzEEAmRrCAUCZ2oCXzIEAmZLCQECZHgCBQJkcwUCZGsDCQAAAgUCZksFAmZLCQCUCgIJAM4IAgkAzggCCQDOCAIFAmRlBQJnZwUCZlgFAmZKBQJkVAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAERZ2V0T25lVGtuUkVBRE9OTFkCAmVHAmVvBAJnawkBAmVGBQkBAmFZAQUCZUcFAmVvBQJiaAUEdW5pdAUEdW5pdAQCZ2UIBQJnawJfMQQCZGUIBQJnawJfMgQCZFoIBQJnawJfMwQCZlQIBQJnawJfNAQCZUkIBQJnawJfNQkAlAoCBQNuaWwJAJUKAwUCZ2UFAmRaBQJmVAJkTAETdW5zdGFrZUFuZEdldE9uZVRrbgMCZ2wCZ2ICZk4EAmZQCgACYVIJAPwHBAUCYU8CKGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJhUgIHQm9vbGVhbgUCYVIJAAIBCQCsAgIJAAMBBQJhUgIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCZ2MDAwkBAmFUAAYJAAACBQJiZwUBbgYFAmZQBAJlSAkAzAgCAwMJAQEhAQUCZ2MGCQECZmMBBQJkTAYJAQJhTAECIWdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmRMCHBheW1lbnRzAAAGCQECYUwBAhhubyBwYXltZW50cyBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJlSAUCZUgEAmVHCQECYVkBBQJnYgQCYWIIBQJkTAZjYWxsZXIEAmFjCAUCZEwNdHJhbnNhY3Rpb25JZAQCZHMJAQJkbAMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZHMFAmRzBAJnbQkA/AcEBQJibgIHdW5zdGFrZQkAzAgCCQDYBAEFAmJoCQDMCAIFAmdsBQNuaWwFA25pbAMJAAACBQJnbQUCZ20EAmduCQECZUYFBQJlRwUCZ2wFAmJoBQJhYgUCYWMDCQAAAgUCZ24FAmduBAJlSQgFAmduAl81BAJmVAgFAmduAl80BAJkWggFAmduAl8zBAJkZQgFAmduAl8yBAJnZQgFAmduAl8xBAJkVAMDCQBmAgUCZk4AAAkAZgIFAmZOBQJnZQcJAQJhTAEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZk4FA25pbAIABQJnZQQCZ2YJAPwHBAUCYU8CBGJ1cm4JAMwIAgUCZ2wFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYmgFAmdsBQNuaWwDCQAAAgUCZ2YFAmdmBAJnZwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZEwGY2FsbGVyBQJkVAUCZUcFA25pbAQCZlgDCQBmAgUCZFoAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhUAUCZFoFAmVHBQNuaWwFA25pbAQCZ28EAmdpAwkAAAIFBHRoaXMFAmFQAAAFAmRaAwUCZUkJAJQKAgkBAS0BCQBkAgUCZFQFAmdpAAAJAJQKAgAACQEBLQEJAGQCBQJkVAUCZ2kEAmR1CAUCZ28CXzEEAmR2CAUCZ28CXzIEAmdwCQECZHQDBQJkdQUCZHYAAAQCZkoIBQJncAJfMQQCZGsIBQJncAJfMgQCZksJAQJkeAIFAmRzBQJkawMJAAACBQJmSwUCZksJAJQKAgkAzggCCQDOCAIJAM4IAgUCZGUFAmdnBQJmWAUCZkoFAmRUCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRMAQNnZXQABAJjUAkBAmRLAQUCZEwEAmdxCAUCY1ACXzEEAmN3CAUCY1ACXzIEAmROCAUCY1ACXzMEAmNlCAUCY1ACXzQEAmN4CAUCY1ACXzUEAmRzCQECZGwDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmRzBQJkcwQCZ3IJAPwHBAUCYU8CBGJ1cm4JAMwIAgUCZE4FA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCY2UFAmROBQNuaWwDCQAAAgUCZ3IFAmdyBAJncwkBAmR0AwkBAS0BBQJncQkBAS0BBQJjdwAABAJmSggFAmdzAl8xBAJkawgFAmdzAl8yBAJmSwkBAmR4AgUCZHMFAmRrAwkAAAIFAmZLBQJmSwkAzggCBQJjeAUCZkoJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEwBCWdldE5vTGVzcwICZ3QCZ3UEAmNQCQECZEsBBQJkTAQCY3YIBQJjUAJfMQQCY3cIBQJjUAJfMgQCZE4IBQJjUAJfMwQCY2UIBQJjUAJfNAQCY3gIBQJjUAJfNQMJAGYCBQJndAUCY3YJAAIBCQCsAgIJAKwCAgkArAICAhxub0xlc3NUaGVuQW10QXNzZXQgZmFpbGVkOiAgCQCkAwEFAmN2AgMgPCAJAKQDAQUCZ3QDCQBmAgUCZ3UFAmN3CQACAQkArAICCQCsAgIJAKwCAgIdbm9MZXNzVGhlblByaWNlQXNzZXQgZmFpbGVkOiAJAKQDAQUCY3cCAyA8IAkApAMBBQJndQQCZHMJAQJkbAMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZHMFAmRzBAJncgkA/AcEBQJhTwIEYnVybgkAzAgCBQJkTgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJjZQUCZE4FA25pbAMJAAACBQJncgUCZ3IEAmd2CQECZHQDCQEBLQEFAmN2CQEBLQEFAmN3AAAEAmZKCAUCZ3YCXzEEAmRrCAUCZ3YCXzIEAmZLCQECZHgCBQJkcwUCZGsDCQAAAgUCZksFAmZLCQDOCAIFAmN4BQJmSgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAENdW5zdGFrZUFuZEdldAECZFQEAmd3AwkBAiE9AgkAkAMBCAUCZEwIcGF5bWVudHMAAAkAAgECGE5vIHBheW1lbnRzIGFyZSBleHBlY3RlZAYDCQAAAgUCZ3cFAmd3BAJiVAkBAmFWAAQCY2cJANkEAQkAkQMCBQJiVAUBcQQCZHMJAQJkbAMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZHMFAmRzBAJnbQkA/AcEBQJibgIHdW5zdGFrZQkAzAgCCQDYBAEFAmNnCQDMCAIFAmRUBQNuaWwFA25pbAMJAAACBQJnbQUCZ20EAmNQCQECY2MECQDYBAEIBQJkTA10cmFuc2FjdGlvbklkCQDYBAEFAmNnBQJkVAgFAmRMBmNhbGxlcgQCY3YIBQJjUAJfMQQCY3cIBQJjUAJfMgQCY2oJAQ1wYXJzZUludFZhbHVlAQgFAmNQAl85BAJjeAgFAmNQA18xMAQCZ3gDAwkBAmFUAAYJAAACBQJjagUBbgkAAgEJAKwCAgIsR2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCY2oGAwkAAAIFAmd4BQJneAQCZ3IJAPwHBAUCYU8CBGJ1cm4JAMwIAgUCZFQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCY2cFAmRUBQNuaWwDCQAAAgUCZ3IFAmdyBAJneQkBAmR0AwkBAS0BBQJjdgkBAS0BBQJjdwAABAJmSggFAmd5Al8xBAJkawgFAmd5Al8yBAJmSwkBAmR4AgUCZHMFAmRrAwkAAAIFAmZLBQJmSwkAzggCBQJjeAUCZkoJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEwBE3Vuc3Rha2VBbmRHZXROb0xlc3MDAmdsAmd6Amd1BAJnYwMJAQJhVAAGCQAAAgUCYmcFAW4EAmVICQDMCAIDCQEBIQEFAmdjBgkAAgECIWdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmRMCHBheW1lbnRzAAAGCQACAQIYbm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZUgFAmVIBAJkcwkBAmRsAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJkcwUCZHMEAmdtCQD8BwQFAmJuAgd1bnN0YWtlCQDMCAIJANgEAQUCYmgJAMwIAgUCZ2wFA25pbAUDbmlsAwkAAAIFAmdtBQJnbQQCY1AJAQJjYwQJANgEAQgFAmRMDXRyYW5zYWN0aW9uSWQJANgEAQUCYmgFAmdsCAUCZEwGY2FsbGVyBAJjdggFAmNQAl8xBAJjdwgFAmNQAl8yBAJjeAgFAmNQA18xMAQCZ0EJAMwIAgMJAGcCBQJjdgUCZ3oGCQACAQkAuQkCCQDMCAICLGFtb3VudCBhc3NldCBhbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZ3oFA25pbAIACQDMCAIDCQBnAgUCY3cFAmd1BgkAAgEJALkJAgkAzAgCAitwcmljZSBhc3NldCBhbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZ3UFA25pbAIABQNuaWwDCQAAAgUCZ0EFAmdBBAJncgkA/AcEBQJhTwIEYnVybgkAzAgCBQJnbAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiaAUCZ2wFA25pbAMJAAACBQJncgUCZ3IEAmdCCQECZHQDCQEBLQEFAmN2CQEBLQEFAmN3AAAEAmZKCAUCZ0ICXzEEAmRrCAUCZ0ICXzIEAmZLCQECZHgCBQJkcwUCZGsDCQAAAgUCZksFAmZLCQDOCAIFAmN4BQJmSgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEIYWN0aXZhdGUCAmdDAmdEAwkBAiE9AgkApQgBCAUCZEwGY2FsbGVyCQClCAEFAmFPCQACAQIScGVybWlzc2lvbnMgZGVuaWVkCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFlAAUCZ0MJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFmAAUCZ0QFA25pbAIHc3VjY2VzcwJkTAEKcmVmcmVzaEtMcAAEAmdFCQELdmFsdWVPckVsc2UCCQCfCAEFAmFrAAAEAmdGAwkAZwIJAGUCBQZoZWlnaHQFAmdFBQJhbgUEdW5pdAkBAmFMAQkAuQkCCQDMCAIJAKQDAQUCYW4JAMwIAgIvIGJsb2NrcyBoYXZlIG5vdCBwYXNzZWQgc2luY2UgdGhlIHByZXZpb3VzIGNhbGwFA25pbAIAAwkAAAIFAmdGBQJnRgQCZEUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAqAMBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAmFqAgEwCQECYU4BAgtpbnZhbGlkIGtMcAQCZ0cJAQJkdAMAAAAAAAAEAmdICAUCZ0cCXzEEAmRrCAUCZ0cCXzIEAmR3AwkBAiE9AgUCZEUFAmRrBQJnSAkBAmFMAQISbm90aGluZyB0byByZWZyZXNoCQCUCgIFAmR3CQCmAwEFAmRrCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRMARxnZXRQb29sQ29uZmlnV3JhcHBlclJFQURPTkxZAAkAlAoCBQNuaWwJAQJhVgACZEwBHGdldEFjY0JhbGFuY2VXcmFwcGVyUkVBRE9OTFkBAmJGCQCUCgIFA25pbAkBAmJFAQUCYkYCZEwBGWNhbGNQcmljZXNXcmFwcGVyUkVBRE9OTFkDAmJOAmJPAmJTBAJjYgkBAmJSAwUCYk4FAmJPBQJiUwkAlAoCBQNuaWwJAMwIAgkApgMBCQCRAwIFAmNiAAAJAMwIAgkApgMBCQCRAwIFAmNiAAEJAMwIAgkApgMBCQCRAwIFAmNiAAIFA25pbAJkTAEUdG9YMThXcmFwcGVyUkVBRE9OTFkCAUUBRgkAlAoCBQNuaWwJAKYDAQkBAUQCBQFFBQFGAmRMARZmcm9tWDE4V3JhcHBlclJFQURPTkxZAgFJAUoJAJQKAgUDbmlsCQEBSAIJAKcDAQUBSQUBSgJkTAEeY2FsY1ByaWNlQmlnSW50V3JhcHBlclJFQURPTkxZAgJiSAJiSQkAlAoCBQNuaWwJAKYDAQkBAmJHAgkApwMBBQJiSAkApwMBBQJiSQJkTAEjZXN0aW1hdGVQdXRPcGVyYXRpb25XcmFwcGVyUkVBRE9OTFkJAmNkAmN6AmNBAmNCAmNDAmNEAmFiAmNFAmNGCQCUCgIFA25pbAkBAmN5CQUCY2QFAmN6BQJjQQUCY0IFAmNDBQJjRAUCYWIFAmNFBQJjRgJkTAEjZXN0aW1hdGVHZXRPcGVyYXRpb25XcmFwcGVyUkVBRE9OTFkEAmNkAmNlAmNmAmFiBAJjUAkBAmNjBAUCY2QFAmNlBQJjZgkBEUBleHRyTmF0aXZlKDEwNjIpAQUCYWIJAJQKAgUDbmlsCQCcCgoIBQJjUAJfMQgFAmNQAl8yCAUCY1ACXzMIBQJjUAJfNAgFAmNQAl81CAUCY1ACXzYIBQJjUAJfNwkApgMBCAUCY1ACXzgIBQJjUAJfOQgFAmNQA18xMAJkTAENc3RhdHNSRUFET05MWQAEAmJUCQECYVYABAJjZwkA2QQBCQCRAwIFAmJUBQFxBAJnSQkAkQMCBQJiVAUBcgQCZ0oJAJEDAgUCYlQFAXMEAmNJCQCRAwIFAmJUBQF2BAJjSgkAkQMCBQJiVAUBdwQCYlUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiVAUBdAQCYlYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiVAUBdQQCZ0sICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCY2cJAKwCAgkArAICAgZBc3NldCAJANgEAQUCY2cCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJnTAkBAmJFAQUCZ0kEAmdNCQECYkUBBQJnSgQCZ04DCQAAAgUCZ0sAAAkAzAgCBQFlCQDMCAIFAWUJAMwIAgUBZQUDbmlsCQECYlIDBQJnTAUCZ00FAmdLBAJjcQAABAJnTwkBAUgCCQCRAwIFAmdOAAEFAWIEAmdQCQEBSAIJAJEDAgUCZ04AAgUBYgQCZ1EJAQV2YWx1ZQEJAJoIAgUCYU8JAQJheQEJAKUIAQUEdGhpcwkAlAoCBQNuaWwJALkJAgkAzAgCAg4lZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmdMCQDMCAIJAKQDAQUCZ00JAMwIAgkApAMBBQJnSwkAzAgCCQCkAwEFAmNxCQDMCAIJAKQDAQUCZ08JAMwIAgkApAMBBQJnUAkAzAgCCQCkAwEFAmdRBQNuaWwFAWoCZEwBIGV2YWx1YXRlUHV0QnlBbW91bnRBc3NldFJFQURPTkxZAQJjQQQCYlQJAQJhVgAEAmNnCQDZBAEJAJEDAgUCYlQFAXEEAmNHCQCRAwIFAmJUBQFyBAJjaAkA2QQBBQJjRwQCY0gJAJEDAgUCYlQFAXMEAmNpCQDZBAEFAmNIBAJiVQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJUBQF0BAJiVgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJUBQF1BAJjagkAkQMCBQJiVAUBcAQCZ0sICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCY2cJAKwCAgkArAICAgZBc3NldCAJANgEAQUCY2cCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJnTAkBAmJFAQUCY0cEAmdNCQECYkUBBQJjSAQCYlAJAQFEAgUCZ0wFAmJVBAJiUQkBAUQCBQJnTQUCYlYEAmNwAwkAAAIFAmdLAAAFAWUJAQJiRwIFAmJRBQJiUAQCY00JAQFEAgUCY0EFAmJVBAJjTgkAvAIDBQJjTQUCY3AFAWQEAmNDCQEBSAIFAmNOBQJiVgQCZFIJAQJjeQkCAACgwh4FAmNBBQJjaAUCY0MFAmNpAgAGBwQCY1gIBQJkUgJfMQQCZ1IIBQJkUgJfMwQCY2wIBQJkUgJfNAQCY24IBQJkUgJfNQQCY2sIBQJkUgJfNgkAlAoCBQNuaWwJALkJAgkAzAgCAhAlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCY1gJAMwIAgkApAMBCQEBSAIFAmNwBQFiCQDMCAIJAKQDAQUCY2wJAMwIAgkApAMBBQJjbgkAzAgCCQCkAwEFAmNrCQDMCAIFAmNqCQDMCAIJAKQDAQUCY0EJAMwIAgkApAMBBQJjQwUDbmlsBQFqAmRMAR9ldmFsdWF0ZVB1dEJ5UHJpY2VBc3NldFJFQURPTkxZAQJjQwQCYlQJAQJhVgAEAmNnCQDZBAEJAJEDAgUCYlQFAXEEAmNHCQCRAwIFAmJUBQFyBAJjaAkA2QQBBQJjRwQCY0gJAJEDAgUCYlQFAXMEAmNpCQDZBAEFAmNIBAJiVQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJUBQF0BAJiVgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJUBQF1BAJjagkAkQMCBQJiVAUBcAQCZ0sICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCY2cJAKwCAgkArAICAgZBc3NldCAJANgEAQUCY2cCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJnUwkBAmJFAQUCY0cEAmdUCQECYkUBBQJjSAQCZ1UJAQFEAgUCZ1MFAmJVBAJnVgkBAUQCBQJnVAUCYlYEAmNwAwkAAAIFAmdLAAAFAWUJAQJiRwIFAmdWBQJnVQQCY04JAQFEAgUCY0MFAmJWBAJjTQkAvAIDBQJjTgUBZAUCY3AEAmNBCQEBSAIFAmNNBQJiVQQCZFIJAQJjeQkCAACgwh4FAmNBBQJjaAUCY0MFAmNpAgAGBwQCY1gIBQJkUgJfMQQCZ1IIBQJkUgJfMwQCY2wIBQJkUgJfNAQCY24IBQJkUgJfNQQCY2sIBQJkUgJfNgkAlAoCBQNuaWwJALkJAgkAzAgCAhAlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCY1gJAMwIAgkApAMBCQEBSAIFAmNwBQFiCQDMCAIJAKQDAQUCY2wJAMwIAgkApAMBBQJjbgkAzAgCCQCkAwEFAmNrCQDMCAIFAmNqCQDMCAIJAKQDAQUCY0EJAMwIAgkApAMBBQJjQwUDbmlsBQFqAmRMARNldmFsdWF0ZUdldFJFQURPTkxZAgJnVwJnWAQCY1AJAQJjYwQCAAUCZ1cFAmdYBQR0aGlzBAJjdggFAmNQAl8xBAJjdwgFAmNQAl8yBAJjbAgFAmNQAl81BAJjbggFAmNQAl82BAJjawgFAmNQAl83BAJjcQgFAmNQAl84BAJjagkBDXBhcnNlSW50VmFsdWUBCAUCY1ACXzkJAJQKAgUDbmlsCQC5CQIJAMwIAgIOJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJjdgkAzAgCCQCkAwEFAmN3CQDMCAIJAKQDAQUCY2wJAMwIAgkApAMBBQJjbgkAzAgCCQCkAwEFAmNrCQDMCAIJAKYDAQUCY3EJAMwIAgkApAMBBQJjagUDbmlsBQFqAQJnWQECZ1oABAJoYQQCZFcJAQJlWgADCQABAgUCZFcCCkJ5dGVWZWN0b3IEAmZkBQJkVwUCZmQDCQABAgUCZFcCBFVuaXQIBQJnWQ9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgQCZFcFAmdZAwkAAQIFAmRXAgVPcmRlcgQCZEEFAmRXBAJoYgkBAmFVAAQCaGMJAQJkegEFAmRBBAJhRAgFAmhjAl8xBAJhRQgFAmhjAl8yBAJhRgkA9AMDCAUCZEEJYm9keUJ5dGVzCQCRAwIIBQJkQQZwcm9vZnMAAAgFAmRBD3NlbmRlclB1YmxpY0tleQQCYUcJAPQDAwgFAmRBCWJvZHlCeXRlcwkAkQMCCAUCZEEGcHJvb2ZzAAEFAmhiAwMDBQJhRAUCYUYHBQJhRwcGCQECYUMEBQJhRAUCYUUFAmFGBQJhRwMJAAECBQJkVwIUU2V0U2NyaXB0VHJhbnNhY3Rpb24EAmZhBQJkVwMJAPQDAwgFAmdZCWJvZHlCeXRlcwkAkQMCCAUCZ1kGcHJvb2ZzAAAFAmhhBgQCaGQJAPYDAQkBBXZhbHVlAQgFAmZhBnNjcmlwdAQCaGUJANsEAQkBBXZhbHVlAQkAnQgCBQJhTwkBAmFBAAQCaGYJAPEHAQUEdGhpcwMJAAACBQJoZQUCaGQJAQIhPQIFAmhmBQJoZAcJAPQDAwgFAmdZCWJvZHlCeXRlcwkAkQMCCAUCZ1kGcHJvb2ZzAAAFAmhhZQflqw==", "height": 3514775, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: HcM9uEsS5q1TuwCd4kdWpCkQoxvTzQTbZs23m3XCCTVa Next: 25Ht9xSLji6uTaxsQUCqW6TnM9NJbMBRWvSAwdLP8HFG Diff:
OldNewDifferences
8282 func absBigInt (val) = if ((zeroBigInt > val))
8383 then -(val)
8484 else val
85+
86+
87+func swapContract () = "%s__swapContract"
8588
8689
8790 func fc () = "%s__factoryContract"
216219
217220 let poolConfigParsed = parsePoolConfig(getPoolConfig())
218221
219-let $t084088574 = poolConfigParsed
222+let $t084698635 = poolConfigParsed
220223
221-let cfgPoolAddress = $t084088574._1
224+let cfgPoolAddress = $t084698635._1
222225
223-let cfgPoolStatus = $t084088574._2
226+let cfgPoolStatus = $t084698635._2
224227
225-let cfgLpAssetId = $t084088574._3
228+let cfgLpAssetId = $t084698635._3
226229
227-let cfgAmountAssetId = $t084088574._4
230+let cfgAmountAssetId = $t084698635._4
228231
229-let cfgPriceAssetId = $t084088574._5
232+let cfgPriceAssetId = $t084698635._5
230233
231-let cfgAmountAssetDecimals = $t084088574._6
234+let cfgAmountAssetDecimals = $t084698635._6
232235
233-let cfgPriceAssetDecimals = $t084088574._7
236+let cfgPriceAssetDecimals = $t084698635._7
234237
235238 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
236239
435438 let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
436439 let amountAssetAmount = order.amount
437440 let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
438- let $t02148021692 = if ((order.orderType == Buy))
441+ let $t02154121753 = if ((order.orderType == Buy))
439442 then $Tuple2(amountAssetAmount, -(priceAssetAmount))
440443 else $Tuple2(-(amountAssetAmount), priceAssetAmount)
441- let amountAssetBalanceDelta = $t02148021692._1
442- let priceAssetBalanceDelta = $t02148021692._2
444+ let amountAssetBalanceDelta = $t02154121753._1
445+ let priceAssetBalanceDelta = $t02154121753._2
443446 if (if (if (isGlobalShutdown())
444447 then true
445448 else (cfgPoolStatus == PoolMatcherDisabled))
452455 then throw("Wrong order assets.")
453456 else {
454457 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
455- let $t02213222232 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
456- let unusedActions = $t02213222232._1
457- let kLpNew = $t02213222232._2
458+ let $t02219322293 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
459+ let unusedActions = $t02219322293._1
460+ let kLpNew = $t02219322293._2
458461 let isOrderValid = (kLpNew >= kLp)
459462 let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
460463 $Tuple2(isOrderValid, info)
533536 else if ((paymentAssetId == cfgPriceAssetId))
534537 then false
535538 else throwErr("invalid asset")
536- let $t02534525638 = if (isEval)
539+ let $t02540625699 = if (isEval)
537540 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
538541 else if (paymentInAmountAsset)
539542 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
540543 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
541- let amountBalanceOld = $t02534525638._1
542- let priceBalanceOld = $t02534525638._2
543- let $t02564225791 = if (paymentInAmountAsset)
544+ let amountBalanceOld = $t02540625699._1
545+ let priceBalanceOld = $t02540625699._2
546+ let $t02570325852 = if (paymentInAmountAsset)
544547 then $Tuple2(paymentAmountRaw, 0)
545548 else $Tuple2(0, paymentAmountRaw)
546- let amountAssetAmountRaw = $t02564225791._1
547- let priceAssetAmountRaw = $t02564225791._2
549+ let amountAssetAmountRaw = $t02570325852._1
550+ let priceAssetAmountRaw = $t02570325852._2
548551 let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
549552 let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
550- let $t02592325987 = takeFee(paymentAmountRaw, inFee)
551- let paymentAmount = $t02592325987._1
552- let feeAmount = $t02592325987._2
553+ let $t02598426048 = takeFee(paymentAmountRaw, inFee)
554+ let paymentAmount = $t02598426048._1
555+ let feeAmount = $t02598426048._2
553556 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
554557 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
555558 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
572575 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
573576 let priceOld = fromX18(priceOldX18, scale8)
574577 let loss = {
575- let $t02766827835 = if (paymentInAmountAsset)
578+ let $t02772927896 = if (paymentInAmountAsset)
576579 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
577580 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
578- let amount = $t02766827835._1
579- let balance = $t02766827835._2
581+ let amount = $t02772927896._1
582+ let balance = $t02772927896._2
580583 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
581584 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
582585 }
616619 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
617620 let redeemedBigInt = toBigInt(paymentAmount)
618621 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
619- let $t02991329969 = takeFee(amountRaw, outFee)
620- let totalAmount = $t02991329969._1
621- let feeAmount = $t02991329969._2
622- let $t02997330199 = if (outInAmountAsset)
622+ let $t02997430030 = takeFee(amountRaw, outFee)
623+ let totalAmount = $t02997430030._1
624+ let feeAmount = $t02997430030._2
625+ let $t03003430260 = if (outInAmountAsset)
623626 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
624627 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
625- let outAmAmount = $t02997330199._1
626- let outPrAmount = $t02997330199._2
627- let amBalanceNew = $t02997330199._3
628- let prBalanceNew = $t02997330199._4
628+ let outAmAmount = $t03003430260._1
629+ let outPrAmount = $t03003430260._2
630+ let amBalanceNew = $t03003430260._3
631+ let prBalanceNew = $t03003430260._4
629632 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
630633 let priceNew = fromX18(priceNewX18, scale8)
631634 let commonState = if (isEval)
688691 throw("Match error")
689692 }
690693 }
694+
695+
696+@Callable(i)
697+func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse) = {
698+ let $t03195732262 = if ((isReverse == false))
699+ then {
700+ let assetOut = getStringOrFail(this, pa())
701+ let assetIn = getStringOrFail(this, aa())
702+ $Tuple2(assetOut, assetIn)
703+ }
704+ else {
705+ let assetOut = getStringOrFail(this, aa())
706+ let assetIn = getStringOrFail(this, pa())
707+ $Tuple2(assetOut, assetIn)
708+ }
709+ let assetOut = $t03195732262._1
710+ let assetIn = $t03195732262._2
711+ let poolAssetInBalance = getAccBalance(assetIn)
712+ let poolAssetOutBalance = getAccBalance(assetOut)
713+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
714+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
715+ let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
716+ let checkK = if ((newK >= oldK))
717+ then true
718+ else throw("new K is fewer error")
719+ if ((checkK == checkK))
720+ then $Tuple2(nil, amountOut)
721+ else throw("Strict value is not equal to itself.")
722+ }
723+
724+
725+
726+@Callable(i)
727+func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo) = {
728+ let swapContact = {
729+ let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil)
730+ if ($isInstanceOf(@, "String"))
731+ then @
732+ else throw(($getType(@) + " couldn't be cast to String"))
733+ }
734+ let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
735+ then true
736+ else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
737+ then true
738+ else throwErr("Permission denied")]
739+ if ((checks == checks))
740+ then {
741+ let pmt = value(i.payments[0])
742+ let assetIn = assetIdToString(pmt.assetId)
743+ let assetOut = if ((isReverse == false))
744+ then getStringOrFail(this, pa())
745+ else getStringOrFail(this, aa())
746+ let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
747+ let poolAssetOutBalance = getAccBalance(assetOut)
748+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
749+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
750+ let newK = (toBigInt(getAccBalance(assetIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
751+ let checkK = if ((newK >= oldK))
752+ then true
753+ else throw("new K is fewer error")
754+ if ((checkK == checkK))
755+ then {
756+ let checkMin = if ((amountOut >= amountOutMin))
757+ then true
758+ else throw("Exchange result is fewer coins than expected")
759+ if ((checkMin == checkMin))
760+ then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))], amountOut)
761+ else throw("Strict value is not equal to itself.")
762+ }
763+ else throw("Strict value is not equal to itself.")
764+ }
765+ else throw("Strict value is not equal to itself.")
766+ }
767+
691768
692769
693770 @Callable(i)
771848 else throw("Strict value is not equal to itself.")
772849 }
773850 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
774- let $t03472735189 = refreshKLpInternal(0, 0, 0)
775- if (($t03472735189 == $t03472735189))
851+ let $t03707137533 = refreshKLpInternal(0, 0, 0)
852+ if (($t03707137533 == $t03707137533))
776853 then {
777- let updatedKLp = $t03472735189._2
778- let refreshKLpActions = $t03472735189._1
854+ let updatedKLp = $t03707137533._2
855+ let refreshKLpActions = $t03707137533._1
779856 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
780857 if ((isUpdatedKLpValid == isUpdatedKLpValid))
781858 then ((state ++ lpTransfer) ++ refreshKLpActions)
807884 let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
808885 if ((currentKLp == currentKLp))
809886 then {
810- let $t03575135816 = refreshKLpInternal(0, 0, 0)
811- let refreshKLpActions = $t03575135816._1
812- let updatedKLp = $t03575135816._2
887+ let $t03809538160 = refreshKLpInternal(0, 0, 0)
888+ let refreshKLpActions = $t03809538160._1
889+ let updatedKLp = $t03809538160._2
813890 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
814891 if ((isUpdatedKLpValid == isUpdatedKLpValid))
815892 then (state ++ refreshKLpActions)
856933 then {
857934 let userAddress = i.caller
858935 let txId = i.transactionId
859- let $t03700437156 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
860- if (($t03700437156 == $t03700437156))
936+ let $t03934839500 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
937+ if (($t03934839500 == $t03934839500))
861938 then {
862- let paymentInAmountAsset = $t03700437156._5
863- let bonus = $t03700437156._4
864- let feeAmount = $t03700437156._3
865- let commonState = $t03700437156._2
866- let emitAmountEstimated = $t03700437156._1
939+ let paymentInAmountAsset = $t03934839500._5
940+ let bonus = $t03934839500._4
941+ let feeAmount = $t03934839500._3
942+ let commonState = $t03934839500._2
943+ let emitAmountEstimated = $t03934839500._1
867944 let emitAmount = if (if ((minOutAmount > 0))
868945 then (minOutAmount > emitAmountEstimated)
869946 else false)
883960 let sendFee = if ((feeAmount > 0))
884961 then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
885962 else nil
886- let $t03774237939 = if ((this == feeCollectorAddress))
963+ let $t04008640283 = if ((this == feeCollectorAddress))
887964 then $Tuple2(0, 0)
888965 else if (paymentInAmountAsset)
889966 then $Tuple2(-(feeAmount), 0)
890967 else $Tuple2(0, -(feeAmount))
891- let amountAssetBalanceDelta = $t03774237939._1
892- let priceAssetBalanceDelta = $t03774237939._2
893- let $t03794238050 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
894- let refreshKLpActions = $t03794238050._1
895- let updatedKLp = $t03794238050._2
968+ let amountAssetBalanceDelta = $t04008640283._1
969+ let priceAssetBalanceDelta = $t04008640283._2
970+ let $t04028640394 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
971+ let refreshKLpActions = $t04028640394._1
972+ let updatedKLp = $t04028640394._2
896973 let kLp = value(getString(keyKLp))
897974 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
898975 if ((isUpdatedKLpValid == isUpdatedKLpValid))
912989
913990 @Callable(i)
914991 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
915- let $t03835638513 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
916- let emitAmountEstimated = $t03835638513._1
917- let commonState = $t03835638513._2
918- let feeAmount = $t03835638513._3
919- let bonus = $t03835638513._4
920- let paymentInAmountAsset = $t03835638513._5
992+ let $t04070040857 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
993+ let emitAmountEstimated = $t04070040857._1
994+ let commonState = $t04070040857._2
995+ let feeAmount = $t04070040857._3
996+ let bonus = $t04070040857._4
997+ let paymentInAmountAsset = $t04070040857._5
921998 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
922999 }
9231000
9541031 then {
9551032 let userAddress = i.caller
9561033 let txId = i.transactionId
957- let $t03939839551 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
958- if (($t03939839551 == $t03939839551))
1034+ let $t04174241895 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1035+ if (($t04174241895 == $t04174241895))
9591036 then {
960- let outInAmountAsset = $t03939839551._5
961- let bonus = $t03939839551._4
962- let feeAmount = $t03939839551._3
963- let commonState = $t03939839551._2
964- let amountEstimated = $t03939839551._1
1037+ let outInAmountAsset = $t04174241895._5
1038+ let bonus = $t04174241895._4
1039+ let feeAmount = $t04174241895._3
1040+ let commonState = $t04174241895._2
1041+ let amountEstimated = $t04174241895._1
9651042 let amount = if (if ((minOutAmount > 0))
9661043 then (minOutAmount > amountEstimated)
9671044 else false)
9741051 let sendFee = if ((feeAmount > 0))
9751052 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
9761053 else nil
977- let $t04005140298 = {
1054+ let $t04239542642 = {
9781055 let feeAmountForCalc = if ((this == feeCollectorAddress))
9791056 then 0
9801057 else feeAmount
9821059 then $Tuple2(-((amount + feeAmountForCalc)), 0)
9831060 else $Tuple2(0, -((amount + feeAmountForCalc)))
9841061 }
985- let amountAssetBalanceDelta = $t04005140298._1
986- let priceAssetBalanceDelta = $t04005140298._2
987- let $t04030140409 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
988- let refreshKLpActions = $t04030140409._1
989- let updatedKLp = $t04030140409._2
1062+ let amountAssetBalanceDelta = $t04239542642._1
1063+ let priceAssetBalanceDelta = $t04239542642._2
1064+ let $t04264542753 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1065+ let refreshKLpActions = $t04264542753._1
1066+ let updatedKLp = $t04264542753._2
9901067 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
9911068 if ((isUpdatedKLpValid == isUpdatedKLpValid))
9921069 then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
10051082
10061083 @Callable(i)
10071084 func getOneTknREADONLY (outAssetId,paymentAmount) = {
1008- let $t04066640822 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1009- let amountEstimated = $t04066640822._1
1010- let commonState = $t04066640822._2
1011- let feeAmount = $t04066640822._3
1012- let bonus = $t04066640822._4
1013- let outInAmountAsset = $t04066640822._5
1085+ let $t04301043166 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1086+ let amountEstimated = $t04301043166._1
1087+ let commonState = $t04301043166._2
1088+ let feeAmount = $t04301043166._3
1089+ let bonus = $t04301043166._4
1090+ let outInAmountAsset = $t04301043166._5
10141091 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
10151092 }
10161093
10471124 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
10481125 if ((unstakeInv == unstakeInv))
10491126 then {
1050- let $t04172741878 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1051- if (($t04172741878 == $t04172741878))
1127+ let $t04407144222 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1128+ if (($t04407144222 == $t04407144222))
10521129 then {
1053- let outInAmountAsset = $t04172741878._5
1054- let bonus = $t04172741878._4
1055- let feeAmount = $t04172741878._3
1056- let commonState = $t04172741878._2
1057- let amountEstimated = $t04172741878._1
1130+ let outInAmountAsset = $t04407144222._5
1131+ let bonus = $t04407144222._4
1132+ let feeAmount = $t04407144222._3
1133+ let commonState = $t04407144222._2
1134+ let amountEstimated = $t04407144222._1
10581135 let amount = if (if ((minOutAmount > 0))
10591136 then (minOutAmount > amountEstimated)
10601137 else false)
10671144 let sendFee = if ((feeAmount > 0))
10681145 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
10691146 else nil
1070- let $t04237342620 = {
1147+ let $t04471744964 = {
10711148 let feeAmountForCalc = if ((this == feeCollectorAddress))
10721149 then 0
10731150 else feeAmount
10751152 then $Tuple2(-((amount + feeAmountForCalc)), 0)
10761153 else $Tuple2(0, -((amount + feeAmountForCalc)))
10771154 }
1078- let amountAssetBalanceDelta = $t04237342620._1
1079- let priceAssetBalanceDelta = $t04237342620._2
1080- let $t04262342731 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1081- let refreshKLpActions = $t04262342731._1
1082- let updatedKLp = $t04262342731._2
1155+ let amountAssetBalanceDelta = $t04471744964._1
1156+ let priceAssetBalanceDelta = $t04471744964._2
1157+ let $t04496745075 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1158+ let refreshKLpActions = $t04496745075._1
1159+ let updatedKLp = $t04496745075._2
10831160 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
10841161 if ((isUpdatedKLpValid == isUpdatedKLpValid))
10851162 then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
11121189 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
11131190 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11141191 then {
1115- let $t04367743759 = refreshKLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1116- let refreshKLpActions = $t04367743759._1
1117- let updatedKLp = $t04367743759._2
1192+ let $t04602146103 = refreshKLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1193+ let refreshKLpActions = $t04602146103._1
1194+ let updatedKLp = $t04602146103._2
11181195 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11191196 if ((isUpdatedKLpValid == isUpdatedKLpValid))
11201197 then (state ++ refreshKLpActions)
11461223 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
11471224 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11481225 then {
1149- let $t04470844789 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1150- let refreshKLpActions = $t04470844789._1
1151- let updatedKLp = $t04470844789._2
1226+ let $t04705247133 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1227+ let refreshKLpActions = $t04705247133._1
1228+ let updatedKLp = $t04705247133._2
11521229 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11531230 if ((isUpdatedKLpValid == isUpdatedKLpValid))
11541231 then (state ++ refreshKLpActions)
11921269 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
11931270 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11941271 then {
1195- let $t04591545996 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1196- let refreshKLpActions = $t04591545996._1
1197- let updatedKLp = $t04591545996._2
1272+ let $t04825948340 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1273+ let refreshKLpActions = $t04825948340._1
1274+ let updatedKLp = $t04825948340._2
11981275 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11991276 if ((isUpdatedKLpValid == isUpdatedKLpValid))
12001277 then (state ++ refreshKLpActions)
12451322 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
12461323 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
12471324 then {
1248- let $t04729147372 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1249- let refreshKLpActions = $t04729147372._1
1250- let updatedKLp = $t04729147372._2
1325+ let $t04963549716 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1326+ let refreshKLpActions = $t04963549716._1
1327+ let updatedKLp = $t04963549716._2
12511328 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
12521329 if ((isUpdatedKLpValid == isUpdatedKLpValid))
12531330 then (state ++ refreshKLpActions)
12821359 if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
12831360 then {
12841361 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1285- let $t04855948623 = refreshKLpInternal(0, 0, 0)
1286- let kLpUpdateActions = $t04855948623._1
1287- let updatedKLp = $t04855948623._2
1362+ let $t05090350967 = refreshKLpInternal(0, 0, 0)
1363+ let kLpUpdateActions = $t05090350967._1
1364+ let updatedKLp = $t05090350967._2
12881365 let actions = if ((kLp != updatedKLp))
12891366 then kLpUpdateActions
12901367 else throwErr("nothing to refresh")
14591536 match tx {
14601537 case order: Order =>
14611538 let matcherPub = getMatcherPubOrFail()
1462- let $t05728557354 = validateMatcherOrderAllowed(order)
1463- let orderValid = $t05728557354._1
1464- let orderValidInfo = $t05728557354._2
1539+ let $t05962959698 = validateMatcherOrderAllowed(order)
1540+ let orderValid = $t05962959698._1
1541+ let orderValidInfo = $t05962959698._2
14651542 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
14661543 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
14671544 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
85+
86+
87+func swapContract () = "%s__swapContract"
8588
8689
8790 func fc () = "%s__factoryContract"
8891
8992
9093 func mpk () = "%s__managerPublicKey"
9194
9295
9396 func pmpk () = "%s__pendingManagerPublicKey"
9497
9598
9699 func pl () = "%s%s__price__last"
97100
98101
99102 func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
100103
101104
102105 func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
103106
104107
105108 func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
106109
107110
108111 func aa () = "%s__amountAsset"
109112
110113
111114 func pa () = "%s__priceAsset"
112115
113116
114117 let keyFee = "%s__fee"
115118
116119 let feeDefault = fraction(10, scale8, 10000)
117120
118121 let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
119122
120123 let keyKLp = makeString(["%s", "kLp"], SEP)
121124
122125 let keyKLpRefreshedHeight = makeString(["%s", "kLpRefreshedHeight"], SEP)
123126
124127 let keyKLpRefreshDelay = makeString(["%s", "refreshKLpDelay"], SEP)
125128
126129 let kLpRefreshDelayDefault = 30
127130
128131 let kLpRefreshDelay = valueOrElse(getInteger(this, keyKLpRefreshDelay), kLpRefreshDelayDefault)
129132
130133 func keyFactoryConfig () = "%s__factoryConfig"
131134
132135
133136 func keyMatcherPub () = "%s%s__matcher__publicKey"
134137
135138
136139 func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
137140
138141
139142 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
140143
141144
142145 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
143146
144147
145148 func keyAllPoolsShutdown () = "%s__shutdown"
146149
147150
148151 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
149152
150153
151154 func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
152155
153156
154157 let keyFeeCollectorAddress = "%s__feeCollectorAddress"
155158
156159 func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
157160
158161
159162 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
160163
161164
162165 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
163166
164167
165168 func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
166169
167170
168171 func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
169172
170173
171174 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
172175
173176 let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
174177
175178 let inFee = {
176179 let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
177180 if ($isInstanceOf(@, "Int"))
178181 then @
179182 else throw(($getType(@) + " couldn't be cast to Int"))
180183 }
181184
182185 let outFee = {
183186 let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
184187 if ($isInstanceOf(@, "Int"))
185188 then @
186189 else throw(($getType(@) + " couldn't be cast to Int"))
187190 }
188191
189192 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
190193
191194
192195 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
193196
194197
195198 func getPoolConfig () = {
196199 let amtAsset = getStringOrFail(this, aa())
197200 let priceAsset = getStringOrFail(this, pa())
198201 let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
199202 let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
200203 split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
201204 }
202205
203206
204207 func parseAssetId (input) = if ((input == wavesString))
205208 then unit
206209 else fromBase58String(input)
207210
208211
209212 func assetIdToString (input) = if ((input == unit))
210213 then wavesString
211214 else toBase58String(value(input))
212215
213216
214217 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]))
215218
216219
217220 let poolConfigParsed = parsePoolConfig(getPoolConfig())
218221
219-let $t084088574 = poolConfigParsed
222+let $t084698635 = poolConfigParsed
220223
221-let cfgPoolAddress = $t084088574._1
224+let cfgPoolAddress = $t084698635._1
222225
223-let cfgPoolStatus = $t084088574._2
226+let cfgPoolStatus = $t084698635._2
224227
225-let cfgLpAssetId = $t084088574._3
228+let cfgLpAssetId = $t084698635._3
226229
227-let cfgAmountAssetId = $t084088574._4
230+let cfgAmountAssetId = $t084698635._4
228231
229-let cfgPriceAssetId = $t084088574._5
232+let cfgPriceAssetId = $t084698635._5
230233
231-let cfgAmountAssetDecimals = $t084088574._6
234+let cfgAmountAssetDecimals = $t084698635._6
232235
233-let cfgPriceAssetDecimals = $t084088574._7
236+let cfgPriceAssetDecimals = $t084698635._7
234237
235238 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
236239
237240
238241 let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
239242
240243 let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
241244
242245 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)
243246
244247
245248 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)
246249
247250
248251 func getAccBalance (assetId) = if ((assetId == "WAVES"))
249252 then wavesBalance(this).available
250253 else assetBalance(this, fromBase58String(assetId))
251254
252255
253256 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
254257
255258
256259 func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
257260
258261
259262 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
260263 let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
261264 let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
262265 calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
263266 }
264267
265268
266269 func calcPrices (amAmt,prAmt,lpAmt) = {
267270 let cfg = getPoolConfig()
268271 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
269272 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
270273 let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
271274 let amAmtX18 = toX18(amAmt, amtAssetDcm)
272275 let prAmtX18 = toX18(prAmt, priceAssetDcm)
273276 let lpAmtX18 = toX18(lpAmt, scale8)
274277 let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
275278 let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
276279 [priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
277280 }
278281
279282
280283 func calculatePrices (amAmt,prAmt,lpAmt) = {
281284 let prices = calcPrices(amAmt, prAmt, lpAmt)
282285 [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
283286 }
284287
285288
286289 func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
287290 let cfg = getPoolConfig()
288291 let lpAssetId = cfg[idxPoolLPAssetId]
289292 let amAssetId = cfg[idxAmtAssetId]
290293 let prAssetId = cfg[idxPriceAssetId]
291294 let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
292295 let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
293296 let poolStatus = cfg[idxPoolStatus]
294297 let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
295298 if ((lpAssetId != pmtAssetId))
296299 then throw("Invalid asset passed.")
297300 else {
298301 let amBalance = getAccBalance(amAssetId)
299302 let amBalanceX18 = toX18(amBalance, amAssetDcm)
300303 let prBalance = getAccBalance(prAssetId)
301304 let prBalanceX18 = toX18(prBalance, prAssetDcm)
302305 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
303306 let curPrice = fromX18(curPriceX18, scale8)
304307 let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
305308 let lpEmissionX18 = toX18(lpEmission, scale8)
306309 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
307310 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
308311 let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
309312 let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
310313 let state = if ((txId58 == ""))
311314 then nil
312315 else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
313316 then unit
314317 else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
315318 then unit
316319 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)]
317320 $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
318321 }
319322 }
320323
321324
322325 func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
323326 let cfg = getPoolConfig()
324327 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
325328 let amAssetIdStr = cfg[idxAmtAssetId]
326329 let prAssetIdStr = cfg[idxPriceAssetId]
327330 let iAmtAssetId = cfg[idxIAmtAssetId]
328331 let iPriceAssetId = cfg[idxIPriceAssetId]
329332 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
330333 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
331334 let poolStatus = cfg[idxPoolStatus]
332335 let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
333336 let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
334337 let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
335338 if (if ((amAssetIdStr != inAmAssetIdStr))
336339 then true
337340 else (prAssetIdStr != inPrAssetIdStr))
338341 then throw("Invalid amt or price asset passed.")
339342 else {
340343 let amBalance = if (isEvaluate)
341344 then getAccBalance(amAssetIdStr)
342345 else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
343346 let prBalance = if (isEvaluate)
344347 then getAccBalance(prAssetIdStr)
345348 else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
346349 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
347350 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
348351 let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
349352 let amBalanceX18 = toX18(amBalance, amtAssetDcm)
350353 let prBalanceX18 = toX18(prBalance, priceAssetDcm)
351354 let res = if ((lpEmission == 0))
352355 then {
353356 let curPriceX18 = zeroBigInt
354357 let slippageX18 = zeroBigInt
355358 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
356359 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
357360 }
358361 else {
359362 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
360363 let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
361364 let slippageToleranceX18 = toX18(slippageTolerance, scale8)
362365 if (if ((curPriceX18 != zeroBigInt))
363366 then (slippageX18 > slippageToleranceX18)
364367 else false)
365368 then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
366369 else {
367370 let lpEmissionX18 = toX18(lpEmission, scale8)
368371 let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
369372 let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
370373 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
371374 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
372375 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
373376 let expAmtAssetAmtX18 = expectedAmts._1
374377 let expPriceAssetAmtX18 = expectedAmts._2
375378 let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
376379 $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
377380 }
378381 }
379382 let calcLpAmt = res._1
380383 let calcAmAssetPmt = res._2
381384 let calcPrAssetPmt = res._3
382385 let curPrice = fromX18(res._4, scale8)
383386 let slippageCalc = fromX18(res._5, scale8)
384387 if ((0 >= calcLpAmt))
385388 then throw("Invalid calculations. LP calculated is less than zero.")
386389 else {
387390 let emitLpAmt = if (!(emitLp))
388391 then 0
389392 else calcLpAmt
390393 let amDiff = (inAmAssetAmt - calcAmAssetPmt)
391394 let prDiff = (inPrAssetAmt - calcPrAssetPmt)
392395 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))]
393396 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
394397 }
395398 }
396399 }
397400
398401
399402 func calcKLp (amountBalance,priceBalance,lpEmission) = {
400403 let amountBalanceX18 = toX18BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals))
401404 let priceBalanceX18 = toX18BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))
402405 let updatedKLp = fraction(pow((amountBalanceX18 * priceBalanceX18), 0, toBigInt(5), 1, 18, DOWN), big1, lpEmission)
403406 if ((lpEmission == big0))
404407 then big0
405408 else updatedKLp
406409 }
407410
408411
409412 func calcCurrentKLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
410413 let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
411414 let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
412415 let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
413416 let currentKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
414417 currentKLp
415418 }
416419
417420
418421 func refreshKLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
419422 let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
420423 let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
421424 let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
422425 let updatedKLp = calcKLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
423426 let actions = [IntegerEntry(keyKLpRefreshedHeight, height), StringEntry(keyKLp, toString(updatedKLp))]
424427 $Tuple2(actions, updatedKLp)
425428 }
426429
427430
428431 func validateUpdatedKLp (oldKLp,updatedKLp) = if ((updatedKLp >= oldKLp))
429432 then true
430433 else throwErr(makeString(["updated KLp lower than current KLp", toString(oldKLp), toString(updatedKLp)], " "))
431434
432435
433436 func validateMatcherOrderAllowed (order) = {
434437 let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
435438 let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
436439 let amountAssetAmount = order.amount
437440 let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
438- let $t02148021692 = if ((order.orderType == Buy))
441+ let $t02154121753 = if ((order.orderType == Buy))
439442 then $Tuple2(amountAssetAmount, -(priceAssetAmount))
440443 else $Tuple2(-(amountAssetAmount), priceAssetAmount)
441- let amountAssetBalanceDelta = $t02148021692._1
442- let priceAssetBalanceDelta = $t02148021692._2
444+ let amountAssetBalanceDelta = $t02154121753._1
445+ let priceAssetBalanceDelta = $t02154121753._2
443446 if (if (if (isGlobalShutdown())
444447 then true
445448 else (cfgPoolStatus == PoolMatcherDisabled))
446449 then true
447450 else (cfgPoolStatus == PoolShutdown))
448451 then throw("Exchange operations disabled")
449452 else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
450453 then true
451454 else (order.assetPair.priceAsset != cfgPriceAssetId))
452455 then throw("Wrong order assets.")
453456 else {
454457 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
455- let $t02213222232 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
456- let unusedActions = $t02213222232._1
457- let kLpNew = $t02213222232._2
458+ let $t02219322293 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
459+ let unusedActions = $t02219322293._1
460+ let kLpNew = $t02219322293._2
458461 let isOrderValid = (kLpNew >= kLp)
459462 let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
460463 $Tuple2(isOrderValid, info)
461464 }
462465 }
463466
464467
465468 func commonGet (i) = if ((size(i.payments) != 1))
466469 then throw("exactly 1 payment is expected")
467470 else {
468471 let pmt = value(i.payments[0])
469472 let pmtAssetId = value(pmt.assetId)
470473 let pmtAmt = pmt.amount
471474 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
472475 let outAmAmt = res._1
473476 let outPrAmt = res._2
474477 let poolStatus = parseIntValue(res._9)
475478 let state = res._10
476479 if (if (isGlobalShutdown())
477480 then true
478481 else (poolStatus == PoolShutdown))
479482 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
480483 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
481484 }
482485
483486
484487 func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
485488 then throw("exactly 2 payments are expected")
486489 else {
487490 let amAssetPmt = value(i.payments[0])
488491 let prAssetPmt = value(i.payments[1])
489492 let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
490493 let poolStatus = parseIntValue(estPut._8)
491494 if (if (if (isGlobalShutdown())
492495 then true
493496 else (poolStatus == PoolPutDisabled))
494497 then true
495498 else (poolStatus == PoolShutdown))
496499 then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
497500 else estPut
498501 }
499502
500503
501504 func emit (amount) = {
502505 let emitInv = invoke(factoryContract, "emit", [amount], nil)
503506 if ((emitInv == emitInv))
504507 then {
505508 let emitInvLegacy = match emitInv {
506509 case legacyFactoryContract: Address =>
507510 invoke(legacyFactoryContract, "emit", [amount], nil)
508511 case _ =>
509512 unit
510513 }
511514 if ((emitInvLegacy == emitInvLegacy))
512515 then amount
513516 else throw("Strict value is not equal to itself.")
514517 }
515518 else throw("Strict value is not equal to itself.")
516519 }
517520
518521
519522 func takeFee (amount,fee) = {
520523 let feeAmount = if ((fee == 0))
521524 then 0
522525 else fraction(amount, fee, scale8)
523526 $Tuple2((amount - feeAmount), feeAmount)
524527 }
525528
526529
527530 func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
528531 let isEval = (txId == unit)
529532 let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
530533 let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
531534 let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
532535 then true
533536 else if ((paymentAssetId == cfgPriceAssetId))
534537 then false
535538 else throwErr("invalid asset")
536- let $t02534525638 = if (isEval)
539+ let $t02540625699 = if (isEval)
537540 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
538541 else if (paymentInAmountAsset)
539542 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
540543 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
541- let amountBalanceOld = $t02534525638._1
542- let priceBalanceOld = $t02534525638._2
543- let $t02564225791 = if (paymentInAmountAsset)
544+ let amountBalanceOld = $t02540625699._1
545+ let priceBalanceOld = $t02540625699._2
546+ let $t02570325852 = if (paymentInAmountAsset)
544547 then $Tuple2(paymentAmountRaw, 0)
545548 else $Tuple2(0, paymentAmountRaw)
546- let amountAssetAmountRaw = $t02564225791._1
547- let priceAssetAmountRaw = $t02564225791._2
549+ let amountAssetAmountRaw = $t02570325852._1
550+ let priceAssetAmountRaw = $t02570325852._2
548551 let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
549552 let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
550- let $t02592325987 = takeFee(paymentAmountRaw, inFee)
551- let paymentAmount = $t02592325987._1
552- let feeAmount = $t02592325987._2
553+ let $t02598426048 = takeFee(paymentAmountRaw, inFee)
554+ let paymentAmount = $t02598426048._1
555+ let feeAmount = $t02598426048._2
553556 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
554557 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
555558 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
556559 let priceNew = fromX18(priceNewX18, scale8)
557560 let paymentBalance = if (paymentInAmountAsset)
558561 then amountBalanceOld
559562 else priceBalanceOld
560563 let paymentBalanceBigInt = toBigInt(paymentBalance)
561564 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
562565 let chechSupply = if ((supplyBigInt > big0))
563566 then true
564567 else throwErr("initial deposit requires all coins")
565568 if ((chechSupply == chechSupply))
566569 then {
567570 let depositBigInt = toBigInt(paymentAmount)
568571 let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
569572 let commonState = if (isEval)
570573 then nil
571574 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))]
572575 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
573576 let priceOld = fromX18(priceOldX18, scale8)
574577 let loss = {
575- let $t02766827835 = if (paymentInAmountAsset)
578+ let $t02772927896 = if (paymentInAmountAsset)
576579 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
577580 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
578- let amount = $t02766827835._1
579- let balance = $t02766827835._2
581+ let amount = $t02772927896._1
582+ let balance = $t02772927896._2
580583 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
581584 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
582585 }
583586 $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
584587 }
585588 else throw("Strict value is not equal to itself.")
586589 }
587590
588591
589592 func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
590593 let isEval = (txId == unit)
591594 let cfg = getPoolConfig()
592595 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
593596 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
594597 let checks = [if ((paymentAssetId == cfgLpAssetId))
595598 then true
596599 else throwErr("invalid lp asset")]
597600 if ((checks == checks))
598601 then {
599602 let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
600603 then true
601604 else if ((outAssetId == cfgPriceAssetId))
602605 then false
603606 else throwErr("invalid asset")
604607 let balanceBigInt = if (outInAmountAsset)
605608 then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
606609 else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
607610 let outInAmountAssetDecimals = if (outInAmountAsset)
608611 then amtAssetDcm
609612 else priceAssetDcm
610613 let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
611614 let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
612615 let outBalance = if (outInAmountAsset)
613616 then amBalanceOld
614617 else prBalanceOld
615618 let outBalanceBigInt = toBigInt(outBalance)
616619 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
617620 let redeemedBigInt = toBigInt(paymentAmount)
618621 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
619- let $t02991329969 = takeFee(amountRaw, outFee)
620- let totalAmount = $t02991329969._1
621- let feeAmount = $t02991329969._2
622- let $t02997330199 = if (outInAmountAsset)
622+ let $t02997430030 = takeFee(amountRaw, outFee)
623+ let totalAmount = $t02997430030._1
624+ let feeAmount = $t02997430030._2
625+ let $t03003430260 = if (outInAmountAsset)
623626 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
624627 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
625- let outAmAmount = $t02997330199._1
626- let outPrAmount = $t02997330199._2
627- let amBalanceNew = $t02997330199._3
628- let prBalanceNew = $t02997330199._4
628+ let outAmAmount = $t03003430260._1
629+ let outPrAmount = $t03003430260._2
630+ let amBalanceNew = $t03003430260._3
631+ let prBalanceNew = $t03003430260._4
629632 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
630633 let priceNew = fromX18(priceNewX18, scale8)
631634 let commonState = if (isEval)
632635 then nil
633636 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)]
634637 let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
635638 let priceOld = fromX18(priceOldX18, scale8)
636639 let loss = {
637640 let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
638641 fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
639642 }
640643 $Tuple5(totalAmount, commonState, feeAmount, loss, outInAmountAsset)
641644 }
642645 else throw("Strict value is not equal to itself.")
643646 }
644647
645648
646649 func managerPublicKeyOrUnit () = match getString(mpk()) {
647650 case s: String =>
648651 fromBase58String(s)
649652 case _: Unit =>
650653 unit
651654 case _ =>
652655 throw("Match error")
653656 }
654657
655658
656659 func pendingManagerPublicKeyOrUnit () = match getString(pmpk()) {
657660 case s: String =>
658661 fromBase58String(s)
659662 case _: Unit =>
660663 unit
661664 case _ =>
662665 throw("Match error")
663666 }
664667
665668
666669 func isManager (i) = match managerPublicKeyOrUnit() {
667670 case pk: ByteVector =>
668671 (i.callerPublicKey == pk)
669672 case _: Unit =>
670673 (i.caller == this)
671674 case _ =>
672675 throw("Match error")
673676 }
674677
675678
676679 func mustManager (i) = {
677680 let pd = throw("Permission denied")
678681 match managerPublicKeyOrUnit() {
679682 case pk: ByteVector =>
680683 if ((i.callerPublicKey == pk))
681684 then true
682685 else pd
683686 case _: Unit =>
684687 if ((i.caller == this))
685688 then true
686689 else pd
687690 case _ =>
688691 throw("Match error")
689692 }
690693 }
694+
695+
696+@Callable(i)
697+func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse) = {
698+ let $t03195732262 = if ((isReverse == false))
699+ then {
700+ let assetOut = getStringOrFail(this, pa())
701+ let assetIn = getStringOrFail(this, aa())
702+ $Tuple2(assetOut, assetIn)
703+ }
704+ else {
705+ let assetOut = getStringOrFail(this, aa())
706+ let assetIn = getStringOrFail(this, pa())
707+ $Tuple2(assetOut, assetIn)
708+ }
709+ let assetOut = $t03195732262._1
710+ let assetIn = $t03195732262._2
711+ let poolAssetInBalance = getAccBalance(assetIn)
712+ let poolAssetOutBalance = getAccBalance(assetOut)
713+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
714+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
715+ let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
716+ let checkK = if ((newK >= oldK))
717+ then true
718+ else throw("new K is fewer error")
719+ if ((checkK == checkK))
720+ then $Tuple2(nil, amountOut)
721+ else throw("Strict value is not equal to itself.")
722+ }
723+
724+
725+
726+@Callable(i)
727+func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo) = {
728+ let swapContact = {
729+ let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil)
730+ if ($isInstanceOf(@, "String"))
731+ then @
732+ else throw(($getType(@) + " couldn't be cast to String"))
733+ }
734+ let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
735+ then true
736+ else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
737+ then true
738+ else throwErr("Permission denied")]
739+ if ((checks == checks))
740+ then {
741+ let pmt = value(i.payments[0])
742+ let assetIn = assetIdToString(pmt.assetId)
743+ let assetOut = if ((isReverse == false))
744+ then getStringOrFail(this, pa())
745+ else getStringOrFail(this, aa())
746+ let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
747+ let poolAssetOutBalance = getAccBalance(assetOut)
748+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
749+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
750+ let newK = (toBigInt(getAccBalance(assetIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
751+ let checkK = if ((newK >= oldK))
752+ then true
753+ else throw("new K is fewer error")
754+ if ((checkK == checkK))
755+ then {
756+ let checkMin = if ((amountOut >= amountOutMin))
757+ then true
758+ else throw("Exchange result is fewer coins than expected")
759+ if ((checkMin == checkMin))
760+ then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))], amountOut)
761+ else throw("Strict value is not equal to itself.")
762+ }
763+ else throw("Strict value is not equal to itself.")
764+ }
765+ else throw("Strict value is not equal to itself.")
766+ }
767+
691768
692769
693770 @Callable(i)
694771 func setManager (pendingManagerPublicKey) = {
695772 let checkCaller = mustManager(i)
696773 if ((checkCaller == checkCaller))
697774 then {
698775 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
699776 if ((checkManagerPublicKey == checkManagerPublicKey))
700777 then [StringEntry(pmpk(), pendingManagerPublicKey)]
701778 else throw("Strict value is not equal to itself.")
702779 }
703780 else throw("Strict value is not equal to itself.")
704781 }
705782
706783
707784
708785 @Callable(i)
709786 func confirmManager () = {
710787 let pm = pendingManagerPublicKeyOrUnit()
711788 let hasPM = if (isDefined(pm))
712789 then true
713790 else throw("No pending manager")
714791 if ((hasPM == hasPM))
715792 then {
716793 let checkPM = if ((i.callerPublicKey == value(pm)))
717794 then true
718795 else throw("You are not pending manager")
719796 if ((checkPM == checkPM))
720797 then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())]
721798 else throw("Strict value is not equal to itself.")
722799 }
723800 else throw("Strict value is not equal to itself.")
724801 }
725802
726803
727804
728805 @Callable(i)
729806 func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
730807 then throw("Invalid slippageTolerance passed")
731808 else {
732809 let estPut = commonPut(i, slippageTolerance, true)
733810 let emitLpAmt = estPut._2
734811 let lpAssetId = estPut._7
735812 let state = estPut._9
736813 let amDiff = estPut._10
737814 let prDiff = estPut._11
738815 let amId = estPut._12
739816 let prId = estPut._13
740817 let amAssetPmt = toBigInt(value(i.payments[0]).amount)
741818 let prAssetPmt = toBigInt(value(i.payments[1]).amount)
742819 let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
743820 if ((currentKLp == currentKLp))
744821 then {
745822 let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
746823 if ((emitInv == emitInv))
747824 then {
748825 let emitInvLegacy = match emitInv {
749826 case legacyFactoryContract: Address =>
750827 invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
751828 case _ =>
752829 unit
753830 }
754831 if ((emitInvLegacy == emitInvLegacy))
755832 then {
756833 let slippageAInv = if ((amDiff > 0))
757834 then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
758835 else nil
759836 if ((slippageAInv == slippageAInv))
760837 then {
761838 let slippagePInv = if ((prDiff > 0))
762839 then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
763840 else nil
764841 if ((slippagePInv == slippagePInv))
765842 then {
766843 let lpTransfer = if (shouldAutoStake)
767844 then {
768845 let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
769846 if ((slpStakeInv == slpStakeInv))
770847 then nil
771848 else throw("Strict value is not equal to itself.")
772849 }
773850 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
774- let $t03472735189 = refreshKLpInternal(0, 0, 0)
775- if (($t03472735189 == $t03472735189))
851+ let $t03707137533 = refreshKLpInternal(0, 0, 0)
852+ if (($t03707137533 == $t03707137533))
776853 then {
777- let updatedKLp = $t03472735189._2
778- let refreshKLpActions = $t03472735189._1
854+ let updatedKLp = $t03707137533._2
855+ let refreshKLpActions = $t03707137533._1
779856 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
780857 if ((isUpdatedKLpValid == isUpdatedKLpValid))
781858 then ((state ++ lpTransfer) ++ refreshKLpActions)
782859 else throw("Strict value is not equal to itself.")
783860 }
784861 else throw("Strict value is not equal to itself.")
785862 }
786863 else throw("Strict value is not equal to itself.")
787864 }
788865 else throw("Strict value is not equal to itself.")
789866 }
790867 else throw("Strict value is not equal to itself.")
791868 }
792869 else throw("Strict value is not equal to itself.")
793870 }
794871 else throw("Strict value is not equal to itself.")
795872 }
796873
797874
798875
799876 @Callable(i)
800877 func putForFree (maxSlippage) = if ((0 > maxSlippage))
801878 then throw("Invalid value passed")
802879 else {
803880 let estPut = commonPut(i, maxSlippage, false)
804881 let state = estPut._9
805882 let amAssetPmt = toBigInt(value(i.payments[0]).amount)
806883 let prAssetPmt = toBigInt(value(i.payments[1]).amount)
807884 let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
808885 if ((currentKLp == currentKLp))
809886 then {
810- let $t03575135816 = refreshKLpInternal(0, 0, 0)
811- let refreshKLpActions = $t03575135816._1
812- let updatedKLp = $t03575135816._2
887+ let $t03809538160 = refreshKLpInternal(0, 0, 0)
888+ let refreshKLpActions = $t03809538160._1
889+ let updatedKLp = $t03809538160._2
813890 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
814891 if ((isUpdatedKLpValid == isUpdatedKLpValid))
815892 then (state ++ refreshKLpActions)
816893 else throw("Strict value is not equal to itself.")
817894 }
818895 else throw("Strict value is not equal to itself.")
819896 }
820897
821898
822899
823900 @Callable(i)
824901 func putOneTkn (minOutAmount,autoStake) = {
825902 let isPoolOneTokenOperationsDisabled = {
826903 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
827904 if ($isInstanceOf(@, "Boolean"))
828905 then @
829906 else throw(($getType(@) + " couldn't be cast to Boolean"))
830907 }
831908 let isPutDisabled = if (if (if (isGlobalShutdown())
832909 then true
833910 else (cfgPoolStatus == PoolPutDisabled))
834911 then true
835912 else (cfgPoolStatus == PoolShutdown))
836913 then true
837914 else isPoolOneTokenOperationsDisabled
838915 let checks = [if (if (!(isPutDisabled))
839916 then true
840917 else isManager(i))
841918 then true
842919 else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
843920 then true
844921 else throwErr("exactly 1 payment are expected")]
845922 if ((checks == checks))
846923 then {
847924 let payment = i.payments[0]
848925 let paymentAssetId = payment.assetId
849926 let paymentAmountRaw = payment.amount
850927 let currentKLp = if ((paymentAssetId == cfgAmountAssetId))
851928 then calcCurrentKLp(toBigInt(paymentAmountRaw), toBigInt(0), toBigInt(0))
852929 else if ((paymentAssetId == cfgPriceAssetId))
853930 then calcCurrentKLp(toBigInt(0), toBigInt(paymentAmountRaw), toBigInt(0))
854931 else throwErr("payment asset is not supported")
855932 if ((currentKLp == currentKLp))
856933 then {
857934 let userAddress = i.caller
858935 let txId = i.transactionId
859- let $t03700437156 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
860- if (($t03700437156 == $t03700437156))
936+ let $t03934839500 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
937+ if (($t03934839500 == $t03934839500))
861938 then {
862- let paymentInAmountAsset = $t03700437156._5
863- let bonus = $t03700437156._4
864- let feeAmount = $t03700437156._3
865- let commonState = $t03700437156._2
866- let emitAmountEstimated = $t03700437156._1
939+ let paymentInAmountAsset = $t03934839500._5
940+ let bonus = $t03934839500._4
941+ let feeAmount = $t03934839500._3
942+ let commonState = $t03934839500._2
943+ let emitAmountEstimated = $t03934839500._1
867944 let emitAmount = if (if ((minOutAmount > 0))
868945 then (minOutAmount > emitAmountEstimated)
869946 else false)
870947 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
871948 else emitAmountEstimated
872949 let emitInv = emit(emitAmount)
873950 if ((emitInv == emitInv))
874951 then {
875952 let lpTransfer = if (autoStake)
876953 then {
877954 let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
878955 if ((stakeInv == stakeInv))
879956 then nil
880957 else throw("Strict value is not equal to itself.")
881958 }
882959 else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
883960 let sendFee = if ((feeAmount > 0))
884961 then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
885962 else nil
886- let $t03774237939 = if ((this == feeCollectorAddress))
963+ let $t04008640283 = if ((this == feeCollectorAddress))
887964 then $Tuple2(0, 0)
888965 else if (paymentInAmountAsset)
889966 then $Tuple2(-(feeAmount), 0)
890967 else $Tuple2(0, -(feeAmount))
891- let amountAssetBalanceDelta = $t03774237939._1
892- let priceAssetBalanceDelta = $t03774237939._2
893- let $t03794238050 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
894- let refreshKLpActions = $t03794238050._1
895- let updatedKLp = $t03794238050._2
968+ let amountAssetBalanceDelta = $t04008640283._1
969+ let priceAssetBalanceDelta = $t04008640283._2
970+ let $t04028640394 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
971+ let refreshKLpActions = $t04028640394._1
972+ let updatedKLp = $t04028640394._2
896973 let kLp = value(getString(keyKLp))
897974 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
898975 if ((isUpdatedKLpValid == isUpdatedKLpValid))
899976 then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
900977 else throw("Strict value is not equal to itself.")
901978 }
902979 else throw("Strict value is not equal to itself.")
903980 }
904981 else throw("Strict value is not equal to itself.")
905982 }
906983 else throw("Strict value is not equal to itself.")
907984 }
908985 else throw("Strict value is not equal to itself.")
909986 }
910987
911988
912989
913990 @Callable(i)
914991 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
915- let $t03835638513 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
916- let emitAmountEstimated = $t03835638513._1
917- let commonState = $t03835638513._2
918- let feeAmount = $t03835638513._3
919- let bonus = $t03835638513._4
920- let paymentInAmountAsset = $t03835638513._5
992+ let $t04070040857 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
993+ let emitAmountEstimated = $t04070040857._1
994+ let commonState = $t04070040857._2
995+ let feeAmount = $t04070040857._3
996+ let bonus = $t04070040857._4
997+ let paymentInAmountAsset = $t04070040857._5
921998 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
922999 }
9231000
9241001
9251002
9261003 @Callable(i)
9271004 func getOneTkn (outAssetIdStr,minOutAmount) = {
9281005 let isPoolOneTokenOperationsDisabled = {
9291006 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
9301007 if ($isInstanceOf(@, "Boolean"))
9311008 then @
9321009 else throw(($getType(@) + " couldn't be cast to Boolean"))
9331010 }
9341011 let isGetDisabled = if (if (isGlobalShutdown())
9351012 then true
9361013 else (cfgPoolStatus == PoolShutdown))
9371014 then true
9381015 else isPoolOneTokenOperationsDisabled
9391016 let checks = [if (if (!(isGetDisabled))
9401017 then true
9411018 else isManager(i))
9421019 then true
9431020 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
9441021 then true
9451022 else throwErr("exactly 1 payment are expected")]
9461023 if ((checks == checks))
9471024 then {
9481025 let outAssetId = parseAssetId(outAssetIdStr)
9491026 let payment = i.payments[0]
9501027 let paymentAssetId = payment.assetId
9511028 let paymentAmount = payment.amount
9521029 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
9531030 if ((currentKLp == currentKLp))
9541031 then {
9551032 let userAddress = i.caller
9561033 let txId = i.transactionId
957- let $t03939839551 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
958- if (($t03939839551 == $t03939839551))
1034+ let $t04174241895 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1035+ if (($t04174241895 == $t04174241895))
9591036 then {
960- let outInAmountAsset = $t03939839551._5
961- let bonus = $t03939839551._4
962- let feeAmount = $t03939839551._3
963- let commonState = $t03939839551._2
964- let amountEstimated = $t03939839551._1
1037+ let outInAmountAsset = $t04174241895._5
1038+ let bonus = $t04174241895._4
1039+ let feeAmount = $t04174241895._3
1040+ let commonState = $t04174241895._2
1041+ let amountEstimated = $t04174241895._1
9651042 let amount = if (if ((minOutAmount > 0))
9661043 then (minOutAmount > amountEstimated)
9671044 else false)
9681045 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
9691046 else amountEstimated
9701047 let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
9711048 if ((burnInv == burnInv))
9721049 then {
9731050 let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
9741051 let sendFee = if ((feeAmount > 0))
9751052 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
9761053 else nil
977- let $t04005140298 = {
1054+ let $t04239542642 = {
9781055 let feeAmountForCalc = if ((this == feeCollectorAddress))
9791056 then 0
9801057 else feeAmount
9811058 if (outInAmountAsset)
9821059 then $Tuple2(-((amount + feeAmountForCalc)), 0)
9831060 else $Tuple2(0, -((amount + feeAmountForCalc)))
9841061 }
985- let amountAssetBalanceDelta = $t04005140298._1
986- let priceAssetBalanceDelta = $t04005140298._2
987- let $t04030140409 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
988- let refreshKLpActions = $t04030140409._1
989- let updatedKLp = $t04030140409._2
1062+ let amountAssetBalanceDelta = $t04239542642._1
1063+ let priceAssetBalanceDelta = $t04239542642._2
1064+ let $t04264542753 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1065+ let refreshKLpActions = $t04264542753._1
1066+ let updatedKLp = $t04264542753._2
9901067 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
9911068 if ((isUpdatedKLpValid == isUpdatedKLpValid))
9921069 then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
9931070 else throw("Strict value is not equal to itself.")
9941071 }
9951072 else throw("Strict value is not equal to itself.")
9961073 }
9971074 else throw("Strict value is not equal to itself.")
9981075 }
9991076 else throw("Strict value is not equal to itself.")
10001077 }
10011078 else throw("Strict value is not equal to itself.")
10021079 }
10031080
10041081
10051082
10061083 @Callable(i)
10071084 func getOneTknREADONLY (outAssetId,paymentAmount) = {
1008- let $t04066640822 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1009- let amountEstimated = $t04066640822._1
1010- let commonState = $t04066640822._2
1011- let feeAmount = $t04066640822._3
1012- let bonus = $t04066640822._4
1013- let outInAmountAsset = $t04066640822._5
1085+ let $t04301043166 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1086+ let amountEstimated = $t04301043166._1
1087+ let commonState = $t04301043166._2
1088+ let feeAmount = $t04301043166._3
1089+ let bonus = $t04301043166._4
1090+ let outInAmountAsset = $t04301043166._5
10141091 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
10151092 }
10161093
10171094
10181095
10191096 @Callable(i)
10201097 func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
10211098 let isPoolOneTokenOperationsDisabled = {
10221099 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
10231100 if ($isInstanceOf(@, "Boolean"))
10241101 then @
10251102 else throw(($getType(@) + " couldn't be cast to Boolean"))
10261103 }
10271104 let isGetDisabled = if (if (isGlobalShutdown())
10281105 then true
10291106 else (cfgPoolStatus == PoolShutdown))
10301107 then true
10311108 else isPoolOneTokenOperationsDisabled
10321109 let checks = [if (if (!(isGetDisabled))
10331110 then true
10341111 else isManager(i))
10351112 then true
10361113 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
10371114 then true
10381115 else throwErr("no payments are expected")]
10391116 if ((checks == checks))
10401117 then {
10411118 let outAssetId = parseAssetId(outAssetIdStr)
10421119 let userAddress = i.caller
10431120 let txId = i.transactionId
10441121 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
10451122 if ((currentKLp == currentKLp))
10461123 then {
10471124 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
10481125 if ((unstakeInv == unstakeInv))
10491126 then {
1050- let $t04172741878 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1051- if (($t04172741878 == $t04172741878))
1127+ let $t04407144222 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1128+ if (($t04407144222 == $t04407144222))
10521129 then {
1053- let outInAmountAsset = $t04172741878._5
1054- let bonus = $t04172741878._4
1055- let feeAmount = $t04172741878._3
1056- let commonState = $t04172741878._2
1057- let amountEstimated = $t04172741878._1
1130+ let outInAmountAsset = $t04407144222._5
1131+ let bonus = $t04407144222._4
1132+ let feeAmount = $t04407144222._3
1133+ let commonState = $t04407144222._2
1134+ let amountEstimated = $t04407144222._1
10581135 let amount = if (if ((minOutAmount > 0))
10591136 then (minOutAmount > amountEstimated)
10601137 else false)
10611138 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
10621139 else amountEstimated
10631140 let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
10641141 if ((burnInv == burnInv))
10651142 then {
10661143 let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
10671144 let sendFee = if ((feeAmount > 0))
10681145 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
10691146 else nil
1070- let $t04237342620 = {
1147+ let $t04471744964 = {
10711148 let feeAmountForCalc = if ((this == feeCollectorAddress))
10721149 then 0
10731150 else feeAmount
10741151 if (outInAmountAsset)
10751152 then $Tuple2(-((amount + feeAmountForCalc)), 0)
10761153 else $Tuple2(0, -((amount + feeAmountForCalc)))
10771154 }
1078- let amountAssetBalanceDelta = $t04237342620._1
1079- let priceAssetBalanceDelta = $t04237342620._2
1080- let $t04262342731 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1081- let refreshKLpActions = $t04262342731._1
1082- let updatedKLp = $t04262342731._2
1155+ let amountAssetBalanceDelta = $t04471744964._1
1156+ let priceAssetBalanceDelta = $t04471744964._2
1157+ let $t04496745075 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1158+ let refreshKLpActions = $t04496745075._1
1159+ let updatedKLp = $t04496745075._2
10831160 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
10841161 if ((isUpdatedKLpValid == isUpdatedKLpValid))
10851162 then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
10861163 else throw("Strict value is not equal to itself.")
10871164 }
10881165 else throw("Strict value is not equal to itself.")
10891166 }
10901167 else throw("Strict value is not equal to itself.")
10911168 }
10921169 else throw("Strict value is not equal to itself.")
10931170 }
10941171 else throw("Strict value is not equal to itself.")
10951172 }
10961173 else throw("Strict value is not equal to itself.")
10971174 }
10981175
10991176
11001177
11011178 @Callable(i)
11021179 func get () = {
11031180 let res = commonGet(i)
11041181 let outAmtAmt = res._1
11051182 let outPrAmt = res._2
11061183 let pmtAmt = res._3
11071184 let pmtAssetId = res._4
11081185 let state = res._5
11091186 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
11101187 if ((currentKLp == currentKLp))
11111188 then {
11121189 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
11131190 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11141191 then {
1115- let $t04367743759 = refreshKLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1116- let refreshKLpActions = $t04367743759._1
1117- let updatedKLp = $t04367743759._2
1192+ let $t04602146103 = refreshKLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1193+ let refreshKLpActions = $t04602146103._1
1194+ let updatedKLp = $t04602146103._2
11181195 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11191196 if ((isUpdatedKLpValid == isUpdatedKLpValid))
11201197 then (state ++ refreshKLpActions)
11211198 else throw("Strict value is not equal to itself.")
11221199 }
11231200 else throw("Strict value is not equal to itself.")
11241201 }
11251202 else throw("Strict value is not equal to itself.")
11261203 }
11271204
11281205
11291206
11301207 @Callable(i)
11311208 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
11321209 let res = commonGet(i)
11331210 let outAmAmt = res._1
11341211 let outPrAmt = res._2
11351212 let pmtAmt = res._3
11361213 let pmtAssetId = res._4
11371214 let state = res._5
11381215 if ((noLessThenAmtAsset > outAmAmt))
11391216 then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
11401217 else if ((noLessThenPriceAsset > outPrAmt))
11411218 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
11421219 else {
11431220 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
11441221 if ((currentKLp == currentKLp))
11451222 then {
11461223 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
11471224 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11481225 then {
1149- let $t04470844789 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1150- let refreshKLpActions = $t04470844789._1
1151- let updatedKLp = $t04470844789._2
1226+ let $t04705247133 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1227+ let refreshKLpActions = $t04705247133._1
1228+ let updatedKLp = $t04705247133._2
11521229 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11531230 if ((isUpdatedKLpValid == isUpdatedKLpValid))
11541231 then (state ++ refreshKLpActions)
11551232 else throw("Strict value is not equal to itself.")
11561233 }
11571234 else throw("Strict value is not equal to itself.")
11581235 }
11591236 else throw("Strict value is not equal to itself.")
11601237 }
11611238 }
11621239
11631240
11641241
11651242 @Callable(i)
11661243 func unstakeAndGet (amount) = {
11671244 let checkPayments = if ((size(i.payments) != 0))
11681245 then throw("No payments are expected")
11691246 else true
11701247 if ((checkPayments == checkPayments))
11711248 then {
11721249 let cfg = getPoolConfig()
11731250 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
11741251 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
11751252 if ((currentKLp == currentKLp))
11761253 then {
11771254 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
11781255 if ((unstakeInv == unstakeInv))
11791256 then {
11801257 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
11811258 let outAmAmt = res._1
11821259 let outPrAmt = res._2
11831260 let poolStatus = parseIntValue(res._9)
11841261 let state = res._10
11851262 let checkPoolStatus = if (if (isGlobalShutdown())
11861263 then true
11871264 else (poolStatus == PoolShutdown))
11881265 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
11891266 else true
11901267 if ((checkPoolStatus == checkPoolStatus))
11911268 then {
11921269 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
11931270 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11941271 then {
1195- let $t04591545996 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1196- let refreshKLpActions = $t04591545996._1
1197- let updatedKLp = $t04591545996._2
1272+ let $t04825948340 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1273+ let refreshKLpActions = $t04825948340._1
1274+ let updatedKLp = $t04825948340._2
11981275 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11991276 if ((isUpdatedKLpValid == isUpdatedKLpValid))
12001277 then (state ++ refreshKLpActions)
12011278 else throw("Strict value is not equal to itself.")
12021279 }
12031280 else throw("Strict value is not equal to itself.")
12041281 }
12051282 else throw("Strict value is not equal to itself.")
12061283 }
12071284 else throw("Strict value is not equal to itself.")
12081285 }
12091286 else throw("Strict value is not equal to itself.")
12101287 }
12111288 else throw("Strict value is not equal to itself.")
12121289 }
12131290
12141291
12151292
12161293 @Callable(i)
12171294 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
12181295 let isGetDisabled = if (isGlobalShutdown())
12191296 then true
12201297 else (cfgPoolStatus == PoolShutdown)
12211298 let checks = [if (!(isGetDisabled))
12221299 then true
12231300 else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
12241301 then true
12251302 else throw("no payments are expected")]
12261303 if ((checks == checks))
12271304 then {
12281305 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
12291306 if ((currentKLp == currentKLp))
12301307 then {
12311308 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
12321309 if ((unstakeInv == unstakeInv))
12331310 then {
12341311 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
12351312 let outAmAmt = res._1
12361313 let outPrAmt = res._2
12371314 let state = res._10
12381315 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
12391316 then true
12401317 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
12411318 then true
12421319 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
12431320 if ((checkAmounts == checkAmounts))
12441321 then {
12451322 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
12461323 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
12471324 then {
1248- let $t04729147372 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1249- let refreshKLpActions = $t04729147372._1
1250- let updatedKLp = $t04729147372._2
1325+ let $t04963549716 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1326+ let refreshKLpActions = $t04963549716._1
1327+ let updatedKLp = $t04963549716._2
12511328 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
12521329 if ((isUpdatedKLpValid == isUpdatedKLpValid))
12531330 then (state ++ refreshKLpActions)
12541331 else throw("Strict value is not equal to itself.")
12551332 }
12561333 else throw("Strict value is not equal to itself.")
12571334 }
12581335 else throw("Strict value is not equal to itself.")
12591336 }
12601337 else throw("Strict value is not equal to itself.")
12611338 }
12621339 else throw("Strict value is not equal to itself.")
12631340 }
12641341 else throw("Strict value is not equal to itself.")
12651342 }
12661343
12671344
12681345
12691346 @Callable(i)
12701347 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
12711348 then throw("permissions denied")
12721349 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
12731350
12741351
12751352
12761353 @Callable(i)
12771354 func refreshKLp () = {
12781355 let lastRefreshedBlockHeight = valueOrElse(getInteger(keyKLpRefreshedHeight), 0)
12791356 let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= kLpRefreshDelay))
12801357 then unit
12811358 else throwErr(makeString([toString(kLpRefreshDelay), " blocks have not passed since the previous call"], ""))
12821359 if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
12831360 then {
12841361 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1285- let $t04855948623 = refreshKLpInternal(0, 0, 0)
1286- let kLpUpdateActions = $t04855948623._1
1287- let updatedKLp = $t04855948623._2
1362+ let $t05090350967 = refreshKLpInternal(0, 0, 0)
1363+ let kLpUpdateActions = $t05090350967._1
1364+ let updatedKLp = $t05090350967._2
12881365 let actions = if ((kLp != updatedKLp))
12891366 then kLpUpdateActions
12901367 else throwErr("nothing to refresh")
12911368 $Tuple2(actions, toString(updatedKLp))
12921369 }
12931370 else throw("Strict value is not equal to itself.")
12941371 }
12951372
12961373
12971374
12981375 @Callable(i)
12991376 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
13001377
13011378
13021379
13031380 @Callable(i)
13041381 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
13051382
13061383
13071384
13081385 @Callable(i)
13091386 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
13101387 let prices = calcPrices(amAmt, prAmt, lpAmt)
13111388 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
13121389 }
13131390
13141391
13151392
13161393 @Callable(i)
13171394 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
13181395
13191396
13201397
13211398 @Callable(i)
13221399 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
13231400
13241401
13251402
13261403 @Callable(i)
13271404 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
13281405
13291406
13301407
13311408 @Callable(i)
13321409 func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
13331410
13341411
13351412
13361413 @Callable(i)
13371414 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
13381415 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
13391416 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
13401417 }
13411418
13421419
13431420
13441421 @Callable(i)
13451422 func statsREADONLY () = {
13461423 let cfg = getPoolConfig()
13471424 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
13481425 let amtAssetId = cfg[idxAmtAssetId]
13491426 let priceAssetId = cfg[idxPriceAssetId]
13501427 let iAmtAssetId = cfg[idxIAmtAssetId]
13511428 let iPriceAssetId = cfg[idxIPriceAssetId]
13521429 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
13531430 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
13541431 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
13551432 let accAmtAssetBalance = getAccBalance(amtAssetId)
13561433 let accPriceAssetBalance = getAccBalance(priceAssetId)
13571434 let pricesList = if ((poolLPBalance == 0))
13581435 then [zeroBigInt, zeroBigInt, zeroBigInt]
13591436 else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
13601437 let curPrice = 0
13611438 let lpAmtAssetShare = fromX18(pricesList[1], scale8)
13621439 let lpPriceAssetShare = fromX18(pricesList[2], scale8)
13631440 let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
13641441 $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))
13651442 }
13661443
13671444
13681445
13691446 @Callable(i)
13701447 func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
13711448 let cfg = getPoolConfig()
13721449 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
13731450 let amAssetIdStr = cfg[idxAmtAssetId]
13741451 let amAssetId = fromBase58String(amAssetIdStr)
13751452 let prAssetIdStr = cfg[idxPriceAssetId]
13761453 let prAssetId = fromBase58String(prAssetIdStr)
13771454 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
13781455 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
13791456 let poolStatus = cfg[idxPoolStatus]
13801457 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
13811458 let accAmtAssetBalance = getAccBalance(amAssetIdStr)
13821459 let accPriceAssetBalance = getAccBalance(prAssetIdStr)
13831460 let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
13841461 let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
13851462 let curPriceX18 = if ((poolLPBalance == 0))
13861463 then zeroBigInt
13871464 else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
13881465 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
13891466 let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
13901467 let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
13911468 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
13921469 let calcLpAmt = estPut._1
13931470 let curPriceCalc = estPut._3
13941471 let amBalance = estPut._4
13951472 let prBalance = estPut._5
13961473 let lpEmission = estPut._6
13971474 $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))
13981475 }
13991476
14001477
14011478
14021479 @Callable(i)
14031480 func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
14041481 let cfg = getPoolConfig()
14051482 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
14061483 let amAssetIdStr = cfg[idxAmtAssetId]
14071484 let amAssetId = fromBase58String(amAssetIdStr)
14081485 let prAssetIdStr = cfg[idxPriceAssetId]
14091486 let prAssetId = fromBase58String(prAssetIdStr)
14101487 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
14111488 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
14121489 let poolStatus = cfg[idxPoolStatus]
14131490 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
14141491 let amBalanceRaw = getAccBalance(amAssetIdStr)
14151492 let prBalanceRaw = getAccBalance(prAssetIdStr)
14161493 let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
14171494 let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
14181495 let curPriceX18 = if ((poolLPBalance == 0))
14191496 then zeroBigInt
14201497 else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
14211498 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
14221499 let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
14231500 let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
14241501 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
14251502 let calcLpAmt = estPut._1
14261503 let curPriceCalc = estPut._3
14271504 let amBalance = estPut._4
14281505 let prBalance = estPut._5
14291506 let lpEmission = estPut._6
14301507 $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))
14311508 }
14321509
14331510
14341511
14351512 @Callable(i)
14361513 func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
14371514 let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
14381515 let outAmAmt = res._1
14391516 let outPrAmt = res._2
14401517 let amBalance = res._5
14411518 let prBalance = res._6
14421519 let lpEmission = res._7
14431520 let curPrice = res._8
14441521 let poolStatus = parseIntValue(res._9)
14451522 $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))
14461523 }
14471524
14481525
14491526 @Verifier(tx)
14501527 func verify () = {
14511528 let targetPublicKey = match managerPublicKeyOrUnit() {
14521529 case pk: ByteVector =>
14531530 pk
14541531 case _: Unit =>
14551532 tx.senderPublicKey
14561533 case _ =>
14571534 throw("Match error")
14581535 }
14591536 match tx {
14601537 case order: Order =>
14611538 let matcherPub = getMatcherPubOrFail()
1462- let $t05728557354 = validateMatcherOrderAllowed(order)
1463- let orderValid = $t05728557354._1
1464- let orderValidInfo = $t05728557354._2
1539+ let $t05962959698 = validateMatcherOrderAllowed(order)
1540+ let orderValid = $t05962959698._1
1541+ let orderValidInfo = $t05962959698._2
14651542 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
14661543 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
14671544 if (if (if (orderValid)
14681545 then senderValid
14691546 else false)
14701547 then matcherValid
14711548 else false)
14721549 then true
14731550 else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
14741551 case s: SetScriptTransaction =>
14751552 if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
14761553 then true
14771554 else {
14781555 let newHash = blake2b256(value(s.script))
14791556 let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
14801557 let currentHash = scriptHash(this)
14811558 if ((allowedHash == newHash))
14821559 then (currentHash != newHash)
14831560 else false
14841561 }
14851562 case _ =>
14861563 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
14871564 }
14881565 }
14891566

github/deemru/w8io/786bc32 
214.98 ms