tx · HU87DcbYa6gkgK6TsWBzv6g6GoAUnvEZsSd5JvXbkGoH

3MqGtuaL3yJbKHqUxnSihJmYroyPf6QDp1x:  -0.04200000 Waves

2023.06.20 15:11 [2630945] smart account 3MqGtuaL3yJbKHqUxnSihJmYroyPf6QDp1x > SELF 0.00000000 Waves

{ "type": 13, "id": "HU87DcbYa6gkgK6TsWBzv6g6GoAUnvEZsSd5JvXbkGoH", "fee": 4200000, "feeAssetId": null, "timestamp": 1687263124165, "version": 2, "chainId": 84, "sender": "3MqGtuaL3yJbKHqUxnSihJmYroyPf6QDp1x", "senderPublicKey": "HNMWjb4Vq8JwETf7kHV57gaKXLvsdCS5KPTaHKa4XKa6", "proofs": [ "4DvB4FgkJEC8hx2SEk9FQZcJjJXY5BnL4TtYscpLEVataZYzBTSC6EEAVR7YgTbLMyFGjw59SkP29vv8HpZXpbFW" ], "script": "base64:BgKSOAgCEgASBQoDAQQBEgcKBQEEAQgBEgQKAgEEEgMKAQESBAoCAQQSBAoCCAESBAoCCAESBAoCCAESBQoDAQgBEgASBAoCAQESAwoBARIFCgMBAQESBAoCCAgSABIAEgMKAQgSBQoDAQEBEgQKAgEBEgQKAggBEgQKAggIEgsKCQgBAQIBAggEBBIGCgQICAEIEgASAwoBARIDCgEBEgQKAggBIgpsUGRlY2ltYWxzIgZzY2FsZTgiDHNjYWxlOEJpZ0ludCIHc2NhbGUxOCIKemVyb0JpZ0ludCIEYmlnMCIEYmlnMSIEYmlnMiILd2F2ZXNTdHJpbmciA1NFUCIKUG9vbEFjdGl2ZSIPUG9vbFB1dERpc2FibGVkIhNQb29sTWF0Y2hlckRpc2FibGVkIgxQb29sU2h1dGRvd24iDmlkeFBvb2xBZGRyZXNzIg1pZHhQb29sU3RhdHVzIhBpZHhQb29sTFBBc3NldElkIg1pZHhBbXRBc3NldElkIg9pZHhQcmljZUFzc2V0SWQiDmlkeEFtdEFzc2V0RGNtIhBpZHhQcmljZUFzc2V0RGNtIg5pZHhJQW10QXNzZXRJZCIQaWR4SVByaWNlQXNzZXRJZCINaWR4TFBBc3NldERjbSISaWR4UG9vbEFtdEFzc2V0QW10IhRpZHhQb29sUHJpY2VBc3NldEFtdCIRaWR4UG9vbExQQXNzZXRBbXQiGWlkeEZhY3RvcnlTdGFraW5nQ29udHJhY3QiGmlkeEZhY3RvcnlTbGlwcGFnZUNvbnRyYWN0IgV0b1gxOCIHb3JpZ1ZhbCINb3JpZ1NjYWxlTXVsdCILdG9YMThCaWdJbnQiB2Zyb21YMTgiA3ZhbCIPcmVzdWx0U2NhbGVNdWx0Igxmcm9tWDE4Um91bmQiBXJvdW5kIgd0b1NjYWxlIgNhbXQiCHJlc1NjYWxlIghjdXJTY2FsZSIDYWJzIglhYnNCaWdJbnQiDHN3YXBDb250cmFjdCICZmMiE2tleU1hbmFnZXJQdWJsaWNLZXkiFmtleU1hbmFnZXJWYXVsdEFkZHJlc3MiAnBsIgJwaCIBaCIJdGltZXN0YW1wIgNwYXUiC3VzZXJBZGRyZXNzIgR0eElkIgNnYXUiAmFhIgJwYSIGa2V5RmVlIgpmZWVEZWZhdWx0IgNmZWUiBmtleUtMcCIVa2V5S0xwUmVmcmVzaGVkSGVpZ2h0IhJrZXlLTHBSZWZyZXNoRGVsYXkiFmtMcFJlZnJlc2hEZWxheURlZmF1bHQiD2tMcFJlZnJlc2hEZWxheSIUa2V5QWRkaXRpb25hbEJhbGFuY2UiB2Fzc2V0SWQiFmtleVN0YWtpbmdBc3NldEJhbGFuY2UiGmdldEFkZGl0aW9uYWxCYWxhbmNlT3JaZXJvIhxnZXRTdGFraW5nQXNzZXRCYWxhbmNlT3JaZXJvIhBrZXlGYWN0b3J5Q29uZmlnIg1rZXlNYXRjaGVyUHViIilrZXlNYXBwaW5nUG9vbENvbnRyYWN0QWRkcmVzc1RvUG9vbEFzc2V0cyITcG9vbENvbnRyYWN0QWRkcmVzcyINa2V5UG9vbENvbmZpZyIJaUFtdEFzc2V0IgtpUHJpY2VBc3NldCIfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZCIMYmFzZUFzc2V0U3RyIhNrZXlBbGxQb29sc1NodXRkb3duIg1rZXlQb29sV2VpZ2h0Ig9jb250cmFjdEFkZHJlc3MiFmtleUFsbG93ZWRMcFNjcmlwdEhhc2giFmtleUZlZUNvbGxlY3RvckFkZHJlc3MiFmtleVNraXBPcmRlclZhbGlkYXRpb24iC3Bvb2xBZGRyZXNzIg90aHJvd09yZGVyRXJyb3IiCm9yZGVyVmFsaWQiDm9yZGVyVmFsaWRJbmZvIgtzZW5kZXJWYWxpZCIMbWF0Y2hlclZhbGlkIhdhZGRyZXNzRnJvbVN0cmluZ09yVGhpcyINYWRkcmVzc1N0cmluZyIHJG1hdGNoMCIBYSIcZ2V0TWFuYWdlclZhdWx0QWRkcmVzc09yVGhpcyIOZmFjdG9yeUFkZHJlc3MiA2ZjYSIBcyIPZ2V0U3RyaW5nT3JGYWlsIgdhZGRyZXNzIgNrZXkiDGdldEludE9yRmFpbCIIdGhyb3dFcnIiA21zZyIGZm10RXJyIg9mYWN0b3J5Q29udHJhY3QiE2ZlZUNvbGxlY3RvckFkZHJlc3MiBWluRmVlIgFAIgZvdXRGZWUiEGlzR2xvYmFsU2h1dGRvd24iE2dldE1hdGNoZXJQdWJPckZhaWwiDWdldFBvb2xDb25maWciCGFtdEFzc2V0IgpwcmljZUFzc2V0IgxwYXJzZUFzc2V0SWQiBWlucHV0Ig9hc3NldElkVG9TdHJpbmciD3BhcnNlUG9vbENvbmZpZyIKcG9vbENvbmZpZyIQcG9vbENvbmZpZ1BhcnNlZCILJHQwOTUyOTk2OTUiDmNmZ1Bvb2xBZGRyZXNzIg1jZmdQb29sU3RhdHVzIgxjZmdMcEFzc2V0SWQiEGNmZ0Ftb3VudEFzc2V0SWQiD2NmZ1ByaWNlQXNzZXRJZCIWY2ZnQW1vdW50QXNzZXREZWNpbWFscyIVY2ZnUHJpY2VBc3NldERlY2ltYWxzIhBnZXRGYWN0b3J5Q29uZmlnIg9zdGFraW5nQ29udHJhY3QiEHNsaXBwYWdlQ29udHJhY3QiEWRhdGFQdXRBY3Rpb25JbmZvIg1pbkFtdEFzc2V0QW10Ig9pblByaWNlQXNzZXRBbXQiCG91dExwQW10IgVwcmljZSIdc2xpcHBhZ2VUb2xlcmFuY2VQYXNzZWRCeVVzZXIiFXNsaXBwYWdlVG9sZXJhbmNlUmVhbCIIdHhIZWlnaHQiC3R4VGltZXN0YW1wIhJzbGlwYWdlQW10QXNzZXRBbXQiFHNsaXBhZ2VQcmljZUFzc2V0QW10IhFkYXRhR2V0QWN0aW9uSW5mbyIOb3V0QW10QXNzZXRBbXQiEG91dFByaWNlQXNzZXRBbXQiB2luTHBBbXQiDWdldEFjY0JhbGFuY2UiDWJhbGFuY2VPblBvb2wiDHRvdGFsQmFsYW5jZSIPY2FsY1ByaWNlQmlnSW50IghwckFtdFgxOCIIYW1BbXRYMTgiFGNhbGNQcmljZUJpZ0ludFJvdW5kIgdnZXRSYXRlIgVwcm94eSIDaW52IgFyIgdkZXBvc2l0IgZhbW91bnQiDnN0YWtpbmdBc3NldElkIhhjdXJyZW50QWRkaXRpb25hbEJhbGFuY2UiGmN1cnJlbnRTdGFraW5nQXNzZXRCYWxhbmNlIgVhc3NldCINZGVwb3NpdEludm9rZSIUcmVjZWl2ZWRTdGFraW5nQXNzZXQiFG5ld0FkZGl0aW9uYWxCYWxhbmNlIhZuZXdTdGFraW5nQXNzZXRCYWxhbmNlIgh3aXRoZHJhdyIMcHJveHlSYXRlTXVsIg1wcm9maXRBZGRyZXNzIhBjdXJyZW50UHJveHlSYXRlIgdvbGRSYXRlIgxzdGFraW5nQXNzZXQiFG9sZFNlbmRTdGFraW5nQW1vdW50IhZzZW5kU3Rha2luZ0Fzc2V0QW1vdW50Igxwcm9maXRBbW91bnQiDndpdGhkcmF3SW52b2tlIg5yZWNlaXZlZEFzc2V0cyITZ2V0TGVhc2VQcm94eUNvbmZpZyIRcmViYWxhbmNlSW50ZXJuYWwiC3RhcmdldFJhdGlvIgptaW5CYWxhbmNlIhRsZWFzYWJsZVRvdGFsQmFsYW5jZSIXdGFyZ2V0QWRkaXRpb25hbEJhbGFuY2UiBGRpZmYiD3NlbmRBc3NldEFtb3VudCIOZ2V0QXNzZXRBbW91bnQiDnJlYmFsYW5jZUFzc2V0Ig0kdDAxNTkzMTE2MDY3Igppc0xlYXNhYmxlIgtsZWFzZWRSYXRpbyIMcHJveHlBZGRyZXNzIgxwcm94eUFzc2V0SWQiFHN0YWtpbmdQcm9maXRBZGRyZXNzIhl3aXRoZHJhd0FuZFJlYmFsYW5jZUFzc2V0IglnZXRBbW91bnQiDSR0MDE2NDY2MTY2MDIiF25ld1RvdGFsTGVhc2FibGVCYWxhbmNlIg53aXRoZHJhd0Ftb3VudCIXd2l0aGRyYXdBbmRSZWJhbGFuY2VBbGwiFGFtb3VudEFzc2V0T3V0QW1vdW50IhNwcmljZUFzc2V0T3V0QW1vdW50IhJBbUFtdFdpdGhkcmF3U3RhdGUiElByQW10V2l0aGRyYXdTdGF0ZSIQcHJpdmF0ZUNhbGNQcmljZSIKYW1Bc3NldERjbSIKcHJBc3NldERjbSIFYW1BbXQiBXByQW10Ig5hbXRBc3NldEFtdFgxOCIQcHJpY2VBc3NldEFtdFgxOCIKY2FsY1ByaWNlcyIFbHBBbXQiA2NmZyILYW10QXNzZXREY20iDXByaWNlQXNzZXREY20iCHByaWNlWDE4IghscEFtdFgxOCITbHBQcmljZUluQW1Bc3NldFgxOCITbHBQcmljZUluUHJBc3NldFgxOCIPY2FsY3VsYXRlUHJpY2VzIgZwcmljZXMiFGVzdGltYXRlR2V0T3BlcmF0aW9uIgZ0eElkNTgiCnBtdEFzc2V0SWQiCHBtdExwQW10IglscEFzc2V0SWQiCWFtQXNzZXRJZCIJcHJBc3NldElkIgpwb29sU3RhdHVzIgpscEVtaXNzaW9uIglhbUJhbGFuY2UiDGFtQmFsYW5jZVgxOCIJcHJCYWxhbmNlIgxwckJhbGFuY2VYMTgiC2N1clByaWNlWDE4IghjdXJQcmljZSILcG10THBBbXRYMTgiDWxwRW1pc3Npb25YMTgiC291dEFtQW10WDE4IgtvdXRQckFtdFgxOCIIb3V0QW1BbXQiCG91dFByQW10IgVzdGF0ZSIUZXN0aW1hdGVQdXRPcGVyYXRpb24iEXNsaXBwYWdlVG9sZXJhbmNlIgxpbkFtQXNzZXRBbXQiC2luQW1Bc3NldElkIgxpblByQXNzZXRBbXQiC2luUHJBc3NldElkIgppc0V2YWx1YXRlIgZlbWl0THAiDGFtQXNzZXRJZFN0ciIMcHJBc3NldElkU3RyIgtpQW10QXNzZXRJZCINaVByaWNlQXNzZXRJZCIOaW5BbUFzc2V0SWRTdHIiDmluUHJBc3NldElkU3RyIg9pbkFtQXNzZXRBbXRYMTgiD2luUHJBc3NldEFtdFgxOCIMdXNlclByaWNlWDE4IgNyZXMiC3NsaXBwYWdlWDE4IhRzbGlwcGFnZVRvbGVyYW5jZVgxOCIKcHJWaWFBbVgxOCIKYW1WaWFQclgxOCIMZXhwZWN0ZWRBbXRzIhFleHBBbXRBc3NldEFtdFgxOCITZXhwUHJpY2VBc3NldEFtdFgxOCIJY2FsY0xwQW10Ig5jYWxjQW1Bc3NldFBtdCIOY2FsY1ByQXNzZXRQbXQiDHNsaXBwYWdlQ2FsYyIJZW1pdExwQW10IgZhbURpZmYiBnByRGlmZiILY29tbW9uU3RhdGUiB2NhbGNLTHAiDWFtb3VudEJhbGFuY2UiDHByaWNlQmFsYW5jZSIQYW1vdW50QmFsYW5jZVgxOCIPcHJpY2VCYWxhbmNlWDE4Igp1cGRhdGVkS0xwIg5jYWxjQ3VycmVudEtMcCIQYW1vdW50QXNzZXREZWx0YSIPcHJpY2VBc3NldERlbHRhIhRscEFzc2V0RW1pc3Npb25EZWx0YSISYW1vdW50QXNzZXRCYWxhbmNlIhFwcmljZUFzc2V0QmFsYW5jZSIPbHBBc3NldEVtaXNzaW9uIgpjdXJyZW50S0xwIhJyZWZyZXNoS0xwSW50ZXJuYWwiF2Ftb3VudEFzc2V0QmFsYW5jZURlbHRhIhZwcmljZUFzc2V0QmFsYW5jZURlbHRhIgdhY3Rpb25zIhNza2lwT3JkZXJWYWxpZGF0aW9uIhJ2YWxpZGF0ZVVwZGF0ZWRLTHAiBm9sZEtMcCIbdmFsaWRhdGVNYXRjaGVyT3JkZXJBbGxvd2VkIgVvcmRlciIRYW1vdW50QXNzZXRBbW91bnQiEHByaWNlQXNzZXRBbW91bnQiDSR0MDI4OTkxMjkyMDMiA2tMcCINJHQwMjk2NDMyOTc0MyINdW51c2VkQWN0aW9ucyIGa0xwTmV3Igxpc09yZGVyVmFsaWQiBGluZm8iCWNvbW1vbkdldCIBaSIDcG10IgZwbXRBbXQiCWNvbW1vblB1dCIKYW1Bc3NldFBtdCIKcHJBc3NldFBtdCIGZXN0UHV0IgRlbWl0IgdlbWl0SW52Ig1lbWl0SW52TGVnYWN5IhVsZWdhY3lGYWN0b3J5Q29udHJhY3QiB3Rha2VGZWUiCWZlZUFtb3VudCIPY2FsY1B1dE9uZVRva2VuIhBwYXltZW50QW1vdW50UmF3Ig5wYXltZW50QXNzZXRJZCIGaXNFdmFsIhBhbW91bnRCYWxhbmNlUmF3Ig9wcmljZUJhbGFuY2VSYXciFHBheW1lbnRJbkFtb3VudEFzc2V0Ig0kdDAzMjg1NjMzMTQ5IhBhbW91bnRCYWxhbmNlT2xkIg9wcmljZUJhbGFuY2VPbGQiDSR0MDMzMTUzMzMzMDIiFGFtb3VudEFzc2V0QW1vdW50UmF3IhNwcmljZUFzc2V0QW1vdW50UmF3Ig0kdDAzMzQzNDMzNDk4Ig1wYXltZW50QW1vdW50IhBhbW91bnRCYWxhbmNlTmV3Ig9wcmljZUJhbGFuY2VOZXciC3ByaWNlTmV3WDE4IghwcmljZU5ldyIOcGF5bWVudEJhbGFuY2UiFHBheW1lbnRCYWxhbmNlQmlnSW50IgxzdXBwbHlCaWdJbnQiC2NoZWNoU3VwcGx5Ig1kZXBvc2l0QmlnSW50Igtpc3N1ZUFtb3VudCILcHJpY2VPbGRYMTgiCHByaWNlT2xkIgRsb3NzIg0kdDAzNTE3OTM1MzQ2IgdiYWxhbmNlIg9pc3N1ZUFtb3VudEJvdGgiD2NhbGNHZXRPbmVUb2tlbiIKb3V0QXNzZXRJZCIGY2hlY2tzIhBvdXRJbkFtb3VudEFzc2V0Ig1iYWxhbmNlQmlnSW50IhhvdXRJbkFtb3VudEFzc2V0RGVjaW1hbHMiDGFtQmFsYW5jZU9sZCIMcHJCYWxhbmNlT2xkIgpvdXRCYWxhbmNlIhBvdXRCYWxhbmNlQmlnSW50Ig5yZWRlZW1lZEJpZ0ludCIJYW1vdW50UmF3Ig0kdDAzNzQyNDM3NDgwIgt0b3RhbEFtb3VudCINJHQwMzc0ODQzNzcxMCILb3V0QW1BbW91bnQiC291dFByQW1vdW50IgxhbUJhbGFuY2VOZXciDHByQmFsYW5jZU5ldyIYYW1vdW50Qm90aEluUGF5bWVudEFzc2V0IhZtYW5hZ2VyUHVibGljS2V5T3JVbml0IhNtYW5hZ2VyVmF1bHRBZGRyZXNzIglpc01hbmFnZXIiAnBrIgttdXN0TWFuYWdlciICcGQiDWNsZWFuQW1vdW50SW4iCWlzUmV2ZXJzZSINZmVlUG9vbEFtb3VudCINJHQwMzk1NjkzOTg3NCIIYXNzZXRPdXQiB2Fzc2V0SW4iEnBvb2xBc3NldEluQmFsYW5jZSITcG9vbEFzc2V0T3V0QmFsYW5jZSIJYW1vdW50T3V0IgRvbGRLIgRuZXdLIgZjaGVja0siDGFtb3VudE91dE1pbiIJYWRkcmVzc1RvIgtzd2FwQ29udGFjdCIIY2hlY2tNaW4iDnJlYmFsYW5jZVN0YXRlIg13aXRoZHJhd1N0YXRlIg9zaG91bGRBdXRvU3Rha2UiBGFtSWQiBHBySWQiDHNsaXBwYWdlQUludiIMc2xpcHBhZ2VQSW52IgpscFRyYW5zZmVyIgtzbHBTdGFrZUludiINJHQwNDQzNjE0NDgyMyIRcmVmcmVzaEtMcEFjdGlvbnMiEWlzVXBkYXRlZEtMcFZhbGlkIgNyZWIiC21heFNsaXBwYWdlIg0kdDA0NTQzNTQ1NTAwIgxtaW5PdXRBbW91bnQiCWF1dG9TdGFrZSIgaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWQiDWlzUHV0RGlzYWJsZWQiB3BheW1lbnQiDSR0MDQ2Njg4NDY4NDAiBWJvbnVzIhNlbWl0QW1vdW50RXN0aW1hdGVkIgplbWl0QW1vdW50IghzdGFrZUludiIHc2VuZEZlZSINJHQwNDc0MjY0NzYyMyINJHQwNDc2MjY0NzczNCINJHQwNDgwODk0ODI0NiINb3V0QXNzZXRJZFN0ciINaXNHZXREaXNhYmxlZCINJHQwNDkxMzE0OTI4NCIPYW1vdW50RXN0aW1hdGVkIgdidXJuSW52Ig1hc3NldFRyYW5zZmVyIg0kdDA0OTk0ODUwMTk1IhBmZWVBbW91bnRGb3JDYWxjIg0kdDA1MDE5ODUwMzA2Ig0kdDA1MDU4NDUwNzQwIg11bnN0YWtlQW1vdW50Igp1bnN0YWtlSW52Ig0kdDA1MTY0NTUxNzk2Ig0kdDA1MjQ1NTUyNzAyIg0kdDA1MjcwNTUyODEzIhRidXJuTFBBc3NldE9uRmFjdG9yeSINJHQwNTM5MDg1Mzk4OSISbm9MZXNzVGhlbkFtdEFzc2V0IhRub0xlc3NUaGVuUHJpY2VBc3NldCINJHQwNTUwODQ1NTE2NSINY2hlY2tQYXltZW50cyIPY2hlY2tQb29sU3RhdHVzIg0kdDA1NjQzNzU2NTE4IhVub0xlc3NUaGVuQW1vdW50QXNzZXQiDGNoZWNrQW1vdW50cyINJHQwNTc5NTk1ODA0MCILYW10QXNzZXRTdHIiDXByaWNlQXNzZXRTdHIiGGxhc3RSZWZyZXNoZWRCbG9ja0hlaWdodCIdY2hlY2tMYXN0UmVmcmVzaGVkQmxvY2tIZWlnaHQiDSR0MDU5MjQ0NTkzMDgiEGtMcFVwZGF0ZUFjdGlvbnMiCmFtdEFzc2V0SWQiDHByaWNlQXNzZXRJZCINcG9vbExQQmFsYW5jZSISYWNjQW10QXNzZXRCYWxhbmNlIhRhY2NQcmljZUFzc2V0QmFsYW5jZSIKcHJpY2VzTGlzdCIPbHBBbXRBc3NldFNoYXJlIhFscFByaWNlQXNzZXRTaGFyZSIKcG9vbFdlaWdodCIMY3VyUHJpY2VDYWxjIgxhbUJhbGFuY2VSYXciDHByQmFsYW5jZVJhdyIPYW1CYWxhbmNlUmF3WDE4Ig9wckJhbGFuY2VSYXdYMTgiEHBheW1lbnRMcEFzc2V0SWQiDHBheW1lbnRMcEFtdCICdHgiBnZlcmlmeSIPdGFyZ2V0UHVibGljS2V5IgptYXRjaGVyUHViIg0kdDA2Nzk3MDY4MDg3IgduZXdIYXNoIgthbGxvd2VkSGFzaCILY3VycmVudEhhc2iCAQABYQAIAAFiAIDC1y8AAWMJALYCAQCAwtcvAAFkCQC2AgEAgICQu7rWrfANAAFlCQC2AgEAAAABZgkAtgIBAAAAAWcJALYCAQABAAFoCQC2AgEAAgABaQIFV0FWRVMAAWoCAl9fAAFrAAEAAWwAAgABbQADAAFuAAQAAW8AAQABcAACAAFxAAMAAXIABAABcwAFAAF0AAYAAXUABwABdgAIAAF3AAkAAXgACgABeQABAAF6AAIAAUEAAwABQgABAAFDAAcBAUQCAUUBRgkAvAIDCQC2AgEFAUUFAWQJALYCAQUBRgEBRwIBRQFGCQC8AgMFAUUFAWQFAUYBAUgCAUkBSgkAoAMBCQC8AgMFAUkJALYCAQUBSgUBZAEBSwMBSQFKAUwJAKADAQkAvQIEBQFJCQC2AgEFAUoFAWQFAUwBAU0DAU4BTwFQCQBrAwUBTgUBTwUBUAEBUQEBSQMJAGYCAAAFAUkJAQEtAQUBSQUBSQEBUgEBSQMJAL8CAgUBZQUBSQkAvgIBBQFJBQFJAQFTAAIQJXNfX3N3YXBDb250cmFjdAEBVAACEyVzX19mYWN0b3J5Q29udHJhY3QBAVUAAhQlc19fbWFuYWdlclB1YmxpY0tleQEBVgACFyVzX19tYW5hZ2VyVmF1bHRBZGRyZXNzAQFXAAIRJXMlc19fcHJpY2VfX2xhc3QBAVgCAVkBWgkAuQkCCQDMCAICGCVzJXMlZCVkX19wcmljZV9faGlzdG9yeQkAzAgCCQCkAwEFAVkJAMwIAgkApAMBBQFaBQNuaWwFAWoBAmFhAgJhYgJhYwkArAICCQCsAgIJAKwCAgILJXMlcyVzX19QX18FAmFiAgJfXwUCYWMBAmFkAgJhYgJhYwkArAICCQCsAgIJAKwCAgILJXMlcyVzX19HX18FAmFiAgJfXwUCYWMBAmFlAAIPJXNfX2Ftb3VudEFzc2V0AQJhZgACDiVzX19wcmljZUFzc2V0AAJhZwIHJXNfX2ZlZQACYWgJAGsDAAoFAWIAkE4AAmFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAmFnBQJhaAACYWoJALkJAgkAzAgCAgIlcwkAzAgCAgNrTHAFA25pbAUBagACYWsJALkJAgkAzAgCAgIlcwkAzAgCAhJrTHBSZWZyZXNoZWRIZWlnaHQFA25pbAUBagACYWwJALkJAgkAzAgCAgIlcwkAzAgCAg9yZWZyZXNoS0xwRGVsYXkFA25pbAUBagACYW0AHgACYW4JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUCYWwFAmFtAQJhbwECYXAJALkJAgkAzAgCAgQlcyVzCQDMCAICDXN0YWtlZEJhbGFuY2UJAMwIAgUCYXAFA25pbAUBagECYXEBAmFwCQC5CQIJAMwIAgIEJXMlcwkAzAgCAhFzaGFyZUFzc2V0QmFsYW5jZQkAzAgCBQJhcAUDbmlsBQFqAQJhcgECYXAJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmFvAQUCYXAAAAECYXMBAmFwCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQJhcQEFAmFwAAABAmF0AAIRJXNfX2ZhY3RvcnlDb25maWcBAmF1AAIYJXMlc19fbWF0Y2hlcl9fcHVibGljS2V5AQJhdgECYXcJAKwCAgkArAICAgglcyVzJXNfXwUCYXcCIF9fbWFwcGluZ3NfX3Bvb2xDb250cmFjdDJMcEFzc2V0AQJheAICYXkCYXoJAKwCAgkArAICCQCsAgIJAKwCAgIIJWQlZCVzX18FAmF5AgJfXwUCYXoCCF9fY29uZmlnAQJhQQECYUIJAKwCAgIoJXMlcyVzX19tYXBwaW5nc19fYmFzZUFzc2V0MmludGVybmFsSWRfXwUCYUIBAmFDAAIMJXNfX3NodXRkb3duAQJhRAECYUUJAKwCAgISJXMlc19fcG9vbFdlaWdodF9fBQJhRQECYUYAAhclc19fYWxsb3dlZExwU2NyaXB0SGFzaAACYUcCFyVzX19mZWVDb2xsZWN0b3JBZGRyZXNzAQJhSAECYUkJAKwCAgIbJXMlc19fc2tpcE9yZGVyVmFsaWRhdGlvbl9fBQJhSQECYUoEAmFLAmFMAmFNAmFOCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICJG9yZGVyIHZhbGlkYXRpb24gZmFpbGVkOiBvcmRlclZhbGlkPQkApQMBBQJhSwICICgFAmFMAgEpAg0gc2VuZGVyVmFsaWQ9CQClAwEFAmFNAg4gbWF0Y2hlclZhbGlkPQkApQMBBQJhTgECYU8BAmFQBAJhUQkApggBBQJhUAMJAAECBQJhUQIHQWRkcmVzcwQCYVIFAmFRBQJhUgUEdGhpcwECYVMABAJhVAQCYVEJAKIIAQkBAVQAAwkAAQIFAmFRAgZTdHJpbmcEAmFVBQJhUQkBAmFPAQUCYVUFBHRoaXMEAmFRCQCdCAIFAmFUCQEBVgADCQABAgUCYVECBlN0cmluZwQCYVYFAmFRCQECYU8BBQJhVgUEdGhpcwECYVcCAmFYAmFZCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUCYVgFAmFZCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmFYCQDMCAICAS4JAMwIAgUCYVkJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAECYVoCAmFYAmFZCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUCYVgFAmFZCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmFYCQDMCAICAS4JAMwIAgUCYVkJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAECYmEBAmJiCQACAQkAuQkCCQDMCAICCGxwLnJpZGU6CQDMCAIFAmJiBQNuaWwCASABAmJjAQJiYgkAuQkCCQDMCAICCGxwLnJpZGU6CQDMCAIFAmJiBQNuaWwCASAAAmJkCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYVcCBQR0aGlzCQEBVAAAAmJlCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYVcCBQJiZAUCYUcAAmJmCgACYmcJAPwHBAUCYmQCEGdldEluRmVlUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJiZwIDSW50BQJiZwkAAgEJAKwCAgkAAwEFAmJnAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQAAmJoCgACYmcJAPwHBAUCYmQCEWdldE91dEZlZVJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYmcCA0ludAUCYmcJAAIBCQCsAgIJAAMBBQJiZwIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AQJiaQAJAQt2YWx1ZU9yRWxzZQIJAJsIAgUCYmQJAQJhQwAHAQJiagAJANkEAQkBAmFXAgUCYmQJAQJhdQABAmJrAAQCYmwJAQJhVwIFBHRoaXMJAQJhZQAEAmJtCQECYVcCBQR0aGlzCQECYWYABAJhegkBAmFaAgUCYmQJAQJhQQEFAmJtBAJheQkBAmFaAgUCYmQJAQJhQQEFAmJsCQC1CQIJAQJhVwIFAmJkCQECYXgCCQCkAwEFAmF5CQCkAwEFAmF6BQFqAQJibgECYm8DCQAAAgUCYm8FAWkFBHVuaXQJANkEAQUCYm8BAmJwAQJibwMJAAACBQJibwUEdW5pdAUBaQkA2AQBCQEFdmFsdWUBBQJibwECYnEBAmJyCQCZCgcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYnIFAW8JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJicgUBcAkA2QQBCQCRAwIFAmJyBQFxCQECYm4BCQCRAwIFAmJyBQFyCQECYm4BCQCRAwIFAmJyBQFzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYnIFAXQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJicgUBdQACYnMJAQJicQEJAQJiawAAAmJ0BQJicwACYnUIBQJidAJfMQACYnYIBQJidAJfMgACYncIBQJidAJfMwACYngIBQJidAJfNAACYnkIBQJidAJfNQACYnoIBQJidAJfNgACYkEIBQJidAJfNwECYkIACQC1CQIJAQJhVwIFAmJkCQECYXQABQFqAAJiQwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgkBAmJCAAUBQgIZaW5jb3JyZWN0IHN0YWtpbmcgYWRkcmVzcwACYkQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIJAQJiQgAFAUMCGWluY29ycmVjdCBzdGFraW5nIGFkZHJlc3MBAmJFCgJiRgJiRwJiSAJiSQJiSgJiSwJiTAJiTQJiTgJiTwkAuQkCCQDMCAICFCVkJWQlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYkYJAMwIAgkApAMBBQJiRwkAzAgCCQCkAwEFAmJICQDMCAIJAKQDAQUCYkkJAMwIAgkApAMBBQJiSgkAzAgCCQCkAwEFAmJLCQDMCAIJAKQDAQUCYkwJAMwIAgkApAMBBQJiTQkAzAgCCQCkAwEFAmJOCQDMCAIJAKQDAQUCYk8FA25pbAUBagECYlAGAmJRAmJSAmJTAmJJAmJMAmJNCQC5CQIJAMwIAgIMJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYlEJAMwIAgkApAMBBQJiUgkAzAgCCQCkAwEFAmJTCQDMCAIJAKQDAQUCYkkJAMwIAgkApAMBBQJiTAkAzAgCCQCkAwEFAmJNBQNuaWwFAWoBAmJUAQJhcAQCYlUDCQAAAgUCYXACBVdBVkVTCAkA7wcBBQR0aGlzCWF2YWlsYWJsZQkA8AcCBQR0aGlzCQDZBAEFAmFwBAJiVgkAZQIJAGQCBQJiVQkBAmFyAQUCYXAJAQJhcwEFAmFwCQCWAwEJAMwIAgAACQDMCAIFAmJWBQNuaWwBAmJXAgJiWAJiWQkAvAIDBQJiWAUBZAUCYlkBAmJaAwJiWAJiWQFMCQC9AgQFAmJYBQFkBQJiWQUBTAECY2EBAmNiBAJjYwkA/AcEBQJjYgIHZ2V0UmF0ZQUDbmlsBQNuaWwDCQAAAgUCY2MFAmNjBAJhUQUCY2MDCQABAgUCYVECA0ludAQCY2QFAmFRBQJjZAkBAmJhAQIgcHJveHkuZ2V0UmF0ZSgpIHVuZXhwZWN0ZWQgdmFsdWUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmNlBAJhcAJjZgJjZwJjYgQCY2gJAQJhcgEFAmFwAwkAAAIFAmNoBQJjaAQCY2kJAQJhcwEFAmNnAwkAAAIFAmNpBQJjaQQCY2oJAQJibgEFAmFwAwkAZgIFAmNmAAAEAmNrCQD8BwQFAmNiAgdkZXBvc2l0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmNqBQJjZgUDbmlsAwkAAAIFAmNrBQJjawQCYVEFAmNrAwkAAQIFAmFRAgNJbnQEAmNsBQJhUQQCY20JAGQCBQJjaAUCY2YEAmNuCQBkAgUCY2kFAmNsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYW8BBQJhcAUCY20JAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhcQEFAmNnBQJjbgUDbmlsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY28GAmFwAmNmAmNnAmNiAmNwAmNxBAJjaAkBAmFyAQUCYXADCQAAAgUCY2gFAmNoBAJjaQkBAmFzAQUCY2cDCQAAAgUCY2kFAmNpBAJjcgkBAmNhAQUCY2IDCQAAAgUCY3IFAmNyBAJjcwkAawMFAmNwBQJjaAUCY2kEAmN0CQECYm4BBQJjZwQCY3UJAGsDBQJjcAUCY2YFAmNzBAJjdgkAawMFAmNwBQJjZgUCY3IEAmN3CQCWAwEJAMwIAgAACQDMCAIJAGUCBQJjdQUCY3YFA25pbAMJAGYCBQJjdgAABAJjeAkA/AcEBQJjYgIId2l0aGRyYXcFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCY3QFAmN2BQNuaWwDCQAAAgUCY3gFAmN4BAJhUQUCY3gDCQABAgUCYVECA0ludAQCY3kFAmFRBAJjbQkAZQIFAmNoBQJjeQQCY24JAGUCCQBlAgUCY2kFAmN2BQJjdwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFvAQUCYXAFAmNtCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXEBBQJjZwUCY24JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCY3EFAmN3CQECYm4BBQJjZwUDbmlsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY3oBAmFwBAJhUQkA/AcEBQJiZAIaZ2V0UG9vbExlYXNlQ29uZmlnUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzCQDMCAIFAmFwBQNuaWwFA25pbAMJAAECBQJhUQIwKEJvb2xlYW4sIEludCwgSW50LCBTdHJpbmcsIFN0cmluZywgSW50LCBTdHJpbmcpBAJhUgUCYVEFAmFSCQECYmEBCQCsAgIJAKwCAgIBWwUCYXACHV0gZ2V0TGVhc2VQcm94eUNvbmZpZygpIGVycm9yAQJjQQcCY0ICYXACY2cCY0MCY2ICY3ACY3EEAmNoCQECYXIBBQJhcAMJAAACBQJjaAUCY2gEAmNpCQECYXMBBQJjZwMJAAACBQJjaQUCY2kEAmNECQCWAwEJAMwIAgAACQDMCAIJAGUCCQECYlQBBQJhcAUCY0MFA25pbAQCY0UJAGsDBQJjQgUCY0QAZAQCY0YJAGUCBQJjaAUCY0UDCQAAAgUCY0YAAAUDbmlsAwkAZgIAAAUCY0YEAmNHCQEBLQEFAmNGCQECY2UEBQJhcAUCY0cFAmNnBQJjYgQCY0gFAmNGCQECY28GBQJhcAUCY0gFAmNnBQJjYgUCY3AFAmNxCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJjSQECYXAEAmNKCQECY3oBBQJhcAQCY0sIBQJjSgJfMQQCY0wIBQJjSgJfMgQCY0MIBQJjSgJfMwQCY00IBQJjSgJfNAQCY04IBQJjSgJfNQQCY3AIBQJjSgJfNgQCY08IBQJjSgJfNwMFAmNLCQECY0EHBQJjTAUCYXAFAmNOBQJjQwkBEUBleHRyTmF0aXZlKDEwNjIpAQUCY00FAmNwCQERQGV4dHJOYXRpdmUoMTA2MikBBQJjTwUDbmlsAQJjUAICYXACY1EEAmNSCQECY3oBBQJhcAQCY0sIBQJjUgJfMQQCY0wIBQJjUgJfMgQCY0MIBQJjUgJfMwQCY00IBQJjUgJfNAQCY04IBQJjUgJfNQQCY3AIBQJjUgJfNgQCY08IBQJjUgJfNwMFAmNLBAJjUwkAlgMBCQDMCAIAAAkAzAgCCQBlAgkAZQIJAQJiVAEFAmFwBQJjUQUCY0MFA25pbAMJAAACBQJjUwUCY1MEAmNtCQBrAwUCY0wFAmNTAGQDCQAAAgUCY20FAmNtBAJjVAkAZQIJAQJhcgEFAmFwBQJjbQMJAAACBQJjVAUCY1QDCQBmAgAABQJjVAkBAmNlBAUCYXAJAQEtAQUCY1QFAmNOCQERQGV4dHJOYXRpdmUoMTA2MikBBQJjTQkBAmNvBgUCYXAFAmNUBQJjTgkBEUBleHRyTmF0aXZlKDEwNjIpAQUCY00FAmNwCQERQGV4dHJOYXRpdmUoMTA2MikBBQJjTwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsAQJjVQICY1YCY1cEAmNYCQECY1ACCQECYVcCBQR0aGlzCQECYWUABQJjVgQCY1kJAQJjUAIJAQJhVwIFBHRoaXMJAQJhZgAFAmNXCQDOCAIFAmNYBQJjWQECY1oEAmRhAmRiAmRjAmRkBAJkZQkBAUQCBQJkYwUCZGEEAmRmCQEBRAIFAmRkBQJkYgkBAmJXAgUCZGYFAmRlAQJkZwMCZGMCZGQCZGgEAmRpCQECYmsABAJkagkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRpBQF0BAJkawkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRpBQF1BAJkbAkBAmNaBAUCZGoFAmRrBQJkYwUCZGQEAmJZCQEBRAIFAmRjBQJkagQCYlgJAQFEAgUCZGQFAmRrBAJkbQkBAUQCBQJkaAUBYgQCZG4JAQJiVwIFAmJZBQJkbQQCZG8JAQJiVwIFAmJYBQJkbQkAzAgCBQJkbAkAzAgCBQJkbgkAzAgCBQJkbwUDbmlsAQJkcAMCZGMCZGQCZGgEAmRxCQECZGcDBQJkYwUCZGQFAmRoCQDMCAIJAQFIAgkAkQMCBQJkcQAABQFiCQDMCAIJAQFIAgkAkQMCBQJkcQABBQFiCQDMCAIJAQFIAgkAkQMCBQJkcQACBQFiBQNuaWwBAmRyBAJkcwJkdAJkdQJhYgQCZGkJAQJiawAEAmR2CQCRAwIFAmRpBQFxBAJkdwkAkQMCBQJkaQUBcgQCZHgJAJEDAgUCZGkFAXMEAmRhCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGkFAXQEAmRiCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGkFAXUEAmR5CQCRAwIFAmRpBQFwBAJkeggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFAmR2CQCsAgIJAKwCAgIGQXNzZXQgBQJkdgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkDCQECIT0CBQJkdgUCZHQJAAIBAhVJbnZhbGlkIGFzc2V0IHBhc3NlZC4EAmRBCQECYlQBBQJkdwQCZEIJAQFEAgUCZEEFAmRhBAJkQwkBAmJUAQUCZHgEAmRECQEBRAIFAmRDBQJkYgQCZEUJAQJiVwIFAmREBQJkQgQCZEYJAQFIAgUCZEUFAWIEAmRHCQEBRAIFAmR1BQFiBAJkSAkBAUQCBQJkegUBYgQCZEkJALwCAwUCZEIFAmRHBQJkSAQCZEoJALwCAwUCZEQFAmRHBQJkSAQCZEsJAQFLAwUCZEkFAmRhBQVGTE9PUgQCZEwJAQFLAwUCZEoFAmRiBQVGTE9PUgQCZE0DCQAAAgUCZHMCAAUDbmlsCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFiBQJkSwMJAAACBQJkdwIFV0FWRVMFBHVuaXQJANkEAQUCZHcJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYWIFAmRMAwkAAAIFAmR4AgVXQVZFUwUEdW5pdAkA2QQBBQJkeAkAzAgCCQELU3RyaW5nRW50cnkCCQECYWQCCQClCAEFAmFiBQJkcwkBAmJQBgUCZEsFAmRMBQJkdQUCZEYFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZEYJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZEYFA25pbAkAnAoKBQJkSwUCZEwFAmR3BQJkeAUCZEEFAmRDBQJkegUCZEUFAmR5BQJkTQECZE4JAmRzAmRPAmRQAmRRAmRSAmRTAmFiAmRUAmRVBAJkaQkBAmJrAAQCZHYJANkEAQkAkQMCBQJkaQUBcQQCZFYJAJEDAgUCZGkFAXIEAmRXCQCRAwIFAmRpBQFzBAJkWAkAkQMCBQJkaQUBdgQCZFkJAJEDAgUCZGkFAXcEAmRqCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGkFAXQEAmRrCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGkFAXUEAmR5CQCRAwIFAmRpBQFwBAJkeggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJkdgkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJkdgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmRaCQDYBAEJAQt2YWx1ZU9yRWxzZQIFAmRRCQDZBAECBVdBVkVTBAJlYQkA2AQBCQELdmFsdWVPckVsc2UCBQJkUwkA2QQBAgVXQVZFUwMDCQECIT0CBQJkVgUCZFoGCQECIT0CBQJkVwUCZWEJAAIBAiJJbnZhbGlkIGFtdCBvciBwcmljZSBhc3NldCBwYXNzZWQuBAJkQQMFAmRUCQECYlQBBQJkVgkAZQIJAQJiVAEFAmRWBQJkUAQCZEMDBQJkVAkBAmJUAQUCZFcJAGUCCQECYlQBBQJkVwUCZFIEAmViCQEBRAIFAmRQBQJkagQCZWMJAQFEAgUCZFIFAmRrBAJlZAkBAmJXAgUCZWMFAmViBAJkQgkBAUQCBQJkQQUCZGoEAmRECQEBRAIFAmRDBQJkawQCZWUDCQAAAgUCZHoAAAQCZEUFAWUEAmVmBQFlBAJkbQkAdgYJALkCAgUCZWIFAmVjAAAJALYCAQAFAAEAAAUERE9XTgkAlwoFCQEBSAIFAmRtBQFiCQEBSAIFAmViBQJkagkBAUgCBQJlYwUCZGsJAQJiVwIJALcCAgUCZEQFAmVjCQC3AgIFAmRCBQJlYgUCZWYEAmRFCQECYlcCBQJkRAUCZEIEAmVmCQC8AgMJAQFSAQkAuAICBQJkRQUCZWQFAWQFAmRFBAJlZwkBAUQCBQJkTwUBYgMDCQECIT0CBQJkRQUBZQkAvwICBQJlZgUCZWcHCQACAQkArAICCQCsAgIJAKwCAgIPUHJpY2Ugc2xpcHBhZ2UgCQCmAwEFAmVmAh4gZXhjZWVkZWQgdGhlIHBhc3NlZCBsaW1pdCBvZiAJAKYDAQUCZWcEAmRICQEBRAIFAmR6BQFiBAJlaAkAvQIEBQJlYgkBAmJaAwUCZEQFAmRCBQdDRUlMSU5HBQFkBQdDRUlMSU5HBAJlaQkAvQIEBQJlYwUBZAkBAmJaAwUCZEQFAmRCBQVGTE9PUgUHQ0VJTElORwQCZWoDCQC/AgIFAmVoBQJlYwkAlAoCBQJlaQUCZWMJAJQKAgUCZWIFAmVoBAJlawgFAmVqAl8xBAJlbAgFAmVqAl8yBAJkbQkAvQIEBQJkSAUCZWwFAmREBQVGTE9PUgkAlwoFCQEBSwMFAmRtBQFiBQVGTE9PUgkBAUsDBQJlawUCZGoFB0NFSUxJTkcJAQFLAwUCZWwFAmRrBQdDRUlMSU5HBQJkRQUCZWYEAmVtCAUCZWUCXzEEAmVuCAUCZWUCXzIEAmVvCAUCZWUCXzMEAmRGCQEBSAIIBQJlZQJfNAUBYgQCZXAJAQFIAggFAmVlAl81BQFiAwkAZwIAAAUCZW0JAAIBAjZJbnZhbGlkIGNhbGN1bGF0aW9ucy4gTFAgY2FsY3VsYXRlZCBpcyBsZXNzIHRoYW4gemVyby4EAmVxAwkBASEBBQJkVQAABQJlbQQCZXIJAGUCBQJkUAUCZW4EAmVzCQBlAgUCZFIFAmVvBAJldAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVcABQJkRgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVgCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJkRgkAzAgCCQELU3RyaW5nRW50cnkCCQECYWECBQJhYgUCZHMJAQJiRQoFAmVuBQJlbwUCZXEFAmRGBQJkTwUCZXAFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmVyBQJlcwUDbmlsCQCfCg0FAmVtBQJlcQUCZEYFAmRBBQJkQwUCZHoFAmR2BQJkeQUCZXQFAmVyBQJlcwUCZFEFAmRTAQJldQMCZXYCZXcCZHoEAmV4CQEBRwIFAmV2CQC2AgEFAmJ6BAJleQkBAUcCBQJldwkAtgIBBQJiQQQCZXoJALwCAwkAdgYJALkCAgUCZXgFAmV5AAAJALYCAQAFAAEAEgUERE9XTgUBZwUCZHoDCQAAAgUCZHoFAWYFAWYFAmV6AQJlQQMCZUICZUMCZUQEAmVFCQC4AgIJALYCAQkBAmJUAQkBAmJwAQUCYngFAmVCBAJlRgkAuAICCQC2AgEJAQJiVAEJAQJicAEFAmJ5BQJlQwQCZUcJALgCAgkAtgIBCAkBBXZhbHVlAQkA7AcBBQJidwhxdWFudGl0eQUCZUQEAmVICQECZXUDBQJlRQUCZUYFAmVHBQJlSAECZUkDAmVKAmVLAmVEBAJlRQkAZAIJAQJiVAEJAQJicAEFAmJ4BQJlSgQCZUYJAGQCCQECYlQBCQECYnABBQJieQUCZUsEAmVHCQBkAggJAQV2YWx1ZQEJAOwHAQUCYncIcXVhbnRpdHkFAmVEBAJlegkBAmV1AwkAtgIBBQJlRQkAtgIBBQJlRgkAtgIBBQJlRwQCZUwJAMwIAgkBDEludGVnZXJFbnRyeQIFAmFrBQZoZWlnaHQJAMwIAgkBC1N0cmluZ0VudHJ5AgUCYWoJAKYDAQUCZXoFA25pbAkAlAoCBQJlTAUCZXoBAmVNAAkBC3ZhbHVlT3JFbHNlAgkAmwgCBQJiZAkBAmFIAQkApQgBBQR0aGlzBwECZU4CAmVPAmV6AwkAwAICBQJlegUCZU8GCQECYmEBCQC5CQIJAMwIAgIidXBkYXRlZCBLTHAgbG93ZXIgdGhhbiBjdXJyZW50IEtMcAkAzAgCCQCmAwEFAmVPCQDMCAIJAKYDAQUCZXoFA25pbAIBIAECZVABAmVRBAJlRQkBAmJUAQkBAmJwAQUCYngEAmVGCQECYlQBCQECYnABBQJieQQCZVIIBQJlUQZhbW91bnQEAmVTCQBuBAgFAmVRBmFtb3VudAgFAmVRBXByaWNlBQFiBQVGTE9PUgQCZVQDCQAAAggFAmVRCW9yZGVyVHlwZQUDQnV5CQCUCgIFAmVSCQEBLQEFAmVTCQCUCgIJAQEtAQUCZVIFAmVTBAJlSggFAmVUAl8xBAJlSwgFAmVUAl8yAwMDCQECYmkABgkAAAIFAmJ2BQFtBgkAAAIFAmJ2BQFuCQACAQIcRXhjaGFuZ2Ugb3BlcmF0aW9ucyBkaXNhYmxlZAMDCQECIT0CCAgFAmVRCWFzc2V0UGFpcgthbW91bnRBc3NldAUCYngGCQECIT0CCAgFAmVRCWFzc2V0UGFpcgpwcmljZUFzc2V0BQJieQkAAgECE1dyb25nIG9yZGVyIGFzc2V0cy4EAmVVCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKgDAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQJhagIBMAkBAmJjAQILaW52YWxpZCBrTHAEAmVWCQECZUkDBQJlSgUCZUsAAAQCZVcIBQJlVgJfMQQCZVgIBQJlVgJfMgQCZVkJAMACAgUCZVgFAmVVBAJlWgkAuQkCCQDMCAICBGtMcD0JAMwIAgkApgMBBQJlVQkAzAgCAggga0xwTmV3PQkAzAgCCQCmAwEFAmVYCQDMCAICFCBhbW91bnRBc3NldEJhbGFuY2U9CQDMCAIJAKQDAQUCZUUJAMwIAgITIHByaWNlQXNzZXRCYWxhbmNlPQkAzAgCCQCkAwEFAmVGCQDMCAICGSBhbW91bnRBc3NldEJhbGFuY2VEZWx0YT0JAMwIAgkApAMBBQJlSgkAzAgCAhggcHJpY2VBc3NldEJhbGFuY2VEZWx0YT0JAMwIAgkApAMBBQJlSwkAzAgCAgggaGVpZ2h0PQkAzAgCCQCkAwEFBmhlaWdodAUDbmlsAgAJAJQKAgUCZVkFAmVaAQJmYQECZmIDCQECIT0CCQCQAwEIBQJmYghwYXltZW50cwABCQACAQIdZXhhY3RseSAxIHBheW1lbnQgaXMgZXhwZWN0ZWQEAmZjCQEFdmFsdWUBCQCRAwIIBQJmYghwYXltZW50cwAABAJkdAkBBXZhbHVlAQgFAmZjB2Fzc2V0SWQEAmZkCAUCZmMGYW1vdW50BAJlZQkBAmRyBAkA2AQBCAUCZmINdHJhbnNhY3Rpb25JZAkA2AQBBQJkdAUCZmQIBQJmYgZjYWxsZXIEAmRLCAUCZWUCXzEEAmRMCAUCZWUCXzIEAmR5CQENcGFyc2VJbnRWYWx1ZQEIBQJlZQJfOQQCZE0IBQJlZQNfMTADAwkBAmJpAAYJAAACBQJkeQUBbgkAAgEJAKwCAgIsR2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCZHkJAJcKBQUCZEsFAmRMBQJmZAUCZHQFAmRNAQJmZQMCZmICZE8CZFUDCQECIT0CCQCQAwEIBQJmYghwYXltZW50cwACCQACAQIfZXhhY3RseSAyIHBheW1lbnRzIGFyZSBleHBlY3RlZAQCZmYJAQV2YWx1ZQEJAJEDAggFAmZiCHBheW1lbnRzAAAEAmZnCQEFdmFsdWUBCQCRAwIIBQJmYghwYXltZW50cwABBAJmaAkBAmROCQkA2AQBCAUCZmINdHJhbnNhY3Rpb25JZAUCZE8IBQJmZgZhbW91bnQIBQJmZgdhc3NldElkCAUCZmcGYW1vdW50CAUCZmcHYXNzZXRJZAkApQgBCAUCZmIGY2FsbGVyBwUCZFUEAmR5CQENcGFyc2VJbnRWYWx1ZQEIBQJmaAJfOAMDAwkBAmJpAAYJAAACBQJkeQUBbAYJAAACBQJkeQUBbgkAAgEJAKwCAgIsUHV0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCZHkFAmZoAQJmaQECY2YEAmZqCQD8BwQFAmJkAgRlbWl0CQDMCAIFAmNmBQNuaWwFA25pbAMJAAACBQJmagUCZmoEAmZrBAJhUQUCZmoDCQABAgUCYVECB0FkZHJlc3MEAmZsBQJhUQkA/AcEBQJmbAIEZW1pdAkAzAgCBQJjZgUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZmsFAmZrBQJjZgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZm0CAmNmAmFpBAJmbgMJAAACBQJhaQAAAAAJAGsDBQJjZgUCYWkFAWIJAJQKAgkAZQIFAmNmBQJmbgUCZm4BAmZvBAJmcAJmcQJhYgJhYwQCZnIJAAACBQJhYwUEdW5pdAQCZnMJAQJiVAEJAQJicAEFAmJ4BAJmdAkBAmJUAQkBAmJwAQUCYnkEAmZ1AwkAAAIFAmZxBQJieAYDCQAAAgUCZnEFAmJ5BwkBAmJhAQINaW52YWxpZCBhc3NldAQCZnYDBQJmcgkAlAoCBQJmcwUCZnQDBQJmdQkAlAoCCQBlAgUCZnMFAmZwBQJmdAkAlAoCBQJmcwkAZQIFAmZ0BQJmcAQCZncIBQJmdgJfMQQCZngIBQJmdgJfMgQCZnkDBQJmdQkAlAoCBQJmcAAACQCUCgIAAAUCZnAEAmZ6CAUCZnkCXzEEAmZBCAUCZnkCXzIEAmVSCAkBAmZtAgUCZnoFAmJmAl8xBAJlUwgJAQJmbQIFAmZBBQJiZgJfMQQCZkIJAQJmbQIFAmZwBQJiZgQCZkMIBQJmQgJfMQQCZm4IBQJmQgJfMgQCZkQJAGQCBQJmdwUCZVIEAmZFCQBkAgUCZngFAmVTBAJmRgkBAmJXAgkBAUQCBQJmRQUCYkEJAQFEAgUCZkQFAmJ6BAJmRwkBAUgCBQJmRgUBYgQCZkgDBQJmdQUCZncFAmZ4BAJmSQkAtgIBBQJmSAQCZkoJALYCAQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJidwkArAICCQCsAgICBmFzc2V0IAkA2AQBBQJidwIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmZLAwkAvwICBQJmSgUBZgYJAQJiYQECImluaXRpYWwgZGVwb3NpdCByZXF1aXJlcyBhbGwgY29pbnMDCQAAAgUCZksFAmZLBAJmTAkAtgIBBQJmQwQCZk0JAJYDAQkAzAgCAAAJAMwIAgkAoAMBCQC6AgIJALkCAgUCZkoJALgCAgkBCnNxcnRCaWdJbnQECQC3AgIFAWQJALoCAgkAuQICBQJmTAUBZAUCZkkAEgASBQRET1dOBQFkBQFkBQNuaWwEAmV0AwUCZnIFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVcABQJmRwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVgCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJmRwkAzAgCCQELU3RyaW5nRW50cnkCCQECYWECCQClCAEJAQV2YWx1ZQEFAmFiCQDYBAEJAQV2YWx1ZQEFAmFjCQECYkUKBQJmegUCZkEFAmZNBQJmRwAAAAAFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAAAAAABQNuaWwEAmZOCQECYlcCCQEBRAIFAmZ4BQJiQQkBAUQCBQJmdwUCYnoEAmZPCQEBSAIFAmZOBQFiBAJmUAQCZlEDBQJmdQkAlAoCBQJmegUCZncJAJQKAgUCZkEFAmZ4BAJjZggFAmZRAl8xBAJmUggFAmZRAl8yBAJmUwkAoAMBCQC8AgMFAmZKCQC2AgEJAGkCBQJjZgACCQC2AgEFAmZSCQBrAwkAZQIFAmZNBQJmUwUBYgUCZlMJAJcKBQUCZk0FAmV0BQJmbgUCZlAFAmZ1CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJmVAUCZlUCZkMCZnECYWICYWMEAmZyCQAAAgUCYWMFBHVuaXQEAmRpCQECYmsABAJkagkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRpBQF0BAJkawkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRpBQF1BAJmVgkAzAgCAwkAAAIFAmZxBQJidwYJAQJiYQECEGludmFsaWQgbHAgYXNzZXQFA25pbAMJAAACBQJmVgUCZlYEAmZXAwkAAAIFAmZVBQJieAYDCQAAAgUCZlUFAmJ5BwkBAmJhAQINaW52YWxpZCBhc3NldAQCZlgDBQJmVwkAtgIBCQECYlQBCQECYnABBQJieAkAtgIBCQECYlQBCQECYnABBQJieQQCZlkDBQJmVwUCZGoFAmRrBAJmWgkBAmJUAQkBAmJwAQUCYngEAmdhCQECYlQBCQECYnABBQJieQQCZ2IDBQJmVwUCZloFAmdhBAJnYwkAtgIBBQJnYgQCZkoJALYCAQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJidwkArAICCQCsAgICBmFzc2V0IAkA2AQBBQJidwIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmdkCQC2AgEFAmZDBAJnZQkAlgMBCQDMCAIAAAkAzAgCCQCgAwEJALoCAgkAuQICBQJmWAkAuAICBQFkCQB2BgkAuAICBQFkCQC6AgIJALkCAgUCZ2QFAWQFAmZKABIFAWgAAAASBQRET1dOBQFkBQNuaWwEAmdmCQECZm0CBQJnZQUCYmgEAmdnCAUCZ2YCXzEEAmZuCAUCZ2YCXzIEAmdoAwUCZlcJAJYKBAUCZ2cAAAkAZQIFAmZaBQJnZQUCZ2EJAJYKBAAABQJnZwUCZloJAGUCBQJnYQUCZ2UEAmdpCAUCZ2gCXzEEAmdqCAUCZ2gCXzIEAmdrCAUCZ2gCXzMEAmdsCAUCZ2gCXzQEAmZGCQECYlcCCQEBRAIFAmdsBQJiQQkBAUQCBQJnawUCYnoEAmZHCQEBSAIFAmZGBQFiBAJldAMFAmZyBQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFkAgkApQgBCQEFdmFsdWUBBQJhYgkA2AQBCQEFdmFsdWUBBQJhYwkBAmJQBgUCZ2kFAmdqBQJmQwUCZkcFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZkcJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZkcFA25pbAQCZk4JAQJiVwIJAQFEAgUCZ2EFAmJBCQEBRAIFAmZaBQJiegQCZk8JAQFIAgUCZk4FAWIEAmZQBAJnbQkAaAIJAKADAQkAvAIDBQJmWAUCZ2QFAmZKAAIJAGsDCQBlAgUCZ2cFAmdtBQFiBQJnbQkAlwoFBQJnZwUCZXQFAmZuBQJmUAUCZlcJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmduAAQCZ28JAQJhUwAEAmFRCQCdCAIFAmdvCQEBVQADCQABAgUCYVECBlN0cmluZwQCYVYFAmFRCQDZBAEFAmFWAwkAAQIFAmFRAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmdwAQJmYgQCYVEJAQJnbgADCQABAgUCYVECCkJ5dGVWZWN0b3IEAmdxBQJhUQkAAAIIBQJmYg9jYWxsZXJQdWJsaWNLZXkFAmdxAwkAAQIFAmFRAgRVbml0CQAAAggFAmZiBmNhbGxlcgUEdGhpcwkAAgECC01hdGNoIGVycm9yAQJncgECZmIEAmdzCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEAmFRCQECZ24AAwkAAQIFAmFRAgpCeXRlVmVjdG9yBAJncQUCYVEDCQAAAggFAmZiD2NhbGxlclB1YmxpY0tleQUCZ3EGBQJncwMJAAECBQJhUQIEVW5pdAMJAAACCAUCZmIGY2FsbGVyBQR0aGlzBgUCZ3MJAAIBAgtNYXRjaCBlcnJvchwCZmIBCXJlYmFsYW5jZQAJAM4IAgkBAmNJAQkBAmFXAgUEdGhpcwkBAmFlAAkBAmNJAQkBAmFXAgUEdGhpcwkBAmFmAAJmYgEhY2FsY3VsYXRlQW1vdW50T3V0Rm9yU3dhcFJFQURPTkxZAwJndAJndQJndgQCZ3cDCQAAAgUCZ3UHBAJneAkBAmFXAgUEdGhpcwkBAmFmAAQCZ3kJAQJhVwIFBHRoaXMJAQJhZQAJAJQKAgUCZ3gFAmd5BAJneAkBAmFXAgUEdGhpcwkBAmFlAAQCZ3kJAQJhVwIFBHRoaXMJAQJhZgAJAJQKAgUCZ3gFAmd5BAJneAgFAmd3Al8xBAJneQgFAmd3Al8yBAJnegkBAmJUAQUCZ3kEAmdBCQECYlQBBQJneAQCZ0IJAGsDBQJnQQUCZ3QJAGQCBQJnegUCZ3QEAmdDCQC5AgIJALYCAQUCZ3oJALYCAQUCZ0EEAmdECQC5AgIJALcCAgkAtwICCQC2AgEJAQJiVAEFAmd5CQC2AgEFAmd0CQC2AgEFAmd2CQC4AgIJALYCAQkBAmJUAQUCZ3gJALYCAQUCZ0IEAmdFAwkAwAICBQJnRAUCZ0MGCQACAQIUbmV3IEsgaXMgZmV3ZXIgZXJyb3IDCQAAAgUCZ0UFAmdFCQCUCgIFA25pbAUCZ0IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZmIBJmNhbGN1bGF0ZUFtb3VudE91dEZvclN3YXBBbmRTZW5kVG9rZW5zBQJndAJndQJnRgJnRwJndgQCZ0gKAAJiZwkA/AcEBQJiZAIXZ2V0U3dhcENvbnRyYWN0UkVBRE9OTFkFA25pbAUDbmlsAwkAAQIFAmJnAgZTdHJpbmcFAmJnCQACAQkArAICCQADAQUCYmcCGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwQCZlYJAMwIAgMJAGcCCAkBBXZhbHVlAQkAkQMCCAUCZmIIcGF5bWVudHMAAAZhbW91bnQFAmd0BgkBAmJhAQIMV3JvbmcgYW1vdW50CQDMCAIDCQAAAggFAmZiBmNhbGxlcgkBEUBleHRyTmF0aXZlKDEwNjIpAQUCZ0gGCQECYmEBAhFQZXJtaXNzaW9uIGRlbmllZAUDbmlsAwkAAAIFAmZWBQJmVgQCZmMJAQV2YWx1ZQEJAJEDAggFAmZiCHBheW1lbnRzAAAEAmd5CQECYnABCAUCZmMHYXNzZXRJZAQCZ3gDCQAAAgUCZ3UHCQECYVcCBQR0aGlzCQECYWYACQECYVcCBQR0aGlzCQECYWUABAJnegkAZQIJAQJiVAEFAmd5CAkBBXZhbHVlAQkAkQMCCAUCZmIIcGF5bWVudHMAAAZhbW91bnQEAmdBCQECYlQBBQJneAQCZ0IJAGsDBQJnQQUCZ3QJAGQCBQJnegUCZ3QEAmdDCQC5AgIJALYCAQUCZ3oJALYCAQUCZ0EEAmdECQC5AgIJALcCAgkAtgIBCQECYlQBBQJneQkAtgIBBQJndgkAuAICCQC2AgEJAQJiVAEFAmd4CQC2AgEFAmdCBAJnRQMJAMACAgUCZ0QFAmdDBgkAAgECFG5ldyBLIGlzIGZld2VyIGVycm9yAwkAAAIFAmdFBQJnRQQCZ0kDCQBnAgUCZ0IFAmdGBgkAAgECLEV4Y2hhbmdlIHJlc3VsdCBpcyBmZXdlciBjb2lucyB0aGFuIGV4cGVjdGVkAwkAAAIFAmdJBQJnSQQCZ0oJAQJjSQEFAmd5AwkAAAIFAmdKBQJnSgQCZ0sJAQJjUAIFAmd4BQJnQgMJAAACBQJnSwUCZ0sJAJQKAgkAzggCCQDOCAIFAmdLBQJnSgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQJnRwUCZ0IJAQJibgEFAmd4BQNuaWwFAmdCCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmZiAQNwdXQCAmRPAmdMAwkAZgIAAAUCZE8JAAIBAiBJbnZhbGlkIHNsaXBwYWdlVG9sZXJhbmNlIHBhc3NlZAQCZmgJAQJmZQMFAmZiBQJkTwYEAmVxCAUCZmgCXzIEAmR2CAUCZmgCXzcEAmRNCAUCZmgCXzkEAmVyCAUCZmgDXzEwBAJlcwgFAmZoA18xMQQCZ00IBQJmaANfMTIEAmdOCAUCZmgDXzEzBAJmZgkAtgIBCAkBBXZhbHVlAQkAkQMCCAUCZmIIcGF5bWVudHMAAAZhbW91bnQEAmZnCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJmYghwYXltZW50cwABBmFtb3VudAQCZUgJAQJlQQMFAmZmBQJmZwkAtgIBAAADCQAAAgUCZUgFAmVIBAJmagkA/AcEBQJiZAIEZW1pdAkAzAgCBQJlcQUDbmlsBQNuaWwDCQAAAgUCZmoFAmZqBAJmawQCYVEFAmZqAwkAAQIFAmFRAgdBZGRyZXNzBAJmbAUCYVEJAPwHBAUCZmwCBGVtaXQJAMwIAgUCZXEFA25pbAUDbmlsBQR1bml0AwkAAAIFAmZrBQJmawQCZ08DCQBmAgUCZXIAAAkA/AcEBQJiRAIDcHV0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmdNBQJlcgUDbmlsBQNuaWwDCQAAAgUCZ08FAmdPBAJnUAMJAGYCBQJlcwAACQD8BwQFAmJEAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZ04FAmVzBQNuaWwFA25pbAMJAAACBQJnUAUCZ1AEAmdRAwUCZ0wEAmdSCQD8BwQFAmJDAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJkdgUCZXEFA25pbAMJAAACBQJnUgUCZ1IFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZmIGY2FsbGVyBQJlcQUCZHYFA25pbAQCZ1MJAQJlSQMAAAAAAAADCQAAAgUCZ1MFAmdTBAJleggFAmdTAl8yBAJnVAgFAmdTAl8xBAJnVQkBAmVOAgUCZUgFAmV6AwkAAAIFAmdVBQJnVQQCZ1YJAPwHBAUEdGhpcwIJcmViYWxhbmNlBQNuaWwFA25pbAMJAAACBQJnVgUCZ1YJAM4IAgkAzggCBQJkTQUCZ1EFAmdUCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmZiAQpwdXRGb3JGcmVlAQJnVwMJAGYCAAAFAmdXCQACAQIUSW52YWxpZCB2YWx1ZSBwYXNzZWQEAmZoCQECZmUDBQJmYgUCZ1cHBAJkTQgFAmZoAl85BAJmZgkAtgIBCAkBBXZhbHVlAQkAkQMCCAUCZmIIcGF5bWVudHMAAAZhbW91bnQEAmZnCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJmYghwYXltZW50cwABBmFtb3VudAQCZUgJAQJlQQMFAmZmBQJmZwkAtgIBAAADCQAAAgUCZUgFAmVIBAJnWAkBAmVJAwAAAAAAAAQCZ1QIBQJnWAJfMQQCZXoIBQJnWAJfMgQCZ1UJAQJlTgIFAmVIBQJlegMJAAACBQJnVQUCZ1UJAM4IAgUCZE0FAmdUCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmZiAQlwdXRPbmVUa24CAmdZAmdaBAJoYQoAAmJnCQD8BwQFAmJkAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYmcCB0Jvb2xlYW4FAmJnCQACAQkArAICCQADAQUCYmcCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmhiAwMDCQECYmkABgkAAAIFAmJ2BQFsBgkAAAIFAmJ2BQFuBgUCaGEEAmZWCQDMCAIDAwkBASEBBQJoYgYJAQJncAEFAmZiBgkBAmJhAQIhcHV0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCZmIIcGF5bWVudHMAAQYJAQJiYQECHmV4YWN0bHkgMSBwYXltZW50IGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmZWBQJmVgQCaGMJAJEDAggFAmZiCHBheW1lbnRzAAAEAmZxCAUCaGMHYXNzZXRJZAQCZnAIBQJoYwZhbW91bnQEAmVIAwkAAAIFAmZxBQJieAkBAmVBAwkAtgIBBQJmcAkAtgIBAAAJALYCAQAAAwkAAAIFAmZxBQJieQkBAmVBAwkAtgIBAAAJALYCAQUCZnAJALYCAQAACQECYmEBAh5wYXltZW50IGFzc2V0IGlzIG5vdCBzdXBwb3J0ZWQDCQAAAgUCZUgFAmVIBAJhYggFAmZiBmNhbGxlcgQCYWMIBQJmYg10cmFuc2FjdGlvbklkBAJoZAkBAmZvBAUCZnAFAmZxBQJhYgUCYWMDCQAAAgUCaGQFAmhkBAJmdQgFAmhkAl81BAJoZQgFAmhkAl80BAJmbggFAmhkAl8zBAJldAgFAmhkAl8yBAJoZggFAmhkAl8xBAJoZwMDCQBmAgUCZ1kAAAkAZgIFAmdZBQJoZgcJAQJiYQEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZ1kFA25pbAIABQJoZgQCZmoJAQJmaQEFAmhnAwkAAAIFAmZqBQJmagQCZ1EDBQJnWgQCaGgJAPwHBAUCYkMCBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJ3BQJoZwUDbmlsAwkAAAIFAmhoBQJoaAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJmYgZjYWxsZXIFAmhnBQJidwUDbmlsBAJoaQMJAGYCBQJmbgAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmJlBQJmbgUCZnEFA25pbAUDbmlsBAJoagMJAAACBQR0aGlzBQJiZQkAlAoCAAAAAAMFAmZ1CQCUCgIJAQEtAQUCZm4AAAkAlAoCAAAJAQEtAQUCZm4EAmVKCAUCaGoCXzEEAmVLCAUCaGoCXzIEAmhrCQECZUkDBQJlSgUCZUsAAAQCZ1QIBQJoawJfMQQCZXoIBQJoawJfMgQCZVUJAQV2YWx1ZQEJAKIIAQUCYWoEAmdVCQECZU4CBQJlSAUCZXoDCQAAAgUCZ1UFAmdVBAJnVgkA/AcEBQR0aGlzAglyZWJhbGFuY2UFA25pbAUDbmlsAwkAAAIFAmdWBQJnVgkAlAoCCQDOCAIJAM4IAgkAzggCBQJldAUCZ1EFAmhpBQJnVAUCaGcJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZmIBEXB1dE9uZVRrblJFQURPTkxZAgJmcQJmcAQCaGwJAQJmbwQFAmZwCQECYm4BBQJmcQUEdW5pdAUEdW5pdAQCaGYIBQJobAJfMQQCZXQIBQJobAJfMgQCZm4IBQJobAJfMwQCaGUIBQJobAJfNAQCZnUIBQJobAJfNQkAlAoCBQNuaWwJAJUKAwUCaGYFAmZuBQJoZQJmYgEJZ2V0T25lVGtuAgJobQJnWQQCaGEKAAJiZwkA/AcEBQJiZAIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmJnAgdCb29sZWFuBQJiZwkAAgEJAKwCAgkAAwEFAmJnAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJobgMDCQECYmkABgkAAAIFAmJ2BQFuBgUCaGEEAmZWCQDMCAIDAwkBASEBBQJobgYJAQJncAEFAmZiBgkBAmJhAQIhZ2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCZmIIcGF5bWVudHMAAQYJAQJiYQECHmV4YWN0bHkgMSBwYXltZW50IGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmZWBQJmVgQCZlUJAQJibgEFAmhtBAJoYwkAkQMCCAUCZmIIcGF5bWVudHMAAAQCZnEIBQJoYwdhc3NldElkBAJmQwgFAmhjBmFtb3VudAQCZUgJAQJlQQMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZUgFAmVIBAJhYggFAmZiBmNhbGxlcgQCYWMIBQJmYg10cmFuc2FjdGlvbklkBAJobwkBAmZUBQUCZlUFAmZDBQJmcQUCYWIFAmFjAwkAAAIFAmhvBQJobwQCZlcIBQJobwJfNQQCaGUIBQJobwJfNAQCZm4IBQJobwJfMwQCZXQIBQJobwJfMgQCaHAIBQJobwJfMQQCY2YDAwkAZgIFAmdZAAAJAGYCBQJnWQUCaHAHCQECYmEBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmdZBQNuaWwCAAUCaHAEAmhxCQD8BwQFAmJkAgRidXJuCQDMCAIFAmZDBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmZxBQJmQwUDbmlsAwkAAAIFAmhxBQJocQQCZ0sJAQJjUAIFAmhtCQBkAgUCY2YJAJYDAQkAzAgCAAAJAMwIAgUCZm4FA25pbAQCaHIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYWIFAmNmBQJmVQUDbmlsBAJoaQMJAGYCBQJmbgAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmJlBQJmbgUCZlUFA25pbAUDbmlsBAJocwQCaHQDCQAAAgUEdGhpcwUCYmUAAAUCZm4DBQJmVwkAlAoCCQEBLQEJAGQCBQJjZgUCaHQAAAkAlAoCAAAJAQEtAQkAZAIFAmNmBQJodAQCZUoIBQJocwJfMQQCZUsIBQJocwJfMgQCaHUJAQJlSQMFAmVKBQJlSwAABAJnVAgFAmh1Al8xBAJleggFAmh1Al8yBAJnVQkBAmVOAgUCZUgFAmV6AwkAAAIFAmdVBQJnVQkAlAoCCQDOCAIJAM4IAgkAzggCCQDOCAIFAmV0BQJnSwUCaHIFAmhpBQJnVAUCY2YJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZmIBEWdldE9uZVRrblJFQURPTkxZAgJmVQJmQwQCaHYJAQJmVAUJAQJibgEFAmZVBQJmQwUCYncFBHVuaXQFBHVuaXQEAmhwCAUCaHYCXzEEAmV0CAUCaHYCXzIEAmZuCAUCaHYCXzMEAmhlCAUCaHYCXzQEAmZXCAUCaHYCXzUJAJQKAgUDbmlsCQCVCgMFAmhwBQJmbgUCaGUCZmIBE3Vuc3Rha2VBbmRHZXRPbmVUa24DAmh3AmhtAmdZBAJoYQoAAmJnCQD8BwQFAmJkAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYmcCB0Jvb2xlYW4FAmJnCQACAQkArAICCQADAQUCYmcCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmhuAwMJAQJiaQAGCQAAAgUCYnYFAW4GBQJoYQQCZlYJAMwIAgMDCQEBIQEFAmhuBgkBAmdwAQUCZmIGCQECYmEBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJmYghwYXltZW50cwAABgkBAmJhAQIYbm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZlYFAmZWBAJmVQkBAmJuAQUCaG0EAmFiCAUCZmIGY2FsbGVyBAJhYwgFAmZiDXRyYW5zYWN0aW9uSWQEAmVICQECZUEDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmVIBQJlSAQCaHgJAPwHBAUCYkMCB3Vuc3Rha2UJAMwIAgkA2AQBBQJidwkAzAgCBQJodwUDbmlsBQNuaWwDCQAAAgUCaHgFAmh4BAJoeQkBAmZUBQUCZlUFAmh3BQJidwUCYWIFAmFjAwkAAAIFAmh5BQJoeQQCZlcIBQJoeQJfNQQCaGUIBQJoeQJfNAQCZm4IBQJoeQJfMwQCZXQIBQJoeQJfMgQCaHAIBQJoeQJfMQQCY2YDAwkAZgIFAmdZAAAJAGYCBQJnWQUCaHAHCQECYmEBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmdZBQNuaWwCAAUCaHAEAmhxCQD8BwQFAmJkAgRidXJuCQDMCAIFAmh3BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJ3BQJodwUDbmlsAwkAAAIFAmhxBQJocQQCZ0sJAQJjUAIFAmhtCQBkAgUCY2YJAJYDAQkAzAgCAAAJAMwIAgUCZm4FA25pbAQCaHIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmZiBmNhbGxlcgUCY2YFAmZVBQNuaWwEAmhpAwkAZgIFAmZuAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYmUFAmZuBQJmVQUDbmlsBQNuaWwEAmh6BAJodAMJAAACBQR0aGlzBQJiZQAABQJmbgMFAmZXCQCUCgIJAQEtAQkAZAIFAmNmBQJodAAACQCUCgIAAAkBAS0BCQBkAgUCY2YFAmh0BAJlSggFAmh6Al8xBAJlSwgFAmh6Al8yBAJoQQkBAmVJAwUCZUoFAmVLAAAEAmdUCAUCaEECXzEEAmV6CAUCaEECXzIEAmdVCQECZU4CBQJlSAUCZXoDCQAAAgUCZ1UFAmdVCQCUCgIJAM4IAgkAzggCCQDOCAIJAM4IAgUCZXQFAmdLBQJocgUCaGkFAmdUBQJjZgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJmYgEDZ2V0AAQCZWUJAQJmYQEFAmZiBAJkSwgFAmVlAl8xBAJkTAgFAmVlAl8yBAJmZAgFAmVlAl8zBAJkdAgFAmVlAl80BAJkTQgFAmVlAl81BAJnSwkBAmNVAgUCZEsFAmRMBAJlSAkBAmVBAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJlSAUCZUgEAmhCCQD8BwQFAmJkAgRidXJuCQDMCAIFAmZkBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmR0BQJmZAUDbmlsAwkAAAIFAmhCBQJoQgQCaEMJAQJlSQMJAQEtAQUCZEsJAQEtAQUCZEwAAAQCZ1QIBQJoQwJfMQQCZXoIBQJoQwJfMgQCZ1UJAQJlTgIFAmVIBQJlegMJAAACBQJnVQUCZ1UJAM4IAgkAzggCBQJnSwUCZE0FAmdUCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmZiAQlnZXROb0xlc3MCAmhEAmhFBAJlZQkBAmZhAQUCZmIEAmRLCAUCZWUCXzEEAmRMCAUCZWUCXzIEAmZkCAUCZWUCXzMEAmR0CAUCZWUCXzQEAmRNCAUCZWUCXzUDCQBmAgUCaEQFAmRLCQACAQkArAICCQCsAgIJAKwCAgIcbm9MZXNzVGhlbkFtdEFzc2V0IGZhaWxlZDogIAkApAMBBQJkSwIDIDwgCQCkAwEFAmhEAwkAZgIFAmhFBQJkTAkAAgEJAKwCAgkArAICCQCsAgICHW5vTGVzc1RoZW5QcmljZUFzc2V0IGZhaWxlZDogCQCkAwEFAmRMAgMgPCAJAKQDAQUCaEUEAmdLCQECY1UCBQJkSwUCZEwEAmVICQECZUEDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmVIBQJlSAQCaEIJAPwHBAUCYmQCBGJ1cm4JAMwIAgUCZmQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZHQFAmZkBQNuaWwDCQAAAgUCaEIFAmhCBAJoRgkBAmVJAwkBAS0BBQJkSwkBAS0BBQJkTAAABAJnVAgFAmhGAl8xBAJleggFAmhGAl8yBAJnVQkBAmVOAgUCZUgFAmV6AwkAAAIFAmdVBQJnVQkAzggCCQDOCAIFAmdLBQJkTQUCZ1QJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZmIBDXVuc3Rha2VBbmRHZXQBAmNmBAJoRwMJAQIhPQIJAJADAQgFAmZiCHBheW1lbnRzAAAJAAIBAhhObyBwYXltZW50cyBhcmUgZXhwZWN0ZWQGAwkAAAIFAmhHBQJoRwQCZGkJAQJiawAEAmR2CQDZBAEJAJEDAgUCZGkFAXEEAmVICQECZUEDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmVIBQJlSAQCaHgJAPwHBAUCYkMCB3Vuc3Rha2UJAMwIAgkA2AQBBQJkdgkAzAgCBQJjZgUDbmlsBQNuaWwDCQAAAgUCaHgFAmh4BAJlZQkBAmRyBAkA2AQBCAUCZmINdHJhbnNhY3Rpb25JZAkA2AQBBQJkdgUCY2YIBQJmYgZjYWxsZXIEAmRLCAUCZWUCXzEEAmRMCAUCZWUCXzIEAmR5CQENcGFyc2VJbnRWYWx1ZQEIBQJlZQJfOQQCZE0IBQJlZQNfMTAEAmdLCQECY1UCBQJkSwUCZEwEAmhIAwMJAQJiaQAGCQAAAgUCZHkFAW4JAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmR5BgMJAAACBQJoSAUCaEgEAmhCCQD8BwQFAmJkAgRidXJuCQDMCAIFAmNmBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmR2BQJjZgUDbmlsAwkAAAIFAmhCBQJoQgQCaEkJAQJlSQMJAQEtAQUCZEsJAQEtAQUCZEwAAAQCZ1QIBQJoSQJfMQQCZXoIBQJoSQJfMgQCZ1UJAQJlTgIFAmVIBQJlegMJAAACBQJnVQUCZ1UJAM4IAgkAzggCBQJnSwUCZE0FAmdUCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmZiARN1bnN0YWtlQW5kR2V0Tm9MZXNzAwJodwJoSgJoRQQCaG4DCQECYmkABgkAAAIFAmJ2BQFuBAJmVgkAzAgCAwkBASEBBQJobgYJAAIBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJmYghwYXltZW50cwAABgkAAgECGG5vIHBheW1lbnRzIGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmZWBQJmVgQCZUgJAQJlQQMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZUgFAmVIBAJoeAkA/AcEBQJiQwIHdW5zdGFrZQkAzAgCCQDYBAEFAmJ3CQDMCAIFAmh3BQNuaWwFA25pbAMJAAACBQJoeAUCaHgEAmVlCQECZHIECQDYBAEIBQJmYg10cmFuc2FjdGlvbklkCQDYBAEFAmJ3BQJodwgFAmZiBmNhbGxlcgQCZEsIBQJlZQJfMQQCZEwIBQJlZQJfMgQCZE0IBQJlZQNfMTAEAmdLCQECY1UCBQJkSwUCZEwEAmhLCQDMCAIDCQBnAgUCZEsFAmhKBgkAAgEJALkJAgkAzAgCAixhbW91bnQgYXNzZXQgYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmhKBQNuaWwCAAkAzAgCAwkAZwIFAmRMBQJoRQYJAAIBCQC5CQIJAMwIAgIrcHJpY2UgYXNzZXQgYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmhFBQNuaWwCAAUDbmlsAwkAAAIFAmhLBQJoSwQCaEIJAPwHBAUCYmQCBGJ1cm4JAMwIAgUCaHcFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYncFAmh3BQNuaWwDCQAAAgUCaEIFAmhCBAJoTAkBAmVJAwkBAS0BBQJkSwkBAS0BBQJkTAAABAJnVAgFAmhMAl8xBAJleggFAmhMAl8yBAJnVQkBAmVOAgUCZUgFAmV6AwkAAAIFAmdVBQJnVQkAzggCCQDOCAIFAmdLBQJkTQUCZ1QJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZmIBCGFjdGl2YXRlAgJoTQJoTgMJAQIhPQIJAKUIAQgFAmZiBmNhbGxlcgkApQgBBQJiZAkAAgECEnBlcm1pc3Npb25zIGRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZQAFAmhNCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZgAFAmhOBQNuaWwCB3N1Y2Nlc3MCZmIBCnJlZnJlc2hLTHAABAJoTwkBC3ZhbHVlT3JFbHNlAgkAnwgBBQJhawAABAJoUAMJAGcCCQBlAgUGaGVpZ2h0BQJoTwUCYW4FBHVuaXQJAQJiYQEJALkJAgkAzAgCCQCkAwEFAmFuCQDMCAICLyBibG9ja3MgaGF2ZSBub3QgcGFzc2VkIHNpbmNlIHRoZSBwcmV2aW91cyBjYWxsBQNuaWwCAAMJAAACBQJoUAUCaFAEAmVVCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKgDAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQJhagIBMAkBAmJjAQILaW52YWxpZCBrTHAEAmhRCQECZUkDAAAAAAAABAJoUggFAmhRAl8xBAJleggFAmhRAl8yBAJlTAMJAQIhPQIFAmVVBQJlegUCaFIJAQJiYQECEm5vdGhpbmcgdG8gcmVmcmVzaAkAlAoCBQJlTAkApgMBBQJlegkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJmYgEcZ2V0UG9vbENvbmZpZ1dyYXBwZXJSRUFET05MWQAJAJQKAgUDbmlsCQECYmsAAmZiARxnZXRBY2NCYWxhbmNlV3JhcHBlclJFQURPTkxZAQJhcAkAlAoCBQNuaWwJAQJiVAEFAmFwAmZiARljYWxjUHJpY2VzV3JhcHBlclJFQURPTkxZAwJkYwJkZAJkaAQCZHEJAQJkZwMFAmRjBQJkZAUCZGgJAJQKAgUDbmlsCQDMCAIJAKYDAQkAkQMCBQJkcQAACQDMCAIJAKYDAQkAkQMCBQJkcQABCQDMCAIJAKYDAQkAkQMCBQJkcQACBQNuaWwCZmIBFHRvWDE4V3JhcHBlclJFQURPTkxZAgFFAUYJAJQKAgUDbmlsCQCmAwEJAQFEAgUBRQUBRgJmYgEWZnJvbVgxOFdyYXBwZXJSRUFET05MWQIBSQFKCQCUCgIFA25pbAkBAUgCCQCnAwEFAUkFAUoCZmIBHmNhbGNQcmljZUJpZ0ludFdyYXBwZXJSRUFET05MWQICYlgCYlkJAJQKAgUDbmlsCQCmAwEJAQJiVwIJAKcDAQUCYlgJAKcDAQUCYlkCZmIBI2VzdGltYXRlUHV0T3BlcmF0aW9uV3JhcHBlclJFQURPTkxZCQJkcwJkTwJkUAJkUQJkUgJkUwJhYgJkVAJkVQkAlAoCBQNuaWwJAQJkTgkFAmRzBQJkTwUCZFAFAmRRBQJkUgUCZFMFAmFiBQJkVAUCZFUCZmIBI2VzdGltYXRlR2V0T3BlcmF0aW9uV3JhcHBlclJFQURPTkxZBAJkcwJkdAJkdQJhYgQCZWUJAQJkcgQFAmRzBQJkdAUCZHUJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmFiCQCUCgIFA25pbAkAnAoKCAUCZWUCXzEIBQJlZQJfMggFAmVlAl8zCAUCZWUCXzQIBQJlZQJfNQgFAmVlAl82CAUCZWUCXzcJAKYDAQgFAmVlAl84CAUCZWUCXzkIBQJlZQNfMTACZmIBDXN0YXRzUkVBRE9OTFkABAJkaQkBAmJrAAQCZHYJANkEAQkAkQMCBQJkaQUBcQQCaFMJAJEDAgUCZGkFAXIEAmhUCQCRAwIFAmRpBQFzBAJkWAkAkQMCBQJkaQUBdgQCZFkJAJEDAgUCZGkFAXcEAmRqCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGkFAXQEAmRrCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGkFAXUEAmhVCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmR2CQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmR2Ag4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCaFYJAQJiVAEFAmhTBAJoVwkBAmJUAQUCaFQEAmhYAwkAAAIFAmhVAAAJAMwIAgUBZQkAzAgCBQFlCQDMCAIFAWUFA25pbAkBAmRnAwUCaFYFAmhXBQJoVQQCZEYAAAQCaFkJAQFIAgkAkQMCBQJoWAABBQFiBAJoWgkBAUgCCQCRAwIFAmhYAAIFAWIEAmlhCQEFdmFsdWUBCQCaCAIFAmJkCQECYUQBCQClCAEFBHRoaXMJAJQKAgUDbmlsCQC5CQIJAMwIAgIOJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJoVgkAzAgCCQCkAwEFAmhXCQDMCAIJAKQDAQUCaFUJAMwIAgkApAMBBQJkRgkAzAgCCQCkAwEFAmhZCQDMCAIJAKQDAQUCaFoJAMwIAgkApAMBBQJpYQUDbmlsBQFqAmZiASBldmFsdWF0ZVB1dEJ5QW1vdW50QXNzZXRSRUFET05MWQECZFAEAmRpCQECYmsABAJkdgkA2QQBCQCRAwIFAmRpBQFxBAJkVgkAkQMCBQJkaQUBcgQCZHcJANkEAQUCZFYEAmRXCQCRAwIFAmRpBQFzBAJkeAkA2QQBBQJkVwQCZGoJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkaQUBdAQCZGsJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkaQUBdQQCZHkJAJEDAgUCZGkFAXAEAmhVCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmR2CQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmR2Ag4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCaFYJAQJiVAEFAmRWBAJoVwkBAmJUAQUCZFcEAmRlCQEBRAIFAmhWBQJkagQCZGYJAQFEAgUCaFcFAmRrBAJkRQMJAAACBQJoVQAABQFlCQECYlcCBQJkZgUCZGUEAmViCQEBRAIFAmRQBQJkagQCZWMJALwCAwUCZWIFAmRFBQFkBAJkUgkBAUgCBQJlYwUCZGsEAmZoCQECZE4JAgAAoMIeBQJkUAUCZHcFAmRSBQJkeAIABgcEAmVtCAUCZmgCXzEEAmliCAUCZmgCXzMEAmRBCAUCZmgCXzQEAmRDCAUCZmgCXzUEAmR6CAUCZmgCXzYJAJQKAgUDbmlsCQC5CQIJAMwIAgIQJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmVtCQDMCAIJAKQDAQkBAUgCBQJkRQUBYgkAzAgCCQCkAwEFAmRBCQDMCAIJAKQDAQUCZEMJAMwIAgkApAMBBQJkegkAzAgCBQJkeQkAzAgCCQCkAwEFAmRQCQDMCAIJAKQDAQUCZFIFA25pbAUBagJmYgEfZXZhbHVhdGVQdXRCeVByaWNlQXNzZXRSRUFET05MWQECZFIEAmRpCQECYmsABAJkdgkA2QQBCQCRAwIFAmRpBQFxBAJkVgkAkQMCBQJkaQUBcgQCZHcJANkEAQUCZFYEAmRXCQCRAwIFAmRpBQFzBAJkeAkA2QQBBQJkVwQCZGoJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkaQUBdAQCZGsJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkaQUBdQQCZHkJAJEDAgUCZGkFAXAEAmhVCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmR2CQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmR2Ag4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCaWMJAQJiVAEFAmRWBAJpZAkBAmJUAQUCZFcEAmllCQEBRAIFAmljBQJkagQCaWYJAQFEAgUCaWQFAmRrBAJkRQMJAAACBQJoVQAABQFlCQECYlcCBQJpZgUCaWUEAmVjCQEBRAIFAmRSBQJkawQCZWIJALwCAwUCZWMFAWQFAmRFBAJkUAkBAUgCBQJlYgUCZGoEAmZoCQECZE4JAgAAoMIeBQJkUAUCZHcFAmRSBQJkeAIABgcEAmVtCAUCZmgCXzEEAmliCAUCZmgCXzMEAmRBCAUCZmgCXzQEAmRDCAUCZmgCXzUEAmR6CAUCZmgCXzYJAJQKAgUDbmlsCQC5CQIJAMwIAgIQJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmVtCQDMCAIJAKQDAQkBAUgCBQJkRQUBYgkAzAgCCQCkAwEFAmRBCQDMCAIJAKQDAQUCZEMJAMwIAgkApAMBBQJkegkAzAgCBQJkeQkAzAgCCQCkAwEFAmRQCQDMCAIJAKQDAQUCZFIFA25pbAUBagJmYgETZXZhbHVhdGVHZXRSRUFET05MWQICaWcCaWgEAmVlCQECZHIEAgAFAmlnBQJpaAUEdGhpcwQCZEsIBQJlZQJfMQQCZEwIBQJlZQJfMgQCZEEIBQJlZQJfNQQCZEMIBQJlZQJfNgQCZHoIBQJlZQJfNwQCZEYIBQJlZQJfOAQCZHkJAQ1wYXJzZUludFZhbHVlAQgFAmVlAl85CQCUCgIFA25pbAkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCZEsJAMwIAgkApAMBBQJkTAkAzAgCCQCkAwEFAmRBCQDMCAIJAKQDAQUCZEMJAMwIAgkApAMBBQJkegkAzAgCCQCmAwEFAmRGCQDMCAIJAKQDAQUCZHkFA25pbAUBagECaWkBAmlqAAQCaWsEAmFRCQECZ24AAwkAAQIFAmFRAgpCeXRlVmVjdG9yBAJncQUCYVEFAmdxAwkAAQIFAmFRAgRVbml0CAUCaWkPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IEAmFRBQJpaQMJAAECBQJhUQIFT3JkZXIEAmVRBQJhUQQCaWwJAQJiagAEAmltAwkBAmVNAAkAlAoCBgIACQECZVABBQJlUQQCYUsIBQJpbQJfMQQCYUwIBQJpbQJfMgQCYU0JAPQDAwgFAmVRCWJvZHlCeXRlcwkAkQMCCAUCZVEGcHJvb2ZzAAAIBQJlUQ9zZW5kZXJQdWJsaWNLZXkEAmFOCQD0AwMIBQJlUQlib2R5Qnl0ZXMJAJEDAggFAmVRBnByb29mcwABBQJpbAMDAwUCYUsFAmFNBwUCYU4HBgkBAmFKBAUCYUsFAmFMBQJhTQUCYU4DCQABAgUCYVECFFNldFNjcmlwdFRyYW5zYWN0aW9uBAJhVgUCYVEDCQD0AwMIBQJpaQlib2R5Qnl0ZXMJAJEDAggFAmlpBnByb29mcwAABQJpawYEAmluCQD2AwEJAQV2YWx1ZQEIBQJhVgZzY3JpcHQEAmlvCQDbBAEJAQV2YWx1ZQEJAJ0IAgUCYmQJAQJhRgAEAmlwCQDxBwEFBHRoaXMDCQAAAgUCaW8FAmluCQECIT0CBQJpcAUCaW4HCQD0AwMIBQJpaQlib2R5Qnl0ZXMJAJEDAggFAmlpBnByb29mcwAABQJpaybyJ24=", "height": 2630945, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: AL3rt1EjiFPdwRroAhMrq7s6oPeDVswrHDrSuPy6ZJcJ Next: 6MudcigNJ85VPrEsv5UXVSsFodtt9EJdXuEPHn8Hy67T Diff:
OldNewDifferences
1-{-# STDLIB_VERSION 5 #-}
1+{-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let lPdecimals = 8
1010 let scale18 = toBigInt(1000000000000000000)
1111
1212 let zeroBigInt = toBigInt(0)
13+
14+let big0 = toBigInt(0)
15+
16+let big1 = toBigInt(1)
17+
18+let big2 = toBigInt(2)
19+
20+let wavesString = "WAVES"
1321
1422 let SEP = "__"
1523
5462 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
5563
5664
65+func toX18BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
66+
67+
5768 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
69+
70+
71+func fromX18Round (val,resultScaleMult,round) = toInt(fraction(val, toBigInt(resultScaleMult), scale18, round))
5872
5973
6074 func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
6175
6276
63-func abs (val) = if ((zeroBigInt > val))
77+func abs (val) = if ((0 > val))
6478 then -(val)
6579 else val
80+
81+
82+func absBigInt (val) = if ((zeroBigInt > val))
83+ then -(val)
84+ else val
85+
86+
87+func swapContract () = "%s__swapContract"
6688
6789
6890 func fc () = "%s__factoryContract"
6991
7092
71-func mpk () = "%s__managerPublicKey"
93+func keyManagerPublicKey () = "%s__managerPublicKey"
7294
7395
74-func pmpk () = "%s__pendingManagerPublicKey"
96+func keyManagerVaultAddress () = "%s__managerVaultAddress"
7597
7698
7799 func pl () = "%s%s__price__last"
90112
91113
92114 func pa () = "%s__priceAsset"
115+
116+
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+
133+func keyAdditionalBalance (assetId) = makeString(["%s%s", "stakedBalance", assetId], SEP)
134+
135+
136+func keyStakingAssetBalance (assetId) = makeString(["%s%s", "shareAssetBalance", assetId], SEP)
137+
138+
139+func getAdditionalBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyAdditionalBalance(assetId)), 0)
140+
141+
142+func getStakingAssetBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyStakingAssetBalance(assetId)), 0)
93143
94144
95145 func keyFactoryConfig () = "%s__factoryConfig"
113163 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
114164
115165
116-func throwOrderError (orderValid,senderValid,matcherValid) = throw(((((("order validation failed: orderValid=" + toString(orderValid)) + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
166+func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
167+
168+
169+let keyFeeCollectorAddress = "%s__feeCollectorAddress"
170+
171+func keySkipOrderValidation (poolAddress) = ("%s%s__skipOrderValidation__" + poolAddress)
172+
173+
174+func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
175+
176+
177+func addressFromStringOrThis (addressString) = match addressFromString(addressString) {
178+ case a: Address =>
179+ a
180+ case _ =>
181+ this
182+}
183+
184+
185+func getManagerVaultAddressOrThis () = {
186+ let factoryAddress = match getString(fc()) {
187+ case fca: String =>
188+ addressFromStringOrThis(fca)
189+ case _ =>
190+ this
191+ }
192+ match getString(factoryAddress, keyManagerVaultAddress()) {
193+ case s: String =>
194+ addressFromStringOrThis(s)
195+ case _ =>
196+ this
197+ }
198+ }
117199
118200
119201 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
122204 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
123205
124206
207+func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
208+
209+
210+func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
211+
212+
125213 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
214+
215+let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
216+
217+let inFee = {
218+ let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
219+ if ($isInstanceOf(@, "Int"))
220+ then @
221+ else throw(($getType(@) + " couldn't be cast to Int"))
222+ }
223+
224+let outFee = {
225+ let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
226+ if ($isInstanceOf(@, "Int"))
227+ then @
228+ else throw(($getType(@) + " couldn't be cast to Int"))
229+ }
126230
127231 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
128232
139243 }
140244
141245
246+func parseAssetId (input) = if ((input == wavesString))
247+ then unit
248+ else fromBase58String(input)
249+
250+
251+func assetIdToString (input) = if ((input == unit))
252+ then wavesString
253+ else toBase58String(value(input))
254+
255+
256+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]))
257+
258+
259+let poolConfigParsed = parsePoolConfig(getPoolConfig())
260+
261+let $t095299695 = poolConfigParsed
262+
263+let cfgPoolAddress = $t095299695._1
264+
265+let cfgPoolStatus = $t095299695._2
266+
267+let cfgLpAssetId = $t095299695._3
268+
269+let cfgAmountAssetId = $t095299695._4
270+
271+let cfgPriceAssetId = $t095299695._5
272+
273+let cfgAmountAssetDecimals = $t095299695._6
274+
275+let cfgPriceAssetDecimals = $t095299695._7
276+
142277 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
143278
279+
280+let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
281+
282+let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
144283
145284 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)
146285
148287 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)
149288
150289
151-func getAccBalance (assetId) = if ((assetId == "WAVES"))
152- then wavesBalance(this).available
153- else assetBalance(this, fromBase58String(assetId))
290+func getAccBalance (assetId) = {
291+ let balanceOnPool = if ((assetId == "WAVES"))
292+ then wavesBalance(this).available
293+ else assetBalance(this, fromBase58String(assetId))
294+ let totalBalance = ((balanceOnPool + getAdditionalBalanceOrZero(assetId)) - getStakingAssetBalanceOrZero(assetId))
295+ max([0, totalBalance])
296+ }
154297
155298
156299 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
300+
301+
302+func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
303+
304+
305+func getRate (proxy) = {
306+ let inv = invoke(proxy, "getRate", nil, nil)
307+ if ((inv == inv))
308+ then match inv {
309+ case r: Int =>
310+ r
311+ case _ =>
312+ throwErr("proxy.getRate() unexpected value")
313+ }
314+ else throw("Strict value is not equal to itself.")
315+ }
316+
317+
318+func deposit (assetId,amount,stakingAssetId,proxy) = {
319+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
320+ if ((currentAdditionalBalance == currentAdditionalBalance))
321+ then {
322+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
323+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
324+ then {
325+ let asset = parseAssetId(assetId)
326+ if ((amount > 0))
327+ then {
328+ let depositInvoke = invoke(proxy, "deposit", nil, [AttachedPayment(asset, amount)])
329+ if ((depositInvoke == depositInvoke))
330+ then match depositInvoke {
331+ case receivedStakingAsset: Int =>
332+ let newAdditionalBalance = (currentAdditionalBalance + amount)
333+ let newStakingAssetBalance = (currentStakingAssetBalance + receivedStakingAsset)
334+[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance)]
335+ case _ =>
336+ nil
337+ }
338+ else throw("Strict value is not equal to itself.")
339+ }
340+ else nil
341+ }
342+ else throw("Strict value is not equal to itself.")
343+ }
344+ else throw("Strict value is not equal to itself.")
345+ }
346+
347+
348+func withdraw (assetId,amount,stakingAssetId,proxy,proxyRateMul,profitAddress) = {
349+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
350+ if ((currentAdditionalBalance == currentAdditionalBalance))
351+ then {
352+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
353+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
354+ then {
355+ let currentProxyRate = getRate(proxy)
356+ if ((currentProxyRate == currentProxyRate))
357+ then {
358+ let oldRate = fraction(proxyRateMul, currentAdditionalBalance, currentStakingAssetBalance)
359+ let stakingAsset = parseAssetId(stakingAssetId)
360+ let oldSendStakingAmount = fraction(proxyRateMul, amount, oldRate)
361+ let sendStakingAssetAmount = fraction(proxyRateMul, amount, currentProxyRate)
362+ let profitAmount = max([0, (oldSendStakingAmount - sendStakingAssetAmount)])
363+ if ((sendStakingAssetAmount > 0))
364+ then {
365+ let withdrawInvoke = invoke(proxy, "withdraw", nil, [AttachedPayment(stakingAsset, sendStakingAssetAmount)])
366+ if ((withdrawInvoke == withdrawInvoke))
367+ then match withdrawInvoke {
368+ case receivedAssets: Int =>
369+ let newAdditionalBalance = (currentAdditionalBalance - receivedAssets)
370+ let newStakingAssetBalance = ((currentStakingAssetBalance - sendStakingAssetAmount) - profitAmount)
371+[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance), ScriptTransfer(profitAddress, profitAmount, parseAssetId(stakingAssetId))]
372+ case _ =>
373+ nil
374+ }
375+ else throw("Strict value is not equal to itself.")
376+ }
377+ else nil
378+ }
379+ else throw("Strict value is not equal to itself.")
380+ }
381+ else throw("Strict value is not equal to itself.")
382+ }
383+ else throw("Strict value is not equal to itself.")
384+ }
385+
386+
387+func getLeaseProxyConfig (assetId) = match invoke(factoryContract, "getPoolLeaseConfigREADONLY", [toString(this), assetId], nil) {
388+ case a: (Boolean, Int, Int, String, String, Int, String) =>
389+ a
390+ case _ =>
391+ throwErr((("[" + assetId) + "] getLeaseProxyConfig() error"))
392+}
393+
394+
395+func rebalanceInternal (targetRatio,assetId,stakingAssetId,minBalance,proxy,proxyRateMul,profitAddress) = {
396+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
397+ if ((currentAdditionalBalance == currentAdditionalBalance))
398+ then {
399+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
400+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
401+ then {
402+ let leasableTotalBalance = max([0, (getAccBalance(assetId) - minBalance)])
403+ let targetAdditionalBalance = fraction(targetRatio, leasableTotalBalance, 100)
404+ let diff = (currentAdditionalBalance - targetAdditionalBalance)
405+ if ((diff == 0))
406+ then nil
407+ else if ((0 > diff))
408+ then {
409+ let sendAssetAmount = -(diff)
410+ deposit(assetId, sendAssetAmount, stakingAssetId, proxy)
411+ }
412+ else {
413+ let getAssetAmount = diff
414+ withdraw(assetId, getAssetAmount, stakingAssetId, proxy, proxyRateMul, profitAddress)
415+ }
416+ }
417+ else throw("Strict value is not equal to itself.")
418+ }
419+ else throw("Strict value is not equal to itself.")
420+ }
421+
422+
423+func rebalanceAsset (assetId) = {
424+ let $t01593116067 = getLeaseProxyConfig(assetId)
425+ let isLeasable = $t01593116067._1
426+ let leasedRatio = $t01593116067._2
427+ let minBalance = $t01593116067._3
428+ let proxyAddress = $t01593116067._4
429+ let proxyAssetId = $t01593116067._5
430+ let proxyRateMul = $t01593116067._6
431+ let stakingProfitAddress = $t01593116067._7
432+ if (isLeasable)
433+ then rebalanceInternal(leasedRatio, assetId, proxyAssetId, minBalance, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
434+ else nil
435+ }
436+
437+
438+func withdrawAndRebalanceAsset (assetId,getAmount) = {
439+ let $t01646616602 = getLeaseProxyConfig(assetId)
440+ let isLeasable = $t01646616602._1
441+ let leasedRatio = $t01646616602._2
442+ let minBalance = $t01646616602._3
443+ let proxyAddress = $t01646616602._4
444+ let proxyAssetId = $t01646616602._5
445+ let proxyRateMul = $t01646616602._6
446+ let stakingProfitAddress = $t01646616602._7
447+ if (isLeasable)
448+ then {
449+ let newTotalLeasableBalance = max([0, ((getAccBalance(assetId) - getAmount) - minBalance)])
450+ if ((newTotalLeasableBalance == newTotalLeasableBalance))
451+ then {
452+ let newAdditionalBalance = fraction(leasedRatio, newTotalLeasableBalance, 100)
453+ if ((newAdditionalBalance == newAdditionalBalance))
454+ then {
455+ let withdrawAmount = (getAdditionalBalanceOrZero(assetId) - newAdditionalBalance)
456+ if ((withdrawAmount == withdrawAmount))
457+ then if ((0 > withdrawAmount))
458+ then deposit(assetId, -(withdrawAmount), proxyAssetId, addressFromStringValue(proxyAddress))
459+ else withdraw(assetId, withdrawAmount, proxyAssetId, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
460+ else throw("Strict value is not equal to itself.")
461+ }
462+ else throw("Strict value is not equal to itself.")
463+ }
464+ else throw("Strict value is not equal to itself.")
465+ }
466+ else nil
467+ }
468+
469+
470+func withdrawAndRebalanceAll (amountAssetOutAmount,priceAssetOutAmount) = {
471+ let AmAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, aa()), amountAssetOutAmount)
472+ let PrAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, pa()), priceAssetOutAmount)
473+ (AmAmtWithdrawState ++ PrAmtWithdrawState)
474+ }
157475
158476
159477 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
205523 let lpEmissionX18 = toX18(lpEmission, scale8)
206524 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
207525 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
208- let outAmAmt = fromX18(outAmAmtX18, amAssetDcm)
209- let outPrAmt = fromX18(outPrAmtX18, prAssetDcm)
526+ let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
527+ let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
210528 let state = if ((txId58 == ""))
211529 then nil
212530 else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
257575 }
258576 else {
259577 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
260- let slippageX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
578+ let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
261579 let slippageToleranceX18 = toX18(slippageTolerance, scale8)
262580 if (if ((curPriceX18 != zeroBigInt))
263581 then (slippageX18 > slippageToleranceX18)
265583 then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
266584 else {
267585 let lpEmissionX18 = toX18(lpEmission, scale8)
268- let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
269- let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
586+ let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
587+ let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
270588 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
271589 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
272590 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
273591 let expAmtAssetAmtX18 = expectedAmts._1
274592 let expPriceAssetAmtX18 = expectedAmts._2
275- let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
276- $Tuple5(fromX18(lpAmtX18, scale8), fromX18(expAmtAssetAmtX18, amtAssetDcm), fromX18(expPriceAssetAmtX18, priceAssetDcm), curPriceX18, slippageX18)
593+ let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
594+ $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
277595 }
278596 }
279597 let calcLpAmt = res._1
296614 }
297615
298616
617+func calcKLp (amountBalance,priceBalance,lpEmission) = {
618+ let amountBalanceX18 = toX18BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals))
619+ let priceBalanceX18 = toX18BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))
620+ let updatedKLp = fraction(pow((amountBalanceX18 * priceBalanceX18), 0, toBigInt(5), 1, 18, DOWN), big1, lpEmission)
621+ if ((lpEmission == big0))
622+ then big0
623+ else updatedKLp
624+ }
625+
626+
627+func calcCurrentKLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
628+ let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
629+ let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
630+ let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
631+ let currentKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
632+ currentKLp
633+ }
634+
635+
636+func refreshKLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
637+ let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
638+ let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
639+ let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
640+ let updatedKLp = calcKLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
641+ let actions = [IntegerEntry(keyKLpRefreshedHeight, height), StringEntry(keyKLp, toString(updatedKLp))]
642+ $Tuple2(actions, updatedKLp)
643+ }
644+
645+
646+func skipOrderValidation () = valueOrElse(getBoolean(factoryContract, keySkipOrderValidation(toString(this))), false)
647+
648+
649+func validateUpdatedKLp (oldKLp,updatedKLp) = if ((updatedKLp >= oldKLp))
650+ then true
651+ else throwErr(makeString(["updated KLp lower than current KLp", toString(oldKLp), toString(updatedKLp)], " "))
652+
653+
299654 func validateMatcherOrderAllowed (order) = {
300- let cfg = getPoolConfig()
301- let amtAssetId = cfg[idxAmtAssetId]
302- let priceAssetId = cfg[idxPriceAssetId]
303- let poolStatus = parseIntValue(cfg[idxPoolStatus])
304- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
305- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
306- let accAmtAssetBalance = getAccBalance(amtAssetId)
307- let accPriceAssetBalance = getAccBalance(priceAssetId)
308- let curPriceX18 = if ((order.orderType == Buy))
309- then privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
310- else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance - order.amount), accPriceAssetBalance)
311- let curPrice = fromX18(curPriceX18, scale8)
655+ let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
656+ let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
657+ let amountAssetAmount = order.amount
658+ let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
659+ let $t02899129203 = if ((order.orderType == Buy))
660+ then $Tuple2(amountAssetAmount, -(priceAssetAmount))
661+ else $Tuple2(-(amountAssetAmount), priceAssetAmount)
662+ let amountAssetBalanceDelta = $t02899129203._1
663+ let priceAssetBalanceDelta = $t02899129203._2
312664 if (if (if (isGlobalShutdown())
313665 then true
314- else (poolStatus == PoolMatcherDisabled))
666+ else (cfgPoolStatus == PoolMatcherDisabled))
315667 then true
316- else (poolStatus == PoolShutdown))
668+ else (cfgPoolStatus == PoolShutdown))
317669 then throw("Exchange operations disabled")
318- else {
319- let orderAmtAsset = order.assetPair.amountAsset
320- let orderAmtAssetStr = if ((orderAmtAsset == unit))
321- then "WAVES"
322- else toBase58String(value(orderAmtAsset))
323- let orderPriceAsset = order.assetPair.priceAsset
324- let orderPriceAssetStr = if ((orderPriceAsset == unit))
325- then "WAVES"
326- else toBase58String(value(orderPriceAsset))
327- if (if ((orderAmtAssetStr != amtAssetId))
328- then true
329- else (orderPriceAssetStr != priceAssetId))
330- then throw("Wrong order assets.")
331- else {
332- let orderPrice = order.price
333- let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
334- let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
335- let isOrderPriceValid = if ((order.orderType == Buy))
336- then (curPrice >= castedOrderPrice)
337- else (castedOrderPrice >= curPrice)
338- true
339- }
340- }
670+ else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
671+ then true
672+ else (order.assetPair.priceAsset != cfgPriceAssetId))
673+ then throw("Wrong order assets.")
674+ else {
675+ let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
676+ let $t02964329743 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
677+ let unusedActions = $t02964329743._1
678+ let kLpNew = $t02964329743._2
679+ let isOrderValid = (kLpNew >= kLp)
680+ let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
681+ $Tuple2(isOrderValid, info)
682+ }
341683 }
342684
343685
377719 }
378720
379721
380-func managerPublicKeyOrUnit () = match getString(mpk()) {
381- case s: String =>
382- fromBase58String(s)
383- case _: Unit =>
384- unit
385- case _ =>
386- throw("Match error")
387-}
722+func emit (amount) = {
723+ let emitInv = invoke(factoryContract, "emit", [amount], nil)
724+ if ((emitInv == emitInv))
725+ then {
726+ let emitInvLegacy = match emitInv {
727+ case legacyFactoryContract: Address =>
728+ invoke(legacyFactoryContract, "emit", [amount], nil)
729+ case _ =>
730+ unit
731+ }
732+ if ((emitInvLegacy == emitInvLegacy))
733+ then amount
734+ else throw("Strict value is not equal to itself.")
735+ }
736+ else throw("Strict value is not equal to itself.")
737+ }
388738
389739
390-func pendingManagerPublicKeyOrUnit () = match getString(pmpk()) {
391- case s: String =>
392- fromBase58String(s)
740+func takeFee (amount,fee) = {
741+ let feeAmount = if ((fee == 0))
742+ then 0
743+ else fraction(amount, fee, scale8)
744+ $Tuple2((amount - feeAmount), feeAmount)
745+ }
746+
747+
748+func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
749+ let isEval = (txId == unit)
750+ let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
751+ let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
752+ let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
753+ then true
754+ else if ((paymentAssetId == cfgPriceAssetId))
755+ then false
756+ else throwErr("invalid asset")
757+ let $t03285633149 = if (isEval)
758+ then $Tuple2(amountBalanceRaw, priceBalanceRaw)
759+ else if (paymentInAmountAsset)
760+ then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
761+ else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
762+ let amountBalanceOld = $t03285633149._1
763+ let priceBalanceOld = $t03285633149._2
764+ let $t03315333302 = if (paymentInAmountAsset)
765+ then $Tuple2(paymentAmountRaw, 0)
766+ else $Tuple2(0, paymentAmountRaw)
767+ let amountAssetAmountRaw = $t03315333302._1
768+ let priceAssetAmountRaw = $t03315333302._2
769+ let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
770+ let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
771+ let $t03343433498 = takeFee(paymentAmountRaw, inFee)
772+ let paymentAmount = $t03343433498._1
773+ let feeAmount = $t03343433498._2
774+ let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
775+ let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
776+ let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
777+ let priceNew = fromX18(priceNewX18, scale8)
778+ let paymentBalance = if (paymentInAmountAsset)
779+ then amountBalanceOld
780+ else priceBalanceOld
781+ let paymentBalanceBigInt = toBigInt(paymentBalance)
782+ let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
783+ let chechSupply = if ((supplyBigInt > big0))
784+ then true
785+ else throwErr("initial deposit requires all coins")
786+ if ((chechSupply == chechSupply))
787+ then {
788+ let depositBigInt = toBigInt(paymentAmount)
789+ let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
790+ let commonState = if (isEval)
791+ then nil
792+ 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))]
793+ let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
794+ let priceOld = fromX18(priceOldX18, scale8)
795+ let loss = {
796+ let $t03517935346 = if (paymentInAmountAsset)
797+ then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
798+ else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
799+ let amount = $t03517935346._1
800+ let balance = $t03517935346._2
801+ let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
802+ fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
803+ }
804+ $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
805+ }
806+ else throw("Strict value is not equal to itself.")
807+ }
808+
809+
810+func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
811+ let isEval = (txId == unit)
812+ let cfg = getPoolConfig()
813+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
814+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
815+ let checks = [if ((paymentAssetId == cfgLpAssetId))
816+ then true
817+ else throwErr("invalid lp asset")]
818+ if ((checks == checks))
819+ then {
820+ let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
821+ then true
822+ else if ((outAssetId == cfgPriceAssetId))
823+ then false
824+ else throwErr("invalid asset")
825+ let balanceBigInt = if (outInAmountAsset)
826+ then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
827+ else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
828+ let outInAmountAssetDecimals = if (outInAmountAsset)
829+ then amtAssetDcm
830+ else priceAssetDcm
831+ let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
832+ let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
833+ let outBalance = if (outInAmountAsset)
834+ then amBalanceOld
835+ else prBalanceOld
836+ let outBalanceBigInt = toBigInt(outBalance)
837+ let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
838+ let redeemedBigInt = toBigInt(paymentAmount)
839+ let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
840+ let $t03742437480 = takeFee(amountRaw, outFee)
841+ let totalAmount = $t03742437480._1
842+ let feeAmount = $t03742437480._2
843+ let $t03748437710 = if (outInAmountAsset)
844+ then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
845+ else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
846+ let outAmAmount = $t03748437710._1
847+ let outPrAmount = $t03748437710._2
848+ let amBalanceNew = $t03748437710._3
849+ let prBalanceNew = $t03748437710._4
850+ let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
851+ let priceNew = fromX18(priceNewX18, scale8)
852+ let commonState = if (isEval)
853+ then nil
854+ 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)]
855+ let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
856+ let priceOld = fromX18(priceOldX18, scale8)
857+ let loss = {
858+ let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
859+ fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
860+ }
861+ $Tuple5(totalAmount, commonState, feeAmount, loss, outInAmountAsset)
862+ }
863+ else throw("Strict value is not equal to itself.")
864+ }
865+
866+
867+func managerPublicKeyOrUnit () = {
868+ let managerVaultAddress = getManagerVaultAddressOrThis()
869+ match getString(managerVaultAddress, keyManagerPublicKey()) {
870+ case s: String =>
871+ fromBase58String(s)
872+ case _: Unit =>
873+ unit
874+ case _ =>
875+ throw("Match error")
876+ }
877+ }
878+
879+
880+func isManager (i) = match managerPublicKeyOrUnit() {
881+ case pk: ByteVector =>
882+ (i.callerPublicKey == pk)
393883 case _: Unit =>
394- unit
884+ (i.caller == this)
395885 case _ =>
396886 throw("Match error")
397887 }
415905
416906
417907 @Callable(i)
418-func constructor (factoryContract) = {
419- let checkCaller = mustManager(i)
420- if ((checkCaller == checkCaller))
421- then [StringEntry(fc(), factoryContract)]
908+func rebalance () = (rebalanceAsset(getStringOrFail(this, aa())) ++ rebalanceAsset(getStringOrFail(this, pa())))
909+
910+
911+
912+@Callable(i)
913+func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse,feePoolAmount) = {
914+ let $t03956939874 = if ((isReverse == false))
915+ then {
916+ let assetOut = getStringOrFail(this, pa())
917+ let assetIn = getStringOrFail(this, aa())
918+ $Tuple2(assetOut, assetIn)
919+ }
920+ else {
921+ let assetOut = getStringOrFail(this, aa())
922+ let assetIn = getStringOrFail(this, pa())
923+ $Tuple2(assetOut, assetIn)
924+ }
925+ let assetOut = $t03956939874._1
926+ let assetIn = $t03956939874._2
927+ let poolAssetInBalance = getAccBalance(assetIn)
928+ let poolAssetOutBalance = getAccBalance(assetOut)
929+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
930+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
931+ let newK = (((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
932+ let checkK = if ((newK >= oldK))
933+ then true
934+ else throw("new K is fewer error")
935+ if ((checkK == checkK))
936+ then $Tuple2(nil, amountOut)
422937 else throw("Strict value is not equal to itself.")
423938 }
424939
425940
426941
427942 @Callable(i)
428-func setManager (pendingManagerPublicKey) = {
429- let checkCaller = mustManager(i)
430- if ((checkCaller == checkCaller))
943+func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo,feePoolAmount) = {
944+ let swapContact = {
945+ let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil)
946+ if ($isInstanceOf(@, "String"))
947+ then @
948+ else throw(($getType(@) + " couldn't be cast to String"))
949+ }
950+ let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
951+ then true
952+ else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
953+ then true
954+ else throwErr("Permission denied")]
955+ if ((checks == checks))
431956 then {
432- let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
433- if ((checkManagerPublicKey == checkManagerPublicKey))
434- then [StringEntry(pmpk(), pendingManagerPublicKey)]
957+ let pmt = value(i.payments[0])
958+ let assetIn = assetIdToString(pmt.assetId)
959+ let assetOut = if ((isReverse == false))
960+ then getStringOrFail(this, pa())
961+ else getStringOrFail(this, aa())
962+ let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
963+ let poolAssetOutBalance = getAccBalance(assetOut)
964+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
965+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
966+ let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
967+ let checkK = if ((newK >= oldK))
968+ then true
969+ else throw("new K is fewer error")
970+ if ((checkK == checkK))
971+ then {
972+ let checkMin = if ((amountOut >= amountOutMin))
973+ then true
974+ else throw("Exchange result is fewer coins than expected")
975+ if ((checkMin == checkMin))
976+ then {
977+ let rebalanceState = rebalanceAsset(assetIn)
978+ if ((rebalanceState == rebalanceState))
979+ then {
980+ let withdrawState = withdrawAndRebalanceAsset(assetOut, amountOut)
981+ if ((withdrawState == withdrawState))
982+ then $Tuple2(((withdrawState ++ rebalanceState) ++ [ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))]), amountOut)
983+ else throw("Strict value is not equal to itself.")
984+ }
985+ else throw("Strict value is not equal to itself.")
986+ }
987+ else throw("Strict value is not equal to itself.")
988+ }
435989 else throw("Strict value is not equal to itself.")
436990 }
437991 else throw("Strict value is not equal to itself.")
440994
441995
442996 @Callable(i)
443-func confirmManager () = {
444- let pm = pendingManagerPublicKeyOrUnit()
445- let hasPM = if (isDefined(pm))
446- then true
447- else throw("No pending manager")
448- if ((hasPM == hasPM))
449- then {
450- let checkPM = if ((i.callerPublicKey == value(pm)))
451- then true
452- else throw("You are not pending manager")
453- if ((checkPM == checkPM))
454- then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())]
455- else throw("Strict value is not equal to itself.")
456- }
457- else throw("Strict value is not equal to itself.")
458- }
997+func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
998+ then throw("Invalid slippageTolerance passed")
999+ else {
1000+ let estPut = commonPut(i, slippageTolerance, true)
1001+ let emitLpAmt = estPut._2
1002+ let lpAssetId = estPut._7
1003+ let state = estPut._9
1004+ let amDiff = estPut._10
1005+ let prDiff = estPut._11
1006+ let amId = estPut._12
1007+ let prId = estPut._13
1008+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1009+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1010+ let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
1011+ if ((currentKLp == currentKLp))
1012+ then {
1013+ let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
1014+ if ((emitInv == emitInv))
1015+ then {
1016+ let emitInvLegacy = match emitInv {
1017+ case legacyFactoryContract: Address =>
1018+ invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
1019+ case _ =>
1020+ unit
1021+ }
1022+ if ((emitInvLegacy == emitInvLegacy))
1023+ then {
1024+ let slippageAInv = if ((amDiff > 0))
1025+ then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
1026+ else nil
1027+ if ((slippageAInv == slippageAInv))
1028+ then {
1029+ let slippagePInv = if ((prDiff > 0))
1030+ then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
1031+ else nil
1032+ if ((slippagePInv == slippagePInv))
1033+ then {
1034+ let lpTransfer = if (shouldAutoStake)
1035+ then {
1036+ let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
1037+ if ((slpStakeInv == slpStakeInv))
1038+ then nil
1039+ else throw("Strict value is not equal to itself.")
1040+ }
1041+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1042+ let $t04436144823 = refreshKLpInternal(0, 0, 0)
1043+ if (($t04436144823 == $t04436144823))
1044+ then {
1045+ let updatedKLp = $t04436144823._2
1046+ let refreshKLpActions = $t04436144823._1
1047+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1048+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1049+ then {
1050+ let reb = invoke(this, "rebalance", nil, nil)
1051+ if ((reb == reb))
1052+ then ((state ++ lpTransfer) ++ refreshKLpActions)
1053+ else throw("Strict value is not equal to itself.")
1054+ }
1055+ else throw("Strict value is not equal to itself.")
1056+ }
1057+ else throw("Strict value is not equal to itself.")
1058+ }
1059+ else throw("Strict value is not equal to itself.")
1060+ }
1061+ else throw("Strict value is not equal to itself.")
1062+ }
1063+ else throw("Strict value is not equal to itself.")
1064+ }
1065+ else throw("Strict value is not equal to itself.")
1066+ }
1067+ else throw("Strict value is not equal to itself.")
1068+ }
4591069
4601070
4611071
4621072 @Callable(i)
463-func put (slippageTolerance,shouldAutoStake) = {
464- let factoryCfg = getFactoryConfig()
465- let stakingContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactoryStakingContract]), "Error. Incorrect staking address.")
466- let slippageContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactorySlippageContract]), "Error. Incorrect slippage contract address.")
467- if ((0 > slippageTolerance))
468- then throw("Invalid slippageTolerance passed")
469- else {
470- let estPut = commonPut(i, slippageTolerance, true)
471- let emitLpAmt = estPut._2
472- let lpAssetId = estPut._7
473- let state = estPut._9
474- let amDiff = estPut._10
475- let prDiff = estPut._11
476- let amId = estPut._12
477- let prId = estPut._13
478- let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
479- if ((emitInv == emitInv))
1073+func putForFree (maxSlippage) = if ((0 > maxSlippage))
1074+ then throw("Invalid value passed")
1075+ else {
1076+ let estPut = commonPut(i, maxSlippage, false)
1077+ let state = estPut._9
1078+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1079+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1080+ let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
1081+ if ((currentKLp == currentKLp))
1082+ then {
1083+ let $t04543545500 = refreshKLpInternal(0, 0, 0)
1084+ let refreshKLpActions = $t04543545500._1
1085+ let updatedKLp = $t04543545500._2
1086+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1087+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1088+ then (state ++ refreshKLpActions)
1089+ else throw("Strict value is not equal to itself.")
1090+ }
1091+ else throw("Strict value is not equal to itself.")
1092+ }
1093+
1094+
1095+
1096+@Callable(i)
1097+func putOneTkn (minOutAmount,autoStake) = {
1098+ let isPoolOneTokenOperationsDisabled = {
1099+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1100+ if ($isInstanceOf(@, "Boolean"))
1101+ then @
1102+ else throw(($getType(@) + " couldn't be cast to Boolean"))
1103+ }
1104+ let isPutDisabled = if (if (if (isGlobalShutdown())
1105+ then true
1106+ else (cfgPoolStatus == PoolPutDisabled))
1107+ then true
1108+ else (cfgPoolStatus == PoolShutdown))
1109+ then true
1110+ else isPoolOneTokenOperationsDisabled
1111+ let checks = [if (if (!(isPutDisabled))
1112+ then true
1113+ else isManager(i))
1114+ then true
1115+ else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
1116+ then true
1117+ else throwErr("exactly 1 payment are expected")]
1118+ if ((checks == checks))
1119+ then {
1120+ let payment = i.payments[0]
1121+ let paymentAssetId = payment.assetId
1122+ let paymentAmountRaw = payment.amount
1123+ let currentKLp = if ((paymentAssetId == cfgAmountAssetId))
1124+ then calcCurrentKLp(toBigInt(paymentAmountRaw), toBigInt(0), toBigInt(0))
1125+ else if ((paymentAssetId == cfgPriceAssetId))
1126+ then calcCurrentKLp(toBigInt(0), toBigInt(paymentAmountRaw), toBigInt(0))
1127+ else throwErr("payment asset is not supported")
1128+ if ((currentKLp == currentKLp))
4801129 then {
481- let emitInvLegacy = match emitInv {
482- case legacyFactoryContract: Address =>
483- invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
484- case _ =>
485- unit
486- }
487- if ((emitInvLegacy == emitInvLegacy))
1130+ let userAddress = i.caller
1131+ let txId = i.transactionId
1132+ let $t04668846840 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
1133+ if (($t04668846840 == $t04668846840))
4881134 then {
489- let slippageAInv = if ((amDiff > 0))
490- then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
491- else nil
492- if ((slippageAInv == slippageAInv))
1135+ let paymentInAmountAsset = $t04668846840._5
1136+ let bonus = $t04668846840._4
1137+ let feeAmount = $t04668846840._3
1138+ let commonState = $t04668846840._2
1139+ let emitAmountEstimated = $t04668846840._1
1140+ let emitAmount = if (if ((minOutAmount > 0))
1141+ then (minOutAmount > emitAmountEstimated)
1142+ else false)
1143+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1144+ else emitAmountEstimated
1145+ let emitInv = emit(emitAmount)
1146+ if ((emitInv == emitInv))
4931147 then {
494- let slippagePInv = if ((prDiff > 0))
495- then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
1148+ let lpTransfer = if (autoStake)
1149+ then {
1150+ let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
1151+ if ((stakeInv == stakeInv))
1152+ then nil
1153+ else throw("Strict value is not equal to itself.")
1154+ }
1155+ else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
1156+ let sendFee = if ((feeAmount > 0))
1157+ then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
4961158 else nil
497- if ((slippagePInv == slippagePInv))
1159+ let $t04742647623 = if ((this == feeCollectorAddress))
1160+ then $Tuple2(0, 0)
1161+ else if (paymentInAmountAsset)
1162+ then $Tuple2(-(feeAmount), 0)
1163+ else $Tuple2(0, -(feeAmount))
1164+ let amountAssetBalanceDelta = $t04742647623._1
1165+ let priceAssetBalanceDelta = $t04742647623._2
1166+ let $t04762647734 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1167+ let refreshKLpActions = $t04762647734._1
1168+ let updatedKLp = $t04762647734._2
1169+ let kLp = value(getString(keyKLp))
1170+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1171+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
4981172 then {
499- let lpTransfer = if (shouldAutoStake)
500- then {
501- let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
502- if ((slpStakeInv == slpStakeInv))
503- then nil
504- else throw("Strict value is not equal to itself.")
505- }
506- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
507- (state ++ lpTransfer)
1173+ let reb = invoke(this, "rebalance", nil, nil)
1174+ if ((reb == reb))
1175+ then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
1176+ else throw("Strict value is not equal to itself.")
5081177 }
5091178 else throw("Strict value is not equal to itself.")
5101179 }
5141183 }
5151184 else throw("Strict value is not equal to itself.")
5161185 }
1186+ else throw("Strict value is not equal to itself.")
5171187 }
5181188
5191189
5201190
5211191 @Callable(i)
522-func putForFree (maxSlippage) = if ((0 > maxSlippage))
523- then throw("Invalid value passed")
524- else {
525- let estPut = commonPut(i, maxSlippage, false)
526- estPut._9
1192+func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
1193+ let $t04808948246 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
1194+ let emitAmountEstimated = $t04808948246._1
1195+ let commonState = $t04808948246._2
1196+ let feeAmount = $t04808948246._3
1197+ let bonus = $t04808948246._4
1198+ let paymentInAmountAsset = $t04808948246._5
1199+ $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
1200+ }
1201+
1202+
1203+
1204+@Callable(i)
1205+func getOneTkn (outAssetIdStr,minOutAmount) = {
1206+ let isPoolOneTokenOperationsDisabled = {
1207+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1208+ if ($isInstanceOf(@, "Boolean"))
1209+ then @
1210+ else throw(($getType(@) + " couldn't be cast to Boolean"))
5271211 }
1212+ let isGetDisabled = if (if (isGlobalShutdown())
1213+ then true
1214+ else (cfgPoolStatus == PoolShutdown))
1215+ then true
1216+ else isPoolOneTokenOperationsDisabled
1217+ let checks = [if (if (!(isGetDisabled))
1218+ then true
1219+ else isManager(i))
1220+ then true
1221+ else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
1222+ then true
1223+ else throwErr("exactly 1 payment are expected")]
1224+ if ((checks == checks))
1225+ then {
1226+ let outAssetId = parseAssetId(outAssetIdStr)
1227+ let payment = i.payments[0]
1228+ let paymentAssetId = payment.assetId
1229+ let paymentAmount = payment.amount
1230+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1231+ if ((currentKLp == currentKLp))
1232+ then {
1233+ let userAddress = i.caller
1234+ let txId = i.transactionId
1235+ let $t04913149284 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1236+ if (($t04913149284 == $t04913149284))
1237+ then {
1238+ let outInAmountAsset = $t04913149284._5
1239+ let bonus = $t04913149284._4
1240+ let feeAmount = $t04913149284._3
1241+ let commonState = $t04913149284._2
1242+ let amountEstimated = $t04913149284._1
1243+ let amount = if (if ((minOutAmount > 0))
1244+ then (minOutAmount > amountEstimated)
1245+ else false)
1246+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1247+ else amountEstimated
1248+ let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
1249+ if ((burnInv == burnInv))
1250+ then {
1251+ let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
1252+ let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
1253+ let sendFee = if ((feeAmount > 0))
1254+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1255+ else nil
1256+ let $t04994850195 = {
1257+ let feeAmountForCalc = if ((this == feeCollectorAddress))
1258+ then 0
1259+ else feeAmount
1260+ if (outInAmountAsset)
1261+ then $Tuple2(-((amount + feeAmountForCalc)), 0)
1262+ else $Tuple2(0, -((amount + feeAmountForCalc)))
1263+ }
1264+ let amountAssetBalanceDelta = $t04994850195._1
1265+ let priceAssetBalanceDelta = $t04994850195._2
1266+ let $t05019850306 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1267+ let refreshKLpActions = $t05019850306._1
1268+ let updatedKLp = $t05019850306._2
1269+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1270+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1271+ then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1272+ else throw("Strict value is not equal to itself.")
1273+ }
1274+ else throw("Strict value is not equal to itself.")
1275+ }
1276+ else throw("Strict value is not equal to itself.")
1277+ }
1278+ else throw("Strict value is not equal to itself.")
1279+ }
1280+ else throw("Strict value is not equal to itself.")
1281+ }
1282+
1283+
1284+
1285+@Callable(i)
1286+func getOneTknREADONLY (outAssetId,paymentAmount) = {
1287+ let $t05058450740 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1288+ let amountEstimated = $t05058450740._1
1289+ let commonState = $t05058450740._2
1290+ let feeAmount = $t05058450740._3
1291+ let bonus = $t05058450740._4
1292+ let outInAmountAsset = $t05058450740._5
1293+ $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
1294+ }
1295+
1296+
1297+
1298+@Callable(i)
1299+func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
1300+ let isPoolOneTokenOperationsDisabled = {
1301+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1302+ if ($isInstanceOf(@, "Boolean"))
1303+ then @
1304+ else throw(($getType(@) + " couldn't be cast to Boolean"))
1305+ }
1306+ let isGetDisabled = if (if (isGlobalShutdown())
1307+ then true
1308+ else (cfgPoolStatus == PoolShutdown))
1309+ then true
1310+ else isPoolOneTokenOperationsDisabled
1311+ let checks = [if (if (!(isGetDisabled))
1312+ then true
1313+ else isManager(i))
1314+ then true
1315+ else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
1316+ then true
1317+ else throwErr("no payments are expected")]
1318+ if ((checks == checks))
1319+ then {
1320+ let outAssetId = parseAssetId(outAssetIdStr)
1321+ let userAddress = i.caller
1322+ let txId = i.transactionId
1323+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1324+ if ((currentKLp == currentKLp))
1325+ then {
1326+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1327+ if ((unstakeInv == unstakeInv))
1328+ then {
1329+ let $t05164551796 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1330+ if (($t05164551796 == $t05164551796))
1331+ then {
1332+ let outInAmountAsset = $t05164551796._5
1333+ let bonus = $t05164551796._4
1334+ let feeAmount = $t05164551796._3
1335+ let commonState = $t05164551796._2
1336+ let amountEstimated = $t05164551796._1
1337+ let amount = if (if ((minOutAmount > 0))
1338+ then (minOutAmount > amountEstimated)
1339+ else false)
1340+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1341+ else amountEstimated
1342+ let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1343+ if ((burnInv == burnInv))
1344+ then {
1345+ let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
1346+ let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
1347+ let sendFee = if ((feeAmount > 0))
1348+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1349+ else nil
1350+ let $t05245552702 = {
1351+ let feeAmountForCalc = if ((this == feeCollectorAddress))
1352+ then 0
1353+ else feeAmount
1354+ if (outInAmountAsset)
1355+ then $Tuple2(-((amount + feeAmountForCalc)), 0)
1356+ else $Tuple2(0, -((amount + feeAmountForCalc)))
1357+ }
1358+ let amountAssetBalanceDelta = $t05245552702._1
1359+ let priceAssetBalanceDelta = $t05245552702._2
1360+ let $t05270552813 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1361+ let refreshKLpActions = $t05270552813._1
1362+ let updatedKLp = $t05270552813._2
1363+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1364+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1365+ then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1366+ else throw("Strict value is not equal to itself.")
1367+ }
1368+ else throw("Strict value is not equal to itself.")
1369+ }
1370+ else throw("Strict value is not equal to itself.")
1371+ }
1372+ else throw("Strict value is not equal to itself.")
1373+ }
1374+ else throw("Strict value is not equal to itself.")
1375+ }
1376+ else throw("Strict value is not equal to itself.")
1377+ }
5281378
5291379
5301380
5311381 @Callable(i)
5321382 func get () = {
5331383 let res = commonGet(i)
534- let outAmtAmt = res._1
1384+ let outAmAmt = res._1
5351385 let outPrAmt = res._2
5361386 let pmtAmt = res._3
5371387 let pmtAssetId = res._4
5381388 let state = res._5
539- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
540- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
541- then state
1389+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1390+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1391+ if ((currentKLp == currentKLp))
1392+ then {
1393+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1394+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1395+ then {
1396+ let $t05390853989 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1397+ let refreshKLpActions = $t05390853989._1
1398+ let updatedKLp = $t05390853989._2
1399+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1400+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1401+ then ((withdrawState ++ state) ++ refreshKLpActions)
1402+ else throw("Strict value is not equal to itself.")
1403+ }
1404+ else throw("Strict value is not equal to itself.")
1405+ }
5421406 else throw("Strict value is not equal to itself.")
5431407 }
5441408
5571421 else if ((noLessThenPriceAsset > outPrAmt))
5581422 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
5591423 else {
560- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
561- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
562- then state
1424+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1425+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1426+ if ((currentKLp == currentKLp))
1427+ then {
1428+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1429+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1430+ then {
1431+ let $t05508455165 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1432+ let refreshKLpActions = $t05508455165._1
1433+ let updatedKLp = $t05508455165._2
1434+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1435+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1436+ then ((withdrawState ++ state) ++ refreshKLpActions)
1437+ else throw("Strict value is not equal to itself.")
1438+ }
1439+ else throw("Strict value is not equal to itself.")
1440+ }
5631441 else throw("Strict value is not equal to itself.")
5641442 }
5651443 }
5741452 if ((checkPayments == checkPayments))
5751453 then {
5761454 let cfg = getPoolConfig()
577- let factoryCfg = getFactoryConfig()
5781455 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
579- let stakingContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactoryStakingContract]), "Error. Incorrect staking address.")
580- let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
581- if ((unstakeInv == unstakeInv))
1456+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1457+ if ((currentKLp == currentKLp))
5821458 then {
583- let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
584- let poolStatus = parseIntValue(res._9)
585- let state = res._10
586- let checkPoolStatus = if (if (isGlobalShutdown())
587- then true
588- else (poolStatus == PoolShutdown))
589- then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
590- else true
591- if ((checkPoolStatus == checkPoolStatus))
1459+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
1460+ if ((unstakeInv == unstakeInv))
5921461 then {
593- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
594- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
595- then state
1462+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1463+ let outAmAmt = res._1
1464+ let outPrAmt = res._2
1465+ let poolStatus = parseIntValue(res._9)
1466+ let state = res._10
1467+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1468+ let checkPoolStatus = if (if (isGlobalShutdown())
1469+ then true
1470+ else (poolStatus == PoolShutdown))
1471+ then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
1472+ else true
1473+ if ((checkPoolStatus == checkPoolStatus))
1474+ then {
1475+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1476+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1477+ then {
1478+ let $t05643756518 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1479+ let refreshKLpActions = $t05643756518._1
1480+ let updatedKLp = $t05643756518._2
1481+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1482+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1483+ then ((withdrawState ++ state) ++ refreshKLpActions)
1484+ else throw("Strict value is not equal to itself.")
1485+ }
1486+ else throw("Strict value is not equal to itself.")
1487+ }
1488+ else throw("Strict value is not equal to itself.")
1489+ }
1490+ else throw("Strict value is not equal to itself.")
1491+ }
1492+ else throw("Strict value is not equal to itself.")
1493+ }
1494+ else throw("Strict value is not equal to itself.")
1495+ }
1496+
1497+
1498+
1499+@Callable(i)
1500+func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
1501+ let isGetDisabled = if (isGlobalShutdown())
1502+ then true
1503+ else (cfgPoolStatus == PoolShutdown)
1504+ let checks = [if (!(isGetDisabled))
1505+ then true
1506+ else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
1507+ then true
1508+ else throw("no payments are expected")]
1509+ if ((checks == checks))
1510+ then {
1511+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1512+ if ((currentKLp == currentKLp))
1513+ then {
1514+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1515+ if ((unstakeInv == unstakeInv))
1516+ then {
1517+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
1518+ let outAmAmt = res._1
1519+ let outPrAmt = res._2
1520+ let state = res._10
1521+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1522+ let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
1523+ then true
1524+ else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
1525+ then true
1526+ else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
1527+ if ((checkAmounts == checkAmounts))
1528+ then {
1529+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1530+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1531+ then {
1532+ let $t05795958040 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1533+ let refreshKLpActions = $t05795958040._1
1534+ let updatedKLp = $t05795958040._2
1535+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1536+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1537+ then ((withdrawState ++ state) ++ refreshKLpActions)
1538+ else throw("Strict value is not equal to itself.")
1539+ }
1540+ else throw("Strict value is not equal to itself.")
1541+ }
5961542 else throw("Strict value is not equal to itself.")
5971543 }
5981544 else throw("Strict value is not equal to itself.")
6081554 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
6091555 then throw("permissions denied")
6101556 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
1557+
1558+
1559+
1560+@Callable(i)
1561+func refreshKLp () = {
1562+ let lastRefreshedBlockHeight = valueOrElse(getInteger(keyKLpRefreshedHeight), 0)
1563+ let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= kLpRefreshDelay))
1564+ then unit
1565+ else throwErr(makeString([toString(kLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1566+ if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
1567+ then {
1568+ let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1569+ let $t05924459308 = refreshKLpInternal(0, 0, 0)
1570+ let kLpUpdateActions = $t05924459308._1
1571+ let updatedKLp = $t05924459308._2
1572+ let actions = if ((kLp != updatedKLp))
1573+ then kLpUpdateActions
1574+ else throwErr("nothing to refresh")
1575+ $Tuple2(actions, toString(updatedKLp))
1576+ }
1577+ else throw("Strict value is not equal to itself.")
1578+ }
6111579
6121580
6131581
7631731
7641732
7651733 @Verifier(tx)
766-func verify () = match tx {
767- case order: Order =>
768- let matcherPub = getMatcherPubOrFail()
769- let orderValid = validateMatcherOrderAllowed(order)
770- let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
771- let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
772- if (if (if (orderValid)
773- then senderValid
774- else false)
775- then matcherValid
776- else false)
777- then true
778- else throwOrderError(orderValid, senderValid, matcherValid)
779- case _ =>
780- let targetPublicKey = match managerPublicKeyOrUnit() {
781- case pk: ByteVector =>
782- pk
783- case _: Unit =>
784- tx.senderPublicKey
785- case _ =>
786- throw("Match error")
787- }
788- sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
789-}
1734+func verify () = {
1735+ let targetPublicKey = match managerPublicKeyOrUnit() {
1736+ case pk: ByteVector =>
1737+ pk
1738+ case _: Unit =>
1739+ tx.senderPublicKey
1740+ case _ =>
1741+ throw("Match error")
1742+ }
1743+ match tx {
1744+ case order: Order =>
1745+ let matcherPub = getMatcherPubOrFail()
1746+ let $t06797068087 = if (skipOrderValidation())
1747+ then $Tuple2(true, "")
1748+ else validateMatcherOrderAllowed(order)
1749+ let orderValid = $t06797068087._1
1750+ let orderValidInfo = $t06797068087._2
1751+ let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
1752+ let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
1753+ if (if (if (orderValid)
1754+ then senderValid
1755+ else false)
1756+ then matcherValid
1757+ else false)
1758+ then true
1759+ else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
1760+ case s: SetScriptTransaction =>
1761+ if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
1762+ then true
1763+ else {
1764+ let newHash = blake2b256(value(s.script))
1765+ let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
1766+ let currentHash = scriptHash(this)
1767+ if ((allowedHash == newHash))
1768+ then (currentHash != newHash)
1769+ else false
1770+ }
1771+ case _ =>
1772+ sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
1773+ }
1774+ }
7901775
Full:
OldNewDifferences
1-{-# STDLIB_VERSION 5 #-}
1+{-# 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)
13+
14+let big0 = toBigInt(0)
15+
16+let big1 = toBigInt(1)
17+
18+let big2 = toBigInt(2)
19+
20+let wavesString = "WAVES"
1321
1422 let SEP = "__"
1523
1624 let PoolActive = 1
1725
1826 let PoolPutDisabled = 2
1927
2028 let PoolMatcherDisabled = 3
2129
2230 let PoolShutdown = 4
2331
2432 let idxPoolAddress = 1
2533
2634 let idxPoolStatus = 2
2735
2836 let idxPoolLPAssetId = 3
2937
3038 let idxAmtAssetId = 4
3139
3240 let idxPriceAssetId = 5
3341
3442 let idxAmtAssetDcm = 6
3543
3644 let idxPriceAssetDcm = 7
3745
3846 let idxIAmtAssetId = 8
3947
4048 let idxIPriceAssetId = 9
4149
4250 let idxLPAssetDcm = 10
4351
4452 let idxPoolAmtAssetAmt = 1
4553
4654 let idxPoolPriceAssetAmt = 2
4755
4856 let idxPoolLPAssetAmt = 3
4957
5058 let idxFactoryStakingContract = 1
5159
5260 let idxFactorySlippageContract = 7
5361
5462 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
5563
5664
65+func toX18BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
66+
67+
5768 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
69+
70+
71+func fromX18Round (val,resultScaleMult,round) = toInt(fraction(val, toBigInt(resultScaleMult), scale18, round))
5872
5973
6074 func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
6175
6276
63-func abs (val) = if ((zeroBigInt > val))
77+func abs (val) = if ((0 > val))
6478 then -(val)
6579 else val
80+
81+
82+func absBigInt (val) = if ((zeroBigInt > val))
83+ then -(val)
84+ else val
85+
86+
87+func swapContract () = "%s__swapContract"
6688
6789
6890 func fc () = "%s__factoryContract"
6991
7092
71-func mpk () = "%s__managerPublicKey"
93+func keyManagerPublicKey () = "%s__managerPublicKey"
7294
7395
74-func pmpk () = "%s__pendingManagerPublicKey"
96+func keyManagerVaultAddress () = "%s__managerVaultAddress"
7597
7698
7799 func pl () = "%s%s__price__last"
78100
79101
80102 func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
81103
82104
83105 func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
84106
85107
86108 func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
87109
88110
89111 func aa () = "%s__amountAsset"
90112
91113
92114 func pa () = "%s__priceAsset"
115+
116+
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+
133+func keyAdditionalBalance (assetId) = makeString(["%s%s", "stakedBalance", assetId], SEP)
134+
135+
136+func keyStakingAssetBalance (assetId) = makeString(["%s%s", "shareAssetBalance", assetId], SEP)
137+
138+
139+func getAdditionalBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyAdditionalBalance(assetId)), 0)
140+
141+
142+func getStakingAssetBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyStakingAssetBalance(assetId)), 0)
93143
94144
95145 func keyFactoryConfig () = "%s__factoryConfig"
96146
97147
98148 func keyMatcherPub () = "%s%s__matcher__publicKey"
99149
100150
101151 func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
102152
103153
104154 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
105155
106156
107157 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
108158
109159
110160 func keyAllPoolsShutdown () = "%s__shutdown"
111161
112162
113163 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
114164
115165
116-func throwOrderError (orderValid,senderValid,matcherValid) = throw(((((("order validation failed: orderValid=" + toString(orderValid)) + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
166+func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
167+
168+
169+let keyFeeCollectorAddress = "%s__feeCollectorAddress"
170+
171+func keySkipOrderValidation (poolAddress) = ("%s%s__skipOrderValidation__" + poolAddress)
172+
173+
174+func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
175+
176+
177+func addressFromStringOrThis (addressString) = match addressFromString(addressString) {
178+ case a: Address =>
179+ a
180+ case _ =>
181+ this
182+}
183+
184+
185+func getManagerVaultAddressOrThis () = {
186+ let factoryAddress = match getString(fc()) {
187+ case fca: String =>
188+ addressFromStringOrThis(fca)
189+ case _ =>
190+ this
191+ }
192+ match getString(factoryAddress, keyManagerVaultAddress()) {
193+ case s: String =>
194+ addressFromStringOrThis(s)
195+ case _ =>
196+ this
197+ }
198+ }
117199
118200
119201 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
120202
121203
122204 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
123205
124206
207+func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
208+
209+
210+func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
211+
212+
125213 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
214+
215+let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
216+
217+let inFee = {
218+ let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
219+ if ($isInstanceOf(@, "Int"))
220+ then @
221+ else throw(($getType(@) + " couldn't be cast to Int"))
222+ }
223+
224+let outFee = {
225+ let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
226+ if ($isInstanceOf(@, "Int"))
227+ then @
228+ else throw(($getType(@) + " couldn't be cast to Int"))
229+ }
126230
127231 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
128232
129233
130234 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
131235
132236
133237 func getPoolConfig () = {
134238 let amtAsset = getStringOrFail(this, aa())
135239 let priceAsset = getStringOrFail(this, pa())
136240 let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
137241 let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
138242 split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
139243 }
140244
141245
246+func parseAssetId (input) = if ((input == wavesString))
247+ then unit
248+ else fromBase58String(input)
249+
250+
251+func assetIdToString (input) = if ((input == unit))
252+ then wavesString
253+ else toBase58String(value(input))
254+
255+
256+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]))
257+
258+
259+let poolConfigParsed = parsePoolConfig(getPoolConfig())
260+
261+let $t095299695 = poolConfigParsed
262+
263+let cfgPoolAddress = $t095299695._1
264+
265+let cfgPoolStatus = $t095299695._2
266+
267+let cfgLpAssetId = $t095299695._3
268+
269+let cfgAmountAssetId = $t095299695._4
270+
271+let cfgPriceAssetId = $t095299695._5
272+
273+let cfgAmountAssetDecimals = $t095299695._6
274+
275+let cfgPriceAssetDecimals = $t095299695._7
276+
142277 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
143278
279+
280+let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
281+
282+let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
144283
145284 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)
146285
147286
148287 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)
149288
150289
151-func getAccBalance (assetId) = if ((assetId == "WAVES"))
152- then wavesBalance(this).available
153- else assetBalance(this, fromBase58String(assetId))
290+func getAccBalance (assetId) = {
291+ let balanceOnPool = if ((assetId == "WAVES"))
292+ then wavesBalance(this).available
293+ else assetBalance(this, fromBase58String(assetId))
294+ let totalBalance = ((balanceOnPool + getAdditionalBalanceOrZero(assetId)) - getStakingAssetBalanceOrZero(assetId))
295+ max([0, totalBalance])
296+ }
154297
155298
156299 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
300+
301+
302+func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
303+
304+
305+func getRate (proxy) = {
306+ let inv = invoke(proxy, "getRate", nil, nil)
307+ if ((inv == inv))
308+ then match inv {
309+ case r: Int =>
310+ r
311+ case _ =>
312+ throwErr("proxy.getRate() unexpected value")
313+ }
314+ else throw("Strict value is not equal to itself.")
315+ }
316+
317+
318+func deposit (assetId,amount,stakingAssetId,proxy) = {
319+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
320+ if ((currentAdditionalBalance == currentAdditionalBalance))
321+ then {
322+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
323+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
324+ then {
325+ let asset = parseAssetId(assetId)
326+ if ((amount > 0))
327+ then {
328+ let depositInvoke = invoke(proxy, "deposit", nil, [AttachedPayment(asset, amount)])
329+ if ((depositInvoke == depositInvoke))
330+ then match depositInvoke {
331+ case receivedStakingAsset: Int =>
332+ let newAdditionalBalance = (currentAdditionalBalance + amount)
333+ let newStakingAssetBalance = (currentStakingAssetBalance + receivedStakingAsset)
334+[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance)]
335+ case _ =>
336+ nil
337+ }
338+ else throw("Strict value is not equal to itself.")
339+ }
340+ else nil
341+ }
342+ else throw("Strict value is not equal to itself.")
343+ }
344+ else throw("Strict value is not equal to itself.")
345+ }
346+
347+
348+func withdraw (assetId,amount,stakingAssetId,proxy,proxyRateMul,profitAddress) = {
349+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
350+ if ((currentAdditionalBalance == currentAdditionalBalance))
351+ then {
352+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
353+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
354+ then {
355+ let currentProxyRate = getRate(proxy)
356+ if ((currentProxyRate == currentProxyRate))
357+ then {
358+ let oldRate = fraction(proxyRateMul, currentAdditionalBalance, currentStakingAssetBalance)
359+ let stakingAsset = parseAssetId(stakingAssetId)
360+ let oldSendStakingAmount = fraction(proxyRateMul, amount, oldRate)
361+ let sendStakingAssetAmount = fraction(proxyRateMul, amount, currentProxyRate)
362+ let profitAmount = max([0, (oldSendStakingAmount - sendStakingAssetAmount)])
363+ if ((sendStakingAssetAmount > 0))
364+ then {
365+ let withdrawInvoke = invoke(proxy, "withdraw", nil, [AttachedPayment(stakingAsset, sendStakingAssetAmount)])
366+ if ((withdrawInvoke == withdrawInvoke))
367+ then match withdrawInvoke {
368+ case receivedAssets: Int =>
369+ let newAdditionalBalance = (currentAdditionalBalance - receivedAssets)
370+ let newStakingAssetBalance = ((currentStakingAssetBalance - sendStakingAssetAmount) - profitAmount)
371+[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance), ScriptTransfer(profitAddress, profitAmount, parseAssetId(stakingAssetId))]
372+ case _ =>
373+ nil
374+ }
375+ else throw("Strict value is not equal to itself.")
376+ }
377+ else nil
378+ }
379+ else throw("Strict value is not equal to itself.")
380+ }
381+ else throw("Strict value is not equal to itself.")
382+ }
383+ else throw("Strict value is not equal to itself.")
384+ }
385+
386+
387+func getLeaseProxyConfig (assetId) = match invoke(factoryContract, "getPoolLeaseConfigREADONLY", [toString(this), assetId], nil) {
388+ case a: (Boolean, Int, Int, String, String, Int, String) =>
389+ a
390+ case _ =>
391+ throwErr((("[" + assetId) + "] getLeaseProxyConfig() error"))
392+}
393+
394+
395+func rebalanceInternal (targetRatio,assetId,stakingAssetId,minBalance,proxy,proxyRateMul,profitAddress) = {
396+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
397+ if ((currentAdditionalBalance == currentAdditionalBalance))
398+ then {
399+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
400+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
401+ then {
402+ let leasableTotalBalance = max([0, (getAccBalance(assetId) - minBalance)])
403+ let targetAdditionalBalance = fraction(targetRatio, leasableTotalBalance, 100)
404+ let diff = (currentAdditionalBalance - targetAdditionalBalance)
405+ if ((diff == 0))
406+ then nil
407+ else if ((0 > diff))
408+ then {
409+ let sendAssetAmount = -(diff)
410+ deposit(assetId, sendAssetAmount, stakingAssetId, proxy)
411+ }
412+ else {
413+ let getAssetAmount = diff
414+ withdraw(assetId, getAssetAmount, stakingAssetId, proxy, proxyRateMul, profitAddress)
415+ }
416+ }
417+ else throw("Strict value is not equal to itself.")
418+ }
419+ else throw("Strict value is not equal to itself.")
420+ }
421+
422+
423+func rebalanceAsset (assetId) = {
424+ let $t01593116067 = getLeaseProxyConfig(assetId)
425+ let isLeasable = $t01593116067._1
426+ let leasedRatio = $t01593116067._2
427+ let minBalance = $t01593116067._3
428+ let proxyAddress = $t01593116067._4
429+ let proxyAssetId = $t01593116067._5
430+ let proxyRateMul = $t01593116067._6
431+ let stakingProfitAddress = $t01593116067._7
432+ if (isLeasable)
433+ then rebalanceInternal(leasedRatio, assetId, proxyAssetId, minBalance, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
434+ else nil
435+ }
436+
437+
438+func withdrawAndRebalanceAsset (assetId,getAmount) = {
439+ let $t01646616602 = getLeaseProxyConfig(assetId)
440+ let isLeasable = $t01646616602._1
441+ let leasedRatio = $t01646616602._2
442+ let minBalance = $t01646616602._3
443+ let proxyAddress = $t01646616602._4
444+ let proxyAssetId = $t01646616602._5
445+ let proxyRateMul = $t01646616602._6
446+ let stakingProfitAddress = $t01646616602._7
447+ if (isLeasable)
448+ then {
449+ let newTotalLeasableBalance = max([0, ((getAccBalance(assetId) - getAmount) - minBalance)])
450+ if ((newTotalLeasableBalance == newTotalLeasableBalance))
451+ then {
452+ let newAdditionalBalance = fraction(leasedRatio, newTotalLeasableBalance, 100)
453+ if ((newAdditionalBalance == newAdditionalBalance))
454+ then {
455+ let withdrawAmount = (getAdditionalBalanceOrZero(assetId) - newAdditionalBalance)
456+ if ((withdrawAmount == withdrawAmount))
457+ then if ((0 > withdrawAmount))
458+ then deposit(assetId, -(withdrawAmount), proxyAssetId, addressFromStringValue(proxyAddress))
459+ else withdraw(assetId, withdrawAmount, proxyAssetId, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
460+ else throw("Strict value is not equal to itself.")
461+ }
462+ else throw("Strict value is not equal to itself.")
463+ }
464+ else throw("Strict value is not equal to itself.")
465+ }
466+ else nil
467+ }
468+
469+
470+func withdrawAndRebalanceAll (amountAssetOutAmount,priceAssetOutAmount) = {
471+ let AmAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, aa()), amountAssetOutAmount)
472+ let PrAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, pa()), priceAssetOutAmount)
473+ (AmAmtWithdrawState ++ PrAmtWithdrawState)
474+ }
157475
158476
159477 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
160478 let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
161479 let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
162480 calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
163481 }
164482
165483
166484 func calcPrices (amAmt,prAmt,lpAmt) = {
167485 let cfg = getPoolConfig()
168486 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
169487 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
170488 let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
171489 let amAmtX18 = toX18(amAmt, amtAssetDcm)
172490 let prAmtX18 = toX18(prAmt, priceAssetDcm)
173491 let lpAmtX18 = toX18(lpAmt, scale8)
174492 let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
175493 let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
176494 [priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
177495 }
178496
179497
180498 func calculatePrices (amAmt,prAmt,lpAmt) = {
181499 let prices = calcPrices(amAmt, prAmt, lpAmt)
182500 [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
183501 }
184502
185503
186504 func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
187505 let cfg = getPoolConfig()
188506 let lpAssetId = cfg[idxPoolLPAssetId]
189507 let amAssetId = cfg[idxAmtAssetId]
190508 let prAssetId = cfg[idxPriceAssetId]
191509 let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
192510 let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
193511 let poolStatus = cfg[idxPoolStatus]
194512 let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
195513 if ((lpAssetId != pmtAssetId))
196514 then throw("Invalid asset passed.")
197515 else {
198516 let amBalance = getAccBalance(amAssetId)
199517 let amBalanceX18 = toX18(amBalance, amAssetDcm)
200518 let prBalance = getAccBalance(prAssetId)
201519 let prBalanceX18 = toX18(prBalance, prAssetDcm)
202520 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
203521 let curPrice = fromX18(curPriceX18, scale8)
204522 let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
205523 let lpEmissionX18 = toX18(lpEmission, scale8)
206524 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
207525 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
208- let outAmAmt = fromX18(outAmAmtX18, amAssetDcm)
209- let outPrAmt = fromX18(outPrAmtX18, prAssetDcm)
526+ let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
527+ let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
210528 let state = if ((txId58 == ""))
211529 then nil
212530 else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
213531 then unit
214532 else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
215533 then unit
216534 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)]
217535 $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
218536 }
219537 }
220538
221539
222540 func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
223541 let cfg = getPoolConfig()
224542 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
225543 let amAssetIdStr = cfg[idxAmtAssetId]
226544 let prAssetIdStr = cfg[idxPriceAssetId]
227545 let iAmtAssetId = cfg[idxIAmtAssetId]
228546 let iPriceAssetId = cfg[idxIPriceAssetId]
229547 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
230548 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
231549 let poolStatus = cfg[idxPoolStatus]
232550 let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
233551 let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
234552 let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
235553 if (if ((amAssetIdStr != inAmAssetIdStr))
236554 then true
237555 else (prAssetIdStr != inPrAssetIdStr))
238556 then throw("Invalid amt or price asset passed.")
239557 else {
240558 let amBalance = if (isEvaluate)
241559 then getAccBalance(amAssetIdStr)
242560 else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
243561 let prBalance = if (isEvaluate)
244562 then getAccBalance(prAssetIdStr)
245563 else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
246564 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
247565 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
248566 let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
249567 let amBalanceX18 = toX18(amBalance, amtAssetDcm)
250568 let prBalanceX18 = toX18(prBalance, priceAssetDcm)
251569 let res = if ((lpEmission == 0))
252570 then {
253571 let curPriceX18 = zeroBigInt
254572 let slippageX18 = zeroBigInt
255573 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
256574 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
257575 }
258576 else {
259577 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
260- let slippageX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
578+ let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
261579 let slippageToleranceX18 = toX18(slippageTolerance, scale8)
262580 if (if ((curPriceX18 != zeroBigInt))
263581 then (slippageX18 > slippageToleranceX18)
264582 else false)
265583 then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
266584 else {
267585 let lpEmissionX18 = toX18(lpEmission, scale8)
268- let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
269- let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
586+ let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
587+ let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
270588 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
271589 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
272590 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
273591 let expAmtAssetAmtX18 = expectedAmts._1
274592 let expPriceAssetAmtX18 = expectedAmts._2
275- let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
276- $Tuple5(fromX18(lpAmtX18, scale8), fromX18(expAmtAssetAmtX18, amtAssetDcm), fromX18(expPriceAssetAmtX18, priceAssetDcm), curPriceX18, slippageX18)
593+ let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
594+ $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
277595 }
278596 }
279597 let calcLpAmt = res._1
280598 let calcAmAssetPmt = res._2
281599 let calcPrAssetPmt = res._3
282600 let curPrice = fromX18(res._4, scale8)
283601 let slippageCalc = fromX18(res._5, scale8)
284602 if ((0 >= calcLpAmt))
285603 then throw("Invalid calculations. LP calculated is less than zero.")
286604 else {
287605 let emitLpAmt = if (!(emitLp))
288606 then 0
289607 else calcLpAmt
290608 let amDiff = (inAmAssetAmt - calcAmAssetPmt)
291609 let prDiff = (inPrAssetAmt - calcPrAssetPmt)
292610 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))]
293611 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
294612 }
295613 }
296614 }
297615
298616
617+func calcKLp (amountBalance,priceBalance,lpEmission) = {
618+ let amountBalanceX18 = toX18BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals))
619+ let priceBalanceX18 = toX18BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))
620+ let updatedKLp = fraction(pow((amountBalanceX18 * priceBalanceX18), 0, toBigInt(5), 1, 18, DOWN), big1, lpEmission)
621+ if ((lpEmission == big0))
622+ then big0
623+ else updatedKLp
624+ }
625+
626+
627+func calcCurrentKLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
628+ let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
629+ let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
630+ let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
631+ let currentKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
632+ currentKLp
633+ }
634+
635+
636+func refreshKLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
637+ let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
638+ let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
639+ let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
640+ let updatedKLp = calcKLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
641+ let actions = [IntegerEntry(keyKLpRefreshedHeight, height), StringEntry(keyKLp, toString(updatedKLp))]
642+ $Tuple2(actions, updatedKLp)
643+ }
644+
645+
646+func skipOrderValidation () = valueOrElse(getBoolean(factoryContract, keySkipOrderValidation(toString(this))), false)
647+
648+
649+func validateUpdatedKLp (oldKLp,updatedKLp) = if ((updatedKLp >= oldKLp))
650+ then true
651+ else throwErr(makeString(["updated KLp lower than current KLp", toString(oldKLp), toString(updatedKLp)], " "))
652+
653+
299654 func validateMatcherOrderAllowed (order) = {
300- let cfg = getPoolConfig()
301- let amtAssetId = cfg[idxAmtAssetId]
302- let priceAssetId = cfg[idxPriceAssetId]
303- let poolStatus = parseIntValue(cfg[idxPoolStatus])
304- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
305- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
306- let accAmtAssetBalance = getAccBalance(amtAssetId)
307- let accPriceAssetBalance = getAccBalance(priceAssetId)
308- let curPriceX18 = if ((order.orderType == Buy))
309- then privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
310- else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance - order.amount), accPriceAssetBalance)
311- let curPrice = fromX18(curPriceX18, scale8)
655+ let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
656+ let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
657+ let amountAssetAmount = order.amount
658+ let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
659+ let $t02899129203 = if ((order.orderType == Buy))
660+ then $Tuple2(amountAssetAmount, -(priceAssetAmount))
661+ else $Tuple2(-(amountAssetAmount), priceAssetAmount)
662+ let amountAssetBalanceDelta = $t02899129203._1
663+ let priceAssetBalanceDelta = $t02899129203._2
312664 if (if (if (isGlobalShutdown())
313665 then true
314- else (poolStatus == PoolMatcherDisabled))
666+ else (cfgPoolStatus == PoolMatcherDisabled))
315667 then true
316- else (poolStatus == PoolShutdown))
668+ else (cfgPoolStatus == PoolShutdown))
317669 then throw("Exchange operations disabled")
318- else {
319- let orderAmtAsset = order.assetPair.amountAsset
320- let orderAmtAssetStr = if ((orderAmtAsset == unit))
321- then "WAVES"
322- else toBase58String(value(orderAmtAsset))
323- let orderPriceAsset = order.assetPair.priceAsset
324- let orderPriceAssetStr = if ((orderPriceAsset == unit))
325- then "WAVES"
326- else toBase58String(value(orderPriceAsset))
327- if (if ((orderAmtAssetStr != amtAssetId))
328- then true
329- else (orderPriceAssetStr != priceAssetId))
330- then throw("Wrong order assets.")
331- else {
332- let orderPrice = order.price
333- let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
334- let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
335- let isOrderPriceValid = if ((order.orderType == Buy))
336- then (curPrice >= castedOrderPrice)
337- else (castedOrderPrice >= curPrice)
338- true
339- }
340- }
670+ else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
671+ then true
672+ else (order.assetPair.priceAsset != cfgPriceAssetId))
673+ then throw("Wrong order assets.")
674+ else {
675+ let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
676+ let $t02964329743 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
677+ let unusedActions = $t02964329743._1
678+ let kLpNew = $t02964329743._2
679+ let isOrderValid = (kLpNew >= kLp)
680+ let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
681+ $Tuple2(isOrderValid, info)
682+ }
341683 }
342684
343685
344686 func commonGet (i) = if ((size(i.payments) != 1))
345687 then throw("exactly 1 payment is expected")
346688 else {
347689 let pmt = value(i.payments[0])
348690 let pmtAssetId = value(pmt.assetId)
349691 let pmtAmt = pmt.amount
350692 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
351693 let outAmAmt = res._1
352694 let outPrAmt = res._2
353695 let poolStatus = parseIntValue(res._9)
354696 let state = res._10
355697 if (if (isGlobalShutdown())
356698 then true
357699 else (poolStatus == PoolShutdown))
358700 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
359701 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
360702 }
361703
362704
363705 func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
364706 then throw("exactly 2 payments are expected")
365707 else {
366708 let amAssetPmt = value(i.payments[0])
367709 let prAssetPmt = value(i.payments[1])
368710 let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
369711 let poolStatus = parseIntValue(estPut._8)
370712 if (if (if (isGlobalShutdown())
371713 then true
372714 else (poolStatus == PoolPutDisabled))
373715 then true
374716 else (poolStatus == PoolShutdown))
375717 then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
376718 else estPut
377719 }
378720
379721
380-func managerPublicKeyOrUnit () = match getString(mpk()) {
381- case s: String =>
382- fromBase58String(s)
383- case _: Unit =>
384- unit
385- case _ =>
386- throw("Match error")
387-}
722+func emit (amount) = {
723+ let emitInv = invoke(factoryContract, "emit", [amount], nil)
724+ if ((emitInv == emitInv))
725+ then {
726+ let emitInvLegacy = match emitInv {
727+ case legacyFactoryContract: Address =>
728+ invoke(legacyFactoryContract, "emit", [amount], nil)
729+ case _ =>
730+ unit
731+ }
732+ if ((emitInvLegacy == emitInvLegacy))
733+ then amount
734+ else throw("Strict value is not equal to itself.")
735+ }
736+ else throw("Strict value is not equal to itself.")
737+ }
388738
389739
390-func pendingManagerPublicKeyOrUnit () = match getString(pmpk()) {
391- case s: String =>
392- fromBase58String(s)
740+func takeFee (amount,fee) = {
741+ let feeAmount = if ((fee == 0))
742+ then 0
743+ else fraction(amount, fee, scale8)
744+ $Tuple2((amount - feeAmount), feeAmount)
745+ }
746+
747+
748+func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
749+ let isEval = (txId == unit)
750+ let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
751+ let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
752+ let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
753+ then true
754+ else if ((paymentAssetId == cfgPriceAssetId))
755+ then false
756+ else throwErr("invalid asset")
757+ let $t03285633149 = if (isEval)
758+ then $Tuple2(amountBalanceRaw, priceBalanceRaw)
759+ else if (paymentInAmountAsset)
760+ then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
761+ else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
762+ let amountBalanceOld = $t03285633149._1
763+ let priceBalanceOld = $t03285633149._2
764+ let $t03315333302 = if (paymentInAmountAsset)
765+ then $Tuple2(paymentAmountRaw, 0)
766+ else $Tuple2(0, paymentAmountRaw)
767+ let amountAssetAmountRaw = $t03315333302._1
768+ let priceAssetAmountRaw = $t03315333302._2
769+ let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
770+ let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
771+ let $t03343433498 = takeFee(paymentAmountRaw, inFee)
772+ let paymentAmount = $t03343433498._1
773+ let feeAmount = $t03343433498._2
774+ let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
775+ let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
776+ let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
777+ let priceNew = fromX18(priceNewX18, scale8)
778+ let paymentBalance = if (paymentInAmountAsset)
779+ then amountBalanceOld
780+ else priceBalanceOld
781+ let paymentBalanceBigInt = toBigInt(paymentBalance)
782+ let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
783+ let chechSupply = if ((supplyBigInt > big0))
784+ then true
785+ else throwErr("initial deposit requires all coins")
786+ if ((chechSupply == chechSupply))
787+ then {
788+ let depositBigInt = toBigInt(paymentAmount)
789+ let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
790+ let commonState = if (isEval)
791+ then nil
792+ 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))]
793+ let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
794+ let priceOld = fromX18(priceOldX18, scale8)
795+ let loss = {
796+ let $t03517935346 = if (paymentInAmountAsset)
797+ then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
798+ else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
799+ let amount = $t03517935346._1
800+ let balance = $t03517935346._2
801+ let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
802+ fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
803+ }
804+ $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
805+ }
806+ else throw("Strict value is not equal to itself.")
807+ }
808+
809+
810+func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
811+ let isEval = (txId == unit)
812+ let cfg = getPoolConfig()
813+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
814+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
815+ let checks = [if ((paymentAssetId == cfgLpAssetId))
816+ then true
817+ else throwErr("invalid lp asset")]
818+ if ((checks == checks))
819+ then {
820+ let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
821+ then true
822+ else if ((outAssetId == cfgPriceAssetId))
823+ then false
824+ else throwErr("invalid asset")
825+ let balanceBigInt = if (outInAmountAsset)
826+ then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
827+ else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
828+ let outInAmountAssetDecimals = if (outInAmountAsset)
829+ then amtAssetDcm
830+ else priceAssetDcm
831+ let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
832+ let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
833+ let outBalance = if (outInAmountAsset)
834+ then amBalanceOld
835+ else prBalanceOld
836+ let outBalanceBigInt = toBigInt(outBalance)
837+ let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
838+ let redeemedBigInt = toBigInt(paymentAmount)
839+ let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
840+ let $t03742437480 = takeFee(amountRaw, outFee)
841+ let totalAmount = $t03742437480._1
842+ let feeAmount = $t03742437480._2
843+ let $t03748437710 = if (outInAmountAsset)
844+ then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
845+ else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
846+ let outAmAmount = $t03748437710._1
847+ let outPrAmount = $t03748437710._2
848+ let amBalanceNew = $t03748437710._3
849+ let prBalanceNew = $t03748437710._4
850+ let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
851+ let priceNew = fromX18(priceNewX18, scale8)
852+ let commonState = if (isEval)
853+ then nil
854+ 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)]
855+ let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
856+ let priceOld = fromX18(priceOldX18, scale8)
857+ let loss = {
858+ let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
859+ fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
860+ }
861+ $Tuple5(totalAmount, commonState, feeAmount, loss, outInAmountAsset)
862+ }
863+ else throw("Strict value is not equal to itself.")
864+ }
865+
866+
867+func managerPublicKeyOrUnit () = {
868+ let managerVaultAddress = getManagerVaultAddressOrThis()
869+ match getString(managerVaultAddress, keyManagerPublicKey()) {
870+ case s: String =>
871+ fromBase58String(s)
872+ case _: Unit =>
873+ unit
874+ case _ =>
875+ throw("Match error")
876+ }
877+ }
878+
879+
880+func isManager (i) = match managerPublicKeyOrUnit() {
881+ case pk: ByteVector =>
882+ (i.callerPublicKey == pk)
393883 case _: Unit =>
394- unit
884+ (i.caller == this)
395885 case _ =>
396886 throw("Match error")
397887 }
398888
399889
400890 func mustManager (i) = {
401891 let pd = throw("Permission denied")
402892 match managerPublicKeyOrUnit() {
403893 case pk: ByteVector =>
404894 if ((i.callerPublicKey == pk))
405895 then true
406896 else pd
407897 case _: Unit =>
408898 if ((i.caller == this))
409899 then true
410900 else pd
411901 case _ =>
412902 throw("Match error")
413903 }
414904 }
415905
416906
417907 @Callable(i)
418-func constructor (factoryContract) = {
419- let checkCaller = mustManager(i)
420- if ((checkCaller == checkCaller))
421- then [StringEntry(fc(), factoryContract)]
908+func rebalance () = (rebalanceAsset(getStringOrFail(this, aa())) ++ rebalanceAsset(getStringOrFail(this, pa())))
909+
910+
911+
912+@Callable(i)
913+func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse,feePoolAmount) = {
914+ let $t03956939874 = if ((isReverse == false))
915+ then {
916+ let assetOut = getStringOrFail(this, pa())
917+ let assetIn = getStringOrFail(this, aa())
918+ $Tuple2(assetOut, assetIn)
919+ }
920+ else {
921+ let assetOut = getStringOrFail(this, aa())
922+ let assetIn = getStringOrFail(this, pa())
923+ $Tuple2(assetOut, assetIn)
924+ }
925+ let assetOut = $t03956939874._1
926+ let assetIn = $t03956939874._2
927+ let poolAssetInBalance = getAccBalance(assetIn)
928+ let poolAssetOutBalance = getAccBalance(assetOut)
929+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
930+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
931+ let newK = (((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
932+ let checkK = if ((newK >= oldK))
933+ then true
934+ else throw("new K is fewer error")
935+ if ((checkK == checkK))
936+ then $Tuple2(nil, amountOut)
422937 else throw("Strict value is not equal to itself.")
423938 }
424939
425940
426941
427942 @Callable(i)
428-func setManager (pendingManagerPublicKey) = {
429- let checkCaller = mustManager(i)
430- if ((checkCaller == checkCaller))
943+func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo,feePoolAmount) = {
944+ let swapContact = {
945+ let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil)
946+ if ($isInstanceOf(@, "String"))
947+ then @
948+ else throw(($getType(@) + " couldn't be cast to String"))
949+ }
950+ let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
951+ then true
952+ else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
953+ then true
954+ else throwErr("Permission denied")]
955+ if ((checks == checks))
431956 then {
432- let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
433- if ((checkManagerPublicKey == checkManagerPublicKey))
434- then [StringEntry(pmpk(), pendingManagerPublicKey)]
957+ let pmt = value(i.payments[0])
958+ let assetIn = assetIdToString(pmt.assetId)
959+ let assetOut = if ((isReverse == false))
960+ then getStringOrFail(this, pa())
961+ else getStringOrFail(this, aa())
962+ let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
963+ let poolAssetOutBalance = getAccBalance(assetOut)
964+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
965+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
966+ let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
967+ let checkK = if ((newK >= oldK))
968+ then true
969+ else throw("new K is fewer error")
970+ if ((checkK == checkK))
971+ then {
972+ let checkMin = if ((amountOut >= amountOutMin))
973+ then true
974+ else throw("Exchange result is fewer coins than expected")
975+ if ((checkMin == checkMin))
976+ then {
977+ let rebalanceState = rebalanceAsset(assetIn)
978+ if ((rebalanceState == rebalanceState))
979+ then {
980+ let withdrawState = withdrawAndRebalanceAsset(assetOut, amountOut)
981+ if ((withdrawState == withdrawState))
982+ then $Tuple2(((withdrawState ++ rebalanceState) ++ [ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))]), amountOut)
983+ else throw("Strict value is not equal to itself.")
984+ }
985+ else throw("Strict value is not equal to itself.")
986+ }
987+ else throw("Strict value is not equal to itself.")
988+ }
435989 else throw("Strict value is not equal to itself.")
436990 }
437991 else throw("Strict value is not equal to itself.")
438992 }
439993
440994
441995
442996 @Callable(i)
443-func confirmManager () = {
444- let pm = pendingManagerPublicKeyOrUnit()
445- let hasPM = if (isDefined(pm))
446- then true
447- else throw("No pending manager")
448- if ((hasPM == hasPM))
449- then {
450- let checkPM = if ((i.callerPublicKey == value(pm)))
451- then true
452- else throw("You are not pending manager")
453- if ((checkPM == checkPM))
454- then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())]
455- else throw("Strict value is not equal to itself.")
456- }
457- else throw("Strict value is not equal to itself.")
458- }
997+func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
998+ then throw("Invalid slippageTolerance passed")
999+ else {
1000+ let estPut = commonPut(i, slippageTolerance, true)
1001+ let emitLpAmt = estPut._2
1002+ let lpAssetId = estPut._7
1003+ let state = estPut._9
1004+ let amDiff = estPut._10
1005+ let prDiff = estPut._11
1006+ let amId = estPut._12
1007+ let prId = estPut._13
1008+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1009+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1010+ let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
1011+ if ((currentKLp == currentKLp))
1012+ then {
1013+ let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
1014+ if ((emitInv == emitInv))
1015+ then {
1016+ let emitInvLegacy = match emitInv {
1017+ case legacyFactoryContract: Address =>
1018+ invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
1019+ case _ =>
1020+ unit
1021+ }
1022+ if ((emitInvLegacy == emitInvLegacy))
1023+ then {
1024+ let slippageAInv = if ((amDiff > 0))
1025+ then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
1026+ else nil
1027+ if ((slippageAInv == slippageAInv))
1028+ then {
1029+ let slippagePInv = if ((prDiff > 0))
1030+ then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
1031+ else nil
1032+ if ((slippagePInv == slippagePInv))
1033+ then {
1034+ let lpTransfer = if (shouldAutoStake)
1035+ then {
1036+ let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
1037+ if ((slpStakeInv == slpStakeInv))
1038+ then nil
1039+ else throw("Strict value is not equal to itself.")
1040+ }
1041+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1042+ let $t04436144823 = refreshKLpInternal(0, 0, 0)
1043+ if (($t04436144823 == $t04436144823))
1044+ then {
1045+ let updatedKLp = $t04436144823._2
1046+ let refreshKLpActions = $t04436144823._1
1047+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1048+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1049+ then {
1050+ let reb = invoke(this, "rebalance", nil, nil)
1051+ if ((reb == reb))
1052+ then ((state ++ lpTransfer) ++ refreshKLpActions)
1053+ else throw("Strict value is not equal to itself.")
1054+ }
1055+ else throw("Strict value is not equal to itself.")
1056+ }
1057+ else throw("Strict value is not equal to itself.")
1058+ }
1059+ else throw("Strict value is not equal to itself.")
1060+ }
1061+ else throw("Strict value is not equal to itself.")
1062+ }
1063+ else throw("Strict value is not equal to itself.")
1064+ }
1065+ else throw("Strict value is not equal to itself.")
1066+ }
1067+ else throw("Strict value is not equal to itself.")
1068+ }
4591069
4601070
4611071
4621072 @Callable(i)
463-func put (slippageTolerance,shouldAutoStake) = {
464- let factoryCfg = getFactoryConfig()
465- let stakingContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactoryStakingContract]), "Error. Incorrect staking address.")
466- let slippageContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactorySlippageContract]), "Error. Incorrect slippage contract address.")
467- if ((0 > slippageTolerance))
468- then throw("Invalid slippageTolerance passed")
469- else {
470- let estPut = commonPut(i, slippageTolerance, true)
471- let emitLpAmt = estPut._2
472- let lpAssetId = estPut._7
473- let state = estPut._9
474- let amDiff = estPut._10
475- let prDiff = estPut._11
476- let amId = estPut._12
477- let prId = estPut._13
478- let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
479- if ((emitInv == emitInv))
1073+func putForFree (maxSlippage) = if ((0 > maxSlippage))
1074+ then throw("Invalid value passed")
1075+ else {
1076+ let estPut = commonPut(i, maxSlippage, false)
1077+ let state = estPut._9
1078+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1079+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1080+ let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
1081+ if ((currentKLp == currentKLp))
1082+ then {
1083+ let $t04543545500 = refreshKLpInternal(0, 0, 0)
1084+ let refreshKLpActions = $t04543545500._1
1085+ let updatedKLp = $t04543545500._2
1086+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1087+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1088+ then (state ++ refreshKLpActions)
1089+ else throw("Strict value is not equal to itself.")
1090+ }
1091+ else throw("Strict value is not equal to itself.")
1092+ }
1093+
1094+
1095+
1096+@Callable(i)
1097+func putOneTkn (minOutAmount,autoStake) = {
1098+ let isPoolOneTokenOperationsDisabled = {
1099+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1100+ if ($isInstanceOf(@, "Boolean"))
1101+ then @
1102+ else throw(($getType(@) + " couldn't be cast to Boolean"))
1103+ }
1104+ let isPutDisabled = if (if (if (isGlobalShutdown())
1105+ then true
1106+ else (cfgPoolStatus == PoolPutDisabled))
1107+ then true
1108+ else (cfgPoolStatus == PoolShutdown))
1109+ then true
1110+ else isPoolOneTokenOperationsDisabled
1111+ let checks = [if (if (!(isPutDisabled))
1112+ then true
1113+ else isManager(i))
1114+ then true
1115+ else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
1116+ then true
1117+ else throwErr("exactly 1 payment are expected")]
1118+ if ((checks == checks))
1119+ then {
1120+ let payment = i.payments[0]
1121+ let paymentAssetId = payment.assetId
1122+ let paymentAmountRaw = payment.amount
1123+ let currentKLp = if ((paymentAssetId == cfgAmountAssetId))
1124+ then calcCurrentKLp(toBigInt(paymentAmountRaw), toBigInt(0), toBigInt(0))
1125+ else if ((paymentAssetId == cfgPriceAssetId))
1126+ then calcCurrentKLp(toBigInt(0), toBigInt(paymentAmountRaw), toBigInt(0))
1127+ else throwErr("payment asset is not supported")
1128+ if ((currentKLp == currentKLp))
4801129 then {
481- let emitInvLegacy = match emitInv {
482- case legacyFactoryContract: Address =>
483- invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
484- case _ =>
485- unit
486- }
487- if ((emitInvLegacy == emitInvLegacy))
1130+ let userAddress = i.caller
1131+ let txId = i.transactionId
1132+ let $t04668846840 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
1133+ if (($t04668846840 == $t04668846840))
4881134 then {
489- let slippageAInv = if ((amDiff > 0))
490- then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
491- else nil
492- if ((slippageAInv == slippageAInv))
1135+ let paymentInAmountAsset = $t04668846840._5
1136+ let bonus = $t04668846840._4
1137+ let feeAmount = $t04668846840._3
1138+ let commonState = $t04668846840._2
1139+ let emitAmountEstimated = $t04668846840._1
1140+ let emitAmount = if (if ((minOutAmount > 0))
1141+ then (minOutAmount > emitAmountEstimated)
1142+ else false)
1143+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1144+ else emitAmountEstimated
1145+ let emitInv = emit(emitAmount)
1146+ if ((emitInv == emitInv))
4931147 then {
494- let slippagePInv = if ((prDiff > 0))
495- then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
1148+ let lpTransfer = if (autoStake)
1149+ then {
1150+ let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
1151+ if ((stakeInv == stakeInv))
1152+ then nil
1153+ else throw("Strict value is not equal to itself.")
1154+ }
1155+ else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
1156+ let sendFee = if ((feeAmount > 0))
1157+ then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
4961158 else nil
497- if ((slippagePInv == slippagePInv))
1159+ let $t04742647623 = if ((this == feeCollectorAddress))
1160+ then $Tuple2(0, 0)
1161+ else if (paymentInAmountAsset)
1162+ then $Tuple2(-(feeAmount), 0)
1163+ else $Tuple2(0, -(feeAmount))
1164+ let amountAssetBalanceDelta = $t04742647623._1
1165+ let priceAssetBalanceDelta = $t04742647623._2
1166+ let $t04762647734 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1167+ let refreshKLpActions = $t04762647734._1
1168+ let updatedKLp = $t04762647734._2
1169+ let kLp = value(getString(keyKLp))
1170+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1171+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
4981172 then {
499- let lpTransfer = if (shouldAutoStake)
500- then {
501- let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
502- if ((slpStakeInv == slpStakeInv))
503- then nil
504- else throw("Strict value is not equal to itself.")
505- }
506- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
507- (state ++ lpTransfer)
1173+ let reb = invoke(this, "rebalance", nil, nil)
1174+ if ((reb == reb))
1175+ then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
1176+ else throw("Strict value is not equal to itself.")
5081177 }
5091178 else throw("Strict value is not equal to itself.")
5101179 }
5111180 else throw("Strict value is not equal to itself.")
5121181 }
5131182 else throw("Strict value is not equal to itself.")
5141183 }
5151184 else throw("Strict value is not equal to itself.")
5161185 }
1186+ else throw("Strict value is not equal to itself.")
5171187 }
5181188
5191189
5201190
5211191 @Callable(i)
522-func putForFree (maxSlippage) = if ((0 > maxSlippage))
523- then throw("Invalid value passed")
524- else {
525- let estPut = commonPut(i, maxSlippage, false)
526- estPut._9
1192+func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
1193+ let $t04808948246 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
1194+ let emitAmountEstimated = $t04808948246._1
1195+ let commonState = $t04808948246._2
1196+ let feeAmount = $t04808948246._3
1197+ let bonus = $t04808948246._4
1198+ let paymentInAmountAsset = $t04808948246._5
1199+ $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
1200+ }
1201+
1202+
1203+
1204+@Callable(i)
1205+func getOneTkn (outAssetIdStr,minOutAmount) = {
1206+ let isPoolOneTokenOperationsDisabled = {
1207+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1208+ if ($isInstanceOf(@, "Boolean"))
1209+ then @
1210+ else throw(($getType(@) + " couldn't be cast to Boolean"))
5271211 }
1212+ let isGetDisabled = if (if (isGlobalShutdown())
1213+ then true
1214+ else (cfgPoolStatus == PoolShutdown))
1215+ then true
1216+ else isPoolOneTokenOperationsDisabled
1217+ let checks = [if (if (!(isGetDisabled))
1218+ then true
1219+ else isManager(i))
1220+ then true
1221+ else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
1222+ then true
1223+ else throwErr("exactly 1 payment are expected")]
1224+ if ((checks == checks))
1225+ then {
1226+ let outAssetId = parseAssetId(outAssetIdStr)
1227+ let payment = i.payments[0]
1228+ let paymentAssetId = payment.assetId
1229+ let paymentAmount = payment.amount
1230+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1231+ if ((currentKLp == currentKLp))
1232+ then {
1233+ let userAddress = i.caller
1234+ let txId = i.transactionId
1235+ let $t04913149284 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1236+ if (($t04913149284 == $t04913149284))
1237+ then {
1238+ let outInAmountAsset = $t04913149284._5
1239+ let bonus = $t04913149284._4
1240+ let feeAmount = $t04913149284._3
1241+ let commonState = $t04913149284._2
1242+ let amountEstimated = $t04913149284._1
1243+ let amount = if (if ((minOutAmount > 0))
1244+ then (minOutAmount > amountEstimated)
1245+ else false)
1246+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1247+ else amountEstimated
1248+ let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
1249+ if ((burnInv == burnInv))
1250+ then {
1251+ let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
1252+ let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
1253+ let sendFee = if ((feeAmount > 0))
1254+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1255+ else nil
1256+ let $t04994850195 = {
1257+ let feeAmountForCalc = if ((this == feeCollectorAddress))
1258+ then 0
1259+ else feeAmount
1260+ if (outInAmountAsset)
1261+ then $Tuple2(-((amount + feeAmountForCalc)), 0)
1262+ else $Tuple2(0, -((amount + feeAmountForCalc)))
1263+ }
1264+ let amountAssetBalanceDelta = $t04994850195._1
1265+ let priceAssetBalanceDelta = $t04994850195._2
1266+ let $t05019850306 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1267+ let refreshKLpActions = $t05019850306._1
1268+ let updatedKLp = $t05019850306._2
1269+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1270+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1271+ then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1272+ else throw("Strict value is not equal to itself.")
1273+ }
1274+ else throw("Strict value is not equal to itself.")
1275+ }
1276+ else throw("Strict value is not equal to itself.")
1277+ }
1278+ else throw("Strict value is not equal to itself.")
1279+ }
1280+ else throw("Strict value is not equal to itself.")
1281+ }
1282+
1283+
1284+
1285+@Callable(i)
1286+func getOneTknREADONLY (outAssetId,paymentAmount) = {
1287+ let $t05058450740 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1288+ let amountEstimated = $t05058450740._1
1289+ let commonState = $t05058450740._2
1290+ let feeAmount = $t05058450740._3
1291+ let bonus = $t05058450740._4
1292+ let outInAmountAsset = $t05058450740._5
1293+ $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
1294+ }
1295+
1296+
1297+
1298+@Callable(i)
1299+func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
1300+ let isPoolOneTokenOperationsDisabled = {
1301+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1302+ if ($isInstanceOf(@, "Boolean"))
1303+ then @
1304+ else throw(($getType(@) + " couldn't be cast to Boolean"))
1305+ }
1306+ let isGetDisabled = if (if (isGlobalShutdown())
1307+ then true
1308+ else (cfgPoolStatus == PoolShutdown))
1309+ then true
1310+ else isPoolOneTokenOperationsDisabled
1311+ let checks = [if (if (!(isGetDisabled))
1312+ then true
1313+ else isManager(i))
1314+ then true
1315+ else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
1316+ then true
1317+ else throwErr("no payments are expected")]
1318+ if ((checks == checks))
1319+ then {
1320+ let outAssetId = parseAssetId(outAssetIdStr)
1321+ let userAddress = i.caller
1322+ let txId = i.transactionId
1323+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1324+ if ((currentKLp == currentKLp))
1325+ then {
1326+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1327+ if ((unstakeInv == unstakeInv))
1328+ then {
1329+ let $t05164551796 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1330+ if (($t05164551796 == $t05164551796))
1331+ then {
1332+ let outInAmountAsset = $t05164551796._5
1333+ let bonus = $t05164551796._4
1334+ let feeAmount = $t05164551796._3
1335+ let commonState = $t05164551796._2
1336+ let amountEstimated = $t05164551796._1
1337+ let amount = if (if ((minOutAmount > 0))
1338+ then (minOutAmount > amountEstimated)
1339+ else false)
1340+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1341+ else amountEstimated
1342+ let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1343+ if ((burnInv == burnInv))
1344+ then {
1345+ let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
1346+ let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
1347+ let sendFee = if ((feeAmount > 0))
1348+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1349+ else nil
1350+ let $t05245552702 = {
1351+ let feeAmountForCalc = if ((this == feeCollectorAddress))
1352+ then 0
1353+ else feeAmount
1354+ if (outInAmountAsset)
1355+ then $Tuple2(-((amount + feeAmountForCalc)), 0)
1356+ else $Tuple2(0, -((amount + feeAmountForCalc)))
1357+ }
1358+ let amountAssetBalanceDelta = $t05245552702._1
1359+ let priceAssetBalanceDelta = $t05245552702._2
1360+ let $t05270552813 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1361+ let refreshKLpActions = $t05270552813._1
1362+ let updatedKLp = $t05270552813._2
1363+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1364+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1365+ then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1366+ else throw("Strict value is not equal to itself.")
1367+ }
1368+ else throw("Strict value is not equal to itself.")
1369+ }
1370+ else throw("Strict value is not equal to itself.")
1371+ }
1372+ else throw("Strict value is not equal to itself.")
1373+ }
1374+ else throw("Strict value is not equal to itself.")
1375+ }
1376+ else throw("Strict value is not equal to itself.")
1377+ }
5281378
5291379
5301380
5311381 @Callable(i)
5321382 func get () = {
5331383 let res = commonGet(i)
534- let outAmtAmt = res._1
1384+ let outAmAmt = res._1
5351385 let outPrAmt = res._2
5361386 let pmtAmt = res._3
5371387 let pmtAssetId = res._4
5381388 let state = res._5
539- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
540- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
541- then state
1389+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1390+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1391+ if ((currentKLp == currentKLp))
1392+ then {
1393+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1394+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1395+ then {
1396+ let $t05390853989 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1397+ let refreshKLpActions = $t05390853989._1
1398+ let updatedKLp = $t05390853989._2
1399+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1400+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1401+ then ((withdrawState ++ state) ++ refreshKLpActions)
1402+ else throw("Strict value is not equal to itself.")
1403+ }
1404+ else throw("Strict value is not equal to itself.")
1405+ }
5421406 else throw("Strict value is not equal to itself.")
5431407 }
5441408
5451409
5461410
5471411 @Callable(i)
5481412 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
5491413 let res = commonGet(i)
5501414 let outAmAmt = res._1
5511415 let outPrAmt = res._2
5521416 let pmtAmt = res._3
5531417 let pmtAssetId = res._4
5541418 let state = res._5
5551419 if ((noLessThenAmtAsset > outAmAmt))
5561420 then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
5571421 else if ((noLessThenPriceAsset > outPrAmt))
5581422 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
5591423 else {
560- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
561- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
562- then state
1424+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1425+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1426+ if ((currentKLp == currentKLp))
1427+ then {
1428+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1429+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1430+ then {
1431+ let $t05508455165 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1432+ let refreshKLpActions = $t05508455165._1
1433+ let updatedKLp = $t05508455165._2
1434+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1435+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1436+ then ((withdrawState ++ state) ++ refreshKLpActions)
1437+ else throw("Strict value is not equal to itself.")
1438+ }
1439+ else throw("Strict value is not equal to itself.")
1440+ }
5631441 else throw("Strict value is not equal to itself.")
5641442 }
5651443 }
5661444
5671445
5681446
5691447 @Callable(i)
5701448 func unstakeAndGet (amount) = {
5711449 let checkPayments = if ((size(i.payments) != 0))
5721450 then throw("No payments are expected")
5731451 else true
5741452 if ((checkPayments == checkPayments))
5751453 then {
5761454 let cfg = getPoolConfig()
577- let factoryCfg = getFactoryConfig()
5781455 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
579- let stakingContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactoryStakingContract]), "Error. Incorrect staking address.")
580- let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
581- if ((unstakeInv == unstakeInv))
1456+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1457+ if ((currentKLp == currentKLp))
5821458 then {
583- let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
584- let poolStatus = parseIntValue(res._9)
585- let state = res._10
586- let checkPoolStatus = if (if (isGlobalShutdown())
587- then true
588- else (poolStatus == PoolShutdown))
589- then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
590- else true
591- if ((checkPoolStatus == checkPoolStatus))
1459+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
1460+ if ((unstakeInv == unstakeInv))
5921461 then {
593- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
594- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
595- then state
1462+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1463+ let outAmAmt = res._1
1464+ let outPrAmt = res._2
1465+ let poolStatus = parseIntValue(res._9)
1466+ let state = res._10
1467+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1468+ let checkPoolStatus = if (if (isGlobalShutdown())
1469+ then true
1470+ else (poolStatus == PoolShutdown))
1471+ then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
1472+ else true
1473+ if ((checkPoolStatus == checkPoolStatus))
1474+ then {
1475+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1476+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1477+ then {
1478+ let $t05643756518 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1479+ let refreshKLpActions = $t05643756518._1
1480+ let updatedKLp = $t05643756518._2
1481+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1482+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1483+ then ((withdrawState ++ state) ++ refreshKLpActions)
1484+ else throw("Strict value is not equal to itself.")
1485+ }
1486+ else throw("Strict value is not equal to itself.")
1487+ }
1488+ else throw("Strict value is not equal to itself.")
1489+ }
1490+ else throw("Strict value is not equal to itself.")
1491+ }
1492+ else throw("Strict value is not equal to itself.")
1493+ }
1494+ else throw("Strict value is not equal to itself.")
1495+ }
1496+
1497+
1498+
1499+@Callable(i)
1500+func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
1501+ let isGetDisabled = if (isGlobalShutdown())
1502+ then true
1503+ else (cfgPoolStatus == PoolShutdown)
1504+ let checks = [if (!(isGetDisabled))
1505+ then true
1506+ else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
1507+ then true
1508+ else throw("no payments are expected")]
1509+ if ((checks == checks))
1510+ then {
1511+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1512+ if ((currentKLp == currentKLp))
1513+ then {
1514+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1515+ if ((unstakeInv == unstakeInv))
1516+ then {
1517+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
1518+ let outAmAmt = res._1
1519+ let outPrAmt = res._2
1520+ let state = res._10
1521+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1522+ let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
1523+ then true
1524+ else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
1525+ then true
1526+ else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
1527+ if ((checkAmounts == checkAmounts))
1528+ then {
1529+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1530+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1531+ then {
1532+ let $t05795958040 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1533+ let refreshKLpActions = $t05795958040._1
1534+ let updatedKLp = $t05795958040._2
1535+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1536+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1537+ then ((withdrawState ++ state) ++ refreshKLpActions)
1538+ else throw("Strict value is not equal to itself.")
1539+ }
1540+ else throw("Strict value is not equal to itself.")
1541+ }
5961542 else throw("Strict value is not equal to itself.")
5971543 }
5981544 else throw("Strict value is not equal to itself.")
5991545 }
6001546 else throw("Strict value is not equal to itself.")
6011547 }
6021548 else throw("Strict value is not equal to itself.")
6031549 }
6041550
6051551
6061552
6071553 @Callable(i)
6081554 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
6091555 then throw("permissions denied")
6101556 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
1557+
1558+
1559+
1560+@Callable(i)
1561+func refreshKLp () = {
1562+ let lastRefreshedBlockHeight = valueOrElse(getInteger(keyKLpRefreshedHeight), 0)
1563+ let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= kLpRefreshDelay))
1564+ then unit
1565+ else throwErr(makeString([toString(kLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1566+ if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
1567+ then {
1568+ let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1569+ let $t05924459308 = refreshKLpInternal(0, 0, 0)
1570+ let kLpUpdateActions = $t05924459308._1
1571+ let updatedKLp = $t05924459308._2
1572+ let actions = if ((kLp != updatedKLp))
1573+ then kLpUpdateActions
1574+ else throwErr("nothing to refresh")
1575+ $Tuple2(actions, toString(updatedKLp))
1576+ }
1577+ else throw("Strict value is not equal to itself.")
1578+ }
6111579
6121580
6131581
6141582 @Callable(i)
6151583 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
6161584
6171585
6181586
6191587 @Callable(i)
6201588 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
6211589
6221590
6231591
6241592 @Callable(i)
6251593 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
6261594 let prices = calcPrices(amAmt, prAmt, lpAmt)
6271595 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
6281596 }
6291597
6301598
6311599
6321600 @Callable(i)
6331601 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
6341602
6351603
6361604
6371605 @Callable(i)
6381606 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
6391607
6401608
6411609
6421610 @Callable(i)
6431611 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
6441612
6451613
6461614
6471615 @Callable(i)
6481616 func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
6491617
6501618
6511619
6521620 @Callable(i)
6531621 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
6541622 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
6551623 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
6561624 }
6571625
6581626
6591627
6601628 @Callable(i)
6611629 func statsREADONLY () = {
6621630 let cfg = getPoolConfig()
6631631 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
6641632 let amtAssetId = cfg[idxAmtAssetId]
6651633 let priceAssetId = cfg[idxPriceAssetId]
6661634 let iAmtAssetId = cfg[idxIAmtAssetId]
6671635 let iPriceAssetId = cfg[idxIPriceAssetId]
6681636 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
6691637 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
6701638 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
6711639 let accAmtAssetBalance = getAccBalance(amtAssetId)
6721640 let accPriceAssetBalance = getAccBalance(priceAssetId)
6731641 let pricesList = if ((poolLPBalance == 0))
6741642 then [zeroBigInt, zeroBigInt, zeroBigInt]
6751643 else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
6761644 let curPrice = 0
6771645 let lpAmtAssetShare = fromX18(pricesList[1], scale8)
6781646 let lpPriceAssetShare = fromX18(pricesList[2], scale8)
6791647 let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
6801648 $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))
6811649 }
6821650
6831651
6841652
6851653 @Callable(i)
6861654 func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
6871655 let cfg = getPoolConfig()
6881656 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
6891657 let amAssetIdStr = cfg[idxAmtAssetId]
6901658 let amAssetId = fromBase58String(amAssetIdStr)
6911659 let prAssetIdStr = cfg[idxPriceAssetId]
6921660 let prAssetId = fromBase58String(prAssetIdStr)
6931661 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
6941662 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
6951663 let poolStatus = cfg[idxPoolStatus]
6961664 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
6971665 let accAmtAssetBalance = getAccBalance(amAssetIdStr)
6981666 let accPriceAssetBalance = getAccBalance(prAssetIdStr)
6991667 let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
7001668 let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
7011669 let curPriceX18 = if ((poolLPBalance == 0))
7021670 then zeroBigInt
7031671 else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
7041672 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
7051673 let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
7061674 let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
7071675 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
7081676 let calcLpAmt = estPut._1
7091677 let curPriceCalc = estPut._3
7101678 let amBalance = estPut._4
7111679 let prBalance = estPut._5
7121680 let lpEmission = estPut._6
7131681 $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))
7141682 }
7151683
7161684
7171685
7181686 @Callable(i)
7191687 func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
7201688 let cfg = getPoolConfig()
7211689 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
7221690 let amAssetIdStr = cfg[idxAmtAssetId]
7231691 let amAssetId = fromBase58String(amAssetIdStr)
7241692 let prAssetIdStr = cfg[idxPriceAssetId]
7251693 let prAssetId = fromBase58String(prAssetIdStr)
7261694 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
7271695 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
7281696 let poolStatus = cfg[idxPoolStatus]
7291697 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
7301698 let amBalanceRaw = getAccBalance(amAssetIdStr)
7311699 let prBalanceRaw = getAccBalance(prAssetIdStr)
7321700 let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
7331701 let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
7341702 let curPriceX18 = if ((poolLPBalance == 0))
7351703 then zeroBigInt
7361704 else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
7371705 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
7381706 let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
7391707 let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
7401708 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
7411709 let calcLpAmt = estPut._1
7421710 let curPriceCalc = estPut._3
7431711 let amBalance = estPut._4
7441712 let prBalance = estPut._5
7451713 let lpEmission = estPut._6
7461714 $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))
7471715 }
7481716
7491717
7501718
7511719 @Callable(i)
7521720 func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
7531721 let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
7541722 let outAmAmt = res._1
7551723 let outPrAmt = res._2
7561724 let amBalance = res._5
7571725 let prBalance = res._6
7581726 let lpEmission = res._7
7591727 let curPrice = res._8
7601728 let poolStatus = parseIntValue(res._9)
7611729 $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))
7621730 }
7631731
7641732
7651733 @Verifier(tx)
766-func verify () = match tx {
767- case order: Order =>
768- let matcherPub = getMatcherPubOrFail()
769- let orderValid = validateMatcherOrderAllowed(order)
770- let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
771- let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
772- if (if (if (orderValid)
773- then senderValid
774- else false)
775- then matcherValid
776- else false)
777- then true
778- else throwOrderError(orderValid, senderValid, matcherValid)
779- case _ =>
780- let targetPublicKey = match managerPublicKeyOrUnit() {
781- case pk: ByteVector =>
782- pk
783- case _: Unit =>
784- tx.senderPublicKey
785- case _ =>
786- throw("Match error")
787- }
788- sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
789-}
1734+func verify () = {
1735+ let targetPublicKey = match managerPublicKeyOrUnit() {
1736+ case pk: ByteVector =>
1737+ pk
1738+ case _: Unit =>
1739+ tx.senderPublicKey
1740+ case _ =>
1741+ throw("Match error")
1742+ }
1743+ match tx {
1744+ case order: Order =>
1745+ let matcherPub = getMatcherPubOrFail()
1746+ let $t06797068087 = if (skipOrderValidation())
1747+ then $Tuple2(true, "")
1748+ else validateMatcherOrderAllowed(order)
1749+ let orderValid = $t06797068087._1
1750+ let orderValidInfo = $t06797068087._2
1751+ let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
1752+ let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
1753+ if (if (if (orderValid)
1754+ then senderValid
1755+ else false)
1756+ then matcherValid
1757+ else false)
1758+ then true
1759+ else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
1760+ case s: SetScriptTransaction =>
1761+ if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
1762+ then true
1763+ else {
1764+ let newHash = blake2b256(value(s.script))
1765+ let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
1766+ let currentHash = scriptHash(this)
1767+ if ((allowedHash == newHash))
1768+ then (currentHash != newHash)
1769+ else false
1770+ }
1771+ case _ =>
1772+ sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
1773+ }
1774+ }
7901775

github/deemru/w8io/026f985 
150.64 ms