tx · 8fcsv2SZsGdQJMGiUrdGE8KYVqKGvam9YpvPda9DjV7V

3N9gee8G3PpYacSwKwjCq4FCoEHrsgupsdA:  -0.04200000 Waves

2023.07.19 15:53 [2672772] smart account 3N9gee8G3PpYacSwKwjCq4FCoEHrsgupsdA > SELF 0.00000000 Waves

{ "type": 13, "id": "8fcsv2SZsGdQJMGiUrdGE8KYVqKGvam9YpvPda9DjV7V", "fee": 4200000, "feeAssetId": null, "timestamp": 1689771225772, "version": 2, "chainId": 84, "sender": "3N9gee8G3PpYacSwKwjCq4FCoEHrsgupsdA", "senderPublicKey": "BC48B3Axpv2LvE7A2JPYR77mgwDkigKqtKZh5352WZmJ", "proofs": [ "47Aob9o9pSANNupT2igB8v4okj8NHvat5gLJ4eQiNSHRLfrj4E8Mvkraa77wZ6PmU13FVUN2oJjmS1MqZyaCynWP" ], "script": "base64:BgKSOAgCEgASBQoDAQQBEgcKBQEEAQgBEgQKAgEEEgMKAQESBAoCAQQSBAoCCAESBAoCCAESBAoCCAESBQoDAQgBEgASBAoCAQESAwoBARIFCgMBAQESBAoCCAgSABIAEgMKAQgSBQoDAQEBEgQKAgEBEgQKAggBEgQKAggIEgsKCQgBAQIBAggEBBIGCgQICAEIEgASAwoBARIDCgEBEgQKAggBIgpsUGRlY2ltYWxzIgZzY2FsZTgiDHNjYWxlOEJpZ0ludCIHc2NhbGUxOCIKemVyb0JpZ0ludCIEYmlnMCIEYmlnMSIEYmlnMiILd2F2ZXNTdHJpbmciA1NFUCIKUG9vbEFjdGl2ZSIPUG9vbFB1dERpc2FibGVkIhNQb29sTWF0Y2hlckRpc2FibGVkIgxQb29sU2h1dGRvd24iDmlkeFBvb2xBZGRyZXNzIg1pZHhQb29sU3RhdHVzIhBpZHhQb29sTFBBc3NldElkIg1pZHhBbXRBc3NldElkIg9pZHhQcmljZUFzc2V0SWQiDmlkeEFtdEFzc2V0RGNtIhBpZHhQcmljZUFzc2V0RGNtIg5pZHhJQW10QXNzZXRJZCIQaWR4SVByaWNlQXNzZXRJZCINaWR4TFBBc3NldERjbSISaWR4UG9vbEFtdEFzc2V0QW10IhRpZHhQb29sUHJpY2VBc3NldEFtdCIRaWR4UG9vbExQQXNzZXRBbXQiGWlkeEZhY3RvcnlTdGFraW5nQ29udHJhY3QiGmlkeEZhY3RvcnlTbGlwcGFnZUNvbnRyYWN0IgV0b1gxOCIHb3JpZ1ZhbCINb3JpZ1NjYWxlTXVsdCILdG9YMThCaWdJbnQiB2Zyb21YMTgiA3ZhbCIPcmVzdWx0U2NhbGVNdWx0Igxmcm9tWDE4Um91bmQiBXJvdW5kIgd0b1NjYWxlIgNhbXQiCHJlc1NjYWxlIghjdXJTY2FsZSIDYWJzIglhYnNCaWdJbnQiDHN3YXBDb250cmFjdCICZmMiE2tleU1hbmFnZXJQdWJsaWNLZXkiFmtleU1hbmFnZXJWYXVsdEFkZHJlc3MiAnBsIgJwaCIBaCIJdGltZXN0YW1wIgNwYXUiC3VzZXJBZGRyZXNzIgR0eElkIgNnYXUiAmFhIgJwYSIGa2V5RmVlIgpmZWVEZWZhdWx0IgNmZWUiBmtleUtMcCIVa2V5S0xwUmVmcmVzaGVkSGVpZ2h0IhJrZXlLTHBSZWZyZXNoRGVsYXkiFmtMcFJlZnJlc2hEZWxheURlZmF1bHQiD2tMcFJlZnJlc2hEZWxheSIUa2V5QWRkaXRpb25hbEJhbGFuY2UiB2Fzc2V0SWQiFmtleVN0YWtpbmdBc3NldEJhbGFuY2UiGmdldEFkZGl0aW9uYWxCYWxhbmNlT3JaZXJvIhxnZXRTdGFraW5nQXNzZXRCYWxhbmNlT3JaZXJvIhBrZXlGYWN0b3J5Q29uZmlnIg1rZXlNYXRjaGVyUHViIilrZXlNYXBwaW5nUG9vbENvbnRyYWN0QWRkcmVzc1RvUG9vbEFzc2V0cyITcG9vbENvbnRyYWN0QWRkcmVzcyINa2V5UG9vbENvbmZpZyIJaUFtdEFzc2V0IgtpUHJpY2VBc3NldCIfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZCIMYmFzZUFzc2V0U3RyIhNrZXlBbGxQb29sc1NodXRkb3duIg1rZXlQb29sV2VpZ2h0Ig9jb250cmFjdEFkZHJlc3MiFmtleUFsbG93ZWRMcFNjcmlwdEhhc2giFmtleUZlZUNvbGxlY3RvckFkZHJlc3MiFmtleVNraXBPcmRlclZhbGlkYXRpb24iC3Bvb2xBZGRyZXNzIg90aHJvd09yZGVyRXJyb3IiCm9yZGVyVmFsaWQiDm9yZGVyVmFsaWRJbmZvIgtzZW5kZXJWYWxpZCIMbWF0Y2hlclZhbGlkIhdhZGRyZXNzRnJvbVN0cmluZ09yVGhpcyINYWRkcmVzc1N0cmluZyIHJG1hdGNoMCIBYSIcZ2V0TWFuYWdlclZhdWx0QWRkcmVzc09yVGhpcyIOZmFjdG9yeUFkZHJlc3MiA2ZjYSIBcyIPZ2V0U3RyaW5nT3JGYWlsIgdhZGRyZXNzIgNrZXkiDGdldEludE9yRmFpbCIIdGhyb3dFcnIiA21zZyIGZm10RXJyIg9mYWN0b3J5Q29udHJhY3QiE2ZlZUNvbGxlY3RvckFkZHJlc3MiBWluRmVlIgFAIgZvdXRGZWUiEGlzR2xvYmFsU2h1dGRvd24iE2dldE1hdGNoZXJQdWJPckZhaWwiDWdldFBvb2xDb25maWciCGFtdEFzc2V0IgpwcmljZUFzc2V0IgxwYXJzZUFzc2V0SWQiBWlucHV0Ig9hc3NldElkVG9TdHJpbmciD3BhcnNlUG9vbENvbmZpZyIKcG9vbENvbmZpZyIQcG9vbENvbmZpZ1BhcnNlZCILJHQwOTUyOTk2OTUiDmNmZ1Bvb2xBZGRyZXNzIg1jZmdQb29sU3RhdHVzIgxjZmdMcEFzc2V0SWQiEGNmZ0Ftb3VudEFzc2V0SWQiD2NmZ1ByaWNlQXNzZXRJZCIWY2ZnQW1vdW50QXNzZXREZWNpbWFscyIVY2ZnUHJpY2VBc3NldERlY2ltYWxzIhBnZXRGYWN0b3J5Q29uZmlnIg9zdGFraW5nQ29udHJhY3QiEHNsaXBwYWdlQ29udHJhY3QiEWRhdGFQdXRBY3Rpb25JbmZvIg1pbkFtdEFzc2V0QW10Ig9pblByaWNlQXNzZXRBbXQiCG91dExwQW10IgVwcmljZSIdc2xpcHBhZ2VUb2xlcmFuY2VQYXNzZWRCeVVzZXIiFXNsaXBwYWdlVG9sZXJhbmNlUmVhbCIIdHhIZWlnaHQiC3R4VGltZXN0YW1wIhJzbGlwYWdlQW10QXNzZXRBbXQiFHNsaXBhZ2VQcmljZUFzc2V0QW10IhFkYXRhR2V0QWN0aW9uSW5mbyIOb3V0QW10QXNzZXRBbXQiEG91dFByaWNlQXNzZXRBbXQiB2luTHBBbXQiDWdldEFjY0JhbGFuY2UiDWJhbGFuY2VPblBvb2wiDHRvdGFsQmFsYW5jZSIPY2FsY1ByaWNlQmlnSW50IghwckFtdFgxOCIIYW1BbXRYMTgiFGNhbGNQcmljZUJpZ0ludFJvdW5kIgdnZXRSYXRlIgVwcm94eSIDaW52IgFyIgdkZXBvc2l0IgZhbW91bnQiDnN0YWtpbmdBc3NldElkIhhjdXJyZW50QWRkaXRpb25hbEJhbGFuY2UiGmN1cnJlbnRTdGFraW5nQXNzZXRCYWxhbmNlIgVhc3NldCINZGVwb3NpdEludm9rZSIUcmVjZWl2ZWRTdGFraW5nQXNzZXQiFG5ld0FkZGl0aW9uYWxCYWxhbmNlIhZuZXdTdGFraW5nQXNzZXRCYWxhbmNlIgh3aXRoZHJhdyIMcHJveHlSYXRlTXVsIg1wcm9maXRBZGRyZXNzIhBjdXJyZW50UHJveHlSYXRlIgdvbGRSYXRlIgxzdGFraW5nQXNzZXQiFG9sZFNlbmRTdGFraW5nQW1vdW50IhZzZW5kU3Rha2luZ0Fzc2V0QW1vdW50Igxwcm9maXRBbW91bnQiDndpdGhkcmF3SW52b2tlIg5yZWNlaXZlZEFzc2V0cyITZ2V0TGVhc2VQcm94eUNvbmZpZyIRcmViYWxhbmNlSW50ZXJuYWwiC3RhcmdldFJhdGlvIgptaW5CYWxhbmNlIhRsZWFzYWJsZVRvdGFsQmFsYW5jZSIXdGFyZ2V0QWRkaXRpb25hbEJhbGFuY2UiBGRpZmYiD3NlbmRBc3NldEFtb3VudCIOZ2V0QXNzZXRBbW91bnQiDnJlYmFsYW5jZUFzc2V0Ig0kdDAxNTkzMTE2MDY3Igppc0xlYXNhYmxlIgtsZWFzZWRSYXRpbyIMcHJveHlBZGRyZXNzIgxwcm94eUFzc2V0SWQiFHN0YWtpbmdQcm9maXRBZGRyZXNzIhl3aXRoZHJhd0FuZFJlYmFsYW5jZUFzc2V0IglnZXRBbW91bnQiDSR0MDE2NDY2MTY2MDIiF25ld1RvdGFsTGVhc2FibGVCYWxhbmNlIg53aXRoZHJhd0Ftb3VudCIXd2l0aGRyYXdBbmRSZWJhbGFuY2VBbGwiFGFtb3VudEFzc2V0T3V0QW1vdW50IhNwcmljZUFzc2V0T3V0QW1vdW50IhJBbUFtdFdpdGhkcmF3U3RhdGUiElByQW10V2l0aGRyYXdTdGF0ZSIQcHJpdmF0ZUNhbGNQcmljZSIKYW1Bc3NldERjbSIKcHJBc3NldERjbSIFYW1BbXQiBXByQW10Ig5hbXRBc3NldEFtdFgxOCIQcHJpY2VBc3NldEFtdFgxOCIKY2FsY1ByaWNlcyIFbHBBbXQiA2NmZyILYW10QXNzZXREY20iDXByaWNlQXNzZXREY20iCHByaWNlWDE4IghscEFtdFgxOCITbHBQcmljZUluQW1Bc3NldFgxOCITbHBQcmljZUluUHJBc3NldFgxOCIPY2FsY3VsYXRlUHJpY2VzIgZwcmljZXMiFGVzdGltYXRlR2V0T3BlcmF0aW9uIgZ0eElkNTgiCnBtdEFzc2V0SWQiCHBtdExwQW10IglscEFzc2V0SWQiCWFtQXNzZXRJZCIJcHJBc3NldElkIgpwb29sU3RhdHVzIgpscEVtaXNzaW9uIglhbUJhbGFuY2UiDGFtQmFsYW5jZVgxOCIJcHJCYWxhbmNlIgxwckJhbGFuY2VYMTgiC2N1clByaWNlWDE4IghjdXJQcmljZSILcG10THBBbXRYMTgiDWxwRW1pc3Npb25YMTgiC291dEFtQW10WDE4IgtvdXRQckFtdFgxOCIIb3V0QW1BbXQiCG91dFByQW10IgVzdGF0ZSIUZXN0aW1hdGVQdXRPcGVyYXRpb24iEXNsaXBwYWdlVG9sZXJhbmNlIgxpbkFtQXNzZXRBbXQiC2luQW1Bc3NldElkIgxpblByQXNzZXRBbXQiC2luUHJBc3NldElkIgppc0V2YWx1YXRlIgZlbWl0THAiDGFtQXNzZXRJZFN0ciIMcHJBc3NldElkU3RyIgtpQW10QXNzZXRJZCINaVByaWNlQXNzZXRJZCIOaW5BbUFzc2V0SWRTdHIiDmluUHJBc3NldElkU3RyIg9pbkFtQXNzZXRBbXRYMTgiD2luUHJBc3NldEFtdFgxOCIMdXNlclByaWNlWDE4IgNyZXMiC3NsaXBwYWdlWDE4IhRzbGlwcGFnZVRvbGVyYW5jZVgxOCIKcHJWaWFBbVgxOCIKYW1WaWFQclgxOCIMZXhwZWN0ZWRBbXRzIhFleHBBbXRBc3NldEFtdFgxOCITZXhwUHJpY2VBc3NldEFtdFgxOCIJY2FsY0xwQW10Ig5jYWxjQW1Bc3NldFBtdCIOY2FsY1ByQXNzZXRQbXQiDHNsaXBwYWdlQ2FsYyIJZW1pdExwQW10IgZhbURpZmYiBnByRGlmZiILY29tbW9uU3RhdGUiB2NhbGNLTHAiDWFtb3VudEJhbGFuY2UiDHByaWNlQmFsYW5jZSIQYW1vdW50QmFsYW5jZVgxOCIPcHJpY2VCYWxhbmNlWDE4Igp1cGRhdGVkS0xwIg5jYWxjQ3VycmVudEtMcCIQYW1vdW50QXNzZXREZWx0YSIPcHJpY2VBc3NldERlbHRhIhRscEFzc2V0RW1pc3Npb25EZWx0YSISYW1vdW50QXNzZXRCYWxhbmNlIhFwcmljZUFzc2V0QmFsYW5jZSIPbHBBc3NldEVtaXNzaW9uIgpjdXJyZW50S0xwIhJyZWZyZXNoS0xwSW50ZXJuYWwiF2Ftb3VudEFzc2V0QmFsYW5jZURlbHRhIhZwcmljZUFzc2V0QmFsYW5jZURlbHRhIgdhY3Rpb25zIhNza2lwT3JkZXJWYWxpZGF0aW9uIhJ2YWxpZGF0ZVVwZGF0ZWRLTHAiBm9sZEtMcCIbdmFsaWRhdGVNYXRjaGVyT3JkZXJBbGxvd2VkIgVvcmRlciIRYW1vdW50QXNzZXRBbW91bnQiEHByaWNlQXNzZXRBbW91bnQiDSR0MDI4OTkxMjkyMDMiA2tMcCINJHQwMjk2NDMyOTc0MyINdW51c2VkQWN0aW9ucyIGa0xwTmV3Igxpc09yZGVyVmFsaWQiBGluZm8iCWNvbW1vbkdldCIBaSIDcG10IgZwbXRBbXQiCWNvbW1vblB1dCIKYW1Bc3NldFBtdCIKcHJBc3NldFBtdCIGZXN0UHV0IgRlbWl0IgdlbWl0SW52Ig1lbWl0SW52TGVnYWN5IhVsZWdhY3lGYWN0b3J5Q29udHJhY3QiB3Rha2VGZWUiCWZlZUFtb3VudCIPY2FsY1B1dE9uZVRva2VuIhBwYXltZW50QW1vdW50UmF3Ig5wYXltZW50QXNzZXRJZCIGaXNFdmFsIhBhbW91bnRCYWxhbmNlUmF3Ig9wcmljZUJhbGFuY2VSYXciFHBheW1lbnRJbkFtb3VudEFzc2V0Ig0kdDAzMjg1NjMzMTQ5IhBhbW91bnRCYWxhbmNlT2xkIg9wcmljZUJhbGFuY2VPbGQiDSR0MDMzMTUzMzMzMDIiFGFtb3VudEFzc2V0QW1vdW50UmF3IhNwcmljZUFzc2V0QW1vdW50UmF3Ig0kdDAzMzQzNDMzNDk4Ig1wYXltZW50QW1vdW50IhBhbW91bnRCYWxhbmNlTmV3Ig9wcmljZUJhbGFuY2VOZXciC3ByaWNlTmV3WDE4IghwcmljZU5ldyIOcGF5bWVudEJhbGFuY2UiFHBheW1lbnRCYWxhbmNlQmlnSW50IgxzdXBwbHlCaWdJbnQiC2NoZWNoU3VwcGx5Ig1kZXBvc2l0QmlnSW50Igtpc3N1ZUFtb3VudCILcHJpY2VPbGRYMTgiCHByaWNlT2xkIgRsb3NzIg0kdDAzNTE3OTM1MzQ2IgdiYWxhbmNlIg9pc3N1ZUFtb3VudEJvdGgiD2NhbGNHZXRPbmVUb2tlbiIKb3V0QXNzZXRJZCIGY2hlY2tzIhBvdXRJbkFtb3VudEFzc2V0Ig1iYWxhbmNlQmlnSW50IhhvdXRJbkFtb3VudEFzc2V0RGVjaW1hbHMiDGFtQmFsYW5jZU9sZCIMcHJCYWxhbmNlT2xkIgpvdXRCYWxhbmNlIhBvdXRCYWxhbmNlQmlnSW50Ig5yZWRlZW1lZEJpZ0ludCIJYW1vdW50UmF3Ig0kdDAzNzQyNDM3NDgwIgt0b3RhbEFtb3VudCINJHQwMzc0ODQzNzcxMCILb3V0QW1BbW91bnQiC291dFByQW1vdW50IgxhbUJhbGFuY2VOZXciDHByQmFsYW5jZU5ldyIYYW1vdW50Qm90aEluUGF5bWVudEFzc2V0IhZtYW5hZ2VyUHVibGljS2V5T3JVbml0IhNtYW5hZ2VyVmF1bHRBZGRyZXNzIglpc01hbmFnZXIiAnBrIgttdXN0TWFuYWdlciICcGQiDWNsZWFuQW1vdW50SW4iCWlzUmV2ZXJzZSINZmVlUG9vbEFtb3VudCINJHQwMzk1NjgzOTg3MyIIYXNzZXRPdXQiB2Fzc2V0SW4iEnBvb2xBc3NldEluQmFsYW5jZSITcG9vbEFzc2V0T3V0QmFsYW5jZSIJYW1vdW50T3V0IgRvbGRLIgRuZXdLIgZjaGVja0siDGFtb3VudE91dE1pbiIJYWRkcmVzc1RvIgtzd2FwQ29udGFjdCIIY2hlY2tNaW4iDnJlYmFsYW5jZVN0YXRlIg13aXRoZHJhd1N0YXRlIg9zaG91bGRBdXRvU3Rha2UiBGFtSWQiBHBySWQiDHNsaXBwYWdlQUludiIMc2xpcHBhZ2VQSW52IgpscFRyYW5zZmVyIgtzbHBTdGFrZUludiINJHQwNDQzNzY0NDgzOCIRcmVmcmVzaEtMcEFjdGlvbnMiEWlzVXBkYXRlZEtMcFZhbGlkIgNyZWIiC21heFNsaXBwYWdlIg0kdDA0NTQ1MDQ1NTE1IgxtaW5PdXRBbW91bnQiCWF1dG9TdGFrZSIgaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWQiDWlzUHV0RGlzYWJsZWQiB3BheW1lbnQiDSR0MDQ2NzAzNDY4NTUiBWJvbnVzIhNlbWl0QW1vdW50RXN0aW1hdGVkIgplbWl0QW1vdW50IghzdGFrZUludiIHc2VuZEZlZSINJHQwNDc0NDE0NzYzOCINJHQwNDc2NDE0Nzc0OSINJHQwNDgxMDQ0ODI2MSINb3V0QXNzZXRJZFN0ciINaXNHZXREaXNhYmxlZCINJHQwNDkxNDY0OTI5OSIPYW1vdW50RXN0aW1hdGVkIgdidXJuSW52Ig1hc3NldFRyYW5zZmVyIg0kdDA0OTk2MzUwMjEwIhBmZWVBbW91bnRGb3JDYWxjIg0kdDA1MDIxMzUwMzIxIg0kdDA1MDU5OTUwNzU1Ig11bnN0YWtlQW1vdW50Igp1bnN0YWtlSW52Ig0kdDA1MTY2MDUxODExIg0kdDA1MjQ3MDUyNzE3Ig0kdDA1MjcyMDUyODI4IhRidXJuTFBBc3NldE9uRmFjdG9yeSINJHQwNTM5MjM1NDAwNCISbm9MZXNzVGhlbkFtdEFzc2V0IhRub0xlc3NUaGVuUHJpY2VBc3NldCINJHQwNTUwOTk1NTE4MCINY2hlY2tQYXltZW50cyIPY2hlY2tQb29sU3RhdHVzIg0kdDA1NjQ1MjU2NTMzIhVub0xlc3NUaGVuQW1vdW50QXNzZXQiDGNoZWNrQW1vdW50cyINJHQwNTc5NzQ1ODA1NSILYW10QXNzZXRTdHIiDXByaWNlQXNzZXRTdHIiGGxhc3RSZWZyZXNoZWRCbG9ja0hlaWdodCIdY2hlY2tMYXN0UmVmcmVzaGVkQmxvY2tIZWlnaHQiDSR0MDU5MjU5NTkzMjMiEGtMcFVwZGF0ZUFjdGlvbnMiCmFtdEFzc2V0SWQiDHByaWNlQXNzZXRJZCINcG9vbExQQmFsYW5jZSISYWNjQW10QXNzZXRCYWxhbmNlIhRhY2NQcmljZUFzc2V0QmFsYW5jZSIKcHJpY2VzTGlzdCIPbHBBbXRBc3NldFNoYXJlIhFscFByaWNlQXNzZXRTaGFyZSIKcG9vbFdlaWdodCIMY3VyUHJpY2VDYWxjIgxhbUJhbGFuY2VSYXciDHByQmFsYW5jZVJhdyIPYW1CYWxhbmNlUmF3WDE4Ig9wckJhbGFuY2VSYXdYMTgiEHBheW1lbnRMcEFzc2V0SWQiDHBheW1lbnRMcEFtdCICdHgiBnZlcmlmeSIPdGFyZ2V0UHVibGljS2V5IgptYXRjaGVyUHViIg0kdDA2Nzk4NTY4MTAyIgduZXdIYXNoIgthbGxvd2VkSGFzaCILY3VycmVudEhhc2iCAQABYQAIAAFiAIDC1y8AAWMJALYCAQCAwtcvAAFkCQC2AgEAgICQu7rWrfANAAFlCQC2AgEAAAABZgkAtgIBAAAAAWcJALYCAQABAAFoCQC2AgEAAgABaQIFV0FWRVMAAWoCAl9fAAFrAAEAAWwAAgABbQADAAFuAAQAAW8AAQABcAACAAFxAAMAAXIABAABcwAFAAF0AAYAAXUABwABdgAIAAF3AAkAAXgACgABeQABAAF6AAIAAUEAAwABQgABAAFDAAcBAUQCAUUBRgkAvAIDCQC2AgEFAUUFAWQJALYCAQUBRgEBRwIBRQFGCQC8AgMFAUUFAWQFAUYBAUgCAUkBSgkAoAMBCQC8AgMFAUkJALYCAQUBSgUBZAEBSwMBSQFKAUwJAKADAQkAvQIEBQFJCQC2AgEFAUoFAWQFAUwBAU0DAU4BTwFQCQBrAwUBTgUBTwUBUAEBUQEBSQMJAGYCAAAFAUkJAQEtAQUBSQUBSQEBUgEBSQMJAL8CAgUBZQUBSQkAvgIBBQFJBQFJAQFTAAIQJXNfX3N3YXBDb250cmFjdAEBVAACEyVzX19mYWN0b3J5Q29udHJhY3QBAVUAAhQlc19fbWFuYWdlclB1YmxpY0tleQEBVgACFyVzX19tYW5hZ2VyVmF1bHRBZGRyZXNzAQFXAAIRJXMlc19fcHJpY2VfX2xhc3QBAVgCAVkBWgkAuQkCCQDMCAICGCVzJXMlZCVkX19wcmljZV9faGlzdG9yeQkAzAgCCQCkAwEFAVkJAMwIAgkApAMBBQFaBQNuaWwFAWoBAmFhAgJhYgJhYwkArAICCQCsAgIJAKwCAgILJXMlcyVzX19QX18FAmFiAgJfXwUCYWMBAmFkAgJhYgJhYwkArAICCQCsAgIJAKwCAgILJXMlcyVzX19HX18FAmFiAgJfXwUCYWMBAmFlAAIPJXNfX2Ftb3VudEFzc2V0AQJhZgACDiVzX19wcmljZUFzc2V0AAJhZwIHJXNfX2ZlZQACYWgJAGsDAAoFAWIAkE4AAmFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAmFnBQJhaAACYWoJALkJAgkAzAgCAgIlcwkAzAgCAgNrTHAFA25pbAUBagACYWsJALkJAgkAzAgCAgIlcwkAzAgCAhJrTHBSZWZyZXNoZWRIZWlnaHQFA25pbAUBagACYWwJALkJAgkAzAgCAgIlcwkAzAgCAg9yZWZyZXNoS0xwRGVsYXkFA25pbAUBagACYW0AHgACYW4JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUCYWwFAmFtAQJhbwECYXAJALkJAgkAzAgCAgQlcyVzCQDMCAICDXN0YWtlZEJhbGFuY2UJAMwIAgUCYXAFA25pbAUBagECYXEBAmFwCQC5CQIJAMwIAgIEJXMlcwkAzAgCAhFzaGFyZUFzc2V0QmFsYW5jZQkAzAgCBQJhcAUDbmlsBQFqAQJhcgECYXAJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmFvAQUCYXAAAAECYXMBAmFwCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQJhcQEFAmFwAAABAmF0AAIRJXNfX2ZhY3RvcnlDb25maWcBAmF1AAIYJXMlc19fbWF0Y2hlcl9fcHVibGljS2V5AQJhdgECYXcJAKwCAgkArAICAgglcyVzJXNfXwUCYXcCIF9fbWFwcGluZ3NfX3Bvb2xDb250cmFjdDJMcEFzc2V0AQJheAICYXkCYXoJAKwCAgkArAICCQCsAgIJAKwCAgIIJWQlZCVzX18FAmF5AgJfXwUCYXoCCF9fY29uZmlnAQJhQQECYUIJAKwCAgIoJXMlcyVzX19tYXBwaW5nc19fYmFzZUFzc2V0MmludGVybmFsSWRfXwUCYUIBAmFDAAIMJXNfX3NodXRkb3duAQJhRAECYUUJAKwCAgISJXMlc19fcG9vbFdlaWdodF9fBQJhRQECYUYAAhclc19fYWxsb3dlZExwU2NyaXB0SGFzaAACYUcCFyVzX19mZWVDb2xsZWN0b3JBZGRyZXNzAQJhSAECYUkJAKwCAgIbJXMlc19fc2tpcE9yZGVyVmFsaWRhdGlvbl9fBQJhSQECYUoEAmFLAmFMAmFNAmFOCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICJG9yZGVyIHZhbGlkYXRpb24gZmFpbGVkOiBvcmRlclZhbGlkPQkApQMBBQJhSwICICgFAmFMAgEpAg0gc2VuZGVyVmFsaWQ9CQClAwEFAmFNAg4gbWF0Y2hlclZhbGlkPQkApQMBBQJhTgECYU8BAmFQBAJhUQkApggBBQJhUAMJAAECBQJhUQIHQWRkcmVzcwQCYVIFAmFRBQJhUgUEdGhpcwECYVMABAJhVAQCYVEJAKIIAQkBAVQAAwkAAQIFAmFRAgZTdHJpbmcEAmFVBQJhUQkBAmFPAQUCYVUFBHRoaXMEAmFRCQCdCAIFAmFUCQEBVgADCQABAgUCYVECBlN0cmluZwQCYVYFAmFRCQECYU8BBQJhVgUEdGhpcwECYVcCAmFYAmFZCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUCYVgFAmFZCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmFYCQDMCAICAS4JAMwIAgUCYVkJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAECYVoCAmFYAmFZCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUCYVgFAmFZCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmFYCQDMCAICAS4JAMwIAgUCYVkJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAECYmEBAmJiCQACAQkAuQkCCQDMCAICCGxwLnJpZGU6CQDMCAIFAmJiBQNuaWwCASABAmJjAQJiYgkAuQkCCQDMCAICCGxwLnJpZGU6CQDMCAIFAmJiBQNuaWwCASAAAmJkCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYVcCBQR0aGlzCQEBVAAAAmJlCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYVcCBQJiZAUCYUcAAmJmCgACYmcJAPwHBAUCYmQCEGdldEluRmVlUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJiZwIDSW50BQJiZwkAAgEJAKwCAgkAAwEFAmJnAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQAAmJoCgACYmcJAPwHBAUCYmQCEWdldE91dEZlZVJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYmcCA0ludAUCYmcJAAIBCQCsAgIJAAMBBQJiZwIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AQJiaQAJAQt2YWx1ZU9yRWxzZQIJAJsIAgUCYmQJAQJhQwAHAQJiagAJANkEAQkBAmFXAgUCYmQJAQJhdQABAmJrAAQCYmwJAQJhVwIFBHRoaXMJAQJhZQAEAmJtCQECYVcCBQR0aGlzCQECYWYABAJhegkBAmFaAgUCYmQJAQJhQQEFAmJtBAJheQkBAmFaAgUCYmQJAQJhQQEFAmJsCQC1CQIJAQJhVwIFAmJkCQECYXgCCQCkAwEFAmF5CQCkAwEFAmF6BQFqAQJibgECYm8DCQAAAgUCYm8FAWkFBHVuaXQJANkEAQUCYm8BAmJwAQJibwMJAAACBQJibwUEdW5pdAUBaQkA2AQBCQEFdmFsdWUBBQJibwECYnEBAmJyCQCZCgcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYnIFAW8JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJicgUBcAkA2QQBCQCRAwIFAmJyBQFxCQECYm4BCQCRAwIFAmJyBQFyCQECYm4BCQCRAwIFAmJyBQFzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYnIFAXQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJicgUBdQACYnMJAQJicQEJAQJiawAAAmJ0BQJicwACYnUIBQJidAJfMQACYnYIBQJidAJfMgACYncIBQJidAJfMwACYngIBQJidAJfNAACYnkIBQJidAJfNQACYnoIBQJidAJfNgACYkEIBQJidAJfNwECYkIACQC1CQIJAQJhVwIFAmJkCQECYXQABQFqAAJiQwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgkBAmJCAAUBQgIZaW5jb3JyZWN0IHN0YWtpbmcgYWRkcmVzcwACYkQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIJAQJiQgAFAUMCGWluY29ycmVjdCBzdGFraW5nIGFkZHJlc3MBAmJFCgJiRgJiRwJiSAJiSQJiSgJiSwJiTAJiTQJiTgJiTwkAuQkCCQDMCAICFCVkJWQlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYkYJAMwIAgkApAMBBQJiRwkAzAgCCQCkAwEFAmJICQDMCAIJAKQDAQUCYkkJAMwIAgkApAMBBQJiSgkAzAgCCQCkAwEFAmJLCQDMCAIJAKQDAQUCYkwJAMwIAgkApAMBBQJiTQkAzAgCCQCkAwEFAmJOCQDMCAIJAKQDAQUCYk8FA25pbAUBagECYlAGAmJRAmJSAmJTAmJJAmJMAmJNCQC5CQIJAMwIAgIMJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYlEJAMwIAgkApAMBBQJiUgkAzAgCCQCkAwEFAmJTCQDMCAIJAKQDAQUCYkkJAMwIAgkApAMBBQJiTAkAzAgCCQCkAwEFAmJNBQNuaWwFAWoBAmJUAQJhcAQCYlUDCQAAAgUCYXACBVdBVkVTCAkA7wcBBQR0aGlzCWF2YWlsYWJsZQkA8AcCBQR0aGlzCQDZBAEFAmFwBAJiVgkAZQIJAGQCBQJiVQkBAmFyAQUCYXAJAQJhcwEFAmFwCQCWAwEJAMwIAgAACQDMCAIFAmJWBQNuaWwBAmJXAgJiWAJiWQkAvAIDBQJiWAUBZAUCYlkBAmJaAwJiWAJiWQFMCQC9AgQFAmJYBQFkBQJiWQUBTAECY2EBAmNiBAJjYwkA/AcEBQJjYgIHZ2V0UmF0ZQUDbmlsBQNuaWwDCQAAAgUCY2MFAmNjBAJhUQUCY2MDCQABAgUCYVECA0ludAQCY2QFAmFRBQJjZAkBAmJhAQIgcHJveHkuZ2V0UmF0ZSgpIHVuZXhwZWN0ZWQgdmFsdWUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmNlBAJhcAJjZgJjZwJjYgQCY2gJAQJhcgEFAmFwAwkAAAIFAmNoBQJjaAQCY2kJAQJhcwEFAmNnAwkAAAIFAmNpBQJjaQQCY2oJAQJibgEFAmFwAwkAZgIFAmNmAAAEAmNrCQD8BwQFAmNiAgdkZXBvc2l0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmNqBQJjZgUDbmlsAwkAAAIFAmNrBQJjawQCYVEFAmNrAwkAAQIFAmFRAgNJbnQEAmNsBQJhUQQCY20JAGQCBQJjaAUCY2YEAmNuCQBkAgUCY2kFAmNsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYW8BBQJhcAUCY20JAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhcQEFAmNnBQJjbgUDbmlsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY28GAmFwAmNmAmNnAmNiAmNwAmNxBAJjaAkBAmFyAQUCYXADCQAAAgUCY2gFAmNoBAJjaQkBAmFzAQUCY2cDCQAAAgUCY2kFAmNpBAJjcgkBAmNhAQUCY2IDCQAAAgUCY3IFAmNyBAJjcwkAawMFAmNwBQJjaAUCY2kEAmN0CQECYm4BBQJjZwQCY3UJAGsDBQJjcAUCY2YFAmNzBAJjdgkAawMFAmNwBQJjZgUCY3IEAmN3CQCWAwEJAMwIAgAACQDMCAIJAGUCBQJjdQUCY3YFA25pbAMJAGYCBQJjdgAABAJjeAkA/AcEBQJjYgIId2l0aGRyYXcFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCY3QFAmN2BQNuaWwDCQAAAgUCY3gFAmN4BAJhUQUCY3gDCQABAgUCYVECA0ludAQCY3kFAmFRBAJjbQkAZQIFAmNoBQJjeQQCY24JAGUCCQBlAgUCY2kFAmN2BQJjdwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFvAQUCYXAFAmNtCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXEBBQJjZwUCY24JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCY3EFAmN3CQECYm4BBQJjZwUDbmlsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY3oBAmFwBAJhUQkA/AcEBQJiZAIaZ2V0UG9vbExlYXNlQ29uZmlnUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzCQDMCAIFAmFwBQNuaWwFA25pbAMJAAECBQJhUQIwKEJvb2xlYW4sIEludCwgSW50LCBTdHJpbmcsIFN0cmluZywgSW50LCBTdHJpbmcpBAJhUgUCYVEFAmFSCQECYmEBCQCsAgIJAKwCAgIBWwUCYXACHV0gZ2V0TGVhc2VQcm94eUNvbmZpZygpIGVycm9yAQJjQQcCY0ICYXACY2cCY0MCY2ICY3ACY3EEAmNoCQECYXIBBQJhcAMJAAACBQJjaAUCY2gEAmNpCQECYXMBBQJjZwMJAAACBQJjaQUCY2kEAmNECQCWAwEJAMwIAgAACQDMCAIJAGUCCQECYlQBBQJhcAUCY0MFA25pbAQCY0UJAGsDBQJjQgUCY0QAZAQCY0YJAGUCBQJjaAUCY0UDCQAAAgUCY0YAAAUDbmlsAwkAZgIAAAUCY0YEAmNHCQEBLQEFAmNGCQECY2UEBQJhcAUCY0cFAmNnBQJjYgQCY0gFAmNGCQECY28GBQJhcAUCY0gFAmNnBQJjYgUCY3AFAmNxCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJjSQECYXAEAmNKCQECY3oBBQJhcAQCY0sIBQJjSgJfMQQCY0wIBQJjSgJfMgQCY0MIBQJjSgJfMwQCY00IBQJjSgJfNAQCY04IBQJjSgJfNQQCY3AIBQJjSgJfNgQCY08IBQJjSgJfNwMFAmNLCQECY0EHBQJjTAUCYXAFAmNOBQJjQwkBEUBleHRyTmF0aXZlKDEwNjIpAQUCY00FAmNwCQERQGV4dHJOYXRpdmUoMTA2MikBBQJjTwUDbmlsAQJjUAICYXACY1EEAmNSCQECY3oBBQJhcAQCY0sIBQJjUgJfMQQCY0wIBQJjUgJfMgQCY0MIBQJjUgJfMwQCY00IBQJjUgJfNAQCY04IBQJjUgJfNQQCY3AIBQJjUgJfNgQCY08IBQJjUgJfNwMFAmNLBAJjUwkAlgMBCQDMCAIAAAkAzAgCCQBlAgkAZQIJAQJiVAEFAmFwBQJjUQUCY0MFA25pbAMJAAACBQJjUwUCY1MEAmNtCQBrAwUCY0wFAmNTAGQDCQAAAgUCY20FAmNtBAJjVAkAZQIJAQJhcgEFAmFwBQJjbQMJAAACBQJjVAUCY1QDCQBmAgAABQJjVAkBAmNlBAUCYXAJAQEtAQUCY1QFAmNOCQERQGV4dHJOYXRpdmUoMTA2MikBBQJjTQkBAmNvBgUCYXAFAmNUBQJjTgkBEUBleHRyTmF0aXZlKDEwNjIpAQUCY00FAmNwCQERQGV4dHJOYXRpdmUoMTA2MikBBQJjTwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgUDbmlsAQJjVQICY1YCY1cEAmNYCQECY1ACCQECYVcCBQR0aGlzCQECYWUABQJjVgQCY1kJAQJjUAIJAQJhVwIFBHRoaXMJAQJhZgAFAmNXCQDOCAIFAmNYBQJjWQECY1oEAmRhAmRiAmRjAmRkBAJkZQkBAUQCBQJkYwUCZGEEAmRmCQEBRAIFAmRkBQJkYgkBAmJXAgUCZGYFAmRlAQJkZwMCZGMCZGQCZGgEAmRpCQECYmsABAJkagkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRpBQF0BAJkawkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRpBQF1BAJkbAkBAmNaBAUCZGoFAmRrBQJkYwUCZGQEAmJZCQEBRAIFAmRjBQJkagQCYlgJAQFEAgUCZGQFAmRrBAJkbQkBAUQCBQJkaAUBYgQCZG4JAQJiVwIFAmJZBQJkbQQCZG8JAQJiVwIFAmJYBQJkbQkAzAgCBQJkbAkAzAgCBQJkbgkAzAgCBQJkbwUDbmlsAQJkcAMCZGMCZGQCZGgEAmRxCQECZGcDBQJkYwUCZGQFAmRoCQDMCAIJAQFIAgkAkQMCBQJkcQAABQFiCQDMCAIJAQFIAgkAkQMCBQJkcQABBQFiCQDMCAIJAQFIAgkAkQMCBQJkcQACBQFiBQNuaWwBAmRyBAJkcwJkdAJkdQJhYgQCZGkJAQJiawAEAmR2CQCRAwIFAmRpBQFxBAJkdwkAkQMCBQJkaQUBcgQCZHgJAJEDAgUCZGkFAXMEAmRhCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGkFAXQEAmRiCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGkFAXUEAmR5CQCRAwIFAmRpBQFwBAJkeggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFAmR2CQCsAgIJAKwCAgIGQXNzZXQgBQJkdgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkDCQECIT0CBQJkdgUCZHQJAAIBAhVJbnZhbGlkIGFzc2V0IHBhc3NlZC4EAmRBCQECYlQBBQJkdwQCZEIJAQFEAgUCZEEFAmRhBAJkQwkBAmJUAQUCZHgEAmRECQEBRAIFAmRDBQJkYgQCZEUJAQJiVwIFAmREBQJkQgQCZEYJAQFIAgUCZEUFAWIEAmRHCQEBRAIFAmR1BQFiBAJkSAkBAUQCBQJkegUBYgQCZEkJALwCAwUCZEIFAmRHBQJkSAQCZEoJALwCAwUCZEQFAmRHBQJkSAQCZEsJAQFLAwUCZEkFAmRhBQVGTE9PUgQCZEwJAQFLAwUCZEoFAmRiBQVGTE9PUgQCZE0DCQAAAgUCZHMCAAUDbmlsCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFiBQJkSwMJAAACBQJkdwIFV0FWRVMFBHVuaXQJANkEAQUCZHcJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYWIFAmRMAwkAAAIFAmR4AgVXQVZFUwUEdW5pdAkA2QQBBQJkeAkAzAgCCQELU3RyaW5nRW50cnkCCQECYWQCCQClCAEFAmFiBQJkcwkBAmJQBgUCZEsFAmRMBQJkdQUCZEYFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZEYJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZEYFA25pbAkAnAoKBQJkSwUCZEwFAmR3BQJkeAUCZEEFAmRDBQJkegUCZEUFAmR5BQJkTQECZE4JAmRzAmRPAmRQAmRRAmRSAmRTAmFiAmRUAmRVBAJkaQkBAmJrAAQCZHYJANkEAQkAkQMCBQJkaQUBcQQCZFYJAJEDAgUCZGkFAXIEAmRXCQCRAwIFAmRpBQFzBAJkWAkAkQMCBQJkaQUBdgQCZFkJAJEDAgUCZGkFAXcEAmRqCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGkFAXQEAmRrCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGkFAXUEAmR5CQCRAwIFAmRpBQFwBAJkeggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJkdgkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJkdgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmRaCQDYBAEJAQt2YWx1ZU9yRWxzZQIFAmRRCQDZBAECBVdBVkVTBAJlYQkA2AQBCQELdmFsdWVPckVsc2UCBQJkUwkA2QQBAgVXQVZFUwMDCQECIT0CBQJkVgUCZFoGCQECIT0CBQJkVwUCZWEJAAIBAiJJbnZhbGlkIGFtdCBvciBwcmljZSBhc3NldCBwYXNzZWQuBAJkQQMFAmRUCQECYlQBBQJkVgkAZQIJAQJiVAEFAmRWBQJkUAQCZEMDBQJkVAkBAmJUAQUCZFcJAGUCCQECYlQBBQJkVwUCZFIEAmViCQEBRAIFAmRQBQJkagQCZWMJAQFEAgUCZFIFAmRrBAJlZAkBAmJXAgUCZWMFAmViBAJkQgkBAUQCBQJkQQUCZGoEAmRECQEBRAIFAmRDBQJkawQCZWUDCQAAAgUCZHoAAAQCZEUFAWUEAmVmBQFlBAJkbQkAdgYJALkCAgUCZWIFAmVjAAAJALYCAQAFAAEAAAUERE9XTgkAlwoFCQEBSAIFAmRtBQFiCQEBSAIFAmViBQJkagkBAUgCBQJlYwUCZGsJAQJiVwIJALcCAgUCZEQFAmVjCQC3AgIFAmRCBQJlYgUCZWYEAmRFCQECYlcCBQJkRAUCZEIEAmVmCQC8AgMJAQFSAQkAuAICBQJkRQUCZWQFAWQFAmRFBAJlZwkBAUQCBQJkTwUBYgMDCQECIT0CBQJkRQUBZQkAvwICBQJlZgUCZWcHCQACAQkArAICCQCsAgIJAKwCAgIPUHJpY2Ugc2xpcHBhZ2UgCQCmAwEFAmVmAh4gZXhjZWVkZWQgdGhlIHBhc3NlZCBsaW1pdCBvZiAJAKYDAQUCZWcEAmRICQEBRAIFAmR6BQFiBAJlaAkAvQIEBQJlYgkBAmJaAwUCZEQFAmRCBQdDRUlMSU5HBQFkBQdDRUlMSU5HBAJlaQkAvQIEBQJlYwUBZAkBAmJaAwUCZEQFAmRCBQVGTE9PUgUHQ0VJTElORwQCZWoDCQC/AgIFAmVoBQJlYwkAlAoCBQJlaQUCZWMJAJQKAgUCZWIFAmVoBAJlawgFAmVqAl8xBAJlbAgFAmVqAl8yBAJkbQkAvQIEBQJkSAUCZWwFAmREBQVGTE9PUgkAlwoFCQEBSwMFAmRtBQFiBQVGTE9PUgkBAUsDBQJlawUCZGoFB0NFSUxJTkcJAQFLAwUCZWwFAmRrBQdDRUlMSU5HBQJkRQUCZWYEAmVtCAUCZWUCXzEEAmVuCAUCZWUCXzIEAmVvCAUCZWUCXzMEAmRGCQEBSAIIBQJlZQJfNAUBYgQCZXAJAQFIAggFAmVlAl81BQFiAwkAZwIAAAUCZW0JAAIBAjZJbnZhbGlkIGNhbGN1bGF0aW9ucy4gTFAgY2FsY3VsYXRlZCBpcyBsZXNzIHRoYW4gemVyby4EAmVxAwkBASEBBQJkVQAABQJlbQQCZXIJAGUCBQJkUAUCZW4EAmVzCQBlAgUCZFIFAmVvBAJldAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVcABQJkRgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVgCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJkRgkAzAgCCQELU3RyaW5nRW50cnkCCQECYWECBQJhYgUCZHMJAQJiRQoFAmVuBQJlbwUCZXEFAmRGBQJkTwUCZXAFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmVyBQJlcwUDbmlsCQCfCg0FAmVtBQJlcQUCZEYFAmRBBQJkQwUCZHoFAmR2BQJkeQUCZXQFAmVyBQJlcwUCZFEFAmRTAQJldQMCZXYCZXcCZHoEAmV4CQEBRwIFAmV2CQC2AgEFAmJ6BAJleQkBAUcCBQJldwkAtgIBBQJiQQQCZXoJALwCAwkAdgYJALkCAgUCZXgFAmV5AAAJALYCAQAFAAEAEgUERE9XTgUBZwUCZHoDCQAAAgUCZHoFAWYFAWYFAmV6AQJlQQMCZUICZUMCZUQEAmVFCQC4AgIJALYCAQkBAmJUAQkBAmJwAQUCYngFAmVCBAJlRgkAuAICCQC2AgEJAQJiVAEJAQJicAEFAmJ5BQJlQwQCZUcJALgCAgkAtgIBCAkBBXZhbHVlAQkA7AcBBQJidwhxdWFudGl0eQUCZUQEAmVICQECZXUDBQJlRQUCZUYFAmVHBQJlSAECZUkDAmVKAmVLAmVEBAJlRQkAZAIJAQJiVAEJAQJicAEFAmJ4BQJlSgQCZUYJAGQCCQECYlQBCQECYnABBQJieQUCZUsEAmVHCQBkAggJAQV2YWx1ZQEJAOwHAQUCYncIcXVhbnRpdHkFAmVEBAJlegkBAmV1AwkAtgIBBQJlRQkAtgIBBQJlRgkAtgIBBQJlRwQCZUwJAMwIAgkBDEludGVnZXJFbnRyeQIFAmFrBQZoZWlnaHQJAMwIAgkBC1N0cmluZ0VudHJ5AgUCYWoJAKYDAQUCZXoFA25pbAkAlAoCBQJlTAUCZXoBAmVNAAkBC3ZhbHVlT3JFbHNlAgkAmwgCBQJiZAkBAmFIAQkApQgBBQR0aGlzBwECZU4CAmVPAmV6AwkAwAICBQJlegUCZU8GCQECYmEBCQC5CQIJAMwIAgIidXBkYXRlZCBLTHAgbG93ZXIgdGhhbiBjdXJyZW50IEtMcAkAzAgCCQCmAwEFAmVPCQDMCAIJAKYDAQUCZXoFA25pbAIBIAECZVABAmVRBAJlRQkBAmJUAQkBAmJwAQUCYngEAmVGCQECYlQBCQECYnABBQJieQQCZVIIBQJlUQZhbW91bnQEAmVTCQBuBAgFAmVRBmFtb3VudAgFAmVRBXByaWNlBQFiBQVGTE9PUgQCZVQDCQAAAggFAmVRCW9yZGVyVHlwZQUDQnV5CQCUCgIFAmVSCQEBLQEFAmVTCQCUCgIJAQEtAQUCZVIFAmVTBAJlSggFAmVUAl8xBAJlSwgFAmVUAl8yAwMDCQECYmkABgkAAAIFAmJ2BQFtBgkAAAIFAmJ2BQFuCQACAQIcRXhjaGFuZ2Ugb3BlcmF0aW9ucyBkaXNhYmxlZAMDCQECIT0CCAgFAmVRCWFzc2V0UGFpcgthbW91bnRBc3NldAUCYngGCQECIT0CCAgFAmVRCWFzc2V0UGFpcgpwcmljZUFzc2V0BQJieQkAAgECE1dyb25nIG9yZGVyIGFzc2V0cy4EAmVVCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKgDAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQJhagIBMAkBAmJjAQILaW52YWxpZCBrTHAEAmVWCQECZUkDBQJlSgUCZUsAAAQCZVcIBQJlVgJfMQQCZVgIBQJlVgJfMgQCZVkJAMACAgUCZVgFAmVVBAJlWgkAuQkCCQDMCAICBGtMcD0JAMwIAgkApgMBBQJlVQkAzAgCAggga0xwTmV3PQkAzAgCCQCmAwEFAmVYCQDMCAICFCBhbW91bnRBc3NldEJhbGFuY2U9CQDMCAIJAKQDAQUCZUUJAMwIAgITIHByaWNlQXNzZXRCYWxhbmNlPQkAzAgCCQCkAwEFAmVGCQDMCAICGSBhbW91bnRBc3NldEJhbGFuY2VEZWx0YT0JAMwIAgkApAMBBQJlSgkAzAgCAhggcHJpY2VBc3NldEJhbGFuY2VEZWx0YT0JAMwIAgkApAMBBQJlSwkAzAgCAgggaGVpZ2h0PQkAzAgCCQCkAwEFBmhlaWdodAUDbmlsAgAJAJQKAgUCZVkFAmVaAQJmYQECZmIDCQECIT0CCQCQAwEIBQJmYghwYXltZW50cwABCQACAQIdZXhhY3RseSAxIHBheW1lbnQgaXMgZXhwZWN0ZWQEAmZjCQEFdmFsdWUBCQCRAwIIBQJmYghwYXltZW50cwAABAJkdAkBBXZhbHVlAQgFAmZjB2Fzc2V0SWQEAmZkCAUCZmMGYW1vdW50BAJlZQkBAmRyBAkA2AQBCAUCZmINdHJhbnNhY3Rpb25JZAkA2AQBBQJkdAUCZmQIBQJmYgZjYWxsZXIEAmRLCAUCZWUCXzEEAmRMCAUCZWUCXzIEAmR5CQENcGFyc2VJbnRWYWx1ZQEIBQJlZQJfOQQCZE0IBQJlZQNfMTADAwkBAmJpAAYJAAACBQJkeQUBbgkAAgEJAKwCAgIsR2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCZHkJAJcKBQUCZEsFAmRMBQJmZAUCZHQFAmRNAQJmZQMCZmICZE8CZFUDCQECIT0CCQCQAwEIBQJmYghwYXltZW50cwACCQACAQIfZXhhY3RseSAyIHBheW1lbnRzIGFyZSBleHBlY3RlZAQCZmYJAQV2YWx1ZQEJAJEDAggFAmZiCHBheW1lbnRzAAAEAmZnCQEFdmFsdWUBCQCRAwIIBQJmYghwYXltZW50cwABBAJmaAkBAmROCQkA2AQBCAUCZmINdHJhbnNhY3Rpb25JZAUCZE8IBQJmZgZhbW91bnQIBQJmZgdhc3NldElkCAUCZmcGYW1vdW50CAUCZmcHYXNzZXRJZAkApQgBCAUCZmIGY2FsbGVyBwUCZFUEAmR5CQENcGFyc2VJbnRWYWx1ZQEIBQJmaAJfOAMDAwkBAmJpAAYJAAACBQJkeQUBbAYJAAACBQJkeQUBbgkAAgEJAKwCAgIsUHV0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCZHkFAmZoAQJmaQECY2YEAmZqCQD8BwQFAmJkAgRlbWl0CQDMCAIFAmNmBQNuaWwFA25pbAMJAAACBQJmagUCZmoEAmZrBAJhUQUCZmoDCQABAgUCYVECB0FkZHJlc3MEAmZsBQJhUQkA/AcEBQJmbAIEZW1pdAkAzAgCBQJjZgUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZmsFAmZrBQJjZgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZm0CAmNmAmFpBAJmbgMJAAACBQJhaQAAAAAJAGsDBQJjZgUCYWkFAWIJAJQKAgkAZQIFAmNmBQJmbgUCZm4BAmZvBAJmcAJmcQJhYgJhYwQCZnIJAAACBQJhYwUEdW5pdAQCZnMJAQJiVAEJAQJicAEFAmJ4BAJmdAkBAmJUAQkBAmJwAQUCYnkEAmZ1AwkAAAIFAmZxBQJieAYDCQAAAgUCZnEFAmJ5BwkBAmJhAQINaW52YWxpZCBhc3NldAQCZnYDBQJmcgkAlAoCBQJmcwUCZnQDBQJmdQkAlAoCCQBlAgUCZnMFAmZwBQJmdAkAlAoCBQJmcwkAZQIFAmZ0BQJmcAQCZncIBQJmdgJfMQQCZngIBQJmdgJfMgQCZnkDBQJmdQkAlAoCBQJmcAAACQCUCgIAAAUCZnAEAmZ6CAUCZnkCXzEEAmZBCAUCZnkCXzIEAmVSCAkBAmZtAgUCZnoFAmJmAl8xBAJlUwgJAQJmbQIFAmZBBQJiZgJfMQQCZkIJAQJmbQIFAmZwBQJiZgQCZkMIBQJmQgJfMQQCZm4IBQJmQgJfMgQCZkQJAGQCBQJmdwUCZVIEAmZFCQBkAgUCZngFAmVTBAJmRgkBAmJXAgkBAUQCBQJmRQUCYkEJAQFEAgUCZkQFAmJ6BAJmRwkBAUgCBQJmRgUBYgQCZkgDBQJmdQUCZncFAmZ4BAJmSQkAtgIBBQJmSAQCZkoJALYCAQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJidwkArAICCQCsAgICBmFzc2V0IAkA2AQBBQJidwIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmZLAwkAvwICBQJmSgUBZgYJAQJiYQECImluaXRpYWwgZGVwb3NpdCByZXF1aXJlcyBhbGwgY29pbnMDCQAAAgUCZksFAmZLBAJmTAkAtgIBBQJmQwQCZk0JAJYDAQkAzAgCAAAJAMwIAgkAoAMBCQC6AgIJALkCAgUCZkoJALgCAgkBCnNxcnRCaWdJbnQECQC3AgIFAWQJALoCAgkAuQICBQJmTAUBZAUCZkkAEgASBQRET1dOBQFkBQFkBQNuaWwEAmV0AwUCZnIFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVcABQJmRwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVgCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJmRwkAzAgCCQELU3RyaW5nRW50cnkCCQECYWECCQClCAEJAQV2YWx1ZQEFAmFiCQDYBAEJAQV2YWx1ZQEFAmFjCQECYkUKBQJmegUCZkEFAmZNBQJmRwAAAAAFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAAAAAABQNuaWwEAmZOCQECYlcCCQEBRAIFAmZ4BQJiQQkBAUQCBQJmdwUCYnoEAmZPCQEBSAIFAmZOBQFiBAJmUAQCZlEDBQJmdQkAlAoCBQJmegUCZncJAJQKAgUCZkEFAmZ4BAJjZggFAmZRAl8xBAJmUggFAmZRAl8yBAJmUwkAoAMBCQC8AgMFAmZKCQC2AgEJAGkCBQJjZgACCQC2AgEFAmZSCQBrAwkAZQIFAmZNBQJmUwUBYgUCZlMJAJcKBQUCZk0FAmV0BQJmbgUCZlAFAmZ1CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJmVAUCZlUCZkMCZnECYWICYWMEAmZyCQAAAgUCYWMFBHVuaXQEAmRpCQECYmsABAJkagkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRpBQF0BAJkawkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRpBQF1BAJmVgkAzAgCAwkAAAIFAmZxBQJidwYJAQJiYQECEGludmFsaWQgbHAgYXNzZXQFA25pbAMJAAACBQJmVgUCZlYEAmZXAwkAAAIFAmZVBQJieAYDCQAAAgUCZlUFAmJ5BwkBAmJhAQINaW52YWxpZCBhc3NldAQCZlgDBQJmVwkAtgIBCQECYlQBCQECYnABBQJieAkAtgIBCQECYlQBCQECYnABBQJieQQCZlkDBQJmVwUCZGoFAmRrBAJmWgkBAmJUAQkBAmJwAQUCYngEAmdhCQECYlQBCQECYnABBQJieQQCZ2IDBQJmVwUCZloFAmdhBAJnYwkAtgIBBQJnYgQCZkoJALYCAQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJidwkArAICCQCsAgICBmFzc2V0IAkA2AQBBQJidwIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmdkCQC2AgEFAmZDBAJnZQkAlgMBCQDMCAIAAAkAzAgCCQCgAwEJALoCAgkAuQICBQJmWAkAuAICBQFkCQB2BgkAuAICBQFkCQC6AgIJALkCAgUCZ2QFAWQFAmZKABIFAWgAAAASBQRET1dOBQFkBQNuaWwEAmdmCQECZm0CBQJnZQUCYmgEAmdnCAUCZ2YCXzEEAmZuCAUCZ2YCXzIEAmdoAwUCZlcJAJYKBAUCZ2cAAAkAZQIFAmZaBQJnZQUCZ2EJAJYKBAAABQJnZwUCZloJAGUCBQJnYQUCZ2UEAmdpCAUCZ2gCXzEEAmdqCAUCZ2gCXzIEAmdrCAUCZ2gCXzMEAmdsCAUCZ2gCXzQEAmZGCQECYlcCCQEBRAIFAmdsBQJiQQkBAUQCBQJnawUCYnoEAmZHCQEBSAIFAmZGBQFiBAJldAMFAmZyBQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFkAgkApQgBCQEFdmFsdWUBBQJhYgkA2AQBCQEFdmFsdWUBBQJhYwkBAmJQBgUCZ2kFAmdqBQJmQwUCZkcFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZkcJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZkcFA25pbAQCZk4JAQJiVwIJAQFEAgUCZ2EFAmJBCQEBRAIFAmZaBQJiegQCZk8JAQFIAgUCZk4FAWIEAmZQBAJnbQkAaAIJAKADAQkAvAIDBQJmWAUCZ2QFAmZKAAIJAGsDCQBlAgUCZ2cFAmdtBQFiBQJnbQkAlwoFBQJnZwUCZXQFAmZuBQJmUAUCZlcJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmduAAQCZ28JAQJhUwAEAmFRCQCdCAIFAmdvCQEBVQADCQABAgUCYVECBlN0cmluZwQCYVYFAmFRCQDZBAEFAmFWAwkAAQIFAmFRAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmdwAQJmYgQCYVEJAQJnbgADCQABAgUCYVECCkJ5dGVWZWN0b3IEAmdxBQJhUQkAAAIIBQJmYg9jYWxsZXJQdWJsaWNLZXkFAmdxAwkAAQIFAmFRAgRVbml0CQAAAggFAmZiBmNhbGxlcgUEdGhpcwkAAgECC01hdGNoIGVycm9yAQJncgECZmIEAmdzCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEAmFRCQECZ24AAwkAAQIFAmFRAgpCeXRlVmVjdG9yBAJncQUCYVEDCQAAAggFAmZiD2NhbGxlclB1YmxpY0tleQUCZ3EGBQJncwMJAAECBQJhUQIEVW5pdAMJAAACCAUCZmIGY2FsbGVyBQR0aGlzBgUCZ3MJAAIBAgtNYXRjaCBlcnJvchwCZmIBCXJlYmFsYW5jZQAJAM4IAgkBAmNJAQkBAmFXAgUEdGhpcwkBAmFlAAkBAmNJAQkBAmFXAgUEdGhpcwkBAmFmAAJmYgEhY2FsY3VsYXRlQW1vdW50T3V0Rm9yU3dhcFJFQURPTkxZAwJndAJndQJndgQCZ3cDCQAAAgUCZ3UHBAJneAkBAmFXAgUEdGhpcwkBAmFmAAQCZ3kJAQJhVwIFBHRoaXMJAQJhZQAJAJQKAgUCZ3gFAmd5BAJneAkBAmFXAgUEdGhpcwkBAmFlAAQCZ3kJAQJhVwIFBHRoaXMJAQJhZgAJAJQKAgUCZ3gFAmd5BAJneAgFAmd3Al8xBAJneQgFAmd3Al8yBAJnegkBAmJUAQUCZ3kEAmdBCQECYlQBBQJneAQCZ0IJAGsDBQJnQQUCZ3QJAGQCBQJnegUCZ3QEAmdDCQC5AgIJALYCAQUCZ3oJALYCAQUCZ0EEAmdECQC5AgIJALcCAgkAtwICCQC2AgEJAQJiVAEFAmd5CQC2AgEFAmd0CQC2AgEFAmd2CQC4AgIJALYCAQkBAmJUAQUCZ3gJALYCAQUCZ0IEAmdFAwkAwAICBQJnRAUCZ0MGCQACAQIUbmV3IEsgaXMgZmV3ZXIgZXJyb3IDCQAAAgUCZ0UFAmdFCQCUCgIFA25pbAUCZ0IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZmIBJmNhbGN1bGF0ZUFtb3VudE91dEZvclN3YXBBbmRTZW5kVG9rZW5zBQJndAJndQJnRgJnRwJndgQCZ0gKAAJiZwkA/AcEBQJiZAIXZ2V0U3dhcENvbnRyYWN0UkVBRE9OTFkFA25pbAUDbmlsAwkAAQIFAmJnAgZTdHJpbmcFAmJnCQACAQkArAICCQADAQUCYmcCGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwQCZlYJAMwIAgMJAGcCCAkBBXZhbHVlAQkAkQMCCAUCZmIIcGF5bWVudHMAAAZhbW91bnQFAmd0BgkBAmJhAQIMV3JvbmcgYW1vdW50CQDMCAIDCQAAAggFAmZiBmNhbGxlcgkBEUBleHRyTmF0aXZlKDEwNjIpAQUCZ0gGCQECYmEBAhFQZXJtaXNzaW9uIGRlbmllZAUDbmlsAwkAAAIFAmZWBQJmVgQCZmMJAQV2YWx1ZQEJAJEDAggFAmZiCHBheW1lbnRzAAAEAmd5CQECYnABCAUCZmMHYXNzZXRJZAQCZ3gDCQAAAgUCZ3UHCQECYVcCBQR0aGlzCQECYWYACQECYVcCBQR0aGlzCQECYWUABAJnegkAZQIJAGUCCQECYlQBBQJneQgJAQV2YWx1ZQEJAJEDAggFAmZiCHBheW1lbnRzAAAGYW1vdW50BQJndgQCZ0EJAQJiVAEFAmd4BAJnQgkAawMFAmdBBQJndAkAZAIFAmd6BQJndAQCZ0MJALkCAgkAtgIBBQJnegkAtgIBBQJnQQQCZ0QJALkCAgkAtwICCQC2AgEJAQJiVAEFAmd5CQC2AgEFAmd2CQC4AgIJALYCAQkBAmJUAQUCZ3gJALYCAQUCZ0IEAmdFAwkAwAICBQJnRAUCZ0MGCQACAQIUbmV3IEsgaXMgZmV3ZXIgZXJyb3IDCQAAAgUCZ0UFAmdFBAJnSQMJAGcCBQJnQgUCZ0YGCQACAQIsRXhjaGFuZ2UgcmVzdWx0IGlzIGZld2VyIGNvaW5zIHRoYW4gZXhwZWN0ZWQDCQAAAgUCZ0kFAmdJBAJnSgkBAmNJAQUCZ3kDCQAAAgUCZ0oFAmdKBAJnSwkBAmNQAgUCZ3gFAmdCAwkAAAIFAmdLBQJnSwkAlAoCCQDOCAIJAM4IAgUCZ0sFAmdKCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmdHBQJnQgkBAmJuAQUCZ3gFA25pbAUCZ0IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZmIBA3B1dAICZE8CZ0wDCQBmAgAABQJkTwkAAgECIEludmFsaWQgc2xpcHBhZ2VUb2xlcmFuY2UgcGFzc2VkBAJmaAkBAmZlAwUCZmIFAmRPBgQCZXEIBQJmaAJfMgQCZHYIBQJmaAJfNwQCZE0IBQJmaAJfOQQCZXIIBQJmaANfMTAEAmVzCAUCZmgDXzExBAJnTQgFAmZoA18xMgQCZ04IBQJmaANfMTMEAmZmCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJmYghwYXltZW50cwAABmFtb3VudAQCZmcJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmZiCHBheW1lbnRzAAEGYW1vdW50BAJlSAkBAmVBAwUCZmYFAmZnCQC2AgEAAAMJAAACBQJlSAUCZUgEAmZqCQD8BwQFAmJkAgRlbWl0CQDMCAIFAmVxBQNuaWwFA25pbAMJAAACBQJmagUCZmoEAmZrBAJhUQUCZmoDCQABAgUCYVECB0FkZHJlc3MEAmZsBQJhUQkA/AcEBQJmbAIEZW1pdAkAzAgCBQJlcQUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZmsFAmZrBAJnTwMJAGYCBQJlcgAACQD8BwQFAmJEAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZ00FAmVyBQNuaWwFA25pbAMJAAACBQJnTwUCZ08EAmdQAwkAZgIFAmVzAAAJAPwHBAUCYkQCA3B1dAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJnTgUCZXMFA25pbAUDbmlsAwkAAAIFAmdQBQJnUAQCZ1EDBQJnTAQCZ1IJAPwHBAUCYkMCBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmR2BQJlcQUDbmlsAwkAAAIFAmdSBQJnUgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJmYgZjYWxsZXIFAmVxBQJkdgUDbmlsBAJnUwkBAmVJAwAAAAAAAAMJAAACBQJnUwUCZ1MEAmV6CAUCZ1MCXzIEAmdUCAUCZ1MCXzEEAmdVCQECZU4CBQJlSAUCZXoDCQAAAgUCZ1UFAmdVBAJnVgkA/AcEBQR0aGlzAglyZWJhbGFuY2UFA25pbAUDbmlsAwkAAAIFAmdWBQJnVgkAzggCCQDOCAIFAmRNBQJnUQUCZ1QJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZmIBCnB1dEZvckZyZWUBAmdXAwkAZgIAAAUCZ1cJAAIBAhRJbnZhbGlkIHZhbHVlIHBhc3NlZAQCZmgJAQJmZQMFAmZiBQJnVwcEAmRNCAUCZmgCXzkEAmZmCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJmYghwYXltZW50cwAABmFtb3VudAQCZmcJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmZiCHBheW1lbnRzAAEGYW1vdW50BAJlSAkBAmVBAwUCZmYFAmZnCQC2AgEAAAMJAAACBQJlSAUCZUgEAmdYCQECZUkDAAAAAAAABAJnVAgFAmdYAl8xBAJleggFAmdYAl8yBAJnVQkBAmVOAgUCZUgFAmV6AwkAAAIFAmdVBQJnVQkAzggCBQJkTQUCZ1QJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZmIBCXB1dE9uZVRrbgICZ1kCZ1oEAmhhCgACYmcJAPwHBAUCYmQCKGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJiZwIHQm9vbGVhbgUCYmcJAAIBCQCsAgIJAAMBBQJiZwIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCaGIDAwMJAQJiaQAGCQAAAgUCYnYFAWwGCQAAAgUCYnYFAW4GBQJoYQQCZlYJAMwIAgMDCQEBIQEFAmhiBgkBAmdwAQUCZmIGCQECYmEBAiFwdXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJmYghwYXltZW50cwABBgkBAmJhAQIeZXhhY3RseSAxIHBheW1lbnQgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZlYFAmZWBAJoYwkAkQMCCAUCZmIIcGF5bWVudHMAAAQCZnEIBQJoYwdhc3NldElkBAJmcAgFAmhjBmFtb3VudAQCZUgDCQAAAgUCZnEFAmJ4CQECZUEDCQC2AgEFAmZwCQC2AgEAAAkAtgIBAAADCQAAAgUCZnEFAmJ5CQECZUEDCQC2AgEAAAkAtgIBBQJmcAkAtgIBAAAJAQJiYQECHnBheW1lbnQgYXNzZXQgaXMgbm90IHN1cHBvcnRlZAMJAAACBQJlSAUCZUgEAmFiCAUCZmIGY2FsbGVyBAJhYwgFAmZiDXRyYW5zYWN0aW9uSWQEAmhkCQECZm8EBQJmcAUCZnEFAmFiBQJhYwMJAAACBQJoZAUCaGQEAmZ1CAUCaGQCXzUEAmhlCAUCaGQCXzQEAmZuCAUCaGQCXzMEAmV0CAUCaGQCXzIEAmhmCAUCaGQCXzEEAmhnAwMJAGYCBQJnWQAACQBmAgUCZ1kFAmhmBwkBAmJhAQkAuQkCCQDMCAICH2Ftb3VudCB0byByZWNlaXZlIGlzIGxlc3MgdGhhbiAJAMwIAgkApAMBBQJnWQUDbmlsAgAFAmhmBAJmagkBAmZpAQUCaGcDCQAAAgUCZmoFAmZqBAJnUQMFAmdaBAJoaAkA/AcEBQJiQwIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYncFAmhnBQNuaWwDCQAAAgUCaGgFAmhoBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmZiBmNhbGxlcgUCaGcFAmJ3BQNuaWwEAmhpAwkAZgIFAmZuAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYmUFAmZuBQJmcQUDbmlsBQNuaWwEAmhqAwkAAAIFBHRoaXMFAmJlCQCUCgIAAAAAAwUCZnUJAJQKAgkBAS0BBQJmbgAACQCUCgIAAAkBAS0BBQJmbgQCZUoIBQJoagJfMQQCZUsIBQJoagJfMgQCaGsJAQJlSQMFAmVKBQJlSwAABAJnVAgFAmhrAl8xBAJleggFAmhrAl8yBAJlVQkBBXZhbHVlAQkAoggBBQJhagQCZ1UJAQJlTgIFAmVIBQJlegMJAAACBQJnVQUCZ1UEAmdWCQD8BwQFBHRoaXMCCXJlYmFsYW5jZQUDbmlsBQNuaWwDCQAAAgUCZ1YFAmdWCQCUCgIJAM4IAgkAzggCCQDOCAIFAmV0BQJnUQUCaGkFAmdUBQJoZwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJmYgERcHV0T25lVGtuUkVBRE9OTFkCAmZxAmZwBAJobAkBAmZvBAUCZnAJAQJibgEFAmZxBQR1bml0BQR1bml0BAJoZggFAmhsAl8xBAJldAgFAmhsAl8yBAJmbggFAmhsAl8zBAJoZQgFAmhsAl80BAJmdQgFAmhsAl81CQCUCgIFA25pbAkAlQoDBQJoZgUCZm4FAmhlAmZiAQlnZXRPbmVUa24CAmhtAmdZBAJoYQoAAmJnCQD8BwQFAmJkAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYmcCB0Jvb2xlYW4FAmJnCQACAQkArAICCQADAQUCYmcCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmhuAwMJAQJiaQAGCQAAAgUCYnYFAW4GBQJoYQQCZlYJAMwIAgMDCQEBIQEFAmhuBgkBAmdwAQUCZmIGCQECYmEBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJmYghwYXltZW50cwABBgkBAmJhAQIeZXhhY3RseSAxIHBheW1lbnQgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZlYFAmZWBAJmVQkBAmJuAQUCaG0EAmhjCQCRAwIIBQJmYghwYXltZW50cwAABAJmcQgFAmhjB2Fzc2V0SWQEAmZDCAUCaGMGYW1vdW50BAJlSAkBAmVBAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJlSAUCZUgEAmFiCAUCZmIGY2FsbGVyBAJhYwgFAmZiDXRyYW5zYWN0aW9uSWQEAmhvCQECZlQFBQJmVQUCZkMFAmZxBQJhYgUCYWMDCQAAAgUCaG8FAmhvBAJmVwgFAmhvAl81BAJoZQgFAmhvAl80BAJmbggFAmhvAl8zBAJldAgFAmhvAl8yBAJocAgFAmhvAl8xBAJjZgMDCQBmAgUCZ1kAAAkAZgIFAmdZBQJocAcJAQJiYQEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZ1kFA25pbAIABQJocAQCaHEJAPwHBAUCYmQCBGJ1cm4JAMwIAgUCZkMFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZnEFAmZDBQNuaWwDCQAAAgUCaHEFAmhxBAJnSwkBAmNQAgUCaG0JAGQCBQJjZgkAlgMBCQDMCAIAAAkAzAgCBQJmbgUDbmlsBAJocgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhYgUCY2YFAmZVBQNuaWwEAmhpAwkAZgIFAmZuAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYmUFAmZuBQJmVQUDbmlsBQNuaWwEAmhzBAJodAMJAAACBQR0aGlzBQJiZQAABQJmbgMFAmZXCQCUCgIJAQEtAQkAZAIFAmNmBQJodAAACQCUCgIAAAkBAS0BCQBkAgUCY2YFAmh0BAJlSggFAmhzAl8xBAJlSwgFAmhzAl8yBAJodQkBAmVJAwUCZUoFAmVLAAAEAmdUCAUCaHUCXzEEAmV6CAUCaHUCXzIEAmdVCQECZU4CBQJlSAUCZXoDCQAAAgUCZ1UFAmdVCQCUCgIJAM4IAgkAzggCCQDOCAIJAM4IAgUCZXQFAmdLBQJocgUCaGkFAmdUBQJjZgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJmYgERZ2V0T25lVGtuUkVBRE9OTFkCAmZVAmZDBAJodgkBAmZUBQkBAmJuAQUCZlUFAmZDBQJidwUEdW5pdAUEdW5pdAQCaHAIBQJodgJfMQQCZXQIBQJodgJfMgQCZm4IBQJodgJfMwQCaGUIBQJodgJfNAQCZlcIBQJodgJfNQkAlAoCBQNuaWwJAJUKAwUCaHAFAmZuBQJoZQJmYgETdW5zdGFrZUFuZEdldE9uZVRrbgMCaHcCaG0CZ1kEAmhhCgACYmcJAPwHBAUCYmQCKGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJiZwIHQm9vbGVhbgUCYmcJAAIBCQCsAgIJAAMBBQJiZwIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCaG4DAwkBAmJpAAYJAAACBQJidgUBbgYFAmhhBAJmVgkAzAgCAwMJAQEhAQUCaG4GCQECZ3ABBQJmYgYJAQJiYQECIWdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmZiCHBheW1lbnRzAAAGCQECYmEBAhhubyBwYXltZW50cyBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJmVgUCZlYEAmZVCQECYm4BBQJobQQCYWIIBQJmYgZjYWxsZXIEAmFjCAUCZmINdHJhbnNhY3Rpb25JZAQCZUgJAQJlQQMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZUgFAmVIBAJoeAkA/AcEBQJiQwIHdW5zdGFrZQkAzAgCCQDYBAEFAmJ3CQDMCAIFAmh3BQNuaWwFA25pbAMJAAACBQJoeAUCaHgEAmh5CQECZlQFBQJmVQUCaHcFAmJ3BQJhYgUCYWMDCQAAAgUCaHkFAmh5BAJmVwgFAmh5Al81BAJoZQgFAmh5Al80BAJmbggFAmh5Al8zBAJldAgFAmh5Al8yBAJocAgFAmh5Al8xBAJjZgMDCQBmAgUCZ1kAAAkAZgIFAmdZBQJocAcJAQJiYQEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZ1kFA25pbAIABQJocAQCaHEJAPwHBAUCYmQCBGJ1cm4JAMwIAgUCaHcFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYncFAmh3BQNuaWwDCQAAAgUCaHEFAmhxBAJnSwkBAmNQAgUCaG0JAGQCBQJjZgkAlgMBCQDMCAIAAAkAzAgCBQJmbgUDbmlsBAJocgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZmIGY2FsbGVyBQJjZgUCZlUFA25pbAQCaGkDCQBmAgUCZm4AAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJiZQUCZm4FAmZVBQNuaWwFA25pbAQCaHoEAmh0AwkAAAIFBHRoaXMFAmJlAAAFAmZuAwUCZlcJAJQKAgkBAS0BCQBkAgUCY2YFAmh0AAAJAJQKAgAACQEBLQEJAGQCBQJjZgUCaHQEAmVKCAUCaHoCXzEEAmVLCAUCaHoCXzIEAmhBCQECZUkDBQJlSgUCZUsAAAQCZ1QIBQJoQQJfMQQCZXoIBQJoQQJfMgQCZ1UJAQJlTgIFAmVIBQJlegMJAAACBQJnVQUCZ1UJAJQKAgkAzggCCQDOCAIJAM4IAgkAzggCBQJldAUCZ0sFAmhyBQJoaQUCZ1QFAmNmCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmZiAQNnZXQABAJlZQkBAmZhAQUCZmIEAmRLCAUCZWUCXzEEAmRMCAUCZWUCXzIEAmZkCAUCZWUCXzMEAmR0CAUCZWUCXzQEAmRNCAUCZWUCXzUEAmdLCQECY1UCBQJkSwUCZEwEAmVICQECZUEDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmVIBQJlSAQCaEIJAPwHBAUCYmQCBGJ1cm4JAMwIAgUCZmQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZHQFAmZkBQNuaWwDCQAAAgUCaEIFAmhCBAJoQwkBAmVJAwkBAS0BBQJkSwkBAS0BBQJkTAAABAJnVAgFAmhDAl8xBAJleggFAmhDAl8yBAJnVQkBAmVOAgUCZUgFAmV6AwkAAAIFAmdVBQJnVQkAzggCCQDOCAIFAmdLBQJkTQUCZ1QJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZmIBCWdldE5vTGVzcwICaEQCaEUEAmVlCQECZmEBBQJmYgQCZEsIBQJlZQJfMQQCZEwIBQJlZQJfMgQCZmQIBQJlZQJfMwQCZHQIBQJlZQJfNAQCZE0IBQJlZQJfNQMJAGYCBQJoRAUCZEsJAAIBCQCsAgIJAKwCAgkArAICAhxub0xlc3NUaGVuQW10QXNzZXQgZmFpbGVkOiAgCQCkAwEFAmRLAgMgPCAJAKQDAQUCaEQDCQBmAgUCaEUFAmRMCQACAQkArAICCQCsAgIJAKwCAgIdbm9MZXNzVGhlblByaWNlQXNzZXQgZmFpbGVkOiAJAKQDAQUCZEwCAyA8IAkApAMBBQJoRQQCZ0sJAQJjVQIFAmRLBQJkTAQCZUgJAQJlQQMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZUgFAmVIBAJoQgkA/AcEBQJiZAIEYnVybgkAzAgCBQJmZAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJkdAUCZmQFA25pbAMJAAACBQJoQgUCaEIEAmhGCQECZUkDCQEBLQEFAmRLCQEBLQEFAmRMAAAEAmdUCAUCaEYCXzEEAmV6CAUCaEYCXzIEAmdVCQECZU4CBQJlSAUCZXoDCQAAAgUCZ1UFAmdVCQDOCAIJAM4IAgUCZ0sFAmRNBQJnVAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJmYgENdW5zdGFrZUFuZEdldAECY2YEAmhHAwkBAiE9AgkAkAMBCAUCZmIIcGF5bWVudHMAAAkAAgECGE5vIHBheW1lbnRzIGFyZSBleHBlY3RlZAYDCQAAAgUCaEcFAmhHBAJkaQkBAmJrAAQCZHYJANkEAQkAkQMCBQJkaQUBcQQCZUgJAQJlQQMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZUgFAmVIBAJoeAkA/AcEBQJiQwIHdW5zdGFrZQkAzAgCCQDYBAEFAmR2CQDMCAIFAmNmBQNuaWwFA25pbAMJAAACBQJoeAUCaHgEAmVlCQECZHIECQDYBAEIBQJmYg10cmFuc2FjdGlvbklkCQDYBAEFAmR2BQJjZggFAmZiBmNhbGxlcgQCZEsIBQJlZQJfMQQCZEwIBQJlZQJfMgQCZHkJAQ1wYXJzZUludFZhbHVlAQgFAmVlAl85BAJkTQgFAmVlA18xMAQCZ0sJAQJjVQIFAmRLBQJkTAQCaEgDAwkBAmJpAAYJAAACBQJkeQUBbgkAAgEJAKwCAgIsR2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCZHkGAwkAAAIFAmhIBQJoSAQCaEIJAPwHBAUCYmQCBGJ1cm4JAMwIAgUCY2YFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZHYFAmNmBQNuaWwDCQAAAgUCaEIFAmhCBAJoSQkBAmVJAwkBAS0BBQJkSwkBAS0BBQJkTAAABAJnVAgFAmhJAl8xBAJleggFAmhJAl8yBAJnVQkBAmVOAgUCZUgFAmV6AwkAAAIFAmdVBQJnVQkAzggCCQDOCAIFAmdLBQJkTQUCZ1QJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZmIBE3Vuc3Rha2VBbmRHZXROb0xlc3MDAmh3AmhKAmhFBAJobgMJAQJiaQAGCQAAAgUCYnYFAW4EAmZWCQDMCAIDCQEBIQEFAmhuBgkAAgECIWdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmZiCHBheW1lbnRzAAAGCQACAQIYbm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZlYFAmZWBAJlSAkBAmVBAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJlSAUCZUgEAmh4CQD8BwQFAmJDAgd1bnN0YWtlCQDMCAIJANgEAQUCYncJAMwIAgUCaHcFA25pbAUDbmlsAwkAAAIFAmh4BQJoeAQCZWUJAQJkcgQJANgEAQgFAmZiDXRyYW5zYWN0aW9uSWQJANgEAQUCYncFAmh3CAUCZmIGY2FsbGVyBAJkSwgFAmVlAl8xBAJkTAgFAmVlAl8yBAJkTQgFAmVlA18xMAQCZ0sJAQJjVQIFAmRLBQJkTAQCaEsJAMwIAgMJAGcCBQJkSwUCaEoGCQACAQkAuQkCCQDMCAICLGFtb3VudCBhc3NldCBhbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCaEoFA25pbAIACQDMCAIDCQBnAgUCZEwFAmhFBgkAAgEJALkJAgkAzAgCAitwcmljZSBhc3NldCBhbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCaEUFA25pbAIABQNuaWwDCQAAAgUCaEsFAmhLBAJoQgkA/AcEBQJiZAIEYnVybgkAzAgCBQJodwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJidwUCaHcFA25pbAMJAAACBQJoQgUCaEIEAmhMCQECZUkDCQEBLQEFAmRLCQEBLQEFAmRMAAAEAmdUCAUCaEwCXzEEAmV6CAUCaEwCXzIEAmdVCQECZU4CBQJlSAUCZXoDCQAAAgUCZ1UFAmdVCQDOCAIJAM4IAgUCZ0sFAmRNBQJnVAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJmYgEIYWN0aXZhdGUCAmhNAmhOAwkBAiE9AgkApQgBCAUCZmIGY2FsbGVyCQClCAEFAmJkCQACAQIScGVybWlzc2lvbnMgZGVuaWVkCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFlAAUCaE0JAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFmAAUCaE4FA25pbAIHc3VjY2VzcwJmYgEKcmVmcmVzaEtMcAAEAmhPCQELdmFsdWVPckVsc2UCCQCfCAEFAmFrAAAEAmhQAwkAZwIJAGUCBQZoZWlnaHQFAmhPBQJhbgUEdW5pdAkBAmJhAQkAuQkCCQDMCAIJAKQDAQUCYW4JAMwIAgIvIGJsb2NrcyBoYXZlIG5vdCBwYXNzZWQgc2luY2UgdGhlIHByZXZpb3VzIGNhbGwFA25pbAIAAwkAAAIFAmhQBQJoUAQCZVUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAqAMBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAmFqAgEwCQECYmMBAgtpbnZhbGlkIGtMcAQCaFEJAQJlSQMAAAAAAAAEAmhSCAUCaFECXzEEAmV6CAUCaFECXzIEAmVMAwkBAiE9AgUCZVUFAmV6BQJoUgkBAmJhAQISbm90aGluZyB0byByZWZyZXNoCQCUCgIFAmVMCQCmAwEFAmV6CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmZiARxnZXRQb29sQ29uZmlnV3JhcHBlclJFQURPTkxZAAkAlAoCBQNuaWwJAQJiawACZmIBHGdldEFjY0JhbGFuY2VXcmFwcGVyUkVBRE9OTFkBAmFwCQCUCgIFA25pbAkBAmJUAQUCYXACZmIBGWNhbGNQcmljZXNXcmFwcGVyUkVBRE9OTFkDAmRjAmRkAmRoBAJkcQkBAmRnAwUCZGMFAmRkBQJkaAkAlAoCBQNuaWwJAMwIAgkApgMBCQCRAwIFAmRxAAAJAMwIAgkApgMBCQCRAwIFAmRxAAEJAMwIAgkApgMBCQCRAwIFAmRxAAIFA25pbAJmYgEUdG9YMThXcmFwcGVyUkVBRE9OTFkCAUUBRgkAlAoCBQNuaWwJAKYDAQkBAUQCBQFFBQFGAmZiARZmcm9tWDE4V3JhcHBlclJFQURPTkxZAgFJAUoJAJQKAgUDbmlsCQEBSAIJAKcDAQUBSQUBSgJmYgEeY2FsY1ByaWNlQmlnSW50V3JhcHBlclJFQURPTkxZAgJiWAJiWQkAlAoCBQNuaWwJAKYDAQkBAmJXAgkApwMBBQJiWAkApwMBBQJiWQJmYgEjZXN0aW1hdGVQdXRPcGVyYXRpb25XcmFwcGVyUkVBRE9OTFkJAmRzAmRPAmRQAmRRAmRSAmRTAmFiAmRUAmRVCQCUCgIFA25pbAkBAmROCQUCZHMFAmRPBQJkUAUCZFEFAmRSBQJkUwUCYWIFAmRUBQJkVQJmYgEjZXN0aW1hdGVHZXRPcGVyYXRpb25XcmFwcGVyUkVBRE9OTFkEAmRzAmR0AmR1AmFiBAJlZQkBAmRyBAUCZHMFAmR0BQJkdQkBEUBleHRyTmF0aXZlKDEwNjIpAQUCYWIJAJQKAgUDbmlsCQCcCgoIBQJlZQJfMQgFAmVlAl8yCAUCZWUCXzMIBQJlZQJfNAgFAmVlAl81CAUCZWUCXzYIBQJlZQJfNwkApgMBCAUCZWUCXzgIBQJlZQJfOQgFAmVlA18xMAJmYgENc3RhdHNSRUFET05MWQAEAmRpCQECYmsABAJkdgkA2QQBCQCRAwIFAmRpBQFxBAJoUwkAkQMCBQJkaQUBcgQCaFQJAJEDAgUCZGkFAXMEAmRYCQCRAwIFAmRpBQF2BAJkWQkAkQMCBQJkaQUBdwQCZGoJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkaQUBdAQCZGsJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkaQUBdQQCaFUICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCZHYJAKwCAgkArAICAgZBc3NldCAJANgEAQUCZHYCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJoVgkBAmJUAQUCaFMEAmhXCQECYlQBBQJoVAQCaFgDCQAAAgUCaFUAAAkAzAgCBQFlCQDMCAIFAWUJAMwIAgUBZQUDbmlsCQECZGcDBQJoVgUCaFcFAmhVBAJkRgAABAJoWQkBAUgCCQCRAwIFAmhYAAEFAWIEAmhaCQEBSAIJAJEDAgUCaFgAAgUBYgQCaWEJAQV2YWx1ZQEJAJoIAgUCYmQJAQJhRAEJAKUIAQUEdGhpcwkAlAoCBQNuaWwJALkJAgkAzAgCAg4lZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmhWCQDMCAIJAKQDAQUCaFcJAMwIAgkApAMBBQJoVQkAzAgCCQCkAwEFAmRGCQDMCAIJAKQDAQUCaFkJAMwIAgkApAMBBQJoWgkAzAgCCQCkAwEFAmlhBQNuaWwFAWoCZmIBIGV2YWx1YXRlUHV0QnlBbW91bnRBc3NldFJFQURPTkxZAQJkUAQCZGkJAQJiawAEAmR2CQDZBAEJAJEDAgUCZGkFAXEEAmRWCQCRAwIFAmRpBQFyBAJkdwkA2QQBBQJkVgQCZFcJAJEDAgUCZGkFAXMEAmR4CQDZBAEFAmRXBAJkagkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRpBQF0BAJkawkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRpBQF1BAJkeQkAkQMCBQJkaQUBcAQCaFUICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCZHYJAKwCAgkArAICAgZBc3NldCAJANgEAQUCZHYCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJoVgkBAmJUAQUCZFYEAmhXCQECYlQBBQJkVwQCZGUJAQFEAgUCaFYFAmRqBAJkZgkBAUQCBQJoVwUCZGsEAmRFAwkAAAIFAmhVAAAFAWUJAQJiVwIFAmRmBQJkZQQCZWIJAQFEAgUCZFAFAmRqBAJlYwkAvAIDBQJlYgUCZEUFAWQEAmRSCQEBSAIFAmVjBQJkawQCZmgJAQJkTgkCAACgwh4FAmRQBQJkdwUCZFIFAmR4AgAGBwQCZW0IBQJmaAJfMQQCaWIIBQJmaAJfMwQCZEEIBQJmaAJfNAQCZEMIBQJmaAJfNQQCZHoIBQJmaAJfNgkAlAoCBQNuaWwJALkJAgkAzAgCAhAlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCZW0JAMwIAgkApAMBCQEBSAIFAmRFBQFiCQDMCAIJAKQDAQUCZEEJAMwIAgkApAMBBQJkQwkAzAgCCQCkAwEFAmR6CQDMCAIFAmR5CQDMCAIJAKQDAQUCZFAJAMwIAgkApAMBBQJkUgUDbmlsBQFqAmZiAR9ldmFsdWF0ZVB1dEJ5UHJpY2VBc3NldFJFQURPTkxZAQJkUgQCZGkJAQJiawAEAmR2CQDZBAEJAJEDAgUCZGkFAXEEAmRWCQCRAwIFAmRpBQFyBAJkdwkA2QQBBQJkVgQCZFcJAJEDAgUCZGkFAXMEAmR4CQDZBAEFAmRXBAJkagkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRpBQF0BAJkawkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRpBQF1BAJkeQkAkQMCBQJkaQUBcAQCaFUICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCZHYJAKwCAgkArAICAgZBc3NldCAJANgEAQUCZHYCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJpYwkBAmJUAQUCZFYEAmlkCQECYlQBBQJkVwQCaWUJAQFEAgUCaWMFAmRqBAJpZgkBAUQCBQJpZAUCZGsEAmRFAwkAAAIFAmhVAAAFAWUJAQJiVwIFAmlmBQJpZQQCZWMJAQFEAgUCZFIFAmRrBAJlYgkAvAIDBQJlYwUBZAUCZEUEAmRQCQEBSAIFAmViBQJkagQCZmgJAQJkTgkCAACgwh4FAmRQBQJkdwUCZFIFAmR4AgAGBwQCZW0IBQJmaAJfMQQCaWIIBQJmaAJfMwQCZEEIBQJmaAJfNAQCZEMIBQJmaAJfNQQCZHoIBQJmaAJfNgkAlAoCBQNuaWwJALkJAgkAzAgCAhAlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCZW0JAMwIAgkApAMBCQEBSAIFAmRFBQFiCQDMCAIJAKQDAQUCZEEJAMwIAgkApAMBBQJkQwkAzAgCCQCkAwEFAmR6CQDMCAIFAmR5CQDMCAIJAKQDAQUCZFAJAMwIAgkApAMBBQJkUgUDbmlsBQFqAmZiARNldmFsdWF0ZUdldFJFQURPTkxZAgJpZwJpaAQCZWUJAQJkcgQCAAUCaWcFAmloBQR0aGlzBAJkSwgFAmVlAl8xBAJkTAgFAmVlAl8yBAJkQQgFAmVlAl81BAJkQwgFAmVlAl82BAJkeggFAmVlAl83BAJkRggFAmVlAl84BAJkeQkBDXBhcnNlSW50VmFsdWUBCAUCZWUCXzkJAJQKAgUDbmlsCQC5CQIJAMwIAgIOJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJkSwkAzAgCCQCkAwEFAmRMCQDMCAIJAKQDAQUCZEEJAMwIAgkApAMBBQJkQwkAzAgCCQCkAwEFAmR6CQDMCAIJAKYDAQUCZEYJAMwIAgkApAMBBQJkeQUDbmlsBQFqAQJpaQECaWoABAJpawQCYVEJAQJnbgADCQABAgUCYVECCkJ5dGVWZWN0b3IEAmdxBQJhUQUCZ3EDCQABAgUCYVECBFVuaXQIBQJpaQ9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgQCYVEFAmlpAwkAAQIFAmFRAgVPcmRlcgQCZVEFAmFRBAJpbAkBAmJqAAQCaW0DCQECZU0ACQCUCgIGAgAJAQJlUAEFAmVRBAJhSwgFAmltAl8xBAJhTAgFAmltAl8yBAJhTQkA9AMDCAUCZVEJYm9keUJ5dGVzCQCRAwIIBQJlUQZwcm9vZnMAAAgFAmVRD3NlbmRlclB1YmxpY0tleQQCYU4JAPQDAwgFAmVRCWJvZHlCeXRlcwkAkQMCCAUCZVEGcHJvb2ZzAAEFAmlsAwMDBQJhSwUCYU0HBQJhTgcGCQECYUoEBQJhSwUCYUwFAmFNBQJhTgMJAAECBQJhUQIUU2V0U2NyaXB0VHJhbnNhY3Rpb24EAmFWBQJhUQMJAPQDAwgFAmlpCWJvZHlCeXRlcwkAkQMCCAUCaWkGcHJvb2ZzAAAFAmlrBgQCaW4JAPYDAQkBBXZhbHVlAQgFAmFWBnNjcmlwdAQCaW8JANsEAQkBBXZhbHVlAQkAnQgCBQJiZAkBAmFGAAQCaXAJAPEHAQUEdGhpcwMJAAACBQJpbwUCaW4JAQIhPQIFAmlwBQJpbgcJAPQDAwgFAmlpCWJvZHlCeXRlcwkAkQMCCAUCaWkGcHJvb2ZzAAAFAmlr8gh5ow==", "height": 2672772, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: ECQc3rGceRVAp7qyJMF8piVrsNUyJye1CdsvFMhTZ71v Next: 3b4ojWsNE7VcM8mKqyGNYRimfDNhRmWCCmS4AhqbgRbs Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let lPdecimals = 8
5+
46 let scale8 = 100000000
57
68 let scale8BigInt = toBigInt(100000000)
1517
1618 let big2 = toBigInt(2)
1719
18-let big3 = toBigInt(3)
19-
20-let big4 = toBigInt(4)
21-
22-let slippage4D = toBigInt((scale8 - ((scale8 * 1) / scale8)))
23-
2420 let wavesString = "WAVES"
25-
26-let ampInitial = 50
27-
28-let Amult = "100"
29-
30-let Dconv = "1"
3121
3222 let SEP = "__"
3323
34-let EMPTY = ""
35-
3624 let PoolActive = 1
3725
38-let PoolPutDis = 2
26+let PoolPutDisabled = 2
3927
40-let PoolMatcherDis = 3
28+let PoolMatcherDisabled = 3
4129
4230 let PoolShutdown = 4
4331
4432 let idxPoolAddress = 1
4533
46-let idxPoolSt = 2
34+let idxPoolStatus = 2
4735
48-let idxLPAsId = 3
36+let idxPoolLPAssetId = 3
4937
50-let idxAmAsId = 4
38+let idxAmtAssetId = 4
5139
52-let idxPrAsId = 5
40+let idxPriceAssetId = 5
5341
54-let idxAmtAsDcm = 6
42+let idxAmtAssetDcm = 6
5543
56-let idxPriceAsDcm = 7
44+let idxPriceAssetDcm = 7
5745
58-let idxIAmtAsId = 8
46+let idxIAmtAssetId = 8
5947
60-let idxIPriceAsId = 9
48+let idxIPriceAssetId = 9
6149
62-let idxFactStakCntr = 1
50+let idxLPAssetDcm = 10
6351
64-let idxFactoryRestCntr = 6
52+let idxPoolAmtAssetAmt = 1
6553
66-let idxFactSlippCntr = 7
54+let idxPoolPriceAssetAmt = 2
6755
68-let idxFactGwxRewCntr = 10
56+let idxPoolLPAssetAmt = 3
6957
70-let feeDefault = fraction(10, scale8, 10000)
58+let idxFactoryStakingContract = 1
7159
72-func t1 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
60+let idxFactorySlippageContract = 7
61+
62+func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
7363
7464
75-func t1BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
65+func toX18BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
7666
7767
78-func f1 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
68+func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
7969
8070
8171 func fromX18Round (val,resultScaleMult,round) = toInt(fraction(val, toBigInt(resultScaleMult), scale18, round))
8272
8373
84-func t2 (origVal,origScaleMult) = fraction(origVal, scale18, toBigInt(origScaleMult))
74+func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
8575
8676
87-func f2 (val,resultScaleMult) = fraction(val, toBigInt(resultScaleMult), scale18)
88-
89-
90-func ts (amt,resScale,curScale) = fraction(amt, resScale, curScale)
91-
92-
93-func abs (val) = if ((zeroBigInt > val))
77+func abs (val) = if ((0 > val))
9478 then -(val)
9579 else val
9680
9882 func absBigInt (val) = if ((zeroBigInt > val))
9983 then -(val)
10084 else val
85+
86+
87+func swapContract () = "%s__swapContract"
10188
10289
10390 func fc () = "%s__factoryContract"
11299 func pl () = "%s%s__price__last"
113100
114101
115-func ph (h,t) = makeString(["%s%s%d%d__price__history", toString(h), toString(t)], SEP)
102+func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
116103
117104
118-func pau (ua,txId) = ((("%s%s%s__P__" + ua) + "__") + txId)
105+func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
119106
120107
121-func gau (ua,txId) = ((("%s%s%s__G__" + ua) + "__") + txId)
108+func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
122109
123110
124111 func aa () = "%s__amountAsset"
127114 func pa () = "%s__priceAsset"
128115
129116
130-func amp () = "%s__amp"
117+let keyFee = "%s__fee"
131118
132-
133-func keyAmpHistory (heightBlocks) = ("%s%d__amp__" + toString(heightBlocks))
134-
135-
136-func keyChangeAmpLastCall () = "%s__changeAmpLastCall"
137-
138-
139-let keyFee = "%s__fee"
119+let feeDefault = fraction(10, scale8, 10000)
140120
141121 let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
142122
143-let keyDLp = makeString(["%s", "dLp"], SEP)
123+let keyKLp = makeString(["%s", "kLp"], SEP)
144124
145-let keyDLpRefreshedHeight = makeString(["%s", "dLpRefreshedHeight"], SEP)
125+let keyKLpRefreshedHeight = makeString(["%s", "kLpRefreshedHeight"], SEP)
146126
147-let keyDLpRefreshDelay = makeString(["%s", "refreshDLpDelay"], SEP)
127+let keyKLpRefreshDelay = makeString(["%s", "refreshKLpDelay"], SEP)
148128
149-let dLpRefreshDelayDefault = 30
129+let kLpRefreshDelayDefault = 30
150130
151-let dLpRefreshDelay = valueOrElse(getInteger(this, keyDLpRefreshDelay), dLpRefreshDelayDefault)
131+let kLpRefreshDelay = valueOrElse(getInteger(this, keyKLpRefreshDelay), kLpRefreshDelayDefault)
152132
153-func fcfg () = "%s__factoryConfig"
133+func keyAdditionalBalance (assetId) = makeString(["%s%s", "stakedBalance", assetId], SEP)
154134
155135
156-func mtpk () = "%s%s__matcher__publicKey"
136+func keyStakingAssetBalance (assetId) = makeString(["%s%s", "shareAssetBalance", assetId], SEP)
157137
158138
159-func pc (iAmtAs,iPrAs) = (((("%d%d%s__" + iAmtAs) + "__") + iPrAs) + "__config")
139+func getAdditionalBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyAdditionalBalance(assetId)), 0)
160140
161141
162-func mba (bAStr) = ("%s%s%s__mappings__baseAsset2internalId__" + bAStr)
142+func getStakingAssetBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyStakingAssetBalance(assetId)), 0)
163143
164144
165-func aps () = "%s__shutdown"
145+func keyFactoryConfig () = "%s__factoryConfig"
166146
167147
168-func keyAllowedLpStableScriptHash () = "%s__allowedLpStableScriptHash"
148+func keyMatcherPub () = "%s%s__matcher__publicKey"
169149
170150
171-func keyFeeCollectorAddress () = "%s__feeCollectorAddress"
151+func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
172152
153+
154+func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
155+
156+
157+func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
158+
159+
160+func keyAllPoolsShutdown () = "%s__shutdown"
161+
162+
163+func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
164+
165+
166+func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
167+
168+
169+let keyFeeCollectorAddress = "%s__feeCollectorAddress"
173170
174171 func keySkipOrderValidation (poolAddress) = ("%s%s__skipOrderValidation__" + poolAddress)
175172
201198 }
202199
203200
204-func strf (addr,key) = valueOrErrorMessage(getString(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
201+func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
205202
206203
207-func intf (addr,key) = valueOrErrorMessage(getInteger(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
204+func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
208205
209206
210-func throwErr (msg) = throw(makeString(["lp_stable.ride:", msg], " "))
207+func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
211208
212209
213-func fmtErr (msg) = makeString(["lp_stable.ride:", msg], " ")
210+func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
214211
215212
216-let fca = addressFromStringValue(strf(this, fc()))
213+let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
214+
215+let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
217216
218217 let inFee = {
219- let @ = invoke(fca, "getInFeeREADONLY", [toString(this)], nil)
218+ let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
220219 if ($isInstanceOf(@, "Int"))
221220 then @
222221 else throw(($getType(@) + " couldn't be cast to Int"))
223222 }
224223
225224 let outFee = {
226- let @ = invoke(fca, "getOutFeeREADONLY", [toString(this)], nil)
225+ let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
227226 if ($isInstanceOf(@, "Int"))
228227 then @
229228 else throw(($getType(@) + " couldn't be cast to Int"))
230229 }
231230
232-let A = strf(this, amp())
233-
234-func igs () = valueOrElse(getBoolean(fca, aps()), false)
231+func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
235232
236233
237-func mp () = fromBase58String(strf(fca, mtpk()))
234+func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
238235
239236
240-let feeCollectorAddress = addressFromStringValue(strf(fca, keyFeeCollectorAddress()))
241-
242-func gpc () = {
243- let amtAs = strf(this, aa())
244- let priceAs = strf(this, pa())
245- let iPriceAs = intf(fca, mba(priceAs))
246- let iAmtAs = intf(fca, mba(amtAs))
247- split(strf(fca, pc(toString(iAmtAs), toString(iPriceAs))), SEP)
237+func getPoolConfig () = {
238+ let amtAsset = getStringOrFail(this, aa())
239+ let priceAsset = getStringOrFail(this, pa())
240+ let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
241+ let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
242+ split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
248243 }
249244
250245
258253 else toBase58String(value(input))
259254
260255
261-func parsePoolConfig (poolConfig) = $Tuple7(addressFromStringValue(poolConfig[idxPoolAddress]), parseIntValue(poolConfig[idxPoolSt]), fromBase58String(poolConfig[idxLPAsId]), parseAssetId(poolConfig[idxAmAsId]), parseAssetId(poolConfig[idxPrAsId]), parseIntValue(poolConfig[idxAmtAsDcm]), parseIntValue(poolConfig[idxPriceAsDcm]))
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]))
262257
263258
264-let poolConfigParsed = parsePoolConfig(gpc())
259+let poolConfigParsed = parsePoolConfig(getPoolConfig())
265260
266-let $t086088794 = poolConfigParsed
261+let $t095299695 = poolConfigParsed
267262
268-let cfgPoolAddress = $t086088794._1
263+let cfgPoolAddress = $t095299695._1
269264
270-let cfgPoolStatus = $t086088794._2
265+let cfgPoolStatus = $t095299695._2
271266
272-let cfgLpAssetId = $t086088794._3
267+let cfgLpAssetId = $t095299695._3
273268
274-let cfgAmountAssetId = $t086088794._4
269+let cfgAmountAssetId = $t095299695._4
275270
276-let cfgPriceAssetId = $t086088794._5
271+let cfgPriceAssetId = $t095299695._5
277272
278-let cfgAmountAssetDecimals = $t086088794._6
273+let cfgAmountAssetDecimals = $t095299695._6
279274
280-let cfgPriceAssetDecimals = $t086088794._7
275+let cfgPriceAssetDecimals = $t095299695._7
281276
282-func gfc () = split(strf(fca, fcfg()), SEP)
277+func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
283278
284279
285-let factoryConfig = gfc()
280+let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
286281
287-let stakingContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactStakCntr]), "Invalid staking contract address")
282+let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
288283
289-let slipageContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactSlippCntr]), "Invalid slipage contract address")
290-
291-let gwxContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactGwxRewCntr]), "Invalid gwx contract address")
292-
293-let restContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactoryRestCntr]), "Invalid gwx contract address")
294-
295-func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slipByUser,slippageReal,txHeight,txTimestamp,slipageAmAmt,slipagePrAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slipByUser), toString(slippageReal), toString(txHeight), toString(txTimestamp), toString(slipageAmAmt), toString(slipagePrAmt)], SEP)
284+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)
296285
297286
298287 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)
299288
300289
301-func getAccBalance (assetId) = if ((assetId == "WAVES"))
302- then wavesBalance(this).available
303- else assetBalance(this, fromBase58String(assetId))
304-
305-
306-func cpbi (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
307-
308-
309-func cpbir (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
310-
311-
312-func vad (A1,A2,slippage) = {
313- let diff = fraction((A1 - A2), scale8BigInt, A2)
314- let pass = ((slippage - abs(diff)) > zeroBigInt)
315- if (!(pass))
316- then throw(("Big slpg: " + toString(diff)))
317- else $Tuple2(pass, min([A1, A2]))
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])
318296 }
319297
320298
321-func vd (D1,D0,slpg) = {
322- let diff = fraction(D0, scale8BigInt, D1)
323- let fail = (slpg > diff)
324- if (if (fail)
325- then true
326- else (D0 > D1))
327- then throw(((((((toString(D0) + " ") + toString(D1)) + " ") + toString(diff)) + " ") + toString(slpg)))
328- else fail
299+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.")
329315 }
330316
331317
332-func pcp (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
333- let amtAsAmtX18 = t1(amAmt, amAssetDcm)
334- let prAsAmtX18 = t1(prAmt, prAssetDcm)
335- cpbi(prAsAmtX18, amtAsAmtX18)
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+ }
475+
476+
477+func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
478+ let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
479+ let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
480+ calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
336481 }
337482
338483
339484 func calcPrices (amAmt,prAmt,lpAmt) = {
340- let amtAsDcm = cfgAmountAssetDecimals
341- let prAsDcm = cfgPriceAssetDecimals
342- let priceX18 = pcp(amtAsDcm, prAsDcm, amAmt, prAmt)
343- let amAmtX18 = t1(amAmt, amtAsDcm)
344- let prAmtX18 = t1(prAmt, prAsDcm)
345- let lpAmtX18 = t1(lpAmt, scale8)
346- let lpPrInAmAsX18 = cpbi(amAmtX18, lpAmtX18)
347- let lpPrInPrAsX18 = cpbi(prAmtX18, lpAmtX18)
348-[priceX18, lpPrInAmAsX18, lpPrInPrAsX18]
485+ let cfg = getPoolConfig()
486+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
487+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
488+ let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
489+ let amAmtX18 = toX18(amAmt, amtAssetDcm)
490+ let prAmtX18 = toX18(prAmt, priceAssetDcm)
491+ let lpAmtX18 = toX18(lpAmt, scale8)
492+ let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
493+ let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
494+[priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
349495 }
350496
351497
352498 func calculatePrices (amAmt,prAmt,lpAmt) = {
353- let p = calcPrices(amAmt, prAmt, lpAmt)
354-[f1(p[0], scale8), f1(p[1], scale8), f1(p[2], scale8)]
499+ let prices = calcPrices(amAmt, prAmt, lpAmt)
500+[fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
501+ }
502+
503+
504+func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
505+ let cfg = getPoolConfig()
506+ let lpAssetId = cfg[idxPoolLPAssetId]
507+ let amAssetId = cfg[idxAmtAssetId]
508+ let prAssetId = cfg[idxPriceAssetId]
509+ let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
510+ let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
511+ let poolStatus = cfg[idxPoolStatus]
512+ let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
513+ if ((lpAssetId != pmtAssetId))
514+ then throw("Invalid asset passed.")
515+ else {
516+ let amBalance = getAccBalance(amAssetId)
517+ let amBalanceX18 = toX18(amBalance, amAssetDcm)
518+ let prBalance = getAccBalance(prAssetId)
519+ let prBalanceX18 = toX18(prBalance, prAssetDcm)
520+ let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
521+ let curPrice = fromX18(curPriceX18, scale8)
522+ let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
523+ let lpEmissionX18 = toX18(lpEmission, scale8)
524+ let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
525+ let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
526+ let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
527+ let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
528+ let state = if ((txId58 == ""))
529+ then nil
530+ else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
531+ then unit
532+ else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
533+ then unit
534+ 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)]
535+ $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
536+ }
537+ }
538+
539+
540+func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
541+ let cfg = getPoolConfig()
542+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
543+ let amAssetIdStr = cfg[idxAmtAssetId]
544+ let prAssetIdStr = cfg[idxPriceAssetId]
545+ let iAmtAssetId = cfg[idxIAmtAssetId]
546+ let iPriceAssetId = cfg[idxIPriceAssetId]
547+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
548+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
549+ let poolStatus = cfg[idxPoolStatus]
550+ let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
551+ let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
552+ let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
553+ if (if ((amAssetIdStr != inAmAssetIdStr))
554+ then true
555+ else (prAssetIdStr != inPrAssetIdStr))
556+ then throw("Invalid amt or price asset passed.")
557+ else {
558+ let amBalance = if (isEvaluate)
559+ then getAccBalance(amAssetIdStr)
560+ else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
561+ let prBalance = if (isEvaluate)
562+ then getAccBalance(prAssetIdStr)
563+ else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
564+ let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
565+ let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
566+ let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
567+ let amBalanceX18 = toX18(amBalance, amtAssetDcm)
568+ let prBalanceX18 = toX18(prBalance, priceAssetDcm)
569+ let res = if ((lpEmission == 0))
570+ then {
571+ let curPriceX18 = zeroBigInt
572+ let slippageX18 = zeroBigInt
573+ let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
574+ $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
575+ }
576+ else {
577+ let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
578+ let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
579+ let slippageToleranceX18 = toX18(slippageTolerance, scale8)
580+ if (if ((curPriceX18 != zeroBigInt))
581+ then (slippageX18 > slippageToleranceX18)
582+ else false)
583+ then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
584+ else {
585+ let lpEmissionX18 = toX18(lpEmission, scale8)
586+ let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
587+ let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
588+ let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
589+ then $Tuple2(amViaPrX18, inPrAssetAmtX18)
590+ else $Tuple2(inAmAssetAmtX18, prViaAmX18)
591+ let expAmtAssetAmtX18 = expectedAmts._1
592+ let expPriceAssetAmtX18 = expectedAmts._2
593+ let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
594+ $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
595+ }
596+ }
597+ let calcLpAmt = res._1
598+ let calcAmAssetPmt = res._2
599+ let calcPrAssetPmt = res._3
600+ let curPrice = fromX18(res._4, scale8)
601+ let slippageCalc = fromX18(res._5, scale8)
602+ if ((0 >= calcLpAmt))
603+ then throw("Invalid calculations. LP calculated is less than zero.")
604+ else {
605+ let emitLpAmt = if (!(emitLp))
606+ then 0
607+ else calcLpAmt
608+ let amDiff = (inAmAssetAmt - calcAmAssetPmt)
609+ let prDiff = (inPrAssetAmt - calcPrAssetPmt)
610+ 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))]
611+ $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
612+ }
613+ }
614+ }
615+
616+
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+
654+func validateMatcherOrderAllowed (order) = {
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
664+ if (if (if (isGlobalShutdown())
665+ then true
666+ else (cfgPoolStatus == PoolMatcherDisabled))
667+ then true
668+ else (cfgPoolStatus == PoolShutdown))
669+ then throw("Exchange operations disabled")
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+ }
683+ }
684+
685+
686+func commonGet (i) = if ((size(i.payments) != 1))
687+ then throw("exactly 1 payment is expected")
688+ else {
689+ let pmt = value(i.payments[0])
690+ let pmtAssetId = value(pmt.assetId)
691+ let pmtAmt = pmt.amount
692+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
693+ let outAmAmt = res._1
694+ let outPrAmt = res._2
695+ let poolStatus = parseIntValue(res._9)
696+ let state = res._10
697+ if (if (isGlobalShutdown())
698+ then true
699+ else (poolStatus == PoolShutdown))
700+ then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
701+ else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
702+ }
703+
704+
705+func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
706+ then throw("exactly 2 payments are expected")
707+ else {
708+ let amAssetPmt = value(i.payments[0])
709+ let prAssetPmt = value(i.payments[1])
710+ let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
711+ let poolStatus = parseIntValue(estPut._8)
712+ if (if (if (isGlobalShutdown())
713+ then true
714+ else (poolStatus == PoolPutDisabled))
715+ then true
716+ else (poolStatus == PoolShutdown))
717+ then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
718+ else estPut
719+ }
720+
721+
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.")
355737 }
356738
357739
363745 }
364746
365747
366-func getD (xp) = {
367- let xp0 = xp[0]
368- let xp1 = xp[1]
369- let s = (xp0 + xp1)
370- if ((s == big0))
371- then big0
372- else {
373- let a = parseIntValue(A)
374- let ann = (a * 2)
375- let p = fraction(xp0, xp1, big1)
376- let xp0_xp1_n_n = fraction(p, big4, big1)
377- let ann_s = fraction(toBigInt(ann), s, big1)
378- let ann_1 = toBigInt((ann - 1))
379- func calcDNext (d) = {
380- let dd = fraction(d, d, big1)
381- let ddd = fraction(dd, d, big1)
382- let dp = fraction(ddd, big1, xp0_xp1_n_n)
383- fraction((ann_s + fraction(dp, big2, big1)), d, (fraction(ann_1, d, big1) + fraction(big3, dp, big1)))
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)
384803 }
385-
386- func calc (acc,i) = if (acc._2)
387- then acc
388- else {
389- let d = acc._1
390- let dNext = calcDNext(d)
391- let dDiffRaw = (dNext - value(d))
392- let dDiff = if ((big0 > dDiffRaw))
393- then -(dDiffRaw)
394- else dDiffRaw
395- if ((big1 >= dDiff))
396- then $Tuple2(dNext, true)
397- else $Tuple2(dNext, false)
398- }
399-
400- let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
401- let $t01329913347 = {
402- let $l = arr
403- let $s = size($l)
404- let $acc0 = $Tuple2(s, false)
405- func $f0_1 ($a,$i) = if (($i >= $s))
406- then $a
407- else calc($a, $l[$i])
408-
409- func $f0_2 ($a,$i) = if (($i >= $s))
410- then $a
411- else throw("List size exceeds 17")
412-
413- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17)
414- }
415- let d = $t01329913347._1
416- let found = $t01329913347._2
417- if (found)
418- then d
419- else throw(("D calculation error, D = " + toString(d)))
420- }
421- }
422-
423-
424-func ego (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
425- let lpId = cfgLpAssetId
426- let amId = toBase58String(value(cfgAmountAssetId))
427- let prId = toBase58String(value(cfgPriceAssetId))
428- let amDcm = cfgAmountAssetDecimals
429- let prDcm = cfgPriceAssetDecimals
430- let sts = toString(cfgPoolStatus)
431- let lpEmiss = valueOrErrorMessage(assetInfo(lpId), "Wrong LP id").quantity
432- if ((toBase58String(lpId) != pmtAssetId))
433- then throw("Wrong pmt asset")
434- else {
435- let amBalance = getAccBalance(amId)
436- let amBalanceX18 = t1(amBalance, amDcm)
437- let prBalance = getAccBalance(prId)
438- let prBalanceX18 = t1(prBalance, prDcm)
439- let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
440- let curPrice = f1(curPriceX18, scale8)
441- let pmtLpAmtX18 = t1(pmtLpAmt, scale8)
442- let lpEmissX18 = t1(lpEmiss, scale8)
443- let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissX18)
444- let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissX18)
445- let outAmAmt = fromX18Round(outAmAmtX18, amDcm, FLOOR)
446- let outPrAmt = fromX18Round(outPrAmtX18, prDcm, FLOOR)
447- let state = if ((txId58 == ""))
448- then nil
449- else [ScriptTransfer(userAddress, outAmAmt, if ((amId == "WAVES"))
450- then unit
451- else fromBase58String(amId)), ScriptTransfer(userAddress, outPrAmt, if ((prId == "WAVES"))
452- then unit
453- else fromBase58String(prId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
454- $Tuple10(outAmAmt, outPrAmt, amId, prId, amBalance, prBalance, lpEmiss, curPriceX18, sts, state)
455- }
456- }
457-
458-
459-func epo (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEval,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
460- let lpId = cfgLpAssetId
461- let amIdStr = toBase58String(value(cfgAmountAssetId))
462- let prIdStr = toBase58String(value(cfgPriceAssetId))
463- let amtDcm = cfgAmountAssetDecimals
464- let priceDcm = cfgPriceAssetDecimals
465- let sts = toString(cfgPoolStatus)
466- let lpEm = valueOrErrorMessage(assetInfo(lpId), "Wr lp as").quantity
467- let amBalance = if (isEval)
468- then getAccBalance(amIdStr)
469- else if (if (isOneAsset)
470- then (pmtId == amIdStr)
471- else false)
472- then (getAccBalance(amIdStr) - pmtAmt)
473- else if (isOneAsset)
474- then getAccBalance(amIdStr)
475- else (getAccBalance(amIdStr) - inAmAmt)
476- let prBalance = if (isEval)
477- then getAccBalance(prIdStr)
478- else if (if (isOneAsset)
479- then (pmtId == prIdStr)
480- else false)
481- then (getAccBalance(prIdStr) - pmtAmt)
482- else if (isOneAsset)
483- then getAccBalance(prIdStr)
484- else (getAccBalance(prIdStr) - inPrAmt)
485- let inAmAssetAmtX18 = t1(inAmAmt, amtDcm)
486- let inPrAssetAmtX18 = t1(inPrAmt, priceDcm)
487- let userPriceX18 = cpbi(inPrAssetAmtX18, inAmAssetAmtX18)
488- let amBalanceX18 = t1(amBalance, amtDcm)
489- let prBalanceX18 = t1(prBalance, priceDcm)
490- let D0 = getD([amBalanceX18, prBalanceX18])
491- let r = if ((lpEm == 0))
492- then {
493- let D1 = getD([(amBalanceX18 + inAmAssetAmtX18), (prBalanceX18 + inPrAssetAmtX18)])
494- let checkD = if ((D1 > D0))
495- then true
496- else throw("D1 should be greater than D0")
497- if ((checkD == checkD))
498- then {
499- let curPriceX18 = zeroBigInt
500- let slippageX18 = zeroBigInt
501- let lpAmtX18 = D1
502- $Tuple5(f1(lpAmtX18, scale8), f1(inAmAssetAmtX18, amtDcm), f1(inPrAssetAmtX18, priceDcm), cpbi((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
503- }
504- else throw("Strict value is not equal to itself.")
505- }
506- else {
507- let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
508- let slippageRealX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
509- let slippageX18 = t1(slippage, scale8)
510- if (if (if (validateSlippage)
511- then (curPriceX18 != zeroBigInt)
512- else false)
513- then (slippageRealX18 > slippageX18)
514- else false)
515- then throw(((("Price slippage " + toString(slippageRealX18)) + " > ") + toString(slippageX18)))
516- else {
517- let lpEmissionX18 = t1(lpEm, scale8)
518- let prViaAmX18 = fraction(inAmAssetAmtX18, cpbir(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
519- let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, cpbir(prBalanceX18, amBalanceX18, FLOOR), CEILING)
520- let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
521- then $Tuple2(amViaPrX18, inPrAssetAmtX18)
522- else $Tuple2(inAmAssetAmtX18, prViaAmX18)
523- let expAmtAssetAmtX18 = expectedAmts._1
524- let expPriceAssetAmtX18 = expectedAmts._2
525- let D1 = getD([(amBalanceX18 + expAmtAssetAmtX18), (prBalanceX18 + expPriceAssetAmtX18)])
526- let checkD = if ((D1 > D0))
527- then true
528- else throw("D1 should be greater than D0")
529- if ((checkD == checkD))
530- then {
531- let lpAmtX18 = fraction(lpEmissionX18, (D1 - D0), D0)
532- $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceDcm, CEILING), curPriceX18, slippageX18)
533- }
534- else throw("Strict value is not equal to itself.")
535- }
536- }
537- let calcLpAmt = r._1
538- let calcAmAssetPmt = r._2
539- let calcPrAssetPmt = r._3
540- let curPrice = f1(r._4, scale8)
541- let slippageCalc = f1(r._5, scale8)
542- if ((0 >= calcLpAmt))
543- then throw("LP <= 0")
544- else {
545- let emitLpAmt = if (!(emitLp))
546- then 0
547- else calcLpAmt
548- let amDiff = (inAmAmt - calcAmAssetPmt)
549- let prDiff = (inPrAmt - calcPrAssetPmt)
550- let $t02110921454 = if (if (isOneAsset)
551- then (pmtId == amIdStr)
552- else false)
553- then $Tuple2(pmtAmt, 0)
554- else if (if (isOneAsset)
555- then (pmtId == prIdStr)
556- else false)
557- then $Tuple2(0, pmtAmt)
558- else $Tuple2(calcAmAssetPmt, calcPrAssetPmt)
559- let writeAmAmt = $t02110921454._1
560- let writePrAmt = $t02110921454._2
561- let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(writeAmAmt, writePrAmt, emitLpAmt, curPrice, slippage, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
562- $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEm, lpId, sts, commonState, amDiff, prDiff, inAmId, inPrId)
563- }
564- }
565-
566-
567-func getYD (xp,i,D) = {
568- let n = big2
569- let x = xp[if ((i == 0))
570- then 1
571- else 0]
572- let aPrecision = parseBigIntValue(Amult)
573- let a = (parseBigIntValue(A) * aPrecision)
574- let s = x
575- let ann = (a * n)
576- let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
577- let b = ((s + ((D * aPrecision) / ann)) - D)
578- func calc (acc,cur) = {
579- let $t02264922669 = acc
580- let y = $t02264922669._1
581- let found = $t02264922669._2
582- if ((found != unit))
583- then acc
584- else {
585- let yNext = (((y * y) + c) / ((big2 * y) + b))
586- let yDiff = absBigInt((yNext - value(y)))
587- if ((big1 >= yDiff))
588- then $Tuple2(yNext, cur)
589- else $Tuple2(yNext, unit)
590- }
591- }
592-
593- let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
594- let $t02297623023 = {
595- let $l = arr
596- let $s = size($l)
597- let $acc0 = $Tuple2(D, unit)
598- func $f0_1 ($a,$i) = if (($i >= $s))
599- then $a
600- else calc($a, $l[$i])
601-
602- func $f0_2 ($a,$i) = if (($i >= $s))
603- then $a
604- else throw("List size exceeds 15")
605-
606- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
607- }
608- let y = $t02297623023._1
609- let found = $t02297623023._2
610- if ((found != unit))
611- then y
612- else throw(("Y calculation error, Y = " + toString(y)))
613- }
614-
615-
616-func calcDLp (amountBalance,priceBalance,lpEmission) = {
617- let updatedDLp = fraction(getD([t1BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals)), t1BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))]), scale18, lpEmission)
618- if ((lpEmission == big0))
619- then big0
620- else updatedDLp
621- }
622-
623-
624-func calcCurrentDLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
625- let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
626- let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
627- let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
628- let currentDLp = calcDLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
629- currentDLp
630- }
631-
632-
633-func refreshDLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
634- let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
635- let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
636- let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
637- let updatedDLp = calcDLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
638- let actions = [IntegerEntry(keyDLpRefreshedHeight, height), StringEntry(keyDLp, toString(updatedDLp))]
639- $Tuple2(actions, updatedDLp)
640- }
641-
642-
643-func validateUpdatedDLp (oldDLp,updatedDLp) = if ((updatedDLp >= oldDLp))
644- then true
645- else throwErr("updated DLp lower than current DLp")
646-
647-
648-func validateMatcherOrderAllowed (order) = {
649- let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
650- let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
651- let amountAssetAmount = order.amount
652- let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
653- let $t02522125433 = if ((order.orderType == Buy))
654- then $Tuple2(amountAssetAmount, -(priceAssetAmount))
655- else $Tuple2(-(amountAssetAmount), priceAssetAmount)
656- let amountAssetBalanceDelta = $t02522125433._1
657- let priceAssetBalanceDelta = $t02522125433._2
658- if (if (if (igs())
659- then true
660- else (cfgPoolStatus == PoolMatcherDis))
661- then true
662- else (cfgPoolStatus == PoolShutdown))
663- then throw("Admin blocked")
664- else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
665- then true
666- else (order.assetPair.priceAsset != cfgPriceAssetId))
667- then throw("Wr assets")
668- else {
669- let dLp = parseBigIntValue(valueOrElse(getString(this, keyDLp), "0"))
670- let $t02577525875 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
671- let unusedActions = $t02577525875._1
672- let dLpNew = $t02577525875._2
673- let isOrderValid = (dLpNew >= dLp)
674- let info = makeString(["dLp=", toString(dLp), " dLpNew=", toString(dLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
675- $Tuple2(isOrderValid, info)
676- }
677- }
678-
679-
680-func cg (i) = if ((size(i.payments) != 1))
681- then throw("1 pmnt exp")
682- else {
683- let pmt = value(i.payments[0])
684- let pmtAssetId = value(pmt.assetId)
685- let pmtAmt = pmt.amount
686- let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
687- let outAmAmt = r._1
688- let outPrAmt = r._2
689- let sts = parseIntValue(r._9)
690- let state = r._10
691- if (if (igs())
692- then true
693- else (sts == PoolShutdown))
694- then throw(("Admin blocked: " + toString(sts)))
695- else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
696- }
697-
698-
699-func cp (caller,txId,amAsPmt,prAsPmt,slippage,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
700- let r = epo(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, (txId == ""), emitLp, isOneAsset, validateSlippage, pmtAmt, pmtId)
701- let sts = parseIntValue(r._8)
702- if (if (if (igs())
703- then true
704- else (sts == PoolPutDis))
705- then true
706- else (sts == PoolShutdown))
707- then throw(("Blocked:" + toString(sts)))
708- else r
709- }
710-
711-
712-func calcPutOneTkn (pmtAmtRaw,pmtAssetId,userAddress,txId,withTakeFee) = {
713- let amId = toBase58String(value(cfgAmountAssetId))
714- let prId = toBase58String(value(cfgPriceAssetId))
715- let lpId = cfgLpAssetId
716- let amtDcm = cfgAmountAssetDecimals
717- let priceDcm = cfgPriceAssetDecimals
718- let lpAssetEmission = toBigInt(valueOrErrorMessage(assetInfo(lpId), "invalid lp asset").quantity)
719- let chechEmission = if ((lpAssetEmission > big0))
720- then true
721- else throw("initial deposit requires all coins")
722- if ((chechEmission == chechEmission))
723- then {
724- let amBalance = getAccBalance(amId)
725- let prBalance = getAccBalance(prId)
726- let $t02853128993 = if ((txId == ""))
727- then $Tuple2(amBalance, prBalance)
728- else if ((pmtAssetId == amId))
729- then if ((pmtAmtRaw > amBalance))
730- then throw("invalid payment amount")
731- else $Tuple2((amBalance - pmtAmtRaw), prBalance)
732- else if ((pmtAssetId == prId))
733- then if ((pmtAmtRaw > prBalance))
734- then throw("invalid payment amount")
735- else $Tuple2(amBalance, (prBalance - pmtAmtRaw))
736- else throw("wrong pmtAssetId")
737- let amBalanceOld = $t02853128993._1
738- let prBalanceOld = $t02853128993._2
739- let $t02899929175 = if ((pmtAssetId == amId))
740- then $Tuple2(pmtAmtRaw, 0)
741- else if ((pmtAssetId == prId))
742- then $Tuple2(0, pmtAmtRaw)
743- else throw("invalid payment")
744- let amAmountRaw = $t02899929175._1
745- let prAmountRaw = $t02899929175._2
746- let $t02917929433 = if (withTakeFee)
747- then $Tuple3(takeFee(amAmountRaw, inFee)._1, takeFee(prAmountRaw, inFee)._1, takeFee(pmtAmtRaw, inFee)._2)
748- else $Tuple3(amAmountRaw, prAmountRaw, 0)
749- let amAmount = $t02917929433._1
750- let prAmount = $t02917929433._2
751- let feeAmount = $t02917929433._3
752- let amBalanceNew = (amBalanceOld + amAmount)
753- let prBalanceNew = (prBalanceOld + prAmount)
754- let D0 = getD([t1(amBalanceOld, cfgAmountAssetDecimals), t1(prBalanceOld, cfgPriceAssetDecimals)])
755- let D1 = getD([t1(amBalanceNew, cfgAmountAssetDecimals), t1(prBalanceNew, cfgPriceAssetDecimals)])
756- let checkD = if ((D1 > D0))
757- then true
758- else throw()
759- if ((checkD == checkD))
760- then {
761- let lpAmount = fraction(lpAssetEmission, (D1 - D0), D0, FLOOR)
762- let curPrice = f1(cpbi(t1(prBalanceNew, priceDcm), t1(amBalanceNew, amtDcm)), scale8)
763- let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId), dataPutActionInfo(amAmountRaw, prAmountRaw, toInt(lpAmount), curPrice, 0, 0, height, lastBlock.timestamp, 0, 0))]
764- let poolProportion = fraction(prBalanceOld, scale8, amBalanceOld)
765- let amountAssetPart = fraction(pmtAmtRaw, scale8, (poolProportion + scale8))
766- let priceAssetPart = (pmtAmtRaw - amountAssetPart)
767- let lpAmtBoth = fraction(lpAssetEmission, toBigInt(priceAssetPart), toBigInt(prBalanceOld))
768- let bonus = toInt(fraction((lpAmount - lpAmtBoth), scale8BigInt, lpAmtBoth))
769- $Tuple4(toInt(lpAmount), commonState, feeAmount, bonus)
770- }
771- else throw("Strict value is not equal to itself.")
804+ $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
772805 }
773806 else throw("Strict value is not equal to itself.")
774807 }
775808
776809
777-func getOneTknV2Internal (outAssetId,minOutAmount,payments,caller,originCaller,transactionId) = {
778- let lpId = toBase58String(value(cfgLpAssetId))
779- let amId = toBase58String(value(cfgAmountAssetId))
780- let prId = toBase58String(value(cfgPriceAssetId))
781- let amDecimals = cfgAmountAssetDecimals
782- let prDecimals = cfgPriceAssetDecimals
783- let poolStatus = cfgPoolStatus
784- let userAddress = if ((caller == restContract))
785- then originCaller
786- else caller
787- let pmt = value(payments[0])
788- let pmtAssetId = value(pmt.assetId)
789- let pmtAmt = pmt.amount
790- let currentDLp = calcCurrentDLp(big0, big0, big0)
791- if ((currentDLp == currentDLp))
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))
792819 then {
793- let txId58 = toBase58String(transactionId)
794- if ((lpId != toBase58String(pmtAssetId)))
795- then throw("Wrong LP")
796- else {
797- let amBalance = getAccBalance(amId)
798- let prBalance = getAccBalance(prId)
799- let $t03154531656 = {
800- let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, pmtAmt], nil)
801- if ($isInstanceOf(@, "(Int, Int)"))
802- then @
803- else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
804- }
805- if (($t03154531656 == $t03154531656))
806- then {
807- let feeAmount = $t03154531656._2
808- let totalGet = $t03154531656._1
809- let totalAmount = if (if ((minOutAmount > 0))
810- then (minOutAmount > totalGet)
811- else false)
812- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
813- else totalGet
814- let $t03184632153 = if ((outAssetId == amId))
815- then $Tuple4(totalAmount, 0, ((amBalance - totalAmount) - feeAmount), prBalance)
816- else if ((outAssetId == prId))
817- then $Tuple4(0, totalAmount, amBalance, ((prBalance - totalAmount) - feeAmount))
818- else throw("invalid out asset id")
819- let outAm = $t03184632153._1
820- let outPr = $t03184632153._2
821- let amBalanceNew = $t03184632153._3
822- let prBalanceNew = $t03184632153._4
823- let curPrX18 = cpbi(t1(prBalanceNew, prDecimals), t1(amBalanceNew, amDecimals))
824- let curPr = f1(curPrX18, scale8)
825- let outAssetIdOrWaves = if ((outAssetId == "WAVES"))
826- then unit
827- else fromBase58String(outAssetId)
828- let sendFeeToMatcher = if ((feeAmount > 0))
829- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetIdOrWaves)]
830- else nil
831- let state = ([ScriptTransfer(userAddress, totalAmount, outAssetIdOrWaves), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, pmtAmt, curPr, height, lastBlock.timestamp)), IntegerEntry(pl(), curPr), IntegerEntry(ph(height, lastBlock.timestamp), curPr)] ++ sendFeeToMatcher)
832- if ((state == state))
833- then {
834- let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
835- if ((burn == burn))
836- then {
837- let $t03293833288 = {
838- let feeAmountForCalc = if ((this == feeCollectorAddress))
839- then 0
840- else feeAmount
841- let outInAmountAsset = if ((parseAssetId(outAssetId) == cfgAmountAssetId))
842- then true
843- else false
844- if (outInAmountAsset)
845- then $Tuple2(-((totalGet + feeAmountForCalc)), 0)
846- else $Tuple2(0, -((totalGet + feeAmountForCalc)))
847- }
848- let amountAssetBalanceDelta = $t03293833288._1
849- let priceAssetBalanceDelta = $t03293833288._2
850- let $t03329133399 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
851- let refreshDLpActions = $t03329133399._1
852- let updatedDLp = $t03329133399._2
853- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
854- if ((isUpdatedDLpValid == isUpdatedDLpValid))
855- then $Tuple2((state ++ refreshDLpActions), totalAmount)
856- else throw("Strict value is not equal to itself.")
857- }
858- else throw("Strict value is not equal to itself.")
859- }
860- else throw("Strict value is not equal to itself.")
861- }
862- else throw("Strict value is not equal to itself.")
863- }
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)
864862 }
865863 else throw("Strict value is not equal to itself.")
866864 }
879877 }
880878
881879
882-let pd = throw("Permission denied")
883-
884880 func isManager (i) = match managerPublicKeyOrUnit() {
885881 case pk: ByteVector =>
886882 (i.callerPublicKey == pk)
891887 }
892888
893889
894-func mustManager (i) = match managerPublicKeyOrUnit() {
895- case pk: ByteVector =>
896- if ((i.callerPublicKey == pk))
897- then true
898- else pd
899- case _: Unit =>
900- if ((i.caller == this))
901- then true
902- else pd
903- case _ =>
904- throw("Match error")
905-}
906-
907-
908-func getY (isReverse,D,poolAmountInBalance) = {
909- let poolConfig = gpc()
910- let amId = poolConfig[idxAmAsId]
911- let prId = poolConfig[idxPrAsId]
912- let n = big2
913- let aPrecision = parseBigIntValue(Amult)
914- let a = (parseBigIntValue(A) * aPrecision)
915- let xp = if ((isReverse == false))
916- then [(toBigInt(getAccBalance(amId)) + poolAmountInBalance), toBigInt(getAccBalance(prId))]
917- else [(toBigInt(getAccBalance(prId)) + poolAmountInBalance), toBigInt(getAccBalance(amId))]
918- let x = xp[0]
919- let s = x
920- let ann = (a * n)
921- let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
922- let b = ((s + ((D * aPrecision) / ann)) - D)
923- func calc (acc,cur) = {
924- let $t03488634906 = acc
925- let y = $t03488634906._1
926- let found = $t03488634906._2
927- if ((found != unit))
928- then acc
929- else {
930- let yNext = (((y * y) + c) / ((big2 * y) + b))
931- let yDiff = absBigInt((yNext - value(y)))
932- if ((big1 >= yDiff))
933- then $Tuple2(yNext, cur)
934- else $Tuple2(yNext, unit)
935- }
936- }
937-
938- let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
939- let $t03523735284 = {
940- let $l = arr
941- let $s = size($l)
942- let $acc0 = $Tuple2(D, unit)
943- func $f0_1 ($a,$i) = if (($i >= $s))
944- then $a
945- else calc($a, $l[$i])
946-
947- func $f0_2 ($a,$i) = if (($i >= $s))
948- then $a
949- else throw("List size exceeds 15")
950-
951- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
952- }
953- let y = $t03523735284._1
954- let found = $t03523735284._2
955- if ((found != unit))
956- then y
957- else throw(("Y calculation error, Y = " + toString(y)))
890+func mustManager (i) = {
891+ let pd = throw("Permission denied")
892+ match managerPublicKeyOrUnit() {
893+ case pk: ByteVector =>
894+ if ((i.callerPublicKey == pk))
895+ then true
896+ else pd
897+ case _: Unit =>
898+ if ((i.caller == this))
899+ then true
900+ else pd
901+ case _ =>
902+ throw("Match error")
903+ }
958904 }
959905
960906
961-func skipOrderValidation () = valueOrElse(getBoolean(fca, keySkipOrderValidation(toString(this))), false)
907+@Callable(i)
908+func rebalance () = (rebalanceAsset(getStringOrFail(this, aa())) ++ rebalanceAsset(getStringOrFail(this, pa())))
909+
962910
963911
964912 @Callable(i)
965913 func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse,feePoolAmount) = {
966- let $t03563636060 = if ((isReverse == false))
914+ let $t03956839873 = if ((isReverse == false))
967915 then {
968- let assetOut = strf(this, pa())
969- let poolAmountInBalance = (toBigInt(getAccBalance(strf(this, aa()))) + toBigInt(cleanAmountIn))
970- $Tuple2(assetOut, poolAmountInBalance)
916+ let assetOut = getStringOrFail(this, pa())
917+ let assetIn = getStringOrFail(this, aa())
918+ $Tuple2(assetOut, assetIn)
971919 }
972920 else {
973- let assetOut = strf(this, aa())
974- let poolAmountInBalance = (toBigInt(getAccBalance(strf(this, pa()))) + toBigInt(cleanAmountIn))
975- $Tuple2(assetOut, poolAmountInBalance)
921+ let assetOut = getStringOrFail(this, aa())
922+ let assetIn = getStringOrFail(this, pa())
923+ $Tuple2(assetOut, assetIn)
976924 }
977- let assetOut = $t03563636060._1
978- let poolAmountInBalance = $t03563636060._2
979- let poolConfig = gpc()
980- let amId = poolConfig[idxAmAsId]
981- let prId = poolConfig[idxPrAsId]
982- let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
983- let D = getD(xp)
984- let y = getY(isReverse, D, toBigInt(cleanAmountIn))
985- let dy = ((toBigInt(getAccBalance(assetOut)) - y) - toBigInt(1))
986- let totalGetRaw = max([0, toInt(dy)])
987- let newXp = if ((isReverse == false))
988- then [((toBigInt(getAccBalance(amId)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)), (toBigInt(getAccBalance(prId)) - dy)]
989- else [(toBigInt(getAccBalance(amId)) - dy), ((toBigInt(getAccBalance(prId)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount))]
990- let newD = getD(newXp)
991- let checkD = if ((newD >= D))
925+ let assetOut = $t03956839873._1
926+ let assetIn = $t03956839873._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))
992933 then true
993- else throw(makeString(["new D is fewer error", toString(D), toString(newD)], "__"))
994- if ((checkD == checkD))
995- then $Tuple2(nil, totalGetRaw)
934+ else throw("new K is fewer error")
935+ if ((checkK == checkK))
936+ then $Tuple2(nil, amountOut)
996937 else throw("Strict value is not equal to itself.")
997938 }
998939
1001942 @Callable(i)
1002943 func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo,feePoolAmount) = {
1003944 let swapContact = {
1004- let @ = invoke(fca, "getSwapContractREADONLY", nil, nil)
945+ let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil)
1005946 if ($isInstanceOf(@, "String"))
1006947 then @
1007948 else throw(($getType(@) + " couldn't be cast to String"))
1015956 then {
1016957 let pmt = value(i.payments[0])
1017958 let assetIn = assetIdToString(pmt.assetId)
1018- let $t03749637890 = if ((isReverse == false))
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) - feePoolAmount)
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))
1019971 then {
1020- let assetOut = strf(this, pa())
1021- let poolAmountInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
1022- $Tuple2(assetOut, poolAmountInBalance)
1023- }
1024- else {
1025- let assetOut = strf(this, aa())
1026- let poolAmountInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
1027- $Tuple2(assetOut, poolAmountInBalance)
1028- }
1029- let assetOut = $t03749637890._1
1030- let poolAmountInBalance = $t03749637890._2
1031- let poolConfig = gpc()
1032- let amId = poolConfig[idxAmAsId]
1033- let prId = poolConfig[idxPrAsId]
1034- let xp = if ((isReverse == false))
1035- then [(toBigInt(getAccBalance(amId)) - toBigInt(value(i.payments[0]).amount)), toBigInt(getAccBalance(prId))]
1036- else [toBigInt(getAccBalance(amId)), (toBigInt(getAccBalance(prId)) - toBigInt(value(i.payments[0]).amount))]
1037- let D = getD(xp)
1038- let y = getY(isReverse, D, toBigInt(0))
1039- let dy = ((toBigInt(getAccBalance(assetOut)) - y) - toBigInt(1))
1040- let totalGetRaw = max([0, toInt(dy)])
1041- let checkMin = if ((totalGetRaw >= amountOutMin))
1042- then true
1043- else throw("Exchange result is fewer coins than expected")
1044- if ((checkMin == checkMin))
1045- then {
1046- let newXp = if ((isReverse == false))
1047- then [(toBigInt(getAccBalance(amId)) + toBigInt(feePoolAmount)), (toBigInt(getAccBalance(prId)) - dy)]
1048- else [(toBigInt(getAccBalance(amId)) - dy), (toBigInt(getAccBalance(prId)) + toBigInt(feePoolAmount))]
1049- let newD = getD(newXp)
1050- let checkD = if ((newD >= D))
972+ let checkMin = if ((amountOut >= amountOutMin))
1051973 then true
1052- else throw("new D is fewer error")
1053- if ((checkD == checkD))
1054- then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), totalGetRaw, parseAssetId(assetOut))], totalGetRaw)
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+ }
1055987 else throw("Strict value is not equal to itself.")
1056988 }
1057989 else throw("Strict value is not equal to itself.")
1062994
1063995
1064996 @Callable(i)
1065-func constructor (fc) = {
1066- let c = mustManager(i)
1067- if ((c == c))
1068- then [StringEntry(fc(), fc)]
1069- else throw("Strict value is not equal to itself.")
1070- }
1071-
1072-
1073-
1074-@Callable(i)
1075-func put (slip,autoStake) = {
1076- let factCfg = gfc()
1077- let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Wr st addr")
1078- let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Wr sl addr")
1079- if ((0 > slip))
1080- then throw("Wrong slippage")
1081- else if ((size(i.payments) != 2))
1082- then throw("2 pmnts expd")
1083- else {
1084- let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1085- let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1086- let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amAssetPmt)
1087- if ((amountAssetBalance == amountAssetBalance))
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))
10881015 then {
1089- let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - prAssetPmt)
1090- if ((priceAssetBalance == priceAssetBalance))
1016+ let emitInvLegacy = match emitInv {
1017+ case legacyFactoryContract: Address =>
1018+ invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
1019+ case _ =>
1020+ unit
1021+ }
1022+ if ((emitInvLegacy == emitInvLegacy))
10911023 then {
1092- let lpAssetEmission = toBigInt(value(assetInfo(cfgLpAssetId)).quantity)
1093- if ((lpAssetEmission == lpAssetEmission))
1024+ let slippageAInv = if ((amDiff > 0))
1025+ then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
1026+ else nil
1027+ if ((slippageAInv == slippageAInv))
10941028 then {
1095- let currentDLp = calcCurrentDLp(amAssetPmt, prAssetPmt, toBigInt(0))
1096- if ((currentDLp == currentDLp))
1029+ let slippagePInv = if ((prDiff > 0))
1030+ then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
1031+ else nil
1032+ if ((slippagePInv == slippagePInv))
10971033 then {
1098- let e = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], slip, true, false, true, 0, "")
1099- let emitLpAmt = e._2
1100- let lpAssetId = e._7
1101- let state = e._9
1102- let amDiff = e._10
1103- let prDiff = e._11
1104- let amId = e._12
1105- let prId = e._13
1106- let r = invoke(fca, "emit", [emitLpAmt], nil)
1107- if ((r == r))
1034+ let lpTransfer = if (shouldAutoStake)
11081035 then {
1109- let el = match r {
1110- case legacy: Address =>
1111- invoke(legacy, "emit", [emitLpAmt], nil)
1112- case _ =>
1113- unit
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.")
11141040 }
1115- if ((el == el))
1041+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1042+ let $t04437644838 = refreshKLpInternal(0, 0, 0)
1043+ if (($t04437644838 == $t04437644838))
1044+ then {
1045+ let updatedKLp = $t04437644838._2
1046+ let refreshKLpActions = $t04437644838._1
1047+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1048+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
11161049 then {
1117- let sa = if ((amDiff > 0))
1118- then invoke(slipCntr, "put", nil, [AttachedPayment(amId, amDiff)])
1119- else nil
1120- if ((sa == sa))
1121- then {
1122- let sp = if ((prDiff > 0))
1123- then invoke(slipCntr, "put", nil, [AttachedPayment(prId, prDiff)])
1124- else nil
1125- if ((sp == sp))
1126- then {
1127- let lpTrnsfr = if (autoStake)
1128- then {
1129- let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
1130- if ((ss == ss))
1131- then nil
1132- else throw("Strict value is not equal to itself.")
1133- }
1134- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1135- let $t04203442176 = refreshDLpInternal(0, 0, 0)
1136- let refreshDLpActions = $t04203442176._1
1137- let updatedDLp = $t04203442176._2
1138- let check = if ((updatedDLp >= currentDLp))
1139- then true
1140- else throwErr(makeString(["updated DLp lower than current DLp", toString(amountAssetBalance), toString(priceAssetBalance), toString(lpAssetEmission), toString(currentDLp), toString(updatedDLp), toString(amDiff), toString(prDiff)], " "))
1141- if ((check == check))
1142- then {
1143- let lpAssetEmissionAfter = value(assetInfo(cfgLpAssetId)).quantity
1144- if ((lpAssetEmissionAfter == lpAssetEmissionAfter))
1145- then ((state ++ lpTrnsfr) ++ refreshDLpActions)
1146- else throw("Strict value is not equal to itself.")
1147- }
1148- else throw("Strict value is not equal to itself.")
1149- }
1150- else throw("Strict value is not equal to itself.")
1151- }
1050+ let reb = invoke(this, "rebalance", nil, nil)
1051+ if ((reb == reb))
1052+ then ((state ++ lpTransfer) ++ refreshKLpActions)
11521053 else throw("Strict value is not equal to itself.")
11531054 }
11541055 else throw("Strict value is not equal to itself.")
11631064 }
11641065 else throw("Strict value is not equal to itself.")
11651066 }
1166- }
1067+ else throw("Strict value is not equal to itself.")
1068+ }
11671069
11681070
11691071
11701072 @Callable(i)
1171-func putOneTknV2 (minOutAmount,autoStake) = {
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 $t04545045515 = refreshKLpInternal(0, 0, 0)
1084+ let refreshKLpActions = $t04545045515._1
1085+ let updatedKLp = $t04545045515._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) = {
11721098 let isPoolOneTokenOperationsDisabled = {
1173- let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1099+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
11741100 if ($isInstanceOf(@, "Boolean"))
11751101 then @
11761102 else throw(($getType(@) + " couldn't be cast to Boolean"))
11771103 }
1178- let isPutDisabled = if (if (if (igs())
1104+ let isPutDisabled = if (if (if (isGlobalShutdown())
11791105 then true
1180- else (cfgPoolStatus == PoolPutDis))
1106+ else (cfgPoolStatus == PoolPutDisabled))
11811107 then true
11821108 else (cfgPoolStatus == PoolShutdown))
11831109 then true
11911117 else throwErr("exactly 1 payment are expected")]
11921118 if ((checks == checks))
11931119 then {
1194- let amId = toBase58String(value(cfgAmountAssetId))
1195- let prId = toBase58String(value(cfgPriceAssetId))
1196- let lpId = cfgLpAssetId
1197- let amDecimals = cfgAmountAssetDecimals
1198- let prDecimals = cfgPriceAssetDecimals
1199- let userAddress = if ((i.caller == this))
1200- then i.originCaller
1201- else i.caller
1202- let pmt = value(i.payments[0])
1203- let pmtAssetId = toBase58String(value(pmt.assetId))
1204- let pmtAmt = pmt.amount
1205- let currentDLp = if ((pmt.assetId == cfgAmountAssetId))
1206- then calcCurrentDLp(toBigInt(pmtAmt), toBigInt(0), toBigInt(0))
1207- else calcCurrentDLp(toBigInt(0), toBigInt(pmtAmt), toBigInt(0))
1208- if ((currentDLp == currentDLp))
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))
12091129 then {
1210- let $t04381743975 = calcPutOneTkn(pmtAmt, pmtAssetId, toString(userAddress), toBase58String(i.transactionId), true)
1211- if (($t04381743975 == $t04381743975))
1130+ let userAddress = i.caller
1131+ let txId = i.transactionId
1132+ let $t04670346855 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
1133+ if (($t04670346855 == $t04670346855))
12121134 then {
1213- let feeAmount = $t04381743975._3
1214- let state = $t04381743975._2
1215- let estimLP = $t04381743975._1
1216- let emitLpAmt = if (if ((minOutAmount > 0))
1217- then (minOutAmount > estimLP)
1135+ let paymentInAmountAsset = $t04670346855._5
1136+ let bonus = $t04670346855._4
1137+ let feeAmount = $t04670346855._3
1138+ let commonState = $t04670346855._2
1139+ let emitAmountEstimated = $t04670346855._1
1140+ let emitAmount = if (if ((minOutAmount > 0))
1141+ then (minOutAmount > emitAmountEstimated)
12181142 else false)
12191143 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1220- else estimLP
1221- let e = invoke(fca, "emit", [emitLpAmt], nil)
1222- if ((e == e))
1144+ else emitAmountEstimated
1145+ let emitInv = emit(emitAmount)
1146+ if ((emitInv == emitInv))
12231147 then {
1224- let el = match e {
1225- case legacy: Address =>
1226- invoke(legacy, "emit", [emitLpAmt], nil)
1227- case _ =>
1228- unit
1229- }
1230- if ((el == el))
1148+ let lpTransfer = if (autoStake)
12311149 then {
1232- let lpTrnsfr = if (autoStake)
1233- then {
1234- let ss = invoke(stakingContract, "stakeFor", [toString(i.caller)], [AttachedPayment(lpId, emitLpAmt)])
1235- if ((ss == ss))
1236- then nil
1237- else throw("Strict value is not equal to itself.")
1238- }
1239- else [ScriptTransfer(i.caller, emitLpAmt, lpId)]
1240- let sendFeeToMatcher = if ((feeAmount > 0))
1241- then [ScriptTransfer(feeCollectorAddress, feeAmount, fromBase58String(pmtAssetId))]
1242- else nil
1243- let $t04486045209 = if ((this == feeCollectorAddress))
1244- then $Tuple2(0, 0)
1245- else {
1246- let paymentInAmountAsset = if ((pmt.assetId == cfgAmountAssetId))
1247- then true
1248- else false
1249- if (paymentInAmountAsset)
1250- then $Tuple2(-(feeAmount), 0)
1251- else $Tuple2(0, -(feeAmount))
1252- }
1253- let amountAssetBalanceDelta = $t04486045209._1
1254- let priceAssetBalanceDelta = $t04486045209._2
1255- let $t04521245320 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1256- let refreshDLpActions = $t04521245320._1
1257- let updatedDLp = $t04521245320._2
1258- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1259- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1260- then $Tuple2((((state ++ lpTrnsfr) ++ sendFeeToMatcher) ++ refreshDLpActions), emitLpAmt)
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)]
1158+ else nil
1159+ let $t04744147638 = 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 = $t04744147638._1
1165+ let priceAssetBalanceDelta = $t04744147638._2
1166+ let $t04764147749 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1167+ let refreshKLpActions = $t04764147749._1
1168+ let updatedKLp = $t04764147749._2
1169+ let kLp = value(getString(keyKLp))
1170+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1171+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1172+ then {
1173+ let reb = invoke(this, "rebalance", nil, nil)
1174+ if ((reb == reb))
1175+ then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
12611176 else throw("Strict value is not equal to itself.")
12621177 }
12631178 else throw("Strict value is not equal to itself.")
12741189
12751190
12761191 @Callable(i)
1277-func putForFree (maxSlpg) = if ((0 > maxSlpg))
1278- then throw("Wrong slpg")
1279- else if ((size(i.payments) != 2))
1280- then throw("2 pmnts expd")
1281- else {
1282- let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], maxSlpg, false, false, true, 0, "")
1283- let state = estPut._9
1284- let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1285- let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1286- let currentDLp = calcCurrentDLp(amAssetPmt, prAssetPmt, toBigInt(0))
1287- if ((currentDLp == currentDLp))
1288- then {
1289- let $t04635046415 = refreshDLpInternal(0, 0, 0)
1290- let refreshDLpActions = $t04635046415._1
1291- let updatedDLp = $t04635046415._2
1292- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1293- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1294- then (state ++ refreshDLpActions)
1295- else throw("Strict value is not equal to itself.")
1296- }
1297- else throw("Strict value is not equal to itself.")
1298- }
1299-
1300-
1301-
1302-@Callable(i)
1303-func get () = {
1304- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1305- if ((currentDLp == currentDLp))
1306- then {
1307- let r = cg(i)
1308- let outAmtAmt = r._1
1309- let outPrAmt = r._2
1310- let pmtAmt = r._3
1311- let pmtAssetId = r._4
1312- let state = r._5
1313- let b = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1314- if ((b == b))
1315- then {
1316- let $t04758847670 = refreshDLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1317- let refreshDLpActions = $t04758847670._1
1318- let updatedDLp = $t04758847670._2
1319- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1320- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1321- then (state ++ refreshDLpActions)
1322- else throw("Strict value is not equal to itself.")
1323- }
1324- else throw("Strict value is not equal to itself.")
1325- }
1326- else throw("Strict value is not equal to itself.")
1192+func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
1193+ let $t04810448261 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
1194+ let emitAmountEstimated = $t04810448261._1
1195+ let commonState = $t04810448261._2
1196+ let feeAmount = $t04810448261._3
1197+ let bonus = $t04810448261._4
1198+ let paymentInAmountAsset = $t04810448261._5
1199+ $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
13271200 }
13281201
13291202
13301203
13311204 @Callable(i)
1332-func getOneTknV2 (outAssetId,minOutAmount) = {
1205+func getOneTkn (outAssetIdStr,minOutAmount) = {
13331206 let isPoolOneTokenOperationsDisabled = {
1334- let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1207+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
13351208 if ($isInstanceOf(@, "Boolean"))
13361209 then @
13371210 else throw(($getType(@) + " couldn't be cast to Boolean"))
13381211 }
1339- let isGetDisabled = if (if (igs())
1212+ let isGetDisabled = if (if (isGlobalShutdown())
13401213 then true
13411214 else (cfgPoolStatus == PoolShutdown))
13421215 then true
13501223 else throwErr("exactly 1 payment are expected")]
13511224 if ((checks == checks))
13521225 then {
1353- let $t04828848443 = getOneTknV2Internal(outAssetId, minOutAmount, i.payments, i.caller, i.originCaller, i.transactionId)
1354- let state = $t04828848443._1
1355- let totalAmount = $t04828848443._2
1356- $Tuple2(state, totalAmount)
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 $t04914649299 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1236+ if (($t04914649299 == $t04914649299))
1237+ then {
1238+ let outInAmountAsset = $t04914649299._5
1239+ let bonus = $t04914649299._4
1240+ let feeAmount = $t04914649299._3
1241+ let commonState = $t04914649299._2
1242+ let amountEstimated = $t04914649299._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 $t04996350210 = {
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 = $t04996350210._1
1265+ let priceAssetBalanceDelta = $t04996350210._2
1266+ let $t05021350321 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1267+ let refreshKLpActions = $t05021350321._1
1268+ let updatedKLp = $t05021350321._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.")
13571279 }
13581280 else throw("Strict value is not equal to itself.")
13591281 }
13611283
13621284
13631285 @Callable(i)
1364-func refreshDLp () = {
1365- let lastRefreshedBlockHeight = valueOrElse(getInteger(keyDLpRefreshedHeight), 0)
1366- let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= dLpRefreshDelay))
1367- then unit
1368- else throwErr(makeString([toString(dLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1369- if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
1286+func getOneTknREADONLY (outAssetId,paymentAmount) = {
1287+ let $t05059950755 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1288+ let amountEstimated = $t05059950755._1
1289+ let commonState = $t05059950755._2
1290+ let feeAmount = $t05059950755._3
1291+ let bonus = $t05059950755._4
1292+ let outInAmountAsset = $t05059950755._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))
13701319 then {
1371- let dLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyDLp), "0")), fmtErr("invalid dLp"))
1372- let $t04896749031 = refreshDLpInternal(0, 0, 0)
1373- let dLpUpdateActions = $t04896749031._1
1374- let updatedDLp = $t04896749031._2
1375- let actions = if ((dLp != updatedDLp))
1376- then dLpUpdateActions
1377- else throwErr("nothing to refresh")
1378- $Tuple2(actions, toString(updatedDLp))
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 $t05166051811 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1330+ if (($t05166051811 == $t05166051811))
1331+ then {
1332+ let outInAmountAsset = $t05166051811._5
1333+ let bonus = $t05166051811._4
1334+ let feeAmount = $t05166051811._3
1335+ let commonState = $t05166051811._2
1336+ let amountEstimated = $t05166051811._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 $t05247052717 = {
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 = $t05247052717._1
1359+ let priceAssetBalanceDelta = $t05247052717._2
1360+ let $t05272052828 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1361+ let refreshKLpActions = $t05272052828._1
1362+ let updatedKLp = $t05272052828._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.")
13791375 }
13801376 else throw("Strict value is not equal to itself.")
13811377 }
13831379
13841380
13851381 @Callable(i)
1386-func getOneTknV2READONLY (outAssetId,lpAssetAmount) = {
1387- let amId = toBase58String(value(cfgAmountAssetId))
1388- let prId = toBase58String(value(cfgPriceAssetId))
1389- let lpId = toBase58String(value(cfgLpAssetId))
1390- let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
1391- let lpEmission = toBigInt(valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "invalid lp asset").quantity)
1392- let D0 = getD(xp)
1393- let D1 = (D0 - fraction(toBigInt(lpAssetAmount), D0, lpEmission))
1394- let index = if ((outAssetId == amId))
1395- then 0
1396- else if ((outAssetId == prId))
1397- then 1
1398- else throw("invalid out asset id")
1399- let newY = getYD(xp, index, D1)
1400- let dy = (xp[index] - newY)
1401- let totalGetRaw = max([0, toInt((dy - big1))])
1402- let $t05004150096 = takeFee(totalGetRaw, outFee)
1403- let totalGet = $t05004150096._1
1404- let feeAmount = $t05004150096._2
1405- $Tuple2(nil, $Tuple2(totalGet, feeAmount))
1406- }
1407-
1408-
1409-
1410-@Callable(i)
1411-func getOneTknV2WithBonusREADONLY (outAssetId,lpAssetAmount) = {
1412- let amId = toBase58String(value(cfgAmountAssetId))
1413- let prId = toBase58String(value(cfgPriceAssetId))
1414- let lpId = toBase58String(value(cfgLpAssetId))
1415- let amBalance = getAccBalance(amId)
1416- let prBalance = getAccBalance(prId)
1417- let $t05047150586 = {
1418- let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, lpAssetAmount], nil)
1419- if ($isInstanceOf(@, "(Int, Int)"))
1420- then @
1421- else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
1422- }
1423- let totalGet = $t05047150586._1
1424- let feeAmount = $t05047150586._2
1425- let r = ego("", lpId, lpAssetAmount, this)
1426- let outAmAmt = r._1
1427- let outPrAmt = r._2
1428- let sumOfGetAssets = (outAmAmt + outPrAmt)
1429- let bonus = if ((sumOfGetAssets == 0))
1430- then if ((totalGet == 0))
1431- then 0
1432- else throw("bonus calculation error")
1433- else fraction((totalGet - sumOfGetAssets), scale8, sumOfGetAssets)
1434- $Tuple2(nil, $Tuple3(totalGet, feeAmount, bonus))
1382+func get () = {
1383+ let res = commonGet(i)
1384+ let outAmAmt = res._1
1385+ let outPrAmt = res._2
1386+ let pmtAmt = res._3
1387+ let pmtAssetId = res._4
1388+ let state = res._5
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 $t05392354004 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1397+ let refreshKLpActions = $t05392354004._1
1398+ let updatedKLp = $t05392354004._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+ }
1406+ else throw("Strict value is not equal to itself.")
14351407 }
14361408
14371409
14381410
14391411 @Callable(i)
14401412 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
1441- let r = cg(i)
1442- let outAmAmt = r._1
1443- let outPrAmt = r._2
1444- let pmtAmt = r._3
1445- let pmtAssetId = r._4
1446- let state = r._5
1413+ let res = commonGet(i)
1414+ let outAmAmt = res._1
1415+ let outPrAmt = res._2
1416+ let pmtAmt = res._3
1417+ let pmtAssetId = res._4
1418+ let state = res._5
14471419 if ((noLessThenAmtAsset > outAmAmt))
1448- then throw(((("Failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
1420+ then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
14491421 else if ((noLessThenPriceAsset > outPrAmt))
1450- then throw(((("Failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
1422+ then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
14511423 else {
1452- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1453- if ((currentDLp == currentDLp))
1424+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1425+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1426+ if ((currentKLp == currentKLp))
14541427 then {
1455- let burnLPAssetOnFactory = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1428+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
14561429 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
14571430 then {
1458- let $t05175251833 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1459- let refreshDLpActions = $t05175251833._1
1460- let updatedDLp = $t05175251833._2
1461- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1462- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1463- then (state ++ refreshDLpActions)
1431+ let $t05509955180 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1432+ let refreshKLpActions = $t05509955180._1
1433+ let updatedKLp = $t05509955180._2
1434+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1435+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1436+ then ((withdrawState ++ state) ++ refreshKLpActions)
14641437 else throw("Strict value is not equal to itself.")
14651438 }
14661439 else throw("Strict value is not equal to itself.")
14741447 @Callable(i)
14751448 func unstakeAndGet (amount) = {
14761449 let checkPayments = if ((size(i.payments) != 0))
1477- then throw("No pmnts expd")
1450+ then throw("No payments are expected")
14781451 else true
14791452 if ((checkPayments == checkPayments))
14801453 then {
1481- let factoryCfg = gfc()
1482- let lpAssetId = cfgLpAssetId
1483- let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1484- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1485- if ((currentDLp == currentDLp))
1454+ let cfg = getPoolConfig()
1455+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1456+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1457+ if ((currentKLp == currentKLp))
14861458 then {
1487- let unstakeInv = invoke(staking, "unstake", [toBase58String(lpAssetId), amount], nil)
1459+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
14881460 if ((unstakeInv == unstakeInv))
14891461 then {
1490- let r = ego(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1491- let outAmAmt = r._1
1492- let outPrAmt = r._2
1493- let sts = parseIntValue(r._9)
1494- let state = r._10
1495- let v = if (if (igs())
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())
14961469 then true
1497- else (sts == PoolShutdown))
1498- then throw(("Blocked: " + toString(sts)))
1470+ else (poolStatus == PoolShutdown))
1471+ then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
14991472 else true
1500- if ((v == v))
1473+ if ((checkPoolStatus == checkPoolStatus))
15011474 then {
1502- let burnA = invoke(fca, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1503- if ((burnA == burnA))
1475+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1476+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
15041477 then {
1505- let $t05286052941 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1506- let refreshDLpActions = $t05286052941._1
1507- let updatedDLp = $t05286052941._2
1508- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1509- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1510- then (state ++ refreshDLpActions)
1478+ let $t05645256533 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1479+ let refreshKLpActions = $t05645256533._1
1480+ let updatedKLp = $t05645256533._2
1481+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1482+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1483+ then ((withdrawState ++ state) ++ refreshKLpActions)
15111484 else throw("Strict value is not equal to itself.")
15121485 }
15131486 else throw("Strict value is not equal to itself.")
15251498
15261499 @Callable(i)
15271500 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
1528- let isGetDisabled = if (igs())
1501+ let isGetDisabled = if (isGlobalShutdown())
15291502 then true
15301503 else (cfgPoolStatus == PoolShutdown)
15311504 let checks = [if (!(isGetDisabled))
15351508 else throw("no payments are expected")]
15361509 if ((checks == checks))
15371510 then {
1538- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1539- if ((currentDLp == currentDLp))
1511+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1512+ if ((currentKLp == currentKLp))
15401513 then {
15411514 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
15421515 if ((unstakeInv == unstakeInv))
15431516 then {
1544- let res = ego(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
1517+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
15451518 let outAmAmt = res._1
15461519 let outPrAmt = res._2
15471520 let state = res._10
1521+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
15481522 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
15491523 then true
15501524 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
15521526 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
15531527 if ((checkAmounts == checkAmounts))
15541528 then {
1555- let burnLPAssetOnFactory = invoke(fca, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1529+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
15561530 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
15571531 then {
1558- let $t05419254273 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1559- let refreshDLpActions = $t05419254273._1
1560- let updatedDLp = $t05419254273._2
1561- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1562- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1563- then (state ++ refreshDLpActions)
1532+ let $t05797458055 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1533+ let refreshKLpActions = $t05797458055._1
1534+ let updatedKLp = $t05797458055._2
1535+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1536+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1537+ then ((withdrawState ++ state) ++ refreshKLpActions)
15641538 else throw("Strict value is not equal to itself.")
15651539 }
15661540 else throw("Strict value is not equal to itself.")
15771551
15781552
15791553 @Callable(i)
1580-func unstakeAndGetOneTknV2 (unstakeAmount,outAssetId,minOutAmount) = {
1581- let isPoolOneTokenOperationsDisabled = {
1582- let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1583- if ($isInstanceOf(@, "Boolean"))
1584- then @
1585- else throw(($getType(@) + " couldn't be cast to Boolean"))
1586- }
1587- let isGetDisabled = if (if (igs())
1588- then true
1589- else (cfgPoolStatus == PoolShutdown))
1590- then true
1591- else isPoolOneTokenOperationsDisabled
1592- let checks = [if (if (!(isGetDisabled))
1593- then true
1594- else isManager(i))
1595- then true
1596- else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
1597- then true
1598- else throwErr("no payments are expected")]
1599- if ((checks == checks))
1554+func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
1555+ then throw("permissions denied")
1556+ 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))
16001567 then {
1601- let factoryCfg = gfc()
1602- let lpAssetId = cfgLpAssetId
1603- let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1604- let userAddress = i.caller
1605- let lpAssetRecipientAddress = this
1606- let unstakeInv = invoke(staking, "unstakeINTERNAL", [lpAssetId, unstakeAmount, userAddress.bytes, lpAssetRecipientAddress.bytes], nil)
1607- if ((unstakeInv == unstakeInv))
1608- then {
1609- let $t05529555483 = getOneTknV2Internal(outAssetId, minOutAmount, [AttachedPayment(lpAssetId, unstakeAmount)], i.caller, i.originCaller, i.transactionId)
1610- let state = $t05529555483._1
1611- let totalAmount = $t05529555483._2
1612- $Tuple2(state, totalAmount)
1613- }
1614- else throw("Strict value is not equal to itself.")
1568+ let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1569+ let $t05925959323 = refreshKLpInternal(0, 0, 0)
1570+ let kLpUpdateActions = $t05925959323._1
1571+ let updatedKLp = $t05925959323._2
1572+ let actions = if ((kLp != updatedKLp))
1573+ then kLpUpdateActions
1574+ else throwErr("nothing to refresh")
1575+ $Tuple2(actions, toString(updatedKLp))
16151576 }
16161577 else throw("Strict value is not equal to itself.")
16171578 }
16191580
16201581
16211582 @Callable(i)
1622-func putOneTknV2WithBonusREADONLY (paymentAmountRaw,paymentAssetId) = {
1623- let $t05561155714 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "", true)
1624- let lpAmount = $t05561155714._1
1625- let state = $t05561155714._2
1626- let feeAmount = $t05561155714._3
1627- let bonus = $t05561155714._4
1628- $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1629- }
1630-
1631-
1632-
1633-@Callable(i)
1634-func putOneTknV2WithoutTakeFeeREADONLY (paymentAmountRaw,paymentAssetId) = {
1635- let $t05586255966 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "", false)
1636- let lpAmount = $t05586255966._1
1637- let state = $t05586255966._2
1638- let feeAmount = $t05586255966._3
1639- let bonus = $t05586255966._4
1640- $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1641- }
1642-
1643-
1644-
1645-@Callable(i)
1646-func activate (amtAsStr,prAsStr) = if ((toString(i.caller) != toString(fca)))
1647- then throw("denied")
1648- else $Tuple2([StringEntry(aa(), amtAsStr), StringEntry(pa(), prAsStr), StringEntry(amp(), toString(ampInitial)), StringEntry(keyAmpHistory(height), toString(ampInitial))], "success")
1649-
1650-
1651-
1652-@Callable(i)
1653-func getPoolConfigWrapperREADONLY () = $Tuple2(nil, gpc())
1583+func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
16541584
16551585
16561586
16611591
16621592 @Callable(i)
16631593 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
1664- let pr = calcPrices(amAmt, prAmt, lpAmt)
1665- $Tuple2(nil, [toString(pr[0]), toString(pr[1]), toString(pr[2])])
1594+ let prices = calcPrices(amAmt, prAmt, lpAmt)
1595+ $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
16661596 }
16671597
16681598
16691599
16701600 @Callable(i)
1671-func fromX18WrapperREADONLY (val,resScaleMult) = $Tuple2(nil, f1(parseBigIntValue(val), resScaleMult))
1601+func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
16721602
16731603
16741604
16751605 @Callable(i)
1676-func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(t1(origVal, origScaleMult)))
1606+func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
16771607
16781608
16791609
16801610 @Callable(i)
1681-func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(cpbi(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
1611+func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
16821612
16831613
16841614
16851615 @Callable(i)
1686-func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,usrAddr,isEval,emitLp) = $Tuple2(nil, epo(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, usrAddr, isEval, emitLp, true, false, 0, ""))
1616+func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
16871617
16881618
16891619
16901620 @Callable(i)
1691-func estimateGetOperationWrapperREADONLY (txId58,pmtAsId,pmtLpAmt,usrAddr) = {
1692- let r = ego(txId58, pmtAsId, pmtLpAmt, addressFromStringValue(usrAddr))
1693- $Tuple2(nil, $Tuple10(r._1, r._2, r._3, r._4, r._5, r._6, r._7, toString(r._8), r._9, r._10))
1621+func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
1622+ let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
1623+ $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
16941624 }
16951625
16961626
16971627
16981628 @Callable(i)
1699-func changeAmp () = {
1700- let cfg = invoke(fca, "getChangeAmpConfigREADONLY", [toString(this)], nil)
1701- let $t05844658645 = match cfg {
1702- case list: List[Any] =>
1703- $Tuple3({
1704- let @ = list[0]
1705- if ($isInstanceOf(@, "Int"))
1706- then @
1707- else throw(($getType(@) + " couldn't be cast to Int"))
1708- }, {
1709- let @ = list[1]
1710- if ($isInstanceOf(@, "Int"))
1711- then @
1712- else throw(($getType(@) + " couldn't be cast to Int"))
1713- }, {
1714- let @ = list[2]
1715- if ($isInstanceOf(@, "Int"))
1716- then @
1717- else throw(($getType(@) + " couldn't be cast to Int"))
1718- })
1719- case _ =>
1720- throwErr("invalid entry type")
1629+func statsREADONLY () = {
1630+ let cfg = getPoolConfig()
1631+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1632+ let amtAssetId = cfg[idxAmtAssetId]
1633+ let priceAssetId = cfg[idxPriceAssetId]
1634+ let iAmtAssetId = cfg[idxIAmtAssetId]
1635+ let iPriceAssetId = cfg[idxIPriceAssetId]
1636+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1637+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1638+ let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1639+ let accAmtAssetBalance = getAccBalance(amtAssetId)
1640+ let accPriceAssetBalance = getAccBalance(priceAssetId)
1641+ let pricesList = if ((poolLPBalance == 0))
1642+ then [zeroBigInt, zeroBigInt, zeroBigInt]
1643+ else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
1644+ let curPrice = 0
1645+ let lpAmtAssetShare = fromX18(pricesList[1], scale8)
1646+ let lpPriceAssetShare = fromX18(pricesList[2], scale8)
1647+ let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
1648+ $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))
17211649 }
1722- let delay = $t05844658645._1
1723- let delta = $t05844658645._2
1724- let target = $t05844658645._3
1725- let curAmp = parseIntValue(getStringValue(amp()))
1726- let newAmpRaw = (curAmp + delta)
1727- let newAmp = if ((0 > delta))
1728- then if ((target > newAmpRaw))
1729- then target
1730- else newAmpRaw
1731- else if ((newAmpRaw > target))
1732- then target
1733- else newAmpRaw
1734- let lastCall = valueOrElse(getInteger(keyChangeAmpLastCall()), 0)
1735- let wait = (lastCall + delay)
1736- let checks = [if ((height > wait))
1737- then true
1738- else throwErr("try again in few blocks"), if ((curAmp != newAmp))
1739- then true
1740- else throwErr("already reached target")]
1741- if ((checks == checks))
1742- then [IntegerEntry(keyChangeAmpLastCall(), height), StringEntry(amp(), toString(newAmp)), StringEntry(keyAmpHistory(height), toString(newAmp))]
1743- else throw("Strict value is not equal to itself.")
1650+
1651+
1652+
1653+@Callable(i)
1654+func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
1655+ let cfg = getPoolConfig()
1656+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1657+ let amAssetIdStr = cfg[idxAmtAssetId]
1658+ let amAssetId = fromBase58String(amAssetIdStr)
1659+ let prAssetIdStr = cfg[idxPriceAssetId]
1660+ let prAssetId = fromBase58String(prAssetIdStr)
1661+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1662+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1663+ let poolStatus = cfg[idxPoolStatus]
1664+ let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1665+ let accAmtAssetBalance = getAccBalance(amAssetIdStr)
1666+ let accPriceAssetBalance = getAccBalance(prAssetIdStr)
1667+ let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
1668+ let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
1669+ let curPriceX18 = if ((poolLPBalance == 0))
1670+ then zeroBigInt
1671+ else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
1672+ let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
1673+ let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
1674+ let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
1675+ let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
1676+ let calcLpAmt = estPut._1
1677+ let curPriceCalc = estPut._3
1678+ let amBalance = estPut._4
1679+ let prBalance = estPut._5
1680+ let lpEmission = estPut._6
1681+ $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))
1682+ }
1683+
1684+
1685+
1686+@Callable(i)
1687+func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
1688+ let cfg = getPoolConfig()
1689+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1690+ let amAssetIdStr = cfg[idxAmtAssetId]
1691+ let amAssetId = fromBase58String(amAssetIdStr)
1692+ let prAssetIdStr = cfg[idxPriceAssetId]
1693+ let prAssetId = fromBase58String(prAssetIdStr)
1694+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1695+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1696+ let poolStatus = cfg[idxPoolStatus]
1697+ let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1698+ let amBalanceRaw = getAccBalance(amAssetIdStr)
1699+ let prBalanceRaw = getAccBalance(prAssetIdStr)
1700+ let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
1701+ let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
1702+ let curPriceX18 = if ((poolLPBalance == 0))
1703+ then zeroBigInt
1704+ else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
1705+ let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
1706+ let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
1707+ let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
1708+ let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
1709+ let calcLpAmt = estPut._1
1710+ let curPriceCalc = estPut._3
1711+ let amBalance = estPut._4
1712+ let prBalance = estPut._5
1713+ let lpEmission = estPut._6
1714+ $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))
1715+ }
1716+
1717+
1718+
1719+@Callable(i)
1720+func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
1721+ let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
1722+ let outAmAmt = res._1
1723+ let outPrAmt = res._2
1724+ let amBalance = res._5
1725+ let prBalance = res._6
1726+ let lpEmission = res._7
1727+ let curPrice = res._8
1728+ let poolStatus = parseIntValue(res._9)
1729+ $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))
17441730 }
17451731
17461732
17561742 }
17571743 match tx {
17581744 case order: Order =>
1759- let matcherPub = mp()
1760- let $t05957859695 = if (skipOrderValidation())
1745+ let matcherPub = getMatcherPubOrFail()
1746+ let $t06798568102 = if (skipOrderValidation())
17611747 then $Tuple2(true, "")
17621748 else validateMatcherOrderAllowed(order)
1763- let orderValid = $t05957859695._1
1764- let orderValidInfo = $t05957859695._2
1749+ let orderValid = $t06798568102._1
1750+ let orderValidInfo = $t06798568102._2
17651751 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
17661752 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
17671753 if (if (if (orderValid)
17761762 then true
17771763 else {
17781764 let newHash = blake2b256(value(s.script))
1779- let allowedHash = fromBase64String(value(getString(fca, keyAllowedLpStableScriptHash())))
1765+ let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
17801766 let currentHash = scriptHash(this)
17811767 if ((allowedHash == newHash))
17821768 then (currentHash != newHash)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let lPdecimals = 8
5+
46 let scale8 = 100000000
57
68 let scale8BigInt = toBigInt(100000000)
79
810 let scale18 = toBigInt(1000000000000000000)
911
1012 let zeroBigInt = toBigInt(0)
1113
1214 let big0 = toBigInt(0)
1315
1416 let big1 = toBigInt(1)
1517
1618 let big2 = toBigInt(2)
1719
18-let big3 = toBigInt(3)
19-
20-let big4 = toBigInt(4)
21-
22-let slippage4D = toBigInt((scale8 - ((scale8 * 1) / scale8)))
23-
2420 let wavesString = "WAVES"
25-
26-let ampInitial = 50
27-
28-let Amult = "100"
29-
30-let Dconv = "1"
3121
3222 let SEP = "__"
3323
34-let EMPTY = ""
35-
3624 let PoolActive = 1
3725
38-let PoolPutDis = 2
26+let PoolPutDisabled = 2
3927
40-let PoolMatcherDis = 3
28+let PoolMatcherDisabled = 3
4129
4230 let PoolShutdown = 4
4331
4432 let idxPoolAddress = 1
4533
46-let idxPoolSt = 2
34+let idxPoolStatus = 2
4735
48-let idxLPAsId = 3
36+let idxPoolLPAssetId = 3
4937
50-let idxAmAsId = 4
38+let idxAmtAssetId = 4
5139
52-let idxPrAsId = 5
40+let idxPriceAssetId = 5
5341
54-let idxAmtAsDcm = 6
42+let idxAmtAssetDcm = 6
5543
56-let idxPriceAsDcm = 7
44+let idxPriceAssetDcm = 7
5745
58-let idxIAmtAsId = 8
46+let idxIAmtAssetId = 8
5947
60-let idxIPriceAsId = 9
48+let idxIPriceAssetId = 9
6149
62-let idxFactStakCntr = 1
50+let idxLPAssetDcm = 10
6351
64-let idxFactoryRestCntr = 6
52+let idxPoolAmtAssetAmt = 1
6553
66-let idxFactSlippCntr = 7
54+let idxPoolPriceAssetAmt = 2
6755
68-let idxFactGwxRewCntr = 10
56+let idxPoolLPAssetAmt = 3
6957
70-let feeDefault = fraction(10, scale8, 10000)
58+let idxFactoryStakingContract = 1
7159
72-func t1 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
60+let idxFactorySlippageContract = 7
61+
62+func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
7363
7464
75-func t1BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
65+func toX18BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
7666
7767
78-func f1 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
68+func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
7969
8070
8171 func fromX18Round (val,resultScaleMult,round) = toInt(fraction(val, toBigInt(resultScaleMult), scale18, round))
8272
8373
84-func t2 (origVal,origScaleMult) = fraction(origVal, scale18, toBigInt(origScaleMult))
74+func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
8575
8676
87-func f2 (val,resultScaleMult) = fraction(val, toBigInt(resultScaleMult), scale18)
88-
89-
90-func ts (amt,resScale,curScale) = fraction(amt, resScale, curScale)
91-
92-
93-func abs (val) = if ((zeroBigInt > val))
77+func abs (val) = if ((0 > val))
9478 then -(val)
9579 else val
9680
9781
9882 func absBigInt (val) = if ((zeroBigInt > val))
9983 then -(val)
10084 else val
85+
86+
87+func swapContract () = "%s__swapContract"
10188
10289
10390 func fc () = "%s__factoryContract"
10491
10592
10693 func keyManagerPublicKey () = "%s__managerPublicKey"
10794
10895
10996 func keyManagerVaultAddress () = "%s__managerVaultAddress"
11097
11198
11299 func pl () = "%s%s__price__last"
113100
114101
115-func ph (h,t) = makeString(["%s%s%d%d__price__history", toString(h), toString(t)], SEP)
102+func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
116103
117104
118-func pau (ua,txId) = ((("%s%s%s__P__" + ua) + "__") + txId)
105+func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
119106
120107
121-func gau (ua,txId) = ((("%s%s%s__G__" + ua) + "__") + txId)
108+func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
122109
123110
124111 func aa () = "%s__amountAsset"
125112
126113
127114 func pa () = "%s__priceAsset"
128115
129116
130-func amp () = "%s__amp"
117+let keyFee = "%s__fee"
131118
132-
133-func keyAmpHistory (heightBlocks) = ("%s%d__amp__" + toString(heightBlocks))
134-
135-
136-func keyChangeAmpLastCall () = "%s__changeAmpLastCall"
137-
138-
139-let keyFee = "%s__fee"
119+let feeDefault = fraction(10, scale8, 10000)
140120
141121 let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
142122
143-let keyDLp = makeString(["%s", "dLp"], SEP)
123+let keyKLp = makeString(["%s", "kLp"], SEP)
144124
145-let keyDLpRefreshedHeight = makeString(["%s", "dLpRefreshedHeight"], SEP)
125+let keyKLpRefreshedHeight = makeString(["%s", "kLpRefreshedHeight"], SEP)
146126
147-let keyDLpRefreshDelay = makeString(["%s", "refreshDLpDelay"], SEP)
127+let keyKLpRefreshDelay = makeString(["%s", "refreshKLpDelay"], SEP)
148128
149-let dLpRefreshDelayDefault = 30
129+let kLpRefreshDelayDefault = 30
150130
151-let dLpRefreshDelay = valueOrElse(getInteger(this, keyDLpRefreshDelay), dLpRefreshDelayDefault)
131+let kLpRefreshDelay = valueOrElse(getInteger(this, keyKLpRefreshDelay), kLpRefreshDelayDefault)
152132
153-func fcfg () = "%s__factoryConfig"
133+func keyAdditionalBalance (assetId) = makeString(["%s%s", "stakedBalance", assetId], SEP)
154134
155135
156-func mtpk () = "%s%s__matcher__publicKey"
136+func keyStakingAssetBalance (assetId) = makeString(["%s%s", "shareAssetBalance", assetId], SEP)
157137
158138
159-func pc (iAmtAs,iPrAs) = (((("%d%d%s__" + iAmtAs) + "__") + iPrAs) + "__config")
139+func getAdditionalBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyAdditionalBalance(assetId)), 0)
160140
161141
162-func mba (bAStr) = ("%s%s%s__mappings__baseAsset2internalId__" + bAStr)
142+func getStakingAssetBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyStakingAssetBalance(assetId)), 0)
163143
164144
165-func aps () = "%s__shutdown"
145+func keyFactoryConfig () = "%s__factoryConfig"
166146
167147
168-func keyAllowedLpStableScriptHash () = "%s__allowedLpStableScriptHash"
148+func keyMatcherPub () = "%s%s__matcher__publicKey"
169149
170150
171-func keyFeeCollectorAddress () = "%s__feeCollectorAddress"
151+func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
172152
153+
154+func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
155+
156+
157+func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
158+
159+
160+func keyAllPoolsShutdown () = "%s__shutdown"
161+
162+
163+func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
164+
165+
166+func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
167+
168+
169+let keyFeeCollectorAddress = "%s__feeCollectorAddress"
173170
174171 func keySkipOrderValidation (poolAddress) = ("%s%s__skipOrderValidation__" + poolAddress)
175172
176173
177174 func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
178175
179176
180177 func addressFromStringOrThis (addressString) = match addressFromString(addressString) {
181178 case a: Address =>
182179 a
183180 case _ =>
184181 this
185182 }
186183
187184
188185 func getManagerVaultAddressOrThis () = {
189186 let factoryAddress = match getString(fc()) {
190187 case fca: String =>
191188 addressFromStringOrThis(fca)
192189 case _ =>
193190 this
194191 }
195192 match getString(factoryAddress, keyManagerVaultAddress()) {
196193 case s: String =>
197194 addressFromStringOrThis(s)
198195 case _ =>
199196 this
200197 }
201198 }
202199
203200
204-func strf (addr,key) = valueOrErrorMessage(getString(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
201+func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
205202
206203
207-func intf (addr,key) = valueOrErrorMessage(getInteger(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
204+func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
208205
209206
210-func throwErr (msg) = throw(makeString(["lp_stable.ride:", msg], " "))
207+func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
211208
212209
213-func fmtErr (msg) = makeString(["lp_stable.ride:", msg], " ")
210+func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
214211
215212
216-let fca = addressFromStringValue(strf(this, fc()))
213+let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
214+
215+let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
217216
218217 let inFee = {
219- let @ = invoke(fca, "getInFeeREADONLY", [toString(this)], nil)
218+ let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
220219 if ($isInstanceOf(@, "Int"))
221220 then @
222221 else throw(($getType(@) + " couldn't be cast to Int"))
223222 }
224223
225224 let outFee = {
226- let @ = invoke(fca, "getOutFeeREADONLY", [toString(this)], nil)
225+ let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
227226 if ($isInstanceOf(@, "Int"))
228227 then @
229228 else throw(($getType(@) + " couldn't be cast to Int"))
230229 }
231230
232-let A = strf(this, amp())
233-
234-func igs () = valueOrElse(getBoolean(fca, aps()), false)
231+func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
235232
236233
237-func mp () = fromBase58String(strf(fca, mtpk()))
234+func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
238235
239236
240-let feeCollectorAddress = addressFromStringValue(strf(fca, keyFeeCollectorAddress()))
241-
242-func gpc () = {
243- let amtAs = strf(this, aa())
244- let priceAs = strf(this, pa())
245- let iPriceAs = intf(fca, mba(priceAs))
246- let iAmtAs = intf(fca, mba(amtAs))
247- split(strf(fca, pc(toString(iAmtAs), toString(iPriceAs))), SEP)
237+func getPoolConfig () = {
238+ let amtAsset = getStringOrFail(this, aa())
239+ let priceAsset = getStringOrFail(this, pa())
240+ let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
241+ let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
242+ split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
248243 }
249244
250245
251246 func parseAssetId (input) = if ((input == wavesString))
252247 then unit
253248 else fromBase58String(input)
254249
255250
256251 func assetIdToString (input) = if ((input == unit))
257252 then wavesString
258253 else toBase58String(value(input))
259254
260255
261-func parsePoolConfig (poolConfig) = $Tuple7(addressFromStringValue(poolConfig[idxPoolAddress]), parseIntValue(poolConfig[idxPoolSt]), fromBase58String(poolConfig[idxLPAsId]), parseAssetId(poolConfig[idxAmAsId]), parseAssetId(poolConfig[idxPrAsId]), parseIntValue(poolConfig[idxAmtAsDcm]), parseIntValue(poolConfig[idxPriceAsDcm]))
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]))
262257
263258
264-let poolConfigParsed = parsePoolConfig(gpc())
259+let poolConfigParsed = parsePoolConfig(getPoolConfig())
265260
266-let $t086088794 = poolConfigParsed
261+let $t095299695 = poolConfigParsed
267262
268-let cfgPoolAddress = $t086088794._1
263+let cfgPoolAddress = $t095299695._1
269264
270-let cfgPoolStatus = $t086088794._2
265+let cfgPoolStatus = $t095299695._2
271266
272-let cfgLpAssetId = $t086088794._3
267+let cfgLpAssetId = $t095299695._3
273268
274-let cfgAmountAssetId = $t086088794._4
269+let cfgAmountAssetId = $t095299695._4
275270
276-let cfgPriceAssetId = $t086088794._5
271+let cfgPriceAssetId = $t095299695._5
277272
278-let cfgAmountAssetDecimals = $t086088794._6
273+let cfgAmountAssetDecimals = $t095299695._6
279274
280-let cfgPriceAssetDecimals = $t086088794._7
275+let cfgPriceAssetDecimals = $t095299695._7
281276
282-func gfc () = split(strf(fca, fcfg()), SEP)
277+func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
283278
284279
285-let factoryConfig = gfc()
280+let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
286281
287-let stakingContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactStakCntr]), "Invalid staking contract address")
282+let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
288283
289-let slipageContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactSlippCntr]), "Invalid slipage contract address")
290-
291-let gwxContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactGwxRewCntr]), "Invalid gwx contract address")
292-
293-let restContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactoryRestCntr]), "Invalid gwx contract address")
294-
295-func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slipByUser,slippageReal,txHeight,txTimestamp,slipageAmAmt,slipagePrAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slipByUser), toString(slippageReal), toString(txHeight), toString(txTimestamp), toString(slipageAmAmt), toString(slipagePrAmt)], SEP)
284+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)
296285
297286
298287 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)
299288
300289
301-func getAccBalance (assetId) = if ((assetId == "WAVES"))
302- then wavesBalance(this).available
303- else assetBalance(this, fromBase58String(assetId))
304-
305-
306-func cpbi (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
307-
308-
309-func cpbir (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
310-
311-
312-func vad (A1,A2,slippage) = {
313- let diff = fraction((A1 - A2), scale8BigInt, A2)
314- let pass = ((slippage - abs(diff)) > zeroBigInt)
315- if (!(pass))
316- then throw(("Big slpg: " + toString(diff)))
317- else $Tuple2(pass, min([A1, A2]))
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])
318296 }
319297
320298
321-func vd (D1,D0,slpg) = {
322- let diff = fraction(D0, scale8BigInt, D1)
323- let fail = (slpg > diff)
324- if (if (fail)
325- then true
326- else (D0 > D1))
327- then throw(((((((toString(D0) + " ") + toString(D1)) + " ") + toString(diff)) + " ") + toString(slpg)))
328- else fail
299+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.")
329315 }
330316
331317
332-func pcp (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
333- let amtAsAmtX18 = t1(amAmt, amAssetDcm)
334- let prAsAmtX18 = t1(prAmt, prAssetDcm)
335- cpbi(prAsAmtX18, amtAsAmtX18)
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+ }
475+
476+
477+func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
478+ let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
479+ let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
480+ calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
336481 }
337482
338483
339484 func calcPrices (amAmt,prAmt,lpAmt) = {
340- let amtAsDcm = cfgAmountAssetDecimals
341- let prAsDcm = cfgPriceAssetDecimals
342- let priceX18 = pcp(amtAsDcm, prAsDcm, amAmt, prAmt)
343- let amAmtX18 = t1(amAmt, amtAsDcm)
344- let prAmtX18 = t1(prAmt, prAsDcm)
345- let lpAmtX18 = t1(lpAmt, scale8)
346- let lpPrInAmAsX18 = cpbi(amAmtX18, lpAmtX18)
347- let lpPrInPrAsX18 = cpbi(prAmtX18, lpAmtX18)
348-[priceX18, lpPrInAmAsX18, lpPrInPrAsX18]
485+ let cfg = getPoolConfig()
486+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
487+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
488+ let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
489+ let amAmtX18 = toX18(amAmt, amtAssetDcm)
490+ let prAmtX18 = toX18(prAmt, priceAssetDcm)
491+ let lpAmtX18 = toX18(lpAmt, scale8)
492+ let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
493+ let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
494+[priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
349495 }
350496
351497
352498 func calculatePrices (amAmt,prAmt,lpAmt) = {
353- let p = calcPrices(amAmt, prAmt, lpAmt)
354-[f1(p[0], scale8), f1(p[1], scale8), f1(p[2], scale8)]
499+ let prices = calcPrices(amAmt, prAmt, lpAmt)
500+[fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
501+ }
502+
503+
504+func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
505+ let cfg = getPoolConfig()
506+ let lpAssetId = cfg[idxPoolLPAssetId]
507+ let amAssetId = cfg[idxAmtAssetId]
508+ let prAssetId = cfg[idxPriceAssetId]
509+ let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
510+ let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
511+ let poolStatus = cfg[idxPoolStatus]
512+ let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
513+ if ((lpAssetId != pmtAssetId))
514+ then throw("Invalid asset passed.")
515+ else {
516+ let amBalance = getAccBalance(amAssetId)
517+ let amBalanceX18 = toX18(amBalance, amAssetDcm)
518+ let prBalance = getAccBalance(prAssetId)
519+ let prBalanceX18 = toX18(prBalance, prAssetDcm)
520+ let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
521+ let curPrice = fromX18(curPriceX18, scale8)
522+ let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
523+ let lpEmissionX18 = toX18(lpEmission, scale8)
524+ let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
525+ let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
526+ let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
527+ let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
528+ let state = if ((txId58 == ""))
529+ then nil
530+ else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
531+ then unit
532+ else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
533+ then unit
534+ 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)]
535+ $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
536+ }
537+ }
538+
539+
540+func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
541+ let cfg = getPoolConfig()
542+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
543+ let amAssetIdStr = cfg[idxAmtAssetId]
544+ let prAssetIdStr = cfg[idxPriceAssetId]
545+ let iAmtAssetId = cfg[idxIAmtAssetId]
546+ let iPriceAssetId = cfg[idxIPriceAssetId]
547+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
548+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
549+ let poolStatus = cfg[idxPoolStatus]
550+ let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
551+ let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
552+ let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
553+ if (if ((amAssetIdStr != inAmAssetIdStr))
554+ then true
555+ else (prAssetIdStr != inPrAssetIdStr))
556+ then throw("Invalid amt or price asset passed.")
557+ else {
558+ let amBalance = if (isEvaluate)
559+ then getAccBalance(amAssetIdStr)
560+ else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
561+ let prBalance = if (isEvaluate)
562+ then getAccBalance(prAssetIdStr)
563+ else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
564+ let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
565+ let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
566+ let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
567+ let amBalanceX18 = toX18(amBalance, amtAssetDcm)
568+ let prBalanceX18 = toX18(prBalance, priceAssetDcm)
569+ let res = if ((lpEmission == 0))
570+ then {
571+ let curPriceX18 = zeroBigInt
572+ let slippageX18 = zeroBigInt
573+ let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
574+ $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
575+ }
576+ else {
577+ let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
578+ let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
579+ let slippageToleranceX18 = toX18(slippageTolerance, scale8)
580+ if (if ((curPriceX18 != zeroBigInt))
581+ then (slippageX18 > slippageToleranceX18)
582+ else false)
583+ then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
584+ else {
585+ let lpEmissionX18 = toX18(lpEmission, scale8)
586+ let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
587+ let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
588+ let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
589+ then $Tuple2(amViaPrX18, inPrAssetAmtX18)
590+ else $Tuple2(inAmAssetAmtX18, prViaAmX18)
591+ let expAmtAssetAmtX18 = expectedAmts._1
592+ let expPriceAssetAmtX18 = expectedAmts._2
593+ let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
594+ $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
595+ }
596+ }
597+ let calcLpAmt = res._1
598+ let calcAmAssetPmt = res._2
599+ let calcPrAssetPmt = res._3
600+ let curPrice = fromX18(res._4, scale8)
601+ let slippageCalc = fromX18(res._5, scale8)
602+ if ((0 >= calcLpAmt))
603+ then throw("Invalid calculations. LP calculated is less than zero.")
604+ else {
605+ let emitLpAmt = if (!(emitLp))
606+ then 0
607+ else calcLpAmt
608+ let amDiff = (inAmAssetAmt - calcAmAssetPmt)
609+ let prDiff = (inPrAssetAmt - calcPrAssetPmt)
610+ 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))]
611+ $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
612+ }
613+ }
614+ }
615+
616+
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+
654+func validateMatcherOrderAllowed (order) = {
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
664+ if (if (if (isGlobalShutdown())
665+ then true
666+ else (cfgPoolStatus == PoolMatcherDisabled))
667+ then true
668+ else (cfgPoolStatus == PoolShutdown))
669+ then throw("Exchange operations disabled")
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+ }
683+ }
684+
685+
686+func commonGet (i) = if ((size(i.payments) != 1))
687+ then throw("exactly 1 payment is expected")
688+ else {
689+ let pmt = value(i.payments[0])
690+ let pmtAssetId = value(pmt.assetId)
691+ let pmtAmt = pmt.amount
692+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
693+ let outAmAmt = res._1
694+ let outPrAmt = res._2
695+ let poolStatus = parseIntValue(res._9)
696+ let state = res._10
697+ if (if (isGlobalShutdown())
698+ then true
699+ else (poolStatus == PoolShutdown))
700+ then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
701+ else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
702+ }
703+
704+
705+func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
706+ then throw("exactly 2 payments are expected")
707+ else {
708+ let amAssetPmt = value(i.payments[0])
709+ let prAssetPmt = value(i.payments[1])
710+ let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
711+ let poolStatus = parseIntValue(estPut._8)
712+ if (if (if (isGlobalShutdown())
713+ then true
714+ else (poolStatus == PoolPutDisabled))
715+ then true
716+ else (poolStatus == PoolShutdown))
717+ then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
718+ else estPut
719+ }
720+
721+
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.")
355737 }
356738
357739
358740 func takeFee (amount,fee) = {
359741 let feeAmount = if ((fee == 0))
360742 then 0
361743 else fraction(amount, fee, scale8)
362744 $Tuple2((amount - feeAmount), feeAmount)
363745 }
364746
365747
366-func getD (xp) = {
367- let xp0 = xp[0]
368- let xp1 = xp[1]
369- let s = (xp0 + xp1)
370- if ((s == big0))
371- then big0
372- else {
373- let a = parseIntValue(A)
374- let ann = (a * 2)
375- let p = fraction(xp0, xp1, big1)
376- let xp0_xp1_n_n = fraction(p, big4, big1)
377- let ann_s = fraction(toBigInt(ann), s, big1)
378- let ann_1 = toBigInt((ann - 1))
379- func calcDNext (d) = {
380- let dd = fraction(d, d, big1)
381- let ddd = fraction(dd, d, big1)
382- let dp = fraction(ddd, big1, xp0_xp1_n_n)
383- fraction((ann_s + fraction(dp, big2, big1)), d, (fraction(ann_1, d, big1) + fraction(big3, dp, big1)))
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)
384803 }
385-
386- func calc (acc,i) = if (acc._2)
387- then acc
388- else {
389- let d = acc._1
390- let dNext = calcDNext(d)
391- let dDiffRaw = (dNext - value(d))
392- let dDiff = if ((big0 > dDiffRaw))
393- then -(dDiffRaw)
394- else dDiffRaw
395- if ((big1 >= dDiff))
396- then $Tuple2(dNext, true)
397- else $Tuple2(dNext, false)
398- }
399-
400- let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
401- let $t01329913347 = {
402- let $l = arr
403- let $s = size($l)
404- let $acc0 = $Tuple2(s, false)
405- func $f0_1 ($a,$i) = if (($i >= $s))
406- then $a
407- else calc($a, $l[$i])
408-
409- func $f0_2 ($a,$i) = if (($i >= $s))
410- then $a
411- else throw("List size exceeds 17")
412-
413- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17)
414- }
415- let d = $t01329913347._1
416- let found = $t01329913347._2
417- if (found)
418- then d
419- else throw(("D calculation error, D = " + toString(d)))
420- }
421- }
422-
423-
424-func ego (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
425- let lpId = cfgLpAssetId
426- let amId = toBase58String(value(cfgAmountAssetId))
427- let prId = toBase58String(value(cfgPriceAssetId))
428- let amDcm = cfgAmountAssetDecimals
429- let prDcm = cfgPriceAssetDecimals
430- let sts = toString(cfgPoolStatus)
431- let lpEmiss = valueOrErrorMessage(assetInfo(lpId), "Wrong LP id").quantity
432- if ((toBase58String(lpId) != pmtAssetId))
433- then throw("Wrong pmt asset")
434- else {
435- let amBalance = getAccBalance(amId)
436- let amBalanceX18 = t1(amBalance, amDcm)
437- let prBalance = getAccBalance(prId)
438- let prBalanceX18 = t1(prBalance, prDcm)
439- let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
440- let curPrice = f1(curPriceX18, scale8)
441- let pmtLpAmtX18 = t1(pmtLpAmt, scale8)
442- let lpEmissX18 = t1(lpEmiss, scale8)
443- let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissX18)
444- let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissX18)
445- let outAmAmt = fromX18Round(outAmAmtX18, amDcm, FLOOR)
446- let outPrAmt = fromX18Round(outPrAmtX18, prDcm, FLOOR)
447- let state = if ((txId58 == ""))
448- then nil
449- else [ScriptTransfer(userAddress, outAmAmt, if ((amId == "WAVES"))
450- then unit
451- else fromBase58String(amId)), ScriptTransfer(userAddress, outPrAmt, if ((prId == "WAVES"))
452- then unit
453- else fromBase58String(prId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
454- $Tuple10(outAmAmt, outPrAmt, amId, prId, amBalance, prBalance, lpEmiss, curPriceX18, sts, state)
455- }
456- }
457-
458-
459-func epo (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEval,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
460- let lpId = cfgLpAssetId
461- let amIdStr = toBase58String(value(cfgAmountAssetId))
462- let prIdStr = toBase58String(value(cfgPriceAssetId))
463- let amtDcm = cfgAmountAssetDecimals
464- let priceDcm = cfgPriceAssetDecimals
465- let sts = toString(cfgPoolStatus)
466- let lpEm = valueOrErrorMessage(assetInfo(lpId), "Wr lp as").quantity
467- let amBalance = if (isEval)
468- then getAccBalance(amIdStr)
469- else if (if (isOneAsset)
470- then (pmtId == amIdStr)
471- else false)
472- then (getAccBalance(amIdStr) - pmtAmt)
473- else if (isOneAsset)
474- then getAccBalance(amIdStr)
475- else (getAccBalance(amIdStr) - inAmAmt)
476- let prBalance = if (isEval)
477- then getAccBalance(prIdStr)
478- else if (if (isOneAsset)
479- then (pmtId == prIdStr)
480- else false)
481- then (getAccBalance(prIdStr) - pmtAmt)
482- else if (isOneAsset)
483- then getAccBalance(prIdStr)
484- else (getAccBalance(prIdStr) - inPrAmt)
485- let inAmAssetAmtX18 = t1(inAmAmt, amtDcm)
486- let inPrAssetAmtX18 = t1(inPrAmt, priceDcm)
487- let userPriceX18 = cpbi(inPrAssetAmtX18, inAmAssetAmtX18)
488- let amBalanceX18 = t1(amBalance, amtDcm)
489- let prBalanceX18 = t1(prBalance, priceDcm)
490- let D0 = getD([amBalanceX18, prBalanceX18])
491- let r = if ((lpEm == 0))
492- then {
493- let D1 = getD([(amBalanceX18 + inAmAssetAmtX18), (prBalanceX18 + inPrAssetAmtX18)])
494- let checkD = if ((D1 > D0))
495- then true
496- else throw("D1 should be greater than D0")
497- if ((checkD == checkD))
498- then {
499- let curPriceX18 = zeroBigInt
500- let slippageX18 = zeroBigInt
501- let lpAmtX18 = D1
502- $Tuple5(f1(lpAmtX18, scale8), f1(inAmAssetAmtX18, amtDcm), f1(inPrAssetAmtX18, priceDcm), cpbi((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
503- }
504- else throw("Strict value is not equal to itself.")
505- }
506- else {
507- let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
508- let slippageRealX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
509- let slippageX18 = t1(slippage, scale8)
510- if (if (if (validateSlippage)
511- then (curPriceX18 != zeroBigInt)
512- else false)
513- then (slippageRealX18 > slippageX18)
514- else false)
515- then throw(((("Price slippage " + toString(slippageRealX18)) + " > ") + toString(slippageX18)))
516- else {
517- let lpEmissionX18 = t1(lpEm, scale8)
518- let prViaAmX18 = fraction(inAmAssetAmtX18, cpbir(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
519- let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, cpbir(prBalanceX18, amBalanceX18, FLOOR), CEILING)
520- let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
521- then $Tuple2(amViaPrX18, inPrAssetAmtX18)
522- else $Tuple2(inAmAssetAmtX18, prViaAmX18)
523- let expAmtAssetAmtX18 = expectedAmts._1
524- let expPriceAssetAmtX18 = expectedAmts._2
525- let D1 = getD([(amBalanceX18 + expAmtAssetAmtX18), (prBalanceX18 + expPriceAssetAmtX18)])
526- let checkD = if ((D1 > D0))
527- then true
528- else throw("D1 should be greater than D0")
529- if ((checkD == checkD))
530- then {
531- let lpAmtX18 = fraction(lpEmissionX18, (D1 - D0), D0)
532- $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceDcm, CEILING), curPriceX18, slippageX18)
533- }
534- else throw("Strict value is not equal to itself.")
535- }
536- }
537- let calcLpAmt = r._1
538- let calcAmAssetPmt = r._2
539- let calcPrAssetPmt = r._3
540- let curPrice = f1(r._4, scale8)
541- let slippageCalc = f1(r._5, scale8)
542- if ((0 >= calcLpAmt))
543- then throw("LP <= 0")
544- else {
545- let emitLpAmt = if (!(emitLp))
546- then 0
547- else calcLpAmt
548- let amDiff = (inAmAmt - calcAmAssetPmt)
549- let prDiff = (inPrAmt - calcPrAssetPmt)
550- let $t02110921454 = if (if (isOneAsset)
551- then (pmtId == amIdStr)
552- else false)
553- then $Tuple2(pmtAmt, 0)
554- else if (if (isOneAsset)
555- then (pmtId == prIdStr)
556- else false)
557- then $Tuple2(0, pmtAmt)
558- else $Tuple2(calcAmAssetPmt, calcPrAssetPmt)
559- let writeAmAmt = $t02110921454._1
560- let writePrAmt = $t02110921454._2
561- let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(writeAmAmt, writePrAmt, emitLpAmt, curPrice, slippage, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
562- $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEm, lpId, sts, commonState, amDiff, prDiff, inAmId, inPrId)
563- }
564- }
565-
566-
567-func getYD (xp,i,D) = {
568- let n = big2
569- let x = xp[if ((i == 0))
570- then 1
571- else 0]
572- let aPrecision = parseBigIntValue(Amult)
573- let a = (parseBigIntValue(A) * aPrecision)
574- let s = x
575- let ann = (a * n)
576- let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
577- let b = ((s + ((D * aPrecision) / ann)) - D)
578- func calc (acc,cur) = {
579- let $t02264922669 = acc
580- let y = $t02264922669._1
581- let found = $t02264922669._2
582- if ((found != unit))
583- then acc
584- else {
585- let yNext = (((y * y) + c) / ((big2 * y) + b))
586- let yDiff = absBigInt((yNext - value(y)))
587- if ((big1 >= yDiff))
588- then $Tuple2(yNext, cur)
589- else $Tuple2(yNext, unit)
590- }
591- }
592-
593- let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
594- let $t02297623023 = {
595- let $l = arr
596- let $s = size($l)
597- let $acc0 = $Tuple2(D, unit)
598- func $f0_1 ($a,$i) = if (($i >= $s))
599- then $a
600- else calc($a, $l[$i])
601-
602- func $f0_2 ($a,$i) = if (($i >= $s))
603- then $a
604- else throw("List size exceeds 15")
605-
606- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
607- }
608- let y = $t02297623023._1
609- let found = $t02297623023._2
610- if ((found != unit))
611- then y
612- else throw(("Y calculation error, Y = " + toString(y)))
613- }
614-
615-
616-func calcDLp (amountBalance,priceBalance,lpEmission) = {
617- let updatedDLp = fraction(getD([t1BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals)), t1BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))]), scale18, lpEmission)
618- if ((lpEmission == big0))
619- then big0
620- else updatedDLp
621- }
622-
623-
624-func calcCurrentDLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
625- let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
626- let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
627- let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
628- let currentDLp = calcDLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
629- currentDLp
630- }
631-
632-
633-func refreshDLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
634- let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
635- let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
636- let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
637- let updatedDLp = calcDLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
638- let actions = [IntegerEntry(keyDLpRefreshedHeight, height), StringEntry(keyDLp, toString(updatedDLp))]
639- $Tuple2(actions, updatedDLp)
640- }
641-
642-
643-func validateUpdatedDLp (oldDLp,updatedDLp) = if ((updatedDLp >= oldDLp))
644- then true
645- else throwErr("updated DLp lower than current DLp")
646-
647-
648-func validateMatcherOrderAllowed (order) = {
649- let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
650- let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
651- let amountAssetAmount = order.amount
652- let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
653- let $t02522125433 = if ((order.orderType == Buy))
654- then $Tuple2(amountAssetAmount, -(priceAssetAmount))
655- else $Tuple2(-(amountAssetAmount), priceAssetAmount)
656- let amountAssetBalanceDelta = $t02522125433._1
657- let priceAssetBalanceDelta = $t02522125433._2
658- if (if (if (igs())
659- then true
660- else (cfgPoolStatus == PoolMatcherDis))
661- then true
662- else (cfgPoolStatus == PoolShutdown))
663- then throw("Admin blocked")
664- else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
665- then true
666- else (order.assetPair.priceAsset != cfgPriceAssetId))
667- then throw("Wr assets")
668- else {
669- let dLp = parseBigIntValue(valueOrElse(getString(this, keyDLp), "0"))
670- let $t02577525875 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
671- let unusedActions = $t02577525875._1
672- let dLpNew = $t02577525875._2
673- let isOrderValid = (dLpNew >= dLp)
674- let info = makeString(["dLp=", toString(dLp), " dLpNew=", toString(dLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
675- $Tuple2(isOrderValid, info)
676- }
677- }
678-
679-
680-func cg (i) = if ((size(i.payments) != 1))
681- then throw("1 pmnt exp")
682- else {
683- let pmt = value(i.payments[0])
684- let pmtAssetId = value(pmt.assetId)
685- let pmtAmt = pmt.amount
686- let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
687- let outAmAmt = r._1
688- let outPrAmt = r._2
689- let sts = parseIntValue(r._9)
690- let state = r._10
691- if (if (igs())
692- then true
693- else (sts == PoolShutdown))
694- then throw(("Admin blocked: " + toString(sts)))
695- else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
696- }
697-
698-
699-func cp (caller,txId,amAsPmt,prAsPmt,slippage,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
700- let r = epo(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, (txId == ""), emitLp, isOneAsset, validateSlippage, pmtAmt, pmtId)
701- let sts = parseIntValue(r._8)
702- if (if (if (igs())
703- then true
704- else (sts == PoolPutDis))
705- then true
706- else (sts == PoolShutdown))
707- then throw(("Blocked:" + toString(sts)))
708- else r
709- }
710-
711-
712-func calcPutOneTkn (pmtAmtRaw,pmtAssetId,userAddress,txId,withTakeFee) = {
713- let amId = toBase58String(value(cfgAmountAssetId))
714- let prId = toBase58String(value(cfgPriceAssetId))
715- let lpId = cfgLpAssetId
716- let amtDcm = cfgAmountAssetDecimals
717- let priceDcm = cfgPriceAssetDecimals
718- let lpAssetEmission = toBigInt(valueOrErrorMessage(assetInfo(lpId), "invalid lp asset").quantity)
719- let chechEmission = if ((lpAssetEmission > big0))
720- then true
721- else throw("initial deposit requires all coins")
722- if ((chechEmission == chechEmission))
723- then {
724- let amBalance = getAccBalance(amId)
725- let prBalance = getAccBalance(prId)
726- let $t02853128993 = if ((txId == ""))
727- then $Tuple2(amBalance, prBalance)
728- else if ((pmtAssetId == amId))
729- then if ((pmtAmtRaw > amBalance))
730- then throw("invalid payment amount")
731- else $Tuple2((amBalance - pmtAmtRaw), prBalance)
732- else if ((pmtAssetId == prId))
733- then if ((pmtAmtRaw > prBalance))
734- then throw("invalid payment amount")
735- else $Tuple2(amBalance, (prBalance - pmtAmtRaw))
736- else throw("wrong pmtAssetId")
737- let amBalanceOld = $t02853128993._1
738- let prBalanceOld = $t02853128993._2
739- let $t02899929175 = if ((pmtAssetId == amId))
740- then $Tuple2(pmtAmtRaw, 0)
741- else if ((pmtAssetId == prId))
742- then $Tuple2(0, pmtAmtRaw)
743- else throw("invalid payment")
744- let amAmountRaw = $t02899929175._1
745- let prAmountRaw = $t02899929175._2
746- let $t02917929433 = if (withTakeFee)
747- then $Tuple3(takeFee(amAmountRaw, inFee)._1, takeFee(prAmountRaw, inFee)._1, takeFee(pmtAmtRaw, inFee)._2)
748- else $Tuple3(amAmountRaw, prAmountRaw, 0)
749- let amAmount = $t02917929433._1
750- let prAmount = $t02917929433._2
751- let feeAmount = $t02917929433._3
752- let amBalanceNew = (amBalanceOld + amAmount)
753- let prBalanceNew = (prBalanceOld + prAmount)
754- let D0 = getD([t1(amBalanceOld, cfgAmountAssetDecimals), t1(prBalanceOld, cfgPriceAssetDecimals)])
755- let D1 = getD([t1(amBalanceNew, cfgAmountAssetDecimals), t1(prBalanceNew, cfgPriceAssetDecimals)])
756- let checkD = if ((D1 > D0))
757- then true
758- else throw()
759- if ((checkD == checkD))
760- then {
761- let lpAmount = fraction(lpAssetEmission, (D1 - D0), D0, FLOOR)
762- let curPrice = f1(cpbi(t1(prBalanceNew, priceDcm), t1(amBalanceNew, amtDcm)), scale8)
763- let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId), dataPutActionInfo(amAmountRaw, prAmountRaw, toInt(lpAmount), curPrice, 0, 0, height, lastBlock.timestamp, 0, 0))]
764- let poolProportion = fraction(prBalanceOld, scale8, amBalanceOld)
765- let amountAssetPart = fraction(pmtAmtRaw, scale8, (poolProportion + scale8))
766- let priceAssetPart = (pmtAmtRaw - amountAssetPart)
767- let lpAmtBoth = fraction(lpAssetEmission, toBigInt(priceAssetPart), toBigInt(prBalanceOld))
768- let bonus = toInt(fraction((lpAmount - lpAmtBoth), scale8BigInt, lpAmtBoth))
769- $Tuple4(toInt(lpAmount), commonState, feeAmount, bonus)
770- }
771- else throw("Strict value is not equal to itself.")
804+ $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
772805 }
773806 else throw("Strict value is not equal to itself.")
774807 }
775808
776809
777-func getOneTknV2Internal (outAssetId,minOutAmount,payments,caller,originCaller,transactionId) = {
778- let lpId = toBase58String(value(cfgLpAssetId))
779- let amId = toBase58String(value(cfgAmountAssetId))
780- let prId = toBase58String(value(cfgPriceAssetId))
781- let amDecimals = cfgAmountAssetDecimals
782- let prDecimals = cfgPriceAssetDecimals
783- let poolStatus = cfgPoolStatus
784- let userAddress = if ((caller == restContract))
785- then originCaller
786- else caller
787- let pmt = value(payments[0])
788- let pmtAssetId = value(pmt.assetId)
789- let pmtAmt = pmt.amount
790- let currentDLp = calcCurrentDLp(big0, big0, big0)
791- if ((currentDLp == currentDLp))
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))
792819 then {
793- let txId58 = toBase58String(transactionId)
794- if ((lpId != toBase58String(pmtAssetId)))
795- then throw("Wrong LP")
796- else {
797- let amBalance = getAccBalance(amId)
798- let prBalance = getAccBalance(prId)
799- let $t03154531656 = {
800- let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, pmtAmt], nil)
801- if ($isInstanceOf(@, "(Int, Int)"))
802- then @
803- else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
804- }
805- if (($t03154531656 == $t03154531656))
806- then {
807- let feeAmount = $t03154531656._2
808- let totalGet = $t03154531656._1
809- let totalAmount = if (if ((minOutAmount > 0))
810- then (minOutAmount > totalGet)
811- else false)
812- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
813- else totalGet
814- let $t03184632153 = if ((outAssetId == amId))
815- then $Tuple4(totalAmount, 0, ((amBalance - totalAmount) - feeAmount), prBalance)
816- else if ((outAssetId == prId))
817- then $Tuple4(0, totalAmount, amBalance, ((prBalance - totalAmount) - feeAmount))
818- else throw("invalid out asset id")
819- let outAm = $t03184632153._1
820- let outPr = $t03184632153._2
821- let amBalanceNew = $t03184632153._3
822- let prBalanceNew = $t03184632153._4
823- let curPrX18 = cpbi(t1(prBalanceNew, prDecimals), t1(amBalanceNew, amDecimals))
824- let curPr = f1(curPrX18, scale8)
825- let outAssetIdOrWaves = if ((outAssetId == "WAVES"))
826- then unit
827- else fromBase58String(outAssetId)
828- let sendFeeToMatcher = if ((feeAmount > 0))
829- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetIdOrWaves)]
830- else nil
831- let state = ([ScriptTransfer(userAddress, totalAmount, outAssetIdOrWaves), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, pmtAmt, curPr, height, lastBlock.timestamp)), IntegerEntry(pl(), curPr), IntegerEntry(ph(height, lastBlock.timestamp), curPr)] ++ sendFeeToMatcher)
832- if ((state == state))
833- then {
834- let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
835- if ((burn == burn))
836- then {
837- let $t03293833288 = {
838- let feeAmountForCalc = if ((this == feeCollectorAddress))
839- then 0
840- else feeAmount
841- let outInAmountAsset = if ((parseAssetId(outAssetId) == cfgAmountAssetId))
842- then true
843- else false
844- if (outInAmountAsset)
845- then $Tuple2(-((totalGet + feeAmountForCalc)), 0)
846- else $Tuple2(0, -((totalGet + feeAmountForCalc)))
847- }
848- let amountAssetBalanceDelta = $t03293833288._1
849- let priceAssetBalanceDelta = $t03293833288._2
850- let $t03329133399 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
851- let refreshDLpActions = $t03329133399._1
852- let updatedDLp = $t03329133399._2
853- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
854- if ((isUpdatedDLpValid == isUpdatedDLpValid))
855- then $Tuple2((state ++ refreshDLpActions), totalAmount)
856- else throw("Strict value is not equal to itself.")
857- }
858- else throw("Strict value is not equal to itself.")
859- }
860- else throw("Strict value is not equal to itself.")
861- }
862- else throw("Strict value is not equal to itself.")
863- }
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)
864862 }
865863 else throw("Strict value is not equal to itself.")
866864 }
867865
868866
869867 func managerPublicKeyOrUnit () = {
870868 let managerVaultAddress = getManagerVaultAddressOrThis()
871869 match getString(managerVaultAddress, keyManagerPublicKey()) {
872870 case s: String =>
873871 fromBase58String(s)
874872 case _: Unit =>
875873 unit
876874 case _ =>
877875 throw("Match error")
878876 }
879877 }
880878
881879
882-let pd = throw("Permission denied")
883-
884880 func isManager (i) = match managerPublicKeyOrUnit() {
885881 case pk: ByteVector =>
886882 (i.callerPublicKey == pk)
887883 case _: Unit =>
888884 (i.caller == this)
889885 case _ =>
890886 throw("Match error")
891887 }
892888
893889
894-func mustManager (i) = match managerPublicKeyOrUnit() {
895- case pk: ByteVector =>
896- if ((i.callerPublicKey == pk))
897- then true
898- else pd
899- case _: Unit =>
900- if ((i.caller == this))
901- then true
902- else pd
903- case _ =>
904- throw("Match error")
905-}
906-
907-
908-func getY (isReverse,D,poolAmountInBalance) = {
909- let poolConfig = gpc()
910- let amId = poolConfig[idxAmAsId]
911- let prId = poolConfig[idxPrAsId]
912- let n = big2
913- let aPrecision = parseBigIntValue(Amult)
914- let a = (parseBigIntValue(A) * aPrecision)
915- let xp = if ((isReverse == false))
916- then [(toBigInt(getAccBalance(amId)) + poolAmountInBalance), toBigInt(getAccBalance(prId))]
917- else [(toBigInt(getAccBalance(prId)) + poolAmountInBalance), toBigInt(getAccBalance(amId))]
918- let x = xp[0]
919- let s = x
920- let ann = (a * n)
921- let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
922- let b = ((s + ((D * aPrecision) / ann)) - D)
923- func calc (acc,cur) = {
924- let $t03488634906 = acc
925- let y = $t03488634906._1
926- let found = $t03488634906._2
927- if ((found != unit))
928- then acc
929- else {
930- let yNext = (((y * y) + c) / ((big2 * y) + b))
931- let yDiff = absBigInt((yNext - value(y)))
932- if ((big1 >= yDiff))
933- then $Tuple2(yNext, cur)
934- else $Tuple2(yNext, unit)
935- }
936- }
937-
938- let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
939- let $t03523735284 = {
940- let $l = arr
941- let $s = size($l)
942- let $acc0 = $Tuple2(D, unit)
943- func $f0_1 ($a,$i) = if (($i >= $s))
944- then $a
945- else calc($a, $l[$i])
946-
947- func $f0_2 ($a,$i) = if (($i >= $s))
948- then $a
949- else throw("List size exceeds 15")
950-
951- $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
952- }
953- let y = $t03523735284._1
954- let found = $t03523735284._2
955- if ((found != unit))
956- then y
957- else throw(("Y calculation error, Y = " + toString(y)))
890+func mustManager (i) = {
891+ let pd = throw("Permission denied")
892+ match managerPublicKeyOrUnit() {
893+ case pk: ByteVector =>
894+ if ((i.callerPublicKey == pk))
895+ then true
896+ else pd
897+ case _: Unit =>
898+ if ((i.caller == this))
899+ then true
900+ else pd
901+ case _ =>
902+ throw("Match error")
903+ }
958904 }
959905
960906
961-func skipOrderValidation () = valueOrElse(getBoolean(fca, keySkipOrderValidation(toString(this))), false)
907+@Callable(i)
908+func rebalance () = (rebalanceAsset(getStringOrFail(this, aa())) ++ rebalanceAsset(getStringOrFail(this, pa())))
909+
962910
963911
964912 @Callable(i)
965913 func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse,feePoolAmount) = {
966- let $t03563636060 = if ((isReverse == false))
914+ let $t03956839873 = if ((isReverse == false))
967915 then {
968- let assetOut = strf(this, pa())
969- let poolAmountInBalance = (toBigInt(getAccBalance(strf(this, aa()))) + toBigInt(cleanAmountIn))
970- $Tuple2(assetOut, poolAmountInBalance)
916+ let assetOut = getStringOrFail(this, pa())
917+ let assetIn = getStringOrFail(this, aa())
918+ $Tuple2(assetOut, assetIn)
971919 }
972920 else {
973- let assetOut = strf(this, aa())
974- let poolAmountInBalance = (toBigInt(getAccBalance(strf(this, pa()))) + toBigInt(cleanAmountIn))
975- $Tuple2(assetOut, poolAmountInBalance)
921+ let assetOut = getStringOrFail(this, aa())
922+ let assetIn = getStringOrFail(this, pa())
923+ $Tuple2(assetOut, assetIn)
976924 }
977- let assetOut = $t03563636060._1
978- let poolAmountInBalance = $t03563636060._2
979- let poolConfig = gpc()
980- let amId = poolConfig[idxAmAsId]
981- let prId = poolConfig[idxPrAsId]
982- let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
983- let D = getD(xp)
984- let y = getY(isReverse, D, toBigInt(cleanAmountIn))
985- let dy = ((toBigInt(getAccBalance(assetOut)) - y) - toBigInt(1))
986- let totalGetRaw = max([0, toInt(dy)])
987- let newXp = if ((isReverse == false))
988- then [((toBigInt(getAccBalance(amId)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)), (toBigInt(getAccBalance(prId)) - dy)]
989- else [(toBigInt(getAccBalance(amId)) - dy), ((toBigInt(getAccBalance(prId)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount))]
990- let newD = getD(newXp)
991- let checkD = if ((newD >= D))
925+ let assetOut = $t03956839873._1
926+ let assetIn = $t03956839873._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))
992933 then true
993- else throw(makeString(["new D is fewer error", toString(D), toString(newD)], "__"))
994- if ((checkD == checkD))
995- then $Tuple2(nil, totalGetRaw)
934+ else throw("new K is fewer error")
935+ if ((checkK == checkK))
936+ then $Tuple2(nil, amountOut)
996937 else throw("Strict value is not equal to itself.")
997938 }
998939
999940
1000941
1001942 @Callable(i)
1002943 func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo,feePoolAmount) = {
1003944 let swapContact = {
1004- let @ = invoke(fca, "getSwapContractREADONLY", nil, nil)
945+ let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil)
1005946 if ($isInstanceOf(@, "String"))
1006947 then @
1007948 else throw(($getType(@) + " couldn't be cast to String"))
1008949 }
1009950 let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
1010951 then true
1011952 else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
1012953 then true
1013954 else throwErr("Permission denied")]
1014955 if ((checks == checks))
1015956 then {
1016957 let pmt = value(i.payments[0])
1017958 let assetIn = assetIdToString(pmt.assetId)
1018- let $t03749637890 = if ((isReverse == false))
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) - feePoolAmount)
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))
1019971 then {
1020- let assetOut = strf(this, pa())
1021- let poolAmountInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
1022- $Tuple2(assetOut, poolAmountInBalance)
1023- }
1024- else {
1025- let assetOut = strf(this, aa())
1026- let poolAmountInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
1027- $Tuple2(assetOut, poolAmountInBalance)
1028- }
1029- let assetOut = $t03749637890._1
1030- let poolAmountInBalance = $t03749637890._2
1031- let poolConfig = gpc()
1032- let amId = poolConfig[idxAmAsId]
1033- let prId = poolConfig[idxPrAsId]
1034- let xp = if ((isReverse == false))
1035- then [(toBigInt(getAccBalance(amId)) - toBigInt(value(i.payments[0]).amount)), toBigInt(getAccBalance(prId))]
1036- else [toBigInt(getAccBalance(amId)), (toBigInt(getAccBalance(prId)) - toBigInt(value(i.payments[0]).amount))]
1037- let D = getD(xp)
1038- let y = getY(isReverse, D, toBigInt(0))
1039- let dy = ((toBigInt(getAccBalance(assetOut)) - y) - toBigInt(1))
1040- let totalGetRaw = max([0, toInt(dy)])
1041- let checkMin = if ((totalGetRaw >= amountOutMin))
1042- then true
1043- else throw("Exchange result is fewer coins than expected")
1044- if ((checkMin == checkMin))
1045- then {
1046- let newXp = if ((isReverse == false))
1047- then [(toBigInt(getAccBalance(amId)) + toBigInt(feePoolAmount)), (toBigInt(getAccBalance(prId)) - dy)]
1048- else [(toBigInt(getAccBalance(amId)) - dy), (toBigInt(getAccBalance(prId)) + toBigInt(feePoolAmount))]
1049- let newD = getD(newXp)
1050- let checkD = if ((newD >= D))
972+ let checkMin = if ((amountOut >= amountOutMin))
1051973 then true
1052- else throw("new D is fewer error")
1053- if ((checkD == checkD))
1054- then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), totalGetRaw, parseAssetId(assetOut))], totalGetRaw)
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+ }
1055987 else throw("Strict value is not equal to itself.")
1056988 }
1057989 else throw("Strict value is not equal to itself.")
1058990 }
1059991 else throw("Strict value is not equal to itself.")
1060992 }
1061993
1062994
1063995
1064996 @Callable(i)
1065-func constructor (fc) = {
1066- let c = mustManager(i)
1067- if ((c == c))
1068- then [StringEntry(fc(), fc)]
1069- else throw("Strict value is not equal to itself.")
1070- }
1071-
1072-
1073-
1074-@Callable(i)
1075-func put (slip,autoStake) = {
1076- let factCfg = gfc()
1077- let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Wr st addr")
1078- let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Wr sl addr")
1079- if ((0 > slip))
1080- then throw("Wrong slippage")
1081- else if ((size(i.payments) != 2))
1082- then throw("2 pmnts expd")
1083- else {
1084- let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1085- let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1086- let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amAssetPmt)
1087- if ((amountAssetBalance == amountAssetBalance))
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))
10881015 then {
1089- let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - prAssetPmt)
1090- if ((priceAssetBalance == priceAssetBalance))
1016+ let emitInvLegacy = match emitInv {
1017+ case legacyFactoryContract: Address =>
1018+ invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
1019+ case _ =>
1020+ unit
1021+ }
1022+ if ((emitInvLegacy == emitInvLegacy))
10911023 then {
1092- let lpAssetEmission = toBigInt(value(assetInfo(cfgLpAssetId)).quantity)
1093- if ((lpAssetEmission == lpAssetEmission))
1024+ let slippageAInv = if ((amDiff > 0))
1025+ then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
1026+ else nil
1027+ if ((slippageAInv == slippageAInv))
10941028 then {
1095- let currentDLp = calcCurrentDLp(amAssetPmt, prAssetPmt, toBigInt(0))
1096- if ((currentDLp == currentDLp))
1029+ let slippagePInv = if ((prDiff > 0))
1030+ then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
1031+ else nil
1032+ if ((slippagePInv == slippagePInv))
10971033 then {
1098- let e = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], slip, true, false, true, 0, "")
1099- let emitLpAmt = e._2
1100- let lpAssetId = e._7
1101- let state = e._9
1102- let amDiff = e._10
1103- let prDiff = e._11
1104- let amId = e._12
1105- let prId = e._13
1106- let r = invoke(fca, "emit", [emitLpAmt], nil)
1107- if ((r == r))
1034+ let lpTransfer = if (shouldAutoStake)
11081035 then {
1109- let el = match r {
1110- case legacy: Address =>
1111- invoke(legacy, "emit", [emitLpAmt], nil)
1112- case _ =>
1113- unit
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.")
11141040 }
1115- if ((el == el))
1041+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1042+ let $t04437644838 = refreshKLpInternal(0, 0, 0)
1043+ if (($t04437644838 == $t04437644838))
1044+ then {
1045+ let updatedKLp = $t04437644838._2
1046+ let refreshKLpActions = $t04437644838._1
1047+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1048+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
11161049 then {
1117- let sa = if ((amDiff > 0))
1118- then invoke(slipCntr, "put", nil, [AttachedPayment(amId, amDiff)])
1119- else nil
1120- if ((sa == sa))
1121- then {
1122- let sp = if ((prDiff > 0))
1123- then invoke(slipCntr, "put", nil, [AttachedPayment(prId, prDiff)])
1124- else nil
1125- if ((sp == sp))
1126- then {
1127- let lpTrnsfr = if (autoStake)
1128- then {
1129- let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
1130- if ((ss == ss))
1131- then nil
1132- else throw("Strict value is not equal to itself.")
1133- }
1134- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1135- let $t04203442176 = refreshDLpInternal(0, 0, 0)
1136- let refreshDLpActions = $t04203442176._1
1137- let updatedDLp = $t04203442176._2
1138- let check = if ((updatedDLp >= currentDLp))
1139- then true
1140- else throwErr(makeString(["updated DLp lower than current DLp", toString(amountAssetBalance), toString(priceAssetBalance), toString(lpAssetEmission), toString(currentDLp), toString(updatedDLp), toString(amDiff), toString(prDiff)], " "))
1141- if ((check == check))
1142- then {
1143- let lpAssetEmissionAfter = value(assetInfo(cfgLpAssetId)).quantity
1144- if ((lpAssetEmissionAfter == lpAssetEmissionAfter))
1145- then ((state ++ lpTrnsfr) ++ refreshDLpActions)
1146- else throw("Strict value is not equal to itself.")
1147- }
1148- else throw("Strict value is not equal to itself.")
1149- }
1150- else throw("Strict value is not equal to itself.")
1151- }
1050+ let reb = invoke(this, "rebalance", nil, nil)
1051+ if ((reb == reb))
1052+ then ((state ++ lpTransfer) ++ refreshKLpActions)
11521053 else throw("Strict value is not equal to itself.")
11531054 }
11541055 else throw("Strict value is not equal to itself.")
11551056 }
11561057 else throw("Strict value is not equal to itself.")
11571058 }
11581059 else throw("Strict value is not equal to itself.")
11591060 }
11601061 else throw("Strict value is not equal to itself.")
11611062 }
11621063 else throw("Strict value is not equal to itself.")
11631064 }
11641065 else throw("Strict value is not equal to itself.")
11651066 }
1166- }
1067+ else throw("Strict value is not equal to itself.")
1068+ }
11671069
11681070
11691071
11701072 @Callable(i)
1171-func putOneTknV2 (minOutAmount,autoStake) = {
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 $t04545045515 = refreshKLpInternal(0, 0, 0)
1084+ let refreshKLpActions = $t04545045515._1
1085+ let updatedKLp = $t04545045515._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) = {
11721098 let isPoolOneTokenOperationsDisabled = {
1173- let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1099+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
11741100 if ($isInstanceOf(@, "Boolean"))
11751101 then @
11761102 else throw(($getType(@) + " couldn't be cast to Boolean"))
11771103 }
1178- let isPutDisabled = if (if (if (igs())
1104+ let isPutDisabled = if (if (if (isGlobalShutdown())
11791105 then true
1180- else (cfgPoolStatus == PoolPutDis))
1106+ else (cfgPoolStatus == PoolPutDisabled))
11811107 then true
11821108 else (cfgPoolStatus == PoolShutdown))
11831109 then true
11841110 else isPoolOneTokenOperationsDisabled
11851111 let checks = [if (if (!(isPutDisabled))
11861112 then true
11871113 else isManager(i))
11881114 then true
11891115 else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
11901116 then true
11911117 else throwErr("exactly 1 payment are expected")]
11921118 if ((checks == checks))
11931119 then {
1194- let amId = toBase58String(value(cfgAmountAssetId))
1195- let prId = toBase58String(value(cfgPriceAssetId))
1196- let lpId = cfgLpAssetId
1197- let amDecimals = cfgAmountAssetDecimals
1198- let prDecimals = cfgPriceAssetDecimals
1199- let userAddress = if ((i.caller == this))
1200- then i.originCaller
1201- else i.caller
1202- let pmt = value(i.payments[0])
1203- let pmtAssetId = toBase58String(value(pmt.assetId))
1204- let pmtAmt = pmt.amount
1205- let currentDLp = if ((pmt.assetId == cfgAmountAssetId))
1206- then calcCurrentDLp(toBigInt(pmtAmt), toBigInt(0), toBigInt(0))
1207- else calcCurrentDLp(toBigInt(0), toBigInt(pmtAmt), toBigInt(0))
1208- if ((currentDLp == currentDLp))
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))
12091129 then {
1210- let $t04381743975 = calcPutOneTkn(pmtAmt, pmtAssetId, toString(userAddress), toBase58String(i.transactionId), true)
1211- if (($t04381743975 == $t04381743975))
1130+ let userAddress = i.caller
1131+ let txId = i.transactionId
1132+ let $t04670346855 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
1133+ if (($t04670346855 == $t04670346855))
12121134 then {
1213- let feeAmount = $t04381743975._3
1214- let state = $t04381743975._2
1215- let estimLP = $t04381743975._1
1216- let emitLpAmt = if (if ((minOutAmount > 0))
1217- then (minOutAmount > estimLP)
1135+ let paymentInAmountAsset = $t04670346855._5
1136+ let bonus = $t04670346855._4
1137+ let feeAmount = $t04670346855._3
1138+ let commonState = $t04670346855._2
1139+ let emitAmountEstimated = $t04670346855._1
1140+ let emitAmount = if (if ((minOutAmount > 0))
1141+ then (minOutAmount > emitAmountEstimated)
12181142 else false)
12191143 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1220- else estimLP
1221- let e = invoke(fca, "emit", [emitLpAmt], nil)
1222- if ((e == e))
1144+ else emitAmountEstimated
1145+ let emitInv = emit(emitAmount)
1146+ if ((emitInv == emitInv))
12231147 then {
1224- let el = match e {
1225- case legacy: Address =>
1226- invoke(legacy, "emit", [emitLpAmt], nil)
1227- case _ =>
1228- unit
1229- }
1230- if ((el == el))
1148+ let lpTransfer = if (autoStake)
12311149 then {
1232- let lpTrnsfr = if (autoStake)
1233- then {
1234- let ss = invoke(stakingContract, "stakeFor", [toString(i.caller)], [AttachedPayment(lpId, emitLpAmt)])
1235- if ((ss == ss))
1236- then nil
1237- else throw("Strict value is not equal to itself.")
1238- }
1239- else [ScriptTransfer(i.caller, emitLpAmt, lpId)]
1240- let sendFeeToMatcher = if ((feeAmount > 0))
1241- then [ScriptTransfer(feeCollectorAddress, feeAmount, fromBase58String(pmtAssetId))]
1242- else nil
1243- let $t04486045209 = if ((this == feeCollectorAddress))
1244- then $Tuple2(0, 0)
1245- else {
1246- let paymentInAmountAsset = if ((pmt.assetId == cfgAmountAssetId))
1247- then true
1248- else false
1249- if (paymentInAmountAsset)
1250- then $Tuple2(-(feeAmount), 0)
1251- else $Tuple2(0, -(feeAmount))
1252- }
1253- let amountAssetBalanceDelta = $t04486045209._1
1254- let priceAssetBalanceDelta = $t04486045209._2
1255- let $t04521245320 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1256- let refreshDLpActions = $t04521245320._1
1257- let updatedDLp = $t04521245320._2
1258- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1259- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1260- then $Tuple2((((state ++ lpTrnsfr) ++ sendFeeToMatcher) ++ refreshDLpActions), emitLpAmt)
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)]
1158+ else nil
1159+ let $t04744147638 = 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 = $t04744147638._1
1165+ let priceAssetBalanceDelta = $t04744147638._2
1166+ let $t04764147749 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1167+ let refreshKLpActions = $t04764147749._1
1168+ let updatedKLp = $t04764147749._2
1169+ let kLp = value(getString(keyKLp))
1170+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1171+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1172+ then {
1173+ let reb = invoke(this, "rebalance", nil, nil)
1174+ if ((reb == reb))
1175+ then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
12611176 else throw("Strict value is not equal to itself.")
12621177 }
12631178 else throw("Strict value is not equal to itself.")
12641179 }
12651180 else throw("Strict value is not equal to itself.")
12661181 }
12671182 else throw("Strict value is not equal to itself.")
12681183 }
12691184 else throw("Strict value is not equal to itself.")
12701185 }
12711186 else throw("Strict value is not equal to itself.")
12721187 }
12731188
12741189
12751190
12761191 @Callable(i)
1277-func putForFree (maxSlpg) = if ((0 > maxSlpg))
1278- then throw("Wrong slpg")
1279- else if ((size(i.payments) != 2))
1280- then throw("2 pmnts expd")
1281- else {
1282- let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], maxSlpg, false, false, true, 0, "")
1283- let state = estPut._9
1284- let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1285- let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1286- let currentDLp = calcCurrentDLp(amAssetPmt, prAssetPmt, toBigInt(0))
1287- if ((currentDLp == currentDLp))
1288- then {
1289- let $t04635046415 = refreshDLpInternal(0, 0, 0)
1290- let refreshDLpActions = $t04635046415._1
1291- let updatedDLp = $t04635046415._2
1292- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1293- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1294- then (state ++ refreshDLpActions)
1295- else throw("Strict value is not equal to itself.")
1296- }
1297- else throw("Strict value is not equal to itself.")
1298- }
1299-
1300-
1301-
1302-@Callable(i)
1303-func get () = {
1304- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1305- if ((currentDLp == currentDLp))
1306- then {
1307- let r = cg(i)
1308- let outAmtAmt = r._1
1309- let outPrAmt = r._2
1310- let pmtAmt = r._3
1311- let pmtAssetId = r._4
1312- let state = r._5
1313- let b = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1314- if ((b == b))
1315- then {
1316- let $t04758847670 = refreshDLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1317- let refreshDLpActions = $t04758847670._1
1318- let updatedDLp = $t04758847670._2
1319- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1320- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1321- then (state ++ refreshDLpActions)
1322- else throw("Strict value is not equal to itself.")
1323- }
1324- else throw("Strict value is not equal to itself.")
1325- }
1326- else throw("Strict value is not equal to itself.")
1192+func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
1193+ let $t04810448261 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
1194+ let emitAmountEstimated = $t04810448261._1
1195+ let commonState = $t04810448261._2
1196+ let feeAmount = $t04810448261._3
1197+ let bonus = $t04810448261._4
1198+ let paymentInAmountAsset = $t04810448261._5
1199+ $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
13271200 }
13281201
13291202
13301203
13311204 @Callable(i)
1332-func getOneTknV2 (outAssetId,minOutAmount) = {
1205+func getOneTkn (outAssetIdStr,minOutAmount) = {
13331206 let isPoolOneTokenOperationsDisabled = {
1334- let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1207+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
13351208 if ($isInstanceOf(@, "Boolean"))
13361209 then @
13371210 else throw(($getType(@) + " couldn't be cast to Boolean"))
13381211 }
1339- let isGetDisabled = if (if (igs())
1212+ let isGetDisabled = if (if (isGlobalShutdown())
13401213 then true
13411214 else (cfgPoolStatus == PoolShutdown))
13421215 then true
13431216 else isPoolOneTokenOperationsDisabled
13441217 let checks = [if (if (!(isGetDisabled))
13451218 then true
13461219 else isManager(i))
13471220 then true
13481221 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
13491222 then true
13501223 else throwErr("exactly 1 payment are expected")]
13511224 if ((checks == checks))
13521225 then {
1353- let $t04828848443 = getOneTknV2Internal(outAssetId, minOutAmount, i.payments, i.caller, i.originCaller, i.transactionId)
1354- let state = $t04828848443._1
1355- let totalAmount = $t04828848443._2
1356- $Tuple2(state, totalAmount)
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 $t04914649299 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1236+ if (($t04914649299 == $t04914649299))
1237+ then {
1238+ let outInAmountAsset = $t04914649299._5
1239+ let bonus = $t04914649299._4
1240+ let feeAmount = $t04914649299._3
1241+ let commonState = $t04914649299._2
1242+ let amountEstimated = $t04914649299._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 $t04996350210 = {
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 = $t04996350210._1
1265+ let priceAssetBalanceDelta = $t04996350210._2
1266+ let $t05021350321 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1267+ let refreshKLpActions = $t05021350321._1
1268+ let updatedKLp = $t05021350321._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.")
13571279 }
13581280 else throw("Strict value is not equal to itself.")
13591281 }
13601282
13611283
13621284
13631285 @Callable(i)
1364-func refreshDLp () = {
1365- let lastRefreshedBlockHeight = valueOrElse(getInteger(keyDLpRefreshedHeight), 0)
1366- let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= dLpRefreshDelay))
1367- then unit
1368- else throwErr(makeString([toString(dLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1369- if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
1286+func getOneTknREADONLY (outAssetId,paymentAmount) = {
1287+ let $t05059950755 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1288+ let amountEstimated = $t05059950755._1
1289+ let commonState = $t05059950755._2
1290+ let feeAmount = $t05059950755._3
1291+ let bonus = $t05059950755._4
1292+ let outInAmountAsset = $t05059950755._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))
13701319 then {
1371- let dLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyDLp), "0")), fmtErr("invalid dLp"))
1372- let $t04896749031 = refreshDLpInternal(0, 0, 0)
1373- let dLpUpdateActions = $t04896749031._1
1374- let updatedDLp = $t04896749031._2
1375- let actions = if ((dLp != updatedDLp))
1376- then dLpUpdateActions
1377- else throwErr("nothing to refresh")
1378- $Tuple2(actions, toString(updatedDLp))
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 $t05166051811 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1330+ if (($t05166051811 == $t05166051811))
1331+ then {
1332+ let outInAmountAsset = $t05166051811._5
1333+ let bonus = $t05166051811._4
1334+ let feeAmount = $t05166051811._3
1335+ let commonState = $t05166051811._2
1336+ let amountEstimated = $t05166051811._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 $t05247052717 = {
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 = $t05247052717._1
1359+ let priceAssetBalanceDelta = $t05247052717._2
1360+ let $t05272052828 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1361+ let refreshKLpActions = $t05272052828._1
1362+ let updatedKLp = $t05272052828._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.")
13791375 }
13801376 else throw("Strict value is not equal to itself.")
13811377 }
13821378
13831379
13841380
13851381 @Callable(i)
1386-func getOneTknV2READONLY (outAssetId,lpAssetAmount) = {
1387- let amId = toBase58String(value(cfgAmountAssetId))
1388- let prId = toBase58String(value(cfgPriceAssetId))
1389- let lpId = toBase58String(value(cfgLpAssetId))
1390- let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
1391- let lpEmission = toBigInt(valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "invalid lp asset").quantity)
1392- let D0 = getD(xp)
1393- let D1 = (D0 - fraction(toBigInt(lpAssetAmount), D0, lpEmission))
1394- let index = if ((outAssetId == amId))
1395- then 0
1396- else if ((outAssetId == prId))
1397- then 1
1398- else throw("invalid out asset id")
1399- let newY = getYD(xp, index, D1)
1400- let dy = (xp[index] - newY)
1401- let totalGetRaw = max([0, toInt((dy - big1))])
1402- let $t05004150096 = takeFee(totalGetRaw, outFee)
1403- let totalGet = $t05004150096._1
1404- let feeAmount = $t05004150096._2
1405- $Tuple2(nil, $Tuple2(totalGet, feeAmount))
1406- }
1407-
1408-
1409-
1410-@Callable(i)
1411-func getOneTknV2WithBonusREADONLY (outAssetId,lpAssetAmount) = {
1412- let amId = toBase58String(value(cfgAmountAssetId))
1413- let prId = toBase58String(value(cfgPriceAssetId))
1414- let lpId = toBase58String(value(cfgLpAssetId))
1415- let amBalance = getAccBalance(amId)
1416- let prBalance = getAccBalance(prId)
1417- let $t05047150586 = {
1418- let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, lpAssetAmount], nil)
1419- if ($isInstanceOf(@, "(Int, Int)"))
1420- then @
1421- else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
1422- }
1423- let totalGet = $t05047150586._1
1424- let feeAmount = $t05047150586._2
1425- let r = ego("", lpId, lpAssetAmount, this)
1426- let outAmAmt = r._1
1427- let outPrAmt = r._2
1428- let sumOfGetAssets = (outAmAmt + outPrAmt)
1429- let bonus = if ((sumOfGetAssets == 0))
1430- then if ((totalGet == 0))
1431- then 0
1432- else throw("bonus calculation error")
1433- else fraction((totalGet - sumOfGetAssets), scale8, sumOfGetAssets)
1434- $Tuple2(nil, $Tuple3(totalGet, feeAmount, bonus))
1382+func get () = {
1383+ let res = commonGet(i)
1384+ let outAmAmt = res._1
1385+ let outPrAmt = res._2
1386+ let pmtAmt = res._3
1387+ let pmtAssetId = res._4
1388+ let state = res._5
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 $t05392354004 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1397+ let refreshKLpActions = $t05392354004._1
1398+ let updatedKLp = $t05392354004._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+ }
1406+ else throw("Strict value is not equal to itself.")
14351407 }
14361408
14371409
14381410
14391411 @Callable(i)
14401412 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
1441- let r = cg(i)
1442- let outAmAmt = r._1
1443- let outPrAmt = r._2
1444- let pmtAmt = r._3
1445- let pmtAssetId = r._4
1446- let state = r._5
1413+ let res = commonGet(i)
1414+ let outAmAmt = res._1
1415+ let outPrAmt = res._2
1416+ let pmtAmt = res._3
1417+ let pmtAssetId = res._4
1418+ let state = res._5
14471419 if ((noLessThenAmtAsset > outAmAmt))
1448- then throw(((("Failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
1420+ then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
14491421 else if ((noLessThenPriceAsset > outPrAmt))
1450- then throw(((("Failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
1422+ then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
14511423 else {
1452- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1453- if ((currentDLp == currentDLp))
1424+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1425+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1426+ if ((currentKLp == currentKLp))
14541427 then {
1455- let burnLPAssetOnFactory = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1428+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
14561429 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
14571430 then {
1458- let $t05175251833 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1459- let refreshDLpActions = $t05175251833._1
1460- let updatedDLp = $t05175251833._2
1461- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1462- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1463- then (state ++ refreshDLpActions)
1431+ let $t05509955180 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1432+ let refreshKLpActions = $t05509955180._1
1433+ let updatedKLp = $t05509955180._2
1434+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1435+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1436+ then ((withdrawState ++ state) ++ refreshKLpActions)
14641437 else throw("Strict value is not equal to itself.")
14651438 }
14661439 else throw("Strict value is not equal to itself.")
14671440 }
14681441 else throw("Strict value is not equal to itself.")
14691442 }
14701443 }
14711444
14721445
14731446
14741447 @Callable(i)
14751448 func unstakeAndGet (amount) = {
14761449 let checkPayments = if ((size(i.payments) != 0))
1477- then throw("No pmnts expd")
1450+ then throw("No payments are expected")
14781451 else true
14791452 if ((checkPayments == checkPayments))
14801453 then {
1481- let factoryCfg = gfc()
1482- let lpAssetId = cfgLpAssetId
1483- let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1484- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1485- if ((currentDLp == currentDLp))
1454+ let cfg = getPoolConfig()
1455+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1456+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1457+ if ((currentKLp == currentKLp))
14861458 then {
1487- let unstakeInv = invoke(staking, "unstake", [toBase58String(lpAssetId), amount], nil)
1459+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
14881460 if ((unstakeInv == unstakeInv))
14891461 then {
1490- let r = ego(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1491- let outAmAmt = r._1
1492- let outPrAmt = r._2
1493- let sts = parseIntValue(r._9)
1494- let state = r._10
1495- let v = if (if (igs())
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())
14961469 then true
1497- else (sts == PoolShutdown))
1498- then throw(("Blocked: " + toString(sts)))
1470+ else (poolStatus == PoolShutdown))
1471+ then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
14991472 else true
1500- if ((v == v))
1473+ if ((checkPoolStatus == checkPoolStatus))
15011474 then {
1502- let burnA = invoke(fca, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1503- if ((burnA == burnA))
1475+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1476+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
15041477 then {
1505- let $t05286052941 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1506- let refreshDLpActions = $t05286052941._1
1507- let updatedDLp = $t05286052941._2
1508- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1509- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1510- then (state ++ refreshDLpActions)
1478+ let $t05645256533 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1479+ let refreshKLpActions = $t05645256533._1
1480+ let updatedKLp = $t05645256533._2
1481+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1482+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1483+ then ((withdrawState ++ state) ++ refreshKLpActions)
15111484 else throw("Strict value is not equal to itself.")
15121485 }
15131486 else throw("Strict value is not equal to itself.")
15141487 }
15151488 else throw("Strict value is not equal to itself.")
15161489 }
15171490 else throw("Strict value is not equal to itself.")
15181491 }
15191492 else throw("Strict value is not equal to itself.")
15201493 }
15211494 else throw("Strict value is not equal to itself.")
15221495 }
15231496
15241497
15251498
15261499 @Callable(i)
15271500 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
1528- let isGetDisabled = if (igs())
1501+ let isGetDisabled = if (isGlobalShutdown())
15291502 then true
15301503 else (cfgPoolStatus == PoolShutdown)
15311504 let checks = [if (!(isGetDisabled))
15321505 then true
15331506 else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
15341507 then true
15351508 else throw("no payments are expected")]
15361509 if ((checks == checks))
15371510 then {
1538- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1539- if ((currentDLp == currentDLp))
1511+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1512+ if ((currentKLp == currentKLp))
15401513 then {
15411514 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
15421515 if ((unstakeInv == unstakeInv))
15431516 then {
1544- let res = ego(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
1517+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
15451518 let outAmAmt = res._1
15461519 let outPrAmt = res._2
15471520 let state = res._10
1521+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
15481522 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
15491523 then true
15501524 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
15511525 then true
15521526 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
15531527 if ((checkAmounts == checkAmounts))
15541528 then {
1555- let burnLPAssetOnFactory = invoke(fca, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1529+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
15561530 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
15571531 then {
1558- let $t05419254273 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1559- let refreshDLpActions = $t05419254273._1
1560- let updatedDLp = $t05419254273._2
1561- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1562- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1563- then (state ++ refreshDLpActions)
1532+ let $t05797458055 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1533+ let refreshKLpActions = $t05797458055._1
1534+ let updatedKLp = $t05797458055._2
1535+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1536+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1537+ then ((withdrawState ++ state) ++ refreshKLpActions)
15641538 else throw("Strict value is not equal to itself.")
15651539 }
15661540 else throw("Strict value is not equal to itself.")
15671541 }
15681542 else throw("Strict value is not equal to itself.")
15691543 }
15701544 else throw("Strict value is not equal to itself.")
15711545 }
15721546 else throw("Strict value is not equal to itself.")
15731547 }
15741548 else throw("Strict value is not equal to itself.")
15751549 }
15761550
15771551
15781552
15791553 @Callable(i)
1580-func unstakeAndGetOneTknV2 (unstakeAmount,outAssetId,minOutAmount) = {
1581- let isPoolOneTokenOperationsDisabled = {
1582- let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1583- if ($isInstanceOf(@, "Boolean"))
1584- then @
1585- else throw(($getType(@) + " couldn't be cast to Boolean"))
1586- }
1587- let isGetDisabled = if (if (igs())
1588- then true
1589- else (cfgPoolStatus == PoolShutdown))
1590- then true
1591- else isPoolOneTokenOperationsDisabled
1592- let checks = [if (if (!(isGetDisabled))
1593- then true
1594- else isManager(i))
1595- then true
1596- else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
1597- then true
1598- else throwErr("no payments are expected")]
1599- if ((checks == checks))
1554+func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
1555+ then throw("permissions denied")
1556+ 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))
16001567 then {
1601- let factoryCfg = gfc()
1602- let lpAssetId = cfgLpAssetId
1603- let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1604- let userAddress = i.caller
1605- let lpAssetRecipientAddress = this
1606- let unstakeInv = invoke(staking, "unstakeINTERNAL", [lpAssetId, unstakeAmount, userAddress.bytes, lpAssetRecipientAddress.bytes], nil)
1607- if ((unstakeInv == unstakeInv))
1608- then {
1609- let $t05529555483 = getOneTknV2Internal(outAssetId, minOutAmount, [AttachedPayment(lpAssetId, unstakeAmount)], i.caller, i.originCaller, i.transactionId)
1610- let state = $t05529555483._1
1611- let totalAmount = $t05529555483._2
1612- $Tuple2(state, totalAmount)
1613- }
1614- else throw("Strict value is not equal to itself.")
1568+ let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1569+ let $t05925959323 = refreshKLpInternal(0, 0, 0)
1570+ let kLpUpdateActions = $t05925959323._1
1571+ let updatedKLp = $t05925959323._2
1572+ let actions = if ((kLp != updatedKLp))
1573+ then kLpUpdateActions
1574+ else throwErr("nothing to refresh")
1575+ $Tuple2(actions, toString(updatedKLp))
16151576 }
16161577 else throw("Strict value is not equal to itself.")
16171578 }
16181579
16191580
16201581
16211582 @Callable(i)
1622-func putOneTknV2WithBonusREADONLY (paymentAmountRaw,paymentAssetId) = {
1623- let $t05561155714 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "", true)
1624- let lpAmount = $t05561155714._1
1625- let state = $t05561155714._2
1626- let feeAmount = $t05561155714._3
1627- let bonus = $t05561155714._4
1628- $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1629- }
1630-
1631-
1632-
1633-@Callable(i)
1634-func putOneTknV2WithoutTakeFeeREADONLY (paymentAmountRaw,paymentAssetId) = {
1635- let $t05586255966 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "", false)
1636- let lpAmount = $t05586255966._1
1637- let state = $t05586255966._2
1638- let feeAmount = $t05586255966._3
1639- let bonus = $t05586255966._4
1640- $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1641- }
1642-
1643-
1644-
1645-@Callable(i)
1646-func activate (amtAsStr,prAsStr) = if ((toString(i.caller) != toString(fca)))
1647- then throw("denied")
1648- else $Tuple2([StringEntry(aa(), amtAsStr), StringEntry(pa(), prAsStr), StringEntry(amp(), toString(ampInitial)), StringEntry(keyAmpHistory(height), toString(ampInitial))], "success")
1649-
1650-
1651-
1652-@Callable(i)
1653-func getPoolConfigWrapperREADONLY () = $Tuple2(nil, gpc())
1583+func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
16541584
16551585
16561586
16571587 @Callable(i)
16581588 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
16591589
16601590
16611591
16621592 @Callable(i)
16631593 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
1664- let pr = calcPrices(amAmt, prAmt, lpAmt)
1665- $Tuple2(nil, [toString(pr[0]), toString(pr[1]), toString(pr[2])])
1594+ let prices = calcPrices(amAmt, prAmt, lpAmt)
1595+ $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
16661596 }
16671597
16681598
16691599
16701600 @Callable(i)
1671-func fromX18WrapperREADONLY (val,resScaleMult) = $Tuple2(nil, f1(parseBigIntValue(val), resScaleMult))
1601+func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
16721602
16731603
16741604
16751605 @Callable(i)
1676-func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(t1(origVal, origScaleMult)))
1606+func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
16771607
16781608
16791609
16801610 @Callable(i)
1681-func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(cpbi(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
1611+func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
16821612
16831613
16841614
16851615 @Callable(i)
1686-func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,usrAddr,isEval,emitLp) = $Tuple2(nil, epo(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, usrAddr, isEval, emitLp, true, false, 0, ""))
1616+func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
16871617
16881618
16891619
16901620 @Callable(i)
1691-func estimateGetOperationWrapperREADONLY (txId58,pmtAsId,pmtLpAmt,usrAddr) = {
1692- let r = ego(txId58, pmtAsId, pmtLpAmt, addressFromStringValue(usrAddr))
1693- $Tuple2(nil, $Tuple10(r._1, r._2, r._3, r._4, r._5, r._6, r._7, toString(r._8), r._9, r._10))
1621+func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
1622+ let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
1623+ $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
16941624 }
16951625
16961626
16971627
16981628 @Callable(i)
1699-func changeAmp () = {
1700- let cfg = invoke(fca, "getChangeAmpConfigREADONLY", [toString(this)], nil)
1701- let $t05844658645 = match cfg {
1702- case list: List[Any] =>
1703- $Tuple3({
1704- let @ = list[0]
1705- if ($isInstanceOf(@, "Int"))
1706- then @
1707- else throw(($getType(@) + " couldn't be cast to Int"))
1708- }, {
1709- let @ = list[1]
1710- if ($isInstanceOf(@, "Int"))
1711- then @
1712- else throw(($getType(@) + " couldn't be cast to Int"))
1713- }, {
1714- let @ = list[2]
1715- if ($isInstanceOf(@, "Int"))
1716- then @
1717- else throw(($getType(@) + " couldn't be cast to Int"))
1718- })
1719- case _ =>
1720- throwErr("invalid entry type")
1629+func statsREADONLY () = {
1630+ let cfg = getPoolConfig()
1631+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1632+ let amtAssetId = cfg[idxAmtAssetId]
1633+ let priceAssetId = cfg[idxPriceAssetId]
1634+ let iAmtAssetId = cfg[idxIAmtAssetId]
1635+ let iPriceAssetId = cfg[idxIPriceAssetId]
1636+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1637+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1638+ let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1639+ let accAmtAssetBalance = getAccBalance(amtAssetId)
1640+ let accPriceAssetBalance = getAccBalance(priceAssetId)
1641+ let pricesList = if ((poolLPBalance == 0))
1642+ then [zeroBigInt, zeroBigInt, zeroBigInt]
1643+ else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
1644+ let curPrice = 0
1645+ let lpAmtAssetShare = fromX18(pricesList[1], scale8)
1646+ let lpPriceAssetShare = fromX18(pricesList[2], scale8)
1647+ let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
1648+ $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))
17211649 }
1722- let delay = $t05844658645._1
1723- let delta = $t05844658645._2
1724- let target = $t05844658645._3
1725- let curAmp = parseIntValue(getStringValue(amp()))
1726- let newAmpRaw = (curAmp + delta)
1727- let newAmp = if ((0 > delta))
1728- then if ((target > newAmpRaw))
1729- then target
1730- else newAmpRaw
1731- else if ((newAmpRaw > target))
1732- then target
1733- else newAmpRaw
1734- let lastCall = valueOrElse(getInteger(keyChangeAmpLastCall()), 0)
1735- let wait = (lastCall + delay)
1736- let checks = [if ((height > wait))
1737- then true
1738- else throwErr("try again in few blocks"), if ((curAmp != newAmp))
1739- then true
1740- else throwErr("already reached target")]
1741- if ((checks == checks))
1742- then [IntegerEntry(keyChangeAmpLastCall(), height), StringEntry(amp(), toString(newAmp)), StringEntry(keyAmpHistory(height), toString(newAmp))]
1743- else throw("Strict value is not equal to itself.")
1650+
1651+
1652+
1653+@Callable(i)
1654+func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
1655+ let cfg = getPoolConfig()
1656+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1657+ let amAssetIdStr = cfg[idxAmtAssetId]
1658+ let amAssetId = fromBase58String(amAssetIdStr)
1659+ let prAssetIdStr = cfg[idxPriceAssetId]
1660+ let prAssetId = fromBase58String(prAssetIdStr)
1661+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1662+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1663+ let poolStatus = cfg[idxPoolStatus]
1664+ let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1665+ let accAmtAssetBalance = getAccBalance(amAssetIdStr)
1666+ let accPriceAssetBalance = getAccBalance(prAssetIdStr)
1667+ let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
1668+ let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
1669+ let curPriceX18 = if ((poolLPBalance == 0))
1670+ then zeroBigInt
1671+ else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
1672+ let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
1673+ let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
1674+ let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
1675+ let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
1676+ let calcLpAmt = estPut._1
1677+ let curPriceCalc = estPut._3
1678+ let amBalance = estPut._4
1679+ let prBalance = estPut._5
1680+ let lpEmission = estPut._6
1681+ $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))
1682+ }
1683+
1684+
1685+
1686+@Callable(i)
1687+func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
1688+ let cfg = getPoolConfig()
1689+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1690+ let amAssetIdStr = cfg[idxAmtAssetId]
1691+ let amAssetId = fromBase58String(amAssetIdStr)
1692+ let prAssetIdStr = cfg[idxPriceAssetId]
1693+ let prAssetId = fromBase58String(prAssetIdStr)
1694+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1695+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1696+ let poolStatus = cfg[idxPoolStatus]
1697+ let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1698+ let amBalanceRaw = getAccBalance(amAssetIdStr)
1699+ let prBalanceRaw = getAccBalance(prAssetIdStr)
1700+ let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
1701+ let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
1702+ let curPriceX18 = if ((poolLPBalance == 0))
1703+ then zeroBigInt
1704+ else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
1705+ let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
1706+ let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
1707+ let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
1708+ let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
1709+ let calcLpAmt = estPut._1
1710+ let curPriceCalc = estPut._3
1711+ let amBalance = estPut._4
1712+ let prBalance = estPut._5
1713+ let lpEmission = estPut._6
1714+ $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))
1715+ }
1716+
1717+
1718+
1719+@Callable(i)
1720+func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
1721+ let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
1722+ let outAmAmt = res._1
1723+ let outPrAmt = res._2
1724+ let amBalance = res._5
1725+ let prBalance = res._6
1726+ let lpEmission = res._7
1727+ let curPrice = res._8
1728+ let poolStatus = parseIntValue(res._9)
1729+ $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))
17441730 }
17451731
17461732
17471733 @Verifier(tx)
17481734 func verify () = {
17491735 let targetPublicKey = match managerPublicKeyOrUnit() {
17501736 case pk: ByteVector =>
17511737 pk
17521738 case _: Unit =>
17531739 tx.senderPublicKey
17541740 case _ =>
17551741 throw("Match error")
17561742 }
17571743 match tx {
17581744 case order: Order =>
1759- let matcherPub = mp()
1760- let $t05957859695 = if (skipOrderValidation())
1745+ let matcherPub = getMatcherPubOrFail()
1746+ let $t06798568102 = if (skipOrderValidation())
17611747 then $Tuple2(true, "")
17621748 else validateMatcherOrderAllowed(order)
1763- let orderValid = $t05957859695._1
1764- let orderValidInfo = $t05957859695._2
1749+ let orderValid = $t06798568102._1
1750+ let orderValidInfo = $t06798568102._2
17651751 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
17661752 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
17671753 if (if (if (orderValid)
17681754 then senderValid
17691755 else false)
17701756 then matcherValid
17711757 else false)
17721758 then true
17731759 else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
17741760 case s: SetScriptTransaction =>
17751761 if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
17761762 then true
17771763 else {
17781764 let newHash = blake2b256(value(s.script))
1779- let allowedHash = fromBase64String(value(getString(fca, keyAllowedLpStableScriptHash())))
1765+ let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
17801766 let currentHash = scriptHash(this)
17811767 if ((allowedHash == newHash))
17821768 then (currentHash != newHash)
17831769 else false
17841770 }
17851771 case _ =>
17861772 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
17871773 }
17881774 }
17891775

github/deemru/w8io/3ef1775 
387.46 ms