tx · 2WgjaRzisTBEtqaBbJ5GRHrKKZ4zQjmWHNyXD59sVb7G

3N6wAa7PMFZJu4Zrmp3avXmMnRTrRpMM9Lh:  -0.03900000 Waves

2023.02.09 13:40 [2441988] smart account 3N6wAa7PMFZJu4Zrmp3avXmMnRTrRpMM9Lh > SELF 0.00000000 Waves

{ "type": 13, "id": "2WgjaRzisTBEtqaBbJ5GRHrKKZ4zQjmWHNyXD59sVb7G", "fee": 3900000, "feeAssetId": null, "timestamp": 1675939225308, "version": 2, "chainId": 84, "sender": "3N6wAa7PMFZJu4Zrmp3avXmMnRTrRpMM9Lh", "senderPublicKey": "Cr8D7eozSzJh7XHsYTjBinPpo3SS83BrCGiBAJsjGxBo", "proofs": [ "3sxBbuHB51gnTfaWbAj3R9QndCryTvq7VNi548Dyhx3vR4RCwpWX53jZ1bEWMuEQG7YY1aikf6tgnGqjq3MD2xVC" ], "script": "base64:BgLRLwgCEgQKAgEEEgYKBAEEAQgSAwoBCBIAEgQKAgEEEgMKAQESBAoCAQQSBAoCCAESBAoCCAESBAoCCAESBQoDAQgBEgASBAoCAQESAwoBARIFCgMBAQESBAoCCAgSABIAEgMKAQgSBQoDAQEBEgQKAgEBEgQKAggBEgQKAggIEgsKCQgBAQIBAggEBBIGCgQICAEIEgASAwoBARIDCgEBEgQKAggBIgpsUGRlY2ltYWxzIgZzY2FsZTgiDHNjYWxlOEJpZ0ludCIHc2NhbGUxOCIKemVyb0JpZ0ludCIEYmlnMCIEYmlnMSIEYmlnMiILd2F2ZXNTdHJpbmciA1NFUCIKUG9vbEFjdGl2ZSIPUG9vbFB1dERpc2FibGVkIhNQb29sTWF0Y2hlckRpc2FibGVkIgxQb29sU2h1dGRvd24iDmlkeFBvb2xBZGRyZXNzIg1pZHhQb29sU3RhdHVzIhBpZHhQb29sTFBBc3NldElkIg1pZHhBbXRBc3NldElkIg9pZHhQcmljZUFzc2V0SWQiDmlkeEFtdEFzc2V0RGNtIhBpZHhQcmljZUFzc2V0RGNtIg5pZHhJQW10QXNzZXRJZCIQaWR4SVByaWNlQXNzZXRJZCINaWR4TFBBc3NldERjbSISaWR4UG9vbEFtdEFzc2V0QW10IhRpZHhQb29sUHJpY2VBc3NldEFtdCIRaWR4UG9vbExQQXNzZXRBbXQiGWlkeEZhY3RvcnlTdGFraW5nQ29udHJhY3QiGmlkeEZhY3RvcnlTbGlwcGFnZUNvbnRyYWN0IgV0b1gxOCIHb3JpZ1ZhbCINb3JpZ1NjYWxlTXVsdCILdG9YMThCaWdJbnQiB2Zyb21YMTgiA3ZhbCIPcmVzdWx0U2NhbGVNdWx0Igxmcm9tWDE4Um91bmQiBXJvdW5kIgd0b1NjYWxlIgNhbXQiCHJlc1NjYWxlIghjdXJTY2FsZSIDYWJzIglhYnNCaWdJbnQiDHN3YXBDb250cmFjdCICZmMiA21wayIEcG1wayICcGwiAnBoIgFoIgl0aW1lc3RhbXAiA3BhdSILdXNlckFkZHJlc3MiBHR4SWQiA2dhdSICYWEiAnBhIgZrZXlGZWUiCmZlZURlZmF1bHQiA2ZlZSIGa2V5S0xwIhVrZXlLTHBSZWZyZXNoZWRIZWlnaHQiEmtleUtMcFJlZnJlc2hEZWxheSIWa0xwUmVmcmVzaERlbGF5RGVmYXVsdCIPa0xwUmVmcmVzaERlbGF5IhBrZXlGYWN0b3J5Q29uZmlnIg1rZXlNYXRjaGVyUHViIilrZXlNYXBwaW5nUG9vbENvbnRyYWN0QWRkcmVzc1RvUG9vbEFzc2V0cyITcG9vbENvbnRyYWN0QWRkcmVzcyINa2V5UG9vbENvbmZpZyIJaUFtdEFzc2V0IgtpUHJpY2VBc3NldCIfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZCIMYmFzZUFzc2V0U3RyIhNrZXlBbGxQb29sc1NodXRkb3duIg1rZXlQb29sV2VpZ2h0Ig9jb250cmFjdEFkZHJlc3MiFmtleUFsbG93ZWRMcFNjcmlwdEhhc2giFmtleUZlZUNvbGxlY3RvckFkZHJlc3MiD3Rocm93T3JkZXJFcnJvciIKb3JkZXJWYWxpZCIOb3JkZXJWYWxpZEluZm8iC3NlbmRlclZhbGlkIgxtYXRjaGVyVmFsaWQiD2dldFN0cmluZ09yRmFpbCIHYWRkcmVzcyIDa2V5IgxnZXRJbnRPckZhaWwiCHRocm93RXJyIgNtc2ciBmZtdEVyciIPZmFjdG9yeUNvbnRyYWN0IhNmZWVDb2xsZWN0b3JBZGRyZXNzIgVpbkZlZSIBQCIGb3V0RmVlIhBpc0dsb2JhbFNodXRkb3duIhNnZXRNYXRjaGVyUHViT3JGYWlsIg1nZXRQb29sQ29uZmlnIghhbXRBc3NldCIKcHJpY2VBc3NldCIMcGFyc2VBc3NldElkIgVpbnB1dCIPYXNzZXRJZFRvU3RyaW5nIg9wYXJzZVBvb2xDb25maWciCnBvb2xDb25maWciEHBvb2xDb25maWdQYXJzZWQiCyR0MDg0Njk4NjM1Ig5jZmdQb29sQWRkcmVzcyINY2ZnUG9vbFN0YXR1cyIMY2ZnTHBBc3NldElkIhBjZmdBbW91bnRBc3NldElkIg9jZmdQcmljZUFzc2V0SWQiFmNmZ0Ftb3VudEFzc2V0RGVjaW1hbHMiFWNmZ1ByaWNlQXNzZXREZWNpbWFscyIQZ2V0RmFjdG9yeUNvbmZpZyIPc3Rha2luZ0NvbnRyYWN0IhBzbGlwcGFnZUNvbnRyYWN0IhFkYXRhUHV0QWN0aW9uSW5mbyINaW5BbXRBc3NldEFtdCIPaW5QcmljZUFzc2V0QW10IghvdXRMcEFtdCIFcHJpY2UiHXNsaXBwYWdlVG9sZXJhbmNlUGFzc2VkQnlVc2VyIhVzbGlwcGFnZVRvbGVyYW5jZVJlYWwiCHR4SGVpZ2h0Igt0eFRpbWVzdGFtcCISc2xpcGFnZUFtdEFzc2V0QW10IhRzbGlwYWdlUHJpY2VBc3NldEFtdCIRZGF0YUdldEFjdGlvbkluZm8iDm91dEFtdEFzc2V0QW10IhBvdXRQcmljZUFzc2V0QW10IgdpbkxwQW10Ig1nZXRBY2NCYWxhbmNlIgdhc3NldElkIg9jYWxjUHJpY2VCaWdJbnQiCHByQW10WDE4IghhbUFtdFgxOCIUY2FsY1ByaWNlQmlnSW50Um91bmQiEHByaXZhdGVDYWxjUHJpY2UiCmFtQXNzZXREY20iCnByQXNzZXREY20iBWFtQW10IgVwckFtdCIOYW10QXNzZXRBbXRYMTgiEHByaWNlQXNzZXRBbXRYMTgiCmNhbGNQcmljZXMiBWxwQW10IgNjZmciC2FtdEFzc2V0RGNtIg1wcmljZUFzc2V0RGNtIghwcmljZVgxOCIIbHBBbXRYMTgiE2xwUHJpY2VJbkFtQXNzZXRYMTgiE2xwUHJpY2VJblByQXNzZXRYMTgiD2NhbGN1bGF0ZVByaWNlcyIGcHJpY2VzIhRlc3RpbWF0ZUdldE9wZXJhdGlvbiIGdHhJZDU4IgpwbXRBc3NldElkIghwbXRMcEFtdCIJbHBBc3NldElkIglhbUFzc2V0SWQiCXByQXNzZXRJZCIKcG9vbFN0YXR1cyIKbHBFbWlzc2lvbiIJYW1CYWxhbmNlIgxhbUJhbGFuY2VYMTgiCXByQmFsYW5jZSIMcHJCYWxhbmNlWDE4IgtjdXJQcmljZVgxOCIIY3VyUHJpY2UiC3BtdExwQW10WDE4Ig1scEVtaXNzaW9uWDE4IgtvdXRBbUFtdFgxOCILb3V0UHJBbXRYMTgiCG91dEFtQW10IghvdXRQckFtdCIFc3RhdGUiFGVzdGltYXRlUHV0T3BlcmF0aW9uIhFzbGlwcGFnZVRvbGVyYW5jZSIMaW5BbUFzc2V0QW10IgtpbkFtQXNzZXRJZCIMaW5QckFzc2V0QW10IgtpblByQXNzZXRJZCIKaXNFdmFsdWF0ZSIGZW1pdExwIgxhbUFzc2V0SWRTdHIiDHByQXNzZXRJZFN0ciILaUFtdEFzc2V0SWQiDWlQcmljZUFzc2V0SWQiDmluQW1Bc3NldElkU3RyIg5pblByQXNzZXRJZFN0ciIPaW5BbUFzc2V0QW10WDE4Ig9pblByQXNzZXRBbXRYMTgiDHVzZXJQcmljZVgxOCIDcmVzIgtzbGlwcGFnZVgxOCIUc2xpcHBhZ2VUb2xlcmFuY2VYMTgiCnByVmlhQW1YMTgiCmFtVmlhUHJYMTgiDGV4cGVjdGVkQW10cyIRZXhwQW10QXNzZXRBbXRYMTgiE2V4cFByaWNlQXNzZXRBbXRYMTgiCWNhbGNMcEFtdCIOY2FsY0FtQXNzZXRQbXQiDmNhbGNQckFzc2V0UG10IgxzbGlwcGFnZUNhbGMiCWVtaXRMcEFtdCIGYW1EaWZmIgZwckRpZmYiC2NvbW1vblN0YXRlIgdjYWxjS0xwIg1hbW91bnRCYWxhbmNlIgxwcmljZUJhbGFuY2UiEGFtb3VudEJhbGFuY2VYMTgiD3ByaWNlQmFsYW5jZVgxOCIKdXBkYXRlZEtMcCIOY2FsY0N1cnJlbnRLTHAiEGFtb3VudEFzc2V0RGVsdGEiD3ByaWNlQXNzZXREZWx0YSIUbHBBc3NldEVtaXNzaW9uRGVsdGEiEmFtb3VudEFzc2V0QmFsYW5jZSIRcHJpY2VBc3NldEJhbGFuY2UiD2xwQXNzZXRFbWlzc2lvbiIKY3VycmVudEtMcCIScmVmcmVzaEtMcEludGVybmFsIhdhbW91bnRBc3NldEJhbGFuY2VEZWx0YSIWcHJpY2VBc3NldEJhbGFuY2VEZWx0YSIHYWN0aW9ucyISdmFsaWRhdGVVcGRhdGVkS0xwIgZvbGRLTHAiG3ZhbGlkYXRlTWF0Y2hlck9yZGVyQWxsb3dlZCIFb3JkZXIiEWFtb3VudEFzc2V0QW1vdW50IhBwcmljZUFzc2V0QW1vdW50Ig0kdDAyMTU0MTIxNzUzIgNrTHAiDSR0MDIyMTkzMjIyOTMiDXVudXNlZEFjdGlvbnMiBmtMcE5ldyIMaXNPcmRlclZhbGlkIgRpbmZvIgljb21tb25HZXQiAWkiA3BtdCIGcG10QW10Igljb21tb25QdXQiCmFtQXNzZXRQbXQiCnByQXNzZXRQbXQiBmVzdFB1dCIEZW1pdCIGYW1vdW50IgdlbWl0SW52Ig1lbWl0SW52TGVnYWN5IgckbWF0Y2gwIhVsZWdhY3lGYWN0b3J5Q29udHJhY3QiB3Rha2VGZWUiCWZlZUFtb3VudCIPY2FsY1B1dE9uZVRva2VuIhBwYXltZW50QW1vdW50UmF3Ig5wYXltZW50QXNzZXRJZCIGaXNFdmFsIhBhbW91bnRCYWxhbmNlUmF3Ig9wcmljZUJhbGFuY2VSYXciFHBheW1lbnRJbkFtb3VudEFzc2V0Ig0kdDAyNTQwNjI1Njk5IhBhbW91bnRCYWxhbmNlT2xkIg9wcmljZUJhbGFuY2VPbGQiDSR0MDI1NzAzMjU4NTIiFGFtb3VudEFzc2V0QW1vdW50UmF3IhNwcmljZUFzc2V0QW1vdW50UmF3Ig0kdDAyNTk4NDI2MDQ4Ig1wYXltZW50QW1vdW50IhBhbW91bnRCYWxhbmNlTmV3Ig9wcmljZUJhbGFuY2VOZXciC3ByaWNlTmV3WDE4IghwcmljZU5ldyIOcGF5bWVudEJhbGFuY2UiFHBheW1lbnRCYWxhbmNlQmlnSW50IgxzdXBwbHlCaWdJbnQiC2NoZWNoU3VwcGx5Ig1kZXBvc2l0QmlnSW50Igtpc3N1ZUFtb3VudCILcHJpY2VPbGRYMTgiCHByaWNlT2xkIgRsb3NzIg0kdDAyNzcyOTI3ODk2IgdiYWxhbmNlIg9pc3N1ZUFtb3VudEJvdGgiD2NhbGNHZXRPbmVUb2tlbiIKb3V0QXNzZXRJZCIGY2hlY2tzIhBvdXRJbkFtb3VudEFzc2V0Ig1iYWxhbmNlQmlnSW50IhhvdXRJbkFtb3VudEFzc2V0RGVjaW1hbHMiDGFtQmFsYW5jZU9sZCIMcHJCYWxhbmNlT2xkIgpvdXRCYWxhbmNlIhBvdXRCYWxhbmNlQmlnSW50Ig5yZWRlZW1lZEJpZ0ludCIJYW1vdW50UmF3Ig0kdDAyOTk3NDMwMDMwIgt0b3RhbEFtb3VudCINJHQwMzAwMzQzMDI2MCILb3V0QW1BbW91bnQiC291dFByQW1vdW50IgxhbUJhbGFuY2VOZXciDHByQmFsYW5jZU5ldyIYYW1vdW50Qm90aEluUGF5bWVudEFzc2V0IhZtYW5hZ2VyUHVibGljS2V5T3JVbml0IgFzIh1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdCIJaXNNYW5hZ2VyIgJwayILbXVzdE1hbmFnZXIiAnBkIg1jbGVhbkFtb3VudEluIglpc1JldmVyc2UiDSR0MDMxOTU1MzIyNjAiCGFzc2V0T3V0Igdhc3NldEluIhJwb29sQXNzZXRJbkJhbGFuY2UiE3Bvb2xBc3NldE91dEJhbGFuY2UiCWFtb3VudE91dCIEb2xkSyIEbmV3SyIGY2hlY2tLIgxhbW91bnRPdXRNaW4iCWFkZHJlc3NUbyILc3dhcENvbnRhY3QiCGNoZWNrTWluIhdwZW5kaW5nTWFuYWdlclB1YmxpY0tleSILY2hlY2tDYWxsZXIiFWNoZWNrTWFuYWdlclB1YmxpY0tleSICcG0iBWhhc1BNIgdjaGVja1BNIg9zaG91bGRBdXRvU3Rha2UiBGFtSWQiBHBySWQiDHNsaXBwYWdlQUludiIMc2xpcHBhZ2VQSW52IgpscFRyYW5zZmVyIgtzbHBTdGFrZUludiINJHQwMzcxNDUzNzYwNyIRcmVmcmVzaEtMcEFjdGlvbnMiEWlzVXBkYXRlZEtMcFZhbGlkIgttYXhTbGlwcGFnZSINJHQwMzgxNjkzODIzNCIMbWluT3V0QW1vdW50IglhdXRvU3Rha2UiIGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkIg1pc1B1dERpc2FibGVkIgdwYXltZW50Ig0kdDAzOTQyMjM5NTc0IgVib251cyITZW1pdEFtb3VudEVzdGltYXRlZCIKZW1pdEFtb3VudCIIc3Rha2VJbnYiB3NlbmRGZWUiDSR0MDQwMTYwNDAzNTciDSR0MDQwMzYwNDA0NjgiDSR0MDQwNzc0NDA5MzEiDW91dEFzc2V0SWRTdHIiDWlzR2V0RGlzYWJsZWQiDSR0MDQxODE2NDE5NjkiD2Ftb3VudEVzdGltYXRlZCIHYnVybkludiINYXNzZXRUcmFuc2ZlciINJHQwNDI0Njk0MjcxNiIQZmVlQW1vdW50Rm9yQ2FsYyINJHQwNDI3MTk0MjgyNyINJHQwNDMwODQ0MzI0MCINdW5zdGFrZUFtb3VudCIKdW5zdGFrZUludiINJHQwNDQxNDU0NDI5NiINJHQwNDQ3OTE0NTAzOCINJHQwNDUwNDE0NTE0OSIJb3V0QW10QW10IhRidXJuTFBBc3NldE9uRmFjdG9yeSINJHQwNDYwOTU0NjE3NyISbm9MZXNzVGhlbkFtdEFzc2V0IhRub0xlc3NUaGVuUHJpY2VBc3NldCINJHQwNDcxMjY0NzIwNyINY2hlY2tQYXltZW50cyIPY2hlY2tQb29sU3RhdHVzIg0kdDA0ODMzMzQ4NDE0IhVub0xlc3NUaGVuQW1vdW50QXNzZXQiDGNoZWNrQW1vdW50cyINJHQwNDk3MDk0OTc5MCILYW10QXNzZXRTdHIiDXByaWNlQXNzZXRTdHIiGGxhc3RSZWZyZXNoZWRCbG9ja0hlaWdodCIdY2hlY2tMYXN0UmVmcmVzaGVkQmxvY2tIZWlnaHQiDSR0MDUwOTc3NTEwNDEiEGtMcFVwZGF0ZUFjdGlvbnMiCmFtdEFzc2V0SWQiDHByaWNlQXNzZXRJZCINcG9vbExQQmFsYW5jZSISYWNjQW10QXNzZXRCYWxhbmNlIhRhY2NQcmljZUFzc2V0QmFsYW5jZSIKcHJpY2VzTGlzdCIPbHBBbXRBc3NldFNoYXJlIhFscFByaWNlQXNzZXRTaGFyZSIKcG9vbFdlaWdodCIMY3VyUHJpY2VDYWxjIgxhbUJhbGFuY2VSYXciDHByQmFsYW5jZVJhdyIPYW1CYWxhbmNlUmF3WDE4Ig9wckJhbGFuY2VSYXdYMTgiEHBheW1lbnRMcEFzc2V0SWQiDHBheW1lbnRMcEFtdCICdHgiBnZlcmlmeSIPdGFyZ2V0UHVibGljS2V5IgptYXRjaGVyUHViIg0kdDA1OTcwMzU5NzcyIgduZXdIYXNoIgthbGxvd2VkSGFzaCILY3VycmVudEhhc2hzAAFhAAgAAWIAgMLXLwABYwkAtgIBAIDC1y8AAWQJALYCAQCAgJC7utat8A0AAWUJALYCAQAAAAFmCQC2AgEAAAABZwkAtgIBAAEAAWgJALYCAQACAAFpAgVXQVZFUwABagICX18AAWsAAQABbAACAAFtAAMAAW4ABAABbwABAAFwAAIAAXEAAwABcgAEAAFzAAUAAXQABgABdQAHAAF2AAgAAXcACQABeAAKAAF5AAEAAXoAAgABQQADAAFCAAEAAUMABwEBRAIBRQFGCQC8AgMJALYCAQUBRQUBZAkAtgIBBQFGAQFHAgFFAUYJALwCAwUBRQUBZAUBRgEBSAIBSQFKCQCgAwEJALwCAwUBSQkAtgIBBQFKBQFkAQFLAwFJAUoBTAkAoAMBCQC9AgQFAUkJALYCAQUBSgUBZAUBTAEBTQMBTgFPAVAJAGsDBQFOBQFPBQFQAQFRAQFJAwkAZgIAAAUBSQkBAS0BBQFJBQFJAQFSAQFJAwkAvwICBQFlBQFJCQC+AgEFAUkFAUkBAVMAAhAlc19fc3dhcENvbnRyYWN0AQFUAAITJXNfX2ZhY3RvcnlDb250cmFjdAEBVQACFCVzX19tYW5hZ2VyUHVibGljS2V5AQFWAAIbJXNfX3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AQFXAAIRJXMlc19fcHJpY2VfX2xhc3QBAVgCAVkBWgkAuQkCCQDMCAICGCVzJXMlZCVkX19wcmljZV9faGlzdG9yeQkAzAgCCQCkAwEFAVkJAMwIAgkApAMBBQFaBQNuaWwFAWoBAmFhAgJhYgJhYwkArAICCQCsAgIJAKwCAgILJXMlcyVzX19QX18FAmFiAgJfXwUCYWMBAmFkAgJhYgJhYwkArAICCQCsAgIJAKwCAgILJXMlcyVzX19HX18FAmFiAgJfXwUCYWMBAmFlAAIPJXNfX2Ftb3VudEFzc2V0AQJhZgACDiVzX19wcmljZUFzc2V0AAJhZwIHJXNfX2ZlZQACYWgJAGsDAAoFAWIAkE4AAmFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAmFnBQJhaAACYWoJALkJAgkAzAgCAgIlcwkAzAgCAgNrTHAFA25pbAUBagACYWsJALkJAgkAzAgCAgIlcwkAzAgCAhJrTHBSZWZyZXNoZWRIZWlnaHQFA25pbAUBagACYWwJALkJAgkAzAgCAgIlcwkAzAgCAg9yZWZyZXNoS0xwRGVsYXkFA25pbAUBagACYW0AHgACYW4JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUCYWwFAmFtAQJhbwACESVzX19mYWN0b3J5Q29uZmlnAQJhcAACGCVzJXNfX21hdGNoZXJfX3B1YmxpY0tleQECYXEBAmFyCQCsAgIJAKwCAgIIJXMlcyVzX18FAmFyAiBfX21hcHBpbmdzX19wb29sQ29udHJhY3QyTHBBc3NldAECYXMCAmF0AmF1CQCsAgIJAKwCAgkArAICCQCsAgICCCVkJWQlc19fBQJhdAICX18FAmF1AghfX2NvbmZpZwECYXYBAmF3CQCsAgICKCVzJXMlc19fbWFwcGluZ3NfX2Jhc2VBc3NldDJpbnRlcm5hbElkX18FAmF3AQJheAACDCVzX19zaHV0ZG93bgECYXkBAmF6CQCsAgICEiVzJXNfX3Bvb2xXZWlnaHRfXwUCYXoBAmFBAAIXJXNfX2FsbG93ZWRMcFNjcmlwdEhhc2gAAmFCAhclc19fZmVlQ29sbGVjdG9yQWRkcmVzcwECYUMEAmFEAmFFAmFGAmFHCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICJG9yZGVyIHZhbGlkYXRpb24gZmFpbGVkOiBvcmRlclZhbGlkPQkApQMBBQJhRAICICgFAmFFAgEpAg0gc2VuZGVyVmFsaWQ9CQClAwEFAmFGAg4gbWF0Y2hlclZhbGlkPQkApQMBBQJhRwECYUgCAmFJAmFKCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUCYUkFAmFKCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmFJCQDMCAICAS4JAMwIAgUCYUoJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAECYUsCAmFJAmFKCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUCYUkFAmFKCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmFJCQDMCAICAS4JAMwIAgUCYUoJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAECYUwBAmFNCQACAQkAuQkCCQDMCAICCGxwLnJpZGU6CQDMCAIFAmFNBQNuaWwCASABAmFOAQJhTQkAuQkCCQDMCAICCGxwLnJpZGU6CQDMCAIFAmFNBQNuaWwCASAAAmFPCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYUgCBQR0aGlzCQEBVAAAAmFQCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYUgCBQJhTwUCYUIAAmFRCgACYVIJAPwHBAUCYU8CEGdldEluRmVlUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJhUgIDSW50BQJhUgkAAgEJAKwCAgkAAwEFAmFSAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQAAmFTCgACYVIJAPwHBAUCYU8CEWdldE91dEZlZVJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYVICA0ludAUCYVIJAAIBCQCsAgIJAAMBBQJhUgIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AQJhVAAJAQt2YWx1ZU9yRWxzZQIJAJsIAgUCYU8JAQJheAAHAQJhVQAJANkEAQkBAmFIAgUCYU8JAQJhcAABAmFWAAQCYVcJAQJhSAIFBHRoaXMJAQJhZQAEAmFYCQECYUgCBQR0aGlzCQECYWYABAJhdQkBAmFLAgUCYU8JAQJhdgEFAmFYBAJhdAkBAmFLAgUCYU8JAQJhdgEFAmFXCQC1CQIJAQJhSAIFAmFPCQECYXMCCQCkAwEFAmF0CQCkAwEFAmF1BQFqAQJhWQECYVoDCQAAAgUCYVoFAWkFBHVuaXQJANkEAQUCYVoBAmJhAQJhWgMJAAACBQJhWgUEdW5pdAUBaQkA2AQBCQEFdmFsdWUBBQJhWgECYmIBAmJjCQCZCgcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYmMFAW8JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiYwUBcAkA2QQBCQCRAwIFAmJjBQFxCQECYVkBCQCRAwIFAmJjBQFyCQECYVkBCQCRAwIFAmJjBQFzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYmMFAXQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiYwUBdQACYmQJAQJiYgEJAQJhVgAAAmJlBQJiZAACYmYIBQJiZQJfMQACYmcIBQJiZQJfMgACYmgIBQJiZQJfMwACYmkIBQJiZQJfNAACYmoIBQJiZQJfNQACYmsIBQJiZQJfNgACYmwIBQJiZQJfNwECYm0ACQC1CQIJAQJhSAIFAmFPCQECYW8ABQFqAAJibgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgkBAmJtAAUBQgIZaW5jb3JyZWN0IHN0YWtpbmcgYWRkcmVzcwACYm8JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIJAQJibQAFAUMCGWluY29ycmVjdCBzdGFraW5nIGFkZHJlc3MBAmJwCgJicQJicgJicwJidAJidQJidgJidwJieAJieQJiegkAuQkCCQDMCAICFCVkJWQlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYnEJAMwIAgkApAMBBQJicgkAzAgCCQCkAwEFAmJzCQDMCAIJAKQDAQUCYnQJAMwIAgkApAMBBQJidQkAzAgCCQCkAwEFAmJ2CQDMCAIJAKQDAQUCYncJAMwIAgkApAMBBQJieAkAzAgCCQCkAwEFAmJ5CQDMCAIJAKQDAQUCYnoFA25pbAUBagECYkEGAmJCAmJDAmJEAmJ0AmJ3AmJ4CQC5CQIJAMwIAgIMJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYkIJAMwIAgkApAMBBQJiQwkAzAgCCQCkAwEFAmJECQDMCAIJAKQDAQUCYnQJAMwIAgkApAMBBQJidwkAzAgCCQCkAwEFAmJ4BQNuaWwFAWoBAmJFAQJiRgMJAAACBQJiRgIFV0FWRVMICQDvBwEFBHRoaXMJYXZhaWxhYmxlCQDwBwIFBHRoaXMJANkEAQUCYkYBAmJHAgJiSAJiSQkAvAIDBQJiSAUBZAUCYkkBAmJKAwJiSAJiSQFMCQC9AgQFAmJIBQFkBQJiSQUBTAECYksEAmJMAmJNAmJOAmJPBAJiUAkBAUQCBQJiTgUCYkwEAmJRCQEBRAIFAmJPBQJiTQkBAmJHAgUCYlEFAmJQAQJiUgMCYk4CYk8CYlMEAmJUCQECYVYABAJiVQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJUBQF0BAJiVgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJUBQF1BAJiVwkBAmJLBAUCYlUFAmJWBQJiTgUCYk8EAmJJCQEBRAIFAmJOBQJiVQQCYkgJAQFEAgUCYk8FAmJWBAJiWAkBAUQCBQJiUwUBYgQCYlkJAQJiRwIFAmJJBQJiWAQCYloJAQJiRwIFAmJIBQJiWAkAzAgCBQJiVwkAzAgCBQJiWQkAzAgCBQJiWgUDbmlsAQJjYQMCYk4CYk8CYlMEAmNiCQECYlIDBQJiTgUCYk8FAmJTCQDMCAIJAQFIAgkAkQMCBQJjYgAABQFiCQDMCAIJAQFIAgkAkQMCBQJjYgABBQFiCQDMCAIJAQFIAgkAkQMCBQJjYgACBQFiBQNuaWwBAmNjBAJjZAJjZQJjZgJhYgQCYlQJAQJhVgAEAmNnCQCRAwIFAmJUBQFxBAJjaAkAkQMCBQJiVAUBcgQCY2kJAJEDAgUCYlQFAXMEAmJMCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlQFAXQEAmJNCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlQFAXUEAmNqCQCRAwIFAmJUBQFwBAJjawgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFAmNnCQCsAgIJAKwCAgIGQXNzZXQgBQJjZwIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkDCQECIT0CBQJjZwUCY2UJAAIBAhVJbnZhbGlkIGFzc2V0IHBhc3NlZC4EAmNsCQECYkUBBQJjaAQCY20JAQFEAgUCY2wFAmJMBAJjbgkBAmJFAQUCY2kEAmNvCQEBRAIFAmNuBQJiTQQCY3AJAQJiRwIFAmNvBQJjbQQCY3EJAQFIAgUCY3AFAWIEAmNyCQEBRAIFAmNmBQFiBAJjcwkBAUQCBQJjawUBYgQCY3QJALwCAwUCY20FAmNyBQJjcwQCY3UJALwCAwUCY28FAmNyBQJjcwQCY3YJAQFLAwUCY3QFAmJMBQVGTE9PUgQCY3cJAQFLAwUCY3UFAmJNBQVGTE9PUgQCY3gDCQAAAgUCY2QCAAUDbmlsCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFiBQJjdgMJAAACBQJjaAIFV0FWRVMFBHVuaXQJANkEAQUCY2gJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYWIFAmN3AwkAAAIFAmNpAgVXQVZFUwUEdW5pdAkA2QQBBQJjaQkAzAgCCQELU3RyaW5nRW50cnkCCQECYWQCCQClCAEFAmFiBQJjZAkBAmJBBgUCY3YFAmN3BQJjZgUCY3EFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCY3EJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCY3EFA25pbAkAnAoKBQJjdgUCY3cFAmNoBQJjaQUCY2wFAmNuBQJjawUCY3AFAmNqBQJjeAECY3kJAmNkAmN6AmNBAmNCAmNDAmNEAmFiAmNFAmNGBAJiVAkBAmFWAAQCY2cJANkEAQkAkQMCBQJiVAUBcQQCY0cJAJEDAgUCYlQFAXIEAmNICQCRAwIFAmJUBQFzBAJjSQkAkQMCBQJiVAUBdgQCY0oJAJEDAgUCYlQFAXcEAmJVCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlQFAXQEAmJWCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlQFAXUEAmNqCQCRAwIFAmJUBQFwBAJjawgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJjZwkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJjZwIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmNLCQDYBAEJAQt2YWx1ZU9yRWxzZQIFAmNCCQDZBAECBVdBVkVTBAJjTAkA2AQBCQELdmFsdWVPckVsc2UCBQJjRAkA2QQBAgVXQVZFUwMDCQECIT0CBQJjRwUCY0sGCQECIT0CBQJjSAUCY0wJAAIBAiJJbnZhbGlkIGFtdCBvciBwcmljZSBhc3NldCBwYXNzZWQuBAJjbAMFAmNFCQECYkUBBQJjRwkAZQIJAQJiRQEFAmNHBQJjQQQCY24DBQJjRQkBAmJFAQUCY0gJAGUCCQECYkUBBQJjSAUCY0MEAmNNCQEBRAIFAmNBBQJiVQQCY04JAQFEAgUCY0MFAmJWBAJjTwkBAmJHAgUCY04FAmNNBAJjbQkBAUQCBQJjbAUCYlUEAmNvCQEBRAIFAmNuBQJiVgQCY1ADCQAAAgUCY2sAAAQCY3AFAWUEAmNRBQFlBAJiWAkAdgYJALkCAgUCY00FAmNOAAAJALYCAQAFAAEAAAUERE9XTgkAlwoFCQEBSAIFAmJYBQFiCQEBSAIFAmNNBQJiVQkBAUgCBQJjTgUCYlYJAQJiRwIJALcCAgUCY28FAmNOCQC3AgIFAmNtBQJjTQUCY1EEAmNwCQECYkcCBQJjbwUCY20EAmNRCQC8AgMJAQFSAQkAuAICBQJjcAUCY08FAWQFAmNwBAJjUgkBAUQCBQJjegUBYgMDCQECIT0CBQJjcAUBZQkAvwICBQJjUQUCY1IHCQACAQkArAICCQCsAgIJAKwCAgIPUHJpY2Ugc2xpcHBhZ2UgCQCmAwEFAmNRAh4gZXhjZWVkZWQgdGhlIHBhc3NlZCBsaW1pdCBvZiAJAKYDAQUCY1IEAmNzCQEBRAIFAmNrBQFiBAJjUwkAvQIEBQJjTQkBAmJKAwUCY28FAmNtBQdDRUlMSU5HBQFkBQdDRUlMSU5HBAJjVAkAvQIEBQJjTgUBZAkBAmJKAwUCY28FAmNtBQVGTE9PUgUHQ0VJTElORwQCY1UDCQC/AgIFAmNTBQJjTgkAlAoCBQJjVAUCY04JAJQKAgUCY00FAmNTBAJjVggFAmNVAl8xBAJjVwgFAmNVAl8yBAJiWAkAvQIEBQJjcwUCY1cFAmNvBQVGTE9PUgkAlwoFCQEBSwMFAmJYBQFiBQVGTE9PUgkBAUsDBQJjVgUCYlUFB0NFSUxJTkcJAQFLAwUCY1cFAmJWBQdDRUlMSU5HBQJjcAUCY1EEAmNYCAUCY1ACXzEEAmNZCAUCY1ACXzIEAmNaCAUCY1ACXzMEAmNxCQEBSAIIBQJjUAJfNAUBYgQCZGEJAQFIAggFAmNQAl81BQFiAwkAZwIAAAUCY1gJAAIBAjZJbnZhbGlkIGNhbGN1bGF0aW9ucy4gTFAgY2FsY3VsYXRlZCBpcyBsZXNzIHRoYW4gemVyby4EAmRiAwkBASEBBQJjRgAABQJjWAQCZGMJAGUCBQJjQQUCY1kEAmRkCQBlAgUCY0MFAmNaBAJkZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVcABQJjcQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVgCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJjcQkAzAgCCQELU3RyaW5nRW50cnkCCQECYWECBQJhYgUCY2QJAQJicAoFAmNZBQJjWgUCZGIFAmNxBQJjegUCZGEFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmRjBQJkZAUDbmlsCQCfCg0FAmNYBQJkYgUCY3EFAmNsBQJjbgUCY2sFAmNnBQJjagUCZGUFAmRjBQJkZAUCY0IFAmNEAQJkZgMCZGcCZGgCY2sEAmRpCQEBRwIFAmRnCQC2AgEFAmJrBAJkagkBAUcCBQJkaAkAtgIBBQJibAQCZGsJALwCAwkAdgYJALkCAgUCZGkFAmRqAAAJALYCAQAFAAEAEgUERE9XTgUBZwUCY2sDCQAAAgUCY2sFAWYFAWYFAmRrAQJkbAMCZG0CZG4CZG8EAmRwCQC4AgIJALYCAQkBAmJFAQkBAmJhAQUCYmkFAmRtBAJkcQkAuAICCQC2AgEJAQJiRQEJAQJiYQEFAmJqBQJkbgQCZHIJALgCAgkAtgIBCAkBBXZhbHVlAQkA7AcBBQJiaAhxdWFudGl0eQUCZG8EAmRzCQECZGYDBQJkcAUCZHEFAmRyBQJkcwECZHQDAmR1AmR2AmRvBAJkcAkAZAIJAQJiRQEJAQJiYQEFAmJpBQJkdQQCZHEJAGQCCQECYkUBCQECYmEBBQJiagUCZHYEAmRyCQBkAggJAQV2YWx1ZQEJAOwHAQUCYmgIcXVhbnRpdHkFAmRvBAJkawkBAmRmAwkAtgIBBQJkcAkAtgIBBQJkcQkAtgIBBQJkcgQCZHcJAMwIAgkBDEludGVnZXJFbnRyeQIFAmFrBQZoZWlnaHQJAMwIAgkBC1N0cmluZ0VudHJ5AgUCYWoJAKYDAQUCZGsFA25pbAkAlAoCBQJkdwUCZGsBAmR4AgJkeQJkawMJAMACAgUCZGsFAmR5BgkBAmFMAQkAuQkCCQDMCAICInVwZGF0ZWQgS0xwIGxvd2VyIHRoYW4gY3VycmVudCBLTHAJAMwIAgkApgMBBQJkeQkAzAgCCQCmAwEFAmRrBQNuaWwCASABAmR6AQJkQQQCZHAJAQJiRQEJAQJiYQEFAmJpBAJkcQkBAmJFAQkBAmJhAQUCYmoEAmRCCAUCZEEGYW1vdW50BAJkQwkAbgQIBQJkQQZhbW91bnQIBQJkQQVwcmljZQUBYgUFRkxPT1IEAmREAwkAAAIIBQJkQQlvcmRlclR5cGUFA0J1eQkAlAoCBQJkQgkBAS0BBQJkQwkAlAoCCQEBLQEFAmRCBQJkQwQCZHUIBQJkRAJfMQQCZHYIBQJkRAJfMgMDAwkBAmFUAAYJAAACBQJiZwUBbQYJAAACBQJiZwUBbgkAAgECHEV4Y2hhbmdlIG9wZXJhdGlvbnMgZGlzYWJsZWQDAwkBAiE9AggIBQJkQQlhc3NldFBhaXILYW1vdW50QXNzZXQFAmJpBgkBAiE9AggIBQJkQQlhc3NldFBhaXIKcHJpY2VBc3NldAUCYmoJAAIBAhNXcm9uZyBvcmRlciBhc3NldHMuBAJkRQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCoAwEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUCYWoCATAJAQJhTgECC2ludmFsaWQga0xwBAJkRgkBAmR0AwUCZHUFAmR2AAAEAmRHCAUCZEYCXzEEAmRICAUCZEYCXzIEAmRJCQDAAgIFAmRIBQJkRQQCZEoJALkJAgkAzAgCAgRrTHA9CQDMCAIJAKYDAQUCZEUJAMwIAgIIIGtMcE5ldz0JAMwIAgkApgMBBQJkSAkAzAgCAhQgYW1vdW50QXNzZXRCYWxhbmNlPQkAzAgCCQCkAwEFAmRwCQDMCAICEyBwcmljZUFzc2V0QmFsYW5jZT0JAMwIAgkApAMBBQJkcQkAzAgCAhkgYW1vdW50QXNzZXRCYWxhbmNlRGVsdGE9CQDMCAIJAKQDAQUCZHUJAMwIAgIYIHByaWNlQXNzZXRCYWxhbmNlRGVsdGE9CQDMCAIJAKQDAQUCZHYJAMwIAgIIIGhlaWdodD0JAMwIAgkApAMBBQZoZWlnaHQFA25pbAIACQCUCgIFAmRJBQJkSgECZEsBAmRMAwkBAiE9AgkAkAMBCAUCZEwIcGF5bWVudHMAAQkAAgECHWV4YWN0bHkgMSBwYXltZW50IGlzIGV4cGVjdGVkBAJkTQkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAAQCY2UJAQV2YWx1ZQEIBQJkTQdhc3NldElkBAJkTggFAmRNBmFtb3VudAQCY1AJAQJjYwQJANgEAQgFAmRMDXRyYW5zYWN0aW9uSWQJANgEAQUCY2UFAmROCAUCZEwGY2FsbGVyBAJjdggFAmNQAl8xBAJjdwgFAmNQAl8yBAJjagkBDXBhcnNlSW50VmFsdWUBCAUCY1ACXzkEAmN4CAUCY1ADXzEwAwMJAQJhVAAGCQAAAgUCY2oFAW4JAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmNqCQCXCgUFAmN2BQJjdwUCZE4FAmNlBQJjeAECZE8DAmRMAmN6AmNGAwkBAiE9AgkAkAMBCAUCZEwIcGF5bWVudHMAAgkAAgECH2V4YWN0bHkgMiBwYXltZW50cyBhcmUgZXhwZWN0ZWQEAmRQCQEFdmFsdWUBCQCRAwIIBQJkTAhwYXltZW50cwAABAJkUQkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAQQCZFIJAQJjeQkJANgEAQgFAmRMDXRyYW5zYWN0aW9uSWQFAmN6CAUCZFAGYW1vdW50CAUCZFAHYXNzZXRJZAgFAmRRBmFtb3VudAgFAmRRB2Fzc2V0SWQJAKUIAQgFAmRMBmNhbGxlcgcFAmNGBAJjagkBDXBhcnNlSW50VmFsdWUBCAUCZFICXzgDAwMJAQJhVAAGCQAAAgUCY2oFAWwGCQAAAgUCY2oFAW4JAAIBCQCsAgICLFB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmNqBQJkUgECZFMBAmRUBAJkVQkA/AcEBQJhTwIEZW1pdAkAzAgCBQJkVAUDbmlsBQNuaWwDCQAAAgUCZFUFAmRVBAJkVgQCZFcFAmRVAwkAAQIFAmRXAgdBZGRyZXNzBAJkWAUCZFcJAPwHBAUCZFgCBGVtaXQJAMwIAgUCZFQFA25pbAUDbmlsBQR1bml0AwkAAAIFAmRWBQJkVgUCZFQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmRZAgJkVAJhaQQCZFoDCQAAAgUCYWkAAAAACQBrAwUCZFQFAmFpBQFiCQCUCgIJAGUCBQJkVAUCZFoFAmRaAQJlYQQCZWICZWMCYWICYWMEAmVkCQAAAgUCYWMFBHVuaXQEAmVlCQECYkUBCQECYmEBBQJiaQQCZWYJAQJiRQEJAQJiYQEFAmJqBAJlZwMJAAACBQJlYwUCYmkGAwkAAAIFAmVjBQJiagcJAQJhTAECDWludmFsaWQgYXNzZXQEAmVoAwUCZWQJAJQKAgUCZWUFAmVmAwUCZWcJAJQKAgkAZQIFAmVlBQJlYgUCZWYJAJQKAgUCZWUJAGUCBQJlZgUCZWIEAmVpCAUCZWgCXzEEAmVqCAUCZWgCXzIEAmVrAwUCZWcJAJQKAgUCZWIAAAkAlAoCAAAFAmViBAJlbAgFAmVrAl8xBAJlbQgFAmVrAl8yBAJkQggJAQJkWQIFAmVsBQJhUQJfMQQCZEMICQECZFkCBQJlbQUCYVECXzEEAmVuCQECZFkCBQJlYgUCYVEEAmVvCAUCZW4CXzEEAmRaCAUCZW4CXzIEAmVwCQBkAgUCZWkFAmRCBAJlcQkAZAIFAmVqBQJkQwQCZXIJAQJiRwIJAQFEAgUCZXEFAmJsCQEBRAIFAmVwBQJiawQCZXMJAQFIAgUCZXIFAWIEAmV0AwUCZWcFAmVpBQJlagQCZXUJALYCAQUCZXQEAmV2CQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYmgJAKwCAgkArAICAgZhc3NldCAJANgEAQUCYmgCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJldwMJAL8CAgUCZXYFAWYGCQECYUwBAiJpbml0aWFsIGRlcG9zaXQgcmVxdWlyZXMgYWxsIGNvaW5zAwkAAAIFAmV3BQJldwQCZXgJALYCAQUCZW8EAmV5CQCWAwEJAMwIAgAACQDMCAIJAKADAQkAugICCQC5AgIFAmV2CQC4AgIJAQpzcXJ0QmlnSW50BAkAtwICBQFkCQC6AgIJALkCAgUCZXgFAWQFAmV1ABIAEgUERE9XTgUBZAUBZAUDbmlsBAJkZQMFAmVkBQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZXMJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZXMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFhAgkApQgBCQEFdmFsdWUBBQJhYgkA2AQBCQEFdmFsdWUBBQJhYwkBAmJwCgUCZWwFAmVtBQJleQUCZXMAAAAABQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wAAAAAAUDbmlsBAJlegkBAmJHAgkBAUQCBQJlagUCYmwJAQFEAgUCZWkFAmJrBAJlQQkBAUgCBQJlegUBYgQCZUIEAmVDAwUCZWcJAJQKAgUCZWwFAmVpCQCUCgIFAmVtBQJlagQCZFQIBQJlQwJfMQQCZUQIBQJlQwJfMgQCZUUJAKADAQkAvAIDBQJldgkAtgIBCQBpAgUCZFQAAgkAtgIBBQJlRAkAawMJAGUCBQJleQUCZUUFAWIFAmVFCQCXCgUFAmV5BQJkZQUCZFoFAmVCBQJlZwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZUYFAmVHAmVvAmVjAmFiAmFjBAJlZAkAAAIFAmFjBQR1bml0BAJiVAkBAmFWAAQCYlUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiVAUBdAQCYlYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiVAUBdQQCZUgJAMwIAgMJAAACBQJlYwUCYmgGCQECYUwBAhBpbnZhbGlkIGxwIGFzc2V0BQNuaWwDCQAAAgUCZUgFAmVIBAJlSQMJAAACBQJlRwUCYmkGAwkAAAIFAmVHBQJiagcJAQJhTAECDWludmFsaWQgYXNzZXQEAmVKAwUCZUkJALYCAQkBAmJFAQkBAmJhAQUCYmkJALYCAQkBAmJFAQkBAmJhAQUCYmoEAmVLAwUCZUkFAmJVBQJiVgQCZUwJAQJiRQEJAQJiYQEFAmJpBAJlTQkBAmJFAQkBAmJhAQUCYmoEAmVOAwUCZUkFAmVMBQJlTQQCZU8JALYCAQUCZU4EAmV2CQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYmgJAKwCAgkArAICAgZhc3NldCAJANgEAQUCYmgCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJlUAkAtgIBBQJlbwQCZVEJAJYDAQkAzAgCAAAJAMwIAgkAoAMBCQC6AgIJALkCAgUCZUoJALgCAgUBZAkAdgYJALgCAgUBZAkAugICCQC5AgIFAmVQBQFkBQJldgASBQFoAAAAEgUERE9XTgUBZAUDbmlsBAJlUgkBAmRZAgUCZVEFAmFTBAJlUwgFAmVSAl8xBAJkWggFAmVSAl8yBAJlVAMFAmVJCQCWCgQFAmVTAAAJAGUCBQJlTAUCZVEFAmVNCQCWCgQAAAUCZVMFAmVMCQBlAgUCZU0FAmVRBAJlVQgFAmVUAl8xBAJlVggFAmVUAl8yBAJlVwgFAmVUAl8zBAJlWAgFAmVUAl80BAJlcgkBAmJHAgkBAUQCBQJlWAUCYmwJAQFEAgUCZVcFAmJrBAJlcwkBAUgCBQJlcgUBYgQCZGUDBQJlZAUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZAIJAKUIAQkBBXZhbHVlAQUCYWIJANgEAQkBBXZhbHVlAQUCYWMJAQJiQQYFAmVVBQJlVgUCZW8FAmVzBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVwAFAmVzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBWAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmVzBQNuaWwEAmV6CQECYkcCCQEBRAIFAmVNBQJibAkBAUQCBQJlTAUCYmsEAmVBCQEBSAIFAmV6BQFiBAJlQgQCZVkJAGgCCQCgAwEJALwCAwUCZUoFAmVQBQJldgACCQBrAwkAZQIFAmVTBQJlWQUBYgUCZVkJAJcKBQUCZVMFAmRlBQJkWgUCZUIFAmVJCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJlWgAEAmRXCQCiCAEJAQFVAAMJAAECBQJkVwIGU3RyaW5nBAJmYQUCZFcJANkEAQUCZmEDCQABAgUCZFcCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgECZmIABAJkVwkAoggBCQEBVgADCQABAgUCZFcCBlN0cmluZwQCZmEFAmRXCQDZBAEFAmZhAwkAAQIFAmRXAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmZjAQJkTAQCZFcJAQJlWgADCQABAgUCZFcCCkJ5dGVWZWN0b3IEAmZkBQJkVwkAAAIIBQJkTA9jYWxsZXJQdWJsaWNLZXkFAmZkAwkAAQIFAmRXAgRVbml0CQAAAggFAmRMBmNhbGxlcgUEdGhpcwkAAgECC01hdGNoIGVycm9yAQJmZQECZEwEAmZmCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEAmRXCQECZVoAAwkAAQIFAmRXAgpCeXRlVmVjdG9yBAJmZAUCZFcDCQAAAggFAmRMD2NhbGxlclB1YmxpY0tleQUCZmQGBQJmZgMJAAECBQJkVwIEVW5pdAMJAAACCAUCZEwGY2FsbGVyBQR0aGlzBgUCZmYJAAIBAgtNYXRjaCBlcnJvch0CZEwBIWNhbGN1bGF0ZUFtb3VudE91dEZvclN3YXBSRUFET05MWQICZmcCZmgEAmZpAwkAAAIFAmZoBwQCZmoJAQJhSAIFBHRoaXMJAQJhZgAEAmZrCQECYUgCBQR0aGlzCQECYWUACQCUCgIFAmZqBQJmawQCZmoJAQJhSAIFBHRoaXMJAQJhZQAEAmZrCQECYUgCBQR0aGlzCQECYWYACQCUCgIFAmZqBQJmawQCZmoIBQJmaQJfMQQCZmsIBQJmaQJfMgQCZmwJAQJiRQEFAmZrBAJmbQkBAmJFAQUCZmoEAmZuCQBrAwUCZm0FAmZnCQBkAgUCZmwFAmZnBAJmbwkAuQICCQC2AgEFAmZsCQC2AgEFAmZtBAJmcAkAuQICCQC3AgIJALYCAQkBAmJFAQUCZmsJALYCAQUCZmcJALgCAgkAtgIBCQECYkUBBQJmagkAtgIBBQJmbgQCZnEDCQDAAgIFAmZwBQJmbwYJAAIBAhRuZXcgSyBpcyBmZXdlciBlcnJvcgMJAAACBQJmcQUCZnEJAJQKAgUDbmlsBQJmbgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEmY2FsY3VsYXRlQW1vdW50T3V0Rm9yU3dhcEFuZFNlbmRUb2tlbnMEAmZnAmZoAmZyAmZzBAJmdAoAAmFSCQD8BwQFAmFPAhdnZXRTd2FwQ29udHJhY3RSRUFET05MWQUDbmlsBQNuaWwDCQABAgUCYVICBlN0cmluZwUCYVIJAAIBCQCsAgIJAAMBBQJhUgIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nBAJlSAkAzAgCAwkAZwIICQEFdmFsdWUBCQCRAwIIBQJkTAhwYXltZW50cwAABmFtb3VudAUCZmcGCQECYUwBAgxXcm9uZyBhbW91bnQJAMwIAgMJAAACCAUCZEwGY2FsbGVyCQERQGV4dHJOYXRpdmUoMTA2MikBBQJmdAYJAQJhTAECEVBlcm1pc3Npb24gZGVuaWVkBQNuaWwDCQAAAgUCZUgFAmVIBAJkTQkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAAQCZmsDCQAAAggFAmRNB2Fzc2V0SWQFBHVuaXQJANgEAQkAmwMBAgVXQVZFUwkA2AQBCQEFdmFsdWUBCAUCZE0HYXNzZXRJZAQCZmoDCQAAAgUCZmgHCQECYUgCBQR0aGlzCQECYWYACQECYUgCBQR0aGlzCQECYWUABAJmbAkAZQIJAQJiRQEFAmZrCAkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAAZhbW91bnQEAmZtCQECYkUBBQJmagQCZm4JAGsDBQJmbQUCZmcJAGQCBQJmbAUCZmcEAmZvCQC5AgIJALYCAQUCZmwJALYCAQUCZm0EAmZwCQC5AgIJALYCAQkBAmJFAQUCZmsJALgCAgkAtgIBCQECYkUBBQJmagkAtgIBBQJmbgQCZnEDCQDAAgIFAmZwBQJmbwYJAAIBAhRuZXcgSyBpcyBmZXdlciBlcnJvcgMJAAACBQJmcQUCZnEEAmZ1AwkAZwIFAmZuBQJmcgYJAAIBAixFeGNoYW5nZSByZXN1bHQgaXMgZmV3ZXIgY29pbnMgdGhhbiBleHBlY3RlZAMJAAACBQJmdQUCZnUJAJQKAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQJmcwUCZm4JAQJhWQEFAmZqBQNuaWwFAmZuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRMAQpzZXRNYW5hZ2VyAQJmdgQCZncJAQJmZQEFAmRMAwkAAAIFAmZ3BQJmdwQCZngJANkEAQUCZnYDCQAAAgUCZngFAmZ4CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFWAAUCZnYFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEOY29uZmlybU1hbmFnZXIABAJmeQkBAmZiAAQCZnoDCQEJaXNEZWZpbmVkAQUCZnkGCQACAQISTm8gcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmZ6BQJmegQCZkEDCQAAAggFAmRMD2NhbGxlclB1YmxpY0tleQkBBXZhbHVlAQUCZnkGCQACAQIbWW91IGFyZSBub3QgcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmZBBQJmQQkAzAgCCQELU3RyaW5nRW50cnkCCQEBVQAJANgEAQkBBXZhbHVlAQUCZnkJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAVYABQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEwBA3B1dAICY3oCZkIDCQBmAgAABQJjegkAAgECIEludmFsaWQgc2xpcHBhZ2VUb2xlcmFuY2UgcGFzc2VkBAJkUgkBAmRPAwUCZEwFAmN6BgQCZGIIBQJkUgJfMgQCY2cIBQJkUgJfNwQCY3gIBQJkUgJfOQQCZGMIBQJkUgNfMTAEAmRkCAUCZFIDXzExBAJmQwgFAmRSA18xMgQCZkQIBQJkUgNfMTMEAmRQCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJkTAhwYXltZW50cwAABmFtb3VudAQCZFEJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmRMCHBheW1lbnRzAAEGYW1vdW50BAJkcwkBAmRsAwUCZFAFAmRRCQC2AgEAAAMJAAACBQJkcwUCZHMEAmRVCQD8BwQFAmFPAgRlbWl0CQDMCAIFAmRiBQNuaWwFA25pbAMJAAACBQJkVQUCZFUEAmRWBAJkVwUCZFUDCQABAgUCZFcCB0FkZHJlc3MEAmRYBQJkVwkA/AcEBQJkWAIEZW1pdAkAzAgCBQJkYgUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZFYFAmRWBAJmRQMJAGYCBQJkYwAACQD8BwQFAmJvAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZkMFAmRjBQNuaWwFA25pbAMJAAACBQJmRQUCZkUEAmZGAwkAZgIFAmRkAAAJAPwHBAUCYm8CA3B1dAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJmRAUCZGQFA25pbAUDbmlsAwkAAAIFAmZGBQJmRgQCZkcDBQJmQgQCZkgJAPwHBAUCYm4CBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmNnBQJkYgUDbmlsAwkAAAIFAmZIBQJmSAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJkTAZjYWxsZXIFAmRiBQJjZwUDbmlsBAJmSQkBAmR0AwAAAAAAAAMJAAACBQJmSQUCZkkEAmRrCAUCZkkCXzIEAmZKCAUCZkkCXzEEAmZLCQECZHgCBQJkcwUCZGsDCQAAAgUCZksFAmZLCQDOCAIJAM4IAgUCY3gFAmZHBQJmSgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEKcHV0Rm9yRnJlZQECZkwDCQBmAgAABQJmTAkAAgECFEludmFsaWQgdmFsdWUgcGFzc2VkBAJkUgkBAmRPAwUCZEwFAmZMBwQCY3gIBQJkUgJfOQQCZFAJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmRMCHBheW1lbnRzAAAGYW1vdW50BAJkUQkAtgIBCAkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAQZhbW91bnQEAmRzCQECZGwDBQJkUAUCZFEJALYCAQAAAwkAAAIFAmRzBQJkcwQCZk0JAQJkdAMAAAAAAAAEAmZKCAUCZk0CXzEEAmRrCAUCZk0CXzIEAmZLCQECZHgCBQJkcwUCZGsDCQAAAgUCZksFAmZLCQDOCAIFAmN4BQJmSgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEJcHV0T25lVGtuAgJmTgJmTwQCZlAKAAJhUgkA/AcEBQJhTwIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFSAgdCb29sZWFuBQJhUgkAAgEJAKwCAgkAAwEFAmFSAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJmUQMDAwkBAmFUAAYJAAACBQJiZwUBbAYJAAACBQJiZwUBbgYFAmZQBAJlSAkAzAgCAwMJAQEhAQUCZlEGCQECZmMBBQJkTAYJAQJhTAECIXB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmRMCHBheW1lbnRzAAEGCQECYUwBAh5leGFjdGx5IDEgcGF5bWVudCBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJlSAUCZUgEAmZSCQCRAwIIBQJkTAhwYXltZW50cwAABAJlYwgFAmZSB2Fzc2V0SWQEAmViCAUCZlIGYW1vdW50BAJkcwMJAAACBQJlYwUCYmkJAQJkbAMJALYCAQUCZWIJALYCAQAACQC2AgEAAAMJAAACBQJlYwUCYmoJAQJkbAMJALYCAQAACQC2AgEFAmViCQC2AgEAAAkBAmFMAQIecGF5bWVudCBhc3NldCBpcyBub3Qgc3VwcG9ydGVkAwkAAAIFAmRzBQJkcwQCYWIIBQJkTAZjYWxsZXIEAmFjCAUCZEwNdHJhbnNhY3Rpb25JZAQCZlMJAQJlYQQFAmViBQJlYwUCYWIFAmFjAwkAAAIFAmZTBQJmUwQCZWcIBQJmUwJfNQQCZlQIBQJmUwJfNAQCZFoIBQJmUwJfMwQCZGUIBQJmUwJfMgQCZlUIBQJmUwJfMQQCZlYDAwkAZgIFAmZOAAAJAGYCBQJmTgUCZlUHCQECYUwBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZOBQNuaWwCAAUCZlUEAmRVCQECZFMBBQJmVgMJAAACBQJkVQUCZFUEAmZHAwUCZk8EAmZXCQD8BwQFAmJuAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiaAUCZlYFA25pbAMJAAACBQJmVwUCZlcFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZEwGY2FsbGVyBQJmVgUCYmgFA25pbAQCZlgDCQBmAgUCZFoAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhUAUCZFoFAmVjBQNuaWwFA25pbAQCZlkDCQAAAgUEdGhpcwUCYVAJAJQKAgAAAAADBQJlZwkAlAoCCQEBLQEFAmRaAAAJAJQKAgAACQEBLQEFAmRaBAJkdQgFAmZZAl8xBAJkdggFAmZZAl8yBAJmWgkBAmR0AwUCZHUFAmR2AAAEAmZKCAUCZloCXzEEAmRrCAUCZloCXzIEAmRFCQEFdmFsdWUBCQCiCAEFAmFqBAJmSwkBAmR4AgUCZHMFAmRrAwkAAAIFAmZLBQJmSwkAlAoCCQDOCAIJAM4IAgkAzggCBQJkZQUCZkcFAmZYBQJmSgUCZlYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEwBEXB1dE9uZVRrblJFQURPTkxZAgJlYwJlYgQCZ2EJAQJlYQQFAmViCQECYVkBBQJlYwUEdW5pdAUEdW5pdAQCZlUIBQJnYQJfMQQCZGUIBQJnYQJfMgQCZFoIBQJnYQJfMwQCZlQIBQJnYQJfNAQCZWcIBQJnYQJfNQkAlAoCBQNuaWwJAJUKAwUCZlUFAmRaBQJmVAJkTAEJZ2V0T25lVGtuAgJnYgJmTgQCZlAKAAJhUgkA/AcEBQJhTwIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFSAgdCb29sZWFuBQJhUgkAAgEJAKwCAgkAAwEFAmFSAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJnYwMDCQECYVQABgkAAAIFAmJnBQFuBgUCZlAEAmVICQDMCAIDAwkBASEBBQJnYwYJAQJmYwEFAmRMBgkBAmFMAQIhZ2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCZEwIcGF5bWVudHMAAQYJAQJhTAECHmV4YWN0bHkgMSBwYXltZW50IGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmVIBQJlSAQCZUcJAQJhWQEFAmdiBAJmUgkAkQMCCAUCZEwIcGF5bWVudHMAAAQCZWMIBQJmUgdhc3NldElkBAJlbwgFAmZSBmFtb3VudAQCZHMJAQJkbAMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZHMFAmRzBAJhYggFAmRMBmNhbGxlcgQCYWMIBQJkTA10cmFuc2FjdGlvbklkBAJnZAkBAmVGBQUCZUcFAmVvBQJlYwUCYWIFAmFjAwkAAAIFAmdkBQJnZAQCZUkIBQJnZAJfNQQCZlQIBQJnZAJfNAQCZFoIBQJnZAJfMwQCZGUIBQJnZAJfMgQCZ2UIBQJnZAJfMQQCZFQDAwkAZgIFAmZOAAAJAGYCBQJmTgUCZ2UHCQECYUwBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZOBQNuaWwCAAUCZ2UEAmdmCQD8BwQFAmFPAgRidXJuCQDMCAIFAmVvBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmVjBQJlbwUDbmlsAwkAAAIFAmdmBQJnZgQCZ2cJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYWIFAmRUBQJlRwUDbmlsBAJmWAMJAGYCBQJkWgAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFQBQJkWgUCZUcFA25pbAUDbmlsBAJnaAQCZ2kDCQAAAgUEdGhpcwUCYVAAAAUCZFoDBQJlSQkAlAoCCQEBLQEJAGQCBQJkVAUCZ2kAAAkAlAoCAAAJAQEtAQkAZAIFAmRUBQJnaQQCZHUIBQJnaAJfMQQCZHYIBQJnaAJfMgQCZ2oJAQJkdAMFAmR1BQJkdgAABAJmSggFAmdqAl8xBAJkawgFAmdqAl8yBAJmSwkBAmR4AgUCZHMFAmRrAwkAAAIFAmZLBQJmSwkAlAoCCQDOCAIJAM4IAgkAzggCBQJkZQUCZ2cFAmZYBQJmSgUCZFQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEwBEWdldE9uZVRrblJFQURPTkxZAgJlRwJlbwQCZ2sJAQJlRgUJAQJhWQEFAmVHBQJlbwUCYmgFBHVuaXQFBHVuaXQEAmdlCAUCZ2sCXzEEAmRlCAUCZ2sCXzIEAmRaCAUCZ2sCXzMEAmZUCAUCZ2sCXzQEAmVJCAUCZ2sCXzUJAJQKAgUDbmlsCQCVCgMFAmdlBQJkWgUCZlQCZEwBE3Vuc3Rha2VBbmRHZXRPbmVUa24DAmdsAmdiAmZOBAJmUAoAAmFSCQD8BwQFAmFPAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYVICB0Jvb2xlYW4FAmFSCQACAQkArAICCQADAQUCYVICHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmdjAwMJAQJhVAAGCQAAAgUCYmcFAW4GBQJmUAQCZUgJAMwIAgMDCQEBIQEFAmdjBgkBAmZjAQUCZEwGCQECYUwBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJkTAhwYXltZW50cwAABgkBAmFMAQIYbm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZUgFAmVIBAJlRwkBAmFZAQUCZ2IEAmFiCAUCZEwGY2FsbGVyBAJhYwgFAmRMDXRyYW5zYWN0aW9uSWQEAmRzCQECZGwDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmRzBQJkcwQCZ20JAPwHBAUCYm4CB3Vuc3Rha2UJAMwIAgkA2AQBBQJiaAkAzAgCBQJnbAUDbmlsBQNuaWwDCQAAAgUCZ20FAmdtBAJnbgkBAmVGBQUCZUcFAmdsBQJiaAUCYWIFAmFjAwkAAAIFAmduBQJnbgQCZUkIBQJnbgJfNQQCZlQIBQJnbgJfNAQCZFoIBQJnbgJfMwQCZGUIBQJnbgJfMgQCZ2UIBQJnbgJfMQQCZFQDAwkAZgIFAmZOAAAJAGYCBQJmTgUCZ2UHCQECYUwBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZOBQNuaWwCAAUCZ2UEAmdmCQD8BwQFAmFPAgRidXJuCQDMCAIFAmdsBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJoBQJnbAUDbmlsAwkAAAIFAmdmBQJnZgQCZ2cJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmRMBmNhbGxlcgUCZFQFAmVHBQNuaWwEAmZYAwkAZgIFAmRaAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYVAFAmRaBQJlRwUDbmlsBQNuaWwEAmdvBAJnaQMJAAACBQR0aGlzBQJhUAAABQJkWgMFAmVJCQCUCgIJAQEtAQkAZAIFAmRUBQJnaQAACQCUCgIAAAkBAS0BCQBkAgUCZFQFAmdpBAJkdQgFAmdvAl8xBAJkdggFAmdvAl8yBAJncAkBAmR0AwUCZHUFAmR2AAAEAmZKCAUCZ3ACXzEEAmRrCAUCZ3ACXzIEAmZLCQECZHgCBQJkcwUCZGsDCQAAAgUCZksFAmZLCQCUCgIJAM4IAgkAzggCCQDOCAIFAmRlBQJnZwUCZlgFAmZKBQJkVAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEDZ2V0AAQCY1AJAQJkSwEFAmRMBAJncQgFAmNQAl8xBAJjdwgFAmNQAl8yBAJkTggFAmNQAl8zBAJjZQgFAmNQAl80BAJjeAgFAmNQAl81BAJkcwkBAmRsAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJkcwUCZHMEAmdyCQD8BwQFAmFPAgRidXJuCQDMCAIFAmROBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmNlBQJkTgUDbmlsAwkAAAIFAmdyBQJncgQCZ3MJAQJkdAMJAQEtAQUCZ3EJAQEtAQUCY3cAAAQCZkoIBQJncwJfMQQCZGsIBQJncwJfMgQCZksJAQJkeAIFAmRzBQJkawMJAAACBQJmSwUCZksJAM4IAgUCY3gFAmZKCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRMAQlnZXROb0xlc3MCAmd0Amd1BAJjUAkBAmRLAQUCZEwEAmN2CAUCY1ACXzEEAmN3CAUCY1ACXzIEAmROCAUCY1ACXzMEAmNlCAUCY1ACXzQEAmN4CAUCY1ACXzUDCQBmAgUCZ3QFAmN2CQACAQkArAICCQCsAgIJAKwCAgIcbm9MZXNzVGhlbkFtdEFzc2V0IGZhaWxlZDogIAkApAMBBQJjdgIDIDwgCQCkAwEFAmd0AwkAZgIFAmd1BQJjdwkAAgEJAKwCAgkArAICCQCsAgICHW5vTGVzc1RoZW5QcmljZUFzc2V0IGZhaWxlZDogCQCkAwEFAmN3AgMgPCAJAKQDAQUCZ3UEAmRzCQECZGwDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmRzBQJkcwQCZ3IJAPwHBAUCYU8CBGJ1cm4JAMwIAgUCZE4FA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCY2UFAmROBQNuaWwDCQAAAgUCZ3IFAmdyBAJndgkBAmR0AwkBAS0BBQJjdgkBAS0BBQJjdwAABAJmSggFAmd2Al8xBAJkawgFAmd2Al8yBAJmSwkBAmR4AgUCZHMFAmRrAwkAAAIFAmZLBQJmSwkAzggCBQJjeAUCZkoJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEwBDXVuc3Rha2VBbmRHZXQBAmRUBAJndwMJAQIhPQIJAJADAQgFAmRMCHBheW1lbnRzAAAJAAIBAhhObyBwYXltZW50cyBhcmUgZXhwZWN0ZWQGAwkAAAIFAmd3BQJndwQCYlQJAQJhVgAEAmNnCQDZBAEJAJEDAgUCYlQFAXEEAmRzCQECZGwDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmRzBQJkcwQCZ20JAPwHBAUCYm4CB3Vuc3Rha2UJAMwIAgkA2AQBBQJjZwkAzAgCBQJkVAUDbmlsBQNuaWwDCQAAAgUCZ20FAmdtBAJjUAkBAmNjBAkA2AQBCAUCZEwNdHJhbnNhY3Rpb25JZAkA2AQBBQJjZwUCZFQIBQJkTAZjYWxsZXIEAmN2CAUCY1ACXzEEAmN3CAUCY1ACXzIEAmNqCQENcGFyc2VJbnRWYWx1ZQEIBQJjUAJfOQQCY3gIBQJjUANfMTAEAmd4AwMJAQJhVAAGCQAAAgUCY2oFAW4JAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmNqBgMJAAACBQJneAUCZ3gEAmdyCQD8BwQFAmFPAgRidXJuCQDMCAIFAmRUBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmNnBQJkVAUDbmlsAwkAAAIFAmdyBQJncgQCZ3kJAQJkdAMJAQEtAQUCY3YJAQEtAQUCY3cAAAQCZkoIBQJneQJfMQQCZGsIBQJneQJfMgQCZksJAQJkeAIFAmRzBQJkawMJAAACBQJmSwUCZksJAM4IAgUCY3gFAmZKCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRMARN1bnN0YWtlQW5kR2V0Tm9MZXNzAwJnbAJnegJndQQCZ2MDCQECYVQABgkAAAIFAmJnBQFuBAJlSAkAzAgCAwkBASEBBQJnYwYJAAIBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJkTAhwYXltZW50cwAABgkAAgECGG5vIHBheW1lbnRzIGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmVIBQJlSAQCZHMJAQJkbAMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZHMFAmRzBAJnbQkA/AcEBQJibgIHdW5zdGFrZQkAzAgCCQDYBAEFAmJoCQDMCAIFAmdsBQNuaWwFA25pbAMJAAACBQJnbQUCZ20EAmNQCQECY2MECQDYBAEIBQJkTA10cmFuc2FjdGlvbklkCQDYBAEFAmJoBQJnbAgFAmRMBmNhbGxlcgQCY3YIBQJjUAJfMQQCY3cIBQJjUAJfMgQCY3gIBQJjUANfMTAEAmdBCQDMCAIDCQBnAgUCY3YFAmd6BgkAAgEJALkJAgkAzAgCAixhbW91bnQgYXNzZXQgYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmd6BQNuaWwCAAkAzAgCAwkAZwIFAmN3BQJndQYJAAIBCQC5CQIJAMwIAgIrcHJpY2UgYXNzZXQgYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmd1BQNuaWwCAAUDbmlsAwkAAAIFAmdBBQJnQQQCZ3IJAPwHBAUCYU8CBGJ1cm4JAMwIAgUCZ2wFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYmgFAmdsBQNuaWwDCQAAAgUCZ3IFAmdyBAJnQgkBAmR0AwkBAS0BBQJjdgkBAS0BBQJjdwAABAJmSggFAmdCAl8xBAJkawgFAmdCAl8yBAJmSwkBAmR4AgUCZHMFAmRrAwkAAAIFAmZLBQJmSwkAzggCBQJjeAUCZkoJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEwBCGFjdGl2YXRlAgJnQwJnRAMJAQIhPQIJAKUIAQgFAmRMBmNhbGxlcgkApQgBBQJhTwkAAgECEnBlcm1pc3Npb25zIGRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZQAFAmdDCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZgAFAmdEBQNuaWwCB3N1Y2Nlc3MCZEwBCnJlZnJlc2hLTHAABAJnRQkBC3ZhbHVlT3JFbHNlAgkAnwgBBQJhawAABAJnRgMJAGcCCQBlAgUGaGVpZ2h0BQJnRQUCYW4FBHVuaXQJAQJhTAEJALkJAgkAzAgCCQCkAwEFAmFuCQDMCAICLyBibG9ja3MgaGF2ZSBub3QgcGFzc2VkIHNpbmNlIHRoZSBwcmV2aW91cyBjYWxsBQNuaWwCAAMJAAACBQJnRgUCZ0YEAmRFCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKgDAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQJhagIBMAkBAmFOAQILaW52YWxpZCBrTHAEAmdHCQECZHQDAAAAAAAABAJnSAgFAmdHAl8xBAJkawgFAmdHAl8yBAJkdwMJAQIhPQIFAmRFBQJkawUCZ0gJAQJhTAECEm5vdGhpbmcgdG8gcmVmcmVzaAkAlAoCBQJkdwkApgMBBQJkawkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEcZ2V0UG9vbENvbmZpZ1dyYXBwZXJSRUFET05MWQAJAJQKAgUDbmlsCQECYVYAAmRMARxnZXRBY2NCYWxhbmNlV3JhcHBlclJFQURPTkxZAQJiRgkAlAoCBQNuaWwJAQJiRQEFAmJGAmRMARljYWxjUHJpY2VzV3JhcHBlclJFQURPTkxZAwJiTgJiTwJiUwQCY2IJAQJiUgMFAmJOBQJiTwUCYlMJAJQKAgUDbmlsCQDMCAIJAKYDAQkAkQMCBQJjYgAACQDMCAIJAKYDAQkAkQMCBQJjYgABCQDMCAIJAKYDAQkAkQMCBQJjYgACBQNuaWwCZEwBFHRvWDE4V3JhcHBlclJFQURPTkxZAgFFAUYJAJQKAgUDbmlsCQCmAwEJAQFEAgUBRQUBRgJkTAEWZnJvbVgxOFdyYXBwZXJSRUFET05MWQIBSQFKCQCUCgIFA25pbAkBAUgCCQCnAwEFAUkFAUoCZEwBHmNhbGNQcmljZUJpZ0ludFdyYXBwZXJSRUFET05MWQICYkgCYkkJAJQKAgUDbmlsCQCmAwEJAQJiRwIJAKcDAQUCYkgJAKcDAQUCYkkCZEwBI2VzdGltYXRlUHV0T3BlcmF0aW9uV3JhcHBlclJFQURPTkxZCQJjZAJjegJjQQJjQgJjQwJjRAJhYgJjRQJjRgkAlAoCBQNuaWwJAQJjeQkFAmNkBQJjegUCY0EFAmNCBQJjQwUCY0QFAmFiBQJjRQUCY0YCZEwBI2VzdGltYXRlR2V0T3BlcmF0aW9uV3JhcHBlclJFQURPTkxZBAJjZAJjZQJjZgJhYgQCY1AJAQJjYwQFAmNkBQJjZQUCY2YJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmFiCQCUCgIFA25pbAkAnAoKCAUCY1ACXzEIBQJjUAJfMggFAmNQAl8zCAUCY1ACXzQIBQJjUAJfNQgFAmNQAl82CAUCY1ACXzcJAKYDAQgFAmNQAl84CAUCY1ACXzkIBQJjUANfMTACZEwBDXN0YXRzUkVBRE9OTFkABAJiVAkBAmFWAAQCY2cJANkEAQkAkQMCBQJiVAUBcQQCZ0kJAJEDAgUCYlQFAXIEAmdKCQCRAwIFAmJUBQFzBAJjSQkAkQMCBQJiVAUBdgQCY0oJAJEDAgUCYlQFAXcEAmJVCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlQFAXQEAmJWCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlQFAXUEAmdLCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmNnCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmNnAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCZ0wJAQJiRQEFAmdJBAJnTQkBAmJFAQUCZ0oEAmdOAwkAAAIFAmdLAAAJAMwIAgUBZQkAzAgCBQFlCQDMCAIFAWUFA25pbAkBAmJSAwUCZ0wFAmdNBQJnSwQCY3EAAAQCZ08JAQFIAgkAkQMCBQJnTgABBQFiBAJnUAkBAUgCCQCRAwIFAmdOAAIFAWIEAmdRCQEFdmFsdWUBCQCaCAIFAmFPCQECYXkBCQClCAEFBHRoaXMJAJQKAgUDbmlsCQC5CQIJAMwIAgIOJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJnTAkAzAgCCQCkAwEFAmdNCQDMCAIJAKQDAQUCZ0sJAMwIAgkApAMBBQJjcQkAzAgCCQCkAwEFAmdPCQDMCAIJAKQDAQUCZ1AJAMwIAgkApAMBBQJnUQUDbmlsBQFqAmRMASBldmFsdWF0ZVB1dEJ5QW1vdW50QXNzZXRSRUFET05MWQECY0EEAmJUCQECYVYABAJjZwkA2QQBCQCRAwIFAmJUBQFxBAJjRwkAkQMCBQJiVAUBcgQCY2gJANkEAQUCY0cEAmNICQCRAwIFAmJUBQFzBAJjaQkA2QQBBQJjSAQCYlUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiVAUBdAQCYlYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiVAUBdQQCY2oJAJEDAgUCYlQFAXAEAmdLCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmNnCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmNnAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCZ0wJAQJiRQEFAmNHBAJnTQkBAmJFAQUCY0gEAmJQCQEBRAIFAmdMBQJiVQQCYlEJAQFEAgUCZ00FAmJWBAJjcAMJAAACBQJnSwAABQFlCQECYkcCBQJiUQUCYlAEAmNNCQEBRAIFAmNBBQJiVQQCY04JALwCAwUCY00FAmNwBQFkBAJjQwkBAUgCBQJjTgUCYlYEAmRSCQECY3kJAgAAoMIeBQJjQQUCY2gFAmNDBQJjaQIABgcEAmNYCAUCZFICXzEEAmdSCAUCZFICXzMEAmNsCAUCZFICXzQEAmNuCAUCZFICXzUEAmNrCAUCZFICXzYJAJQKAgUDbmlsCQC5CQIJAMwIAgIQJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmNYCQDMCAIJAKQDAQkBAUgCBQJjcAUBYgkAzAgCCQCkAwEFAmNsCQDMCAIJAKQDAQUCY24JAMwIAgkApAMBBQJjawkAzAgCBQJjagkAzAgCCQCkAwEFAmNBCQDMCAIJAKQDAQUCY0MFA25pbAUBagJkTAEfZXZhbHVhdGVQdXRCeVByaWNlQXNzZXRSRUFET05MWQECY0MEAmJUCQECYVYABAJjZwkA2QQBCQCRAwIFAmJUBQFxBAJjRwkAkQMCBQJiVAUBcgQCY2gJANkEAQUCY0cEAmNICQCRAwIFAmJUBQFzBAJjaQkA2QQBBQJjSAQCYlUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiVAUBdAQCYlYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiVAUBdQQCY2oJAJEDAgUCYlQFAXAEAmdLCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmNnCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmNnAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCZ1MJAQJiRQEFAmNHBAJnVAkBAmJFAQUCY0gEAmdVCQEBRAIFAmdTBQJiVQQCZ1YJAQFEAgUCZ1QFAmJWBAJjcAMJAAACBQJnSwAABQFlCQECYkcCBQJnVgUCZ1UEAmNOCQEBRAIFAmNDBQJiVgQCY00JALwCAwUCY04FAWQFAmNwBAJjQQkBAUgCBQJjTQUCYlUEAmRSCQECY3kJAgAAoMIeBQJjQQUCY2gFAmNDBQJjaQIABgcEAmNYCAUCZFICXzEEAmdSCAUCZFICXzMEAmNsCAUCZFICXzQEAmNuCAUCZFICXzUEAmNrCAUCZFICXzYJAJQKAgUDbmlsCQC5CQIJAMwIAgIQJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmNYCQDMCAIJAKQDAQkBAUgCBQJjcAUBYgkAzAgCCQCkAwEFAmNsCQDMCAIJAKQDAQUCY24JAMwIAgkApAMBBQJjawkAzAgCBQJjagkAzAgCCQCkAwEFAmNBCQDMCAIJAKQDAQUCY0MFA25pbAUBagJkTAETZXZhbHVhdGVHZXRSRUFET05MWQICZ1cCZ1gEAmNQCQECY2MEAgAFAmdXBQJnWAUEdGhpcwQCY3YIBQJjUAJfMQQCY3cIBQJjUAJfMgQCY2wIBQJjUAJfNQQCY24IBQJjUAJfNgQCY2sIBQJjUAJfNwQCY3EIBQJjUAJfOAQCY2oJAQ1wYXJzZUludFZhbHVlAQgFAmNQAl85CQCUCgIFA25pbAkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCY3YJAMwIAgkApAMBBQJjdwkAzAgCCQCkAwEFAmNsCQDMCAIJAKQDAQUCY24JAMwIAgkApAMBBQJjawkAzAgCCQCmAwEFAmNxCQDMCAIJAKQDAQUCY2oFA25pbAUBagECZ1kBAmdaAAQCaGEEAmRXCQECZVoAAwkAAQIFAmRXAgpCeXRlVmVjdG9yBAJmZAUCZFcFAmZkAwkAAQIFAmRXAgRVbml0CAUCZ1kPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IEAmRXBQJnWQMJAAECBQJkVwIFT3JkZXIEAmRBBQJkVwQCaGIJAQJhVQAEAmhjCQECZHoBBQJkQQQCYUQIBQJoYwJfMQQCYUUIBQJoYwJfMgQCYUYJAPQDAwgFAmRBCWJvZHlCeXRlcwkAkQMCCAUCZEEGcHJvb2ZzAAAIBQJkQQ9zZW5kZXJQdWJsaWNLZXkEAmFHCQD0AwMIBQJkQQlib2R5Qnl0ZXMJAJEDAggFAmRBBnByb29mcwABBQJoYgMDAwUCYUQFAmFGBwUCYUcHBgkBAmFDBAUCYUQFAmFFBQJhRgUCYUcDCQABAgUCZFcCFFNldFNjcmlwdFRyYW5zYWN0aW9uBAJmYQUCZFcDCQD0AwMIBQJnWQlib2R5Qnl0ZXMJAJEDAggFAmdZBnByb29mcwAABQJoYQYEAmhkCQD2AwEJAQV2YWx1ZQEIBQJmYQZzY3JpcHQEAmhlCQDbBAEJAQV2YWx1ZQEJAJ0IAgUCYU8JAQJhQQAEAmhmCQDxBwEFBHRoaXMDCQAAAgUCaGUFAmhkCQECIT0CBQJoZgUCaGQHCQD0AwMIBQJnWQlib2R5Qnl0ZXMJAJEDAggFAmdZBnByb29mcwAABQJoYdSzfpw=", "height": 2441988, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: D1PAW6mpJ54LFR4q6KnpGCasiyg8MFLCN9y6rVDJn6ys Next: 5B2GFR6f4TRhfJ5VQKTCccn2LRgsrjYU1kzLHNEy1rJw Diff:
OldNewDifferences
114114 func pa () = "%s__priceAsset"
115115
116116
117+let keyFee = "%s__fee"
118+
119+let feeDefault = fraction(10, scale8, 10000)
120+
121+let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
122+
123+let keyKLp = makeString(["%s", "kLp"], SEP)
124+
125+let keyKLpRefreshedHeight = makeString(["%s", "kLpRefreshedHeight"], SEP)
126+
127+let keyKLpRefreshDelay = makeString(["%s", "refreshKLpDelay"], SEP)
128+
129+let kLpRefreshDelayDefault = 30
130+
131+let kLpRefreshDelay = valueOrElse(getInteger(this, keyKLpRefreshDelay), kLpRefreshDelayDefault)
132+
117133 func keyFactoryConfig () = "%s__factoryConfig"
118134
119135
140156
141157 let keyFeeCollectorAddress = "%s__feeCollectorAddress"
142158
143-func throwOrderError (orderValid,senderValid,matcherValid) = throw(((((("order validation failed: orderValid=" + toString(orderValid)) + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
159+func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
144160
145161
146162 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
150166
151167
152168 func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
169+
170+
171+func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
153172
154173
155174 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
200219
201220 let poolConfigParsed = parsePoolConfig(getPoolConfig())
202221
203-let $t079068072 = poolConfigParsed
222+let $t084698635 = poolConfigParsed
204223
205-let cfgPoolAddress = $t079068072._1
224+let cfgPoolAddress = $t084698635._1
206225
207-let cfgPoolStatus = $t079068072._2
226+let cfgPoolStatus = $t084698635._2
208227
209-let cfgLpAssetId = $t079068072._3
228+let cfgLpAssetId = $t084698635._3
210229
211-let cfgAmountAssetId = $t079068072._4
230+let cfgAmountAssetId = $t084698635._4
212231
213-let cfgPriceAssetId = $t079068072._5
232+let cfgPriceAssetId = $t084698635._5
214233
215-let cfgAmountAssetDecimals = $t079068072._6
234+let cfgAmountAssetDecimals = $t084698635._6
216235
217-let cfgPriceAssetDecimals = $t079068072._7
236+let cfgPriceAssetDecimals = $t084698635._7
218237
219238 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
220239
235254
236255
237256 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
257+
258+
259+func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
238260
239261
240262 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
286308 let lpEmissionX18 = toX18(lpEmission, scale8)
287309 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
288310 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
289- let outAmAmt = fromX18(outAmAmtX18, amAssetDcm)
290- let outPrAmt = fromX18(outPrAmtX18, prAssetDcm)
311+ let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
312+ let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
291313 let state = if ((txId58 == ""))
292314 then nil
293315 else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
346368 then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
347369 else {
348370 let lpEmissionX18 = toX18(lpEmission, scale8)
349- let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
350- let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
371+ let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
372+ let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
351373 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
352374 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
353375 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
354376 let expAmtAssetAmtX18 = expectedAmts._1
355377 let expPriceAssetAmtX18 = expectedAmts._2
356- let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
357- $Tuple5(fromX18(lpAmtX18, scale8), fromX18(expAmtAssetAmtX18, amtAssetDcm), fromX18(expPriceAssetAmtX18, priceAssetDcm), curPriceX18, slippageX18)
378+ let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
379+ $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
358380 }
359381 }
360382 let calcLpAmt = res._1
377399 }
378400
379401
402+func calcKLp (amountBalance,priceBalance,lpEmission) = {
403+ let amountBalanceX18 = toX18BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals))
404+ let priceBalanceX18 = toX18BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))
405+ let updatedKLp = fraction(pow((amountBalanceX18 * priceBalanceX18), 0, toBigInt(5), 1, 18, DOWN), big1, lpEmission)
406+ if ((lpEmission == big0))
407+ then big0
408+ else updatedKLp
409+ }
410+
411+
412+func calcCurrentKLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
413+ let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
414+ let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
415+ let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
416+ let currentKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
417+ currentKLp
418+ }
419+
420+
421+func refreshKLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
422+ let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
423+ let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
424+ let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
425+ let updatedKLp = calcKLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
426+ let actions = [IntegerEntry(keyKLpRefreshedHeight, height), StringEntry(keyKLp, toString(updatedKLp))]
427+ $Tuple2(actions, updatedKLp)
428+ }
429+
430+
431+func validateUpdatedKLp (oldKLp,updatedKLp) = if ((updatedKLp >= oldKLp))
432+ then true
433+ else throwErr(makeString(["updated KLp lower than current KLp", toString(oldKLp), toString(updatedKLp)], " "))
434+
435+
380436 func validateMatcherOrderAllowed (order) = {
381- let cfg = getPoolConfig()
382- let amtAssetId = cfg[idxAmtAssetId]
383- let priceAssetId = cfg[idxPriceAssetId]
384- let poolStatus = parseIntValue(cfg[idxPoolStatus])
385- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
386- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
387- let accAmtAssetBalance = getAccBalance(amtAssetId)
388- let accPriceAssetBalance = getAccBalance(priceAssetId)
389- let curPriceX18 = if ((order.orderType == Buy))
390- then privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
391- else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance - order.amount), accPriceAssetBalance)
392- let curPrice = fromX18(curPriceX18, scale8)
437+ let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
438+ let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
439+ let amountAssetAmount = order.amount
440+ let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
441+ let $t02154121753 = if ((order.orderType == Buy))
442+ then $Tuple2(amountAssetAmount, -(priceAssetAmount))
443+ else $Tuple2(-(amountAssetAmount), priceAssetAmount)
444+ let amountAssetBalanceDelta = $t02154121753._1
445+ let priceAssetBalanceDelta = $t02154121753._2
393446 if (if (if (isGlobalShutdown())
394447 then true
395- else (poolStatus == PoolMatcherDisabled))
448+ else (cfgPoolStatus == PoolMatcherDisabled))
396449 then true
397- else (poolStatus == PoolShutdown))
450+ else (cfgPoolStatus == PoolShutdown))
398451 then throw("Exchange operations disabled")
399- else {
400- let orderAmtAsset = order.assetPair.amountAsset
401- let orderAmtAssetStr = if ((orderAmtAsset == unit))
402- then "WAVES"
403- else toBase58String(value(orderAmtAsset))
404- let orderPriceAsset = order.assetPair.priceAsset
405- let orderPriceAssetStr = if ((orderPriceAsset == unit))
406- then "WAVES"
407- else toBase58String(value(orderPriceAsset))
408- if (if ((orderAmtAssetStr != amtAssetId))
409- then true
410- else (orderPriceAssetStr != priceAssetId))
411- then throw("Wrong order assets.")
412- else {
413- let orderPrice = order.price
414- let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
415- let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
416- let isOrderPriceValid = if ((order.orderType == Buy))
417- then (curPrice >= castedOrderPrice)
418- else (castedOrderPrice >= curPrice)
419- true
420- }
421- }
452+ else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
453+ then true
454+ else (order.assetPair.priceAsset != cfgPriceAssetId))
455+ then throw("Wrong order assets.")
456+ else {
457+ let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
458+ let $t02219322293 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
459+ let unusedActions = $t02219322293._1
460+ let kLpNew = $t02219322293._2
461+ let isOrderValid = (kLpNew >= kLp)
462+ let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
463+ $Tuple2(isOrderValid, info)
464+ }
422465 }
423466
424467
493536 else if ((paymentAssetId == cfgPriceAssetId))
494537 then false
495538 else throwErr("invalid asset")
496- let $t02296923262 = if (isEval)
539+ let $t02540625699 = if (isEval)
497540 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
498541 else if (paymentInAmountAsset)
499542 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
500543 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
501- let amountBalanceOld = $t02296923262._1
502- let priceBalanceOld = $t02296923262._2
503- let $t02326623415 = if (paymentInAmountAsset)
544+ let amountBalanceOld = $t02540625699._1
545+ let priceBalanceOld = $t02540625699._2
546+ let $t02570325852 = if (paymentInAmountAsset)
504547 then $Tuple2(paymentAmountRaw, 0)
505548 else $Tuple2(0, paymentAmountRaw)
506- let amountAssetAmountRaw = $t02326623415._1
507- let priceAssetAmountRaw = $t02326623415._2
549+ let amountAssetAmountRaw = $t02570325852._1
550+ let priceAssetAmountRaw = $t02570325852._2
508551 let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
509552 let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
510- let $t02354723611 = takeFee(paymentAmountRaw, inFee)
511- let paymentAmount = $t02354723611._1
512- let feeAmount = $t02354723611._2
553+ let $t02598426048 = takeFee(paymentAmountRaw, inFee)
554+ let paymentAmount = $t02598426048._1
555+ let feeAmount = $t02598426048._2
513556 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
514557 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
515558 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
532575 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
533576 let priceOld = fromX18(priceOldX18, scale8)
534577 let loss = {
535- let $t02508825255 = if (paymentInAmountAsset)
578+ let $t02772927896 = if (paymentInAmountAsset)
536579 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
537580 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
538- let amount = $t02508825255._1
539- let balance = $t02508825255._2
581+ let amount = $t02772927896._1
582+ let balance = $t02772927896._2
540583 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
541584 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
542585 }
543- $Tuple4(issueAmount, commonState, feeAmount, loss)
586+ $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
544587 }
545588 else throw("Strict value is not equal to itself.")
546589 }
548591
549592 func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
550593 let isEval = (txId == unit)
594+ let cfg = getPoolConfig()
595+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
596+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
551597 let checks = [if ((paymentAssetId == cfgLpAssetId))
552598 then true
553599 else throwErr("invalid lp asset")]
561607 let balanceBigInt = if (outInAmountAsset)
562608 then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
563609 else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
610+ let outInAmountAssetDecimals = if (outInAmountAsset)
611+ then amtAssetDcm
612+ else priceAssetDcm
564613 let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
565614 let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
566615 let outBalance = if (outInAmountAsset)
570619 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
571620 let redeemedBigInt = toBigInt(paymentAmount)
572621 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
573- let $t02683526891 = takeFee(amountRaw, outFee)
574- let totalAmount = $t02683526891._1
575- let feeAmount = $t02683526891._2
576- let $t02689527121 = if (outInAmountAsset)
622+ let $t02997430030 = takeFee(amountRaw, outFee)
623+ let totalAmount = $t02997430030._1
624+ let feeAmount = $t02997430030._2
625+ let $t03003430260 = if (outInAmountAsset)
577626 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
578627 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
579- let outAmAmount = $t02689527121._1
580- let outPrAmount = $t02689527121._2
581- let amBalanceNew = $t02689527121._3
582- let prBalanceNew = $t02689527121._4
628+ let outAmAmount = $t03003430260._1
629+ let outPrAmount = $t03003430260._2
630+ let amBalanceNew = $t03003430260._3
631+ let prBalanceNew = $t03003430260._4
583632 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
584633 let priceNew = fromX18(priceNewX18, scale8)
585634 let commonState = if (isEval)
591640 let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
592641 fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
593642 }
594- $Tuple4(totalAmount, commonState, feeAmount, loss)
643+ $Tuple5(totalAmount, commonState, feeAmount, loss, outInAmountAsset)
595644 }
596645 else throw("Strict value is not equal to itself.")
597646 }
646695
647696 @Callable(i)
648697 func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse) = {
649- let $t02879829103 = if ((isReverse == false))
698+ let $t03195532260 = if ((isReverse == false))
650699 then {
651700 let assetOut = getStringOrFail(this, pa())
652701 let assetIn = getStringOrFail(this, aa())
657706 let assetIn = getStringOrFail(this, pa())
658707 $Tuple2(assetOut, assetIn)
659708 }
660- let assetOut = $t02879829103._1
661- let assetIn = $t02879829103._2
709+ let assetOut = $t03195532260._1
710+ let assetIn = $t03195532260._2
662711 let poolAssetInBalance = getAccBalance(assetIn)
663712 let poolAssetOutBalance = getAccBalance(assetOut)
664713 let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
676725
677726 @Callable(i)
678727 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+ }
679734 let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
680735 then true
681- else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(getStringOrFail(this, swapContract()))))
736+ else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
682737 then true
683738 else throwErr("Permission denied")]
684739 if ((checks == checks))
692747 else getStringOrFail(this, aa())
693748 let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
694749 let poolAssetOutBalance = getAccBalance(assetOut)
695- let amountOut = ((poolAssetOutBalance * cleanAmountIn) / (poolAssetInBalance + cleanAmountIn))
696- let oldK = (poolAssetInBalance * poolAssetOutBalance)
697- let newK = (getAccBalance(assetIn) * (getAccBalance(assetOut) - amountOut))
750+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
751+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
752+ let newK = (toBigInt(getAccBalance(assetIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
698753 let checkK = if ((newK >= oldK))
699754 then true
700755 else throw("new K is fewer error")
704759 then true
705760 else throw("Exchange result is fewer coins than expected")
706761 if ((checkMin == checkMin))
707- then [ScriptTransfer(addressFromStringValue(addressTo), amountOut, if ((assetIn == "WAVES"))
708- then unit
709- else fromBase58String(assetOut))]
762+ then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))], amountOut)
710763 else throw("Strict value is not equal to itself.")
711764 }
712765 else throw("Strict value is not equal to itself.")
763816 let prDiff = estPut._11
764817 let amId = estPut._12
765818 let prId = estPut._13
766- let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
767- if ((emitInv == emitInv))
819+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
820+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
821+ let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
822+ if ((currentKLp == currentKLp))
768823 then {
769- let emitInvLegacy = match emitInv {
770- case legacyFactoryContract: Address =>
771- invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
772- case _ =>
773- unit
774- }
775- if ((emitInvLegacy == emitInvLegacy))
824+ let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
825+ if ((emitInv == emitInv))
776826 then {
777- let slippageAInv = if ((amDiff > 0))
778- then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
779- else nil
780- if ((slippageAInv == slippageAInv))
827+ let emitInvLegacy = match emitInv {
828+ case legacyFactoryContract: Address =>
829+ invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
830+ case _ =>
831+ unit
832+ }
833+ if ((emitInvLegacy == emitInvLegacy))
781834 then {
782- let slippagePInv = if ((prDiff > 0))
783- then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
835+ let slippageAInv = if ((amDiff > 0))
836+ then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
784837 else nil
785- if ((slippagePInv == slippagePInv))
838+ if ((slippageAInv == slippageAInv))
786839 then {
787- let lpTransfer = if (shouldAutoStake)
840+ let slippagePInv = if ((prDiff > 0))
841+ then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
842+ else nil
843+ if ((slippagePInv == slippagePInv))
788844 then {
789- let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
790- if ((slpStakeInv == slpStakeInv))
791- then nil
845+ let lpTransfer = if (shouldAutoStake)
846+ then {
847+ let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
848+ if ((slpStakeInv == slpStakeInv))
849+ then nil
850+ else throw("Strict value is not equal to itself.")
851+ }
852+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
853+ let $t03714537607 = refreshKLpInternal(0, 0, 0)
854+ if (($t03714537607 == $t03714537607))
855+ then {
856+ let updatedKLp = $t03714537607._2
857+ let refreshKLpActions = $t03714537607._1
858+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
859+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
860+ then ((state ++ lpTransfer) ++ refreshKLpActions)
861+ else throw("Strict value is not equal to itself.")
862+ }
792863 else throw("Strict value is not equal to itself.")
793864 }
794- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
795- (state ++ lpTransfer)
865+ else throw("Strict value is not equal to itself.")
796866 }
797867 else throw("Strict value is not equal to itself.")
798868 }
810880 then throw("Invalid value passed")
811881 else {
812882 let estPut = commonPut(i, maxSlippage, false)
813- estPut._9
883+ let state = estPut._9
884+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
885+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
886+ let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
887+ if ((currentKLp == currentKLp))
888+ then {
889+ let $t03816938234 = refreshKLpInternal(0, 0, 0)
890+ let refreshKLpActions = $t03816938234._1
891+ let updatedKLp = $t03816938234._2
892+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
893+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
894+ then (state ++ refreshKLpActions)
895+ else throw("Strict value is not equal to itself.")
896+ }
897+ else throw("Strict value is not equal to itself.")
814898 }
815899
816900
842926 let payment = i.payments[0]
843927 let paymentAssetId = payment.assetId
844928 let paymentAmountRaw = payment.amount
845- let userAddress = i.caller
846- let txId = i.transactionId
847- let $t03429434424 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
848- if (($t03429434424 == $t03429434424))
929+ let currentKLp = if ((paymentAssetId == cfgAmountAssetId))
930+ then calcCurrentKLp(toBigInt(paymentAmountRaw), toBigInt(0), toBigInt(0))
931+ else if ((paymentAssetId == cfgPriceAssetId))
932+ then calcCurrentKLp(toBigInt(0), toBigInt(paymentAmountRaw), toBigInt(0))
933+ else throwErr("payment asset is not supported")
934+ if ((currentKLp == currentKLp))
849935 then {
850- let bonus = $t03429434424._4
851- let feeAmount = $t03429434424._3
852- let commonState = $t03429434424._2
853- let emitAmountEstimated = $t03429434424._1
854- let emitAmount = if (if ((minOutAmount > 0))
855- then (minOutAmount > emitAmountEstimated)
856- else false)
857- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
858- else emitAmountEstimated
859- let emitInv = emit(emitAmount)
860- if ((emitInv == emitInv))
936+ let userAddress = i.caller
937+ let txId = i.transactionId
938+ let $t03942239574 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
939+ if (($t03942239574 == $t03942239574))
861940 then {
862- let lpTransfer = if (autoStake)
941+ let paymentInAmountAsset = $t03942239574._5
942+ let bonus = $t03942239574._4
943+ let feeAmount = $t03942239574._3
944+ let commonState = $t03942239574._2
945+ let emitAmountEstimated = $t03942239574._1
946+ let emitAmount = if (if ((minOutAmount > 0))
947+ then (minOutAmount > emitAmountEstimated)
948+ else false)
949+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
950+ else emitAmountEstimated
951+ let emitInv = emit(emitAmount)
952+ if ((emitInv == emitInv))
863953 then {
864- let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
865- if ((stakeInv == stakeInv))
866- then nil
954+ let lpTransfer = if (autoStake)
955+ then {
956+ let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
957+ if ((stakeInv == stakeInv))
958+ then nil
959+ else throw("Strict value is not equal to itself.")
960+ }
961+ else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
962+ let sendFee = if ((feeAmount > 0))
963+ then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
964+ else nil
965+ let $t04016040357 = if ((this == feeCollectorAddress))
966+ then $Tuple2(0, 0)
967+ else if (paymentInAmountAsset)
968+ then $Tuple2(-(feeAmount), 0)
969+ else $Tuple2(0, -(feeAmount))
970+ let amountAssetBalanceDelta = $t04016040357._1
971+ let priceAssetBalanceDelta = $t04016040357._2
972+ let $t04036040468 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
973+ let refreshKLpActions = $t04036040468._1
974+ let updatedKLp = $t04036040468._2
975+ let kLp = value(getString(keyKLp))
976+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
977+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
978+ then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
867979 else throw("Strict value is not equal to itself.")
868980 }
869- else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
870- let sendFee = if ((feeAmount > 0))
871- then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
872- else nil
873- $Tuple2(((commonState ++ lpTransfer) ++ sendFee), emitAmount)
981+ else throw("Strict value is not equal to itself.")
874982 }
875983 else throw("Strict value is not equal to itself.")
876984 }
883991
884992 @Callable(i)
885993 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
886- let $t03515335288 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
887- let emitAmountEstimated = $t03515335288._1
888- let commonState = $t03515335288._2
889- let feeAmount = $t03515335288._3
890- let bonus = $t03515335288._4
994+ let $t04077440931 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
995+ let emitAmountEstimated = $t04077440931._1
996+ let commonState = $t04077440931._2
997+ let feeAmount = $t04077440931._3
998+ let bonus = $t04077440931._4
999+ let paymentInAmountAsset = $t04077440931._5
8911000 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
8921001 }
8931002
9191028 let payment = i.payments[0]
9201029 let paymentAssetId = payment.assetId
9211030 let paymentAmount = payment.amount
922- let userAddress = i.caller
923- let txId = i.transactionId
924- let $t03609336228 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
925- if (($t03609336228 == $t03609336228))
1031+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1032+ if ((currentKLp == currentKLp))
9261033 then {
927- let bonus = $t03609336228._4
928- let feeAmount = $t03609336228._3
929- let commonState = $t03609336228._2
930- let amountEstimated = $t03609336228._1
931- let amount = if (if ((minOutAmount > 0))
932- then (minOutAmount > amountEstimated)
933- else false)
934- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
935- else amountEstimated
936- let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
937- if ((burnInv == burnInv))
1034+ let userAddress = i.caller
1035+ let txId = i.transactionId
1036+ let $t04181641969 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1037+ if (($t04181641969 == $t04181641969))
9381038 then {
939- let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
940- let sendFee = if ((feeAmount > 0))
941- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
942- else nil
943- $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
1039+ let outInAmountAsset = $t04181641969._5
1040+ let bonus = $t04181641969._4
1041+ let feeAmount = $t04181641969._3
1042+ let commonState = $t04181641969._2
1043+ let amountEstimated = $t04181641969._1
1044+ let amount = if (if ((minOutAmount > 0))
1045+ then (minOutAmount > amountEstimated)
1046+ else false)
1047+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1048+ else amountEstimated
1049+ let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
1050+ if ((burnInv == burnInv))
1051+ then {
1052+ let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
1053+ let sendFee = if ((feeAmount > 0))
1054+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1055+ else nil
1056+ let $t04246942716 = {
1057+ let feeAmountForCalc = if ((this == feeCollectorAddress))
1058+ then 0
1059+ else feeAmount
1060+ if (outInAmountAsset)
1061+ then $Tuple2(-((amount + feeAmountForCalc)), 0)
1062+ else $Tuple2(0, -((amount + feeAmountForCalc)))
1063+ }
1064+ let amountAssetBalanceDelta = $t04246942716._1
1065+ let priceAssetBalanceDelta = $t04246942716._2
1066+ let $t04271942827 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1067+ let refreshKLpActions = $t04271942827._1
1068+ let updatedKLp = $t04271942827._2
1069+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1070+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1071+ then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1072+ else throw("Strict value is not equal to itself.")
1073+ }
1074+ else throw("Strict value is not equal to itself.")
9441075 }
9451076 else throw("Strict value is not equal to itself.")
9461077 }
9531084
9541085 @Callable(i)
9551086 func getOneTknREADONLY (outAssetId,paymentAmount) = {
956- let $t03686337001 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
957- let amountEstimated = $t03686337001._1
958- let commonState = $t03686337001._2
959- let feeAmount = $t03686337001._3
960- let bonus = $t03686337001._4
1087+ let $t04308443240 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1088+ let amountEstimated = $t04308443240._1
1089+ let commonState = $t04308443240._2
1090+ let feeAmount = $t04308443240._3
1091+ let bonus = $t04308443240._4
1092+ let outInAmountAsset = $t04308443240._5
9611093 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
9621094 }
9631095
9881120 let outAssetId = parseAssetId(outAssetIdStr)
9891121 let userAddress = i.caller
9901122 let txId = i.transactionId
991- let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
992- if ((unstakeInv == unstakeInv))
1123+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1124+ if ((currentKLp == currentKLp))
9931125 then {
994- let $t03782637959 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
995- if (($t03782637959 == $t03782637959))
1126+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1127+ if ((unstakeInv == unstakeInv))
9961128 then {
997- let bonus = $t03782637959._4
998- let feeAmount = $t03782637959._3
999- let commonState = $t03782637959._2
1000- let amountEstimated = $t03782637959._1
1001- let amount = if (if ((minOutAmount > 0))
1002- then (minOutAmount > amountEstimated)
1003- else false)
1004- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1005- else amountEstimated
1006- let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1007- if ((burnInv == burnInv))
1129+ let $t04414544296 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1130+ if (($t04414544296 == $t04414544296))
10081131 then {
1009- let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
1010- let sendFee = if ((feeAmount > 0))
1011- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1012- else nil
1013- $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
1132+ let outInAmountAsset = $t04414544296._5
1133+ let bonus = $t04414544296._4
1134+ let feeAmount = $t04414544296._3
1135+ let commonState = $t04414544296._2
1136+ let amountEstimated = $t04414544296._1
1137+ let amount = if (if ((minOutAmount > 0))
1138+ then (minOutAmount > amountEstimated)
1139+ else false)
1140+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1141+ else amountEstimated
1142+ let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1143+ if ((burnInv == burnInv))
1144+ then {
1145+ let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
1146+ let sendFee = if ((feeAmount > 0))
1147+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1148+ else nil
1149+ let $t04479145038 = {
1150+ let feeAmountForCalc = if ((this == feeCollectorAddress))
1151+ then 0
1152+ else feeAmount
1153+ if (outInAmountAsset)
1154+ then $Tuple2(-((amount + feeAmountForCalc)), 0)
1155+ else $Tuple2(0, -((amount + feeAmountForCalc)))
1156+ }
1157+ let amountAssetBalanceDelta = $t04479145038._1
1158+ let priceAssetBalanceDelta = $t04479145038._2
1159+ let $t04504145149 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1160+ let refreshKLpActions = $t04504145149._1
1161+ let updatedKLp = $t04504145149._2
1162+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1163+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1164+ then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1165+ else throw("Strict value is not equal to itself.")
1166+ }
1167+ else throw("Strict value is not equal to itself.")
10141168 }
10151169 else throw("Strict value is not equal to itself.")
10161170 }
10311185 let pmtAmt = res._3
10321186 let pmtAssetId = res._4
10331187 let state = res._5
1034- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1035- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1036- then state
1188+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1189+ if ((currentKLp == currentKLp))
1190+ then {
1191+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1192+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1193+ then {
1194+ let $t04609546177 = refreshKLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1195+ let refreshKLpActions = $t04609546177._1
1196+ let updatedKLp = $t04609546177._2
1197+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1198+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1199+ then (state ++ refreshKLpActions)
1200+ else throw("Strict value is not equal to itself.")
1201+ }
1202+ else throw("Strict value is not equal to itself.")
1203+ }
10371204 else throw("Strict value is not equal to itself.")
10381205 }
10391206
10521219 else if ((noLessThenPriceAsset > outPrAmt))
10531220 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
10541221 else {
1055- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1056- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1057- then state
1222+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1223+ if ((currentKLp == currentKLp))
1224+ then {
1225+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1226+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1227+ then {
1228+ let $t04712647207 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1229+ let refreshKLpActions = $t04712647207._1
1230+ let updatedKLp = $t04712647207._2
1231+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1232+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1233+ then (state ++ refreshKLpActions)
1234+ else throw("Strict value is not equal to itself.")
1235+ }
1236+ else throw("Strict value is not equal to itself.")
1237+ }
10581238 else throw("Strict value is not equal to itself.")
10591239 }
10601240 }
10701250 then {
10711251 let cfg = getPoolConfig()
10721252 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1073- let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
1074- if ((unstakeInv == unstakeInv))
1253+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1254+ if ((currentKLp == currentKLp))
10751255 then {
1076- let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1077- let poolStatus = parseIntValue(res._9)
1078- let state = res._10
1079- let checkPoolStatus = if (if (isGlobalShutdown())
1080- then true
1081- else (poolStatus == PoolShutdown))
1082- then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
1083- else true
1084- if ((checkPoolStatus == checkPoolStatus))
1256+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
1257+ if ((unstakeInv == unstakeInv))
10851258 then {
1086- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1087- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1088- then state
1259+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1260+ let outAmAmt = res._1
1261+ let outPrAmt = res._2
1262+ let poolStatus = parseIntValue(res._9)
1263+ let state = res._10
1264+ let checkPoolStatus = if (if (isGlobalShutdown())
1265+ then true
1266+ else (poolStatus == PoolShutdown))
1267+ then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
1268+ else true
1269+ if ((checkPoolStatus == checkPoolStatus))
1270+ then {
1271+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1272+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1273+ then {
1274+ let $t04833348414 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1275+ let refreshKLpActions = $t04833348414._1
1276+ let updatedKLp = $t04833348414._2
1277+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1278+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1279+ then (state ++ refreshKLpActions)
1280+ else throw("Strict value is not equal to itself.")
1281+ }
1282+ else throw("Strict value is not equal to itself.")
1283+ }
10891284 else throw("Strict value is not equal to itself.")
10901285 }
10911286 else throw("Strict value is not equal to itself.")
11091304 else throw("no payments are expected")]
11101305 if ((checks == checks))
11111306 then {
1112- let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1113- if ((unstakeInv == unstakeInv))
1307+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1308+ if ((currentKLp == currentKLp))
11141309 then {
1115- let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
1116- let outAmAmt = res._1
1117- let outPrAmt = res._2
1118- let state = res._10
1119- let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
1120- then true
1121- else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
1122- then true
1123- else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
1124- if ((checkAmounts == checkAmounts))
1310+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1311+ if ((unstakeInv == unstakeInv))
11251312 then {
1126- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1127- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1128- then state
1313+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
1314+ let outAmAmt = res._1
1315+ let outPrAmt = res._2
1316+ let state = res._10
1317+ let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
1318+ then true
1319+ else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
1320+ then true
1321+ else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
1322+ if ((checkAmounts == checkAmounts))
1323+ then {
1324+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1325+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1326+ then {
1327+ let $t04970949790 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1328+ let refreshKLpActions = $t04970949790._1
1329+ let updatedKLp = $t04970949790._2
1330+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1331+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1332+ then (state ++ refreshKLpActions)
1333+ else throw("Strict value is not equal to itself.")
1334+ }
1335+ else throw("Strict value is not equal to itself.")
1336+ }
11291337 else throw("Strict value is not equal to itself.")
11301338 }
11311339 else throw("Strict value is not equal to itself.")
11411349 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
11421350 then throw("permissions denied")
11431351 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
1352+
1353+
1354+
1355+@Callable(i)
1356+func refreshKLp () = {
1357+ let lastRefreshedBlockHeight = valueOrElse(getInteger(keyKLpRefreshedHeight), 0)
1358+ let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= kLpRefreshDelay))
1359+ then unit
1360+ else throwErr(makeString([toString(kLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1361+ if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
1362+ then {
1363+ let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1364+ let $t05097751041 = refreshKLpInternal(0, 0, 0)
1365+ let kLpUpdateActions = $t05097751041._1
1366+ let updatedKLp = $t05097751041._2
1367+ let actions = if ((kLp != updatedKLp))
1368+ then kLpUpdateActions
1369+ else throwErr("nothing to refresh")
1370+ $Tuple2(actions, toString(updatedKLp))
1371+ }
1372+ else throw("Strict value is not equal to itself.")
1373+ }
11441374
11451375
11461376
13081538 match tx {
13091539 case order: Order =>
13101540 let matcherPub = getMatcherPubOrFail()
1311- let orderValid = validateMatcherOrderAllowed(order)
1541+ let $t05970359772 = validateMatcherOrderAllowed(order)
1542+ let orderValid = $t05970359772._1
1543+ let orderValidInfo = $t05970359772._2
13121544 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
13131545 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
13141546 if (if (if (orderValid)
13171549 then matcherValid
13181550 else false)
13191551 then true
1320- else throwOrderError(orderValid, senderValid, matcherValid)
1552+ else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
13211553 case s: SetScriptTransaction =>
1322- let newHash = blake2b256(value(s.script))
1323- let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
1324- let currentHash = scriptHash(this)
1325- if (if ((allowedHash == newHash))
1326- then (currentHash != newHash)
1327- else false)
1554+ if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
13281555 then true
1329- else sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
1556+ else {
1557+ let newHash = blake2b256(value(s.script))
1558+ let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
1559+ let currentHash = scriptHash(this)
1560+ if ((allowedHash == newHash))
1561+ then (currentHash != newHash)
1562+ else false
1563+ }
13301564 case _ =>
13311565 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
13321566 }
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let lPdecimals = 8
55
66 let scale8 = 100000000
77
88 let scale8BigInt = toBigInt(100000000)
99
1010 let scale18 = toBigInt(1000000000000000000)
1111
1212 let zeroBigInt = toBigInt(0)
1313
1414 let big0 = toBigInt(0)
1515
1616 let big1 = toBigInt(1)
1717
1818 let big2 = toBigInt(2)
1919
2020 let wavesString = "WAVES"
2121
2222 let SEP = "__"
2323
2424 let PoolActive = 1
2525
2626 let PoolPutDisabled = 2
2727
2828 let PoolMatcherDisabled = 3
2929
3030 let PoolShutdown = 4
3131
3232 let idxPoolAddress = 1
3333
3434 let idxPoolStatus = 2
3535
3636 let idxPoolLPAssetId = 3
3737
3838 let idxAmtAssetId = 4
3939
4040 let idxPriceAssetId = 5
4141
4242 let idxAmtAssetDcm = 6
4343
4444 let idxPriceAssetDcm = 7
4545
4646 let idxIAmtAssetId = 8
4747
4848 let idxIPriceAssetId = 9
4949
5050 let idxLPAssetDcm = 10
5151
5252 let idxPoolAmtAssetAmt = 1
5353
5454 let idxPoolPriceAssetAmt = 2
5555
5656 let idxPoolLPAssetAmt = 3
5757
5858 let idxFactoryStakingContract = 1
5959
6060 let idxFactorySlippageContract = 7
6161
6262 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
6363
6464
6565 func toX18BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
6666
6767
6868 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
6969
7070
7171 func fromX18Round (val,resultScaleMult,round) = toInt(fraction(val, toBigInt(resultScaleMult), scale18, round))
7272
7373
7474 func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
7575
7676
7777 func abs (val) = if ((0 > val))
7878 then -(val)
7979 else val
8080
8181
8282 func absBigInt (val) = if ((zeroBigInt > val))
8383 then -(val)
8484 else val
8585
8686
8787 func swapContract () = "%s__swapContract"
8888
8989
9090 func fc () = "%s__factoryContract"
9191
9292
9393 func mpk () = "%s__managerPublicKey"
9494
9595
9696 func pmpk () = "%s__pendingManagerPublicKey"
9797
9898
9999 func pl () = "%s%s__price__last"
100100
101101
102102 func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
103103
104104
105105 func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
106106
107107
108108 func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
109109
110110
111111 func aa () = "%s__amountAsset"
112112
113113
114114 func pa () = "%s__priceAsset"
115115
116116
117+let keyFee = "%s__fee"
118+
119+let feeDefault = fraction(10, scale8, 10000)
120+
121+let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
122+
123+let keyKLp = makeString(["%s", "kLp"], SEP)
124+
125+let keyKLpRefreshedHeight = makeString(["%s", "kLpRefreshedHeight"], SEP)
126+
127+let keyKLpRefreshDelay = makeString(["%s", "refreshKLpDelay"], SEP)
128+
129+let kLpRefreshDelayDefault = 30
130+
131+let kLpRefreshDelay = valueOrElse(getInteger(this, keyKLpRefreshDelay), kLpRefreshDelayDefault)
132+
117133 func keyFactoryConfig () = "%s__factoryConfig"
118134
119135
120136 func keyMatcherPub () = "%s%s__matcher__publicKey"
121137
122138
123139 func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
124140
125141
126142 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
127143
128144
129145 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
130146
131147
132148 func keyAllPoolsShutdown () = "%s__shutdown"
133149
134150
135151 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
136152
137153
138154 func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
139155
140156
141157 let keyFeeCollectorAddress = "%s__feeCollectorAddress"
142158
143-func throwOrderError (orderValid,senderValid,matcherValid) = throw(((((("order validation failed: orderValid=" + toString(orderValid)) + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
159+func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
144160
145161
146162 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
147163
148164
149165 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
150166
151167
152168 func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
169+
170+
171+func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
153172
154173
155174 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
156175
157176 let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
158177
159178 let inFee = {
160179 let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
161180 if ($isInstanceOf(@, "Int"))
162181 then @
163182 else throw(($getType(@) + " couldn't be cast to Int"))
164183 }
165184
166185 let outFee = {
167186 let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
168187 if ($isInstanceOf(@, "Int"))
169188 then @
170189 else throw(($getType(@) + " couldn't be cast to Int"))
171190 }
172191
173192 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
174193
175194
176195 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
177196
178197
179198 func getPoolConfig () = {
180199 let amtAsset = getStringOrFail(this, aa())
181200 let priceAsset = getStringOrFail(this, pa())
182201 let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
183202 let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
184203 split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
185204 }
186205
187206
188207 func parseAssetId (input) = if ((input == wavesString))
189208 then unit
190209 else fromBase58String(input)
191210
192211
193212 func assetIdToString (input) = if ((input == unit))
194213 then wavesString
195214 else toBase58String(value(input))
196215
197216
198217 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]))
199218
200219
201220 let poolConfigParsed = parsePoolConfig(getPoolConfig())
202221
203-let $t079068072 = poolConfigParsed
222+let $t084698635 = poolConfigParsed
204223
205-let cfgPoolAddress = $t079068072._1
224+let cfgPoolAddress = $t084698635._1
206225
207-let cfgPoolStatus = $t079068072._2
226+let cfgPoolStatus = $t084698635._2
208227
209-let cfgLpAssetId = $t079068072._3
228+let cfgLpAssetId = $t084698635._3
210229
211-let cfgAmountAssetId = $t079068072._4
230+let cfgAmountAssetId = $t084698635._4
212231
213-let cfgPriceAssetId = $t079068072._5
232+let cfgPriceAssetId = $t084698635._5
214233
215-let cfgAmountAssetDecimals = $t079068072._6
234+let cfgAmountAssetDecimals = $t084698635._6
216235
217-let cfgPriceAssetDecimals = $t079068072._7
236+let cfgPriceAssetDecimals = $t084698635._7
218237
219238 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
220239
221240
222241 let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
223242
224243 let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
225244
226245 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)
227246
228247
229248 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)
230249
231250
232251 func getAccBalance (assetId) = if ((assetId == "WAVES"))
233252 then wavesBalance(this).available
234253 else assetBalance(this, fromBase58String(assetId))
235254
236255
237256 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
257+
258+
259+func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
238260
239261
240262 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
241263 let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
242264 let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
243265 calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
244266 }
245267
246268
247269 func calcPrices (amAmt,prAmt,lpAmt) = {
248270 let cfg = getPoolConfig()
249271 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
250272 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
251273 let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
252274 let amAmtX18 = toX18(amAmt, amtAssetDcm)
253275 let prAmtX18 = toX18(prAmt, priceAssetDcm)
254276 let lpAmtX18 = toX18(lpAmt, scale8)
255277 let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
256278 let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
257279 [priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
258280 }
259281
260282
261283 func calculatePrices (amAmt,prAmt,lpAmt) = {
262284 let prices = calcPrices(amAmt, prAmt, lpAmt)
263285 [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
264286 }
265287
266288
267289 func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
268290 let cfg = getPoolConfig()
269291 let lpAssetId = cfg[idxPoolLPAssetId]
270292 let amAssetId = cfg[idxAmtAssetId]
271293 let prAssetId = cfg[idxPriceAssetId]
272294 let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
273295 let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
274296 let poolStatus = cfg[idxPoolStatus]
275297 let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
276298 if ((lpAssetId != pmtAssetId))
277299 then throw("Invalid asset passed.")
278300 else {
279301 let amBalance = getAccBalance(amAssetId)
280302 let amBalanceX18 = toX18(amBalance, amAssetDcm)
281303 let prBalance = getAccBalance(prAssetId)
282304 let prBalanceX18 = toX18(prBalance, prAssetDcm)
283305 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
284306 let curPrice = fromX18(curPriceX18, scale8)
285307 let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
286308 let lpEmissionX18 = toX18(lpEmission, scale8)
287309 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
288310 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
289- let outAmAmt = fromX18(outAmAmtX18, amAssetDcm)
290- let outPrAmt = fromX18(outPrAmtX18, prAssetDcm)
311+ let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
312+ let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
291313 let state = if ((txId58 == ""))
292314 then nil
293315 else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
294316 then unit
295317 else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
296318 then unit
297319 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)]
298320 $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
299321 }
300322 }
301323
302324
303325 func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
304326 let cfg = getPoolConfig()
305327 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
306328 let amAssetIdStr = cfg[idxAmtAssetId]
307329 let prAssetIdStr = cfg[idxPriceAssetId]
308330 let iAmtAssetId = cfg[idxIAmtAssetId]
309331 let iPriceAssetId = cfg[idxIPriceAssetId]
310332 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
311333 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
312334 let poolStatus = cfg[idxPoolStatus]
313335 let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
314336 let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
315337 let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
316338 if (if ((amAssetIdStr != inAmAssetIdStr))
317339 then true
318340 else (prAssetIdStr != inPrAssetIdStr))
319341 then throw("Invalid amt or price asset passed.")
320342 else {
321343 let amBalance = if (isEvaluate)
322344 then getAccBalance(amAssetIdStr)
323345 else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
324346 let prBalance = if (isEvaluate)
325347 then getAccBalance(prAssetIdStr)
326348 else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
327349 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
328350 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
329351 let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
330352 let amBalanceX18 = toX18(amBalance, amtAssetDcm)
331353 let prBalanceX18 = toX18(prBalance, priceAssetDcm)
332354 let res = if ((lpEmission == 0))
333355 then {
334356 let curPriceX18 = zeroBigInt
335357 let slippageX18 = zeroBigInt
336358 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
337359 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
338360 }
339361 else {
340362 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
341363 let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
342364 let slippageToleranceX18 = toX18(slippageTolerance, scale8)
343365 if (if ((curPriceX18 != zeroBigInt))
344366 then (slippageX18 > slippageToleranceX18)
345367 else false)
346368 then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
347369 else {
348370 let lpEmissionX18 = toX18(lpEmission, scale8)
349- let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
350- let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
371+ let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
372+ let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
351373 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
352374 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
353375 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
354376 let expAmtAssetAmtX18 = expectedAmts._1
355377 let expPriceAssetAmtX18 = expectedAmts._2
356- let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
357- $Tuple5(fromX18(lpAmtX18, scale8), fromX18(expAmtAssetAmtX18, amtAssetDcm), fromX18(expPriceAssetAmtX18, priceAssetDcm), curPriceX18, slippageX18)
378+ let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
379+ $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
358380 }
359381 }
360382 let calcLpAmt = res._1
361383 let calcAmAssetPmt = res._2
362384 let calcPrAssetPmt = res._3
363385 let curPrice = fromX18(res._4, scale8)
364386 let slippageCalc = fromX18(res._5, scale8)
365387 if ((0 >= calcLpAmt))
366388 then throw("Invalid calculations. LP calculated is less than zero.")
367389 else {
368390 let emitLpAmt = if (!(emitLp))
369391 then 0
370392 else calcLpAmt
371393 let amDiff = (inAmAssetAmt - calcAmAssetPmt)
372394 let prDiff = (inPrAssetAmt - calcPrAssetPmt)
373395 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))]
374396 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
375397 }
376398 }
377399 }
378400
379401
402+func calcKLp (amountBalance,priceBalance,lpEmission) = {
403+ let amountBalanceX18 = toX18BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals))
404+ let priceBalanceX18 = toX18BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))
405+ let updatedKLp = fraction(pow((amountBalanceX18 * priceBalanceX18), 0, toBigInt(5), 1, 18, DOWN), big1, lpEmission)
406+ if ((lpEmission == big0))
407+ then big0
408+ else updatedKLp
409+ }
410+
411+
412+func calcCurrentKLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
413+ let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
414+ let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
415+ let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
416+ let currentKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
417+ currentKLp
418+ }
419+
420+
421+func refreshKLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
422+ let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
423+ let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
424+ let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
425+ let updatedKLp = calcKLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
426+ let actions = [IntegerEntry(keyKLpRefreshedHeight, height), StringEntry(keyKLp, toString(updatedKLp))]
427+ $Tuple2(actions, updatedKLp)
428+ }
429+
430+
431+func validateUpdatedKLp (oldKLp,updatedKLp) = if ((updatedKLp >= oldKLp))
432+ then true
433+ else throwErr(makeString(["updated KLp lower than current KLp", toString(oldKLp), toString(updatedKLp)], " "))
434+
435+
380436 func validateMatcherOrderAllowed (order) = {
381- let cfg = getPoolConfig()
382- let amtAssetId = cfg[idxAmtAssetId]
383- let priceAssetId = cfg[idxPriceAssetId]
384- let poolStatus = parseIntValue(cfg[idxPoolStatus])
385- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
386- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
387- let accAmtAssetBalance = getAccBalance(amtAssetId)
388- let accPriceAssetBalance = getAccBalance(priceAssetId)
389- let curPriceX18 = if ((order.orderType == Buy))
390- then privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
391- else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance - order.amount), accPriceAssetBalance)
392- let curPrice = fromX18(curPriceX18, scale8)
437+ let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
438+ let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
439+ let amountAssetAmount = order.amount
440+ let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
441+ let $t02154121753 = if ((order.orderType == Buy))
442+ then $Tuple2(amountAssetAmount, -(priceAssetAmount))
443+ else $Tuple2(-(amountAssetAmount), priceAssetAmount)
444+ let amountAssetBalanceDelta = $t02154121753._1
445+ let priceAssetBalanceDelta = $t02154121753._2
393446 if (if (if (isGlobalShutdown())
394447 then true
395- else (poolStatus == PoolMatcherDisabled))
448+ else (cfgPoolStatus == PoolMatcherDisabled))
396449 then true
397- else (poolStatus == PoolShutdown))
450+ else (cfgPoolStatus == PoolShutdown))
398451 then throw("Exchange operations disabled")
399- else {
400- let orderAmtAsset = order.assetPair.amountAsset
401- let orderAmtAssetStr = if ((orderAmtAsset == unit))
402- then "WAVES"
403- else toBase58String(value(orderAmtAsset))
404- let orderPriceAsset = order.assetPair.priceAsset
405- let orderPriceAssetStr = if ((orderPriceAsset == unit))
406- then "WAVES"
407- else toBase58String(value(orderPriceAsset))
408- if (if ((orderAmtAssetStr != amtAssetId))
409- then true
410- else (orderPriceAssetStr != priceAssetId))
411- then throw("Wrong order assets.")
412- else {
413- let orderPrice = order.price
414- let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
415- let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
416- let isOrderPriceValid = if ((order.orderType == Buy))
417- then (curPrice >= castedOrderPrice)
418- else (castedOrderPrice >= curPrice)
419- true
420- }
421- }
452+ else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
453+ then true
454+ else (order.assetPair.priceAsset != cfgPriceAssetId))
455+ then throw("Wrong order assets.")
456+ else {
457+ let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
458+ let $t02219322293 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
459+ let unusedActions = $t02219322293._1
460+ let kLpNew = $t02219322293._2
461+ let isOrderValid = (kLpNew >= kLp)
462+ let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
463+ $Tuple2(isOrderValid, info)
464+ }
422465 }
423466
424467
425468 func commonGet (i) = if ((size(i.payments) != 1))
426469 then throw("exactly 1 payment is expected")
427470 else {
428471 let pmt = value(i.payments[0])
429472 let pmtAssetId = value(pmt.assetId)
430473 let pmtAmt = pmt.amount
431474 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
432475 let outAmAmt = res._1
433476 let outPrAmt = res._2
434477 let poolStatus = parseIntValue(res._9)
435478 let state = res._10
436479 if (if (isGlobalShutdown())
437480 then true
438481 else (poolStatus == PoolShutdown))
439482 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
440483 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
441484 }
442485
443486
444487 func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
445488 then throw("exactly 2 payments are expected")
446489 else {
447490 let amAssetPmt = value(i.payments[0])
448491 let prAssetPmt = value(i.payments[1])
449492 let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
450493 let poolStatus = parseIntValue(estPut._8)
451494 if (if (if (isGlobalShutdown())
452495 then true
453496 else (poolStatus == PoolPutDisabled))
454497 then true
455498 else (poolStatus == PoolShutdown))
456499 then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
457500 else estPut
458501 }
459502
460503
461504 func emit (amount) = {
462505 let emitInv = invoke(factoryContract, "emit", [amount], nil)
463506 if ((emitInv == emitInv))
464507 then {
465508 let emitInvLegacy = match emitInv {
466509 case legacyFactoryContract: Address =>
467510 invoke(legacyFactoryContract, "emit", [amount], nil)
468511 case _ =>
469512 unit
470513 }
471514 if ((emitInvLegacy == emitInvLegacy))
472515 then amount
473516 else throw("Strict value is not equal to itself.")
474517 }
475518 else throw("Strict value is not equal to itself.")
476519 }
477520
478521
479522 func takeFee (amount,fee) = {
480523 let feeAmount = if ((fee == 0))
481524 then 0
482525 else fraction(amount, fee, scale8)
483526 $Tuple2((amount - feeAmount), feeAmount)
484527 }
485528
486529
487530 func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
488531 let isEval = (txId == unit)
489532 let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
490533 let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
491534 let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
492535 then true
493536 else if ((paymentAssetId == cfgPriceAssetId))
494537 then false
495538 else throwErr("invalid asset")
496- let $t02296923262 = if (isEval)
539+ let $t02540625699 = if (isEval)
497540 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
498541 else if (paymentInAmountAsset)
499542 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
500543 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
501- let amountBalanceOld = $t02296923262._1
502- let priceBalanceOld = $t02296923262._2
503- let $t02326623415 = if (paymentInAmountAsset)
544+ let amountBalanceOld = $t02540625699._1
545+ let priceBalanceOld = $t02540625699._2
546+ let $t02570325852 = if (paymentInAmountAsset)
504547 then $Tuple2(paymentAmountRaw, 0)
505548 else $Tuple2(0, paymentAmountRaw)
506- let amountAssetAmountRaw = $t02326623415._1
507- let priceAssetAmountRaw = $t02326623415._2
549+ let amountAssetAmountRaw = $t02570325852._1
550+ let priceAssetAmountRaw = $t02570325852._2
508551 let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
509552 let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
510- let $t02354723611 = takeFee(paymentAmountRaw, inFee)
511- let paymentAmount = $t02354723611._1
512- let feeAmount = $t02354723611._2
553+ let $t02598426048 = takeFee(paymentAmountRaw, inFee)
554+ let paymentAmount = $t02598426048._1
555+ let feeAmount = $t02598426048._2
513556 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
514557 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
515558 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
516559 let priceNew = fromX18(priceNewX18, scale8)
517560 let paymentBalance = if (paymentInAmountAsset)
518561 then amountBalanceOld
519562 else priceBalanceOld
520563 let paymentBalanceBigInt = toBigInt(paymentBalance)
521564 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
522565 let chechSupply = if ((supplyBigInt > big0))
523566 then true
524567 else throwErr("initial deposit requires all coins")
525568 if ((chechSupply == chechSupply))
526569 then {
527570 let depositBigInt = toBigInt(paymentAmount)
528571 let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
529572 let commonState = if (isEval)
530573 then nil
531574 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))]
532575 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
533576 let priceOld = fromX18(priceOldX18, scale8)
534577 let loss = {
535- let $t02508825255 = if (paymentInAmountAsset)
578+ let $t02772927896 = if (paymentInAmountAsset)
536579 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
537580 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
538- let amount = $t02508825255._1
539- let balance = $t02508825255._2
581+ let amount = $t02772927896._1
582+ let balance = $t02772927896._2
540583 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
541584 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
542585 }
543- $Tuple4(issueAmount, commonState, feeAmount, loss)
586+ $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
544587 }
545588 else throw("Strict value is not equal to itself.")
546589 }
547590
548591
549592 func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
550593 let isEval = (txId == unit)
594+ let cfg = getPoolConfig()
595+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
596+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
551597 let checks = [if ((paymentAssetId == cfgLpAssetId))
552598 then true
553599 else throwErr("invalid lp asset")]
554600 if ((checks == checks))
555601 then {
556602 let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
557603 then true
558604 else if ((outAssetId == cfgPriceAssetId))
559605 then false
560606 else throwErr("invalid asset")
561607 let balanceBigInt = if (outInAmountAsset)
562608 then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
563609 else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
610+ let outInAmountAssetDecimals = if (outInAmountAsset)
611+ then amtAssetDcm
612+ else priceAssetDcm
564613 let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
565614 let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
566615 let outBalance = if (outInAmountAsset)
567616 then amBalanceOld
568617 else prBalanceOld
569618 let outBalanceBigInt = toBigInt(outBalance)
570619 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
571620 let redeemedBigInt = toBigInt(paymentAmount)
572621 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
573- let $t02683526891 = takeFee(amountRaw, outFee)
574- let totalAmount = $t02683526891._1
575- let feeAmount = $t02683526891._2
576- let $t02689527121 = if (outInAmountAsset)
622+ let $t02997430030 = takeFee(amountRaw, outFee)
623+ let totalAmount = $t02997430030._1
624+ let feeAmount = $t02997430030._2
625+ let $t03003430260 = if (outInAmountAsset)
577626 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
578627 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
579- let outAmAmount = $t02689527121._1
580- let outPrAmount = $t02689527121._2
581- let amBalanceNew = $t02689527121._3
582- let prBalanceNew = $t02689527121._4
628+ let outAmAmount = $t03003430260._1
629+ let outPrAmount = $t03003430260._2
630+ let amBalanceNew = $t03003430260._3
631+ let prBalanceNew = $t03003430260._4
583632 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
584633 let priceNew = fromX18(priceNewX18, scale8)
585634 let commonState = if (isEval)
586635 then nil
587636 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)]
588637 let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
589638 let priceOld = fromX18(priceOldX18, scale8)
590639 let loss = {
591640 let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
592641 fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
593642 }
594- $Tuple4(totalAmount, commonState, feeAmount, loss)
643+ $Tuple5(totalAmount, commonState, feeAmount, loss, outInAmountAsset)
595644 }
596645 else throw("Strict value is not equal to itself.")
597646 }
598647
599648
600649 func managerPublicKeyOrUnit () = match getString(mpk()) {
601650 case s: String =>
602651 fromBase58String(s)
603652 case _: Unit =>
604653 unit
605654 case _ =>
606655 throw("Match error")
607656 }
608657
609658
610659 func pendingManagerPublicKeyOrUnit () = match getString(pmpk()) {
611660 case s: String =>
612661 fromBase58String(s)
613662 case _: Unit =>
614663 unit
615664 case _ =>
616665 throw("Match error")
617666 }
618667
619668
620669 func isManager (i) = match managerPublicKeyOrUnit() {
621670 case pk: ByteVector =>
622671 (i.callerPublicKey == pk)
623672 case _: Unit =>
624673 (i.caller == this)
625674 case _ =>
626675 throw("Match error")
627676 }
628677
629678
630679 func mustManager (i) = {
631680 let pd = throw("Permission denied")
632681 match managerPublicKeyOrUnit() {
633682 case pk: ByteVector =>
634683 if ((i.callerPublicKey == pk))
635684 then true
636685 else pd
637686 case _: Unit =>
638687 if ((i.caller == this))
639688 then true
640689 else pd
641690 case _ =>
642691 throw("Match error")
643692 }
644693 }
645694
646695
647696 @Callable(i)
648697 func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse) = {
649- let $t02879829103 = if ((isReverse == false))
698+ let $t03195532260 = if ((isReverse == false))
650699 then {
651700 let assetOut = getStringOrFail(this, pa())
652701 let assetIn = getStringOrFail(this, aa())
653702 $Tuple2(assetOut, assetIn)
654703 }
655704 else {
656705 let assetOut = getStringOrFail(this, aa())
657706 let assetIn = getStringOrFail(this, pa())
658707 $Tuple2(assetOut, assetIn)
659708 }
660- let assetOut = $t02879829103._1
661- let assetIn = $t02879829103._2
709+ let assetOut = $t03195532260._1
710+ let assetIn = $t03195532260._2
662711 let poolAssetInBalance = getAccBalance(assetIn)
663712 let poolAssetOutBalance = getAccBalance(assetOut)
664713 let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
665714 let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
666715 let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
667716 let checkK = if ((newK >= oldK))
668717 then true
669718 else throw("new K is fewer error")
670719 if ((checkK == checkK))
671720 then $Tuple2(nil, amountOut)
672721 else throw("Strict value is not equal to itself.")
673722 }
674723
675724
676725
677726 @Callable(i)
678727 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+ }
679734 let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
680735 then true
681- else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(getStringOrFail(this, swapContract()))))
736+ else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
682737 then true
683738 else throwErr("Permission denied")]
684739 if ((checks == checks))
685740 then {
686741 let pmt = value(i.payments[0])
687742 let assetIn = if ((pmt.assetId == unit))
688743 then toBase58String(toBytes("WAVES"))
689744 else toBase58String(value(pmt.assetId))
690745 let assetOut = if ((isReverse == false))
691746 then getStringOrFail(this, pa())
692747 else getStringOrFail(this, aa())
693748 let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
694749 let poolAssetOutBalance = getAccBalance(assetOut)
695- let amountOut = ((poolAssetOutBalance * cleanAmountIn) / (poolAssetInBalance + cleanAmountIn))
696- let oldK = (poolAssetInBalance * poolAssetOutBalance)
697- let newK = (getAccBalance(assetIn) * (getAccBalance(assetOut) - amountOut))
750+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
751+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
752+ let newK = (toBigInt(getAccBalance(assetIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
698753 let checkK = if ((newK >= oldK))
699754 then true
700755 else throw("new K is fewer error")
701756 if ((checkK == checkK))
702757 then {
703758 let checkMin = if ((amountOut >= amountOutMin))
704759 then true
705760 else throw("Exchange result is fewer coins than expected")
706761 if ((checkMin == checkMin))
707- then [ScriptTransfer(addressFromStringValue(addressTo), amountOut, if ((assetIn == "WAVES"))
708- then unit
709- else fromBase58String(assetOut))]
762+ then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))], amountOut)
710763 else throw("Strict value is not equal to itself.")
711764 }
712765 else throw("Strict value is not equal to itself.")
713766 }
714767 else throw("Strict value is not equal to itself.")
715768 }
716769
717770
718771
719772 @Callable(i)
720773 func setManager (pendingManagerPublicKey) = {
721774 let checkCaller = mustManager(i)
722775 if ((checkCaller == checkCaller))
723776 then {
724777 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
725778 if ((checkManagerPublicKey == checkManagerPublicKey))
726779 then [StringEntry(pmpk(), pendingManagerPublicKey)]
727780 else throw("Strict value is not equal to itself.")
728781 }
729782 else throw("Strict value is not equal to itself.")
730783 }
731784
732785
733786
734787 @Callable(i)
735788 func confirmManager () = {
736789 let pm = pendingManagerPublicKeyOrUnit()
737790 let hasPM = if (isDefined(pm))
738791 then true
739792 else throw("No pending manager")
740793 if ((hasPM == hasPM))
741794 then {
742795 let checkPM = if ((i.callerPublicKey == value(pm)))
743796 then true
744797 else throw("You are not pending manager")
745798 if ((checkPM == checkPM))
746799 then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())]
747800 else throw("Strict value is not equal to itself.")
748801 }
749802 else throw("Strict value is not equal to itself.")
750803 }
751804
752805
753806
754807 @Callable(i)
755808 func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
756809 then throw("Invalid slippageTolerance passed")
757810 else {
758811 let estPut = commonPut(i, slippageTolerance, true)
759812 let emitLpAmt = estPut._2
760813 let lpAssetId = estPut._7
761814 let state = estPut._9
762815 let amDiff = estPut._10
763816 let prDiff = estPut._11
764817 let amId = estPut._12
765818 let prId = estPut._13
766- let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
767- if ((emitInv == emitInv))
819+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
820+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
821+ let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
822+ if ((currentKLp == currentKLp))
768823 then {
769- let emitInvLegacy = match emitInv {
770- case legacyFactoryContract: Address =>
771- invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
772- case _ =>
773- unit
774- }
775- if ((emitInvLegacy == emitInvLegacy))
824+ let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
825+ if ((emitInv == emitInv))
776826 then {
777- let slippageAInv = if ((amDiff > 0))
778- then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
779- else nil
780- if ((slippageAInv == slippageAInv))
827+ let emitInvLegacy = match emitInv {
828+ case legacyFactoryContract: Address =>
829+ invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
830+ case _ =>
831+ unit
832+ }
833+ if ((emitInvLegacy == emitInvLegacy))
781834 then {
782- let slippagePInv = if ((prDiff > 0))
783- then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
835+ let slippageAInv = if ((amDiff > 0))
836+ then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
784837 else nil
785- if ((slippagePInv == slippagePInv))
838+ if ((slippageAInv == slippageAInv))
786839 then {
787- let lpTransfer = if (shouldAutoStake)
840+ let slippagePInv = if ((prDiff > 0))
841+ then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
842+ else nil
843+ if ((slippagePInv == slippagePInv))
788844 then {
789- let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
790- if ((slpStakeInv == slpStakeInv))
791- then nil
845+ let lpTransfer = if (shouldAutoStake)
846+ then {
847+ let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
848+ if ((slpStakeInv == slpStakeInv))
849+ then nil
850+ else throw("Strict value is not equal to itself.")
851+ }
852+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
853+ let $t03714537607 = refreshKLpInternal(0, 0, 0)
854+ if (($t03714537607 == $t03714537607))
855+ then {
856+ let updatedKLp = $t03714537607._2
857+ let refreshKLpActions = $t03714537607._1
858+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
859+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
860+ then ((state ++ lpTransfer) ++ refreshKLpActions)
861+ else throw("Strict value is not equal to itself.")
862+ }
792863 else throw("Strict value is not equal to itself.")
793864 }
794- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
795- (state ++ lpTransfer)
865+ else throw("Strict value is not equal to itself.")
796866 }
797867 else throw("Strict value is not equal to itself.")
798868 }
799869 else throw("Strict value is not equal to itself.")
800870 }
801871 else throw("Strict value is not equal to itself.")
802872 }
803873 else throw("Strict value is not equal to itself.")
804874 }
805875
806876
807877
808878 @Callable(i)
809879 func putForFree (maxSlippage) = if ((0 > maxSlippage))
810880 then throw("Invalid value passed")
811881 else {
812882 let estPut = commonPut(i, maxSlippage, false)
813- estPut._9
883+ let state = estPut._9
884+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
885+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
886+ let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
887+ if ((currentKLp == currentKLp))
888+ then {
889+ let $t03816938234 = refreshKLpInternal(0, 0, 0)
890+ let refreshKLpActions = $t03816938234._1
891+ let updatedKLp = $t03816938234._2
892+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
893+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
894+ then (state ++ refreshKLpActions)
895+ else throw("Strict value is not equal to itself.")
896+ }
897+ else throw("Strict value is not equal to itself.")
814898 }
815899
816900
817901
818902 @Callable(i)
819903 func putOneTkn (minOutAmount,autoStake) = {
820904 let isPoolOneTokenOperationsDisabled = {
821905 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
822906 if ($isInstanceOf(@, "Boolean"))
823907 then @
824908 else throw(($getType(@) + " couldn't be cast to Boolean"))
825909 }
826910 let isPutDisabled = if (if (if (isGlobalShutdown())
827911 then true
828912 else (cfgPoolStatus == PoolPutDisabled))
829913 then true
830914 else (cfgPoolStatus == PoolShutdown))
831915 then true
832916 else isPoolOneTokenOperationsDisabled
833917 let checks = [if (if (!(isPutDisabled))
834918 then true
835919 else isManager(i))
836920 then true
837921 else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
838922 then true
839923 else throwErr("exactly 1 payment are expected")]
840924 if ((checks == checks))
841925 then {
842926 let payment = i.payments[0]
843927 let paymentAssetId = payment.assetId
844928 let paymentAmountRaw = payment.amount
845- let userAddress = i.caller
846- let txId = i.transactionId
847- let $t03429434424 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
848- if (($t03429434424 == $t03429434424))
929+ let currentKLp = if ((paymentAssetId == cfgAmountAssetId))
930+ then calcCurrentKLp(toBigInt(paymentAmountRaw), toBigInt(0), toBigInt(0))
931+ else if ((paymentAssetId == cfgPriceAssetId))
932+ then calcCurrentKLp(toBigInt(0), toBigInt(paymentAmountRaw), toBigInt(0))
933+ else throwErr("payment asset is not supported")
934+ if ((currentKLp == currentKLp))
849935 then {
850- let bonus = $t03429434424._4
851- let feeAmount = $t03429434424._3
852- let commonState = $t03429434424._2
853- let emitAmountEstimated = $t03429434424._1
854- let emitAmount = if (if ((minOutAmount > 0))
855- then (minOutAmount > emitAmountEstimated)
856- else false)
857- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
858- else emitAmountEstimated
859- let emitInv = emit(emitAmount)
860- if ((emitInv == emitInv))
936+ let userAddress = i.caller
937+ let txId = i.transactionId
938+ let $t03942239574 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
939+ if (($t03942239574 == $t03942239574))
861940 then {
862- let lpTransfer = if (autoStake)
941+ let paymentInAmountAsset = $t03942239574._5
942+ let bonus = $t03942239574._4
943+ let feeAmount = $t03942239574._3
944+ let commonState = $t03942239574._2
945+ let emitAmountEstimated = $t03942239574._1
946+ let emitAmount = if (if ((minOutAmount > 0))
947+ then (minOutAmount > emitAmountEstimated)
948+ else false)
949+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
950+ else emitAmountEstimated
951+ let emitInv = emit(emitAmount)
952+ if ((emitInv == emitInv))
863953 then {
864- let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
865- if ((stakeInv == stakeInv))
866- then nil
954+ let lpTransfer = if (autoStake)
955+ then {
956+ let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
957+ if ((stakeInv == stakeInv))
958+ then nil
959+ else throw("Strict value is not equal to itself.")
960+ }
961+ else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
962+ let sendFee = if ((feeAmount > 0))
963+ then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
964+ else nil
965+ let $t04016040357 = if ((this == feeCollectorAddress))
966+ then $Tuple2(0, 0)
967+ else if (paymentInAmountAsset)
968+ then $Tuple2(-(feeAmount), 0)
969+ else $Tuple2(0, -(feeAmount))
970+ let amountAssetBalanceDelta = $t04016040357._1
971+ let priceAssetBalanceDelta = $t04016040357._2
972+ let $t04036040468 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
973+ let refreshKLpActions = $t04036040468._1
974+ let updatedKLp = $t04036040468._2
975+ let kLp = value(getString(keyKLp))
976+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
977+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
978+ then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
867979 else throw("Strict value is not equal to itself.")
868980 }
869- else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
870- let sendFee = if ((feeAmount > 0))
871- then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
872- else nil
873- $Tuple2(((commonState ++ lpTransfer) ++ sendFee), emitAmount)
981+ else throw("Strict value is not equal to itself.")
874982 }
875983 else throw("Strict value is not equal to itself.")
876984 }
877985 else throw("Strict value is not equal to itself.")
878986 }
879987 else throw("Strict value is not equal to itself.")
880988 }
881989
882990
883991
884992 @Callable(i)
885993 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
886- let $t03515335288 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
887- let emitAmountEstimated = $t03515335288._1
888- let commonState = $t03515335288._2
889- let feeAmount = $t03515335288._3
890- let bonus = $t03515335288._4
994+ let $t04077440931 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
995+ let emitAmountEstimated = $t04077440931._1
996+ let commonState = $t04077440931._2
997+ let feeAmount = $t04077440931._3
998+ let bonus = $t04077440931._4
999+ let paymentInAmountAsset = $t04077440931._5
8911000 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
8921001 }
8931002
8941003
8951004
8961005 @Callable(i)
8971006 func getOneTkn (outAssetIdStr,minOutAmount) = {
8981007 let isPoolOneTokenOperationsDisabled = {
8991008 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
9001009 if ($isInstanceOf(@, "Boolean"))
9011010 then @
9021011 else throw(($getType(@) + " couldn't be cast to Boolean"))
9031012 }
9041013 let isGetDisabled = if (if (isGlobalShutdown())
9051014 then true
9061015 else (cfgPoolStatus == PoolShutdown))
9071016 then true
9081017 else isPoolOneTokenOperationsDisabled
9091018 let checks = [if (if (!(isGetDisabled))
9101019 then true
9111020 else isManager(i))
9121021 then true
9131022 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
9141023 then true
9151024 else throwErr("exactly 1 payment are expected")]
9161025 if ((checks == checks))
9171026 then {
9181027 let outAssetId = parseAssetId(outAssetIdStr)
9191028 let payment = i.payments[0]
9201029 let paymentAssetId = payment.assetId
9211030 let paymentAmount = payment.amount
922- let userAddress = i.caller
923- let txId = i.transactionId
924- let $t03609336228 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
925- if (($t03609336228 == $t03609336228))
1031+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1032+ if ((currentKLp == currentKLp))
9261033 then {
927- let bonus = $t03609336228._4
928- let feeAmount = $t03609336228._3
929- let commonState = $t03609336228._2
930- let amountEstimated = $t03609336228._1
931- let amount = if (if ((minOutAmount > 0))
932- then (minOutAmount > amountEstimated)
933- else false)
934- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
935- else amountEstimated
936- let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
937- if ((burnInv == burnInv))
1034+ let userAddress = i.caller
1035+ let txId = i.transactionId
1036+ let $t04181641969 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1037+ if (($t04181641969 == $t04181641969))
9381038 then {
939- let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
940- let sendFee = if ((feeAmount > 0))
941- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
942- else nil
943- $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
1039+ let outInAmountAsset = $t04181641969._5
1040+ let bonus = $t04181641969._4
1041+ let feeAmount = $t04181641969._3
1042+ let commonState = $t04181641969._2
1043+ let amountEstimated = $t04181641969._1
1044+ let amount = if (if ((minOutAmount > 0))
1045+ then (minOutAmount > amountEstimated)
1046+ else false)
1047+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1048+ else amountEstimated
1049+ let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
1050+ if ((burnInv == burnInv))
1051+ then {
1052+ let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
1053+ let sendFee = if ((feeAmount > 0))
1054+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1055+ else nil
1056+ let $t04246942716 = {
1057+ let feeAmountForCalc = if ((this == feeCollectorAddress))
1058+ then 0
1059+ else feeAmount
1060+ if (outInAmountAsset)
1061+ then $Tuple2(-((amount + feeAmountForCalc)), 0)
1062+ else $Tuple2(0, -((amount + feeAmountForCalc)))
1063+ }
1064+ let amountAssetBalanceDelta = $t04246942716._1
1065+ let priceAssetBalanceDelta = $t04246942716._2
1066+ let $t04271942827 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1067+ let refreshKLpActions = $t04271942827._1
1068+ let updatedKLp = $t04271942827._2
1069+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1070+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1071+ then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1072+ else throw("Strict value is not equal to itself.")
1073+ }
1074+ else throw("Strict value is not equal to itself.")
9441075 }
9451076 else throw("Strict value is not equal to itself.")
9461077 }
9471078 else throw("Strict value is not equal to itself.")
9481079 }
9491080 else throw("Strict value is not equal to itself.")
9501081 }
9511082
9521083
9531084
9541085 @Callable(i)
9551086 func getOneTknREADONLY (outAssetId,paymentAmount) = {
956- let $t03686337001 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
957- let amountEstimated = $t03686337001._1
958- let commonState = $t03686337001._2
959- let feeAmount = $t03686337001._3
960- let bonus = $t03686337001._4
1087+ let $t04308443240 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1088+ let amountEstimated = $t04308443240._1
1089+ let commonState = $t04308443240._2
1090+ let feeAmount = $t04308443240._3
1091+ let bonus = $t04308443240._4
1092+ let outInAmountAsset = $t04308443240._5
9611093 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
9621094 }
9631095
9641096
9651097
9661098 @Callable(i)
9671099 func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
9681100 let isPoolOneTokenOperationsDisabled = {
9691101 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
9701102 if ($isInstanceOf(@, "Boolean"))
9711103 then @
9721104 else throw(($getType(@) + " couldn't be cast to Boolean"))
9731105 }
9741106 let isGetDisabled = if (if (isGlobalShutdown())
9751107 then true
9761108 else (cfgPoolStatus == PoolShutdown))
9771109 then true
9781110 else isPoolOneTokenOperationsDisabled
9791111 let checks = [if (if (!(isGetDisabled))
9801112 then true
9811113 else isManager(i))
9821114 then true
9831115 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
9841116 then true
9851117 else throwErr("no payments are expected")]
9861118 if ((checks == checks))
9871119 then {
9881120 let outAssetId = parseAssetId(outAssetIdStr)
9891121 let userAddress = i.caller
9901122 let txId = i.transactionId
991- let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
992- if ((unstakeInv == unstakeInv))
1123+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1124+ if ((currentKLp == currentKLp))
9931125 then {
994- let $t03782637959 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
995- if (($t03782637959 == $t03782637959))
1126+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1127+ if ((unstakeInv == unstakeInv))
9961128 then {
997- let bonus = $t03782637959._4
998- let feeAmount = $t03782637959._3
999- let commonState = $t03782637959._2
1000- let amountEstimated = $t03782637959._1
1001- let amount = if (if ((minOutAmount > 0))
1002- then (minOutAmount > amountEstimated)
1003- else false)
1004- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1005- else amountEstimated
1006- let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1007- if ((burnInv == burnInv))
1129+ let $t04414544296 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1130+ if (($t04414544296 == $t04414544296))
10081131 then {
1009- let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
1010- let sendFee = if ((feeAmount > 0))
1011- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1012- else nil
1013- $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
1132+ let outInAmountAsset = $t04414544296._5
1133+ let bonus = $t04414544296._4
1134+ let feeAmount = $t04414544296._3
1135+ let commonState = $t04414544296._2
1136+ let amountEstimated = $t04414544296._1
1137+ let amount = if (if ((minOutAmount > 0))
1138+ then (minOutAmount > amountEstimated)
1139+ else false)
1140+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1141+ else amountEstimated
1142+ let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1143+ if ((burnInv == burnInv))
1144+ then {
1145+ let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
1146+ let sendFee = if ((feeAmount > 0))
1147+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1148+ else nil
1149+ let $t04479145038 = {
1150+ let feeAmountForCalc = if ((this == feeCollectorAddress))
1151+ then 0
1152+ else feeAmount
1153+ if (outInAmountAsset)
1154+ then $Tuple2(-((amount + feeAmountForCalc)), 0)
1155+ else $Tuple2(0, -((amount + feeAmountForCalc)))
1156+ }
1157+ let amountAssetBalanceDelta = $t04479145038._1
1158+ let priceAssetBalanceDelta = $t04479145038._2
1159+ let $t04504145149 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1160+ let refreshKLpActions = $t04504145149._1
1161+ let updatedKLp = $t04504145149._2
1162+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1163+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1164+ then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1165+ else throw("Strict value is not equal to itself.")
1166+ }
1167+ else throw("Strict value is not equal to itself.")
10141168 }
10151169 else throw("Strict value is not equal to itself.")
10161170 }
10171171 else throw("Strict value is not equal to itself.")
10181172 }
10191173 else throw("Strict value is not equal to itself.")
10201174 }
10211175 else throw("Strict value is not equal to itself.")
10221176 }
10231177
10241178
10251179
10261180 @Callable(i)
10271181 func get () = {
10281182 let res = commonGet(i)
10291183 let outAmtAmt = res._1
10301184 let outPrAmt = res._2
10311185 let pmtAmt = res._3
10321186 let pmtAssetId = res._4
10331187 let state = res._5
1034- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1035- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1036- then state
1188+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1189+ if ((currentKLp == currentKLp))
1190+ then {
1191+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1192+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1193+ then {
1194+ let $t04609546177 = refreshKLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1195+ let refreshKLpActions = $t04609546177._1
1196+ let updatedKLp = $t04609546177._2
1197+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1198+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1199+ then (state ++ refreshKLpActions)
1200+ else throw("Strict value is not equal to itself.")
1201+ }
1202+ else throw("Strict value is not equal to itself.")
1203+ }
10371204 else throw("Strict value is not equal to itself.")
10381205 }
10391206
10401207
10411208
10421209 @Callable(i)
10431210 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
10441211 let res = commonGet(i)
10451212 let outAmAmt = res._1
10461213 let outPrAmt = res._2
10471214 let pmtAmt = res._3
10481215 let pmtAssetId = res._4
10491216 let state = res._5
10501217 if ((noLessThenAmtAsset > outAmAmt))
10511218 then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
10521219 else if ((noLessThenPriceAsset > outPrAmt))
10531220 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
10541221 else {
1055- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1056- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1057- then state
1222+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1223+ if ((currentKLp == currentKLp))
1224+ then {
1225+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1226+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1227+ then {
1228+ let $t04712647207 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1229+ let refreshKLpActions = $t04712647207._1
1230+ let updatedKLp = $t04712647207._2
1231+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1232+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1233+ then (state ++ refreshKLpActions)
1234+ else throw("Strict value is not equal to itself.")
1235+ }
1236+ else throw("Strict value is not equal to itself.")
1237+ }
10581238 else throw("Strict value is not equal to itself.")
10591239 }
10601240 }
10611241
10621242
10631243
10641244 @Callable(i)
10651245 func unstakeAndGet (amount) = {
10661246 let checkPayments = if ((size(i.payments) != 0))
10671247 then throw("No payments are expected")
10681248 else true
10691249 if ((checkPayments == checkPayments))
10701250 then {
10711251 let cfg = getPoolConfig()
10721252 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1073- let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
1074- if ((unstakeInv == unstakeInv))
1253+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1254+ if ((currentKLp == currentKLp))
10751255 then {
1076- let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1077- let poolStatus = parseIntValue(res._9)
1078- let state = res._10
1079- let checkPoolStatus = if (if (isGlobalShutdown())
1080- then true
1081- else (poolStatus == PoolShutdown))
1082- then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
1083- else true
1084- if ((checkPoolStatus == checkPoolStatus))
1256+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
1257+ if ((unstakeInv == unstakeInv))
10851258 then {
1086- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1087- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1088- then state
1259+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1260+ let outAmAmt = res._1
1261+ let outPrAmt = res._2
1262+ let poolStatus = parseIntValue(res._9)
1263+ let state = res._10
1264+ let checkPoolStatus = if (if (isGlobalShutdown())
1265+ then true
1266+ else (poolStatus == PoolShutdown))
1267+ then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
1268+ else true
1269+ if ((checkPoolStatus == checkPoolStatus))
1270+ then {
1271+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1272+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1273+ then {
1274+ let $t04833348414 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1275+ let refreshKLpActions = $t04833348414._1
1276+ let updatedKLp = $t04833348414._2
1277+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1278+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1279+ then (state ++ refreshKLpActions)
1280+ else throw("Strict value is not equal to itself.")
1281+ }
1282+ else throw("Strict value is not equal to itself.")
1283+ }
10891284 else throw("Strict value is not equal to itself.")
10901285 }
10911286 else throw("Strict value is not equal to itself.")
10921287 }
10931288 else throw("Strict value is not equal to itself.")
10941289 }
10951290 else throw("Strict value is not equal to itself.")
10961291 }
10971292
10981293
10991294
11001295 @Callable(i)
11011296 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
11021297 let isGetDisabled = if (isGlobalShutdown())
11031298 then true
11041299 else (cfgPoolStatus == PoolShutdown)
11051300 let checks = [if (!(isGetDisabled))
11061301 then true
11071302 else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
11081303 then true
11091304 else throw("no payments are expected")]
11101305 if ((checks == checks))
11111306 then {
1112- let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1113- if ((unstakeInv == unstakeInv))
1307+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1308+ if ((currentKLp == currentKLp))
11141309 then {
1115- let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
1116- let outAmAmt = res._1
1117- let outPrAmt = res._2
1118- let state = res._10
1119- let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
1120- then true
1121- else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
1122- then true
1123- else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
1124- if ((checkAmounts == checkAmounts))
1310+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1311+ if ((unstakeInv == unstakeInv))
11251312 then {
1126- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1127- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1128- then state
1313+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
1314+ let outAmAmt = res._1
1315+ let outPrAmt = res._2
1316+ let state = res._10
1317+ let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
1318+ then true
1319+ else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
1320+ then true
1321+ else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
1322+ if ((checkAmounts == checkAmounts))
1323+ then {
1324+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1325+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1326+ then {
1327+ let $t04970949790 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1328+ let refreshKLpActions = $t04970949790._1
1329+ let updatedKLp = $t04970949790._2
1330+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1331+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1332+ then (state ++ refreshKLpActions)
1333+ else throw("Strict value is not equal to itself.")
1334+ }
1335+ else throw("Strict value is not equal to itself.")
1336+ }
11291337 else throw("Strict value is not equal to itself.")
11301338 }
11311339 else throw("Strict value is not equal to itself.")
11321340 }
11331341 else throw("Strict value is not equal to itself.")
11341342 }
11351343 else throw("Strict value is not equal to itself.")
11361344 }
11371345
11381346
11391347
11401348 @Callable(i)
11411349 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
11421350 then throw("permissions denied")
11431351 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
1352+
1353+
1354+
1355+@Callable(i)
1356+func refreshKLp () = {
1357+ let lastRefreshedBlockHeight = valueOrElse(getInteger(keyKLpRefreshedHeight), 0)
1358+ let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= kLpRefreshDelay))
1359+ then unit
1360+ else throwErr(makeString([toString(kLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1361+ if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
1362+ then {
1363+ let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1364+ let $t05097751041 = refreshKLpInternal(0, 0, 0)
1365+ let kLpUpdateActions = $t05097751041._1
1366+ let updatedKLp = $t05097751041._2
1367+ let actions = if ((kLp != updatedKLp))
1368+ then kLpUpdateActions
1369+ else throwErr("nothing to refresh")
1370+ $Tuple2(actions, toString(updatedKLp))
1371+ }
1372+ else throw("Strict value is not equal to itself.")
1373+ }
11441374
11451375
11461376
11471377 @Callable(i)
11481378 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
11491379
11501380
11511381
11521382 @Callable(i)
11531383 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
11541384
11551385
11561386
11571387 @Callable(i)
11581388 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
11591389 let prices = calcPrices(amAmt, prAmt, lpAmt)
11601390 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
11611391 }
11621392
11631393
11641394
11651395 @Callable(i)
11661396 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
11671397
11681398
11691399
11701400 @Callable(i)
11711401 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
11721402
11731403
11741404
11751405 @Callable(i)
11761406 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
11771407
11781408
11791409
11801410 @Callable(i)
11811411 func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
11821412
11831413
11841414
11851415 @Callable(i)
11861416 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
11871417 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
11881418 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
11891419 }
11901420
11911421
11921422
11931423 @Callable(i)
11941424 func statsREADONLY () = {
11951425 let cfg = getPoolConfig()
11961426 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
11971427 let amtAssetId = cfg[idxAmtAssetId]
11981428 let priceAssetId = cfg[idxPriceAssetId]
11991429 let iAmtAssetId = cfg[idxIAmtAssetId]
12001430 let iPriceAssetId = cfg[idxIPriceAssetId]
12011431 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
12021432 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
12031433 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
12041434 let accAmtAssetBalance = getAccBalance(amtAssetId)
12051435 let accPriceAssetBalance = getAccBalance(priceAssetId)
12061436 let pricesList = if ((poolLPBalance == 0))
12071437 then [zeroBigInt, zeroBigInt, zeroBigInt]
12081438 else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
12091439 let curPrice = 0
12101440 let lpAmtAssetShare = fromX18(pricesList[1], scale8)
12111441 let lpPriceAssetShare = fromX18(pricesList[2], scale8)
12121442 let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
12131443 $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))
12141444 }
12151445
12161446
12171447
12181448 @Callable(i)
12191449 func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
12201450 let cfg = getPoolConfig()
12211451 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
12221452 let amAssetIdStr = cfg[idxAmtAssetId]
12231453 let amAssetId = fromBase58String(amAssetIdStr)
12241454 let prAssetIdStr = cfg[idxPriceAssetId]
12251455 let prAssetId = fromBase58String(prAssetIdStr)
12261456 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
12271457 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
12281458 let poolStatus = cfg[idxPoolStatus]
12291459 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
12301460 let accAmtAssetBalance = getAccBalance(amAssetIdStr)
12311461 let accPriceAssetBalance = getAccBalance(prAssetIdStr)
12321462 let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
12331463 let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
12341464 let curPriceX18 = if ((poolLPBalance == 0))
12351465 then zeroBigInt
12361466 else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
12371467 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
12381468 let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
12391469 let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
12401470 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
12411471 let calcLpAmt = estPut._1
12421472 let curPriceCalc = estPut._3
12431473 let amBalance = estPut._4
12441474 let prBalance = estPut._5
12451475 let lpEmission = estPut._6
12461476 $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))
12471477 }
12481478
12491479
12501480
12511481 @Callable(i)
12521482 func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
12531483 let cfg = getPoolConfig()
12541484 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
12551485 let amAssetIdStr = cfg[idxAmtAssetId]
12561486 let amAssetId = fromBase58String(amAssetIdStr)
12571487 let prAssetIdStr = cfg[idxPriceAssetId]
12581488 let prAssetId = fromBase58String(prAssetIdStr)
12591489 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
12601490 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
12611491 let poolStatus = cfg[idxPoolStatus]
12621492 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
12631493 let amBalanceRaw = getAccBalance(amAssetIdStr)
12641494 let prBalanceRaw = getAccBalance(prAssetIdStr)
12651495 let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
12661496 let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
12671497 let curPriceX18 = if ((poolLPBalance == 0))
12681498 then zeroBigInt
12691499 else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
12701500 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
12711501 let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
12721502 let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
12731503 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
12741504 let calcLpAmt = estPut._1
12751505 let curPriceCalc = estPut._3
12761506 let amBalance = estPut._4
12771507 let prBalance = estPut._5
12781508 let lpEmission = estPut._6
12791509 $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))
12801510 }
12811511
12821512
12831513
12841514 @Callable(i)
12851515 func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
12861516 let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
12871517 let outAmAmt = res._1
12881518 let outPrAmt = res._2
12891519 let amBalance = res._5
12901520 let prBalance = res._6
12911521 let lpEmission = res._7
12921522 let curPrice = res._8
12931523 let poolStatus = parseIntValue(res._9)
12941524 $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))
12951525 }
12961526
12971527
12981528 @Verifier(tx)
12991529 func verify () = {
13001530 let targetPublicKey = match managerPublicKeyOrUnit() {
13011531 case pk: ByteVector =>
13021532 pk
13031533 case _: Unit =>
13041534 tx.senderPublicKey
13051535 case _ =>
13061536 throw("Match error")
13071537 }
13081538 match tx {
13091539 case order: Order =>
13101540 let matcherPub = getMatcherPubOrFail()
1311- let orderValid = validateMatcherOrderAllowed(order)
1541+ let $t05970359772 = validateMatcherOrderAllowed(order)
1542+ let orderValid = $t05970359772._1
1543+ let orderValidInfo = $t05970359772._2
13121544 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
13131545 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
13141546 if (if (if (orderValid)
13151547 then senderValid
13161548 else false)
13171549 then matcherValid
13181550 else false)
13191551 then true
1320- else throwOrderError(orderValid, senderValid, matcherValid)
1552+ else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
13211553 case s: SetScriptTransaction =>
1322- let newHash = blake2b256(value(s.script))
1323- let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
1324- let currentHash = scriptHash(this)
1325- if (if ((allowedHash == newHash))
1326- then (currentHash != newHash)
1327- else false)
1554+ if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
13281555 then true
1329- else sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
1556+ else {
1557+ let newHash = blake2b256(value(s.script))
1558+ let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
1559+ let currentHash = scriptHash(this)
1560+ if ((allowedHash == newHash))
1561+ then (currentHash != newHash)
1562+ else false
1563+ }
13301564 case _ =>
13311565 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
13321566 }
13331567 }
13341568

github/deemru/w8io/3ef1775 
250.62 ms