tx · CoqDWyUagozJ2SZefxEvreec7QK3g3V9LhFyRD839Xp5

3N8bTRc9HTDrWbXfA9DTU5BiZnW9RmgJmVx:  -0.04200000 Waves

2024.12.19 12:19 [3421226] smart account 3N8bTRc9HTDrWbXfA9DTU5BiZnW9RmgJmVx > SELF 0.00000000 Waves

{ "type": 13, "id": "CoqDWyUagozJ2SZefxEvreec7QK3g3V9LhFyRD839Xp5", "fee": 4200000, "feeAssetId": null, "timestamp": 1734600023748, "version": 2, "chainId": 84, "sender": "3N8bTRc9HTDrWbXfA9DTU5BiZnW9RmgJmVx", "senderPublicKey": "4FZssnx8mgS8Khrq4FSD52Kj8tUGsEgmLUH6S95iTzfZ", "proofs": [ "ARmr2M8D8N9hm9NDG85mbta31gsauVknLHXdrh76uexDjUmGasfEFVFXeJ2fckwuZFzZmWNSnpqzCdbV7KKLKow" ], "script": "base64:BgLWOAgCEgASBQoDAQQBEgcKBQEEAQgBEgQKAgEEEgMKAQESBAoCAQQSBAoCCAESBAoCCAESBAoCCAESBQoDAQgBEgASBAoCAQESAwoBARIFCgMBAQESBAoCCAgSABIAEgMKAQgSBQoDAQEBEgQKAgEBEgQKAggBEgQKAggIEgsKCQgBAQIBAggEBBIGCgQICAEIEgASAwoBARIDCgEBEgQKAggBIgpsUGRlY2ltYWxzIgZzY2FsZTgiDHNjYWxlOEJpZ0ludCIHc2NhbGUxOCIKemVyb0JpZ0ludCIEYmlnMCIEYmlnMSIEYmlnMiILd2F2ZXNTdHJpbmciA1NFUCIKUG9vbEFjdGl2ZSIPUG9vbFB1dERpc2FibGVkIhNQb29sTWF0Y2hlckRpc2FibGVkIgxQb29sU2h1dGRvd24iDmlkeFBvb2xBZGRyZXNzIg1pZHhQb29sU3RhdHVzIhBpZHhQb29sTFBBc3NldElkIg1pZHhBbXRBc3NldElkIg9pZHhQcmljZUFzc2V0SWQiDmlkeEFtdEFzc2V0RGNtIhBpZHhQcmljZUFzc2V0RGNtIg5pZHhJQW10QXNzZXRJZCIQaWR4SVByaWNlQXNzZXRJZCINaWR4TFBBc3NldERjbSISaWR4UG9vbEFtdEFzc2V0QW10IhRpZHhQb29sUHJpY2VBc3NldEFtdCIRaWR4UG9vbExQQXNzZXRBbXQiGWlkeEZhY3RvcnlTdGFraW5nQ29udHJhY3QiGmlkeEZhY3RvcnlTbGlwcGFnZUNvbnRyYWN0IgV0b1gxOCIHb3JpZ1ZhbCINb3JpZ1NjYWxlTXVsdCILdG9YMThCaWdJbnQiB2Zyb21YMTgiA3ZhbCIPcmVzdWx0U2NhbGVNdWx0Igxmcm9tWDE4Um91bmQiBXJvdW5kIgd0b1NjYWxlIgNhbXQiCHJlc1NjYWxlIghjdXJTY2FsZSIDYWJzIglhYnNCaWdJbnQiDHN3YXBDb250cmFjdCICZmMiE2tleU1hbmFnZXJQdWJsaWNLZXkiFmtleU1hbmFnZXJWYXVsdEFkZHJlc3MiAnBsIgJwaCIBaCIJdGltZXN0YW1wIgNwYXUiC3VzZXJBZGRyZXNzIgR0eElkIgNnYXUiAmFhIgJwYSIGa2V5RmVlIgpmZWVEZWZhdWx0IgNmZWUiBmtleUtMcCIVa2V5S0xwUmVmcmVzaGVkSGVpZ2h0IhJrZXlLTHBSZWZyZXNoRGVsYXkiFmtMcFJlZnJlc2hEZWxheURlZmF1bHQiD2tMcFJlZnJlc2hEZWxheSIUa2V5QWRkaXRpb25hbEJhbGFuY2UiB2Fzc2V0SWQiFmtleVN0YWtpbmdBc3NldEJhbGFuY2UiGmdldEFkZGl0aW9uYWxCYWxhbmNlT3JaZXJvIhxnZXRTdGFraW5nQXNzZXRCYWxhbmNlT3JaZXJvIhBrZXlGYWN0b3J5Q29uZmlnIg1rZXlNYXRjaGVyUHViIilrZXlNYXBwaW5nUG9vbENvbnRyYWN0QWRkcmVzc1RvUG9vbEFzc2V0cyITcG9vbENvbnRyYWN0QWRkcmVzcyINa2V5UG9vbENvbmZpZyIJaUFtdEFzc2V0IgtpUHJpY2VBc3NldCIfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZCIMYmFzZUFzc2V0U3RyIhNrZXlBbGxQb29sc1NodXRkb3duIg1rZXlQb29sV2VpZ2h0Ig9jb250cmFjdEFkZHJlc3MiFmtleUFsbG93ZWRMcFNjcmlwdEhhc2giFmtleUZlZUNvbGxlY3RvckFkZHJlc3MiFmtleVNraXBPcmRlclZhbGlkYXRpb24iC3Bvb2xBZGRyZXNzIg90aHJvd09yZGVyRXJyb3IiCm9yZGVyVmFsaWQiDm9yZGVyVmFsaWRJbmZvIgxtYXRjaGVyVmFsaWQiF2FkZHJlc3NGcm9tU3RyaW5nT3JUaGlzIg1hZGRyZXNzU3RyaW5nIgckbWF0Y2gwIgFhIhxnZXRNYW5hZ2VyVmF1bHRBZGRyZXNzT3JUaGlzIg5mYWN0b3J5QWRkcmVzcyIDZmNhIgFzIg9nZXRTdHJpbmdPckZhaWwiB2FkZHJlc3MiA2tleSIMZ2V0SW50T3JGYWlsIgh0aHJvd0VyciIDbXNnIgZmbXRFcnIiD2ZhY3RvcnlDb250cmFjdCITZmVlQ29sbGVjdG9yQWRkcmVzcyIFaW5GZWUiAUAiBm91dEZlZSIVa2V5QWRkcmVzc1doaXRlbGlzdGVkIhRpc0FkZHJlc3NXaGl0ZWxpc3RlZCIQaXNHbG9iYWxTaHV0ZG93biITZ2V0TWF0Y2hlclB1Yk9yRmFpbCINZ2V0UG9vbENvbmZpZyIIYW10QXNzZXQiCnByaWNlQXNzZXQiDHBhcnNlQXNzZXRJZCIFaW5wdXQiD2Fzc2V0SWRUb1N0cmluZyIPcGFyc2VQb29sQ29uZmlnIgpwb29sQ29uZmlnIhBwb29sQ29uZmlnUGFyc2VkIgskdDA5NzAyOTg2OCIOY2ZnUG9vbEFkZHJlc3MiDWNmZ1Bvb2xTdGF0dXMiDGNmZ0xwQXNzZXRJZCIQY2ZnQW1vdW50QXNzZXRJZCIPY2ZnUHJpY2VBc3NldElkIhZjZmdBbW91bnRBc3NldERlY2ltYWxzIhVjZmdQcmljZUFzc2V0RGVjaW1hbHMiEGdldEZhY3RvcnlDb25maWciD3N0YWtpbmdDb250cmFjdCIQc2xpcHBhZ2VDb250cmFjdCIRZGF0YVB1dEFjdGlvbkluZm8iDWluQW10QXNzZXRBbXQiD2luUHJpY2VBc3NldEFtdCIIb3V0THBBbXQiBXByaWNlIh1zbGlwcGFnZVRvbGVyYW5jZVBhc3NlZEJ5VXNlciIVc2xpcHBhZ2VUb2xlcmFuY2VSZWFsIgh0eEhlaWdodCILdHhUaW1lc3RhbXAiEnNsaXBhZ2VBbXRBc3NldEFtdCIUc2xpcGFnZVByaWNlQXNzZXRBbXQiEWRhdGFHZXRBY3Rpb25JbmZvIg5vdXRBbXRBc3NldEFtdCIQb3V0UHJpY2VBc3NldEFtdCIHaW5McEFtdCINZ2V0QWNjQmFsYW5jZSINYmFsYW5jZU9uUG9vbCIMdG90YWxCYWxhbmNlIg9jYWxjUHJpY2VCaWdJbnQiCHByQW10WDE4IghhbUFtdFgxOCIUY2FsY1ByaWNlQmlnSW50Um91bmQiB2dldFJhdGUiBXByb3h5IgNpbnYiAXIiB2RlcG9zaXQiBmFtb3VudCIOc3Rha2luZ0Fzc2V0SWQiGGN1cnJlbnRBZGRpdGlvbmFsQmFsYW5jZSIaY3VycmVudFN0YWtpbmdBc3NldEJhbGFuY2UiBWFzc2V0Ig1kZXBvc2l0SW52b2tlIhRyZWNlaXZlZFN0YWtpbmdBc3NldCIUbmV3QWRkaXRpb25hbEJhbGFuY2UiFm5ld1N0YWtpbmdBc3NldEJhbGFuY2UiCHdpdGhkcmF3Igxwcm94eVJhdGVNdWwiDXByb2ZpdEFkZHJlc3MiEGN1cnJlbnRQcm94eVJhdGUiB29sZFJhdGUiDHN0YWtpbmdBc3NldCIUb2xkU2VuZFN0YWtpbmdBbW91bnQiFnNlbmRTdGFraW5nQXNzZXRBbW91bnQiDHByb2ZpdEFtb3VudCIOd2l0aGRyYXdJbnZva2UiDnJlY2VpdmVkQXNzZXRzIhNnZXRMZWFzZVByb3h5Q29uZmlnIhFyZWJhbGFuY2VJbnRlcm5hbCILdGFyZ2V0UmF0aW8iCm1pbkJhbGFuY2UiFGxlYXNhYmxlVG90YWxCYWxhbmNlIhd0YXJnZXRBZGRpdGlvbmFsQmFsYW5jZSIEZGlmZiIPc2VuZEFzc2V0QW1vdW50Ig5nZXRBc3NldEFtb3VudCIOcmViYWxhbmNlQXNzZXQiDSR0MDE2MTUzMTYyODkiCmlzTGVhc2FibGUiC2xlYXNlZFJhdGlvIgxwcm94eUFkZHJlc3MiDHByb3h5QXNzZXRJZCIUc3Rha2luZ1Byb2ZpdEFkZHJlc3MiGXdpdGhkcmF3QW5kUmViYWxhbmNlQXNzZXQiCWdldEFtb3VudCINJHQwMTY2ODgxNjgyNCIXbmV3VG90YWxMZWFzYWJsZUJhbGFuY2UiDndpdGhkcmF3QW1vdW50Ihd3aXRoZHJhd0FuZFJlYmFsYW5jZUFsbCIUYW1vdW50QXNzZXRPdXRBbW91bnQiE3ByaWNlQXNzZXRPdXRBbW91bnQiEkFtQW10V2l0aGRyYXdTdGF0ZSISUHJBbXRXaXRoZHJhd1N0YXRlIhBwcml2YXRlQ2FsY1ByaWNlIgphbUFzc2V0RGNtIgpwckFzc2V0RGNtIgVhbUFtdCIFcHJBbXQiDmFtdEFzc2V0QW10WDE4IhBwcmljZUFzc2V0QW10WDE4IgpjYWxjUHJpY2VzIgVscEFtdCIDY2ZnIgthbXRBc3NldERjbSINcHJpY2VBc3NldERjbSIIcHJpY2VYMTgiCGxwQW10WDE4IhNscFByaWNlSW5BbUFzc2V0WDE4IhNscFByaWNlSW5QckFzc2V0WDE4Ig9jYWxjdWxhdGVQcmljZXMiBnByaWNlcyIUZXN0aW1hdGVHZXRPcGVyYXRpb24iBnR4SWQ1OCIKcG10QXNzZXRJZCIIcG10THBBbXQiCWxwQXNzZXRJZCIJYW1Bc3NldElkIglwckFzc2V0SWQiCnBvb2xTdGF0dXMiCmxwRW1pc3Npb24iCWFtQmFsYW5jZSIMYW1CYWxhbmNlWDE4IglwckJhbGFuY2UiDHByQmFsYW5jZVgxOCILY3VyUHJpY2VYMTgiCGN1clByaWNlIgtwbXRMcEFtdFgxOCINbHBFbWlzc2lvblgxOCILb3V0QW1BbXRYMTgiC291dFByQW10WDE4IghvdXRBbUFtdCIIb3V0UHJBbXQiBXN0YXRlIhRlc3RpbWF0ZVB1dE9wZXJhdGlvbiIRc2xpcHBhZ2VUb2xlcmFuY2UiDGluQW1Bc3NldEFtdCILaW5BbUFzc2V0SWQiDGluUHJBc3NldEFtdCILaW5QckFzc2V0SWQiCmlzRXZhbHVhdGUiBmVtaXRMcCIMYW1Bc3NldElkU3RyIgxwckFzc2V0SWRTdHIiC2lBbXRBc3NldElkIg1pUHJpY2VBc3NldElkIg5pbkFtQXNzZXRJZFN0ciIOaW5QckFzc2V0SWRTdHIiD2luQW1Bc3NldEFtdFgxOCIPaW5QckFzc2V0QW10WDE4Igx1c2VyUHJpY2VYMTgiA3JlcyILc2xpcHBhZ2VYMTgiFHNsaXBwYWdlVG9sZXJhbmNlWDE4IgpwclZpYUFtWDE4IgphbVZpYVByWDE4IgxleHBlY3RlZEFtdHMiEWV4cEFtdEFzc2V0QW10WDE4IhNleHBQcmljZUFzc2V0QW10WDE4IgljYWxjTHBBbXQiDmNhbGNBbUFzc2V0UG10Ig5jYWxjUHJBc3NldFBtdCIMc2xpcHBhZ2VDYWxjIgllbWl0THBBbXQiBmFtRGlmZiIGcHJEaWZmIgtjb21tb25TdGF0ZSIHY2FsY0tMcCINYW1vdW50QmFsYW5jZSIMcHJpY2VCYWxhbmNlIhBhbW91bnRCYWxhbmNlWDE4Ig9wcmljZUJhbGFuY2VYMTgiCnVwZGF0ZWRLTHAiDmNhbGNDdXJyZW50S0xwIhBhbW91bnRBc3NldERlbHRhIg9wcmljZUFzc2V0RGVsdGEiFGxwQXNzZXRFbWlzc2lvbkRlbHRhIhJhbW91bnRBc3NldEJhbGFuY2UiEXByaWNlQXNzZXRCYWxhbmNlIg9scEFzc2V0RW1pc3Npb24iCmN1cnJlbnRLTHAiEnJlZnJlc2hLTHBJbnRlcm5hbCIXYW1vdW50QXNzZXRCYWxhbmNlRGVsdGEiFnByaWNlQXNzZXRCYWxhbmNlRGVsdGEiB2FjdGlvbnMiE3NraXBPcmRlclZhbGlkYXRpb24iEnZhbGlkYXRlVXBkYXRlZEtMcCIGb2xkS0xwIht2YWxpZGF0ZU1hdGNoZXJPcmRlckFsbG93ZWQiBW9yZGVyIhFhbW91bnRBc3NldEFtb3VudCIQcHJpY2VBc3NldEFtb3VudCINJHQwMjk0NTAyOTY2MiIDa0xwIg0kdDAzMDEwMjMwMjAyIg11bnVzZWRBY3Rpb25zIgZrTHBOZXciDGlzT3JkZXJWYWxpZCIEaW5mbyIJY29tbW9uR2V0IgFpIgNwbXQiBnBtdEFtdCINaXNHZXREaXNhYmxlZCIJY29tbW9uUHV0IgphbUFzc2V0UG10IgpwckFzc2V0UG10IgZlc3RQdXQiDWlzUHV0RGlzYWJsZWQiBGVtaXQiB2VtaXRJbnYiDWVtaXRJbnZMZWdhY3kiFWxlZ2FjeUZhY3RvcnlDb250cmFjdCIHdGFrZUZlZSIJZmVlQW1vdW50Ig9jYWxjUHV0T25lVG9rZW4iEHBheW1lbnRBbW91bnRSYXciDnBheW1lbnRBc3NldElkIgZpc0V2YWwiEGFtb3VudEJhbGFuY2VSYXciD3ByaWNlQmFsYW5jZVJhdyIUcGF5bWVudEluQW1vdW50QXNzZXQiDSR0MDMzMzg4MzM2ODEiEGFtb3VudEJhbGFuY2VPbGQiD3ByaWNlQmFsYW5jZU9sZCINJHQwMzM2ODUzMzgzNCIUYW1vdW50QXNzZXRBbW91bnRSYXciE3ByaWNlQXNzZXRBbW91bnRSYXciDSR0MDMzOTY2MzQwMzAiDXBheW1lbnRBbW91bnQiEGFtb3VudEJhbGFuY2VOZXciD3ByaWNlQmFsYW5jZU5ldyILcHJpY2VOZXdYMTgiCHByaWNlTmV3Ig5wYXltZW50QmFsYW5jZSIUcGF5bWVudEJhbGFuY2VCaWdJbnQiDHN1cHBseUJpZ0ludCILY2hlY2hTdXBwbHkiDWRlcG9zaXRCaWdJbnQiC2lzc3VlQW1vdW50IgtwcmljZU9sZFgxOCIIcHJpY2VPbGQiBGxvc3MiDSR0MDM1NzExMzU4NzgiB2JhbGFuY2UiD2lzc3VlQW1vdW50Qm90aCIPY2FsY0dldE9uZVRva2VuIgpvdXRBc3NldElkIgZjaGVja3MiEG91dEluQW1vdW50QXNzZXQiDWJhbGFuY2VCaWdJbnQiGG91dEluQW1vdW50QXNzZXREZWNpbWFscyIMYW1CYWxhbmNlT2xkIgxwckJhbGFuY2VPbGQiCm91dEJhbGFuY2UiEG91dEJhbGFuY2VCaWdJbnQiDnJlZGVlbWVkQmlnSW50IglhbW91bnRSYXciDSR0MDM3OTU2MzgwMTIiC3RvdGFsQW1vdW50Ig0kdDAzODAxNjM4MjQyIgtvdXRBbUFtb3VudCILb3V0UHJBbW91bnQiDGFtQmFsYW5jZU5ldyIMcHJCYWxhbmNlTmV3IhhhbW91bnRCb3RoSW5QYXltZW50QXNzZXQiFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQiE21hbmFnZXJWYXVsdEFkZHJlc3MiCWlzTWFuYWdlciICcGsiC211c3RNYW5hZ2VyIgJwZCINY2xlYW5BbW91bnRJbiIJaXNSZXZlcnNlIg1mZWVQb29sQW1vdW50Ig0kdDA0MDEwMDQwNDA1Ighhc3NldE91dCIHYXNzZXRJbiIScG9vbEFzc2V0SW5CYWxhbmNlIhNwb29sQXNzZXRPdXRCYWxhbmNlIglhbW91bnRPdXQiBG9sZEsiBG5ld0siBmNoZWNrSyIMYW1vdW50T3V0TWluIglhZGRyZXNzVG8iC3N3YXBDb250YWN0IhJpc1Bvb2xTd2FwRGlzYWJsZWQiDmlzU3dhcERpc2FibGVkIghjaGVja01pbiIRcmVmcmVzaEtMcEFjdGlvbnMiDnJlYmFsYW5jZVN0YXRlIg13aXRoZHJhd1N0YXRlIg9zaG91bGRBdXRvU3Rha2UiBGFtSWQiBHBySWQiDHNsaXBwYWdlQUludiIMc2xpcHBhZ2VQSW52IgpscFRyYW5zZmVyIgtzbHBTdGFrZUludiINJHQwNDU1ODE0NjA0MyIRaXNVcGRhdGVkS0xwVmFsaWQiA3JlYiILbWF4U2xpcHBhZ2UiDSR0MDQ2NjU1NDY3MjAiDG1pbk91dEFtb3VudCIJYXV0b1N0YWtlIiBpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZCIHcGF5bWVudCINJHQwNDc5NDk0ODEwMSIFYm9udXMiE2VtaXRBbW91bnRFc3RpbWF0ZWQiCmVtaXRBbW91bnQiCHN0YWtlSW52IgdzZW5kRmVlIg0kdDA0ODY4NzQ4ODg0Ig0kdDA0ODg4NzQ4OTk1Ig0kdDA0OTM1MDQ5NTA3Ig1vdXRBc3NldElkU3RyIg0kdDA1MDQyOTUwNTgyIg9hbW91bnRFc3RpbWF0ZWQiB2J1cm5JbnYiDWFzc2V0VHJhbnNmZXIiDSR0MDUxMjQ2NTE0OTMiEGZlZUFtb3VudEZvckNhbGMiDSR0MDUxNDk2NTE2MDQiDSR0MDUxODgyNTIwMzgiDXVuc3Rha2VBbW91bnQiCnVuc3Rha2VJbnYiDSR0MDUyOTgwNTMxMzEiDSR0MDUzNzkwNTQwMzciDSR0MDU0MDQwNTQxNDgiFGJ1cm5MUEFzc2V0T25GYWN0b3J5Ig0kdDA1NTI0MzU1MzI0IhJub0xlc3NUaGVuQW10QXNzZXQiFG5vTGVzc1RoZW5QcmljZUFzc2V0Ig0kdDA1NjQxOTU2NTAwIg1jaGVja1BheW1lbnRzIg9jaGVja1Bvb2xTdGF0dXMiDSR0MDU3ODQ4NTc5MjkiFW5vTGVzc1RoZW5BbW91bnRBc3NldCIMY2hlY2tBbW91bnRzIg0kdDA1OTQwNzU5NDg4IgthbXRBc3NldFN0ciINcHJpY2VBc3NldFN0ciIYbGFzdFJlZnJlc2hlZEJsb2NrSGVpZ2h0Ih1jaGVja0xhc3RSZWZyZXNoZWRCbG9ja0hlaWdodCINJHQwNjA2OTI2MDc1NiIQa0xwVXBkYXRlQWN0aW9ucyIKYW10QXNzZXRJZCIMcHJpY2VBc3NldElkIg1wb29sTFBCYWxhbmNlIhJhY2NBbXRBc3NldEJhbGFuY2UiFGFjY1ByaWNlQXNzZXRCYWxhbmNlIgpwcmljZXNMaXN0Ig9scEFtdEFzc2V0U2hhcmUiEWxwUHJpY2VBc3NldFNoYXJlIgpwb29sV2VpZ2h0IgxjdXJQcmljZUNhbGMiDGFtQmFsYW5jZVJhdyIMcHJCYWxhbmNlUmF3Ig9hbUJhbGFuY2VSYXdYMTgiD3ByQmFsYW5jZVJhd1gxOCIQcGF5bWVudExwQXNzZXRJZCIMcGF5bWVudExwQW10IgJ0eCIGdmVyaWZ5Ig90YXJnZXRQdWJsaWNLZXkiCm1hdGNoZXJQdWIiDSR0MDY5NDE4Njk2NDYiB25ld0hhc2giC2FsbG93ZWRIYXNoIgtjdXJyZW50SGFzaIQBAAFhAAgAAWIAgMLXLwABYwkAtgIBAIDC1y8AAWQJALYCAQCAgJC7utat8A0AAWUJALYCAQAAAAFmCQC2AgEAAAABZwkAtgIBAAEAAWgJALYCAQACAAFpAgVXQVZFUwABagICX18AAWsAAQABbAACAAFtAAMAAW4ABAABbwABAAFwAAIAAXEAAwABcgAEAAFzAAUAAXQABgABdQAHAAF2AAgAAXcACQABeAAKAAF5AAEAAXoAAgABQQADAAFCAAEAAUMABwEBRAIBRQFGCQC8AgMJALYCAQUBRQUBZAkAtgIBBQFGAQFHAgFFAUYJALwCAwUBRQUBZAUBRgEBSAIBSQFKCQCgAwEJALwCAwUBSQkAtgIBBQFKBQFkAQFLAwFJAUoBTAkAoAMBCQC9AgQFAUkJALYCAQUBSgUBZAUBTAEBTQMBTgFPAVAJAGsDBQFOBQFPBQFQAQFRAQFJAwkAZgIAAAUBSQkBAS0BBQFJBQFJAQFSAQFJAwkAvwICBQFlBQFJCQC+AgEFAUkFAUkBAVMAAhAlc19fc3dhcENvbnRyYWN0AQFUAAITJXNfX2ZhY3RvcnlDb250cmFjdAEBVQACFCVzX19tYW5hZ2VyUHVibGljS2V5AQFWAAIXJXNfX21hbmFnZXJWYXVsdEFkZHJlc3MBAVcAAhElcyVzX19wcmljZV9fbGFzdAEBWAIBWQFaCQC5CQIJAMwIAgIYJXMlcyVkJWRfX3ByaWNlX19oaXN0b3J5CQDMCAIJAKQDAQUBWQkAzAgCCQCkAwEFAVoFA25pbAUBagECYWECAmFiAmFjCQCsAgIJAKwCAgkArAICAgslcyVzJXNfX1BfXwUCYWICAl9fBQJhYwECYWQCAmFiAmFjCQCsAgIJAKwCAgkArAICAgslcyVzJXNfX0dfXwUCYWICAl9fBQJhYwECYWUAAg8lc19fYW1vdW50QXNzZXQBAmFmAAIOJXNfX3ByaWNlQXNzZXQAAmFnAgclc19fZmVlAAJhaAkAawMACgUBYgCQTgACYWkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUCYWcFAmFoAAJhagkAuQkCCQDMCAICAiVzCQDMCAICA2tMcAUDbmlsBQFqAAJhawkAuQkCCQDMCAICAiVzCQDMCAICEmtMcFJlZnJlc2hlZEhlaWdodAUDbmlsBQFqAAJhbAkAuQkCCQDMCAICAiVzCQDMCAICD3JlZnJlc2hLTHBEZWxheQUDbmlsBQFqAAJhbQAeAAJhbgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQJhbAUCYW0BAmFvAQJhcAkAuQkCCQDMCAICBCVzJXMJAMwIAgINc3Rha2VkQmFsYW5jZQkAzAgCBQJhcAUDbmlsBQFqAQJhcQECYXAJALkJAgkAzAgCAgQlcyVzCQDMCAICEXNoYXJlQXNzZXRCYWxhbmNlCQDMCAIFAmFwBQNuaWwFAWoBAmFyAQJhcAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYW8BBQJhcAAAAQJhcwECYXAJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmFxAQUCYXAAAAECYXQAAhElc19fZmFjdG9yeUNvbmZpZwECYXUAAhglcyVzX19tYXRjaGVyX19wdWJsaWNLZXkBAmF2AQJhdwkArAICCQCsAgICCCVzJXMlc19fBQJhdwIgX19tYXBwaW5nc19fcG9vbENvbnRyYWN0MkxwQXNzZXQBAmF4AgJheQJhegkArAICCQCsAgIJAKwCAgkArAICAgglZCVkJXNfXwUCYXkCAl9fBQJhegIIX19jb25maWcBAmFBAQJhQgkArAICAiglcyVzJXNfX21hcHBpbmdzX19iYXNlQXNzZXQyaW50ZXJuYWxJZF9fBQJhQgECYUMAAgwlc19fc2h1dGRvd24BAmFEAQJhRQkArAICAhIlcyVzX19wb29sV2VpZ2h0X18FAmFFAQJhRgACFyVzX19hbGxvd2VkTHBTY3JpcHRIYXNoAAJhRwIXJXNfX2ZlZUNvbGxlY3RvckFkZHJlc3MBAmFIAQJhSQkArAICAhslcyVzX19za2lwT3JkZXJWYWxpZGF0aW9uX18FAmFJAQJhSgMCYUsCYUwCYU0JAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAiRvcmRlciB2YWxpZGF0aW9uIGZhaWxlZDogb3JkZXJWYWxpZD0JAKUDAQUCYUsCAiAoBQJhTAIBKQIOIG1hdGNoZXJWYWxpZD0JAKUDAQUCYU0BAmFOAQJhTwQCYVAJAKYIAQUCYU8DCQABAgUCYVACB0FkZHJlc3MEAmFRBQJhUAUCYVEFBHRoaXMBAmFSAAQCYVMEAmFQCQCiCAEJAQFUAAMJAAECBQJhUAIGU3RyaW5nBAJhVAUCYVAJAQJhTgEFAmFUBQR0aGlzBAJhUAkAnQgCBQJhUwkBAVYAAwkAAQIFAmFQAgZTdHJpbmcEAmFVBQJhUAkBAmFOAQUCYVUFBHRoaXMBAmFWAgJhVwJhWAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFAmFXBQJhWAkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQJhVwkAzAgCAgEuCQDMCAIFAmFYCQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABAmFZAgJhVwJhWAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFAmFXBQJhWAkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQJhVwkAzAgCAgEuCQDMCAIFAmFYCQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABAmFaAQJiYQkAAgEJALkJAgkAzAgCAghscC5yaWRlOgkAzAgCBQJiYQUDbmlsAgEgAQJiYgECYmEJALkJAgkAzAgCAghscC5yaWRlOgkAzAgCBQJiYQUDbmlsAgEgAAJiYwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFWAgUEdGhpcwkBAVQAAAJiZAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFWAgUCYmMFAmFHAAJiZQoAAmJmCQD8BwQFAmJjAhBnZXRJbkZlZVJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYmYCA0ludAUCYmYJAAIBCQCsAgIJAAMBBQJiZgIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AAJiZwoAAmJmCQD8BwQFAmJjAhFnZXRPdXRGZWVSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmJmAgNJbnQFAmJmCQACAQkArAICCQADAQUCYmYCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAECYmgBAmFXCQC5CQIJAMwIAgIEJXMlcwkAzAgCAgt3aGl0ZWxpc3RlZAkAzAgCCQClCAEFAmFXBQNuaWwFAWoBAmJpAQJhVwkBC3ZhbHVlT3JFbHNlAgkAmwgCBQJiYwkBAmJoAQUCYVcHAQJiagAJAQt2YWx1ZU9yRWxzZQIJAJsIAgUCYmMJAQJhQwAHAQJiawAJANkEAQkBAmFWAgUCYmMJAQJhdQABAmJsAAQCYm0JAQJhVgIFBHRoaXMJAQJhZQAEAmJuCQECYVYCBQR0aGlzCQECYWYABAJhegkBAmFZAgUCYmMJAQJhQQEFAmJuBAJheQkBAmFZAgUCYmMJAQJhQQEFAmJtCQC1CQIJAQJhVgIFAmJjCQECYXgCCQCkAwEFAmF5CQCkAwEFAmF6BQFqAQJibwECYnADCQAAAgUCYnAFAWkFBHVuaXQJANkEAQUCYnABAmJxAQJicAMJAAACBQJicAUEdW5pdAUBaQkA2AQBCQEFdmFsdWUBBQJicAECYnIBAmJzCQCZCgcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYnMFAW8JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJicwUBcAkA2QQBCQCRAwIFAmJzBQFxCQECYm8BCQCRAwIFAmJzBQFyCQECYm8BCQCRAwIFAmJzBQFzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYnMFAXQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJicwUBdQACYnQJAQJicgEJAQJibAAAAmJ1BQJidAACYnYIBQJidQJfMQACYncIBQJidQJfMgACYngIBQJidQJfMwACYnkIBQJidQJfNAACYnoIBQJidQJfNQACYkEIBQJidQJfNgACYkIIBQJidQJfNwECYkMACQC1CQIJAQJhVgIFAmJjCQECYXQABQFqAAJiRAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgkBAmJDAAUBQgIZaW5jb3JyZWN0IHN0YWtpbmcgYWRkcmVzcwACYkUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIJAQJiQwAFAUMCGWluY29ycmVjdCBzdGFraW5nIGFkZHJlc3MBAmJGCgJiRwJiSAJiSQJiSgJiSwJiTAJiTQJiTgJiTwJiUAkAuQkCCQDMCAICFCVkJWQlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYkcJAMwIAgkApAMBBQJiSAkAzAgCCQCkAwEFAmJJCQDMCAIJAKQDAQUCYkoJAMwIAgkApAMBBQJiSwkAzAgCCQCkAwEFAmJMCQDMCAIJAKQDAQUCYk0JAMwIAgkApAMBBQJiTgkAzAgCCQCkAwEFAmJPCQDMCAIJAKQDAQUCYlAFA25pbAUBagECYlEGAmJSAmJTAmJUAmJKAmJNAmJOCQC5CQIJAMwIAgIMJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYlIJAMwIAgkApAMBBQJiUwkAzAgCCQCkAwEFAmJUCQDMCAIJAKQDAQUCYkoJAMwIAgkApAMBBQJiTQkAzAgCCQCkAwEFAmJOBQNuaWwFAWoBAmJVAQJhcAQCYlYDCQAAAgUCYXACBVdBVkVTCAkA7wcBBQR0aGlzCWF2YWlsYWJsZQkA8AcCBQR0aGlzCQDZBAEFAmFwBAJiVwkAZQIJAGQCBQJiVgkBAmFyAQUCYXAJAQJhcwEFAmFwCQCWAwEJAMwIAgAACQDMCAIFAmJXBQNuaWwBAmJYAgJiWQJiWgkAvAIDBQJiWQUBZAUCYloBAmNhAwJiWQJiWgFMCQC9AgQFAmJZBQFkBQJiWgUBTAECY2IBAmNjBAJjZAkA/AcEBQJjYwIHZ2V0UmF0ZQUDbmlsBQNuaWwDCQAAAgUCY2QFAmNkBAJhUAUCY2QDCQABAgUCYVACA0ludAQCY2UFAmFQBQJjZQkBAmFaAQIgcHJveHkuZ2V0UmF0ZSgpIHVuZXhwZWN0ZWQgdmFsdWUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmNmBAJhcAJjZwJjaAJjYwQCY2kJAQJhcgEFAmFwAwkAAAIFAmNpBQJjaQQCY2oJAQJhcwEFAmNoAwkAAAIFAmNqBQJjagQCY2sJAQJibwEFAmFwAwkAZgIFAmNnAAAEAmNsCQD8BwQFAmNjAgdkZXBvc2l0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmNrBQJjZwUDbmlsAwkAAAIFAmNsBQJjbAQCYVAFAmNsAwkAAQIFAmFQAgNJbnQEAmNtBQJhUAQCY24JAGQCBQJjaQUCY2cEAmNvCQBkAgUCY2oFAmNtCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYW8BBQJhcAUCY24JAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhcQEFAmNoBQJjbwUDbmlsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY3AGAmFwAmNnAmNoAmNjAmNxAmNyBAJjaQkBAmFyAQUCYXADCQAAAgUCY2kFAmNpBAJjagkBAmFzAQUCY2gDCQAAAgUCY2oFAmNqBAJjcwkBAmNiAQUCY2MDCQAAAgUCY3MFAmNzBAJjdAkAawMFAmNxBQJjaQUCY2oEAmN1CQECYm8BBQJjaAQCY3YJAGsDBQJjcQUCY2cFAmN0BAJjdwkAawMFAmNxBQJjZwUCY3MEAmN4CQCWAwEJAMwIAgAACQDMCAIJAGUCBQJjdgUCY3cFA25pbAMJAGYCBQJjdwAABAJjeQkA/AcEBQJjYwIId2l0aGRyYXcFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCY3UFAmN3BQNuaWwDCQAAAgUCY3kFAmN5BAJhUAUCY3kDCQABAgUCYVACA0ludAQCY3oFAmFQBAJjbgkAZQIFAmNpBQJjegQCY28JAGUCCQBlAgUCY2oFAmN3BQJjeAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFvAQUCYXAFAmNuCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYXEBBQJjaAUCY28JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCY3IFAmN4CQECYm8BBQJjaAUDbmlsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY0EBAmFwBAJhUAkA/AcEBQJiYwIaZ2V0UG9vbExlYXNlQ29uZmlnUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzCQDMCAIFAmFwBQNuaWwFA25pbAMJAAECBQJhUAIwKEJvb2xlYW4sIEludCwgSW50LCBTdHJpbmcsIFN0cmluZywgSW50LCBTdHJpbmcpBAJhUQUCYVAFAmFRCQECYVoBCQCsAgIJAKwCAgIBWwUCYXACHV0gZ2V0TGVhc2VQcm94eUNvbmZpZygpIGVycm9yAQJjQgcCY0MCYXACY2gCY0QCY2MCY3ECY3IEAmNqCQECYXMBBQJjaAMJAAACBQJjagUCY2oEAmNpAwkBAiE9AgUCY2oAAAkBAmFyAQUCYXAAAAMJAAACBQJjaQUCY2kEAmNFCQCWAwEJAMwIAgAACQDMCAIJAGUCCQECYlUBBQJhcAUCY0QFA25pbAQCY0YJAGsDBQJjQwUCY0UAZAQCY0cJAGUCBQJjaQUCY0YDCQAAAgUCY0cAAAUDbmlsAwkAZgIAAAUCY0cEAmNICQEBLQEFAmNHCQECY2YEBQJhcAUCY0gFAmNoBQJjYwQCY0kFAmNHCQECY3AGBQJhcAUCY0kFAmNoBQJjYwUCY3EFAmNyCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJjSgECYXAEAmNLCQECY0EBBQJhcAQCY0wIBQJjSwJfMQQCY00IBQJjSwJfMgQCY0QIBQJjSwJfMwQCY04IBQJjSwJfNAQCY08IBQJjSwJfNQQCY3EIBQJjSwJfNgQCY1AIBQJjSwJfNwMFAmNMCQECY0IHBQJjTQUCYXAFAmNPBQJjRAkBEUBleHRyTmF0aXZlKDEwNjIpAQUCY04FAmNxCQERQGV4dHJOYXRpdmUoMTA2MikBBQJjUAUDbmlsAQJjUQICYXACY1IEAmNTCQECY0EBBQJhcAQCY0wIBQJjUwJfMQQCY00IBQJjUwJfMgQCY0QIBQJjUwJfMwQCY04IBQJjUwJfNAQCY08IBQJjUwJfNQQCY3EIBQJjUwJfNgQCY1AIBQJjUwJfNwMFAmNMBAJjagkBAmFzAQUCY08DCQAAAgUCY2oFAmNqBAJjaQMJAQIhPQIFAmNqAAAJAQJhcgEFAmFwAAADCQAAAgUCY2kFAmNpBAJjVAkAlgMBCQDMCAIAAAkAzAgCCQBlAgkAZQIJAQJiVQEFAmFwBQJjUgUCY0QFA25pbAMJAAACBQJjVAUCY1QEAmNuCQBrAwUCY00FAmNUAGQDCQAAAgUCY24FAmNuBAJjVQkAZQIFAmNpBQJjbgMJAAACBQJjVQUCY1UDCQAAAgUCY1UAAAUDbmlsAwkAZgIAAAUCY1UJAQJjZgQFAmFwCQEBLQEFAmNVBQJjTwkBEUBleHRyTmF0aXZlKDEwNjIpAQUCY04JAQJjcAYFAmFwBQJjVQUCY08JARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmNOBQJjcQkBEUBleHRyTmF0aXZlKDEwNjIpAQUCY1AJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4FA25pbAECY1YCAmNXAmNYBAJjWQkBAmNRAgkBAmFWAgUEdGhpcwkBAmFlAAUCY1cEAmNaCQECY1ECCQECYVYCBQR0aGlzCQECYWYABQJjWAkAzggCBQJjWQUCY1oBAmRhBAJkYgJkYwJkZAJkZQQCZGYJAQFEAgUCZGQFAmRiBAJkZwkBAUQCBQJkZQUCZGMJAQJiWAIFAmRnBQJkZgECZGgDAmRkAmRlAmRpBAJkagkBAmJsAAQCZGsJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkagUBdAQCZGwJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkagUBdQQCZG0JAQJkYQQFAmRrBQJkbAUCZGQFAmRlBAJiWgkBAUQCBQJkZAUCZGsEAmJZCQEBRAIFAmRlBQJkbAQCZG4JAQFEAgUCZGkFAWIEAmRvCQECYlgCBQJiWgUCZG4EAmRwCQECYlgCBQJiWQUCZG4JAMwIAgUCZG0JAMwIAgUCZG8JAMwIAgUCZHAFA25pbAECZHEDAmRkAmRlAmRpBAJkcgkBAmRoAwUCZGQFAmRlBQJkaQkAzAgCCQEBSAIJAJEDAgUCZHIAAAUBYgkAzAgCCQEBSAIJAJEDAgUCZHIAAQUBYgkAzAgCCQEBSAIJAJEDAgUCZHIAAgUBYgUDbmlsAQJkcwQCZHQCZHUCZHYCYWIEAmRqCQECYmwABAJkdwkAkQMCBQJkagUBcQQCZHgJAJEDAgUCZGoFAXIEAmR5CQCRAwIFAmRqBQFzBAJkYgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRqBQF0BAJkYwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRqBQF1BAJkegkAkQMCBQJkagUBcAQCZEEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQkA2QQBBQJkdwkArAICCQCsAgICBkFzc2V0IAUCZHcCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5AwkBAiE9AgUCZHcFAmR1CQACAQIVSW52YWxpZCBhc3NldCBwYXNzZWQuBAJkQgkBAmJVAQUCZHgEAmRDCQEBRAIFAmRCBQJkYgQCZEQJAQJiVQEFAmR5BAJkRQkBAUQCBQJkRAUCZGMEAmRGCQECYlgCBQJkRQUCZEMEAmRHCQEBSAIFAmRGBQFiBAJkSAkBAUQCBQJkdgUBYgQCZEkJAQFEAgUCZEEFAWIEAmRKCQC8AgMFAmRDBQJkSAUCZEkEAmRLCQC8AgMFAmRFBQJkSAUCZEkEAmRMCQEBSwMFAmRKBQJkYgUFRkxPT1IEAmRNCQEBSwMFAmRLBQJkYwUFRkxPT1IEAmROAwkAAAIFAmR0AgAFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhYgUCZEwDCQAAAgUCZHgCBVdBVkVTBQR1bml0CQDZBAEFAmR4CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFiBQJkTQMJAAACBQJkeQIFV0FWRVMFBHVuaXQJANkEAQUCZHkJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFkAgkApQgBBQJhYgUCZHQJAQJiUQYFAmRMBQJkTQUCZHYFAmRHBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVwAFAmRHCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBWAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmRHBQNuaWwJAJwKCgUCZEwFAmRNBQJkeAUCZHkFAmRCBQJkRAUCZEEFAmRGBQJkegUCZE4BAmRPCQJkdAJkUAJkUQJkUgJkUwJkVAJhYgJkVQJkVgQCZGoJAQJibAAEAmR3CQDZBAEJAJEDAgUCZGoFAXEEAmRXCQCRAwIFAmRqBQFyBAJkWAkAkQMCBQJkagUBcwQCZFkJAJEDAgUCZGoFAXYEAmRaCQCRAwIFAmRqBQF3BAJkawkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRqBQF0BAJkbAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRqBQF1BAJkegkAkQMCBQJkagUBcAQCZEEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCZHcJAKwCAgkArAICAgZBc3NldCAJANgEAQUCZHcCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJlYQkA2AQBCQELdmFsdWVPckVsc2UCBQJkUgkA2QQBAgVXQVZFUwQCZWIJANgEAQkBC3ZhbHVlT3JFbHNlAgUCZFQJANkEAQIFV0FWRVMDAwkBAiE9AgUCZFcFAmVhBgkBAiE9AgUCZFgFAmViCQACAQIiSW52YWxpZCBhbXQgb3IgcHJpY2UgYXNzZXQgcGFzc2VkLgQCZEIDBQJkVQkBAmJVAQUCZFcJAGUCCQECYlUBBQJkVwUCZFEEAmREAwUCZFUJAQJiVQEFAmRYCQBlAgkBAmJVAQUCZFgFAmRTBAJlYwkBAUQCBQJkUQUCZGsEAmVkCQEBRAIFAmRTBQJkbAQCZWUJAQJiWAIFAmVkBQJlYwQCZEMJAQFEAgUCZEIFAmRrBAJkRQkBAUQCBQJkRAUCZGwEAmVmAwkAAAIFAmRBAAAEAmRGBQFlBAJlZwUBZQQCZG4JAHYGCQC5AgIFAmVjBQJlZAAACQC2AgEABQABAAAFBERPV04JAJcKBQkBAUgCBQJkbgUBYgkBAUgCBQJlYwUCZGsJAQFIAgUCZWQFAmRsCQECYlgCCQC3AgIFAmRFBQJlZAkAtwICBQJkQwUCZWMFAmVnBAJkRgkBAmJYAgUCZEUFAmRDBAJlZwkAvAIDCQEBUgEJALgCAgUCZEYFAmVlBQFkBQJkRgQCZWgJAQFEAgUCZFAFAWIDAwkBAiE9AgUCZEYFAWUJAL8CAgUCZWcFAmVoBwkAAgEJAKwCAgkArAICCQCsAgICD1ByaWNlIHNsaXBwYWdlIAkApgMBBQJlZwIeIGV4Y2VlZGVkIHRoZSBwYXNzZWQgbGltaXQgb2YgCQCmAwEFAmVoBAJkSQkBAUQCBQJkQQUBYgQCZWkJAL0CBAUCZWMJAQJjYQMFAmRFBQJkQwUHQ0VJTElORwUBZAUHQ0VJTElORwQCZWoJAL0CBAUCZWQFAWQJAQJjYQMFAmRFBQJkQwUFRkxPT1IFB0NFSUxJTkcEAmVrAwkAvwICBQJlaQUCZWQJAJQKAgUCZWoFAmVkCQCUCgIFAmVjBQJlaQQCZWwIBQJlawJfMQQCZW0IBQJlawJfMgQCZG4JAL0CBAUCZEkFAmVtBQJkRQUFRkxPT1IJAJcKBQkBAUsDBQJkbgUBYgUFRkxPT1IJAQFLAwUCZWwFAmRrBQdDRUlMSU5HCQEBSwMFAmVtBQJkbAUHQ0VJTElORwUCZEYFAmVnBAJlbggFAmVmAl8xBAJlbwgFAmVmAl8yBAJlcAgFAmVmAl8zBAJkRwkBAUgCCAUCZWYCXzQFAWIEAmVxCQEBSAIIBQJlZgJfNQUBYgMJAGcCAAAFAmVuCQACAQI2SW52YWxpZCBjYWxjdWxhdGlvbnMuIExQIGNhbGN1bGF0ZWQgaXMgbGVzcyB0aGFuIHplcm8uBAJlcgMJAQEhAQUCZFYAAAUCZW4EAmVzCQBlAgUCZFEFAmVvBAJldAkAZQIFAmRTBQJlcAQCZXUJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZEcJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZEcJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFhAgUCYWIFAmR0CQECYkYKBQJlbwUCZXAFAmVyBQJkRwUCZFAFAmVxBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJlcwUCZXQFA25pbAkAnwoNBQJlbgUCZXIFAmRHBQJkQgUCZEQFAmRBBQJkdwUCZHoFAmV1BQJlcwUCZXQFAmRSBQJkVAECZXYDAmV3AmV4AmRBBAJleQkBAUcCBQJldwkAtgIBBQJiQQQCZXoJAQFHAgUCZXgJALYCAQUCYkIEAmVBCQC8AgMJAHYGCQC5AgIFAmV5BQJlegAACQC2AgEABQABABIFBERPV04FAWcFAmRBAwkAAAIFAmRBBQFmBQFmBQJlQQECZUIDAmVDAmVEAmVFBAJlRgkAuAICCQC2AgEJAQJiVQEJAQJicQEFAmJ5BQJlQwQCZUcJALgCAgkAtgIBCQECYlUBCQECYnEBBQJiegUCZUQEAmVICQC4AgIJALYCAQgJAQV2YWx1ZQEJAOwHAQUCYngIcXVhbnRpdHkFAmVFBAJlSQkBAmV2AwUCZUYFAmVHBQJlSAUCZUkBAmVKAwJlSwJlTAJlRQQCZUYJAGQCCQECYlUBCQECYnEBBQJieQUCZUsEAmVHCQBkAgkBAmJVAQkBAmJxAQUCYnoFAmVMBAJlSAkAZAIICQEFdmFsdWUBCQDsBwEFAmJ4CHF1YW50aXR5BQJlRQQCZUEJAQJldgMJALYCAQUCZUYJALYCAQUCZUcJALYCAQUCZUgEAmVNCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJhawUGaGVpZ2h0CQDMCAIJAQtTdHJpbmdFbnRyeQIFAmFqCQCmAwEFAmVBBQNuaWwJAJQKAgUCZU0FAmVBAQJlTgAJAQt2YWx1ZU9yRWxzZQIJAJsIAgUCYmMJAQJhSAEJAKUIAQUEdGhpcwcBAmVPAgJlUAJlQQMJAMACAgUCZUEFAmVQBgkBAmFaAQkAuQkCCQDMCAICInVwZGF0ZWQgS0xwIGxvd2VyIHRoYW4gY3VycmVudCBLTHAJAMwIAgkApgMBBQJlUAkAzAgCCQCmAwEFAmVBBQNuaWwCASABAmVRAQJlUgQCZUYJAQJiVQEJAQJicQEFAmJ5BAJlRwkBAmJVAQkBAmJxAQUCYnoEAmVTCAUCZVIGYW1vdW50BAJlVAkAbgQIBQJlUgZhbW91bnQIBQJlUgVwcmljZQUBYgUFRkxPT1IEAmVVAwkAAAIIBQJlUglvcmRlclR5cGUFA0J1eQkAlAoCBQJlUwkBAS0BBQJlVAkAlAoCCQEBLQEFAmVTBQJlVAQCZUsIBQJlVQJfMQQCZUwIBQJlVQJfMgMDAwkBAmJqAAYJAAACBQJidwUBbQYJAAACBQJidwUBbgkAAgECHEV4Y2hhbmdlIG9wZXJhdGlvbnMgZGlzYWJsZWQDAwkBAiE9AggIBQJlUglhc3NldFBhaXILYW1vdW50QXNzZXQFAmJ5BgkBAiE9AggIBQJlUglhc3NldFBhaXIKcHJpY2VBc3NldAUCYnoJAAIBAhNXcm9uZyBvcmRlciBhc3NldHMuBAJlVgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCoAwEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUCYWoCATAJAQJiYgECC2ludmFsaWQga0xwBAJlVwkBAmVKAwUCZUsFAmVMAAAEAmVYCAUCZVcCXzEEAmVZCAUCZVcCXzIEAmVaCQDAAgIFAmVZBQJlVgQCZmEJALkJAgkAzAgCAgRrTHA9CQDMCAIJAKYDAQUCZVYJAMwIAgIIIGtMcE5ldz0JAMwIAgkApgMBBQJlWQkAzAgCAhQgYW1vdW50QXNzZXRCYWxhbmNlPQkAzAgCCQCkAwEFAmVGCQDMCAICEyBwcmljZUFzc2V0QmFsYW5jZT0JAMwIAgkApAMBBQJlRwkAzAgCAhkgYW1vdW50QXNzZXRCYWxhbmNlRGVsdGE9CQDMCAIJAKQDAQUCZUsJAMwIAgIYIHByaWNlQXNzZXRCYWxhbmNlRGVsdGE9CQDMCAIJAKQDAQUCZUwJAMwIAgIIIGhlaWdodD0JAMwIAgkApAMBBQZoZWlnaHQFA25pbAIACQCUCgIFAmVaBQJmYQECZmIBAmZjAwkBAiE9AgkAkAMBCAUCZmMIcGF5bWVudHMAAQkAAgECHWV4YWN0bHkgMSBwYXltZW50IGlzIGV4cGVjdGVkBAJmZAkBBXZhbHVlAQkAkQMCCAUCZmMIcGF5bWVudHMAAAQCZHUJAQV2YWx1ZQEIBQJmZAdhc3NldElkBAJmZQgFAmZkBmFtb3VudAQCZWYJAQJkcwQJANgEAQgFAmZjDXRyYW5zYWN0aW9uSWQJANgEAQUCZHUFAmZlCAUCZmMGY2FsbGVyBAJkTAgFAmVmAl8xBAJkTQgFAmVmAl8yBAJkTggFAmVmA18xMAQCZmYDCQEBIQEJAQJiaQEIBQJmYwZjYWxsZXIDCQECYmoABgkAAAIFAmJ3BQFuBwMFAmZmCQACAQkArAICAixHZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4uIFN0YXR1cyA9IAkApAMBBQJidwkAlwoFBQJkTAUCZE0FAmZlBQJkdQUCZE4BAmZnAwJmYwJkUAJkVgMJAQIhPQIJAJADAQgFAmZjCHBheW1lbnRzAAIJAAIBAh9leGFjdGx5IDIgcGF5bWVudHMgYXJlIGV4cGVjdGVkBAJmaAkBBXZhbHVlAQkAkQMCCAUCZmMIcGF5bWVudHMAAAQCZmkJAQV2YWx1ZQEJAJEDAggFAmZjCHBheW1lbnRzAAEEAmZqCQECZE8JCQDYBAEIBQJmYw10cmFuc2FjdGlvbklkBQJkUAgFAmZoBmFtb3VudAgFAmZoB2Fzc2V0SWQIBQJmaQZhbW91bnQIBQJmaQdhc3NldElkCQClCAEIBQJmYwZjYWxsZXIHBQJkVgQCZmsDCQEBIQEJAQJiaQEIBQJmYwZjYWxsZXIDAwkBAmJqAAYJAAACBQJidwUBbAYJAAACBQJidwUBbgcDBQJmawkAAgEJAKwCAgIsUHV0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCYncFAmZqAQJmbAECY2cEAmZtCQD8BwQFAmJjAgRlbWl0CQDMCAIFAmNnBQNuaWwFA25pbAMJAAACBQJmbQUCZm0EAmZuBAJhUAUCZm0DCQABAgUCYVACB0FkZHJlc3MEAmZvBQJhUAkA/AcEBQJmbwIEZW1pdAkAzAgCBQJjZwUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZm4FAmZuBQJjZwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZnACAmNnAmFpBAJmcQMJAAACBQJhaQAAAAAJAGsDBQJjZwUCYWkFAWIJAJQKAgkAZQIFAmNnBQJmcQUCZnEBAmZyBAJmcwJmdAJhYgJhYwQCZnUJAAACBQJhYwUEdW5pdAQCZnYJAQJiVQEJAQJicQEFAmJ5BAJmdwkBAmJVAQkBAmJxAQUCYnoEAmZ4AwkAAAIFAmZ0BQJieQYDCQAAAgUCZnQFAmJ6BwkBAmFaAQINaW52YWxpZCBhc3NldAQCZnkDBQJmdQkAlAoCBQJmdgUCZncDBQJmeAkAlAoCCQBlAgUCZnYFAmZzBQJmdwkAlAoCBQJmdgkAZQIFAmZ3BQJmcwQCZnoIBQJmeQJfMQQCZkEIBQJmeQJfMgQCZkIDBQJmeAkAlAoCBQJmcwAACQCUCgIAAAUCZnMEAmZDCAUCZkICXzEEAmZECAUCZkICXzIEAmVTCAkBAmZwAgUCZkMFAmJlAl8xBAJlVAgJAQJmcAIFAmZEBQJiZQJfMQQCZkUJAQJmcAIFAmZzBQJiZQQCZkYIBQJmRQJfMQQCZnEIBQJmRQJfMgQCZkcJAGQCBQJmegUCZVMEAmZICQBkAgUCZkEFAmVUBAJmSQkBAmJYAgkBAUQCBQJmSAUCYkIJAQFEAgUCZkcFAmJBBAJmSgkBAUgCBQJmSQUBYgQCZksDBQJmeAUCZnoFAmZBBAJmTAkAtgIBBQJmSwQCZk0JALYCAQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJieAkArAICCQCsAgICBmFzc2V0IAkA2AQBBQJieAIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmZOAwkAvwICBQJmTQUBZgYJAQJhWgECImluaXRpYWwgZGVwb3NpdCByZXF1aXJlcyBhbGwgY29pbnMDCQAAAgUCZk4FAmZOBAJmTwkAtgIBBQJmRgQCZlAJAJYDAQkAzAgCAAAJAMwIAgkAoAMBCQC6AgIJALkCAgUCZk0JALgCAgkBCnNxcnRCaWdJbnQECQC3AgIFAWQJALoCAgkAuQICBQJmTwUBZAUCZkwAEgASBQRET1dOBQFkBQFkBQNuaWwEAmV1AwUCZnUFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVcABQJmSgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVgCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJmSgkAzAgCCQELU3RyaW5nRW50cnkCCQECYWECCQClCAEJAQV2YWx1ZQEFAmFiCQDYBAEJAQV2YWx1ZQEFAmFjCQECYkYKBQJmQwUCZkQFAmZQBQJmSgAAAAAFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAAAAAABQNuaWwEAmZRCQECYlgCCQEBRAIFAmZBBQJiQgkBAUQCBQJmegUCYkEEAmZSCQEBSAIFAmZRBQFiBAJmUwQCZlQDBQJmeAkAlAoCBQJmQwUCZnoJAJQKAgUCZkQFAmZBBAJjZwgFAmZUAl8xBAJmVQgFAmZUAl8yBAJmVgkAoAMBCQC8AgMFAmZNCQC2AgEJAGkCBQJjZwACCQC2AgEFAmZVCQBrAwkAZQIFAmZQBQJmVgUBYgUCZlYJAJcKBQUCZlAFAmV1BQJmcQUCZlMFAmZ4CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJmVwUCZlgCZkYCZnQCYWICYWMEAmZ1CQAAAgUCYWMFBHVuaXQEAmRqCQECYmwABAJkawkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRqBQF0BAJkbAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRqBQF1BAJmWQkAzAgCAwkAAAIFAmZ0BQJieAYJAQJhWgECEGludmFsaWQgbHAgYXNzZXQFA25pbAMJAAACBQJmWQUCZlkEAmZaAwkAAAIFAmZYBQJieQYDCQAAAgUCZlgFAmJ6BwkBAmFaAQINaW52YWxpZCBhc3NldAQCZ2EDBQJmWgkAtgIBCQECYlUBCQECYnEBBQJieQkAtgIBCQECYlUBCQECYnEBBQJiegQCZ2IDBQJmWgUCZGsFAmRsBAJnYwkBAmJVAQkBAmJxAQUCYnkEAmdkCQECYlUBCQECYnEBBQJiegQCZ2UDBQJmWgUCZ2MFAmdkBAJnZgkAtgIBBQJnZQQCZk0JALYCAQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJieAkArAICCQCsAgICBmFzc2V0IAkA2AQBBQJieAIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmdnCQC2AgEFAmZGBAJnaAkAlgMBCQDMCAIAAAkAzAgCCQCgAwEJALoCAgkAuQICBQJnYQkAuAICBQFkCQB2BgkAuAICBQFkCQC6AgIJALkCAgUCZ2cFAWQFAmZNABIFAWgAAAASBQRET1dOBQFkBQNuaWwEAmdpCQECZnACBQJnaAUCYmcEAmdqCAUCZ2kCXzEEAmZxCAUCZ2kCXzIEAmdrAwUCZloJAJYKBAUCZ2oAAAkAZQIFAmdjBQJnaAUCZ2QJAJYKBAAABQJnagUCZ2MJAGUCBQJnZAUCZ2gEAmdsCAUCZ2sCXzEEAmdtCAUCZ2sCXzIEAmduCAUCZ2sCXzMEAmdvCAUCZ2sCXzQEAmZJCQECYlgCCQEBRAIFAmdvBQJiQgkBAUQCBQJnbgUCYkEEAmZKCQEBSAIFAmZJBQFiBAJldQMFAmZ1BQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFkAgkApQgBCQEFdmFsdWUBBQJhYgkA2AQBCQEFdmFsdWUBBQJhYwkBAmJRBgUCZ2wFAmdtBQJmRgUCZkoFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZkoJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZkoFA25pbAQCZlEJAQJiWAIJAQFEAgUCZ2QFAmJCCQEBRAIFAmdjBQJiQQQCZlIJAQFIAgUCZlEFAWIEAmZTBAJncAkAaAIJAKADAQkAvAIDBQJnYQUCZ2cFAmZNAAIJAGsDCQBlAgUCZ2oFAmdwBQFiBQJncAkAlwoFBQJnagUCZXUFAmZxBQJmUwUCZloJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmdxAAQCZ3IJAQJhUgAEAmFQCQCdCAIFAmdyCQEBVQADCQABAgUCYVACBlN0cmluZwQCYVUFAmFQCQDZBAEFAmFVAwkAAQIFAmFQAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmdzAQJmYwQCYVAJAQJncQADCQABAgUCYVACCkJ5dGVWZWN0b3IEAmd0BQJhUAkAAAIIBQJmYw9jYWxsZXJQdWJsaWNLZXkFAmd0AwkAAQIFAmFQAgRVbml0CQAAAggFAmZjBmNhbGxlcgUEdGhpcwkAAgECC01hdGNoIGVycm9yAQJndQECZmMEAmd2CQACAQIRUGVybWlzc2lvbiBkZW5pZWQEAmFQCQECZ3EAAwkAAQIFAmFQAgpCeXRlVmVjdG9yBAJndAUCYVADCQAAAggFAmZjD2NhbGxlclB1YmxpY0tleQUCZ3QGBQJndgMJAAECBQJhUAIEVW5pdAMJAAACCAUCZmMGY2FsbGVyBQR0aGlzBgUCZ3YJAAIBAgtNYXRjaCBlcnJvchwCZmMBCXJlYmFsYW5jZQAJAM4IAgkBAmNKAQkBAmFWAgUEdGhpcwkBAmFlAAkBAmNKAQkBAmFWAgUEdGhpcwkBAmFmAAJmYwEhY2FsY3VsYXRlQW1vdW50T3V0Rm9yU3dhcFJFQURPTkxZAwJndwJneAJneQQCZ3oDCQAAAgUCZ3gHBAJnQQkBAmFWAgUEdGhpcwkBAmFmAAQCZ0IJAQJhVgIFBHRoaXMJAQJhZQAJAJQKAgUCZ0EFAmdCBAJnQQkBAmFWAgUEdGhpcwkBAmFlAAQCZ0IJAQJhVgIFBHRoaXMJAQJhZgAJAJQKAgUCZ0EFAmdCBAJnQQgFAmd6Al8xBAJnQggFAmd6Al8yBAJnQwkBAmJVAQUCZ0IEAmdECQECYlUBBQJnQQQCZ0UJAGsDBQJnRAUCZ3cJAGQCBQJnQwUCZ3cEAmdGCQC5AgIJALYCAQUCZ0MJALYCAQUCZ0QEAmdHCQC5AgIJALcCAgkAtwICCQC2AgEJAQJiVQEFAmdCCQC2AgEFAmd3CQC2AgEFAmd5CQC4AgIJALYCAQkBAmJVAQUCZ0EJALYCAQUCZ0UEAmdIAwkAwAICBQJnRwUCZ0YGCQACAQIUbmV3IEsgaXMgZmV3ZXIgZXJyb3IDCQAAAgUCZ0gFAmdICQCUCgIFA25pbAUCZ0UJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZmMBJmNhbGN1bGF0ZUFtb3VudE91dEZvclN3YXBBbmRTZW5kVG9rZW5zBQJndwJneAJnSQJnSgJneQQCZ0sKAAJiZgkA/AcEBQJiYwIXZ2V0U3dhcENvbnRyYWN0UkVBRE9OTFkFA25pbAUDbmlsAwkAAQIFAmJmAgZTdHJpbmcFAmJmCQACAQkArAICCQADAQUCYmYCGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwQCZ0wKAAJiZgkA/AcEBQJiYwIaaXNQb29sU3dhcERpc2FibGVkUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJiZgIHQm9vbGVhbgUCYmYJAAIBCQCsAgIJAAMBBQJiZgIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCZ00DCQEBIQEJAQJiaQEIBQJmYwZjYWxsZXIDAwkBAmJqAAYJAAACBQJidwUBbgYFAmdMBwQCZlkJAMwIAgMDCQEBIQEFAmdNBgkBAmdzAQUCZmMGCQECYVoBAiJzd2FwIG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQBnAggJAQV2YWx1ZQEJAJEDAggFAmZjCHBheW1lbnRzAAAGYW1vdW50BQJndwYJAQJhWgECDFdyb25nIGFtb3VudAkAzAgCAwkAAAIIBQJmYwZjYWxsZXIJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmdLBgkBAmFaAQIRUGVybWlzc2lvbiBkZW5pZWQFA25pbAMJAAACBQJmWQUCZlkEAmZkCQEFdmFsdWUBCQCRAwIIBQJmYwhwYXltZW50cwAABAJnQgkBAmJxAQgFAmZkB2Fzc2V0SWQEAmdBAwkAAAIFAmd4BwkBAmFWAgUEdGhpcwkBAmFmAAkBAmFWAgUEdGhpcwkBAmFlAAQCZ0MJAGUCCQBlAgkBAmJVAQUCZ0IICQEFdmFsdWUBCQCRAwIIBQJmYwhwYXltZW50cwAABmFtb3VudAUCZ3kEAmdECQECYlUBBQJnQQQCZ0UJAGsDBQJnRAUCZ3cJAGQCBQJnQwUCZ3cEAmdGCQC5AgIJALYCAQUCZ0MJALYCAQUCZ0QEAmdHCQC5AgIJALcCAgkAtgIBCQECYlUBBQJnQgkAtgIBBQJneQkAuAICCQC2AgEJAQJiVQEFAmdBCQC2AgEFAmdFBAJnSAMJAMACAgUCZ0cFAmdGBgkAAgECFG5ldyBLIGlzIGZld2VyIGVycm9yAwkAAAIFAmdIBQJnSAQCZ04DCQBnAgUCZ0UFAmdJBgkAAgECLEV4Y2hhbmdlIHJlc3VsdCBpcyBmZXdlciBjb2lucyB0aGFuIGV4cGVjdGVkAwkAAAIFAmdOBQJnTgQCZUsDBQJneAkBAS0BBQJnRQUCZ3kEAmVMAwUCZ3gFAmd5CQEBLQEFAmdFBAJnTwgJAQJlSgMFAmVLBQJlTAAAAl8xAwkAAAIFAmdPBQJnTwQCZ1AJAQJjSgEFAmdCAwkAAAIFAmdQBQJnUAQCZ1EJAQJjUQIFAmdBBQJnRQMJAAACBQJnUQUCZ1EJAJQKAgkAzggCCQDOCAIFAmdRBQJnUAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQJnSgUCZ0UJAQJibwEFAmdBBQNuaWwFAmdFCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmZjAQNwdXQCAmRQAmdSAwkAZgIAAAUCZFAJAAIBAiBJbnZhbGlkIHNsaXBwYWdlVG9sZXJhbmNlIHBhc3NlZAQCZmoJAQJmZwMFAmZjBQJkUAYEAmVyCAUCZmoCXzIEAmR3CAUCZmoCXzcEAmROCAUCZmoCXzkEAmVzCAUCZmoDXzEwBAJldAgFAmZqA18xMQQCZ1MIBQJmagNfMTIEAmdUCAUCZmoDXzEzBAJmaAkAtgIBCAkBBXZhbHVlAQkAkQMCCAUCZmMIcGF5bWVudHMAAAZhbW91bnQEAmZpCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJmYwhwYXltZW50cwABBmFtb3VudAQCZUkJAQJlQgMFAmZoBQJmaQkAtgIBAAADCQAAAgUCZUkFAmVJBAJmbQkA/AcEBQJiYwIEZW1pdAkAzAgCBQJlcgUDbmlsBQNuaWwDCQAAAgUCZm0FAmZtBAJmbgQCYVAFAmZtAwkAAQIFAmFQAgdBZGRyZXNzBAJmbwUCYVAJAPwHBAUCZm8CBGVtaXQJAMwIAgUCZXIFA25pbAUDbmlsBQR1bml0AwkAAAIFAmZuBQJmbgQCZ1UDCQBmAgUCZXMAAAkA/AcEBQJiRQIDcHV0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmdTBQJlcwUDbmlsBQNuaWwDCQAAAgUCZ1UFAmdVBAJnVgMJAGYCBQJldAAACQD8BwQFAmJFAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZ1QFAmV0BQNuaWwFA25pbAMJAAACBQJnVgUCZ1YEAmdXAwUCZ1IEAmdYCQD8BwQFAmJEAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJkdwUCZXIFA25pbAMJAAACBQJnWAUCZ1gFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZmMGY2FsbGVyBQJlcgUCZHcFA25pbAQCZ1kJAQJlSgMAAAAAAAADCQAAAgUCZ1kFAmdZBAJlQQgFAmdZAl8yBAJnTwgFAmdZAl8xBAJnWgkBAmVPAgUCZUkFAmVBAwkAAAIFAmdaBQJnWgQCaGEJAPwHBAUEdGhpcwIJcmViYWxhbmNlBQNuaWwFA25pbAMJAAACBQJoYQUCaGEJAM4IAgkAzggCBQJkTgUCZ1cFAmdPCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmZjAQpwdXRGb3JGcmVlAQJoYgMJAGYCAAAFAmhiCQACAQIUSW52YWxpZCB2YWx1ZSBwYXNzZWQEAmZqCQECZmcDBQJmYwUCaGIHBAJkTggFAmZqAl85BAJmaAkAtgIBCAkBBXZhbHVlAQkAkQMCCAUCZmMIcGF5bWVudHMAAAZhbW91bnQEAmZpCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJmYwhwYXltZW50cwABBmFtb3VudAQCZUkJAQJlQgMFAmZoBQJmaQkAtgIBAAADCQAAAgUCZUkFAmVJBAJoYwkBAmVKAwAAAAAAAAQCZ08IBQJoYwJfMQQCZUEIBQJoYwJfMgQCZ1oJAQJlTwIFAmVJBQJlQQMJAAACBQJnWgUCZ1oJAM4IAgUCZE4FAmdPCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmZjAQlwdXRPbmVUa24CAmhkAmhlBAJoZgoAAmJmCQD8BwQFAmJjAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYmYCB0Jvb2xlYW4FAmJmCQACAQkArAICCQADAQUCYmYCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmZrAwkBASEBCQECYmkBCAUCZmMGY2FsbGVyAwMDCQECYmoABgkAAAIFAmJ3BQFsBgkAAAIFAmJ3BQFuBgUCaGYHBAJmWQkAzAgCAwMJAQEhAQUCZmsGCQECZ3MBBQJmYwYJAQJhWgECIXB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmZjCHBheW1lbnRzAAEGCQECYVoBAh5leGFjdGx5IDEgcGF5bWVudCBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJmWQUCZlkEAmhnCQCRAwIIBQJmYwhwYXltZW50cwAABAJmdAgFAmhnB2Fzc2V0SWQEAmZzCAUCaGcGYW1vdW50BAJlSQMJAAACBQJmdAUCYnkJAQJlQgMJALYCAQUCZnMJALYCAQAACQC2AgEAAAMJAAACBQJmdAUCYnoJAQJlQgMJALYCAQAACQC2AgEFAmZzCQC2AgEAAAkBAmFaAQIecGF5bWVudCBhc3NldCBpcyBub3Qgc3VwcG9ydGVkAwkAAAIFAmVJBQJlSQQCYWIIBQJmYwZjYWxsZXIEAmFjCAUCZmMNdHJhbnNhY3Rpb25JZAQCaGgJAQJmcgQFAmZzBQJmdAUCYWIFAmFjAwkAAAIFAmhoBQJoaAQCZngIBQJoaAJfNQQCaGkIBQJoaAJfNAQCZnEIBQJoaAJfMwQCZXUIBQJoaAJfMgQCaGoIBQJoaAJfMQQCaGsDAwkAZgIFAmhkAAAJAGYCBQJoZAUCaGoHCQECYVoBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmhkBQNuaWwCAAUCaGoEAmZtCQECZmwBBQJoawMJAAACBQJmbQUCZm0EAmdXAwUCaGUEAmhsCQD8BwQFAmJEAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJieAUCaGsFA25pbAMJAAACBQJobAUCaGwFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZmMGY2FsbGVyBQJoawUCYngFA25pbAQCaG0DCQBmAgUCZnEAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJiZAUCZnEFAmZ0BQNuaWwFA25pbAQCaG4DCQAAAgUEdGhpcwUCYmQJAJQKAgAAAAADBQJmeAkAlAoCCQEBLQEFAmZxAAAJAJQKAgAACQEBLQEFAmZxBAJlSwgFAmhuAl8xBAJlTAgFAmhuAl8yBAJobwkBAmVKAwUCZUsFAmVMAAAEAmdPCAUCaG8CXzEEAmVBCAUCaG8CXzIEAmVWCQEFdmFsdWUBCQCiCAEFAmFqBAJnWgkBAmVPAgUCZUkFAmVBAwkAAAIFAmdaBQJnWgQCaGEJAPwHBAUEdGhpcwIJcmViYWxhbmNlBQNuaWwFA25pbAMJAAACBQJoYQUCaGEJAJQKAgkAzggCCQDOCAIJAM4IAgUCZXUFAmdXBQJobQUCZ08FAmhrCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmZjARFwdXRPbmVUa25SRUFET05MWQICZnQCZnMEAmhwCQECZnIEBQJmcwkBAmJvAQUCZnQFBHVuaXQFBHVuaXQEAmhqCAUCaHACXzEEAmV1CAUCaHACXzIEAmZxCAUCaHACXzMEAmhpCAUCaHACXzQEAmZ4CAUCaHACXzUJAJQKAgUDbmlsCQCVCgMFAmhqBQJmcQUCaGkCZmMBCWdldE9uZVRrbgICaHECaGQEAmhmCgACYmYJAPwHBAUCYmMCKGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJiZgIHQm9vbGVhbgUCYmYJAAIBCQCsAgIJAAMBBQJiZgIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCZmYDCQEBIQEJAQJiaQEIBQJmYwZjYWxsZXIDAwkBAmJqAAYJAAACBQJidwUBbgYFAmhmBwQCZlkJAMwIAgMDCQEBIQEFAmZmBgkBAmdzAQUCZmMGCQECYVoBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJmYwhwYXltZW50cwABBgkBAmFaAQIeZXhhY3RseSAxIHBheW1lbnQgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZlkFAmZZBAJmWAkBAmJvAQUCaHEEAmhnCQCRAwIIBQJmYwhwYXltZW50cwAABAJmdAgFAmhnB2Fzc2V0SWQEAmZGCAUCaGcGYW1vdW50BAJlSQkBAmVCAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJlSQUCZUkEAmFiCAUCZmMGY2FsbGVyBAJhYwgFAmZjDXRyYW5zYWN0aW9uSWQEAmhyCQECZlcFBQJmWAUCZkYFAmZ0BQJhYgUCYWMDCQAAAgUCaHIFAmhyBAJmWggFAmhyAl81BAJoaQgFAmhyAl80BAJmcQgFAmhyAl8zBAJldQgFAmhyAl8yBAJocwgFAmhyAl8xBAJjZwMDCQBmAgUCaGQAAAkAZgIFAmhkBQJocwcJAQJhWgEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCaGQFA25pbAIABQJocwQCaHQJAPwHBAUCYmMCBGJ1cm4JAMwIAgUCZkYFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZnQFAmZGBQNuaWwDCQAAAgUCaHQFAmh0BAJnUQkBAmNRAgUCaHEJAGQCBQJjZwkAlgMBCQDMCAIAAAkAzAgCBQJmcQUDbmlsBAJodQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhYgUCY2cFAmZYBQNuaWwEAmhtAwkAZgIFAmZxAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYmQFAmZxBQJmWAUDbmlsBQNuaWwEAmh2BAJodwMJAAACBQR0aGlzBQJiZAAABQJmcQMFAmZaCQCUCgIJAQEtAQkAZAIFAmNnBQJodwAACQCUCgIAAAkBAS0BCQBkAgUCY2cFAmh3BAJlSwgFAmh2Al8xBAJlTAgFAmh2Al8yBAJoeAkBAmVKAwUCZUsFAmVMAAAEAmdPCAUCaHgCXzEEAmVBCAUCaHgCXzIEAmdaCQECZU8CBQJlSQUCZUEDCQAAAgUCZ1oFAmdaCQCUCgIJAM4IAgkAzggCCQDOCAIJAM4IAgUCZXUFAmdRBQJodQUCaG0FAmdPBQJjZwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJmYwERZ2V0T25lVGtuUkVBRE9OTFkCAmZYAmZGBAJoeQkBAmZXBQkBAmJvAQUCZlgFAmZGBQJieAUEdW5pdAUEdW5pdAQCaHMIBQJoeQJfMQQCZXUIBQJoeQJfMgQCZnEIBQJoeQJfMwQCaGkIBQJoeQJfNAQCZloIBQJoeQJfNQkAlAoCBQNuaWwJAJUKAwUCaHMFAmZxBQJoaQJmYwETdW5zdGFrZUFuZEdldE9uZVRrbgMCaHoCaHECaGQEAmhmCgACYmYJAPwHBAUCYmMCKGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJiZgIHQm9vbGVhbgUCYmYJAAIBCQCsAgIJAAMBBQJiZgIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCZmYDCQEBIQEJAQJiaQEIBQJmYwZjYWxsZXIDAwkBAmJqAAYJAAACBQJidwUBbgYFAmhmBwQCZlkJAMwIAgMDCQEBIQEFAmZmBgkBAmdzAQUCZmMGCQECYVoBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJmYwhwYXltZW50cwAABgkBAmFaAQIYbm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZlkFAmZZBAJmWAkBAmJvAQUCaHEEAmFiCAUCZmMGY2FsbGVyBAJhYwgFAmZjDXRyYW5zYWN0aW9uSWQEAmVJCQECZUIDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmVJBQJlSQQCaEEJAPwHBAUCYkQCB3Vuc3Rha2UJAMwIAgkA2AQBBQJieAkAzAgCBQJoegUDbmlsBQNuaWwDCQAAAgUCaEEFAmhBBAJoQgkBAmZXBQUCZlgFAmh6BQJieAUCYWIFAmFjAwkAAAIFAmhCBQJoQgQCZloIBQJoQgJfNQQCaGkIBQJoQgJfNAQCZnEIBQJoQgJfMwQCZXUIBQJoQgJfMgQCaHMIBQJoQgJfMQQCY2cDAwkAZgIFAmhkAAAJAGYCBQJoZAUCaHMHCQECYVoBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmhkBQNuaWwCAAUCaHMEAmh0CQD8BwQFAmJjAgRidXJuCQDMCAIFAmh6BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJ4BQJoegUDbmlsAwkAAAIFAmh0BQJodAQCZ1EJAQJjUQIFAmhxCQBkAgUCY2cJAJYDAQkAzAgCAAAJAMwIAgUCZnEFA25pbAQCaHUJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmZjBmNhbGxlcgUCY2cFAmZYBQNuaWwEAmhtAwkAZgIFAmZxAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYmQFAmZxBQJmWAUDbmlsBQNuaWwEAmhDBAJodwMJAAACBQR0aGlzBQJiZAAABQJmcQMFAmZaCQCUCgIJAQEtAQkAZAIFAmNnBQJodwAACQCUCgIAAAkBAS0BCQBkAgUCY2cFAmh3BAJlSwgFAmhDAl8xBAJlTAgFAmhDAl8yBAJoRAkBAmVKAwUCZUsFAmVMAAAEAmdPCAUCaEQCXzEEAmVBCAUCaEQCXzIEAmdaCQECZU8CBQJlSQUCZUEDCQAAAgUCZ1oFAmdaCQCUCgIJAM4IAgkAzggCCQDOCAIJAM4IAgUCZXUFAmdRBQJodQUCaG0FAmdPBQJjZwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJmYwEDZ2V0AAQCZWYJAQJmYgEFAmZjBAJkTAgFAmVmAl8xBAJkTQgFAmVmAl8yBAJmZQgFAmVmAl8zBAJkdQgFAmVmAl80BAJkTggFAmVmAl81BAJnUQkBAmNWAgUCZEwFAmRNBAJlSQkBAmVCAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJlSQUCZUkEAmhFCQD8BwQFAmJjAgRidXJuCQDMCAIFAmZlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmR1BQJmZQUDbmlsAwkAAAIFAmhFBQJoRQQCaEYJAQJlSgMJAQEtAQUCZEwJAQEtAQUCZE0AAAQCZ08IBQJoRgJfMQQCZUEIBQJoRgJfMgQCZ1oJAQJlTwIFAmVJBQJlQQMJAAACBQJnWgUCZ1oJAM4IAgkAzggCBQJnUQUCZE4FAmdPCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmZjAQlnZXROb0xlc3MCAmhHAmhIBAJlZgkBAmZiAQUCZmMEAmRMCAUCZWYCXzEEAmRNCAUCZWYCXzIEAmZlCAUCZWYCXzMEAmR1CAUCZWYCXzQEAmROCAUCZWYCXzUDCQBmAgUCaEcFAmRMCQACAQkArAICCQCsAgIJAKwCAgIcbm9MZXNzVGhlbkFtdEFzc2V0IGZhaWxlZDogIAkApAMBBQJkTAIDIDwgCQCkAwEFAmhHAwkAZgIFAmhIBQJkTQkAAgEJAKwCAgkArAICCQCsAgICHW5vTGVzc1RoZW5QcmljZUFzc2V0IGZhaWxlZDogCQCkAwEFAmRNAgMgPCAJAKQDAQUCaEgEAmdRCQECY1YCBQJkTAUCZE0EAmVJCQECZUIDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmVJBQJlSQQCaEUJAPwHBAUCYmMCBGJ1cm4JAMwIAgUCZmUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZHUFAmZlBQNuaWwDCQAAAgUCaEUFAmhFBAJoSQkBAmVKAwkBAS0BBQJkTAkBAS0BBQJkTQAABAJnTwgFAmhJAl8xBAJlQQgFAmhJAl8yBAJnWgkBAmVPAgUCZUkFAmVBAwkAAAIFAmdaBQJnWgkAzggCCQDOCAIFAmdRBQJkTgUCZ08JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZmMBDXVuc3Rha2VBbmRHZXQBAmNnBAJoSgMJAQIhPQIJAJADAQgFAmZjCHBheW1lbnRzAAAJAAIBAhhObyBwYXltZW50cyBhcmUgZXhwZWN0ZWQGAwkAAAIFAmhKBQJoSgQCZGoJAQJibAAEAmR3CQDZBAEJAJEDAgUCZGoFAXEEAmVJCQECZUIDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmVJBQJlSQQCaEEJAPwHBAUCYkQCB3Vuc3Rha2UJAMwIAgkA2AQBBQJkdwkAzAgCBQJjZwUDbmlsBQNuaWwDCQAAAgUCaEEFAmhBBAJlZgkBAmRzBAkA2AQBCAUCZmMNdHJhbnNhY3Rpb25JZAkA2AQBBQJkdwUCY2cIBQJmYwZjYWxsZXIEAmRMCAUCZWYCXzEEAmRNCAUCZWYCXzIEAmR6CQENcGFyc2VJbnRWYWx1ZQEIBQJlZgJfOQQCZE4IBQJlZgNfMTAEAmdRCQECY1YCBQJkTAUCZE0EAmZmAwkBASEBCQECYmkBCAUCZmMGY2FsbGVyAwkBAmJqAAYJAAACBQJidwUBbgcEAmhLAwUCZmYJAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmR6BgMJAAACBQJoSwUCaEsEAmhFCQD8BwQFAmJjAgRidXJuCQDMCAIFAmNnBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmR3BQJjZwUDbmlsAwkAAAIFAmhFBQJoRQQCaEwJAQJlSgMJAQEtAQUCZEwJAQEtAQUCZE0AAAQCZ08IBQJoTAJfMQQCZUEIBQJoTAJfMgQCZ1oJAQJlTwIFAmVJBQJlQQMJAAACBQJnWgUCZ1oJAM4IAgkAzggCBQJnUQUCZE4FAmdPCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmZjARN1bnN0YWtlQW5kR2V0Tm9MZXNzAwJoegJoTQJoSAQCZmYDCQEBIQEJAQJiaQEIBQJmYwZjYWxsZXIDCQECYmoABgkAAAIFAmJ3BQFuBwQCZlkJAMwIAgMJAQEhAQUCZmYGCQACAQIhZ2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCZmMIcGF5bWVudHMAAAYJAAIBAhhubyBwYXltZW50cyBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJmWQUCZlkEAmVJCQECZUIDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmVJBQJlSQQCaEEJAPwHBAUCYkQCB3Vuc3Rha2UJAMwIAgkA2AQBBQJieAkAzAgCBQJoegUDbmlsBQNuaWwDCQAAAgUCaEEFAmhBBAJlZgkBAmRzBAkA2AQBCAUCZmMNdHJhbnNhY3Rpb25JZAkA2AQBBQJieAUCaHoIBQJmYwZjYWxsZXIEAmRMCAUCZWYCXzEEAmRNCAUCZWYCXzIEAmROCAUCZWYDXzEwBAJnUQkBAmNWAgUCZEwFAmRNBAJoTgkAzAgCAwkAZwIFAmRMBQJoTQYJAAIBCQC5CQIJAMwIAgIsYW1vdW50IGFzc2V0IGFtb3VudCB0byByZWNlaXZlIGlzIGxlc3MgdGhhbiAJAMwIAgkApAMBBQJoTQUDbmlsAgAJAMwIAgMJAGcCBQJkTQUCaEgGCQACAQkAuQkCCQDMCAICK3ByaWNlIGFzc2V0IGFtb3VudCB0byByZWNlaXZlIGlzIGxlc3MgdGhhbiAJAMwIAgkApAMBBQJoSAUDbmlsAgAFA25pbAMJAAACBQJoTgUCaE4EAmhFCQD8BwQFAmJjAgRidXJuCQDMCAIFAmh6BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJ4BQJoegUDbmlsAwkAAAIFAmhFBQJoRQQCaE8JAQJlSgMJAQEtAQUCZEwJAQEtAQUCZE0AAAQCZ08IBQJoTwJfMQQCZUEIBQJoTwJfMgQCZ1oJAQJlTwIFAmVJBQJlQQMJAAACBQJnWgUCZ1oJAM4IAgkAzggCBQJnUQUCZE4FAmdPCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmZjAQhhY3RpdmF0ZQICaFACaFEDCQECIT0CCQClCAEIBQJmYwZjYWxsZXIJAKUIAQUCYmMJAAIBAhJwZXJtaXNzaW9ucyBkZW5pZWQJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQECYWUABQJoUAkAzAgCCQELU3RyaW5nRW50cnkCCQECYWYABQJoUQUDbmlsAgdzdWNjZXNzAmZjAQpyZWZyZXNoS0xwAAQCaFIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUCYWsAAAQCaFMDCQBnAgkAZQIFBmhlaWdodAUCaFIFAmFuBQR1bml0CQECYVoBCQC5CQIJAMwIAgkApAMBBQJhbgkAzAgCAi8gYmxvY2tzIGhhdmUgbm90IHBhc3NlZCBzaW5jZSB0aGUgcHJldmlvdXMgY2FsbAUDbmlsAgADCQAAAgUCaFMFAmhTBAJlVgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCoAwEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUCYWoCATAJAQJiYgECC2ludmFsaWQga0xwBAJoVAkBAmVKAwAAAAAAAAQCaFUIBQJoVAJfMQQCZUEIBQJoVAJfMgQCZU0DCQECIT0CBQJlVgUCZUEFAmhVCQECYVoBAhJub3RoaW5nIHRvIHJlZnJlc2gJAJQKAgUCZU0JAKYDAQUCZUEJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZmMBHGdldFBvb2xDb25maWdXcmFwcGVyUkVBRE9OTFkACQCUCgIFA25pbAkBAmJsAAJmYwEcZ2V0QWNjQmFsYW5jZVdyYXBwZXJSRUFET05MWQECYXAJAJQKAgUDbmlsCQECYlUBBQJhcAJmYwEZY2FsY1ByaWNlc1dyYXBwZXJSRUFET05MWQMCZGQCZGUCZGkEAmRyCQECZGgDBQJkZAUCZGUFAmRpCQCUCgIFA25pbAkAzAgCCQCmAwEJAJEDAgUCZHIAAAkAzAgCCQCmAwEJAJEDAgUCZHIAAQkAzAgCCQCmAwEJAJEDAgUCZHIAAgUDbmlsAmZjARR0b1gxOFdyYXBwZXJSRUFET05MWQIBRQFGCQCUCgIFA25pbAkApgMBCQEBRAIFAUUFAUYCZmMBFmZyb21YMThXcmFwcGVyUkVBRE9OTFkCAUkBSgkAlAoCBQNuaWwJAQFIAgkApwMBBQFJBQFKAmZjAR5jYWxjUHJpY2VCaWdJbnRXcmFwcGVyUkVBRE9OTFkCAmJZAmJaCQCUCgIFA25pbAkApgMBCQECYlgCCQCnAwEFAmJZCQCnAwEFAmJaAmZjASNlc3RpbWF0ZVB1dE9wZXJhdGlvbldyYXBwZXJSRUFET05MWQkCZHQCZFACZFECZFICZFMCZFQCYWICZFUCZFYJAJQKAgUDbmlsCQECZE8JBQJkdAUCZFAFAmRRBQJkUgUCZFMFAmRUBQJhYgUCZFUFAmRWAmZjASNlc3RpbWF0ZUdldE9wZXJhdGlvbldyYXBwZXJSRUFET05MWQQCZHQCZHUCZHYCYWIEAmVmCQECZHMEBQJkdAUCZHUFAmR2CQERQGV4dHJOYXRpdmUoMTA2MikBBQJhYgkAlAoCBQNuaWwJAJwKCggFAmVmAl8xCAUCZWYCXzIIBQJlZgJfMwgFAmVmAl80CAUCZWYCXzUIBQJlZgJfNggFAmVmAl83CQCmAwEIBQJlZgJfOAgFAmVmAl85CAUCZWYDXzEwAmZjAQ1zdGF0c1JFQURPTkxZAAQCZGoJAQJibAAEAmR3CQDZBAEJAJEDAgUCZGoFAXEEAmhWCQCRAwIFAmRqBQFyBAJoVwkAkQMCBQJkagUBcwQCZFkJAJEDAgUCZGoFAXYEAmRaCQCRAwIFAmRqBQF3BAJkawkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRqBQF0BAJkbAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRqBQF1BAJoWAgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJkdwkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJkdwIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmhZCQECYlUBBQJoVgQCaFoJAQJiVQEFAmhXBAJpYQMJAAACBQJoWAAACQDMCAIFAWUJAMwIAgUBZQkAzAgCBQFlBQNuaWwJAQJkaAMFAmhZBQJoWgUCaFgEAmRHAAAEAmliCQEBSAIJAJEDAgUCaWEAAQUBYgQCaWMJAQFIAgkAkQMCBQJpYQACBQFiBAJpZAkBBXZhbHVlAQkAmggCBQJiYwkBAmFEAQkApQgBBQR0aGlzCQCUCgIFA25pbAkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCaFkJAMwIAgkApAMBBQJoWgkAzAgCCQCkAwEFAmhYCQDMCAIJAKQDAQUCZEcJAMwIAgkApAMBBQJpYgkAzAgCCQCkAwEFAmljCQDMCAIJAKQDAQUCaWQFA25pbAUBagJmYwEgZXZhbHVhdGVQdXRCeUFtb3VudEFzc2V0UkVBRE9OTFkBAmRRBAJkagkBAmJsAAQCZHcJANkEAQkAkQMCBQJkagUBcQQCZFcJAJEDAgUCZGoFAXIEAmR4CQDZBAEFAmRXBAJkWAkAkQMCBQJkagUBcwQCZHkJANkEAQUCZFgEAmRrCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGoFAXQEAmRsCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGoFAXUEAmR6CQCRAwIFAmRqBQFwBAJoWAgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJkdwkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJkdwIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmhZCQECYlUBBQJkVwQCaFoJAQJiVQEFAmRYBAJkZgkBAUQCBQJoWQUCZGsEAmRnCQEBRAIFAmhaBQJkbAQCZEYDCQAAAgUCaFgAAAUBZQkBAmJYAgUCZGcFAmRmBAJlYwkBAUQCBQJkUQUCZGsEAmVkCQC8AgMFAmVjBQJkRgUBZAQCZFMJAQFIAgUCZWQFAmRsBAJmagkBAmRPCQIAAKDCHgUCZFEFAmR4BQJkUwUCZHkCAAYHBAJlbggFAmZqAl8xBAJpZQgFAmZqAl8zBAJkQggFAmZqAl80BAJkRAgFAmZqAl81BAJkQQgFAmZqAl82CQCUCgIFA25pbAkAuQkCCQDMCAICECVkJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJlbgkAzAgCCQCkAwEJAQFIAgUCZEYFAWIJAMwIAgkApAMBBQJkQgkAzAgCCQCkAwEFAmRECQDMCAIJAKQDAQUCZEEJAMwIAgUCZHoJAMwIAgkApAMBBQJkUQkAzAgCCQCkAwEFAmRTBQNuaWwFAWoCZmMBH2V2YWx1YXRlUHV0QnlQcmljZUFzc2V0UkVBRE9OTFkBAmRTBAJkagkBAmJsAAQCZHcJANkEAQkAkQMCBQJkagUBcQQCZFcJAJEDAgUCZGoFAXIEAmR4CQDZBAEFAmRXBAJkWAkAkQMCBQJkagUBcwQCZHkJANkEAQUCZFgEAmRrCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGoFAXQEAmRsCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZGoFAXUEAmR6CQCRAwIFAmRqBQFwBAJoWAgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJkdwkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJkdwIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmlmCQECYlUBBQJkVwQCaWcJAQJiVQEFAmRYBAJpaAkBAUQCBQJpZgUCZGsEAmlpCQEBRAIFAmlnBQJkbAQCZEYDCQAAAgUCaFgAAAUBZQkBAmJYAgUCaWkFAmloBAJlZAkBAUQCBQJkUwUCZGwEAmVjCQC8AgMFAmVkBQFkBQJkRgQCZFEJAQFIAgUCZWMFAmRrBAJmagkBAmRPCQIAAKDCHgUCZFEFAmR4BQJkUwUCZHkCAAYHBAJlbggFAmZqAl8xBAJpZQgFAmZqAl8zBAJkQggFAmZqAl80BAJkRAgFAmZqAl81BAJkQQgFAmZqAl82CQCUCgIFA25pbAkAuQkCCQDMCAICECVkJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJlbgkAzAgCCQCkAwEJAQFIAgUCZEYFAWIJAMwIAgkApAMBBQJkQgkAzAgCCQCkAwEFAmRECQDMCAIJAKQDAQUCZEEJAMwIAgUCZHoJAMwIAgkApAMBBQJkUQkAzAgCCQCkAwEFAmRTBQNuaWwFAWoCZmMBE2V2YWx1YXRlR2V0UkVBRE9OTFkCAmlqAmlrBAJlZgkBAmRzBAIABQJpagUCaWsFBHRoaXMEAmRMCAUCZWYCXzEEAmRNCAUCZWYCXzIEAmRCCAUCZWYCXzUEAmRECAUCZWYCXzYEAmRBCAUCZWYCXzcEAmRHCAUCZWYCXzgEAmR6CQENcGFyc2VJbnRWYWx1ZQEIBQJlZgJfOQkAlAoCBQNuaWwJALkJAgkAzAgCAg4lZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmRMCQDMCAIJAKQDAQUCZE0JAMwIAgkApAMBBQJkQgkAzAgCCQCkAwEFAmRECQDMCAIJAKQDAQUCZEEJAMwIAgkApgMBBQJkRwkAzAgCCQCkAwEFAmR6BQNuaWwFAWoBAmlsAQJpbQAEAmluBAJhUAkBAmdxAAMJAAECBQJhUAIKQnl0ZVZlY3RvcgQCZ3QFAmFQBQJndAMJAAECBQJhUAIEVW5pdAgFAmlsD3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yBAJhUAUCaWwDCQABAgUCYVACBU9yZGVyBAJlUgUCYVAEAmlvCQECYmsABAJpcAMJAQJlTgAJAJQKAgYCAAkBAmVRAQUCZVIEAmFLCAUCaXACXzEEAmFMCAUCaXACXzIEAmFNCQD0AwMIBQJlUglib2R5Qnl0ZXMJAJEDAggFAmVSBnByb29mcwABBQJpbwMDBQJhSwUCYU0HBgkBAmFKAwUCYUsFAmFMBQJhTQMJAAECBQJhUAIUU2V0U2NyaXB0VHJhbnNhY3Rpb24EAmFVBQJhUAMJAPQDAwgFAmlsCWJvZHlCeXRlcwkAkQMCCAUCaWwGcHJvb2ZzAAAFAmluBgQCaXEJAPYDAQkBBXZhbHVlAQgFAmFVBnNjcmlwdAQCaXIJANsEAQkBBXZhbHVlAQkAnQgCBQJiYwkBAmFGAAQCaXMJAPEHAQUEdGhpcwMJAAACBQJpcgUCaXEJAQIhPQIFAmlzBQJpcQcJAPQDAwgFAmlsCWJvZHlCeXRlcwkAkQMCCAUCaWwGcHJvb2ZzAAAFAmluoXX8uA==", "height": 3421226, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 7qYPuz3aAiht7yEf4UdSjEmnry8ewgQ3qz8GUfMnNN5E Next: none 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
10084 else val
10185
10286
87+func swapContract () = "%s__swapContract"
88+
89+
10390 func fc () = "%s__factoryContract"
10491
10592
106-func mpk () = "%s__managerPublicKey"
93+func keyManagerPublicKey () = "%s__managerPublicKey"
10794
10895
109-func pmpk () = "%s__pendingManagerPublicKey"
96+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"
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
177-func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
174+func throwOrderError (orderValid,orderValidInfo,matcherValid) = throw((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " matcherValid=") + toString(matcherValid)))
178175
179176
180-func strf (addr,key) = valueOrErrorMessage(getString(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
177+func addressFromStringOrThis (addressString) = match addressFromString(addressString) {
178+ case a: Address =>
179+ a
180+ case _ =>
181+ this
182+}
181183
182184
183-func intf (addr,key) = valueOrErrorMessage(getInteger(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
185+func getManagerVaultAddressOrThis () = {
186+ let factoryAddress = match getString(fc()) {
187+ case fca: String =>
188+ addressFromStringOrThis(fca)
189+ case _ =>
190+ this
191+ }
192+ match getString(factoryAddress, keyManagerVaultAddress()) {
193+ case s: String =>
194+ addressFromStringOrThis(s)
195+ case _ =>
196+ this
197+ }
198+ }
184199
185200
186-func throwErr (msg) = throw(makeString(["lp_stable.ride:", msg], " "))
201+func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
187202
188203
189-func fmtErr (msg) = makeString(["lp_stable.ride:", msg], " ")
204+func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
190205
191206
192-let fca = addressFromStringValue(strf(this, fc()))
207+func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
208+
209+
210+func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
211+
212+
213+let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
214+
215+let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
193216
194217 let inFee = {
195- let @ = invoke(fca, "getInFeeREADONLY", [toString(this)], nil)
218+ let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
196219 if ($isInstanceOf(@, "Int"))
197220 then @
198221 else throw(($getType(@) + " couldn't be cast to Int"))
199222 }
200223
201224 let outFee = {
202- let @ = invoke(fca, "getOutFeeREADONLY", [toString(this)], nil)
225+ let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
203226 if ($isInstanceOf(@, "Int"))
204227 then @
205228 else throw(($getType(@) + " couldn't be cast to Int"))
206229 }
207230
208-let A = strf(this, amp())
209-
210-func igs () = valueOrElse(getBoolean(fca, aps()), false)
231+func keyAddressWhitelisted (address) = makeString(["%s%s", "whitelisted", toString(address)], SEP)
211232
212233
213-func mp () = fromBase58String(strf(fca, mtpk()))
234+func isAddressWhitelisted (address) = valueOrElse(getBoolean(factoryContract, keyAddressWhitelisted(address)), false)
214235
215236
216-let feeCollectorAddress = addressFromStringValue(strf(fca, keyFeeCollectorAddress()))
237+func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
217238
218-func gpc () = {
219- let amtAs = strf(this, aa())
220- let priceAs = strf(this, pa())
221- let iPriceAs = intf(fca, mba(priceAs))
222- let iAmtAs = intf(fca, mba(amtAs))
223- split(strf(fca, pc(toString(iAmtAs), toString(iPriceAs))), SEP)
239+
240+func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
241+
242+
243+func getPoolConfig () = {
244+ let amtAsset = getStringOrFail(this, aa())
245+ let priceAsset = getStringOrFail(this, pa())
246+ let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
247+ let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
248+ split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
224249 }
225250
226251
234259 else toBase58String(value(input))
235260
236261
237-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]))
262+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]))
238263
239264
240-let poolConfigParsed = parsePoolConfig(gpc())
265+let poolConfigParsed = parsePoolConfig(getPoolConfig())
241266
242-let $t080878273 = poolConfigParsed
267+let $t097029868 = poolConfigParsed
243268
244-let cfgPoolAddress = $t080878273._1
269+let cfgPoolAddress = $t097029868._1
245270
246-let cfgPoolStatus = $t080878273._2
271+let cfgPoolStatus = $t097029868._2
247272
248-let cfgLpAssetId = $t080878273._3
273+let cfgLpAssetId = $t097029868._3
249274
250-let cfgAmountAssetId = $t080878273._4
275+let cfgAmountAssetId = $t097029868._4
251276
252-let cfgPriceAssetId = $t080878273._5
277+let cfgPriceAssetId = $t097029868._5
253278
254-let cfgAmountAssetDecimals = $t080878273._6
279+let cfgAmountAssetDecimals = $t097029868._6
255280
256-let cfgPriceAssetDecimals = $t080878273._7
281+let cfgPriceAssetDecimals = $t097029868._7
257282
258-func gfc () = split(strf(fca, fcfg()), SEP)
283+func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
259284
260285
261-let factoryConfig = gfc()
286+let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
262287
263-let stakingContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactStakCntr]), "Invalid staking contract address")
288+let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
264289
265-let slipageContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactSlippCntr]), "Invalid slipage contract address")
266-
267-let gwxContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactGwxRewCntr]), "Invalid gwx contract address")
268-
269-let restContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactoryRestCntr]), "Invalid gwx contract address")
270-
271-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)
290+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)
272291
273292
274293 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)
275294
276295
277-func getAccBalance (assetId) = if ((assetId == "WAVES"))
278- then wavesBalance(this).available
279- else assetBalance(this, fromBase58String(assetId))
280-
281-
282-func cpbi (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
283-
284-
285-func cpbir (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
286-
287-
288-func vad (A1,A2,slippage) = {
289- let diff = fraction((A1 - A2), scale8BigInt, A2)
290- let pass = ((slippage - abs(diff)) > zeroBigInt)
291- if (!(pass))
292- then throw(("Big slpg: " + toString(diff)))
293- else $Tuple2(pass, min([A1, A2]))
296+func getAccBalance (assetId) = {
297+ let balanceOnPool = if ((assetId == "WAVES"))
298+ then wavesBalance(this).available
299+ else assetBalance(this, fromBase58String(assetId))
300+ let totalBalance = ((balanceOnPool + getAdditionalBalanceOrZero(assetId)) - getStakingAssetBalanceOrZero(assetId))
301+ max([0, totalBalance])
294302 }
295303
296304
297-func vd (D1,D0,slpg) = {
298- let diff = fraction(D0, scale8BigInt, D1)
299- let fail = (slpg > diff)
300- if (if (fail)
301- then true
302- else (D0 > D1))
303- then throw(((((((toString(D0) + " ") + toString(D1)) + " ") + toString(diff)) + " ") + toString(slpg)))
304- else fail
305+func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
306+
307+
308+func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
309+
310+
311+func getRate (proxy) = {
312+ let inv = invoke(proxy, "getRate", nil, nil)
313+ if ((inv == inv))
314+ then match inv {
315+ case r: Int =>
316+ r
317+ case _ =>
318+ throwErr("proxy.getRate() unexpected value")
319+ }
320+ else throw("Strict value is not equal to itself.")
305321 }
306322
307323
308-func pcp (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
309- let amtAsAmtX18 = t1(amAmt, amAssetDcm)
310- let prAsAmtX18 = t1(prAmt, prAssetDcm)
311- cpbi(prAsAmtX18, amtAsAmtX18)
324+func deposit (assetId,amount,stakingAssetId,proxy) = {
325+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
326+ if ((currentAdditionalBalance == currentAdditionalBalance))
327+ then {
328+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
329+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
330+ then {
331+ let asset = parseAssetId(assetId)
332+ if ((amount > 0))
333+ then {
334+ let depositInvoke = invoke(proxy, "deposit", nil, [AttachedPayment(asset, amount)])
335+ if ((depositInvoke == depositInvoke))
336+ then match depositInvoke {
337+ case receivedStakingAsset: Int =>
338+ let newAdditionalBalance = (currentAdditionalBalance + amount)
339+ let newStakingAssetBalance = (currentStakingAssetBalance + receivedStakingAsset)
340+[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance)]
341+ case _ =>
342+ nil
343+ }
344+ else throw("Strict value is not equal to itself.")
345+ }
346+ else nil
347+ }
348+ else throw("Strict value is not equal to itself.")
349+ }
350+ else throw("Strict value is not equal to itself.")
351+ }
352+
353+
354+func withdraw (assetId,amount,stakingAssetId,proxy,proxyRateMul,profitAddress) = {
355+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
356+ if ((currentAdditionalBalance == currentAdditionalBalance))
357+ then {
358+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
359+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
360+ then {
361+ let currentProxyRate = getRate(proxy)
362+ if ((currentProxyRate == currentProxyRate))
363+ then {
364+ let oldRate = fraction(proxyRateMul, currentAdditionalBalance, currentStakingAssetBalance)
365+ let stakingAsset = parseAssetId(stakingAssetId)
366+ let oldSendStakingAmount = fraction(proxyRateMul, amount, oldRate)
367+ let sendStakingAssetAmount = fraction(proxyRateMul, amount, currentProxyRate)
368+ let profitAmount = max([0, (oldSendStakingAmount - sendStakingAssetAmount)])
369+ if ((sendStakingAssetAmount > 0))
370+ then {
371+ let withdrawInvoke = invoke(proxy, "withdraw", nil, [AttachedPayment(stakingAsset, sendStakingAssetAmount)])
372+ if ((withdrawInvoke == withdrawInvoke))
373+ then match withdrawInvoke {
374+ case receivedAssets: Int =>
375+ let newAdditionalBalance = (currentAdditionalBalance - receivedAssets)
376+ let newStakingAssetBalance = ((currentStakingAssetBalance - sendStakingAssetAmount) - profitAmount)
377+[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance), ScriptTransfer(profitAddress, profitAmount, parseAssetId(stakingAssetId))]
378+ case _ =>
379+ nil
380+ }
381+ else throw("Strict value is not equal to itself.")
382+ }
383+ else nil
384+ }
385+ else throw("Strict value is not equal to itself.")
386+ }
387+ else throw("Strict value is not equal to itself.")
388+ }
389+ else throw("Strict value is not equal to itself.")
390+ }
391+
392+
393+func getLeaseProxyConfig (assetId) = match invoke(factoryContract, "getPoolLeaseConfigREADONLY", [toString(this), assetId], nil) {
394+ case a: (Boolean, Int, Int, String, String, Int, String) =>
395+ a
396+ case _ =>
397+ throwErr((("[" + assetId) + "] getLeaseProxyConfig() error"))
398+}
399+
400+
401+func rebalanceInternal (targetRatio,assetId,stakingAssetId,minBalance,proxy,proxyRateMul,profitAddress) = {
402+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
403+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
404+ then {
405+ let currentAdditionalBalance = if ((currentStakingAssetBalance != 0))
406+ then getAdditionalBalanceOrZero(assetId)
407+ else 0
408+ if ((currentAdditionalBalance == currentAdditionalBalance))
409+ then {
410+ let leasableTotalBalance = max([0, (getAccBalance(assetId) - minBalance)])
411+ let targetAdditionalBalance = fraction(targetRatio, leasableTotalBalance, 100)
412+ let diff = (currentAdditionalBalance - targetAdditionalBalance)
413+ if ((diff == 0))
414+ then nil
415+ else if ((0 > diff))
416+ then {
417+ let sendAssetAmount = -(diff)
418+ deposit(assetId, sendAssetAmount, stakingAssetId, proxy)
419+ }
420+ else {
421+ let getAssetAmount = diff
422+ withdraw(assetId, getAssetAmount, stakingAssetId, proxy, proxyRateMul, profitAddress)
423+ }
424+ }
425+ else throw("Strict value is not equal to itself.")
426+ }
427+ else throw("Strict value is not equal to itself.")
428+ }
429+
430+
431+func rebalanceAsset (assetId) = {
432+ let $t01615316289 = getLeaseProxyConfig(assetId)
433+ let isLeasable = $t01615316289._1
434+ let leasedRatio = $t01615316289._2
435+ let minBalance = $t01615316289._3
436+ let proxyAddress = $t01615316289._4
437+ let proxyAssetId = $t01615316289._5
438+ let proxyRateMul = $t01615316289._6
439+ let stakingProfitAddress = $t01615316289._7
440+ if (isLeasable)
441+ then rebalanceInternal(leasedRatio, assetId, proxyAssetId, minBalance, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
442+ else nil
443+ }
444+
445+
446+func withdrawAndRebalanceAsset (assetId,getAmount) = {
447+ let $t01668816824 = getLeaseProxyConfig(assetId)
448+ let isLeasable = $t01668816824._1
449+ let leasedRatio = $t01668816824._2
450+ let minBalance = $t01668816824._3
451+ let proxyAddress = $t01668816824._4
452+ let proxyAssetId = $t01668816824._5
453+ let proxyRateMul = $t01668816824._6
454+ let stakingProfitAddress = $t01668816824._7
455+ if (isLeasable)
456+ then {
457+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(proxyAssetId)
458+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
459+ then {
460+ let currentAdditionalBalance = if ((currentStakingAssetBalance != 0))
461+ then getAdditionalBalanceOrZero(assetId)
462+ else 0
463+ if ((currentAdditionalBalance == currentAdditionalBalance))
464+ then {
465+ let newTotalLeasableBalance = max([0, ((getAccBalance(assetId) - getAmount) - minBalance)])
466+ if ((newTotalLeasableBalance == newTotalLeasableBalance))
467+ then {
468+ let newAdditionalBalance = fraction(leasedRatio, newTotalLeasableBalance, 100)
469+ if ((newAdditionalBalance == newAdditionalBalance))
470+ then {
471+ let withdrawAmount = (currentAdditionalBalance - newAdditionalBalance)
472+ if ((withdrawAmount == withdrawAmount))
473+ then if ((withdrawAmount == 0))
474+ then nil
475+ else if ((0 > withdrawAmount))
476+ then deposit(assetId, -(withdrawAmount), proxyAssetId, addressFromStringValue(proxyAddress))
477+ else withdraw(assetId, withdrawAmount, proxyAssetId, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
478+ else throw("Strict value is not equal to itself.")
479+ }
480+ else throw("Strict value is not equal to itself.")
481+ }
482+ else throw("Strict value is not equal to itself.")
483+ }
484+ else throw("Strict value is not equal to itself.")
485+ }
486+ else throw("Strict value is not equal to itself.")
487+ }
488+ else nil
489+ }
490+
491+
492+func withdrawAndRebalanceAll (amountAssetOutAmount,priceAssetOutAmount) = {
493+ let AmAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, aa()), amountAssetOutAmount)
494+ let PrAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, pa()), priceAssetOutAmount)
495+ (AmAmtWithdrawState ++ PrAmtWithdrawState)
496+ }
497+
498+
499+func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
500+ let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
501+ let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
502+ calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
312503 }
313504
314505
315506 func calcPrices (amAmt,prAmt,lpAmt) = {
316- let amtAsDcm = cfgAmountAssetDecimals
317- let prAsDcm = cfgPriceAssetDecimals
318- let priceX18 = pcp(amtAsDcm, prAsDcm, amAmt, prAmt)
319- let amAmtX18 = t1(amAmt, amtAsDcm)
320- let prAmtX18 = t1(prAmt, prAsDcm)
321- let lpAmtX18 = t1(lpAmt, scale8)
322- let lpPrInAmAsX18 = cpbi(amAmtX18, lpAmtX18)
323- let lpPrInPrAsX18 = cpbi(prAmtX18, lpAmtX18)
324-[priceX18, lpPrInAmAsX18, lpPrInPrAsX18]
507+ let cfg = getPoolConfig()
508+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
509+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
510+ let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
511+ let amAmtX18 = toX18(amAmt, amtAssetDcm)
512+ let prAmtX18 = toX18(prAmt, priceAssetDcm)
513+ let lpAmtX18 = toX18(lpAmt, scale8)
514+ let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
515+ let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
516+[priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
325517 }
326518
327519
328520 func calculatePrices (amAmt,prAmt,lpAmt) = {
329- let p = calcPrices(amAmt, prAmt, lpAmt)
330-[f1(p[0], scale8), f1(p[1], scale8), f1(p[2], scale8)]
521+ let prices = calcPrices(amAmt, prAmt, lpAmt)
522+[fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
523+ }
524+
525+
526+func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
527+ let cfg = getPoolConfig()
528+ let lpAssetId = cfg[idxPoolLPAssetId]
529+ let amAssetId = cfg[idxAmtAssetId]
530+ let prAssetId = cfg[idxPriceAssetId]
531+ let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
532+ let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
533+ let poolStatus = cfg[idxPoolStatus]
534+ let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
535+ if ((lpAssetId != pmtAssetId))
536+ then throw("Invalid asset passed.")
537+ else {
538+ let amBalance = getAccBalance(amAssetId)
539+ let amBalanceX18 = toX18(amBalance, amAssetDcm)
540+ let prBalance = getAccBalance(prAssetId)
541+ let prBalanceX18 = toX18(prBalance, prAssetDcm)
542+ let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
543+ let curPrice = fromX18(curPriceX18, scale8)
544+ let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
545+ let lpEmissionX18 = toX18(lpEmission, scale8)
546+ let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
547+ let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
548+ let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
549+ let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
550+ let state = if ((txId58 == ""))
551+ then nil
552+ else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
553+ then unit
554+ else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
555+ then unit
556+ 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)]
557+ $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
558+ }
559+ }
560+
561+
562+func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
563+ let cfg = getPoolConfig()
564+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
565+ let amAssetIdStr = cfg[idxAmtAssetId]
566+ let prAssetIdStr = cfg[idxPriceAssetId]
567+ let iAmtAssetId = cfg[idxIAmtAssetId]
568+ let iPriceAssetId = cfg[idxIPriceAssetId]
569+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
570+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
571+ let poolStatus = cfg[idxPoolStatus]
572+ let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
573+ let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
574+ let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
575+ if (if ((amAssetIdStr != inAmAssetIdStr))
576+ then true
577+ else (prAssetIdStr != inPrAssetIdStr))
578+ then throw("Invalid amt or price asset passed.")
579+ else {
580+ let amBalance = if (isEvaluate)
581+ then getAccBalance(amAssetIdStr)
582+ else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
583+ let prBalance = if (isEvaluate)
584+ then getAccBalance(prAssetIdStr)
585+ else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
586+ let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
587+ let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
588+ let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
589+ let amBalanceX18 = toX18(amBalance, amtAssetDcm)
590+ let prBalanceX18 = toX18(prBalance, priceAssetDcm)
591+ let res = if ((lpEmission == 0))
592+ then {
593+ let curPriceX18 = zeroBigInt
594+ let slippageX18 = zeroBigInt
595+ let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
596+ $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
597+ }
598+ else {
599+ let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
600+ let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
601+ let slippageToleranceX18 = toX18(slippageTolerance, scale8)
602+ if (if ((curPriceX18 != zeroBigInt))
603+ then (slippageX18 > slippageToleranceX18)
604+ else false)
605+ then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
606+ else {
607+ let lpEmissionX18 = toX18(lpEmission, scale8)
608+ let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
609+ let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
610+ let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
611+ then $Tuple2(amViaPrX18, inPrAssetAmtX18)
612+ else $Tuple2(inAmAssetAmtX18, prViaAmX18)
613+ let expAmtAssetAmtX18 = expectedAmts._1
614+ let expPriceAssetAmtX18 = expectedAmts._2
615+ let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
616+ $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
617+ }
618+ }
619+ let calcLpAmt = res._1
620+ let calcAmAssetPmt = res._2
621+ let calcPrAssetPmt = res._3
622+ let curPrice = fromX18(res._4, scale8)
623+ let slippageCalc = fromX18(res._5, scale8)
624+ if ((0 >= calcLpAmt))
625+ then throw("Invalid calculations. LP calculated is less than zero.")
626+ else {
627+ let emitLpAmt = if (!(emitLp))
628+ then 0
629+ else calcLpAmt
630+ let amDiff = (inAmAssetAmt - calcAmAssetPmt)
631+ let prDiff = (inPrAssetAmt - calcPrAssetPmt)
632+ 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))]
633+ $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
634+ }
635+ }
636+ }
637+
638+
639+func calcKLp (amountBalance,priceBalance,lpEmission) = {
640+ let amountBalanceX18 = toX18BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals))
641+ let priceBalanceX18 = toX18BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))
642+ let updatedKLp = fraction(pow((amountBalanceX18 * priceBalanceX18), 0, toBigInt(5), 1, 18, DOWN), big1, lpEmission)
643+ if ((lpEmission == big0))
644+ then big0
645+ else updatedKLp
646+ }
647+
648+
649+func calcCurrentKLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
650+ let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
651+ let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
652+ let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
653+ let currentKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
654+ currentKLp
655+ }
656+
657+
658+func refreshKLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
659+ let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
660+ let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
661+ let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
662+ let updatedKLp = calcKLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
663+ let actions = [IntegerEntry(keyKLpRefreshedHeight, height), StringEntry(keyKLp, toString(updatedKLp))]
664+ $Tuple2(actions, updatedKLp)
665+ }
666+
667+
668+func skipOrderValidation () = valueOrElse(getBoolean(factoryContract, keySkipOrderValidation(toString(this))), false)
669+
670+
671+func validateUpdatedKLp (oldKLp,updatedKLp) = if ((updatedKLp >= oldKLp))
672+ then true
673+ else throwErr(makeString(["updated KLp lower than current KLp", toString(oldKLp), toString(updatedKLp)], " "))
674+
675+
676+func validateMatcherOrderAllowed (order) = {
677+ let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
678+ let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
679+ let amountAssetAmount = order.amount
680+ let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
681+ let $t02945029662 = if ((order.orderType == Buy))
682+ then $Tuple2(amountAssetAmount, -(priceAssetAmount))
683+ else $Tuple2(-(amountAssetAmount), priceAssetAmount)
684+ let amountAssetBalanceDelta = $t02945029662._1
685+ let priceAssetBalanceDelta = $t02945029662._2
686+ if (if (if (isGlobalShutdown())
687+ then true
688+ else (cfgPoolStatus == PoolMatcherDisabled))
689+ then true
690+ else (cfgPoolStatus == PoolShutdown))
691+ then throw("Exchange operations disabled")
692+ else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
693+ then true
694+ else (order.assetPair.priceAsset != cfgPriceAssetId))
695+ then throw("Wrong order assets.")
696+ else {
697+ let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
698+ let $t03010230202 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
699+ let unusedActions = $t03010230202._1
700+ let kLpNew = $t03010230202._2
701+ let isOrderValid = (kLpNew >= kLp)
702+ let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
703+ $Tuple2(isOrderValid, info)
704+ }
705+ }
706+
707+
708+func commonGet (i) = if ((size(i.payments) != 1))
709+ then throw("exactly 1 payment is expected")
710+ else {
711+ let pmt = value(i.payments[0])
712+ let pmtAssetId = value(pmt.assetId)
713+ let pmtAmt = pmt.amount
714+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
715+ let outAmAmt = res._1
716+ let outPrAmt = res._2
717+ let state = res._10
718+ let isGetDisabled = if (!(isAddressWhitelisted(i.caller)))
719+ then if (isGlobalShutdown())
720+ then true
721+ else (cfgPoolStatus == PoolShutdown)
722+ else false
723+ if (isGetDisabled)
724+ then throw(("Get operation is blocked by admin. Status = " + toString(cfgPoolStatus)))
725+ else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
726+ }
727+
728+
729+func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
730+ then throw("exactly 2 payments are expected")
731+ else {
732+ let amAssetPmt = value(i.payments[0])
733+ let prAssetPmt = value(i.payments[1])
734+ let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
735+ let isPutDisabled = if (!(isAddressWhitelisted(i.caller)))
736+ then if (if (isGlobalShutdown())
737+ then true
738+ else (cfgPoolStatus == PoolPutDisabled))
739+ then true
740+ else (cfgPoolStatus == PoolShutdown)
741+ else false
742+ if (isPutDisabled)
743+ then throw(("Put operation is blocked by admin. Status = " + toString(cfgPoolStatus)))
744+ else estPut
745+ }
746+
747+
748+func emit (amount) = {
749+ let emitInv = invoke(factoryContract, "emit", [amount], nil)
750+ if ((emitInv == emitInv))
751+ then {
752+ let emitInvLegacy = match emitInv {
753+ case legacyFactoryContract: Address =>
754+ invoke(legacyFactoryContract, "emit", [amount], nil)
755+ case _ =>
756+ unit
757+ }
758+ if ((emitInvLegacy == emitInvLegacy))
759+ then amount
760+ else throw("Strict value is not equal to itself.")
761+ }
762+ else throw("Strict value is not equal to itself.")
331763 }
332764
333765
339771 }
340772
341773
342-func getD (xp) = {
343- let xp0 = xp[0]
344- let xp1 = xp[1]
345- let s = (xp0 + xp1)
346- if ((s == big0))
347- then big0
348- else {
349- let a = parseIntValue(A)
350- let ann = (a * 2)
351- let p = fraction(xp0, xp1, big1)
352- let xp0_xp1_n_n = fraction(p, big4, big1)
353- let ann_s = fraction(toBigInt(ann), s, big1)
354- let ann_1 = toBigInt((ann - 1))
355- func calcDNext (d) = {
356- let dd = fraction(d, d, big1)
357- let ddd = fraction(dd, d, big1)
358- let dp = fraction(ddd, big1, xp0_xp1_n_n)
359- fraction((ann_s + fraction(dp, big2, big1)), d, (fraction(ann_1, d, big1) + fraction(big3, dp, big1)))
774+func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
775+ let isEval = (txId == unit)
776+ let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
777+ let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
778+ let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
779+ then true
780+ else if ((paymentAssetId == cfgPriceAssetId))
781+ then false
782+ else throwErr("invalid asset")
783+ let $t03338833681 = if (isEval)
784+ then $Tuple2(amountBalanceRaw, priceBalanceRaw)
785+ else if (paymentInAmountAsset)
786+ then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
787+ else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
788+ let amountBalanceOld = $t03338833681._1
789+ let priceBalanceOld = $t03338833681._2
790+ let $t03368533834 = if (paymentInAmountAsset)
791+ then $Tuple2(paymentAmountRaw, 0)
792+ else $Tuple2(0, paymentAmountRaw)
793+ let amountAssetAmountRaw = $t03368533834._1
794+ let priceAssetAmountRaw = $t03368533834._2
795+ let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
796+ let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
797+ let $t03396634030 = takeFee(paymentAmountRaw, inFee)
798+ let paymentAmount = $t03396634030._1
799+ let feeAmount = $t03396634030._2
800+ let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
801+ let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
802+ let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
803+ let priceNew = fromX18(priceNewX18, scale8)
804+ let paymentBalance = if (paymentInAmountAsset)
805+ then amountBalanceOld
806+ else priceBalanceOld
807+ let paymentBalanceBigInt = toBigInt(paymentBalance)
808+ let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
809+ let chechSupply = if ((supplyBigInt > big0))
810+ then true
811+ else throwErr("initial deposit requires all coins")
812+ if ((chechSupply == chechSupply))
813+ then {
814+ let depositBigInt = toBigInt(paymentAmount)
815+ let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
816+ let commonState = if (isEval)
817+ then nil
818+ 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))]
819+ let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
820+ let priceOld = fromX18(priceOldX18, scale8)
821+ let loss = {
822+ let $t03571135878 = if (paymentInAmountAsset)
823+ then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
824+ else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
825+ let amount = $t03571135878._1
826+ let balance = $t03571135878._2
827+ let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
828+ fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
360829 }
361-
362- func calc (acc,i) = if (acc._2)
363- then acc
364- else {
365- let d = acc._1
366- let dNext = calcDNext(d)
367- let dDiffRaw = (dNext - value(d))
368- let dDiff = if ((big0 > dDiffRaw))
369- then -(dDiffRaw)
370- else dDiffRaw
371- if ((big1 >= dDiff))
372- then $Tuple2(dNext, true)
373- else $Tuple2(dNext, false)
374- }
375-
376- let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
377- let $t01277812826 = {
378- let $l = arr
379- let $s = size($l)
380- let $acc0 = $Tuple2(s, false)
381- func $f0_1 ($a,$i) = if (($i >= $s))
382- then $a
383- else calc($a, $l[$i])
384-
385- func $f0_2 ($a,$i) = if (($i >= $s))
386- then $a
387- else throw("List size exceeds 17")
388-
389- $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)
390- }
391- let d = $t01277812826._1
392- let found = $t01277812826._2
393- if (found)
394- then d
395- else throw(("D calculation error, D = " + toString(d)))
396- }
397- }
398-
399-
400-func ego (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
401- let lpId = cfgLpAssetId
402- let amId = toBase58String(value(cfgAmountAssetId))
403- let prId = toBase58String(value(cfgPriceAssetId))
404- let amDcm = cfgAmountAssetDecimals
405- let prDcm = cfgPriceAssetDecimals
406- let sts = toString(cfgPoolStatus)
407- let lpEmiss = valueOrErrorMessage(assetInfo(lpId), "Wrong LP id").quantity
408- if ((toBase58String(lpId) != pmtAssetId))
409- then throw("Wrong pmt asset")
410- else {
411- let amBalance = getAccBalance(amId)
412- let amBalanceX18 = t1(amBalance, amDcm)
413- let prBalance = getAccBalance(prId)
414- let prBalanceX18 = t1(prBalance, prDcm)
415- let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
416- let curPrice = f1(curPriceX18, scale8)
417- let pmtLpAmtX18 = t1(pmtLpAmt, scale8)
418- let lpEmissX18 = t1(lpEmiss, scale8)
419- let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissX18)
420- let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissX18)
421- let outAmAmt = fromX18Round(outAmAmtX18, amDcm, FLOOR)
422- let outPrAmt = fromX18Round(outPrAmtX18, prDcm, FLOOR)
423- let state = if ((txId58 == ""))
424- then nil
425- else [ScriptTransfer(userAddress, outAmAmt, if ((amId == "WAVES"))
426- then unit
427- else fromBase58String(amId)), ScriptTransfer(userAddress, outPrAmt, if ((prId == "WAVES"))
428- then unit
429- 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)]
430- $Tuple10(outAmAmt, outPrAmt, amId, prId, amBalance, prBalance, lpEmiss, curPriceX18, sts, state)
431- }
432- }
433-
434-
435-func epo (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEval,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
436- let lpId = cfgLpAssetId
437- let amIdStr = toBase58String(value(cfgAmountAssetId))
438- let prIdStr = toBase58String(value(cfgPriceAssetId))
439- let amtDcm = cfgAmountAssetDecimals
440- let priceDcm = cfgPriceAssetDecimals
441- let sts = toString(cfgPoolStatus)
442- let lpEm = valueOrErrorMessage(assetInfo(lpId), "Wr lp as").quantity
443- let amBalance = if (isEval)
444- then getAccBalance(amIdStr)
445- else if (if (isOneAsset)
446- then (pmtId == amIdStr)
447- else false)
448- then (getAccBalance(amIdStr) - pmtAmt)
449- else if (isOneAsset)
450- then getAccBalance(amIdStr)
451- else (getAccBalance(amIdStr) - inAmAmt)
452- let prBalance = if (isEval)
453- then getAccBalance(prIdStr)
454- else if (if (isOneAsset)
455- then (pmtId == prIdStr)
456- else false)
457- then (getAccBalance(prIdStr) - pmtAmt)
458- else if (isOneAsset)
459- then getAccBalance(prIdStr)
460- else (getAccBalance(prIdStr) - inPrAmt)
461- let inAmAssetAmtX18 = t1(inAmAmt, amtDcm)
462- let inPrAssetAmtX18 = t1(inPrAmt, priceDcm)
463- let userPriceX18 = cpbi(inPrAssetAmtX18, inAmAssetAmtX18)
464- let amBalanceX18 = t1(amBalance, amtDcm)
465- let prBalanceX18 = t1(prBalance, priceDcm)
466- let D0 = getD([amBalanceX18, prBalanceX18])
467- let r = if ((lpEm == 0))
468- then {
469- let D1 = getD([(amBalanceX18 + inAmAssetAmtX18), (prBalanceX18 + inPrAssetAmtX18)])
470- let checkD = if ((D1 > D0))
471- then true
472- else throw("D1 should be greater than D0")
473- if ((checkD == checkD))
474- then {
475- let curPriceX18 = zeroBigInt
476- let slippageX18 = zeroBigInt
477- let lpAmtX18 = D1
478- $Tuple5(f1(lpAmtX18, scale8), f1(inAmAssetAmtX18, amtDcm), f1(inPrAssetAmtX18, priceDcm), cpbi((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
479- }
480- else throw("Strict value is not equal to itself.")
481- }
482- else {
483- let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
484- let slippageRealX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
485- let slippageX18 = t1(slippage, scale8)
486- if (if (if (validateSlippage)
487- then (curPriceX18 != zeroBigInt)
488- else false)
489- then (slippageRealX18 > slippageX18)
490- else false)
491- then throw(((("Price slippage " + toString(slippageRealX18)) + " > ") + toString(slippageX18)))
492- else {
493- let lpEmissionX18 = t1(lpEm, scale8)
494- let prViaAmX18 = fraction(inAmAssetAmtX18, cpbir(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
495- let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, cpbir(prBalanceX18, amBalanceX18, FLOOR), CEILING)
496- let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
497- then $Tuple2(amViaPrX18, inPrAssetAmtX18)
498- else $Tuple2(inAmAssetAmtX18, prViaAmX18)
499- let expAmtAssetAmtX18 = expectedAmts._1
500- let expPriceAssetAmtX18 = expectedAmts._2
501- let D1 = getD([(amBalanceX18 + expAmtAssetAmtX18), (prBalanceX18 + expPriceAssetAmtX18)])
502- let checkD = if ((D1 > D0))
503- then true
504- else throw("D1 should be greater than D0")
505- if ((checkD == checkD))
506- then {
507- let lpAmtX18 = fraction(lpEmissionX18, (D1 - D0), D0)
508- $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceDcm, CEILING), curPriceX18, slippageX18)
509- }
510- else throw("Strict value is not equal to itself.")
511- }
512- }
513- let calcLpAmt = r._1
514- let calcAmAssetPmt = r._2
515- let calcPrAssetPmt = r._3
516- let curPrice = f1(r._4, scale8)
517- let slippageCalc = f1(r._5, scale8)
518- if ((0 >= calcLpAmt))
519- then throw("LP <= 0")
520- else {
521- let emitLpAmt = if (!(emitLp))
522- then 0
523- else calcLpAmt
524- let amDiff = (inAmAmt - calcAmAssetPmt)
525- let prDiff = (inPrAmt - calcPrAssetPmt)
526- let $t02058820933 = if (if (isOneAsset)
527- then (pmtId == amIdStr)
528- else false)
529- then $Tuple2(pmtAmt, 0)
530- else if (if (isOneAsset)
531- then (pmtId == prIdStr)
532- else false)
533- then $Tuple2(0, pmtAmt)
534- else $Tuple2(calcAmAssetPmt, calcPrAssetPmt)
535- let writeAmAmt = $t02058820933._1
536- let writePrAmt = $t02058820933._2
537- 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))]
538- $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEm, lpId, sts, commonState, amDiff, prDiff, inAmId, inPrId)
539- }
540- }
541-
542-
543-func getYD (xp,i,D) = {
544- let n = big2
545- let x = xp[if ((i == 0))
546- then 1
547- else 0]
548- let aPrecision = parseBigIntValue(Amult)
549- let a = (parseBigIntValue(A) * aPrecision)
550- let s = x
551- let ann = (a * n)
552- let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
553- let b = ((s + ((D * aPrecision) / ann)) - D)
554- func calc (acc,cur) = {
555- let $t02212822148 = acc
556- let y = $t02212822148._1
557- let found = $t02212822148._2
558- if ((found != unit))
559- then acc
560- else {
561- let yNext = (((y * y) + c) / ((big2 * y) + b))
562- let yDiff = absBigInt((yNext - value(y)))
563- if ((big1 >= yDiff))
564- then $Tuple2(yNext, cur)
565- else $Tuple2(yNext, unit)
566- }
567- }
568-
569- let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
570- let $t02245522502 = {
571- let $l = arr
572- let $s = size($l)
573- let $acc0 = $Tuple2(D, unit)
574- func $f0_1 ($a,$i) = if (($i >= $s))
575- then $a
576- else calc($a, $l[$i])
577-
578- func $f0_2 ($a,$i) = if (($i >= $s))
579- then $a
580- else throw("List size exceeds 15")
581-
582- $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)
583- }
584- let y = $t02245522502._1
585- let found = $t02245522502._2
586- if ((found != unit))
587- then y
588- else throw(("Y calculation error, Y = " + toString(y)))
589- }
590-
591-
592-func calcDLp (amountBalance,priceBalance,lpEmission) = {
593- let updatedDLp = fraction(getD([t1BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals)), t1BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))]), scale18, lpEmission)
594- if ((lpEmission == big0))
595- then big0
596- else updatedDLp
597- }
598-
599-
600-func calcCurrentDLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
601- let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
602- let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
603- let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
604- let currentDLp = calcDLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
605- currentDLp
606- }
607-
608-
609-func refreshDLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
610- let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
611- let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
612- let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
613- let updatedDLp = calcDLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
614- let actions = [IntegerEntry(keyDLpRefreshedHeight, height), StringEntry(keyDLp, toString(updatedDLp))]
615- $Tuple2(actions, updatedDLp)
616- }
617-
618-
619-func validateUpdatedDLp (oldDLp,updatedDLp) = if ((updatedDLp >= oldDLp))
620- then true
621- else throwErr("updated DLp lower than current DLp")
622-
623-
624-func validateMatcherOrderAllowed (order) = {
625- let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
626- let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
627- let amountAssetAmount = order.amount
628- let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
629- let $t02470024912 = if ((order.orderType == Buy))
630- then $Tuple2(amountAssetAmount, -(priceAssetAmount))
631- else $Tuple2(-(amountAssetAmount), priceAssetAmount)
632- let amountAssetBalanceDelta = $t02470024912._1
633- let priceAssetBalanceDelta = $t02470024912._2
634- if (if (if (igs())
635- then true
636- else (cfgPoolStatus == PoolMatcherDis))
637- then true
638- else (cfgPoolStatus == PoolShutdown))
639- then throw("Admin blocked")
640- else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
641- then true
642- else (order.assetPair.priceAsset != cfgPriceAssetId))
643- then throw("Wr assets")
644- else {
645- let dLp = parseBigIntValue(valueOrElse(getString(this, keyDLp), "0"))
646- let $t02525425354 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
647- let unusedActions = $t02525425354._1
648- let dLpNew = $t02525425354._2
649- let isOrderValid = (dLpNew >= dLp)
650- let info = makeString(["dLp=", toString(dLp), " dLpNew=", toString(dLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
651- $Tuple2(isOrderValid, info)
652- }
653- }
654-
655-
656-func cg (i) = if ((size(i.payments) != 1))
657- then throw("1 pmnt exp")
658- else {
659- let pmt = value(i.payments[0])
660- let pmtAssetId = value(pmt.assetId)
661- let pmtAmt = pmt.amount
662- let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
663- let outAmAmt = r._1
664- let outPrAmt = r._2
665- let sts = parseIntValue(r._9)
666- let state = r._10
667- if (if (igs())
668- then true
669- else (sts == PoolShutdown))
670- then throw(("Admin blocked: " + toString(sts)))
671- else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
672- }
673-
674-
675-func cp (caller,txId,amAsPmt,prAsPmt,slippage,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
676- let r = epo(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, (txId == ""), emitLp, isOneAsset, validateSlippage, pmtAmt, pmtId)
677- let sts = parseIntValue(r._8)
678- if (if (if (igs())
679- then true
680- else (sts == PoolPutDis))
681- then true
682- else (sts == PoolShutdown))
683- then throw(("Blocked:" + toString(sts)))
684- else r
685- }
686-
687-
688-func calcPutOneTkn (pmtAmtRaw,pmtAssetId,userAddress,txId,withTakeFee) = {
689- let amId = toBase58String(value(cfgAmountAssetId))
690- let prId = toBase58String(value(cfgPriceAssetId))
691- let lpId = cfgLpAssetId
692- let amtDcm = cfgAmountAssetDecimals
693- let priceDcm = cfgPriceAssetDecimals
694- let lpAssetEmission = toBigInt(valueOrErrorMessage(assetInfo(lpId), "invalid lp asset").quantity)
695- let chechEmission = if ((lpAssetEmission > big0))
696- then true
697- else throw("initial deposit requires all coins")
698- if ((chechEmission == chechEmission))
699- then {
700- let amBalance = getAccBalance(amId)
701- let prBalance = getAccBalance(prId)
702- let $t02801028472 = if ((txId == ""))
703- then $Tuple2(amBalance, prBalance)
704- else if ((pmtAssetId == amId))
705- then if ((pmtAmtRaw > amBalance))
706- then throw("invalid payment amount")
707- else $Tuple2((amBalance - pmtAmtRaw), prBalance)
708- else if ((pmtAssetId == prId))
709- then if ((pmtAmtRaw > prBalance))
710- then throw("invalid payment amount")
711- else $Tuple2(amBalance, (prBalance - pmtAmtRaw))
712- else throw("wrong pmtAssetId")
713- let amBalanceOld = $t02801028472._1
714- let prBalanceOld = $t02801028472._2
715- let $t02847828654 = if ((pmtAssetId == amId))
716- then $Tuple2(pmtAmtRaw, 0)
717- else if ((pmtAssetId == prId))
718- then $Tuple2(0, pmtAmtRaw)
719- else throw("invalid payment")
720- let amAmountRaw = $t02847828654._1
721- let prAmountRaw = $t02847828654._2
722- let $t02865828912 = if (withTakeFee)
723- then $Tuple3(takeFee(amAmountRaw, inFee)._1, takeFee(prAmountRaw, inFee)._1, takeFee(pmtAmtRaw, inFee)._2)
724- else $Tuple3(amAmountRaw, prAmountRaw, 0)
725- let amAmount = $t02865828912._1
726- let prAmount = $t02865828912._2
727- let feeAmount = $t02865828912._3
728- let amBalanceNew = (amBalanceOld + amAmount)
729- let prBalanceNew = (prBalanceOld + prAmount)
730- let D0 = getD([t1(amBalanceOld, cfgAmountAssetDecimals), t1(prBalanceOld, cfgPriceAssetDecimals)])
731- let D1 = getD([t1(amBalanceNew, cfgAmountAssetDecimals), t1(prBalanceNew, cfgPriceAssetDecimals)])
732- let checkD = if ((D1 > D0))
733- then true
734- else throw()
735- if ((checkD == checkD))
736- then {
737- let lpAmount = fraction(lpAssetEmission, (D1 - D0), D0, FLOOR)
738- let curPrice = f1(cpbi(t1(prBalanceNew, priceDcm), t1(amBalanceNew, amtDcm)), scale8)
739- 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))]
740- let poolProportion = fraction(prBalanceOld, scale8, amBalanceOld)
741- let amountAssetPart = fraction(pmtAmtRaw, scale8, (poolProportion + scale8))
742- let priceAssetPart = (pmtAmtRaw - amountAssetPart)
743- let lpAmtBoth = fraction(lpAssetEmission, toBigInt(priceAssetPart), toBigInt(prBalanceOld))
744- let bonus = toInt(fraction((lpAmount - lpAmtBoth), scale8BigInt, lpAmtBoth))
745- $Tuple4(toInt(lpAmount), commonState, feeAmount, bonus)
746- }
747- else throw("Strict value is not equal to itself.")
830+ $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
748831 }
749832 else throw("Strict value is not equal to itself.")
750833 }
751834
752835
753-func getOneTknV2Internal (outAssetId,minOutAmount,payments,caller,originCaller,transactionId) = {
754- let lpId = toBase58String(value(cfgLpAssetId))
755- let amId = toBase58String(value(cfgAmountAssetId))
756- let prId = toBase58String(value(cfgPriceAssetId))
757- let amDecimals = cfgAmountAssetDecimals
758- let prDecimals = cfgPriceAssetDecimals
759- let poolStatus = cfgPoolStatus
760- let userAddress = if ((caller == restContract))
761- then originCaller
762- else caller
763- let pmt = value(payments[0])
764- let pmtAssetId = value(pmt.assetId)
765- let pmtAmt = pmt.amount
766- let currentDLp = calcCurrentDLp(big0, big0, big0)
767- if ((currentDLp == currentDLp))
836+func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
837+ let isEval = (txId == unit)
838+ let cfg = getPoolConfig()
839+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
840+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
841+ let checks = [if ((paymentAssetId == cfgLpAssetId))
842+ then true
843+ else throwErr("invalid lp asset")]
844+ if ((checks == checks))
768845 then {
769- let txId58 = toBase58String(transactionId)
770- if ((lpId != toBase58String(pmtAssetId)))
771- then throw("Wrong LP")
772- else {
773- let amBalance = getAccBalance(amId)
774- let prBalance = getAccBalance(prId)
775- let $t03102431135 = {
776- let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, pmtAmt], nil)
777- if ($isInstanceOf(@, "(Int, Int)"))
778- then @
779- else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
780- }
781- if (($t03102431135 == $t03102431135))
782- then {
783- let feeAmount = $t03102431135._2
784- let totalGet = $t03102431135._1
785- let totalAmount = if (if ((minOutAmount > 0))
786- then (minOutAmount > totalGet)
787- else false)
788- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
789- else totalGet
790- let $t03132531632 = if ((outAssetId == amId))
791- then $Tuple4(totalAmount, 0, ((amBalance - totalAmount) - feeAmount), prBalance)
792- else if ((outAssetId == prId))
793- then $Tuple4(0, totalAmount, amBalance, ((prBalance - totalAmount) - feeAmount))
794- else throw("invalid out asset id")
795- let outAm = $t03132531632._1
796- let outPr = $t03132531632._2
797- let amBalanceNew = $t03132531632._3
798- let prBalanceNew = $t03132531632._4
799- let curPrX18 = cpbi(t1(prBalanceNew, prDecimals), t1(amBalanceNew, amDecimals))
800- let curPr = f1(curPrX18, scale8)
801- let outAssetIdOrWaves = if ((outAssetId == "WAVES"))
802- then unit
803- else fromBase58String(outAssetId)
804- let sendFeeToMatcher = if ((feeAmount > 0))
805- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetIdOrWaves)]
806- else nil
807- 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)
808- if ((state == state))
809- then {
810- let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
811- if ((burn == burn))
812- then {
813- let $t03241732767 = {
814- let feeAmountForCalc = if ((this == feeCollectorAddress))
815- then 0
816- else feeAmount
817- let outInAmountAsset = if ((parseAssetId(outAssetId) == cfgAmountAssetId))
818- then true
819- else false
820- if (outInAmountAsset)
821- then $Tuple2(-((totalGet + feeAmountForCalc)), 0)
822- else $Tuple2(0, -((totalGet + feeAmountForCalc)))
823- }
824- let amountAssetBalanceDelta = $t03241732767._1
825- let priceAssetBalanceDelta = $t03241732767._2
826- let $t03277032878 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
827- let refreshDLpActions = $t03277032878._1
828- let updatedDLp = $t03277032878._2
829- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
830- if ((isUpdatedDLpValid == isUpdatedDLpValid))
831- then $Tuple2((state ++ refreshDLpActions), totalAmount)
832- else throw("Strict value is not equal to itself.")
833- }
834- else throw("Strict value is not equal to itself.")
835- }
836- else throw("Strict value is not equal to itself.")
837- }
838- else throw("Strict value is not equal to itself.")
839- }
846+ let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
847+ then true
848+ else if ((outAssetId == cfgPriceAssetId))
849+ then false
850+ else throwErr("invalid asset")
851+ let balanceBigInt = if (outInAmountAsset)
852+ then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
853+ else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
854+ let outInAmountAssetDecimals = if (outInAmountAsset)
855+ then amtAssetDcm
856+ else priceAssetDcm
857+ let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
858+ let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
859+ let outBalance = if (outInAmountAsset)
860+ then amBalanceOld
861+ else prBalanceOld
862+ let outBalanceBigInt = toBigInt(outBalance)
863+ let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
864+ let redeemedBigInt = toBigInt(paymentAmount)
865+ let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
866+ let $t03795638012 = takeFee(amountRaw, outFee)
867+ let totalAmount = $t03795638012._1
868+ let feeAmount = $t03795638012._2
869+ let $t03801638242 = if (outInAmountAsset)
870+ then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
871+ else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
872+ let outAmAmount = $t03801638242._1
873+ let outPrAmount = $t03801638242._2
874+ let amBalanceNew = $t03801638242._3
875+ let prBalanceNew = $t03801638242._4
876+ let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
877+ let priceNew = fromX18(priceNewX18, scale8)
878+ let commonState = if (isEval)
879+ then nil
880+ 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)]
881+ let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
882+ let priceOld = fromX18(priceOldX18, scale8)
883+ let loss = {
884+ let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
885+ fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
886+ }
887+ $Tuple5(totalAmount, commonState, feeAmount, loss, outInAmountAsset)
840888 }
841889 else throw("Strict value is not equal to itself.")
842890 }
843891
844892
845-func m () = match getString(mpk()) {
846- case s: String =>
847- fromBase58String(s)
848- case _: Unit =>
849- unit
850- case _ =>
851- throw("Match error")
852-}
893+func managerPublicKeyOrUnit () = {
894+ let managerVaultAddress = getManagerVaultAddressOrThis()
895+ match getString(managerVaultAddress, keyManagerPublicKey()) {
896+ case s: String =>
897+ fromBase58String(s)
898+ case _: Unit =>
899+ unit
900+ case _ =>
901+ throw("Match error")
902+ }
903+ }
853904
854905
855-func pm () = match getString(pmpk()) {
856- case s: String =>
857- fromBase58String(s)
858- case _: Unit =>
859- unit
860- case _ =>
861- throw("Match error")
862-}
863-
864-
865-let pd = throw("Permission denied")
866-
867-func isManager (i) = match m() {
906+func isManager (i) = match managerPublicKeyOrUnit() {
868907 case pk: ByteVector =>
869908 (i.callerPublicKey == pk)
870909 case _: Unit =>
874913 }
875914
876915
877-func mm (i) = match m() {
878- case pk: ByteVector =>
879- if ((i.callerPublicKey == pk))
880- then true
881- else pd
882- case _: Unit =>
883- if ((i.caller == this))
884- then true
885- else pd
886- case _ =>
887- throw("Match error")
888-}
889-
890-
891-func getY (isReverse,D,poolAmountInBalance) = {
892- let poolConfig = gpc()
893- let amId = poolConfig[idxAmAsId]
894- let prId = poolConfig[idxPrAsId]
895- let n = big2
896- let aPrecision = parseBigIntValue(Amult)
897- let a = (parseBigIntValue(A) * aPrecision)
898- let xp = if ((isReverse == false))
899- then [(toBigInt(getAccBalance(amId)) + poolAmountInBalance), toBigInt(getAccBalance(prId))]
900- else [(toBigInt(getAccBalance(prId)) + poolAmountInBalance), toBigInt(getAccBalance(amId))]
901- let x = xp[0]
902- let s = x
903- let ann = (a * n)
904- let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
905- let b = ((s + ((D * aPrecision) / ann)) - D)
906- func calc (acc,cur) = {
907- let $t03432534345 = acc
908- let y = $t03432534345._1
909- let found = $t03432534345._2
910- if ((found != unit))
911- then acc
912- else {
913- let yNext = (((y * y) + c) / ((big2 * y) + b))
914- let yDiff = absBigInt((yNext - value(y)))
915- if ((big1 >= yDiff))
916- then $Tuple2(yNext, cur)
917- else $Tuple2(yNext, unit)
918- }
919- }
920-
921- let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
922- let $t03467634723 = {
923- let $l = arr
924- let $s = size($l)
925- let $acc0 = $Tuple2(D, unit)
926- func $f0_1 ($a,$i) = if (($i >= $s))
927- then $a
928- else calc($a, $l[$i])
929-
930- func $f0_2 ($a,$i) = if (($i >= $s))
931- then $a
932- else throw("List size exceeds 15")
933-
934- $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)
935- }
936- let y = $t03467634723._1
937- let found = $t03467634723._2
938- if ((found != unit))
939- then y
940- else throw(("Y calculation error, Y = " + toString(y)))
916+func mustManager (i) = {
917+ let pd = throw("Permission denied")
918+ match managerPublicKeyOrUnit() {
919+ case pk: ByteVector =>
920+ if ((i.callerPublicKey == pk))
921+ then true
922+ else pd
923+ case _: Unit =>
924+ if ((i.caller == this))
925+ then true
926+ else pd
927+ case _ =>
928+ throw("Match error")
929+ }
941930 }
942931
943932
944-func skipOrderValidation () = valueOrElse(getBoolean(fca, keySkipOrderValidation(toString(this))), false)
933+@Callable(i)
934+func rebalance () = (rebalanceAsset(getStringOrFail(this, aa())) ++ rebalanceAsset(getStringOrFail(this, pa())))
935+
945936
946937
947938 @Callable(i)
948939 func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse,feePoolAmount) = {
949- let $t03507535499 = if ((isReverse == false))
940+ let $t04010040405 = if ((isReverse == false))
950941 then {
951- let assetOut = strf(this, pa())
952- let poolAmountInBalance = (toBigInt(getAccBalance(strf(this, aa()))) + toBigInt(cleanAmountIn))
953- $Tuple2(assetOut, poolAmountInBalance)
942+ let assetOut = getStringOrFail(this, pa())
943+ let assetIn = getStringOrFail(this, aa())
944+ $Tuple2(assetOut, assetIn)
954945 }
955946 else {
956- let assetOut = strf(this, aa())
957- let poolAmountInBalance = (toBigInt(getAccBalance(strf(this, pa()))) + toBigInt(cleanAmountIn))
958- $Tuple2(assetOut, poolAmountInBalance)
947+ let assetOut = getStringOrFail(this, aa())
948+ let assetIn = getStringOrFail(this, pa())
949+ $Tuple2(assetOut, assetIn)
959950 }
960- let assetOut = $t03507535499._1
961- let poolAmountInBalance = $t03507535499._2
962- let poolConfig = gpc()
963- let amId = poolConfig[idxAmAsId]
964- let prId = poolConfig[idxPrAsId]
965- let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
966- let D = getD(xp)
967- let y = getY(isReverse, D, toBigInt(cleanAmountIn))
968- let dy = ((toBigInt(getAccBalance(assetOut)) - y) - toBigInt(1))
969- let totalGetRaw = max([0, toInt(dy)])
970- let newXp = if ((isReverse == false))
971- then [((toBigInt(getAccBalance(amId)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)), (toBigInt(getAccBalance(prId)) - dy)]
972- else [(toBigInt(getAccBalance(amId)) - dy), ((toBigInt(getAccBalance(prId)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount))]
973- let newD = getD(newXp)
974- let checkD = if ((newD >= D))
951+ let assetOut = $t04010040405._1
952+ let assetIn = $t04010040405._2
953+ let poolAssetInBalance = getAccBalance(assetIn)
954+ let poolAssetOutBalance = getAccBalance(assetOut)
955+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
956+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
957+ let newK = (((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
958+ let checkK = if ((newK >= oldK))
975959 then true
976- else throw(makeString(["new D is fewer error", toString(D), toString(newD)], "__"))
977- if ((checkD == checkD))
978- then $Tuple2(nil, totalGetRaw)
960+ else throw("new K is fewer error")
961+ if ((checkK == checkK))
962+ then $Tuple2(nil, amountOut)
979963 else throw("Strict value is not equal to itself.")
980964 }
981965
984968 @Callable(i)
985969 func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo,feePoolAmount) = {
986970 let swapContact = {
987- let @ = invoke(fca, "getSwapContractREADONLY", nil, nil)
971+ let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil)
988972 if ($isInstanceOf(@, "String"))
989973 then @
990974 else throw(($getType(@) + " couldn't be cast to String"))
991975 }
992- let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
976+ let isPoolSwapDisabled = {
977+ let @ = invoke(factoryContract, "isPoolSwapDisabledREADONLY", [toString(this)], nil)
978+ if ($isInstanceOf(@, "Boolean"))
979+ then @
980+ else throw(($getType(@) + " couldn't be cast to Boolean"))
981+ }
982+ let isSwapDisabled = if (!(isAddressWhitelisted(i.caller)))
983+ then if (if (isGlobalShutdown())
984+ then true
985+ else (cfgPoolStatus == PoolShutdown))
986+ then true
987+ else isPoolSwapDisabled
988+ else false
989+ let checks = [if (if (!(isSwapDisabled))
990+ then true
991+ else isManager(i))
992+ then true
993+ else throwErr("swap operation is blocked by admin"), if ((value(i.payments[0]).amount >= cleanAmountIn))
993994 then true
994995 else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
995996 then true
998999 then {
9991000 let pmt = value(i.payments[0])
10001001 let assetIn = assetIdToString(pmt.assetId)
1001- let $t03693537329 = if ((isReverse == false))
1002+ let assetOut = if ((isReverse == false))
1003+ then getStringOrFail(this, pa())
1004+ else getStringOrFail(this, aa())
1005+ let poolAssetInBalance = ((getAccBalance(assetIn) - value(i.payments[0]).amount) - feePoolAmount)
1006+ let poolAssetOutBalance = getAccBalance(assetOut)
1007+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
1008+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
1009+ let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
1010+ let checkK = if ((newK >= oldK))
1011+ then true
1012+ else throw("new K is fewer error")
1013+ if ((checkK == checkK))
10021014 then {
1003- let assetOut = strf(this, pa())
1004- let poolAmountInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
1005- $Tuple2(assetOut, poolAmountInBalance)
1006- }
1007- else {
1008- let assetOut = strf(this, aa())
1009- let poolAmountInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
1010- $Tuple2(assetOut, poolAmountInBalance)
1011- }
1012- let assetOut = $t03693537329._1
1013- let poolAmountInBalance = $t03693537329._2
1014- let poolConfig = gpc()
1015- let amId = poolConfig[idxAmAsId]
1016- let prId = poolConfig[idxPrAsId]
1017- let xp = if ((isReverse == false))
1018- then [(toBigInt(getAccBalance(amId)) - toBigInt(value(i.payments[0]).amount)), toBigInt(getAccBalance(prId))]
1019- else [toBigInt(getAccBalance(amId)), (toBigInt(getAccBalance(prId)) - toBigInt(value(i.payments[0]).amount))]
1020- let D = getD(xp)
1021- let y = getY(isReverse, D, toBigInt(0))
1022- let dy = ((toBigInt(getAccBalance(assetOut)) - y) - toBigInt(1))
1023- let totalGetRaw = max([0, toInt(dy)])
1024- let checkMin = if ((totalGetRaw >= amountOutMin))
1025- then true
1026- else throw("Exchange result is fewer coins than expected")
1027- if ((checkMin == checkMin))
1028- then {
1029- let newXp = if ((isReverse == false))
1030- then [(toBigInt(getAccBalance(amId)) + toBigInt(feePoolAmount)), (toBigInt(getAccBalance(prId)) - dy)]
1031- else [(toBigInt(getAccBalance(amId)) - dy), (toBigInt(getAccBalance(prId)) + toBigInt(feePoolAmount))]
1032- let newD = getD(newXp)
1033- let checkD = if ((newD >= D))
1015+ let checkMin = if ((amountOut >= amountOutMin))
10341016 then true
1035- else throw("new D is fewer error")
1036- if ((checkD == checkD))
1037- then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), totalGetRaw, parseAssetId(assetOut))], totalGetRaw)
1038- else throw("Strict value is not equal to itself.")
1039- }
1040- else throw("Strict value is not equal to itself.")
1041- }
1042- else throw("Strict value is not equal to itself.")
1043- }
1044-
1045-
1046-
1047-@Callable(i)
1048-func constructor (fc) = {
1049- let c = mm(i)
1050- if ((c == c))
1051- then [StringEntry(fc(), fc)]
1052- else throw("Strict value is not equal to itself.")
1053- }
1054-
1055-
1056-
1057-@Callable(i)
1058-func setManager (pendingManagerPublicKey) = {
1059- let c = mm(i)
1060- if ((c == c))
1061- then {
1062- let cm = fromBase58String(pendingManagerPublicKey)
1063- if ((cm == cm))
1064- then [StringEntry(pmpk(), pendingManagerPublicKey)]
1065- else throw("Strict value is not equal to itself.")
1066- }
1067- else throw("Strict value is not equal to itself.")
1068- }
1069-
1070-
1071-
1072-@Callable(i)
1073-func confirmManager () = {
1074- let p = pm()
1075- let hpm = if (isDefined(p))
1076- then true
1077- else throw("No pending manager")
1078- if ((hpm == hpm))
1079- then {
1080- let cpm = if ((i.callerPublicKey == value(p)))
1081- then true
1082- else throw("You are not pending manager")
1083- if ((cpm == cpm))
1084- then [StringEntry(mpk(), toBase58String(value(p))), DeleteEntry(pmpk())]
1085- else throw("Strict value is not equal to itself.")
1086- }
1087- else throw("Strict value is not equal to itself.")
1088- }
1089-
1090-
1091-
1092-@Callable(i)
1093-func put (slip,autoStake) = {
1094- let factCfg = gfc()
1095- let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Wr st addr")
1096- let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Wr sl addr")
1097- if ((0 > slip))
1098- then throw("Wrong slippage")
1099- else if ((size(i.payments) != 2))
1100- then throw("2 pmnts expd")
1101- else {
1102- let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1103- let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1104- let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amAssetPmt)
1105- if ((amountAssetBalance == amountAssetBalance))
1106- then {
1107- let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - prAssetPmt)
1108- if ((priceAssetBalance == priceAssetBalance))
1109- then {
1110- let lpAssetEmission = toBigInt(value(assetInfo(cfgLpAssetId)).quantity)
1111- if ((lpAssetEmission == lpAssetEmission))
1112- then {
1113- let currentDLp = calcCurrentDLp(amAssetPmt, prAssetPmt, toBigInt(0))
1114- if ((currentDLp == currentDLp))
1115- then {
1116- 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, "")
1117- let emitLpAmt = e._2
1118- let lpAssetId = e._7
1119- let state = e._9
1120- let amDiff = e._10
1121- let prDiff = e._11
1122- let amId = e._12
1123- let prId = e._13
1124- let r = invoke(fca, "emit", [emitLpAmt], nil)
1125- if ((r == r))
1126- then {
1127- let el = match r {
1128- case legacy: Address =>
1129- invoke(legacy, "emit", [emitLpAmt], nil)
1130- case _ =>
1131- unit
1132- }
1133- if ((el == el))
1134- then {
1135- let sa = if ((amDiff > 0))
1136- then invoke(slipCntr, "put", nil, [AttachedPayment(amId, amDiff)])
1137- else nil
1138- if ((sa == sa))
1139- then {
1140- let sp = if ((prDiff > 0))
1141- then invoke(slipCntr, "put", nil, [AttachedPayment(prId, prDiff)])
1142- else nil
1143- if ((sp == sp))
1144- then {
1145- let lpTrnsfr = if (autoStake)
1146- then {
1147- let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
1148- if ((ss == ss))
1149- then nil
1150- else throw("Strict value is not equal to itself.")
1151- }
1152- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1153- let $t04194842090 = refreshDLpInternal(0, 0, 0)
1154- let refreshDLpActions = $t04194842090._1
1155- let updatedDLp = $t04194842090._2
1156- let check = if ((updatedDLp >= currentDLp))
1157- then true
1158- else throwErr(makeString(["updated DLp lower than current DLp", toString(amountAssetBalance), toString(priceAssetBalance), toString(lpAssetEmission), toString(currentDLp), toString(updatedDLp), toString(amDiff), toString(prDiff)], " "))
1159- if ((check == check))
1160- then {
1161- let lpAssetEmissionAfter = value(assetInfo(cfgLpAssetId)).quantity
1162- if ((lpAssetEmissionAfter == lpAssetEmissionAfter))
1163- then ((state ++ lpTrnsfr) ++ refreshDLpActions)
1164- else throw("Strict value is not equal to itself.")
1165- }
1166- else throw("Strict value is not equal to itself.")
1167- }
1168- else throw("Strict value is not equal to itself.")
1169- }
1170- else throw("Strict value is not equal to itself.")
1171- }
1172- else throw("Strict value is not equal to itself.")
1173- }
1174- else throw("Strict value is not equal to itself.")
1175- }
1176- else throw("Strict value is not equal to itself.")
1177- }
1178- else throw("Strict value is not equal to itself.")
1179- }
1180- else throw("Strict value is not equal to itself.")
1181- }
1182- else throw("Strict value is not equal to itself.")
1183- }
1184- }
1185-
1186-
1187-
1188-@Callable(i)
1189-func putOneTknV2 (minOutAmount,autoStake) = {
1190- let isPoolOneTokenOperationsDisabled = {
1191- let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1192- if ($isInstanceOf(@, "Boolean"))
1193- then @
1194- else throw(($getType(@) + " couldn't be cast to Boolean"))
1195- }
1196- let isPutDisabled = if (if (if (igs())
1197- then true
1198- else (cfgPoolStatus == PoolPutDis))
1199- then true
1200- else (cfgPoolStatus == PoolShutdown))
1201- then true
1202- else isPoolOneTokenOperationsDisabled
1203- let checks = [if (if (!(isPutDisabled))
1204- then true
1205- else isManager(i))
1206- then true
1207- else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
1208- then true
1209- else throwErr("exactly 1 payment are expected")]
1210- if ((checks == checks))
1211- then {
1212- let amId = toBase58String(value(cfgAmountAssetId))
1213- let prId = toBase58String(value(cfgPriceAssetId))
1214- let lpId = cfgLpAssetId
1215- let amDecimals = cfgAmountAssetDecimals
1216- let prDecimals = cfgPriceAssetDecimals
1217- let userAddress = if ((i.caller == this))
1218- then i.originCaller
1219- else i.caller
1220- let pmt = value(i.payments[0])
1221- let pmtAssetId = toBase58String(value(pmt.assetId))
1222- let pmtAmt = pmt.amount
1223- let currentDLp = if ((pmt.assetId == cfgAmountAssetId))
1224- then calcCurrentDLp(toBigInt(pmtAmt), toBigInt(0), toBigInt(0))
1225- else calcCurrentDLp(toBigInt(0), toBigInt(pmtAmt), toBigInt(0))
1226- if ((currentDLp == currentDLp))
1227- then {
1228- let $t04373143889 = calcPutOneTkn(pmtAmt, pmtAssetId, toString(userAddress), toBase58String(i.transactionId), true)
1229- if (($t04373143889 == $t04373143889))
1017+ else throw("Exchange result is fewer coins than expected")
1018+ if ((checkMin == checkMin))
12301019 then {
1231- let feeAmount = $t04373143889._3
1232- let state = $t04373143889._2
1233- let estimLP = $t04373143889._1
1234- let emitLpAmt = if (if ((minOutAmount > 0))
1235- then (minOutAmount > estimLP)
1236- else false)
1237- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1238- else estimLP
1239- let e = invoke(fca, "emit", [emitLpAmt], nil)
1240- if ((e == e))
1020+ let amountAssetBalanceDelta = if (isReverse)
1021+ then -(amountOut)
1022+ else feePoolAmount
1023+ let priceAssetBalanceDelta = if (isReverse)
1024+ then feePoolAmount
1025+ else -(amountOut)
1026+ let refreshKLpActions = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)._1
1027+ if ((refreshKLpActions == refreshKLpActions))
12411028 then {
1242- let el = match e {
1243- case legacy: Address =>
1244- invoke(legacy, "emit", [emitLpAmt], nil)
1245- case _ =>
1246- unit
1247- }
1248- if ((el == el))
1029+ let rebalanceState = rebalanceAsset(assetIn)
1030+ if ((rebalanceState == rebalanceState))
12491031 then {
1250- let lpTrnsfr = if (autoStake)
1251- then {
1252- let ss = invoke(stakingContract, "stakeFor", [toString(i.caller)], [AttachedPayment(lpId, emitLpAmt)])
1253- if ((ss == ss))
1254- then nil
1255- else throw("Strict value is not equal to itself.")
1256- }
1257- else [ScriptTransfer(i.caller, emitLpAmt, lpId)]
1258- let sendFeeToMatcher = if ((feeAmount > 0))
1259- then [ScriptTransfer(feeCollectorAddress, feeAmount, fromBase58String(pmtAssetId))]
1260- else nil
1261- let $t04477445123 = if ((this == feeCollectorAddress))
1262- then $Tuple2(0, 0)
1263- else {
1264- let paymentInAmountAsset = if ((pmt.assetId == cfgAmountAssetId))
1265- then true
1266- else false
1267- if (paymentInAmountAsset)
1268- then $Tuple2(-(feeAmount), 0)
1269- else $Tuple2(0, -(feeAmount))
1270- }
1271- let amountAssetBalanceDelta = $t04477445123._1
1272- let priceAssetBalanceDelta = $t04477445123._2
1273- let $t04512645234 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1274- let refreshDLpActions = $t04512645234._1
1275- let updatedDLp = $t04512645234._2
1276- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1277- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1278- then $Tuple2((((state ++ lpTrnsfr) ++ sendFeeToMatcher) ++ refreshDLpActions), emitLpAmt)
1032+ let withdrawState = withdrawAndRebalanceAsset(assetOut, amountOut)
1033+ if ((withdrawState == withdrawState))
1034+ then $Tuple2(((withdrawState ++ rebalanceState) ++ [ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))]), amountOut)
12791035 else throw("Strict value is not equal to itself.")
12801036 }
12811037 else throw("Strict value is not equal to itself.")
12921048
12931049
12941050 @Callable(i)
1295-func putForFree (maxSlpg) = if ((0 > maxSlpg))
1296- then throw("Wrong slpg")
1297- else if ((size(i.payments) != 2))
1298- then throw("2 pmnts expd")
1299- else {
1300- 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, "")
1301- let state = estPut._9
1302- let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1303- let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1304- let currentDLp = calcCurrentDLp(amAssetPmt, prAssetPmt, toBigInt(0))
1305- if ((currentDLp == currentDLp))
1306- then {
1307- let $t04626446329 = refreshDLpInternal(0, 0, 0)
1308- let refreshDLpActions = $t04626446329._1
1309- let updatedDLp = $t04626446329._2
1310- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1311- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1312- then (state ++ refreshDLpActions)
1313- else throw("Strict value is not equal to itself.")
1314- }
1315- else throw("Strict value is not equal to itself.")
1316- }
1051+func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
1052+ then throw("Invalid slippageTolerance passed")
1053+ else {
1054+ let estPut = commonPut(i, slippageTolerance, true)
1055+ let emitLpAmt = estPut._2
1056+ let lpAssetId = estPut._7
1057+ let state = estPut._9
1058+ let amDiff = estPut._10
1059+ let prDiff = estPut._11
1060+ let amId = estPut._12
1061+ let prId = estPut._13
1062+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1063+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1064+ let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
1065+ if ((currentKLp == currentKLp))
1066+ then {
1067+ let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
1068+ if ((emitInv == emitInv))
1069+ then {
1070+ let emitInvLegacy = match emitInv {
1071+ case legacyFactoryContract: Address =>
1072+ invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
1073+ case _ =>
1074+ unit
1075+ }
1076+ if ((emitInvLegacy == emitInvLegacy))
1077+ then {
1078+ let slippageAInv = if ((amDiff > 0))
1079+ then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
1080+ else nil
1081+ if ((slippageAInv == slippageAInv))
1082+ then {
1083+ let slippagePInv = if ((prDiff > 0))
1084+ then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
1085+ else nil
1086+ if ((slippagePInv == slippagePInv))
1087+ then {
1088+ let lpTransfer = if (shouldAutoStake)
1089+ then {
1090+ let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
1091+ if ((slpStakeInv == slpStakeInv))
1092+ then nil
1093+ else throw("Strict value is not equal to itself.")
1094+ }
1095+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1096+ let $t04558146043 = refreshKLpInternal(0, 0, 0)
1097+ if (($t04558146043 == $t04558146043))
1098+ then {
1099+ let updatedKLp = $t04558146043._2
1100+ let refreshKLpActions = $t04558146043._1
1101+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1102+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1103+ then {
1104+ let reb = invoke(this, "rebalance", nil, nil)
1105+ if ((reb == reb))
1106+ then ((state ++ lpTransfer) ++ refreshKLpActions)
1107+ else throw("Strict value is not equal to itself.")
1108+ }
1109+ else throw("Strict value is not equal to itself.")
1110+ }
1111+ else throw("Strict value is not equal to itself.")
1112+ }
1113+ else throw("Strict value is not equal to itself.")
1114+ }
1115+ else throw("Strict value is not equal to itself.")
1116+ }
1117+ else throw("Strict value is not equal to itself.")
1118+ }
1119+ else throw("Strict value is not equal to itself.")
1120+ }
1121+ else throw("Strict value is not equal to itself.")
1122+ }
13171123
13181124
13191125
13201126 @Callable(i)
1321-func get () = {
1322- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1323- if ((currentDLp == currentDLp))
1127+func putForFree (maxSlippage) = if ((0 > maxSlippage))
1128+ then throw("Invalid value passed")
1129+ else {
1130+ let estPut = commonPut(i, maxSlippage, false)
1131+ let state = estPut._9
1132+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1133+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1134+ let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
1135+ if ((currentKLp == currentKLp))
1136+ then {
1137+ let $t04665546720 = refreshKLpInternal(0, 0, 0)
1138+ let refreshKLpActions = $t04665546720._1
1139+ let updatedKLp = $t04665546720._2
1140+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1141+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1142+ then (state ++ refreshKLpActions)
1143+ else throw("Strict value is not equal to itself.")
1144+ }
1145+ else throw("Strict value is not equal to itself.")
1146+ }
1147+
1148+
1149+
1150+@Callable(i)
1151+func putOneTkn (minOutAmount,autoStake) = {
1152+ let isPoolOneTokenOperationsDisabled = {
1153+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1154+ if ($isInstanceOf(@, "Boolean"))
1155+ then @
1156+ else throw(($getType(@) + " couldn't be cast to Boolean"))
1157+ }
1158+ let isPutDisabled = if (!(isAddressWhitelisted(i.caller)))
1159+ then if (if (if (isGlobalShutdown())
1160+ then true
1161+ else (cfgPoolStatus == PoolPutDisabled))
1162+ then true
1163+ else (cfgPoolStatus == PoolShutdown))
1164+ then true
1165+ else isPoolOneTokenOperationsDisabled
1166+ else false
1167+ let checks = [if (if (!(isPutDisabled))
1168+ then true
1169+ else isManager(i))
1170+ then true
1171+ else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
1172+ then true
1173+ else throwErr("exactly 1 payment are expected")]
1174+ if ((checks == checks))
13241175 then {
1325- let r = cg(i)
1326- let outAmtAmt = r._1
1327- let outPrAmt = r._2
1328- let pmtAmt = r._3
1329- let pmtAssetId = r._4
1330- let state = r._5
1331- let b = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1332- if ((b == b))
1176+ let payment = i.payments[0]
1177+ let paymentAssetId = payment.assetId
1178+ let paymentAmountRaw = payment.amount
1179+ let currentKLp = if ((paymentAssetId == cfgAmountAssetId))
1180+ then calcCurrentKLp(toBigInt(paymentAmountRaw), toBigInt(0), toBigInt(0))
1181+ else if ((paymentAssetId == cfgPriceAssetId))
1182+ then calcCurrentKLp(toBigInt(0), toBigInt(paymentAmountRaw), toBigInt(0))
1183+ else throwErr("payment asset is not supported")
1184+ if ((currentKLp == currentKLp))
13331185 then {
1334- let $t04750247584 = refreshDLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1335- let refreshDLpActions = $t04750247584._1
1336- let updatedDLp = $t04750247584._2
1337- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1338- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1339- then (state ++ refreshDLpActions)
1186+ let userAddress = i.caller
1187+ let txId = i.transactionId
1188+ let $t04794948101 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
1189+ if (($t04794948101 == $t04794948101))
1190+ then {
1191+ let paymentInAmountAsset = $t04794948101._5
1192+ let bonus = $t04794948101._4
1193+ let feeAmount = $t04794948101._3
1194+ let commonState = $t04794948101._2
1195+ let emitAmountEstimated = $t04794948101._1
1196+ let emitAmount = if (if ((minOutAmount > 0))
1197+ then (minOutAmount > emitAmountEstimated)
1198+ else false)
1199+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1200+ else emitAmountEstimated
1201+ let emitInv = emit(emitAmount)
1202+ if ((emitInv == emitInv))
1203+ then {
1204+ let lpTransfer = if (autoStake)
1205+ then {
1206+ let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
1207+ if ((stakeInv == stakeInv))
1208+ then nil
1209+ else throw("Strict value is not equal to itself.")
1210+ }
1211+ else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
1212+ let sendFee = if ((feeAmount > 0))
1213+ then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
1214+ else nil
1215+ let $t04868748884 = if ((this == feeCollectorAddress))
1216+ then $Tuple2(0, 0)
1217+ else if (paymentInAmountAsset)
1218+ then $Tuple2(-(feeAmount), 0)
1219+ else $Tuple2(0, -(feeAmount))
1220+ let amountAssetBalanceDelta = $t04868748884._1
1221+ let priceAssetBalanceDelta = $t04868748884._2
1222+ let $t04888748995 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1223+ let refreshKLpActions = $t04888748995._1
1224+ let updatedKLp = $t04888748995._2
1225+ let kLp = value(getString(keyKLp))
1226+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1227+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1228+ then {
1229+ let reb = invoke(this, "rebalance", nil, nil)
1230+ if ((reb == reb))
1231+ then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
1232+ else throw("Strict value is not equal to itself.")
1233+ }
1234+ else throw("Strict value is not equal to itself.")
1235+ }
1236+ else throw("Strict value is not equal to itself.")
1237+ }
13401238 else throw("Strict value is not equal to itself.")
13411239 }
13421240 else throw("Strict value is not equal to itself.")
13471245
13481246
13491247 @Callable(i)
1350-func getOneTknV2 (outAssetId,minOutAmount) = {
1248+func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
1249+ let $t04935049507 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
1250+ let emitAmountEstimated = $t04935049507._1
1251+ let commonState = $t04935049507._2
1252+ let feeAmount = $t04935049507._3
1253+ let bonus = $t04935049507._4
1254+ let paymentInAmountAsset = $t04935049507._5
1255+ $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
1256+ }
1257+
1258+
1259+
1260+@Callable(i)
1261+func getOneTkn (outAssetIdStr,minOutAmount) = {
13511262 let isPoolOneTokenOperationsDisabled = {
1352- let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1263+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
13531264 if ($isInstanceOf(@, "Boolean"))
13541265 then @
13551266 else throw(($getType(@) + " couldn't be cast to Boolean"))
13561267 }
1357- let isGetDisabled = if (if (igs())
1358- then true
1359- else (cfgPoolStatus == PoolShutdown))
1360- then true
1361- else isPoolOneTokenOperationsDisabled
1268+ let isGetDisabled = if (!(isAddressWhitelisted(i.caller)))
1269+ then if (if (isGlobalShutdown())
1270+ then true
1271+ else (cfgPoolStatus == PoolShutdown))
1272+ then true
1273+ else isPoolOneTokenOperationsDisabled
1274+ else false
13621275 let checks = [if (if (!(isGetDisabled))
13631276 then true
13641277 else isManager(i))
13681281 else throwErr("exactly 1 payment are expected")]
13691282 if ((checks == checks))
13701283 then {
1371- let $t04820248357 = getOneTknV2Internal(outAssetId, minOutAmount, i.payments, i.caller, i.originCaller, i.transactionId)
1372- let state = $t04820248357._1
1373- let totalAmount = $t04820248357._2
1374- $Tuple2(state, totalAmount)
1284+ let outAssetId = parseAssetId(outAssetIdStr)
1285+ let payment = i.payments[0]
1286+ let paymentAssetId = payment.assetId
1287+ let paymentAmount = payment.amount
1288+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1289+ if ((currentKLp == currentKLp))
1290+ then {
1291+ let userAddress = i.caller
1292+ let txId = i.transactionId
1293+ let $t05042950582 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1294+ if (($t05042950582 == $t05042950582))
1295+ then {
1296+ let outInAmountAsset = $t05042950582._5
1297+ let bonus = $t05042950582._4
1298+ let feeAmount = $t05042950582._3
1299+ let commonState = $t05042950582._2
1300+ let amountEstimated = $t05042950582._1
1301+ let amount = if (if ((minOutAmount > 0))
1302+ then (minOutAmount > amountEstimated)
1303+ else false)
1304+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1305+ else amountEstimated
1306+ let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
1307+ if ((burnInv == burnInv))
1308+ then {
1309+ let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
1310+ let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
1311+ let sendFee = if ((feeAmount > 0))
1312+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1313+ else nil
1314+ let $t05124651493 = {
1315+ let feeAmountForCalc = if ((this == feeCollectorAddress))
1316+ then 0
1317+ else feeAmount
1318+ if (outInAmountAsset)
1319+ then $Tuple2(-((amount + feeAmountForCalc)), 0)
1320+ else $Tuple2(0, -((amount + feeAmountForCalc)))
1321+ }
1322+ let amountAssetBalanceDelta = $t05124651493._1
1323+ let priceAssetBalanceDelta = $t05124651493._2
1324+ let $t05149651604 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1325+ let refreshKLpActions = $t05149651604._1
1326+ let updatedKLp = $t05149651604._2
1327+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1328+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1329+ then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1330+ else throw("Strict value is not equal to itself.")
1331+ }
1332+ else throw("Strict value is not equal to itself.")
1333+ }
1334+ else throw("Strict value is not equal to itself.")
1335+ }
1336+ else throw("Strict value is not equal to itself.")
13751337 }
13761338 else throw("Strict value is not equal to itself.")
13771339 }
13791341
13801342
13811343 @Callable(i)
1382-func refreshDLp () = {
1383- let lastRefreshedBlockHeight = valueOrElse(getInteger(keyDLpRefreshedHeight), 0)
1384- let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= dLpRefreshDelay))
1385- then unit
1386- else throwErr(makeString([toString(dLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1387- if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
1344+func getOneTknREADONLY (outAssetId,paymentAmount) = {
1345+ let $t05188252038 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1346+ let amountEstimated = $t05188252038._1
1347+ let commonState = $t05188252038._2
1348+ let feeAmount = $t05188252038._3
1349+ let bonus = $t05188252038._4
1350+ let outInAmountAsset = $t05188252038._5
1351+ $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
1352+ }
1353+
1354+
1355+
1356+@Callable(i)
1357+func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
1358+ let isPoolOneTokenOperationsDisabled = {
1359+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1360+ if ($isInstanceOf(@, "Boolean"))
1361+ then @
1362+ else throw(($getType(@) + " couldn't be cast to Boolean"))
1363+ }
1364+ let isGetDisabled = if (!(isAddressWhitelisted(i.caller)))
1365+ then if (if (isGlobalShutdown())
1366+ then true
1367+ else (cfgPoolStatus == PoolShutdown))
1368+ then true
1369+ else isPoolOneTokenOperationsDisabled
1370+ else false
1371+ let checks = [if (if (!(isGetDisabled))
1372+ then true
1373+ else isManager(i))
1374+ then true
1375+ else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
1376+ then true
1377+ else throwErr("no payments are expected")]
1378+ if ((checks == checks))
13881379 then {
1389- let dLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyDLp), "0")), fmtErr("invalid dLp"))
1390- let $t04888148945 = refreshDLpInternal(0, 0, 0)
1391- let dLpUpdateActions = $t04888148945._1
1392- let updatedDLp = $t04888148945._2
1393- let actions = if ((dLp != updatedDLp))
1394- then dLpUpdateActions
1395- else throwErr("nothing to refresh")
1396- $Tuple2(actions, toString(updatedDLp))
1380+ let outAssetId = parseAssetId(outAssetIdStr)
1381+ let userAddress = i.caller
1382+ let txId = i.transactionId
1383+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1384+ if ((currentKLp == currentKLp))
1385+ then {
1386+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1387+ if ((unstakeInv == unstakeInv))
1388+ then {
1389+ let $t05298053131 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1390+ if (($t05298053131 == $t05298053131))
1391+ then {
1392+ let outInAmountAsset = $t05298053131._5
1393+ let bonus = $t05298053131._4
1394+ let feeAmount = $t05298053131._3
1395+ let commonState = $t05298053131._2
1396+ let amountEstimated = $t05298053131._1
1397+ let amount = if (if ((minOutAmount > 0))
1398+ then (minOutAmount > amountEstimated)
1399+ else false)
1400+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1401+ else amountEstimated
1402+ let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1403+ if ((burnInv == burnInv))
1404+ then {
1405+ let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
1406+ let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
1407+ let sendFee = if ((feeAmount > 0))
1408+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1409+ else nil
1410+ let $t05379054037 = {
1411+ let feeAmountForCalc = if ((this == feeCollectorAddress))
1412+ then 0
1413+ else feeAmount
1414+ if (outInAmountAsset)
1415+ then $Tuple2(-((amount + feeAmountForCalc)), 0)
1416+ else $Tuple2(0, -((amount + feeAmountForCalc)))
1417+ }
1418+ let amountAssetBalanceDelta = $t05379054037._1
1419+ let priceAssetBalanceDelta = $t05379054037._2
1420+ let $t05404054148 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1421+ let refreshKLpActions = $t05404054148._1
1422+ let updatedKLp = $t05404054148._2
1423+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1424+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1425+ then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1426+ else throw("Strict value is not equal to itself.")
1427+ }
1428+ else throw("Strict value is not equal to itself.")
1429+ }
1430+ else throw("Strict value is not equal to itself.")
1431+ }
1432+ else throw("Strict value is not equal to itself.")
1433+ }
1434+ else throw("Strict value is not equal to itself.")
13971435 }
13981436 else throw("Strict value is not equal to itself.")
13991437 }
14011439
14021440
14031441 @Callable(i)
1404-func getOneTknV2READONLY (outAssetId,lpAssetAmount) = {
1405- let amId = toBase58String(value(cfgAmountAssetId))
1406- let prId = toBase58String(value(cfgPriceAssetId))
1407- let lpId = toBase58String(value(cfgLpAssetId))
1408- let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
1409- let lpEmission = toBigInt(valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "invalid lp asset").quantity)
1410- let D0 = getD(xp)
1411- let D1 = (D0 - fraction(toBigInt(lpAssetAmount), D0, lpEmission))
1412- let index = if ((outAssetId == amId))
1413- then 0
1414- else if ((outAssetId == prId))
1415- then 1
1416- else throw("invalid out asset id")
1417- let newY = getYD(xp, index, D1)
1418- let dy = (xp[index] - newY)
1419- let totalGetRaw = max([0, toInt((dy - big1))])
1420- let $t04995550010 = takeFee(totalGetRaw, outFee)
1421- let totalGet = $t04995550010._1
1422- let feeAmount = $t04995550010._2
1423- $Tuple2(nil, $Tuple2(totalGet, feeAmount))
1424- }
1425-
1426-
1427-
1428-@Callable(i)
1429-func getOneTknV2WithBonusREADONLY (outAssetId,lpAssetAmount) = {
1430- let amId = toBase58String(value(cfgAmountAssetId))
1431- let prId = toBase58String(value(cfgPriceAssetId))
1432- let lpId = toBase58String(value(cfgLpAssetId))
1433- let amBalance = getAccBalance(amId)
1434- let prBalance = getAccBalance(prId)
1435- let $t05038550500 = {
1436- let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, lpAssetAmount], nil)
1437- if ($isInstanceOf(@, "(Int, Int)"))
1438- then @
1439- else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
1440- }
1441- let totalGet = $t05038550500._1
1442- let feeAmount = $t05038550500._2
1443- let r = ego("", lpId, lpAssetAmount, this)
1444- let outAmAmt = r._1
1445- let outPrAmt = r._2
1446- let sumOfGetAssets = (outAmAmt + outPrAmt)
1447- let bonus = if ((sumOfGetAssets == 0))
1448- then if ((totalGet == 0))
1449- then 0
1450- else throw("bonus calculation error")
1451- else fraction((totalGet - sumOfGetAssets), scale8, sumOfGetAssets)
1452- $Tuple2(nil, $Tuple3(totalGet, feeAmount, bonus))
1442+func get () = {
1443+ let res = commonGet(i)
1444+ let outAmAmt = res._1
1445+ let outPrAmt = res._2
1446+ let pmtAmt = res._3
1447+ let pmtAssetId = res._4
1448+ let state = res._5
1449+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1450+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1451+ if ((currentKLp == currentKLp))
1452+ then {
1453+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1454+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1455+ then {
1456+ let $t05524355324 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1457+ let refreshKLpActions = $t05524355324._1
1458+ let updatedKLp = $t05524355324._2
1459+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1460+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1461+ then ((withdrawState ++ state) ++ refreshKLpActions)
1462+ else throw("Strict value is not equal to itself.")
1463+ }
1464+ else throw("Strict value is not equal to itself.")
1465+ }
1466+ else throw("Strict value is not equal to itself.")
14531467 }
14541468
14551469
14561470
14571471 @Callable(i)
14581472 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
1459- let r = cg(i)
1460- let outAmAmt = r._1
1461- let outPrAmt = r._2
1462- let pmtAmt = r._3
1463- let pmtAssetId = r._4
1464- let state = r._5
1473+ let res = commonGet(i)
1474+ let outAmAmt = res._1
1475+ let outPrAmt = res._2
1476+ let pmtAmt = res._3
1477+ let pmtAssetId = res._4
1478+ let state = res._5
14651479 if ((noLessThenAmtAsset > outAmAmt))
1466- then throw(((("Failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
1480+ then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
14671481 else if ((noLessThenPriceAsset > outPrAmt))
1468- then throw(((("Failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
1482+ then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
14691483 else {
1470- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1471- if ((currentDLp == currentDLp))
1484+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1485+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1486+ if ((currentKLp == currentKLp))
14721487 then {
1473- let burnLPAssetOnFactory = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1488+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
14741489 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
14751490 then {
1476- let $t05166651747 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1477- let refreshDLpActions = $t05166651747._1
1478- let updatedDLp = $t05166651747._2
1479- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1480- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1481- then (state ++ refreshDLpActions)
1491+ let $t05641956500 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1492+ let refreshKLpActions = $t05641956500._1
1493+ let updatedKLp = $t05641956500._2
1494+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1495+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1496+ then ((withdrawState ++ state) ++ refreshKLpActions)
14821497 else throw("Strict value is not equal to itself.")
14831498 }
14841499 else throw("Strict value is not equal to itself.")
14921507 @Callable(i)
14931508 func unstakeAndGet (amount) = {
14941509 let checkPayments = if ((size(i.payments) != 0))
1495- then throw("No pmnts expd")
1510+ then throw("No payments are expected")
14961511 else true
14971512 if ((checkPayments == checkPayments))
14981513 then {
1499- let factoryCfg = gfc()
1500- let lpAssetId = cfgLpAssetId
1501- let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1502- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1503- if ((currentDLp == currentDLp))
1514+ let cfg = getPoolConfig()
1515+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1516+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1517+ if ((currentKLp == currentKLp))
15041518 then {
1505- let unstakeInv = invoke(staking, "unstake", [toBase58String(lpAssetId), amount], nil)
1519+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
15061520 if ((unstakeInv == unstakeInv))
15071521 then {
1508- let r = ego(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1509- let outAmAmt = r._1
1510- let outPrAmt = r._2
1511- let sts = parseIntValue(r._9)
1512- let state = r._10
1513- let v = if (if (igs())
1514- then true
1515- else (sts == PoolShutdown))
1516- then throw(("Blocked: " + toString(sts)))
1522+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1523+ let outAmAmt = res._1
1524+ let outPrAmt = res._2
1525+ let poolStatus = parseIntValue(res._9)
1526+ let state = res._10
1527+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1528+ let isGetDisabled = if (!(isAddressWhitelisted(i.caller)))
1529+ then if (isGlobalShutdown())
1530+ then true
1531+ else (cfgPoolStatus == PoolShutdown)
1532+ else false
1533+ let checkPoolStatus = if (isGetDisabled)
1534+ then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
15171535 else true
1518- if ((v == v))
1536+ if ((checkPoolStatus == checkPoolStatus))
15191537 then {
1520- let burnA = invoke(fca, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1521- if ((burnA == burnA))
1538+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1539+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
15221540 then {
1523- let $t05277452855 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1524- let refreshDLpActions = $t05277452855._1
1525- let updatedDLp = $t05277452855._2
1526- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1527- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1528- then (state ++ refreshDLpActions)
1541+ let $t05784857929 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1542+ let refreshKLpActions = $t05784857929._1
1543+ let updatedKLp = $t05784857929._2
1544+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1545+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1546+ then ((withdrawState ++ state) ++ refreshKLpActions)
15291547 else throw("Strict value is not equal to itself.")
15301548 }
15311549 else throw("Strict value is not equal to itself.")
15431561
15441562 @Callable(i)
15451563 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
1546- let isGetDisabled = if (igs())
1547- then true
1548- else (cfgPoolStatus == PoolShutdown)
1564+ let isGetDisabled = if (!(isAddressWhitelisted(i.caller)))
1565+ then if (isGlobalShutdown())
1566+ then true
1567+ else (cfgPoolStatus == PoolShutdown)
1568+ else false
15491569 let checks = [if (!(isGetDisabled))
15501570 then true
15511571 else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
15531573 else throw("no payments are expected")]
15541574 if ((checks == checks))
15551575 then {
1556- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1557- if ((currentDLp == currentDLp))
1576+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1577+ if ((currentKLp == currentKLp))
15581578 then {
15591579 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
15601580 if ((unstakeInv == unstakeInv))
15611581 then {
1562- let res = ego(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
1582+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
15631583 let outAmAmt = res._1
15641584 let outPrAmt = res._2
15651585 let state = res._10
1586+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
15661587 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
15671588 then true
15681589 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
15701591 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
15711592 if ((checkAmounts == checkAmounts))
15721593 then {
1573- let burnLPAssetOnFactory = invoke(fca, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1594+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
15741595 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
15751596 then {
1576- let $t05410654187 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1577- let refreshDLpActions = $t05410654187._1
1578- let updatedDLp = $t05410654187._2
1579- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1580- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1581- then (state ++ refreshDLpActions)
1597+ let $t05940759488 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1598+ let refreshKLpActions = $t05940759488._1
1599+ let updatedKLp = $t05940759488._2
1600+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1601+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1602+ then ((withdrawState ++ state) ++ refreshKLpActions)
15821603 else throw("Strict value is not equal to itself.")
15831604 }
15841605 else throw("Strict value is not equal to itself.")
15951616
15961617
15971618 @Callable(i)
1598-func unstakeAndGetOneTknV2 (unstakeAmount,outAssetId,minOutAmount) = {
1599- let isPoolOneTokenOperationsDisabled = {
1600- let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1601- if ($isInstanceOf(@, "Boolean"))
1602- then @
1603- else throw(($getType(@) + " couldn't be cast to Boolean"))
1604- }
1605- let isGetDisabled = if (if (igs())
1606- then true
1607- else (cfgPoolStatus == PoolShutdown))
1608- then true
1609- else isPoolOneTokenOperationsDisabled
1610- let checks = [if (if (!(isGetDisabled))
1611- then true
1612- else isManager(i))
1613- then true
1614- else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
1615- then true
1616- else throwErr("no payments are expected")]
1617- if ((checks == checks))
1619+func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
1620+ then throw("permissions denied")
1621+ else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
1622+
1623+
1624+
1625+@Callable(i)
1626+func refreshKLp () = {
1627+ let lastRefreshedBlockHeight = valueOrElse(getInteger(keyKLpRefreshedHeight), 0)
1628+ let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= kLpRefreshDelay))
1629+ then unit
1630+ else throwErr(makeString([toString(kLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1631+ if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
16181632 then {
1619- let factoryCfg = gfc()
1620- let lpAssetId = cfgLpAssetId
1621- let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1622- let userAddress = i.caller
1623- let lpAssetRecipientAddress = this
1624- let unstakeInv = invoke(staking, "unstakeINTERNAL", [lpAssetId, unstakeAmount, userAddress.bytes, lpAssetRecipientAddress.bytes], nil)
1625- if ((unstakeInv == unstakeInv))
1626- then {
1627- let $t05520955397 = getOneTknV2Internal(outAssetId, minOutAmount, [AttachedPayment(lpAssetId, unstakeAmount)], i.caller, i.originCaller, i.transactionId)
1628- let state = $t05520955397._1
1629- let totalAmount = $t05520955397._2
1630- $Tuple2(state, totalAmount)
1631- }
1632- else throw("Strict value is not equal to itself.")
1633+ let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1634+ let $t06069260756 = refreshKLpInternal(0, 0, 0)
1635+ let kLpUpdateActions = $t06069260756._1
1636+ let updatedKLp = $t06069260756._2
1637+ let actions = if ((kLp != updatedKLp))
1638+ then kLpUpdateActions
1639+ else throwErr("nothing to refresh")
1640+ $Tuple2(actions, toString(updatedKLp))
16331641 }
16341642 else throw("Strict value is not equal to itself.")
16351643 }
16371645
16381646
16391647 @Callable(i)
1640-func putOneTknV2WithBonusREADONLY (paymentAmountRaw,paymentAssetId) = {
1641- let $t05552555628 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "", true)
1642- let lpAmount = $t05552555628._1
1643- let state = $t05552555628._2
1644- let feeAmount = $t05552555628._3
1645- let bonus = $t05552555628._4
1646- $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1647- }
1648-
1649-
1650-
1651-@Callable(i)
1652-func putOneTknV2WithoutTakeFeeREADONLY (paymentAmountRaw,paymentAssetId) = {
1653- let $t05577655880 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "", false)
1654- let lpAmount = $t05577655880._1
1655- let state = $t05577655880._2
1656- let feeAmount = $t05577655880._3
1657- let bonus = $t05577655880._4
1658- $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1659- }
1660-
1661-
1662-
1663-@Callable(i)
1664-func activate (amtAsStr,prAsStr) = if ((toString(i.caller) != toString(fca)))
1665- then throw("denied")
1666- else $Tuple2([StringEntry(aa(), amtAsStr), StringEntry(pa(), prAsStr), StringEntry(amp(), toString(ampInitial))], "success")
1667-
1668-
1669-
1670-@Callable(i)
1671-func getPoolConfigWrapperREADONLY () = $Tuple2(nil, gpc())
1648+func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
16721649
16731650
16741651
16791656
16801657 @Callable(i)
16811658 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
1682- let pr = calcPrices(amAmt, prAmt, lpAmt)
1683- $Tuple2(nil, [toString(pr[0]), toString(pr[1]), toString(pr[2])])
1659+ let prices = calcPrices(amAmt, prAmt, lpAmt)
1660+ $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
16841661 }
16851662
16861663
16871664
16881665 @Callable(i)
1689-func fromX18WrapperREADONLY (val,resScaleMult) = $Tuple2(nil, f1(parseBigIntValue(val), resScaleMult))
1666+func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
16901667
16911668
16921669
16931670 @Callable(i)
1694-func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(t1(origVal, origScaleMult)))
1671+func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
16951672
16961673
16971674
16981675 @Callable(i)
1699-func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(cpbi(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
1676+func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
17001677
17011678
17021679
17031680 @Callable(i)
1704-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, ""))
1681+func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
17051682
17061683
17071684
17081685 @Callable(i)
1709-func estimateGetOperationWrapperREADONLY (txId58,pmtAsId,pmtLpAmt,usrAddr) = {
1710- let r = ego(txId58, pmtAsId, pmtLpAmt, addressFromStringValue(usrAddr))
1711- $Tuple2(nil, $Tuple10(r._1, r._2, r._3, r._4, r._5, r._6, r._7, toString(r._8), r._9, r._10))
1686+func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
1687+ let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
1688+ $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
17121689 }
17131690
17141691
17151692
17161693 @Callable(i)
1717-func changeAmp () = {
1718- let cfg = invoke(fca, "getChangeAmpConfigREADONLY", [toString(this)], nil)
1719- let $t05828958488 = match cfg {
1720- case list: List[Any] =>
1721- $Tuple3({
1722- let @ = list[0]
1723- if ($isInstanceOf(@, "Int"))
1724- then @
1725- else throw(($getType(@) + " couldn't be cast to Int"))
1726- }, {
1727- let @ = list[1]
1728- if ($isInstanceOf(@, "Int"))
1729- then @
1730- else throw(($getType(@) + " couldn't be cast to Int"))
1731- }, {
1732- let @ = list[2]
1733- if ($isInstanceOf(@, "Int"))
1734- then @
1735- else throw(($getType(@) + " couldn't be cast to Int"))
1736- })
1737- case _ =>
1738- throwErr("invalid entry type")
1694+func statsREADONLY () = {
1695+ let cfg = getPoolConfig()
1696+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1697+ let amtAssetId = cfg[idxAmtAssetId]
1698+ let priceAssetId = cfg[idxPriceAssetId]
1699+ let iAmtAssetId = cfg[idxIAmtAssetId]
1700+ let iPriceAssetId = cfg[idxIPriceAssetId]
1701+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1702+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1703+ let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1704+ let accAmtAssetBalance = getAccBalance(amtAssetId)
1705+ let accPriceAssetBalance = getAccBalance(priceAssetId)
1706+ let pricesList = if ((poolLPBalance == 0))
1707+ then [zeroBigInt, zeroBigInt, zeroBigInt]
1708+ else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
1709+ let curPrice = 0
1710+ let lpAmtAssetShare = fromX18(pricesList[1], scale8)
1711+ let lpPriceAssetShare = fromX18(pricesList[2], scale8)
1712+ let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
1713+ $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))
17391714 }
1740- let delay = $t05828958488._1
1741- let delta = $t05828958488._2
1742- let target = $t05828958488._3
1743- let curAmp = parseIntValue(getStringValue(amp()))
1744- let newAmpRaw = (curAmp + delta)
1745- let newAmp = if ((0 > delta))
1746- then if ((target > newAmpRaw))
1747- then target
1748- else newAmpRaw
1749- else if ((newAmpRaw > target))
1750- then target
1751- else newAmpRaw
1752- let lastCall = valueOrElse(getInteger(keyChangeAmpLastCall()), 0)
1753- let wait = (lastCall + delay)
1754- let checks = [if ((height > wait))
1755- then true
1756- else throwErr("try again in few blocks"), if ((curAmp != newAmp))
1757- then true
1758- else throwErr("already reached target")]
1759- if ((checks == checks))
1760- then [IntegerEntry(keyChangeAmpLastCall(), height), StringEntry(amp(), toString(newAmp)), StringEntry(keyAmpHistory(height), toString(newAmp))]
1761- else throw("Strict value is not equal to itself.")
1715+
1716+
1717+
1718+@Callable(i)
1719+func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
1720+ let cfg = getPoolConfig()
1721+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1722+ let amAssetIdStr = cfg[idxAmtAssetId]
1723+ let amAssetId = fromBase58String(amAssetIdStr)
1724+ let prAssetIdStr = cfg[idxPriceAssetId]
1725+ let prAssetId = fromBase58String(prAssetIdStr)
1726+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1727+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1728+ let poolStatus = cfg[idxPoolStatus]
1729+ let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1730+ let accAmtAssetBalance = getAccBalance(amAssetIdStr)
1731+ let accPriceAssetBalance = getAccBalance(prAssetIdStr)
1732+ let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
1733+ let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
1734+ let curPriceX18 = if ((poolLPBalance == 0))
1735+ then zeroBigInt
1736+ else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
1737+ let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
1738+ let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
1739+ let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
1740+ let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
1741+ let calcLpAmt = estPut._1
1742+ let curPriceCalc = estPut._3
1743+ let amBalance = estPut._4
1744+ let prBalance = estPut._5
1745+ let lpEmission = estPut._6
1746+ $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))
1747+ }
1748+
1749+
1750+
1751+@Callable(i)
1752+func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
1753+ let cfg = getPoolConfig()
1754+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1755+ let amAssetIdStr = cfg[idxAmtAssetId]
1756+ let amAssetId = fromBase58String(amAssetIdStr)
1757+ let prAssetIdStr = cfg[idxPriceAssetId]
1758+ let prAssetId = fromBase58String(prAssetIdStr)
1759+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1760+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1761+ let poolStatus = cfg[idxPoolStatus]
1762+ let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1763+ let amBalanceRaw = getAccBalance(amAssetIdStr)
1764+ let prBalanceRaw = getAccBalance(prAssetIdStr)
1765+ let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
1766+ let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
1767+ let curPriceX18 = if ((poolLPBalance == 0))
1768+ then zeroBigInt
1769+ else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
1770+ let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
1771+ let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
1772+ let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
1773+ let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
1774+ let calcLpAmt = estPut._1
1775+ let curPriceCalc = estPut._3
1776+ let amBalance = estPut._4
1777+ let prBalance = estPut._5
1778+ let lpEmission = estPut._6
1779+ $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))
1780+ }
1781+
1782+
1783+
1784+@Callable(i)
1785+func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
1786+ let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
1787+ let outAmAmt = res._1
1788+ let outPrAmt = res._2
1789+ let amBalance = res._5
1790+ let prBalance = res._6
1791+ let lpEmission = res._7
1792+ let curPrice = res._8
1793+ let poolStatus = parseIntValue(res._9)
1794+ $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))
17621795 }
17631796
17641797
17651798 @Verifier(tx)
17661799 func verify () = {
1767- let targetPublicKey = match m() {
1800+ let targetPublicKey = match managerPublicKeyOrUnit() {
17681801 case pk: ByteVector =>
17691802 pk
17701803 case _: Unit =>
17741807 }
17751808 match tx {
17761809 case order: Order =>
1777- let matcherPub = mp()
1778- let $t05940059517 = if (skipOrderValidation())
1810+ let matcherPub = getMatcherPubOrFail()
1811+ let $t06941869646 = if (skipOrderValidation())
17791812 then $Tuple2(true, "")
17801813 else validateMatcherOrderAllowed(order)
1781- let orderValid = $t05940059517._1
1782- let orderValidInfo = $t05940059517._2
1783- let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
1814+ let orderValid = $t06941869646._1
1815+ let orderValidInfo = $t06941869646._2
17841816 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
1785- if (if (if (orderValid)
1786- then senderValid
1787- else false)
1817+ if (if (orderValid)
17881818 then matcherValid
17891819 else false)
17901820 then true
1791- else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
1821+ else throwOrderError(orderValid, orderValidInfo, matcherValid)
17921822 case s: SetScriptTransaction =>
17931823 if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
17941824 then true
17951825 else {
17961826 let newHash = blake2b256(value(s.script))
1797- let allowedHash = fromBase64String(value(getString(fca, keyAllowedLpStableScriptHash())))
1827+ let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
17981828 let currentHash = scriptHash(this)
17991829 if ((allowedHash == newHash))
18001830 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
10185
10286
87+func swapContract () = "%s__swapContract"
88+
89+
10390 func fc () = "%s__factoryContract"
10491
10592
106-func mpk () = "%s__managerPublicKey"
93+func keyManagerPublicKey () = "%s__managerPublicKey"
10794
10895
109-func pmpk () = "%s__pendingManagerPublicKey"
96+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
177-func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
174+func throwOrderError (orderValid,orderValidInfo,matcherValid) = throw((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " matcherValid=") + toString(matcherValid)))
178175
179176
180-func strf (addr,key) = valueOrErrorMessage(getString(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
177+func addressFromStringOrThis (addressString) = match addressFromString(addressString) {
178+ case a: Address =>
179+ a
180+ case _ =>
181+ this
182+}
181183
182184
183-func intf (addr,key) = valueOrErrorMessage(getInteger(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
185+func getManagerVaultAddressOrThis () = {
186+ let factoryAddress = match getString(fc()) {
187+ case fca: String =>
188+ addressFromStringOrThis(fca)
189+ case _ =>
190+ this
191+ }
192+ match getString(factoryAddress, keyManagerVaultAddress()) {
193+ case s: String =>
194+ addressFromStringOrThis(s)
195+ case _ =>
196+ this
197+ }
198+ }
184199
185200
186-func throwErr (msg) = throw(makeString(["lp_stable.ride:", msg], " "))
201+func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
187202
188203
189-func fmtErr (msg) = makeString(["lp_stable.ride:", msg], " ")
204+func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
190205
191206
192-let fca = addressFromStringValue(strf(this, fc()))
207+func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
208+
209+
210+func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
211+
212+
213+let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
214+
215+let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
193216
194217 let inFee = {
195- let @ = invoke(fca, "getInFeeREADONLY", [toString(this)], nil)
218+ let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
196219 if ($isInstanceOf(@, "Int"))
197220 then @
198221 else throw(($getType(@) + " couldn't be cast to Int"))
199222 }
200223
201224 let outFee = {
202- let @ = invoke(fca, "getOutFeeREADONLY", [toString(this)], nil)
225+ let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
203226 if ($isInstanceOf(@, "Int"))
204227 then @
205228 else throw(($getType(@) + " couldn't be cast to Int"))
206229 }
207230
208-let A = strf(this, amp())
209-
210-func igs () = valueOrElse(getBoolean(fca, aps()), false)
231+func keyAddressWhitelisted (address) = makeString(["%s%s", "whitelisted", toString(address)], SEP)
211232
212233
213-func mp () = fromBase58String(strf(fca, mtpk()))
234+func isAddressWhitelisted (address) = valueOrElse(getBoolean(factoryContract, keyAddressWhitelisted(address)), false)
214235
215236
216-let feeCollectorAddress = addressFromStringValue(strf(fca, keyFeeCollectorAddress()))
237+func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
217238
218-func gpc () = {
219- let amtAs = strf(this, aa())
220- let priceAs = strf(this, pa())
221- let iPriceAs = intf(fca, mba(priceAs))
222- let iAmtAs = intf(fca, mba(amtAs))
223- split(strf(fca, pc(toString(iAmtAs), toString(iPriceAs))), SEP)
239+
240+func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
241+
242+
243+func getPoolConfig () = {
244+ let amtAsset = getStringOrFail(this, aa())
245+ let priceAsset = getStringOrFail(this, pa())
246+ let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
247+ let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
248+ split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
224249 }
225250
226251
227252 func parseAssetId (input) = if ((input == wavesString))
228253 then unit
229254 else fromBase58String(input)
230255
231256
232257 func assetIdToString (input) = if ((input == unit))
233258 then wavesString
234259 else toBase58String(value(input))
235260
236261
237-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]))
262+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]))
238263
239264
240-let poolConfigParsed = parsePoolConfig(gpc())
265+let poolConfigParsed = parsePoolConfig(getPoolConfig())
241266
242-let $t080878273 = poolConfigParsed
267+let $t097029868 = poolConfigParsed
243268
244-let cfgPoolAddress = $t080878273._1
269+let cfgPoolAddress = $t097029868._1
245270
246-let cfgPoolStatus = $t080878273._2
271+let cfgPoolStatus = $t097029868._2
247272
248-let cfgLpAssetId = $t080878273._3
273+let cfgLpAssetId = $t097029868._3
249274
250-let cfgAmountAssetId = $t080878273._4
275+let cfgAmountAssetId = $t097029868._4
251276
252-let cfgPriceAssetId = $t080878273._5
277+let cfgPriceAssetId = $t097029868._5
253278
254-let cfgAmountAssetDecimals = $t080878273._6
279+let cfgAmountAssetDecimals = $t097029868._6
255280
256-let cfgPriceAssetDecimals = $t080878273._7
281+let cfgPriceAssetDecimals = $t097029868._7
257282
258-func gfc () = split(strf(fca, fcfg()), SEP)
283+func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
259284
260285
261-let factoryConfig = gfc()
286+let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
262287
263-let stakingContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactStakCntr]), "Invalid staking contract address")
288+let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
264289
265-let slipageContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactSlippCntr]), "Invalid slipage contract address")
266-
267-let gwxContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactGwxRewCntr]), "Invalid gwx contract address")
268-
269-let restContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactoryRestCntr]), "Invalid gwx contract address")
270-
271-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)
290+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)
272291
273292
274293 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)
275294
276295
277-func getAccBalance (assetId) = if ((assetId == "WAVES"))
278- then wavesBalance(this).available
279- else assetBalance(this, fromBase58String(assetId))
280-
281-
282-func cpbi (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
283-
284-
285-func cpbir (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
286-
287-
288-func vad (A1,A2,slippage) = {
289- let diff = fraction((A1 - A2), scale8BigInt, A2)
290- let pass = ((slippage - abs(diff)) > zeroBigInt)
291- if (!(pass))
292- then throw(("Big slpg: " + toString(diff)))
293- else $Tuple2(pass, min([A1, A2]))
296+func getAccBalance (assetId) = {
297+ let balanceOnPool = if ((assetId == "WAVES"))
298+ then wavesBalance(this).available
299+ else assetBalance(this, fromBase58String(assetId))
300+ let totalBalance = ((balanceOnPool + getAdditionalBalanceOrZero(assetId)) - getStakingAssetBalanceOrZero(assetId))
301+ max([0, totalBalance])
294302 }
295303
296304
297-func vd (D1,D0,slpg) = {
298- let diff = fraction(D0, scale8BigInt, D1)
299- let fail = (slpg > diff)
300- if (if (fail)
301- then true
302- else (D0 > D1))
303- then throw(((((((toString(D0) + " ") + toString(D1)) + " ") + toString(diff)) + " ") + toString(slpg)))
304- else fail
305+func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
306+
307+
308+func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
309+
310+
311+func getRate (proxy) = {
312+ let inv = invoke(proxy, "getRate", nil, nil)
313+ if ((inv == inv))
314+ then match inv {
315+ case r: Int =>
316+ r
317+ case _ =>
318+ throwErr("proxy.getRate() unexpected value")
319+ }
320+ else throw("Strict value is not equal to itself.")
305321 }
306322
307323
308-func pcp (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
309- let amtAsAmtX18 = t1(amAmt, amAssetDcm)
310- let prAsAmtX18 = t1(prAmt, prAssetDcm)
311- cpbi(prAsAmtX18, amtAsAmtX18)
324+func deposit (assetId,amount,stakingAssetId,proxy) = {
325+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
326+ if ((currentAdditionalBalance == currentAdditionalBalance))
327+ then {
328+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
329+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
330+ then {
331+ let asset = parseAssetId(assetId)
332+ if ((amount > 0))
333+ then {
334+ let depositInvoke = invoke(proxy, "deposit", nil, [AttachedPayment(asset, amount)])
335+ if ((depositInvoke == depositInvoke))
336+ then match depositInvoke {
337+ case receivedStakingAsset: Int =>
338+ let newAdditionalBalance = (currentAdditionalBalance + amount)
339+ let newStakingAssetBalance = (currentStakingAssetBalance + receivedStakingAsset)
340+[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance)]
341+ case _ =>
342+ nil
343+ }
344+ else throw("Strict value is not equal to itself.")
345+ }
346+ else nil
347+ }
348+ else throw("Strict value is not equal to itself.")
349+ }
350+ else throw("Strict value is not equal to itself.")
351+ }
352+
353+
354+func withdraw (assetId,amount,stakingAssetId,proxy,proxyRateMul,profitAddress) = {
355+ let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
356+ if ((currentAdditionalBalance == currentAdditionalBalance))
357+ then {
358+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
359+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
360+ then {
361+ let currentProxyRate = getRate(proxy)
362+ if ((currentProxyRate == currentProxyRate))
363+ then {
364+ let oldRate = fraction(proxyRateMul, currentAdditionalBalance, currentStakingAssetBalance)
365+ let stakingAsset = parseAssetId(stakingAssetId)
366+ let oldSendStakingAmount = fraction(proxyRateMul, amount, oldRate)
367+ let sendStakingAssetAmount = fraction(proxyRateMul, amount, currentProxyRate)
368+ let profitAmount = max([0, (oldSendStakingAmount - sendStakingAssetAmount)])
369+ if ((sendStakingAssetAmount > 0))
370+ then {
371+ let withdrawInvoke = invoke(proxy, "withdraw", nil, [AttachedPayment(stakingAsset, sendStakingAssetAmount)])
372+ if ((withdrawInvoke == withdrawInvoke))
373+ then match withdrawInvoke {
374+ case receivedAssets: Int =>
375+ let newAdditionalBalance = (currentAdditionalBalance - receivedAssets)
376+ let newStakingAssetBalance = ((currentStakingAssetBalance - sendStakingAssetAmount) - profitAmount)
377+[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance), ScriptTransfer(profitAddress, profitAmount, parseAssetId(stakingAssetId))]
378+ case _ =>
379+ nil
380+ }
381+ else throw("Strict value is not equal to itself.")
382+ }
383+ else nil
384+ }
385+ else throw("Strict value is not equal to itself.")
386+ }
387+ else throw("Strict value is not equal to itself.")
388+ }
389+ else throw("Strict value is not equal to itself.")
390+ }
391+
392+
393+func getLeaseProxyConfig (assetId) = match invoke(factoryContract, "getPoolLeaseConfigREADONLY", [toString(this), assetId], nil) {
394+ case a: (Boolean, Int, Int, String, String, Int, String) =>
395+ a
396+ case _ =>
397+ throwErr((("[" + assetId) + "] getLeaseProxyConfig() error"))
398+}
399+
400+
401+func rebalanceInternal (targetRatio,assetId,stakingAssetId,minBalance,proxy,proxyRateMul,profitAddress) = {
402+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
403+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
404+ then {
405+ let currentAdditionalBalance = if ((currentStakingAssetBalance != 0))
406+ then getAdditionalBalanceOrZero(assetId)
407+ else 0
408+ if ((currentAdditionalBalance == currentAdditionalBalance))
409+ then {
410+ let leasableTotalBalance = max([0, (getAccBalance(assetId) - minBalance)])
411+ let targetAdditionalBalance = fraction(targetRatio, leasableTotalBalance, 100)
412+ let diff = (currentAdditionalBalance - targetAdditionalBalance)
413+ if ((diff == 0))
414+ then nil
415+ else if ((0 > diff))
416+ then {
417+ let sendAssetAmount = -(diff)
418+ deposit(assetId, sendAssetAmount, stakingAssetId, proxy)
419+ }
420+ else {
421+ let getAssetAmount = diff
422+ withdraw(assetId, getAssetAmount, stakingAssetId, proxy, proxyRateMul, profitAddress)
423+ }
424+ }
425+ else throw("Strict value is not equal to itself.")
426+ }
427+ else throw("Strict value is not equal to itself.")
428+ }
429+
430+
431+func rebalanceAsset (assetId) = {
432+ let $t01615316289 = getLeaseProxyConfig(assetId)
433+ let isLeasable = $t01615316289._1
434+ let leasedRatio = $t01615316289._2
435+ let minBalance = $t01615316289._3
436+ let proxyAddress = $t01615316289._4
437+ let proxyAssetId = $t01615316289._5
438+ let proxyRateMul = $t01615316289._6
439+ let stakingProfitAddress = $t01615316289._7
440+ if (isLeasable)
441+ then rebalanceInternal(leasedRatio, assetId, proxyAssetId, minBalance, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
442+ else nil
443+ }
444+
445+
446+func withdrawAndRebalanceAsset (assetId,getAmount) = {
447+ let $t01668816824 = getLeaseProxyConfig(assetId)
448+ let isLeasable = $t01668816824._1
449+ let leasedRatio = $t01668816824._2
450+ let minBalance = $t01668816824._3
451+ let proxyAddress = $t01668816824._4
452+ let proxyAssetId = $t01668816824._5
453+ let proxyRateMul = $t01668816824._6
454+ let stakingProfitAddress = $t01668816824._7
455+ if (isLeasable)
456+ then {
457+ let currentStakingAssetBalance = getStakingAssetBalanceOrZero(proxyAssetId)
458+ if ((currentStakingAssetBalance == currentStakingAssetBalance))
459+ then {
460+ let currentAdditionalBalance = if ((currentStakingAssetBalance != 0))
461+ then getAdditionalBalanceOrZero(assetId)
462+ else 0
463+ if ((currentAdditionalBalance == currentAdditionalBalance))
464+ then {
465+ let newTotalLeasableBalance = max([0, ((getAccBalance(assetId) - getAmount) - minBalance)])
466+ if ((newTotalLeasableBalance == newTotalLeasableBalance))
467+ then {
468+ let newAdditionalBalance = fraction(leasedRatio, newTotalLeasableBalance, 100)
469+ if ((newAdditionalBalance == newAdditionalBalance))
470+ then {
471+ let withdrawAmount = (currentAdditionalBalance - newAdditionalBalance)
472+ if ((withdrawAmount == withdrawAmount))
473+ then if ((withdrawAmount == 0))
474+ then nil
475+ else if ((0 > withdrawAmount))
476+ then deposit(assetId, -(withdrawAmount), proxyAssetId, addressFromStringValue(proxyAddress))
477+ else withdraw(assetId, withdrawAmount, proxyAssetId, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
478+ else throw("Strict value is not equal to itself.")
479+ }
480+ else throw("Strict value is not equal to itself.")
481+ }
482+ else throw("Strict value is not equal to itself.")
483+ }
484+ else throw("Strict value is not equal to itself.")
485+ }
486+ else throw("Strict value is not equal to itself.")
487+ }
488+ else nil
489+ }
490+
491+
492+func withdrawAndRebalanceAll (amountAssetOutAmount,priceAssetOutAmount) = {
493+ let AmAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, aa()), amountAssetOutAmount)
494+ let PrAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, pa()), priceAssetOutAmount)
495+ (AmAmtWithdrawState ++ PrAmtWithdrawState)
496+ }
497+
498+
499+func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
500+ let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
501+ let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
502+ calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
312503 }
313504
314505
315506 func calcPrices (amAmt,prAmt,lpAmt) = {
316- let amtAsDcm = cfgAmountAssetDecimals
317- let prAsDcm = cfgPriceAssetDecimals
318- let priceX18 = pcp(amtAsDcm, prAsDcm, amAmt, prAmt)
319- let amAmtX18 = t1(amAmt, amtAsDcm)
320- let prAmtX18 = t1(prAmt, prAsDcm)
321- let lpAmtX18 = t1(lpAmt, scale8)
322- let lpPrInAmAsX18 = cpbi(amAmtX18, lpAmtX18)
323- let lpPrInPrAsX18 = cpbi(prAmtX18, lpAmtX18)
324-[priceX18, lpPrInAmAsX18, lpPrInPrAsX18]
507+ let cfg = getPoolConfig()
508+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
509+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
510+ let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
511+ let amAmtX18 = toX18(amAmt, amtAssetDcm)
512+ let prAmtX18 = toX18(prAmt, priceAssetDcm)
513+ let lpAmtX18 = toX18(lpAmt, scale8)
514+ let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
515+ let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
516+[priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
325517 }
326518
327519
328520 func calculatePrices (amAmt,prAmt,lpAmt) = {
329- let p = calcPrices(amAmt, prAmt, lpAmt)
330-[f1(p[0], scale8), f1(p[1], scale8), f1(p[2], scale8)]
521+ let prices = calcPrices(amAmt, prAmt, lpAmt)
522+[fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
523+ }
524+
525+
526+func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
527+ let cfg = getPoolConfig()
528+ let lpAssetId = cfg[idxPoolLPAssetId]
529+ let amAssetId = cfg[idxAmtAssetId]
530+ let prAssetId = cfg[idxPriceAssetId]
531+ let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
532+ let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
533+ let poolStatus = cfg[idxPoolStatus]
534+ let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
535+ if ((lpAssetId != pmtAssetId))
536+ then throw("Invalid asset passed.")
537+ else {
538+ let amBalance = getAccBalance(amAssetId)
539+ let amBalanceX18 = toX18(amBalance, amAssetDcm)
540+ let prBalance = getAccBalance(prAssetId)
541+ let prBalanceX18 = toX18(prBalance, prAssetDcm)
542+ let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
543+ let curPrice = fromX18(curPriceX18, scale8)
544+ let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
545+ let lpEmissionX18 = toX18(lpEmission, scale8)
546+ let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
547+ let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
548+ let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
549+ let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
550+ let state = if ((txId58 == ""))
551+ then nil
552+ else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
553+ then unit
554+ else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
555+ then unit
556+ 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)]
557+ $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
558+ }
559+ }
560+
561+
562+func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
563+ let cfg = getPoolConfig()
564+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
565+ let amAssetIdStr = cfg[idxAmtAssetId]
566+ let prAssetIdStr = cfg[idxPriceAssetId]
567+ let iAmtAssetId = cfg[idxIAmtAssetId]
568+ let iPriceAssetId = cfg[idxIPriceAssetId]
569+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
570+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
571+ let poolStatus = cfg[idxPoolStatus]
572+ let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
573+ let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
574+ let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
575+ if (if ((amAssetIdStr != inAmAssetIdStr))
576+ then true
577+ else (prAssetIdStr != inPrAssetIdStr))
578+ then throw("Invalid amt or price asset passed.")
579+ else {
580+ let amBalance = if (isEvaluate)
581+ then getAccBalance(amAssetIdStr)
582+ else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
583+ let prBalance = if (isEvaluate)
584+ then getAccBalance(prAssetIdStr)
585+ else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
586+ let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
587+ let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
588+ let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
589+ let amBalanceX18 = toX18(amBalance, amtAssetDcm)
590+ let prBalanceX18 = toX18(prBalance, priceAssetDcm)
591+ let res = if ((lpEmission == 0))
592+ then {
593+ let curPriceX18 = zeroBigInt
594+ let slippageX18 = zeroBigInt
595+ let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
596+ $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
597+ }
598+ else {
599+ let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
600+ let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
601+ let slippageToleranceX18 = toX18(slippageTolerance, scale8)
602+ if (if ((curPriceX18 != zeroBigInt))
603+ then (slippageX18 > slippageToleranceX18)
604+ else false)
605+ then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
606+ else {
607+ let lpEmissionX18 = toX18(lpEmission, scale8)
608+ let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
609+ let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
610+ let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
611+ then $Tuple2(amViaPrX18, inPrAssetAmtX18)
612+ else $Tuple2(inAmAssetAmtX18, prViaAmX18)
613+ let expAmtAssetAmtX18 = expectedAmts._1
614+ let expPriceAssetAmtX18 = expectedAmts._2
615+ let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
616+ $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
617+ }
618+ }
619+ let calcLpAmt = res._1
620+ let calcAmAssetPmt = res._2
621+ let calcPrAssetPmt = res._3
622+ let curPrice = fromX18(res._4, scale8)
623+ let slippageCalc = fromX18(res._5, scale8)
624+ if ((0 >= calcLpAmt))
625+ then throw("Invalid calculations. LP calculated is less than zero.")
626+ else {
627+ let emitLpAmt = if (!(emitLp))
628+ then 0
629+ else calcLpAmt
630+ let amDiff = (inAmAssetAmt - calcAmAssetPmt)
631+ let prDiff = (inPrAssetAmt - calcPrAssetPmt)
632+ 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))]
633+ $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
634+ }
635+ }
636+ }
637+
638+
639+func calcKLp (amountBalance,priceBalance,lpEmission) = {
640+ let amountBalanceX18 = toX18BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals))
641+ let priceBalanceX18 = toX18BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))
642+ let updatedKLp = fraction(pow((amountBalanceX18 * priceBalanceX18), 0, toBigInt(5), 1, 18, DOWN), big1, lpEmission)
643+ if ((lpEmission == big0))
644+ then big0
645+ else updatedKLp
646+ }
647+
648+
649+func calcCurrentKLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
650+ let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
651+ let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
652+ let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
653+ let currentKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
654+ currentKLp
655+ }
656+
657+
658+func refreshKLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
659+ let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
660+ let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
661+ let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
662+ let updatedKLp = calcKLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
663+ let actions = [IntegerEntry(keyKLpRefreshedHeight, height), StringEntry(keyKLp, toString(updatedKLp))]
664+ $Tuple2(actions, updatedKLp)
665+ }
666+
667+
668+func skipOrderValidation () = valueOrElse(getBoolean(factoryContract, keySkipOrderValidation(toString(this))), false)
669+
670+
671+func validateUpdatedKLp (oldKLp,updatedKLp) = if ((updatedKLp >= oldKLp))
672+ then true
673+ else throwErr(makeString(["updated KLp lower than current KLp", toString(oldKLp), toString(updatedKLp)], " "))
674+
675+
676+func validateMatcherOrderAllowed (order) = {
677+ let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
678+ let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
679+ let amountAssetAmount = order.amount
680+ let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
681+ let $t02945029662 = if ((order.orderType == Buy))
682+ then $Tuple2(amountAssetAmount, -(priceAssetAmount))
683+ else $Tuple2(-(amountAssetAmount), priceAssetAmount)
684+ let amountAssetBalanceDelta = $t02945029662._1
685+ let priceAssetBalanceDelta = $t02945029662._2
686+ if (if (if (isGlobalShutdown())
687+ then true
688+ else (cfgPoolStatus == PoolMatcherDisabled))
689+ then true
690+ else (cfgPoolStatus == PoolShutdown))
691+ then throw("Exchange operations disabled")
692+ else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
693+ then true
694+ else (order.assetPair.priceAsset != cfgPriceAssetId))
695+ then throw("Wrong order assets.")
696+ else {
697+ let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
698+ let $t03010230202 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
699+ let unusedActions = $t03010230202._1
700+ let kLpNew = $t03010230202._2
701+ let isOrderValid = (kLpNew >= kLp)
702+ let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
703+ $Tuple2(isOrderValid, info)
704+ }
705+ }
706+
707+
708+func commonGet (i) = if ((size(i.payments) != 1))
709+ then throw("exactly 1 payment is expected")
710+ else {
711+ let pmt = value(i.payments[0])
712+ let pmtAssetId = value(pmt.assetId)
713+ let pmtAmt = pmt.amount
714+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
715+ let outAmAmt = res._1
716+ let outPrAmt = res._2
717+ let state = res._10
718+ let isGetDisabled = if (!(isAddressWhitelisted(i.caller)))
719+ then if (isGlobalShutdown())
720+ then true
721+ else (cfgPoolStatus == PoolShutdown)
722+ else false
723+ if (isGetDisabled)
724+ then throw(("Get operation is blocked by admin. Status = " + toString(cfgPoolStatus)))
725+ else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
726+ }
727+
728+
729+func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
730+ then throw("exactly 2 payments are expected")
731+ else {
732+ let amAssetPmt = value(i.payments[0])
733+ let prAssetPmt = value(i.payments[1])
734+ let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
735+ let isPutDisabled = if (!(isAddressWhitelisted(i.caller)))
736+ then if (if (isGlobalShutdown())
737+ then true
738+ else (cfgPoolStatus == PoolPutDisabled))
739+ then true
740+ else (cfgPoolStatus == PoolShutdown)
741+ else false
742+ if (isPutDisabled)
743+ then throw(("Put operation is blocked by admin. Status = " + toString(cfgPoolStatus)))
744+ else estPut
745+ }
746+
747+
748+func emit (amount) = {
749+ let emitInv = invoke(factoryContract, "emit", [amount], nil)
750+ if ((emitInv == emitInv))
751+ then {
752+ let emitInvLegacy = match emitInv {
753+ case legacyFactoryContract: Address =>
754+ invoke(legacyFactoryContract, "emit", [amount], nil)
755+ case _ =>
756+ unit
757+ }
758+ if ((emitInvLegacy == emitInvLegacy))
759+ then amount
760+ else throw("Strict value is not equal to itself.")
761+ }
762+ else throw("Strict value is not equal to itself.")
331763 }
332764
333765
334766 func takeFee (amount,fee) = {
335767 let feeAmount = if ((fee == 0))
336768 then 0
337769 else fraction(amount, fee, scale8)
338770 $Tuple2((amount - feeAmount), feeAmount)
339771 }
340772
341773
342-func getD (xp) = {
343- let xp0 = xp[0]
344- let xp1 = xp[1]
345- let s = (xp0 + xp1)
346- if ((s == big0))
347- then big0
348- else {
349- let a = parseIntValue(A)
350- let ann = (a * 2)
351- let p = fraction(xp0, xp1, big1)
352- let xp0_xp1_n_n = fraction(p, big4, big1)
353- let ann_s = fraction(toBigInt(ann), s, big1)
354- let ann_1 = toBigInt((ann - 1))
355- func calcDNext (d) = {
356- let dd = fraction(d, d, big1)
357- let ddd = fraction(dd, d, big1)
358- let dp = fraction(ddd, big1, xp0_xp1_n_n)
359- fraction((ann_s + fraction(dp, big2, big1)), d, (fraction(ann_1, d, big1) + fraction(big3, dp, big1)))
774+func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
775+ let isEval = (txId == unit)
776+ let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
777+ let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
778+ let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
779+ then true
780+ else if ((paymentAssetId == cfgPriceAssetId))
781+ then false
782+ else throwErr("invalid asset")
783+ let $t03338833681 = if (isEval)
784+ then $Tuple2(amountBalanceRaw, priceBalanceRaw)
785+ else if (paymentInAmountAsset)
786+ then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
787+ else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
788+ let amountBalanceOld = $t03338833681._1
789+ let priceBalanceOld = $t03338833681._2
790+ let $t03368533834 = if (paymentInAmountAsset)
791+ then $Tuple2(paymentAmountRaw, 0)
792+ else $Tuple2(0, paymentAmountRaw)
793+ let amountAssetAmountRaw = $t03368533834._1
794+ let priceAssetAmountRaw = $t03368533834._2
795+ let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
796+ let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
797+ let $t03396634030 = takeFee(paymentAmountRaw, inFee)
798+ let paymentAmount = $t03396634030._1
799+ let feeAmount = $t03396634030._2
800+ let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
801+ let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
802+ let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
803+ let priceNew = fromX18(priceNewX18, scale8)
804+ let paymentBalance = if (paymentInAmountAsset)
805+ then amountBalanceOld
806+ else priceBalanceOld
807+ let paymentBalanceBigInt = toBigInt(paymentBalance)
808+ let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
809+ let chechSupply = if ((supplyBigInt > big0))
810+ then true
811+ else throwErr("initial deposit requires all coins")
812+ if ((chechSupply == chechSupply))
813+ then {
814+ let depositBigInt = toBigInt(paymentAmount)
815+ let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
816+ let commonState = if (isEval)
817+ then nil
818+ 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))]
819+ let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
820+ let priceOld = fromX18(priceOldX18, scale8)
821+ let loss = {
822+ let $t03571135878 = if (paymentInAmountAsset)
823+ then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
824+ else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
825+ let amount = $t03571135878._1
826+ let balance = $t03571135878._2
827+ let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
828+ fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
360829 }
361-
362- func calc (acc,i) = if (acc._2)
363- then acc
364- else {
365- let d = acc._1
366- let dNext = calcDNext(d)
367- let dDiffRaw = (dNext - value(d))
368- let dDiff = if ((big0 > dDiffRaw))
369- then -(dDiffRaw)
370- else dDiffRaw
371- if ((big1 >= dDiff))
372- then $Tuple2(dNext, true)
373- else $Tuple2(dNext, false)
374- }
375-
376- let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
377- let $t01277812826 = {
378- let $l = arr
379- let $s = size($l)
380- let $acc0 = $Tuple2(s, false)
381- func $f0_1 ($a,$i) = if (($i >= $s))
382- then $a
383- else calc($a, $l[$i])
384-
385- func $f0_2 ($a,$i) = if (($i >= $s))
386- then $a
387- else throw("List size exceeds 17")
388-
389- $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)
390- }
391- let d = $t01277812826._1
392- let found = $t01277812826._2
393- if (found)
394- then d
395- else throw(("D calculation error, D = " + toString(d)))
396- }
397- }
398-
399-
400-func ego (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
401- let lpId = cfgLpAssetId
402- let amId = toBase58String(value(cfgAmountAssetId))
403- let prId = toBase58String(value(cfgPriceAssetId))
404- let amDcm = cfgAmountAssetDecimals
405- let prDcm = cfgPriceAssetDecimals
406- let sts = toString(cfgPoolStatus)
407- let lpEmiss = valueOrErrorMessage(assetInfo(lpId), "Wrong LP id").quantity
408- if ((toBase58String(lpId) != pmtAssetId))
409- then throw("Wrong pmt asset")
410- else {
411- let amBalance = getAccBalance(amId)
412- let amBalanceX18 = t1(amBalance, amDcm)
413- let prBalance = getAccBalance(prId)
414- let prBalanceX18 = t1(prBalance, prDcm)
415- let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
416- let curPrice = f1(curPriceX18, scale8)
417- let pmtLpAmtX18 = t1(pmtLpAmt, scale8)
418- let lpEmissX18 = t1(lpEmiss, scale8)
419- let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissX18)
420- let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissX18)
421- let outAmAmt = fromX18Round(outAmAmtX18, amDcm, FLOOR)
422- let outPrAmt = fromX18Round(outPrAmtX18, prDcm, FLOOR)
423- let state = if ((txId58 == ""))
424- then nil
425- else [ScriptTransfer(userAddress, outAmAmt, if ((amId == "WAVES"))
426- then unit
427- else fromBase58String(amId)), ScriptTransfer(userAddress, outPrAmt, if ((prId == "WAVES"))
428- then unit
429- 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)]
430- $Tuple10(outAmAmt, outPrAmt, amId, prId, amBalance, prBalance, lpEmiss, curPriceX18, sts, state)
431- }
432- }
433-
434-
435-func epo (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEval,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
436- let lpId = cfgLpAssetId
437- let amIdStr = toBase58String(value(cfgAmountAssetId))
438- let prIdStr = toBase58String(value(cfgPriceAssetId))
439- let amtDcm = cfgAmountAssetDecimals
440- let priceDcm = cfgPriceAssetDecimals
441- let sts = toString(cfgPoolStatus)
442- let lpEm = valueOrErrorMessage(assetInfo(lpId), "Wr lp as").quantity
443- let amBalance = if (isEval)
444- then getAccBalance(amIdStr)
445- else if (if (isOneAsset)
446- then (pmtId == amIdStr)
447- else false)
448- then (getAccBalance(amIdStr) - pmtAmt)
449- else if (isOneAsset)
450- then getAccBalance(amIdStr)
451- else (getAccBalance(amIdStr) - inAmAmt)
452- let prBalance = if (isEval)
453- then getAccBalance(prIdStr)
454- else if (if (isOneAsset)
455- then (pmtId == prIdStr)
456- else false)
457- then (getAccBalance(prIdStr) - pmtAmt)
458- else if (isOneAsset)
459- then getAccBalance(prIdStr)
460- else (getAccBalance(prIdStr) - inPrAmt)
461- let inAmAssetAmtX18 = t1(inAmAmt, amtDcm)
462- let inPrAssetAmtX18 = t1(inPrAmt, priceDcm)
463- let userPriceX18 = cpbi(inPrAssetAmtX18, inAmAssetAmtX18)
464- let amBalanceX18 = t1(amBalance, amtDcm)
465- let prBalanceX18 = t1(prBalance, priceDcm)
466- let D0 = getD([amBalanceX18, prBalanceX18])
467- let r = if ((lpEm == 0))
468- then {
469- let D1 = getD([(amBalanceX18 + inAmAssetAmtX18), (prBalanceX18 + inPrAssetAmtX18)])
470- let checkD = if ((D1 > D0))
471- then true
472- else throw("D1 should be greater than D0")
473- if ((checkD == checkD))
474- then {
475- let curPriceX18 = zeroBigInt
476- let slippageX18 = zeroBigInt
477- let lpAmtX18 = D1
478- $Tuple5(f1(lpAmtX18, scale8), f1(inAmAssetAmtX18, amtDcm), f1(inPrAssetAmtX18, priceDcm), cpbi((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
479- }
480- else throw("Strict value is not equal to itself.")
481- }
482- else {
483- let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
484- let slippageRealX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
485- let slippageX18 = t1(slippage, scale8)
486- if (if (if (validateSlippage)
487- then (curPriceX18 != zeroBigInt)
488- else false)
489- then (slippageRealX18 > slippageX18)
490- else false)
491- then throw(((("Price slippage " + toString(slippageRealX18)) + " > ") + toString(slippageX18)))
492- else {
493- let lpEmissionX18 = t1(lpEm, scale8)
494- let prViaAmX18 = fraction(inAmAssetAmtX18, cpbir(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
495- let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, cpbir(prBalanceX18, amBalanceX18, FLOOR), CEILING)
496- let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
497- then $Tuple2(amViaPrX18, inPrAssetAmtX18)
498- else $Tuple2(inAmAssetAmtX18, prViaAmX18)
499- let expAmtAssetAmtX18 = expectedAmts._1
500- let expPriceAssetAmtX18 = expectedAmts._2
501- let D1 = getD([(amBalanceX18 + expAmtAssetAmtX18), (prBalanceX18 + expPriceAssetAmtX18)])
502- let checkD = if ((D1 > D0))
503- then true
504- else throw("D1 should be greater than D0")
505- if ((checkD == checkD))
506- then {
507- let lpAmtX18 = fraction(lpEmissionX18, (D1 - D0), D0)
508- $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceDcm, CEILING), curPriceX18, slippageX18)
509- }
510- else throw("Strict value is not equal to itself.")
511- }
512- }
513- let calcLpAmt = r._1
514- let calcAmAssetPmt = r._2
515- let calcPrAssetPmt = r._3
516- let curPrice = f1(r._4, scale8)
517- let slippageCalc = f1(r._5, scale8)
518- if ((0 >= calcLpAmt))
519- then throw("LP <= 0")
520- else {
521- let emitLpAmt = if (!(emitLp))
522- then 0
523- else calcLpAmt
524- let amDiff = (inAmAmt - calcAmAssetPmt)
525- let prDiff = (inPrAmt - calcPrAssetPmt)
526- let $t02058820933 = if (if (isOneAsset)
527- then (pmtId == amIdStr)
528- else false)
529- then $Tuple2(pmtAmt, 0)
530- else if (if (isOneAsset)
531- then (pmtId == prIdStr)
532- else false)
533- then $Tuple2(0, pmtAmt)
534- else $Tuple2(calcAmAssetPmt, calcPrAssetPmt)
535- let writeAmAmt = $t02058820933._1
536- let writePrAmt = $t02058820933._2
537- 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))]
538- $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEm, lpId, sts, commonState, amDiff, prDiff, inAmId, inPrId)
539- }
540- }
541-
542-
543-func getYD (xp,i,D) = {
544- let n = big2
545- let x = xp[if ((i == 0))
546- then 1
547- else 0]
548- let aPrecision = parseBigIntValue(Amult)
549- let a = (parseBigIntValue(A) * aPrecision)
550- let s = x
551- let ann = (a * n)
552- let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
553- let b = ((s + ((D * aPrecision) / ann)) - D)
554- func calc (acc,cur) = {
555- let $t02212822148 = acc
556- let y = $t02212822148._1
557- let found = $t02212822148._2
558- if ((found != unit))
559- then acc
560- else {
561- let yNext = (((y * y) + c) / ((big2 * y) + b))
562- let yDiff = absBigInt((yNext - value(y)))
563- if ((big1 >= yDiff))
564- then $Tuple2(yNext, cur)
565- else $Tuple2(yNext, unit)
566- }
567- }
568-
569- let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
570- let $t02245522502 = {
571- let $l = arr
572- let $s = size($l)
573- let $acc0 = $Tuple2(D, unit)
574- func $f0_1 ($a,$i) = if (($i >= $s))
575- then $a
576- else calc($a, $l[$i])
577-
578- func $f0_2 ($a,$i) = if (($i >= $s))
579- then $a
580- else throw("List size exceeds 15")
581-
582- $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)
583- }
584- let y = $t02245522502._1
585- let found = $t02245522502._2
586- if ((found != unit))
587- then y
588- else throw(("Y calculation error, Y = " + toString(y)))
589- }
590-
591-
592-func calcDLp (amountBalance,priceBalance,lpEmission) = {
593- let updatedDLp = fraction(getD([t1BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals)), t1BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))]), scale18, lpEmission)
594- if ((lpEmission == big0))
595- then big0
596- else updatedDLp
597- }
598-
599-
600-func calcCurrentDLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
601- let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
602- let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
603- let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
604- let currentDLp = calcDLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
605- currentDLp
606- }
607-
608-
609-func refreshDLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
610- let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
611- let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
612- let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
613- let updatedDLp = calcDLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
614- let actions = [IntegerEntry(keyDLpRefreshedHeight, height), StringEntry(keyDLp, toString(updatedDLp))]
615- $Tuple2(actions, updatedDLp)
616- }
617-
618-
619-func validateUpdatedDLp (oldDLp,updatedDLp) = if ((updatedDLp >= oldDLp))
620- then true
621- else throwErr("updated DLp lower than current DLp")
622-
623-
624-func validateMatcherOrderAllowed (order) = {
625- let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
626- let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
627- let amountAssetAmount = order.amount
628- let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
629- let $t02470024912 = if ((order.orderType == Buy))
630- then $Tuple2(amountAssetAmount, -(priceAssetAmount))
631- else $Tuple2(-(amountAssetAmount), priceAssetAmount)
632- let amountAssetBalanceDelta = $t02470024912._1
633- let priceAssetBalanceDelta = $t02470024912._2
634- if (if (if (igs())
635- then true
636- else (cfgPoolStatus == PoolMatcherDis))
637- then true
638- else (cfgPoolStatus == PoolShutdown))
639- then throw("Admin blocked")
640- else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
641- then true
642- else (order.assetPair.priceAsset != cfgPriceAssetId))
643- then throw("Wr assets")
644- else {
645- let dLp = parseBigIntValue(valueOrElse(getString(this, keyDLp), "0"))
646- let $t02525425354 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
647- let unusedActions = $t02525425354._1
648- let dLpNew = $t02525425354._2
649- let isOrderValid = (dLpNew >= dLp)
650- let info = makeString(["dLp=", toString(dLp), " dLpNew=", toString(dLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
651- $Tuple2(isOrderValid, info)
652- }
653- }
654-
655-
656-func cg (i) = if ((size(i.payments) != 1))
657- then throw("1 pmnt exp")
658- else {
659- let pmt = value(i.payments[0])
660- let pmtAssetId = value(pmt.assetId)
661- let pmtAmt = pmt.amount
662- let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
663- let outAmAmt = r._1
664- let outPrAmt = r._2
665- let sts = parseIntValue(r._9)
666- let state = r._10
667- if (if (igs())
668- then true
669- else (sts == PoolShutdown))
670- then throw(("Admin blocked: " + toString(sts)))
671- else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
672- }
673-
674-
675-func cp (caller,txId,amAsPmt,prAsPmt,slippage,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
676- let r = epo(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, (txId == ""), emitLp, isOneAsset, validateSlippage, pmtAmt, pmtId)
677- let sts = parseIntValue(r._8)
678- if (if (if (igs())
679- then true
680- else (sts == PoolPutDis))
681- then true
682- else (sts == PoolShutdown))
683- then throw(("Blocked:" + toString(sts)))
684- else r
685- }
686-
687-
688-func calcPutOneTkn (pmtAmtRaw,pmtAssetId,userAddress,txId,withTakeFee) = {
689- let amId = toBase58String(value(cfgAmountAssetId))
690- let prId = toBase58String(value(cfgPriceAssetId))
691- let lpId = cfgLpAssetId
692- let amtDcm = cfgAmountAssetDecimals
693- let priceDcm = cfgPriceAssetDecimals
694- let lpAssetEmission = toBigInt(valueOrErrorMessage(assetInfo(lpId), "invalid lp asset").quantity)
695- let chechEmission = if ((lpAssetEmission > big0))
696- then true
697- else throw("initial deposit requires all coins")
698- if ((chechEmission == chechEmission))
699- then {
700- let amBalance = getAccBalance(amId)
701- let prBalance = getAccBalance(prId)
702- let $t02801028472 = if ((txId == ""))
703- then $Tuple2(amBalance, prBalance)
704- else if ((pmtAssetId == amId))
705- then if ((pmtAmtRaw > amBalance))
706- then throw("invalid payment amount")
707- else $Tuple2((amBalance - pmtAmtRaw), prBalance)
708- else if ((pmtAssetId == prId))
709- then if ((pmtAmtRaw > prBalance))
710- then throw("invalid payment amount")
711- else $Tuple2(amBalance, (prBalance - pmtAmtRaw))
712- else throw("wrong pmtAssetId")
713- let amBalanceOld = $t02801028472._1
714- let prBalanceOld = $t02801028472._2
715- let $t02847828654 = if ((pmtAssetId == amId))
716- then $Tuple2(pmtAmtRaw, 0)
717- else if ((pmtAssetId == prId))
718- then $Tuple2(0, pmtAmtRaw)
719- else throw("invalid payment")
720- let amAmountRaw = $t02847828654._1
721- let prAmountRaw = $t02847828654._2
722- let $t02865828912 = if (withTakeFee)
723- then $Tuple3(takeFee(amAmountRaw, inFee)._1, takeFee(prAmountRaw, inFee)._1, takeFee(pmtAmtRaw, inFee)._2)
724- else $Tuple3(amAmountRaw, prAmountRaw, 0)
725- let amAmount = $t02865828912._1
726- let prAmount = $t02865828912._2
727- let feeAmount = $t02865828912._3
728- let amBalanceNew = (amBalanceOld + amAmount)
729- let prBalanceNew = (prBalanceOld + prAmount)
730- let D0 = getD([t1(amBalanceOld, cfgAmountAssetDecimals), t1(prBalanceOld, cfgPriceAssetDecimals)])
731- let D1 = getD([t1(amBalanceNew, cfgAmountAssetDecimals), t1(prBalanceNew, cfgPriceAssetDecimals)])
732- let checkD = if ((D1 > D0))
733- then true
734- else throw()
735- if ((checkD == checkD))
736- then {
737- let lpAmount = fraction(lpAssetEmission, (D1 - D0), D0, FLOOR)
738- let curPrice = f1(cpbi(t1(prBalanceNew, priceDcm), t1(amBalanceNew, amtDcm)), scale8)
739- 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))]
740- let poolProportion = fraction(prBalanceOld, scale8, amBalanceOld)
741- let amountAssetPart = fraction(pmtAmtRaw, scale8, (poolProportion + scale8))
742- let priceAssetPart = (pmtAmtRaw - amountAssetPart)
743- let lpAmtBoth = fraction(lpAssetEmission, toBigInt(priceAssetPart), toBigInt(prBalanceOld))
744- let bonus = toInt(fraction((lpAmount - lpAmtBoth), scale8BigInt, lpAmtBoth))
745- $Tuple4(toInt(lpAmount), commonState, feeAmount, bonus)
746- }
747- else throw("Strict value is not equal to itself.")
830+ $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
748831 }
749832 else throw("Strict value is not equal to itself.")
750833 }
751834
752835
753-func getOneTknV2Internal (outAssetId,minOutAmount,payments,caller,originCaller,transactionId) = {
754- let lpId = toBase58String(value(cfgLpAssetId))
755- let amId = toBase58String(value(cfgAmountAssetId))
756- let prId = toBase58String(value(cfgPriceAssetId))
757- let amDecimals = cfgAmountAssetDecimals
758- let prDecimals = cfgPriceAssetDecimals
759- let poolStatus = cfgPoolStatus
760- let userAddress = if ((caller == restContract))
761- then originCaller
762- else caller
763- let pmt = value(payments[0])
764- let pmtAssetId = value(pmt.assetId)
765- let pmtAmt = pmt.amount
766- let currentDLp = calcCurrentDLp(big0, big0, big0)
767- if ((currentDLp == currentDLp))
836+func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
837+ let isEval = (txId == unit)
838+ let cfg = getPoolConfig()
839+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
840+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
841+ let checks = [if ((paymentAssetId == cfgLpAssetId))
842+ then true
843+ else throwErr("invalid lp asset")]
844+ if ((checks == checks))
768845 then {
769- let txId58 = toBase58String(transactionId)
770- if ((lpId != toBase58String(pmtAssetId)))
771- then throw("Wrong LP")
772- else {
773- let amBalance = getAccBalance(amId)
774- let prBalance = getAccBalance(prId)
775- let $t03102431135 = {
776- let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, pmtAmt], nil)
777- if ($isInstanceOf(@, "(Int, Int)"))
778- then @
779- else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
780- }
781- if (($t03102431135 == $t03102431135))
782- then {
783- let feeAmount = $t03102431135._2
784- let totalGet = $t03102431135._1
785- let totalAmount = if (if ((minOutAmount > 0))
786- then (minOutAmount > totalGet)
787- else false)
788- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
789- else totalGet
790- let $t03132531632 = if ((outAssetId == amId))
791- then $Tuple4(totalAmount, 0, ((amBalance - totalAmount) - feeAmount), prBalance)
792- else if ((outAssetId == prId))
793- then $Tuple4(0, totalAmount, amBalance, ((prBalance - totalAmount) - feeAmount))
794- else throw("invalid out asset id")
795- let outAm = $t03132531632._1
796- let outPr = $t03132531632._2
797- let amBalanceNew = $t03132531632._3
798- let prBalanceNew = $t03132531632._4
799- let curPrX18 = cpbi(t1(prBalanceNew, prDecimals), t1(amBalanceNew, amDecimals))
800- let curPr = f1(curPrX18, scale8)
801- let outAssetIdOrWaves = if ((outAssetId == "WAVES"))
802- then unit
803- else fromBase58String(outAssetId)
804- let sendFeeToMatcher = if ((feeAmount > 0))
805- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetIdOrWaves)]
806- else nil
807- 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)
808- if ((state == state))
809- then {
810- let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
811- if ((burn == burn))
812- then {
813- let $t03241732767 = {
814- let feeAmountForCalc = if ((this == feeCollectorAddress))
815- then 0
816- else feeAmount
817- let outInAmountAsset = if ((parseAssetId(outAssetId) == cfgAmountAssetId))
818- then true
819- else false
820- if (outInAmountAsset)
821- then $Tuple2(-((totalGet + feeAmountForCalc)), 0)
822- else $Tuple2(0, -((totalGet + feeAmountForCalc)))
823- }
824- let amountAssetBalanceDelta = $t03241732767._1
825- let priceAssetBalanceDelta = $t03241732767._2
826- let $t03277032878 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
827- let refreshDLpActions = $t03277032878._1
828- let updatedDLp = $t03277032878._2
829- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
830- if ((isUpdatedDLpValid == isUpdatedDLpValid))
831- then $Tuple2((state ++ refreshDLpActions), totalAmount)
832- else throw("Strict value is not equal to itself.")
833- }
834- else throw("Strict value is not equal to itself.")
835- }
836- else throw("Strict value is not equal to itself.")
837- }
838- else throw("Strict value is not equal to itself.")
839- }
846+ let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
847+ then true
848+ else if ((outAssetId == cfgPriceAssetId))
849+ then false
850+ else throwErr("invalid asset")
851+ let balanceBigInt = if (outInAmountAsset)
852+ then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
853+ else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
854+ let outInAmountAssetDecimals = if (outInAmountAsset)
855+ then amtAssetDcm
856+ else priceAssetDcm
857+ let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
858+ let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
859+ let outBalance = if (outInAmountAsset)
860+ then amBalanceOld
861+ else prBalanceOld
862+ let outBalanceBigInt = toBigInt(outBalance)
863+ let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
864+ let redeemedBigInt = toBigInt(paymentAmount)
865+ let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
866+ let $t03795638012 = takeFee(amountRaw, outFee)
867+ let totalAmount = $t03795638012._1
868+ let feeAmount = $t03795638012._2
869+ let $t03801638242 = if (outInAmountAsset)
870+ then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
871+ else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
872+ let outAmAmount = $t03801638242._1
873+ let outPrAmount = $t03801638242._2
874+ let amBalanceNew = $t03801638242._3
875+ let prBalanceNew = $t03801638242._4
876+ let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
877+ let priceNew = fromX18(priceNewX18, scale8)
878+ let commonState = if (isEval)
879+ then nil
880+ 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)]
881+ let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
882+ let priceOld = fromX18(priceOldX18, scale8)
883+ let loss = {
884+ let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
885+ fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
886+ }
887+ $Tuple5(totalAmount, commonState, feeAmount, loss, outInAmountAsset)
840888 }
841889 else throw("Strict value is not equal to itself.")
842890 }
843891
844892
845-func m () = match getString(mpk()) {
846- case s: String =>
847- fromBase58String(s)
848- case _: Unit =>
849- unit
850- case _ =>
851- throw("Match error")
852-}
893+func managerPublicKeyOrUnit () = {
894+ let managerVaultAddress = getManagerVaultAddressOrThis()
895+ match getString(managerVaultAddress, keyManagerPublicKey()) {
896+ case s: String =>
897+ fromBase58String(s)
898+ case _: Unit =>
899+ unit
900+ case _ =>
901+ throw("Match error")
902+ }
903+ }
853904
854905
855-func pm () = match getString(pmpk()) {
856- case s: String =>
857- fromBase58String(s)
858- case _: Unit =>
859- unit
860- case _ =>
861- throw("Match error")
862-}
863-
864-
865-let pd = throw("Permission denied")
866-
867-func isManager (i) = match m() {
906+func isManager (i) = match managerPublicKeyOrUnit() {
868907 case pk: ByteVector =>
869908 (i.callerPublicKey == pk)
870909 case _: Unit =>
871910 (i.caller == this)
872911 case _ =>
873912 throw("Match error")
874913 }
875914
876915
877-func mm (i) = match m() {
878- case pk: ByteVector =>
879- if ((i.callerPublicKey == pk))
880- then true
881- else pd
882- case _: Unit =>
883- if ((i.caller == this))
884- then true
885- else pd
886- case _ =>
887- throw("Match error")
888-}
889-
890-
891-func getY (isReverse,D,poolAmountInBalance) = {
892- let poolConfig = gpc()
893- let amId = poolConfig[idxAmAsId]
894- let prId = poolConfig[idxPrAsId]
895- let n = big2
896- let aPrecision = parseBigIntValue(Amult)
897- let a = (parseBigIntValue(A) * aPrecision)
898- let xp = if ((isReverse == false))
899- then [(toBigInt(getAccBalance(amId)) + poolAmountInBalance), toBigInt(getAccBalance(prId))]
900- else [(toBigInt(getAccBalance(prId)) + poolAmountInBalance), toBigInt(getAccBalance(amId))]
901- let x = xp[0]
902- let s = x
903- let ann = (a * n)
904- let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
905- let b = ((s + ((D * aPrecision) / ann)) - D)
906- func calc (acc,cur) = {
907- let $t03432534345 = acc
908- let y = $t03432534345._1
909- let found = $t03432534345._2
910- if ((found != unit))
911- then acc
912- else {
913- let yNext = (((y * y) + c) / ((big2 * y) + b))
914- let yDiff = absBigInt((yNext - value(y)))
915- if ((big1 >= yDiff))
916- then $Tuple2(yNext, cur)
917- else $Tuple2(yNext, unit)
918- }
919- }
920-
921- let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
922- let $t03467634723 = {
923- let $l = arr
924- let $s = size($l)
925- let $acc0 = $Tuple2(D, unit)
926- func $f0_1 ($a,$i) = if (($i >= $s))
927- then $a
928- else calc($a, $l[$i])
929-
930- func $f0_2 ($a,$i) = if (($i >= $s))
931- then $a
932- else throw("List size exceeds 15")
933-
934- $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)
935- }
936- let y = $t03467634723._1
937- let found = $t03467634723._2
938- if ((found != unit))
939- then y
940- else throw(("Y calculation error, Y = " + toString(y)))
916+func mustManager (i) = {
917+ let pd = throw("Permission denied")
918+ match managerPublicKeyOrUnit() {
919+ case pk: ByteVector =>
920+ if ((i.callerPublicKey == pk))
921+ then true
922+ else pd
923+ case _: Unit =>
924+ if ((i.caller == this))
925+ then true
926+ else pd
927+ case _ =>
928+ throw("Match error")
929+ }
941930 }
942931
943932
944-func skipOrderValidation () = valueOrElse(getBoolean(fca, keySkipOrderValidation(toString(this))), false)
933+@Callable(i)
934+func rebalance () = (rebalanceAsset(getStringOrFail(this, aa())) ++ rebalanceAsset(getStringOrFail(this, pa())))
935+
945936
946937
947938 @Callable(i)
948939 func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse,feePoolAmount) = {
949- let $t03507535499 = if ((isReverse == false))
940+ let $t04010040405 = if ((isReverse == false))
950941 then {
951- let assetOut = strf(this, pa())
952- let poolAmountInBalance = (toBigInt(getAccBalance(strf(this, aa()))) + toBigInt(cleanAmountIn))
953- $Tuple2(assetOut, poolAmountInBalance)
942+ let assetOut = getStringOrFail(this, pa())
943+ let assetIn = getStringOrFail(this, aa())
944+ $Tuple2(assetOut, assetIn)
954945 }
955946 else {
956- let assetOut = strf(this, aa())
957- let poolAmountInBalance = (toBigInt(getAccBalance(strf(this, pa()))) + toBigInt(cleanAmountIn))
958- $Tuple2(assetOut, poolAmountInBalance)
947+ let assetOut = getStringOrFail(this, aa())
948+ let assetIn = getStringOrFail(this, pa())
949+ $Tuple2(assetOut, assetIn)
959950 }
960- let assetOut = $t03507535499._1
961- let poolAmountInBalance = $t03507535499._2
962- let poolConfig = gpc()
963- let amId = poolConfig[idxAmAsId]
964- let prId = poolConfig[idxPrAsId]
965- let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
966- let D = getD(xp)
967- let y = getY(isReverse, D, toBigInt(cleanAmountIn))
968- let dy = ((toBigInt(getAccBalance(assetOut)) - y) - toBigInt(1))
969- let totalGetRaw = max([0, toInt(dy)])
970- let newXp = if ((isReverse == false))
971- then [((toBigInt(getAccBalance(amId)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)), (toBigInt(getAccBalance(prId)) - dy)]
972- else [(toBigInt(getAccBalance(amId)) - dy), ((toBigInt(getAccBalance(prId)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount))]
973- let newD = getD(newXp)
974- let checkD = if ((newD >= D))
951+ let assetOut = $t04010040405._1
952+ let assetIn = $t04010040405._2
953+ let poolAssetInBalance = getAccBalance(assetIn)
954+ let poolAssetOutBalance = getAccBalance(assetOut)
955+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
956+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
957+ let newK = (((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
958+ let checkK = if ((newK >= oldK))
975959 then true
976- else throw(makeString(["new D is fewer error", toString(D), toString(newD)], "__"))
977- if ((checkD == checkD))
978- then $Tuple2(nil, totalGetRaw)
960+ else throw("new K is fewer error")
961+ if ((checkK == checkK))
962+ then $Tuple2(nil, amountOut)
979963 else throw("Strict value is not equal to itself.")
980964 }
981965
982966
983967
984968 @Callable(i)
985969 func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo,feePoolAmount) = {
986970 let swapContact = {
987- let @ = invoke(fca, "getSwapContractREADONLY", nil, nil)
971+ let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil)
988972 if ($isInstanceOf(@, "String"))
989973 then @
990974 else throw(($getType(@) + " couldn't be cast to String"))
991975 }
992- let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
976+ let isPoolSwapDisabled = {
977+ let @ = invoke(factoryContract, "isPoolSwapDisabledREADONLY", [toString(this)], nil)
978+ if ($isInstanceOf(@, "Boolean"))
979+ then @
980+ else throw(($getType(@) + " couldn't be cast to Boolean"))
981+ }
982+ let isSwapDisabled = if (!(isAddressWhitelisted(i.caller)))
983+ then if (if (isGlobalShutdown())
984+ then true
985+ else (cfgPoolStatus == PoolShutdown))
986+ then true
987+ else isPoolSwapDisabled
988+ else false
989+ let checks = [if (if (!(isSwapDisabled))
990+ then true
991+ else isManager(i))
992+ then true
993+ else throwErr("swap operation is blocked by admin"), if ((value(i.payments[0]).amount >= cleanAmountIn))
993994 then true
994995 else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
995996 then true
996997 else throwErr("Permission denied")]
997998 if ((checks == checks))
998999 then {
9991000 let pmt = value(i.payments[0])
10001001 let assetIn = assetIdToString(pmt.assetId)
1001- let $t03693537329 = if ((isReverse == false))
1002+ let assetOut = if ((isReverse == false))
1003+ then getStringOrFail(this, pa())
1004+ else getStringOrFail(this, aa())
1005+ let poolAssetInBalance = ((getAccBalance(assetIn) - value(i.payments[0]).amount) - feePoolAmount)
1006+ let poolAssetOutBalance = getAccBalance(assetOut)
1007+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
1008+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
1009+ let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
1010+ let checkK = if ((newK >= oldK))
1011+ then true
1012+ else throw("new K is fewer error")
1013+ if ((checkK == checkK))
10021014 then {
1003- let assetOut = strf(this, pa())
1004- let poolAmountInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
1005- $Tuple2(assetOut, poolAmountInBalance)
1006- }
1007- else {
1008- let assetOut = strf(this, aa())
1009- let poolAmountInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
1010- $Tuple2(assetOut, poolAmountInBalance)
1011- }
1012- let assetOut = $t03693537329._1
1013- let poolAmountInBalance = $t03693537329._2
1014- let poolConfig = gpc()
1015- let amId = poolConfig[idxAmAsId]
1016- let prId = poolConfig[idxPrAsId]
1017- let xp = if ((isReverse == false))
1018- then [(toBigInt(getAccBalance(amId)) - toBigInt(value(i.payments[0]).amount)), toBigInt(getAccBalance(prId))]
1019- else [toBigInt(getAccBalance(amId)), (toBigInt(getAccBalance(prId)) - toBigInt(value(i.payments[0]).amount))]
1020- let D = getD(xp)
1021- let y = getY(isReverse, D, toBigInt(0))
1022- let dy = ((toBigInt(getAccBalance(assetOut)) - y) - toBigInt(1))
1023- let totalGetRaw = max([0, toInt(dy)])
1024- let checkMin = if ((totalGetRaw >= amountOutMin))
1025- then true
1026- else throw("Exchange result is fewer coins than expected")
1027- if ((checkMin == checkMin))
1028- then {
1029- let newXp = if ((isReverse == false))
1030- then [(toBigInt(getAccBalance(amId)) + toBigInt(feePoolAmount)), (toBigInt(getAccBalance(prId)) - dy)]
1031- else [(toBigInt(getAccBalance(amId)) - dy), (toBigInt(getAccBalance(prId)) + toBigInt(feePoolAmount))]
1032- let newD = getD(newXp)
1033- let checkD = if ((newD >= D))
1015+ let checkMin = if ((amountOut >= amountOutMin))
10341016 then true
1035- else throw("new D is fewer error")
1036- if ((checkD == checkD))
1037- then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), totalGetRaw, parseAssetId(assetOut))], totalGetRaw)
1038- else throw("Strict value is not equal to itself.")
1039- }
1040- else throw("Strict value is not equal to itself.")
1041- }
1042- else throw("Strict value is not equal to itself.")
1043- }
1044-
1045-
1046-
1047-@Callable(i)
1048-func constructor (fc) = {
1049- let c = mm(i)
1050- if ((c == c))
1051- then [StringEntry(fc(), fc)]
1052- else throw("Strict value is not equal to itself.")
1053- }
1054-
1055-
1056-
1057-@Callable(i)
1058-func setManager (pendingManagerPublicKey) = {
1059- let c = mm(i)
1060- if ((c == c))
1061- then {
1062- let cm = fromBase58String(pendingManagerPublicKey)
1063- if ((cm == cm))
1064- then [StringEntry(pmpk(), pendingManagerPublicKey)]
1065- else throw("Strict value is not equal to itself.")
1066- }
1067- else throw("Strict value is not equal to itself.")
1068- }
1069-
1070-
1071-
1072-@Callable(i)
1073-func confirmManager () = {
1074- let p = pm()
1075- let hpm = if (isDefined(p))
1076- then true
1077- else throw("No pending manager")
1078- if ((hpm == hpm))
1079- then {
1080- let cpm = if ((i.callerPublicKey == value(p)))
1081- then true
1082- else throw("You are not pending manager")
1083- if ((cpm == cpm))
1084- then [StringEntry(mpk(), toBase58String(value(p))), DeleteEntry(pmpk())]
1085- else throw("Strict value is not equal to itself.")
1086- }
1087- else throw("Strict value is not equal to itself.")
1088- }
1089-
1090-
1091-
1092-@Callable(i)
1093-func put (slip,autoStake) = {
1094- let factCfg = gfc()
1095- let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Wr st addr")
1096- let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Wr sl addr")
1097- if ((0 > slip))
1098- then throw("Wrong slippage")
1099- else if ((size(i.payments) != 2))
1100- then throw("2 pmnts expd")
1101- else {
1102- let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1103- let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1104- let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amAssetPmt)
1105- if ((amountAssetBalance == amountAssetBalance))
1106- then {
1107- let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - prAssetPmt)
1108- if ((priceAssetBalance == priceAssetBalance))
1109- then {
1110- let lpAssetEmission = toBigInt(value(assetInfo(cfgLpAssetId)).quantity)
1111- if ((lpAssetEmission == lpAssetEmission))
1112- then {
1113- let currentDLp = calcCurrentDLp(amAssetPmt, prAssetPmt, toBigInt(0))
1114- if ((currentDLp == currentDLp))
1115- then {
1116- 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, "")
1117- let emitLpAmt = e._2
1118- let lpAssetId = e._7
1119- let state = e._9
1120- let amDiff = e._10
1121- let prDiff = e._11
1122- let amId = e._12
1123- let prId = e._13
1124- let r = invoke(fca, "emit", [emitLpAmt], nil)
1125- if ((r == r))
1126- then {
1127- let el = match r {
1128- case legacy: Address =>
1129- invoke(legacy, "emit", [emitLpAmt], nil)
1130- case _ =>
1131- unit
1132- }
1133- if ((el == el))
1134- then {
1135- let sa = if ((amDiff > 0))
1136- then invoke(slipCntr, "put", nil, [AttachedPayment(amId, amDiff)])
1137- else nil
1138- if ((sa == sa))
1139- then {
1140- let sp = if ((prDiff > 0))
1141- then invoke(slipCntr, "put", nil, [AttachedPayment(prId, prDiff)])
1142- else nil
1143- if ((sp == sp))
1144- then {
1145- let lpTrnsfr = if (autoStake)
1146- then {
1147- let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
1148- if ((ss == ss))
1149- then nil
1150- else throw("Strict value is not equal to itself.")
1151- }
1152- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1153- let $t04194842090 = refreshDLpInternal(0, 0, 0)
1154- let refreshDLpActions = $t04194842090._1
1155- let updatedDLp = $t04194842090._2
1156- let check = if ((updatedDLp >= currentDLp))
1157- then true
1158- else throwErr(makeString(["updated DLp lower than current DLp", toString(amountAssetBalance), toString(priceAssetBalance), toString(lpAssetEmission), toString(currentDLp), toString(updatedDLp), toString(amDiff), toString(prDiff)], " "))
1159- if ((check == check))
1160- then {
1161- let lpAssetEmissionAfter = value(assetInfo(cfgLpAssetId)).quantity
1162- if ((lpAssetEmissionAfter == lpAssetEmissionAfter))
1163- then ((state ++ lpTrnsfr) ++ refreshDLpActions)
1164- else throw("Strict value is not equal to itself.")
1165- }
1166- else throw("Strict value is not equal to itself.")
1167- }
1168- else throw("Strict value is not equal to itself.")
1169- }
1170- else throw("Strict value is not equal to itself.")
1171- }
1172- else throw("Strict value is not equal to itself.")
1173- }
1174- else throw("Strict value is not equal to itself.")
1175- }
1176- else throw("Strict value is not equal to itself.")
1177- }
1178- else throw("Strict value is not equal to itself.")
1179- }
1180- else throw("Strict value is not equal to itself.")
1181- }
1182- else throw("Strict value is not equal to itself.")
1183- }
1184- }
1185-
1186-
1187-
1188-@Callable(i)
1189-func putOneTknV2 (minOutAmount,autoStake) = {
1190- let isPoolOneTokenOperationsDisabled = {
1191- let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1192- if ($isInstanceOf(@, "Boolean"))
1193- then @
1194- else throw(($getType(@) + " couldn't be cast to Boolean"))
1195- }
1196- let isPutDisabled = if (if (if (igs())
1197- then true
1198- else (cfgPoolStatus == PoolPutDis))
1199- then true
1200- else (cfgPoolStatus == PoolShutdown))
1201- then true
1202- else isPoolOneTokenOperationsDisabled
1203- let checks = [if (if (!(isPutDisabled))
1204- then true
1205- else isManager(i))
1206- then true
1207- else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
1208- then true
1209- else throwErr("exactly 1 payment are expected")]
1210- if ((checks == checks))
1211- then {
1212- let amId = toBase58String(value(cfgAmountAssetId))
1213- let prId = toBase58String(value(cfgPriceAssetId))
1214- let lpId = cfgLpAssetId
1215- let amDecimals = cfgAmountAssetDecimals
1216- let prDecimals = cfgPriceAssetDecimals
1217- let userAddress = if ((i.caller == this))
1218- then i.originCaller
1219- else i.caller
1220- let pmt = value(i.payments[0])
1221- let pmtAssetId = toBase58String(value(pmt.assetId))
1222- let pmtAmt = pmt.amount
1223- let currentDLp = if ((pmt.assetId == cfgAmountAssetId))
1224- then calcCurrentDLp(toBigInt(pmtAmt), toBigInt(0), toBigInt(0))
1225- else calcCurrentDLp(toBigInt(0), toBigInt(pmtAmt), toBigInt(0))
1226- if ((currentDLp == currentDLp))
1227- then {
1228- let $t04373143889 = calcPutOneTkn(pmtAmt, pmtAssetId, toString(userAddress), toBase58String(i.transactionId), true)
1229- if (($t04373143889 == $t04373143889))
1017+ else throw("Exchange result is fewer coins than expected")
1018+ if ((checkMin == checkMin))
12301019 then {
1231- let feeAmount = $t04373143889._3
1232- let state = $t04373143889._2
1233- let estimLP = $t04373143889._1
1234- let emitLpAmt = if (if ((minOutAmount > 0))
1235- then (minOutAmount > estimLP)
1236- else false)
1237- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1238- else estimLP
1239- let e = invoke(fca, "emit", [emitLpAmt], nil)
1240- if ((e == e))
1020+ let amountAssetBalanceDelta = if (isReverse)
1021+ then -(amountOut)
1022+ else feePoolAmount
1023+ let priceAssetBalanceDelta = if (isReverse)
1024+ then feePoolAmount
1025+ else -(amountOut)
1026+ let refreshKLpActions = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)._1
1027+ if ((refreshKLpActions == refreshKLpActions))
12411028 then {
1242- let el = match e {
1243- case legacy: Address =>
1244- invoke(legacy, "emit", [emitLpAmt], nil)
1245- case _ =>
1246- unit
1247- }
1248- if ((el == el))
1029+ let rebalanceState = rebalanceAsset(assetIn)
1030+ if ((rebalanceState == rebalanceState))
12491031 then {
1250- let lpTrnsfr = if (autoStake)
1251- then {
1252- let ss = invoke(stakingContract, "stakeFor", [toString(i.caller)], [AttachedPayment(lpId, emitLpAmt)])
1253- if ((ss == ss))
1254- then nil
1255- else throw("Strict value is not equal to itself.")
1256- }
1257- else [ScriptTransfer(i.caller, emitLpAmt, lpId)]
1258- let sendFeeToMatcher = if ((feeAmount > 0))
1259- then [ScriptTransfer(feeCollectorAddress, feeAmount, fromBase58String(pmtAssetId))]
1260- else nil
1261- let $t04477445123 = if ((this == feeCollectorAddress))
1262- then $Tuple2(0, 0)
1263- else {
1264- let paymentInAmountAsset = if ((pmt.assetId == cfgAmountAssetId))
1265- then true
1266- else false
1267- if (paymentInAmountAsset)
1268- then $Tuple2(-(feeAmount), 0)
1269- else $Tuple2(0, -(feeAmount))
1270- }
1271- let amountAssetBalanceDelta = $t04477445123._1
1272- let priceAssetBalanceDelta = $t04477445123._2
1273- let $t04512645234 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1274- let refreshDLpActions = $t04512645234._1
1275- let updatedDLp = $t04512645234._2
1276- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1277- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1278- then $Tuple2((((state ++ lpTrnsfr) ++ sendFeeToMatcher) ++ refreshDLpActions), emitLpAmt)
1032+ let withdrawState = withdrawAndRebalanceAsset(assetOut, amountOut)
1033+ if ((withdrawState == withdrawState))
1034+ then $Tuple2(((withdrawState ++ rebalanceState) ++ [ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))]), amountOut)
12791035 else throw("Strict value is not equal to itself.")
12801036 }
12811037 else throw("Strict value is not equal to itself.")
12821038 }
12831039 else throw("Strict value is not equal to itself.")
12841040 }
12851041 else throw("Strict value is not equal to itself.")
12861042 }
12871043 else throw("Strict value is not equal to itself.")
12881044 }
12891045 else throw("Strict value is not equal to itself.")
12901046 }
12911047
12921048
12931049
12941050 @Callable(i)
1295-func putForFree (maxSlpg) = if ((0 > maxSlpg))
1296- then throw("Wrong slpg")
1297- else if ((size(i.payments) != 2))
1298- then throw("2 pmnts expd")
1299- else {
1300- 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, "")
1301- let state = estPut._9
1302- let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1303- let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1304- let currentDLp = calcCurrentDLp(amAssetPmt, prAssetPmt, toBigInt(0))
1305- if ((currentDLp == currentDLp))
1306- then {
1307- let $t04626446329 = refreshDLpInternal(0, 0, 0)
1308- let refreshDLpActions = $t04626446329._1
1309- let updatedDLp = $t04626446329._2
1310- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1311- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1312- then (state ++ refreshDLpActions)
1313- else throw("Strict value is not equal to itself.")
1314- }
1315- else throw("Strict value is not equal to itself.")
1316- }
1051+func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
1052+ then throw("Invalid slippageTolerance passed")
1053+ else {
1054+ let estPut = commonPut(i, slippageTolerance, true)
1055+ let emitLpAmt = estPut._2
1056+ let lpAssetId = estPut._7
1057+ let state = estPut._9
1058+ let amDiff = estPut._10
1059+ let prDiff = estPut._11
1060+ let amId = estPut._12
1061+ let prId = estPut._13
1062+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1063+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1064+ let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
1065+ if ((currentKLp == currentKLp))
1066+ then {
1067+ let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
1068+ if ((emitInv == emitInv))
1069+ then {
1070+ let emitInvLegacy = match emitInv {
1071+ case legacyFactoryContract: Address =>
1072+ invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
1073+ case _ =>
1074+ unit
1075+ }
1076+ if ((emitInvLegacy == emitInvLegacy))
1077+ then {
1078+ let slippageAInv = if ((amDiff > 0))
1079+ then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
1080+ else nil
1081+ if ((slippageAInv == slippageAInv))
1082+ then {
1083+ let slippagePInv = if ((prDiff > 0))
1084+ then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
1085+ else nil
1086+ if ((slippagePInv == slippagePInv))
1087+ then {
1088+ let lpTransfer = if (shouldAutoStake)
1089+ then {
1090+ let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
1091+ if ((slpStakeInv == slpStakeInv))
1092+ then nil
1093+ else throw("Strict value is not equal to itself.")
1094+ }
1095+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1096+ let $t04558146043 = refreshKLpInternal(0, 0, 0)
1097+ if (($t04558146043 == $t04558146043))
1098+ then {
1099+ let updatedKLp = $t04558146043._2
1100+ let refreshKLpActions = $t04558146043._1
1101+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1102+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1103+ then {
1104+ let reb = invoke(this, "rebalance", nil, nil)
1105+ if ((reb == reb))
1106+ then ((state ++ lpTransfer) ++ refreshKLpActions)
1107+ else throw("Strict value is not equal to itself.")
1108+ }
1109+ else throw("Strict value is not equal to itself.")
1110+ }
1111+ else throw("Strict value is not equal to itself.")
1112+ }
1113+ else throw("Strict value is not equal to itself.")
1114+ }
1115+ else throw("Strict value is not equal to itself.")
1116+ }
1117+ else throw("Strict value is not equal to itself.")
1118+ }
1119+ else throw("Strict value is not equal to itself.")
1120+ }
1121+ else throw("Strict value is not equal to itself.")
1122+ }
13171123
13181124
13191125
13201126 @Callable(i)
1321-func get () = {
1322- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1323- if ((currentDLp == currentDLp))
1127+func putForFree (maxSlippage) = if ((0 > maxSlippage))
1128+ then throw("Invalid value passed")
1129+ else {
1130+ let estPut = commonPut(i, maxSlippage, false)
1131+ let state = estPut._9
1132+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1133+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1134+ let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
1135+ if ((currentKLp == currentKLp))
1136+ then {
1137+ let $t04665546720 = refreshKLpInternal(0, 0, 0)
1138+ let refreshKLpActions = $t04665546720._1
1139+ let updatedKLp = $t04665546720._2
1140+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1141+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1142+ then (state ++ refreshKLpActions)
1143+ else throw("Strict value is not equal to itself.")
1144+ }
1145+ else throw("Strict value is not equal to itself.")
1146+ }
1147+
1148+
1149+
1150+@Callable(i)
1151+func putOneTkn (minOutAmount,autoStake) = {
1152+ let isPoolOneTokenOperationsDisabled = {
1153+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1154+ if ($isInstanceOf(@, "Boolean"))
1155+ then @
1156+ else throw(($getType(@) + " couldn't be cast to Boolean"))
1157+ }
1158+ let isPutDisabled = if (!(isAddressWhitelisted(i.caller)))
1159+ then if (if (if (isGlobalShutdown())
1160+ then true
1161+ else (cfgPoolStatus == PoolPutDisabled))
1162+ then true
1163+ else (cfgPoolStatus == PoolShutdown))
1164+ then true
1165+ else isPoolOneTokenOperationsDisabled
1166+ else false
1167+ let checks = [if (if (!(isPutDisabled))
1168+ then true
1169+ else isManager(i))
1170+ then true
1171+ else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
1172+ then true
1173+ else throwErr("exactly 1 payment are expected")]
1174+ if ((checks == checks))
13241175 then {
1325- let r = cg(i)
1326- let outAmtAmt = r._1
1327- let outPrAmt = r._2
1328- let pmtAmt = r._3
1329- let pmtAssetId = r._4
1330- let state = r._5
1331- let b = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1332- if ((b == b))
1176+ let payment = i.payments[0]
1177+ let paymentAssetId = payment.assetId
1178+ let paymentAmountRaw = payment.amount
1179+ let currentKLp = if ((paymentAssetId == cfgAmountAssetId))
1180+ then calcCurrentKLp(toBigInt(paymentAmountRaw), toBigInt(0), toBigInt(0))
1181+ else if ((paymentAssetId == cfgPriceAssetId))
1182+ then calcCurrentKLp(toBigInt(0), toBigInt(paymentAmountRaw), toBigInt(0))
1183+ else throwErr("payment asset is not supported")
1184+ if ((currentKLp == currentKLp))
13331185 then {
1334- let $t04750247584 = refreshDLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1335- let refreshDLpActions = $t04750247584._1
1336- let updatedDLp = $t04750247584._2
1337- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1338- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1339- then (state ++ refreshDLpActions)
1186+ let userAddress = i.caller
1187+ let txId = i.transactionId
1188+ let $t04794948101 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
1189+ if (($t04794948101 == $t04794948101))
1190+ then {
1191+ let paymentInAmountAsset = $t04794948101._5
1192+ let bonus = $t04794948101._4
1193+ let feeAmount = $t04794948101._3
1194+ let commonState = $t04794948101._2
1195+ let emitAmountEstimated = $t04794948101._1
1196+ let emitAmount = if (if ((minOutAmount > 0))
1197+ then (minOutAmount > emitAmountEstimated)
1198+ else false)
1199+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1200+ else emitAmountEstimated
1201+ let emitInv = emit(emitAmount)
1202+ if ((emitInv == emitInv))
1203+ then {
1204+ let lpTransfer = if (autoStake)
1205+ then {
1206+ let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
1207+ if ((stakeInv == stakeInv))
1208+ then nil
1209+ else throw("Strict value is not equal to itself.")
1210+ }
1211+ else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
1212+ let sendFee = if ((feeAmount > 0))
1213+ then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
1214+ else nil
1215+ let $t04868748884 = if ((this == feeCollectorAddress))
1216+ then $Tuple2(0, 0)
1217+ else if (paymentInAmountAsset)
1218+ then $Tuple2(-(feeAmount), 0)
1219+ else $Tuple2(0, -(feeAmount))
1220+ let amountAssetBalanceDelta = $t04868748884._1
1221+ let priceAssetBalanceDelta = $t04868748884._2
1222+ let $t04888748995 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1223+ let refreshKLpActions = $t04888748995._1
1224+ let updatedKLp = $t04888748995._2
1225+ let kLp = value(getString(keyKLp))
1226+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1227+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1228+ then {
1229+ let reb = invoke(this, "rebalance", nil, nil)
1230+ if ((reb == reb))
1231+ then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
1232+ else throw("Strict value is not equal to itself.")
1233+ }
1234+ else throw("Strict value is not equal to itself.")
1235+ }
1236+ else throw("Strict value is not equal to itself.")
1237+ }
13401238 else throw("Strict value is not equal to itself.")
13411239 }
13421240 else throw("Strict value is not equal to itself.")
13431241 }
13441242 else throw("Strict value is not equal to itself.")
13451243 }
13461244
13471245
13481246
13491247 @Callable(i)
1350-func getOneTknV2 (outAssetId,minOutAmount) = {
1248+func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
1249+ let $t04935049507 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
1250+ let emitAmountEstimated = $t04935049507._1
1251+ let commonState = $t04935049507._2
1252+ let feeAmount = $t04935049507._3
1253+ let bonus = $t04935049507._4
1254+ let paymentInAmountAsset = $t04935049507._5
1255+ $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
1256+ }
1257+
1258+
1259+
1260+@Callable(i)
1261+func getOneTkn (outAssetIdStr,minOutAmount) = {
13511262 let isPoolOneTokenOperationsDisabled = {
1352- let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1263+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
13531264 if ($isInstanceOf(@, "Boolean"))
13541265 then @
13551266 else throw(($getType(@) + " couldn't be cast to Boolean"))
13561267 }
1357- let isGetDisabled = if (if (igs())
1358- then true
1359- else (cfgPoolStatus == PoolShutdown))
1360- then true
1361- else isPoolOneTokenOperationsDisabled
1268+ let isGetDisabled = if (!(isAddressWhitelisted(i.caller)))
1269+ then if (if (isGlobalShutdown())
1270+ then true
1271+ else (cfgPoolStatus == PoolShutdown))
1272+ then true
1273+ else isPoolOneTokenOperationsDisabled
1274+ else false
13621275 let checks = [if (if (!(isGetDisabled))
13631276 then true
13641277 else isManager(i))
13651278 then true
13661279 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
13671280 then true
13681281 else throwErr("exactly 1 payment are expected")]
13691282 if ((checks == checks))
13701283 then {
1371- let $t04820248357 = getOneTknV2Internal(outAssetId, minOutAmount, i.payments, i.caller, i.originCaller, i.transactionId)
1372- let state = $t04820248357._1
1373- let totalAmount = $t04820248357._2
1374- $Tuple2(state, totalAmount)
1284+ let outAssetId = parseAssetId(outAssetIdStr)
1285+ let payment = i.payments[0]
1286+ let paymentAssetId = payment.assetId
1287+ let paymentAmount = payment.amount
1288+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1289+ if ((currentKLp == currentKLp))
1290+ then {
1291+ let userAddress = i.caller
1292+ let txId = i.transactionId
1293+ let $t05042950582 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1294+ if (($t05042950582 == $t05042950582))
1295+ then {
1296+ let outInAmountAsset = $t05042950582._5
1297+ let bonus = $t05042950582._4
1298+ let feeAmount = $t05042950582._3
1299+ let commonState = $t05042950582._2
1300+ let amountEstimated = $t05042950582._1
1301+ let amount = if (if ((minOutAmount > 0))
1302+ then (minOutAmount > amountEstimated)
1303+ else false)
1304+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1305+ else amountEstimated
1306+ let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
1307+ if ((burnInv == burnInv))
1308+ then {
1309+ let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
1310+ let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
1311+ let sendFee = if ((feeAmount > 0))
1312+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1313+ else nil
1314+ let $t05124651493 = {
1315+ let feeAmountForCalc = if ((this == feeCollectorAddress))
1316+ then 0
1317+ else feeAmount
1318+ if (outInAmountAsset)
1319+ then $Tuple2(-((amount + feeAmountForCalc)), 0)
1320+ else $Tuple2(0, -((amount + feeAmountForCalc)))
1321+ }
1322+ let amountAssetBalanceDelta = $t05124651493._1
1323+ let priceAssetBalanceDelta = $t05124651493._2
1324+ let $t05149651604 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1325+ let refreshKLpActions = $t05149651604._1
1326+ let updatedKLp = $t05149651604._2
1327+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1328+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1329+ then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1330+ else throw("Strict value is not equal to itself.")
1331+ }
1332+ else throw("Strict value is not equal to itself.")
1333+ }
1334+ else throw("Strict value is not equal to itself.")
1335+ }
1336+ else throw("Strict value is not equal to itself.")
13751337 }
13761338 else throw("Strict value is not equal to itself.")
13771339 }
13781340
13791341
13801342
13811343 @Callable(i)
1382-func refreshDLp () = {
1383- let lastRefreshedBlockHeight = valueOrElse(getInteger(keyDLpRefreshedHeight), 0)
1384- let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= dLpRefreshDelay))
1385- then unit
1386- else throwErr(makeString([toString(dLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1387- if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
1344+func getOneTknREADONLY (outAssetId,paymentAmount) = {
1345+ let $t05188252038 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1346+ let amountEstimated = $t05188252038._1
1347+ let commonState = $t05188252038._2
1348+ let feeAmount = $t05188252038._3
1349+ let bonus = $t05188252038._4
1350+ let outInAmountAsset = $t05188252038._5
1351+ $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
1352+ }
1353+
1354+
1355+
1356+@Callable(i)
1357+func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
1358+ let isPoolOneTokenOperationsDisabled = {
1359+ let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1360+ if ($isInstanceOf(@, "Boolean"))
1361+ then @
1362+ else throw(($getType(@) + " couldn't be cast to Boolean"))
1363+ }
1364+ let isGetDisabled = if (!(isAddressWhitelisted(i.caller)))
1365+ then if (if (isGlobalShutdown())
1366+ then true
1367+ else (cfgPoolStatus == PoolShutdown))
1368+ then true
1369+ else isPoolOneTokenOperationsDisabled
1370+ else false
1371+ let checks = [if (if (!(isGetDisabled))
1372+ then true
1373+ else isManager(i))
1374+ then true
1375+ else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
1376+ then true
1377+ else throwErr("no payments are expected")]
1378+ if ((checks == checks))
13881379 then {
1389- let dLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyDLp), "0")), fmtErr("invalid dLp"))
1390- let $t04888148945 = refreshDLpInternal(0, 0, 0)
1391- let dLpUpdateActions = $t04888148945._1
1392- let updatedDLp = $t04888148945._2
1393- let actions = if ((dLp != updatedDLp))
1394- then dLpUpdateActions
1395- else throwErr("nothing to refresh")
1396- $Tuple2(actions, toString(updatedDLp))
1380+ let outAssetId = parseAssetId(outAssetIdStr)
1381+ let userAddress = i.caller
1382+ let txId = i.transactionId
1383+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1384+ if ((currentKLp == currentKLp))
1385+ then {
1386+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1387+ if ((unstakeInv == unstakeInv))
1388+ then {
1389+ let $t05298053131 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1390+ if (($t05298053131 == $t05298053131))
1391+ then {
1392+ let outInAmountAsset = $t05298053131._5
1393+ let bonus = $t05298053131._4
1394+ let feeAmount = $t05298053131._3
1395+ let commonState = $t05298053131._2
1396+ let amountEstimated = $t05298053131._1
1397+ let amount = if (if ((minOutAmount > 0))
1398+ then (minOutAmount > amountEstimated)
1399+ else false)
1400+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1401+ else amountEstimated
1402+ let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1403+ if ((burnInv == burnInv))
1404+ then {
1405+ let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
1406+ let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
1407+ let sendFee = if ((feeAmount > 0))
1408+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1409+ else nil
1410+ let $t05379054037 = {
1411+ let feeAmountForCalc = if ((this == feeCollectorAddress))
1412+ then 0
1413+ else feeAmount
1414+ if (outInAmountAsset)
1415+ then $Tuple2(-((amount + feeAmountForCalc)), 0)
1416+ else $Tuple2(0, -((amount + feeAmountForCalc)))
1417+ }
1418+ let amountAssetBalanceDelta = $t05379054037._1
1419+ let priceAssetBalanceDelta = $t05379054037._2
1420+ let $t05404054148 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1421+ let refreshKLpActions = $t05404054148._1
1422+ let updatedKLp = $t05404054148._2
1423+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1424+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1425+ then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1426+ else throw("Strict value is not equal to itself.")
1427+ }
1428+ else throw("Strict value is not equal to itself.")
1429+ }
1430+ else throw("Strict value is not equal to itself.")
1431+ }
1432+ else throw("Strict value is not equal to itself.")
1433+ }
1434+ else throw("Strict value is not equal to itself.")
13971435 }
13981436 else throw("Strict value is not equal to itself.")
13991437 }
14001438
14011439
14021440
14031441 @Callable(i)
1404-func getOneTknV2READONLY (outAssetId,lpAssetAmount) = {
1405- let amId = toBase58String(value(cfgAmountAssetId))
1406- let prId = toBase58String(value(cfgPriceAssetId))
1407- let lpId = toBase58String(value(cfgLpAssetId))
1408- let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
1409- let lpEmission = toBigInt(valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "invalid lp asset").quantity)
1410- let D0 = getD(xp)
1411- let D1 = (D0 - fraction(toBigInt(lpAssetAmount), D0, lpEmission))
1412- let index = if ((outAssetId == amId))
1413- then 0
1414- else if ((outAssetId == prId))
1415- then 1
1416- else throw("invalid out asset id")
1417- let newY = getYD(xp, index, D1)
1418- let dy = (xp[index] - newY)
1419- let totalGetRaw = max([0, toInt((dy - big1))])
1420- let $t04995550010 = takeFee(totalGetRaw, outFee)
1421- let totalGet = $t04995550010._1
1422- let feeAmount = $t04995550010._2
1423- $Tuple2(nil, $Tuple2(totalGet, feeAmount))
1424- }
1425-
1426-
1427-
1428-@Callable(i)
1429-func getOneTknV2WithBonusREADONLY (outAssetId,lpAssetAmount) = {
1430- let amId = toBase58String(value(cfgAmountAssetId))
1431- let prId = toBase58String(value(cfgPriceAssetId))
1432- let lpId = toBase58String(value(cfgLpAssetId))
1433- let amBalance = getAccBalance(amId)
1434- let prBalance = getAccBalance(prId)
1435- let $t05038550500 = {
1436- let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, lpAssetAmount], nil)
1437- if ($isInstanceOf(@, "(Int, Int)"))
1438- then @
1439- else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
1440- }
1441- let totalGet = $t05038550500._1
1442- let feeAmount = $t05038550500._2
1443- let r = ego("", lpId, lpAssetAmount, this)
1444- let outAmAmt = r._1
1445- let outPrAmt = r._2
1446- let sumOfGetAssets = (outAmAmt + outPrAmt)
1447- let bonus = if ((sumOfGetAssets == 0))
1448- then if ((totalGet == 0))
1449- then 0
1450- else throw("bonus calculation error")
1451- else fraction((totalGet - sumOfGetAssets), scale8, sumOfGetAssets)
1452- $Tuple2(nil, $Tuple3(totalGet, feeAmount, bonus))
1442+func get () = {
1443+ let res = commonGet(i)
1444+ let outAmAmt = res._1
1445+ let outPrAmt = res._2
1446+ let pmtAmt = res._3
1447+ let pmtAssetId = res._4
1448+ let state = res._5
1449+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1450+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1451+ if ((currentKLp == currentKLp))
1452+ then {
1453+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1454+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1455+ then {
1456+ let $t05524355324 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1457+ let refreshKLpActions = $t05524355324._1
1458+ let updatedKLp = $t05524355324._2
1459+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1460+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1461+ then ((withdrawState ++ state) ++ refreshKLpActions)
1462+ else throw("Strict value is not equal to itself.")
1463+ }
1464+ else throw("Strict value is not equal to itself.")
1465+ }
1466+ else throw("Strict value is not equal to itself.")
14531467 }
14541468
14551469
14561470
14571471 @Callable(i)
14581472 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
1459- let r = cg(i)
1460- let outAmAmt = r._1
1461- let outPrAmt = r._2
1462- let pmtAmt = r._3
1463- let pmtAssetId = r._4
1464- let state = r._5
1473+ let res = commonGet(i)
1474+ let outAmAmt = res._1
1475+ let outPrAmt = res._2
1476+ let pmtAmt = res._3
1477+ let pmtAssetId = res._4
1478+ let state = res._5
14651479 if ((noLessThenAmtAsset > outAmAmt))
1466- then throw(((("Failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
1480+ then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
14671481 else if ((noLessThenPriceAsset > outPrAmt))
1468- then throw(((("Failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
1482+ then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
14691483 else {
1470- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1471- if ((currentDLp == currentDLp))
1484+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1485+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1486+ if ((currentKLp == currentKLp))
14721487 then {
1473- let burnLPAssetOnFactory = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1488+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
14741489 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
14751490 then {
1476- let $t05166651747 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1477- let refreshDLpActions = $t05166651747._1
1478- let updatedDLp = $t05166651747._2
1479- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1480- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1481- then (state ++ refreshDLpActions)
1491+ let $t05641956500 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1492+ let refreshKLpActions = $t05641956500._1
1493+ let updatedKLp = $t05641956500._2
1494+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1495+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1496+ then ((withdrawState ++ state) ++ refreshKLpActions)
14821497 else throw("Strict value is not equal to itself.")
14831498 }
14841499 else throw("Strict value is not equal to itself.")
14851500 }
14861501 else throw("Strict value is not equal to itself.")
14871502 }
14881503 }
14891504
14901505
14911506
14921507 @Callable(i)
14931508 func unstakeAndGet (amount) = {
14941509 let checkPayments = if ((size(i.payments) != 0))
1495- then throw("No pmnts expd")
1510+ then throw("No payments are expected")
14961511 else true
14971512 if ((checkPayments == checkPayments))
14981513 then {
1499- let factoryCfg = gfc()
1500- let lpAssetId = cfgLpAssetId
1501- let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1502- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1503- if ((currentDLp == currentDLp))
1514+ let cfg = getPoolConfig()
1515+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1516+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1517+ if ((currentKLp == currentKLp))
15041518 then {
1505- let unstakeInv = invoke(staking, "unstake", [toBase58String(lpAssetId), amount], nil)
1519+ let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
15061520 if ((unstakeInv == unstakeInv))
15071521 then {
1508- let r = ego(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1509- let outAmAmt = r._1
1510- let outPrAmt = r._2
1511- let sts = parseIntValue(r._9)
1512- let state = r._10
1513- let v = if (if (igs())
1514- then true
1515- else (sts == PoolShutdown))
1516- then throw(("Blocked: " + toString(sts)))
1522+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1523+ let outAmAmt = res._1
1524+ let outPrAmt = res._2
1525+ let poolStatus = parseIntValue(res._9)
1526+ let state = res._10
1527+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1528+ let isGetDisabled = if (!(isAddressWhitelisted(i.caller)))
1529+ then if (isGlobalShutdown())
1530+ then true
1531+ else (cfgPoolStatus == PoolShutdown)
1532+ else false
1533+ let checkPoolStatus = if (isGetDisabled)
1534+ then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
15171535 else true
1518- if ((v == v))
1536+ if ((checkPoolStatus == checkPoolStatus))
15191537 then {
1520- let burnA = invoke(fca, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1521- if ((burnA == burnA))
1538+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1539+ if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
15221540 then {
1523- let $t05277452855 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1524- let refreshDLpActions = $t05277452855._1
1525- let updatedDLp = $t05277452855._2
1526- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1527- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1528- then (state ++ refreshDLpActions)
1541+ let $t05784857929 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1542+ let refreshKLpActions = $t05784857929._1
1543+ let updatedKLp = $t05784857929._2
1544+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1545+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1546+ then ((withdrawState ++ state) ++ refreshKLpActions)
15291547 else throw("Strict value is not equal to itself.")
15301548 }
15311549 else throw("Strict value is not equal to itself.")
15321550 }
15331551 else throw("Strict value is not equal to itself.")
15341552 }
15351553 else throw("Strict value is not equal to itself.")
15361554 }
15371555 else throw("Strict value is not equal to itself.")
15381556 }
15391557 else throw("Strict value is not equal to itself.")
15401558 }
15411559
15421560
15431561
15441562 @Callable(i)
15451563 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
1546- let isGetDisabled = if (igs())
1547- then true
1548- else (cfgPoolStatus == PoolShutdown)
1564+ let isGetDisabled = if (!(isAddressWhitelisted(i.caller)))
1565+ then if (isGlobalShutdown())
1566+ then true
1567+ else (cfgPoolStatus == PoolShutdown)
1568+ else false
15491569 let checks = [if (!(isGetDisabled))
15501570 then true
15511571 else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
15521572 then true
15531573 else throw("no payments are expected")]
15541574 if ((checks == checks))
15551575 then {
1556- let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1557- if ((currentDLp == currentDLp))
1576+ let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1577+ if ((currentKLp == currentKLp))
15581578 then {
15591579 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
15601580 if ((unstakeInv == unstakeInv))
15611581 then {
1562- let res = ego(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
1582+ let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
15631583 let outAmAmt = res._1
15641584 let outPrAmt = res._2
15651585 let state = res._10
1586+ let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
15661587 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
15671588 then true
15681589 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
15691590 then true
15701591 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
15711592 if ((checkAmounts == checkAmounts))
15721593 then {
1573- let burnLPAssetOnFactory = invoke(fca, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1594+ let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
15741595 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
15751596 then {
1576- let $t05410654187 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1577- let refreshDLpActions = $t05410654187._1
1578- let updatedDLp = $t05410654187._2
1579- let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1580- if ((isUpdatedDLpValid == isUpdatedDLpValid))
1581- then (state ++ refreshDLpActions)
1597+ let $t05940759488 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1598+ let refreshKLpActions = $t05940759488._1
1599+ let updatedKLp = $t05940759488._2
1600+ let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1601+ if ((isUpdatedKLpValid == isUpdatedKLpValid))
1602+ then ((withdrawState ++ state) ++ refreshKLpActions)
15821603 else throw("Strict value is not equal to itself.")
15831604 }
15841605 else throw("Strict value is not equal to itself.")
15851606 }
15861607 else throw("Strict value is not equal to itself.")
15871608 }
15881609 else throw("Strict value is not equal to itself.")
15891610 }
15901611 else throw("Strict value is not equal to itself.")
15911612 }
15921613 else throw("Strict value is not equal to itself.")
15931614 }
15941615
15951616
15961617
15971618 @Callable(i)
1598-func unstakeAndGetOneTknV2 (unstakeAmount,outAssetId,minOutAmount) = {
1599- let isPoolOneTokenOperationsDisabled = {
1600- let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1601- if ($isInstanceOf(@, "Boolean"))
1602- then @
1603- else throw(($getType(@) + " couldn't be cast to Boolean"))
1604- }
1605- let isGetDisabled = if (if (igs())
1606- then true
1607- else (cfgPoolStatus == PoolShutdown))
1608- then true
1609- else isPoolOneTokenOperationsDisabled
1610- let checks = [if (if (!(isGetDisabled))
1611- then true
1612- else isManager(i))
1613- then true
1614- else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
1615- then true
1616- else throwErr("no payments are expected")]
1617- if ((checks == checks))
1619+func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
1620+ then throw("permissions denied")
1621+ else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
1622+
1623+
1624+
1625+@Callable(i)
1626+func refreshKLp () = {
1627+ let lastRefreshedBlockHeight = valueOrElse(getInteger(keyKLpRefreshedHeight), 0)
1628+ let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= kLpRefreshDelay))
1629+ then unit
1630+ else throwErr(makeString([toString(kLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1631+ if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
16181632 then {
1619- let factoryCfg = gfc()
1620- let lpAssetId = cfgLpAssetId
1621- let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1622- let userAddress = i.caller
1623- let lpAssetRecipientAddress = this
1624- let unstakeInv = invoke(staking, "unstakeINTERNAL", [lpAssetId, unstakeAmount, userAddress.bytes, lpAssetRecipientAddress.bytes], nil)
1625- if ((unstakeInv == unstakeInv))
1626- then {
1627- let $t05520955397 = getOneTknV2Internal(outAssetId, minOutAmount, [AttachedPayment(lpAssetId, unstakeAmount)], i.caller, i.originCaller, i.transactionId)
1628- let state = $t05520955397._1
1629- let totalAmount = $t05520955397._2
1630- $Tuple2(state, totalAmount)
1631- }
1632- else throw("Strict value is not equal to itself.")
1633+ let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1634+ let $t06069260756 = refreshKLpInternal(0, 0, 0)
1635+ let kLpUpdateActions = $t06069260756._1
1636+ let updatedKLp = $t06069260756._2
1637+ let actions = if ((kLp != updatedKLp))
1638+ then kLpUpdateActions
1639+ else throwErr("nothing to refresh")
1640+ $Tuple2(actions, toString(updatedKLp))
16331641 }
16341642 else throw("Strict value is not equal to itself.")
16351643 }
16361644
16371645
16381646
16391647 @Callable(i)
1640-func putOneTknV2WithBonusREADONLY (paymentAmountRaw,paymentAssetId) = {
1641- let $t05552555628 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "", true)
1642- let lpAmount = $t05552555628._1
1643- let state = $t05552555628._2
1644- let feeAmount = $t05552555628._3
1645- let bonus = $t05552555628._4
1646- $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1647- }
1648-
1649-
1650-
1651-@Callable(i)
1652-func putOneTknV2WithoutTakeFeeREADONLY (paymentAmountRaw,paymentAssetId) = {
1653- let $t05577655880 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "", false)
1654- let lpAmount = $t05577655880._1
1655- let state = $t05577655880._2
1656- let feeAmount = $t05577655880._3
1657- let bonus = $t05577655880._4
1658- $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1659- }
1660-
1661-
1662-
1663-@Callable(i)
1664-func activate (amtAsStr,prAsStr) = if ((toString(i.caller) != toString(fca)))
1665- then throw("denied")
1666- else $Tuple2([StringEntry(aa(), amtAsStr), StringEntry(pa(), prAsStr), StringEntry(amp(), toString(ampInitial))], "success")
1667-
1668-
1669-
1670-@Callable(i)
1671-func getPoolConfigWrapperREADONLY () = $Tuple2(nil, gpc())
1648+func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
16721649
16731650
16741651
16751652 @Callable(i)
16761653 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
16771654
16781655
16791656
16801657 @Callable(i)
16811658 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
1682- let pr = calcPrices(amAmt, prAmt, lpAmt)
1683- $Tuple2(nil, [toString(pr[0]), toString(pr[1]), toString(pr[2])])
1659+ let prices = calcPrices(amAmt, prAmt, lpAmt)
1660+ $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
16841661 }
16851662
16861663
16871664
16881665 @Callable(i)
1689-func fromX18WrapperREADONLY (val,resScaleMult) = $Tuple2(nil, f1(parseBigIntValue(val), resScaleMult))
1666+func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
16901667
16911668
16921669
16931670 @Callable(i)
1694-func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(t1(origVal, origScaleMult)))
1671+func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
16951672
16961673
16971674
16981675 @Callable(i)
1699-func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(cpbi(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
1676+func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
17001677
17011678
17021679
17031680 @Callable(i)
1704-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, ""))
1681+func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
17051682
17061683
17071684
17081685 @Callable(i)
1709-func estimateGetOperationWrapperREADONLY (txId58,pmtAsId,pmtLpAmt,usrAddr) = {
1710- let r = ego(txId58, pmtAsId, pmtLpAmt, addressFromStringValue(usrAddr))
1711- $Tuple2(nil, $Tuple10(r._1, r._2, r._3, r._4, r._5, r._6, r._7, toString(r._8), r._9, r._10))
1686+func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
1687+ let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
1688+ $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
17121689 }
17131690
17141691
17151692
17161693 @Callable(i)
1717-func changeAmp () = {
1718- let cfg = invoke(fca, "getChangeAmpConfigREADONLY", [toString(this)], nil)
1719- let $t05828958488 = match cfg {
1720- case list: List[Any] =>
1721- $Tuple3({
1722- let @ = list[0]
1723- if ($isInstanceOf(@, "Int"))
1724- then @
1725- else throw(($getType(@) + " couldn't be cast to Int"))
1726- }, {
1727- let @ = list[1]
1728- if ($isInstanceOf(@, "Int"))
1729- then @
1730- else throw(($getType(@) + " couldn't be cast to Int"))
1731- }, {
1732- let @ = list[2]
1733- if ($isInstanceOf(@, "Int"))
1734- then @
1735- else throw(($getType(@) + " couldn't be cast to Int"))
1736- })
1737- case _ =>
1738- throwErr("invalid entry type")
1694+func statsREADONLY () = {
1695+ let cfg = getPoolConfig()
1696+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1697+ let amtAssetId = cfg[idxAmtAssetId]
1698+ let priceAssetId = cfg[idxPriceAssetId]
1699+ let iAmtAssetId = cfg[idxIAmtAssetId]
1700+ let iPriceAssetId = cfg[idxIPriceAssetId]
1701+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1702+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1703+ let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1704+ let accAmtAssetBalance = getAccBalance(amtAssetId)
1705+ let accPriceAssetBalance = getAccBalance(priceAssetId)
1706+ let pricesList = if ((poolLPBalance == 0))
1707+ then [zeroBigInt, zeroBigInt, zeroBigInt]
1708+ else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
1709+ let curPrice = 0
1710+ let lpAmtAssetShare = fromX18(pricesList[1], scale8)
1711+ let lpPriceAssetShare = fromX18(pricesList[2], scale8)
1712+ let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
1713+ $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))
17391714 }
1740- let delay = $t05828958488._1
1741- let delta = $t05828958488._2
1742- let target = $t05828958488._3
1743- let curAmp = parseIntValue(getStringValue(amp()))
1744- let newAmpRaw = (curAmp + delta)
1745- let newAmp = if ((0 > delta))
1746- then if ((target > newAmpRaw))
1747- then target
1748- else newAmpRaw
1749- else if ((newAmpRaw > target))
1750- then target
1751- else newAmpRaw
1752- let lastCall = valueOrElse(getInteger(keyChangeAmpLastCall()), 0)
1753- let wait = (lastCall + delay)
1754- let checks = [if ((height > wait))
1755- then true
1756- else throwErr("try again in few blocks"), if ((curAmp != newAmp))
1757- then true
1758- else throwErr("already reached target")]
1759- if ((checks == checks))
1760- then [IntegerEntry(keyChangeAmpLastCall(), height), StringEntry(amp(), toString(newAmp)), StringEntry(keyAmpHistory(height), toString(newAmp))]
1761- else throw("Strict value is not equal to itself.")
1715+
1716+
1717+
1718+@Callable(i)
1719+func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
1720+ let cfg = getPoolConfig()
1721+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1722+ let amAssetIdStr = cfg[idxAmtAssetId]
1723+ let amAssetId = fromBase58String(amAssetIdStr)
1724+ let prAssetIdStr = cfg[idxPriceAssetId]
1725+ let prAssetId = fromBase58String(prAssetIdStr)
1726+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1727+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1728+ let poolStatus = cfg[idxPoolStatus]
1729+ let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1730+ let accAmtAssetBalance = getAccBalance(amAssetIdStr)
1731+ let accPriceAssetBalance = getAccBalance(prAssetIdStr)
1732+ let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
1733+ let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
1734+ let curPriceX18 = if ((poolLPBalance == 0))
1735+ then zeroBigInt
1736+ else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
1737+ let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
1738+ let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
1739+ let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
1740+ let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
1741+ let calcLpAmt = estPut._1
1742+ let curPriceCalc = estPut._3
1743+ let amBalance = estPut._4
1744+ let prBalance = estPut._5
1745+ let lpEmission = estPut._6
1746+ $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))
1747+ }
1748+
1749+
1750+
1751+@Callable(i)
1752+func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
1753+ let cfg = getPoolConfig()
1754+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1755+ let amAssetIdStr = cfg[idxAmtAssetId]
1756+ let amAssetId = fromBase58String(amAssetIdStr)
1757+ let prAssetIdStr = cfg[idxPriceAssetId]
1758+ let prAssetId = fromBase58String(prAssetIdStr)
1759+ let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1760+ let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1761+ let poolStatus = cfg[idxPoolStatus]
1762+ let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1763+ let amBalanceRaw = getAccBalance(amAssetIdStr)
1764+ let prBalanceRaw = getAccBalance(prAssetIdStr)
1765+ let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
1766+ let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
1767+ let curPriceX18 = if ((poolLPBalance == 0))
1768+ then zeroBigInt
1769+ else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
1770+ let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
1771+ let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
1772+ let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
1773+ let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
1774+ let calcLpAmt = estPut._1
1775+ let curPriceCalc = estPut._3
1776+ let amBalance = estPut._4
1777+ let prBalance = estPut._5
1778+ let lpEmission = estPut._6
1779+ $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))
1780+ }
1781+
1782+
1783+
1784+@Callable(i)
1785+func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
1786+ let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
1787+ let outAmAmt = res._1
1788+ let outPrAmt = res._2
1789+ let amBalance = res._5
1790+ let prBalance = res._6
1791+ let lpEmission = res._7
1792+ let curPrice = res._8
1793+ let poolStatus = parseIntValue(res._9)
1794+ $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))
17621795 }
17631796
17641797
17651798 @Verifier(tx)
17661799 func verify () = {
1767- let targetPublicKey = match m() {
1800+ let targetPublicKey = match managerPublicKeyOrUnit() {
17681801 case pk: ByteVector =>
17691802 pk
17701803 case _: Unit =>
17711804 tx.senderPublicKey
17721805 case _ =>
17731806 throw("Match error")
17741807 }
17751808 match tx {
17761809 case order: Order =>
1777- let matcherPub = mp()
1778- let $t05940059517 = if (skipOrderValidation())
1810+ let matcherPub = getMatcherPubOrFail()
1811+ let $t06941869646 = if (skipOrderValidation())
17791812 then $Tuple2(true, "")
17801813 else validateMatcherOrderAllowed(order)
1781- let orderValid = $t05940059517._1
1782- let orderValidInfo = $t05940059517._2
1783- let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
1814+ let orderValid = $t06941869646._1
1815+ let orderValidInfo = $t06941869646._2
17841816 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
1785- if (if (if (orderValid)
1786- then senderValid
1787- else false)
1817+ if (if (orderValid)
17881818 then matcherValid
17891819 else false)
17901820 then true
1791- else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
1821+ else throwOrderError(orderValid, orderValidInfo, matcherValid)
17921822 case s: SetScriptTransaction =>
17931823 if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
17941824 then true
17951825 else {
17961826 let newHash = blake2b256(value(s.script))
1797- let allowedHash = fromBase64String(value(getString(fca, keyAllowedLpStableScriptHash())))
1827+ let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
17981828 let currentHash = scriptHash(this)
17991829 if ((allowedHash == newHash))
18001830 then (currentHash != newHash)
18011831 else false
18021832 }
18031833 case _ =>
18041834 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
18051835 }
18061836 }
18071837

github/deemru/w8io/169f3d6 
514.12 ms