tx · Akkr5XfNpiNvetyT2BetD2mAY3dQfNoP7qpio7T749iE

3PBxqamajfw2cHR2wmv5usiWxBncKLdXVdu:  -0.04000000 Waves

2023.05.17 17:26 [3647504] smart account 3PBxqamajfw2cHR2wmv5usiWxBncKLdXVdu > SELF 0.00000000 Waves

{ "type": 13, "id": "Akkr5XfNpiNvetyT2BetD2mAY3dQfNoP7qpio7T749iE", "fee": 4000000, "feeAssetId": null, "timestamp": 1684333366565, "version": 2, "chainId": 87, "sender": "3PBxqamajfw2cHR2wmv5usiWxBncKLdXVdu", "senderPublicKey": "3LWgDbfjghzhn2YFkfeuWRPvAWwnd16Ycs6dP2MYYZsM", "proofs": [ "oPYrYYAwQU1oUYCnqV97FgJY9R88LDQjDWUx98GRE5S7nSspLhQjXJCbwTAneUKcHKXhjj3cjgNFPfYPjhNZ6RR" ], "script": "base64:BgKALQgCEgUKAwEEARIHCgUBBAEIARIDCgEIEgQKAgEEEgQKAgEEEgMKAQESABIECgIIARIAEgQKAggBEgQKAggBEgQKAgEBEgMKAQESBQoDAQEBEgUKAwEIARIECgIBCBIECgIBCBIECgIICBIAEgMKAQgSBQoDAQEBEgQKAggBEgQKAgEBEgQKAggIEgsKCQgBAQIBAggEBBIGCgQICAEIEgAiBnNjYWxlOCIMc2NhbGU4QmlnSW50IgdzY2FsZTE4Igp6ZXJvQmlnSW50IgRiaWcwIgRiaWcxIgRiaWcyIgRiaWczIgRiaWc0IgpzbGlwcGFnZTREIgt3YXZlc1N0cmluZyIKYW1wSW5pdGlhbCIFQW11bHQiBURjb252IgNTRVAiBUVNUFRZIgpQb29sQWN0aXZlIgpQb29sUHV0RGlzIg5Qb29sTWF0Y2hlckRpcyIMUG9vbFNodXRkb3duIg5pZHhQb29sQWRkcmVzcyIJaWR4UG9vbFN0IglpZHhMUEFzSWQiCWlkeEFtQXNJZCIJaWR4UHJBc0lkIgtpZHhBbXRBc0RjbSINaWR4UHJpY2VBc0RjbSILaWR4SUFtdEFzSWQiDWlkeElQcmljZUFzSWQiD2lkeEZhY3RTdGFrQ250ciISaWR4RmFjdG9yeVJlc3RDbnRyIhBpZHhGYWN0U2xpcHBDbnRyIhFpZHhGYWN0R3d4UmV3Q250ciIKZmVlRGVmYXVsdCICdDEiB29yaWdWYWwiDW9yaWdTY2FsZU11bHQiCHQxQmlnSW50IgJmMSIDdmFsIg9yZXN1bHRTY2FsZU11bHQiDGZyb21YMThSb3VuZCIFcm91bmQiAnQyIgJmMiICdHMiA2FtdCIIcmVzU2NhbGUiCGN1clNjYWxlIgNhYnMiCWFic0JpZ0ludCICZmMiE2tleU1hbmFnZXJQdWJsaWNLZXkiFmtleU1hbmFnZXJWYXVsdEFkZHJlc3MiAnBsIgJwaCIBaCIBdCIDcGF1IgJ1YSIEdHhJZCIDZ2F1IgJhYSICcGEiA2FtcCINa2V5QW1wSGlzdG9yeSIMaGVpZ2h0QmxvY2tzIhRrZXlDaGFuZ2VBbXBMYXN0Q2FsbCIGa2V5RmVlIgNmZWUiBmtleURMcCIVa2V5RExwUmVmcmVzaGVkSGVpZ2h0IhJrZXlETHBSZWZyZXNoRGVsYXkiFmRMcFJlZnJlc2hEZWxheURlZmF1bHQiD2RMcFJlZnJlc2hEZWxheSIEZmNmZyIEbXRwayICcGMiBmlBbXRBcyIFaVByQXMiA21iYSIFYkFTdHIiA2FwcyIca2V5QWxsb3dlZExwU3RhYmxlU2NyaXB0SGFzaCIWa2V5RmVlQ29sbGVjdG9yQWRkcmVzcyIWa2V5U2tpcE9yZGVyVmFsaWRhdGlvbiILcG9vbEFkZHJlc3MiD3Rocm93T3JkZXJFcnJvciIKb3JkZXJWYWxpZCIOb3JkZXJWYWxpZEluZm8iC3NlbmRlclZhbGlkIgxtYXRjaGVyVmFsaWQiF2FkZHJlc3NGcm9tU3RyaW5nT3JUaGlzIg1hZGRyZXNzU3RyaW5nIgckbWF0Y2gwIgFhIhxnZXRNYW5hZ2VyVmF1bHRBZGRyZXNzT3JUaGlzIg5mYWN0b3J5QWRkcmVzcyIDZmNhIgFzIgRzdHJmIgRhZGRyIgNrZXkiBGludGYiCHRocm93RXJyIgNtc2ciBmZtdEVyciIFaW5GZWUiAUAiBm91dEZlZSIBQSIDaWdzIgJtcCITZmVlQ29sbGVjdG9yQWRkcmVzcyIDZ3BjIgVhbXRBcyIHcHJpY2VBcyIIaVByaWNlQXMiDHBhcnNlQXNzZXRJZCIFaW5wdXQiD2Fzc2V0SWRUb1N0cmluZyIPcGFyc2VQb29sQ29uZmlnIgpwb29sQ29uZmlnIhBwb29sQ29uZmlnUGFyc2VkIgskdDA4NjA4ODc5NCIOY2ZnUG9vbEFkZHJlc3MiDWNmZ1Bvb2xTdGF0dXMiDGNmZ0xwQXNzZXRJZCIQY2ZnQW1vdW50QXNzZXRJZCIPY2ZnUHJpY2VBc3NldElkIhZjZmdBbW91bnRBc3NldERlY2ltYWxzIhVjZmdQcmljZUFzc2V0RGVjaW1hbHMiA2dmYyINZmFjdG9yeUNvbmZpZyIPc3Rha2luZ0NvbnRyYWN0Ig9zbGlwYWdlQ29udHJhY3QiC2d3eENvbnRyYWN0IgxyZXN0Q29udHJhY3QiEWRhdGFQdXRBY3Rpb25JbmZvIg1pbkFtdEFzc2V0QW10Ig9pblByaWNlQXNzZXRBbXQiCG91dExwQW10IgVwcmljZSIKc2xpcEJ5VXNlciIMc2xpcHBhZ2VSZWFsIgh0eEhlaWdodCILdHhUaW1lc3RhbXAiDHNsaXBhZ2VBbUFtdCIMc2xpcGFnZVByQW10IhFkYXRhR2V0QWN0aW9uSW5mbyIOb3V0QW10QXNzZXRBbXQiEG91dFByaWNlQXNzZXRBbXQiB2luTHBBbXQiDWdldEFjY0JhbGFuY2UiB2Fzc2V0SWQiBGNwYmkiCHByQW10WDE4IghhbUFtdFgxOCIFY3BiaXIiA3ZhZCICQTEiAkEyIghzbGlwcGFnZSIEZGlmZiIEcGFzcyICdmQiAkQxIgJEMCIEc2xwZyIEZmFpbCIDcGNwIgphbUFzc2V0RGNtIgpwckFzc2V0RGNtIgVhbUFtdCIFcHJBbXQiC2FtdEFzQW10WDE4IgpwckFzQW10WDE4IgpjYWxjUHJpY2VzIgVscEFtdCIIYW10QXNEY20iB3ByQXNEY20iCHByaWNlWDE4IghscEFtdFgxOCINbHBQckluQW1Bc1gxOCINbHBQckluUHJBc1gxOCIPY2FsY3VsYXRlUHJpY2VzIgFwIgd0YWtlRmVlIgZhbW91bnQiCWZlZUFtb3VudCIEZ2V0RCICeHAiA3hwMCIDeHAxIgNhbm4iC3hwMF94cDFfbl9uIgVhbm5fcyIFYW5uXzEiCWNhbGNETmV4dCIBZCICZGQiA2RkZCICZHAiBGNhbGMiA2FjYyIBaSIFZE5leHQiCGREaWZmUmF3IgVkRGlmZiIDYXJyIg0kdDAxMzI5OTEzMzQ3IgIkbCICJHMiBSRhY2MwIgUkZjBfMSICJGEiAiRpIgUkZjBfMiIFZm91bmQiA2VnbyIGdHhJZDU4IgpwbXRBc3NldElkIghwbXRMcEFtdCILdXNlckFkZHJlc3MiBGxwSWQiBGFtSWQiBHBySWQiBWFtRGNtIgVwckRjbSIDc3RzIgdscEVtaXNzIglhbUJhbGFuY2UiDGFtQmFsYW5jZVgxOCIJcHJCYWxhbmNlIgxwckJhbGFuY2VYMTgiC2N1clByaWNlWDE4IghjdXJQcmljZSILcG10THBBbXRYMTgiCmxwRW1pc3NYMTgiC291dEFtQW10WDE4IgtvdXRQckFtdFgxOCIIb3V0QW1BbXQiCG91dFByQW10IgVzdGF0ZSIDZXBvIgdpbkFtQW10IgZpbkFtSWQiB2luUHJBbXQiBmluUHJJZCIGaXNFdmFsIgZlbWl0THAiCmlzT25lQXNzZXQiEHZhbGlkYXRlU2xpcHBhZ2UiBnBtdEFtdCIFcG10SWQiB2FtSWRTdHIiB3BySWRTdHIiBmFtdERjbSIIcHJpY2VEY20iBGxwRW0iD2luQW1Bc3NldEFtdFgxOCIPaW5QckFzc2V0QW10WDE4Igx1c2VyUHJpY2VYMTgiAXIiBmNoZWNrRCILc2xpcHBhZ2VYMTgiD3NsaXBwYWdlUmVhbFgxOCINbHBFbWlzc2lvblgxOCIKcHJWaWFBbVgxOCIKYW1WaWFQclgxOCIMZXhwZWN0ZWRBbXRzIhFleHBBbXRBc3NldEFtdFgxOCITZXhwUHJpY2VBc3NldEFtdFgxOCIJY2FsY0xwQW10Ig5jYWxjQW1Bc3NldFBtdCIOY2FsY1ByQXNzZXRQbXQiDHNsaXBwYWdlQ2FsYyIJZW1pdExwQW10IgZhbURpZmYiBnByRGlmZiINJHQwMjExMDkyMTQ1NCIKd3JpdGVBbUFtdCIKd3JpdGVQckFtdCILY29tbW9uU3RhdGUiBWdldFlEIgFEIgFuIgF4IgphUHJlY2lzaW9uIgFjIgFiIgNjdXIiDSR0MDIyNjQ5MjI2NjkiAXkiBXlOZXh0IgV5RGlmZiINJHQwMjI5NzYyMzAyMyIHY2FsY0RMcCINYW1vdW50QmFsYW5jZSIMcHJpY2VCYWxhbmNlIgpscEVtaXNzaW9uIgp1cGRhdGVkRExwIg5jYWxjQ3VycmVudERMcCIQYW1vdW50QXNzZXREZWx0YSIPcHJpY2VBc3NldERlbHRhIhRscEFzc2V0RW1pc3Npb25EZWx0YSISYW1vdW50QXNzZXRCYWxhbmNlIhFwcmljZUFzc2V0QmFsYW5jZSIPbHBBc3NldEVtaXNzaW9uIgpjdXJyZW50RExwIhJyZWZyZXNoRExwSW50ZXJuYWwiF2Ftb3VudEFzc2V0QmFsYW5jZURlbHRhIhZwcmljZUFzc2V0QmFsYW5jZURlbHRhIgdhY3Rpb25zIhJ2YWxpZGF0ZVVwZGF0ZWRETHAiBm9sZERMcCIbdmFsaWRhdGVNYXRjaGVyT3JkZXJBbGxvd2VkIgVvcmRlciIRYW1vdW50QXNzZXRBbW91bnQiEHByaWNlQXNzZXRBbW91bnQiDSR0MDI1MjIxMjU0MzMiA2RMcCINJHQwMjU3NzUyNTg3NSINdW51c2VkQWN0aW9ucyIGZExwTmV3Igxpc09yZGVyVmFsaWQiBGluZm8iAmNnIgNwbXQiAmNwIgZjYWxsZXIiB2FtQXNQbXQiB3ByQXNQbXQiDWNhbGNQdXRPbmVUa24iCXBtdEFtdFJhdyILd2l0aFRha2VGZWUiDWNoZWNoRW1pc3Npb24iDSR0MDI4NTMxMjg5OTMiDGFtQmFsYW5jZU9sZCIMcHJCYWxhbmNlT2xkIg0kdDAyODk5OTI5MTc1IgthbUFtb3VudFJhdyILcHJBbW91bnRSYXciDSR0MDI5MTc5Mjk0MzMiCGFtQW1vdW50IghwckFtb3VudCIMYW1CYWxhbmNlTmV3IgxwckJhbGFuY2VOZXciCGxwQW1vdW50Ig5wb29sUHJvcG9ydGlvbiIPYW1vdW50QXNzZXRQYXJ0Ig5wcmljZUFzc2V0UGFydCIJbHBBbXRCb3RoIgVib251cyITZ2V0T25lVGtuVjJJbnRlcm5hbCIKb3V0QXNzZXRJZCIMbWluT3V0QW1vdW50IghwYXltZW50cyIMb3JpZ2luQ2FsbGVyIg10cmFuc2FjdGlvbklkIgphbURlY2ltYWxzIgpwckRlY2ltYWxzIgpwb29sU3RhdHVzIg0kdDAzMTU0NTMxNjU2Igh0b3RhbEdldCILdG90YWxBbW91bnQiDSR0MDMxODQ2MzIxNTMiBW91dEFtIgVvdXRQciIIY3VyUHJYMTgiBWN1clByIhFvdXRBc3NldElkT3JXYXZlcyIQc2VuZEZlZVRvTWF0Y2hlciIEYnVybiINJHQwMzI5MzgzMzI4OCIQZmVlQW1vdW50Rm9yQ2FsYyIQb3V0SW5BbW91bnRBc3NldCINJHQwMzMyOTEzMzM5OSIRcmVmcmVzaERMcEFjdGlvbnMiEWlzVXBkYXRlZERMcFZhbGlkIhZtYW5hZ2VyUHVibGljS2V5T3JVbml0IhNtYW5hZ2VyVmF1bHRBZGRyZXNzIgJwZCIJaXNNYW5hZ2VyIgJwayILbXVzdE1hbmFnZXIiBGdldFkiCWlzUmV2ZXJzZSITcG9vbEFtb3VudEluQmFsYW5jZSINJHQwMzQ4ODYzNDkwNiINJHQwMzUyMzczNTI4NCITc2tpcE9yZGVyVmFsaWRhdGlvbiINY2xlYW5BbW91bnRJbiINZmVlUG9vbEFtb3VudCINJHQwMzU2MzYzNjA2MCIIYXNzZXRPdXQiAmR5Igt0b3RhbEdldFJhdyIFbmV3WHAiBG5ld0QiDGFtb3VudE91dE1pbiIJYWRkcmVzc1RvIgtzd2FwQ29udGFjdCIGY2hlY2tzIgdhc3NldEluIg0kdDAzNzQ5NjM3ODkwIghjaGVja01pbiIEc2xpcCIJYXV0b1N0YWtlIgdmYWN0Q2ZnIgtzdGFraW5nQ250ciIIc2xpcENudHIiCmFtQXNzZXRQbXQiCnByQXNzZXRQbXQiAWUiCWxwQXNzZXRJZCICZWwiBmxlZ2FjeSICc2EiAnNwIghscFRybnNmciICc3MiDSR0MDQyMDM0NDIxNzYiBWNoZWNrIhRscEFzc2V0RW1pc3Npb25BZnRlciIgaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWQiDWlzUHV0RGlzYWJsZWQiDSR0MDQzODE3NDM5NzUiB2VzdGltTFAiDSR0MDQ0ODYwNDUyMDkiFHBheW1lbnRJbkFtb3VudEFzc2V0Ig0kdDA0NTIxMjQ1MzIwIgdtYXhTbHBnIgZlc3RQdXQiDSR0MDQ2MzUwNDY0MTUiCW91dEFtdEFtdCINJHQwNDc1ODg0NzY3MCINaXNHZXREaXNhYmxlZCINJHQwNDgyODg0ODQ0MyIYbGFzdFJlZnJlc2hlZEJsb2NrSGVpZ2h0Ih1jaGVja0xhc3RSZWZyZXNoZWRCbG9ja0hlaWdodCINJHQwNDg5Njc0OTAzMSIQZExwVXBkYXRlQWN0aW9ucyINbHBBc3NldEFtb3VudCIFaW5kZXgiBG5ld1kiDSR0MDUwMDQxNTAwOTYiDSR0MDUwNDcxNTA1ODYiDnN1bU9mR2V0QXNzZXRzIhJub0xlc3NUaGVuQW10QXNzZXQiFG5vTGVzc1RoZW5QcmljZUFzc2V0IhRidXJuTFBBc3NldE9uRmFjdG9yeSINJHQwNTE3NTI1MTgzMyINY2hlY2tQYXltZW50cyIKZmFjdG9yeUNmZyIHc3Rha2luZyIKdW5zdGFrZUludiIBdiIFYnVybkEiDSR0MDUyODYwNTI5NDEiDXVuc3Rha2VBbW91bnQiFW5vTGVzc1RoZW5BbW91bnRBc3NldCIDcmVzIgxjaGVja0Ftb3VudHMiDSR0MDU0MTkyNTQyNzMiF2xwQXNzZXRSZWNpcGllbnRBZGRyZXNzIg0kdDA1NTI5NTU1NDgzIhBwYXltZW50QW1vdW50UmF3Ig5wYXltZW50QXNzZXRJZCINJHQwNTU2MTE1NTcxNCINJHQwNTU4NjI1NTk2NiIIYW10QXNTdHIiB3ByQXNTdHIiAnByIgxyZXNTY2FsZU11bHQiB3VzckFkZHIiB3BtdEFzSWQiA2NmZyINJHQwNTgzNzU1ODU3NCIEbGlzdCIFZGVsYXkiBWRlbHRhIgZ0YXJnZXQiBmN1ckFtcCIJbmV3QW1wUmF3IgZuZXdBbXAiCGxhc3RDYWxsIgR3YWl0IgJ0eCIGdmVyaWZ5Ig90YXJnZXRQdWJsaWNLZXkiCm1hdGNoZXJQdWIiDSR0MDU5NTA3NTk2MjQiB25ld0hhc2giC2FsbG93ZWRIYXNoIgtjdXJyZW50SGFzaIUBAAFhAIDC1y8AAWIJALYCAQCAwtcvAAFjCQC2AgEAgICQu7rWrfANAAFkCQC2AgEAAAABZQkAtgIBAAAAAWYJALYCAQABAAFnCQC2AgEAAgABaAkAtgIBAAMAAWkJALYCAQAEAAFqCQC2AgEJAGUCBQFhCQBpAgkAaAIFAWEAAQUBYQABawIFV0FWRVMAAWwAMgABbQIDMTAwAAFuAgExAAFvAgJfXwABcAIAAAFxAAEAAXIAAgABcwADAAF0AAQAAXUAAQABdgACAAF3AAMAAXgABAABeQAFAAF6AAYAAUEABwABQgAIAAFDAAkAAUQAAQABRQAGAAFGAAcAAUcACgABSAkAawMACgUBYQCQTgEBSQIBSgFLCQC8AgMJALYCAQUBSgUBYwkAtgIBBQFLAQFMAgFKAUsJALwCAwUBSgUBYwUBSwEBTQIBTgFPCQCgAwEJALwCAwUBTgkAtgIBBQFPBQFjAQFQAwFOAU8BUQkAoAMBCQC9AgQFAU4JALYCAQUBTwUBYwUBUQEBUgIBSgFLCQC8AgMFAUoFAWMJALYCAQUBSwEBUwIBTgFPCQC8AgMFAU4JALYCAQUBTwUBYwEBVAMBVQFWAVcJAGsDBQFVBQFWBQFXAQFYAQFOAwkAvwICBQFkBQFOCQC+AgEFAU4FAU4BAVkBAU4DCQC/AgIFAWQFAU4JAL4CAQUBTgUBTgEBWgACEyVzX19mYWN0b3J5Q29udHJhY3QBAmFhAAIUJXNfX21hbmFnZXJQdWJsaWNLZXkBAmFiAAIXJXNfX21hbmFnZXJWYXVsdEFkZHJlc3MBAmFjAAIRJXMlc19fcHJpY2VfX2xhc3QBAmFkAgJhZQJhZgkAuQkCCQDMCAICGCVzJXMlZCVkX19wcmljZV9faGlzdG9yeQkAzAgCCQCkAwEFAmFlCQDMCAIJAKQDAQUCYWYFA25pbAUBbwECYWcCAmFoAmFpCQCsAgIJAKwCAgkArAICAgslcyVzJXNfX1BfXwUCYWgCAl9fBQJhaQECYWoCAmFoAmFpCQCsAgIJAKwCAgkArAICAgslcyVzJXNfX0dfXwUCYWgCAl9fBQJhaQECYWsAAg8lc19fYW1vdW50QXNzZXQBAmFsAAIOJXNfX3ByaWNlQXNzZXQBAmFtAAIHJXNfX2FtcAECYW4BAmFvCQCsAgICCyVzJWRfX2FtcF9fCQCkAwEFAmFvAQJhcAACFSVzX19jaGFuZ2VBbXBMYXN0Q2FsbAACYXECByVzX19mZWUAAmFyCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAmFxBQFIAAJhcwkAuQkCCQDMCAICAiVzCQDMCAICA2RMcAUDbmlsBQFvAAJhdAkAuQkCCQDMCAICAiVzCQDMCAICEmRMcFJlZnJlc2hlZEhlaWdodAUDbmlsBQFvAAJhdQkAuQkCCQDMCAICAiVzCQDMCAICD3JlZnJlc2hETHBEZWxheQUDbmlsBQFvAAJhdgAeAAJhdwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQJhdQUCYXYBAmF4AAIRJXNfX2ZhY3RvcnlDb25maWcBAmF5AAIYJXMlc19fbWF0Y2hlcl9fcHVibGljS2V5AQJhegICYUECYUIJAKwCAgkArAICCQCsAgIJAKwCAgIIJWQlZCVzX18FAmFBAgJfXwUCYUICCF9fY29uZmlnAQJhQwECYUQJAKwCAgIoJXMlcyVzX19tYXBwaW5nc19fYmFzZUFzc2V0MmludGVybmFsSWRfXwUCYUQBAmFFAAIMJXNfX3NodXRkb3duAQJhRgACHSVzX19hbGxvd2VkTHBTdGFibGVTY3JpcHRIYXNoAQJhRwACFyVzX19mZWVDb2xsZWN0b3JBZGRyZXNzAQJhSAECYUkJAKwCAgIbJXMlc19fc2tpcE9yZGVyVmFsaWRhdGlvbl9fBQJhSQECYUoEAmFLAmFMAmFNAmFOCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgICJG9yZGVyIHZhbGlkYXRpb24gZmFpbGVkOiBvcmRlclZhbGlkPQkApQMBBQJhSwICICgFAmFMAgEpAg0gc2VuZGVyVmFsaWQ9CQClAwEFAmFNAg4gbWF0Y2hlclZhbGlkPQkApQMBBQJhTgECYU8BAmFQBAJhUQkApggBBQJhUAMJAAECBQJhUQIHQWRkcmVzcwQCYVIFAmFRBQJhUgUEdGhpcwECYVMABAJhVAQCYVEJAKIIAQkBAVoAAwkAAQIFAmFRAgZTdHJpbmcEAmFVBQJhUQkBAmFPAQUCYVUFBHRoaXMEAmFRCQCdCAIFAmFUCQECYWIAAwkAAQIFAmFRAgZTdHJpbmcEAmFWBQJhUQkBAmFPAQUCYVYFBHRoaXMBAmFXAgJhWAJhWQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFAmFYBQJhWQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQJhWAkAzAgCAgEuCQDMCAIFAmFZCQDMCAICDCBub3QgZGVmaW5lZAUDbmlsAgABAmFaAgJhWAJhWQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFAmFYBQJhWQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQJhWAkAzAgCAgEuCQDMCAIFAmFZCQDMCAICDCBub3QgZGVmaW5lZAUDbmlsAgABAmJhAQJiYgkAAgEJALkJAgkAzAgCAg9scF9zdGFibGUucmlkZToJAMwIAgUCYmIFA25pbAIBIAECYmMBAmJiCQC5CQIJAMwIAgIPbHBfc3RhYmxlLnJpZGU6CQDMCAIFAmJiBQNuaWwCASAAAmFVCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYVcCBQR0aGlzCQEBWgAAAmJkCgACYmUJAPwHBAUCYVUCEGdldEluRmVlUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJiZQIDSW50BQJiZQkAAgEJAKwCAgkAAwEFAmJlAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQAAmJmCgACYmUJAPwHBAUCYVUCEWdldE91dEZlZVJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYmUCA0ludAUCYmUJAAIBCQCsAgIJAAMBBQJiZQIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AAJiZwkBAmFXAgUEdGhpcwkBAmFtAAECYmgACQELdmFsdWVPckVsc2UCCQCbCAIFAmFVCQECYUUABwECYmkACQDZBAEJAQJhVwIFAmFVCQECYXkAAAJiagkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFXAgUCYVUJAQJhRwABAmJrAAQCYmwJAQJhVwIFBHRoaXMJAQJhawAEAmJtCQECYVcCBQR0aGlzCQECYWwABAJibgkBAmFaAgUCYVUJAQJhQwEFAmJtBAJhQQkBAmFaAgUCYVUJAQJhQwEFAmJsCQC1CQIJAQJhVwIFAmFVCQECYXoCCQCkAwEFAmFBCQCkAwEFAmJuBQFvAQJibwECYnADCQAAAgUCYnAFAWsFBHVuaXQJANkEAQUCYnABAmJxAQJicAMJAAACBQJicAUEdW5pdAUBawkA2AQBCQEFdmFsdWUBBQJicAECYnIBAmJzCQCZCgcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYnMFAXUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJicwUBdgkA2QQBCQCRAwIFAmJzBQF3CQECYm8BCQCRAwIFAmJzBQF4CQECYm8BCQCRAwIFAmJzBQF5CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYnMFAXoJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJicwUBQQACYnQJAQJicgEJAQJiawAAAmJ1BQJidAACYnYIBQJidQJfMQACYncIBQJidQJfMgACYngIBQJidQJfMwACYnkIBQJidQJfNAACYnoIBQJidQJfNQACYkEIBQJidQJfNgACYkIIBQJidQJfNwECYkMACQC1CQIJAQJhVwIFAmFVCQECYXgABQFvAAJiRAkBAmJDAAACYkUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFAmJEBQFEAiBJbnZhbGlkIHN0YWtpbmcgY29udHJhY3QgYWRkcmVzcwACYkYJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFAmJEBQFGAiBJbnZhbGlkIHNsaXBhZ2UgY29udHJhY3QgYWRkcmVzcwACYkcJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFAmJEBQFHAhxJbnZhbGlkIGd3eCBjb250cmFjdCBhZGRyZXNzAAJiSAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUCYkQFAUUCHEludmFsaWQgZ3d4IGNvbnRyYWN0IGFkZHJlc3MBAmJJCgJiSgJiSwJiTAJiTQJiTgJiTwJiUAJiUQJiUgJiUwkAuQkCCQDMCAICFCVkJWQlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYkoJAMwIAgkApAMBBQJiSwkAzAgCCQCkAwEFAmJMCQDMCAIJAKQDAQUCYk0JAMwIAgkApAMBBQJiTgkAzAgCCQCkAwEFAmJPCQDMCAIJAKQDAQUCYlAJAMwIAgkApAMBBQJiUQkAzAgCCQCkAwEFAmJSCQDMCAIJAKQDAQUCYlMFA25pbAUBbwECYlQGAmJVAmJWAmJXAmJNAmJQAmJRCQC5CQIJAMwIAgIMJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYlUJAMwIAgkApAMBBQJiVgkAzAgCCQCkAwEFAmJXCQDMCAIJAKQDAQUCYk0JAMwIAgkApAMBBQJiUAkAzAgCCQCkAwEFAmJRBQNuaWwFAW8BAmJYAQJiWQMJAAACBQJiWQIFV0FWRVMICQDvBwEFBHRoaXMJYXZhaWxhYmxlCQDwBwIFBHRoaXMJANkEAQUCYlkBAmJaAgJjYQJjYgkAvAIDBQJjYQUBYwUCY2IBAmNjAwJjYQJjYgFRCQC9AgQFAmNhBQFjBQJjYgUBUQECY2QDAmNlAmNmAmNnBAJjaAkAvAIDCQC4AgIFAmNlBQJjZgUBYgUCY2YEAmNpCQC/AgIJALgCAgUCY2cJAQFYAQUCY2gFAWQDCQEBIQEFAmNpCQACAQkArAICAgpCaWcgc2xwZzogCQCmAwEFAmNoCQCUCgIFAmNpCQCZAwEJAMwIAgUCY2UJAMwIAgUCY2YFA25pbAECY2oDAmNrAmNsAmNtBAJjaAkAvAIDBQJjbAUBYgUCY2sEAmNuCQC/AgIFAmNtBQJjaAMDBQJjbgYJAL8CAgUCY2wFAmNrCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkApgMBBQJjbAIBIAkApgMBBQJjawIBIAkApgMBBQJjaAIBIAkApgMBBQJjbQUCY24BAmNvBAJjcAJjcQJjcgJjcwQCY3QJAQFJAgUCY3IFAmNwBAJjdQkBAUkCBQJjcwUCY3EJAQJiWgIFAmN1BQJjdAECY3YDAmNyAmNzAmN3BAJjeAUCYkEEAmN5BQJiQgQCY3oJAQJjbwQFAmN4BQJjeQUCY3IFAmNzBAJjYgkBAUkCBQJjcgUCY3gEAmNhCQEBSQIFAmNzBQJjeQQCY0EJAQFJAgUCY3cFAWEEAmNCCQECYloCBQJjYgUCY0EEAmNDCQECYloCBQJjYQUCY0EJAMwIAgUCY3oJAMwIAgUCY0IJAMwIAgUCY0MFA25pbAECY0QDAmNyAmNzAmN3BAJjRQkBAmN2AwUCY3IFAmNzBQJjdwkAzAgCCQEBTQIJAJEDAgUCY0UAAAUBYQkAzAgCCQEBTQIJAJEDAgUCY0UAAQUBYQkAzAgCCQEBTQIJAJEDAgUCY0UAAgUBYQUDbmlsAQJjRgICY0cCYXIEAmNIAwkAAAIFAmFyAAAAAAkAawMFAmNHBQJhcgUBYQkAlAoCCQBlAgUCY0cFAmNIBQJjSAECY0kBAmNKBAJjSwkAkQMCBQJjSgAABAJjTAkAkQMCBQJjSgABBAJhVgkAtwICBQJjSwUCY0wDCQAAAgUCYVYFAWUFAWUEAmFSCQENcGFyc2VJbnRWYWx1ZQEFAmJnBAJjTQkAaAIFAmFSAAIEAmNFCQC8AgMFAmNLBQJjTAUBZgQCY04JALwCAwUCY0UFAWkFAWYEAmNPCQC8AgMJALYCAQUCY00FAmFWBQFmBAJjUAkAtgIBCQBlAgUCY00AAQoBAmNRAQJjUgQCY1MJALwCAwUCY1IFAmNSBQFmBAJjVAkAvAIDBQJjUwUCY1IFAWYEAmNVCQC8AgMFAmNUBQFmBQJjTgkAvAIDCQC3AgIFAmNPCQC8AgMFAmNVBQFnBQFmBQJjUgkAtwICCQC8AgMFAmNQBQJjUgUBZgkAvAIDBQFoBQJjVQUBZgoBAmNWAgJjVwJjWAMIBQJjVwJfMgUCY1cEAmNSCAUCY1cCXzEEAmNZCQECY1EBBQJjUgQCY1oJALgCAgUCY1kJAQV2YWx1ZQEFAmNSBAJkYQMJAL8CAgUBZQUCY1oJAL4CAQUCY1oFAmNaAwkAwAICBQFmBQJkYQkAlAoCBQJjWQYJAJQKAgUCY1kHBAJkYgkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYJAMwIAgAHCQDMCAIACAkAzAgCAAkJAMwIAgAKCQDMCAIACwkAzAgCAAwJAMwIAgANCQDMCAIADgkAzAgCAA8JAMwIAgAQBQNuaWwEAmRjCgACZGQFAmRiCgACZGUJAJADAQUCZGQKAAJkZgkAlAoCBQJhVgcKAQJkZwICZGgCZGkDCQBnAgUCZGkFAmRlBQJkaAkBAmNWAgUCZGgJAJEDAgUCZGQFAmRpCgECZGoCAmRoAmRpAwkAZwIFAmRpBQJkZQUCZGgJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxNwkBAmRqAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgUCZGYAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEEAmNSCAUCZGMCXzEEAmRrCAUCZGMCXzIDBQJkawUCY1IJAAIBCQCsAgICGUQgY2FsY3VsYXRpb24gZXJyb3IsIEQgPSAJAKYDAQUCY1IBAmRsBAJkbQJkbgJkbwJkcAQCZHEFAmJ4BAJkcgkA2AQBCQEFdmFsdWUBBQJieQQCZHMJANgEAQkBBXZhbHVlAQUCYnoEAmR0BQJiQQQCZHUFAmJCBAJkdgkApAMBBQJidwQCZHcICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCZHECC1dyb25nIExQIGlkCHF1YW50aXR5AwkBAiE9AgkA2AQBBQJkcQUCZG4JAAIBAg9Xcm9uZyBwbXQgYXNzZXQEAmR4CQECYlgBBQJkcgQCZHkJAQFJAgUCZHgFAmR0BAJkegkBAmJYAQUCZHMEAmRBCQEBSQIFAmR6BQJkdQQCZEIJAQJiWgIFAmRBBQJkeQQCZEMJAQFNAgUCZEIFAWEEAmRECQEBSQIFAmRvBQFhBAJkRQkBAUkCBQJkdwUBYQQCZEYJALwCAwUCZHkFAmREBQJkRQQCZEcJALwCAwUCZEEFAmREBQJkRQQCZEgJAQFQAwUCZEYFAmR0BQVGTE9PUgQCZEkJAQFQAwUCZEcFAmR1BQVGTE9PUgQCZEoDCQAAAgUCZG0CAAUDbmlsCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmRwBQJkSAMJAAACBQJkcgIFV0FWRVMFBHVuaXQJANkEAQUCZHIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCZHAFAmRJAwkAAAIFAmRzAgVXQVZFUwUEdW5pdAkA2QQBBQJkcwkAzAgCCQELU3RyaW5nRW50cnkCCQECYWoCCQClCAEFAmRwBQJkbQkBAmJUBgUCZEgFAmRJBQJkbwUCZEMFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhYwAFAmRDCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYWQCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJkQwUDbmlsCQCcCgoFAmRIBQJkSQUCZHIFAmRzBQJkeAUCZHoFAmR3BQJkQgUCZHYFAmRKAQJkSw0CZG0CY2cCZEwCZE0CZE4CZE8CZHACZFACZFECZFICZFMCZFQCZFUEAmRxBQJieAQCZFYJANgEAQkBBXZhbHVlAQUCYnkEAmRXCQDYBAEJAQV2YWx1ZQEFAmJ6BAJkWAUCYkEEAmRZBQJiQgQCZHYJAKQDAQUCYncEAmRaCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmRxAghXciBscCBhcwhxdWFudGl0eQQCZHgDBQJkUAkBAmJYAQUCZFYDAwUCZFIJAAACBQJkVQUCZFYHCQBlAgkBAmJYAQUCZFYFAmRUAwUCZFIJAQJiWAEFAmRWCQBlAgkBAmJYAQUCZFYFAmRMBAJkegMFAmRQCQECYlgBBQJkVwMDBQJkUgkAAAIFAmRVBQJkVwcJAGUCCQECYlgBBQJkVwUCZFQDBQJkUgkBAmJYAQUCZFcJAGUCCQECYlgBBQJkVwUCZE4EAmVhCQEBSQIFAmRMBQJkWAQCZWIJAQFJAgUCZE4FAmRZBAJlYwkBAmJaAgUCZWIFAmVhBAJkeQkBAUkCBQJkeAUCZFgEAmRBCQEBSQIFAmR6BQJkWQQCY2wJAQJjSQEJAMwIAgUCZHkJAMwIAgUCZEEFA25pbAQCZWQDCQAAAgUCZFoAAAQCY2sJAQJjSQEJAMwIAgkAtwICBQJkeQUCZWEJAMwIAgkAtwICBQJkQQUCZWIFA25pbAQCZWUDCQC/AgIFAmNrBQJjbAYJAAIBAhxEMSBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIEQwAwkAAAIFAmVlBQJlZQQCZEIFAWQEAmVmBQFkBAJjQQUCY2sJAJcKBQkBAU0CBQJjQQUBYQkBAU0CBQJlYQUCZFgJAQFNAgUCZWIFAmRZCQECYloCCQC3AgIFAmRBBQJlYgkAtwICBQJkeQUCZWEFAmVmCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAJkQgkBAmJaAgUCZEEFAmR5BAJlZwkAvAIDCQEBWAEJALgCAgUCZEIFAmVjBQFjBQJkQgQCZWYJAQFJAgUCY2cFAWEDAwMFAmRTCQECIT0CBQJkQgUBZAcJAL8CAgUCZWcFAmVmBwkAAgEJAKwCAgkArAICCQCsAgICD1ByaWNlIHNsaXBwYWdlIAkApgMBBQJlZwIDID4gCQCmAwEFAmVmBAJlaAkBAUkCBQJkWgUBYQQCZWkJAL0CBAUCZWEJAQJjYwMFAmRBBQJkeQUHQ0VJTElORwUBYwUHQ0VJTElORwQCZWoJAL0CBAUCZWIFAWMJAQJjYwMFAmRBBQJkeQUFRkxPT1IFB0NFSUxJTkcEAmVrAwkAvwICBQJlaQUCZWIJAJQKAgUCZWoFAmViCQCUCgIFAmVhBQJlaQQCZWwIBQJlawJfMQQCZW0IBQJlawJfMgQCY2sJAQJjSQEJAMwIAgkAtwICBQJkeQUCZWwJAMwIAgkAtwICBQJkQQUCZW0FA25pbAQCZWUDCQC/AgIFAmNrBQJjbAYJAAIBAhxEMSBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIEQwAwkAAAIFAmVlBQJlZQQCY0EJALwCAwUCZWgJALgCAgUCY2sFAmNsBQJjbAkAlwoFCQEBUAMFAmNBBQFhBQVGTE9PUgkBAVADBQJlbAUCZFgFB0NFSUxJTkcJAQFQAwUCZW0FAmRZBQdDRUlMSU5HBQJkQgUCZWYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EAmVuCAUCZWQCXzEEAmVvCAUCZWQCXzIEAmVwCAUCZWQCXzMEAmRDCQEBTQIIBQJlZAJfNAUBYQQCZXEJAQFNAggFAmVkAl81BQFhAwkAZwIAAAUCZW4JAAIBAgdMUCA8PSAwBAJlcgMJAQEhAQUCZFEAAAUCZW4EAmVzCQBlAgUCZEwFAmVvBAJldAkAZQIFAmROBQJlcAQCZXUDAwUCZFIJAAACBQJkVQUCZFYHCQCUCgIFAmRUAAADAwUCZFIJAAACBQJkVQUCZFcHCQCUCgIAAAUCZFQJAJQKAgUCZW8FAmVwBAJldggFAmV1Al8xBAJldwgFAmV1Al8yBAJleAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFjAAUCZEMJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhZAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmRDCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZwIFAmRwBQJkbQkBAmJJCgUCZXYFAmV3BQJlcgUCZEMFAmNnBQJlcQUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZXMFAmV0BQNuaWwJAJ8KDQUCZW4FAmVyBQJkQwUCZHgFAmR6BQJkWgUCZHEFAmR2BQJleAUCZXMFAmV0BQJkTQUCZE8BAmV5AwJjSgJjWAJlegQCZUEFAWcEAmVCCQCRAwIFAmNKAwkAAAIFAmNYAAAAAQAABAJlQwkApwMBBQFtBAJhUgkAuQICCQCnAwEFAmJnBQJlQwQCYVYFAmVCBAJjTQkAuQICBQJhUgUCZUEEAmVECQC6AgIJALkCAgkAuQICCQC6AgIJALkCAgUCZXoFAmV6CQC5AgIFAmVCBQJlQQUCZXoFAmVDCQC5AgIFAmNNBQJlQQQCZUUJALgCAgkAtwICBQJhVgkAugICCQC5AgIFAmV6BQJlQwUCY00FAmV6CgECY1YCAmNXAmVGBAJlRwUCY1cEAmVICAUCZUcCXzEEAmRrCAUCZUcCXzIDCQECIT0CBQJkawUEdW5pdAUCY1cEAmVJCQC6AgIJALcCAgkAuQICBQJlSAUCZUgFAmVECQC3AgIJALkCAgUBZwUCZUgFAmVFBAJlSgkBAVkBCQC4AgIFAmVJCQEFdmFsdWUBBQJlSAMJAMACAgUBZgUCZUoJAJQKAgUCZUkFAmVGCQCUCgIFAmVJBQR1bml0BAJkYgkAzAgCAAAJAMwIAgABCQDMCAIAAgkAzAgCAAMJAMwIAgAECQDMCAIABQkAzAgCAAYJAMwIAgAHCQDMCAIACAkAzAgCAAkJAMwIAgAKCQDMCAIACwkAzAgCAAwJAMwIAgANCQDMCAIADgUDbmlsBAJlSwoAAmRkBQJkYgoAAmRlCQCQAwEFAmRkCgACZGYJAJQKAgUCZXoFBHVuaXQKAQJkZwICZGgCZGkDCQBnAgUCZGkFAmRlBQJkaAkBAmNWAgUCZGgJAJEDAgUCZGQFAmRpCgECZGoCAmRoAmRpAwkAZwIFAmRpBQJkZQUCZGgJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyAxNQkBAmRqAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgkBAmRnAgUCZGYAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwQCZUgIBQJlSwJfMQQCZGsIBQJlSwJfMgMJAQIhPQIFAmRrBQR1bml0BQJlSAkAAgEJAKwCAgIZWSBjYWxjdWxhdGlvbiBlcnJvciwgWSA9IAkApgMBBQJlSAECZUwDAmVNAmVOAmVPBAJlUAkAvAIDCQECY0kBCQDMCAIJAQFMAgUCZU0JALYCAQUCYkEJAMwIAgkBAUwCBQJlTgkAtgIBBQJiQgUDbmlsBQFjBQJlTwMJAAACBQJlTwUBZQUBZQUCZVABAmVRAwJlUgJlUwJlVAQCZVUJALgCAgkAtgIBCQECYlgBCQECYnEBBQJieQUCZVIEAmVWCQC4AgIJALYCAQkBAmJYAQkBAmJxAQUCYnoFAmVTBAJlVwkAuAICCQC2AgEICQEFdmFsdWUBCQDsBwEFAmJ4CHF1YW50aXR5BQJlVAQCZVgJAQJlTAMFAmVVBQJlVgUCZVcFAmVYAQJlWQMCZVoCZmECZVQEAmVVCQBkAgkBAmJYAQkBAmJxAQUCYnkFAmVaBAJlVgkAZAIJAQJiWAEJAQJicQEFAmJ6BQJmYQQCZVcJAGQCCAkBBXZhbHVlAQkA7AcBBQJieAhxdWFudGl0eQUCZVQEAmVQCQECZUwDCQC2AgEFAmVVCQC2AgEFAmVWCQC2AgEFAmVXBAJmYgkAzAgCCQEMSW50ZWdlckVudHJ5AgUCYXQFBmhlaWdodAkAzAgCCQELU3RyaW5nRW50cnkCBQJhcwkApgMBBQJlUAUDbmlsCQCUCgIFAmZiBQJlUAECZmMCAmZkAmVQAwkAwAICBQJlUAUCZmQGCQECYmEBAiJ1cGRhdGVkIERMcCBsb3dlciB0aGFuIGN1cnJlbnQgRExwAQJmZQECZmYEAmVVCQECYlgBCQECYnEBBQJieQQCZVYJAQJiWAEJAQJicQEFAmJ6BAJmZwgFAmZmBmFtb3VudAQCZmgJAG4ECAUCZmYGYW1vdW50CAUCZmYFcHJpY2UFAWEFBUZMT09SBAJmaQMJAAACCAUCZmYJb3JkZXJUeXBlBQNCdXkJAJQKAgUCZmcJAQEtAQUCZmgJAJQKAgkBAS0BBQJmZwUCZmgEAmVaCAUCZmkCXzEEAmZhCAUCZmkCXzIDAwMJAQJiaAAGCQAAAgUCYncFAXMGCQAAAgUCYncFAXQJAAIBAg1BZG1pbiBibG9ja2VkAwMJAQIhPQIICAUCZmYJYXNzZXRQYWlyC2Ftb3VudEFzc2V0BQJieQYJAQIhPQIICAUCZmYJYXNzZXRQYWlyCnByaWNlQXNzZXQFAmJ6CQACAQIJV3IgYXNzZXRzBAJmagkApwMBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAmFzAgEwBAJmawkBAmVZAwUCZVoFAmZhAAAEAmZsCAUCZmsCXzEEAmZtCAUCZmsCXzIEAmZuCQDAAgIFAmZtBQJmagQCZm8JALkJAgkAzAgCAgRkTHA9CQDMCAIJAKYDAQUCZmoJAMwIAgIIIGRMcE5ldz0JAMwIAgkApgMBBQJmbQkAzAgCAhQgYW1vdW50QXNzZXRCYWxhbmNlPQkAzAgCCQCkAwEFAmVVCQDMCAICEyBwcmljZUFzc2V0QmFsYW5jZT0JAMwIAgkApAMBBQJlVgkAzAgCAhkgYW1vdW50QXNzZXRCYWxhbmNlRGVsdGE9CQDMCAIJAKQDAQUCZVoJAMwIAgIYIHByaWNlQXNzZXRCYWxhbmNlRGVsdGE9CQDMCAIJAKQDAQUCZmEJAMwIAgIIIGhlaWdodD0JAMwIAgkApAMBBQZoZWlnaHQFA25pbAIACQCUCgIFAmZuBQJmbwECZnABAmNYAwkBAiE9AgkAkAMBCAUCY1gIcGF5bWVudHMAAQkAAgECCjEgcG1udCBleHAEAmZxCQEFdmFsdWUBCQCRAwIIBQJjWAhwYXltZW50cwAABAJkbgkBBXZhbHVlAQgFAmZxB2Fzc2V0SWQEAmRUCAUCZnEGYW1vdW50BAJlZAkBAmRsBAkA2AQBCAUCY1gNdHJhbnNhY3Rpb25JZAkA2AQBBQJkbgUCZFQIBQJjWAZjYWxsZXIEAmRICAUCZWQCXzEEAmRJCAUCZWQCXzIEAmR2CQENcGFyc2VJbnRWYWx1ZQEIBQJlZAJfOQQCZEoIBQJlZANfMTADAwkBAmJoAAYJAAACBQJkdgUBdAkAAgEJAKwCAgIPQWRtaW4gYmxvY2tlZDogCQCkAwEFAmR2CQCXCgUFAmRIBQJkSQUCZFQFAmRuBQJkSgECZnIKAmZzAmFpAmZ0AmZ1AmNnAmRRAmRSAmRTAmRUAmRVBAJlZAkBAmRLDQUCYWkFAmNnCAkBBXZhbHVlAQUCZnQGYW1vdW50CAkBBXZhbHVlAQUCZnQHYXNzZXRJZAgJAQV2YWx1ZQEFAmZ1BmFtb3VudAgJAQV2YWx1ZQEFAmZ1B2Fzc2V0SWQFAmZzCQAAAgUCYWkCAAUCZFEFAmRSBQJkUwUCZFQFAmRVBAJkdgkBDXBhcnNlSW50VmFsdWUBCAUCZWQCXzgDAwMJAQJiaAAGCQAAAgUCZHYFAXIGCQAAAgUCZHYFAXQJAAIBCQCsAgICCEJsb2NrZWQ6CQCkAwEFAmR2BQJlZAECZnYFAmZ3AmRuAmRwAmFpAmZ4BAJkcgkA2AQBCQEFdmFsdWUBBQJieQQCZHMJANgEAQkBBXZhbHVlAQUCYnoEAmRxBQJieAQCZFgFAmJBBAJkWQUCYkIEAmVXCQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCZHECEGludmFsaWQgbHAgYXNzZXQIcXVhbnRpdHkEAmZ5AwkAvwICBQJlVwUBZQYJAAIBAiJpbml0aWFsIGRlcG9zaXQgcmVxdWlyZXMgYWxsIGNvaW5zAwkAAAIFAmZ5BQJmeQQCZHgJAQJiWAEFAmRyBAJkegkBAmJYAQUCZHMEAmZ6AwkAAAIFAmFpAgAJAJQKAgUCZHgFAmR6AwkAAAIFAmRuBQJkcgMJAGYCBQJmdwUCZHgJAAIBAhZpbnZhbGlkIHBheW1lbnQgYW1vdW50CQCUCgIJAGUCBQJkeAUCZncFAmR6AwkAAAIFAmRuBQJkcwMJAGYCBQJmdwUCZHoJAAIBAhZpbnZhbGlkIHBheW1lbnQgYW1vdW50CQCUCgIFAmR4CQBlAgUCZHoFAmZ3CQACAQIQd3JvbmcgcG10QXNzZXRJZAQCZkEIBQJmegJfMQQCZkIIBQJmegJfMgQCZkMDCQAAAgUCZG4FAmRyCQCUCgIFAmZ3AAADCQAAAgUCZG4FAmRzCQCUCgIAAAUCZncJAAIBAg9pbnZhbGlkIHBheW1lbnQEAmZECAUCZkMCXzEEAmZFCAUCZkMCXzIEAmZGAwUCZngJAJUKAwgJAQJjRgIFAmZEBQJiZAJfMQgJAQJjRgIFAmZFBQJiZAJfMQgJAQJjRgIFAmZ3BQJiZAJfMgkAlQoDBQJmRAUCZkUAAAQCZkcIBQJmRgJfMQQCZkgIBQJmRgJfMgQCY0gIBQJmRgJfMwQCZkkJAGQCBQJmQQUCZkcEAmZKCQBkAgUCZkIFAmZIBAJjbAkBAmNJAQkAzAgCCQEBSQIFAmZBBQJiQQkAzAgCCQEBSQIFAmZCBQJiQgUDbmlsBAJjawkBAmNJAQkAzAgCCQEBSQIFAmZJBQJiQQkAzAgCCQEBSQIFAmZKBQJiQgUDbmlsBAJlZQMJAL8CAgUCY2sFAmNsBgkBBXRocm93AAMJAAACBQJlZQUCZWUEAmZLCQC9AgQFAmVXCQC4AgIFAmNrBQJjbAUCY2wFBUZMT09SBAJkQwkBAU0CCQECYloCCQEBSQIFAmZKBQJkWQkBAUkCBQJmSQUCZFgFAWEEAmV4CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYWMABQJkQwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFkAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZEMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFnAgUCZHAFAmFpCQECYkkKBQJmRAUCZkUJAKADAQUCZksFAmRDAAAAAAUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAAAAAAFA25pbAQCZkwJAGsDBQJmQgUBYQUCZkEEAmZNCQBrAwUCZncFAWEJAGQCBQJmTAUBYQQCZk4JAGUCBQJmdwUCZk0EAmZPCQC8AgMFAmVXCQC2AgEFAmZOCQC2AgEFAmZCBAJmUAkAoAMBCQC8AgMJALgCAgUCZksFAmZPBQFiBQJmTwkAlgoECQCgAwEFAmZLBQJleAUCY0gFAmZQCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJmUQYCZlICZlMCZlQCZnMCZlUCZlYEAmRxCQDYBAEJAQV2YWx1ZQEFAmJ4BAJkcgkA2AQBCQEFdmFsdWUBBQJieQQCZHMJANgEAQkBBXZhbHVlAQUCYnoEAmZXBQJiQQQCZlgFAmJCBAJmWQUCYncEAmRwAwkAAAIFAmZzBQJiSAUCZlUFAmZzBAJmcQkBBXZhbHVlAQkAkQMCBQJmVAAABAJkbgkBBXZhbHVlAQgFAmZxB2Fzc2V0SWQEAmRUCAUCZnEGYW1vdW50BAJlWAkBAmVRAwUBZQUBZQUBZQMJAAACBQJlWAUCZVgEAmRtCQDYBAEFAmZWAwkBAiE9AgUCZHEJANgEAQUCZG4JAAIBAghXcm9uZyBMUAQCZHgJAQJiWAEFAmRyBAJkegkBAmJYAQUCZHMEAmZaCgACYmUJAPwHBAUEdGhpcwITZ2V0T25lVGtuVjJSRUFET05MWQkAzAgCBQJmUgkAzAgCBQJkVAUDbmlsBQNuaWwDCQABAgUCYmUCCihJbnQsIEludCkFAmJlCQACAQkArAICCQADAQUCYmUCHyBjb3VsZG4ndCBiZSBjYXN0IHRvIChJbnQsIEludCkDCQAAAgUCZloFAmZaBAJjSAgFAmZaAl8yBAJnYQgFAmZaAl8xBAJnYgMDCQBmAgUCZlMAAAkAZgIFAmZTBQJnYQcJAQJiYQEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZlMFA25pbAIABQJnYQQCZ2MDCQAAAgUCZlIFAmRyCQCWCgQFAmdiAAAJAGUCCQBlAgUCZHgFAmdiBQJjSAUCZHoDCQAAAgUCZlIFAmRzCQCWCgQAAAUCZ2IFAmR4CQBlAgkAZQIFAmR6BQJnYgUCY0gJAAIBAhRpbnZhbGlkIG91dCBhc3NldCBpZAQCZ2QIBQJnYwJfMQQCZ2UIBQJnYwJfMgQCZkkIBQJnYwJfMwQCZkoIBQJnYwJfNAQCZ2YJAQJiWgIJAQFJAgUCZkoFAmZYCQEBSQIFAmZJBQJmVwQCZ2cJAQFNAgUCZ2YFAWEEAmdoAwkAAAIFAmZSAgVXQVZFUwUEdW5pdAkA2QQBBQJmUgQCZ2kDCQBmAgUCY0gAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJiagUCY0gFAmdoBQNuaWwFA25pbAQCZEoJAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJkcAUCZ2IFAmdoCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhagIJAKUIAQUCZHAFAmRtCQECYlQGBQJnZAUCZ2UFAmRUBQJnZwUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFjAAUCZ2cJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhZAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmdnBQNuaWwFAmdpAwkAAAIFAmRKBQJkSgQCZ2oJAPwHBAUCYVUCBGJ1cm4JAMwIAgUCZFQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZG4FAmRUBQNuaWwDCQAAAgUCZ2oFAmdqBAJnawQCZ2wDCQAAAgUEdGhpcwUCYmoAAAUCY0gEAmdtAwkAAAIJAQJibwEFAmZSBQJieQYHAwUCZ20JAJQKAgkBAS0BCQBkAgUCZ2EFAmdsAAAJAJQKAgAACQEBLQEJAGQCBQJnYQUCZ2wEAmVaCAUCZ2sCXzEEAmZhCAUCZ2sCXzIEAmduCQECZVkDBQJlWgUCZmEAAAQCZ28IBQJnbgJfMQQCZVAIBQJnbgJfMgQCZ3AJAQJmYwIFAmVYBQJlUAMJAAACBQJncAUCZ3AJAJQKAgkAzggCBQJkSgUCZ28FAmdiCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJncQAEAmdyCQECYVMABAJhUQkAnQgCBQJncgkBAmFhAAMJAAECBQJhUQIGU3RyaW5nBAJhVgUCYVEJANkEAQUCYVYDCQABAgUCYVECBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgACZ3MJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAECZ3QBAmNYBAJhUQkBAmdxAAMJAAECBQJhUQIKQnl0ZVZlY3RvcgQCZ3UFAmFRCQAAAggFAmNYD2NhbGxlclB1YmxpY0tleQUCZ3UDCQABAgUCYVECBFVuaXQJAAACCAUCY1gGY2FsbGVyBQR0aGlzCQACAQILTWF0Y2ggZXJyb3IBAmd2AQJjWAQCYVEJAQJncQADCQABAgUCYVECCkJ5dGVWZWN0b3IEAmd1BQJhUQMJAAACCAUCY1gPY2FsbGVyUHVibGljS2V5BQJndQYFAmdzAwkAAQIFAmFRAgRVbml0AwkAAAIIBQJjWAZjYWxsZXIFBHRoaXMGBQJncwkAAgECC01hdGNoIGVycm9yAQJndwMCZ3gCZXoCZ3kEAmJzCQECYmsABAJkcgkAkQMCBQJicwUBeAQCZHMJAJEDAgUCYnMFAXkEAmVBBQFnBAJlQwkApwMBBQFtBAJhUgkAuQICCQCnAwEFAmJnBQJlQwQCY0oDCQAAAgUCZ3gHCQDMCAIJALcCAgkAtgIBCQECYlgBBQJkcgUCZ3kJAMwIAgkAtgIBCQECYlgBBQJkcwUDbmlsCQDMCAIJALcCAgkAtgIBCQECYlgBBQJkcwUCZ3kJAMwIAgkAtgIBCQECYlgBBQJkcgUDbmlsBAJlQgkAkQMCBQJjSgAABAJhVgUCZUIEAmNNCQC5AgIFAmFSBQJlQQQCZUQJALoCAgkAuQICCQC5AgIJALoCAgkAuQICBQJlegUCZXoJALkCAgUCZUIFAmVBBQJlegUCZUMJALkCAgUCY00FAmVBBAJlRQkAuAICCQC3AgIFAmFWCQC6AgIJALkCAgUCZXoFAmVDBQJjTQUCZXoKAQJjVgICY1cCZUYEAmd6BQJjVwQCZUgIBQJnegJfMQQCZGsIBQJnegJfMgMJAQIhPQIFAmRrBQR1bml0BQJjVwQCZUkJALoCAgkAtwICCQC5AgIFAmVIBQJlSAUCZUQJALcCAgkAuQICBQFnBQJlSAUCZUUEAmVKCQEBWQEJALgCAgUCZUkJAQV2YWx1ZQEFAmVIAwkAwAICBQFmBQJlSgkAlAoCBQJlSQUCZUYJAJQKAgUCZUkFBHVuaXQEAmRiCQDMCAIAAAkAzAgCAAEJAMwIAgACCQDMCAIAAwkAzAgCAAQJAMwIAgAFCQDMCAIABgkAzAgCAAcJAMwIAgAICQDMCAIACQkAzAgCAAoJAMwIAgALCQDMCAIADAkAzAgCAA0JAMwIAgAOBQNuaWwEAmdBCgACZGQFAmRiCgACZGUJAJADAQUCZGQKAAJkZgkAlAoCBQJlegUEdW5pdAoBAmRnAgJkaAJkaQMJAGcCBQJkaQUCZGUFAmRoCQECY1YCBQJkaAkAkQMCBQJkZAUCZGkKAQJkagICZGgCZGkDCQBnAgUCZGkFAmRlBQJkaAkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDE1CQECZGoCCQECZGcCCQECZGcCCQECZGcCCQECZGcCCQECZGcCCQECZGcCCQECZGcCCQECZGcCCQECZGcCCQECZGcCCQECZGcCCQECZGcCCQECZGcCCQECZGcCCQECZGcCBQJkZgAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPBAJlSAgFAmdBAl8xBAJkawgFAmdBAl8yAwkBAiE9AgUCZGsFBHVuaXQFAmVICQACAQkArAICAhlZIGNhbGN1bGF0aW9uIGVycm9yLCBZID0gCQCmAwEFAmVIAQJnQgAJAQt2YWx1ZU9yRWxzZQIJAJsIAgUCYVUJAQJhSAEJAKUIAQUEdGhpcwcbAmNYASFjYWxjdWxhdGVBbW91bnRPdXRGb3JTd2FwUkVBRE9OTFkDAmdDAmd4AmdEBAJnRQMJAAACBQJneAcEAmdGCQECYVcCBQR0aGlzCQECYWwABAJneQkAtwICCQC2AgEJAQJiWAEJAQJhVwIFBHRoaXMJAQJhawAJALYCAQUCZ0MJAJQKAgUCZ0YFAmd5BAJnRgkBAmFXAgUEdGhpcwkBAmFrAAQCZ3kJALcCAgkAtgIBCQECYlgBCQECYVcCBQR0aGlzCQECYWwACQC2AgEFAmdDCQCUCgIFAmdGBQJneQQCZ0YIBQJnRQJfMQQCZ3kIBQJnRQJfMgQCYnMJAQJiawAEAmRyCQCRAwIFAmJzBQF4BAJkcwkAkQMCBQJicwUBeQQCY0oJAMwIAgkAtgIBCQECYlgBBQJkcgkAzAgCCQC2AgEJAQJiWAEFAmRzBQNuaWwEAmV6CQECY0kBBQJjSgQCZUgJAQJndwMFAmd4BQJlegkAtgIBBQJnQwQCZ0cJALgCAgkAuAICCQC2AgEJAQJiWAEFAmdGBQJlSAkAtgIBAAEEAmdICQCWAwEJAMwIAgAACQDMCAIJAKADAQUCZ0cFA25pbAQCZ0kDCQAAAgUCZ3gHCQDMCAIJALcCAgkAtwICCQC2AgEJAQJiWAEFAmRyCQC2AgEFAmdDCQC2AgEFAmdECQDMCAIJALgCAgkAtgIBCQECYlgBBQJkcwUCZ0cFA25pbAkAzAgCCQC4AgIJALYCAQkBAmJYAQUCZHIFAmdHCQDMCAIJALcCAgkAtwICCQC2AgEJAQJiWAEFAmRzCQC2AgEFAmdDCQC2AgEFAmdEBQNuaWwEAmdKCQECY0kBBQJnSQQCZWUDCQDAAgIFAmdKBQJlegYJAAIBCQC5CQIJAMwIAgIUbmV3IEQgaXMgZmV3ZXIgZXJyb3IJAMwIAgkApgMBBQJlegkAzAgCCQCmAwEFAmdKBQNuaWwCAl9fAwkAAAIFAmVlBQJlZQkAlAoCBQNuaWwFAmdICQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNYASZjYWxjdWxhdGVBbW91bnRPdXRGb3JTd2FwQW5kU2VuZFRva2VucwUCZ0MCZ3gCZ0sCZ0wCZ0QEAmdNCgACYmUJAPwHBAUCYVUCF2dldFN3YXBDb250cmFjdFJFQURPTkxZBQNuaWwFA25pbAMJAAECBQJiZQIGU3RyaW5nBQJiZQkAAgEJAKwCAgkAAwEFAmJlAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcEAmdOCQDMCAIDCQBnAggJAQV2YWx1ZQEJAJEDAggFAmNYCHBheW1lbnRzAAAGYW1vdW50BQJnQwYJAQJiYQECDFdyb25nIGFtb3VudAkAzAgCAwkAAAIIBQJjWAZjYWxsZXIJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmdNBgkBAmJhAQIRUGVybWlzc2lvbiBkZW5pZWQFA25pbAMJAAACBQJnTgUCZ04EAmZxCQEFdmFsdWUBCQCRAwIIBQJjWAhwYXltZW50cwAABAJnTwkBAmJxAQgFAmZxB2Fzc2V0SWQEAmdQAwkAAAIFAmd4BwQCZ0YJAQJhVwIFBHRoaXMJAQJhbAAEAmd5CQBlAgkBAmJYAQUCZ08ICQEFdmFsdWUBCQCRAwIIBQJjWAhwYXltZW50cwAABmFtb3VudAkAlAoCBQJnRgUCZ3kEAmdGCQECYVcCBQR0aGlzCQECYWsABAJneQkAZQIJAQJiWAEFAmdPCAkBBXZhbHVlAQkAkQMCCAUCY1gIcGF5bWVudHMAAAZhbW91bnQJAJQKAgUCZ0YFAmd5BAJnRggFAmdQAl8xBAJneQgFAmdQAl8yBAJicwkBAmJrAAQCZHIJAJEDAgUCYnMFAXgEAmRzCQCRAwIFAmJzBQF5BAJjSgMJAAACBQJneAcJAMwIAgkAuAICCQC2AgEJAQJiWAEFAmRyCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJjWAhwYXltZW50cwAABmFtb3VudAkAzAgCCQC2AgEJAQJiWAEFAmRzBQNuaWwJAMwIAgkAtgIBCQECYlgBBQJkcgkAzAgCCQC4AgIJALYCAQkBAmJYAQUCZHMJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmNYCHBheW1lbnRzAAAGYW1vdW50BQNuaWwEAmV6CQECY0kBBQJjSgQCZUgJAQJndwMFAmd4BQJlegkAtgIBAAAEAmdHCQC4AgIJALgCAgkAtgIBCQECYlgBBQJnRgUCZUgJALYCAQABBAJnSAkAlgMBCQDMCAIAAAkAzAgCCQCgAwEFAmdHBQNuaWwEAmdRAwkAZwIFAmdIBQJnSwYJAAIBAixFeGNoYW5nZSByZXN1bHQgaXMgZmV3ZXIgY29pbnMgdGhhbiBleHBlY3RlZAMJAAACBQJnUQUCZ1EEAmdJAwkAAAIFAmd4BwkAzAgCCQC3AgIJALYCAQkBAmJYAQUCZHIJALYCAQUCZ0QJAMwIAgkAuAICCQC2AgEJAQJiWAEFAmRzBQJnRwUDbmlsCQDMCAIJALgCAgkAtgIBCQECYlgBBQJkcgUCZ0cJAMwIAgkAtwICCQC2AgEJAQJiWAEFAmRzCQC2AgEFAmdEBQNuaWwEAmdKCQECY0kBBQJnSQQCZWUDCQDAAgIFAmdKBQJlegYJAAIBAhRuZXcgRCBpcyBmZXdlciBlcnJvcgMJAAACBQJlZQUCZWUJAJQKAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQJnTAUCZ0gJAQJibwEFAmdGBQNuaWwFAmdICQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNYAQtjb25zdHJ1Y3RvcgEBWgQCZUQJAQJndgEFAmNYAwkAAAIFAmVEBQJlRAkAzAgCCQELU3RyaW5nRW50cnkCCQEBWgAFAVoFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjWAEDcHV0AgJnUgJnUwQCZ1QJAQJiQwAEAmdVCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCBQJnVAUBRAIKV3Igc3QgYWRkcgQCZ1YJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFAmdUBQFGAgpXciBzbCBhZGRyAwkAZgIAAAUCZ1IJAAIBAg5Xcm9uZyBzbGlwcGFnZQMJAQIhPQIJAJADAQgFAmNYCHBheW1lbnRzAAIJAAIBAgwyIHBtbnRzIGV4cGQEAmdXCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJjWAhwYXltZW50cwAABmFtb3VudAQCZ1gJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmNYCHBheW1lbnRzAAEGYW1vdW50BAJlVQkAuAICCQC2AgEJAQJiWAEJAQJicQEFAmJ5BQJnVwMJAAACBQJlVQUCZVUEAmVWCQC4AgIJALYCAQkBAmJYAQkBAmJxAQUCYnoFAmdYAwkAAAIFAmVWBQJlVgQCZVcJALYCAQgJAQV2YWx1ZQEJAOwHAQUCYngIcXVhbnRpdHkDCQAAAgUCZVcFAmVXBAJlWAkBAmVRAwUCZ1cFAmdYCQC2AgEAAAMJAAACBQJlWAUCZVgEAmdZCQECZnIKCQClCAEIBQJjWAZjYWxsZXIJANgEAQgFAmNYDXRyYW5zYWN0aW9uSWQJAQ9BdHRhY2hlZFBheW1lbnQCCAkBBXZhbHVlAQkAkQMCCAUCY1gIcGF5bWVudHMAAAdhc3NldElkCAkBBXZhbHVlAQkAkQMCCAUCY1gIcGF5bWVudHMAAAZhbW91bnQJAJEDAggFAmNYCHBheW1lbnRzAAEFAmdSBgcGAAACAAQCZXIIBQJnWQJfMgQCZ1oIBQJnWQJfNwQCZEoIBQJnWQJfOQQCZXMIBQJnWQNfMTAEAmV0CAUCZ1kDXzExBAJkcggFAmdZA18xMgQCZHMIBQJnWQNfMTMEAmVkCQD8BwQFAmFVAgRlbWl0CQDMCAIFAmVyBQNuaWwFA25pbAMJAAACBQJlZAUCZWQEAmhhBAJhUQUCZWQDCQABAgUCYVECB0FkZHJlc3MEAmhiBQJhUQkA/AcEBQJoYgIEZW1pdAkAzAgCBQJlcgUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCaGEFAmhhBAJoYwMJAGYCBQJlcwAACQD8BwQFAmdWAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZHIFAmVzBQNuaWwFA25pbAMJAAACBQJoYwUCaGMEAmhkAwkAZgIFAmV0AAAJAPwHBAUCZ1YCA3B1dAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJkcwUCZXQFA25pbAUDbmlsAwkAAAIFAmhkBQJoZAQCaGUDBQJnUwQCaGYJAPwHBAUCZ1UCBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmdaBQJlcgUDbmlsAwkAAAIFAmhmBQJoZgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJjWAZjYWxsZXIFAmVyBQJnWgUDbmlsBAJoZwkBAmVZAwAAAAAAAAQCZ28IBQJoZwJfMQQCZVAIBQJoZwJfMgQCaGgDCQDAAgIFAmVQBQJlWAYJAQJiYQEJALkJAgkAzAgCAiJ1cGRhdGVkIERMcCBsb3dlciB0aGFuIGN1cnJlbnQgRExwCQDMCAIJAKYDAQUCZVUJAMwIAgkApgMBBQJlVgkAzAgCCQCmAwEFAmVXCQDMCAIJAKYDAQUCZVgJAMwIAgkApgMBBQJlUAkAzAgCCQCkAwEFAmVzCQDMCAIJAKQDAQUCZXQFA25pbAIBIAMJAAACBQJoaAUCaGgEAmhpCAkBBXZhbHVlAQkA7AcBBQJieAhxdWFudGl0eQMJAAACBQJoaQUCaGkJAM4IAgkAzggCBQJkSgUCaGUFAmdvCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNYAQtwdXRPbmVUa25WMgICZlMCZ1MEAmhqCgACYmUJAPwHBAUCYVUCKGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJiZQIHQm9vbGVhbgUCYmUJAAIBCQCsAgIJAAMBBQJiZQIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCaGsDAwMJAQJiaAAGCQAAAgUCYncFAXIGCQAAAgUCYncFAXQGBQJoagQCZ04JAMwIAgMDCQEBIQEFAmhrBgkBAmd0AQUCY1gGCQECYmEBAiFwdXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJjWAhwYXltZW50cwABBgkBAmJhAQIeZXhhY3RseSAxIHBheW1lbnQgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZ04FAmdOBAJkcgkA2AQBCQEFdmFsdWUBBQJieQQCZHMJANgEAQkBBXZhbHVlAQUCYnoEAmRxBQJieAQCZlcFAmJBBAJmWAUCYkIEAmRwAwkAAAIIBQJjWAZjYWxsZXIFBHRoaXMIBQJjWAxvcmlnaW5DYWxsZXIIBQJjWAZjYWxsZXIEAmZxCQEFdmFsdWUBCQCRAwIIBQJjWAhwYXltZW50cwAABAJkbgkA2AQBCQEFdmFsdWUBCAUCZnEHYXNzZXRJZAQCZFQIBQJmcQZhbW91bnQEAmVYAwkAAAIIBQJmcQdhc3NldElkBQJieQkBAmVRAwkAtgIBBQJkVAkAtgIBAAAJALYCAQAACQECZVEDCQC2AgEAAAkAtgIBBQJkVAkAtgIBAAADCQAAAgUCZVgFAmVYBAJobAkBAmZ2BQUCZFQFAmRuCQClCAEFAmRwCQDYBAEIBQJjWA10cmFuc2FjdGlvbklkBgMJAAACBQJobAUCaGwEAmNICAUCaGwCXzMEAmRKCAUCaGwCXzIEAmhtCAUCaGwCXzEEAmVyAwMJAGYCBQJmUwAACQBmAgUCZlMFAmhtBwkBAmJhAQkAuQkCCQDMCAICH2Ftb3VudCB0byByZWNlaXZlIGlzIGxlc3MgdGhhbiAJAMwIAgkApAMBBQJmUwUDbmlsAgAFAmhtBAJnWQkA/AcEBQJhVQIEZW1pdAkAzAgCBQJlcgUDbmlsBQNuaWwDCQAAAgUCZ1kFAmdZBAJoYQQCYVEFAmdZAwkAAQIFAmFRAgdBZGRyZXNzBAJoYgUCYVEJAPwHBAUCaGICBGVtaXQJAMwIAgUCZXIFA25pbAUDbmlsBQR1bml0AwkAAAIFAmhhBQJoYQQCaGUDBQJnUwQCaGYJAPwHBAUCYkUCCHN0YWtlRm9yCQDMCAIJAKUIAQgFAmNYBmNhbGxlcgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJkcQUCZXIFA25pbAMJAAACBQJoZgUCaGYFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCY1gGY2FsbGVyBQJlcgUCZHEFA25pbAQCZ2kDCQBmAgUCY0gAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJiagUCY0gJANkEAQUCZG4FA25pbAUDbmlsBAJobgMJAAACBQR0aGlzBQJiagkAlAoCAAAAAAQCaG8DCQAAAggFAmZxB2Fzc2V0SWQFAmJ5BgcDBQJobwkAlAoCCQEBLQEFAmNIAAAJAJQKAgAACQEBLQEFAmNIBAJlWggFAmhuAl8xBAJmYQgFAmhuAl8yBAJocAkBAmVZAwUCZVoFAmZhAAAEAmdvCAUCaHACXzEEAmVQCAUCaHACXzIEAmdwCQECZmMCBQJlWAUCZVADCQAAAgUCZ3AFAmdwCQCUCgIJAM4IAgkAzggCCQDOCAIFAmRKBQJoZQUCZ2kFAmdvBQJlcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjWAEKcHV0Rm9yRnJlZQECaHEDCQBmAgAABQJocQkAAgECCldyb25nIHNscGcDCQECIT0CCQCQAwEIBQJjWAhwYXltZW50cwACCQACAQIMMiBwbW50cyBleHBkBAJocgkBAmZyCgkApQgBCAUCY1gGY2FsbGVyCQDYBAEIBQJjWA10cmFuc2FjdGlvbklkCQEPQXR0YWNoZWRQYXltZW50AggJAQV2YWx1ZQEJAJEDAggFAmNYCHBheW1lbnRzAAAHYXNzZXRJZAgJAQV2YWx1ZQEJAJEDAggFAmNYCHBheW1lbnRzAAAGYW1vdW50CQCRAwIIBQJjWAhwYXltZW50cwABBQJocQcHBgAAAgAEAmRKCAUCaHICXzkEAmdXCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJjWAhwYXltZW50cwAABmFtb3VudAQCZ1gJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmNYCHBheW1lbnRzAAEGYW1vdW50BAJlWAkBAmVRAwUCZ1cFAmdYCQC2AgEAAAMJAAACBQJlWAUCZVgEAmhzCQECZVkDAAAAAAAABAJnbwgFAmhzAl8xBAJlUAgFAmhzAl8yBAJncAkBAmZjAgUCZVgFAmVQAwkAAAIFAmdwBQJncAkAzggCBQJkSgUCZ28JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CY1gBA2dldAAEAmVYCQECZVEDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmVYBQJlWAQCZWQJAQJmcAEFAmNYBAJodAgFAmVkAl8xBAJkSQgFAmVkAl8yBAJkVAgFAmVkAl8zBAJkbggFAmVkAl80BAJkSggFAmVkAl81BAJlRQkA/AcEBQJhVQIEYnVybgkAzAgCBQJkVAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJkbgUCZFQFA25pbAMJAAACBQJlRQUCZUUEAmh1CQECZVkDCQEBLQEFAmh0CQEBLQEFAmRJAAAEAmdvCAUCaHUCXzEEAmVQCAUCaHUCXzIEAmdwCQECZmMCBQJlWAUCZVADCQAAAgUCZ3AFAmdwCQDOCAIFAmRKBQJnbwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjWAELZ2V0T25lVGtuVjICAmZSAmZTBAJoagoAAmJlCQD8BwQFAmFVAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYmUCB0Jvb2xlYW4FAmJlCQACAQkArAICCQADAQUCYmUCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmh2AwMJAQJiaAAGCQAAAgUCYncFAXQGBQJoagQCZ04JAMwIAgMDCQEBIQEFAmh2BgkBAmd0AQUCY1gGCQECYmEBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJjWAhwYXltZW50cwABBgkBAmJhAQIeZXhhY3RseSAxIHBheW1lbnQgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZ04FAmdOBAJodwkBAmZRBgUCZlIFAmZTCAUCY1gIcGF5bWVudHMIBQJjWAZjYWxsZXIIBQJjWAxvcmlnaW5DYWxsZXIIBQJjWA10cmFuc2FjdGlvbklkBAJkSggFAmh3Al8xBAJnYggFAmh3Al8yCQCUCgIFAmRKBQJnYgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjWAEKcmVmcmVzaERMcAAEAmh4CQELdmFsdWVPckVsc2UCCQCfCAEFAmF0AAAEAmh5AwkAZwIJAGUCBQZoZWlnaHQFAmh4BQJhdwUEdW5pdAkBAmJhAQkAuQkCCQDMCAIJAKQDAQUCYXcJAMwIAgIvIGJsb2NrcyBoYXZlIG5vdCBwYXNzZWQgc2luY2UgdGhlIHByZXZpb3VzIGNhbGwFA25pbAIAAwkAAAIFAmh5BQJoeQQCZmoJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAqAMBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAmFzAgEwCQECYmMBAgtpbnZhbGlkIGRMcAQCaHoJAQJlWQMAAAAAAAAEAmhBCAUCaHoCXzEEAmVQCAUCaHoCXzIEAmZiAwkBAiE9AgUCZmoFAmVQBQJoQQkBAmJhAQISbm90aGluZyB0byByZWZyZXNoCQCUCgIFAmZiCQCmAwEFAmVQCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNYARNnZXRPbmVUa25WMlJFQURPTkxZAgJmUgJoQgQCZHIJANgEAQkBBXZhbHVlAQUCYnkEAmRzCQDYBAEJAQV2YWx1ZQEFAmJ6BAJkcQkA2AQBCQEFdmFsdWUBBQJieAQCY0oJAMwIAgkAtgIBCQECYlgBBQJkcgkAzAgCCQC2AgEJAQJiWAEFAmRzBQNuaWwEAmVPCQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQkA2QQBBQJkcQIQaW52YWxpZCBscCBhc3NldAhxdWFudGl0eQQCY2wJAQJjSQEFAmNKBAJjawkAuAICBQJjbAkAvAIDCQC2AgEFAmhCBQJjbAUCZU8EAmhDAwkAAAIFAmZSBQJkcgAAAwkAAAIFAmZSBQJkcwABCQACAQIUaW52YWxpZCBvdXQgYXNzZXQgaWQEAmhECQECZXkDBQJjSgUCaEMFAmNrBAJnRwkAuAICCQCRAwIFAmNKBQJoQwUCaEQEAmdICQCWAwEJAMwIAgAACQDMCAIJAKADAQkAuAICBQJnRwUBZgUDbmlsBAJoRQkBAmNGAgUCZ0gFAmJmBAJnYQgFAmhFAl8xBAJjSAgFAmhFAl8yCQCUCgIFA25pbAkAlAoCBQJnYQUCY0gCY1gBHGdldE9uZVRrblYyV2l0aEJvbnVzUkVBRE9OTFkCAmZSAmhCBAJkcgkA2AQBCQEFdmFsdWUBBQJieQQCZHMJANgEAQkBBXZhbHVlAQUCYnoEAmRxCQDYBAEJAQV2YWx1ZQEFAmJ4BAJkeAkBAmJYAQUCZHIEAmR6CQECYlgBBQJkcwQCaEYKAAJiZQkA/AcEBQR0aGlzAhNnZXRPbmVUa25WMlJFQURPTkxZCQDMCAIFAmZSCQDMCAIFAmhCBQNuaWwFA25pbAMJAAECBQJiZQIKKEludCwgSW50KQUCYmUJAAIBCQCsAgIJAAMBBQJiZQIfIGNvdWxkbid0IGJlIGNhc3QgdG8gKEludCwgSW50KQQCZ2EIBQJoRgJfMQQCY0gIBQJoRgJfMgQCZWQJAQJkbAQCAAUCZHEFAmhCBQR0aGlzBAJkSAgFAmVkAl8xBAJkSQgFAmVkAl8yBAJoRwkAZAIFAmRIBQJkSQQCZlADCQAAAgUCaEcAAAMJAAACBQJnYQAAAAAJAAIBAhdib251cyBjYWxjdWxhdGlvbiBlcnJvcgkAawMJAGUCBQJnYQUCaEcFAWEFAmhHCQCUCgIFA25pbAkAlQoDBQJnYQUCY0gFAmZQAmNYAQlnZXROb0xlc3MCAmhIAmhJBAJlZAkBAmZwAQUCY1gEAmRICAUCZWQCXzEEAmRJCAUCZWQCXzIEAmRUCAUCZWQCXzMEAmRuCAUCZWQCXzQEAmRKCAUCZWQCXzUDCQBmAgUCaEgFAmRICQACAQkArAICCQCsAgIJAKwCAgIJRmFpbGVkOiAgCQCkAwEFAmRIAgMgPCAJAKQDAQUCaEgDCQBmAgUCaEkFAmRJCQACAQkArAICCQCsAgIJAKwCAgIIRmFpbGVkOiAJAKQDAQUCZEkCAyA8IAkApAMBBQJoSQQCZVgJAQJlUQMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZVgFAmVYBAJoSgkA/AcEBQJhVQIEYnVybgkAzAgCBQJkVAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJkbgUCZFQFA25pbAMJAAACBQJoSgUCaEoEAmhLCQECZVkDCQEBLQEFAmRICQEBLQEFAmRJAAAEAmdvCAUCaEsCXzEEAmVQCAUCaEsCXzIEAmdwCQECZmMCBQJlWAUCZVADCQAAAgUCZ3AFAmdwCQDOCAIFAmRKBQJnbwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjWAENdW5zdGFrZUFuZEdldAECY0cEAmhMAwkBAiE9AgkAkAMBCAUCY1gIcGF5bWVudHMAAAkAAgECDU5vIHBtbnRzIGV4cGQGAwkAAAIFAmhMBQJoTAQCaE0JAQJiQwAEAmdaBQJieAQCaE4JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFAmhNBQFEAgpXciBzdCBhZGRyBAJlWAkBAmVRAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJlWAUCZVgEAmhPCQD8BwQFAmhOAgd1bnN0YWtlCQDMCAIJANgEAQUCZ1oJAMwIAgUCY0cFA25pbAUDbmlsAwkAAAIFAmhPBQJoTwQCZWQJAQJkbAQJANgEAQgFAmNYDXRyYW5zYWN0aW9uSWQJANgEAQUCZ1oFAmNHCAUCY1gGY2FsbGVyBAJkSAgFAmVkAl8xBAJkSQgFAmVkAl8yBAJkdgkBDXBhcnNlSW50VmFsdWUBCAUCZWQCXzkEAmRKCAUCZWQDXzEwBAJoUAMDCQECYmgABgkAAAIFAmR2BQF0CQACAQkArAICAglCbG9ja2VkOiAJAKQDAQUCZHYGAwkAAAIFAmhQBQJoUAQCaFEJAPwHBAUCYVUCBGJ1cm4JAMwIAgUCY0cFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZ1oFAmNHBQNuaWwDCQAAAgUCaFEFAmhRBAJoUgkBAmVZAwkBAS0BBQJkSAkBAS0BBQJkSQAABAJnbwgFAmhSAl8xBAJlUAgFAmhSAl8yBAJncAkBAmZjAgUCZVgFAmVQAwkAAAIFAmdwBQJncAkAzggCBQJkSgUCZ28JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CY1gBE3Vuc3Rha2VBbmRHZXROb0xlc3MDAmhTAmhUAmhJBAJodgMJAQJiaAAGCQAAAgUCYncFAXQEAmdOCQDMCAIDCQEBIQEFAmh2BgkAAgECIWdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmNYCHBheW1lbnRzAAAGCQACAQIYbm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZ04FAmdOBAJlWAkBAmVRAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJlWAUCZVgEAmhPCQD8BwQFAmJFAgd1bnN0YWtlCQDMCAIJANgEAQUCYngJAMwIAgUCaFMFA25pbAUDbmlsAwkAAAIFAmhPBQJoTwQCaFUJAQJkbAQJANgEAQgFAmNYDXRyYW5zYWN0aW9uSWQJANgEAQUCYngFAmhTCAUCY1gGY2FsbGVyBAJkSAgFAmhVAl8xBAJkSQgFAmhVAl8yBAJkSggFAmhVA18xMAQCaFYJAMwIAgMJAGcCBQJkSAUCaFQGCQACAQkAuQkCCQDMCAICLGFtb3VudCBhc3NldCBhbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCaFQFA25pbAIACQDMCAIDCQBnAgUCZEkFAmhJBgkAAgEJALkJAgkAzAgCAitwcmljZSBhc3NldCBhbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCaEkFA25pbAIABQNuaWwDCQAAAgUCaFYFAmhWBAJoSgkA/AcEBQJhVQIEYnVybgkAzAgCBQJoUwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJieAUCaFMFA25pbAMJAAACBQJoSgUCaEoEAmhXCQECZVkDCQEBLQEFAmRICQEBLQEFAmRJAAAEAmdvCAUCaFcCXzEEAmVQCAUCaFcCXzIEAmdwCQECZmMCBQJlWAUCZVADCQAAAgUCZ3AFAmdwCQDOCAIFAmRKBQJnbwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjWAEVdW5zdGFrZUFuZEdldE9uZVRrblYyAwJoUwJmUgJmUwQCaGoKAAJiZQkA/AcEBQJhVQIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmJlAgdCb29sZWFuBQJiZQkAAgEJAKwCAgkAAwEFAmJlAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJodgMDCQECYmgABgkAAAIFAmJ3BQF0BgUCaGoEAmdOCQDMCAIDAwkBASEBBQJodgYJAQJndAEFAmNYBgkBAmJhAQIhZ2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCY1gIcGF5bWVudHMAAAYJAQJiYQECGG5vIHBheW1lbnRzIGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmdOBQJnTgQCaE0JAQJiQwAEAmdaBQJieAQCaE4JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFAmhNBQFEAgpXciBzdCBhZGRyBAJkcAgFAmNYBmNhbGxlcgQCaFgFBHRoaXMEAmhPCQD8BwQFAmhOAg91bnN0YWtlSU5URVJOQUwJAMwIAgUCZ1oJAMwIAgUCaFMJAMwIAggFAmRwBWJ5dGVzCQDMCAIIBQJoWAVieXRlcwUDbmlsBQNuaWwDCQAAAgUCaE8FAmhPBAJoWQkBAmZRBgUCZlIFAmZTCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJnWgUCaFMFA25pbAgFAmNYBmNhbGxlcggFAmNYDG9yaWdpbkNhbGxlcggFAmNYDXRyYW5zYWN0aW9uSWQEAmRKCAUCaFkCXzEEAmdiCAUCaFkCXzIJAJQKAgUCZEoFAmdiCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNYARxwdXRPbmVUa25WMldpdGhCb251c1JFQURPTkxZAgJoWgJpYQQCaWIJAQJmdgUFAmhaBQJpYQIAAgAGBAJmSwgFAmliAl8xBAJkSggFAmliAl8yBAJjSAgFAmliAl8zBAJmUAgFAmliAl80CQCUCgIFA25pbAkAlQoDBQJmSwUCY0gFAmZQAmNYASFwdXRPbmVUa25WMldpdGhvdXRUYWtlRmVlUkVBRE9OTFkCAmhaAmlhBAJpYwkBAmZ2BQUCaFoFAmlhAgACAAcEAmZLCAUCaWMCXzEEAmRKCAUCaWMCXzIEAmNICAUCaWMCXzMEAmZQCAUCaWMCXzQJAJQKAgUDbmlsCQCVCgMFAmZLBQJjSAUCZlACY1gBCGFjdGl2YXRlAgJpZAJpZQMJAQIhPQIJAKUIAQgFAmNYBmNhbGxlcgkApQgBBQJhVQkAAgECBmRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhawAFAmlkCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhbAAFAmllCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhbQAJAKQDAQUBbAUDbmlsAgdzdWNjZXNzAmNYARxnZXRQb29sQ29uZmlnV3JhcHBlclJFQURPTkxZAAkAlAoCBQNuaWwJAQJiawACY1gBHGdldEFjY0JhbGFuY2VXcmFwcGVyUkVBRE9OTFkBAmJZCQCUCgIFA25pbAkBAmJYAQUCYlkCY1gBGWNhbGNQcmljZXNXcmFwcGVyUkVBRE9OTFkDAmNyAmNzAmN3BAJpZgkBAmN2AwUCY3IFAmNzBQJjdwkAlAoCBQNuaWwJAMwIAgkApgMBCQCRAwIFAmlmAAAJAMwIAgkApgMBCQCRAwIFAmlmAAEJAMwIAgkApgMBCQCRAwIFAmlmAAIFA25pbAJjWAEWZnJvbVgxOFdyYXBwZXJSRUFET05MWQIBTgJpZwkAlAoCBQNuaWwJAQFNAgkApwMBBQFOBQJpZwJjWAEUdG9YMThXcmFwcGVyUkVBRE9OTFkCAUoBSwkAlAoCBQNuaWwJAKYDAQkBAUkCBQFKBQFLAmNYAR5jYWxjUHJpY2VCaWdJbnRXcmFwcGVyUkVBRE9OTFkCAmNhAmNiCQCUCgIFA25pbAkApgMBCQECYloCCQCnAwEFAmNhCQCnAwEFAmNiAmNYASNlc3RpbWF0ZVB1dE9wZXJhdGlvbldyYXBwZXJSRUFET05MWQkCZG0CY2cCZEwCZE0CZE4CZE8CaWgCZFACZFEJAJQKAgUDbmlsCQECZEsNBQJkbQUCY2cFAmRMBQJkTQUCZE4FAmRPBQJpaAUCZFAFAmRRBgcAAAIAAmNYASNlc3RpbWF0ZUdldE9wZXJhdGlvbldyYXBwZXJSRUFET05MWQQCZG0CaWkCZG8CaWgEAmVkCQECZGwEBQJkbQUCaWkFAmRvCQERQGV4dHJOYXRpdmUoMTA2MikBBQJpaAkAlAoCBQNuaWwJAJwKCggFAmVkAl8xCAUCZWQCXzIIBQJlZAJfMwgFAmVkAl80CAUCZWQCXzUIBQJlZAJfNggFAmVkAl83CQCmAwEIBQJlZAJfOAgFAmVkAl85CAUCZWQDXzEwAmNYAQljaGFuZ2VBbXAABAJpagkA/AcEBQJhVQIaZ2V0Q2hhbmdlQW1wQ29uZmlnUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAQCaWsEAmFRBQJpagMJAAECBQJhUQIJTGlzdFtBbnldBAJpbAUCYVEJAJUKAwoAAmJlCQCRAwIFAmlsAAADCQABAgUCYmUCA0ludAUCYmUJAAIBCQCsAgIJAAMBBQJiZQIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50CgACYmUJAJEDAgUCaWwAAQMJAAECBQJiZQIDSW50BQJiZQkAAgEJAKwCAgkAAwEFAmJlAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQKAAJiZQkAkQMCBQJpbAACAwkAAQIFAmJlAgNJbnQFAmJlCQACAQkArAICCQADAQUCYmUCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAkBAmJhAQISaW52YWxpZCBlbnRyeSB0eXBlBAJpbQgFAmlrAl8xBAJpbggFAmlrAl8yBAJpbwgFAmlrAl8zBAJpcAkBDXBhcnNlSW50VmFsdWUBCQERQGV4dHJOYXRpdmUoMTA1OCkBCQECYW0ABAJpcQkAZAIFAmlwBQJpbgQCaXIDCQBmAgAABQJpbgMJAGYCBQJpbwUCaXEFAmlvBQJpcQMJAGYCBQJpcQUCaW8FAmlvBQJpcQQCaXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAmFwAAAABAJpdAkAZAIFAmlzBQJpbQQCZ04JAMwIAgMJAGYCBQZoZWlnaHQFAml0BgkBAmJhAQIXdHJ5IGFnYWluIGluIGZldyBibG9ja3MJAMwIAgMJAQIhPQIFAmlwBQJpcgYJAQJiYQECFmFscmVhZHkgcmVhY2hlZCB0YXJnZXQFA25pbAMJAAACBQJnTgUCZ04JAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhcAAFBmhlaWdodAkAzAgCCQELU3RyaW5nRW50cnkCCQECYW0ACQCkAwEFAmlyCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhbgEFBmhlaWdodAkApAMBBQJpcgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJpdQECaXYABAJpdwQCYVEJAQJncQADCQABAgUCYVECCkJ5dGVWZWN0b3IEAmd1BQJhUQUCZ3UDCQABAgUCYVECBFVuaXQIBQJpdQ9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgQCYVEFAml1AwkAAQIFAmFRAgVPcmRlcgQCZmYFAmFRBAJpeAkBAmJpAAQCaXkDCQECZ0IACQCUCgIGAgAJAQJmZQEFAmZmBAJhSwgFAml5Al8xBAJhTAgFAml5Al8yBAJhTQkA9AMDCAUCZmYJYm9keUJ5dGVzCQCRAwIIBQJmZgZwcm9vZnMAAAgFAmZmD3NlbmRlclB1YmxpY0tleQQCYU4JAPQDAwgFAmZmCWJvZHlCeXRlcwkAkQMCCAUCZmYGcHJvb2ZzAAEFAml4AwMDBQJhSwUCYU0HBQJhTgcGCQECYUoEBQJhSwUCYUwFAmFNBQJhTgMJAAECBQJhUQIUU2V0U2NyaXB0VHJhbnNhY3Rpb24EAmFWBQJhUQMJAPQDAwgFAml1CWJvZHlCeXRlcwkAkQMCCAUCaXUGcHJvb2ZzAAAFAml3BgQCaXoJAPYDAQkBBXZhbHVlAQgFAmFWBnNjcmlwdAQCaUEJANsEAQkBBXZhbHVlAQkAnQgCBQJhVQkBAmFGAAQCaUIJAPEHAQUEdGhpcwMJAAACBQJpQQUCaXoJAQIhPQIFAmlCBQJpegcJAPQDAwgFAml1CWJvZHlCeXRlcwkAkQMCCAUCaXUGcHJvb2ZzAAAFAml3HRMn8g==", "height": 3647504, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 3mEpuVvwwyGYUMAGCdENQx82NbfC8MSmHXLr4drL88jq Next: 3mBJw8vvKQNPStfwEFV8nThVQqhRCWSxHTMykg3pWtHF Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let lPdecimals = 8
5-
64 let scale8 = 100000000
75
86 let scale8BigInt = toBigInt(100000000)
1715
1816 let big2 = toBigInt(2)
1917
18+let big3 = toBigInt(3)
19+
20+let big4 = toBigInt(4)
21+
22+let slippage4D = toBigInt((scale8 - ((scale8 * 1) / scale8)))
23+
2024 let wavesString = "WAVES"
25+
26+let ampInitial = 50
27+
28+let Amult = "100"
29+
30+let Dconv = "1"
2131
2232 let SEP = "__"
2333
34+let EMPTY = ""
35+
2436 let PoolActive = 1
2537
26-let PoolPutDisabled = 2
38+let PoolPutDis = 2
2739
28-let PoolMatcherDisabled = 3
40+let PoolMatcherDis = 3
2941
3042 let PoolShutdown = 4
3143
3244 let idxPoolAddress = 1
3345
34-let idxPoolStatus = 2
46+let idxPoolSt = 2
3547
36-let idxPoolLPAssetId = 3
48+let idxLPAsId = 3
3749
38-let idxAmtAssetId = 4
50+let idxAmAsId = 4
3951
40-let idxPriceAssetId = 5
52+let idxPrAsId = 5
4153
42-let idxAmtAssetDcm = 6
54+let idxAmtAsDcm = 6
4355
44-let idxPriceAssetDcm = 7
56+let idxPriceAsDcm = 7
4557
46-let idxIAmtAssetId = 8
58+let idxIAmtAsId = 8
4759
48-let idxIPriceAssetId = 9
60+let idxIPriceAsId = 9
4961
50-let idxLPAssetDcm = 10
62+let idxFactStakCntr = 1
5163
52-let idxPoolAmtAssetAmt = 1
64+let idxFactoryRestCntr = 6
5365
54-let idxPoolPriceAssetAmt = 2
66+let idxFactSlippCntr = 7
5567
56-let idxPoolLPAssetAmt = 3
68+let idxFactGwxRewCntr = 10
5769
58-let idxFactoryStakingContract = 1
70+let feeDefault = fraction(10, scale8, 10000)
5971
60-let idxFactorySlippageContract = 7
61-
62-func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
72+func t1 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
6373
6474
65-func toX18BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
75+func t1BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
6676
6777
68-func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
78+func f1 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
6979
7080
7181 func fromX18Round (val,resultScaleMult,round) = toInt(fraction(val, toBigInt(resultScaleMult), scale18, round))
7282
7383
74-func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
84+func t2 (origVal,origScaleMult) = fraction(origVal, scale18, toBigInt(origScaleMult))
7585
7686
77-func abs (val) = if ((0 > val))
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))
7894 then -(val)
7995 else val
8096
8298 func absBigInt (val) = if ((zeroBigInt > val))
8399 then -(val)
84100 else val
85-
86-
87-func swapContract () = "%s__swapContract"
88101
89102
90103 func fc () = "%s__factoryContract"
99112 func pl () = "%s%s__price__last"
100113
101114
102-func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
115+func ph (h,t) = makeString(["%s%s%d%d__price__history", toString(h), toString(t)], SEP)
103116
104117
105-func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
118+func pau (ua,txId) = ((("%s%s%s__P__" + ua) + "__") + txId)
106119
107120
108-func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
121+func gau (ua,txId) = ((("%s%s%s__G__" + ua) + "__") + txId)
109122
110123
111124 func aa () = "%s__amountAsset"
114127 func pa () = "%s__priceAsset"
115128
116129
130+func amp () = "%s__amp"
131+
132+
133+func keyAmpHistory (heightBlocks) = ("%s%d__amp__" + toString(heightBlocks))
134+
135+
136+func keyChangeAmpLastCall () = "%s__changeAmpLastCall"
137+
138+
117139 let keyFee = "%s__fee"
118-
119-let feeDefault = fraction(10, scale8, 10000)
120140
121141 let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
122142
123-let keyKLp = makeString(["%s", "kLp"], SEP)
143+let keyDLp = makeString(["%s", "dLp"], SEP)
124144
125-let keyKLpRefreshedHeight = makeString(["%s", "kLpRefreshedHeight"], SEP)
145+let keyDLpRefreshedHeight = makeString(["%s", "dLpRefreshedHeight"], SEP)
126146
127-let keyKLpRefreshDelay = makeString(["%s", "refreshKLpDelay"], SEP)
147+let keyDLpRefreshDelay = makeString(["%s", "refreshDLpDelay"], SEP)
128148
129-let kLpRefreshDelayDefault = 30
149+let dLpRefreshDelayDefault = 30
130150
131-let kLpRefreshDelay = valueOrElse(getInteger(this, keyKLpRefreshDelay), kLpRefreshDelayDefault)
151+let dLpRefreshDelay = valueOrElse(getInteger(this, keyDLpRefreshDelay), dLpRefreshDelayDefault)
132152
133-func keyAdditionalBalance (assetId) = makeString(["%s%s", "stakedBalance", assetId], SEP)
153+func fcfg () = "%s__factoryConfig"
134154
135155
136-func keyStakingAssetBalance (assetId) = makeString(["%s%s", "shareAssetBalance", assetId], SEP)
156+func mtpk () = "%s%s__matcher__publicKey"
137157
138158
139-func getAdditionalBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyAdditionalBalance(assetId)), 0)
159+func pc (iAmtAs,iPrAs) = (((("%d%d%s__" + iAmtAs) + "__") + iPrAs) + "__config")
140160
141161
142-func getStakingAssetBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyStakingAssetBalance(assetId)), 0)
162+func mba (bAStr) = ("%s%s%s__mappings__baseAsset2internalId__" + bAStr)
143163
144164
145-func keyFactoryConfig () = "%s__factoryConfig"
165+func aps () = "%s__shutdown"
146166
147167
148-func keyMatcherPub () = "%s%s__matcher__publicKey"
168+func keyAllowedLpStableScriptHash () = "%s__allowedLpStableScriptHash"
149169
150170
151-func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
171+func keyFeeCollectorAddress () = "%s__feeCollectorAddress"
152172
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"
170173
171174 func keySkipOrderValidation (poolAddress) = ("%s%s__skipOrderValidation__" + poolAddress)
172175
198201 }
199202
200203
201-func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
204+func strf (addr,key) = valueOrErrorMessage(getString(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
202205
203206
204-func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
207+func intf (addr,key) = valueOrErrorMessage(getInteger(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
205208
206209
207-func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
210+func throwErr (msg) = throw(makeString(["lp_stable.ride:", msg], " "))
208211
209212
210-func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
213+func fmtErr (msg) = makeString(["lp_stable.ride:", msg], " ")
211214
212215
213-let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
214-
215-let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
216+let fca = addressFromStringValue(strf(this, fc()))
216217
217218 let inFee = {
218- let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
219+ let @ = invoke(fca, "getInFeeREADONLY", [toString(this)], nil)
219220 if ($isInstanceOf(@, "Int"))
220221 then @
221222 else throw(($getType(@) + " couldn't be cast to Int"))
222223 }
223224
224225 let outFee = {
225- let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
226+ let @ = invoke(fca, "getOutFeeREADONLY", [toString(this)], nil)
226227 if ($isInstanceOf(@, "Int"))
227228 then @
228229 else throw(($getType(@) + " couldn't be cast to Int"))
229230 }
230231
231-func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
232+let A = strf(this, amp())
233+
234+func igs () = valueOrElse(getBoolean(fca, aps()), false)
232235
233236
234-func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
237+func mp () = fromBase58String(strf(fca, mtpk()))
235238
236239
237-func getPoolConfig () = {
238- let amtAsset = getStringOrFail(this, aa())
239- let priceAsset = getStringOrFail(this, pa())
240- let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
241- let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
242- split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
240+let feeCollectorAddress = addressFromStringValue(strf(fca, keyFeeCollectorAddress()))
241+
242+func gpc () = {
243+ let amtAs = strf(this, aa())
244+ let priceAs = strf(this, pa())
245+ let iPriceAs = intf(fca, mba(priceAs))
246+ let iAmtAs = intf(fca, mba(amtAs))
247+ split(strf(fca, pc(toString(iAmtAs), toString(iPriceAs))), SEP)
243248 }
244249
245250
253258 else toBase58String(value(input))
254259
255260
256-func parsePoolConfig (poolConfig) = $Tuple7(addressFromStringValue(poolConfig[idxPoolAddress]), parseIntValue(poolConfig[idxPoolStatus]), fromBase58String(poolConfig[idxPoolLPAssetId]), parseAssetId(poolConfig[idxAmtAssetId]), parseAssetId(poolConfig[idxPriceAssetId]), parseIntValue(poolConfig[idxAmtAssetDcm]), parseIntValue(poolConfig[idxPriceAssetDcm]))
261+func parsePoolConfig (poolConfig) = $Tuple7(addressFromStringValue(poolConfig[idxPoolAddress]), parseIntValue(poolConfig[idxPoolSt]), fromBase58String(poolConfig[idxLPAsId]), parseAssetId(poolConfig[idxAmAsId]), parseAssetId(poolConfig[idxPrAsId]), parseIntValue(poolConfig[idxAmtAsDcm]), parseIntValue(poolConfig[idxPriceAsDcm]))
257262
258263
259-let poolConfigParsed = parsePoolConfig(getPoolConfig())
264+let poolConfigParsed = parsePoolConfig(gpc())
260265
261-let $t095299695 = poolConfigParsed
266+let $t086088794 = poolConfigParsed
262267
263-let cfgPoolAddress = $t095299695._1
268+let cfgPoolAddress = $t086088794._1
264269
265-let cfgPoolStatus = $t095299695._2
270+let cfgPoolStatus = $t086088794._2
266271
267-let cfgLpAssetId = $t095299695._3
272+let cfgLpAssetId = $t086088794._3
268273
269-let cfgAmountAssetId = $t095299695._4
274+let cfgAmountAssetId = $t086088794._4
270275
271-let cfgPriceAssetId = $t095299695._5
276+let cfgPriceAssetId = $t086088794._5
272277
273-let cfgAmountAssetDecimals = $t095299695._6
278+let cfgAmountAssetDecimals = $t086088794._6
274279
275-let cfgPriceAssetDecimals = $t095299695._7
280+let cfgPriceAssetDecimals = $t086088794._7
276281
277-func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
282+func gfc () = split(strf(fca, fcfg()), SEP)
278283
279284
280-let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
285+let factoryConfig = gfc()
281286
282-let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
287+let stakingContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactStakCntr]), "Invalid staking contract address")
283288
284-func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slippageTolerancePassedByUser,slippageToleranceReal,txHeight,txTimestamp,slipageAmtAssetAmt,slipagePriceAssetAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slippageTolerancePassedByUser), toString(slippageToleranceReal), toString(txHeight), toString(txTimestamp), toString(slipageAmtAssetAmt), toString(slipagePriceAssetAmt)], SEP)
289+let slipageContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactSlippCntr]), "Invalid slipage contract address")
290+
291+let gwxContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactGwxRewCntr]), "Invalid gwx contract address")
292+
293+let restContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactoryRestCntr]), "Invalid gwx contract address")
294+
295+func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slipByUser,slippageReal,txHeight,txTimestamp,slipageAmAmt,slipagePrAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slipByUser), toString(slippageReal), toString(txHeight), toString(txTimestamp), toString(slipageAmAmt), toString(slipagePrAmt)], SEP)
285296
286297
287298 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)
288299
289300
290-func getAccBalance (assetId) = {
291- let balanceOnPool = if ((assetId == "WAVES"))
292- then wavesBalance(this).available
293- else assetBalance(this, fromBase58String(assetId))
294- let totalBalance = ((balanceOnPool + getAdditionalBalanceOrZero(assetId)) - getStakingAssetBalanceOrZero(assetId))
295- max([0, totalBalance])
301+func getAccBalance (assetId) = if ((assetId == "WAVES"))
302+ then wavesBalance(this).available
303+ else assetBalance(this, fromBase58String(assetId))
304+
305+
306+func cpbi (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
307+
308+
309+func cpbir (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
310+
311+
312+func vad (A1,A2,slippage) = {
313+ let diff = fraction((A1 - A2), scale8BigInt, A2)
314+ let pass = ((slippage - abs(diff)) > zeroBigInt)
315+ if (!(pass))
316+ then throw(("Big slpg: " + toString(diff)))
317+ else $Tuple2(pass, min([A1, A2]))
296318 }
297319
298320
299-func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
300-
301-
302-func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
303-
304-
305-func getRate (proxy) = {
306- let inv = invoke(proxy, "getRate", nil, nil)
307- if ((inv == inv))
308- then match inv {
309- case r: Int =>
310- r
311- case _ =>
312- throwErr("proxy.getRate() unexpected value")
313- }
314- else throw("Strict value is not equal to itself.")
321+func vd (D1,D0,slpg) = {
322+ let diff = fraction(D0, scale8BigInt, D1)
323+ let fail = (slpg > diff)
324+ if (if (fail)
325+ then true
326+ else (D0 > D1))
327+ then throw(((((((toString(D0) + " ") + toString(D1)) + " ") + toString(diff)) + " ") + toString(slpg)))
328+ else fail
315329 }
316330
317331
318-func deposit (assetId,amount,stakingAssetId,proxy) = {
319- let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
320- if ((currentAdditionalBalance == currentAdditionalBalance))
321- then {
322- let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
323- if ((currentStakingAssetBalance == currentStakingAssetBalance))
324- then {
325- let asset = parseAssetId(assetId)
326- if ((amount > 0))
327- then {
328- let depositInvoke = invoke(proxy, "deposit", nil, [AttachedPayment(asset, amount)])
329- if ((depositInvoke == depositInvoke))
330- then match depositInvoke {
331- case receivedStakingAsset: Int =>
332- let newAdditionalBalance = (currentAdditionalBalance + amount)
333- let newStakingAssetBalance = (currentStakingAssetBalance + receivedStakingAsset)
334-[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance)]
335- case _ =>
336- nil
337- }
338- else throw("Strict value is not equal to itself.")
339- }
340- else nil
341- }
342- else throw("Strict value is not equal to itself.")
343- }
344- else throw("Strict value is not equal to itself.")
345- }
346-
347-
348-func withdraw (assetId,amount,stakingAssetId,proxy,proxyRateMul,profitAddress) = {
349- let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
350- if ((currentAdditionalBalance == currentAdditionalBalance))
351- then {
352- let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
353- if ((currentStakingAssetBalance == currentStakingAssetBalance))
354- then {
355- let currentProxyRate = getRate(proxy)
356- if ((currentProxyRate == currentProxyRate))
357- then {
358- let oldRate = fraction(proxyRateMul, currentAdditionalBalance, currentStakingAssetBalance)
359- let stakingAsset = parseAssetId(stakingAssetId)
360- let oldSendStakingAmount = fraction(proxyRateMul, amount, oldRate)
361- let sendStakingAssetAmount = fraction(proxyRateMul, amount, currentProxyRate)
362- let profitAmount = max([0, (oldSendStakingAmount - sendStakingAssetAmount)])
363- if ((sendStakingAssetAmount > 0))
364- then {
365- let withdrawInvoke = invoke(proxy, "withdraw", nil, [AttachedPayment(stakingAsset, sendStakingAssetAmount)])
366- if ((withdrawInvoke == withdrawInvoke))
367- then match withdrawInvoke {
368- case receivedAssets: Int =>
369- let newAdditionalBalance = (currentAdditionalBalance - receivedAssets)
370- let newStakingAssetBalance = ((currentStakingAssetBalance - sendStakingAssetAmount) - profitAmount)
371-[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance), ScriptTransfer(profitAddress, profitAmount, parseAssetId(stakingAssetId))]
372- case _ =>
373- nil
374- }
375- else throw("Strict value is not equal to itself.")
376- }
377- else nil
378- }
379- else throw("Strict value is not equal to itself.")
380- }
381- else throw("Strict value is not equal to itself.")
382- }
383- else throw("Strict value is not equal to itself.")
384- }
385-
386-
387-func getLeaseProxyConfig (assetId) = match invoke(factoryContract, "getPoolLeaseConfigREADONLY", [toString(this), assetId], nil) {
388- case a: (Boolean, Int, Int, String, String, Int, String) =>
389- a
390- case _ =>
391- throwErr((("[" + assetId) + "] getLeaseProxyConfig() error"))
392-}
393-
394-
395-func rebalanceInternal (targetRatio,assetId,stakingAssetId,minBalance,proxy,proxyRateMul,profitAddress) = {
396- let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
397- if ((currentAdditionalBalance == currentAdditionalBalance))
398- then {
399- let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
400- if ((currentStakingAssetBalance == currentStakingAssetBalance))
401- then {
402- let leasableTotalBalance = max([0, (getAccBalance(assetId) - minBalance)])
403- let targetAdditionalBalance = fraction(targetRatio, leasableTotalBalance, 100)
404- let diff = (currentAdditionalBalance - targetAdditionalBalance)
405- if ((diff == 0))
406- then nil
407- else if ((0 > diff))
408- then {
409- let sendAssetAmount = -(diff)
410- deposit(assetId, sendAssetAmount, stakingAssetId, proxy)
411- }
412- else {
413- let getAssetAmount = diff
414- withdraw(assetId, getAssetAmount, stakingAssetId, proxy, proxyRateMul, profitAddress)
415- }
416- }
417- else throw("Strict value is not equal to itself.")
418- }
419- else throw("Strict value is not equal to itself.")
420- }
421-
422-
423-func rebalanceAsset (assetId) = {
424- let $t01593116067 = getLeaseProxyConfig(assetId)
425- let isLeasable = $t01593116067._1
426- let leasedRatio = $t01593116067._2
427- let minBalance = $t01593116067._3
428- let proxyAddress = $t01593116067._4
429- let proxyAssetId = $t01593116067._5
430- let proxyRateMul = $t01593116067._6
431- let stakingProfitAddress = $t01593116067._7
432- if (isLeasable)
433- then rebalanceInternal(leasedRatio, assetId, proxyAssetId, minBalance, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
434- else nil
435- }
436-
437-
438-func withdrawAndRebalanceAsset (assetId,getAmount) = {
439- let $t01646616602 = getLeaseProxyConfig(assetId)
440- let isLeasable = $t01646616602._1
441- let leasedRatio = $t01646616602._2
442- let minBalance = $t01646616602._3
443- let proxyAddress = $t01646616602._4
444- let proxyAssetId = $t01646616602._5
445- let proxyRateMul = $t01646616602._6
446- let stakingProfitAddress = $t01646616602._7
447- if (isLeasable)
448- then {
449- let newTotalLeasableBalance = max([0, ((getAccBalance(assetId) - getAmount) - minBalance)])
450- if ((newTotalLeasableBalance == newTotalLeasableBalance))
451- then {
452- let newAdditionalBalance = fraction(leasedRatio, newTotalLeasableBalance, 100)
453- if ((newAdditionalBalance == newAdditionalBalance))
454- then {
455- let withdrawAmount = (getAdditionalBalanceOrZero(assetId) - newAdditionalBalance)
456- if ((withdrawAmount == withdrawAmount))
457- then if ((0 > withdrawAmount))
458- then deposit(assetId, -(withdrawAmount), proxyAssetId, addressFromStringValue(proxyAddress))
459- else withdraw(assetId, withdrawAmount, proxyAssetId, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
460- else throw("Strict value is not equal to itself.")
461- }
462- else throw("Strict value is not equal to itself.")
463- }
464- else throw("Strict value is not equal to itself.")
465- }
466- else nil
467- }
468-
469-
470-func withdrawAndRebalanceAll (amountAssetOutAmount,priceAssetOutAmount) = {
471- let AmAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, aa()), amountAssetOutAmount)
472- let PrAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, pa()), priceAssetOutAmount)
473- (AmAmtWithdrawState ++ PrAmtWithdrawState)
474- }
475-
476-
477-func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
478- let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
479- let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
480- calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
332+func pcp (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
333+ let amtAsAmtX18 = t1(amAmt, amAssetDcm)
334+ let prAsAmtX18 = t1(prAmt, prAssetDcm)
335+ cpbi(prAsAmtX18, amtAsAmtX18)
481336 }
482337
483338
484339 func calcPrices (amAmt,prAmt,lpAmt) = {
485- let cfg = getPoolConfig()
486- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
487- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
488- let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
489- let amAmtX18 = toX18(amAmt, amtAssetDcm)
490- let prAmtX18 = toX18(prAmt, priceAssetDcm)
491- let lpAmtX18 = toX18(lpAmt, scale8)
492- let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
493- let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
494-[priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
340+ let amtAsDcm = cfgAmountAssetDecimals
341+ let prAsDcm = cfgPriceAssetDecimals
342+ let priceX18 = pcp(amtAsDcm, prAsDcm, amAmt, prAmt)
343+ let amAmtX18 = t1(amAmt, amtAsDcm)
344+ let prAmtX18 = t1(prAmt, prAsDcm)
345+ let lpAmtX18 = t1(lpAmt, scale8)
346+ let lpPrInAmAsX18 = cpbi(amAmtX18, lpAmtX18)
347+ let lpPrInPrAsX18 = cpbi(prAmtX18, lpAmtX18)
348+[priceX18, lpPrInAmAsX18, lpPrInPrAsX18]
495349 }
496350
497351
498352 func calculatePrices (amAmt,prAmt,lpAmt) = {
499- let prices = calcPrices(amAmt, prAmt, lpAmt)
500-[fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
501- }
502-
503-
504-func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
505- let cfg = getPoolConfig()
506- let lpAssetId = cfg[idxPoolLPAssetId]
507- let amAssetId = cfg[idxAmtAssetId]
508- let prAssetId = cfg[idxPriceAssetId]
509- let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
510- let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
511- let poolStatus = cfg[idxPoolStatus]
512- let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
513- if ((lpAssetId != pmtAssetId))
514- then throw("Invalid asset passed.")
515- else {
516- let amBalance = getAccBalance(amAssetId)
517- let amBalanceX18 = toX18(amBalance, amAssetDcm)
518- let prBalance = getAccBalance(prAssetId)
519- let prBalanceX18 = toX18(prBalance, prAssetDcm)
520- let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
521- let curPrice = fromX18(curPriceX18, scale8)
522- let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
523- let lpEmissionX18 = toX18(lpEmission, scale8)
524- let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
525- let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
526- let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
527- let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
528- let state = if ((txId58 == ""))
529- then nil
530- else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
531- then unit
532- else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
533- then unit
534- else fromBase58String(prAssetId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
535- $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
536- }
537- }
538-
539-
540-func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
541- let cfg = getPoolConfig()
542- let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
543- let amAssetIdStr = cfg[idxAmtAssetId]
544- let prAssetIdStr = cfg[idxPriceAssetId]
545- let iAmtAssetId = cfg[idxIAmtAssetId]
546- let iPriceAssetId = cfg[idxIPriceAssetId]
547- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
548- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
549- let poolStatus = cfg[idxPoolStatus]
550- let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
551- let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
552- let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
553- if (if ((amAssetIdStr != inAmAssetIdStr))
554- then true
555- else (prAssetIdStr != inPrAssetIdStr))
556- then throw("Invalid amt or price asset passed.")
557- else {
558- let amBalance = if (isEvaluate)
559- then getAccBalance(amAssetIdStr)
560- else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
561- let prBalance = if (isEvaluate)
562- then getAccBalance(prAssetIdStr)
563- else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
564- let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
565- let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
566- let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
567- let amBalanceX18 = toX18(amBalance, amtAssetDcm)
568- let prBalanceX18 = toX18(prBalance, priceAssetDcm)
569- let res = if ((lpEmission == 0))
570- then {
571- let curPriceX18 = zeroBigInt
572- let slippageX18 = zeroBigInt
573- let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
574- $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
575- }
576- else {
577- let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
578- let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
579- let slippageToleranceX18 = toX18(slippageTolerance, scale8)
580- if (if ((curPriceX18 != zeroBigInt))
581- then (slippageX18 > slippageToleranceX18)
582- else false)
583- then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
584- else {
585- let lpEmissionX18 = toX18(lpEmission, scale8)
586- let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
587- let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
588- let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
589- then $Tuple2(amViaPrX18, inPrAssetAmtX18)
590- else $Tuple2(inAmAssetAmtX18, prViaAmX18)
591- let expAmtAssetAmtX18 = expectedAmts._1
592- let expPriceAssetAmtX18 = expectedAmts._2
593- let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
594- $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
595- }
596- }
597- let calcLpAmt = res._1
598- let calcAmAssetPmt = res._2
599- let calcPrAssetPmt = res._3
600- let curPrice = fromX18(res._4, scale8)
601- let slippageCalc = fromX18(res._5, scale8)
602- if ((0 >= calcLpAmt))
603- then throw("Invalid calculations. LP calculated is less than zero.")
604- else {
605- let emitLpAmt = if (!(emitLp))
606- then 0
607- else calcLpAmt
608- let amDiff = (inAmAssetAmt - calcAmAssetPmt)
609- let prDiff = (inPrAssetAmt - calcPrAssetPmt)
610- let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(calcAmAssetPmt, calcPrAssetPmt, emitLpAmt, curPrice, slippageTolerance, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
611- $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
612- }
613- }
614- }
615-
616-
617-func calcKLp (amountBalance,priceBalance,lpEmission) = {
618- let amountBalanceX18 = toX18BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals))
619- let priceBalanceX18 = toX18BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))
620- let updatedKLp = fraction(pow((amountBalanceX18 * priceBalanceX18), 0, toBigInt(5), 1, 18, DOWN), big1, lpEmission)
621- if ((lpEmission == big0))
622- then big0
623- else updatedKLp
624- }
625-
626-
627-func calcCurrentKLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
628- let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
629- let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
630- let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
631- let currentKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
632- currentKLp
633- }
634-
635-
636-func refreshKLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
637- let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
638- let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
639- let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
640- let updatedKLp = calcKLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
641- let actions = [IntegerEntry(keyKLpRefreshedHeight, height), StringEntry(keyKLp, toString(updatedKLp))]
642- $Tuple2(actions, updatedKLp)
643- }
644-
645-
646-func skipOrderValidation () = valueOrElse(getBoolean(factoryContract, keySkipOrderValidation(toString(this))), false)
647-
648-
649-func validateUpdatedKLp (oldKLp,updatedKLp) = if ((updatedKLp >= oldKLp))
650- then true
651- else throwErr(makeString(["updated KLp lower than current KLp", toString(oldKLp), toString(updatedKLp)], " "))
652-
653-
654-func validateMatcherOrderAllowed (order) = {
655- let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
656- let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
657- let amountAssetAmount = order.amount
658- let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
659- let $t02899129203 = if ((order.orderType == Buy))
660- then $Tuple2(amountAssetAmount, -(priceAssetAmount))
661- else $Tuple2(-(amountAssetAmount), priceAssetAmount)
662- let amountAssetBalanceDelta = $t02899129203._1
663- let priceAssetBalanceDelta = $t02899129203._2
664- if (if (if (isGlobalShutdown())
665- then true
666- else (cfgPoolStatus == PoolMatcherDisabled))
667- then true
668- else (cfgPoolStatus == PoolShutdown))
669- then throw("Exchange operations disabled")
670- else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
671- then true
672- else (order.assetPair.priceAsset != cfgPriceAssetId))
673- then throw("Wrong order assets.")
674- else {
675- let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
676- let $t02964329743 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
677- let unusedActions = $t02964329743._1
678- let kLpNew = $t02964329743._2
679- let isOrderValid = (kLpNew >= kLp)
680- let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
681- $Tuple2(isOrderValid, info)
682- }
683- }
684-
685-
686-func commonGet (i) = if ((size(i.payments) != 1))
687- then throw("exactly 1 payment is expected")
688- else {
689- let pmt = value(i.payments[0])
690- let pmtAssetId = value(pmt.assetId)
691- let pmtAmt = pmt.amount
692- let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
693- let outAmAmt = res._1
694- let outPrAmt = res._2
695- let poolStatus = parseIntValue(res._9)
696- let state = res._10
697- if (if (isGlobalShutdown())
698- then true
699- else (poolStatus == PoolShutdown))
700- then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
701- else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
702- }
703-
704-
705-func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
706- then throw("exactly 2 payments are expected")
707- else {
708- let amAssetPmt = value(i.payments[0])
709- let prAssetPmt = value(i.payments[1])
710- let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
711- let poolStatus = parseIntValue(estPut._8)
712- if (if (if (isGlobalShutdown())
713- then true
714- else (poolStatus == PoolPutDisabled))
715- then true
716- else (poolStatus == PoolShutdown))
717- then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
718- else estPut
719- }
720-
721-
722-func emit (amount) = {
723- let emitInv = invoke(factoryContract, "emit", [amount], nil)
724- if ((emitInv == emitInv))
725- then {
726- let emitInvLegacy = match emitInv {
727- case legacyFactoryContract: Address =>
728- invoke(legacyFactoryContract, "emit", [amount], nil)
729- case _ =>
730- unit
731- }
732- if ((emitInvLegacy == emitInvLegacy))
733- then amount
734- else throw("Strict value is not equal to itself.")
735- }
736- else throw("Strict value is not equal to itself.")
353+ let p = calcPrices(amAmt, prAmt, lpAmt)
354+[f1(p[0], scale8), f1(p[1], scale8), f1(p[2], scale8)]
737355 }
738356
739357
745363 }
746364
747365
748-func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
749- let isEval = (txId == unit)
750- let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
751- let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
752- let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
366+func getD (xp) = {
367+ let xp0 = xp[0]
368+ let xp1 = xp[1]
369+ let s = (xp0 + xp1)
370+ if ((s == big0))
371+ then big0
372+ else {
373+ let a = parseIntValue(A)
374+ let ann = (a * 2)
375+ let p = fraction(xp0, xp1, big1)
376+ let xp0_xp1_n_n = fraction(p, big4, big1)
377+ let ann_s = fraction(toBigInt(ann), s, big1)
378+ let ann_1 = toBigInt((ann - 1))
379+ func calcDNext (d) = {
380+ let dd = fraction(d, d, big1)
381+ let ddd = fraction(dd, d, big1)
382+ let dp = fraction(ddd, big1, xp0_xp1_n_n)
383+ fraction((ann_s + fraction(dp, big2, big1)), d, (fraction(ann_1, d, big1) + fraction(big3, dp, big1)))
384+ }
385+
386+ func calc (acc,i) = if (acc._2)
387+ then acc
388+ else {
389+ let d = acc._1
390+ let dNext = calcDNext(d)
391+ let dDiffRaw = (dNext - value(d))
392+ let dDiff = if ((big0 > dDiffRaw))
393+ then -(dDiffRaw)
394+ else dDiffRaw
395+ if ((big1 >= dDiff))
396+ then $Tuple2(dNext, true)
397+ else $Tuple2(dNext, false)
398+ }
399+
400+ let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
401+ let $t01329913347 = {
402+ let $l = arr
403+ let $s = size($l)
404+ let $acc0 = $Tuple2(s, false)
405+ func $f0_1 ($a,$i) = if (($i >= $s))
406+ then $a
407+ else calc($a, $l[$i])
408+
409+ func $f0_2 ($a,$i) = if (($i >= $s))
410+ then $a
411+ else throw("List size exceeds 17")
412+
413+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17)
414+ }
415+ let d = $t01329913347._1
416+ let found = $t01329913347._2
417+ if (found)
418+ then d
419+ else throw(("D calculation error, D = " + toString(d)))
420+ }
421+ }
422+
423+
424+func ego (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
425+ let lpId = cfgLpAssetId
426+ let amId = toBase58String(value(cfgAmountAssetId))
427+ let prId = toBase58String(value(cfgPriceAssetId))
428+ let amDcm = cfgAmountAssetDecimals
429+ let prDcm = cfgPriceAssetDecimals
430+ let sts = toString(cfgPoolStatus)
431+ let lpEmiss = valueOrErrorMessage(assetInfo(lpId), "Wrong LP id").quantity
432+ if ((toBase58String(lpId) != pmtAssetId))
433+ then throw("Wrong pmt asset")
434+ else {
435+ let amBalance = getAccBalance(amId)
436+ let amBalanceX18 = t1(amBalance, amDcm)
437+ let prBalance = getAccBalance(prId)
438+ let prBalanceX18 = t1(prBalance, prDcm)
439+ let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
440+ let curPrice = f1(curPriceX18, scale8)
441+ let pmtLpAmtX18 = t1(pmtLpAmt, scale8)
442+ let lpEmissX18 = t1(lpEmiss, scale8)
443+ let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissX18)
444+ let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissX18)
445+ let outAmAmt = fromX18Round(outAmAmtX18, amDcm, FLOOR)
446+ let outPrAmt = fromX18Round(outPrAmtX18, prDcm, FLOOR)
447+ let state = if ((txId58 == ""))
448+ then nil
449+ else [ScriptTransfer(userAddress, outAmAmt, if ((amId == "WAVES"))
450+ then unit
451+ else fromBase58String(amId)), ScriptTransfer(userAddress, outPrAmt, if ((prId == "WAVES"))
452+ then unit
453+ else fromBase58String(prId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
454+ $Tuple10(outAmAmt, outPrAmt, amId, prId, amBalance, prBalance, lpEmiss, curPriceX18, sts, state)
455+ }
456+ }
457+
458+
459+func epo (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEval,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
460+ let lpId = cfgLpAssetId
461+ let amIdStr = toBase58String(value(cfgAmountAssetId))
462+ let prIdStr = toBase58String(value(cfgPriceAssetId))
463+ let amtDcm = cfgAmountAssetDecimals
464+ let priceDcm = cfgPriceAssetDecimals
465+ let sts = toString(cfgPoolStatus)
466+ let lpEm = valueOrErrorMessage(assetInfo(lpId), "Wr lp as").quantity
467+ let amBalance = if (isEval)
468+ then getAccBalance(amIdStr)
469+ else if (if (isOneAsset)
470+ then (pmtId == amIdStr)
471+ else false)
472+ then (getAccBalance(amIdStr) - pmtAmt)
473+ else if (isOneAsset)
474+ then getAccBalance(amIdStr)
475+ else (getAccBalance(amIdStr) - inAmAmt)
476+ let prBalance = if (isEval)
477+ then getAccBalance(prIdStr)
478+ else if (if (isOneAsset)
479+ then (pmtId == prIdStr)
480+ else false)
481+ then (getAccBalance(prIdStr) - pmtAmt)
482+ else if (isOneAsset)
483+ then getAccBalance(prIdStr)
484+ else (getAccBalance(prIdStr) - inPrAmt)
485+ let inAmAssetAmtX18 = t1(inAmAmt, amtDcm)
486+ let inPrAssetAmtX18 = t1(inPrAmt, priceDcm)
487+ let userPriceX18 = cpbi(inPrAssetAmtX18, inAmAssetAmtX18)
488+ let amBalanceX18 = t1(amBalance, amtDcm)
489+ let prBalanceX18 = t1(prBalance, priceDcm)
490+ let D0 = getD([amBalanceX18, prBalanceX18])
491+ let r = if ((lpEm == 0))
492+ then {
493+ let D1 = getD([(amBalanceX18 + inAmAssetAmtX18), (prBalanceX18 + inPrAssetAmtX18)])
494+ let checkD = if ((D1 > D0))
495+ then true
496+ else throw("D1 should be greater than D0")
497+ if ((checkD == checkD))
498+ then {
499+ let curPriceX18 = zeroBigInt
500+ let slippageX18 = zeroBigInt
501+ let lpAmtX18 = D1
502+ $Tuple5(f1(lpAmtX18, scale8), f1(inAmAssetAmtX18, amtDcm), f1(inPrAssetAmtX18, priceDcm), cpbi((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
503+ }
504+ else throw("Strict value is not equal to itself.")
505+ }
506+ else {
507+ let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
508+ let slippageRealX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
509+ let slippageX18 = t1(slippage, scale8)
510+ if (if (if (validateSlippage)
511+ then (curPriceX18 != zeroBigInt)
512+ else false)
513+ then (slippageRealX18 > slippageX18)
514+ else false)
515+ then throw(((("Price slippage " + toString(slippageRealX18)) + " > ") + toString(slippageX18)))
516+ else {
517+ let lpEmissionX18 = t1(lpEm, scale8)
518+ let prViaAmX18 = fraction(inAmAssetAmtX18, cpbir(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
519+ let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, cpbir(prBalanceX18, amBalanceX18, FLOOR), CEILING)
520+ let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
521+ then $Tuple2(amViaPrX18, inPrAssetAmtX18)
522+ else $Tuple2(inAmAssetAmtX18, prViaAmX18)
523+ let expAmtAssetAmtX18 = expectedAmts._1
524+ let expPriceAssetAmtX18 = expectedAmts._2
525+ let D1 = getD([(amBalanceX18 + expAmtAssetAmtX18), (prBalanceX18 + expPriceAssetAmtX18)])
526+ let checkD = if ((D1 > D0))
527+ then true
528+ else throw("D1 should be greater than D0")
529+ if ((checkD == checkD))
530+ then {
531+ let lpAmtX18 = fraction(lpEmissionX18, (D1 - D0), D0)
532+ $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceDcm, CEILING), curPriceX18, slippageX18)
533+ }
534+ else throw("Strict value is not equal to itself.")
535+ }
536+ }
537+ let calcLpAmt = r._1
538+ let calcAmAssetPmt = r._2
539+ let calcPrAssetPmt = r._3
540+ let curPrice = f1(r._4, scale8)
541+ let slippageCalc = f1(r._5, scale8)
542+ if ((0 >= calcLpAmt))
543+ then throw("LP <= 0")
544+ else {
545+ let emitLpAmt = if (!(emitLp))
546+ then 0
547+ else calcLpAmt
548+ let amDiff = (inAmAmt - calcAmAssetPmt)
549+ let prDiff = (inPrAmt - calcPrAssetPmt)
550+ let $t02110921454 = if (if (isOneAsset)
551+ then (pmtId == amIdStr)
552+ else false)
553+ then $Tuple2(pmtAmt, 0)
554+ else if (if (isOneAsset)
555+ then (pmtId == prIdStr)
556+ else false)
557+ then $Tuple2(0, pmtAmt)
558+ else $Tuple2(calcAmAssetPmt, calcPrAssetPmt)
559+ let writeAmAmt = $t02110921454._1
560+ let writePrAmt = $t02110921454._2
561+ let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(writeAmAmt, writePrAmt, emitLpAmt, curPrice, slippage, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
562+ $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEm, lpId, sts, commonState, amDiff, prDiff, inAmId, inPrId)
563+ }
564+ }
565+
566+
567+func getYD (xp,i,D) = {
568+ let n = big2
569+ let x = xp[if ((i == 0))
570+ then 1
571+ else 0]
572+ let aPrecision = parseBigIntValue(Amult)
573+ let a = (parseBigIntValue(A) * aPrecision)
574+ let s = x
575+ let ann = (a * n)
576+ let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
577+ let b = ((s + ((D * aPrecision) / ann)) - D)
578+ func calc (acc,cur) = {
579+ let $t02264922669 = acc
580+ let y = $t02264922669._1
581+ let found = $t02264922669._2
582+ if ((found != unit))
583+ then acc
584+ else {
585+ let yNext = (((y * y) + c) / ((big2 * y) + b))
586+ let yDiff = absBigInt((yNext - value(y)))
587+ if ((big1 >= yDiff))
588+ then $Tuple2(yNext, cur)
589+ else $Tuple2(yNext, unit)
590+ }
591+ }
592+
593+ let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
594+ let $t02297623023 = {
595+ let $l = arr
596+ let $s = size($l)
597+ let $acc0 = $Tuple2(D, unit)
598+ func $f0_1 ($a,$i) = if (($i >= $s))
599+ then $a
600+ else calc($a, $l[$i])
601+
602+ func $f0_2 ($a,$i) = if (($i >= $s))
603+ then $a
604+ else throw("List size exceeds 15")
605+
606+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
607+ }
608+ let y = $t02297623023._1
609+ let found = $t02297623023._2
610+ if ((found != unit))
611+ then y
612+ else throw(("Y calculation error, Y = " + toString(y)))
613+ }
614+
615+
616+func calcDLp (amountBalance,priceBalance,lpEmission) = {
617+ let updatedDLp = fraction(getD([t1BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals)), t1BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))]), scale18, lpEmission)
618+ if ((lpEmission == big0))
619+ then big0
620+ else updatedDLp
621+ }
622+
623+
624+func calcCurrentDLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
625+ let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
626+ let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
627+ let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
628+ let currentDLp = calcDLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
629+ currentDLp
630+ }
631+
632+
633+func refreshDLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
634+ let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
635+ let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
636+ let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
637+ let updatedDLp = calcDLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
638+ let actions = [IntegerEntry(keyDLpRefreshedHeight, height), StringEntry(keyDLp, toString(updatedDLp))]
639+ $Tuple2(actions, updatedDLp)
640+ }
641+
642+
643+func validateUpdatedDLp (oldDLp,updatedDLp) = if ((updatedDLp >= oldDLp))
644+ then true
645+ else throwErr("updated DLp lower than current DLp")
646+
647+
648+func validateMatcherOrderAllowed (order) = {
649+ let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
650+ let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
651+ let amountAssetAmount = order.amount
652+ let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
653+ let $t02522125433 = if ((order.orderType == Buy))
654+ then $Tuple2(amountAssetAmount, -(priceAssetAmount))
655+ else $Tuple2(-(amountAssetAmount), priceAssetAmount)
656+ let amountAssetBalanceDelta = $t02522125433._1
657+ let priceAssetBalanceDelta = $t02522125433._2
658+ if (if (if (igs())
753659 then true
754- else if ((paymentAssetId == cfgPriceAssetId))
755- then false
756- else throwErr("invalid asset")
757- let $t03285633149 = if (isEval)
758- then $Tuple2(amountBalanceRaw, priceBalanceRaw)
759- else if (paymentInAmountAsset)
760- then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
761- else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
762- let amountBalanceOld = $t03285633149._1
763- let priceBalanceOld = $t03285633149._2
764- let $t03315333302 = if (paymentInAmountAsset)
765- then $Tuple2(paymentAmountRaw, 0)
766- else $Tuple2(0, paymentAmountRaw)
767- let amountAssetAmountRaw = $t03315333302._1
768- let priceAssetAmountRaw = $t03315333302._2
769- let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
770- let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
771- let $t03343433498 = takeFee(paymentAmountRaw, inFee)
772- let paymentAmount = $t03343433498._1
773- let feeAmount = $t03343433498._2
774- let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
775- let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
776- let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
777- let priceNew = fromX18(priceNewX18, scale8)
778- let paymentBalance = if (paymentInAmountAsset)
779- then amountBalanceOld
780- else priceBalanceOld
781- let paymentBalanceBigInt = toBigInt(paymentBalance)
782- let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
783- let chechSupply = if ((supplyBigInt > big0))
660+ else (cfgPoolStatus == PoolMatcherDis))
784661 then true
785- else throwErr("initial deposit requires all coins")
786- if ((chechSupply == chechSupply))
662+ else (cfgPoolStatus == PoolShutdown))
663+ then throw("Admin blocked")
664+ else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
665+ then true
666+ else (order.assetPair.priceAsset != cfgPriceAssetId))
667+ then throw("Wr assets")
668+ else {
669+ let dLp = parseBigIntValue(valueOrElse(getString(this, keyDLp), "0"))
670+ let $t02577525875 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
671+ let unusedActions = $t02577525875._1
672+ let dLpNew = $t02577525875._2
673+ let isOrderValid = (dLpNew >= dLp)
674+ let info = makeString(["dLp=", toString(dLp), " dLpNew=", toString(dLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
675+ $Tuple2(isOrderValid, info)
676+ }
677+ }
678+
679+
680+func cg (i) = if ((size(i.payments) != 1))
681+ then throw("1 pmnt exp")
682+ else {
683+ let pmt = value(i.payments[0])
684+ let pmtAssetId = value(pmt.assetId)
685+ let pmtAmt = pmt.amount
686+ let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
687+ let outAmAmt = r._1
688+ let outPrAmt = r._2
689+ let sts = parseIntValue(r._9)
690+ let state = r._10
691+ if (if (igs())
692+ then true
693+ else (sts == PoolShutdown))
694+ then throw(("Admin blocked: " + toString(sts)))
695+ else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
696+ }
697+
698+
699+func cp (caller,txId,amAsPmt,prAsPmt,slippage,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
700+ let r = epo(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, (txId == ""), emitLp, isOneAsset, validateSlippage, pmtAmt, pmtId)
701+ let sts = parseIntValue(r._8)
702+ if (if (if (igs())
703+ then true
704+ else (sts == PoolPutDis))
705+ then true
706+ else (sts == PoolShutdown))
707+ then throw(("Blocked:" + toString(sts)))
708+ else r
709+ }
710+
711+
712+func calcPutOneTkn (pmtAmtRaw,pmtAssetId,userAddress,txId,withTakeFee) = {
713+ let amId = toBase58String(value(cfgAmountAssetId))
714+ let prId = toBase58String(value(cfgPriceAssetId))
715+ let lpId = cfgLpAssetId
716+ let amtDcm = cfgAmountAssetDecimals
717+ let priceDcm = cfgPriceAssetDecimals
718+ let lpAssetEmission = toBigInt(valueOrErrorMessage(assetInfo(lpId), "invalid lp asset").quantity)
719+ let chechEmission = if ((lpAssetEmission > big0))
720+ then true
721+ else throw("initial deposit requires all coins")
722+ if ((chechEmission == chechEmission))
787723 then {
788- let depositBigInt = toBigInt(paymentAmount)
789- let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
790- let commonState = if (isEval)
791- then nil
792- else [IntegerEntry(pl(), priceNew), IntegerEntry(ph(height, lastBlock.timestamp), priceNew), StringEntry(pau(toString(value(userAddress)), toBase58String(value(txId))), dataPutActionInfo(amountAssetAmountRaw, priceAssetAmountRaw, issueAmount, priceNew, 0, 0, height, lastBlock.timestamp, 0, 0))]
793- let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
794- let priceOld = fromX18(priceOldX18, scale8)
795- let loss = {
796- let $t03517935346 = if (paymentInAmountAsset)
797- then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
798- else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
799- let amount = $t03517935346._1
800- let balance = $t03517935346._2
801- let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
802- fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
803- }
804- $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
724+ let amBalance = getAccBalance(amId)
725+ let prBalance = getAccBalance(prId)
726+ let $t02853128993 = if ((txId == ""))
727+ then $Tuple2(amBalance, prBalance)
728+ else if ((pmtAssetId == amId))
729+ then if ((pmtAmtRaw > amBalance))
730+ then throw("invalid payment amount")
731+ else $Tuple2((amBalance - pmtAmtRaw), prBalance)
732+ else if ((pmtAssetId == prId))
733+ then if ((pmtAmtRaw > prBalance))
734+ then throw("invalid payment amount")
735+ else $Tuple2(amBalance, (prBalance - pmtAmtRaw))
736+ else throw("wrong pmtAssetId")
737+ let amBalanceOld = $t02853128993._1
738+ let prBalanceOld = $t02853128993._2
739+ let $t02899929175 = if ((pmtAssetId == amId))
740+ then $Tuple2(pmtAmtRaw, 0)
741+ else if ((pmtAssetId == prId))
742+ then $Tuple2(0, pmtAmtRaw)
743+ else throw("invalid payment")
744+ let amAmountRaw = $t02899929175._1
745+ let prAmountRaw = $t02899929175._2
746+ let $t02917929433 = if (withTakeFee)
747+ then $Tuple3(takeFee(amAmountRaw, inFee)._1, takeFee(prAmountRaw, inFee)._1, takeFee(pmtAmtRaw, inFee)._2)
748+ else $Tuple3(amAmountRaw, prAmountRaw, 0)
749+ let amAmount = $t02917929433._1
750+ let prAmount = $t02917929433._2
751+ let feeAmount = $t02917929433._3
752+ let amBalanceNew = (amBalanceOld + amAmount)
753+ let prBalanceNew = (prBalanceOld + prAmount)
754+ let D0 = getD([t1(amBalanceOld, cfgAmountAssetDecimals), t1(prBalanceOld, cfgPriceAssetDecimals)])
755+ let D1 = getD([t1(amBalanceNew, cfgAmountAssetDecimals), t1(prBalanceNew, cfgPriceAssetDecimals)])
756+ let checkD = if ((D1 > D0))
757+ then true
758+ else throw()
759+ if ((checkD == checkD))
760+ then {
761+ let lpAmount = fraction(lpAssetEmission, (D1 - D0), D0, FLOOR)
762+ let curPrice = f1(cpbi(t1(prBalanceNew, priceDcm), t1(amBalanceNew, amtDcm)), scale8)
763+ let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId), dataPutActionInfo(amAmountRaw, prAmountRaw, toInt(lpAmount), curPrice, 0, 0, height, lastBlock.timestamp, 0, 0))]
764+ let poolProportion = fraction(prBalanceOld, scale8, amBalanceOld)
765+ let amountAssetPart = fraction(pmtAmtRaw, scale8, (poolProportion + scale8))
766+ let priceAssetPart = (pmtAmtRaw - amountAssetPart)
767+ let lpAmtBoth = fraction(lpAssetEmission, toBigInt(priceAssetPart), toBigInt(prBalanceOld))
768+ let bonus = toInt(fraction((lpAmount - lpAmtBoth), scale8BigInt, lpAmtBoth))
769+ $Tuple4(toInt(lpAmount), commonState, feeAmount, bonus)
770+ }
771+ else throw("Strict value is not equal to itself.")
805772 }
806773 else throw("Strict value is not equal to itself.")
807774 }
808775
809776
810-func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
811- let isEval = (txId == unit)
812- let cfg = getPoolConfig()
813- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
814- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
815- let checks = [if ((paymentAssetId == cfgLpAssetId))
816- then true
817- else throwErr("invalid lp asset")]
818- if ((checks == checks))
777+func getOneTknV2Internal (outAssetId,minOutAmount,payments,caller,originCaller,transactionId) = {
778+ let lpId = toBase58String(value(cfgLpAssetId))
779+ let amId = toBase58String(value(cfgAmountAssetId))
780+ let prId = toBase58String(value(cfgPriceAssetId))
781+ let amDecimals = cfgAmountAssetDecimals
782+ let prDecimals = cfgPriceAssetDecimals
783+ let poolStatus = cfgPoolStatus
784+ let userAddress = if ((caller == restContract))
785+ then originCaller
786+ else caller
787+ let pmt = value(payments[0])
788+ let pmtAssetId = value(pmt.assetId)
789+ let pmtAmt = pmt.amount
790+ let currentDLp = calcCurrentDLp(big0, big0, big0)
791+ if ((currentDLp == currentDLp))
819792 then {
820- let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
821- then true
822- else if ((outAssetId == cfgPriceAssetId))
823- then false
824- else throwErr("invalid asset")
825- let balanceBigInt = if (outInAmountAsset)
826- then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
827- else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
828- let outInAmountAssetDecimals = if (outInAmountAsset)
829- then amtAssetDcm
830- else priceAssetDcm
831- let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
832- let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
833- let outBalance = if (outInAmountAsset)
834- then amBalanceOld
835- else prBalanceOld
836- let outBalanceBigInt = toBigInt(outBalance)
837- let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
838- let redeemedBigInt = toBigInt(paymentAmount)
839- let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
840- let $t03742437480 = takeFee(amountRaw, outFee)
841- let totalAmount = $t03742437480._1
842- let feeAmount = $t03742437480._2
843- let $t03748437710 = if (outInAmountAsset)
844- then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
845- else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
846- let outAmAmount = $t03748437710._1
847- let outPrAmount = $t03748437710._2
848- let amBalanceNew = $t03748437710._3
849- let prBalanceNew = $t03748437710._4
850- let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
851- let priceNew = fromX18(priceNewX18, scale8)
852- let commonState = if (isEval)
853- then nil
854- else [StringEntry(gau(toString(value(userAddress)), toBase58String(value(txId))), dataGetActionInfo(outAmAmount, outPrAmount, paymentAmount, priceNew, height, lastBlock.timestamp)), IntegerEntry(pl(), priceNew), IntegerEntry(ph(height, lastBlock.timestamp), priceNew)]
855- let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
856- let priceOld = fromX18(priceOldX18, scale8)
857- let loss = {
858- let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
859- fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
860- }
861- $Tuple5(totalAmount, commonState, feeAmount, loss, outInAmountAsset)
793+ let txId58 = toBase58String(transactionId)
794+ if ((lpId != toBase58String(pmtAssetId)))
795+ then throw("Wrong LP")
796+ else {
797+ let amBalance = getAccBalance(amId)
798+ let prBalance = getAccBalance(prId)
799+ let $t03154531656 = {
800+ let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, pmtAmt], nil)
801+ if ($isInstanceOf(@, "(Int, Int)"))
802+ then @
803+ else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
804+ }
805+ if (($t03154531656 == $t03154531656))
806+ then {
807+ let feeAmount = $t03154531656._2
808+ let totalGet = $t03154531656._1
809+ let totalAmount = if (if ((minOutAmount > 0))
810+ then (minOutAmount > totalGet)
811+ else false)
812+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
813+ else totalGet
814+ let $t03184632153 = if ((outAssetId == amId))
815+ then $Tuple4(totalAmount, 0, ((amBalance - totalAmount) - feeAmount), prBalance)
816+ else if ((outAssetId == prId))
817+ then $Tuple4(0, totalAmount, amBalance, ((prBalance - totalAmount) - feeAmount))
818+ else throw("invalid out asset id")
819+ let outAm = $t03184632153._1
820+ let outPr = $t03184632153._2
821+ let amBalanceNew = $t03184632153._3
822+ let prBalanceNew = $t03184632153._4
823+ let curPrX18 = cpbi(t1(prBalanceNew, prDecimals), t1(amBalanceNew, amDecimals))
824+ let curPr = f1(curPrX18, scale8)
825+ let outAssetIdOrWaves = if ((outAssetId == "WAVES"))
826+ then unit
827+ else fromBase58String(outAssetId)
828+ let sendFeeToMatcher = if ((feeAmount > 0))
829+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetIdOrWaves)]
830+ else nil
831+ let state = ([ScriptTransfer(userAddress, totalAmount, outAssetIdOrWaves), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, pmtAmt, curPr, height, lastBlock.timestamp)), IntegerEntry(pl(), curPr), IntegerEntry(ph(height, lastBlock.timestamp), curPr)] ++ sendFeeToMatcher)
832+ if ((state == state))
833+ then {
834+ let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
835+ if ((burn == burn))
836+ then {
837+ let $t03293833288 = {
838+ let feeAmountForCalc = if ((this == feeCollectorAddress))
839+ then 0
840+ else feeAmount
841+ let outInAmountAsset = if ((parseAssetId(outAssetId) == cfgAmountAssetId))
842+ then true
843+ else false
844+ if (outInAmountAsset)
845+ then $Tuple2(-((totalGet + feeAmountForCalc)), 0)
846+ else $Tuple2(0, -((totalGet + feeAmountForCalc)))
847+ }
848+ let amountAssetBalanceDelta = $t03293833288._1
849+ let priceAssetBalanceDelta = $t03293833288._2
850+ let $t03329133399 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
851+ let refreshDLpActions = $t03329133399._1
852+ let updatedDLp = $t03329133399._2
853+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
854+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
855+ then $Tuple2((state ++ refreshDLpActions), totalAmount)
856+ else throw("Strict value is not equal to itself.")
857+ }
858+ else throw("Strict value is not equal to itself.")
859+ }
860+ else throw("Strict value is not equal to itself.")
861+ }
862+ else throw("Strict value is not equal to itself.")
863+ }
862864 }
863865 else throw("Strict value is not equal to itself.")
864866 }
877879 }
878880
879881
882+let pd = throw("Permission denied")
883+
880884 func isManager (i) = match managerPublicKeyOrUnit() {
881885 case pk: ByteVector =>
882886 (i.callerPublicKey == pk)
887891 }
888892
889893
890-func mustManager (i) = {
891- let pd = throw("Permission denied")
892- match managerPublicKeyOrUnit() {
893- case pk: ByteVector =>
894- if ((i.callerPublicKey == pk))
895- then true
896- else pd
897- case _: Unit =>
898- if ((i.caller == this))
899- then true
900- else pd
901- case _ =>
902- throw("Match error")
903- }
894+func mustManager (i) = match managerPublicKeyOrUnit() {
895+ case pk: ByteVector =>
896+ if ((i.callerPublicKey == pk))
897+ then true
898+ else pd
899+ case _: Unit =>
900+ if ((i.caller == this))
901+ then true
902+ else pd
903+ case _ =>
904+ throw("Match error")
905+}
906+
907+
908+func getY (isReverse,D,poolAmountInBalance) = {
909+ let poolConfig = gpc()
910+ let amId = poolConfig[idxAmAsId]
911+ let prId = poolConfig[idxPrAsId]
912+ let n = big2
913+ let aPrecision = parseBigIntValue(Amult)
914+ let a = (parseBigIntValue(A) * aPrecision)
915+ let xp = if ((isReverse == false))
916+ then [(toBigInt(getAccBalance(amId)) + poolAmountInBalance), toBigInt(getAccBalance(prId))]
917+ else [(toBigInt(getAccBalance(prId)) + poolAmountInBalance), toBigInt(getAccBalance(amId))]
918+ let x = xp[0]
919+ let s = x
920+ let ann = (a * n)
921+ let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
922+ let b = ((s + ((D * aPrecision) / ann)) - D)
923+ func calc (acc,cur) = {
924+ let $t03488634906 = acc
925+ let y = $t03488634906._1
926+ let found = $t03488634906._2
927+ if ((found != unit))
928+ then acc
929+ else {
930+ let yNext = (((y * y) + c) / ((big2 * y) + b))
931+ let yDiff = absBigInt((yNext - value(y)))
932+ if ((big1 >= yDiff))
933+ then $Tuple2(yNext, cur)
934+ else $Tuple2(yNext, unit)
935+ }
936+ }
937+
938+ let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
939+ let $t03523735284 = {
940+ let $l = arr
941+ let $s = size($l)
942+ let $acc0 = $Tuple2(D, unit)
943+ func $f0_1 ($a,$i) = if (($i >= $s))
944+ then $a
945+ else calc($a, $l[$i])
946+
947+ func $f0_2 ($a,$i) = if (($i >= $s))
948+ then $a
949+ else throw("List size exceeds 15")
950+
951+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
952+ }
953+ let y = $t03523735284._1
954+ let found = $t03523735284._2
955+ if ((found != unit))
956+ then y
957+ else throw(("Y calculation error, Y = " + toString(y)))
904958 }
905959
906960
907-@Callable(i)
908-func rebalance () = (rebalanceAsset(getStringOrFail(this, aa())) ++ rebalanceAsset(getStringOrFail(this, pa())))
909-
961+func skipOrderValidation () = valueOrElse(getBoolean(fca, keySkipOrderValidation(toString(this))), false)
910962
911963
912964 @Callable(i)
913965 func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse,feePoolAmount) = {
914- let $t03956939874 = if ((isReverse == false))
966+ let $t03563636060 = if ((isReverse == false))
915967 then {
916- let assetOut = getStringOrFail(this, pa())
917- let assetIn = getStringOrFail(this, aa())
918- $Tuple2(assetOut, assetIn)
968+ let assetOut = strf(this, pa())
969+ let poolAmountInBalance = (toBigInt(getAccBalance(strf(this, aa()))) + toBigInt(cleanAmountIn))
970+ $Tuple2(assetOut, poolAmountInBalance)
919971 }
920972 else {
921- let assetOut = getStringOrFail(this, aa())
922- let assetIn = getStringOrFail(this, pa())
923- $Tuple2(assetOut, assetIn)
973+ let assetOut = strf(this, aa())
974+ let poolAmountInBalance = (toBigInt(getAccBalance(strf(this, pa()))) + toBigInt(cleanAmountIn))
975+ $Tuple2(assetOut, poolAmountInBalance)
924976 }
925- let assetOut = $t03956939874._1
926- let assetIn = $t03956939874._2
927- let poolAssetInBalance = getAccBalance(assetIn)
928- let poolAssetOutBalance = getAccBalance(assetOut)
929- let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
930- let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
931- let newK = (((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
932- let checkK = if ((newK >= oldK))
977+ let assetOut = $t03563636060._1
978+ let poolAmountInBalance = $t03563636060._2
979+ let poolConfig = gpc()
980+ let amId = poolConfig[idxAmAsId]
981+ let prId = poolConfig[idxPrAsId]
982+ let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
983+ let D = getD(xp)
984+ let y = getY(isReverse, D, toBigInt(cleanAmountIn))
985+ let dy = ((toBigInt(getAccBalance(assetOut)) - y) - toBigInt(1))
986+ let totalGetRaw = max([0, toInt(dy)])
987+ let newXp = if ((isReverse == false))
988+ then [((toBigInt(getAccBalance(amId)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)), (toBigInt(getAccBalance(prId)) - dy)]
989+ else [(toBigInt(getAccBalance(amId)) - dy), ((toBigInt(getAccBalance(prId)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount))]
990+ let newD = getD(newXp)
991+ let checkD = if ((newD >= D))
933992 then true
934- else throw("new K is fewer error")
935- if ((checkK == checkK))
936- then $Tuple2(nil, amountOut)
993+ else throw(makeString(["new D is fewer error", toString(D), toString(newD)], "__"))
994+ if ((checkD == checkD))
995+ then $Tuple2(nil, totalGetRaw)
937996 else throw("Strict value is not equal to itself.")
938997 }
939998
9421001 @Callable(i)
9431002 func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo,feePoolAmount) = {
9441003 let swapContact = {
945- let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil)
1004+ let @ = invoke(fca, "getSwapContractREADONLY", nil, nil)
9461005 if ($isInstanceOf(@, "String"))
9471006 then @
9481007 else throw(($getType(@) + " couldn't be cast to String"))
9561015 then {
9571016 let pmt = value(i.payments[0])
9581017 let assetIn = assetIdToString(pmt.assetId)
959- let assetOut = if ((isReverse == false))
960- then getStringOrFail(this, pa())
961- else getStringOrFail(this, aa())
962- let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
963- let poolAssetOutBalance = getAccBalance(assetOut)
964- let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
965- let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
966- let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
967- let checkK = if ((newK >= oldK))
1018+ let $t03749637890 = if ((isReverse == false))
1019+ then {
1020+ let assetOut = strf(this, pa())
1021+ let poolAmountInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
1022+ $Tuple2(assetOut, poolAmountInBalance)
1023+ }
1024+ else {
1025+ let assetOut = strf(this, aa())
1026+ let poolAmountInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
1027+ $Tuple2(assetOut, poolAmountInBalance)
1028+ }
1029+ let assetOut = $t03749637890._1
1030+ let poolAmountInBalance = $t03749637890._2
1031+ let poolConfig = gpc()
1032+ let amId = poolConfig[idxAmAsId]
1033+ let prId = poolConfig[idxPrAsId]
1034+ let xp = if ((isReverse == false))
1035+ then [(toBigInt(getAccBalance(amId)) - toBigInt(value(i.payments[0]).amount)), toBigInt(getAccBalance(prId))]
1036+ else [toBigInt(getAccBalance(amId)), (toBigInt(getAccBalance(prId)) - toBigInt(value(i.payments[0]).amount))]
1037+ let D = getD(xp)
1038+ let y = getY(isReverse, D, toBigInt(0))
1039+ let dy = ((toBigInt(getAccBalance(assetOut)) - y) - toBigInt(1))
1040+ let totalGetRaw = max([0, toInt(dy)])
1041+ let checkMin = if ((totalGetRaw >= amountOutMin))
9681042 then true
969- else throw("new K is fewer error")
970- if ((checkK == checkK))
1043+ else throw("Exchange result is fewer coins than expected")
1044+ if ((checkMin == checkMin))
9711045 then {
972- let checkMin = if ((amountOut >= amountOutMin))
1046+ let newXp = if ((isReverse == false))
1047+ then [(toBigInt(getAccBalance(amId)) + toBigInt(feePoolAmount)), (toBigInt(getAccBalance(prId)) - dy)]
1048+ else [(toBigInt(getAccBalance(amId)) - dy), (toBigInt(getAccBalance(prId)) + toBigInt(feePoolAmount))]
1049+ let newD = getD(newXp)
1050+ let checkD = if ((newD >= D))
9731051 then true
974- else throw("Exchange result is fewer coins than expected")
975- if ((checkMin == checkMin))
976- then {
977- let rebalanceState = rebalanceAsset(assetIn)
978- if ((rebalanceState == rebalanceState))
979- then {
980- let withdrawState = withdrawAndRebalanceAsset(assetOut, amountOut)
981- if ((withdrawState == withdrawState))
982- then $Tuple2(((withdrawState ++ rebalanceState) ++ [ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))]), amountOut)
983- else throw("Strict value is not equal to itself.")
984- }
985- else throw("Strict value is not equal to itself.")
986- }
1052+ else throw("new D is fewer error")
1053+ if ((checkD == checkD))
1054+ then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), totalGetRaw, parseAssetId(assetOut))], totalGetRaw)
9871055 else throw("Strict value is not equal to itself.")
9881056 }
9891057 else throw("Strict value is not equal to itself.")
9941062
9951063
9961064 @Callable(i)
997-func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
998- then throw("Invalid slippageTolerance passed")
999- else {
1000- let estPut = commonPut(i, slippageTolerance, true)
1001- let emitLpAmt = estPut._2
1002- let lpAssetId = estPut._7
1003- let state = estPut._9
1004- let amDiff = estPut._10
1005- let prDiff = estPut._11
1006- let amId = estPut._12
1007- let prId = estPut._13
1008- let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1009- let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1010- let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
1011- if ((currentKLp == currentKLp))
1012- then {
1013- let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
1014- if ((emitInv == emitInv))
1065+func constructor (fc) = {
1066+ let c = mustManager(i)
1067+ if ((c == c))
1068+ then [StringEntry(fc(), fc)]
1069+ else throw("Strict value is not equal to itself.")
1070+ }
1071+
1072+
1073+
1074+@Callable(i)
1075+func put (slip,autoStake) = {
1076+ let factCfg = gfc()
1077+ let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Wr st addr")
1078+ let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Wr sl addr")
1079+ if ((0 > slip))
1080+ then throw("Wrong slippage")
1081+ else if ((size(i.payments) != 2))
1082+ then throw("2 pmnts expd")
1083+ else {
1084+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1085+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1086+ let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amAssetPmt)
1087+ if ((amountAssetBalance == amountAssetBalance))
10151088 then {
1016- let emitInvLegacy = match emitInv {
1017- case legacyFactoryContract: Address =>
1018- invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
1019- case _ =>
1020- unit
1021- }
1022- if ((emitInvLegacy == emitInvLegacy))
1089+ let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - prAssetPmt)
1090+ if ((priceAssetBalance == priceAssetBalance))
10231091 then {
1024- let slippageAInv = if ((amDiff > 0))
1025- then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
1026- else nil
1027- if ((slippageAInv == slippageAInv))
1092+ let lpAssetEmission = toBigInt(value(assetInfo(cfgLpAssetId)).quantity)
1093+ if ((lpAssetEmission == lpAssetEmission))
10281094 then {
1029- let slippagePInv = if ((prDiff > 0))
1030- then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
1031- else nil
1032- if ((slippagePInv == slippagePInv))
1095+ let currentDLp = calcCurrentDLp(amAssetPmt, prAssetPmt, toBigInt(0))
1096+ if ((currentDLp == currentDLp))
10331097 then {
1034- let lpTransfer = if (shouldAutoStake)
1098+ let e = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], slip, true, false, true, 0, "")
1099+ let emitLpAmt = e._2
1100+ let lpAssetId = e._7
1101+ let state = e._9
1102+ let amDiff = e._10
1103+ let prDiff = e._11
1104+ let amId = e._12
1105+ let prId = e._13
1106+ let r = invoke(fca, "emit", [emitLpAmt], nil)
1107+ if ((r == r))
10351108 then {
1036- let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
1037- if ((slpStakeInv == slpStakeInv))
1038- then nil
1039- else throw("Strict value is not equal to itself.")
1109+ let el = match r {
1110+ case legacy: Address =>
1111+ invoke(legacy, "emit", [emitLpAmt], nil)
1112+ case _ =>
1113+ unit
10401114 }
1041- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1042- let $t04436144823 = refreshKLpInternal(0, 0, 0)
1043- if (($t04436144823 == $t04436144823))
1044- then {
1045- let updatedKLp = $t04436144823._2
1046- let refreshKLpActions = $t04436144823._1
1047- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1048- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1115+ if ((el == el))
10491116 then {
1050- let reb = invoke(this, "rebalance", nil, nil)
1051- if ((reb == reb))
1052- then ((state ++ lpTransfer) ++ refreshKLpActions)
1117+ let sa = if ((amDiff > 0))
1118+ then invoke(slipCntr, "put", nil, [AttachedPayment(amId, amDiff)])
1119+ else nil
1120+ if ((sa == sa))
1121+ then {
1122+ let sp = if ((prDiff > 0))
1123+ then invoke(slipCntr, "put", nil, [AttachedPayment(prId, prDiff)])
1124+ else nil
1125+ if ((sp == sp))
1126+ then {
1127+ let lpTrnsfr = if (autoStake)
1128+ then {
1129+ let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
1130+ if ((ss == ss))
1131+ then nil
1132+ else throw("Strict value is not equal to itself.")
1133+ }
1134+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1135+ let $t04203442176 = refreshDLpInternal(0, 0, 0)
1136+ let refreshDLpActions = $t04203442176._1
1137+ let updatedDLp = $t04203442176._2
1138+ let check = if ((updatedDLp >= currentDLp))
1139+ then true
1140+ else throwErr(makeString(["updated DLp lower than current DLp", toString(amountAssetBalance), toString(priceAssetBalance), toString(lpAssetEmission), toString(currentDLp), toString(updatedDLp), toString(amDiff), toString(prDiff)], " "))
1141+ if ((check == check))
1142+ then {
1143+ let lpAssetEmissionAfter = value(assetInfo(cfgLpAssetId)).quantity
1144+ if ((lpAssetEmissionAfter == lpAssetEmissionAfter))
1145+ then ((state ++ lpTrnsfr) ++ refreshDLpActions)
1146+ else throw("Strict value is not equal to itself.")
1147+ }
1148+ else throw("Strict value is not equal to itself.")
1149+ }
1150+ else throw("Strict value is not equal to itself.")
1151+ }
10531152 else throw("Strict value is not equal to itself.")
10541153 }
10551154 else throw("Strict value is not equal to itself.")
10641163 }
10651164 else throw("Strict value is not equal to itself.")
10661165 }
1067- else throw("Strict value is not equal to itself.")
1068- }
1166+ }
10691167
10701168
10711169
10721170 @Callable(i)
1073-func putForFree (maxSlippage) = if ((0 > maxSlippage))
1074- then throw("Invalid value passed")
1075- else {
1076- let estPut = commonPut(i, maxSlippage, false)
1077- let state = estPut._9
1078- let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1079- let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1080- let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
1081- if ((currentKLp == currentKLp))
1082- then {
1083- let $t04543545500 = refreshKLpInternal(0, 0, 0)
1084- let refreshKLpActions = $t04543545500._1
1085- let updatedKLp = $t04543545500._2
1086- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1087- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1088- then (state ++ refreshKLpActions)
1089- else throw("Strict value is not equal to itself.")
1090- }
1091- else throw("Strict value is not equal to itself.")
1092- }
1093-
1094-
1095-
1096-@Callable(i)
1097-func putOneTkn (minOutAmount,autoStake) = {
1171+func putOneTknV2 (minOutAmount,autoStake) = {
10981172 let isPoolOneTokenOperationsDisabled = {
1099- let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1173+ let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
11001174 if ($isInstanceOf(@, "Boolean"))
11011175 then @
11021176 else throw(($getType(@) + " couldn't be cast to Boolean"))
11031177 }
1104- let isPutDisabled = if (if (if (isGlobalShutdown())
1178+ let isPutDisabled = if (if (if (igs())
11051179 then true
1106- else (cfgPoolStatus == PoolPutDisabled))
1180+ else (cfgPoolStatus == PoolPutDis))
11071181 then true
11081182 else (cfgPoolStatus == PoolShutdown))
11091183 then true
11171191 else throwErr("exactly 1 payment are expected")]
11181192 if ((checks == checks))
11191193 then {
1120- let payment = i.payments[0]
1121- let paymentAssetId = payment.assetId
1122- let paymentAmountRaw = payment.amount
1123- let currentKLp = if ((paymentAssetId == cfgAmountAssetId))
1124- then calcCurrentKLp(toBigInt(paymentAmountRaw), toBigInt(0), toBigInt(0))
1125- else if ((paymentAssetId == cfgPriceAssetId))
1126- then calcCurrentKLp(toBigInt(0), toBigInt(paymentAmountRaw), toBigInt(0))
1127- else throwErr("payment asset is not supported")
1128- if ((currentKLp == currentKLp))
1194+ let amId = toBase58String(value(cfgAmountAssetId))
1195+ let prId = toBase58String(value(cfgPriceAssetId))
1196+ let lpId = cfgLpAssetId
1197+ let amDecimals = cfgAmountAssetDecimals
1198+ let prDecimals = cfgPriceAssetDecimals
1199+ let userAddress = if ((i.caller == this))
1200+ then i.originCaller
1201+ else i.caller
1202+ let pmt = value(i.payments[0])
1203+ let pmtAssetId = toBase58String(value(pmt.assetId))
1204+ let pmtAmt = pmt.amount
1205+ let currentDLp = if ((pmt.assetId == cfgAmountAssetId))
1206+ then calcCurrentDLp(toBigInt(pmtAmt), toBigInt(0), toBigInt(0))
1207+ else calcCurrentDLp(toBigInt(0), toBigInt(pmtAmt), toBigInt(0))
1208+ if ((currentDLp == currentDLp))
11291209 then {
1130- let userAddress = i.caller
1131- let txId = i.transactionId
1132- let $t04668846840 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
1133- if (($t04668846840 == $t04668846840))
1210+ let $t04381743975 = calcPutOneTkn(pmtAmt, pmtAssetId, toString(userAddress), toBase58String(i.transactionId), true)
1211+ if (($t04381743975 == $t04381743975))
11341212 then {
1135- let paymentInAmountAsset = $t04668846840._5
1136- let bonus = $t04668846840._4
1137- let feeAmount = $t04668846840._3
1138- let commonState = $t04668846840._2
1139- let emitAmountEstimated = $t04668846840._1
1140- let emitAmount = if (if ((minOutAmount > 0))
1141- then (minOutAmount > emitAmountEstimated)
1213+ let feeAmount = $t04381743975._3
1214+ let state = $t04381743975._2
1215+ let estimLP = $t04381743975._1
1216+ let emitLpAmt = if (if ((minOutAmount > 0))
1217+ then (minOutAmount > estimLP)
11421218 else false)
11431219 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1144- else emitAmountEstimated
1145- let emitInv = emit(emitAmount)
1146- if ((emitInv == emitInv))
1220+ else estimLP
1221+ let e = invoke(fca, "emit", [emitLpAmt], nil)
1222+ if ((e == e))
11471223 then {
1148- let lpTransfer = if (autoStake)
1224+ let el = match e {
1225+ case legacy: Address =>
1226+ invoke(legacy, "emit", [emitLpAmt], nil)
1227+ case _ =>
1228+ unit
1229+ }
1230+ if ((el == el))
11491231 then {
1150- let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
1151- if ((stakeInv == stakeInv))
1152- then nil
1153- else throw("Strict value is not equal to itself.")
1154- }
1155- else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
1156- let sendFee = if ((feeAmount > 0))
1157- then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
1158- else nil
1159- let $t04742647623 = if ((this == feeCollectorAddress))
1160- then $Tuple2(0, 0)
1161- else if (paymentInAmountAsset)
1162- then $Tuple2(-(feeAmount), 0)
1163- else $Tuple2(0, -(feeAmount))
1164- let amountAssetBalanceDelta = $t04742647623._1
1165- let priceAssetBalanceDelta = $t04742647623._2
1166- let $t04762647734 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1167- let refreshKLpActions = $t04762647734._1
1168- let updatedKLp = $t04762647734._2
1169- let kLp = value(getString(keyKLp))
1170- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1171- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1172- then {
1173- let reb = invoke(this, "rebalance", nil, nil)
1174- if ((reb == reb))
1175- then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
1232+ let lpTrnsfr = if (autoStake)
1233+ then {
1234+ let ss = invoke(stakingContract, "stakeFor", [toString(i.caller)], [AttachedPayment(lpId, emitLpAmt)])
1235+ if ((ss == ss))
1236+ then nil
1237+ else throw("Strict value is not equal to itself.")
1238+ }
1239+ else [ScriptTransfer(i.caller, emitLpAmt, lpId)]
1240+ let sendFeeToMatcher = if ((feeAmount > 0))
1241+ then [ScriptTransfer(feeCollectorAddress, feeAmount, fromBase58String(pmtAssetId))]
1242+ else nil
1243+ let $t04486045209 = if ((this == feeCollectorAddress))
1244+ then $Tuple2(0, 0)
1245+ else {
1246+ let paymentInAmountAsset = if ((pmt.assetId == cfgAmountAssetId))
1247+ then true
1248+ else false
1249+ if (paymentInAmountAsset)
1250+ then $Tuple2(-(feeAmount), 0)
1251+ else $Tuple2(0, -(feeAmount))
1252+ }
1253+ let amountAssetBalanceDelta = $t04486045209._1
1254+ let priceAssetBalanceDelta = $t04486045209._2
1255+ let $t04521245320 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1256+ let refreshDLpActions = $t04521245320._1
1257+ let updatedDLp = $t04521245320._2
1258+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1259+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1260+ then $Tuple2((((state ++ lpTrnsfr) ++ sendFeeToMatcher) ++ refreshDLpActions), emitLpAmt)
11761261 else throw("Strict value is not equal to itself.")
11771262 }
11781263 else throw("Strict value is not equal to itself.")
11891274
11901275
11911276 @Callable(i)
1192-func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
1193- let $t04808948246 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
1194- let emitAmountEstimated = $t04808948246._1
1195- let commonState = $t04808948246._2
1196- let feeAmount = $t04808948246._3
1197- let bonus = $t04808948246._4
1198- let paymentInAmountAsset = $t04808948246._5
1199- $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
1277+func putForFree (maxSlpg) = if ((0 > maxSlpg))
1278+ then throw("Wrong slpg")
1279+ else if ((size(i.payments) != 2))
1280+ then throw("2 pmnts expd")
1281+ else {
1282+ let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], maxSlpg, false, false, true, 0, "")
1283+ let state = estPut._9
1284+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1285+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1286+ let currentDLp = calcCurrentDLp(amAssetPmt, prAssetPmt, toBigInt(0))
1287+ if ((currentDLp == currentDLp))
1288+ then {
1289+ let $t04635046415 = refreshDLpInternal(0, 0, 0)
1290+ let refreshDLpActions = $t04635046415._1
1291+ let updatedDLp = $t04635046415._2
1292+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1293+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1294+ then (state ++ refreshDLpActions)
1295+ else throw("Strict value is not equal to itself.")
1296+ }
1297+ else throw("Strict value is not equal to itself.")
1298+ }
1299+
1300+
1301+
1302+@Callable(i)
1303+func get () = {
1304+ let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1305+ if ((currentDLp == currentDLp))
1306+ then {
1307+ let r = cg(i)
1308+ let outAmtAmt = r._1
1309+ let outPrAmt = r._2
1310+ let pmtAmt = r._3
1311+ let pmtAssetId = r._4
1312+ let state = r._5
1313+ let b = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1314+ if ((b == b))
1315+ then {
1316+ let $t04758847670 = refreshDLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1317+ let refreshDLpActions = $t04758847670._1
1318+ let updatedDLp = $t04758847670._2
1319+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1320+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1321+ then (state ++ refreshDLpActions)
1322+ else throw("Strict value is not equal to itself.")
1323+ }
1324+ else throw("Strict value is not equal to itself.")
1325+ }
1326+ else throw("Strict value is not equal to itself.")
12001327 }
12011328
12021329
12031330
12041331 @Callable(i)
1205-func getOneTkn (outAssetIdStr,minOutAmount) = {
1332+func getOneTknV2 (outAssetId,minOutAmount) = {
12061333 let isPoolOneTokenOperationsDisabled = {
1207- let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1334+ let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
12081335 if ($isInstanceOf(@, "Boolean"))
12091336 then @
12101337 else throw(($getType(@) + " couldn't be cast to Boolean"))
12111338 }
1212- let isGetDisabled = if (if (isGlobalShutdown())
1339+ let isGetDisabled = if (if (igs())
12131340 then true
12141341 else (cfgPoolStatus == PoolShutdown))
12151342 then true
12231350 else throwErr("exactly 1 payment are expected")]
12241351 if ((checks == checks))
12251352 then {
1226- let outAssetId = parseAssetId(outAssetIdStr)
1227- let payment = i.payments[0]
1228- let paymentAssetId = payment.assetId
1229- let paymentAmount = payment.amount
1230- let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1231- if ((currentKLp == currentKLp))
1232- then {
1233- let userAddress = i.caller
1234- let txId = i.transactionId
1235- let $t04913149284 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1236- if (($t04913149284 == $t04913149284))
1237- then {
1238- let outInAmountAsset = $t04913149284._5
1239- let bonus = $t04913149284._4
1240- let feeAmount = $t04913149284._3
1241- let commonState = $t04913149284._2
1242- let amountEstimated = $t04913149284._1
1243- let amount = if (if ((minOutAmount > 0))
1244- then (minOutAmount > amountEstimated)
1245- else false)
1246- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1247- else amountEstimated
1248- let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
1249- if ((burnInv == burnInv))
1250- then {
1251- let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
1252- let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
1253- let sendFee = if ((feeAmount > 0))
1254- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1255- else nil
1256- let $t04994850195 = {
1257- let feeAmountForCalc = if ((this == feeCollectorAddress))
1258- then 0
1259- else feeAmount
1260- if (outInAmountAsset)
1261- then $Tuple2(-((amount + feeAmountForCalc)), 0)
1262- else $Tuple2(0, -((amount + feeAmountForCalc)))
1263- }
1264- let amountAssetBalanceDelta = $t04994850195._1
1265- let priceAssetBalanceDelta = $t04994850195._2
1266- let $t05019850306 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1267- let refreshKLpActions = $t05019850306._1
1268- let updatedKLp = $t05019850306._2
1269- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1270- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1271- then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1272- else throw("Strict value is not equal to itself.")
1273- }
1274- else throw("Strict value is not equal to itself.")
1275- }
1276- else throw("Strict value is not equal to itself.")
1277- }
1278- else throw("Strict value is not equal to itself.")
1353+ let $t04828848443 = getOneTknV2Internal(outAssetId, minOutAmount, i.payments, i.caller, i.originCaller, i.transactionId)
1354+ let state = $t04828848443._1
1355+ let totalAmount = $t04828848443._2
1356+ $Tuple2(state, totalAmount)
12791357 }
12801358 else throw("Strict value is not equal to itself.")
12811359 }
12831361
12841362
12851363 @Callable(i)
1286-func getOneTknREADONLY (outAssetId,paymentAmount) = {
1287- let $t05058450740 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1288- let amountEstimated = $t05058450740._1
1289- let commonState = $t05058450740._2
1290- let feeAmount = $t05058450740._3
1291- let bonus = $t05058450740._4
1292- let outInAmountAsset = $t05058450740._5
1293- $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
1294- }
1295-
1296-
1297-
1298-@Callable(i)
1299-func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
1300- let isPoolOneTokenOperationsDisabled = {
1301- let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1302- if ($isInstanceOf(@, "Boolean"))
1303- then @
1304- else throw(($getType(@) + " couldn't be cast to Boolean"))
1305- }
1306- let isGetDisabled = if (if (isGlobalShutdown())
1307- then true
1308- else (cfgPoolStatus == PoolShutdown))
1309- then true
1310- else isPoolOneTokenOperationsDisabled
1311- let checks = [if (if (!(isGetDisabled))
1312- then true
1313- else isManager(i))
1314- then true
1315- else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
1316- then true
1317- else throwErr("no payments are expected")]
1318- if ((checks == checks))
1364+func refreshDLp () = {
1365+ let lastRefreshedBlockHeight = valueOrElse(getInteger(keyDLpRefreshedHeight), 0)
1366+ let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= dLpRefreshDelay))
1367+ then unit
1368+ else throwErr(makeString([toString(dLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1369+ if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
13191370 then {
1320- let outAssetId = parseAssetId(outAssetIdStr)
1321- let userAddress = i.caller
1322- let txId = i.transactionId
1323- let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1324- if ((currentKLp == currentKLp))
1325- then {
1326- let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1327- if ((unstakeInv == unstakeInv))
1328- then {
1329- let $t05164551796 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1330- if (($t05164551796 == $t05164551796))
1331- then {
1332- let outInAmountAsset = $t05164551796._5
1333- let bonus = $t05164551796._4
1334- let feeAmount = $t05164551796._3
1335- let commonState = $t05164551796._2
1336- let amountEstimated = $t05164551796._1
1337- let amount = if (if ((minOutAmount > 0))
1338- then (minOutAmount > amountEstimated)
1339- else false)
1340- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1341- else amountEstimated
1342- let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1343- if ((burnInv == burnInv))
1344- then {
1345- let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
1346- let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
1347- let sendFee = if ((feeAmount > 0))
1348- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1349- else nil
1350- let $t05245552702 = {
1351- let feeAmountForCalc = if ((this == feeCollectorAddress))
1352- then 0
1353- else feeAmount
1354- if (outInAmountAsset)
1355- then $Tuple2(-((amount + feeAmountForCalc)), 0)
1356- else $Tuple2(0, -((amount + feeAmountForCalc)))
1357- }
1358- let amountAssetBalanceDelta = $t05245552702._1
1359- let priceAssetBalanceDelta = $t05245552702._2
1360- let $t05270552813 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1361- let refreshKLpActions = $t05270552813._1
1362- let updatedKLp = $t05270552813._2
1363- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1364- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1365- then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1366- else throw("Strict value is not equal to itself.")
1367- }
1368- else throw("Strict value is not equal to itself.")
1369- }
1370- else throw("Strict value is not equal to itself.")
1371- }
1372- else throw("Strict value is not equal to itself.")
1373- }
1374- else throw("Strict value is not equal to itself.")
1371+ let dLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyDLp), "0")), fmtErr("invalid dLp"))
1372+ let $t04896749031 = refreshDLpInternal(0, 0, 0)
1373+ let dLpUpdateActions = $t04896749031._1
1374+ let updatedDLp = $t04896749031._2
1375+ let actions = if ((dLp != updatedDLp))
1376+ then dLpUpdateActions
1377+ else throwErr("nothing to refresh")
1378+ $Tuple2(actions, toString(updatedDLp))
13751379 }
13761380 else throw("Strict value is not equal to itself.")
13771381 }
13791383
13801384
13811385 @Callable(i)
1382-func get () = {
1383- let res = commonGet(i)
1384- let outAmAmt = res._1
1385- let outPrAmt = res._2
1386- let pmtAmt = res._3
1387- let pmtAssetId = res._4
1388- let state = res._5
1389- let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1390- let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1391- if ((currentKLp == currentKLp))
1392- then {
1393- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1394- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1395- then {
1396- let $t05390853989 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1397- let refreshKLpActions = $t05390853989._1
1398- let updatedKLp = $t05390853989._2
1399- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1400- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1401- then ((withdrawState ++ state) ++ refreshKLpActions)
1402- else throw("Strict value is not equal to itself.")
1403- }
1404- else throw("Strict value is not equal to itself.")
1405- }
1406- else throw("Strict value is not equal to itself.")
1386+func getOneTknV2READONLY (outAssetId,lpAssetAmount) = {
1387+ let amId = toBase58String(value(cfgAmountAssetId))
1388+ let prId = toBase58String(value(cfgPriceAssetId))
1389+ let lpId = toBase58String(value(cfgLpAssetId))
1390+ let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
1391+ let lpEmission = toBigInt(valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "invalid lp asset").quantity)
1392+ let D0 = getD(xp)
1393+ let D1 = (D0 - fraction(toBigInt(lpAssetAmount), D0, lpEmission))
1394+ let index = if ((outAssetId == amId))
1395+ then 0
1396+ else if ((outAssetId == prId))
1397+ then 1
1398+ else throw("invalid out asset id")
1399+ let newY = getYD(xp, index, D1)
1400+ let dy = (xp[index] - newY)
1401+ let totalGetRaw = max([0, toInt((dy - big1))])
1402+ let $t05004150096 = takeFee(totalGetRaw, outFee)
1403+ let totalGet = $t05004150096._1
1404+ let feeAmount = $t05004150096._2
1405+ $Tuple2(nil, $Tuple2(totalGet, feeAmount))
1406+ }
1407+
1408+
1409+
1410+@Callable(i)
1411+func getOneTknV2WithBonusREADONLY (outAssetId,lpAssetAmount) = {
1412+ let amId = toBase58String(value(cfgAmountAssetId))
1413+ let prId = toBase58String(value(cfgPriceAssetId))
1414+ let lpId = toBase58String(value(cfgLpAssetId))
1415+ let amBalance = getAccBalance(amId)
1416+ let prBalance = getAccBalance(prId)
1417+ let $t05047150586 = {
1418+ let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, lpAssetAmount], nil)
1419+ if ($isInstanceOf(@, "(Int, Int)"))
1420+ then @
1421+ else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
1422+ }
1423+ let totalGet = $t05047150586._1
1424+ let feeAmount = $t05047150586._2
1425+ let r = ego("", lpId, lpAssetAmount, this)
1426+ let outAmAmt = r._1
1427+ let outPrAmt = r._2
1428+ let sumOfGetAssets = (outAmAmt + outPrAmt)
1429+ let bonus = if ((sumOfGetAssets == 0))
1430+ then if ((totalGet == 0))
1431+ then 0
1432+ else throw("bonus calculation error")
1433+ else fraction((totalGet - sumOfGetAssets), scale8, sumOfGetAssets)
1434+ $Tuple2(nil, $Tuple3(totalGet, feeAmount, bonus))
14071435 }
14081436
14091437
14101438
14111439 @Callable(i)
14121440 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
1413- let res = commonGet(i)
1414- let outAmAmt = res._1
1415- let outPrAmt = res._2
1416- let pmtAmt = res._3
1417- let pmtAssetId = res._4
1418- let state = res._5
1441+ let r = cg(i)
1442+ let outAmAmt = r._1
1443+ let outPrAmt = r._2
1444+ let pmtAmt = r._3
1445+ let pmtAssetId = r._4
1446+ let state = r._5
14191447 if ((noLessThenAmtAsset > outAmAmt))
1420- then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
1448+ then throw(((("Failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
14211449 else if ((noLessThenPriceAsset > outPrAmt))
1422- then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
1450+ then throw(((("Failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
14231451 else {
1424- let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1425- let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1426- if ((currentKLp == currentKLp))
1452+ let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1453+ if ((currentDLp == currentDLp))
14271454 then {
1428- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1455+ let burnLPAssetOnFactory = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
14291456 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
14301457 then {
1431- let $t05508455165 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1432- let refreshKLpActions = $t05508455165._1
1433- let updatedKLp = $t05508455165._2
1434- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1435- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1436- then ((withdrawState ++ state) ++ refreshKLpActions)
1458+ let $t05175251833 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1459+ let refreshDLpActions = $t05175251833._1
1460+ let updatedDLp = $t05175251833._2
1461+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1462+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1463+ then (state ++ refreshDLpActions)
14371464 else throw("Strict value is not equal to itself.")
14381465 }
14391466 else throw("Strict value is not equal to itself.")
14471474 @Callable(i)
14481475 func unstakeAndGet (amount) = {
14491476 let checkPayments = if ((size(i.payments) != 0))
1450- then throw("No payments are expected")
1477+ then throw("No pmnts expd")
14511478 else true
14521479 if ((checkPayments == checkPayments))
14531480 then {
1454- let cfg = getPoolConfig()
1455- let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1456- let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1457- if ((currentKLp == currentKLp))
1481+ let factoryCfg = gfc()
1482+ let lpAssetId = cfgLpAssetId
1483+ let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1484+ let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1485+ if ((currentDLp == currentDLp))
14581486 then {
1459- let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
1487+ let unstakeInv = invoke(staking, "unstake", [toBase58String(lpAssetId), amount], nil)
14601488 if ((unstakeInv == unstakeInv))
14611489 then {
1462- let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1463- let outAmAmt = res._1
1464- let outPrAmt = res._2
1465- let poolStatus = parseIntValue(res._9)
1466- let state = res._10
1467- let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1468- let checkPoolStatus = if (if (isGlobalShutdown())
1490+ let r = ego(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1491+ let outAmAmt = r._1
1492+ let outPrAmt = r._2
1493+ let sts = parseIntValue(r._9)
1494+ let state = r._10
1495+ let v = if (if (igs())
14691496 then true
1470- else (poolStatus == PoolShutdown))
1471- then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
1497+ else (sts == PoolShutdown))
1498+ then throw(("Blocked: " + toString(sts)))
14721499 else true
1473- if ((checkPoolStatus == checkPoolStatus))
1500+ if ((v == v))
14741501 then {
1475- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1476- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1502+ let burnA = invoke(fca, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1503+ if ((burnA == burnA))
14771504 then {
1478- let $t05643756518 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1479- let refreshKLpActions = $t05643756518._1
1480- let updatedKLp = $t05643756518._2
1481- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1482- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1483- then ((withdrawState ++ state) ++ refreshKLpActions)
1505+ let $t05286052941 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1506+ let refreshDLpActions = $t05286052941._1
1507+ let updatedDLp = $t05286052941._2
1508+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1509+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1510+ then (state ++ refreshDLpActions)
14841511 else throw("Strict value is not equal to itself.")
14851512 }
14861513 else throw("Strict value is not equal to itself.")
14981525
14991526 @Callable(i)
15001527 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
1501- let isGetDisabled = if (isGlobalShutdown())
1528+ let isGetDisabled = if (igs())
15021529 then true
15031530 else (cfgPoolStatus == PoolShutdown)
15041531 let checks = [if (!(isGetDisabled))
15081535 else throw("no payments are expected")]
15091536 if ((checks == checks))
15101537 then {
1511- let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1512- if ((currentKLp == currentKLp))
1538+ let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1539+ if ((currentDLp == currentDLp))
15131540 then {
15141541 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
15151542 if ((unstakeInv == unstakeInv))
15161543 then {
1517- let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
1544+ let res = ego(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
15181545 let outAmAmt = res._1
15191546 let outPrAmt = res._2
15201547 let state = res._10
1521- let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
15221548 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
15231549 then true
15241550 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
15261552 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
15271553 if ((checkAmounts == checkAmounts))
15281554 then {
1529- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1555+ let burnLPAssetOnFactory = invoke(fca, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
15301556 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
15311557 then {
1532- let $t05795958040 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1533- let refreshKLpActions = $t05795958040._1
1534- let updatedKLp = $t05795958040._2
1535- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1536- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1537- then ((withdrawState ++ state) ++ refreshKLpActions)
1558+ let $t05419254273 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1559+ let refreshDLpActions = $t05419254273._1
1560+ let updatedDLp = $t05419254273._2
1561+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1562+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1563+ then (state ++ refreshDLpActions)
15381564 else throw("Strict value is not equal to itself.")
15391565 }
15401566 else throw("Strict value is not equal to itself.")
15511577
15521578
15531579 @Callable(i)
1554-func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
1555- then throw("permissions denied")
1556- else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
1557-
1558-
1559-
1560-@Callable(i)
1561-func refreshKLp () = {
1562- let lastRefreshedBlockHeight = valueOrElse(getInteger(keyKLpRefreshedHeight), 0)
1563- let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= kLpRefreshDelay))
1564- then unit
1565- else throwErr(makeString([toString(kLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1566- if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
1580+func unstakeAndGetOneTknV2 (unstakeAmount,outAssetId,minOutAmount) = {
1581+ let isPoolOneTokenOperationsDisabled = {
1582+ let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1583+ if ($isInstanceOf(@, "Boolean"))
1584+ then @
1585+ else throw(($getType(@) + " couldn't be cast to Boolean"))
1586+ }
1587+ let isGetDisabled = if (if (igs())
1588+ then true
1589+ else (cfgPoolStatus == PoolShutdown))
1590+ then true
1591+ else isPoolOneTokenOperationsDisabled
1592+ let checks = [if (if (!(isGetDisabled))
1593+ then true
1594+ else isManager(i))
1595+ then true
1596+ else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
1597+ then true
1598+ else throwErr("no payments are expected")]
1599+ if ((checks == checks))
15671600 then {
1568- let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1569- let $t05924459308 = refreshKLpInternal(0, 0, 0)
1570- let kLpUpdateActions = $t05924459308._1
1571- let updatedKLp = $t05924459308._2
1572- let actions = if ((kLp != updatedKLp))
1573- then kLpUpdateActions
1574- else throwErr("nothing to refresh")
1575- $Tuple2(actions, toString(updatedKLp))
1601+ let factoryCfg = gfc()
1602+ let lpAssetId = cfgLpAssetId
1603+ let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1604+ let userAddress = i.caller
1605+ let lpAssetRecipientAddress = this
1606+ let unstakeInv = invoke(staking, "unstakeINTERNAL", [lpAssetId, unstakeAmount, userAddress.bytes, lpAssetRecipientAddress.bytes], nil)
1607+ if ((unstakeInv == unstakeInv))
1608+ then {
1609+ let $t05529555483 = getOneTknV2Internal(outAssetId, minOutAmount, [AttachedPayment(lpAssetId, unstakeAmount)], i.caller, i.originCaller, i.transactionId)
1610+ let state = $t05529555483._1
1611+ let totalAmount = $t05529555483._2
1612+ $Tuple2(state, totalAmount)
1613+ }
1614+ else throw("Strict value is not equal to itself.")
15761615 }
15771616 else throw("Strict value is not equal to itself.")
15781617 }
15801619
15811620
15821621 @Callable(i)
1583-func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
1622+func putOneTknV2WithBonusREADONLY (paymentAmountRaw,paymentAssetId) = {
1623+ let $t05561155714 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "", true)
1624+ let lpAmount = $t05561155714._1
1625+ let state = $t05561155714._2
1626+ let feeAmount = $t05561155714._3
1627+ let bonus = $t05561155714._4
1628+ $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1629+ }
1630+
1631+
1632+
1633+@Callable(i)
1634+func putOneTknV2WithoutTakeFeeREADONLY (paymentAmountRaw,paymentAssetId) = {
1635+ let $t05586255966 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "", false)
1636+ let lpAmount = $t05586255966._1
1637+ let state = $t05586255966._2
1638+ let feeAmount = $t05586255966._3
1639+ let bonus = $t05586255966._4
1640+ $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1641+ }
1642+
1643+
1644+
1645+@Callable(i)
1646+func activate (amtAsStr,prAsStr) = if ((toString(i.caller) != toString(fca)))
1647+ then throw("denied")
1648+ else $Tuple2([StringEntry(aa(), amtAsStr), StringEntry(pa(), prAsStr), StringEntry(amp(), toString(ampInitial))], "success")
1649+
1650+
1651+
1652+@Callable(i)
1653+func getPoolConfigWrapperREADONLY () = $Tuple2(nil, gpc())
15841654
15851655
15861656
15911661
15921662 @Callable(i)
15931663 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
1594- let prices = calcPrices(amAmt, prAmt, lpAmt)
1595- $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
1664+ let pr = calcPrices(amAmt, prAmt, lpAmt)
1665+ $Tuple2(nil, [toString(pr[0]), toString(pr[1]), toString(pr[2])])
15961666 }
15971667
15981668
15991669
16001670 @Callable(i)
1601-func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
1671+func fromX18WrapperREADONLY (val,resScaleMult) = $Tuple2(nil, f1(parseBigIntValue(val), resScaleMult))
16021672
16031673
16041674
16051675 @Callable(i)
1606-func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
1676+func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(t1(origVal, origScaleMult)))
16071677
16081678
16091679
16101680 @Callable(i)
1611-func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
1681+func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(cpbi(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
16121682
16131683
16141684
16151685 @Callable(i)
1616-func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
1686+func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,usrAddr,isEval,emitLp) = $Tuple2(nil, epo(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, usrAddr, isEval, emitLp, true, false, 0, ""))
16171687
16181688
16191689
16201690 @Callable(i)
1621-func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
1622- let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
1623- $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
1691+func estimateGetOperationWrapperREADONLY (txId58,pmtAsId,pmtLpAmt,usrAddr) = {
1692+ let r = ego(txId58, pmtAsId, pmtLpAmt, addressFromStringValue(usrAddr))
1693+ $Tuple2(nil, $Tuple10(r._1, r._2, r._3, r._4, r._5, r._6, r._7, toString(r._8), r._9, r._10))
16241694 }
16251695
16261696
16271697
16281698 @Callable(i)
1629-func statsREADONLY () = {
1630- let cfg = getPoolConfig()
1631- let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1632- let amtAssetId = cfg[idxAmtAssetId]
1633- let priceAssetId = cfg[idxPriceAssetId]
1634- let iAmtAssetId = cfg[idxIAmtAssetId]
1635- let iPriceAssetId = cfg[idxIPriceAssetId]
1636- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1637- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1638- let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1639- let accAmtAssetBalance = getAccBalance(amtAssetId)
1640- let accPriceAssetBalance = getAccBalance(priceAssetId)
1641- let pricesList = if ((poolLPBalance == 0))
1642- then [zeroBigInt, zeroBigInt, zeroBigInt]
1643- else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
1644- let curPrice = 0
1645- let lpAmtAssetShare = fromX18(pricesList[1], scale8)
1646- let lpPriceAssetShare = fromX18(pricesList[2], scale8)
1647- let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
1648- $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(accAmtAssetBalance), toString(accPriceAssetBalance), toString(poolLPBalance), toString(curPrice), toString(lpAmtAssetShare), toString(lpPriceAssetShare), toString(poolWeight)], SEP))
1699+func changeAmp () = {
1700+ let cfg = invoke(fca, "getChangeAmpConfigREADONLY", [toString(this)], nil)
1701+ let $t05837558574 = match cfg {
1702+ case list: List[Any] =>
1703+ $Tuple3({
1704+ let @ = list[0]
1705+ if ($isInstanceOf(@, "Int"))
1706+ then @
1707+ else throw(($getType(@) + " couldn't be cast to Int"))
1708+ }, {
1709+ let @ = list[1]
1710+ if ($isInstanceOf(@, "Int"))
1711+ then @
1712+ else throw(($getType(@) + " couldn't be cast to Int"))
1713+ }, {
1714+ let @ = list[2]
1715+ if ($isInstanceOf(@, "Int"))
1716+ then @
1717+ else throw(($getType(@) + " couldn't be cast to Int"))
1718+ })
1719+ case _ =>
1720+ throwErr("invalid entry type")
16491721 }
1650-
1651-
1652-
1653-@Callable(i)
1654-func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
1655- let cfg = getPoolConfig()
1656- let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1657- let amAssetIdStr = cfg[idxAmtAssetId]
1658- let amAssetId = fromBase58String(amAssetIdStr)
1659- let prAssetIdStr = cfg[idxPriceAssetId]
1660- let prAssetId = fromBase58String(prAssetIdStr)
1661- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1662- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1663- let poolStatus = cfg[idxPoolStatus]
1664- let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1665- let accAmtAssetBalance = getAccBalance(amAssetIdStr)
1666- let accPriceAssetBalance = getAccBalance(prAssetIdStr)
1667- let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
1668- let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
1669- let curPriceX18 = if ((poolLPBalance == 0))
1670- then zeroBigInt
1671- else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
1672- let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
1673- let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
1674- let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
1675- let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
1676- let calcLpAmt = estPut._1
1677- let curPriceCalc = estPut._3
1678- let amBalance = estPut._4
1679- let prBalance = estPut._5
1680- let lpEmission = estPut._6
1681- $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(calcLpAmt), toString(fromX18(curPriceX18, scale8)), toString(amBalance), toString(prBalance), toString(lpEmission), poolStatus, toString(inAmAssetAmt), toString(inPrAssetAmt)], SEP))
1682- }
1683-
1684-
1685-
1686-@Callable(i)
1687-func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
1688- let cfg = getPoolConfig()
1689- let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1690- let amAssetIdStr = cfg[idxAmtAssetId]
1691- let amAssetId = fromBase58String(amAssetIdStr)
1692- let prAssetIdStr = cfg[idxPriceAssetId]
1693- let prAssetId = fromBase58String(prAssetIdStr)
1694- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1695- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1696- let poolStatus = cfg[idxPoolStatus]
1697- let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1698- let amBalanceRaw = getAccBalance(amAssetIdStr)
1699- let prBalanceRaw = getAccBalance(prAssetIdStr)
1700- let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
1701- let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
1702- let curPriceX18 = if ((poolLPBalance == 0))
1703- then zeroBigInt
1704- else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
1705- let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
1706- let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
1707- let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
1708- let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
1709- let calcLpAmt = estPut._1
1710- let curPriceCalc = estPut._3
1711- let amBalance = estPut._4
1712- let prBalance = estPut._5
1713- let lpEmission = estPut._6
1714- $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(calcLpAmt), toString(fromX18(curPriceX18, scale8)), toString(amBalance), toString(prBalance), toString(lpEmission), poolStatus, toString(inAmAssetAmt), toString(inPrAssetAmt)], SEP))
1715- }
1716-
1717-
1718-
1719-@Callable(i)
1720-func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
1721- let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
1722- let outAmAmt = res._1
1723- let outPrAmt = res._2
1724- let amBalance = res._5
1725- let prBalance = res._6
1726- let lpEmission = res._7
1727- let curPrice = res._8
1728- let poolStatus = parseIntValue(res._9)
1729- $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(outAmAmt), toString(outPrAmt), toString(amBalance), toString(prBalance), toString(lpEmission), toString(curPrice), toString(poolStatus)], SEP))
1722+ let delay = $t05837558574._1
1723+ let delta = $t05837558574._2
1724+ let target = $t05837558574._3
1725+ let curAmp = parseIntValue(getStringValue(amp()))
1726+ let newAmpRaw = (curAmp + delta)
1727+ let newAmp = if ((0 > delta))
1728+ then if ((target > newAmpRaw))
1729+ then target
1730+ else newAmpRaw
1731+ else if ((newAmpRaw > target))
1732+ then target
1733+ else newAmpRaw
1734+ let lastCall = valueOrElse(getInteger(keyChangeAmpLastCall()), 0)
1735+ let wait = (lastCall + delay)
1736+ let checks = [if ((height > wait))
1737+ then true
1738+ else throwErr("try again in few blocks"), if ((curAmp != newAmp))
1739+ then true
1740+ else throwErr("already reached target")]
1741+ if ((checks == checks))
1742+ then [IntegerEntry(keyChangeAmpLastCall(), height), StringEntry(amp(), toString(newAmp)), StringEntry(keyAmpHistory(height), toString(newAmp))]
1743+ else throw("Strict value is not equal to itself.")
17301744 }
17311745
17321746
17421756 }
17431757 match tx {
17441758 case order: Order =>
1745- let matcherPub = getMatcherPubOrFail()
1746- let $t06797068087 = if (skipOrderValidation())
1759+ let matcherPub = mp()
1760+ let $t05950759624 = if (skipOrderValidation())
17471761 then $Tuple2(true, "")
17481762 else validateMatcherOrderAllowed(order)
1749- let orderValid = $t06797068087._1
1750- let orderValidInfo = $t06797068087._2
1763+ let orderValid = $t05950759624._1
1764+ let orderValidInfo = $t05950759624._2
17511765 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
17521766 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
17531767 if (if (if (orderValid)
17621776 then true
17631777 else {
17641778 let newHash = blake2b256(value(s.script))
1765- let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
1779+ let allowedHash = fromBase64String(value(getString(fca, keyAllowedLpStableScriptHash())))
17661780 let currentHash = scriptHash(this)
17671781 if ((allowedHash == newHash))
17681782 then (currentHash != newHash)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let lPdecimals = 8
5-
64 let scale8 = 100000000
75
86 let scale8BigInt = toBigInt(100000000)
97
108 let scale18 = toBigInt(1000000000000000000)
119
1210 let zeroBigInt = toBigInt(0)
1311
1412 let big0 = toBigInt(0)
1513
1614 let big1 = toBigInt(1)
1715
1816 let big2 = toBigInt(2)
1917
18+let big3 = toBigInt(3)
19+
20+let big4 = toBigInt(4)
21+
22+let slippage4D = toBigInt((scale8 - ((scale8 * 1) / scale8)))
23+
2024 let wavesString = "WAVES"
25+
26+let ampInitial = 50
27+
28+let Amult = "100"
29+
30+let Dconv = "1"
2131
2232 let SEP = "__"
2333
34+let EMPTY = ""
35+
2436 let PoolActive = 1
2537
26-let PoolPutDisabled = 2
38+let PoolPutDis = 2
2739
28-let PoolMatcherDisabled = 3
40+let PoolMatcherDis = 3
2941
3042 let PoolShutdown = 4
3143
3244 let idxPoolAddress = 1
3345
34-let idxPoolStatus = 2
46+let idxPoolSt = 2
3547
36-let idxPoolLPAssetId = 3
48+let idxLPAsId = 3
3749
38-let idxAmtAssetId = 4
50+let idxAmAsId = 4
3951
40-let idxPriceAssetId = 5
52+let idxPrAsId = 5
4153
42-let idxAmtAssetDcm = 6
54+let idxAmtAsDcm = 6
4355
44-let idxPriceAssetDcm = 7
56+let idxPriceAsDcm = 7
4557
46-let idxIAmtAssetId = 8
58+let idxIAmtAsId = 8
4759
48-let idxIPriceAssetId = 9
60+let idxIPriceAsId = 9
4961
50-let idxLPAssetDcm = 10
62+let idxFactStakCntr = 1
5163
52-let idxPoolAmtAssetAmt = 1
64+let idxFactoryRestCntr = 6
5365
54-let idxPoolPriceAssetAmt = 2
66+let idxFactSlippCntr = 7
5567
56-let idxPoolLPAssetAmt = 3
68+let idxFactGwxRewCntr = 10
5769
58-let idxFactoryStakingContract = 1
70+let feeDefault = fraction(10, scale8, 10000)
5971
60-let idxFactorySlippageContract = 7
61-
62-func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
72+func t1 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
6373
6474
65-func toX18BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
75+func t1BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
6676
6777
68-func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
78+func f1 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
6979
7080
7181 func fromX18Round (val,resultScaleMult,round) = toInt(fraction(val, toBigInt(resultScaleMult), scale18, round))
7282
7383
74-func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
84+func t2 (origVal,origScaleMult) = fraction(origVal, scale18, toBigInt(origScaleMult))
7585
7686
77-func abs (val) = if ((0 > val))
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))
7894 then -(val)
7995 else val
8096
8197
8298 func absBigInt (val) = if ((zeroBigInt > val))
8399 then -(val)
84100 else val
85-
86-
87-func swapContract () = "%s__swapContract"
88101
89102
90103 func fc () = "%s__factoryContract"
91104
92105
93106 func keyManagerPublicKey () = "%s__managerPublicKey"
94107
95108
96109 func keyManagerVaultAddress () = "%s__managerVaultAddress"
97110
98111
99112 func pl () = "%s%s__price__last"
100113
101114
102-func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
115+func ph (h,t) = makeString(["%s%s%d%d__price__history", toString(h), toString(t)], SEP)
103116
104117
105-func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
118+func pau (ua,txId) = ((("%s%s%s__P__" + ua) + "__") + txId)
106119
107120
108-func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
121+func gau (ua,txId) = ((("%s%s%s__G__" + ua) + "__") + txId)
109122
110123
111124 func aa () = "%s__amountAsset"
112125
113126
114127 func pa () = "%s__priceAsset"
115128
116129
130+func amp () = "%s__amp"
131+
132+
133+func keyAmpHistory (heightBlocks) = ("%s%d__amp__" + toString(heightBlocks))
134+
135+
136+func keyChangeAmpLastCall () = "%s__changeAmpLastCall"
137+
138+
117139 let keyFee = "%s__fee"
118-
119-let feeDefault = fraction(10, scale8, 10000)
120140
121141 let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
122142
123-let keyKLp = makeString(["%s", "kLp"], SEP)
143+let keyDLp = makeString(["%s", "dLp"], SEP)
124144
125-let keyKLpRefreshedHeight = makeString(["%s", "kLpRefreshedHeight"], SEP)
145+let keyDLpRefreshedHeight = makeString(["%s", "dLpRefreshedHeight"], SEP)
126146
127-let keyKLpRefreshDelay = makeString(["%s", "refreshKLpDelay"], SEP)
147+let keyDLpRefreshDelay = makeString(["%s", "refreshDLpDelay"], SEP)
128148
129-let kLpRefreshDelayDefault = 30
149+let dLpRefreshDelayDefault = 30
130150
131-let kLpRefreshDelay = valueOrElse(getInteger(this, keyKLpRefreshDelay), kLpRefreshDelayDefault)
151+let dLpRefreshDelay = valueOrElse(getInteger(this, keyDLpRefreshDelay), dLpRefreshDelayDefault)
132152
133-func keyAdditionalBalance (assetId) = makeString(["%s%s", "stakedBalance", assetId], SEP)
153+func fcfg () = "%s__factoryConfig"
134154
135155
136-func keyStakingAssetBalance (assetId) = makeString(["%s%s", "shareAssetBalance", assetId], SEP)
156+func mtpk () = "%s%s__matcher__publicKey"
137157
138158
139-func getAdditionalBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyAdditionalBalance(assetId)), 0)
159+func pc (iAmtAs,iPrAs) = (((("%d%d%s__" + iAmtAs) + "__") + iPrAs) + "__config")
140160
141161
142-func getStakingAssetBalanceOrZero (assetId) = valueOrElse(getInteger(this, keyStakingAssetBalance(assetId)), 0)
162+func mba (bAStr) = ("%s%s%s__mappings__baseAsset2internalId__" + bAStr)
143163
144164
145-func keyFactoryConfig () = "%s__factoryConfig"
165+func aps () = "%s__shutdown"
146166
147167
148-func keyMatcherPub () = "%s%s__matcher__publicKey"
168+func keyAllowedLpStableScriptHash () = "%s__allowedLpStableScriptHash"
149169
150170
151-func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
171+func keyFeeCollectorAddress () = "%s__feeCollectorAddress"
152172
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"
170173
171174 func keySkipOrderValidation (poolAddress) = ("%s%s__skipOrderValidation__" + poolAddress)
172175
173176
174177 func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
175178
176179
177180 func addressFromStringOrThis (addressString) = match addressFromString(addressString) {
178181 case a: Address =>
179182 a
180183 case _ =>
181184 this
182185 }
183186
184187
185188 func getManagerVaultAddressOrThis () = {
186189 let factoryAddress = match getString(fc()) {
187190 case fca: String =>
188191 addressFromStringOrThis(fca)
189192 case _ =>
190193 this
191194 }
192195 match getString(factoryAddress, keyManagerVaultAddress()) {
193196 case s: String =>
194197 addressFromStringOrThis(s)
195198 case _ =>
196199 this
197200 }
198201 }
199202
200203
201-func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
204+func strf (addr,key) = valueOrErrorMessage(getString(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
202205
203206
204-func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
207+func intf (addr,key) = valueOrErrorMessage(getInteger(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
205208
206209
207-func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
210+func throwErr (msg) = throw(makeString(["lp_stable.ride:", msg], " "))
208211
209212
210-func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
213+func fmtErr (msg) = makeString(["lp_stable.ride:", msg], " ")
211214
212215
213-let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
214-
215-let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
216+let fca = addressFromStringValue(strf(this, fc()))
216217
217218 let inFee = {
218- let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
219+ let @ = invoke(fca, "getInFeeREADONLY", [toString(this)], nil)
219220 if ($isInstanceOf(@, "Int"))
220221 then @
221222 else throw(($getType(@) + " couldn't be cast to Int"))
222223 }
223224
224225 let outFee = {
225- let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
226+ let @ = invoke(fca, "getOutFeeREADONLY", [toString(this)], nil)
226227 if ($isInstanceOf(@, "Int"))
227228 then @
228229 else throw(($getType(@) + " couldn't be cast to Int"))
229230 }
230231
231-func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
232+let A = strf(this, amp())
233+
234+func igs () = valueOrElse(getBoolean(fca, aps()), false)
232235
233236
234-func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
237+func mp () = fromBase58String(strf(fca, mtpk()))
235238
236239
237-func getPoolConfig () = {
238- let amtAsset = getStringOrFail(this, aa())
239- let priceAsset = getStringOrFail(this, pa())
240- let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
241- let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
242- split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
240+let feeCollectorAddress = addressFromStringValue(strf(fca, keyFeeCollectorAddress()))
241+
242+func gpc () = {
243+ let amtAs = strf(this, aa())
244+ let priceAs = strf(this, pa())
245+ let iPriceAs = intf(fca, mba(priceAs))
246+ let iAmtAs = intf(fca, mba(amtAs))
247+ split(strf(fca, pc(toString(iAmtAs), toString(iPriceAs))), SEP)
243248 }
244249
245250
246251 func parseAssetId (input) = if ((input == wavesString))
247252 then unit
248253 else fromBase58String(input)
249254
250255
251256 func assetIdToString (input) = if ((input == unit))
252257 then wavesString
253258 else toBase58String(value(input))
254259
255260
256-func parsePoolConfig (poolConfig) = $Tuple7(addressFromStringValue(poolConfig[idxPoolAddress]), parseIntValue(poolConfig[idxPoolStatus]), fromBase58String(poolConfig[idxPoolLPAssetId]), parseAssetId(poolConfig[idxAmtAssetId]), parseAssetId(poolConfig[idxPriceAssetId]), parseIntValue(poolConfig[idxAmtAssetDcm]), parseIntValue(poolConfig[idxPriceAssetDcm]))
261+func parsePoolConfig (poolConfig) = $Tuple7(addressFromStringValue(poolConfig[idxPoolAddress]), parseIntValue(poolConfig[idxPoolSt]), fromBase58String(poolConfig[idxLPAsId]), parseAssetId(poolConfig[idxAmAsId]), parseAssetId(poolConfig[idxPrAsId]), parseIntValue(poolConfig[idxAmtAsDcm]), parseIntValue(poolConfig[idxPriceAsDcm]))
257262
258263
259-let poolConfigParsed = parsePoolConfig(getPoolConfig())
264+let poolConfigParsed = parsePoolConfig(gpc())
260265
261-let $t095299695 = poolConfigParsed
266+let $t086088794 = poolConfigParsed
262267
263-let cfgPoolAddress = $t095299695._1
268+let cfgPoolAddress = $t086088794._1
264269
265-let cfgPoolStatus = $t095299695._2
270+let cfgPoolStatus = $t086088794._2
266271
267-let cfgLpAssetId = $t095299695._3
272+let cfgLpAssetId = $t086088794._3
268273
269-let cfgAmountAssetId = $t095299695._4
274+let cfgAmountAssetId = $t086088794._4
270275
271-let cfgPriceAssetId = $t095299695._5
276+let cfgPriceAssetId = $t086088794._5
272277
273-let cfgAmountAssetDecimals = $t095299695._6
278+let cfgAmountAssetDecimals = $t086088794._6
274279
275-let cfgPriceAssetDecimals = $t095299695._7
280+let cfgPriceAssetDecimals = $t086088794._7
276281
277-func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
282+func gfc () = split(strf(fca, fcfg()), SEP)
278283
279284
280-let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
285+let factoryConfig = gfc()
281286
282-let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
287+let stakingContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactStakCntr]), "Invalid staking contract address")
283288
284-func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slippageTolerancePassedByUser,slippageToleranceReal,txHeight,txTimestamp,slipageAmtAssetAmt,slipagePriceAssetAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slippageTolerancePassedByUser), toString(slippageToleranceReal), toString(txHeight), toString(txTimestamp), toString(slipageAmtAssetAmt), toString(slipagePriceAssetAmt)], SEP)
289+let slipageContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactSlippCntr]), "Invalid slipage contract address")
290+
291+let gwxContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactGwxRewCntr]), "Invalid gwx contract address")
292+
293+let restContract = valueOrErrorMessage(addressFromString(factoryConfig[idxFactoryRestCntr]), "Invalid gwx contract address")
294+
295+func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slipByUser,slippageReal,txHeight,txTimestamp,slipageAmAmt,slipagePrAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slipByUser), toString(slippageReal), toString(txHeight), toString(txTimestamp), toString(slipageAmAmt), toString(slipagePrAmt)], SEP)
285296
286297
287298 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)
288299
289300
290-func getAccBalance (assetId) = {
291- let balanceOnPool = if ((assetId == "WAVES"))
292- then wavesBalance(this).available
293- else assetBalance(this, fromBase58String(assetId))
294- let totalBalance = ((balanceOnPool + getAdditionalBalanceOrZero(assetId)) - getStakingAssetBalanceOrZero(assetId))
295- max([0, totalBalance])
301+func getAccBalance (assetId) = if ((assetId == "WAVES"))
302+ then wavesBalance(this).available
303+ else assetBalance(this, fromBase58String(assetId))
304+
305+
306+func cpbi (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
307+
308+
309+func cpbir (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
310+
311+
312+func vad (A1,A2,slippage) = {
313+ let diff = fraction((A1 - A2), scale8BigInt, A2)
314+ let pass = ((slippage - abs(diff)) > zeroBigInt)
315+ if (!(pass))
316+ then throw(("Big slpg: " + toString(diff)))
317+ else $Tuple2(pass, min([A1, A2]))
296318 }
297319
298320
299-func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
300-
301-
302-func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
303-
304-
305-func getRate (proxy) = {
306- let inv = invoke(proxy, "getRate", nil, nil)
307- if ((inv == inv))
308- then match inv {
309- case r: Int =>
310- r
311- case _ =>
312- throwErr("proxy.getRate() unexpected value")
313- }
314- else throw("Strict value is not equal to itself.")
321+func vd (D1,D0,slpg) = {
322+ let diff = fraction(D0, scale8BigInt, D1)
323+ let fail = (slpg > diff)
324+ if (if (fail)
325+ then true
326+ else (D0 > D1))
327+ then throw(((((((toString(D0) + " ") + toString(D1)) + " ") + toString(diff)) + " ") + toString(slpg)))
328+ else fail
315329 }
316330
317331
318-func deposit (assetId,amount,stakingAssetId,proxy) = {
319- let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
320- if ((currentAdditionalBalance == currentAdditionalBalance))
321- then {
322- let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
323- if ((currentStakingAssetBalance == currentStakingAssetBalance))
324- then {
325- let asset = parseAssetId(assetId)
326- if ((amount > 0))
327- then {
328- let depositInvoke = invoke(proxy, "deposit", nil, [AttachedPayment(asset, amount)])
329- if ((depositInvoke == depositInvoke))
330- then match depositInvoke {
331- case receivedStakingAsset: Int =>
332- let newAdditionalBalance = (currentAdditionalBalance + amount)
333- let newStakingAssetBalance = (currentStakingAssetBalance + receivedStakingAsset)
334-[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance)]
335- case _ =>
336- nil
337- }
338- else throw("Strict value is not equal to itself.")
339- }
340- else nil
341- }
342- else throw("Strict value is not equal to itself.")
343- }
344- else throw("Strict value is not equal to itself.")
345- }
346-
347-
348-func withdraw (assetId,amount,stakingAssetId,proxy,proxyRateMul,profitAddress) = {
349- let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
350- if ((currentAdditionalBalance == currentAdditionalBalance))
351- then {
352- let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
353- if ((currentStakingAssetBalance == currentStakingAssetBalance))
354- then {
355- let currentProxyRate = getRate(proxy)
356- if ((currentProxyRate == currentProxyRate))
357- then {
358- let oldRate = fraction(proxyRateMul, currentAdditionalBalance, currentStakingAssetBalance)
359- let stakingAsset = parseAssetId(stakingAssetId)
360- let oldSendStakingAmount = fraction(proxyRateMul, amount, oldRate)
361- let sendStakingAssetAmount = fraction(proxyRateMul, amount, currentProxyRate)
362- let profitAmount = max([0, (oldSendStakingAmount - sendStakingAssetAmount)])
363- if ((sendStakingAssetAmount > 0))
364- then {
365- let withdrawInvoke = invoke(proxy, "withdraw", nil, [AttachedPayment(stakingAsset, sendStakingAssetAmount)])
366- if ((withdrawInvoke == withdrawInvoke))
367- then match withdrawInvoke {
368- case receivedAssets: Int =>
369- let newAdditionalBalance = (currentAdditionalBalance - receivedAssets)
370- let newStakingAssetBalance = ((currentStakingAssetBalance - sendStakingAssetAmount) - profitAmount)
371-[IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance), ScriptTransfer(profitAddress, profitAmount, parseAssetId(stakingAssetId))]
372- case _ =>
373- nil
374- }
375- else throw("Strict value is not equal to itself.")
376- }
377- else nil
378- }
379- else throw("Strict value is not equal to itself.")
380- }
381- else throw("Strict value is not equal to itself.")
382- }
383- else throw("Strict value is not equal to itself.")
384- }
385-
386-
387-func getLeaseProxyConfig (assetId) = match invoke(factoryContract, "getPoolLeaseConfigREADONLY", [toString(this), assetId], nil) {
388- case a: (Boolean, Int, Int, String, String, Int, String) =>
389- a
390- case _ =>
391- throwErr((("[" + assetId) + "] getLeaseProxyConfig() error"))
392-}
393-
394-
395-func rebalanceInternal (targetRatio,assetId,stakingAssetId,minBalance,proxy,proxyRateMul,profitAddress) = {
396- let currentAdditionalBalance = getAdditionalBalanceOrZero(assetId)
397- if ((currentAdditionalBalance == currentAdditionalBalance))
398- then {
399- let currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId)
400- if ((currentStakingAssetBalance == currentStakingAssetBalance))
401- then {
402- let leasableTotalBalance = max([0, (getAccBalance(assetId) - minBalance)])
403- let targetAdditionalBalance = fraction(targetRatio, leasableTotalBalance, 100)
404- let diff = (currentAdditionalBalance - targetAdditionalBalance)
405- if ((diff == 0))
406- then nil
407- else if ((0 > diff))
408- then {
409- let sendAssetAmount = -(diff)
410- deposit(assetId, sendAssetAmount, stakingAssetId, proxy)
411- }
412- else {
413- let getAssetAmount = diff
414- withdraw(assetId, getAssetAmount, stakingAssetId, proxy, proxyRateMul, profitAddress)
415- }
416- }
417- else throw("Strict value is not equal to itself.")
418- }
419- else throw("Strict value is not equal to itself.")
420- }
421-
422-
423-func rebalanceAsset (assetId) = {
424- let $t01593116067 = getLeaseProxyConfig(assetId)
425- let isLeasable = $t01593116067._1
426- let leasedRatio = $t01593116067._2
427- let minBalance = $t01593116067._3
428- let proxyAddress = $t01593116067._4
429- let proxyAssetId = $t01593116067._5
430- let proxyRateMul = $t01593116067._6
431- let stakingProfitAddress = $t01593116067._7
432- if (isLeasable)
433- then rebalanceInternal(leasedRatio, assetId, proxyAssetId, minBalance, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
434- else nil
435- }
436-
437-
438-func withdrawAndRebalanceAsset (assetId,getAmount) = {
439- let $t01646616602 = getLeaseProxyConfig(assetId)
440- let isLeasable = $t01646616602._1
441- let leasedRatio = $t01646616602._2
442- let minBalance = $t01646616602._3
443- let proxyAddress = $t01646616602._4
444- let proxyAssetId = $t01646616602._5
445- let proxyRateMul = $t01646616602._6
446- let stakingProfitAddress = $t01646616602._7
447- if (isLeasable)
448- then {
449- let newTotalLeasableBalance = max([0, ((getAccBalance(assetId) - getAmount) - minBalance)])
450- if ((newTotalLeasableBalance == newTotalLeasableBalance))
451- then {
452- let newAdditionalBalance = fraction(leasedRatio, newTotalLeasableBalance, 100)
453- if ((newAdditionalBalance == newAdditionalBalance))
454- then {
455- let withdrawAmount = (getAdditionalBalanceOrZero(assetId) - newAdditionalBalance)
456- if ((withdrawAmount == withdrawAmount))
457- then if ((0 > withdrawAmount))
458- then deposit(assetId, -(withdrawAmount), proxyAssetId, addressFromStringValue(proxyAddress))
459- else withdraw(assetId, withdrawAmount, proxyAssetId, addressFromStringValue(proxyAddress), proxyRateMul, addressFromStringValue(stakingProfitAddress))
460- else throw("Strict value is not equal to itself.")
461- }
462- else throw("Strict value is not equal to itself.")
463- }
464- else throw("Strict value is not equal to itself.")
465- }
466- else nil
467- }
468-
469-
470-func withdrawAndRebalanceAll (amountAssetOutAmount,priceAssetOutAmount) = {
471- let AmAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, aa()), amountAssetOutAmount)
472- let PrAmtWithdrawState = withdrawAndRebalanceAsset(getStringOrFail(this, pa()), priceAssetOutAmount)
473- (AmAmtWithdrawState ++ PrAmtWithdrawState)
474- }
475-
476-
477-func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
478- let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
479- let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
480- calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
332+func pcp (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
333+ let amtAsAmtX18 = t1(amAmt, amAssetDcm)
334+ let prAsAmtX18 = t1(prAmt, prAssetDcm)
335+ cpbi(prAsAmtX18, amtAsAmtX18)
481336 }
482337
483338
484339 func calcPrices (amAmt,prAmt,lpAmt) = {
485- let cfg = getPoolConfig()
486- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
487- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
488- let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
489- let amAmtX18 = toX18(amAmt, amtAssetDcm)
490- let prAmtX18 = toX18(prAmt, priceAssetDcm)
491- let lpAmtX18 = toX18(lpAmt, scale8)
492- let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
493- let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
494-[priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
340+ let amtAsDcm = cfgAmountAssetDecimals
341+ let prAsDcm = cfgPriceAssetDecimals
342+ let priceX18 = pcp(amtAsDcm, prAsDcm, amAmt, prAmt)
343+ let amAmtX18 = t1(amAmt, amtAsDcm)
344+ let prAmtX18 = t1(prAmt, prAsDcm)
345+ let lpAmtX18 = t1(lpAmt, scale8)
346+ let lpPrInAmAsX18 = cpbi(amAmtX18, lpAmtX18)
347+ let lpPrInPrAsX18 = cpbi(prAmtX18, lpAmtX18)
348+[priceX18, lpPrInAmAsX18, lpPrInPrAsX18]
495349 }
496350
497351
498352 func calculatePrices (amAmt,prAmt,lpAmt) = {
499- let prices = calcPrices(amAmt, prAmt, lpAmt)
500-[fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
501- }
502-
503-
504-func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
505- let cfg = getPoolConfig()
506- let lpAssetId = cfg[idxPoolLPAssetId]
507- let amAssetId = cfg[idxAmtAssetId]
508- let prAssetId = cfg[idxPriceAssetId]
509- let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
510- let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
511- let poolStatus = cfg[idxPoolStatus]
512- let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
513- if ((lpAssetId != pmtAssetId))
514- then throw("Invalid asset passed.")
515- else {
516- let amBalance = getAccBalance(amAssetId)
517- let amBalanceX18 = toX18(amBalance, amAssetDcm)
518- let prBalance = getAccBalance(prAssetId)
519- let prBalanceX18 = toX18(prBalance, prAssetDcm)
520- let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
521- let curPrice = fromX18(curPriceX18, scale8)
522- let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
523- let lpEmissionX18 = toX18(lpEmission, scale8)
524- let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
525- let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
526- let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
527- let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
528- let state = if ((txId58 == ""))
529- then nil
530- else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
531- then unit
532- else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
533- then unit
534- else fromBase58String(prAssetId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
535- $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
536- }
537- }
538-
539-
540-func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
541- let cfg = getPoolConfig()
542- let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
543- let amAssetIdStr = cfg[idxAmtAssetId]
544- let prAssetIdStr = cfg[idxPriceAssetId]
545- let iAmtAssetId = cfg[idxIAmtAssetId]
546- let iPriceAssetId = cfg[idxIPriceAssetId]
547- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
548- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
549- let poolStatus = cfg[idxPoolStatus]
550- let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
551- let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
552- let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
553- if (if ((amAssetIdStr != inAmAssetIdStr))
554- then true
555- else (prAssetIdStr != inPrAssetIdStr))
556- then throw("Invalid amt or price asset passed.")
557- else {
558- let amBalance = if (isEvaluate)
559- then getAccBalance(amAssetIdStr)
560- else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
561- let prBalance = if (isEvaluate)
562- then getAccBalance(prAssetIdStr)
563- else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
564- let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
565- let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
566- let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
567- let amBalanceX18 = toX18(amBalance, amtAssetDcm)
568- let prBalanceX18 = toX18(prBalance, priceAssetDcm)
569- let res = if ((lpEmission == 0))
570- then {
571- let curPriceX18 = zeroBigInt
572- let slippageX18 = zeroBigInt
573- let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
574- $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
575- }
576- else {
577- let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
578- let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
579- let slippageToleranceX18 = toX18(slippageTolerance, scale8)
580- if (if ((curPriceX18 != zeroBigInt))
581- then (slippageX18 > slippageToleranceX18)
582- else false)
583- then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
584- else {
585- let lpEmissionX18 = toX18(lpEmission, scale8)
586- let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
587- let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
588- let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
589- then $Tuple2(amViaPrX18, inPrAssetAmtX18)
590- else $Tuple2(inAmAssetAmtX18, prViaAmX18)
591- let expAmtAssetAmtX18 = expectedAmts._1
592- let expPriceAssetAmtX18 = expectedAmts._2
593- let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
594- $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
595- }
596- }
597- let calcLpAmt = res._1
598- let calcAmAssetPmt = res._2
599- let calcPrAssetPmt = res._3
600- let curPrice = fromX18(res._4, scale8)
601- let slippageCalc = fromX18(res._5, scale8)
602- if ((0 >= calcLpAmt))
603- then throw("Invalid calculations. LP calculated is less than zero.")
604- else {
605- let emitLpAmt = if (!(emitLp))
606- then 0
607- else calcLpAmt
608- let amDiff = (inAmAssetAmt - calcAmAssetPmt)
609- let prDiff = (inPrAssetAmt - calcPrAssetPmt)
610- let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(calcAmAssetPmt, calcPrAssetPmt, emitLpAmt, curPrice, slippageTolerance, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
611- $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
612- }
613- }
614- }
615-
616-
617-func calcKLp (amountBalance,priceBalance,lpEmission) = {
618- let amountBalanceX18 = toX18BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals))
619- let priceBalanceX18 = toX18BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))
620- let updatedKLp = fraction(pow((amountBalanceX18 * priceBalanceX18), 0, toBigInt(5), 1, 18, DOWN), big1, lpEmission)
621- if ((lpEmission == big0))
622- then big0
623- else updatedKLp
624- }
625-
626-
627-func calcCurrentKLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
628- let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
629- let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
630- let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
631- let currentKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
632- currentKLp
633- }
634-
635-
636-func refreshKLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
637- let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
638- let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
639- let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
640- let updatedKLp = calcKLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
641- let actions = [IntegerEntry(keyKLpRefreshedHeight, height), StringEntry(keyKLp, toString(updatedKLp))]
642- $Tuple2(actions, updatedKLp)
643- }
644-
645-
646-func skipOrderValidation () = valueOrElse(getBoolean(factoryContract, keySkipOrderValidation(toString(this))), false)
647-
648-
649-func validateUpdatedKLp (oldKLp,updatedKLp) = if ((updatedKLp >= oldKLp))
650- then true
651- else throwErr(makeString(["updated KLp lower than current KLp", toString(oldKLp), toString(updatedKLp)], " "))
652-
653-
654-func validateMatcherOrderAllowed (order) = {
655- let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
656- let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
657- let amountAssetAmount = order.amount
658- let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
659- let $t02899129203 = if ((order.orderType == Buy))
660- then $Tuple2(amountAssetAmount, -(priceAssetAmount))
661- else $Tuple2(-(amountAssetAmount), priceAssetAmount)
662- let amountAssetBalanceDelta = $t02899129203._1
663- let priceAssetBalanceDelta = $t02899129203._2
664- if (if (if (isGlobalShutdown())
665- then true
666- else (cfgPoolStatus == PoolMatcherDisabled))
667- then true
668- else (cfgPoolStatus == PoolShutdown))
669- then throw("Exchange operations disabled")
670- else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
671- then true
672- else (order.assetPair.priceAsset != cfgPriceAssetId))
673- then throw("Wrong order assets.")
674- else {
675- let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
676- let $t02964329743 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
677- let unusedActions = $t02964329743._1
678- let kLpNew = $t02964329743._2
679- let isOrderValid = (kLpNew >= kLp)
680- let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
681- $Tuple2(isOrderValid, info)
682- }
683- }
684-
685-
686-func commonGet (i) = if ((size(i.payments) != 1))
687- then throw("exactly 1 payment is expected")
688- else {
689- let pmt = value(i.payments[0])
690- let pmtAssetId = value(pmt.assetId)
691- let pmtAmt = pmt.amount
692- let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
693- let outAmAmt = res._1
694- let outPrAmt = res._2
695- let poolStatus = parseIntValue(res._9)
696- let state = res._10
697- if (if (isGlobalShutdown())
698- then true
699- else (poolStatus == PoolShutdown))
700- then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
701- else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
702- }
703-
704-
705-func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
706- then throw("exactly 2 payments are expected")
707- else {
708- let amAssetPmt = value(i.payments[0])
709- let prAssetPmt = value(i.payments[1])
710- let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
711- let poolStatus = parseIntValue(estPut._8)
712- if (if (if (isGlobalShutdown())
713- then true
714- else (poolStatus == PoolPutDisabled))
715- then true
716- else (poolStatus == PoolShutdown))
717- then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
718- else estPut
719- }
720-
721-
722-func emit (amount) = {
723- let emitInv = invoke(factoryContract, "emit", [amount], nil)
724- if ((emitInv == emitInv))
725- then {
726- let emitInvLegacy = match emitInv {
727- case legacyFactoryContract: Address =>
728- invoke(legacyFactoryContract, "emit", [amount], nil)
729- case _ =>
730- unit
731- }
732- if ((emitInvLegacy == emitInvLegacy))
733- then amount
734- else throw("Strict value is not equal to itself.")
735- }
736- else throw("Strict value is not equal to itself.")
353+ let p = calcPrices(amAmt, prAmt, lpAmt)
354+[f1(p[0], scale8), f1(p[1], scale8), f1(p[2], scale8)]
737355 }
738356
739357
740358 func takeFee (amount,fee) = {
741359 let feeAmount = if ((fee == 0))
742360 then 0
743361 else fraction(amount, fee, scale8)
744362 $Tuple2((amount - feeAmount), feeAmount)
745363 }
746364
747365
748-func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
749- let isEval = (txId == unit)
750- let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
751- let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
752- let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
366+func getD (xp) = {
367+ let xp0 = xp[0]
368+ let xp1 = xp[1]
369+ let s = (xp0 + xp1)
370+ if ((s == big0))
371+ then big0
372+ else {
373+ let a = parseIntValue(A)
374+ let ann = (a * 2)
375+ let p = fraction(xp0, xp1, big1)
376+ let xp0_xp1_n_n = fraction(p, big4, big1)
377+ let ann_s = fraction(toBigInt(ann), s, big1)
378+ let ann_1 = toBigInt((ann - 1))
379+ func calcDNext (d) = {
380+ let dd = fraction(d, d, big1)
381+ let ddd = fraction(dd, d, big1)
382+ let dp = fraction(ddd, big1, xp0_xp1_n_n)
383+ fraction((ann_s + fraction(dp, big2, big1)), d, (fraction(ann_1, d, big1) + fraction(big3, dp, big1)))
384+ }
385+
386+ func calc (acc,i) = if (acc._2)
387+ then acc
388+ else {
389+ let d = acc._1
390+ let dNext = calcDNext(d)
391+ let dDiffRaw = (dNext - value(d))
392+ let dDiff = if ((big0 > dDiffRaw))
393+ then -(dDiffRaw)
394+ else dDiffRaw
395+ if ((big1 >= dDiff))
396+ then $Tuple2(dNext, true)
397+ else $Tuple2(dNext, false)
398+ }
399+
400+ let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
401+ let $t01329913347 = {
402+ let $l = arr
403+ let $s = size($l)
404+ let $acc0 = $Tuple2(s, false)
405+ func $f0_1 ($a,$i) = if (($i >= $s))
406+ then $a
407+ else calc($a, $l[$i])
408+
409+ func $f0_2 ($a,$i) = if (($i >= $s))
410+ then $a
411+ else throw("List size exceeds 17")
412+
413+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17)
414+ }
415+ let d = $t01329913347._1
416+ let found = $t01329913347._2
417+ if (found)
418+ then d
419+ else throw(("D calculation error, D = " + toString(d)))
420+ }
421+ }
422+
423+
424+func ego (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
425+ let lpId = cfgLpAssetId
426+ let amId = toBase58String(value(cfgAmountAssetId))
427+ let prId = toBase58String(value(cfgPriceAssetId))
428+ let amDcm = cfgAmountAssetDecimals
429+ let prDcm = cfgPriceAssetDecimals
430+ let sts = toString(cfgPoolStatus)
431+ let lpEmiss = valueOrErrorMessage(assetInfo(lpId), "Wrong LP id").quantity
432+ if ((toBase58String(lpId) != pmtAssetId))
433+ then throw("Wrong pmt asset")
434+ else {
435+ let amBalance = getAccBalance(amId)
436+ let amBalanceX18 = t1(amBalance, amDcm)
437+ let prBalance = getAccBalance(prId)
438+ let prBalanceX18 = t1(prBalance, prDcm)
439+ let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
440+ let curPrice = f1(curPriceX18, scale8)
441+ let pmtLpAmtX18 = t1(pmtLpAmt, scale8)
442+ let lpEmissX18 = t1(lpEmiss, scale8)
443+ let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissX18)
444+ let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissX18)
445+ let outAmAmt = fromX18Round(outAmAmtX18, amDcm, FLOOR)
446+ let outPrAmt = fromX18Round(outPrAmtX18, prDcm, FLOOR)
447+ let state = if ((txId58 == ""))
448+ then nil
449+ else [ScriptTransfer(userAddress, outAmAmt, if ((amId == "WAVES"))
450+ then unit
451+ else fromBase58String(amId)), ScriptTransfer(userAddress, outPrAmt, if ((prId == "WAVES"))
452+ then unit
453+ else fromBase58String(prId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
454+ $Tuple10(outAmAmt, outPrAmt, amId, prId, amBalance, prBalance, lpEmiss, curPriceX18, sts, state)
455+ }
456+ }
457+
458+
459+func epo (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEval,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
460+ let lpId = cfgLpAssetId
461+ let amIdStr = toBase58String(value(cfgAmountAssetId))
462+ let prIdStr = toBase58String(value(cfgPriceAssetId))
463+ let amtDcm = cfgAmountAssetDecimals
464+ let priceDcm = cfgPriceAssetDecimals
465+ let sts = toString(cfgPoolStatus)
466+ let lpEm = valueOrErrorMessage(assetInfo(lpId), "Wr lp as").quantity
467+ let amBalance = if (isEval)
468+ then getAccBalance(amIdStr)
469+ else if (if (isOneAsset)
470+ then (pmtId == amIdStr)
471+ else false)
472+ then (getAccBalance(amIdStr) - pmtAmt)
473+ else if (isOneAsset)
474+ then getAccBalance(amIdStr)
475+ else (getAccBalance(amIdStr) - inAmAmt)
476+ let prBalance = if (isEval)
477+ then getAccBalance(prIdStr)
478+ else if (if (isOneAsset)
479+ then (pmtId == prIdStr)
480+ else false)
481+ then (getAccBalance(prIdStr) - pmtAmt)
482+ else if (isOneAsset)
483+ then getAccBalance(prIdStr)
484+ else (getAccBalance(prIdStr) - inPrAmt)
485+ let inAmAssetAmtX18 = t1(inAmAmt, amtDcm)
486+ let inPrAssetAmtX18 = t1(inPrAmt, priceDcm)
487+ let userPriceX18 = cpbi(inPrAssetAmtX18, inAmAssetAmtX18)
488+ let amBalanceX18 = t1(amBalance, amtDcm)
489+ let prBalanceX18 = t1(prBalance, priceDcm)
490+ let D0 = getD([amBalanceX18, prBalanceX18])
491+ let r = if ((lpEm == 0))
492+ then {
493+ let D1 = getD([(amBalanceX18 + inAmAssetAmtX18), (prBalanceX18 + inPrAssetAmtX18)])
494+ let checkD = if ((D1 > D0))
495+ then true
496+ else throw("D1 should be greater than D0")
497+ if ((checkD == checkD))
498+ then {
499+ let curPriceX18 = zeroBigInt
500+ let slippageX18 = zeroBigInt
501+ let lpAmtX18 = D1
502+ $Tuple5(f1(lpAmtX18, scale8), f1(inAmAssetAmtX18, amtDcm), f1(inPrAssetAmtX18, priceDcm), cpbi((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
503+ }
504+ else throw("Strict value is not equal to itself.")
505+ }
506+ else {
507+ let curPriceX18 = cpbi(prBalanceX18, amBalanceX18)
508+ let slippageRealX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
509+ let slippageX18 = t1(slippage, scale8)
510+ if (if (if (validateSlippage)
511+ then (curPriceX18 != zeroBigInt)
512+ else false)
513+ then (slippageRealX18 > slippageX18)
514+ else false)
515+ then throw(((("Price slippage " + toString(slippageRealX18)) + " > ") + toString(slippageX18)))
516+ else {
517+ let lpEmissionX18 = t1(lpEm, scale8)
518+ let prViaAmX18 = fraction(inAmAssetAmtX18, cpbir(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
519+ let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, cpbir(prBalanceX18, amBalanceX18, FLOOR), CEILING)
520+ let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
521+ then $Tuple2(amViaPrX18, inPrAssetAmtX18)
522+ else $Tuple2(inAmAssetAmtX18, prViaAmX18)
523+ let expAmtAssetAmtX18 = expectedAmts._1
524+ let expPriceAssetAmtX18 = expectedAmts._2
525+ let D1 = getD([(amBalanceX18 + expAmtAssetAmtX18), (prBalanceX18 + expPriceAssetAmtX18)])
526+ let checkD = if ((D1 > D0))
527+ then true
528+ else throw("D1 should be greater than D0")
529+ if ((checkD == checkD))
530+ then {
531+ let lpAmtX18 = fraction(lpEmissionX18, (D1 - D0), D0)
532+ $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceDcm, CEILING), curPriceX18, slippageX18)
533+ }
534+ else throw("Strict value is not equal to itself.")
535+ }
536+ }
537+ let calcLpAmt = r._1
538+ let calcAmAssetPmt = r._2
539+ let calcPrAssetPmt = r._3
540+ let curPrice = f1(r._4, scale8)
541+ let slippageCalc = f1(r._5, scale8)
542+ if ((0 >= calcLpAmt))
543+ then throw("LP <= 0")
544+ else {
545+ let emitLpAmt = if (!(emitLp))
546+ then 0
547+ else calcLpAmt
548+ let amDiff = (inAmAmt - calcAmAssetPmt)
549+ let prDiff = (inPrAmt - calcPrAssetPmt)
550+ let $t02110921454 = if (if (isOneAsset)
551+ then (pmtId == amIdStr)
552+ else false)
553+ then $Tuple2(pmtAmt, 0)
554+ else if (if (isOneAsset)
555+ then (pmtId == prIdStr)
556+ else false)
557+ then $Tuple2(0, pmtAmt)
558+ else $Tuple2(calcAmAssetPmt, calcPrAssetPmt)
559+ let writeAmAmt = $t02110921454._1
560+ let writePrAmt = $t02110921454._2
561+ let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(writeAmAmt, writePrAmt, emitLpAmt, curPrice, slippage, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
562+ $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEm, lpId, sts, commonState, amDiff, prDiff, inAmId, inPrId)
563+ }
564+ }
565+
566+
567+func getYD (xp,i,D) = {
568+ let n = big2
569+ let x = xp[if ((i == 0))
570+ then 1
571+ else 0]
572+ let aPrecision = parseBigIntValue(Amult)
573+ let a = (parseBigIntValue(A) * aPrecision)
574+ let s = x
575+ let ann = (a * n)
576+ let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
577+ let b = ((s + ((D * aPrecision) / ann)) - D)
578+ func calc (acc,cur) = {
579+ let $t02264922669 = acc
580+ let y = $t02264922669._1
581+ let found = $t02264922669._2
582+ if ((found != unit))
583+ then acc
584+ else {
585+ let yNext = (((y * y) + c) / ((big2 * y) + b))
586+ let yDiff = absBigInt((yNext - value(y)))
587+ if ((big1 >= yDiff))
588+ then $Tuple2(yNext, cur)
589+ else $Tuple2(yNext, unit)
590+ }
591+ }
592+
593+ let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
594+ let $t02297623023 = {
595+ let $l = arr
596+ let $s = size($l)
597+ let $acc0 = $Tuple2(D, unit)
598+ func $f0_1 ($a,$i) = if (($i >= $s))
599+ then $a
600+ else calc($a, $l[$i])
601+
602+ func $f0_2 ($a,$i) = if (($i >= $s))
603+ then $a
604+ else throw("List size exceeds 15")
605+
606+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
607+ }
608+ let y = $t02297623023._1
609+ let found = $t02297623023._2
610+ if ((found != unit))
611+ then y
612+ else throw(("Y calculation error, Y = " + toString(y)))
613+ }
614+
615+
616+func calcDLp (amountBalance,priceBalance,lpEmission) = {
617+ let updatedDLp = fraction(getD([t1BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals)), t1BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))]), scale18, lpEmission)
618+ if ((lpEmission == big0))
619+ then big0
620+ else updatedDLp
621+ }
622+
623+
624+func calcCurrentDLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
625+ let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
626+ let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
627+ let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
628+ let currentDLp = calcDLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
629+ currentDLp
630+ }
631+
632+
633+func refreshDLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
634+ let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
635+ let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
636+ let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
637+ let updatedDLp = calcDLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
638+ let actions = [IntegerEntry(keyDLpRefreshedHeight, height), StringEntry(keyDLp, toString(updatedDLp))]
639+ $Tuple2(actions, updatedDLp)
640+ }
641+
642+
643+func validateUpdatedDLp (oldDLp,updatedDLp) = if ((updatedDLp >= oldDLp))
644+ then true
645+ else throwErr("updated DLp lower than current DLp")
646+
647+
648+func validateMatcherOrderAllowed (order) = {
649+ let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
650+ let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
651+ let amountAssetAmount = order.amount
652+ let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
653+ let $t02522125433 = if ((order.orderType == Buy))
654+ then $Tuple2(amountAssetAmount, -(priceAssetAmount))
655+ else $Tuple2(-(amountAssetAmount), priceAssetAmount)
656+ let amountAssetBalanceDelta = $t02522125433._1
657+ let priceAssetBalanceDelta = $t02522125433._2
658+ if (if (if (igs())
753659 then true
754- else if ((paymentAssetId == cfgPriceAssetId))
755- then false
756- else throwErr("invalid asset")
757- let $t03285633149 = if (isEval)
758- then $Tuple2(amountBalanceRaw, priceBalanceRaw)
759- else if (paymentInAmountAsset)
760- then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
761- else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
762- let amountBalanceOld = $t03285633149._1
763- let priceBalanceOld = $t03285633149._2
764- let $t03315333302 = if (paymentInAmountAsset)
765- then $Tuple2(paymentAmountRaw, 0)
766- else $Tuple2(0, paymentAmountRaw)
767- let amountAssetAmountRaw = $t03315333302._1
768- let priceAssetAmountRaw = $t03315333302._2
769- let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
770- let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
771- let $t03343433498 = takeFee(paymentAmountRaw, inFee)
772- let paymentAmount = $t03343433498._1
773- let feeAmount = $t03343433498._2
774- let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
775- let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
776- let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
777- let priceNew = fromX18(priceNewX18, scale8)
778- let paymentBalance = if (paymentInAmountAsset)
779- then amountBalanceOld
780- else priceBalanceOld
781- let paymentBalanceBigInt = toBigInt(paymentBalance)
782- let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
783- let chechSupply = if ((supplyBigInt > big0))
660+ else (cfgPoolStatus == PoolMatcherDis))
784661 then true
785- else throwErr("initial deposit requires all coins")
786- if ((chechSupply == chechSupply))
662+ else (cfgPoolStatus == PoolShutdown))
663+ then throw("Admin blocked")
664+ else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
665+ then true
666+ else (order.assetPair.priceAsset != cfgPriceAssetId))
667+ then throw("Wr assets")
668+ else {
669+ let dLp = parseBigIntValue(valueOrElse(getString(this, keyDLp), "0"))
670+ let $t02577525875 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
671+ let unusedActions = $t02577525875._1
672+ let dLpNew = $t02577525875._2
673+ let isOrderValid = (dLpNew >= dLp)
674+ let info = makeString(["dLp=", toString(dLp), " dLpNew=", toString(dLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
675+ $Tuple2(isOrderValid, info)
676+ }
677+ }
678+
679+
680+func cg (i) = if ((size(i.payments) != 1))
681+ then throw("1 pmnt exp")
682+ else {
683+ let pmt = value(i.payments[0])
684+ let pmtAssetId = value(pmt.assetId)
685+ let pmtAmt = pmt.amount
686+ let r = ego(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
687+ let outAmAmt = r._1
688+ let outPrAmt = r._2
689+ let sts = parseIntValue(r._9)
690+ let state = r._10
691+ if (if (igs())
692+ then true
693+ else (sts == PoolShutdown))
694+ then throw(("Admin blocked: " + toString(sts)))
695+ else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
696+ }
697+
698+
699+func cp (caller,txId,amAsPmt,prAsPmt,slippage,emitLp,isOneAsset,validateSlippage,pmtAmt,pmtId) = {
700+ let r = epo(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, (txId == ""), emitLp, isOneAsset, validateSlippage, pmtAmt, pmtId)
701+ let sts = parseIntValue(r._8)
702+ if (if (if (igs())
703+ then true
704+ else (sts == PoolPutDis))
705+ then true
706+ else (sts == PoolShutdown))
707+ then throw(("Blocked:" + toString(sts)))
708+ else r
709+ }
710+
711+
712+func calcPutOneTkn (pmtAmtRaw,pmtAssetId,userAddress,txId,withTakeFee) = {
713+ let amId = toBase58String(value(cfgAmountAssetId))
714+ let prId = toBase58String(value(cfgPriceAssetId))
715+ let lpId = cfgLpAssetId
716+ let amtDcm = cfgAmountAssetDecimals
717+ let priceDcm = cfgPriceAssetDecimals
718+ let lpAssetEmission = toBigInt(valueOrErrorMessage(assetInfo(lpId), "invalid lp asset").quantity)
719+ let chechEmission = if ((lpAssetEmission > big0))
720+ then true
721+ else throw("initial deposit requires all coins")
722+ if ((chechEmission == chechEmission))
787723 then {
788- let depositBigInt = toBigInt(paymentAmount)
789- let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
790- let commonState = if (isEval)
791- then nil
792- else [IntegerEntry(pl(), priceNew), IntegerEntry(ph(height, lastBlock.timestamp), priceNew), StringEntry(pau(toString(value(userAddress)), toBase58String(value(txId))), dataPutActionInfo(amountAssetAmountRaw, priceAssetAmountRaw, issueAmount, priceNew, 0, 0, height, lastBlock.timestamp, 0, 0))]
793- let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
794- let priceOld = fromX18(priceOldX18, scale8)
795- let loss = {
796- let $t03517935346 = if (paymentInAmountAsset)
797- then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
798- else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
799- let amount = $t03517935346._1
800- let balance = $t03517935346._2
801- let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
802- fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
803- }
804- $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
724+ let amBalance = getAccBalance(amId)
725+ let prBalance = getAccBalance(prId)
726+ let $t02853128993 = if ((txId == ""))
727+ then $Tuple2(amBalance, prBalance)
728+ else if ((pmtAssetId == amId))
729+ then if ((pmtAmtRaw > amBalance))
730+ then throw("invalid payment amount")
731+ else $Tuple2((amBalance - pmtAmtRaw), prBalance)
732+ else if ((pmtAssetId == prId))
733+ then if ((pmtAmtRaw > prBalance))
734+ then throw("invalid payment amount")
735+ else $Tuple2(amBalance, (prBalance - pmtAmtRaw))
736+ else throw("wrong pmtAssetId")
737+ let amBalanceOld = $t02853128993._1
738+ let prBalanceOld = $t02853128993._2
739+ let $t02899929175 = if ((pmtAssetId == amId))
740+ then $Tuple2(pmtAmtRaw, 0)
741+ else if ((pmtAssetId == prId))
742+ then $Tuple2(0, pmtAmtRaw)
743+ else throw("invalid payment")
744+ let amAmountRaw = $t02899929175._1
745+ let prAmountRaw = $t02899929175._2
746+ let $t02917929433 = if (withTakeFee)
747+ then $Tuple3(takeFee(amAmountRaw, inFee)._1, takeFee(prAmountRaw, inFee)._1, takeFee(pmtAmtRaw, inFee)._2)
748+ else $Tuple3(amAmountRaw, prAmountRaw, 0)
749+ let amAmount = $t02917929433._1
750+ let prAmount = $t02917929433._2
751+ let feeAmount = $t02917929433._3
752+ let amBalanceNew = (amBalanceOld + amAmount)
753+ let prBalanceNew = (prBalanceOld + prAmount)
754+ let D0 = getD([t1(amBalanceOld, cfgAmountAssetDecimals), t1(prBalanceOld, cfgPriceAssetDecimals)])
755+ let D1 = getD([t1(amBalanceNew, cfgAmountAssetDecimals), t1(prBalanceNew, cfgPriceAssetDecimals)])
756+ let checkD = if ((D1 > D0))
757+ then true
758+ else throw()
759+ if ((checkD == checkD))
760+ then {
761+ let lpAmount = fraction(lpAssetEmission, (D1 - D0), D0, FLOOR)
762+ let curPrice = f1(cpbi(t1(prBalanceNew, priceDcm), t1(amBalanceNew, amtDcm)), scale8)
763+ let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId), dataPutActionInfo(amAmountRaw, prAmountRaw, toInt(lpAmount), curPrice, 0, 0, height, lastBlock.timestamp, 0, 0))]
764+ let poolProportion = fraction(prBalanceOld, scale8, amBalanceOld)
765+ let amountAssetPart = fraction(pmtAmtRaw, scale8, (poolProportion + scale8))
766+ let priceAssetPart = (pmtAmtRaw - amountAssetPart)
767+ let lpAmtBoth = fraction(lpAssetEmission, toBigInt(priceAssetPart), toBigInt(prBalanceOld))
768+ let bonus = toInt(fraction((lpAmount - lpAmtBoth), scale8BigInt, lpAmtBoth))
769+ $Tuple4(toInt(lpAmount), commonState, feeAmount, bonus)
770+ }
771+ else throw("Strict value is not equal to itself.")
805772 }
806773 else throw("Strict value is not equal to itself.")
807774 }
808775
809776
810-func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
811- let isEval = (txId == unit)
812- let cfg = getPoolConfig()
813- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
814- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
815- let checks = [if ((paymentAssetId == cfgLpAssetId))
816- then true
817- else throwErr("invalid lp asset")]
818- if ((checks == checks))
777+func getOneTknV2Internal (outAssetId,minOutAmount,payments,caller,originCaller,transactionId) = {
778+ let lpId = toBase58String(value(cfgLpAssetId))
779+ let amId = toBase58String(value(cfgAmountAssetId))
780+ let prId = toBase58String(value(cfgPriceAssetId))
781+ let amDecimals = cfgAmountAssetDecimals
782+ let prDecimals = cfgPriceAssetDecimals
783+ let poolStatus = cfgPoolStatus
784+ let userAddress = if ((caller == restContract))
785+ then originCaller
786+ else caller
787+ let pmt = value(payments[0])
788+ let pmtAssetId = value(pmt.assetId)
789+ let pmtAmt = pmt.amount
790+ let currentDLp = calcCurrentDLp(big0, big0, big0)
791+ if ((currentDLp == currentDLp))
819792 then {
820- let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
821- then true
822- else if ((outAssetId == cfgPriceAssetId))
823- then false
824- else throwErr("invalid asset")
825- let balanceBigInt = if (outInAmountAsset)
826- then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
827- else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
828- let outInAmountAssetDecimals = if (outInAmountAsset)
829- then amtAssetDcm
830- else priceAssetDcm
831- let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
832- let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
833- let outBalance = if (outInAmountAsset)
834- then amBalanceOld
835- else prBalanceOld
836- let outBalanceBigInt = toBigInt(outBalance)
837- let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
838- let redeemedBigInt = toBigInt(paymentAmount)
839- let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
840- let $t03742437480 = takeFee(amountRaw, outFee)
841- let totalAmount = $t03742437480._1
842- let feeAmount = $t03742437480._2
843- let $t03748437710 = if (outInAmountAsset)
844- then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
845- else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
846- let outAmAmount = $t03748437710._1
847- let outPrAmount = $t03748437710._2
848- let amBalanceNew = $t03748437710._3
849- let prBalanceNew = $t03748437710._4
850- let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
851- let priceNew = fromX18(priceNewX18, scale8)
852- let commonState = if (isEval)
853- then nil
854- else [StringEntry(gau(toString(value(userAddress)), toBase58String(value(txId))), dataGetActionInfo(outAmAmount, outPrAmount, paymentAmount, priceNew, height, lastBlock.timestamp)), IntegerEntry(pl(), priceNew), IntegerEntry(ph(height, lastBlock.timestamp), priceNew)]
855- let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
856- let priceOld = fromX18(priceOldX18, scale8)
857- let loss = {
858- let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
859- fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
860- }
861- $Tuple5(totalAmount, commonState, feeAmount, loss, outInAmountAsset)
793+ let txId58 = toBase58String(transactionId)
794+ if ((lpId != toBase58String(pmtAssetId)))
795+ then throw("Wrong LP")
796+ else {
797+ let amBalance = getAccBalance(amId)
798+ let prBalance = getAccBalance(prId)
799+ let $t03154531656 = {
800+ let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, pmtAmt], nil)
801+ if ($isInstanceOf(@, "(Int, Int)"))
802+ then @
803+ else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
804+ }
805+ if (($t03154531656 == $t03154531656))
806+ then {
807+ let feeAmount = $t03154531656._2
808+ let totalGet = $t03154531656._1
809+ let totalAmount = if (if ((minOutAmount > 0))
810+ then (minOutAmount > totalGet)
811+ else false)
812+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
813+ else totalGet
814+ let $t03184632153 = if ((outAssetId == amId))
815+ then $Tuple4(totalAmount, 0, ((amBalance - totalAmount) - feeAmount), prBalance)
816+ else if ((outAssetId == prId))
817+ then $Tuple4(0, totalAmount, amBalance, ((prBalance - totalAmount) - feeAmount))
818+ else throw("invalid out asset id")
819+ let outAm = $t03184632153._1
820+ let outPr = $t03184632153._2
821+ let amBalanceNew = $t03184632153._3
822+ let prBalanceNew = $t03184632153._4
823+ let curPrX18 = cpbi(t1(prBalanceNew, prDecimals), t1(amBalanceNew, amDecimals))
824+ let curPr = f1(curPrX18, scale8)
825+ let outAssetIdOrWaves = if ((outAssetId == "WAVES"))
826+ then unit
827+ else fromBase58String(outAssetId)
828+ let sendFeeToMatcher = if ((feeAmount > 0))
829+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetIdOrWaves)]
830+ else nil
831+ let state = ([ScriptTransfer(userAddress, totalAmount, outAssetIdOrWaves), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, pmtAmt, curPr, height, lastBlock.timestamp)), IntegerEntry(pl(), curPr), IntegerEntry(ph(height, lastBlock.timestamp), curPr)] ++ sendFeeToMatcher)
832+ if ((state == state))
833+ then {
834+ let burn = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
835+ if ((burn == burn))
836+ then {
837+ let $t03293833288 = {
838+ let feeAmountForCalc = if ((this == feeCollectorAddress))
839+ then 0
840+ else feeAmount
841+ let outInAmountAsset = if ((parseAssetId(outAssetId) == cfgAmountAssetId))
842+ then true
843+ else false
844+ if (outInAmountAsset)
845+ then $Tuple2(-((totalGet + feeAmountForCalc)), 0)
846+ else $Tuple2(0, -((totalGet + feeAmountForCalc)))
847+ }
848+ let amountAssetBalanceDelta = $t03293833288._1
849+ let priceAssetBalanceDelta = $t03293833288._2
850+ let $t03329133399 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
851+ let refreshDLpActions = $t03329133399._1
852+ let updatedDLp = $t03329133399._2
853+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
854+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
855+ then $Tuple2((state ++ refreshDLpActions), totalAmount)
856+ else throw("Strict value is not equal to itself.")
857+ }
858+ else throw("Strict value is not equal to itself.")
859+ }
860+ else throw("Strict value is not equal to itself.")
861+ }
862+ else throw("Strict value is not equal to itself.")
863+ }
862864 }
863865 else throw("Strict value is not equal to itself.")
864866 }
865867
866868
867869 func managerPublicKeyOrUnit () = {
868870 let managerVaultAddress = getManagerVaultAddressOrThis()
869871 match getString(managerVaultAddress, keyManagerPublicKey()) {
870872 case s: String =>
871873 fromBase58String(s)
872874 case _: Unit =>
873875 unit
874876 case _ =>
875877 throw("Match error")
876878 }
877879 }
878880
879881
882+let pd = throw("Permission denied")
883+
880884 func isManager (i) = match managerPublicKeyOrUnit() {
881885 case pk: ByteVector =>
882886 (i.callerPublicKey == pk)
883887 case _: Unit =>
884888 (i.caller == this)
885889 case _ =>
886890 throw("Match error")
887891 }
888892
889893
890-func mustManager (i) = {
891- let pd = throw("Permission denied")
892- match managerPublicKeyOrUnit() {
893- case pk: ByteVector =>
894- if ((i.callerPublicKey == pk))
895- then true
896- else pd
897- case _: Unit =>
898- if ((i.caller == this))
899- then true
900- else pd
901- case _ =>
902- throw("Match error")
903- }
894+func mustManager (i) = match managerPublicKeyOrUnit() {
895+ case pk: ByteVector =>
896+ if ((i.callerPublicKey == pk))
897+ then true
898+ else pd
899+ case _: Unit =>
900+ if ((i.caller == this))
901+ then true
902+ else pd
903+ case _ =>
904+ throw("Match error")
905+}
906+
907+
908+func getY (isReverse,D,poolAmountInBalance) = {
909+ let poolConfig = gpc()
910+ let amId = poolConfig[idxAmAsId]
911+ let prId = poolConfig[idxPrAsId]
912+ let n = big2
913+ let aPrecision = parseBigIntValue(Amult)
914+ let a = (parseBigIntValue(A) * aPrecision)
915+ let xp = if ((isReverse == false))
916+ then [(toBigInt(getAccBalance(amId)) + poolAmountInBalance), toBigInt(getAccBalance(prId))]
917+ else [(toBigInt(getAccBalance(prId)) + poolAmountInBalance), toBigInt(getAccBalance(amId))]
918+ let x = xp[0]
919+ let s = x
920+ let ann = (a * n)
921+ let c = (((((D * D) / (x * n)) * D) * aPrecision) / (ann * n))
922+ let b = ((s + ((D * aPrecision) / ann)) - D)
923+ func calc (acc,cur) = {
924+ let $t03488634906 = acc
925+ let y = $t03488634906._1
926+ let found = $t03488634906._2
927+ if ((found != unit))
928+ then acc
929+ else {
930+ let yNext = (((y * y) + c) / ((big2 * y) + b))
931+ let yDiff = absBigInt((yNext - value(y)))
932+ if ((big1 >= yDiff))
933+ then $Tuple2(yNext, cur)
934+ else $Tuple2(yNext, unit)
935+ }
936+ }
937+
938+ let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
939+ let $t03523735284 = {
940+ let $l = arr
941+ let $s = size($l)
942+ let $acc0 = $Tuple2(D, unit)
943+ func $f0_1 ($a,$i) = if (($i >= $s))
944+ then $a
945+ else calc($a, $l[$i])
946+
947+ func $f0_2 ($a,$i) = if (($i >= $s))
948+ then $a
949+ else throw("List size exceeds 15")
950+
951+ $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15)
952+ }
953+ let y = $t03523735284._1
954+ let found = $t03523735284._2
955+ if ((found != unit))
956+ then y
957+ else throw(("Y calculation error, Y = " + toString(y)))
904958 }
905959
906960
907-@Callable(i)
908-func rebalance () = (rebalanceAsset(getStringOrFail(this, aa())) ++ rebalanceAsset(getStringOrFail(this, pa())))
909-
961+func skipOrderValidation () = valueOrElse(getBoolean(fca, keySkipOrderValidation(toString(this))), false)
910962
911963
912964 @Callable(i)
913965 func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse,feePoolAmount) = {
914- let $t03956939874 = if ((isReverse == false))
966+ let $t03563636060 = if ((isReverse == false))
915967 then {
916- let assetOut = getStringOrFail(this, pa())
917- let assetIn = getStringOrFail(this, aa())
918- $Tuple2(assetOut, assetIn)
968+ let assetOut = strf(this, pa())
969+ let poolAmountInBalance = (toBigInt(getAccBalance(strf(this, aa()))) + toBigInt(cleanAmountIn))
970+ $Tuple2(assetOut, poolAmountInBalance)
919971 }
920972 else {
921- let assetOut = getStringOrFail(this, aa())
922- let assetIn = getStringOrFail(this, pa())
923- $Tuple2(assetOut, assetIn)
973+ let assetOut = strf(this, aa())
974+ let poolAmountInBalance = (toBigInt(getAccBalance(strf(this, pa()))) + toBigInt(cleanAmountIn))
975+ $Tuple2(assetOut, poolAmountInBalance)
924976 }
925- let assetOut = $t03956939874._1
926- let assetIn = $t03956939874._2
927- let poolAssetInBalance = getAccBalance(assetIn)
928- let poolAssetOutBalance = getAccBalance(assetOut)
929- let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
930- let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
931- let newK = (((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
932- let checkK = if ((newK >= oldK))
977+ let assetOut = $t03563636060._1
978+ let poolAmountInBalance = $t03563636060._2
979+ let poolConfig = gpc()
980+ let amId = poolConfig[idxAmAsId]
981+ let prId = poolConfig[idxPrAsId]
982+ let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
983+ let D = getD(xp)
984+ let y = getY(isReverse, D, toBigInt(cleanAmountIn))
985+ let dy = ((toBigInt(getAccBalance(assetOut)) - y) - toBigInt(1))
986+ let totalGetRaw = max([0, toInt(dy)])
987+ let newXp = if ((isReverse == false))
988+ then [((toBigInt(getAccBalance(amId)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)), (toBigInt(getAccBalance(prId)) - dy)]
989+ else [(toBigInt(getAccBalance(amId)) - dy), ((toBigInt(getAccBalance(prId)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount))]
990+ let newD = getD(newXp)
991+ let checkD = if ((newD >= D))
933992 then true
934- else throw("new K is fewer error")
935- if ((checkK == checkK))
936- then $Tuple2(nil, amountOut)
993+ else throw(makeString(["new D is fewer error", toString(D), toString(newD)], "__"))
994+ if ((checkD == checkD))
995+ then $Tuple2(nil, totalGetRaw)
937996 else throw("Strict value is not equal to itself.")
938997 }
939998
940999
9411000
9421001 @Callable(i)
9431002 func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo,feePoolAmount) = {
9441003 let swapContact = {
945- let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil)
1004+ let @ = invoke(fca, "getSwapContractREADONLY", nil, nil)
9461005 if ($isInstanceOf(@, "String"))
9471006 then @
9481007 else throw(($getType(@) + " couldn't be cast to String"))
9491008 }
9501009 let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
9511010 then true
9521011 else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
9531012 then true
9541013 else throwErr("Permission denied")]
9551014 if ((checks == checks))
9561015 then {
9571016 let pmt = value(i.payments[0])
9581017 let assetIn = assetIdToString(pmt.assetId)
959- let assetOut = if ((isReverse == false))
960- then getStringOrFail(this, pa())
961- else getStringOrFail(this, aa())
962- let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
963- let poolAssetOutBalance = getAccBalance(assetOut)
964- let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
965- let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
966- let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
967- let checkK = if ((newK >= oldK))
1018+ let $t03749637890 = if ((isReverse == false))
1019+ then {
1020+ let assetOut = strf(this, pa())
1021+ let poolAmountInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
1022+ $Tuple2(assetOut, poolAmountInBalance)
1023+ }
1024+ else {
1025+ let assetOut = strf(this, aa())
1026+ let poolAmountInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
1027+ $Tuple2(assetOut, poolAmountInBalance)
1028+ }
1029+ let assetOut = $t03749637890._1
1030+ let poolAmountInBalance = $t03749637890._2
1031+ let poolConfig = gpc()
1032+ let amId = poolConfig[idxAmAsId]
1033+ let prId = poolConfig[idxPrAsId]
1034+ let xp = if ((isReverse == false))
1035+ then [(toBigInt(getAccBalance(amId)) - toBigInt(value(i.payments[0]).amount)), toBigInt(getAccBalance(prId))]
1036+ else [toBigInt(getAccBalance(amId)), (toBigInt(getAccBalance(prId)) - toBigInt(value(i.payments[0]).amount))]
1037+ let D = getD(xp)
1038+ let y = getY(isReverse, D, toBigInt(0))
1039+ let dy = ((toBigInt(getAccBalance(assetOut)) - y) - toBigInt(1))
1040+ let totalGetRaw = max([0, toInt(dy)])
1041+ let checkMin = if ((totalGetRaw >= amountOutMin))
9681042 then true
969- else throw("new K is fewer error")
970- if ((checkK == checkK))
1043+ else throw("Exchange result is fewer coins than expected")
1044+ if ((checkMin == checkMin))
9711045 then {
972- let checkMin = if ((amountOut >= amountOutMin))
1046+ let newXp = if ((isReverse == false))
1047+ then [(toBigInt(getAccBalance(amId)) + toBigInt(feePoolAmount)), (toBigInt(getAccBalance(prId)) - dy)]
1048+ else [(toBigInt(getAccBalance(amId)) - dy), (toBigInt(getAccBalance(prId)) + toBigInt(feePoolAmount))]
1049+ let newD = getD(newXp)
1050+ let checkD = if ((newD >= D))
9731051 then true
974- else throw("Exchange result is fewer coins than expected")
975- if ((checkMin == checkMin))
976- then {
977- let rebalanceState = rebalanceAsset(assetIn)
978- if ((rebalanceState == rebalanceState))
979- then {
980- let withdrawState = withdrawAndRebalanceAsset(assetOut, amountOut)
981- if ((withdrawState == withdrawState))
982- then $Tuple2(((withdrawState ++ rebalanceState) ++ [ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))]), amountOut)
983- else throw("Strict value is not equal to itself.")
984- }
985- else throw("Strict value is not equal to itself.")
986- }
1052+ else throw("new D is fewer error")
1053+ if ((checkD == checkD))
1054+ then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), totalGetRaw, parseAssetId(assetOut))], totalGetRaw)
9871055 else throw("Strict value is not equal to itself.")
9881056 }
9891057 else throw("Strict value is not equal to itself.")
9901058 }
9911059 else throw("Strict value is not equal to itself.")
9921060 }
9931061
9941062
9951063
9961064 @Callable(i)
997-func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
998- then throw("Invalid slippageTolerance passed")
999- else {
1000- let estPut = commonPut(i, slippageTolerance, true)
1001- let emitLpAmt = estPut._2
1002- let lpAssetId = estPut._7
1003- let state = estPut._9
1004- let amDiff = estPut._10
1005- let prDiff = estPut._11
1006- let amId = estPut._12
1007- let prId = estPut._13
1008- let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1009- let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1010- let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
1011- if ((currentKLp == currentKLp))
1012- then {
1013- let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
1014- if ((emitInv == emitInv))
1065+func constructor (fc) = {
1066+ let c = mustManager(i)
1067+ if ((c == c))
1068+ then [StringEntry(fc(), fc)]
1069+ else throw("Strict value is not equal to itself.")
1070+ }
1071+
1072+
1073+
1074+@Callable(i)
1075+func put (slip,autoStake) = {
1076+ let factCfg = gfc()
1077+ let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Wr st addr")
1078+ let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Wr sl addr")
1079+ if ((0 > slip))
1080+ then throw("Wrong slippage")
1081+ else if ((size(i.payments) != 2))
1082+ then throw("2 pmnts expd")
1083+ else {
1084+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1085+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1086+ let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amAssetPmt)
1087+ if ((amountAssetBalance == amountAssetBalance))
10151088 then {
1016- let emitInvLegacy = match emitInv {
1017- case legacyFactoryContract: Address =>
1018- invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
1019- case _ =>
1020- unit
1021- }
1022- if ((emitInvLegacy == emitInvLegacy))
1089+ let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - prAssetPmt)
1090+ if ((priceAssetBalance == priceAssetBalance))
10231091 then {
1024- let slippageAInv = if ((amDiff > 0))
1025- then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
1026- else nil
1027- if ((slippageAInv == slippageAInv))
1092+ let lpAssetEmission = toBigInt(value(assetInfo(cfgLpAssetId)).quantity)
1093+ if ((lpAssetEmission == lpAssetEmission))
10281094 then {
1029- let slippagePInv = if ((prDiff > 0))
1030- then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
1031- else nil
1032- if ((slippagePInv == slippagePInv))
1095+ let currentDLp = calcCurrentDLp(amAssetPmt, prAssetPmt, toBigInt(0))
1096+ if ((currentDLp == currentDLp))
10331097 then {
1034- let lpTransfer = if (shouldAutoStake)
1098+ let e = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], slip, true, false, true, 0, "")
1099+ let emitLpAmt = e._2
1100+ let lpAssetId = e._7
1101+ let state = e._9
1102+ let amDiff = e._10
1103+ let prDiff = e._11
1104+ let amId = e._12
1105+ let prId = e._13
1106+ let r = invoke(fca, "emit", [emitLpAmt], nil)
1107+ if ((r == r))
10351108 then {
1036- let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
1037- if ((slpStakeInv == slpStakeInv))
1038- then nil
1039- else throw("Strict value is not equal to itself.")
1109+ let el = match r {
1110+ case legacy: Address =>
1111+ invoke(legacy, "emit", [emitLpAmt], nil)
1112+ case _ =>
1113+ unit
10401114 }
1041- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1042- let $t04436144823 = refreshKLpInternal(0, 0, 0)
1043- if (($t04436144823 == $t04436144823))
1044- then {
1045- let updatedKLp = $t04436144823._2
1046- let refreshKLpActions = $t04436144823._1
1047- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1048- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1115+ if ((el == el))
10491116 then {
1050- let reb = invoke(this, "rebalance", nil, nil)
1051- if ((reb == reb))
1052- then ((state ++ lpTransfer) ++ refreshKLpActions)
1117+ let sa = if ((amDiff > 0))
1118+ then invoke(slipCntr, "put", nil, [AttachedPayment(amId, amDiff)])
1119+ else nil
1120+ if ((sa == sa))
1121+ then {
1122+ let sp = if ((prDiff > 0))
1123+ then invoke(slipCntr, "put", nil, [AttachedPayment(prId, prDiff)])
1124+ else nil
1125+ if ((sp == sp))
1126+ then {
1127+ let lpTrnsfr = if (autoStake)
1128+ then {
1129+ let ss = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
1130+ if ((ss == ss))
1131+ then nil
1132+ else throw("Strict value is not equal to itself.")
1133+ }
1134+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
1135+ let $t04203442176 = refreshDLpInternal(0, 0, 0)
1136+ let refreshDLpActions = $t04203442176._1
1137+ let updatedDLp = $t04203442176._2
1138+ let check = if ((updatedDLp >= currentDLp))
1139+ then true
1140+ else throwErr(makeString(["updated DLp lower than current DLp", toString(amountAssetBalance), toString(priceAssetBalance), toString(lpAssetEmission), toString(currentDLp), toString(updatedDLp), toString(amDiff), toString(prDiff)], " "))
1141+ if ((check == check))
1142+ then {
1143+ let lpAssetEmissionAfter = value(assetInfo(cfgLpAssetId)).quantity
1144+ if ((lpAssetEmissionAfter == lpAssetEmissionAfter))
1145+ then ((state ++ lpTrnsfr) ++ refreshDLpActions)
1146+ else throw("Strict value is not equal to itself.")
1147+ }
1148+ else throw("Strict value is not equal to itself.")
1149+ }
1150+ else throw("Strict value is not equal to itself.")
1151+ }
10531152 else throw("Strict value is not equal to itself.")
10541153 }
10551154 else throw("Strict value is not equal to itself.")
10561155 }
10571156 else throw("Strict value is not equal to itself.")
10581157 }
10591158 else throw("Strict value is not equal to itself.")
10601159 }
10611160 else throw("Strict value is not equal to itself.")
10621161 }
10631162 else throw("Strict value is not equal to itself.")
10641163 }
10651164 else throw("Strict value is not equal to itself.")
10661165 }
1067- else throw("Strict value is not equal to itself.")
1068- }
1166+ }
10691167
10701168
10711169
10721170 @Callable(i)
1073-func putForFree (maxSlippage) = if ((0 > maxSlippage))
1074- then throw("Invalid value passed")
1075- else {
1076- let estPut = commonPut(i, maxSlippage, false)
1077- let state = estPut._9
1078- let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1079- let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1080- let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
1081- if ((currentKLp == currentKLp))
1082- then {
1083- let $t04543545500 = refreshKLpInternal(0, 0, 0)
1084- let refreshKLpActions = $t04543545500._1
1085- let updatedKLp = $t04543545500._2
1086- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1087- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1088- then (state ++ refreshKLpActions)
1089- else throw("Strict value is not equal to itself.")
1090- }
1091- else throw("Strict value is not equal to itself.")
1092- }
1093-
1094-
1095-
1096-@Callable(i)
1097-func putOneTkn (minOutAmount,autoStake) = {
1171+func putOneTknV2 (minOutAmount,autoStake) = {
10981172 let isPoolOneTokenOperationsDisabled = {
1099- let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1173+ let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
11001174 if ($isInstanceOf(@, "Boolean"))
11011175 then @
11021176 else throw(($getType(@) + " couldn't be cast to Boolean"))
11031177 }
1104- let isPutDisabled = if (if (if (isGlobalShutdown())
1178+ let isPutDisabled = if (if (if (igs())
11051179 then true
1106- else (cfgPoolStatus == PoolPutDisabled))
1180+ else (cfgPoolStatus == PoolPutDis))
11071181 then true
11081182 else (cfgPoolStatus == PoolShutdown))
11091183 then true
11101184 else isPoolOneTokenOperationsDisabled
11111185 let checks = [if (if (!(isPutDisabled))
11121186 then true
11131187 else isManager(i))
11141188 then true
11151189 else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
11161190 then true
11171191 else throwErr("exactly 1 payment are expected")]
11181192 if ((checks == checks))
11191193 then {
1120- let payment = i.payments[0]
1121- let paymentAssetId = payment.assetId
1122- let paymentAmountRaw = payment.amount
1123- let currentKLp = if ((paymentAssetId == cfgAmountAssetId))
1124- then calcCurrentKLp(toBigInt(paymentAmountRaw), toBigInt(0), toBigInt(0))
1125- else if ((paymentAssetId == cfgPriceAssetId))
1126- then calcCurrentKLp(toBigInt(0), toBigInt(paymentAmountRaw), toBigInt(0))
1127- else throwErr("payment asset is not supported")
1128- if ((currentKLp == currentKLp))
1194+ let amId = toBase58String(value(cfgAmountAssetId))
1195+ let prId = toBase58String(value(cfgPriceAssetId))
1196+ let lpId = cfgLpAssetId
1197+ let amDecimals = cfgAmountAssetDecimals
1198+ let prDecimals = cfgPriceAssetDecimals
1199+ let userAddress = if ((i.caller == this))
1200+ then i.originCaller
1201+ else i.caller
1202+ let pmt = value(i.payments[0])
1203+ let pmtAssetId = toBase58String(value(pmt.assetId))
1204+ let pmtAmt = pmt.amount
1205+ let currentDLp = if ((pmt.assetId == cfgAmountAssetId))
1206+ then calcCurrentDLp(toBigInt(pmtAmt), toBigInt(0), toBigInt(0))
1207+ else calcCurrentDLp(toBigInt(0), toBigInt(pmtAmt), toBigInt(0))
1208+ if ((currentDLp == currentDLp))
11291209 then {
1130- let userAddress = i.caller
1131- let txId = i.transactionId
1132- let $t04668846840 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
1133- if (($t04668846840 == $t04668846840))
1210+ let $t04381743975 = calcPutOneTkn(pmtAmt, pmtAssetId, toString(userAddress), toBase58String(i.transactionId), true)
1211+ if (($t04381743975 == $t04381743975))
11341212 then {
1135- let paymentInAmountAsset = $t04668846840._5
1136- let bonus = $t04668846840._4
1137- let feeAmount = $t04668846840._3
1138- let commonState = $t04668846840._2
1139- let emitAmountEstimated = $t04668846840._1
1140- let emitAmount = if (if ((minOutAmount > 0))
1141- then (minOutAmount > emitAmountEstimated)
1213+ let feeAmount = $t04381743975._3
1214+ let state = $t04381743975._2
1215+ let estimLP = $t04381743975._1
1216+ let emitLpAmt = if (if ((minOutAmount > 0))
1217+ then (minOutAmount > estimLP)
11421218 else false)
11431219 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1144- else emitAmountEstimated
1145- let emitInv = emit(emitAmount)
1146- if ((emitInv == emitInv))
1220+ else estimLP
1221+ let e = invoke(fca, "emit", [emitLpAmt], nil)
1222+ if ((e == e))
11471223 then {
1148- let lpTransfer = if (autoStake)
1224+ let el = match e {
1225+ case legacy: Address =>
1226+ invoke(legacy, "emit", [emitLpAmt], nil)
1227+ case _ =>
1228+ unit
1229+ }
1230+ if ((el == el))
11491231 then {
1150- let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
1151- if ((stakeInv == stakeInv))
1152- then nil
1153- else throw("Strict value is not equal to itself.")
1154- }
1155- else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
1156- let sendFee = if ((feeAmount > 0))
1157- then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
1158- else nil
1159- let $t04742647623 = if ((this == feeCollectorAddress))
1160- then $Tuple2(0, 0)
1161- else if (paymentInAmountAsset)
1162- then $Tuple2(-(feeAmount), 0)
1163- else $Tuple2(0, -(feeAmount))
1164- let amountAssetBalanceDelta = $t04742647623._1
1165- let priceAssetBalanceDelta = $t04742647623._2
1166- let $t04762647734 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1167- let refreshKLpActions = $t04762647734._1
1168- let updatedKLp = $t04762647734._2
1169- let kLp = value(getString(keyKLp))
1170- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1171- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1172- then {
1173- let reb = invoke(this, "rebalance", nil, nil)
1174- if ((reb == reb))
1175- then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
1232+ let lpTrnsfr = if (autoStake)
1233+ then {
1234+ let ss = invoke(stakingContract, "stakeFor", [toString(i.caller)], [AttachedPayment(lpId, emitLpAmt)])
1235+ if ((ss == ss))
1236+ then nil
1237+ else throw("Strict value is not equal to itself.")
1238+ }
1239+ else [ScriptTransfer(i.caller, emitLpAmt, lpId)]
1240+ let sendFeeToMatcher = if ((feeAmount > 0))
1241+ then [ScriptTransfer(feeCollectorAddress, feeAmount, fromBase58String(pmtAssetId))]
1242+ else nil
1243+ let $t04486045209 = if ((this == feeCollectorAddress))
1244+ then $Tuple2(0, 0)
1245+ else {
1246+ let paymentInAmountAsset = if ((pmt.assetId == cfgAmountAssetId))
1247+ then true
1248+ else false
1249+ if (paymentInAmountAsset)
1250+ then $Tuple2(-(feeAmount), 0)
1251+ else $Tuple2(0, -(feeAmount))
1252+ }
1253+ let amountAssetBalanceDelta = $t04486045209._1
1254+ let priceAssetBalanceDelta = $t04486045209._2
1255+ let $t04521245320 = refreshDLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1256+ let refreshDLpActions = $t04521245320._1
1257+ let updatedDLp = $t04521245320._2
1258+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1259+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1260+ then $Tuple2((((state ++ lpTrnsfr) ++ sendFeeToMatcher) ++ refreshDLpActions), emitLpAmt)
11761261 else throw("Strict value is not equal to itself.")
11771262 }
11781263 else throw("Strict value is not equal to itself.")
11791264 }
11801265 else throw("Strict value is not equal to itself.")
11811266 }
11821267 else throw("Strict value is not equal to itself.")
11831268 }
11841269 else throw("Strict value is not equal to itself.")
11851270 }
11861271 else throw("Strict value is not equal to itself.")
11871272 }
11881273
11891274
11901275
11911276 @Callable(i)
1192-func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
1193- let $t04808948246 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
1194- let emitAmountEstimated = $t04808948246._1
1195- let commonState = $t04808948246._2
1196- let feeAmount = $t04808948246._3
1197- let bonus = $t04808948246._4
1198- let paymentInAmountAsset = $t04808948246._5
1199- $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
1277+func putForFree (maxSlpg) = if ((0 > maxSlpg))
1278+ then throw("Wrong slpg")
1279+ else if ((size(i.payments) != 2))
1280+ then throw("2 pmnts expd")
1281+ else {
1282+ let estPut = cp(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], maxSlpg, false, false, true, 0, "")
1283+ let state = estPut._9
1284+ let amAssetPmt = toBigInt(value(i.payments[0]).amount)
1285+ let prAssetPmt = toBigInt(value(i.payments[1]).amount)
1286+ let currentDLp = calcCurrentDLp(amAssetPmt, prAssetPmt, toBigInt(0))
1287+ if ((currentDLp == currentDLp))
1288+ then {
1289+ let $t04635046415 = refreshDLpInternal(0, 0, 0)
1290+ let refreshDLpActions = $t04635046415._1
1291+ let updatedDLp = $t04635046415._2
1292+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1293+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1294+ then (state ++ refreshDLpActions)
1295+ else throw("Strict value is not equal to itself.")
1296+ }
1297+ else throw("Strict value is not equal to itself.")
1298+ }
1299+
1300+
1301+
1302+@Callable(i)
1303+func get () = {
1304+ let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1305+ if ((currentDLp == currentDLp))
1306+ then {
1307+ let r = cg(i)
1308+ let outAmtAmt = r._1
1309+ let outPrAmt = r._2
1310+ let pmtAmt = r._3
1311+ let pmtAssetId = r._4
1312+ let state = r._5
1313+ let b = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1314+ if ((b == b))
1315+ then {
1316+ let $t04758847670 = refreshDLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1317+ let refreshDLpActions = $t04758847670._1
1318+ let updatedDLp = $t04758847670._2
1319+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1320+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1321+ then (state ++ refreshDLpActions)
1322+ else throw("Strict value is not equal to itself.")
1323+ }
1324+ else throw("Strict value is not equal to itself.")
1325+ }
1326+ else throw("Strict value is not equal to itself.")
12001327 }
12011328
12021329
12031330
12041331 @Callable(i)
1205-func getOneTkn (outAssetIdStr,minOutAmount) = {
1332+func getOneTknV2 (outAssetId,minOutAmount) = {
12061333 let isPoolOneTokenOperationsDisabled = {
1207- let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1334+ let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
12081335 if ($isInstanceOf(@, "Boolean"))
12091336 then @
12101337 else throw(($getType(@) + " couldn't be cast to Boolean"))
12111338 }
1212- let isGetDisabled = if (if (isGlobalShutdown())
1339+ let isGetDisabled = if (if (igs())
12131340 then true
12141341 else (cfgPoolStatus == PoolShutdown))
12151342 then true
12161343 else isPoolOneTokenOperationsDisabled
12171344 let checks = [if (if (!(isGetDisabled))
12181345 then true
12191346 else isManager(i))
12201347 then true
12211348 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
12221349 then true
12231350 else throwErr("exactly 1 payment are expected")]
12241351 if ((checks == checks))
12251352 then {
1226- let outAssetId = parseAssetId(outAssetIdStr)
1227- let payment = i.payments[0]
1228- let paymentAssetId = payment.assetId
1229- let paymentAmount = payment.amount
1230- let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1231- if ((currentKLp == currentKLp))
1232- then {
1233- let userAddress = i.caller
1234- let txId = i.transactionId
1235- let $t04913149284 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1236- if (($t04913149284 == $t04913149284))
1237- then {
1238- let outInAmountAsset = $t04913149284._5
1239- let bonus = $t04913149284._4
1240- let feeAmount = $t04913149284._3
1241- let commonState = $t04913149284._2
1242- let amountEstimated = $t04913149284._1
1243- let amount = if (if ((minOutAmount > 0))
1244- then (minOutAmount > amountEstimated)
1245- else false)
1246- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1247- else amountEstimated
1248- let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
1249- if ((burnInv == burnInv))
1250- then {
1251- let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
1252- let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
1253- let sendFee = if ((feeAmount > 0))
1254- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1255- else nil
1256- let $t04994850195 = {
1257- let feeAmountForCalc = if ((this == feeCollectorAddress))
1258- then 0
1259- else feeAmount
1260- if (outInAmountAsset)
1261- then $Tuple2(-((amount + feeAmountForCalc)), 0)
1262- else $Tuple2(0, -((amount + feeAmountForCalc)))
1263- }
1264- let amountAssetBalanceDelta = $t04994850195._1
1265- let priceAssetBalanceDelta = $t04994850195._2
1266- let $t05019850306 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1267- let refreshKLpActions = $t05019850306._1
1268- let updatedKLp = $t05019850306._2
1269- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1270- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1271- then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1272- else throw("Strict value is not equal to itself.")
1273- }
1274- else throw("Strict value is not equal to itself.")
1275- }
1276- else throw("Strict value is not equal to itself.")
1277- }
1278- else throw("Strict value is not equal to itself.")
1353+ let $t04828848443 = getOneTknV2Internal(outAssetId, minOutAmount, i.payments, i.caller, i.originCaller, i.transactionId)
1354+ let state = $t04828848443._1
1355+ let totalAmount = $t04828848443._2
1356+ $Tuple2(state, totalAmount)
12791357 }
12801358 else throw("Strict value is not equal to itself.")
12811359 }
12821360
12831361
12841362
12851363 @Callable(i)
1286-func getOneTknREADONLY (outAssetId,paymentAmount) = {
1287- let $t05058450740 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1288- let amountEstimated = $t05058450740._1
1289- let commonState = $t05058450740._2
1290- let feeAmount = $t05058450740._3
1291- let bonus = $t05058450740._4
1292- let outInAmountAsset = $t05058450740._5
1293- $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
1294- }
1295-
1296-
1297-
1298-@Callable(i)
1299-func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
1300- let isPoolOneTokenOperationsDisabled = {
1301- let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1302- if ($isInstanceOf(@, "Boolean"))
1303- then @
1304- else throw(($getType(@) + " couldn't be cast to Boolean"))
1305- }
1306- let isGetDisabled = if (if (isGlobalShutdown())
1307- then true
1308- else (cfgPoolStatus == PoolShutdown))
1309- then true
1310- else isPoolOneTokenOperationsDisabled
1311- let checks = [if (if (!(isGetDisabled))
1312- then true
1313- else isManager(i))
1314- then true
1315- else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
1316- then true
1317- else throwErr("no payments are expected")]
1318- if ((checks == checks))
1364+func refreshDLp () = {
1365+ let lastRefreshedBlockHeight = valueOrElse(getInteger(keyDLpRefreshedHeight), 0)
1366+ let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= dLpRefreshDelay))
1367+ then unit
1368+ else throwErr(makeString([toString(dLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1369+ if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
13191370 then {
1320- let outAssetId = parseAssetId(outAssetIdStr)
1321- let userAddress = i.caller
1322- let txId = i.transactionId
1323- let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1324- if ((currentKLp == currentKLp))
1325- then {
1326- let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
1327- if ((unstakeInv == unstakeInv))
1328- then {
1329- let $t05164551796 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1330- if (($t05164551796 == $t05164551796))
1331- then {
1332- let outInAmountAsset = $t05164551796._5
1333- let bonus = $t05164551796._4
1334- let feeAmount = $t05164551796._3
1335- let commonState = $t05164551796._2
1336- let amountEstimated = $t05164551796._1
1337- let amount = if (if ((minOutAmount > 0))
1338- then (minOutAmount > amountEstimated)
1339- else false)
1340- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1341- else amountEstimated
1342- let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1343- if ((burnInv == burnInv))
1344- then {
1345- let withdrawState = withdrawAndRebalanceAsset(outAssetIdStr, (amount + max([0, feeAmount])))
1346- let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
1347- let sendFee = if ((feeAmount > 0))
1348- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
1349- else nil
1350- let $t05245552702 = {
1351- let feeAmountForCalc = if ((this == feeCollectorAddress))
1352- then 0
1353- else feeAmount
1354- if (outInAmountAsset)
1355- then $Tuple2(-((amount + feeAmountForCalc)), 0)
1356- else $Tuple2(0, -((amount + feeAmountForCalc)))
1357- }
1358- let amountAssetBalanceDelta = $t05245552702._1
1359- let priceAssetBalanceDelta = $t05245552702._2
1360- let $t05270552813 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1361- let refreshKLpActions = $t05270552813._1
1362- let updatedKLp = $t05270552813._2
1363- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1364- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1365- then $Tuple2(((((commonState ++ withdrawState) ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
1366- else throw("Strict value is not equal to itself.")
1367- }
1368- else throw("Strict value is not equal to itself.")
1369- }
1370- else throw("Strict value is not equal to itself.")
1371- }
1372- else throw("Strict value is not equal to itself.")
1373- }
1374- else throw("Strict value is not equal to itself.")
1371+ let dLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyDLp), "0")), fmtErr("invalid dLp"))
1372+ let $t04896749031 = refreshDLpInternal(0, 0, 0)
1373+ let dLpUpdateActions = $t04896749031._1
1374+ let updatedDLp = $t04896749031._2
1375+ let actions = if ((dLp != updatedDLp))
1376+ then dLpUpdateActions
1377+ else throwErr("nothing to refresh")
1378+ $Tuple2(actions, toString(updatedDLp))
13751379 }
13761380 else throw("Strict value is not equal to itself.")
13771381 }
13781382
13791383
13801384
13811385 @Callable(i)
1382-func get () = {
1383- let res = commonGet(i)
1384- let outAmAmt = res._1
1385- let outPrAmt = res._2
1386- let pmtAmt = res._3
1387- let pmtAssetId = res._4
1388- let state = res._5
1389- let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1390- let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1391- if ((currentKLp == currentKLp))
1392- then {
1393- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1394- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1395- then {
1396- let $t05390853989 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1397- let refreshKLpActions = $t05390853989._1
1398- let updatedKLp = $t05390853989._2
1399- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1400- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1401- then ((withdrawState ++ state) ++ refreshKLpActions)
1402- else throw("Strict value is not equal to itself.")
1403- }
1404- else throw("Strict value is not equal to itself.")
1405- }
1406- else throw("Strict value is not equal to itself.")
1386+func getOneTknV2READONLY (outAssetId,lpAssetAmount) = {
1387+ let amId = toBase58String(value(cfgAmountAssetId))
1388+ let prId = toBase58String(value(cfgPriceAssetId))
1389+ let lpId = toBase58String(value(cfgLpAssetId))
1390+ let xp = [toBigInt(getAccBalance(amId)), toBigInt(getAccBalance(prId))]
1391+ let lpEmission = toBigInt(valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "invalid lp asset").quantity)
1392+ let D0 = getD(xp)
1393+ let D1 = (D0 - fraction(toBigInt(lpAssetAmount), D0, lpEmission))
1394+ let index = if ((outAssetId == amId))
1395+ then 0
1396+ else if ((outAssetId == prId))
1397+ then 1
1398+ else throw("invalid out asset id")
1399+ let newY = getYD(xp, index, D1)
1400+ let dy = (xp[index] - newY)
1401+ let totalGetRaw = max([0, toInt((dy - big1))])
1402+ let $t05004150096 = takeFee(totalGetRaw, outFee)
1403+ let totalGet = $t05004150096._1
1404+ let feeAmount = $t05004150096._2
1405+ $Tuple2(nil, $Tuple2(totalGet, feeAmount))
1406+ }
1407+
1408+
1409+
1410+@Callable(i)
1411+func getOneTknV2WithBonusREADONLY (outAssetId,lpAssetAmount) = {
1412+ let amId = toBase58String(value(cfgAmountAssetId))
1413+ let prId = toBase58String(value(cfgPriceAssetId))
1414+ let lpId = toBase58String(value(cfgLpAssetId))
1415+ let amBalance = getAccBalance(amId)
1416+ let prBalance = getAccBalance(prId)
1417+ let $t05047150586 = {
1418+ let @ = invoke(this, "getOneTknV2READONLY", [outAssetId, lpAssetAmount], nil)
1419+ if ($isInstanceOf(@, "(Int, Int)"))
1420+ then @
1421+ else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
1422+ }
1423+ let totalGet = $t05047150586._1
1424+ let feeAmount = $t05047150586._2
1425+ let r = ego("", lpId, lpAssetAmount, this)
1426+ let outAmAmt = r._1
1427+ let outPrAmt = r._2
1428+ let sumOfGetAssets = (outAmAmt + outPrAmt)
1429+ let bonus = if ((sumOfGetAssets == 0))
1430+ then if ((totalGet == 0))
1431+ then 0
1432+ else throw("bonus calculation error")
1433+ else fraction((totalGet - sumOfGetAssets), scale8, sumOfGetAssets)
1434+ $Tuple2(nil, $Tuple3(totalGet, feeAmount, bonus))
14071435 }
14081436
14091437
14101438
14111439 @Callable(i)
14121440 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
1413- let res = commonGet(i)
1414- let outAmAmt = res._1
1415- let outPrAmt = res._2
1416- let pmtAmt = res._3
1417- let pmtAssetId = res._4
1418- let state = res._5
1441+ let r = cg(i)
1442+ let outAmAmt = r._1
1443+ let outPrAmt = r._2
1444+ let pmtAmt = r._3
1445+ let pmtAssetId = r._4
1446+ let state = r._5
14191447 if ((noLessThenAmtAsset > outAmAmt))
1420- then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
1448+ then throw(((("Failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
14211449 else if ((noLessThenPriceAsset > outPrAmt))
1422- then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
1450+ then throw(((("Failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
14231451 else {
1424- let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1425- let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1426- if ((currentKLp == currentKLp))
1452+ let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1453+ if ((currentDLp == currentDLp))
14271454 then {
1428- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
1455+ let burnLPAssetOnFactory = invoke(fca, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
14291456 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
14301457 then {
1431- let $t05508455165 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1432- let refreshKLpActions = $t05508455165._1
1433- let updatedKLp = $t05508455165._2
1434- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1435- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1436- then ((withdrawState ++ state) ++ refreshKLpActions)
1458+ let $t05175251833 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1459+ let refreshDLpActions = $t05175251833._1
1460+ let updatedDLp = $t05175251833._2
1461+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1462+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1463+ then (state ++ refreshDLpActions)
14371464 else throw("Strict value is not equal to itself.")
14381465 }
14391466 else throw("Strict value is not equal to itself.")
14401467 }
14411468 else throw("Strict value is not equal to itself.")
14421469 }
14431470 }
14441471
14451472
14461473
14471474 @Callable(i)
14481475 func unstakeAndGet (amount) = {
14491476 let checkPayments = if ((size(i.payments) != 0))
1450- then throw("No payments are expected")
1477+ then throw("No pmnts expd")
14511478 else true
14521479 if ((checkPayments == checkPayments))
14531480 then {
1454- let cfg = getPoolConfig()
1455- let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1456- let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1457- if ((currentKLp == currentKLp))
1481+ let factoryCfg = gfc()
1482+ let lpAssetId = cfgLpAssetId
1483+ let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1484+ let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1485+ if ((currentDLp == currentDLp))
14581486 then {
1459- let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
1487+ let unstakeInv = invoke(staking, "unstake", [toBase58String(lpAssetId), amount], nil)
14601488 if ((unstakeInv == unstakeInv))
14611489 then {
1462- let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1463- let outAmAmt = res._1
1464- let outPrAmt = res._2
1465- let poolStatus = parseIntValue(res._9)
1466- let state = res._10
1467- let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
1468- let checkPoolStatus = if (if (isGlobalShutdown())
1490+ let r = ego(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
1491+ let outAmAmt = r._1
1492+ let outPrAmt = r._2
1493+ let sts = parseIntValue(r._9)
1494+ let state = r._10
1495+ let v = if (if (igs())
14691496 then true
1470- else (poolStatus == PoolShutdown))
1471- then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
1497+ else (sts == PoolShutdown))
1498+ then throw(("Blocked: " + toString(sts)))
14721499 else true
1473- if ((checkPoolStatus == checkPoolStatus))
1500+ if ((v == v))
14741501 then {
1475- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1476- if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
1502+ let burnA = invoke(fca, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
1503+ if ((burnA == burnA))
14771504 then {
1478- let $t05643756518 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1479- let refreshKLpActions = $t05643756518._1
1480- let updatedKLp = $t05643756518._2
1481- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1482- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1483- then ((withdrawState ++ state) ++ refreshKLpActions)
1505+ let $t05286052941 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1506+ let refreshDLpActions = $t05286052941._1
1507+ let updatedDLp = $t05286052941._2
1508+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1509+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1510+ then (state ++ refreshDLpActions)
14841511 else throw("Strict value is not equal to itself.")
14851512 }
14861513 else throw("Strict value is not equal to itself.")
14871514 }
14881515 else throw("Strict value is not equal to itself.")
14891516 }
14901517 else throw("Strict value is not equal to itself.")
14911518 }
14921519 else throw("Strict value is not equal to itself.")
14931520 }
14941521 else throw("Strict value is not equal to itself.")
14951522 }
14961523
14971524
14981525
14991526 @Callable(i)
15001527 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
1501- let isGetDisabled = if (isGlobalShutdown())
1528+ let isGetDisabled = if (igs())
15021529 then true
15031530 else (cfgPoolStatus == PoolShutdown)
15041531 let checks = [if (!(isGetDisabled))
15051532 then true
15061533 else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
15071534 then true
15081535 else throw("no payments are expected")]
15091536 if ((checks == checks))
15101537 then {
1511- let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
1512- if ((currentKLp == currentKLp))
1538+ let currentDLp = calcCurrentDLp(toBigInt(0), toBigInt(0), toBigInt(0))
1539+ if ((currentDLp == currentDLp))
15131540 then {
15141541 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
15151542 if ((unstakeInv == unstakeInv))
15161543 then {
1517- let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
1544+ let res = ego(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
15181545 let outAmAmt = res._1
15191546 let outPrAmt = res._2
15201547 let state = res._10
1521- let withdrawState = withdrawAndRebalanceAll(outAmAmt, outPrAmt)
15221548 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
15231549 then true
15241550 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
15251551 then true
15261552 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
15271553 if ((checkAmounts == checkAmounts))
15281554 then {
1529- let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
1555+ let burnLPAssetOnFactory = invoke(fca, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
15301556 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
15311557 then {
1532- let $t05795958040 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1533- let refreshKLpActions = $t05795958040._1
1534- let updatedKLp = $t05795958040._2
1535- let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
1536- if ((isUpdatedKLpValid == isUpdatedKLpValid))
1537- then ((withdrawState ++ state) ++ refreshKLpActions)
1558+ let $t05419254273 = refreshDLpInternal(-(outAmAmt), -(outPrAmt), 0)
1559+ let refreshDLpActions = $t05419254273._1
1560+ let updatedDLp = $t05419254273._2
1561+ let isUpdatedDLpValid = validateUpdatedDLp(currentDLp, updatedDLp)
1562+ if ((isUpdatedDLpValid == isUpdatedDLpValid))
1563+ then (state ++ refreshDLpActions)
15381564 else throw("Strict value is not equal to itself.")
15391565 }
15401566 else throw("Strict value is not equal to itself.")
15411567 }
15421568 else throw("Strict value is not equal to itself.")
15431569 }
15441570 else throw("Strict value is not equal to itself.")
15451571 }
15461572 else throw("Strict value is not equal to itself.")
15471573 }
15481574 else throw("Strict value is not equal to itself.")
15491575 }
15501576
15511577
15521578
15531579 @Callable(i)
1554-func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
1555- then throw("permissions denied")
1556- else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
1557-
1558-
1559-
1560-@Callable(i)
1561-func refreshKLp () = {
1562- let lastRefreshedBlockHeight = valueOrElse(getInteger(keyKLpRefreshedHeight), 0)
1563- let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= kLpRefreshDelay))
1564- then unit
1565- else throwErr(makeString([toString(kLpRefreshDelay), " blocks have not passed since the previous call"], ""))
1566- if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
1580+func unstakeAndGetOneTknV2 (unstakeAmount,outAssetId,minOutAmount) = {
1581+ let isPoolOneTokenOperationsDisabled = {
1582+ let @ = invoke(fca, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
1583+ if ($isInstanceOf(@, "Boolean"))
1584+ then @
1585+ else throw(($getType(@) + " couldn't be cast to Boolean"))
1586+ }
1587+ let isGetDisabled = if (if (igs())
1588+ then true
1589+ else (cfgPoolStatus == PoolShutdown))
1590+ then true
1591+ else isPoolOneTokenOperationsDisabled
1592+ let checks = [if (if (!(isGetDisabled))
1593+ then true
1594+ else isManager(i))
1595+ then true
1596+ else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
1597+ then true
1598+ else throwErr("no payments are expected")]
1599+ if ((checks == checks))
15671600 then {
1568- let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1569- let $t05924459308 = refreshKLpInternal(0, 0, 0)
1570- let kLpUpdateActions = $t05924459308._1
1571- let updatedKLp = $t05924459308._2
1572- let actions = if ((kLp != updatedKLp))
1573- then kLpUpdateActions
1574- else throwErr("nothing to refresh")
1575- $Tuple2(actions, toString(updatedKLp))
1601+ let factoryCfg = gfc()
1602+ let lpAssetId = cfgLpAssetId
1603+ let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
1604+ let userAddress = i.caller
1605+ let lpAssetRecipientAddress = this
1606+ let unstakeInv = invoke(staking, "unstakeINTERNAL", [lpAssetId, unstakeAmount, userAddress.bytes, lpAssetRecipientAddress.bytes], nil)
1607+ if ((unstakeInv == unstakeInv))
1608+ then {
1609+ let $t05529555483 = getOneTknV2Internal(outAssetId, minOutAmount, [AttachedPayment(lpAssetId, unstakeAmount)], i.caller, i.originCaller, i.transactionId)
1610+ let state = $t05529555483._1
1611+ let totalAmount = $t05529555483._2
1612+ $Tuple2(state, totalAmount)
1613+ }
1614+ else throw("Strict value is not equal to itself.")
15761615 }
15771616 else throw("Strict value is not equal to itself.")
15781617 }
15791618
15801619
15811620
15821621 @Callable(i)
1583-func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
1622+func putOneTknV2WithBonusREADONLY (paymentAmountRaw,paymentAssetId) = {
1623+ let $t05561155714 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "", true)
1624+ let lpAmount = $t05561155714._1
1625+ let state = $t05561155714._2
1626+ let feeAmount = $t05561155714._3
1627+ let bonus = $t05561155714._4
1628+ $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1629+ }
1630+
1631+
1632+
1633+@Callable(i)
1634+func putOneTknV2WithoutTakeFeeREADONLY (paymentAmountRaw,paymentAssetId) = {
1635+ let $t05586255966 = calcPutOneTkn(paymentAmountRaw, paymentAssetId, "", "", false)
1636+ let lpAmount = $t05586255966._1
1637+ let state = $t05586255966._2
1638+ let feeAmount = $t05586255966._3
1639+ let bonus = $t05586255966._4
1640+ $Tuple2(nil, $Tuple3(lpAmount, feeAmount, bonus))
1641+ }
1642+
1643+
1644+
1645+@Callable(i)
1646+func activate (amtAsStr,prAsStr) = if ((toString(i.caller) != toString(fca)))
1647+ then throw("denied")
1648+ else $Tuple2([StringEntry(aa(), amtAsStr), StringEntry(pa(), prAsStr), StringEntry(amp(), toString(ampInitial))], "success")
1649+
1650+
1651+
1652+@Callable(i)
1653+func getPoolConfigWrapperREADONLY () = $Tuple2(nil, gpc())
15841654
15851655
15861656
15871657 @Callable(i)
15881658 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
15891659
15901660
15911661
15921662 @Callable(i)
15931663 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
1594- let prices = calcPrices(amAmt, prAmt, lpAmt)
1595- $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
1664+ let pr = calcPrices(amAmt, prAmt, lpAmt)
1665+ $Tuple2(nil, [toString(pr[0]), toString(pr[1]), toString(pr[2])])
15961666 }
15971667
15981668
15991669
16001670 @Callable(i)
1601-func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
1671+func fromX18WrapperREADONLY (val,resScaleMult) = $Tuple2(nil, f1(parseBigIntValue(val), resScaleMult))
16021672
16031673
16041674
16051675 @Callable(i)
1606-func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
1676+func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(t1(origVal, origScaleMult)))
16071677
16081678
16091679
16101680 @Callable(i)
1611-func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
1681+func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(cpbi(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
16121682
16131683
16141684
16151685 @Callable(i)
1616-func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
1686+func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,usrAddr,isEval,emitLp) = $Tuple2(nil, epo(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, usrAddr, isEval, emitLp, true, false, 0, ""))
16171687
16181688
16191689
16201690 @Callable(i)
1621-func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
1622- let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
1623- $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
1691+func estimateGetOperationWrapperREADONLY (txId58,pmtAsId,pmtLpAmt,usrAddr) = {
1692+ let r = ego(txId58, pmtAsId, pmtLpAmt, addressFromStringValue(usrAddr))
1693+ $Tuple2(nil, $Tuple10(r._1, r._2, r._3, r._4, r._5, r._6, r._7, toString(r._8), r._9, r._10))
16241694 }
16251695
16261696
16271697
16281698 @Callable(i)
1629-func statsREADONLY () = {
1630- let cfg = getPoolConfig()
1631- let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1632- let amtAssetId = cfg[idxAmtAssetId]
1633- let priceAssetId = cfg[idxPriceAssetId]
1634- let iAmtAssetId = cfg[idxIAmtAssetId]
1635- let iPriceAssetId = cfg[idxIPriceAssetId]
1636- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1637- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1638- let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1639- let accAmtAssetBalance = getAccBalance(amtAssetId)
1640- let accPriceAssetBalance = getAccBalance(priceAssetId)
1641- let pricesList = if ((poolLPBalance == 0))
1642- then [zeroBigInt, zeroBigInt, zeroBigInt]
1643- else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
1644- let curPrice = 0
1645- let lpAmtAssetShare = fromX18(pricesList[1], scale8)
1646- let lpPriceAssetShare = fromX18(pricesList[2], scale8)
1647- let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
1648- $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(accAmtAssetBalance), toString(accPriceAssetBalance), toString(poolLPBalance), toString(curPrice), toString(lpAmtAssetShare), toString(lpPriceAssetShare), toString(poolWeight)], SEP))
1699+func changeAmp () = {
1700+ let cfg = invoke(fca, "getChangeAmpConfigREADONLY", [toString(this)], nil)
1701+ let $t05837558574 = match cfg {
1702+ case list: List[Any] =>
1703+ $Tuple3({
1704+ let @ = list[0]
1705+ if ($isInstanceOf(@, "Int"))
1706+ then @
1707+ else throw(($getType(@) + " couldn't be cast to Int"))
1708+ }, {
1709+ let @ = list[1]
1710+ if ($isInstanceOf(@, "Int"))
1711+ then @
1712+ else throw(($getType(@) + " couldn't be cast to Int"))
1713+ }, {
1714+ let @ = list[2]
1715+ if ($isInstanceOf(@, "Int"))
1716+ then @
1717+ else throw(($getType(@) + " couldn't be cast to Int"))
1718+ })
1719+ case _ =>
1720+ throwErr("invalid entry type")
16491721 }
1650-
1651-
1652-
1653-@Callable(i)
1654-func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
1655- let cfg = getPoolConfig()
1656- let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1657- let amAssetIdStr = cfg[idxAmtAssetId]
1658- let amAssetId = fromBase58String(amAssetIdStr)
1659- let prAssetIdStr = cfg[idxPriceAssetId]
1660- let prAssetId = fromBase58String(prAssetIdStr)
1661- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1662- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1663- let poolStatus = cfg[idxPoolStatus]
1664- let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1665- let accAmtAssetBalance = getAccBalance(amAssetIdStr)
1666- let accPriceAssetBalance = getAccBalance(prAssetIdStr)
1667- let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
1668- let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
1669- let curPriceX18 = if ((poolLPBalance == 0))
1670- then zeroBigInt
1671- else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
1672- let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
1673- let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
1674- let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
1675- let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
1676- let calcLpAmt = estPut._1
1677- let curPriceCalc = estPut._3
1678- let amBalance = estPut._4
1679- let prBalance = estPut._5
1680- let lpEmission = estPut._6
1681- $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(calcLpAmt), toString(fromX18(curPriceX18, scale8)), toString(amBalance), toString(prBalance), toString(lpEmission), poolStatus, toString(inAmAssetAmt), toString(inPrAssetAmt)], SEP))
1682- }
1683-
1684-
1685-
1686-@Callable(i)
1687-func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
1688- let cfg = getPoolConfig()
1689- let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
1690- let amAssetIdStr = cfg[idxAmtAssetId]
1691- let amAssetId = fromBase58String(amAssetIdStr)
1692- let prAssetIdStr = cfg[idxPriceAssetId]
1693- let prAssetId = fromBase58String(prAssetIdStr)
1694- let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
1695- let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
1696- let poolStatus = cfg[idxPoolStatus]
1697- let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
1698- let amBalanceRaw = getAccBalance(amAssetIdStr)
1699- let prBalanceRaw = getAccBalance(prAssetIdStr)
1700- let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
1701- let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
1702- let curPriceX18 = if ((poolLPBalance == 0))
1703- then zeroBigInt
1704- else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
1705- let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
1706- let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
1707- let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
1708- let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
1709- let calcLpAmt = estPut._1
1710- let curPriceCalc = estPut._3
1711- let amBalance = estPut._4
1712- let prBalance = estPut._5
1713- let lpEmission = estPut._6
1714- $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(calcLpAmt), toString(fromX18(curPriceX18, scale8)), toString(amBalance), toString(prBalance), toString(lpEmission), poolStatus, toString(inAmAssetAmt), toString(inPrAssetAmt)], SEP))
1715- }
1716-
1717-
1718-
1719-@Callable(i)
1720-func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
1721- let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
1722- let outAmAmt = res._1
1723- let outPrAmt = res._2
1724- let amBalance = res._5
1725- let prBalance = res._6
1726- let lpEmission = res._7
1727- let curPrice = res._8
1728- let poolStatus = parseIntValue(res._9)
1729- $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(outAmAmt), toString(outPrAmt), toString(amBalance), toString(prBalance), toString(lpEmission), toString(curPrice), toString(poolStatus)], SEP))
1722+ let delay = $t05837558574._1
1723+ let delta = $t05837558574._2
1724+ let target = $t05837558574._3
1725+ let curAmp = parseIntValue(getStringValue(amp()))
1726+ let newAmpRaw = (curAmp + delta)
1727+ let newAmp = if ((0 > delta))
1728+ then if ((target > newAmpRaw))
1729+ then target
1730+ else newAmpRaw
1731+ else if ((newAmpRaw > target))
1732+ then target
1733+ else newAmpRaw
1734+ let lastCall = valueOrElse(getInteger(keyChangeAmpLastCall()), 0)
1735+ let wait = (lastCall + delay)
1736+ let checks = [if ((height > wait))
1737+ then true
1738+ else throwErr("try again in few blocks"), if ((curAmp != newAmp))
1739+ then true
1740+ else throwErr("already reached target")]
1741+ if ((checks == checks))
1742+ then [IntegerEntry(keyChangeAmpLastCall(), height), StringEntry(amp(), toString(newAmp)), StringEntry(keyAmpHistory(height), toString(newAmp))]
1743+ else throw("Strict value is not equal to itself.")
17301744 }
17311745
17321746
17331747 @Verifier(tx)
17341748 func verify () = {
17351749 let targetPublicKey = match managerPublicKeyOrUnit() {
17361750 case pk: ByteVector =>
17371751 pk
17381752 case _: Unit =>
17391753 tx.senderPublicKey
17401754 case _ =>
17411755 throw("Match error")
17421756 }
17431757 match tx {
17441758 case order: Order =>
1745- let matcherPub = getMatcherPubOrFail()
1746- let $t06797068087 = if (skipOrderValidation())
1759+ let matcherPub = mp()
1760+ let $t05950759624 = if (skipOrderValidation())
17471761 then $Tuple2(true, "")
17481762 else validateMatcherOrderAllowed(order)
1749- let orderValid = $t06797068087._1
1750- let orderValidInfo = $t06797068087._2
1763+ let orderValid = $t05950759624._1
1764+ let orderValidInfo = $t05950759624._2
17511765 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
17521766 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
17531767 if (if (if (orderValid)
17541768 then senderValid
17551769 else false)
17561770 then matcherValid
17571771 else false)
17581772 then true
17591773 else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
17601774 case s: SetScriptTransaction =>
17611775 if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
17621776 then true
17631777 else {
17641778 let newHash = blake2b256(value(s.script))
1765- let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
1779+ let allowedHash = fromBase64String(value(getString(fca, keyAllowedLpStableScriptHash())))
17661780 let currentHash = scriptHash(this)
17671781 if ((allowedHash == newHash))
17681782 then (currentHash != newHash)
17691783 else false
17701784 }
17711785 case _ =>
17721786 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
17731787 }
17741788 }
17751789

github/deemru/w8io/3ef1775 
373.07 ms