tx · DPP933bf78KSoAd84cEYLNG3d8e8Ab1s3F25VEZAP949

3P85wJKhiQeTEZrLvvmkZgapHcQWcHFPJFZ:  -0.01400000 Waves

2021.10.06 19:22 [2799607] smart account 3P85wJKhiQeTEZrLvvmkZgapHcQWcHFPJFZ > SELF 0.00000000 Waves

{ "type": 13, "id": "DPP933bf78KSoAd84cEYLNG3d8e8Ab1s3F25VEZAP949", "fee": 1400000, "feeAssetId": null, "timestamp": 1633537325107, "version": 1, "sender": "3P85wJKhiQeTEZrLvvmkZgapHcQWcHFPJFZ", "senderPublicKey": "Ev26VHM5PgcWMx41mUgVEYw4uDh8euRUm7Kx1cEdgy2T", "proofs": [ "5hYZoVZFRTJqUdzYoSXvE5vsrGe4At9ipQ7NH5GLsTMfWZWvhBGRTyi2wQq1xaxLEMX7VvSVEijCDg6FhsJdoVqi" ], "script": "base64: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AAEFAAAAAWgJAARMAAAAAgkAAaQAAAABBQAAAAl0aW1lc3RhbXAFAAAAA25pbAUAAAADU0VQAQAAABBrZXlGYWN0b3J5Q29uZmlnAAAAAAIAAAARJXNfX2ZhY3RvcnlDb25maWcBAAAAKWtleU1hcHBpbmdQb29sQ29udHJhY3RBZGRyZXNzVG9Qb29sQXNzZXRzAAAAAQAAABNwb29sQ29udHJhY3RBZGRyZXNzCQABLAAAAAIJAAEsAAAAAgIAAAAIJXMlcyVzX18FAAAAE3Bvb2xDb250cmFjdEFkZHJlc3MCAAAAIF9fbWFwcGluZ3NfX3Bvb2xDb250cmFjdDJMcEFzc2V0AQAAAA1rZXlQb29sQ29uZmlnAAAAAgAAAAlpQW10QXNzZXQAAAALaVByaWNlQXNzZXQJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAIJWQlZCVzX18FAAAACWlBbXRBc3NldAIAAAACX18FAAAAC2lQcmljZUFzc2V0AgAAAAhfX2NvbmZpZwEAAAAfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZAAAAAEAAAAMYmFzZUFzc2V0U3RyCQABLAAAAAICAAAAKCVzJXMlc19fbWFwcGluZ3NfX2Jhc2VBc3NldDJpbnRlcm5hbElkX18FAAAADGJhc2VBc3NldFN0cgEAAAATa2V5QWxsUG9vbHNTaHV0ZG93bgAAAAACAAAADCVzX19zaHV0ZG93bgEAAAANa2V5UG9vbFdlaWdodAAAAAEAAAAPY29udHJhY3RBZGRyZXNzCQABLAAAAAICAAAAEiVzJXNfX3Bvb2xXZWlnaHRfXwUAAAAPY29udHJhY3RBZGRyZXNzAQAAAA9nZXRTdHJpbmdPckZhaWwAAAACAAAAB2FkZHJlc3MAAAADa2V5CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAHYWRkcmVzcwUAAAADa2V5CQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAACm1hbmRhdG9yeSAJAAQlAAAAAQUAAAAHYWRkcmVzcwIAAAABLgUAAAADa2V5AgAAAA8gaXMgbm90IGRlZmluZWQBAAAADGdldEludE9yRmFpbAAAAAIAAAAHYWRkcmVzcwAAAANrZXkJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAdhZGRyZXNzBQAAAANrZXkJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAKbWFuZGF0b3J5IAkABCUAAAABBQAAAAdhZGRyZXNzAgAAAAEuBQAAAANrZXkCAAAADyBpcyBub3QgZGVmaW5lZAAAAAAPZmFjdG9yeUNvbnRyYWN0CQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAgUAAAAEdGhpcwkBAAAAEmtleUZhY3RvcnlDb250cmFjdAAAAAABAAAAEGlzR2xvYmFsU2h1dGRvd24AAAAACQEAAAALdmFsdWVPckVsc2UAAAACCQAEGwAAAAIFAAAAD2ZhY3RvcnlDb250cmFjdAkBAAAAE2tleUFsbFBvb2xzU2h1dGRvd24AAAAABwEAAAANZ2V0UG9vbENvbmZpZwAAAAAEAAAACGFtdEFzc2V0CQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAgUAAAAEdGhpcwkBAAAAC2tleUFtdEFzc2V0AAAAAAQAAAAKcHJpY2VBc3NldAkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAIFAAAABHRoaXMJAQAAAA1rZXlQcmljZUFzc2V0AAAAAAQAAAALaVByaWNlQXNzZXQJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAAA9mYWN0b3J5Q29udHJhY3QJAQAAAB9rZXlNYXBwaW5nc0Jhc2VBc3NldDJpbnRlcm5hbElkAAAAAQUAAAAKcHJpY2VBc3NldAQAAAAJaUFtdEFzc2V0CQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAPZmFjdG9yeUNvbnRyYWN0CQEAAAAfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZAAAAAEFAAAACGFtdEFzc2V0CQAEtQAAAAIJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAACBQAAAA9mYWN0b3J5Q29udHJhY3QJAQAAAA1rZXlQb29sQ29uZmlnAAAAAgkAAaQAAAABBQAAAAlpQW10QXNzZXQJAAGkAAAAAQUAAAALaVByaWNlQXNzZXQFAAAAA1NFUAEAAAAQZ2V0RmFjdG9yeUNvbmZpZwAAAAAJAAS1AAAAAgkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAIFAAAAD2ZhY3RvcnlDb250cmFjdAkBAAAAEGtleUZhY3RvcnlDb25maWcAAAAABQAAAANTRVABAAAAEWRhdGFQdXRBY3Rpb25JbmZvAAAACgAAAA1pbkFtdEFzc2V0QW10AAAAD2luUHJpY2VBc3NldEFtdAAAAAhvdXRMcEFtdAAAAAVwcmljZQAAAB1zbGlwcGFnZVRvbGVyYW5jZVBhc3NlZEJ5VXNlcgAAABVzbGlwcGFnZVRvbGVyYW5jZVJlYWwAAAAIdHhIZWlnaHQAAAALdHhUaW1lc3RhbXAAAAASc2xpcGFnZUFtdEFzc2V0QW10AAAAFHNsaXBhZ2VQcmljZUFzc2V0QW10CQAEuQAAAAIJAARMAAAAAgIAAAASJWQlZCVkJWQlZCVkJWQlZCVkCQAETAAAAAIJAAGkAAAAAQUAAAANaW5BbXRBc3NldEFtdAkABEwAAAACCQABpAAAAAEFAAAAD2luUHJpY2VBc3NldEFtdAkABEwAAAACCQABpAAAAAEFAAAACG91dExwQW10CQAETAAAAAIJAAGkAAAAAQUAAAAFcHJpY2UJAARMAAAAAgkAAaQAAAABBQAAAB1zbGlwcGFnZVRvbGVyYW5jZVBhc3NlZEJ5VXNlcgkABEwAAAACCQABpAAAAAEFAAAAFXNsaXBwYWdlVG9sZXJhbmNlUmVhbAkABEwAAAACCQABpAAAAAEFAAAACHR4SGVpZ2h0CQAETAAAAAIJAAGkAAAAAQUAAAALdHhUaW1lc3RhbXAJAARMAAAAAgkAAaQAAAABBQAAABJzbGlwYWdlQW10QXNzZXRBbXQJAARMAAAAAgkAAaQAAAABBQAAABRzbGlwYWdlUHJpY2VBc3NldEFtdAUAAAADbmlsBQAAAANTRVABAAAAEWRhdGFHZXRBY3Rpb25JbmZvAAAABgAAAA5vdXRBbXRBc3NldEFtdAAAABBvdXRQcmljZUFzc2V0QW10AAAAB2luTHBBbXQAAAAFcHJpY2UAAAAIdHhIZWlnaHQAAAALdHhUaW1lc3RhbXAJAAS5AAAAAgkABEwAAAACAgAAAAwlZCVkJWQlZCVkJWQJAARMAAAAAgkAAaQAAAABBQAAAA5vdXRBbXRBc3NldEFtdAkABEwAAAACCQABpAAAAAEFAAAAEG91dFByaWNlQXNzZXRBbXQJAARMAAAAAgkAAaQAAAABBQAAAAdpbkxwQW10CQAETAAAAAIJAAGkAAAAAQUAAAAFcHJpY2UJAARMAAAAAgkAAaQAAAABBQAAAAh0eEhlaWdodAkABEwAAAACCQABpAAAAAEFAAAAC3R4VGltZXN0YW1wBQAAAANuaWwFAAAAA1NFUAEAAAANZ2V0QWNjQmFsYW5jZQAAAAEAAAAHYXNzZXRJZAMJAAAAAAAAAgUAAAAHYXNzZXRJZAIAAAAFV0FWRVMICQAD7wAAAAEFAAAABHRoaXMAAAAJYXZhaWxhYmxlCQAD8AAAAAIFAAAABHRoaXMJAAJZAAAAAQUAAAAHYXNzZXRJZAEAAAAPY2FsY1ByaWNlQmlnSW50AAAAAwAAABNwcmljZUFzc2V0TG9ja2VkQW10AAAAEmFtdEFzc2V0bExvY2tlZEFtdAAAAAtyZXN1bHRTY2FsZQkAATwAAAADBQAAABNwcmljZUFzc2V0TG9ja2VkQW10BQAAAAtyZXN1bHRTY2FsZQUAAAASYW10QXNzZXRsTG9ja2VkQW10AQAAABBwcml2YXRlQ2FsY1ByaWNlAAAABAAAAAthbXRBc3NldERjbQAAAA1wcmljZUFzc2V0RGNtAAAAC2FtdEFzc2V0QW10AAAADXByaWNlQXNzZXRBbXQEAAAADmFtdEFzc2V0QW10WDE4CQEAAAAFdG9YMTgAAAACBQAAAAthbXRBc3NldEFtdAUAAAALYW10QXNzZXREY20EAAAAEHByaWNlQXNzZXRBbXRYMTgJAQAAAAV0b1gxOAAAAAIFAAAADXByaWNlQXNzZXRBbXQFAAAADXByaWNlQXNzZXREY20JAAGgAAAAAQkBAAAAD2NhbGNQcmljZUJpZ0ludAAAAAMFAAAAEHByaWNlQXNzZXRBbXRYMTgFAAAADmFtdEFzc2V0QW10WDE4BQAAAAxzY2FsZThCaWdJbnQBAAAACmNhbGNQcmljZXMAAAADAAAAC2FtdEFzc2V0QW10AAAADXByaWNlQXNzZXRBbXQAAAAFbHBBbXQEAAAAA2NmZwkBAAAADWdldFBvb2xDb25maWcAAAAABAAAAAthbXRBc3NldERjbQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAA2NmZwUAAAAOaWR4QW10QXNzZXREY20EAAAADXByaWNlQXNzZXREY20JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAANjZmcFAAAAEGlkeFByaWNlQXNzZXREY20EAAAACXBvb2xQcmljZQkBAAAAEHByaXZhdGVDYWxjUHJpY2UAAAAEBQAAAAthbXRBc3NldERjbQUAAAANcHJpY2VBc3NldERjbQUAAAALYW10QXNzZXRBbXQFAAAADXByaWNlQXNzZXRBbXQEAAAADmFtdEFzc2V0QW10WDE4CQEAAAAFdG9YMTgAAAACBQAAAAthbXRBc3NldEFtdAUAAAALYW10QXNzZXREY20EAAAAEHByaWNlQXNzZXRBbXRYMTgJAQAAAAV0b1gxOAAAAAIFAAAADXByaWNlQXNzZXRBbXQFAAAADXByaWNlQXNzZXREY20EAAAACGxwQW10WDE4CQEAAAAFdG9YMTgAAAACBQAAAAVscEFtdAUAAAAGc2NhbGU4BAAAABFscFByaWNlSW5BbXRBc3NldAkAAaAAAAABCQEAAAAPY2FsY1ByaWNlQmlnSW50AAAAAwUAAAAOYW10QXNzZXRBbXRYMTgFAAAACGxwQW10WDE4BQAAAAxzY2FsZThCaWdJbnQEAAAAE2xwUHJpY2VJblByaWNlQXNzZXQJAAGgAAAAAQkBAAAAD2NhbGNQcmljZUJpZ0ludAAAAAMFAAAAEHByaWNlQXNzZXRBbXRYMTgFAAAACGxwQW10WDE4BQAAAAxzY2FsZThCaWdJbnQJAARMAAAAAgUAAAAJcG9vbFByaWNlCQAETAAAAAIFAAAAEWxwUHJpY2VJbkFtdEFzc2V0CQAETAAAAAIFAAAAE2xwUHJpY2VJblByaWNlQXNzZXQFAAAAA25pbAEAAAAUZXN0aW1hdGVHZXRPcGVyYXRpb24AAAADAAAAEHBheW1lbnRMcEFzc2V0SWQAAAAMcGF5bWVudExwQW10AAAAC3VzZXJBZGRyZXNzBAAAAA5wb29sQ29uZmlnTGlzdAkBAAAADWdldFBvb2xDb25maWcAAAAABAAAAAlscEFzc2V0SWQJAAGRAAAAAgUAAAAOcG9vbENvbmZpZ0xpc3QFAAAAEGlkeFBvb2xMUEFzc2V0SWQEAAAACmFtdEFzc2V0SWQJAAGRAAAAAgUAAAAOcG9vbENvbmZpZ0xpc3QFAAAADWlkeEFtdEFzc2V0SWQEAAAADHByaWNlQXNzZXRJZAkAAZEAAAACBQAAAA5wb29sQ29uZmlnTGlzdAUAAAAPaWR4UHJpY2VBc3NldElkBAAAAAtpQW10QXNzZXRJZAkAAZEAAAACBQAAAA5wb29sQ29uZmlnTGlzdAUAAAAOaWR4SUFtdEFzc2V0SWQEAAAADWlQcmljZUFzc2V0SWQJAAGRAAAAAgUAAAAOcG9vbENvbmZpZ0xpc3QFAAAAEGlkeElQcmljZUFzc2V0SWQEAAAAC2FtdEFzc2V0RGNtCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAOcG9vbENvbmZpZ0xpc3QFAAAADmlkeEFtdEFzc2V0RGNtBAAAAA1wcmljZUFzc2V0RGNtCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAOcG9vbENvbmZpZ0xpc3QFAAAAEGlkeFByaWNlQXNzZXREY20EAAAACnBvb2xTdGF0dXMJAAGRAAAAAgUAAAAOcG9vbENvbmZpZ0xpc3QFAAAADWlkeFBvb2xTdGF0dXMEAAAADXBvb2xMUEJhbGFuY2UICQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAPsAAAAAQkAAlkAAAABBQAAAAlscEFzc2V0SWQJAAEsAAAAAgkAASwAAAACAgAAAAZBc3NldCAFAAAACWxwQXNzZXRJZAIAAAAOIGRvZXNuJ3QgZXhpc3QAAAAIcXVhbnRpdHkDCQEAAAACIT0AAAACBQAAAAlscEFzc2V0SWQFAAAAEHBheW1lbnRMcEFzc2V0SWQJAAACAAAAAQIAAAAVSW52YWxpZCBhc3NldCBwYXNzZWQuBAAAAA9hbXRBc3NldEJhbGFuY2UJAQAAAA1nZXRBY2NCYWxhbmNlAAAAAQUAAAAKYW10QXNzZXRJZAQAAAASYW10QXNzZXRCYWxhbmNlWDE4CQEAAAAFdG9YMTgAAAACBQAAAA9hbXRBc3NldEJhbGFuY2UFAAAAC2FtdEFzc2V0RGNtBAAAABFwcmljZUFzc2V0QmFsYW5jZQkBAAAADWdldEFjY0JhbGFuY2UAAAABBQAAAAxwcmljZUFzc2V0SWQEAAAAFHByaWNlQXNzZXRCYWxhbmNlWDE4CQEAAAAFdG9YMTgAAAACBQAAABFwcmljZUFzc2V0QmFsYW5jZQUAAAANcHJpY2VBc3NldERjbQQAAAAIY3VyUHJpY2UJAAGgAAAAAQkBAAAAD2NhbGNQcmljZUJpZ0ludAAAAAMFAAAAFHByaWNlQXNzZXRCYWxhbmNlWDE4BQAAABJhbXRBc3NldEJhbGFuY2VYMTgFAAAADHNjYWxlOEJpZ0ludAQAAAAPcGF5bWVudExwQW10WDE4CQEAAAAFdG9YMTgAAAACBQAAAAxwYXltZW50THBBbXQFAAAABnNjYWxlOAQAAAAQcG9vbExQQmFsYW5jZVgxOAkBAAAABXRvWDE4AAAAAgUAAAANcG9vbExQQmFsYW5jZQUAAAAGc2NhbGU4BAAAAA5vdXRBbXRBc3NldEFtdAkAATwAAAADBQAAABJhbXRBc3NldEJhbGFuY2VYMTgFAAAAD3BheW1lbnRMcEFtdFgxOAUAAAAQcG9vbExQQmFsYW5jZVgxOAQAAAAQb3V0UHJpY2VBc3NldEFtdAkAATwAAAADBQAAABRwcmljZUFzc2V0QmFsYW5jZVgxOAUAAAAPcGF5bWVudExwQW10WDE4BQAAABBwb29sTFBCYWxhbmNlWDE4BAAAABNvdXRBbXRBc3NldEFtdEZpbmFsCQEAAAAHZnJvbVgxOAAAAAIFAAAADm91dEFtdEFzc2V0QW10BQAAAAthbXRBc3NldERjbQQAAAAVb3V0UHJpY2VBc3NldEFtdEZpbmFsCQEAAAAHZnJvbVgxOAAAAAIFAAAAEG91dFByaWNlQXNzZXRBbXQFAAAADXByaWNlQXNzZXREY20JAAUdAAAACwUAAAATb3V0QW10QXNzZXRBbXRGaW5hbAUAAAAVb3V0UHJpY2VBc3NldEFtdEZpbmFsBQAAAAtpQW10QXNzZXRJZAUAAAANaVByaWNlQXNzZXRJZAUAAAAKYW10QXNzZXRJZAUAAAAMcHJpY2VBc3NldElkBQAAAA9hbXRBc3NldEJhbGFuY2UFAAAAEXByaWNlQXNzZXRCYWxhbmNlBQAAAA1wb29sTFBCYWxhbmNlBQAAAAhjdXJQcmljZQUAAAAKcG9vbFN0YXR1cwEAAAAUZXN0aW1hdGVQdXRPcGVyYXRpb24AAAAHAAAAEXNsaXBwYWdlVG9sZXJhbmNlAAAADWluQW10QXNzZXRBbXQAAAAMaW5BbXRBc3NldElkAAAAD2luUHJpY2VBc3NldEFtdAAAAA5pblByaWNlQXNzZXRJZAAAAAt1c2VyQWRkcmVzcwAAAAppc0V2YWx1YXRlBAAAAANjZmcJAQAAAA1nZXRQb29sQ29uZmlnAAAAAAQAAAAJbHBBc3NldElkCQACWQAAAAEJAAGRAAAAAgUAAAADY2ZnBQAAABBpZHhQb29sTFBBc3NldElkBAAAAAphbXRBc3NldElkCQABkQAAAAIFAAAAA2NmZwUAAAANaWR4QW10QXNzZXRJZAQAAAAMcHJpY2VBc3NldElkCQABkQAAAAIFAAAAA2NmZwUAAAAPaWR4UHJpY2VBc3NldElkBAAAAAtpQW10QXNzZXRJZAkAAZEAAAACBQAAAANjZmcFAAAADmlkeElBbXRBc3NldElkBAAAAA1pUHJpY2VBc3NldElkCQABkQAAAAIFAAAAA2NmZwUAAAAQaWR4SVByaWNlQXNzZXRJZAQAAAALYW10QXNzZXREY20JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAANjZmcFAAAADmlkeEFtdEFzc2V0RGNtBAAAAA1wcmljZUFzc2V0RGNtCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAADY2ZnBQAAABBpZHhQcmljZUFzc2V0RGNtBAAAAApwb29sU3RhdHVzCQABkQAAAAIFAAAAA2NmZwUAAAANaWR4UG9vbFN0YXR1cwQAAAANcG9vbExQQmFsYW5jZQgJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkAA+wAAAABBQAAAAlscEFzc2V0SWQJAAEsAAAAAgkAASwAAAACAgAAAAZBc3NldCAJAAJYAAAAAQUAAAAJbHBBc3NldElkAgAAAA4gZG9lc24ndCBleGlzdAAAAAhxdWFudGl0eQMDCQEAAAACIT0AAAACBQAAAAphbXRBc3NldElkBQAAAAxpbkFtdEFzc2V0SWQGCQEAAAACIT0AAAACBQAAAAxwcmljZUFzc2V0SWQFAAAADmluUHJpY2VBc3NldElkCQAAAgAAAAECAAAAIkludmFsaWQgYW10IG9yIHByaWNlIGFzc2V0IHBhc3NlZC4EAAAAEmFjY0FtdEFzc2V0QmFsYW5jZQMFAAAACmlzRXZhbHVhdGUJAQAAAA1nZXRBY2NCYWxhbmNlAAAAAQUAAAAKYW10QXNzZXRJZAkAAGUAAAACCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAACmFtdEFzc2V0SWQFAAAADWluQW10QXNzZXRBbXQEAAAAFGFjY1ByaWNlQXNzZXRCYWxhbmNlAwUAAAAKaXNFdmFsdWF0ZQkBAAAADWdldEFjY0JhbGFuY2UAAAABBQAAAAxwcmljZUFzc2V0SWQJAABlAAAAAgkBAAAADWdldEFjY0JhbGFuY2UAAAABBQAAAAxwcmljZUFzc2V0SWQFAAAAD2luUHJpY2VBc3NldEFtdAQAAAAQaW5BbXRBc3NldEFtdFgxOAkBAAAABXRvWDE4AAAAAgUAAAANaW5BbXRBc3NldEFtdAUAAAALYW10QXNzZXREY20EAAAAEmluUHJpY2VBc3NldEFtdFgxOAkBAAAABXRvWDE4AAAAAgUAAAAPaW5QcmljZUFzc2V0QW10BQAAAA1wcmljZUFzc2V0RGNtBAAAAAl1c2VyUHJpY2UJAAGgAAAAAQkBAAAAD2NhbGNQcmljZUJpZ0ludAAAAAMFAAAAEmluUHJpY2VBc3NldEFtdFgxOAUAAAAQaW5BbXRBc3NldEFtdFgxOAUAAAAMc2NhbGU4QmlnSW50BAAAABVhY2NBbXRBc3NldEJhbGFuY2VYMTgJAQAAAAV0b1gxOAAAAAIFAAAAEmFjY0FtdEFzc2V0QmFsYW5jZQUAAAALYW10QXNzZXREY20EAAAAF2FjY1ByaWNlQXNzZXRCYWxhbmNlWDE4CQEAAAAFdG9YMTgAAAACBQAAABRhY2NQcmljZUFzc2V0QmFsYW5jZQUAAAANcHJpY2VBc3NldERjbQQAAAAIY3VyUHJpY2UDCQAAAAAAAAIFAAAADXBvb2xMUEJhbGFuY2UAAAAAAAAAAAAAAAAAAAAAAAAJAAGgAAAAAQkBAAAAD2NhbGNQcmljZUJpZ0ludAAAAAMFAAAAF2FjY1ByaWNlQXNzZXRCYWxhbmNlWDE4BQAAABVhY2NBbXRBc3NldEJhbGFuY2VYMTgFAAAADHNjYWxlOEJpZ0ludAQAAAAIc2xpcHBhZ2UDCQAAAAAAAAIFAAAACGN1clByaWNlAAAAAAAAAAAAAAAAAAAAAAAAAwkAAGYAAAACBQAAAAhjdXJQcmljZQUAAAAJdXNlclByaWNlCQAAawAAAAMJAABlAAAAAgUAAAAIY3VyUHJpY2UFAAAACXVzZXJQcmljZQUAAAAGc2NhbGU4BQAAAAhjdXJQcmljZQkAAGsAAAADCQAAZQAAAAIFAAAACXVzZXJQcmljZQUAAAAIY3VyUHJpY2UFAAAABnNjYWxlOAUAAAAIY3VyUHJpY2UDAwkBAAAAAiE9AAAAAgUAAAAIY3VyUHJpY2UAAAAAAAAAAAAJAABmAAAAAgUAAAAIc2xpcHBhZ2UFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBwkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAA9QcmljZSBzbGlwcGFnZSAJAAGkAAAAAQUAAAAIc2xpcHBhZ2UCAAAAHiBleGNlZWRlZCB0aGUgcGFzc2VkIGxpbWl0IG9mIAkAAaQAAAABBQAAABFzbGlwcGFnZVRvbGVyYW5jZQQAAAADcmVzAwkAAAAAAAACBQAAAA1wb29sTFBCYWxhbmNlAAAAAAAAAAAABAAAAAtscFJlc3VsdEJ1ZgkAAHYAAAAGCQABOQAAAAIFAAAAEGluQW10QXNzZXRBbXRYMTgFAAAAEmluUHJpY2VBc3NldEFtdFgxOAAAAAAAAAAAAAkAATYAAAABAAAAAAAAAAAFAAAAAAAAAAABAAAAAAAAAAAABQAAAARET1dOCQAFFgAAAAQJAQAAAAdmcm9tWDE4AAAAAgUAAAALbHBSZXN1bHRCdWYFAAAABnNjYWxlOAkBAAAAB2Zyb21YMTgAAAACBQAAABBpbkFtdEFzc2V0QW10WDE4BQAAAAthbXRBc3NldERjbQkBAAAAB2Zyb21YMTgAAAACBQAAABJpblByaWNlQXNzZXRBbXRYMTgFAAAADXByaWNlQXNzZXREY20JAAGgAAAAAQkBAAAAD2NhbGNQcmljZUJpZ0ludAAAAAMJAAE3AAAAAgUAAAAXYWNjUHJpY2VBc3NldEJhbGFuY2VYMTgFAAAAEmluUHJpY2VBc3NldEFtdFgxOAkAATcAAAACBQAAABVhY2NBbXRBc3NldEJhbGFuY2VYMTgFAAAAEGluQW10QXNzZXRBbXRYMTgFAAAADHNjYWxlOEJpZ0ludAQAAAAQcG9vbExQQmFsYW5jZVgxOAkBAAAABXRvWDE4AAAAAgUAAAANcG9vbExQQmFsYW5jZQUAAAAGc2NhbGU4BAAAAAtjdXJQcmljZVgxOAkBAAAABXRvWDE4AAAAAgUAAAAIY3VyUHJpY2UFAAAABnNjYWxlOAQAAAAGcEVxQnlBCQABPAAAAAMFAAAAC2N1clByaWNlWDE4BQAAABBpbkFtdEFzc2V0QW10WDE4BQAAAAdzY2FsZTE4BAAAAA5yZXNBc3NldHNUb1B1dAMJAAE/AAAAAgUAAAAGcEVxQnlBBQAAABJpblByaWNlQXNzZXRBbXRYMTgJAAUUAAAAAgkAATwAAAADBQAAABJpblByaWNlQXNzZXRBbXRYMTgFAAAAB3NjYWxlMTgFAAAAC2N1clByaWNlWDE4BQAAABJpblByaWNlQXNzZXRBbXRYMTgJAAUUAAAAAgUAAAAQaW5BbXRBc3NldEFtdFgxOAUAAAAGcEVxQnlBBAAAAAhscFJlc3VsdAkBAAAAB2Zyb21YMTgAAAACCQABPAAAAAMFAAAAEHBvb2xMUEJhbGFuY2VYMTgIBQAAAA5yZXNBc3NldHNUb1B1dAAAAAJfMgUAAAAXYWNjUHJpY2VBc3NldEJhbGFuY2VYMTgFAAAABnNjYWxlOAkABRYAAAAEBQAAAAhscFJlc3VsdAkBAAAAB2Zyb21YMTgAAAACCAUAAAAOcmVzQXNzZXRzVG9QdXQAAAACXzEFAAAAC2FtdEFzc2V0RGNtCQEAAAAHZnJvbVgxOAAAAAIIBQAAAA5yZXNBc3NldHNUb1B1dAAAAAJfMgUAAAANcHJpY2VBc3NldERjbQkAAaAAAAABCQEAAAAPY2FsY1ByaWNlQmlnSW50AAAAAwkAATcAAAACBQAAABdhY2NQcmljZUFzc2V0QmFsYW5jZVgxOAgFAAAADnJlc0Fzc2V0c1RvUHV0AAAAAl8yCQABNwAAAAIFAAAAFWFjY0FtdEFzc2V0QmFsYW5jZVgxOAgFAAAADnJlc0Fzc2V0c1RvUHV0AAAAAl8xBQAAAAxzY2FsZThCaWdJbnQDCQAAZwAAAAIAAAAAAAAAAAAIBQAAAANyZXMAAAACXzEJAAACAAAAAQIAAAA2SW52YWxpZCBjYWxjdWxhdGlvbnMuIExQIGNhbGN1bGF0ZWQgaXMgbGVzcyB0aGFuIHplcm8uCQAFHgAAAAwIBQAAAANyZXMAAAACXzEIBQAAAANyZXMAAAACXzQFAAAAEmFjY0FtdEFzc2V0QmFsYW5jZQUAAAAUYWNjUHJpY2VBc3NldEJhbGFuY2UFAAAADXBvb2xMUEJhbGFuY2UFAAAAC2lBbXRBc3NldElkBQAAAA1pUHJpY2VBc3NldElkBQAAAAlscEFzc2V0SWQFAAAACHNsaXBwYWdlBQAAAApwb29sU3RhdHVzCAUAAAADcmVzAAAAAl8yCAUAAAADcmVzAAAAAl8zAQAAABt2YWxpZGF0ZU1hdGNoZXJPcmRlckFsbG93ZWQAAAABAAAABW9yZGVyBAAAAANjZmcJAQAAAA1nZXRQb29sQ29uZmlnAAAAAAQAAAAKYW10QXNzZXRJZAkAAZEAAAACBQAAAANjZmcFAAAADWlkeEFtdEFzc2V0SWQEAAAADHByaWNlQXNzZXRJZAkAAZEAAAACBQAAAANjZmcFAAAAD2lkeFByaWNlQXNzZXRJZAQAAAAKcG9vbFN0YXR1cwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAA2NmZwUAAAANaWR4UG9vbFN0YXR1cwQAAAALYW10QXNzZXREY20JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAANjZmcFAAAADmlkeEFtdEFzc2V0RGNtBAAAAA1wcmljZUFzc2V0RGNtCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAADY2ZnBQAAABBpZHhQcmljZUFzc2V0RGNtBAAAABJhY2NBbXRBc3NldEJhbGFuY2UJAQAAAA1nZXRBY2NCYWxhbmNlAAAAAQUAAAAKYW10QXNzZXRJZAQAAAAUYWNjUHJpY2VBc3NldEJhbGFuY2UJAQAAAA1nZXRBY2NCYWxhbmNlAAAAAQUAAAAMcHJpY2VBc3NldElkBAAAAAhjdXJQcmljZQMJAAAAAAAAAggFAAAABW9yZGVyAAAACW9yZGVyVHlwZQUAAAADQnV5CQEAAAAQcHJpdmF0ZUNhbGNQcmljZQAAAAQFAAAAC2FtdEFzc2V0RGNtBQAAAA1wcmljZUFzc2V0RGNtCQAAZAAAAAIFAAAAEmFjY0FtdEFzc2V0QmFsYW5jZQgFAAAABW9yZGVyAAAABmFtb3VudAUAAAAUYWNjUHJpY2VBc3NldEJhbGFuY2UJAQAAABBwcml2YXRlQ2FsY1ByaWNlAAAABAUAAAALYW10QXNzZXREY20FAAAADXByaWNlQXNzZXREY20JAABlAAAAAgUAAAASYWNjQW10QXNzZXRCYWxhbmNlCAUAAAAFb3JkZXIAAAAGYW1vdW50BQAAABRhY2NQcmljZUFzc2V0QmFsYW5jZQMDAwkBAAAAEGlzR2xvYmFsU2h1dGRvd24AAAAABgkAAAAAAAACBQAAAApwb29sU3RhdHVzBQAAABNQb29sTWF0Y2hlckRpc2FibGVkBgkAAAAAAAACBQAAAApwb29sU3RhdHVzBQAAAAxQb29sU2h1dGRvd24JAAACAAAAAQIAAAAcRXhjaGFuZ2Ugb3BlcmF0aW9ucyBkaXNhYmxlZAQAAAANb3JkZXJBbXRBc3NldAgIBQAAAAVvcmRlcgAAAAlhc3NldFBhaXIAAAALYW1vdW50QXNzZXQEAAAAEG9yZGVyQW10QXNzZXRTdHIDCQAAAAAAAAIFAAAADW9yZGVyQW10QXNzZXQFAAAABHVuaXQCAAAABVdBVkVTCQACWAAAAAEJAQAAAAV2YWx1ZQAAAAEFAAAADW9yZGVyQW10QXNzZXQEAAAAD29yZGVyUHJpY2VBc3NldAgIBQAAAAVvcmRlcgAAAAlhc3NldFBhaXIAAAAKcHJpY2VBc3NldAQAAAASb3JkZXJQcmljZUFzc2V0U3RyAwkAAAAAAAACBQAAAA9vcmRlclByaWNlQXNzZXQFAAAABHVuaXQCAAAABVdBVkVTCQACWAAAAAEJAQAAAAV2YWx1ZQAAAAEFAAAAD29yZGVyUHJpY2VBc3NldAMDCQEAAAACIT0AAAACBQAAABBvcmRlckFtdEFzc2V0U3RyBQAAAAphbXRBc3NldElkBgkBAAAAAiE9AAAAAgUAAAASb3JkZXJQcmljZUFzc2V0U3RyBQAAAAxwcmljZUFzc2V0SWQJAAACAAAAAQIAAAATV3Jvbmcgb3JkZXIgYXNzZXRzLgQAAAAKb3JkZXJQcmljZQgFAAAABW9yZGVyAAAA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AQUAAAAMaW5BbXRBc3NldElkBQAAAA9pblByaWNlQXNzZXRBbXQJAAJYAAAAAQUAAAAOaW5QcmljZUFzc2V0SWQJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBwQAAAAIb3V0THBBbXQIBQAAAAZlc3RQdXQAAAACXzEEAAAACGN1clByaWNlCAUAAAAGZXN0UHV0AAAAAl8yBAAAABNwb29sQW10QXNzZXRCYWxhbmNlCAUAAAAGZXN0UHV0AAAAAl8zBAAAABVwb29sUHJpY2VBc3NldEJhbGFuY2UIBQAAAAZlc3RQdXQAAAACXzQEAAAADXBvb2xMUEJhbGFuY2UIBQAAAAZlc3RQdXQAAAACXzUEAAAAC2lBbXRBc3NldElkCAUAAAAGZXN0UHV0AAAAAl82BAAAAA1pUHJpY2VBc3NldElkCAUAAAAGZXN0UHV0AAAAAl83BAAAAAlscEFzc2V0SWQIBQAAAAZlc3RQdXQAAAACXzgEAAAADHNsaXBwYWdlQ2FsYwgFAAAABmVzdFB1dAAAAAJfOQQAAAAKcG9vbFN0YXR1cwkBAAAADXBhcnNlSW50VmFsdWUAAAABCAUAAAAGZXN0UHV0AAAAA18xMAQAAAAOcmVhbEFtdEFzc2V0SW4IBQAAAAZlc3RQdXQAAAADXzExBAAAABByZWFsUHJpY2VBc3NldEluCAUAAAAGZXN0UHV0AAAAA18xMgMDAwkBAAAAEGlzR2xvYmFsU2h1dGRvd24AAAAABgkAAAAAAAACBQAAAApwb29sU3RhdHVzBQAAAA9Qb29sUHV0RGlzYWJsZWQGCQAAAAAAAAIFAAAACnBvb2xTdGF0dXMFAAAADFBvb2xTaHV0ZG93bgkAAAIAAAABCQABLAAAAAICAAAALFB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQABpAAAAAEFAAAACnBvb2xTdGF0dXMEAAAAC2xwQW10VG9FbWl0AwkBAAAAASEAAAABBQAAAAZlbWl0THAAAAAAAAAAAAAFAAAACG91dExwQW10BAAAAA5kaWZmSW5BbXRBc3NldAkAAGUAAAACBQAAAA1pbkFtdEFzc2V0QW10BQAAAA5yZWFsQW10QXNzZXRJbgQAAAAQZGlmZkluUHJpY2VBc3NldAkAAGUAAAACBQAAAA9pblByaWNlQXNzZXRBbXQFAAAAEHJlYWxQcmljZUFzc2V0SW4EAAAADmRhdGFTdGF0ZVdyaXRlCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAAxrZXlQcmljZUxhc3QAAAAACQABLAAAAAICAAAABCVzX18JAAGkAAAAAQUAAAAIY3VyUHJpY2UJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAD2tleVByaWNlSGlzdG9yeQAAAAIFAAAABmhlaWdodAgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAJAAEsAAAAAgIAAAAEJXNfXwkAAaQAAAABBQAAAAhjdXJQcmljZQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAASa2V5UHV0QWN0aW9uQnlVc2VyAAAAAgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIJAAJYAAAAAQgFAAAAAWkAAAANdHJhbnNhY3Rpb25JZAkBAAAAEWRhdGFQdXRBY3Rpb25JbmZvAAAACgUAAAAOcmVhbEFtdEFzc2V0SW4FAAAAEHJlYWxQcmljZUFzc2V0SW4FAAAAC2xwQW10VG9FbWl0BQAAAAhjdXJQcmljZQUAAAARc2xpcHBhZ2VUb2xlcmFuY2UFAAAADHNsaXBwYWdlQ2FsYwUAAAAGaGVpZ2h0CAUAAAAJbGFzdEJsb2NrAAAACXRpbWVzdGFtcAUAAAAOZGlmZkluQW10QXNzZXQFAAAAEGRpZmZJblByaWNlQXNzZXQFAAAAA25pbAkABRsAAAAJBQAAAAtscEFtdFRvRW1pdAUAAAAJbHBBc3NldElkBQAAAA5kYXRhU3RhdGVXcml0ZQUAAAANaW5BbXRBc3NldEFtdAUAAAAOcmVhbEFtdEFzc2V0SW4FAAAAD2luUHJpY2VBc3NldEFtdAUAAAAQcmVhbFByaWNlQXNzZXRJbggFAAAAC3BtdEFtdEFzc2V0AAAAB2Fzc2V0SWQIBQAAAA1wbXRQcmljZUFzc2V0AAAAB2Fzc2V0SWQAAAAKAAAAAWkBAAAAC2NvbnN0cnVjdG9yAAAAAgAAAA9mYWN0b3J5Q29udHJhY3QAAAAQbWFuYWdlclB1YmxpY0tleQMJAQAAAAIhPQAAAAIIBQAAAAFpAAAABmNhbGxlcgUAAAAEdGhpcwkAAAIAAAABAgAAABJwZXJtaXNzaW9ucyBkZW5pZWQJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAEmtleUZhY3RvcnlDb250cmFjdAAAAAAFAAAAD2ZhY3RvcnlDb250cmFjdAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAATa2V5TWFuYWdlclB1YmxpY0tleQAAAAAFAAAAEG1hbmFnZXJQdWJsaWNLZXkFAAAAA25pbAAAAAFpAQAAAANwdXQAAAACAAAAEXNsaXBwYWdlVG9sZXJhbmNlAAAAD3Nob3VsZEF1dG9TdGFrZQQAAAAKZmFjdG9yeUNmZwkBAAAAEGdldEZhY3RvcnlDb25maWcAAAAABAAAAA9zdGFraW5nQ29udHJhY3QJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABCQABkQAAAAIFAAAACmZhY3RvcnlDZmcFAAAAGWlkeEZhY3RvcnlTdGFraW5nQ29udHJhY3QCAAAAIUVycm9yLiBJbmNvcnJlY3Qgc3Rha2luZyBhZGRyZXNzLgQAAAAQc2xpcHBhZ2VDb250cmFjdAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEJAAGRAAAAAgUAAAAKZmFjdG9yeUNmZwUAAAAaaWR4RmFjdG9yeVNsaXBwYWdlQ29udHJhY3QCAAAAK0Vycm9yLiBJbmNvcnJlY3Qgc2xpcHBhZ2UgY29udHJhY3QgYWRkcmVzcy4EAAAAB2FjdGlvbnMJAQAAAAljb21tb25QdXQAAAADBQAAAAFpBQAAABFzbGlwcGFnZVRvbGVyYW5jZQYEAAAACWFtdFRvRW1pdAgFAAAAB2FjdGlvbnMAAAACXzEEAAAACWxwQXNzZXRJZAgFAAAAB2FjdGlvbnMAAAACXzIEAAAABXN0YXRlCAUAAAAHYWN0aW9ucwAAAAJfMwQAAAAFaW5BbXQIBQAAAAdhY3Rpb25zAAAAAl80BAAAAAlyZWFsSW5BbXQIBQAAAAdhY3Rpb25zAAAAAl81BAAAAAdpblByaWNlCAUAAAAHYWN0aW9ucwAAAAJfNgQAAAALcmVhbEluUHJpY2UIBQAAAAdhY3Rpb25zAAAA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YW5jZQAAAA1pbkFtdEFzc2V0QW10AAAAC3VzZXJBZGRyZXNzBAAAAANjZmcJAQAAAA1nZXRQb29sQ29uZmlnAAAAAAQAAAAJbHBBc3NldElkCQACWQAAAAEJAAGRAAAAAgUAAAADY2ZnBQAAABBpZHhQb29sTFBBc3NldElkBAAAAAphbXRBc3NldElkCQABkQAAAAIFAAAAA2NmZwUAAAANaWR4QW10QXNzZXRJZAQAAAAMcHJpY2VBc3NldElkCQABkQAAAAIFAAAAA2NmZwUAAAAPaWR4UHJpY2VBc3NldElkBAAAAAtpQW10QXNzZXRJZAkAAZEAAAACBQAAAANjZmcFAAAADmlkeElBbXRBc3NldElkBAAAAA1pUHJpY2VBc3NldElkCQABkQAAAAIFAAAAA2NmZwUAAAAQaWR4SVByaWNlQXNzZXRJZAQAAAALYW10QXNzZXREY20JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAANjZmcFAAAADmlkeEFtdEFzc2V0RGNtBAAAAA1wcmljZUFzc2V0RGNtCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAADY2ZnBQAAABBpZHhQcmljZUFzc2V0RGNtBAAAAApwb29sU3RhdHVzCQABkQAAAAIFAAAAA2NmZwUAAAANaWR4UG9vbFN0YXR1cwQAAAANcG9vbExQQmFsYW5jZQgJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkAA+wAAAABBQAAAAlscEFzc2V0SWQJAAEsAAAAAgkAASwAAAACAgAAAAZBc3NldCAJAAJYAAAAAQUAAAAJbHBBc3NldElkAgAAAA4gZG9lc24ndCBleGlzdAAAAAhxdWFudGl0eQQAAAASYWNjQW10QXNzZXRCYWxhbmNlCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAACmFtdEFzc2V0SWQEAAAAFGFjY1ByaWNlQXNzZXRCYWxhbmNlCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAADHByaWNlQXNzZXRJZAQAAAAOYW10QXNzZXRBbXRYMTgJAQAAAAV0b1gxOAAAAAIFAAAAEmFjY0FtdEFzc2V0QmFsYW5jZQUAAAALYW10QXNzZXREY20EAAAAEHByaWNlQXNzZXRBbXRYMTgJAQAAAAV0b1gxOAAAAAIFAAAAFGFjY1ByaWNlQXNzZXRCYWxhbmNlBQAAAA1wcmljZUFzc2V0RGNtBAAAAAtjdXJQcmljZVgxOAMJAAAAAAAAAgUAAAANcG9vbExQQmFsYW5jZQAAAAAAAAAAAAkAATYAAAABAAAAAAAAAAAACQEAAAAPY2FsY1ByaWNlQmlnSW50AAAAAwUAAAAQcHJpY2VBc3NldEFtdFgxOAUAAAAOYW10QXNzZXRBbXRYMTgFAAAAB3NjYWxlMTgEAAAAEGluQW10QXNzZXRBbXRYMTgJAQAAAAV0b1gxOAAAAAIFAAAADWluQW10QXNzZXRBbXQFAAAAC2FtdEFzc2V0RGNtBAAAABJpblByaWNlQXNzZXRBbXRYMTgJAAE8AAAAAwUAAAAQaW5BbXRBc3NldEFtdFgxOAUAAAALY3VyUHJpY2VYMTgFAAAAB3NjYWxlMTgEAAAAD2luUHJpY2VBc3NldEFtdAkBAAAAB2Zyb21YMTgAAAACBQAAABJpblByaWNlQXNzZXRBbXRYMTgFAAAADXByaWNlQXNzZXREY20EAAAAE2VzdGltYXRlZFB1dFJlc3VsdHMJAQAAABRlc3RpbWF0ZVB1dE9wZXJhdGlvbgAAAAcFAAAAEXNsaXBwYWdlVG9sZXJhbmNlBQAAAA1pbkFtdEFzc2V0QW10BQAAAAphbXRBc3NldElkBQAAAA9pblByaWNlQXNzZXRBbXQFAAAADHByaWNlQXNzZXRJZAUAAAALdXNlckFkZHJlc3MGBAAAAAxvdXRMcEFtdENhbGMIBQAAABNlc3RpbWF0ZWRQdXRSZXN1bHRzAAAAAl8xBAAAAAxjdXJQcmljZUNhbGMIBQAAABNlc3RpbWF0ZWRQdXRSZXN1bHRzAAAAAl8yBAAAABdwb29sQW10QXNzZXRCYWxhbmNlQ2FsYwgFAAAAE2VzdGltYXRlZFB1dFJlc3VsdHMAAAACXzMEAAAAGXBvb2xQcmljZUFzc2V0QmFsYW5jZUNBbGMIBQAAABNlc3RpbWF0ZWRQdXRSZXN1bHRzAAAAAl80BAAAABFwb29sTFBCYWxhbmNlQ2FsYwgFAAAAE2VzdGltYXRlZFB1dFJlc3VsdHMAAAACXzUEAAAADnBvb2xTdGF0dXNDYWxjCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEIBQAAABNlc3RpbWF0ZWRQdXRSZXN1bHRzAAAAA18xMAkABRQAAAACBQAAAANuaWwJAAS5AAAAAgkABEwAAAACAgAAAAwlZCVkJWQlZCVkJWQJAARMAAAAAgkAAaQAAAABBQAAAAxvdXRMcEFtdENhbGMJAARMAAAAAgkAAaQAAAABCQEAAAAHZnJvbVgxOAAAAAIFAAAAC2N1clByaWNlWDE4BQAAAAZzY2FsZTgJAARMAAAAAgkAAaQAAAABBQAAABdwb29sQW10QXNzZXRCYWxhbmNlQ2FsYwkABEwAAAACCQABpAAAAAEFAAAAGXBvb2xQcmljZUFzc2V0QmFsYW5jZUNBbGMJAARMAAAAAgkAAaQAAAABBQAAABFwb29sTFBCYWxhbmNlQ2FsYwkABEwAAAACCQABpAAAAAEFAAAADnBvb2xTdGF0dXNDYWxjBQAAAANuaWwFAAAAA1NFUAAAAAFpAQAAAB9ldmFsdWF0ZVB1dEJ5UHJpY2VBc3NldFJFQURPTkxZAAAAAwAAABFzbGlwcGFnZVRvbGVyYW5jZQAAAA9pblByaWNlQXNzZXRBbXQAAAALdXNlckFkZHJlc3MEAAAAA2NmZwkBAAAADWdldFBvb2xDb25maWcAAAAABAAAAAlscEFzc2V0SWQJAAJZAAAAAQkAAZEAAAACBQAAAANjZmcFAAAAEGlkeFBvb2xMUEFzc2V0SWQEAAAACmFtdEFzc2V0SWQJAAGRAAAAAgUAAAADY2ZnBQAAAA1pZHhBbXRBc3NldElkBAAAAAxwcmljZUFzc2V0SWQJAAGRAAAAAgUAAAADY2ZnBQAAAA9pZHhQcmljZUFzc2V0SWQEAAAAC2lBbXRBc3NldElkCQABkQAAAAIFAAAAA2NmZwUAAAAOaWR4SUFtdEFzc2V0SWQEAAAADWlQcmljZUFzc2V0SWQJAAGRAAAAAgUAAAADY2ZnBQAAABBpZHhJUHJpY2VBc3NldElkBAAAAAthbXRBc3NldERjbQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAA2NmZwUAAAAOaWR4QW10QXNzZXREY20EAAAADXByaWNlQXNzZXREY20JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAANjZmcFAAAAEGlkeFByaWNlQXNzZXREY20EAAAACnBvb2xTdGF0dXMJAAGRAAAAAgUAAAADY2ZnBQAAAA1pZHhQb29sU3RhdHVzBAAAAA1wb29sTFBCYWxhbmNlCAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAD7AAAAAEFAAAACWxwQXNzZXRJZAkAASwAAAACCQABLAAAAAICAAAABkFzc2V0IAkAAlgAAAABBQAAAAlscEFzc2V0SWQCAAAADiBkb2Vzbid0IGV4aXN0AAAACHF1YW50aXR5BAAAABJhY2NBbXRBc3NldEJhbGFuY2UJAQAAAA1nZXRBY2NCYWxhbmNlAAAAAQUAAAAKYW10QXNzZXRJZAQAAAAUYWNjUHJpY2VBc3NldEJhbGFuY2UJAQAAAA1nZXRBY2NCYWxhbmNlAAAAAQUAAAAMcHJpY2VBc3NldElkBAAAAA5hbXRBc3NldEFtdFgxOAkBAAAABXRvWDE4AAAAAgUAAAASYWNjQW10QXNzZXRCYWxhbmNlBQAAAAthbXRBc3NldERjbQQAAAAQcHJpY2VBc3NldEFtdFgxOAkBAAAABXRvWDE4AAAAAgUAAAAUYWNjUHJpY2VBc3NldEJhbGFuY2UFAAAADXByaWNlQXNzZXREY20EAAAAC2N1clByaWNlWDE4AwkAAAAAAAACBQAAAA1wb29sTFBCYWxhbmNlAAAAAAAAAAAACQABNgAAAAEAAAAAAAAAAAAJAQAAAA9jYWxjUHJpY2VCaWdJbnQAAAADBQAAABBwcmljZUFzc2V0QW10WDE4BQAAAA5hbXRBc3NldEFtdFgxOAUAAAAHc2NhbGUxOAQAAAASaW5QcmljZUFzc2V0QW10WDE4CQEAAAAFdG9YMTgAAAACBQAAAA9pblByaWNlQXNzZXRBbXQFAAAADXByaWNlQXNzZXREY20EAAAAEGluQW10QXNzZXRBbXRYMTgJAAE8AAAAAwUAAAASaW5QcmljZUFzc2V0QW10WDE4BQAAAAdzY2FsZTE4BQAAAAtjdXJQcmljZVgxOAQAAAANaW5BbXRBc3NldEFtdAkBAAAAB2Zyb21YMTgAAAACBQAAABBpbkFtdEFzc2V0QW10WDE4BQAAAAthbXRBc3NldERjbQQAAAATZXN0aW1hdGVkUHV0UmVzdWx0cwkBAAAAFGVzdGltYXRlUHV0T3BlcmF0aW9uAAAABwUAAAARc2xpcHBhZ2VUb2xlcmFuY2UFAAAADWluQW10QXNzZXRBbXQFAAAACmFtdEFzc2V0SWQFAAAAD2luUHJpY2VBc3NldEFtdAUAAAAMcHJpY2VBc3NldElkBQAAAAt1c2VyQWRkcmVzcwYEAAAADG91dExwQW10Q2FsYwgFAAAAE2VzdGltYXRlZFB1dFJlc3VsdHMAAAACXzEEAAAADGN1clByaWNlQ2FsYwgFAAAAE2VzdGltYXRlZFB1dFJlc3VsdHMAAAACXzIEAAAAF3Bvb2xBbXRBc3NldEJhbGFuY2VDYWxjCAUAAAATZXN0aW1hdGVkUHV0UmVzdWx0cwAAAAJfMwQAAAAZcG9vbFByaWNlQXNzZXRCYWxhbmNlQ0FsYwgFAAAAE2VzdGltYXRlZFB1dFJlc3VsdHMAAAACXzQEAAAAEXBvb2xMUEJhbGFuY2VDYWxjCAUAAAATZXN0aW1hdGVkUHV0UmVzdWx0cwAAAAJfNQQAAAAOcG9vbFN0YXR1c0NhbGMJAQAAAA1wYXJzZUludFZhbHVlAAAAAQgFAAAAE2VzdGltYXRlZFB1dFJlc3VsdHMAAAADXzEwCQAFFAAAAAIFAAAAA25pbAkABLkAAAACCQAETAAAAAICAAAADCVkJWQlZCVkJWQlZAkABEwAAAACCQABpAAAAAEFAAAADG91dExwQW10Q2FsYwkABEwAAAACCQABpAAAAAEJAQAAAAdmcm9tWDE4AAAAAgUAAAALY3VyUHJpY2VYMTgFAAAABnNjYWxlOAkABEwAAAACCQABpAAAAAEFAAAAF3Bvb2xBbXRBc3NldEJhbGFuY2VDYWxjCQAETAAAAAIJAAGkAAAAAQUAAAAZcG9vbFByaWNlQXNzZXRCYWxhbmNlQ0FsYwkABEwAAAACCQABpAAAAAEFAAAAEXBvb2xMUEJhbGFuY2VDYWxjCQAETAAAAAIJAAGkAAAAAQUAAAAOcG9vbFN0YXR1c0NhbGMFAAAAA25pbAUAAAADU0VQAAAAAWkBAAAAE2V2YWx1YXRlR2V0UkVBRE9OTFkAAAADAAAAEHBheW1lbnRMcEFzc2V0SWQAAAAMcGF5bWVudExwQW10AAAAC3VzZXJBZGRyZXNzBAAAAANyZXMJAQAAABRlc3RpbWF0ZUdldE9wZXJhdGlvbgAAAAMFAAAAEHBheW1lbnRMcEFzc2V0SWQFAAAADHBheW1lbnRMcEFtdAUAAAALdXNlckFkZHJlc3MEAAAADm91dEFtdEFzc2V0QW10CAUAAAADcmVzAAAAAl8xBAAAABBvdXRQcmljZUFzc2V0QW10CAUAAAADcmVzAAAAAl8yBAAAABNwb29sQW10QXNzZXRCYWxhbmNlCAUAAAADcmVzAAAAAl83BAAAABVwb29sUHJpY2VBc3NldEJhbGFuY2UIBQAAAANyZXMAAAACXzgEAAAADXBvb2xMUEJhbGFuY2UIBQAAAANyZXMAAAACXzkEAAAACGN1clByaWNlCAUAAAADcmVzAAAAA18xMAQAAAAKcG9vbFN0YXR1cwkBAAAADXBhcnNlSW50VmFsdWUAAAABCAUAAAADcmVzAAAAA18xMQkABRQAAAACBQAAAANuaWwJAAS5AAAAAgkABEwAAAACAgAAAA4lZCVkJWQlZCVkJWQlZAkABEwAAAACCQABpAAAAAEFAAAADm91dEFtdEFzc2V0QW10CQAETAAAAAIJAAGkAAAAAQUAAAAQb3V0UHJpY2VBc3NldEFtdAkABEwAAAACCQABpAAAAAEFAAAAE3Bvb2xBbXRBc3NldEJhbGFuY2UJAARMAAAAAgkAAaQAAAABBQAAABVwb29sUHJpY2VBc3NldEJhbGFuY2UJAARMAAAAAgkAAaQAAAABBQAAAA1wb29sTFBCYWxhbmNlCQAETAAAAAIJAAGkAAAAAQUAAAAIY3VyUHJpY2UJAARMAAAAAgkAAaQAAAABBQAAAApwb29sU3RhdHVzBQAAAANuaWwFAAAAA1NFUAAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAAEAAAAByRtYXRjaDAFAAAAAnR4AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAAVPcmRlcgQAAAAFb3JkZXIFAAAAByRtYXRjaDADCQEAAAAbdmFsaWRhdGVNYXRjaGVyT3JkZXJBbGxvd2VkAAAAAQUAAAAFb3JkZXIJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAACAUAAAACdHgAAAAPc2VuZGVyUHVibGljS2V5BwkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAIBQAAAAJ0eAAAAA9zZW5kZXJQdWJsaWNLZXkYfUD1", "chainId": 87, "height": 2799607, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 3tiitTK3UwkW2SiTQV9QTpUC3NyGALjNgNuvmdP4YHmC Next: none Diff:
OldNewDifferences
1010 let scale18 = toBigInt(1000000000000000000)
1111
1212 let SEP = "__"
13+
14+let EMPTY = ""
1315
1416 let PoolActive = 1
1517
3941
4042 let idxLPAssetDcm = 10
4143
42-let idxMatcherPublicKey = 11
43-
4444 let idxPoolAmtAssetAmt = 1
4545
4646 let idxPoolPriceAssetAmt = 2
5151
5252 let idxFactorySlippageContract = 7
5353
54+func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
55+
56+
57+func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
58+
59+
60+func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
61+
62+
5463 func keyFactoryContract () = "%s__factoryContract"
64+
65+
66+func keyManagerPublicKey () = "%s__managerPublicKey"
5567
5668
5769 func keyPriceLast () = "%s%s__price__last"
5870
5971
6072 func keyPriceHistory (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
61-
62-
63-func keyPoolLiquidity (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__locked")
6473
6574
6675 func keyPutActionByUser (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
7382
7483
7584 func keyPriceAsset () = "%s__priceAsset"
76-
77-
78-func keySlippagePriceAssetCumulative () = "%s__slippagePriceAssetCumulative"
79-
80-
81-func keySlippageAmountAssetCumulative () = "%s__slippageAmountAssetCumulative"
8285
8386
8487 func keyKHistoric (h,timestamp) = makeString(["%s%s%d%d__K_history", toString(h), toString(timestamp)], SEP)
102105 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
103106
104107
105-let factoryContract = addressFromStringValue(valueOrErrorMessage(getString(this, keyFactoryContract()), "No Factory Acc found."))
108+func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
109+
110+
111+func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
112+
113+
114+let factoryContract = addressFromStringValue(getStringOrFail(this, keyFactoryContract()))
106115
107116 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
108117
109118
110119 func getPoolConfig () = {
111- let amtAsset = valueOrErrorMessage(getString(this, keyAmtAsset()), "No config for amt asset found")
112- let priceAsset = valueOrErrorMessage(getString(this, keyPriceAsset()), "No config for price asset found")
113- let iPriceAsset = valueOrErrorMessage(getInteger(factoryContract, keyMappingsBaseAsset2internalId(priceAsset)), "No config for internal price asset found")
114- let iAmtAsset = valueOrErrorMessage(getInteger(factoryContract, keyMappingsBaseAsset2internalId(amtAsset)), "No config for internal amt asset found")
115- split(valueOrErrorMessage(getString(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), "No factory config found for pool assets."), SEP)
120+ let amtAsset = getStringOrFail(this, keyAmtAsset())
121+ let priceAsset = getStringOrFail(this, keyPriceAsset())
122+ let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
123+ let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
124+ split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
116125 }
117126
118127
119-func getFactoryConfig () = split(valueOrErrorMessage(getString(factoryContract, keyFactoryConfig()), "No factory config found."), SEP)
120-
121-
122-func dataPoolLiquidity (amtAssetLocked,priceAssetLocked,lpTokenLocked) = makeString(["%d%d%d", toString(amtAssetLocked), toString(priceAssetLocked), toString(lpTokenLocked)], SEP)
123-
124-
125-func getPoolLiquidity (iAmtAssetId,iPriceAssetId) = split(valueOrElse(getString(this, keyPoolLiquidity(iAmtAssetId, iPriceAssetId)), dataPoolLiquidity(0, 0, 0)), SEP)
128+func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
126129
127130
128131 func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slippageTolerancePassedByUser,slippageToleranceReal,txHeight,txTimestamp,slipageAmtAssetAmt,slipagePriceAssetAmt) = makeString(["%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)
136139 else assetBalance(this, fromBase58String(assetId))
137140
138141
139-func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
140-
141-
142-func toScaleBigInt (amt,resScale,curScale) = fraction(amt, resScale, curScale)
143-
144-
145142 func calcPriceBigInt (priceAssetLockedAmt,amtAssetlLockedAmt,resultScale) = fraction(priceAssetLockedAmt, resultScale, amtAssetlLockedAmt)
146143
147144
148145 func privateCalcPrice (amtAssetDcm,priceAssetDcm,amtAssetAmt,priceAssetAmt) = {
149- let amtAssetAmtCasted = toScaleBigInt(toBigInt(amtAssetAmt), scale18, toBigInt(amtAssetDcm))
150- let priceAssetAmtCasted = toScaleBigInt(toBigInt(priceAssetAmt), scale18, toBigInt(priceAssetDcm))
151- toInt(calcPriceBigInt(priceAssetAmtCasted, amtAssetAmtCasted, scale8BigInt))
146+ let amtAssetAmtX18 = toX18(amtAssetAmt, amtAssetDcm)
147+ let priceAssetAmtX18 = toX18(priceAssetAmt, priceAssetDcm)
148+ toInt(calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18, scale8BigInt))
152149 }
153150
154151
157154 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
158155 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
159156 let poolPrice = privateCalcPrice(amtAssetDcm, priceAssetDcm, amtAssetAmt, priceAssetAmt)
160- let amtAssetPoolLockedAmt = toScaleBigInt(toBigInt(amtAssetAmt), scale18, toBigInt(amtAssetDcm))
161- let priceAssetPoolLockedAmt = toScaleBigInt(toBigInt(priceAssetAmt), scale18, toBigInt(priceAssetDcm))
162- let lpAmtScaled = toScaleBigInt(toBigInt(lpAmt), scale18, scale8BigInt)
163- let lpPriceInAmtAsset = toInt(calcPriceBigInt(amtAssetPoolLockedAmt, lpAmtScaled, scale8BigInt))
164- let lpPriceInPriceAsset = toInt(calcPriceBigInt(priceAssetPoolLockedAmt, lpAmtScaled, scale8BigInt))
157+ let amtAssetAmtX18 = toX18(amtAssetAmt, amtAssetDcm)
158+ let priceAssetAmtX18 = toX18(priceAssetAmt, priceAssetDcm)
159+ let lpAmtX18 = toX18(lpAmt, scale8)
160+ let lpPriceInAmtAsset = toInt(calcPriceBigInt(amtAssetAmtX18, lpAmtX18, scale8BigInt))
161+ let lpPriceInPriceAsset = toInt(calcPriceBigInt(priceAssetAmtX18, lpAmtX18, scale8BigInt))
165162 [poolPrice, lpPriceInAmtAsset, lpPriceInPriceAsset]
166163 }
167164
176173 let amtAssetDcm = parseIntValue(poolConfigList[idxAmtAssetDcm])
177174 let priceAssetDcm = parseIntValue(poolConfigList[idxPriceAssetDcm])
178175 let poolStatus = poolConfigList[idxPoolStatus]
179- let poolLiquidityList = getPoolLiquidity(iAmtAssetId, iPriceAssetId)
180176 let poolLPBalance = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
181177 if ((lpAssetId != paymentLpAssetId))
182178 then throw("Invalid asset passed.")
183179 else {
184- let amtAssetPoolLockedAmt = toScaleBigInt(toBigInt(getAccBalance(amtAssetId)), scale18, toBigInt(amtAssetDcm))
185- let priceAssetPoolLockedAmt = toScaleBigInt(toBigInt(getAccBalance(priceAssetId)), scale18, toBigInt(priceAssetDcm))
186- let curPrice = toInt(calcPriceBigInt(priceAssetPoolLockedAmt, amtAssetPoolLockedAmt, scale8BigInt))
187- let paymentLpAmtBuf = toScaleBigInt(toBigInt(paymentLpAmt), scale18, scale8BigInt)
188- let poolLPBalanceBuf = toScaleBigInt(toBigInt(poolLPBalance), scale18, scale8BigInt)
189- let outAmtAssetAmt = fraction(amtAssetPoolLockedAmt, paymentLpAmtBuf, poolLPBalanceBuf)
190- let outPriceAssetAmt = fraction(priceAssetPoolLockedAmt, paymentLpAmtBuf, poolLPBalanceBuf)
191- let outAmtAssetAmtFinal = toInt(toScaleBigInt(outAmtAssetAmt, toBigInt(amtAssetDcm), scale18))
192- let outPriceAssetAmtFinal = toInt(toScaleBigInt(outPriceAssetAmt, toBigInt(priceAssetDcm), scale18))
193- $Tuple11(outAmtAssetAmtFinal, outPriceAssetAmtFinal, iAmtAssetId, iPriceAssetId, amtAssetId, priceAssetId, toInt(toScaleBigInt(amtAssetPoolLockedAmt, toBigInt(amtAssetDcm), scale18)), toInt(toScaleBigInt(priceAssetPoolLockedAmt, toBigInt(priceAssetDcm), scale18)), poolLPBalance, curPrice, poolStatus)
180+ let amtAssetBalance = getAccBalance(amtAssetId)
181+ let amtAssetBalanceX18 = toX18(amtAssetBalance, amtAssetDcm)
182+ let priceAssetBalance = getAccBalance(priceAssetId)
183+ let priceAssetBalanceX18 = toX18(priceAssetBalance, priceAssetDcm)
184+ let curPrice = toInt(calcPriceBigInt(priceAssetBalanceX18, amtAssetBalanceX18, scale8BigInt))
185+ let paymentLpAmtX18 = toX18(paymentLpAmt, scale8)
186+ let poolLPBalanceX18 = toX18(poolLPBalance, scale8)
187+ let outAmtAssetAmt = fraction(amtAssetBalanceX18, paymentLpAmtX18, poolLPBalanceX18)
188+ let outPriceAssetAmt = fraction(priceAssetBalanceX18, paymentLpAmtX18, poolLPBalanceX18)
189+ let outAmtAssetAmtFinal = fromX18(outAmtAssetAmt, amtAssetDcm)
190+ let outPriceAssetAmtFinal = fromX18(outPriceAssetAmt, priceAssetDcm)
191+ $Tuple11(outAmtAssetAmtFinal, outPriceAssetAmtFinal, iAmtAssetId, iPriceAssetId, amtAssetId, priceAssetId, amtAssetBalance, priceAssetBalance, poolLPBalance, curPrice, poolStatus)
194192 }
195193 }
196194
205203 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
206204 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
207205 let poolStatus = cfg[idxPoolStatus]
208- let poolLiquidityDataList = getPoolLiquidity(iAmtAssetId, iPriceAssetId)
209206 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
210207 if (if ((amtAssetId != inAmtAssetId))
211208 then true
218215 let accPriceAssetBalance = if (isEvaluate)
219216 then getAccBalance(priceAssetId)
220217 else (getAccBalance(priceAssetId) - inPriceAssetAmt)
221- let amtAssetDcmBigInt = toBigInt(amtAssetDcm)
222- let priceAssetDcmBigInt = toBigInt(priceAssetDcm)
223- let inAmtAssetAmtCalc = toScaleBigInt(toBigInt(inAmtAssetAmt), scale18, amtAssetDcmBigInt)
224- let inPriceAssetAmtCalc = toScaleBigInt(toBigInt(inPriceAssetAmt), scale18, priceAssetDcmBigInt)
225- let userPrice = toInt(calcPriceBigInt(inPriceAssetAmtCalc, inAmtAssetAmtCalc, scale8BigInt))
226- let amtAssetPoolLockedAmt = toScaleBigInt(toBigInt(accAmtAssetBalance), scale18, amtAssetDcmBigInt)
227- let priceAssetPoolLockedAmt = toScaleBigInt(toBigInt(accPriceAssetBalance), scale18, priceAssetDcmBigInt)
218+ let inAmtAssetAmtX18 = toX18(inAmtAssetAmt, amtAssetDcm)
219+ let inPriceAssetAmtX18 = toX18(inPriceAssetAmt, priceAssetDcm)
220+ let userPrice = toInt(calcPriceBigInt(inPriceAssetAmtX18, inAmtAssetAmtX18, scale8BigInt))
221+ let accAmtAssetBalanceX18 = toX18(accAmtAssetBalance, amtAssetDcm)
222+ let accPriceAssetBalanceX18 = toX18(accPriceAssetBalance, priceAssetDcm)
228223 let curPrice = if ((poolLPBalance == 0))
229224 then 0
230- else toInt(calcPriceBigInt(priceAssetPoolLockedAmt, amtAssetPoolLockedAmt, scale8BigInt))
225+ else toInt(calcPriceBigInt(accPriceAssetBalanceX18, accAmtAssetBalanceX18, scale8BigInt))
231226 let slippage = if ((curPrice == 0))
232227 then 0
233228 else if ((curPrice > userPrice))
240235 else {
241236 let res = if ((poolLPBalance == 0))
242237 then {
243- let lpResultBuf = pow((inAmtAssetAmtCalc * inPriceAssetAmtCalc), 0, toBigInt(5), 1, 0, DOWN)
244- $Tuple4(toInt(toScaleBigInt(lpResultBuf, scale8BigInt, scale18)), toInt(toScaleBigInt(inAmtAssetAmtCalc, amtAssetDcmBigInt, scale18)), toInt(toScaleBigInt(inPriceAssetAmtCalc, priceAssetDcmBigInt, scale18)), toInt(calcPriceBigInt((priceAssetPoolLockedAmt + inPriceAssetAmtCalc), (amtAssetPoolLockedAmt + inAmtAssetAmtCalc), scale8BigInt)))
238+ let lpResultBuf = pow((inAmtAssetAmtX18 * inPriceAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
239+ $Tuple4(fromX18(lpResultBuf, scale8), fromX18(inAmtAssetAmtX18, amtAssetDcm), fromX18(inPriceAssetAmtX18, priceAssetDcm), toInt(calcPriceBigInt((accPriceAssetBalanceX18 + inPriceAssetAmtX18), (accAmtAssetBalanceX18 + inAmtAssetAmtX18), scale8BigInt)))
245240 }
246241 else {
247- let poolLPBalanceBuf = toScaleBigInt(toBigInt(poolLPBalance), scale18, scale8BigInt)
248- let curPriceScaled = toScaleBigInt(toBigInt(curPrice), scale18, scale8BigInt)
249- let pEqByA = fraction(curPriceScaled, inAmtAssetAmtCalc, scale18)
250- let resAssetsToPut = if ((pEqByA > inPriceAssetAmtCalc))
251- then $Tuple2(fraction(inPriceAssetAmtCalc, scale18, curPriceScaled), inPriceAssetAmtCalc)
252- else $Tuple2(inAmtAssetAmtCalc, pEqByA)
253- let lpResult = toInt(toScaleBigInt(fraction(poolLPBalanceBuf, resAssetsToPut._2, priceAssetPoolLockedAmt), scale8BigInt, scale18))
254- $Tuple4(lpResult, toInt(toScaleBigInt(resAssetsToPut._1, amtAssetDcmBigInt, scale18)), toInt(toScaleBigInt(resAssetsToPut._2, priceAssetDcmBigInt, scale18)), toInt(calcPriceBigInt((priceAssetPoolLockedAmt + resAssetsToPut._2), (amtAssetPoolLockedAmt + resAssetsToPut._1), scale8BigInt)))
242+ let poolLPBalanceX18 = toX18(poolLPBalance, scale8)
243+ let curPriceX18 = toX18(curPrice, scale8)
244+ let pEqByA = fraction(curPriceX18, inAmtAssetAmtX18, scale18)
245+ let resAssetsToPut = if ((pEqByA > inPriceAssetAmtX18))
246+ then $Tuple2(fraction(inPriceAssetAmtX18, scale18, curPriceX18), inPriceAssetAmtX18)
247+ else $Tuple2(inAmtAssetAmtX18, pEqByA)
248+ let lpResult = fromX18(fraction(poolLPBalanceX18, resAssetsToPut._2, accPriceAssetBalanceX18), scale8)
249+ $Tuple4(lpResult, fromX18(resAssetsToPut._1, amtAssetDcm), fromX18(resAssetsToPut._2, priceAssetDcm), toInt(calcPriceBigInt((accPriceAssetBalanceX18 + resAssetsToPut._2), (accAmtAssetBalanceX18 + resAssetsToPut._1), scale8BigInt)))
255250 }
256251 if ((0 >= res._1))
257252 then throw("Invalid calculations. LP calculated is less than zero.")
266261 let amtAssetId = cfg[idxAmtAssetId]
267262 let priceAssetId = cfg[idxPriceAssetId]
268263 let poolStatus = parseIntValue(cfg[idxPoolStatus])
269- let matcherPublicKeyStr = cfg[idxMatcherPublicKey]
270264 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
271265 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
272266 let accAmtAssetBalance = getAccBalance(amtAssetId)
273267 let accPriceAssetBalance = getAccBalance(priceAssetId)
274268 let curPrice = if ((order.orderType == Buy))
275269 then privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
276- else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
277- if (!(sigVerify(order.bodyBytes, order.proofs[0], fromBase58String(matcherPublicKeyStr))))
278- then throw("Incorrect order sender.")
270+ else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance - order.amount), accPriceAssetBalance)
271+ if (if (if (isGlobalShutdown())
272+ then true
273+ else (poolStatus == PoolMatcherDisabled))
274+ then true
275+ else (poolStatus == PoolShutdown))
276+ then throw("Exchange operations disabled")
279277 else {
280278 let orderAmtAsset = order.assetPair.amountAsset
281279 let orderAmtAssetStr = if ((orderAmtAsset == unit))
285283 let orderPriceAssetStr = if ((orderPriceAsset == unit))
286284 then "WAVES"
287285 else toBase58String(value(orderPriceAsset))
288- let orderPrice = order.price
289- let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
290- let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
291- let isOrderPriceValid = if ((order.orderType == Buy))
292- then (curPrice >= castedOrderPrice)
293- else (castedOrderPrice >= curPrice)
294- true
286+ if (if ((orderAmtAssetStr != amtAssetId))
287+ then true
288+ else (orderPriceAssetStr != priceAssetId))
289+ then throw("Wrong order assets.")
290+ else {
291+ let orderPrice = order.price
292+ let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
293+ let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
294+ let isOrderPriceValid = if ((order.orderType == Buy))
295+ then (curPrice >= castedOrderPrice)
296+ else (castedOrderPrice >= curPrice)
297+ if (!(isOrderPriceValid))
298+ then throw("Order price leads to K decrease.")
299+ else true
300+ }
295301 }
296302 }
297303
320326 then unit
321327 else fromBase58String(amtAssetId)), ScriptTransfer(i.caller, outPriceAssetAmt, if ((priceAssetId == "WAVES"))
322328 then unit
323- else fromBase58String(priceAssetId)), StringEntry(keyPoolLiquidity(iAmtAssetId, iPriceAssetId), dataPoolLiquidity((poolAmtAssetBalance - outAmtAssetAmt), (poolPriceAssetBalance - outPriceAssetAmt), (poolLPBalance - pmtAssetAmt))), StringEntry(keyGetActionByUser(toString(i.caller), toBase58String(i.transactionId)), dataGetActionInfo(outAmtAssetAmt, outPriceAssetAmt, pmtAssetAmt, curPrice, height, lastBlock.timestamp)), StringEntry(keyPriceLast(), ("%s__" + toString(curPrice))), StringEntry(keyPriceHistory(height, lastBlock.timestamp), ("%s__" + toString(curPrice)))])
329+ else fromBase58String(priceAssetId)), StringEntry(keyGetActionByUser(toString(i.caller), toBase58String(i.transactionId)), dataGetActionInfo(outAmtAssetAmt, outPriceAssetAmt, pmtAssetAmt, curPrice, height, lastBlock.timestamp)), StringEntry(keyPriceLast(), ("%s__" + toString(curPrice))), StringEntry(keyPriceHistory(height, lastBlock.timestamp), ("%s__" + toString(curPrice)))])
324330 }
325331
326332
327-func commonPut (i,slippageTolerance,shouldAutoStake,emitLp) = {
333+func commonPut (i,slippageTolerance,emitLp) = {
328334 let pmtAmtAsset = value(i.payments[0])
329335 let inAmtAssetAmt = pmtAmtAsset.amount
330336 let inAmtAssetId = if (!(isDefined(pmtAmtAsset.assetId)))
360366 else outLpAmt
361367 let diffInAmtAsset = (inAmtAssetAmt - realAmtAssetIn)
362368 let diffInPriceAsset = (inPriceAssetAmt - realPriceAssetIn)
363- let slippageAmtAssetCum = valueOrElse(getInteger(this, keySlippageAmountAssetCumulative()), 0)
364- let slippagePriceAssetCum = valueOrElse(getInteger(this, keySlippagePriceAssetCumulative()), 0)
365- let dataStateWrite = [StringEntry(keyPriceLast(), ("%s__" + toString(curPrice))), StringEntry(keyPriceHistory(height, lastBlock.timestamp), ("%s__" + toString(curPrice))), StringEntry(keyPutActionByUser(toString(i.caller), toBase58String(i.transactionId)), dataPutActionInfo(realAmtAssetIn, realPriceAssetIn, lpAmtToEmit, curPrice, slippageTolerance, slippageCalc, height, lastBlock.timestamp, diffInAmtAsset, diffInPriceAsset)), StringEntry(keyPoolLiquidity(iAmtAssetId, iPriceAssetId), dataPoolLiquidity((poolAmtAssetBalance + realAmtAssetIn), (poolPriceAssetBalance + realPriceAssetIn), (poolLPBalance + lpAmtToEmit)))]
369+ let dataStateWrite = [StringEntry(keyPriceLast(), ("%s__" + toString(curPrice))), StringEntry(keyPriceHistory(height, lastBlock.timestamp), ("%s__" + toString(curPrice))), StringEntry(keyPutActionByUser(toString(i.caller), toBase58String(i.transactionId)), dataPutActionInfo(realAmtAssetIn, realPriceAssetIn, lpAmtToEmit, curPrice, slippageTolerance, slippageCalc, height, lastBlock.timestamp, diffInAmtAsset, diffInPriceAsset))]
366370 $Tuple9(lpAmtToEmit, lpAssetId, dataStateWrite, inAmtAssetAmt, realAmtAssetIn, inPriceAssetAmt, realPriceAssetIn, pmtAmtAsset.assetId, pmtPriceAsset.assetId)
367371 }
368372 }
369373
370374
371375 @Callable(i)
372-func constructor (factoryContract) = if ((i.caller != this))
376+func constructor (factoryContract,managerPublicKey) = if ((i.caller != this))
373377 then throw("permissions denied")
374- else [StringEntry(keyFactoryContract(), factoryContract)]
378+ else [StringEntry(keyFactoryContract(), factoryContract), StringEntry(keyManagerPublicKey(), managerPublicKey)]
375379
376380
377381
378382 @Callable(i)
379383 func put (slippageTolerance,shouldAutoStake) = {
380384 let factoryCfg = getFactoryConfig()
381- let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactoryStakingContract]), "Error. Incorrect staking address.")
385+ let stakingContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactoryStakingContract]), "Error. Incorrect staking address.")
382386 let slippageContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactorySlippageContract]), "Error. Incorrect slippage contract address.")
383- let actions = commonPut(i, slippageTolerance, shouldAutoStake, true)
387+ let actions = commonPut(i, slippageTolerance, true)
384388 let amtToEmit = actions._1
385389 let lpAssetId = actions._2
386390 let state = actions._3
388392 let realInAmt = actions._5
389393 let inPrice = actions._6
390394 let realInPrice = actions._7
391- let prId = actions._8
392- let amId = actions._9
395+ let amId = actions._8
396+ let prId = actions._9
393397 let diffInAmtAsset = (inAmt - realInAmt)
394398 let diffInPriceAsset = (inPrice - realInPrice)
395- let slippageAmtAssetCum = valueOrElse(getInteger(this, keySlippageAmountAssetCumulative()), 0)
396- let slippagePriceAssetCum = valueOrElse(getInteger(this, keySlippagePriceAssetCumulative()), 0)
397- let emit = invoke(factoryContract, "emit", [actions._1], nil)
398- if ((emit == emit))
399+ let emitInv = invoke(factoryContract, "emit", [amtToEmit], nil)
400+ if ((emitInv == emitInv))
399401 then {
400- let dataAndSlippage = (state ++ (if ((inAmt > realInAmt))
402+ let slippageAInv = if ((inAmt > realInAmt))
403+ then invoke(slippageContract, "put", nil, [AttachedPayment(amId, diffInAmtAsset)])
404+ else nil
405+ if ((slippageAInv == slippageAInv))
401406 then {
402- let stake = invoke(slippageContract, "put", nil, [AttachedPayment(amId, diffInAmtAsset)])
403- if ((stake == stake))
404- then [IntegerEntry(keySlippageAmountAssetCumulative(), (slippageAmtAssetCum + diffInAmtAsset))]
407+ let slippagePInv = if ((inPrice > realInPrice))
408+ then invoke(slippageContract, "put", nil, [AttachedPayment(prId, diffInPriceAsset)])
409+ else nil
410+ if ((slippagePInv == slippagePInv))
411+ then {
412+ let lpStakeInv = if (shouldAutoStake)
413+ then invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, amtToEmit)])
414+ else nil
415+ if ((lpStakeInv == lpStakeInv))
416+ then (state :+ ScriptTransfer(i.caller, amtToEmit, lpAssetId))
417+ else throw("Strict value is not equal to itself.")
418+ }
405419 else throw("Strict value is not equal to itself.")
406420 }
407- else (nil ++ (if ((inPrice > realInPrice))
408- then {
409- let stake = invoke(slippageContract, "put", nil, [AttachedPayment(prId, diffInPriceAsset)])
410- if ((stake == stake))
411- then [IntegerEntry(keySlippagePriceAssetCumulative(), (slippagePriceAssetCum + diffInPriceAsset))]
412- else throw("Strict value is not equal to itself.")
413- }
414- else nil))))
415- let finalResults = if (shouldAutoStake)
416- then {
417- let stake = invoke(staking, "stake", nil, [AttachedPayment(lpAssetId, amtToEmit)])
418- if ((stake == stake))
419- then dataAndSlippage
420- else throw("Strict value is not equal to itself.")
421- }
422- else (dataAndSlippage :+ ScriptTransfer(i.caller, amtToEmit, lpAssetId))
423- finalResults
421+ else throw("Strict value is not equal to itself.")
424422 }
425423 else throw("Strict value is not equal to itself.")
426424 }
429427
430428 @Callable(i)
431429 func putForFree () = {
432- let actions = commonPut(i, 0, false, false)
430+ let actions = commonPut(i, 0, false)
433431 actions._3
434432 }
435433
490488 let iPriceAssetId = cfg[idxIPriceAssetId]
491489 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
492490 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
493- let poolLiquidityDataList = getPoolLiquidity(iAmtAssetId, iPriceAssetId)
494491 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
495492 let accAmtAssetBalance = getAccBalance(amtAssetId)
496493 let accPriceAssetBalance = getAccBalance(priceAssetId)
498495 let curPrice = pricesList[0]
499496 let lpAmtAssetShare = pricesList[1]
500497 let lpPriceAssetShare = pricesList[2]
501- let poolWeight = valueOrErrorMessage(getInteger(factoryContract, keyPoolWeight(toString(this))), "Pool doesn't have weight.")
498+ let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
502499 $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))
503500 }
504501
515512 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
516513 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
517514 let poolStatus = cfg[idxPoolStatus]
518- let poolLiquidityDataList = getPoolLiquidity(iAmtAssetId, iPriceAssetId)
519515 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
520516 let accAmtAssetBalance = getAccBalance(amtAssetId)
521517 let accPriceAssetBalance = getAccBalance(priceAssetId)
522- let amtAssetAmtScaled = toScaleBigInt(toBigInt(accAmtAssetBalance), scale18, toBigInt(amtAssetDcm))
523- let priceAssetAmtScaled = toScaleBigInt(toBigInt(accPriceAssetBalance), scale18, toBigInt(priceAssetDcm))
524- let curPrice = if ((poolLPBalance == 0))
518+ let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
519+ let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
520+ let curPriceX18 = if ((poolLPBalance == 0))
525521 then toBigInt(0)
526- else calcPriceBigInt(priceAssetAmtScaled, amtAssetAmtScaled, scale18)
527- let inAmtAssetAmtScaled = toScaleBigInt(toBigInt(inAmtAssetAmt), scale18, toBigInt(amtAssetDcm))
528- let inPriceAssetAmtCalc = fraction(inAmtAssetAmtScaled, curPrice, scale18)
529- let inPriceAssetAmt = toInt(toScaleBigInt(inPriceAssetAmtCalc, toBigInt(priceAssetDcm), scale18))
522+ else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18, scale18)
523+ let inAmtAssetAmtX18 = toX18(inAmtAssetAmt, amtAssetDcm)
524+ let inPriceAssetAmtX18 = fraction(inAmtAssetAmtX18, curPriceX18, scale18)
525+ let inPriceAssetAmt = fromX18(inPriceAssetAmtX18, priceAssetDcm)
530526 let estimatedPutResults = estimatePutOperation(slippageTolerance, inAmtAssetAmt, amtAssetId, inPriceAssetAmt, priceAssetId, userAddress, true)
531527 let outLpAmtCalc = estimatedPutResults._1
532528 let curPriceCalc = estimatedPutResults._2
534530 let poolPriceAssetBalanceCAlc = estimatedPutResults._4
535531 let poolLPBalanceCalc = estimatedPutResults._5
536532 let poolStatusCalc = parseIntValue(estimatedPutResults._10)
537- $Tuple2(nil, makeString(["%d%d%d%d%d%d", toString(outLpAmtCalc), toString(toInt(toScaleBigInt(curPrice, scale8BigInt, scale18))), toString(poolAmtAssetBalanceCalc), toString(poolPriceAssetBalanceCAlc), toString(poolLPBalanceCalc), toString(poolStatusCalc)], SEP))
533+ $Tuple2(nil, makeString(["%d%d%d%d%d%d", toString(outLpAmtCalc), toString(fromX18(curPriceX18, scale8)), toString(poolAmtAssetBalanceCalc), toString(poolPriceAssetBalanceCAlc), toString(poolLPBalanceCalc), toString(poolStatusCalc)], SEP))
538534 }
539535
540536
550546 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
551547 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
552548 let poolStatus = cfg[idxPoolStatus]
553- let poolLiquidityDataList = getPoolLiquidity(iAmtAssetId, iPriceAssetId)
554549 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
555550 let accAmtAssetBalance = getAccBalance(amtAssetId)
556551 let accPriceAssetBalance = getAccBalance(priceAssetId)
557- let amtAssetAmtScaled = toScaleBigInt(toBigInt(accAmtAssetBalance), scale18, toBigInt(amtAssetDcm))
558- let priceAssetAmtScaled = toScaleBigInt(toBigInt(accPriceAssetBalance), scale18, toBigInt(priceAssetDcm))
559- let curPrice = if ((poolLPBalance == 0))
552+ let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
553+ let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
554+ let curPriceX18 = if ((poolLPBalance == 0))
560555 then toBigInt(0)
561- else calcPriceBigInt(priceAssetAmtScaled, amtAssetAmtScaled, scale18)
562- let inPriceAssetAmtScaled = toScaleBigInt(toBigInt(inPriceAssetAmt), scale18, toBigInt(priceAssetDcm))
563- let inAmtAssetAmtCalc = fraction(inPriceAssetAmtScaled, scale18, curPrice)
564- let inAmtAssetAmt = toInt(toScaleBigInt(inAmtAssetAmtCalc, toBigInt(amtAssetDcm), scale18))
556+ else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18, scale18)
557+ let inPriceAssetAmtX18 = toX18(inPriceAssetAmt, priceAssetDcm)
558+ let inAmtAssetAmtX18 = fraction(inPriceAssetAmtX18, scale18, curPriceX18)
559+ let inAmtAssetAmt = fromX18(inAmtAssetAmtX18, amtAssetDcm)
565560 let estimatedPutResults = estimatePutOperation(slippageTolerance, inAmtAssetAmt, amtAssetId, inPriceAssetAmt, priceAssetId, userAddress, true)
566561 let outLpAmtCalc = estimatedPutResults._1
567562 let curPriceCalc = estimatedPutResults._2
569564 let poolPriceAssetBalanceCAlc = estimatedPutResults._4
570565 let poolLPBalanceCalc = estimatedPutResults._5
571566 let poolStatusCalc = parseIntValue(estimatedPutResults._10)
572- $Tuple2(nil, makeString(["%d%d%d%d%d%d", toString(outLpAmtCalc), toString(toInt(toScaleBigInt(curPrice, scale8BigInt, scale18))), toString(poolAmtAssetBalanceCalc), toString(poolPriceAssetBalanceCAlc), toString(poolLPBalanceCalc), toString(poolStatusCalc)], SEP))
567+ $Tuple2(nil, makeString(["%d%d%d%d%d%d", toString(outLpAmtCalc), toString(fromX18(curPriceX18, scale8)), toString(poolAmtAssetBalanceCalc), toString(poolPriceAssetBalanceCAlc), toString(poolLPBalanceCalc), toString(poolStatusCalc)], SEP))
573568 }
574569
575570
591586 @Verifier(tx)
592587 func verify () = match tx {
593588 case order: Order =>
594- validateMatcherOrderAllowed(order)
589+ if (validateMatcherOrderAllowed(order))
590+ then sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
591+ else false
595592 case _ =>
596593 sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
597594 }
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
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 SEP = "__"
13+
14+let EMPTY = ""
1315
1416 let PoolActive = 1
1517
1618 let PoolPutDisabled = 2
1719
1820 let PoolMatcherDisabled = 3
1921
2022 let PoolShutdown = 4
2123
2224 let idxPoolAddress = 1
2325
2426 let idxPoolStatus = 2
2527
2628 let idxPoolLPAssetId = 3
2729
2830 let idxAmtAssetId = 4
2931
3032 let idxPriceAssetId = 5
3133
3234 let idxAmtAssetDcm = 6
3335
3436 let idxPriceAssetDcm = 7
3537
3638 let idxIAmtAssetId = 8
3739
3840 let idxIPriceAssetId = 9
3941
4042 let idxLPAssetDcm = 10
4143
42-let idxMatcherPublicKey = 11
43-
4444 let idxPoolAmtAssetAmt = 1
4545
4646 let idxPoolPriceAssetAmt = 2
4747
4848 let idxPoolLPAssetAmt = 3
4949
5050 let idxFactoryStakingContract = 1
5151
5252 let idxFactorySlippageContract = 7
5353
54+func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
55+
56+
57+func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
58+
59+
60+func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
61+
62+
5463 func keyFactoryContract () = "%s__factoryContract"
64+
65+
66+func keyManagerPublicKey () = "%s__managerPublicKey"
5567
5668
5769 func keyPriceLast () = "%s%s__price__last"
5870
5971
6072 func keyPriceHistory (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
61-
62-
63-func keyPoolLiquidity (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__locked")
6473
6574
6675 func keyPutActionByUser (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
6776
6877
6978 func keyGetActionByUser (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
7079
7180
7281 func keyAmtAsset () = "%s__amountAsset"
7382
7483
7584 func keyPriceAsset () = "%s__priceAsset"
76-
77-
78-func keySlippagePriceAssetCumulative () = "%s__slippagePriceAssetCumulative"
79-
80-
81-func keySlippageAmountAssetCumulative () = "%s__slippageAmountAssetCumulative"
8285
8386
8487 func keyKHistoric (h,timestamp) = makeString(["%s%s%d%d__K_history", toString(h), toString(timestamp)], SEP)
8588
8689
8790 func keyFactoryConfig () = "%s__factoryConfig"
8891
8992
9093 func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
9194
9295
9396 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
9497
9598
9699 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
97100
98101
99102 func keyAllPoolsShutdown () = "%s__shutdown"
100103
101104
102105 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
103106
104107
105-let factoryContract = addressFromStringValue(valueOrErrorMessage(getString(this, keyFactoryContract()), "No Factory Acc found."))
108+func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
109+
110+
111+func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
112+
113+
114+let factoryContract = addressFromStringValue(getStringOrFail(this, keyFactoryContract()))
106115
107116 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
108117
109118
110119 func getPoolConfig () = {
111- let amtAsset = valueOrErrorMessage(getString(this, keyAmtAsset()), "No config for amt asset found")
112- let priceAsset = valueOrErrorMessage(getString(this, keyPriceAsset()), "No config for price asset found")
113- let iPriceAsset = valueOrErrorMessage(getInteger(factoryContract, keyMappingsBaseAsset2internalId(priceAsset)), "No config for internal price asset found")
114- let iAmtAsset = valueOrErrorMessage(getInteger(factoryContract, keyMappingsBaseAsset2internalId(amtAsset)), "No config for internal amt asset found")
115- split(valueOrErrorMessage(getString(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), "No factory config found for pool assets."), SEP)
120+ let amtAsset = getStringOrFail(this, keyAmtAsset())
121+ let priceAsset = getStringOrFail(this, keyPriceAsset())
122+ let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
123+ let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
124+ split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
116125 }
117126
118127
119-func getFactoryConfig () = split(valueOrErrorMessage(getString(factoryContract, keyFactoryConfig()), "No factory config found."), SEP)
120-
121-
122-func dataPoolLiquidity (amtAssetLocked,priceAssetLocked,lpTokenLocked) = makeString(["%d%d%d", toString(amtAssetLocked), toString(priceAssetLocked), toString(lpTokenLocked)], SEP)
123-
124-
125-func getPoolLiquidity (iAmtAssetId,iPriceAssetId) = split(valueOrElse(getString(this, keyPoolLiquidity(iAmtAssetId, iPriceAssetId)), dataPoolLiquidity(0, 0, 0)), SEP)
128+func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
126129
127130
128131 func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slippageTolerancePassedByUser,slippageToleranceReal,txHeight,txTimestamp,slipageAmtAssetAmt,slipagePriceAssetAmt) = makeString(["%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)
129132
130133
131134 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)
132135
133136
134137 func getAccBalance (assetId) = if ((assetId == "WAVES"))
135138 then wavesBalance(this).available
136139 else assetBalance(this, fromBase58String(assetId))
137140
138141
139-func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
140-
141-
142-func toScaleBigInt (amt,resScale,curScale) = fraction(amt, resScale, curScale)
143-
144-
145142 func calcPriceBigInt (priceAssetLockedAmt,amtAssetlLockedAmt,resultScale) = fraction(priceAssetLockedAmt, resultScale, amtAssetlLockedAmt)
146143
147144
148145 func privateCalcPrice (amtAssetDcm,priceAssetDcm,amtAssetAmt,priceAssetAmt) = {
149- let amtAssetAmtCasted = toScaleBigInt(toBigInt(amtAssetAmt), scale18, toBigInt(amtAssetDcm))
150- let priceAssetAmtCasted = toScaleBigInt(toBigInt(priceAssetAmt), scale18, toBigInt(priceAssetDcm))
151- toInt(calcPriceBigInt(priceAssetAmtCasted, amtAssetAmtCasted, scale8BigInt))
146+ let amtAssetAmtX18 = toX18(amtAssetAmt, amtAssetDcm)
147+ let priceAssetAmtX18 = toX18(priceAssetAmt, priceAssetDcm)
148+ toInt(calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18, scale8BigInt))
152149 }
153150
154151
155152 func calcPrices (amtAssetAmt,priceAssetAmt,lpAmt) = {
156153 let cfg = getPoolConfig()
157154 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
158155 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
159156 let poolPrice = privateCalcPrice(amtAssetDcm, priceAssetDcm, amtAssetAmt, priceAssetAmt)
160- let amtAssetPoolLockedAmt = toScaleBigInt(toBigInt(amtAssetAmt), scale18, toBigInt(amtAssetDcm))
161- let priceAssetPoolLockedAmt = toScaleBigInt(toBigInt(priceAssetAmt), scale18, toBigInt(priceAssetDcm))
162- let lpAmtScaled = toScaleBigInt(toBigInt(lpAmt), scale18, scale8BigInt)
163- let lpPriceInAmtAsset = toInt(calcPriceBigInt(amtAssetPoolLockedAmt, lpAmtScaled, scale8BigInt))
164- let lpPriceInPriceAsset = toInt(calcPriceBigInt(priceAssetPoolLockedAmt, lpAmtScaled, scale8BigInt))
157+ let amtAssetAmtX18 = toX18(amtAssetAmt, amtAssetDcm)
158+ let priceAssetAmtX18 = toX18(priceAssetAmt, priceAssetDcm)
159+ let lpAmtX18 = toX18(lpAmt, scale8)
160+ let lpPriceInAmtAsset = toInt(calcPriceBigInt(amtAssetAmtX18, lpAmtX18, scale8BigInt))
161+ let lpPriceInPriceAsset = toInt(calcPriceBigInt(priceAssetAmtX18, lpAmtX18, scale8BigInt))
165162 [poolPrice, lpPriceInAmtAsset, lpPriceInPriceAsset]
166163 }
167164
168165
169166 func estimateGetOperation (paymentLpAssetId,paymentLpAmt,userAddress) = {
170167 let poolConfigList = getPoolConfig()
171168 let lpAssetId = poolConfigList[idxPoolLPAssetId]
172169 let amtAssetId = poolConfigList[idxAmtAssetId]
173170 let priceAssetId = poolConfigList[idxPriceAssetId]
174171 let iAmtAssetId = poolConfigList[idxIAmtAssetId]
175172 let iPriceAssetId = poolConfigList[idxIPriceAssetId]
176173 let amtAssetDcm = parseIntValue(poolConfigList[idxAmtAssetDcm])
177174 let priceAssetDcm = parseIntValue(poolConfigList[idxPriceAssetDcm])
178175 let poolStatus = poolConfigList[idxPoolStatus]
179- let poolLiquidityList = getPoolLiquidity(iAmtAssetId, iPriceAssetId)
180176 let poolLPBalance = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
181177 if ((lpAssetId != paymentLpAssetId))
182178 then throw("Invalid asset passed.")
183179 else {
184- let amtAssetPoolLockedAmt = toScaleBigInt(toBigInt(getAccBalance(amtAssetId)), scale18, toBigInt(amtAssetDcm))
185- let priceAssetPoolLockedAmt = toScaleBigInt(toBigInt(getAccBalance(priceAssetId)), scale18, toBigInt(priceAssetDcm))
186- let curPrice = toInt(calcPriceBigInt(priceAssetPoolLockedAmt, amtAssetPoolLockedAmt, scale8BigInt))
187- let paymentLpAmtBuf = toScaleBigInt(toBigInt(paymentLpAmt), scale18, scale8BigInt)
188- let poolLPBalanceBuf = toScaleBigInt(toBigInt(poolLPBalance), scale18, scale8BigInt)
189- let outAmtAssetAmt = fraction(amtAssetPoolLockedAmt, paymentLpAmtBuf, poolLPBalanceBuf)
190- let outPriceAssetAmt = fraction(priceAssetPoolLockedAmt, paymentLpAmtBuf, poolLPBalanceBuf)
191- let outAmtAssetAmtFinal = toInt(toScaleBigInt(outAmtAssetAmt, toBigInt(amtAssetDcm), scale18))
192- let outPriceAssetAmtFinal = toInt(toScaleBigInt(outPriceAssetAmt, toBigInt(priceAssetDcm), scale18))
193- $Tuple11(outAmtAssetAmtFinal, outPriceAssetAmtFinal, iAmtAssetId, iPriceAssetId, amtAssetId, priceAssetId, toInt(toScaleBigInt(amtAssetPoolLockedAmt, toBigInt(amtAssetDcm), scale18)), toInt(toScaleBigInt(priceAssetPoolLockedAmt, toBigInt(priceAssetDcm), scale18)), poolLPBalance, curPrice, poolStatus)
180+ let amtAssetBalance = getAccBalance(amtAssetId)
181+ let amtAssetBalanceX18 = toX18(amtAssetBalance, amtAssetDcm)
182+ let priceAssetBalance = getAccBalance(priceAssetId)
183+ let priceAssetBalanceX18 = toX18(priceAssetBalance, priceAssetDcm)
184+ let curPrice = toInt(calcPriceBigInt(priceAssetBalanceX18, amtAssetBalanceX18, scale8BigInt))
185+ let paymentLpAmtX18 = toX18(paymentLpAmt, scale8)
186+ let poolLPBalanceX18 = toX18(poolLPBalance, scale8)
187+ let outAmtAssetAmt = fraction(amtAssetBalanceX18, paymentLpAmtX18, poolLPBalanceX18)
188+ let outPriceAssetAmt = fraction(priceAssetBalanceX18, paymentLpAmtX18, poolLPBalanceX18)
189+ let outAmtAssetAmtFinal = fromX18(outAmtAssetAmt, amtAssetDcm)
190+ let outPriceAssetAmtFinal = fromX18(outPriceAssetAmt, priceAssetDcm)
191+ $Tuple11(outAmtAssetAmtFinal, outPriceAssetAmtFinal, iAmtAssetId, iPriceAssetId, amtAssetId, priceAssetId, amtAssetBalance, priceAssetBalance, poolLPBalance, curPrice, poolStatus)
194192 }
195193 }
196194
197195
198196 func estimatePutOperation (slippageTolerance,inAmtAssetAmt,inAmtAssetId,inPriceAssetAmt,inPriceAssetId,userAddress,isEvaluate) = {
199197 let cfg = getPoolConfig()
200198 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
201199 let amtAssetId = cfg[idxAmtAssetId]
202200 let priceAssetId = cfg[idxPriceAssetId]
203201 let iAmtAssetId = cfg[idxIAmtAssetId]
204202 let iPriceAssetId = cfg[idxIPriceAssetId]
205203 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
206204 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
207205 let poolStatus = cfg[idxPoolStatus]
208- let poolLiquidityDataList = getPoolLiquidity(iAmtAssetId, iPriceAssetId)
209206 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
210207 if (if ((amtAssetId != inAmtAssetId))
211208 then true
212209 else (priceAssetId != inPriceAssetId))
213210 then throw("Invalid amt or price asset passed.")
214211 else {
215212 let accAmtAssetBalance = if (isEvaluate)
216213 then getAccBalance(amtAssetId)
217214 else (getAccBalance(amtAssetId) - inAmtAssetAmt)
218215 let accPriceAssetBalance = if (isEvaluate)
219216 then getAccBalance(priceAssetId)
220217 else (getAccBalance(priceAssetId) - inPriceAssetAmt)
221- let amtAssetDcmBigInt = toBigInt(amtAssetDcm)
222- let priceAssetDcmBigInt = toBigInt(priceAssetDcm)
223- let inAmtAssetAmtCalc = toScaleBigInt(toBigInt(inAmtAssetAmt), scale18, amtAssetDcmBigInt)
224- let inPriceAssetAmtCalc = toScaleBigInt(toBigInt(inPriceAssetAmt), scale18, priceAssetDcmBigInt)
225- let userPrice = toInt(calcPriceBigInt(inPriceAssetAmtCalc, inAmtAssetAmtCalc, scale8BigInt))
226- let amtAssetPoolLockedAmt = toScaleBigInt(toBigInt(accAmtAssetBalance), scale18, amtAssetDcmBigInt)
227- let priceAssetPoolLockedAmt = toScaleBigInt(toBigInt(accPriceAssetBalance), scale18, priceAssetDcmBigInt)
218+ let inAmtAssetAmtX18 = toX18(inAmtAssetAmt, amtAssetDcm)
219+ let inPriceAssetAmtX18 = toX18(inPriceAssetAmt, priceAssetDcm)
220+ let userPrice = toInt(calcPriceBigInt(inPriceAssetAmtX18, inAmtAssetAmtX18, scale8BigInt))
221+ let accAmtAssetBalanceX18 = toX18(accAmtAssetBalance, amtAssetDcm)
222+ let accPriceAssetBalanceX18 = toX18(accPriceAssetBalance, priceAssetDcm)
228223 let curPrice = if ((poolLPBalance == 0))
229224 then 0
230- else toInt(calcPriceBigInt(priceAssetPoolLockedAmt, amtAssetPoolLockedAmt, scale8BigInt))
225+ else toInt(calcPriceBigInt(accPriceAssetBalanceX18, accAmtAssetBalanceX18, scale8BigInt))
231226 let slippage = if ((curPrice == 0))
232227 then 0
233228 else if ((curPrice > userPrice))
234229 then fraction((curPrice - userPrice), scale8, curPrice)
235230 else fraction((userPrice - curPrice), scale8, curPrice)
236231 if (if ((curPrice != 0))
237232 then (slippage > slippageTolerance)
238233 else false)
239234 then throw(((("Price slippage " + toString(slippage)) + " exceeded the passed limit of ") + toString(slippageTolerance)))
240235 else {
241236 let res = if ((poolLPBalance == 0))
242237 then {
243- let lpResultBuf = pow((inAmtAssetAmtCalc * inPriceAssetAmtCalc), 0, toBigInt(5), 1, 0, DOWN)
244- $Tuple4(toInt(toScaleBigInt(lpResultBuf, scale8BigInt, scale18)), toInt(toScaleBigInt(inAmtAssetAmtCalc, amtAssetDcmBigInt, scale18)), toInt(toScaleBigInt(inPriceAssetAmtCalc, priceAssetDcmBigInt, scale18)), toInt(calcPriceBigInt((priceAssetPoolLockedAmt + inPriceAssetAmtCalc), (amtAssetPoolLockedAmt + inAmtAssetAmtCalc), scale8BigInt)))
238+ let lpResultBuf = pow((inAmtAssetAmtX18 * inPriceAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
239+ $Tuple4(fromX18(lpResultBuf, scale8), fromX18(inAmtAssetAmtX18, amtAssetDcm), fromX18(inPriceAssetAmtX18, priceAssetDcm), toInt(calcPriceBigInt((accPriceAssetBalanceX18 + inPriceAssetAmtX18), (accAmtAssetBalanceX18 + inAmtAssetAmtX18), scale8BigInt)))
245240 }
246241 else {
247- let poolLPBalanceBuf = toScaleBigInt(toBigInt(poolLPBalance), scale18, scale8BigInt)
248- let curPriceScaled = toScaleBigInt(toBigInt(curPrice), scale18, scale8BigInt)
249- let pEqByA = fraction(curPriceScaled, inAmtAssetAmtCalc, scale18)
250- let resAssetsToPut = if ((pEqByA > inPriceAssetAmtCalc))
251- then $Tuple2(fraction(inPriceAssetAmtCalc, scale18, curPriceScaled), inPriceAssetAmtCalc)
252- else $Tuple2(inAmtAssetAmtCalc, pEqByA)
253- let lpResult = toInt(toScaleBigInt(fraction(poolLPBalanceBuf, resAssetsToPut._2, priceAssetPoolLockedAmt), scale8BigInt, scale18))
254- $Tuple4(lpResult, toInt(toScaleBigInt(resAssetsToPut._1, amtAssetDcmBigInt, scale18)), toInt(toScaleBigInt(resAssetsToPut._2, priceAssetDcmBigInt, scale18)), toInt(calcPriceBigInt((priceAssetPoolLockedAmt + resAssetsToPut._2), (amtAssetPoolLockedAmt + resAssetsToPut._1), scale8BigInt)))
242+ let poolLPBalanceX18 = toX18(poolLPBalance, scale8)
243+ let curPriceX18 = toX18(curPrice, scale8)
244+ let pEqByA = fraction(curPriceX18, inAmtAssetAmtX18, scale18)
245+ let resAssetsToPut = if ((pEqByA > inPriceAssetAmtX18))
246+ then $Tuple2(fraction(inPriceAssetAmtX18, scale18, curPriceX18), inPriceAssetAmtX18)
247+ else $Tuple2(inAmtAssetAmtX18, pEqByA)
248+ let lpResult = fromX18(fraction(poolLPBalanceX18, resAssetsToPut._2, accPriceAssetBalanceX18), scale8)
249+ $Tuple4(lpResult, fromX18(resAssetsToPut._1, amtAssetDcm), fromX18(resAssetsToPut._2, priceAssetDcm), toInt(calcPriceBigInt((accPriceAssetBalanceX18 + resAssetsToPut._2), (accAmtAssetBalanceX18 + resAssetsToPut._1), scale8BigInt)))
255250 }
256251 if ((0 >= res._1))
257252 then throw("Invalid calculations. LP calculated is less than zero.")
258253 else $Tuple12(res._1, res._4, accAmtAssetBalance, accPriceAssetBalance, poolLPBalance, iAmtAssetId, iPriceAssetId, lpAssetId, slippage, poolStatus, res._2, res._3)
259254 }
260255 }
261256 }
262257
263258
264259 func validateMatcherOrderAllowed (order) = {
265260 let cfg = getPoolConfig()
266261 let amtAssetId = cfg[idxAmtAssetId]
267262 let priceAssetId = cfg[idxPriceAssetId]
268263 let poolStatus = parseIntValue(cfg[idxPoolStatus])
269- let matcherPublicKeyStr = cfg[idxMatcherPublicKey]
270264 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
271265 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
272266 let accAmtAssetBalance = getAccBalance(amtAssetId)
273267 let accPriceAssetBalance = getAccBalance(priceAssetId)
274268 let curPrice = if ((order.orderType == Buy))
275269 then privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
276- else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
277- if (!(sigVerify(order.bodyBytes, order.proofs[0], fromBase58String(matcherPublicKeyStr))))
278- then throw("Incorrect order sender.")
270+ else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance - order.amount), accPriceAssetBalance)
271+ if (if (if (isGlobalShutdown())
272+ then true
273+ else (poolStatus == PoolMatcherDisabled))
274+ then true
275+ else (poolStatus == PoolShutdown))
276+ then throw("Exchange operations disabled")
279277 else {
280278 let orderAmtAsset = order.assetPair.amountAsset
281279 let orderAmtAssetStr = if ((orderAmtAsset == unit))
282280 then "WAVES"
283281 else toBase58String(value(orderAmtAsset))
284282 let orderPriceAsset = order.assetPair.priceAsset
285283 let orderPriceAssetStr = if ((orderPriceAsset == unit))
286284 then "WAVES"
287285 else toBase58String(value(orderPriceAsset))
288- let orderPrice = order.price
289- let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
290- let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
291- let isOrderPriceValid = if ((order.orderType == Buy))
292- then (curPrice >= castedOrderPrice)
293- else (castedOrderPrice >= curPrice)
294- true
286+ if (if ((orderAmtAssetStr != amtAssetId))
287+ then true
288+ else (orderPriceAssetStr != priceAssetId))
289+ then throw("Wrong order assets.")
290+ else {
291+ let orderPrice = order.price
292+ let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
293+ let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
294+ let isOrderPriceValid = if ((order.orderType == Buy))
295+ then (curPrice >= castedOrderPrice)
296+ else (castedOrderPrice >= curPrice)
297+ if (!(isOrderPriceValid))
298+ then throw("Order price leads to K decrease.")
299+ else true
300+ }
295301 }
296302 }
297303
298304
299305 func commonGet (i) = {
300306 let pmtAmtAsset = value(i.payments[0])
301307 let pmtAssetId = value(pmtAmtAsset.assetId)
302308 let pmtAssetAmt = pmtAmtAsset.amount
303309 let res = estimateGetOperation(toBase58String(pmtAssetId), pmtAssetAmt, toString(i.caller))
304310 let outAmtAssetAmt = res._1
305311 let outPriceAssetAmt = res._2
306312 let iAmtAssetId = res._3
307313 let iPriceAssetId = res._4
308314 let amtAssetId = res._5
309315 let priceAssetId = res._6
310316 let poolAmtAssetBalance = res._7
311317 let poolPriceAssetBalance = res._8
312318 let poolLPBalance = res._9
313319 let curPrice = res._10
314320 let poolStatus = parseIntValue(res._11)
315321 if (if (isGlobalShutdown())
316322 then true
317323 else (poolStatus == PoolShutdown))
318324 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
319325 else $Tuple5(outAmtAssetAmt, outPriceAssetAmt, pmtAssetAmt, pmtAssetId, [ScriptTransfer(i.caller, outAmtAssetAmt, if ((amtAssetId == "WAVES"))
320326 then unit
321327 else fromBase58String(amtAssetId)), ScriptTransfer(i.caller, outPriceAssetAmt, if ((priceAssetId == "WAVES"))
322328 then unit
323- else fromBase58String(priceAssetId)), StringEntry(keyPoolLiquidity(iAmtAssetId, iPriceAssetId), dataPoolLiquidity((poolAmtAssetBalance - outAmtAssetAmt), (poolPriceAssetBalance - outPriceAssetAmt), (poolLPBalance - pmtAssetAmt))), StringEntry(keyGetActionByUser(toString(i.caller), toBase58String(i.transactionId)), dataGetActionInfo(outAmtAssetAmt, outPriceAssetAmt, pmtAssetAmt, curPrice, height, lastBlock.timestamp)), StringEntry(keyPriceLast(), ("%s__" + toString(curPrice))), StringEntry(keyPriceHistory(height, lastBlock.timestamp), ("%s__" + toString(curPrice)))])
329+ else fromBase58String(priceAssetId)), StringEntry(keyGetActionByUser(toString(i.caller), toBase58String(i.transactionId)), dataGetActionInfo(outAmtAssetAmt, outPriceAssetAmt, pmtAssetAmt, curPrice, height, lastBlock.timestamp)), StringEntry(keyPriceLast(), ("%s__" + toString(curPrice))), StringEntry(keyPriceHistory(height, lastBlock.timestamp), ("%s__" + toString(curPrice)))])
324330 }
325331
326332
327-func commonPut (i,slippageTolerance,shouldAutoStake,emitLp) = {
333+func commonPut (i,slippageTolerance,emitLp) = {
328334 let pmtAmtAsset = value(i.payments[0])
329335 let inAmtAssetAmt = pmtAmtAsset.amount
330336 let inAmtAssetId = if (!(isDefined(pmtAmtAsset.assetId)))
331337 then fromBase58String("WAVES")
332338 else value(pmtAmtAsset.assetId)
333339 let pmtPriceAsset = value(i.payments[1])
334340 let inPriceAssetAmt = pmtPriceAsset.amount
335341 let inPriceAssetId = if (!(isDefined(pmtPriceAsset.assetId)))
336342 then fromBase58String("WAVES")
337343 else value(pmtPriceAsset.assetId)
338344 let estPut = estimatePutOperation(slippageTolerance, inAmtAssetAmt, toBase58String(inAmtAssetId), inPriceAssetAmt, toBase58String(inPriceAssetId), toString(i.caller), false)
339345 let outLpAmt = estPut._1
340346 let curPrice = estPut._2
341347 let poolAmtAssetBalance = estPut._3
342348 let poolPriceAssetBalance = estPut._4
343349 let poolLPBalance = estPut._5
344350 let iAmtAssetId = estPut._6
345351 let iPriceAssetId = estPut._7
346352 let lpAssetId = estPut._8
347353 let slippageCalc = estPut._9
348354 let poolStatus = parseIntValue(estPut._10)
349355 let realAmtAssetIn = estPut._11
350356 let realPriceAssetIn = estPut._12
351357 if (if (if (isGlobalShutdown())
352358 then true
353359 else (poolStatus == PoolPutDisabled))
354360 then true
355361 else (poolStatus == PoolShutdown))
356362 then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
357363 else {
358364 let lpAmtToEmit = if (!(emitLp))
359365 then 0
360366 else outLpAmt
361367 let diffInAmtAsset = (inAmtAssetAmt - realAmtAssetIn)
362368 let diffInPriceAsset = (inPriceAssetAmt - realPriceAssetIn)
363- let slippageAmtAssetCum = valueOrElse(getInteger(this, keySlippageAmountAssetCumulative()), 0)
364- let slippagePriceAssetCum = valueOrElse(getInteger(this, keySlippagePriceAssetCumulative()), 0)
365- let dataStateWrite = [StringEntry(keyPriceLast(), ("%s__" + toString(curPrice))), StringEntry(keyPriceHistory(height, lastBlock.timestamp), ("%s__" + toString(curPrice))), StringEntry(keyPutActionByUser(toString(i.caller), toBase58String(i.transactionId)), dataPutActionInfo(realAmtAssetIn, realPriceAssetIn, lpAmtToEmit, curPrice, slippageTolerance, slippageCalc, height, lastBlock.timestamp, diffInAmtAsset, diffInPriceAsset)), StringEntry(keyPoolLiquidity(iAmtAssetId, iPriceAssetId), dataPoolLiquidity((poolAmtAssetBalance + realAmtAssetIn), (poolPriceAssetBalance + realPriceAssetIn), (poolLPBalance + lpAmtToEmit)))]
369+ let dataStateWrite = [StringEntry(keyPriceLast(), ("%s__" + toString(curPrice))), StringEntry(keyPriceHistory(height, lastBlock.timestamp), ("%s__" + toString(curPrice))), StringEntry(keyPutActionByUser(toString(i.caller), toBase58String(i.transactionId)), dataPutActionInfo(realAmtAssetIn, realPriceAssetIn, lpAmtToEmit, curPrice, slippageTolerance, slippageCalc, height, lastBlock.timestamp, diffInAmtAsset, diffInPriceAsset))]
366370 $Tuple9(lpAmtToEmit, lpAssetId, dataStateWrite, inAmtAssetAmt, realAmtAssetIn, inPriceAssetAmt, realPriceAssetIn, pmtAmtAsset.assetId, pmtPriceAsset.assetId)
367371 }
368372 }
369373
370374
371375 @Callable(i)
372-func constructor (factoryContract) = if ((i.caller != this))
376+func constructor (factoryContract,managerPublicKey) = if ((i.caller != this))
373377 then throw("permissions denied")
374- else [StringEntry(keyFactoryContract(), factoryContract)]
378+ else [StringEntry(keyFactoryContract(), factoryContract), StringEntry(keyManagerPublicKey(), managerPublicKey)]
375379
376380
377381
378382 @Callable(i)
379383 func put (slippageTolerance,shouldAutoStake) = {
380384 let factoryCfg = getFactoryConfig()
381- let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactoryStakingContract]), "Error. Incorrect staking address.")
385+ let stakingContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactoryStakingContract]), "Error. Incorrect staking address.")
382386 let slippageContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactorySlippageContract]), "Error. Incorrect slippage contract address.")
383- let actions = commonPut(i, slippageTolerance, shouldAutoStake, true)
387+ let actions = commonPut(i, slippageTolerance, true)
384388 let amtToEmit = actions._1
385389 let lpAssetId = actions._2
386390 let state = actions._3
387391 let inAmt = actions._4
388392 let realInAmt = actions._5
389393 let inPrice = actions._6
390394 let realInPrice = actions._7
391- let prId = actions._8
392- let amId = actions._9
395+ let amId = actions._8
396+ let prId = actions._9
393397 let diffInAmtAsset = (inAmt - realInAmt)
394398 let diffInPriceAsset = (inPrice - realInPrice)
395- let slippageAmtAssetCum = valueOrElse(getInteger(this, keySlippageAmountAssetCumulative()), 0)
396- let slippagePriceAssetCum = valueOrElse(getInteger(this, keySlippagePriceAssetCumulative()), 0)
397- let emit = invoke(factoryContract, "emit", [actions._1], nil)
398- if ((emit == emit))
399+ let emitInv = invoke(factoryContract, "emit", [amtToEmit], nil)
400+ if ((emitInv == emitInv))
399401 then {
400- let dataAndSlippage = (state ++ (if ((inAmt > realInAmt))
402+ let slippageAInv = if ((inAmt > realInAmt))
403+ then invoke(slippageContract, "put", nil, [AttachedPayment(amId, diffInAmtAsset)])
404+ else nil
405+ if ((slippageAInv == slippageAInv))
401406 then {
402- let stake = invoke(slippageContract, "put", nil, [AttachedPayment(amId, diffInAmtAsset)])
403- if ((stake == stake))
404- then [IntegerEntry(keySlippageAmountAssetCumulative(), (slippageAmtAssetCum + diffInAmtAsset))]
407+ let slippagePInv = if ((inPrice > realInPrice))
408+ then invoke(slippageContract, "put", nil, [AttachedPayment(prId, diffInPriceAsset)])
409+ else nil
410+ if ((slippagePInv == slippagePInv))
411+ then {
412+ let lpStakeInv = if (shouldAutoStake)
413+ then invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, amtToEmit)])
414+ else nil
415+ if ((lpStakeInv == lpStakeInv))
416+ then (state :+ ScriptTransfer(i.caller, amtToEmit, lpAssetId))
417+ else throw("Strict value is not equal to itself.")
418+ }
405419 else throw("Strict value is not equal to itself.")
406420 }
407- else (nil ++ (if ((inPrice > realInPrice))
408- then {
409- let stake = invoke(slippageContract, "put", nil, [AttachedPayment(prId, diffInPriceAsset)])
410- if ((stake == stake))
411- then [IntegerEntry(keySlippagePriceAssetCumulative(), (slippagePriceAssetCum + diffInPriceAsset))]
412- else throw("Strict value is not equal to itself.")
413- }
414- else nil))))
415- let finalResults = if (shouldAutoStake)
416- then {
417- let stake = invoke(staking, "stake", nil, [AttachedPayment(lpAssetId, amtToEmit)])
418- if ((stake == stake))
419- then dataAndSlippage
420- else throw("Strict value is not equal to itself.")
421- }
422- else (dataAndSlippage :+ ScriptTransfer(i.caller, amtToEmit, lpAssetId))
423- finalResults
421+ else throw("Strict value is not equal to itself.")
424422 }
425423 else throw("Strict value is not equal to itself.")
426424 }
427425
428426
429427
430428 @Callable(i)
431429 func putForFree () = {
432- let actions = commonPut(i, 0, false, false)
430+ let actions = commonPut(i, 0, false)
433431 actions._3
434432 }
435433
436434
437435
438436 @Callable(i)
439437 func get () = {
440438 let res = commonGet(i)
441439 let outAmtAssetAmt = res._1
442440 let outPriceAssetAmt = res._2
443441 let pmtAssetAmt = res._3
444442 let pmtAssetId = res._4
445443 let actions = res._5
446444 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAssetAmt], [AttachedPayment(pmtAssetId, pmtAssetAmt)])
447445 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
448446 then actions
449447 else throw("Strict value is not equal to itself.")
450448 }
451449
452450
453451
454452 @Callable(i)
455453 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
456454 let res = commonGet(i)
457455 let outAmtAssetAmt = res._1
458456 let outPriceAssetAmt = res._2
459457 let pmtAssetAmt = res._3
460458 let pmtAssetId = res._4
461459 let actions = res._5
462460 if ((noLessThenAmtAsset > outAmtAssetAmt))
463461 then throw(((("noLessThenAmtAsset failed: " + toString(outAmtAssetAmt)) + " < ") + toString(noLessThenAmtAsset)))
464462 else if ((noLessThenPriceAsset > outPriceAssetAmt))
465463 then throw(((("noLessThenPriceAsset failed: " + toString(outPriceAssetAmt)) + " < ") + toString(noLessThenPriceAsset)))
466464 else {
467465 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAssetAmt], [AttachedPayment(pmtAssetId, pmtAssetAmt)])
468466 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
469467 then actions
470468 else throw("Strict value is not equal to itself.")
471469 }
472470 }
473471
474472
475473
476474 @Callable(i)
477475 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
478476 then throw("permissions denied")
479477 else $Tuple2([StringEntry(keyAmtAsset(), amtAssetStr), StringEntry(keyPriceAsset(), priceAssetStr)], "success")
480478
481479
482480
483481 @Callable(i)
484482 func statsREADONLY () = {
485483 let cfg = getPoolConfig()
486484 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
487485 let amtAssetId = cfg[idxAmtAssetId]
488486 let priceAssetId = cfg[idxPriceAssetId]
489487 let iAmtAssetId = cfg[idxIAmtAssetId]
490488 let iPriceAssetId = cfg[idxIPriceAssetId]
491489 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
492490 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
493- let poolLiquidityDataList = getPoolLiquidity(iAmtAssetId, iPriceAssetId)
494491 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
495492 let accAmtAssetBalance = getAccBalance(amtAssetId)
496493 let accPriceAssetBalance = getAccBalance(priceAssetId)
497494 let pricesList = calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
498495 let curPrice = pricesList[0]
499496 let lpAmtAssetShare = pricesList[1]
500497 let lpPriceAssetShare = pricesList[2]
501- let poolWeight = valueOrErrorMessage(getInteger(factoryContract, keyPoolWeight(toString(this))), "Pool doesn't have weight.")
498+ let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
502499 $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))
503500 }
504501
505502
506503
507504 @Callable(i)
508505 func evaluatePutByAmtAssetREADONLY (slippageTolerance,inAmtAssetAmt,userAddress) = {
509506 let cfg = getPoolConfig()
510507 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
511508 let amtAssetId = cfg[idxAmtAssetId]
512509 let priceAssetId = cfg[idxPriceAssetId]
513510 let iAmtAssetId = cfg[idxIAmtAssetId]
514511 let iPriceAssetId = cfg[idxIPriceAssetId]
515512 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
516513 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
517514 let poolStatus = cfg[idxPoolStatus]
518- let poolLiquidityDataList = getPoolLiquidity(iAmtAssetId, iPriceAssetId)
519515 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
520516 let accAmtAssetBalance = getAccBalance(amtAssetId)
521517 let accPriceAssetBalance = getAccBalance(priceAssetId)
522- let amtAssetAmtScaled = toScaleBigInt(toBigInt(accAmtAssetBalance), scale18, toBigInt(amtAssetDcm))
523- let priceAssetAmtScaled = toScaleBigInt(toBigInt(accPriceAssetBalance), scale18, toBigInt(priceAssetDcm))
524- let curPrice = if ((poolLPBalance == 0))
518+ let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
519+ let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
520+ let curPriceX18 = if ((poolLPBalance == 0))
525521 then toBigInt(0)
526- else calcPriceBigInt(priceAssetAmtScaled, amtAssetAmtScaled, scale18)
527- let inAmtAssetAmtScaled = toScaleBigInt(toBigInt(inAmtAssetAmt), scale18, toBigInt(amtAssetDcm))
528- let inPriceAssetAmtCalc = fraction(inAmtAssetAmtScaled, curPrice, scale18)
529- let inPriceAssetAmt = toInt(toScaleBigInt(inPriceAssetAmtCalc, toBigInt(priceAssetDcm), scale18))
522+ else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18, scale18)
523+ let inAmtAssetAmtX18 = toX18(inAmtAssetAmt, amtAssetDcm)
524+ let inPriceAssetAmtX18 = fraction(inAmtAssetAmtX18, curPriceX18, scale18)
525+ let inPriceAssetAmt = fromX18(inPriceAssetAmtX18, priceAssetDcm)
530526 let estimatedPutResults = estimatePutOperation(slippageTolerance, inAmtAssetAmt, amtAssetId, inPriceAssetAmt, priceAssetId, userAddress, true)
531527 let outLpAmtCalc = estimatedPutResults._1
532528 let curPriceCalc = estimatedPutResults._2
533529 let poolAmtAssetBalanceCalc = estimatedPutResults._3
534530 let poolPriceAssetBalanceCAlc = estimatedPutResults._4
535531 let poolLPBalanceCalc = estimatedPutResults._5
536532 let poolStatusCalc = parseIntValue(estimatedPutResults._10)
537- $Tuple2(nil, makeString(["%d%d%d%d%d%d", toString(outLpAmtCalc), toString(toInt(toScaleBigInt(curPrice, scale8BigInt, scale18))), toString(poolAmtAssetBalanceCalc), toString(poolPriceAssetBalanceCAlc), toString(poolLPBalanceCalc), toString(poolStatusCalc)], SEP))
533+ $Tuple2(nil, makeString(["%d%d%d%d%d%d", toString(outLpAmtCalc), toString(fromX18(curPriceX18, scale8)), toString(poolAmtAssetBalanceCalc), toString(poolPriceAssetBalanceCAlc), toString(poolLPBalanceCalc), toString(poolStatusCalc)], SEP))
538534 }
539535
540536
541537
542538 @Callable(i)
543539 func evaluatePutByPriceAssetREADONLY (slippageTolerance,inPriceAssetAmt,userAddress) = {
544540 let cfg = getPoolConfig()
545541 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
546542 let amtAssetId = cfg[idxAmtAssetId]
547543 let priceAssetId = cfg[idxPriceAssetId]
548544 let iAmtAssetId = cfg[idxIAmtAssetId]
549545 let iPriceAssetId = cfg[idxIPriceAssetId]
550546 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
551547 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
552548 let poolStatus = cfg[idxPoolStatus]
553- let poolLiquidityDataList = getPoolLiquidity(iAmtAssetId, iPriceAssetId)
554549 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
555550 let accAmtAssetBalance = getAccBalance(amtAssetId)
556551 let accPriceAssetBalance = getAccBalance(priceAssetId)
557- let amtAssetAmtScaled = toScaleBigInt(toBigInt(accAmtAssetBalance), scale18, toBigInt(amtAssetDcm))
558- let priceAssetAmtScaled = toScaleBigInt(toBigInt(accPriceAssetBalance), scale18, toBigInt(priceAssetDcm))
559- let curPrice = if ((poolLPBalance == 0))
552+ let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
553+ let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
554+ let curPriceX18 = if ((poolLPBalance == 0))
560555 then toBigInt(0)
561- else calcPriceBigInt(priceAssetAmtScaled, amtAssetAmtScaled, scale18)
562- let inPriceAssetAmtScaled = toScaleBigInt(toBigInt(inPriceAssetAmt), scale18, toBigInt(priceAssetDcm))
563- let inAmtAssetAmtCalc = fraction(inPriceAssetAmtScaled, scale18, curPrice)
564- let inAmtAssetAmt = toInt(toScaleBigInt(inAmtAssetAmtCalc, toBigInt(amtAssetDcm), scale18))
556+ else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18, scale18)
557+ let inPriceAssetAmtX18 = toX18(inPriceAssetAmt, priceAssetDcm)
558+ let inAmtAssetAmtX18 = fraction(inPriceAssetAmtX18, scale18, curPriceX18)
559+ let inAmtAssetAmt = fromX18(inAmtAssetAmtX18, amtAssetDcm)
565560 let estimatedPutResults = estimatePutOperation(slippageTolerance, inAmtAssetAmt, amtAssetId, inPriceAssetAmt, priceAssetId, userAddress, true)
566561 let outLpAmtCalc = estimatedPutResults._1
567562 let curPriceCalc = estimatedPutResults._2
568563 let poolAmtAssetBalanceCalc = estimatedPutResults._3
569564 let poolPriceAssetBalanceCAlc = estimatedPutResults._4
570565 let poolLPBalanceCalc = estimatedPutResults._5
571566 let poolStatusCalc = parseIntValue(estimatedPutResults._10)
572- $Tuple2(nil, makeString(["%d%d%d%d%d%d", toString(outLpAmtCalc), toString(toInt(toScaleBigInt(curPrice, scale8BigInt, scale18))), toString(poolAmtAssetBalanceCalc), toString(poolPriceAssetBalanceCAlc), toString(poolLPBalanceCalc), toString(poolStatusCalc)], SEP))
567+ $Tuple2(nil, makeString(["%d%d%d%d%d%d", toString(outLpAmtCalc), toString(fromX18(curPriceX18, scale8)), toString(poolAmtAssetBalanceCalc), toString(poolPriceAssetBalanceCAlc), toString(poolLPBalanceCalc), toString(poolStatusCalc)], SEP))
573568 }
574569
575570
576571
577572 @Callable(i)
578573 func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt,userAddress) = {
579574 let res = estimateGetOperation(paymentLpAssetId, paymentLpAmt, userAddress)
580575 let outAmtAssetAmt = res._1
581576 let outPriceAssetAmt = res._2
582577 let poolAmtAssetBalance = res._7
583578 let poolPriceAssetBalance = res._8
584579 let poolLPBalance = res._9
585580 let curPrice = res._10
586581 let poolStatus = parseIntValue(res._11)
587582 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(outAmtAssetAmt), toString(outPriceAssetAmt), toString(poolAmtAssetBalance), toString(poolPriceAssetBalance), toString(poolLPBalance), toString(curPrice), toString(poolStatus)], SEP))
588583 }
589584
590585
591586 @Verifier(tx)
592587 func verify () = match tx {
593588 case order: Order =>
594- validateMatcherOrderAllowed(order)
589+ if (validateMatcherOrderAllowed(order))
590+ then sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
591+ else false
595592 case _ =>
596593 sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
597594 }
598595

github/deemru/w8io/6500d08 
103.15 ms