tx · 5n6Lq1rt6PqMEEABZaqoKynoFU3mSPn93aD3HhVis3yQ

3MrULQRLc52GWrJF1tMcAm4M78fPe57o9Kt:  -0.03800000 Waves

2023.02.09 22:38 [2442511] smart account 3MrULQRLc52GWrJF1tMcAm4M78fPe57o9Kt > SELF 0.00000000 Waves

{ "type": 13, "id": "5n6Lq1rt6PqMEEABZaqoKynoFU3mSPn93aD3HhVis3yQ", "fee": 3800000, "feeAssetId": null, "timestamp": 1675971492773, "version": 2, "chainId": 84, "sender": "3MrULQRLc52GWrJF1tMcAm4M78fPe57o9Kt", "senderPublicKey": "Aig94J3pRT3J41eXw33rJrs67gTCECiMVRZrbtuoARit", "proofs": [ "3eMBcpHxRewcCER8sHt4dFJ5iP5WxVkJtmzwkj7LXwk4TAP3GzWanReo6rNz3NyFgdVfZv7SMWJgtxYHC6HDzMSj" ], "script": "base64:BgLRLwgCEgQKAgEEEgYKBAEEAQgSAwoBCBIAEgQKAgEEEgMKAQESBAoCAQQSBAoCCAESBAoCCAESBAoCCAESBQoDAQgBEgASBAoCAQESAwoBARIFCgMBAQESBAoCCAgSABIAEgMKAQgSBQoDAQEBEgQKAgEBEgQKAggBEgQKAggIEgsKCQgBAQIBAggEBBIGCgQICAEIEgASAwoBARIDCgEBEgQKAggBIgpsUGRlY2ltYWxzIgZzY2FsZTgiDHNjYWxlOEJpZ0ludCIHc2NhbGUxOCIKemVyb0JpZ0ludCIEYmlnMCIEYmlnMSIEYmlnMiILd2F2ZXNTdHJpbmciA1NFUCIKUG9vbEFjdGl2ZSIPUG9vbFB1dERpc2FibGVkIhNQb29sTWF0Y2hlckRpc2FibGVkIgxQb29sU2h1dGRvd24iDmlkeFBvb2xBZGRyZXNzIg1pZHhQb29sU3RhdHVzIhBpZHhQb29sTFBBc3NldElkIg1pZHhBbXRBc3NldElkIg9pZHhQcmljZUFzc2V0SWQiDmlkeEFtdEFzc2V0RGNtIhBpZHhQcmljZUFzc2V0RGNtIg5pZHhJQW10QXNzZXRJZCIQaWR4SVByaWNlQXNzZXRJZCINaWR4TFBBc3NldERjbSISaWR4UG9vbEFtdEFzc2V0QW10IhRpZHhQb29sUHJpY2VBc3NldEFtdCIRaWR4UG9vbExQQXNzZXRBbXQiGWlkeEZhY3RvcnlTdGFraW5nQ29udHJhY3QiGmlkeEZhY3RvcnlTbGlwcGFnZUNvbnRyYWN0IgV0b1gxOCIHb3JpZ1ZhbCINb3JpZ1NjYWxlTXVsdCILdG9YMThCaWdJbnQiB2Zyb21YMTgiA3ZhbCIPcmVzdWx0U2NhbGVNdWx0Igxmcm9tWDE4Um91bmQiBXJvdW5kIgd0b1NjYWxlIgNhbXQiCHJlc1NjYWxlIghjdXJTY2FsZSIDYWJzIglhYnNCaWdJbnQiDHN3YXBDb250cmFjdCICZmMiA21wayIEcG1wayICcGwiAnBoIgFoIgl0aW1lc3RhbXAiA3BhdSILdXNlckFkZHJlc3MiBHR4SWQiA2dhdSICYWEiAnBhIgZrZXlGZWUiCmZlZURlZmF1bHQiA2ZlZSIGa2V5S0xwIhVrZXlLTHBSZWZyZXNoZWRIZWlnaHQiEmtleUtMcFJlZnJlc2hEZWxheSIWa0xwUmVmcmVzaERlbGF5RGVmYXVsdCIPa0xwUmVmcmVzaERlbGF5IhBrZXlGYWN0b3J5Q29uZmlnIg1rZXlNYXRjaGVyUHViIilrZXlNYXBwaW5nUG9vbENvbnRyYWN0QWRkcmVzc1RvUG9vbEFzc2V0cyITcG9vbENvbnRyYWN0QWRkcmVzcyINa2V5UG9vbENvbmZpZyIJaUFtdEFzc2V0IgtpUHJpY2VBc3NldCIfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZCIMYmFzZUFzc2V0U3RyIhNrZXlBbGxQb29sc1NodXRkb3duIg1rZXlQb29sV2VpZ2h0Ig9jb250cmFjdEFkZHJlc3MiFmtleUFsbG93ZWRMcFNjcmlwdEhhc2giFmtleUZlZUNvbGxlY3RvckFkZHJlc3MiD3Rocm93T3JkZXJFcnJvciIKb3JkZXJWYWxpZCIOb3JkZXJWYWxpZEluZm8iC3NlbmRlclZhbGlkIgxtYXRjaGVyVmFsaWQiD2dldFN0cmluZ09yRmFpbCIHYWRkcmVzcyIDa2V5IgxnZXRJbnRPckZhaWwiCHRocm93RXJyIgNtc2ciBmZtdEVyciIPZmFjdG9yeUNvbnRyYWN0IhNmZWVDb2xsZWN0b3JBZGRyZXNzIgVpbkZlZSIBQCIGb3V0RmVlIhBpc0dsb2JhbFNodXRkb3duIhNnZXRNYXRjaGVyUHViT3JGYWlsIg1nZXRQb29sQ29uZmlnIghhbXRBc3NldCIKcHJpY2VBc3NldCIMcGFyc2VBc3NldElkIgVpbnB1dCIPYXNzZXRJZFRvU3RyaW5nIg9wYXJzZVBvb2xDb25maWciCnBvb2xDb25maWciEHBvb2xDb25maWdQYXJzZWQiCyR0MDg0Njk4NjM1Ig5jZmdQb29sQWRkcmVzcyINY2ZnUG9vbFN0YXR1cyIMY2ZnTHBBc3NldElkIhBjZmdBbW91bnRBc3NldElkIg9jZmdQcmljZUFzc2V0SWQiFmNmZ0Ftb3VudEFzc2V0RGVjaW1hbHMiFWNmZ1ByaWNlQXNzZXREZWNpbWFscyIQZ2V0RmFjdG9yeUNvbmZpZyIPc3Rha2luZ0NvbnRyYWN0IhBzbGlwcGFnZUNvbnRyYWN0IhFkYXRhUHV0QWN0aW9uSW5mbyINaW5BbXRBc3NldEFtdCIPaW5QcmljZUFzc2V0QW10IghvdXRMcEFtdCIFcHJpY2UiHXNsaXBwYWdlVG9sZXJhbmNlUGFzc2VkQnlVc2VyIhVzbGlwcGFnZVRvbGVyYW5jZVJlYWwiCHR4SGVpZ2h0Igt0eFRpbWVzdGFtcCISc2xpcGFnZUFtdEFzc2V0QW10IhRzbGlwYWdlUHJpY2VBc3NldEFtdCIRZGF0YUdldEFjdGlvbkluZm8iDm91dEFtdEFzc2V0QW10IhBvdXRQcmljZUFzc2V0QW10IgdpbkxwQW10Ig1nZXRBY2NCYWxhbmNlIgdhc3NldElkIg9jYWxjUHJpY2VCaWdJbnQiCHByQW10WDE4IghhbUFtdFgxOCIUY2FsY1ByaWNlQmlnSW50Um91bmQiEHByaXZhdGVDYWxjUHJpY2UiCmFtQXNzZXREY20iCnByQXNzZXREY20iBWFtQW10IgVwckFtdCIOYW10QXNzZXRBbXRYMTgiEHByaWNlQXNzZXRBbXRYMTgiCmNhbGNQcmljZXMiBWxwQW10IgNjZmciC2FtdEFzc2V0RGNtIg1wcmljZUFzc2V0RGNtIghwcmljZVgxOCIIbHBBbXRYMTgiE2xwUHJpY2VJbkFtQXNzZXRYMTgiE2xwUHJpY2VJblByQXNzZXRYMTgiD2NhbGN1bGF0ZVByaWNlcyIGcHJpY2VzIhRlc3RpbWF0ZUdldE9wZXJhdGlvbiIGdHhJZDU4IgpwbXRBc3NldElkIghwbXRMcEFtdCIJbHBBc3NldElkIglhbUFzc2V0SWQiCXByQXNzZXRJZCIKcG9vbFN0YXR1cyIKbHBFbWlzc2lvbiIJYW1CYWxhbmNlIgxhbUJhbGFuY2VYMTgiCXByQmFsYW5jZSIMcHJCYWxhbmNlWDE4IgtjdXJQcmljZVgxOCIIY3VyUHJpY2UiC3BtdExwQW10WDE4Ig1scEVtaXNzaW9uWDE4IgtvdXRBbUFtdFgxOCILb3V0UHJBbXRYMTgiCG91dEFtQW10IghvdXRQckFtdCIFc3RhdGUiFGVzdGltYXRlUHV0T3BlcmF0aW9uIhFzbGlwcGFnZVRvbGVyYW5jZSIMaW5BbUFzc2V0QW10IgtpbkFtQXNzZXRJZCIMaW5QckFzc2V0QW10IgtpblByQXNzZXRJZCIKaXNFdmFsdWF0ZSIGZW1pdExwIgxhbUFzc2V0SWRTdHIiDHByQXNzZXRJZFN0ciILaUFtdEFzc2V0SWQiDWlQcmljZUFzc2V0SWQiDmluQW1Bc3NldElkU3RyIg5pblByQXNzZXRJZFN0ciIPaW5BbUFzc2V0QW10WDE4Ig9pblByQXNzZXRBbXRYMTgiDHVzZXJQcmljZVgxOCIDcmVzIgtzbGlwcGFnZVgxOCIUc2xpcHBhZ2VUb2xlcmFuY2VYMTgiCnByVmlhQW1YMTgiCmFtVmlhUHJYMTgiDGV4cGVjdGVkQW10cyIRZXhwQW10QXNzZXRBbXRYMTgiE2V4cFByaWNlQXNzZXRBbXRYMTgiCWNhbGNMcEFtdCIOY2FsY0FtQXNzZXRQbXQiDmNhbGNQckFzc2V0UG10IgxzbGlwcGFnZUNhbGMiCWVtaXRMcEFtdCIGYW1EaWZmIgZwckRpZmYiC2NvbW1vblN0YXRlIgdjYWxjS0xwIg1hbW91bnRCYWxhbmNlIgxwcmljZUJhbGFuY2UiEGFtb3VudEJhbGFuY2VYMTgiD3ByaWNlQmFsYW5jZVgxOCIKdXBkYXRlZEtMcCIOY2FsY0N1cnJlbnRLTHAiEGFtb3VudEFzc2V0RGVsdGEiD3ByaWNlQXNzZXREZWx0YSIUbHBBc3NldEVtaXNzaW9uRGVsdGEiEmFtb3VudEFzc2V0QmFsYW5jZSIRcHJpY2VBc3NldEJhbGFuY2UiD2xwQXNzZXRFbWlzc2lvbiIKY3VycmVudEtMcCIScmVmcmVzaEtMcEludGVybmFsIhdhbW91bnRBc3NldEJhbGFuY2VEZWx0YSIWcHJpY2VBc3NldEJhbGFuY2VEZWx0YSIHYWN0aW9ucyISdmFsaWRhdGVVcGRhdGVkS0xwIgZvbGRLTHAiG3ZhbGlkYXRlTWF0Y2hlck9yZGVyQWxsb3dlZCIFb3JkZXIiEWFtb3VudEFzc2V0QW1vdW50IhBwcmljZUFzc2V0QW1vdW50Ig0kdDAyMTU0MTIxNzUzIgNrTHAiDSR0MDIyMTkzMjIyOTMiDXVudXNlZEFjdGlvbnMiBmtMcE5ldyIMaXNPcmRlclZhbGlkIgRpbmZvIgljb21tb25HZXQiAWkiA3BtdCIGcG10QW10Igljb21tb25QdXQiCmFtQXNzZXRQbXQiCnByQXNzZXRQbXQiBmVzdFB1dCIEZW1pdCIGYW1vdW50IgdlbWl0SW52Ig1lbWl0SW52TGVnYWN5IgckbWF0Y2gwIhVsZWdhY3lGYWN0b3J5Q29udHJhY3QiB3Rha2VGZWUiCWZlZUFtb3VudCIPY2FsY1B1dE9uZVRva2VuIhBwYXltZW50QW1vdW50UmF3Ig5wYXltZW50QXNzZXRJZCIGaXNFdmFsIhBhbW91bnRCYWxhbmNlUmF3Ig9wcmljZUJhbGFuY2VSYXciFHBheW1lbnRJbkFtb3VudEFzc2V0Ig0kdDAyNTQwNjI1Njk5IhBhbW91bnRCYWxhbmNlT2xkIg9wcmljZUJhbGFuY2VPbGQiDSR0MDI1NzAzMjU4NTIiFGFtb3VudEFzc2V0QW1vdW50UmF3IhNwcmljZUFzc2V0QW1vdW50UmF3Ig0kdDAyNTk4NDI2MDQ4Ig1wYXltZW50QW1vdW50IhBhbW91bnRCYWxhbmNlTmV3Ig9wcmljZUJhbGFuY2VOZXciC3ByaWNlTmV3WDE4IghwcmljZU5ldyIOcGF5bWVudEJhbGFuY2UiFHBheW1lbnRCYWxhbmNlQmlnSW50IgxzdXBwbHlCaWdJbnQiC2NoZWNoU3VwcGx5Ig1kZXBvc2l0QmlnSW50Igtpc3N1ZUFtb3VudCILcHJpY2VPbGRYMTgiCHByaWNlT2xkIgRsb3NzIg0kdDAyNzcyOTI3ODk2IgdiYWxhbmNlIg9pc3N1ZUFtb3VudEJvdGgiD2NhbGNHZXRPbmVUb2tlbiIKb3V0QXNzZXRJZCIGY2hlY2tzIhBvdXRJbkFtb3VudEFzc2V0Ig1iYWxhbmNlQmlnSW50IhhvdXRJbkFtb3VudEFzc2V0RGVjaW1hbHMiDGFtQmFsYW5jZU9sZCIMcHJCYWxhbmNlT2xkIgpvdXRCYWxhbmNlIhBvdXRCYWxhbmNlQmlnSW50Ig5yZWRlZW1lZEJpZ0ludCIJYW1vdW50UmF3Ig0kdDAyOTk3NDMwMDMwIgt0b3RhbEFtb3VudCINJHQwMzAwMzQzMDI2MCILb3V0QW1BbW91bnQiC291dFByQW1vdW50IgxhbUJhbGFuY2VOZXciDHByQmFsYW5jZU5ldyIYYW1vdW50Qm90aEluUGF5bWVudEFzc2V0IhZtYW5hZ2VyUHVibGljS2V5T3JVbml0IgFzIh1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdCIJaXNNYW5hZ2VyIgJwayILbXVzdE1hbmFnZXIiAnBkIg1jbGVhbkFtb3VudEluIglpc1JldmVyc2UiDSR0MDMxOTU1MzIyNjAiCGFzc2V0T3V0Igdhc3NldEluIhJwb29sQXNzZXRJbkJhbGFuY2UiE3Bvb2xBc3NldE91dEJhbGFuY2UiCWFtb3VudE91dCIEb2xkSyIEbmV3SyIGY2hlY2tLIgxhbW91bnRPdXRNaW4iCWFkZHJlc3NUbyILc3dhcENvbnRhY3QiCGNoZWNrTWluIhdwZW5kaW5nTWFuYWdlclB1YmxpY0tleSILY2hlY2tDYWxsZXIiFWNoZWNrTWFuYWdlclB1YmxpY0tleSICcG0iBWhhc1BNIgdjaGVja1BNIg9zaG91bGRBdXRvU3Rha2UiBGFtSWQiBHBySWQiDHNsaXBwYWdlQUludiIMc2xpcHBhZ2VQSW52IgpscFRyYW5zZmVyIgtzbHBTdGFrZUludiINJHQwMzcxNDUzNzYwNyIRcmVmcmVzaEtMcEFjdGlvbnMiEWlzVXBkYXRlZEtMcFZhbGlkIgttYXhTbGlwcGFnZSINJHQwMzgxNjkzODIzNCIMbWluT3V0QW1vdW50IglhdXRvU3Rha2UiIGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkIg1pc1B1dERpc2FibGVkIgdwYXltZW50Ig0kdDAzOTQyMjM5NTc0IgVib251cyITZW1pdEFtb3VudEVzdGltYXRlZCIKZW1pdEFtb3VudCIIc3Rha2VJbnYiB3NlbmRGZWUiDSR0MDQwMTYwNDAzNTciDSR0MDQwMzYwNDA0NjgiDSR0MDQwNzc0NDA5MzEiDW91dEFzc2V0SWRTdHIiDWlzR2V0RGlzYWJsZWQiDSR0MDQxODE2NDE5NjkiD2Ftb3VudEVzdGltYXRlZCIHYnVybkludiINYXNzZXRUcmFuc2ZlciINJHQwNDI0Njk0MjcxNiIQZmVlQW1vdW50Rm9yQ2FsYyINJHQwNDI3MTk0MjgyNyINJHQwNDMwODQ0MzI0MCINdW5zdGFrZUFtb3VudCIKdW5zdGFrZUludiINJHQwNDQxNDU0NDI5NiINJHQwNDQ3OTE0NTAzOCINJHQwNDUwNDE0NTE0OSIJb3V0QW10QW10IhRidXJuTFBBc3NldE9uRmFjdG9yeSINJHQwNDYwOTU0NjE3NyISbm9MZXNzVGhlbkFtdEFzc2V0IhRub0xlc3NUaGVuUHJpY2VBc3NldCINJHQwNDcxMjY0NzIwNyINY2hlY2tQYXltZW50cyIPY2hlY2tQb29sU3RhdHVzIg0kdDA0ODMzMzQ4NDE0IhVub0xlc3NUaGVuQW1vdW50QXNzZXQiDGNoZWNrQW1vdW50cyINJHQwNDk3MDk0OTc5MCILYW10QXNzZXRTdHIiDXByaWNlQXNzZXRTdHIiGGxhc3RSZWZyZXNoZWRCbG9ja0hlaWdodCIdY2hlY2tMYXN0UmVmcmVzaGVkQmxvY2tIZWlnaHQiDSR0MDUwOTc3NTEwNDEiEGtMcFVwZGF0ZUFjdGlvbnMiCmFtdEFzc2V0SWQiDHByaWNlQXNzZXRJZCINcG9vbExQQmFsYW5jZSISYWNjQW10QXNzZXRCYWxhbmNlIhRhY2NQcmljZUFzc2V0QmFsYW5jZSIKcHJpY2VzTGlzdCIPbHBBbXRBc3NldFNoYXJlIhFscFByaWNlQXNzZXRTaGFyZSIKcG9vbFdlaWdodCIMY3VyUHJpY2VDYWxjIgxhbUJhbGFuY2VSYXciDHByQmFsYW5jZVJhdyIPYW1CYWxhbmNlUmF3WDE4Ig9wckJhbGFuY2VSYXdYMTgiEHBheW1lbnRMcEFzc2V0SWQiDHBheW1lbnRMcEFtdCICdHgiBnZlcmlmeSIPdGFyZ2V0UHVibGljS2V5IgptYXRjaGVyUHViIg0kdDA1OTcwMzU5NzcyIgduZXdIYXNoIgthbGxvd2VkSGFzaCILY3VycmVudEhhc2hzAAFhAAgAAWIAgMLXLwABYwkAtgIBAIDC1y8AAWQJALYCAQCAgJC7utat8A0AAWUJALYCAQAAAAFmCQC2AgEAAAABZwkAtgIBAAEAAWgJALYCAQACAAFpAgVXQVZFUwABagICX18AAWsAAQABbAACAAFtAAMAAW4ABAABbwABAAFwAAIAAXEAAwABcgAEAAFzAAUAAXQABgABdQAHAAF2AAgAAXcACQABeAAKAAF5AAEAAXoAAgABQQADAAFCAAEAAUMABwEB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pQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJhUgIDSW50BQJhUgkAAgEJAKwCAgkAAwEFAmFSAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQAAmFTCgACYVIJAPwHBAUCYU8CEWdldE91dEZlZVJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYVICA0ludAUCYVIJAAIBCQCsAgIJAAMBBQJhUgIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AQJhVAAJAQt2YWx1ZU9yRWxzZQIJAJsIAgUCYU8JAQJheAAHAQJhVQAJANkEAQkBAmFIAgUCYU8JAQJhcAABAmFWAAQCYVcJAQJhSAIFBHRoaXMJAQJhZQAEAmFYCQECYUgCBQR0aGlzCQECYWYABAJhdQkBAmFLAgUCYU8JAQJhdgEFAmFYBAJhdAkBAmFLAgUCYU8JAQJhdgEFAmFXCQC1CQIJAQJhSAIFAmFPCQECYXMCCQCkAwEFAmF0CQCkAwEFAmF1BQFqAQJhWQECYVoDCQAAAgUCYVoFAWkFBHVuaXQJANkEAQUCYVoBAmJhAQJhWgMJAAACBQJhWgUEdW5pdAUBaQkA2AQBCQEFdmFsdWUBBQJhWgECYmIBAmJjCQCZCgcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYmMFAW8JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiYwUBcAkA2QQBCQCRAwIFAmJjBQFxCQECYVkBCQCRAwIFAmJjBQFyCQECYVkBCQCRAwIFAmJjBQFzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYmMFAXQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiYwUBdQACYmQJAQJiYgEJAQJhVgAAAmJlBQJiZAACYmYIBQJiZQJfMQACYmcIBQJiZQJfMgACYmgIBQJiZQJfMwACYmkIBQJiZQJfNAACYmoIBQJiZQJfNQACYmsIBQJiZQJfNgACYmwIBQJiZQJfNwECYm0ACQC1CQIJAQJhSAIFAmFPCQECYW8ABQFqAAJibgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgkBAmJtAAUBQgIZaW5jb3JyZWN0IHN0YWtpbmcgYWRkcmVzcwACYm8JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIJAQJibQAFAUMCGWluY29ycmVjdCBzdGFraW5nIGFkZHJlc3MBAmJwCgJicQJicgJicwJidAJidQJidgJidwJieAJieQJiegkAuQkCCQDMCAICFCVkJWQlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYnEJAMwIAgkApAMBBQJicgkAzAgCCQCkAwEFAmJzCQDMCAIJAKQDAQUCYnQJAMwIAgkApAMBBQJidQkAzAgCCQCkAwEFAmJ2CQDMCAIJAKQDAQUCYncJAMwIAgkApAMBBQJieAkAzAgCCQCkAwEFAmJ5CQDMCAIJAKQDAQUCYnoFA25pbAUBagECYkEGAmJCAmJDAmJEAmJ0AmJ3AmJ4CQC5CQIJAMwIAgIMJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYkIJAMwIAgkApAMBBQJiQwkAzAgCCQCkAwEFAmJECQDMCAIJAKQDAQUCYnQJAMwIAgkApAMBBQJidwkAzAgCCQCkAwEFAmJ4BQNuaWwFAWoBAmJFAQJiRgMJAAACBQJiRgIFV0FWRVMICQDvBwEFBHRoaXMJYXZhaWxhYmxlCQDwBwIFBHRoaXMJANkEAQUCYkYBAmJHAgJiSAJiSQkAvAIDBQJiSAUBZAUCYkkBAmJKAwJiSAJiSQFMCQC9AgQFAmJIBQFkBQJiSQUBTAECYksEAmJMAmJNAmJOAmJPBAJiUAkBAUQCBQJiTgUCYkwEAmJRCQEBRAIFAmJPBQJiTQkBAmJHAgUCYlEFAmJQAQJiUgMCYk4CYk8CYlMEAmJUCQECYVYABAJiVQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJUBQF0BAJiVgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJUBQF1BAJiVwkBAmJLBAUCYlUFAmJWBQJiTgUCYk8EAmJJCQEBRAIFAmJOBQJiVQQCYkgJAQFEAgUCYk8FAmJWBAJiWAkBAUQCBQJiUwUBYgQCYlkJAQJiRwIFAmJJBQJiWAQCYloJAQJiRwIFAmJIBQJiWAkAzAgCBQJiVwkAzAgCBQJiWQkAzAgCBQJiWgUDbmlsAQJjYQMCYk4CYk8CYlMEAmNiCQECYlIDBQJiTgUCYk8FAmJTCQDMCAIJAQFIAgkAkQMCBQJjYgAABQFiCQDMCAIJAQFIAgkAkQMCBQJjYgABBQFiCQDMCAIJAQFIAgkAkQMCBQJjYgACBQFiBQNuaWwBAmNjBAJjZAJjZQJjZgJhYgQCYlQJAQJhVgAEAmNnCQCRAwIFAmJUBQFxBAJjaAkAkQMCBQJiVAUBcgQCY2kJAJEDAgUCYlQFAXMEAmJMCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlQFAXQEAmJNCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlQFAXUEAmNqCQCRAwIFAmJUBQFwBAJjawgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFAmNnCQCsAgIJAKwCAgIGQXNzZXQgBQJjZwIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkDCQECIT0CBQJjZwUCY2UJAAIBAhVJbnZhbGlkIGFzc2V0IHBhc3NlZC4EAmNsCQECYkUBBQJjaAQCY20JAQFEAgUCY2wFAmJMBAJjbgkBAmJFAQUCY2kEAmNvCQEBRAIFAmNuBQJiTQQCY3AJAQJiRwIFAmNvBQJjbQQCY3EJAQFIAgUCY3AFAWIEAmNyCQEBRAIFAmNmBQFiBAJjcwkBAUQCBQJjawUBYgQCY3QJALwCAwUCY20FAmNyBQJjcwQCY3UJALwCAwUCY28FAmNyBQJjcwQCY3YJAQFLAwUCY3QFAmJMBQVGTE9PUgQCY3cJAQFLAwUCY3UFAmJNBQVGTE9PUgQCY3gDCQAAAgUCY2QCAAUDbmlsCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFiBQJjdgMJAAACBQJjaAIFV0FWRVMFBHVuaXQJANkEAQUCY2gJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYWIFAmN3AwkAAAIFAmNpAgVXQVZFUwUEdW5pdAkA2QQBBQJjaQkAzAgCCQELU3RyaW5nRW50cnkCCQECYWQCCQClCAEFAmFiBQJjZAkBAmJBBgUCY3YFAmN3BQJjZgUCY3EFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCY3EJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCY3EFA25pbAkAnAoKBQJjdgUCY3cFAmNoBQJjaQUCY2wFAmNuBQJjawUCY3AFAmNqBQJjeAECY3kJAmNkAmN6AmNBAmNCAmNDAmNEAmFiAmNFAmNGBAJiVAkBAmFWAAQCY2cJANkEAQkAkQMCBQJiVAUBcQQCY0cJAJEDAgUCYlQFAXIEAmNICQCRAwIFAmJUBQFzBAJjSQkAkQMCBQJiVAUBdgQCY0oJAJEDAgUCYlQFAXcEAmJVCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlQFAXQEAmJWCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYlQFAXUEAmNqCQCRAwIFAmJUBQFwBAJjawgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJjZwkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJjZwIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmNLCQDYBAEJAQt2YWx1ZU9yRWxzZQIFAmNCCQDZBAECBVdBVkVTBAJjTAkA2AQBCQELdmFsdWVPckVsc2UCBQJjRAkA2QQBAgVXQVZFUwMDCQECIT0CBQJjRwUCY0sGCQECIT0CBQJjSAUCY0wJAAIBAiJJbnZhbGlkIGFtdCBvciBwcmljZSBhc3NldCBwYXNzZWQuBAJjbAMFAmNFCQECYkUBBQJjRwkAZQIJAQJiRQEFAmNHBQJjQQQCY24DBQJjRQkBAmJFAQUCY0gJAGUCCQECYkUBBQJjSAUCY0MEAmNNCQEBRAIFAmNBBQJiVQQCY04JAQFEAgUCY0MFAmJWBAJjTwkBAmJHAgUCY04FAmNNBAJjbQkBAUQCBQJjbAUCYlUEAmNvCQEBRAIFAmNuBQJiVgQCY1ADCQAAAgUCY2sAAAQCY3AFAWUEAmNRBQFlBAJiWAkAdgYJALkCAgUCY00FAmNOAAAJALYCAQAFAAEAAAUERE9XTgkAlwoFCQEBSAIFAmJYBQFiCQEBSAIFAmNNBQJiVQkBAUgCBQJjTgUCYlYJAQJiRwIJALcCAgUCY28FAmNOCQC3AgIFAmNtBQJjTQUCY1EEAmNwCQECYkcCBQJjbwUCY20EAmNRCQC8AgMJAQFSAQkAuAICBQJjcAUCY08FAWQFAmNwBAJjUgkBAUQCBQJjegUBYgMDCQECIT0CBQJjcAUBZQkAvwICBQJjUQUCY1IHCQACAQkArAICCQCsAgIJAKwCAgIPUHJpY2Ugc2xpcHBhZ2UgCQCmAwEFAmNRAh4gZXhjZWVkZWQgdGhlIHBhc3NlZCBsaW1pdCBvZiAJAKYDAQUCY1IEAmNzCQEBRAIFAmNrBQFiBAJjUwkAvQIEBQJjTQkBAmJKAwUCY28FAmNtBQdDRUlMSU5HBQFkBQdDRUlMSU5HBAJjVAkAvQIEBQJjTgUBZAkBAmJKAwUCY28FAmNtBQVGTE9PUgUHQ0VJTElORwQCY1UDCQC/AgIFAmNTBQJjTgkAlAoCBQJjVAUCY04JAJQKAgUCY00FAmNTBAJjVggFAmNVAl8xBAJjVwgFAmNVAl8yBAJiWAkAvQIEBQJjcwUCY1cFAmNvBQVGTE9PUgkAlwoFCQEBSwMFAmJYBQFiBQVGTE9PUgkBAUsDBQJjVgUCYlUFB0NFSUxJTkcJAQFLAwUCY1cFAmJWBQdDRUlMSU5HBQJjcAUCY1EEAmNYCAUCY1ACXzEEAmNZCAUCY1ACXzIEAmNaCAUCY1ACXzMEAmNxCQEBSAIIBQJjUAJfNAUBYgQCZGEJAQFIAggFAmNQAl81BQFiAwkAZwIAAAUCY1gJAAIBAjZJbnZhbGlkIGNhbGN1bGF0aW9ucy4gTFAgY2FsY3VsYXRlZCBpcyBsZXNzIHRoYW4gemVyby4EAmRiAwkBASEBBQJjRgAABQJjWAQCZGMJAGUCBQJjQQUCY1kEAmRkCQBlAgUCY0MFAmNaBAJkZQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVcABQJjcQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVgCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJjcQkAzAgCCQELU3RyaW5nRW50cnkCCQECYWECBQJhYgUCY2QJAQJicAoFAmNZBQJjWgUCZGIFAmNxBQJjegUCZGEFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmRjBQJkZAUDbmlsCQCfCg0FAmNYBQJkYgUCY3EFAmNsBQJjbgUCY2sFAmNnBQJjagUCZGUFAmRjBQJkZAUCY0IFAmNEAQJkZgMCZGcCZGgCY2sEAmRpCQEBRwIFAmRnCQC2AgEFAmJrBAJkagkBAUcCBQJkaAkAtgIBBQJibAQCZGsJALwCAwkAdgYJALkCAgUCZGkFAmRqAAAJALYCAQAFAAEAEgUERE9XTgUBZwUCY2sDCQAAAgUCY2sFAWYFAWYFAmRrAQJkbAMCZG0CZG4CZG8EAmRwCQC4AgIJALYCAQkBAmJFAQkBAmJhAQUCYmkFAmRtBAJkcQkAuAICCQC2AgEJAQJiRQEJAQJiYQEFAmJqBQJkbgQCZHIJALgCAgkAtgIBCAkBBXZhbHVlAQkA7AcBBQJiaAhxdWFudGl0eQUCZG8EAmRzCQECZGYDBQJkcAUCZHEFAmRyBQJkcwECZHQDAmR1AmR2AmRvBAJkcAkAZAIJAQJiRQEJAQJiYQEFAmJpBQJkdQQCZHEJAGQCCQECYkUBCQECYmEBBQJiagUCZHYEAmRyCQBkAggJAQV2YWx1ZQEJAOwHAQUCYmgIcXVhbnRpdHkFAmRvBAJkawkBAmRmAwkAtgIBBQJkcAkAtgIBBQJkcQkAtgIBBQJkcgQCZHcJAMwIAgkBDEludGVnZXJFbnRyeQIFAmFrBQZoZWlnaHQJAMwIAgkBC1N0cmluZ0VudHJ5AgUCYWoJAKYDAQUCZGsFA25pbAkAlAoCBQJkdwUCZGsBAmR4AgJkeQJkawMJAMACAgUCZGsFAmR5BgkBAmFMAQkAuQkCCQDMCAICInVwZGF0ZWQgS0xwIGxvd2VyIHRoYW4gY3VycmVudCBLTHAJAMwIAgkApgMBBQJkeQkAzAgCCQCmAwEFAmRrBQNuaWwCASABAmR6AQJkQQQCZHAJAQJiRQEJAQJiYQEFAmJpBAJkcQkBAmJFAQkBAmJhAQUCYmoEAmRCCAUCZEEGYW1vdW50BAJkQwkAbgQIBQJkQQZhbW91bnQIBQJkQQVwcmljZQUBYgUFRkxPT1IEAmREAwkAAAIIBQJkQQlvcmRlclR5cGUFA0J1eQkAlAoCBQJkQgkBAS0BBQJkQwkAlAoCCQEBLQEFAmRCBQJkQwQCZHUIBQJkRAJfMQQCZHYIBQJkRAJfMgMDAwkBAmFUAAYJAAACBQJiZwUBbQYJAAACBQJiZwUBbgkAAgECHEV4Y2hhbmdlIG9wZXJhdGlvbnMgZGlzYWJsZWQDAwkBAiE9AggIBQJkQQlhc3NldFBhaXILYW1vdW50QXNzZXQFAmJpBgkBAiE9AggIBQJkQQlhc3NldFBhaXIKcHJpY2VBc3NldAUCYmoJAAIBAhNXcm9uZyBvcmRlciBhc3NldHMuBAJkRQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCoAwEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUCYWoCATAJAQJhTgECC2ludmFsaWQga0xwBAJkRgkBAmR0AwUCZHUFAmR2AAAEAmRHCAUCZEYCXzEEAmRICAUCZEYCXzIEAmRJCQDAAgIFAmRIBQJkRQQCZEoJALkJAgkAzAgCAgRrTHA9CQDMCAIJAKYDAQUCZEUJAMwIAgIIIGtMcE5ldz0JAMwIAgkApgMBBQJkSAkAzAgCAhQgYW1vdW50QXNzZXRCYWxhbmNlPQkAzAgCCQCkAwEFAmRwCQDMCAICEyBwcmljZUFzc2V0QmFsYW5jZT0JAMwIAgkApAMBBQJkcQkAzAgCAhkgYW1vdW50QXNzZXRCYWxhbmNlRGVsdGE9CQDMCAIJAKQDAQUCZHUJAMwIAgIYIHByaWNlQXNzZXRCYWxhbmNlRGVsdGE9CQDMCAIJAKQDAQUCZHYJAMwIAgIIIGhlaWdodD0JAMwIAgkApAMBBQZoZWlnaHQFA25pbAIACQCUCgIFAmRJBQJkSgECZEsBAmRMAwkBAiE9AgkAkAMBCAUCZEwIcGF5bWVudHMAAQkAAgECHWV4YWN0bHkgMSBwYXltZW50IGlzIGV4cGVjdGVkBAJkTQkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAAQCY2UJAQV2YWx1ZQEIBQJkTQdhc3NldElkBAJkTggFAmRNBmFtb3VudAQCY1AJAQJjYwQJANgEAQgFAmRMDXRyYW5zYWN0aW9uSWQJANgEAQUCY2UFAmROCAUCZEwGY2FsbGVyBAJjdggFAmNQAl8xBAJjdwgFAmNQAl8yBAJjagkBDXBhcnNlSW50VmFsdWUBCAUCY1ACXzkEAmN4CAUCY1ADXzEwAwMJAQJhVAAGCQAAAgUCY2oFAW4JAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmNqCQCXCgUFAmN2BQJjdwUCZE4FAmNlBQJjeAECZE8DAmRMAmN6AmNGAwkBAiE9AgkAkAMBCAUCZEwIcGF5bWVudHMAAgkAAgECH2V4YWN0bHkgMiBwYXltZW50cyBhcmUgZXhwZWN0ZWQEAmRQCQEFdmFsdWUBCQCRAwIIBQJkTAhwYXltZW50cwAABAJkUQkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAQQCZFIJAQJjeQkJANgEAQgFAmRMDXRyYW5zYWN0aW9uSWQFAmN6CAUCZFAGYW1vdW50CAUCZFAHYXNzZXRJZAgFAmRRBmFtb3VudAgFAmRRB2Fzc2V0SWQJAKUIAQgFAmRMBmNhbGxlcgcFAmNGBAJjagkBDXBhcnNlSW50VmFsdWUBCAUCZFICXzgDAwMJAQJhVAAGCQAAAgUCY2oFAWwGCQAAAgUCY2oFAW4JAAIBCQCsAgICLFB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmNqBQJkUgECZFMBAmRUBAJkVQkA/AcEBQJhTwIEZW1pdAkAzAgCBQJkVAUDbmlsBQNuaWwDCQAAAgUCZFUFAmRVBAJkVgQCZFcFAmRVAwkAAQIFAmRXAgdBZGRyZXNzBAJkWAUCZFcJAPwHBAUCZFgCBGVtaXQJAMwIAgUCZFQFA25pbAUDbmlsBQR1bml0AwkAAAIFAmRWBQJkVgUCZFQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmRZAgJkVAJhaQQCZFoDCQAAAgUCYWkAAAAACQBrAwUCZFQFAmFpBQFiCQCUCgIJAGUCBQJkVAUCZFoFAmRaAQJlYQQCZWICZWMCYWICYWMEAmVkCQAAAgUCYWMFBHVuaXQEAmVlCQECYkUBCQECYmEBBQJiaQQCZWYJAQJiRQEJAQJiYQEFAmJqBAJlZwMJAAACBQJlYwUCYmkGAwkAAAIFAmVjBQJiagcJAQJhTAECDWludmFsaWQgYXNzZXQEAmVoAwUCZWQJAJQKAgUCZWUFAmVmAwUCZWcJAJQKAgkAZQIFAmVlBQJlYgUCZWYJAJQKAgUCZWUJAGUCBQJlZgUCZWIEAmVpCAUCZWgCXzEEAmVqCAUCZWgCXzIEAmVrAwUCZWcJAJQKAgUCZWIAAAkAlAoCAAAFAmViBAJlbAgFAmVrAl8xBAJlbQgFAmVrAl8yBAJkQggJAQJkWQIFAmVsBQJhUQJfMQQCZEMICQECZFkCBQJlbQUCYVECXzEEAmVuCQECZFkCBQJlYgUCYVEEAmVvCAUCZW4CXzEEAmRaCAUCZW4CXzIEAmVwCQBkAgUCZWkFAmRCBAJlcQkAZAIFAmVqBQJkQwQCZXIJAQJiRwIJAQFEAgUCZXEFAmJsCQEBRAIFAmVwBQJiawQCZXMJAQFIAgUCZXIFAWIEAmV0AwUCZWcFAmVpBQJlagQCZXUJALYCAQUCZXQEAmV2CQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYmgJAKwCAgkArAICAgZhc3NldCAJANgEAQUCYmgCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJldwMJAL8CAgUCZXYFAWYGCQECYUwBAiJpbml0aWFsIGRlcG9zaXQgcmVxdWlyZXMgYWxsIGNvaW5zAwkAAAIFAmV3BQJldwQCZXgJALYCAQUCZW8EAmV5CQCWAwEJAMwIAgAACQDMCAIJAKADAQkAugICCQC5AgIFAmV2CQC4AgIJAQpzcXJ0QmlnSW50BAkAtwICBQFkCQC6AgIJALkCAgUCZXgFAWQFAmV1ABIAEgUERE9XTgUBZAUBZAUDbmlsBAJkZQMFAmVkBQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZXMJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZXMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFhAgkApQgBCQEFdmFsdWUBBQJhYgkA2AQBCQEFdmFsdWUBBQJhYwkBAmJwCgUCZWwFAmVtBQJleQUCZXMAAAAABQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wAAAAAAUDbmlsBAJlegkBAmJHAgkBAUQCBQJlagUCYmwJAQFEAgUCZWkFAmJrBAJlQQkBAUgCBQJlegUBYgQCZUIEAmVDAwUCZWcJAJQKAgUCZWwFAmVpCQCUCgIFAmVtBQJlagQCZFQIBQJlQwJfMQQCZUQIBQJlQwJfMgQCZUUJAKADAQkAvAIDBQJldgkAtgIBCQBpAgUCZFQAAgkAtgIBBQJlRAkAawMJAGUCBQJleQUCZUUFAWIFAmVFCQCXCgUFAmV5BQJkZQUCZFoFAmVCBQJlZwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZUYFAmVHAmVvAmVjAmFiAmFjBAJlZAkAAAIFAmFjBQR1bml0BAJiVAkBAmFWAAQCYlUJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiVAUBdAQCYlYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiVAUBdQQCZUgJAMwIAgMJAAACBQJlYwUCYmgGCQECYUwBAhBpbnZhbGlkIGxwIGFzc2V0BQNuaWwDCQAAAgUCZUgFAmVIBAJlSQMJAAACBQJlRwUCYmkGAwkAAAIFAmVHBQJiagcJAQJhTAECDWludmFsaWQgYXNzZXQEAmVKAwUCZUkJALYCAQkBAmJFAQkBAmJhAQUCYmkJALYCAQkBAmJFAQkBAmJhAQUCYmoEAmVLAwUCZUkFAmJVBQJiVgQCZUwJAQJiRQEJAQJiYQEFAmJpBAJlTQkBAmJFAQkBAmJhAQUCYmoEAmVOAwUCZUkFAmVMBQJlTQQCZU8JALYCAQUCZU4EAmV2CQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYmgJAKwCAgkArAICAgZhc3NldCAJANgEAQUCYmgCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJlUAkAtgIBBQJlbwQCZVEJAJYDAQkAzAgCAAAJAMwIAgkAoAMBCQC6AgIJALkCAgUCZUoJALgCAgUBZAkAdgYJALgCAgUBZAkAugICCQC5AgIFAmVQBQFkBQJldgASBQFoAAAAEgUERE9XTgUBZAUDbmlsBAJlUgkBAmRZAgUCZVEFAmFTBAJlUwgFAmVSAl8xBAJkWggFAmVSAl8yBAJlVAMFAmVJCQCWCgQFAmVTAAAJAGUCBQJlTAUCZVEFAmVNCQCWCgQAAAUCZVMFAmVMCQBlAgUCZU0FAmVRBAJlVQgFAmVUAl8xBAJlVggFAmVUAl8yBAJlVwgFAmVUAl8zBAJlWAgFAmVUAl80BAJlcgkBAmJHAgkBAUQCBQJlWAUCYmwJAQFEAgUCZVcFAmJrBAJlcwkBAUgCBQJlcgUBYgQCZGUDBQJlZAUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZAIJAKUIAQkBBXZhbHVlAQUCYWIJANgEAQkBBXZhbHVlAQUCYWMJAQJiQQYFAmVVBQJlVgUCZW8FAmVzBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVwAFAmVzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBWAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmVzBQNuaWwEAmV6CQECYkcCCQEBRAIFAmVNBQJibAkBAUQCBQJlTAUCYmsEAmVBCQEBSAIFAmV6BQFiBAJlQgQCZVkJAGgCCQCgAwEJALwCAwUCZUoFAmVQBQJldgACCQBrAwkAZQIFAmVTBQJlWQUBYgUCZVkJAJcKBQUCZVMFAmRlBQJkWgUCZUIFAmVJCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJlWgAEAmRXCQCiCAEJAQFVAAMJAAECBQJkVwIGU3RyaW5nBAJmYQUCZFcJANkEAQUCZmEDCQABAgUCZFcCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgECZmIABAJkVwkAoggBCQEBVgADCQABAgUCZFcCBlN0cmluZwQCZmEFAmRXCQDZBAEFAmZhAwkAAQIFAmRXAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmZjAQJkTAQCZFcJAQJlWgADCQABAgUCZFcCCkJ5dGVWZWN0b3IEAmZkBQJkVwkAAAIIBQJkTA9jYWxsZXJQdWJsaWNLZXkFAmZkAwkAAQIFAmRXAgRVbml0CQAAAggFAmRMBmNhbGxlcgUEdGhpcwkAAgECC01hdGNoIGVycm9yAQJmZQECZEwEAmZmCQACAQIRUGVybWlzc2lvbiBkZW5pZWQEAmRXCQECZVoAAwkAAQIFAmRXAgpCeXRlVmVjdG9yBAJmZAUCZFcDCQAAAggFAmRMD2NhbGxlclB1YmxpY0tleQUCZmQGBQJmZgMJAAECBQJkVwIEVW5pdAMJAAACCAUCZEwGY2FsbGVyBQR0aGlzBgUCZmYJAAIBAgtNYXRjaCBlcnJvch0CZEwBIWNhbGN1bGF0ZUFtb3VudE91dEZvclN3YXBSRUFET05MWQICZmcCZmgEAmZpAwkAAAIFAmZoBwQCZmoJAQJhSAIFBHRoaXMJAQJhZgAEAmZrCQECYUgCBQR0aGlzCQECYWUACQCUCgIFAmZqBQJmawQCZmoJAQJhSAIFBHRoaXMJAQJhZQAEAmZrCQECYUgCBQR0aGlzCQECYWYACQCUCgIFAmZqBQJmawQCZmoIBQJmaQJfMQQCZmsIBQJmaQJfMgQCZmwJAQJiRQEFAmZrBAJmbQkBAmJFAQUCZmoEAmZuCQBrAwUCZm0FAmZnCQBkAgUCZmwFAmZnBAJmbwkAuQICCQC2AgEFAmZsCQC2AgEFAmZtBAJmcAkAuQICCQC3AgIJALYCAQkBAmJFAQUCZmsJALYCAQUCZmcJALgCAgkAtgIBCQECYkUBBQJmagkAtgIBBQJmbgQCZnEDCQDAAgIFAmZwBQJmbwYJAAIBAhRuZXcgSyBpcyBmZXdlciBlcnJvcgMJAAACBQJmcQUCZnEJAJQKAgUDbmlsBQJmbgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEmY2FsY3VsYXRlQW1vdW50T3V0Rm9yU3dhcEFuZFNlbmRUb2tlbnMEAmZnAmZoAmZyAmZzBAJmdAoAAmFSCQD8BwQFAmFPAhdnZXRTd2FwQ29udHJhY3RSRUFET05MWQUDbmlsBQNuaWwDCQABAgUCYVICBlN0cmluZwUCYVIJAAIBCQCsAgIJAAMBBQJhUgIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nBAJlSAkAzAgCAwkAZwIICQEFdmFsdWUBCQCRAwIIBQJkTAhwYXltZW50cwAABmFtb3VudAUCZmcGCQECYUwBAgxXcm9uZyBhbW91bnQJAMwIAgMJAAACCAUCZEwGY2FsbGVyCQERQGV4dHJOYXRpdmUoMTA2MikBBQJmdAYJAQJhTAECEVBlcm1pc3Npb24gZGVuaWVkBQNuaWwDCQAAAgUCZUgFAmVIBAJkTQkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAAQCZmsDCQAAAggFAmRNB2Fzc2V0SWQFBHVuaXQJANgEAQkAmwMBAgVXQVZFUwkA2AQBCQEFdmFsdWUBCAUCZE0HYXNzZXRJZAQCZmoDCQAAAgUCZmgHCQECYUgCBQR0aGlzCQECYWYACQECYUgCBQR0aGlzCQECYWUABAJmbAkAZQIJAQJiRQEFAmZrCAkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAAZhbW91bnQEAmZtCQECYkUBBQJmagQCZm4JAGsDBQJmbQUCZmcJAGQCBQJmbAUCZmcEAmZvCQC5AgIJALYCAQUCZmwJALYCAQUCZm0EAmZwCQC5AgIJALYCAQkBAmJFAQUCZmsJALgCAgkAtgIBCQECYkUBBQJmagkAtgIBBQJmbgQCZnEDCQDAAgIFAmZwBQJmbwYJAAIBAhRuZXcgSyBpcyBmZXdlciBlcnJvcgMJAAACBQJmcQUCZnEEAmZ1AwkAZwIFAmZuBQJmcgYJAAIBAixFeGNoYW5nZSByZXN1bHQgaXMgZmV3ZXIgY29pbnMgdGhhbiBleHBlY3RlZAMJAAACBQJmdQUCZnUJAJQKAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQJmcwUCZm4JAQJhWQEFAmZqBQNuaWwFAmZuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRMAQpzZXRNYW5hZ2VyAQJmdgQCZncJAQJmZQEFAmRMAwkAAAIFAmZ3BQJmdwQCZngJANkEAQUCZnYDCQAAAgUCZngFAmZ4CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFWAAUCZnYFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEOY29uZmlybU1hbmFnZXIABAJmeQkBAmZiAAQCZnoDCQEJaXNEZWZpbmVkAQUCZnkGCQACAQISTm8gcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmZ6BQJmegQCZkEDCQAAAggFAmRMD2NhbGxlclB1YmxpY0tleQkBBXZhbHVlAQUCZnkGCQACAQIbWW91IGFyZSBub3QgcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmZBBQJmQQkAzAgCCQELU3RyaW5nRW50cnkCCQEBVQAJANgEAQkBBXZhbHVlAQUCZnkJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAVYABQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEwBA3B1dAICY3oCZkIDCQBmAgAABQJjegkAAgECIEludmFsaWQgc2xpcHBhZ2VUb2xlcmFuY2UgcGFzc2VkBAJkUgkBAmRPAwUCZEwFAmN6BgQCZGIIBQJkUgJfMgQCY2cIBQJkUgJfNwQCY3gIBQJkUgJfOQQCZGMIBQJkUgNfMTAEAmRkCAUCZFIDXzExBAJmQwgFAmRSA18xMgQCZkQIBQJkUgNfMTMEAmRQCQC2AgEICQEFdmFsdWUBCQCRAwIIBQJkTAhwYXltZW50cwAABmFtb3VudAQCZFEJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmRMCHBheW1lbnRzAAEGYW1vdW50BAJkcwkBAmRsAwUCZFAFAmRRCQC2AgEAAAMJAAACBQJkcwUCZHMEAmRVCQD8BwQFAmFPAgRlbWl0CQDMCAIFAmRiBQNuaWwFA25pbAMJAAACBQJkVQUCZFUEAmRWBAJkVwUCZFUDCQABAgUCZFcCB0FkZHJlc3MEAmRYBQJkVwkA/AcEBQJkWAIEZW1pdAkAzAgCBQJkYgUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZFYFAmRWBAJmRQMJAGYCBQJkYwAACQD8BwQFAmJvAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZkMFAmRjBQNuaWwFA25pbAMJAAACBQJmRQUCZkUEAmZGAwkAZgIFAmRkAAAJAPwHBAUCYm8CA3B1dAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJmRAUCZGQFA25pbAUDbmlsAwkAAAIFAmZGBQJmRgQCZkcDBQJmQgQCZkgJAPwHBAUCYm4CBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmNnBQJkYgUDbmlsAwkAAAIFAmZIBQJmSAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJkTAZjYWxsZXIFAmRiBQJjZwUDbmlsBAJmSQkBAmR0AwAAAAAAAAMJAAACBQJmSQUCZkkEAmRrCAUCZkkCXzIEAmZKCAUCZkkCXzEEAmZLCQECZHgCBQJkcwUCZGsDCQAAAgUCZksFAmZLCQDOCAIJAM4IAgUCY3gFAmZHBQJmSgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEKcHV0Rm9yRnJlZQECZkwDCQBmAgAABQJmTAkAAgECFEludmFsaWQgdmFsdWUgcGFzc2VkBAJkUgkBAmRPAwUCZEwFAmZMBwQCY3gIBQJkUgJfOQQCZFAJALYCAQgJAQV2YWx1ZQEJAJEDAggFAmRMCHBheW1lbnRzAAAGYW1vdW50BAJkUQkAtgIBCAkBBXZhbHVlAQkAkQMCCAUCZEwIcGF5bWVudHMAAQZhbW91bnQEAmRzCQECZGwDBQJkUAUCZFEJALYCAQAAAwkAAAIFAmRzBQJkcwQCZk0JAQJkdAMAAAAAAAAEAmZKCAUCZk0CXzEEAmRrCAUCZk0CXzIEAmZLCQECZHgCBQJkcwUCZGsDCQAAAgUCZksFAmZLCQDOCAIFAmN4BQJmSgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEJcHV0T25lVGtuAgJmTgJmTwQCZlAKAAJhUgkA/AcEBQJhTwIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFSAgdCb29sZWFuBQJhUgkAAgEJAKwCAgkAAwEFAmFSAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJmUQMDAwkBAmFUAAYJAAACBQJiZwUBbAYJAAACBQJiZwUBbgYFAmZQBAJlSAkAzAgCAwMJAQEhAQUCZlEGCQECZmMBBQJkTAYJAQJhTAECIXB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmRMCHBheW1lbnRzAAEGCQECYUwBAh5leGFjdGx5IDEgcGF5bWVudCBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJlSAUCZUgEAmZSCQCRAwIIBQJkTAhwYXltZW50cwAABAJlYwgFAmZSB2Fzc2V0SWQEAmViCAUCZlIGYW1vdW50BAJkcwMJAAACBQJlYwUCYmkJAQJkbAMJALYCAQUCZWIJALYCAQAACQC2AgEAAAMJAAACBQJlYwUCYmoJAQJkbAMJALYCAQAACQC2AgEFAmViCQC2AgEAAAkBAmFMAQIecGF5bWVudCBhc3NldCBpcyBub3Qgc3VwcG9ydGVkAwkAAAIFAmRzBQJkcwQCYWIIBQJkTAZjYWxsZXIEAmFjCAUCZEwNdHJhbnNhY3Rpb25JZAQCZlMJAQJlYQQFAmViBQJlYwUCYWIFAmFjAwkAAAIFAmZTBQJmUwQCZWcIBQJmUwJfNQQCZlQIBQJmUwJfNAQCZFoIBQJmUwJfMwQCZGUIBQJmUwJfMgQCZlUIBQJmUwJfMQQCZlYDAwkAZgIFAmZOAAAJAGYCBQJmTgUCZlUHCQECYUwBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZOBQNuaWwCAAUCZlUEAmRVCQECZFMBBQJmVgMJAAACBQJkVQUCZFUEAmZHAwUCZk8EAmZXCQD8BwQFAmJuAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiaAUCZlYFA25pbAMJAAACBQJmVwUCZlcFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZEwGY2FsbGVyBQJmVgUCYmgFA25pbAQCZlgDCQBmAgUCZFoAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhUAUCZFoFAmVjBQNuaWwFA25pbAQCZlkDCQAAAgUEdGhpcwUCYVAJAJQKAgAAAAADBQJlZwkAlAoCCQEBLQEFAmRaAAAJAJQKAgAACQEBLQEFAmRaBAJkdQgFAmZZAl8xBAJkdggFAmZZAl8yBAJmWgkBAmR0AwUCZHUFAmR2AAAEAmZKCAUCZloCXzEEAmRrCAUCZloCXzIEAmRFCQEFdmFsdWUBCQCiCAEFAmFqBAJmSwkBAmR4AgUCZHMFAmRrAwkAAAIFAmZLBQJmSwkAlAoCCQDOCAIJAM4IAgkAzggCBQJkZQUCZkcFAmZYBQJmSgUCZlYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEwBEXB1dE9uZVRrblJFQURPTkxZAgJlYwJlYgQCZ2EJAQJlYQQFAmViCQECYVkBBQJlYwUEdW5pdAUEdW5pdAQCZlUIBQJnYQJfMQQCZGUIBQJnYQJfMgQCZFoIBQJnYQJfMwQCZlQIBQJnYQJfNAQCZWcIBQJnYQJfNQkAlAoCBQNuaWwJAJUKAwUCZlUFAmRaBQJmVAJkTAEJZ2V0T25lVGtuAgJnYgJmTgQCZlAKAAJhUgkA/AcEBQJhTwIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFSAgdCb29sZWFuBQJhUgkAAgEJAKwCAgkAAwEFAmFSAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJnYwMDCQECYVQABgkAAAIFAmJnBQFuBgUCZlAEAmVICQDMCAIDAwkBASEBBQJnYwYJAQJmYwEFAmRMBgkBAmFMAQIhZ2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCZEwIcGF5bWVudHMAAQYJAQJhTAECHmV4YWN0bHkgMSBwYXltZW50IGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmVIBQJlSAQCZUcJAQJhWQEFAmdiBAJmUgkAkQMCCAUCZEwIcGF5bWVudHMAAAQCZWMIBQJmUgdhc3NldElkBAJlbwgFAmZSBmFtb3VudAQCZHMJAQJkbAMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZHMFAmRzBAJhYggFAmRMBmNhbGxlcgQCYWMIBQJkTA10cmFuc2FjdGlvbklkBAJnZAkBAmVGBQUCZUcFAmVvBQJlYwUCYWIFAmFjAwkAAAIFAmdkBQJnZAQCZUkIBQJnZAJfNQQCZlQIBQJnZAJfNAQCZFoIBQJnZAJfMwQCZGUIBQJnZAJfMgQCZ2UIBQJnZAJfMQQCZFQDAwkAZgIFAmZOAAAJAGYCBQJmTgUCZ2UHCQECYUwBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZOBQNuaWwCAAUCZ2UEAmdmCQD8BwQFAmFPAgRidXJuCQDMCAIFAmVvBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmVjBQJlbwUDbmlsAwkAAAIFAmdmBQJnZgQCZ2cJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYWIFAmRUBQJlRwUDbmlsBAJmWAMJAGYCBQJkWgAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFQBQJkWgUCZUcFA25pbAUDbmlsBAJnaAQCZ2kDCQAAAgUEdGhpcwUCYVAAAAUCZFoDBQJlSQkAlAoCCQEBLQEJAGQCBQJkVAUCZ2kAAAkAlAoCAAAJAQEtAQkAZAIFAmRUBQJnaQQCZHUIBQJnaAJfMQQCZHYIBQJnaAJfMgQCZ2oJAQJkdAMFAmR1BQJkdgAABAJmSggFAmdqAl8xBAJkawgFAmdqAl8yBAJmSwkBAmR4AgUCZHMFAmRrAwkAAAIFAmZLBQJmSwkAlAoCCQDOCAIJAM4IAgkAzggCBQJkZQUCZ2cFAmZYBQJmSgUCZFQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEwBEWdldE9uZVRrblJFQURPTkxZAgJlRwJlbwQCZ2sJAQJlRgUJAQJhWQEFAmVHBQJlbwUCYmgFBHVuaXQFBHVuaXQEAmdlCAUCZ2sCXzEEAmRlCAUCZ2sCXzIEAmRaCAUCZ2sCXzMEAmZUCAUCZ2sCXzQEAmVJCAUCZ2sCXzUJAJQKAgUDbmlsCQCVCgMFAmdlBQJkWgUCZlQCZEwBE3Vuc3Rha2VBbmRHZXRPbmVUa24DAmdsAmdiAmZOBAJmUAoAAmFSCQD8BwQFAmFPAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYVICB0Jvb2xlYW4FAmFSCQACAQkArAICCQADAQUCYVICHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmdjAwMJAQJhVAAGCQAAAgUCYmcFAW4GBQJmUAQCZUgJAMwIAgMDCQEBIQEFAmdjBgkBAmZjAQUCZEwGCQECYUwBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJkTAhwYXltZW50cwAABgkBAmFMAQIYbm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZUgFAmVIBAJlRwkBAmFZAQUCZ2IEAmFiCAUCZEwGY2FsbGVyBAJhYwgFAmRMDXRyYW5zYWN0aW9uSWQEAmRzCQECZGwDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmRzBQJkcwQCZ20JAPwHBAUCYm4CB3Vuc3Rha2UJAMwIAgkA2AQBBQJiaAkAzAgCBQJnbAUDbmlsBQNuaWwDCQAAAgUCZ20FAmdtBAJnbgkBAmVGBQUCZUcFAmdsBQJiaAUCYWIFAmFjAwkAAAIFAmduBQJnbgQCZUkIBQJnbgJfNQQCZlQIBQJnbgJfNAQCZFoIBQJnbgJfMwQCZGUIBQJnbgJfMgQCZ2UIBQJnbgJfMQQCZFQDAwkAZgIFAmZOAAAJAGYCBQJmTgUCZ2UHCQECYUwBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZOBQNuaWwCAAUCZ2UEAmdmCQD8BwQFAmFPAgRidXJuCQDMCAIFAmdsBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJoBQJnbAUDbmlsAwkAAAIFAmdmBQJnZgQCZ2cJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmRMBmNhbGxlcgUCZFQFAmVHBQNuaWwEAmZYAwkAZgIFAmRaAAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYVAFAmRaBQJlRwUDbmlsBQNuaWwEAmdvBAJnaQMJAAACBQR0aGlzBQJhUAAABQJkWgMFAmVJCQCUCgIJAQEtAQkAZAIFAmRUBQJnaQAACQCUCgIAAAkBAS0BCQBkAgUCZFQFAmdpBAJkdQgFAmdvAl8xBAJkdggFAmdvAl8yBAJncAkBAmR0AwUCZHUFAmR2AAAEAmZKCAUCZ3ACXzEEAmRrCAUCZ3ACXzIEAmZLCQECZHgCBQJkcwUCZGsDCQAAAgUCZksFAmZLCQCUCgIJAM4IAgkAzggCCQDOCAIFAmRlBQJnZwUCZlgFAmZKBQJkVAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEDZ2V0AAQCY1AJAQJkSwEFAmRMBAJncQgFAmNQAl8xBAJjdwgFAmNQAl8yBAJkTggFAmNQAl8zBAJjZQgFAmNQAl80BAJjeAgFAmNQAl81BAJkcwkBAmRsAwkAtgIBAAAJALYCAQAACQC2AgEAAAMJAAACBQJkcwUCZHMEAmdyCQD8BwQFAmFPAgRidXJuCQDMCAIFAmROBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmNlBQJkTgUDbmlsAwkAAAIFAmdyBQJncgQCZ3MJAQJkdAMJAQEtAQUCZ3EJAQEtAQUCY3cAAAQCZkoIBQJncwJfMQQCZGsIBQJncwJfMgQCZksJAQJkeAIFAmRzBQJkawMJAAACBQJmSwUCZksJAM4IAgUCY3gFAmZKCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRMAQlnZXROb0xlc3MCAmd0Amd1BAJjUAkBAmRLAQUCZEwEAmN2CAUCY1ACXzEEAmN3CAUCY1ACXzIEAmROCAUCY1ACXzMEAmNlCAUCY1ACXzQEAmN4CAUCY1ACXzUDCQBmAgUCZ3QFAmN2CQACAQkArAICCQCsAgIJAKwCAgIcbm9MZXNzVGhlbkFtdEFzc2V0IGZhaWxlZDogIAkApAMBBQJjdgIDIDwgCQCkAwEFAmd0AwkAZgIFAmd1BQJjdwkAAgEJAKwCAgkArAICCQCsAgICHW5vTGVzc1RoZW5QcmljZUFzc2V0IGZhaWxlZDogCQCkAwEFAmN3AgMgPCAJAKQDAQUCZ3UEAmRzCQECZGwDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmRzBQJkcwQCZ3IJAPwHBAUCYU8CBGJ1cm4JAMwIAgUCZE4FA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCY2UFAmROBQNuaWwDCQAAAgUCZ3IFAmdyBAJndgkBAmR0AwkBAS0BBQJjdgkBAS0BBQJjdwAABAJmSggFAmd2Al8xBAJkawgFAmd2Al8yBAJmSwkBAmR4AgUCZHMFAmRrAwkAAAIFAmZLBQJmSwkAzggCBQJjeAUCZkoJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEwBDXVuc3Rha2VBbmRHZXQBAmRUBAJndwMJAQIhPQIJAJADAQgFAmRMCHBheW1lbnRzAAAJAAIBAhhObyBwYXltZW50cyBhcmUgZXhwZWN0ZWQGAwkAAAIFAmd3BQJndwQCYlQJAQJhVgAEAmNnCQDZBAEJAJEDAgUCYlQFAXEEAmRzCQECZGwDCQC2AgEAAAkAtgIBAAAJALYCAQAAAwkAAAIFAmRzBQJkcwQCZ20JAPwHBAUCYm4CB3Vuc3Rha2UJAMwIAgkA2AQBBQJjZwkAzAgCBQJkVAUDbmlsBQNuaWwDCQAAAgUCZ20FAmdtBAJjUAkBAmNjBAkA2AQBCAUCZEwNdHJhbnNhY3Rpb25JZAkA2AQBBQJjZwUCZFQIBQJkTAZjYWxsZXIEAmN2CAUCY1ACXzEEAmN3CAUCY1ACXzIEAmNqCQENcGFyc2VJbnRWYWx1ZQEIBQJjUAJfOQQCY3gIBQJjUANfMTAEAmd4AwMJAQJhVAAGCQAAAgUCY2oFAW4JAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmNqBgMJAAACBQJneAUCZ3gEAmdyCQD8BwQFAmFPAgRidXJuCQDMCAIFAmRUBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmNnBQJkVAUDbmlsAwkAAAIFAmdyBQJncgQCZ3kJAQJkdAMJAQEtAQUCY3YJAQEtAQUCY3cAAAQCZkoIBQJneQJfMQQCZGsIBQJneQJfMgQCZksJAQJkeAIFAmRzBQJkawMJAAACBQJmSwUCZksJAM4IAgUCY3gFAmZKCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRMARN1bnN0YWtlQW5kR2V0Tm9MZXNzAwJnbAJnegJndQQCZ2MDCQECYVQABgkAAAIFAmJnBQFuBAJlSAkAzAgCAwkBASEBBQJnYwYJAAIBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJkTAhwYXltZW50cwAABgkAAgECGG5vIHBheW1lbnRzIGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmVIBQJlSAQCZHMJAQJkbAMJALYCAQAACQC2AgEAAAkAtgIBAAADCQAAAgUCZHMFAmRzBAJnbQkA/AcEBQJibgIHdW5zdGFrZQkAzAgCCQDYBAEFAmJoCQDMCAIFAmdsBQNuaWwFA25pbAMJAAACBQJnbQUCZ20EAmNQCQECY2MECQDYBAEIBQJkTA10cmFuc2FjdGlvbklkCQDYBAEFAmJoBQJnbAgFAmRMBmNhbGxlcgQCY3YIBQJjUAJfMQQCY3cIBQJjUAJfMgQCY3gIBQJjUANfMTAEAmdBCQDMCAIDCQBnAgUCY3YFAmd6BgkAAgEJALkJAgkAzAgCAixhbW91bnQgYXNzZXQgYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmd6BQNuaWwCAAkAzAgCAwkAZwIFAmN3BQJndQYJAAIBCQC5CQIJAMwIAgIrcHJpY2UgYXNzZXQgYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmd1BQNuaWwCAAUDbmlsAwkAAAIFAmdBBQJnQQQCZ3IJAPwHBAUCYU8CBGJ1cm4JAMwIAgUCZ2wFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYmgFAmdsBQNuaWwDCQAAAgUCZ3IFAmdyBAJnQgkBAmR0AwkBAS0BBQJjdgkBAS0BBQJjdwAABAJmSggFAmdCAl8xBAJkawgFAmdCAl8yBAJmSwkBAmR4AgUCZHMFAmRrAwkAAAIFAmZLBQJmSwkAzggCBQJjeAUCZkoJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZEwBCGFjdGl2YXRlAgJnQwJnRAMJAQIhPQIJAKUIAQgFAmRMBmNhbGxlcgkApQgBBQJhTwkAAgECEnBlcm1pc3Npb25zIGRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZQAFAmdDCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZgAFAmdEBQNuaWwCB3N1Y2Nlc3MCZEwBCnJlZnJlc2hLTHAABAJnRQkBC3ZhbHVlT3JFbHNlAgkAnwgBBQJhawAABAJnRgMJAGcCCQBlAgUGaGVpZ2h0BQJnRQUCYW4FBHVuaXQJAQJhTAEJALkJAgkAzAgCCQCkAwEFAmFuCQDMCAICLyBibG9ja3MgaGF2ZSBub3QgcGFzc2VkIHNpbmNlIHRoZSBwcmV2aW91cyBjYWxsBQNuaWwCAAMJAAACBQJnRgUCZ0YEAmRFCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKgDAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQJhagIBMAkBAmFOAQILaW52YWxpZCBrTHAEAmdHCQECZHQDAAAAAAAABAJnSAgFAmdHAl8xBAJkawgFAmdHAl8yBAJkdwMJAQIhPQIFAmRFBQJkawUCZ0gJAQJhTAECEm5vdGhpbmcgdG8gcmVmcmVzaAkAlAoCBQJkdwkApgMBBQJkawkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkTAEcZ2V0UG9vbENvbmZpZ1dyYXBwZXJS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BQJjagkAzAgCCQCkAwEFAmNBCQDMCAIJAKQDAQUCY0MFA25pbAUBagJkTAETZXZhbHVhdGVHZXRSRUFET05MWQICZ1cCZ1gEAmNQCQECY2MEAgAFAmdXBQJnWAUEdGhpcwQCY3YIBQJjUAJfMQQCY3cIBQJjUAJfMgQCY2wIBQJjUAJfNQQCY24IBQJjUAJfNgQCY2sIBQJjUAJfNwQCY3EIBQJjUAJfOAQCY2oJAQ1wYXJzZUludFZhbHVlAQgFAmNQAl85CQCUCgIFA25pbAkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCY3YJAMwIAgkApAMBBQJjdwkAzAgCCQCkAwEFAmNsCQDMCAIJAKQDAQUCY24JAMwIAgkApAMBBQJjawkAzAgCCQCmAwEFAmNxCQDMCAIJAKQDAQUCY2oFA25pbAUBagECZ1kBAmdaAAQCaGEEAmRXCQECZVoAAwkAAQIFAmRXAgpCeXRlVmVjdG9yBAJmZAUCZFcFAmZkAwkAAQIFAmRXAgRVbml0CAUCZ1kPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IEAmRXBQJnWQMJAAECBQJkVwIFT3JkZXIEAmRBBQJkVwQCaGIJAQJhVQAEAmhjCQECZHoBBQJkQQQCYUQIBQJoYwJfMQQCYUUIBQJoYwJfMgQCYUYJAPQDAwgFAmRBCWJvZHlCeXRlcwkAkQMCCAUCZEEGcHJvb2ZzAAAIBQJkQQ9zZW5kZXJQdWJsaWNLZXkEAmFHCQD0AwMIBQJkQQlib2R5Qnl0ZXMJAJEDAggFAmRBBnByb29mcwABBQJoYgMDAwUCYUQFAmFGBwUCYUcHBgkBAmFDBAUCYUQFAmFFBQJhRgUCYUcDCQABAgUCZFcCFFNldFNjcmlwdFRyYW5zYWN0aW9uBAJmYQUCZFcDCQD0AwMIBQJnWQlib2R5Qnl0ZXMJAJEDAggFAmdZBnByb29mcwAABQJoYQYEAmhkCQD2AwEJAQV2YWx1ZQEIBQJmYQZzY3JpcHQEAmhlCQDbBAEJAQV2YWx1ZQEJAJ0IAgUCYU8JAQJhQQAEAmhmCQDxBwEFBHRoaXMDCQAAAgUCaGUFAmhkCQECIT0CBQJoZgUCaGQHCQD0AwMIBQJnWQlib2R5Qnl0ZXMJAJEDAggFAmdZBnByb29mcwAABQJoYdSzfpw=", "height": 2442511, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: H6KaSV79q6U8himNxYJkhm3ivk6H51theadhdYM9zcEY Next: FNDWQgACqbnPFxcRw99WZLe6UFZG753sLRkhhFKsFk1A Diff:
OldNewDifferences
8282 func absBigInt (val) = if ((zeroBigInt > val))
8383 then -(val)
8484 else val
85+
86+
87+func swapContract () = "%s__swapContract"
8588
8689
8790 func fc () = "%s__factoryContract"
216219
217220 let poolConfigParsed = parsePoolConfig(getPoolConfig())
218221
219-let $t084088574 = poolConfigParsed
222+let $t084698635 = poolConfigParsed
220223
221-let cfgPoolAddress = $t084088574._1
224+let cfgPoolAddress = $t084698635._1
222225
223-let cfgPoolStatus = $t084088574._2
226+let cfgPoolStatus = $t084698635._2
224227
225-let cfgLpAssetId = $t084088574._3
228+let cfgLpAssetId = $t084698635._3
226229
227-let cfgAmountAssetId = $t084088574._4
230+let cfgAmountAssetId = $t084698635._4
228231
229-let cfgPriceAssetId = $t084088574._5
232+let cfgPriceAssetId = $t084698635._5
230233
231-let cfgAmountAssetDecimals = $t084088574._6
234+let cfgAmountAssetDecimals = $t084698635._6
232235
233-let cfgPriceAssetDecimals = $t084088574._7
236+let cfgPriceAssetDecimals = $t084698635._7
234237
235238 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
236239
435438 let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
436439 let amountAssetAmount = order.amount
437440 let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
438- let $t02148021692 = if ((order.orderType == Buy))
441+ let $t02154121753 = if ((order.orderType == Buy))
439442 then $Tuple2(amountAssetAmount, -(priceAssetAmount))
440443 else $Tuple2(-(amountAssetAmount), priceAssetAmount)
441- let amountAssetBalanceDelta = $t02148021692._1
442- let priceAssetBalanceDelta = $t02148021692._2
444+ let amountAssetBalanceDelta = $t02154121753._1
445+ let priceAssetBalanceDelta = $t02154121753._2
443446 if (if (if (isGlobalShutdown())
444447 then true
445448 else (cfgPoolStatus == PoolMatcherDisabled))
452455 then throw("Wrong order assets.")
453456 else {
454457 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
455- let $t02213222232 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
456- let unusedActions = $t02213222232._1
457- let kLpNew = $t02213222232._2
458+ let $t02219322293 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
459+ let unusedActions = $t02219322293._1
460+ let kLpNew = $t02219322293._2
458461 let isOrderValid = (kLpNew >= kLp)
459462 let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
460463 $Tuple2(isOrderValid, info)
533536 else if ((paymentAssetId == cfgPriceAssetId))
534537 then false
535538 else throwErr("invalid asset")
536- let $t02534525638 = if (isEval)
539+ let $t02540625699 = if (isEval)
537540 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
538541 else if (paymentInAmountAsset)
539542 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
540543 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
541- let amountBalanceOld = $t02534525638._1
542- let priceBalanceOld = $t02534525638._2
543- let $t02564225791 = if (paymentInAmountAsset)
544+ let amountBalanceOld = $t02540625699._1
545+ let priceBalanceOld = $t02540625699._2
546+ let $t02570325852 = if (paymentInAmountAsset)
544547 then $Tuple2(paymentAmountRaw, 0)
545548 else $Tuple2(0, paymentAmountRaw)
546- let amountAssetAmountRaw = $t02564225791._1
547- let priceAssetAmountRaw = $t02564225791._2
549+ let amountAssetAmountRaw = $t02570325852._1
550+ let priceAssetAmountRaw = $t02570325852._2
548551 let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
549552 let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
550- let $t02592325987 = takeFee(paymentAmountRaw, inFee)
551- let paymentAmount = $t02592325987._1
552- let feeAmount = $t02592325987._2
553+ let $t02598426048 = takeFee(paymentAmountRaw, inFee)
554+ let paymentAmount = $t02598426048._1
555+ let feeAmount = $t02598426048._2
553556 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
554557 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
555558 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
572575 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
573576 let priceOld = fromX18(priceOldX18, scale8)
574577 let loss = {
575- let $t02766827835 = if (paymentInAmountAsset)
578+ let $t02772927896 = if (paymentInAmountAsset)
576579 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
577580 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
578- let amount = $t02766827835._1
579- let balance = $t02766827835._2
581+ let amount = $t02772927896._1
582+ let balance = $t02772927896._2
580583 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
581584 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
582585 }
616619 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
617620 let redeemedBigInt = toBigInt(paymentAmount)
618621 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
619- let $t02991329969 = takeFee(amountRaw, outFee)
620- let totalAmount = $t02991329969._1
621- let feeAmount = $t02991329969._2
622- let $t02997330199 = if (outInAmountAsset)
622+ let $t02997430030 = takeFee(amountRaw, outFee)
623+ let totalAmount = $t02997430030._1
624+ let feeAmount = $t02997430030._2
625+ let $t03003430260 = if (outInAmountAsset)
623626 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
624627 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
625- let outAmAmount = $t02997330199._1
626- let outPrAmount = $t02997330199._2
627- let amBalanceNew = $t02997330199._3
628- let prBalanceNew = $t02997330199._4
628+ let outAmAmount = $t03003430260._1
629+ let outPrAmount = $t03003430260._2
630+ let amBalanceNew = $t03003430260._3
631+ let prBalanceNew = $t03003430260._4
629632 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
630633 let priceNew = fromX18(priceNewX18, scale8)
631634 let commonState = if (isEval)
688691 throw("Match error")
689692 }
690693 }
694+
695+
696+@Callable(i)
697+func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse) = {
698+ let $t03195532260 = if ((isReverse == false))
699+ then {
700+ let assetOut = getStringOrFail(this, pa())
701+ let assetIn = getStringOrFail(this, aa())
702+ $Tuple2(assetOut, assetIn)
703+ }
704+ else {
705+ let assetOut = getStringOrFail(this, aa())
706+ let assetIn = getStringOrFail(this, pa())
707+ $Tuple2(assetOut, assetIn)
708+ }
709+ let assetOut = $t03195532260._1
710+ let assetIn = $t03195532260._2
711+ let poolAssetInBalance = getAccBalance(assetIn)
712+ let poolAssetOutBalance = getAccBalance(assetOut)
713+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
714+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
715+ let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
716+ let checkK = if ((newK >= oldK))
717+ then true
718+ else throw("new K is fewer error")
719+ if ((checkK == checkK))
720+ then $Tuple2(nil, amountOut)
721+ else throw("Strict value is not equal to itself.")
722+ }
723+
724+
725+
726+@Callable(i)
727+func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo) = {
728+ let swapContact = {
729+ let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil)
730+ if ($isInstanceOf(@, "String"))
731+ then @
732+ else throw(($getType(@) + " couldn't be cast to String"))
733+ }
734+ let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
735+ then true
736+ else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
737+ then true
738+ else throwErr("Permission denied")]
739+ if ((checks == checks))
740+ then {
741+ let pmt = value(i.payments[0])
742+ let assetIn = if ((pmt.assetId == unit))
743+ then toBase58String(toBytes("WAVES"))
744+ else toBase58String(value(pmt.assetId))
745+ let assetOut = if ((isReverse == false))
746+ then getStringOrFail(this, pa())
747+ else getStringOrFail(this, aa())
748+ let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
749+ let poolAssetOutBalance = getAccBalance(assetOut)
750+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
751+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
752+ let newK = (toBigInt(getAccBalance(assetIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
753+ let checkK = if ((newK >= oldK))
754+ then true
755+ else throw("new K is fewer error")
756+ if ((checkK == checkK))
757+ then {
758+ let checkMin = if ((amountOut >= amountOutMin))
759+ then true
760+ else throw("Exchange result is fewer coins than expected")
761+ if ((checkMin == checkMin))
762+ then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))], amountOut)
763+ else throw("Strict value is not equal to itself.")
764+ }
765+ else throw("Strict value is not equal to itself.")
766+ }
767+ else throw("Strict value is not equal to itself.")
768+ }
769+
691770
692771
693772 @Callable(i)
771850 else throw("Strict value is not equal to itself.")
772851 }
773852 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
774- let $t03472735189 = refreshKLpInternal(0, 0, 0)
775- if (($t03472735189 == $t03472735189))
853+ let $t03714537607 = refreshKLpInternal(0, 0, 0)
854+ if (($t03714537607 == $t03714537607))
776855 then {
777- let updatedKLp = $t03472735189._2
778- let refreshKLpActions = $t03472735189._1
856+ let updatedKLp = $t03714537607._2
857+ let refreshKLpActions = $t03714537607._1
779858 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
780859 if ((isUpdatedKLpValid == isUpdatedKLpValid))
781860 then ((state ++ lpTransfer) ++ refreshKLpActions)
807886 let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
808887 if ((currentKLp == currentKLp))
809888 then {
810- let $t03575135816 = refreshKLpInternal(0, 0, 0)
811- let refreshKLpActions = $t03575135816._1
812- let updatedKLp = $t03575135816._2
889+ let $t03816938234 = refreshKLpInternal(0, 0, 0)
890+ let refreshKLpActions = $t03816938234._1
891+ let updatedKLp = $t03816938234._2
813892 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
814893 if ((isUpdatedKLpValid == isUpdatedKLpValid))
815894 then (state ++ refreshKLpActions)
856935 then {
857936 let userAddress = i.caller
858937 let txId = i.transactionId
859- let $t03700437156 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
860- if (($t03700437156 == $t03700437156))
938+ let $t03942239574 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
939+ if (($t03942239574 == $t03942239574))
861940 then {
862- let paymentInAmountAsset = $t03700437156._5
863- let bonus = $t03700437156._4
864- let feeAmount = $t03700437156._3
865- let commonState = $t03700437156._2
866- let emitAmountEstimated = $t03700437156._1
941+ let paymentInAmountAsset = $t03942239574._5
942+ let bonus = $t03942239574._4
943+ let feeAmount = $t03942239574._3
944+ let commonState = $t03942239574._2
945+ let emitAmountEstimated = $t03942239574._1
867946 let emitAmount = if (if ((minOutAmount > 0))
868947 then (minOutAmount > emitAmountEstimated)
869948 else false)
883962 let sendFee = if ((feeAmount > 0))
884963 then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
885964 else nil
886- let $t03774237939 = if ((this == feeCollectorAddress))
965+ let $t04016040357 = if ((this == feeCollectorAddress))
887966 then $Tuple2(0, 0)
888967 else if (paymentInAmountAsset)
889968 then $Tuple2(-(feeAmount), 0)
890969 else $Tuple2(0, -(feeAmount))
891- let amountAssetBalanceDelta = $t03774237939._1
892- let priceAssetBalanceDelta = $t03774237939._2
893- let $t03794238050 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
894- let refreshKLpActions = $t03794238050._1
895- let updatedKLp = $t03794238050._2
970+ let amountAssetBalanceDelta = $t04016040357._1
971+ let priceAssetBalanceDelta = $t04016040357._2
972+ let $t04036040468 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
973+ let refreshKLpActions = $t04036040468._1
974+ let updatedKLp = $t04036040468._2
896975 let kLp = value(getString(keyKLp))
897976 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
898977 if ((isUpdatedKLpValid == isUpdatedKLpValid))
912991
913992 @Callable(i)
914993 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
915- let $t03835638513 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
916- let emitAmountEstimated = $t03835638513._1
917- let commonState = $t03835638513._2
918- let feeAmount = $t03835638513._3
919- let bonus = $t03835638513._4
920- let paymentInAmountAsset = $t03835638513._5
994+ let $t04077440931 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
995+ let emitAmountEstimated = $t04077440931._1
996+ let commonState = $t04077440931._2
997+ let feeAmount = $t04077440931._3
998+ let bonus = $t04077440931._4
999+ let paymentInAmountAsset = $t04077440931._5
9211000 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
9221001 }
9231002
9541033 then {
9551034 let userAddress = i.caller
9561035 let txId = i.transactionId
957- let $t03939839551 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
958- if (($t03939839551 == $t03939839551))
1036+ let $t04181641969 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1037+ if (($t04181641969 == $t04181641969))
9591038 then {
960- let outInAmountAsset = $t03939839551._5
961- let bonus = $t03939839551._4
962- let feeAmount = $t03939839551._3
963- let commonState = $t03939839551._2
964- let amountEstimated = $t03939839551._1
1039+ let outInAmountAsset = $t04181641969._5
1040+ let bonus = $t04181641969._4
1041+ let feeAmount = $t04181641969._3
1042+ let commonState = $t04181641969._2
1043+ let amountEstimated = $t04181641969._1
9651044 let amount = if (if ((minOutAmount > 0))
9661045 then (minOutAmount > amountEstimated)
9671046 else false)
9741053 let sendFee = if ((feeAmount > 0))
9751054 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
9761055 else nil
977- let $t04005140298 = {
1056+ let $t04246942716 = {
9781057 let feeAmountForCalc = if ((this == feeCollectorAddress))
9791058 then 0
9801059 else feeAmount
9821061 then $Tuple2(-((amount + feeAmountForCalc)), 0)
9831062 else $Tuple2(0, -((amount + feeAmountForCalc)))
9841063 }
985- let amountAssetBalanceDelta = $t04005140298._1
986- let priceAssetBalanceDelta = $t04005140298._2
987- let $t04030140409 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
988- let refreshKLpActions = $t04030140409._1
989- let updatedKLp = $t04030140409._2
1064+ let amountAssetBalanceDelta = $t04246942716._1
1065+ let priceAssetBalanceDelta = $t04246942716._2
1066+ let $t04271942827 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1067+ let refreshKLpActions = $t04271942827._1
1068+ let updatedKLp = $t04271942827._2
9901069 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
9911070 if ((isUpdatedKLpValid == isUpdatedKLpValid))
9921071 then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
10051084
10061085 @Callable(i)
10071086 func getOneTknREADONLY (outAssetId,paymentAmount) = {
1008- let $t04066640822 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1009- let amountEstimated = $t04066640822._1
1010- let commonState = $t04066640822._2
1011- let feeAmount = $t04066640822._3
1012- let bonus = $t04066640822._4
1013- let outInAmountAsset = $t04066640822._5
1087+ let $t04308443240 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1088+ let amountEstimated = $t04308443240._1
1089+ let commonState = $t04308443240._2
1090+ let feeAmount = $t04308443240._3
1091+ let bonus = $t04308443240._4
1092+ let outInAmountAsset = $t04308443240._5
10141093 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
10151094 }
10161095
10471126 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
10481127 if ((unstakeInv == unstakeInv))
10491128 then {
1050- let $t04172741878 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1051- if (($t04172741878 == $t04172741878))
1129+ let $t04414544296 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1130+ if (($t04414544296 == $t04414544296))
10521131 then {
1053- let outInAmountAsset = $t04172741878._5
1054- let bonus = $t04172741878._4
1055- let feeAmount = $t04172741878._3
1056- let commonState = $t04172741878._2
1057- let amountEstimated = $t04172741878._1
1132+ let outInAmountAsset = $t04414544296._5
1133+ let bonus = $t04414544296._4
1134+ let feeAmount = $t04414544296._3
1135+ let commonState = $t04414544296._2
1136+ let amountEstimated = $t04414544296._1
10581137 let amount = if (if ((minOutAmount > 0))
10591138 then (minOutAmount > amountEstimated)
10601139 else false)
10671146 let sendFee = if ((feeAmount > 0))
10681147 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
10691148 else nil
1070- let $t04237342620 = {
1149+ let $t04479145038 = {
10711150 let feeAmountForCalc = if ((this == feeCollectorAddress))
10721151 then 0
10731152 else feeAmount
10751154 then $Tuple2(-((amount + feeAmountForCalc)), 0)
10761155 else $Tuple2(0, -((amount + feeAmountForCalc)))
10771156 }
1078- let amountAssetBalanceDelta = $t04237342620._1
1079- let priceAssetBalanceDelta = $t04237342620._2
1080- let $t04262342731 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1081- let refreshKLpActions = $t04262342731._1
1082- let updatedKLp = $t04262342731._2
1157+ let amountAssetBalanceDelta = $t04479145038._1
1158+ let priceAssetBalanceDelta = $t04479145038._2
1159+ let $t04504145149 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1160+ let refreshKLpActions = $t04504145149._1
1161+ let updatedKLp = $t04504145149._2
10831162 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
10841163 if ((isUpdatedKLpValid == isUpdatedKLpValid))
10851164 then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
11121191 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
11131192 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11141193 then {
1115- let $t04367743759 = refreshKLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1116- let refreshKLpActions = $t04367743759._1
1117- let updatedKLp = $t04367743759._2
1194+ let $t04609546177 = refreshKLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1195+ let refreshKLpActions = $t04609546177._1
1196+ let updatedKLp = $t04609546177._2
11181197 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11191198 if ((isUpdatedKLpValid == isUpdatedKLpValid))
11201199 then (state ++ refreshKLpActions)
11461225 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
11471226 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11481227 then {
1149- let $t04470844789 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1150- let refreshKLpActions = $t04470844789._1
1151- let updatedKLp = $t04470844789._2
1228+ let $t04712647207 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1229+ let refreshKLpActions = $t04712647207._1
1230+ let updatedKLp = $t04712647207._2
11521231 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11531232 if ((isUpdatedKLpValid == isUpdatedKLpValid))
11541233 then (state ++ refreshKLpActions)
11921271 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
11931272 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11941273 then {
1195- let $t04591545996 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1196- let refreshKLpActions = $t04591545996._1
1197- let updatedKLp = $t04591545996._2
1274+ let $t04833348414 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1275+ let refreshKLpActions = $t04833348414._1
1276+ let updatedKLp = $t04833348414._2
11981277 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11991278 if ((isUpdatedKLpValid == isUpdatedKLpValid))
12001279 then (state ++ refreshKLpActions)
12451324 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
12461325 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
12471326 then {
1248- let $t04729147372 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1249- let refreshKLpActions = $t04729147372._1
1250- let updatedKLp = $t04729147372._2
1327+ let $t04970949790 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1328+ let refreshKLpActions = $t04970949790._1
1329+ let updatedKLp = $t04970949790._2
12511330 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
12521331 if ((isUpdatedKLpValid == isUpdatedKLpValid))
12531332 then (state ++ refreshKLpActions)
12821361 if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
12831362 then {
12841363 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1285- let $t04855948623 = refreshKLpInternal(0, 0, 0)
1286- let kLpUpdateActions = $t04855948623._1
1287- let updatedKLp = $t04855948623._2
1364+ let $t05097751041 = refreshKLpInternal(0, 0, 0)
1365+ let kLpUpdateActions = $t05097751041._1
1366+ let updatedKLp = $t05097751041._2
12881367 let actions = if ((kLp != updatedKLp))
12891368 then kLpUpdateActions
12901369 else throwErr("nothing to refresh")
14591538 match tx {
14601539 case order: Order =>
14611540 let matcherPub = getMatcherPubOrFail()
1462- let $t05728557354 = validateMatcherOrderAllowed(order)
1463- let orderValid = $t05728557354._1
1464- let orderValidInfo = $t05728557354._2
1541+ let $t05970359772 = validateMatcherOrderAllowed(order)
1542+ let orderValid = $t05970359772._1
1543+ let orderValidInfo = $t05970359772._2
14651544 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
14661545 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
14671546 if (if (if (orderValid)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let lPdecimals = 8
55
66 let scale8 = 100000000
77
88 let scale8BigInt = toBigInt(100000000)
99
1010 let scale18 = toBigInt(1000000000000000000)
1111
1212 let zeroBigInt = toBigInt(0)
1313
1414 let big0 = toBigInt(0)
1515
1616 let big1 = toBigInt(1)
1717
1818 let big2 = toBigInt(2)
1919
2020 let wavesString = "WAVES"
2121
2222 let SEP = "__"
2323
2424 let PoolActive = 1
2525
2626 let PoolPutDisabled = 2
2727
2828 let PoolMatcherDisabled = 3
2929
3030 let PoolShutdown = 4
3131
3232 let idxPoolAddress = 1
3333
3434 let idxPoolStatus = 2
3535
3636 let idxPoolLPAssetId = 3
3737
3838 let idxAmtAssetId = 4
3939
4040 let idxPriceAssetId = 5
4141
4242 let idxAmtAssetDcm = 6
4343
4444 let idxPriceAssetDcm = 7
4545
4646 let idxIAmtAssetId = 8
4747
4848 let idxIPriceAssetId = 9
4949
5050 let idxLPAssetDcm = 10
5151
5252 let idxPoolAmtAssetAmt = 1
5353
5454 let idxPoolPriceAssetAmt = 2
5555
5656 let idxPoolLPAssetAmt = 3
5757
5858 let idxFactoryStakingContract = 1
5959
6060 let idxFactorySlippageContract = 7
6161
6262 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
6363
6464
6565 func toX18BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
6666
6767
6868 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
6969
7070
7171 func fromX18Round (val,resultScaleMult,round) = toInt(fraction(val, toBigInt(resultScaleMult), scale18, round))
7272
7373
7474 func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
7575
7676
7777 func abs (val) = if ((0 > val))
7878 then -(val)
7979 else val
8080
8181
8282 func absBigInt (val) = if ((zeroBigInt > val))
8383 then -(val)
8484 else val
85+
86+
87+func swapContract () = "%s__swapContract"
8588
8689
8790 func fc () = "%s__factoryContract"
8891
8992
9093 func mpk () = "%s__managerPublicKey"
9194
9295
9396 func pmpk () = "%s__pendingManagerPublicKey"
9497
9598
9699 func pl () = "%s%s__price__last"
97100
98101
99102 func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
100103
101104
102105 func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
103106
104107
105108 func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
106109
107110
108111 func aa () = "%s__amountAsset"
109112
110113
111114 func pa () = "%s__priceAsset"
112115
113116
114117 let keyFee = "%s__fee"
115118
116119 let feeDefault = fraction(10, scale8, 10000)
117120
118121 let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
119122
120123 let keyKLp = makeString(["%s", "kLp"], SEP)
121124
122125 let keyKLpRefreshedHeight = makeString(["%s", "kLpRefreshedHeight"], SEP)
123126
124127 let keyKLpRefreshDelay = makeString(["%s", "refreshKLpDelay"], SEP)
125128
126129 let kLpRefreshDelayDefault = 30
127130
128131 let kLpRefreshDelay = valueOrElse(getInteger(this, keyKLpRefreshDelay), kLpRefreshDelayDefault)
129132
130133 func keyFactoryConfig () = "%s__factoryConfig"
131134
132135
133136 func keyMatcherPub () = "%s%s__matcher__publicKey"
134137
135138
136139 func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
137140
138141
139142 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
140143
141144
142145 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
143146
144147
145148 func keyAllPoolsShutdown () = "%s__shutdown"
146149
147150
148151 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
149152
150153
151154 func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
152155
153156
154157 let keyFeeCollectorAddress = "%s__feeCollectorAddress"
155158
156159 func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
157160
158161
159162 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
160163
161164
162165 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
163166
164167
165168 func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
166169
167170
168171 func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
169172
170173
171174 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
172175
173176 let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
174177
175178 let inFee = {
176179 let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
177180 if ($isInstanceOf(@, "Int"))
178181 then @
179182 else throw(($getType(@) + " couldn't be cast to Int"))
180183 }
181184
182185 let outFee = {
183186 let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
184187 if ($isInstanceOf(@, "Int"))
185188 then @
186189 else throw(($getType(@) + " couldn't be cast to Int"))
187190 }
188191
189192 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
190193
191194
192195 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
193196
194197
195198 func getPoolConfig () = {
196199 let amtAsset = getStringOrFail(this, aa())
197200 let priceAsset = getStringOrFail(this, pa())
198201 let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
199202 let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
200203 split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
201204 }
202205
203206
204207 func parseAssetId (input) = if ((input == wavesString))
205208 then unit
206209 else fromBase58String(input)
207210
208211
209212 func assetIdToString (input) = if ((input == unit))
210213 then wavesString
211214 else toBase58String(value(input))
212215
213216
214217 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]))
215218
216219
217220 let poolConfigParsed = parsePoolConfig(getPoolConfig())
218221
219-let $t084088574 = poolConfigParsed
222+let $t084698635 = poolConfigParsed
220223
221-let cfgPoolAddress = $t084088574._1
224+let cfgPoolAddress = $t084698635._1
222225
223-let cfgPoolStatus = $t084088574._2
226+let cfgPoolStatus = $t084698635._2
224227
225-let cfgLpAssetId = $t084088574._3
228+let cfgLpAssetId = $t084698635._3
226229
227-let cfgAmountAssetId = $t084088574._4
230+let cfgAmountAssetId = $t084698635._4
228231
229-let cfgPriceAssetId = $t084088574._5
232+let cfgPriceAssetId = $t084698635._5
230233
231-let cfgAmountAssetDecimals = $t084088574._6
234+let cfgAmountAssetDecimals = $t084698635._6
232235
233-let cfgPriceAssetDecimals = $t084088574._7
236+let cfgPriceAssetDecimals = $t084698635._7
234237
235238 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
236239
237240
238241 let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
239242
240243 let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
241244
242245 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)
243246
244247
245248 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)
246249
247250
248251 func getAccBalance (assetId) = if ((assetId == "WAVES"))
249252 then wavesBalance(this).available
250253 else assetBalance(this, fromBase58String(assetId))
251254
252255
253256 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
254257
255258
256259 func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round)
257260
258261
259262 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
260263 let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
261264 let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
262265 calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
263266 }
264267
265268
266269 func calcPrices (amAmt,prAmt,lpAmt) = {
267270 let cfg = getPoolConfig()
268271 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
269272 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
270273 let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
271274 let amAmtX18 = toX18(amAmt, amtAssetDcm)
272275 let prAmtX18 = toX18(prAmt, priceAssetDcm)
273276 let lpAmtX18 = toX18(lpAmt, scale8)
274277 let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
275278 let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
276279 [priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
277280 }
278281
279282
280283 func calculatePrices (amAmt,prAmt,lpAmt) = {
281284 let prices = calcPrices(amAmt, prAmt, lpAmt)
282285 [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
283286 }
284287
285288
286289 func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
287290 let cfg = getPoolConfig()
288291 let lpAssetId = cfg[idxPoolLPAssetId]
289292 let amAssetId = cfg[idxAmtAssetId]
290293 let prAssetId = cfg[idxPriceAssetId]
291294 let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
292295 let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
293296 let poolStatus = cfg[idxPoolStatus]
294297 let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
295298 if ((lpAssetId != pmtAssetId))
296299 then throw("Invalid asset passed.")
297300 else {
298301 let amBalance = getAccBalance(amAssetId)
299302 let amBalanceX18 = toX18(amBalance, amAssetDcm)
300303 let prBalance = getAccBalance(prAssetId)
301304 let prBalanceX18 = toX18(prBalance, prAssetDcm)
302305 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
303306 let curPrice = fromX18(curPriceX18, scale8)
304307 let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
305308 let lpEmissionX18 = toX18(lpEmission, scale8)
306309 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
307310 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
308311 let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR)
309312 let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR)
310313 let state = if ((txId58 == ""))
311314 then nil
312315 else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
313316 then unit
314317 else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
315318 then unit
316319 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)]
317320 $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
318321 }
319322 }
320323
321324
322325 func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
323326 let cfg = getPoolConfig()
324327 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
325328 let amAssetIdStr = cfg[idxAmtAssetId]
326329 let prAssetIdStr = cfg[idxPriceAssetId]
327330 let iAmtAssetId = cfg[idxIAmtAssetId]
328331 let iPriceAssetId = cfg[idxIPriceAssetId]
329332 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
330333 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
331334 let poolStatus = cfg[idxPoolStatus]
332335 let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
333336 let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
334337 let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
335338 if (if ((amAssetIdStr != inAmAssetIdStr))
336339 then true
337340 else (prAssetIdStr != inPrAssetIdStr))
338341 then throw("Invalid amt or price asset passed.")
339342 else {
340343 let amBalance = if (isEvaluate)
341344 then getAccBalance(amAssetIdStr)
342345 else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
343346 let prBalance = if (isEvaluate)
344347 then getAccBalance(prAssetIdStr)
345348 else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
346349 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
347350 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
348351 let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
349352 let amBalanceX18 = toX18(amBalance, amtAssetDcm)
350353 let prBalanceX18 = toX18(prBalance, priceAssetDcm)
351354 let res = if ((lpEmission == 0))
352355 then {
353356 let curPriceX18 = zeroBigInt
354357 let slippageX18 = zeroBigInt
355358 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
356359 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
357360 }
358361 else {
359362 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
360363 let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
361364 let slippageToleranceX18 = toX18(slippageTolerance, scale8)
362365 if (if ((curPriceX18 != zeroBigInt))
363366 then (slippageX18 > slippageToleranceX18)
364367 else false)
365368 then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
366369 else {
367370 let lpEmissionX18 = toX18(lpEmission, scale8)
368371 let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING)
369372 let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING)
370373 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
371374 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
372375 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
373376 let expAmtAssetAmtX18 = expectedAmts._1
374377 let expPriceAssetAmtX18 = expectedAmts._2
375378 let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR)
376379 $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18)
377380 }
378381 }
379382 let calcLpAmt = res._1
380383 let calcAmAssetPmt = res._2
381384 let calcPrAssetPmt = res._3
382385 let curPrice = fromX18(res._4, scale8)
383386 let slippageCalc = fromX18(res._5, scale8)
384387 if ((0 >= calcLpAmt))
385388 then throw("Invalid calculations. LP calculated is less than zero.")
386389 else {
387390 let emitLpAmt = if (!(emitLp))
388391 then 0
389392 else calcLpAmt
390393 let amDiff = (inAmAssetAmt - calcAmAssetPmt)
391394 let prDiff = (inPrAssetAmt - calcPrAssetPmt)
392395 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))]
393396 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
394397 }
395398 }
396399 }
397400
398401
399402 func calcKLp (amountBalance,priceBalance,lpEmission) = {
400403 let amountBalanceX18 = toX18BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals))
401404 let priceBalanceX18 = toX18BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals))
402405 let updatedKLp = fraction(pow((amountBalanceX18 * priceBalanceX18), 0, toBigInt(5), 1, 18, DOWN), big1, lpEmission)
403406 if ((lpEmission == big0))
404407 then big0
405408 else updatedKLp
406409 }
407410
408411
409412 func calcCurrentKLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = {
410413 let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta)
411414 let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta)
412415 let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta)
413416 let currentKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpAssetEmission)
414417 currentKLp
415418 }
416419
417420
418421 func refreshKLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = {
419422 let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta)
420423 let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta)
421424 let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta)
422425 let updatedKLp = calcKLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission))
423426 let actions = [IntegerEntry(keyKLpRefreshedHeight, height), StringEntry(keyKLp, toString(updatedKLp))]
424427 $Tuple2(actions, updatedKLp)
425428 }
426429
427430
428431 func validateUpdatedKLp (oldKLp,updatedKLp) = if ((updatedKLp >= oldKLp))
429432 then true
430433 else throwErr(makeString(["updated KLp lower than current KLp", toString(oldKLp), toString(updatedKLp)], " "))
431434
432435
433436 func validateMatcherOrderAllowed (order) = {
434437 let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId))
435438 let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId))
436439 let amountAssetAmount = order.amount
437440 let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR)
438- let $t02148021692 = if ((order.orderType == Buy))
441+ let $t02154121753 = if ((order.orderType == Buy))
439442 then $Tuple2(amountAssetAmount, -(priceAssetAmount))
440443 else $Tuple2(-(amountAssetAmount), priceAssetAmount)
441- let amountAssetBalanceDelta = $t02148021692._1
442- let priceAssetBalanceDelta = $t02148021692._2
444+ let amountAssetBalanceDelta = $t02154121753._1
445+ let priceAssetBalanceDelta = $t02154121753._2
443446 if (if (if (isGlobalShutdown())
444447 then true
445448 else (cfgPoolStatus == PoolMatcherDisabled))
446449 then true
447450 else (cfgPoolStatus == PoolShutdown))
448451 then throw("Exchange operations disabled")
449452 else if (if ((order.assetPair.amountAsset != cfgAmountAssetId))
450453 then true
451454 else (order.assetPair.priceAsset != cfgPriceAssetId))
452455 then throw("Wrong order assets.")
453456 else {
454457 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
455- let $t02213222232 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
456- let unusedActions = $t02213222232._1
457- let kLpNew = $t02213222232._2
458+ let $t02219322293 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
459+ let unusedActions = $t02219322293._1
460+ let kLpNew = $t02219322293._2
458461 let isOrderValid = (kLpNew >= kLp)
459462 let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "")
460463 $Tuple2(isOrderValid, info)
461464 }
462465 }
463466
464467
465468 func commonGet (i) = if ((size(i.payments) != 1))
466469 then throw("exactly 1 payment is expected")
467470 else {
468471 let pmt = value(i.payments[0])
469472 let pmtAssetId = value(pmt.assetId)
470473 let pmtAmt = pmt.amount
471474 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
472475 let outAmAmt = res._1
473476 let outPrAmt = res._2
474477 let poolStatus = parseIntValue(res._9)
475478 let state = res._10
476479 if (if (isGlobalShutdown())
477480 then true
478481 else (poolStatus == PoolShutdown))
479482 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
480483 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
481484 }
482485
483486
484487 func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
485488 then throw("exactly 2 payments are expected")
486489 else {
487490 let amAssetPmt = value(i.payments[0])
488491 let prAssetPmt = value(i.payments[1])
489492 let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
490493 let poolStatus = parseIntValue(estPut._8)
491494 if (if (if (isGlobalShutdown())
492495 then true
493496 else (poolStatus == PoolPutDisabled))
494497 then true
495498 else (poolStatus == PoolShutdown))
496499 then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
497500 else estPut
498501 }
499502
500503
501504 func emit (amount) = {
502505 let emitInv = invoke(factoryContract, "emit", [amount], nil)
503506 if ((emitInv == emitInv))
504507 then {
505508 let emitInvLegacy = match emitInv {
506509 case legacyFactoryContract: Address =>
507510 invoke(legacyFactoryContract, "emit", [amount], nil)
508511 case _ =>
509512 unit
510513 }
511514 if ((emitInvLegacy == emitInvLegacy))
512515 then amount
513516 else throw("Strict value is not equal to itself.")
514517 }
515518 else throw("Strict value is not equal to itself.")
516519 }
517520
518521
519522 func takeFee (amount,fee) = {
520523 let feeAmount = if ((fee == 0))
521524 then 0
522525 else fraction(amount, fee, scale8)
523526 $Tuple2((amount - feeAmount), feeAmount)
524527 }
525528
526529
527530 func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
528531 let isEval = (txId == unit)
529532 let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
530533 let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
531534 let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
532535 then true
533536 else if ((paymentAssetId == cfgPriceAssetId))
534537 then false
535538 else throwErr("invalid asset")
536- let $t02534525638 = if (isEval)
539+ let $t02540625699 = if (isEval)
537540 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
538541 else if (paymentInAmountAsset)
539542 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
540543 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
541- let amountBalanceOld = $t02534525638._1
542- let priceBalanceOld = $t02534525638._2
543- let $t02564225791 = if (paymentInAmountAsset)
544+ let amountBalanceOld = $t02540625699._1
545+ let priceBalanceOld = $t02540625699._2
546+ let $t02570325852 = if (paymentInAmountAsset)
544547 then $Tuple2(paymentAmountRaw, 0)
545548 else $Tuple2(0, paymentAmountRaw)
546- let amountAssetAmountRaw = $t02564225791._1
547- let priceAssetAmountRaw = $t02564225791._2
549+ let amountAssetAmountRaw = $t02570325852._1
550+ let priceAssetAmountRaw = $t02570325852._2
548551 let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
549552 let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
550- let $t02592325987 = takeFee(paymentAmountRaw, inFee)
551- let paymentAmount = $t02592325987._1
552- let feeAmount = $t02592325987._2
553+ let $t02598426048 = takeFee(paymentAmountRaw, inFee)
554+ let paymentAmount = $t02598426048._1
555+ let feeAmount = $t02598426048._2
553556 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
554557 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
555558 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
556559 let priceNew = fromX18(priceNewX18, scale8)
557560 let paymentBalance = if (paymentInAmountAsset)
558561 then amountBalanceOld
559562 else priceBalanceOld
560563 let paymentBalanceBigInt = toBigInt(paymentBalance)
561564 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
562565 let chechSupply = if ((supplyBigInt > big0))
563566 then true
564567 else throwErr("initial deposit requires all coins")
565568 if ((chechSupply == chechSupply))
566569 then {
567570 let depositBigInt = toBigInt(paymentAmount)
568571 let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
569572 let commonState = if (isEval)
570573 then nil
571574 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))]
572575 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
573576 let priceOld = fromX18(priceOldX18, scale8)
574577 let loss = {
575- let $t02766827835 = if (paymentInAmountAsset)
578+ let $t02772927896 = if (paymentInAmountAsset)
576579 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
577580 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
578- let amount = $t02766827835._1
579- let balance = $t02766827835._2
581+ let amount = $t02772927896._1
582+ let balance = $t02772927896._2
580583 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
581584 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
582585 }
583586 $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset)
584587 }
585588 else throw("Strict value is not equal to itself.")
586589 }
587590
588591
589592 func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
590593 let isEval = (txId == unit)
591594 let cfg = getPoolConfig()
592595 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
593596 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
594597 let checks = [if ((paymentAssetId == cfgLpAssetId))
595598 then true
596599 else throwErr("invalid lp asset")]
597600 if ((checks == checks))
598601 then {
599602 let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
600603 then true
601604 else if ((outAssetId == cfgPriceAssetId))
602605 then false
603606 else throwErr("invalid asset")
604607 let balanceBigInt = if (outInAmountAsset)
605608 then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
606609 else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
607610 let outInAmountAssetDecimals = if (outInAmountAsset)
608611 then amtAssetDcm
609612 else priceAssetDcm
610613 let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
611614 let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
612615 let outBalance = if (outInAmountAsset)
613616 then amBalanceOld
614617 else prBalanceOld
615618 let outBalanceBigInt = toBigInt(outBalance)
616619 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
617620 let redeemedBigInt = toBigInt(paymentAmount)
618621 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
619- let $t02991329969 = takeFee(amountRaw, outFee)
620- let totalAmount = $t02991329969._1
621- let feeAmount = $t02991329969._2
622- let $t02997330199 = if (outInAmountAsset)
622+ let $t02997430030 = takeFee(amountRaw, outFee)
623+ let totalAmount = $t02997430030._1
624+ let feeAmount = $t02997430030._2
625+ let $t03003430260 = if (outInAmountAsset)
623626 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
624627 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
625- let outAmAmount = $t02997330199._1
626- let outPrAmount = $t02997330199._2
627- let amBalanceNew = $t02997330199._3
628- let prBalanceNew = $t02997330199._4
628+ let outAmAmount = $t03003430260._1
629+ let outPrAmount = $t03003430260._2
630+ let amBalanceNew = $t03003430260._3
631+ let prBalanceNew = $t03003430260._4
629632 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
630633 let priceNew = fromX18(priceNewX18, scale8)
631634 let commonState = if (isEval)
632635 then nil
633636 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)]
634637 let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
635638 let priceOld = fromX18(priceOldX18, scale8)
636639 let loss = {
637640 let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
638641 fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
639642 }
640643 $Tuple5(totalAmount, commonState, feeAmount, loss, outInAmountAsset)
641644 }
642645 else throw("Strict value is not equal to itself.")
643646 }
644647
645648
646649 func managerPublicKeyOrUnit () = match getString(mpk()) {
647650 case s: String =>
648651 fromBase58String(s)
649652 case _: Unit =>
650653 unit
651654 case _ =>
652655 throw("Match error")
653656 }
654657
655658
656659 func pendingManagerPublicKeyOrUnit () = match getString(pmpk()) {
657660 case s: String =>
658661 fromBase58String(s)
659662 case _: Unit =>
660663 unit
661664 case _ =>
662665 throw("Match error")
663666 }
664667
665668
666669 func isManager (i) = match managerPublicKeyOrUnit() {
667670 case pk: ByteVector =>
668671 (i.callerPublicKey == pk)
669672 case _: Unit =>
670673 (i.caller == this)
671674 case _ =>
672675 throw("Match error")
673676 }
674677
675678
676679 func mustManager (i) = {
677680 let pd = throw("Permission denied")
678681 match managerPublicKeyOrUnit() {
679682 case pk: ByteVector =>
680683 if ((i.callerPublicKey == pk))
681684 then true
682685 else pd
683686 case _: Unit =>
684687 if ((i.caller == this))
685688 then true
686689 else pd
687690 case _ =>
688691 throw("Match error")
689692 }
690693 }
694+
695+
696+@Callable(i)
697+func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse) = {
698+ let $t03195532260 = if ((isReverse == false))
699+ then {
700+ let assetOut = getStringOrFail(this, pa())
701+ let assetIn = getStringOrFail(this, aa())
702+ $Tuple2(assetOut, assetIn)
703+ }
704+ else {
705+ let assetOut = getStringOrFail(this, aa())
706+ let assetIn = getStringOrFail(this, pa())
707+ $Tuple2(assetOut, assetIn)
708+ }
709+ let assetOut = $t03195532260._1
710+ let assetIn = $t03195532260._2
711+ let poolAssetInBalance = getAccBalance(assetIn)
712+ let poolAssetOutBalance = getAccBalance(assetOut)
713+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
714+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
715+ let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
716+ let checkK = if ((newK >= oldK))
717+ then true
718+ else throw("new K is fewer error")
719+ if ((checkK == checkK))
720+ then $Tuple2(nil, amountOut)
721+ else throw("Strict value is not equal to itself.")
722+ }
723+
724+
725+
726+@Callable(i)
727+func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo) = {
728+ let swapContact = {
729+ let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil)
730+ if ($isInstanceOf(@, "String"))
731+ then @
732+ else throw(($getType(@) + " couldn't be cast to String"))
733+ }
734+ let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
735+ then true
736+ else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact)))
737+ then true
738+ else throwErr("Permission denied")]
739+ if ((checks == checks))
740+ then {
741+ let pmt = value(i.payments[0])
742+ let assetIn = if ((pmt.assetId == unit))
743+ then toBase58String(toBytes("WAVES"))
744+ else toBase58String(value(pmt.assetId))
745+ let assetOut = if ((isReverse == false))
746+ then getStringOrFail(this, pa())
747+ else getStringOrFail(this, aa())
748+ let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
749+ let poolAssetOutBalance = getAccBalance(assetOut)
750+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
751+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
752+ let newK = (toBigInt(getAccBalance(assetIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
753+ let checkK = if ((newK >= oldK))
754+ then true
755+ else throw("new K is fewer error")
756+ if ((checkK == checkK))
757+ then {
758+ let checkMin = if ((amountOut >= amountOutMin))
759+ then true
760+ else throw("Exchange result is fewer coins than expected")
761+ if ((checkMin == checkMin))
762+ then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))], amountOut)
763+ else throw("Strict value is not equal to itself.")
764+ }
765+ else throw("Strict value is not equal to itself.")
766+ }
767+ else throw("Strict value is not equal to itself.")
768+ }
769+
691770
692771
693772 @Callable(i)
694773 func setManager (pendingManagerPublicKey) = {
695774 let checkCaller = mustManager(i)
696775 if ((checkCaller == checkCaller))
697776 then {
698777 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
699778 if ((checkManagerPublicKey == checkManagerPublicKey))
700779 then [StringEntry(pmpk(), pendingManagerPublicKey)]
701780 else throw("Strict value is not equal to itself.")
702781 }
703782 else throw("Strict value is not equal to itself.")
704783 }
705784
706785
707786
708787 @Callable(i)
709788 func confirmManager () = {
710789 let pm = pendingManagerPublicKeyOrUnit()
711790 let hasPM = if (isDefined(pm))
712791 then true
713792 else throw("No pending manager")
714793 if ((hasPM == hasPM))
715794 then {
716795 let checkPM = if ((i.callerPublicKey == value(pm)))
717796 then true
718797 else throw("You are not pending manager")
719798 if ((checkPM == checkPM))
720799 then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())]
721800 else throw("Strict value is not equal to itself.")
722801 }
723802 else throw("Strict value is not equal to itself.")
724803 }
725804
726805
727806
728807 @Callable(i)
729808 func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
730809 then throw("Invalid slippageTolerance passed")
731810 else {
732811 let estPut = commonPut(i, slippageTolerance, true)
733812 let emitLpAmt = estPut._2
734813 let lpAssetId = estPut._7
735814 let state = estPut._9
736815 let amDiff = estPut._10
737816 let prDiff = estPut._11
738817 let amId = estPut._12
739818 let prId = estPut._13
740819 let amAssetPmt = toBigInt(value(i.payments[0]).amount)
741820 let prAssetPmt = toBigInt(value(i.payments[1]).amount)
742821 let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
743822 if ((currentKLp == currentKLp))
744823 then {
745824 let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
746825 if ((emitInv == emitInv))
747826 then {
748827 let emitInvLegacy = match emitInv {
749828 case legacyFactoryContract: Address =>
750829 invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
751830 case _ =>
752831 unit
753832 }
754833 if ((emitInvLegacy == emitInvLegacy))
755834 then {
756835 let slippageAInv = if ((amDiff > 0))
757836 then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
758837 else nil
759838 if ((slippageAInv == slippageAInv))
760839 then {
761840 let slippagePInv = if ((prDiff > 0))
762841 then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
763842 else nil
764843 if ((slippagePInv == slippagePInv))
765844 then {
766845 let lpTransfer = if (shouldAutoStake)
767846 then {
768847 let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
769848 if ((slpStakeInv == slpStakeInv))
770849 then nil
771850 else throw("Strict value is not equal to itself.")
772851 }
773852 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
774- let $t03472735189 = refreshKLpInternal(0, 0, 0)
775- if (($t03472735189 == $t03472735189))
853+ let $t03714537607 = refreshKLpInternal(0, 0, 0)
854+ if (($t03714537607 == $t03714537607))
776855 then {
777- let updatedKLp = $t03472735189._2
778- let refreshKLpActions = $t03472735189._1
856+ let updatedKLp = $t03714537607._2
857+ let refreshKLpActions = $t03714537607._1
779858 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
780859 if ((isUpdatedKLpValid == isUpdatedKLpValid))
781860 then ((state ++ lpTransfer) ++ refreshKLpActions)
782861 else throw("Strict value is not equal to itself.")
783862 }
784863 else throw("Strict value is not equal to itself.")
785864 }
786865 else throw("Strict value is not equal to itself.")
787866 }
788867 else throw("Strict value is not equal to itself.")
789868 }
790869 else throw("Strict value is not equal to itself.")
791870 }
792871 else throw("Strict value is not equal to itself.")
793872 }
794873 else throw("Strict value is not equal to itself.")
795874 }
796875
797876
798877
799878 @Callable(i)
800879 func putForFree (maxSlippage) = if ((0 > maxSlippage))
801880 then throw("Invalid value passed")
802881 else {
803882 let estPut = commonPut(i, maxSlippage, false)
804883 let state = estPut._9
805884 let amAssetPmt = toBigInt(value(i.payments[0]).amount)
806885 let prAssetPmt = toBigInt(value(i.payments[1]).amount)
807886 let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0))
808887 if ((currentKLp == currentKLp))
809888 then {
810- let $t03575135816 = refreshKLpInternal(0, 0, 0)
811- let refreshKLpActions = $t03575135816._1
812- let updatedKLp = $t03575135816._2
889+ let $t03816938234 = refreshKLpInternal(0, 0, 0)
890+ let refreshKLpActions = $t03816938234._1
891+ let updatedKLp = $t03816938234._2
813892 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
814893 if ((isUpdatedKLpValid == isUpdatedKLpValid))
815894 then (state ++ refreshKLpActions)
816895 else throw("Strict value is not equal to itself.")
817896 }
818897 else throw("Strict value is not equal to itself.")
819898 }
820899
821900
822901
823902 @Callable(i)
824903 func putOneTkn (minOutAmount,autoStake) = {
825904 let isPoolOneTokenOperationsDisabled = {
826905 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
827906 if ($isInstanceOf(@, "Boolean"))
828907 then @
829908 else throw(($getType(@) + " couldn't be cast to Boolean"))
830909 }
831910 let isPutDisabled = if (if (if (isGlobalShutdown())
832911 then true
833912 else (cfgPoolStatus == PoolPutDisabled))
834913 then true
835914 else (cfgPoolStatus == PoolShutdown))
836915 then true
837916 else isPoolOneTokenOperationsDisabled
838917 let checks = [if (if (!(isPutDisabled))
839918 then true
840919 else isManager(i))
841920 then true
842921 else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
843922 then true
844923 else throwErr("exactly 1 payment are expected")]
845924 if ((checks == checks))
846925 then {
847926 let payment = i.payments[0]
848927 let paymentAssetId = payment.assetId
849928 let paymentAmountRaw = payment.amount
850929 let currentKLp = if ((paymentAssetId == cfgAmountAssetId))
851930 then calcCurrentKLp(toBigInt(paymentAmountRaw), toBigInt(0), toBigInt(0))
852931 else if ((paymentAssetId == cfgPriceAssetId))
853932 then calcCurrentKLp(toBigInt(0), toBigInt(paymentAmountRaw), toBigInt(0))
854933 else throwErr("payment asset is not supported")
855934 if ((currentKLp == currentKLp))
856935 then {
857936 let userAddress = i.caller
858937 let txId = i.transactionId
859- let $t03700437156 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
860- if (($t03700437156 == $t03700437156))
938+ let $t03942239574 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
939+ if (($t03942239574 == $t03942239574))
861940 then {
862- let paymentInAmountAsset = $t03700437156._5
863- let bonus = $t03700437156._4
864- let feeAmount = $t03700437156._3
865- let commonState = $t03700437156._2
866- let emitAmountEstimated = $t03700437156._1
941+ let paymentInAmountAsset = $t03942239574._5
942+ let bonus = $t03942239574._4
943+ let feeAmount = $t03942239574._3
944+ let commonState = $t03942239574._2
945+ let emitAmountEstimated = $t03942239574._1
867946 let emitAmount = if (if ((minOutAmount > 0))
868947 then (minOutAmount > emitAmountEstimated)
869948 else false)
870949 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
871950 else emitAmountEstimated
872951 let emitInv = emit(emitAmount)
873952 if ((emitInv == emitInv))
874953 then {
875954 let lpTransfer = if (autoStake)
876955 then {
877956 let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
878957 if ((stakeInv == stakeInv))
879958 then nil
880959 else throw("Strict value is not equal to itself.")
881960 }
882961 else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
883962 let sendFee = if ((feeAmount > 0))
884963 then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
885964 else nil
886- let $t03774237939 = if ((this == feeCollectorAddress))
965+ let $t04016040357 = if ((this == feeCollectorAddress))
887966 then $Tuple2(0, 0)
888967 else if (paymentInAmountAsset)
889968 then $Tuple2(-(feeAmount), 0)
890969 else $Tuple2(0, -(feeAmount))
891- let amountAssetBalanceDelta = $t03774237939._1
892- let priceAssetBalanceDelta = $t03774237939._2
893- let $t03794238050 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
894- let refreshKLpActions = $t03794238050._1
895- let updatedKLp = $t03794238050._2
970+ let amountAssetBalanceDelta = $t04016040357._1
971+ let priceAssetBalanceDelta = $t04016040357._2
972+ let $t04036040468 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
973+ let refreshKLpActions = $t04036040468._1
974+ let updatedKLp = $t04036040468._2
896975 let kLp = value(getString(keyKLp))
897976 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
898977 if ((isUpdatedKLpValid == isUpdatedKLpValid))
899978 then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount)
900979 else throw("Strict value is not equal to itself.")
901980 }
902981 else throw("Strict value is not equal to itself.")
903982 }
904983 else throw("Strict value is not equal to itself.")
905984 }
906985 else throw("Strict value is not equal to itself.")
907986 }
908987 else throw("Strict value is not equal to itself.")
909988 }
910989
911990
912991
913992 @Callable(i)
914993 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
915- let $t03835638513 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
916- let emitAmountEstimated = $t03835638513._1
917- let commonState = $t03835638513._2
918- let feeAmount = $t03835638513._3
919- let bonus = $t03835638513._4
920- let paymentInAmountAsset = $t03835638513._5
994+ let $t04077440931 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
995+ let emitAmountEstimated = $t04077440931._1
996+ let commonState = $t04077440931._2
997+ let feeAmount = $t04077440931._3
998+ let bonus = $t04077440931._4
999+ let paymentInAmountAsset = $t04077440931._5
9211000 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
9221001 }
9231002
9241003
9251004
9261005 @Callable(i)
9271006 func getOneTkn (outAssetIdStr,minOutAmount) = {
9281007 let isPoolOneTokenOperationsDisabled = {
9291008 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
9301009 if ($isInstanceOf(@, "Boolean"))
9311010 then @
9321011 else throw(($getType(@) + " couldn't be cast to Boolean"))
9331012 }
9341013 let isGetDisabled = if (if (isGlobalShutdown())
9351014 then true
9361015 else (cfgPoolStatus == PoolShutdown))
9371016 then true
9381017 else isPoolOneTokenOperationsDisabled
9391018 let checks = [if (if (!(isGetDisabled))
9401019 then true
9411020 else isManager(i))
9421021 then true
9431022 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
9441023 then true
9451024 else throwErr("exactly 1 payment are expected")]
9461025 if ((checks == checks))
9471026 then {
9481027 let outAssetId = parseAssetId(outAssetIdStr)
9491028 let payment = i.payments[0]
9501029 let paymentAssetId = payment.assetId
9511030 let paymentAmount = payment.amount
9521031 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
9531032 if ((currentKLp == currentKLp))
9541033 then {
9551034 let userAddress = i.caller
9561035 let txId = i.transactionId
957- let $t03939839551 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
958- if (($t03939839551 == $t03939839551))
1036+ let $t04181641969 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
1037+ if (($t04181641969 == $t04181641969))
9591038 then {
960- let outInAmountAsset = $t03939839551._5
961- let bonus = $t03939839551._4
962- let feeAmount = $t03939839551._3
963- let commonState = $t03939839551._2
964- let amountEstimated = $t03939839551._1
1039+ let outInAmountAsset = $t04181641969._5
1040+ let bonus = $t04181641969._4
1041+ let feeAmount = $t04181641969._3
1042+ let commonState = $t04181641969._2
1043+ let amountEstimated = $t04181641969._1
9651044 let amount = if (if ((minOutAmount > 0))
9661045 then (minOutAmount > amountEstimated)
9671046 else false)
9681047 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
9691048 else amountEstimated
9701049 let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
9711050 if ((burnInv == burnInv))
9721051 then {
9731052 let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
9741053 let sendFee = if ((feeAmount > 0))
9751054 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
9761055 else nil
977- let $t04005140298 = {
1056+ let $t04246942716 = {
9781057 let feeAmountForCalc = if ((this == feeCollectorAddress))
9791058 then 0
9801059 else feeAmount
9811060 if (outInAmountAsset)
9821061 then $Tuple2(-((amount + feeAmountForCalc)), 0)
9831062 else $Tuple2(0, -((amount + feeAmountForCalc)))
9841063 }
985- let amountAssetBalanceDelta = $t04005140298._1
986- let priceAssetBalanceDelta = $t04005140298._2
987- let $t04030140409 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
988- let refreshKLpActions = $t04030140409._1
989- let updatedKLp = $t04030140409._2
1064+ let amountAssetBalanceDelta = $t04246942716._1
1065+ let priceAssetBalanceDelta = $t04246942716._2
1066+ let $t04271942827 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1067+ let refreshKLpActions = $t04271942827._1
1068+ let updatedKLp = $t04271942827._2
9901069 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
9911070 if ((isUpdatedKLpValid == isUpdatedKLpValid))
9921071 then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
9931072 else throw("Strict value is not equal to itself.")
9941073 }
9951074 else throw("Strict value is not equal to itself.")
9961075 }
9971076 else throw("Strict value is not equal to itself.")
9981077 }
9991078 else throw("Strict value is not equal to itself.")
10001079 }
10011080 else throw("Strict value is not equal to itself.")
10021081 }
10031082
10041083
10051084
10061085 @Callable(i)
10071086 func getOneTknREADONLY (outAssetId,paymentAmount) = {
1008- let $t04066640822 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1009- let amountEstimated = $t04066640822._1
1010- let commonState = $t04066640822._2
1011- let feeAmount = $t04066640822._3
1012- let bonus = $t04066640822._4
1013- let outInAmountAsset = $t04066640822._5
1087+ let $t04308443240 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
1088+ let amountEstimated = $t04308443240._1
1089+ let commonState = $t04308443240._2
1090+ let feeAmount = $t04308443240._3
1091+ let bonus = $t04308443240._4
1092+ let outInAmountAsset = $t04308443240._5
10141093 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
10151094 }
10161095
10171096
10181097
10191098 @Callable(i)
10201099 func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
10211100 let isPoolOneTokenOperationsDisabled = {
10221101 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
10231102 if ($isInstanceOf(@, "Boolean"))
10241103 then @
10251104 else throw(($getType(@) + " couldn't be cast to Boolean"))
10261105 }
10271106 let isGetDisabled = if (if (isGlobalShutdown())
10281107 then true
10291108 else (cfgPoolStatus == PoolShutdown))
10301109 then true
10311110 else isPoolOneTokenOperationsDisabled
10321111 let checks = [if (if (!(isGetDisabled))
10331112 then true
10341113 else isManager(i))
10351114 then true
10361115 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
10371116 then true
10381117 else throwErr("no payments are expected")]
10391118 if ((checks == checks))
10401119 then {
10411120 let outAssetId = parseAssetId(outAssetIdStr)
10421121 let userAddress = i.caller
10431122 let txId = i.transactionId
10441123 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
10451124 if ((currentKLp == currentKLp))
10461125 then {
10471126 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
10481127 if ((unstakeInv == unstakeInv))
10491128 then {
1050- let $t04172741878 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1051- if (($t04172741878 == $t04172741878))
1129+ let $t04414544296 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
1130+ if (($t04414544296 == $t04414544296))
10521131 then {
1053- let outInAmountAsset = $t04172741878._5
1054- let bonus = $t04172741878._4
1055- let feeAmount = $t04172741878._3
1056- let commonState = $t04172741878._2
1057- let amountEstimated = $t04172741878._1
1132+ let outInAmountAsset = $t04414544296._5
1133+ let bonus = $t04414544296._4
1134+ let feeAmount = $t04414544296._3
1135+ let commonState = $t04414544296._2
1136+ let amountEstimated = $t04414544296._1
10581137 let amount = if (if ((minOutAmount > 0))
10591138 then (minOutAmount > amountEstimated)
10601139 else false)
10611140 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
10621141 else amountEstimated
10631142 let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
10641143 if ((burnInv == burnInv))
10651144 then {
10661145 let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
10671146 let sendFee = if ((feeAmount > 0))
10681147 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
10691148 else nil
1070- let $t04237342620 = {
1149+ let $t04479145038 = {
10711150 let feeAmountForCalc = if ((this == feeCollectorAddress))
10721151 then 0
10731152 else feeAmount
10741153 if (outInAmountAsset)
10751154 then $Tuple2(-((amount + feeAmountForCalc)), 0)
10761155 else $Tuple2(0, -((amount + feeAmountForCalc)))
10771156 }
1078- let amountAssetBalanceDelta = $t04237342620._1
1079- let priceAssetBalanceDelta = $t04237342620._2
1080- let $t04262342731 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1081- let refreshKLpActions = $t04262342731._1
1082- let updatedKLp = $t04262342731._2
1157+ let amountAssetBalanceDelta = $t04479145038._1
1158+ let priceAssetBalanceDelta = $t04479145038._2
1159+ let $t04504145149 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0)
1160+ let refreshKLpActions = $t04504145149._1
1161+ let updatedKLp = $t04504145149._2
10831162 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
10841163 if ((isUpdatedKLpValid == isUpdatedKLpValid))
10851164 then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount)
10861165 else throw("Strict value is not equal to itself.")
10871166 }
10881167 else throw("Strict value is not equal to itself.")
10891168 }
10901169 else throw("Strict value is not equal to itself.")
10911170 }
10921171 else throw("Strict value is not equal to itself.")
10931172 }
10941173 else throw("Strict value is not equal to itself.")
10951174 }
10961175 else throw("Strict value is not equal to itself.")
10971176 }
10981177
10991178
11001179
11011180 @Callable(i)
11021181 func get () = {
11031182 let res = commonGet(i)
11041183 let outAmtAmt = res._1
11051184 let outPrAmt = res._2
11061185 let pmtAmt = res._3
11071186 let pmtAssetId = res._4
11081187 let state = res._5
11091188 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
11101189 if ((currentKLp == currentKLp))
11111190 then {
11121191 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
11131192 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11141193 then {
1115- let $t04367743759 = refreshKLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1116- let refreshKLpActions = $t04367743759._1
1117- let updatedKLp = $t04367743759._2
1194+ let $t04609546177 = refreshKLpInternal(-(outAmtAmt), -(outPrAmt), 0)
1195+ let refreshKLpActions = $t04609546177._1
1196+ let updatedKLp = $t04609546177._2
11181197 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11191198 if ((isUpdatedKLpValid == isUpdatedKLpValid))
11201199 then (state ++ refreshKLpActions)
11211200 else throw("Strict value is not equal to itself.")
11221201 }
11231202 else throw("Strict value is not equal to itself.")
11241203 }
11251204 else throw("Strict value is not equal to itself.")
11261205 }
11271206
11281207
11291208
11301209 @Callable(i)
11311210 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
11321211 let res = commonGet(i)
11331212 let outAmAmt = res._1
11341213 let outPrAmt = res._2
11351214 let pmtAmt = res._3
11361215 let pmtAssetId = res._4
11371216 let state = res._5
11381217 if ((noLessThenAmtAsset > outAmAmt))
11391218 then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
11401219 else if ((noLessThenPriceAsset > outPrAmt))
11411220 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
11421221 else {
11431222 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
11441223 if ((currentKLp == currentKLp))
11451224 then {
11461225 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
11471226 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11481227 then {
1149- let $t04470844789 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1150- let refreshKLpActions = $t04470844789._1
1151- let updatedKLp = $t04470844789._2
1228+ let $t04712647207 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1229+ let refreshKLpActions = $t04712647207._1
1230+ let updatedKLp = $t04712647207._2
11521231 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11531232 if ((isUpdatedKLpValid == isUpdatedKLpValid))
11541233 then (state ++ refreshKLpActions)
11551234 else throw("Strict value is not equal to itself.")
11561235 }
11571236 else throw("Strict value is not equal to itself.")
11581237 }
11591238 else throw("Strict value is not equal to itself.")
11601239 }
11611240 }
11621241
11631242
11641243
11651244 @Callable(i)
11661245 func unstakeAndGet (amount) = {
11671246 let checkPayments = if ((size(i.payments) != 0))
11681247 then throw("No payments are expected")
11691248 else true
11701249 if ((checkPayments == checkPayments))
11711250 then {
11721251 let cfg = getPoolConfig()
11731252 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
11741253 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
11751254 if ((currentKLp == currentKLp))
11761255 then {
11771256 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
11781257 if ((unstakeInv == unstakeInv))
11791258 then {
11801259 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
11811260 let outAmAmt = res._1
11821261 let outPrAmt = res._2
11831262 let poolStatus = parseIntValue(res._9)
11841263 let state = res._10
11851264 let checkPoolStatus = if (if (isGlobalShutdown())
11861265 then true
11871266 else (poolStatus == PoolShutdown))
11881267 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
11891268 else true
11901269 if ((checkPoolStatus == checkPoolStatus))
11911270 then {
11921271 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
11931272 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11941273 then {
1195- let $t04591545996 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1196- let refreshKLpActions = $t04591545996._1
1197- let updatedKLp = $t04591545996._2
1274+ let $t04833348414 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1275+ let refreshKLpActions = $t04833348414._1
1276+ let updatedKLp = $t04833348414._2
11981277 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
11991278 if ((isUpdatedKLpValid == isUpdatedKLpValid))
12001279 then (state ++ refreshKLpActions)
12011280 else throw("Strict value is not equal to itself.")
12021281 }
12031282 else throw("Strict value is not equal to itself.")
12041283 }
12051284 else throw("Strict value is not equal to itself.")
12061285 }
12071286 else throw("Strict value is not equal to itself.")
12081287 }
12091288 else throw("Strict value is not equal to itself.")
12101289 }
12111290 else throw("Strict value is not equal to itself.")
12121291 }
12131292
12141293
12151294
12161295 @Callable(i)
12171296 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
12181297 let isGetDisabled = if (isGlobalShutdown())
12191298 then true
12201299 else (cfgPoolStatus == PoolShutdown)
12211300 let checks = [if (!(isGetDisabled))
12221301 then true
12231302 else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
12241303 then true
12251304 else throw("no payments are expected")]
12261305 if ((checks == checks))
12271306 then {
12281307 let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0))
12291308 if ((currentKLp == currentKLp))
12301309 then {
12311310 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
12321311 if ((unstakeInv == unstakeInv))
12331312 then {
12341313 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
12351314 let outAmAmt = res._1
12361315 let outPrAmt = res._2
12371316 let state = res._10
12381317 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
12391318 then true
12401319 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
12411320 then true
12421321 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
12431322 if ((checkAmounts == checkAmounts))
12441323 then {
12451324 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
12461325 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
12471326 then {
1248- let $t04729147372 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1249- let refreshKLpActions = $t04729147372._1
1250- let updatedKLp = $t04729147372._2
1327+ let $t04970949790 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0)
1328+ let refreshKLpActions = $t04970949790._1
1329+ let updatedKLp = $t04970949790._2
12511330 let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp)
12521331 if ((isUpdatedKLpValid == isUpdatedKLpValid))
12531332 then (state ++ refreshKLpActions)
12541333 else throw("Strict value is not equal to itself.")
12551334 }
12561335 else throw("Strict value is not equal to itself.")
12571336 }
12581337 else throw("Strict value is not equal to itself.")
12591338 }
12601339 else throw("Strict value is not equal to itself.")
12611340 }
12621341 else throw("Strict value is not equal to itself.")
12631342 }
12641343 else throw("Strict value is not equal to itself.")
12651344 }
12661345
12671346
12681347
12691348 @Callable(i)
12701349 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
12711350 then throw("permissions denied")
12721351 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
12731352
12741353
12751354
12761355 @Callable(i)
12771356 func refreshKLp () = {
12781357 let lastRefreshedBlockHeight = valueOrElse(getInteger(keyKLpRefreshedHeight), 0)
12791358 let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= kLpRefreshDelay))
12801359 then unit
12811360 else throwErr(makeString([toString(kLpRefreshDelay), " blocks have not passed since the previous call"], ""))
12821361 if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
12831362 then {
12841363 let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp"))
1285- let $t04855948623 = refreshKLpInternal(0, 0, 0)
1286- let kLpUpdateActions = $t04855948623._1
1287- let updatedKLp = $t04855948623._2
1364+ let $t05097751041 = refreshKLpInternal(0, 0, 0)
1365+ let kLpUpdateActions = $t05097751041._1
1366+ let updatedKLp = $t05097751041._2
12881367 let actions = if ((kLp != updatedKLp))
12891368 then kLpUpdateActions
12901369 else throwErr("nothing to refresh")
12911370 $Tuple2(actions, toString(updatedKLp))
12921371 }
12931372 else throw("Strict value is not equal to itself.")
12941373 }
12951374
12961375
12971376
12981377 @Callable(i)
12991378 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
13001379
13011380
13021381
13031382 @Callable(i)
13041383 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
13051384
13061385
13071386
13081387 @Callable(i)
13091388 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
13101389 let prices = calcPrices(amAmt, prAmt, lpAmt)
13111390 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
13121391 }
13131392
13141393
13151394
13161395 @Callable(i)
13171396 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
13181397
13191398
13201399
13211400 @Callable(i)
13221401 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
13231402
13241403
13251404
13261405 @Callable(i)
13271406 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
13281407
13291408
13301409
13311410 @Callable(i)
13321411 func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
13331412
13341413
13351414
13361415 @Callable(i)
13371416 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
13381417 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
13391418 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
13401419 }
13411420
13421421
13431422
13441423 @Callable(i)
13451424 func statsREADONLY () = {
13461425 let cfg = getPoolConfig()
13471426 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
13481427 let amtAssetId = cfg[idxAmtAssetId]
13491428 let priceAssetId = cfg[idxPriceAssetId]
13501429 let iAmtAssetId = cfg[idxIAmtAssetId]
13511430 let iPriceAssetId = cfg[idxIPriceAssetId]
13521431 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
13531432 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
13541433 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
13551434 let accAmtAssetBalance = getAccBalance(amtAssetId)
13561435 let accPriceAssetBalance = getAccBalance(priceAssetId)
13571436 let pricesList = if ((poolLPBalance == 0))
13581437 then [zeroBigInt, zeroBigInt, zeroBigInt]
13591438 else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
13601439 let curPrice = 0
13611440 let lpAmtAssetShare = fromX18(pricesList[1], scale8)
13621441 let lpPriceAssetShare = fromX18(pricesList[2], scale8)
13631442 let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
13641443 $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))
13651444 }
13661445
13671446
13681447
13691448 @Callable(i)
13701449 func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
13711450 let cfg = getPoolConfig()
13721451 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
13731452 let amAssetIdStr = cfg[idxAmtAssetId]
13741453 let amAssetId = fromBase58String(amAssetIdStr)
13751454 let prAssetIdStr = cfg[idxPriceAssetId]
13761455 let prAssetId = fromBase58String(prAssetIdStr)
13771456 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
13781457 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
13791458 let poolStatus = cfg[idxPoolStatus]
13801459 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
13811460 let accAmtAssetBalance = getAccBalance(amAssetIdStr)
13821461 let accPriceAssetBalance = getAccBalance(prAssetIdStr)
13831462 let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
13841463 let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
13851464 let curPriceX18 = if ((poolLPBalance == 0))
13861465 then zeroBigInt
13871466 else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
13881467 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
13891468 let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
13901469 let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
13911470 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
13921471 let calcLpAmt = estPut._1
13931472 let curPriceCalc = estPut._3
13941473 let amBalance = estPut._4
13951474 let prBalance = estPut._5
13961475 let lpEmission = estPut._6
13971476 $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))
13981477 }
13991478
14001479
14011480
14021481 @Callable(i)
14031482 func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
14041483 let cfg = getPoolConfig()
14051484 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
14061485 let amAssetIdStr = cfg[idxAmtAssetId]
14071486 let amAssetId = fromBase58String(amAssetIdStr)
14081487 let prAssetIdStr = cfg[idxPriceAssetId]
14091488 let prAssetId = fromBase58String(prAssetIdStr)
14101489 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
14111490 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
14121491 let poolStatus = cfg[idxPoolStatus]
14131492 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
14141493 let amBalanceRaw = getAccBalance(amAssetIdStr)
14151494 let prBalanceRaw = getAccBalance(prAssetIdStr)
14161495 let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
14171496 let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
14181497 let curPriceX18 = if ((poolLPBalance == 0))
14191498 then zeroBigInt
14201499 else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
14211500 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
14221501 let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
14231502 let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
14241503 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
14251504 let calcLpAmt = estPut._1
14261505 let curPriceCalc = estPut._3
14271506 let amBalance = estPut._4
14281507 let prBalance = estPut._5
14291508 let lpEmission = estPut._6
14301509 $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))
14311510 }
14321511
14331512
14341513
14351514 @Callable(i)
14361515 func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
14371516 let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
14381517 let outAmAmt = res._1
14391518 let outPrAmt = res._2
14401519 let amBalance = res._5
14411520 let prBalance = res._6
14421521 let lpEmission = res._7
14431522 let curPrice = res._8
14441523 let poolStatus = parseIntValue(res._9)
14451524 $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))
14461525 }
14471526
14481527
14491528 @Verifier(tx)
14501529 func verify () = {
14511530 let targetPublicKey = match managerPublicKeyOrUnit() {
14521531 case pk: ByteVector =>
14531532 pk
14541533 case _: Unit =>
14551534 tx.senderPublicKey
14561535 case _ =>
14571536 throw("Match error")
14581537 }
14591538 match tx {
14601539 case order: Order =>
14611540 let matcherPub = getMatcherPubOrFail()
1462- let $t05728557354 = validateMatcherOrderAllowed(order)
1463- let orderValid = $t05728557354._1
1464- let orderValidInfo = $t05728557354._2
1541+ let $t05970359772 = validateMatcherOrderAllowed(order)
1542+ let orderValid = $t05970359772._1
1543+ let orderValidInfo = $t05970359772._2
14651544 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
14661545 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
14671546 if (if (if (orderValid)
14681547 then senderValid
14691548 else false)
14701549 then matcherValid
14711550 else false)
14721551 then true
14731552 else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid)
14741553 case s: SetScriptTransaction =>
14751554 if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
14761555 then true
14771556 else {
14781557 let newHash = blake2b256(value(s.script))
14791558 let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
14801559 let currentHash = scriptHash(this)
14811560 if ((allowedHash == newHash))
14821561 then (currentHash != newHash)
14831562 else false
14841563 }
14851564 case _ =>
14861565 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
14871566 }
14881567 }
14891568

github/deemru/w8io/3ef1775 
292.27 ms