tx · 3e6bvMNuYHEy6zBhzzsE7w89A1u5crTWYNMqwWspyHsg

3NAefciWv6f9fWvEXdGgpHfanJFG8HqfjuT:  -0.01400000 Waves

2021.12.23 02:34 [1846139] smart account 3NAefciWv6f9fWvEXdGgpHfanJFG8HqfjuT > SELF 0.00000000 Waves

{ "type": 13, "id": "3e6bvMNuYHEy6zBhzzsE7w89A1u5crTWYNMqwWspyHsg", "fee": 1400000, "feeAssetId": null, "timestamp": 1640216066358, "version": 1, "sender": "3NAefciWv6f9fWvEXdGgpHfanJFG8HqfjuT", "senderPublicKey": "D1BL65meykxFZTCuq7jq9HSGLLnWvQamQPUNrguW5w39", "proofs": [ "4qNQBLV9YK86TQaCWuznro8tbgapNWmBQhX55MXgR4aQNw7tLvW85EiLM9x5KsDA3H3jH5MUQn7Sjw92PGVRfeac" ], "script": "base64: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DWtleU1hdGNoZXJQdWIAAAAAAgAAABglcyVzX19tYXRjaGVyX19wdWJsaWNLZXkBAAAADWtleVBvb2xDb25maWcAAAACAAAACWlBbXRBc3NldAAAAAtpUHJpY2VBc3NldAkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAAglZCVkJXNfXwUAAAAJaUFtdEFzc2V0AgAAAAJfXwUAAAALaVByaWNlQXNzZXQCAAAACF9fY29uZmlnAQAAAB9rZXlNYXBwaW5nc0Jhc2VBc3NldDJpbnRlcm5hbElkAAAAAQAAAAxiYXNlQXNzZXRTdHIJAAEsAAAAAgIAAAAoJXMlcyVzX19tYXBwaW5nc19fYmFzZUFzc2V0MmludGVybmFsSWRfXwUAAAAMYmFzZUFzc2V0U3RyAQAAABNrZXlBbGxQb29sc1NodXRkb3duAAAAAAIAAAAMJXNfX3NodXRkb3duAQAAAA1rZXlQb29sV2VpZ2h0AAAAAQAAAA9jb250cmFjdEFkZHJlc3MJAAEsAAAAAgIAAAASJXMlc19fcG9vbFdlaWdodF9fBQAAAA9jb250cmFjdEFkZHJlc3MBAAAAD3Rocm93T3JkZXJFcnJvcgAAAAMAAAAKb3JkZXJWYWxpZAAAAAtzZW5kZXJWYWxpZAAAAAxtYXRjaGVyVmFsaWQJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAJG9yZGVyIHZhbGlkYXRpb24gZmFpbGVkOiBvcmRlclZhbGlkPQkAAaUAAAABBQAAAApvcmRlclZhbGlkAgAAAA0gc2VuZGVyVmFsaWQ9CQABpQAAAAEFAAAAC3NlbmRlclZhbGlkAgAAAA4gbWF0Y2hlclZhbGlkPQkAAaUAAAABBQAAAAxtYXRjaGVyVmFsaWQBAAAAD2dldFN0cmluZ09yRmFpbAAAAAIAAAAHYWRkcmVzcwAAAANrZXkJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAdhZGRyZXNzBQAAAANrZXkJAAS5AAAAAgkABEwAAAACAgAAAAptYW5kYXRvcnkgCQAETAAAAAIJAAQlAAAAAQUAAAAHYWRkcmVzcwkABEwAAAACAgAAAAEuCQAETAAA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WDE4CQEAAAAFdG9YMTgAAAACBQAAAAhwbXRMcEFtdAUAAAAGc2NhbGU4BAAAAA1scEVtaXNzaW9uWDE4CQEAAAAFdG9YMTgAAAACBQAAAApscEVtaXNzaW9uBQAAAAZzY2FsZTgEAAAAC291dEFtQW10WDE4CQABPAAAAAMFAAAADGFtQmFsYW5jZVgxOAUAAAALcG10THBBbXRYMTgFAAAADWxwRW1pc3Npb25YMTgEAAAAC291dFByQW10WDE4CQABPAAAAAMFAAAADHByQmFsYW5jZVgxOAUAAAALcG10THBBbXRYMTgFAAAADWxwRW1pc3Npb25YMTgEAAAACG91dEFtQW10CQEAAAAHZnJvbVgxOAAAAAIFAAAAC291dEFtQW10WDE4BQAAAAVhbURjbQQAAAAIb3V0UHJBbXQJAQAAAAdmcm9tWDE4AAAAAgUAAAALb3V0UHJBbXRYMTgFAAAABXByRGNtBAAAAAVzdGF0ZQMJAAAAAAAAAgUAAAAGdHhJZDU4AgAAAAAFAAAAA25pbAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAAt1c2VyQWRkcmVzcwUAAAAIb3V0QW1BbXQDCQAAAAAAAAIFAAAABGFtSWQCAAAABVdBVkVTBQAAAAR1bml0CQACWQAAAAEFAAAABGFtSWQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAALdXNlckFkZHJlc3MFAAAACG91dFByQW10AwkAAAAAAAACBQAAAARwcklkAgAAAAVXQVZFUwUAAAAEdW5pdAkAAlkAAAABBQAAAARwcklkCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAABJrZXlHZXRBY3Rpb25CeVVzZXIAAAACCQAEJQAAAAEFAAAAC3VzZXJBZGRyZXNzBQAAAAZ0eElkNTgJAQAAABFkYXRhR2V0QWN0aW9uSW5mbwAAAAYFAAAACG91dEFtQW10BQAAAAhvdXRQckFtdAUAAAAIcG10THBBbXQFAAAACGN1clByaWNlBQAAAAZoZWlnaHQIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAMa2V5UHJpY2VMYXN0AAAAAAUAAAAIY3VyUHJpY2UJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA9rZXlQcmljZUhpc3RvcnkAAAACBQAAAAZoZWlnaHQIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wBQAAAAhjdXJQcmljZQUAAAADbmlsCQAFHAAAAAoFAAAACG91dEFtQW10BQAAAAhvdXRQckFtdAUAAAAEYW1JZAUAAAAEcHJJZAUAAAAJYW1CYWxhbmNlBQAAAAlwckJhbGFuY2UFAAAACmxwRW1pc3Npb24FAAAAC2N1clByaWNlWDE4BQAAAApwb29sU3RhdHVzBQAAAAVzdGF0ZQEAAAAUZXN0aW1hdGVQdXRPcGVyYXRpb24AAAAJAAAABnR4SWQ1OAAAAAhzbGlwcGFnZQAAAAdpbkFtQW10AAAABmluQW1JZAAAAAdpblByQW10AAAABmluUHJJZAAAAAt1c2VyQWRkcmVzcwAAAAppc0V2YWx1YXRlAAAABmVtaXRMcAQAAAADY2ZnCQEAAAANZ2V0UG9vbENvbmZpZwAAAAAEAAAABGxwSWQJAAJZAAAAAQkAAZEAAAACBQAAAANjZmcFAAAACWlkeExQQXNJZAQAAAAHYW1JZFN0cgkAAZEAAAACBQAAAANjZmcFAAAACWlkeEFtQXNJZAQAAAAHcHJJZFN0cgkAAZEAAAACBQAAAANjZmcFAAAACWlkeFByQXNJZAQAAAAJaW5BbUlkU3RyCQABkQAAAAIFAAAAA2NmZwUAAAALaWR4SUFtdEFzSWQEAAAACWluUHJJZFN0cgkAAZEAAAACBQAAAANjZmcFAAAADWlkeElQcmljZUFzSWQEAAAABmFtdERjbQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAA2NmZwUAAAALaWR4QW10QXNEY20EAAAACHByaWNlRGNtCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAADY2ZnBQAAAA1pZHhQcmljZUFzRGNtBAAAAApwb29sU3RhdHVzCQABkQAAAAIFAAAAA2NmZwUAAAANaWR4UG9vbFN0YXR1cwQAAAAKbHBFbWlzc2lvbggJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkAA+wAAAABBQAAAARscElkAgAAAA9Xcm9uZyBscCBhc3NldC4AAAAIcXVhbnRpdHkEAAAACWFtQmFsYW5jZQMFAAAACmlzRXZhbHVhdGUJAQAAAA1nZXRBY2NCYWxhbmNlAAAAAQUAAAAHYW1JZFN0cgkAAGUAAAACCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAAB2FtSWRTdHIFAAAAB2luQW1BbXQEAAAACXByQmFsYW5jZQMFAAAACmlzRXZhbHVhdGUJAQAAAA1nZXRBY2NCYWxhbmNlAAAAAQUAAAAHcHJJZFN0cgkAAGUAAAACCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAAB3BySWRTdHIFAAAAB2luUHJBbXQEAAAAD2luQW1Bc3NldEFtdFgxOAkBAAAABXRvWDE4AAAAAgUAAAAHaW5BbUFtdAUAAAAGYW10RGNtBAAAAA9pblByQXNzZXRBbXRYMTgJAQAAAAV0b1gxOAAAAAIFAAAAB2luUHJBbXQFAAAACHByaWNlRGNtBAAAAAx1c2VyUHJpY2VYMTgJAQAAAA9jYWxjUHJpY2VCaWdJbnQAAAACBQAAAA9pblByQXNzZXRBbXRYMTgFAAAAD2luQW1Bc3NldEFtdFgxOAQAAAAMYW1CYWxhbmNlWDE4CQEAAAAFdG9YMTgAAAACBQAAAAlhbUJhbGFuY2UFAAAABmFtdERjbQQAAAAMcHJCYWxhbmNlWDE4CQEAAAAFdG9YMTgAAAACBQAAAAlwckJhbGFuY2UFAAAACHByaWNlRGNtBAAAAANyZXMDCQAAAAAAAAIFAAAACmxwRW1pc3Npb24AAAAAAAAAAAAEAAAAC2N1clByaWNlWDE4BQAAAAp6ZXJvQmlnSW50BAAAAAtzbGlwcGFnZVgxOAUAAAAKemVyb0JpZ0ludAQAAAAIbHBBbXRYMTgJAAB2AAAABgkAATkAAAACBQAAAA9pbkFtQXNzZXRBbXRYMTgFAAAAD2luUHJBc3NldEFtdFgxOAAAAAAAAAAAAAkAATYAAAABAAAAAAAAAAAFAAAAAAAAAAABAAAAAAAAAAAABQAAAARET1dOCQAFFwAAAAUJAQAAAAdmcm9tWDE4AAAAAgUAAAAIbHBBbXRYMTgFAAAABnNjYWxlOAkBAAAAB2Zyb21YMTgAAAACBQAAAA9pbkFtQXNzZXRBbXRYMTgFAAAABmFtdERjbQkBAAAAB2Zyb21YMTgAAAACBQAAAA9pblByQXNzZXRBbXRYMTgFAAAACHByaWNlRGNtCQEAAAAPY2FsY1ByaWNlQmlnSW50AAAAAgkAATcAAAACBQAAAAxwckJhbGFuY2VYMTgFAAAAD2luUHJBc3NldEFtdFgxOAkAATcAAAACBQAAAAxhbUJhbGFuY2VYMTgFAAAAD2luQW1Bc3NldEFtdFgxOAUAAAALc2xpcHBhZ2VYMTgEAAAAC2N1clByaWNlWDE4CQEAAAAPY2FsY1ByaWNlQmlnSW50AAAAAgUAAAAMcHJCYWxhbmNlWDE4BQAAAAxhbUJhbGFuY2VYMTgEAAAAD3NsaXBwYWdlUmVhbFgxOAkAATwAAAADCQEAAAADYWJzAAAAAQkAATgAAAACBQAAAAtjdXJQcmljZVgxOAUAAAAMdXNlclByaWNlWDE4BQAAAAdzY2FsZTE4BQAAAAtjdXJQcmljZVgxOAQAAAALc2xpcHBhZ2VYMTgJAQAAAAV0b1gxOAAAAAIFAAAACHNsaXBwYWdlBQAAAAZzY2FsZTgDAwkBAAAAAiE9AAAAAgUAAAALY3VyUHJpY2VYMTgFAAAACnplcm9CaWdJbnQJAAE/AAAAAgUAAAAPc2xpcHBhZ2VSZWFsWDE4BQAAAAtzbGlwcGFnZVgxOAcJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAPUHJpY2Ugc2xpcHBhZ2UgCQABpgAAAAEFAAAAD3NsaXBwYWdlUmVhbFgxOAIAAAAKIGV4Y2VlZGVkIAkAAaYAAAABBQAAAAtzbGlwcGFnZVgxOAQAAAANbHBFbWlzc2lvblgxOAkBAAAABXRvWDE4AAAAAgUAAAAKbHBFbWlzc2lvbgUAAAAGc2NhbGU4BAAAAApwclZpYUFtWDE4CQABPAAAAAMFAAAAD2luQW1Bc3NldEFtdFgxOAUAAAALY3VyUHJpY2VYMTgFAAAAB3NjYWxlMTgEAAAACmFtVmlhUHJYMTgJAAE8AAAAAwUAAAAPaW5QckFzc2V0QW10WDE4BQAAAAdzY2FsZTE4BQAAAAtjdXJQcmljZVgxOAQAAAAMZXhwZWN0ZWRBbXRzAwkAAT8AAAACBQAAAApwclZpYUFtWDE4BQAAAA9pblByQXNzZXRBbXRYMTgJAAUUAAAAAgUAAAAKYW1WaWFQclgxOAUAAAAPaW5QckFzc2V0QW10WDE4CQAFFAAAAAIFAAAAD2luQW1Bc3NldEFtdFgxOAUAAAAKcHJWaWFBbVgxOAQAAAARZXhwQW10QXNzZXRBbXRYMTgIBQAAAAxleHBlY3RlZEFtdHMAAAACXzEEAAAAE2V4cFByaWNlQXNzZXRBbXRYMTgIBQAAAAxleHBlY3RlZEFtdHMAAAACXzIEAAAACGxwQW10WDE4CQABPAAAAAMFAAAADWxwRW1pc3Npb25YMTgFAAAAE2V4cFByaWNlQXNzZXRBbXRYMTgFAAAADHByQmFsYW5jZVgxOAkABRcAAAAFCQEAAAAHZnJvbVgxOAAAAAIFAAAACGxwQW10WDE4BQAAAAZzY2FsZTgJAQAAAAdmcm9tWDE4AAAAAgUAAAARZXhwQW10QXNzZXRBbXRYMTgFAAAABmFtdERjbQkBAAAAB2Zyb21YMTgAAAACBQAAABNleHBQcmljZUFzc2V0QW10WDE4BQAAAAhwcmljZURjbQUAAAALY3VyUHJpY2VYMTgFAAAAC3NsaXBwYWdlWDE4BAAAAAljYWxjTHBBbXQIBQAAAANyZXMAAAACXzEEAAAADmNhbGNBbUFzc2V0UG10CAUAAAADcmVzAAAAAl8yBAAAAA5jYWxjUHJBc3NldFBtdAgFAAAAA3JlcwAAAAJfMwQAAAAIY3VyUHJpY2UJAQAAAAdmcm9tWDE4AAAAAggFAAAAA3JlcwAAAAJfNAUAAAAGc2NhbGU4BAAAAAxzbGlwcGFnZUNhbGMJAQAAAAdmcm9tWDE4AAAAAggFAAAAA3JlcwAAAAJfNQUAAAAGc2NhbGU4AwkAAGcAAAACAAAAAAAAAAAABQAAAAljYWxjTHBBbXQJAAACAAAAAQIAAAAVTFAgaXMgbGVzcyB0aGFuIHplcm8uBAAAAAllbWl0THBBbXQDCQEAAAABIQAAAAEFAAAABmVtaXRMcAAAAAAAAAAAAAUAAAAJY2FsY0xwQW10BAAAAAZhbURpZmYJAABlAAAAAgUAAAAHaW5BbUFtdAUAAAAOY2FsY0FtQXNzZXRQbXQEAAAABnByRGlmZgkAAGUAAAACBQAAAAdpblByQW10BQAAAA5jYWxjUHJBc3NldFBtdAQAAAALY29tbW9uU3RhdGUJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAAxrZXlQcmljZUxhc3QAAAAABQAAAAhjdXJQcmljZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAD2tleVByaWNlSGlzdG9yeQAAAAIFAAAABmhlaWdodAgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAFAAAACGN1clByaWNlCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAABJrZXlQdXRBY3Rpb25CeVVzZXIAAAACBQAAAAt1c2VyQWRkcmVzcwUAAAAGdHhJZDU4CQEAAAARZGF0YVB1dEFjdGlvbkluZm8AAAAKBQAAAA5jYWxjQW1Bc3NldFBtdAUAAAAOY2FsY1ByQXNzZXRQbXQFAAAACWVtaXRMcEFtdAUAAAAIY3VyUHJpY2UFAAAACHNsaXBwYWdlBQAAAAxzbGlwcGFnZUNhbGMFAAAABmhlaWdodAgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAFAAAABmFtRGlmZgUAAAAGcHJEaWZmBQAAAANuaWwJAAUfAAAADQUAAAAJY2FsY0xwQW10BQAAAAllbWl0THBBbXQFAAAACGN1clByaWNlBQAAAAlhbUJhbGFuY2UFAAAACXByQmFsYW5jZQUAAAAKbHBFbWlzc2lvbgUAAAAEbHBJZAUAAAAKcG9vbFN0YXR1cwUAAAALY29tbW9uU3RhdGUFAAAABmFtRGlmZgUAAAAGcHJEaWZmBQAAAAZpbkFtSWQFAAAABmluUHJJZAEAAAAbdmFsaWRhdGVNYXRjaGVyT3JkZXJBbGxvd2VkAAAAAQAAAAVvcmRlcgQAAAADY2ZnCQEAAAANZ2V0UG9vbENvbmZpZwAAAAAEAAAACmFtdEFzc2V0SWQJAAGRAAAAAgUAAAADY2ZnBQAAAAlpZHhBbUFzSWQEAAAADHByaWNlQXNzZXRJZAkAAZEAAAACBQAAAANjZmcFAAAACWlkeFByQXNJZAQAAAAKcG9vbFN0YXR1cwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAA2NmZwUAAAANaWR4UG9vbFN0YXR1cwQAAAALYW10QXNzZXREY20JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAANjZmcFAAAAC2lkeEFtdEFzRGNtBAAAAA1wcmljZUFzc2V0RGNtCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAADY2ZnBQAAAA1pZHhQcmljZUFzRGNtBAAAABJhY2NBbXRBc3NldEJhbGFuY2UJAQAAAA1nZXRBY2NCYWxhbmNlAAAAAQUAAAAKYW10QXNzZXRJZAQAAAAUYWNjUHJpY2VBc3NldEJhbGFuY2UJAQAAAA1nZXRBY2NCYWxhbmNlAAAAAQUAAAAMcHJpY2VBc3NldElkBAAAAAtjdXJQcmljZVgxOAMJAAAAAAAAAggFAAAABW9yZGVyAAAACW9yZGVyVHlwZQUAAAADQnV5CQEAAAAQcHJpdmF0ZUNhbGNQcmljZQAAAAQFAAAAC2FtdEFzc2V0RGNtBQAAAA1wcmljZUFzc2V0RGNtCQAAZAAAAAIFAAAAEmFjY0FtdEFzc2V0QmFsYW5jZQgFAAAABW9yZGVyAAAABmFtb3VudAUAAAAUYWNjUHJpY2VBc3NldEJhbGFuY2UJAQAAABBwcml2YXRlQ2FsY1ByaWNlAAAABAUAAAALYW10QXNzZXREY20FAAAADXByaWNlQXNzZXREY20JAABlAAAAAgUAAAASYWNjQW10QXNzZXRCYWxhbmNlCAUAAAAFb3JkZXIAAAAGYW1vdW50BQAAABRhY2NQcmljZUFzc2V0QmFsYW5jZQQAAAAIY3VyUHJpY2UJAQAAAAdmcm9tWDE4AAAAAgUAAAALY3VyUHJpY2VYMTgFAAAABnNjYWxlOAMDAwkBAAAAEGlzR2xvYmFsU2h1dGRvd24AAAAABgkAAAAAAAACBQAAAApwb29sU3RhdHVzBQAAABNQb29sTWF0Y2hlckRpc2FibGVkBgkAAAAAAAACBQAAAApwb29sU3RhdHVzBQAAAAxQb29sU2h1dGRvd24JAAACAAAAAQIAAAAcRXhjaGFuZ2Ugb3BlcmF0aW9ucyBkaXNhYmxlZAQAAAANb3JkZXJBbXRBc3NldAgIBQAAAAVvcmRlcgAAAAlhc3NldFBhaXIAAAALYW1vdW50QXNzZXQEAAAAEG9yZGVyQW10QXNzZXRTdHIDCQAAAAAAAAIFAAAADW9yZGVyQW10QXNzZXQFAAAABHVuaXQCAAAA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dXRBbUFtdAQAAAAWYW1Td29wUGFydEluUHJpY2VBc3NldAkAAGUAAAACBQAAAA5yZXN1bHRQckFtb3VudAUAAAAIb3V0UHJBbXQEAAAAB2NvbnZSZXMJAAE8AAAAAwkBAAAABXRvWDE4AAAAAgUAAAAWYW1Td29wUGFydEluUHJpY2VBc3NldAUAAAAFYW1EY20FAAAAB3NjYWxlMTgFAAAADHN3YXBQcmljZVgxOAQAAAAHcHJBc1JlcwkBAAAAB2Zyb21YMTgAAAACCQABPAAAAAMJAQAAAAV0b1gxOAAAAAIFAAAACG91dEFtQW10BQAAAAVhbURjbQUAAAAMc3dhcFByaWNlWDE4BQAAAAdzY2FsZTE4BQAAAAVwckRjbQQAAAALYW1Bc3NldERpZmYJAAE8AAAAAwkAATgAAAACBQAAAAdjb252UmVzBQAAAA5hbUFzc2V0U3dhcFgxOAUAAAAMc2NhbGU4QmlnSW50BQAAAA5hbUFzc2V0U3dhcFgxOAMDCQABPwAAAAIFAAAAC2FtQXNzZXREaWZmBQAAAAljYWxjRXJyb3IGCQABPwAAAAIJAAE+AAAAAQUAAAAJY2FsY0Vycm9yBQAAAAthbUFzc2V0RGlmZgkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABtTbGlwcGFnZSBleGVlZGVkIHRoZSB2YWx1ZSAJAAGmAAAAAQUAAAAJY2FsY0Vycm9yAgAAAA4gYW5kIGVxdWFsIHRvIAkAAaYAAAABBQAAAAthbUFzc2V0RGlmZgkAAGQAAAACBQAAAAdwckFzUmVzBQAAAAhvdXRQckFtdAQAAAAJYW1CYWxhbmNlCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAABGFtSWQEAAAADGFtQmFsYW5jZVgxOAkBAAAABXRvWDE4AAAAAgUAAAAJYW1CYWxhbmNlBQAAAAVhbURjbQQAAAAJcHJCYWxhbmNlCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAABHBySWQEAAAADHByQmFsYW5jZVgxOAkBAAAABXRvWDE4AAAAAgUAAAAJcHJCYWxhbmNlBQAAAAVwckRjbQQAAAALY3VyUHJpY2VYMTgJAQAAAA9jYWxjUHJpY2VCaWdJbnQAAAACBQAAAAxwckJhbGFuY2VYMTgFAAAADGFtQmFsYW5jZVgxOAQAAAAIY3VyUHJpY2UJAQAAAAdmcm9tWDE4AAAAAgUAAAALY3VyUHJpY2VYMTgFAAAABnNjYWxlOAQAAAAFc3RhdGUJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAALdXNlckFkZHJlc3MFAAAABnRvdGFsUgMJAAAAAAAAAgUAAAANcmVzdWx0QXNzZXRJZAIAAAAFV0FWRVMFAAAABHVuaXQJAAJZAAAAAQUAAAANcmVzdWx0QXNzZXRJZAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAASa2V5R2V0QWN0aW9uQnlVc2VyAAAAAgkABCUAAAABBQAAAAt1c2VyQWRkcmVzcwUAAAAGdHhJZDU4CQEAAAARZGF0YUdldEFjdGlvbkluZm8AAAAGBQAAAA9yZXN1bHRBbXRBbW91bnQFAAAADnJlc3VsdFByQW1vdW50BQAAAAZwbXRBbXQFAAAACGN1clByaWNlBQAAAAZoZWlnaHQIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAMa2V5UHJpY2VMYXN0AAAAAAUAAAAIY3VyUHJpY2UJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA9rZXlQcmljZUhpc3RvcnkAAAACBQAAAAZoZWlnaHQIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wBQAAAAhjdXJQcmljZQUAAAADbmlsBAAAAARidXJuCQAD/AAAAAQFAAAAD2ZhY3RvcnlDb250cmFjdAIAAAAEYnVybgkABEwAAAACBQAAAAZwbXRBbXQFAAAAA25pbAkABEwAAAACCQEAAAAPQXR0YWNoZWRQYXltZW50AAAAAgUAAAAKcG10QXNzZXRJZAUAAAAGcG10QW10BQAAAANuaWwDCQAAAAAAAAIFAAAABGJ1cm4FAAAABGJ1cm4FAAAABXN0YXRlCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAAlnZXROb0xlc3MAAAACAAAAEm5vTGVzc1RoZW5BbXRBc3NldAAAABRub0xlc3NUaGVu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ZWNrUG9vbFN0YXR1cwUAAAAPY2hlY2tQb29sU3RhdHVzBAAAABRidXJuTFBBc3NldE9uRmFjdG9yeQkAA/wAAAAEBQAAAA9mYWN0b3J5Q29udHJhY3QCAAAABGJ1cm4JAARMAAAAAgUAAAAGYW1vdW50BQAAAANuaWwJAARMAAAAAgkBAAAAD0F0dGFjaGVkUGF5bWVudAAAAAIFAAAACWxwQXNzZXRJZAUAAAAGYW1vdW50BQAAAANuaWwDCQAAAAAAAAIFAAAAFGJ1cm5MUEFzc2V0T25GYWN0b3J5BQAAABRidXJuTFBBc3NldE9uRmFjdG9yeQUAAAAFc3RhdGUJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAACGFjdGl2YXRlAAAAAgAAAAthbXRBc3NldFN0cgAAAA1wcmljZUFzc2V0U3RyAwkBAAAAAiE9AAAAAgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIJAAQlAAAAAQUAAAAPZmFjdG9yeUNvbnRyYWN0CQAAAgAAAAECAAAAEnBlcm1pc3Npb25zIGRlbmllZAkABRQAAAACCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAAtrZXlBbXRBc3NldAAAAAAFAAAAC2FtdEFzc2V0U3RyCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAA1rZXlQcmljZUFzc2V0AAAAAAUAAAANcHJpY2VBc3NldFN0cgUAAAADbmlsAgAAAAdzdWNjZXNzAAAAAWkBAAAAHGdldFBvb2xDb25maWdXcmFwcGVyUkVBRE9OTFkAAAAACQAFFAAAAAIFAAAAA25pbAkBAAAADWdldFBvb2xDb25maWcAAAAAAAAAAWkBAAAAHGdldEFjY0JhbGFuY2VXcmFwcGVyUkVBRE9OTFkAAAABAAAAB2Fzc2V0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", "chainId": 84, "height": 1846139, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 4zEtJ4QrBCgeQkeD2FZDKZh3yeF9brTEiqjjmRWuXtLd Next: EtZRbQc5CoNTa5athsaSXetL4PMzkzZXmMAg6BMW2bCT Diff:
OldNewDifferences
211211 }
212212
213213
214-func estimatePutOperation (txId58,slippageTolerance,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEvaluate,emitLp,isOneAsset) = {
214+func estimatePutOperation (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEvaluate,emitLp) = {
215215 let cfg = getPoolConfig()
216216 let lpId = fromBase58String(cfg[idxLPAsId])
217217 let amIdStr = cfg[idxAmAsId]
221221 let amtDcm = parseIntValue(cfg[idxAmtAsDcm])
222222 let priceDcm = parseIntValue(cfg[idxPriceAsDcm])
223223 let poolStatus = cfg[idxPoolStatus]
224- let lpEmission = valueOrErrorMessage(assetInfo(lpId), (("Asset " + toBase58String(lpId)) + " doesn't exist")).quantity
224+ let lpEmission = valueOrErrorMessage(assetInfo(lpId), "Wrong lp asset.").quantity
225225 let amBalance = if (isEvaluate)
226226 then getAccBalance(amIdStr)
227227 else (getAccBalance(amIdStr) - inAmAmt)
241241 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtDcm), fromX18(inPrAssetAmtX18, priceDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
242242 }
243243 else {
244- let tRes = if (isOneAsset)
245- then {
244+ let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
245+ let slippageRealX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
246+ let slippageX18 = toX18(slippage, scale8)
247+ if (if ((curPriceX18 != zeroBigInt))
248+ then (slippageRealX18 > slippageX18)
249+ else false)
250+ then throw(((("Price slippage " + toString(slippageRealX18)) + " exceeded ") + toString(slippageX18)))
251+ else {
246252 let lpEmissionX18 = toX18(lpEmission, scale8)
247- let sumInAssets = (inAmAssetAmtX18 + inPrAssetAmtX18)
248- let sumPoolBalances = (amBalanceX18 + prBalanceX18)
249- let lpAmtX18 = fraction(lpEmissionX18, sumInAssets, sumPoolBalances)
250- let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
251- $Tuple5(fromX18(lpAmtX18, scale8), inAmAmt, inPrAmt, curPriceX18, toBigInt(0))
253+ let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
254+ let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
255+ let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
256+ then $Tuple2(amViaPrX18, inPrAssetAmtX18)
257+ else $Tuple2(inAmAssetAmtX18, prViaAmX18)
258+ let expAmtAssetAmtX18 = expectedAmts._1
259+ let expPriceAssetAmtX18 = expectedAmts._2
260+ let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
261+ $Tuple5(fromX18(lpAmtX18, scale8), fromX18(expAmtAssetAmtX18, amtDcm), fromX18(expPriceAssetAmtX18, priceDcm), curPriceX18, slippageX18)
252262 }
253- else {
254- let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
255- let slippageX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
256- let slippageToleranceX18 = toX18(slippageTolerance, scale8)
257- if (if ((curPriceX18 != zeroBigInt))
258- then (slippageX18 > slippageToleranceX18)
259- else false)
260- then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
261- else {
262- let lpEmissionX18 = toX18(lpEmission, scale8)
263- let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
264- let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
265- let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
266- then $Tuple2(amViaPrX18, inPrAssetAmtX18)
267- else $Tuple2(inAmAssetAmtX18, prViaAmX18)
268- let expAmtAssetAmtX18 = expectedAmts._1
269- let expPriceAssetAmtX18 = expectedAmts._2
270- let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
271- $Tuple5(fromX18(lpAmtX18, scale8), fromX18(expAmtAssetAmtX18, amtDcm), fromX18(expPriceAssetAmtX18, priceDcm), curPriceX18, slippageX18)
272- }
273- }
274- tRes
275263 }
276264 let calcLpAmt = res._1
277265 let calcAmAssetPmt = res._2
279267 let curPrice = fromX18(res._4, scale8)
280268 let slippageCalc = fromX18(res._5, scale8)
281269 if ((0 >= calcLpAmt))
282- then throw("Invalid calculations. LP calculated is less than zero.")
270+ then throw("LP is less than zero.")
283271 else {
284272 let emitLpAmt = if (!(emitLp))
285273 then 0
286274 else calcLpAmt
287275 let amDiff = (inAmAmt - calcAmAssetPmt)
288276 let prDiff = (inPrAmt - calcPrAssetPmt)
289- let commonState = [IntegerEntry(keyPriceLast(), curPrice), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), curPrice), StringEntry(keyPutActionByUser(userAddress, txId58), dataPutActionInfo(calcAmAssetPmt, calcPrAssetPmt, emitLpAmt, curPrice, slippageTolerance, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
277+ let commonState = [IntegerEntry(keyPriceLast(), curPrice), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), curPrice), StringEntry(keyPutActionByUser(userAddress, txId58), dataPutActionInfo(calcAmAssetPmt, calcPrAssetPmt, emitLpAmt, curPrice, slippage, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
290278 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpId, poolStatus, commonState, amDiff, prDiff, inAmId, inPrId)
291279 }
292280 }
356344 }
357345
358346
359-func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
360- then throw("exactly 2 payments are expected")
361- else {
362- let amAssetPmt = value(i.payments[0])
363- let prAssetPmt = value(i.payments[1])
364- let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp, false)
365- let status = parseIntValue(estPut._8)
366- if (if (if (isGlobalShutdown())
367- then true
368- else (status == PoolPutDisabled))
369- then true
370- else (status == PoolShutdown))
371- then throw(("Put operation is blocked by admin. Status = " + toString(status)))
372- else estPut
373- }
347+func commonPut (caller,txId,amAsPmt,prAsPmt,slippage,emitLp) = {
348+ let estPut = estimatePutOperation(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, false, emitLp)
349+ let status = parseIntValue(estPut._8)
350+ if (if (if (isGlobalShutdown())
351+ then true
352+ else (status == PoolPutDisabled))
353+ then true
354+ else (status == PoolShutdown))
355+ then throw(("Put operation is blocked by admin. Status = " + toString(status)))
356+ else estPut
357+ }
374358
375359
376360 func calcD (a,b,lVal) = {
399383
400384
401385 @Callable(i)
402-func put (slippage,autoStake) = {
386+func put (slip,autoStake) = {
403387 let factCfg = getFactoryConfig()
404- let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Error. Incorrect staking address.")
405- let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Error. Incorrect slippage contract address.")
406- if ((0 > slippage))
407- then throw("Invalid slippageTolerance passed")
408- else {
409- let estPut = commonPut(i, slippage, true)
410- let emitLpAmt = estPut._2
411- let lpAssetId = estPut._7
412- let state = estPut._9
413- let amDiff = estPut._10
414- let prDiff = estPut._11
415- let amId = estPut._12
416- let prId = estPut._13
417- let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
418- if ((emitInv == emitInv))
419- then {
420- let slippageAInv = if ((amDiff > 0))
421- then invoke(slipCntr, "put", nil, [AttachedPayment(amId, amDiff)])
422- else nil
423- if ((slippageAInv == slippageAInv))
424- then {
425- let slippagePInv = if ((prDiff > 0))
426- then invoke(slipCntr, "put", nil, [AttachedPayment(prId, prDiff)])
427- else nil
428- if ((slippagePInv == slippagePInv))
429- then {
430- let lpTrnsfr = if (autoStake)
431- then {
432- let slpStakeInv = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
433- if ((slpStakeInv == slpStakeInv))
434- then nil
435- else throw("Strict value is not equal to itself.")
436- }
437- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
438- (state ++ lpTrnsfr)
439- }
440- else throw("Strict value is not equal to itself.")
441- }
442- else throw("Strict value is not equal to itself.")
443- }
444- else throw("Strict value is not equal to itself.")
445- }
388+ let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Incorrect staking address.")
389+ let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Incorrect slippage address.")
390+ if ((0 > slip))
391+ then throw("Invalid slippage.")
392+ else if ((size(i.payments) != 2))
393+ then throw("2 payments are expected")
394+ else {
395+ let estPut = commonPut(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], slip, true)
396+ let emitLpAmt = estPut._2
397+ let lpAssetId = estPut._7
398+ let state = estPut._9
399+ let amDiff = estPut._10
400+ let prDiff = estPut._11
401+ let amId = estPut._12
402+ let prId = estPut._13
403+ let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
404+ if ((emitInv == emitInv))
405+ then {
406+ let slippageAInv = if ((amDiff > 0))
407+ then invoke(slipCntr, "put", nil, [AttachedPayment(amId, amDiff)])
408+ else nil
409+ if ((slippageAInv == slippageAInv))
410+ then {
411+ let slippagePInv = if ((prDiff > 0))
412+ then invoke(slipCntr, "put", nil, [AttachedPayment(prId, prDiff)])
413+ else nil
414+ if ((slippagePInv == slippagePInv))
415+ then {
416+ let lpTrnsfr = if (autoStake)
417+ then {
418+ let slpStakeInv = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
419+ if ((slpStakeInv == slpStakeInv))
420+ then nil
421+ else throw("Strict value is not equal to itself.")
422+ }
423+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
424+ (state ++ lpTrnsfr)
425+ }
426+ else throw("Strict value is not equal to itself.")
427+ }
428+ else throw("Strict value is not equal to itself.")
429+ }
430+ else throw("Strict value is not equal to itself.")
431+ }
446432 }
447433
448434
450436 @Callable(i)
451437 func putOneTkn (inAmtAmount,inPrAmount,autoStake) = {
452438 let cfg = getFactoryConfig()
453- let stakingContract = valueOrErrorMessage(addressFromString(cfg[idxFactStakCntr]), "Error. Incorrect staking address.")
439+ let stakingCntr = valueOrErrorMessage(addressFromString(cfg[idxFactStakCntr]), "Wrong staking address")
440+ let slipCntr = valueOrErrorMessage(addressFromString(cfg[idxFactSlippCntr]), "Wrong slippage address")
454441 let poolCfg = getPoolConfig()
455442 let amId = poolCfg[idxAmAsId]
456443 let prId = poolCfg[idxPrAsId]
464451 let pmtAmt = pmt.amount
465452 let amAssetSwapX18 = toX18(inAmtAmount, amDcm)
466453 let prAssetSwapX18 = toX18(inPrAmount, prDcm)
467- let inPrice = calcPriceBigInt(prAssetSwapX18, amAssetSwapX18)
468454 let amBalance = getAccBalance(amId)
469- let amBalanceX18 = toX18(amBalance, amDcm)
470455 let prBalance = getAccBalance(prId)
471- let prBalanceX18 = toX18(prBalance, prDcm)
472456 let dCur = calcD(toBigInt(amBalance), toBigInt(prBalance), 50)
473457 let isValid = if ((pmtAssetId == amId))
474458 then {
475459 let pmtAmtX18 = toX18(pmtAmt, amDcm)
476460 let prAdiff = prAssetSwapX18
477461 let amAdiff = (pmtAmtX18 - amAssetSwapX18)
478- let dNew = calcD((toBigInt(amBalance) - toBigInt(fromX18(amAdiff, amDcm))), (toBigInt(prBalance) + toBigInt(fromX18(prAdiff, prDcm))), 50)
479- true
462+ let dSwap = calcD((toBigInt(amBalance) + toBigInt(fromX18(amAdiff, amDcm))), (toBigInt(prBalance) - toBigInt(fromX18(prAdiff, prDcm))), 50)
463+ if ((dSwap > dCur))
464+ then throw("Incorrect argiments passed. Deposit lead to D decrease.")
465+ else true
480466 }
481467 else {
482468 let pmtPrX18 = toX18(pmtAmt, prDcm)
483469 let prAdiff = (prAssetSwapX18 - pmtPrX18)
484470 let amAdiff = amAssetSwapX18
485- let dNew = calcD((toBigInt(amBalance) + toBigInt(fromX18(amAdiff, amDcm))), (toBigInt(prBalance) - toBigInt(fromX18(prAdiff, prDcm))), 50)
486- true
471+ let dNew = calcD((toBigInt(amBalance) - toBigInt(fromX18(amAdiff, amDcm))), (toBigInt(prBalance) + toBigInt(fromX18(prAdiff, prDcm))), 50)
472+ if ((dNew > dCur))
473+ then throw("Wrong arguments passed. D decreased.")
474+ else true
487475 }
488476 if (!(isValid))
489477 then throw("Errors.")
490478 else {
491- let estPut = estimatePutOperation(toBase58String(i.transactionId), 0, inAmtAmount, fromBase58String(amId), inPrAmount, fromBase58String(prId), toString(i.caller), false, true, true)
479+ let estPut = commonPut(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amId), inAmtAmount), AttachedPayment(fromBase58String(prId), inPrAmount), 50000000000, true)
492480 let emitLpAmt = estPut._2
493481 let lpAssetId = estPut._7
494- let status = parseIntValue(estPut._8)
495- if (if (if (isGlobalShutdown())
496- then true
497- else (status == PoolPutDisabled))
498- then true
499- else (status == PoolShutdown))
500- then throw(("Put operation is blocked by admin. Status = " + toString(status)))
501- else {
502- let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
503- if ((emitInv == emitInv))
482+ let state = estPut._9
483+ let amDiff = estPut._10
484+ let prDiff = estPut._11
485+ let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
486+ if ((emitInv == emitInv))
487+ then {
488+ let slippageAInv = if ((amDiff > 0))
489+ then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(amId), amDiff)])
490+ else nil
491+ if ((slippageAInv == slippageAInv))
504492 then {
505- let lpTrnsfr = if (autoStake)
493+ let slippagePInv = if ((prDiff > 0))
494+ then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(prId), prDiff)])
495+ else nil
496+ if ((slippagePInv == slippagePInv))
506497 then {
507- let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
508- if ((stakeInv == stakeInv))
509- then nil
510- else throw("Strict value is not equal to itself.")
498+ let lpTrnsfr = if (autoStake)
499+ then {
500+ let slpStakeInv = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
501+ if ((slpStakeInv == slpStakeInv))
502+ then nil
503+ else throw("Strict value is not equal to itself.")
504+ }
505+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
506+ (state ++ lpTrnsfr)
511507 }
512- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
513- (estPut._9 ++ lpTrnsfr)
508+ else throw("Strict value is not equal to itself.")
514509 }
515510 else throw("Strict value is not equal to itself.")
516511 }
512+ else throw("Strict value is not equal to itself.")
517513 }
518514 }
519515 }
523519 @Callable(i)
524520 func putForFree (maxSlippage) = if ((0 > maxSlippage))
525521 then throw("Invalid value passed")
526- else {
527- let estPut = commonPut(i, maxSlippage, false)
528- estPut._9
529- }
522+ else if ((size(i.payments) != 2))
523+ then throw("exactly 2 payments are expected")
524+ else {
525+ let estPut = commonPut(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], maxSlippage, false)
526+ estPut._9
527+ }
530528
531529
532530
728726
729727
730728 @Callable(i)
731-func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEvaluate,emitLp,isOneAsset) = $Tuple2(nil, estimatePutOperation(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, userAddress, isEvaluate, emitLp, isOneAsset))
729+func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, userAddress, isEvaluate, emitLp))
732730
733731
734732
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 calcError = toBigInt(1000000)
1111
1212 let scale18 = toBigInt(1000000000000000000)
1313
1414 let zeroBigInt = toBigInt(0)
1515
1616 let oneBigInt = toBigInt(1)
1717
1818 let SEP = "__"
1919
2020 let EMPTY = ""
2121
2222 let PoolActive = 1
2323
2424 let PoolPutDisabled = 2
2525
2626 let PoolMatcherDisabled = 3
2727
2828 let PoolShutdown = 4
2929
3030 let idxPoolAddress = 1
3131
3232 let idxPoolStatus = 2
3333
3434 let idxLPAsId = 3
3535
3636 let idxAmAsId = 4
3737
3838 let idxPrAsId = 5
3939
4040 let idxAmtAsDcm = 6
4141
4242 let idxPriceAsDcm = 7
4343
4444 let idxIAmtAsId = 8
4545
4646 let idxIPriceAsId = 9
4747
4848 let idxFactStakCntr = 1
4949
5050 let idxFactSlippCntr = 7
5151
5252 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
5353
5454
5555 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
5656
5757
5858 func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
5959
6060
6161 func abs (val) = if ((zeroBigInt > val))
6262 then -(val)
6363 else val
6464
6565
6666 func keyFactCntr () = "%s__factoryContract"
6767
6868
6969 func keyManagerPublicKey () = "%s__managerPublicKey"
7070
7171
7272 func keyPriceLast () = "%s%s__price__last"
7373
7474
7575 func keyPriceHistory (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
7676
7777
7878 func keyPutActionByUser (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
7979
8080
8181 func keyGetActionByUser (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
8282
8383
8484 func keyAmtAsset () = "%s__amountAsset"
8585
8686
8787 func keyPriceAsset () = "%s__priceAsset"
8888
8989
9090 func keyFactoryConfig () = "%s__factoryConfig"
9191
9292
9393 func keyMatcherPub () = "%s%s__matcher__publicKey"
9494
9595
9696 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
9797
9898
9999 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
100100
101101
102102 func keyAllPoolsShutdown () = "%s__shutdown"
103103
104104
105105 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
106106
107107
108108 func throwOrderError (orderValid,senderValid,matcherValid) = throw(((((("order validation failed: orderValid=" + toString(orderValid)) + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
109109
110110
111111 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
112112
113113
114114 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
115115
116116
117117 let factoryContract = addressFromStringValue(getStringOrFail(this, keyFactCntr()))
118118
119119 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
120120
121121
122122 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
123123
124124
125125 func getPoolConfig () = {
126126 let amtAs = getStringOrFail(this, keyAmtAsset())
127127 let priceAs = getStringOrFail(this, keyPriceAsset())
128128 let iPriceAs = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAs))
129129 let iAmtAs = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAs))
130130 split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAs), toString(iPriceAs))), SEP)
131131 }
132132
133133
134134 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
135135
136136
137137 func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slippageByUser,slippageReal,txHeight,txTimestamp,slipageAmAmt,slipagePrAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slippageByUser), toString(slippageReal), toString(txHeight), toString(txTimestamp), toString(slipageAmAmt), toString(slipagePrAmt)], SEP)
138138
139139
140140 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)
141141
142142
143143 func getAccBalance (assetId) = if ((assetId == "WAVES"))
144144 then wavesBalance(this).available
145145 else assetBalance(this, fromBase58String(assetId))
146146
147147
148148 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
149149
150150
151151 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
152152 let amtAsAmtX18 = toX18(amAmt, amAssetDcm)
153153 let prAsAmtX18 = toX18(prAmt, prAssetDcm)
154154 calcPriceBigInt(prAsAmtX18, amtAsAmtX18)
155155 }
156156
157157
158158 func calcPrices (amAmt,prAmt,lpAmt) = {
159159 let cfg = getPoolConfig()
160160 let amtAsDcm = parseIntValue(cfg[idxAmtAsDcm])
161161 let prAsDcm = parseIntValue(cfg[idxPriceAsDcm])
162162 let priceX18 = privateCalcPrice(amtAsDcm, prAsDcm, amAmt, prAmt)
163163 let amAmtX18 = toX18(amAmt, amtAsDcm)
164164 let prAmtX18 = toX18(prAmt, prAsDcm)
165165 let lpAmtX18 = toX18(lpAmt, scale8)
166166 let lpPrInAmAsX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
167167 let lpPrInPrAsX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
168168 [priceX18, lpPrInAmAsX18, lpPrInPrAsX18]
169169 }
170170
171171
172172 func calculatePrices (amAmt,prAmt,lpAmt) = {
173173 let prices = calcPrices(amAmt, prAmt, lpAmt)
174174 [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
175175 }
176176
177177
178178 func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
179179 let cfg = getPoolConfig()
180180 let lpId = cfg[idxLPAsId]
181181 let amId = cfg[idxAmAsId]
182182 let prId = cfg[idxPrAsId]
183183 let amDcm = parseIntValue(cfg[idxAmtAsDcm])
184184 let prDcm = parseIntValue(cfg[idxPriceAsDcm])
185185 let poolStatus = cfg[idxPoolStatus]
186186 let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpId)), (("Asset " + lpId) + " doesn't exist")).quantity
187187 if ((lpId != pmtAssetId))
188188 then throw("Invalid asset passed.")
189189 else {
190190 let amBalance = getAccBalance(amId)
191191 let amBalanceX18 = toX18(amBalance, amDcm)
192192 let prBalance = getAccBalance(prId)
193193 let prBalanceX18 = toX18(prBalance, prDcm)
194194 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
195195 let curPrice = fromX18(curPriceX18, scale8)
196196 let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
197197 let lpEmissionX18 = toX18(lpEmission, scale8)
198198 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
199199 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
200200 let outAmAmt = fromX18(outAmAmtX18, amDcm)
201201 let outPrAmt = fromX18(outPrAmtX18, prDcm)
202202 let state = if ((txId58 == ""))
203203 then nil
204204 else [ScriptTransfer(userAddress, outAmAmt, if ((amId == "WAVES"))
205205 then unit
206206 else fromBase58String(amId)), ScriptTransfer(userAddress, outPrAmt, if ((prId == "WAVES"))
207207 then unit
208208 else fromBase58String(prId)), StringEntry(keyGetActionByUser(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(keyPriceLast(), curPrice), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), curPrice)]
209209 $Tuple10(outAmAmt, outPrAmt, amId, prId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
210210 }
211211 }
212212
213213
214-func estimatePutOperation (txId58,slippageTolerance,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEvaluate,emitLp,isOneAsset) = {
214+func estimatePutOperation (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEvaluate,emitLp) = {
215215 let cfg = getPoolConfig()
216216 let lpId = fromBase58String(cfg[idxLPAsId])
217217 let amIdStr = cfg[idxAmAsId]
218218 let prIdStr = cfg[idxPrAsId]
219219 let inAmIdStr = cfg[idxIAmtAsId]
220220 let inPrIdStr = cfg[idxIPriceAsId]
221221 let amtDcm = parseIntValue(cfg[idxAmtAsDcm])
222222 let priceDcm = parseIntValue(cfg[idxPriceAsDcm])
223223 let poolStatus = cfg[idxPoolStatus]
224- let lpEmission = valueOrErrorMessage(assetInfo(lpId), (("Asset " + toBase58String(lpId)) + " doesn't exist")).quantity
224+ let lpEmission = valueOrErrorMessage(assetInfo(lpId), "Wrong lp asset.").quantity
225225 let amBalance = if (isEvaluate)
226226 then getAccBalance(amIdStr)
227227 else (getAccBalance(amIdStr) - inAmAmt)
228228 let prBalance = if (isEvaluate)
229229 then getAccBalance(prIdStr)
230230 else (getAccBalance(prIdStr) - inPrAmt)
231231 let inAmAssetAmtX18 = toX18(inAmAmt, amtDcm)
232232 let inPrAssetAmtX18 = toX18(inPrAmt, priceDcm)
233233 let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
234234 let amBalanceX18 = toX18(amBalance, amtDcm)
235235 let prBalanceX18 = toX18(prBalance, priceDcm)
236236 let res = if ((lpEmission == 0))
237237 then {
238238 let curPriceX18 = zeroBigInt
239239 let slippageX18 = zeroBigInt
240240 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
241241 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtDcm), fromX18(inPrAssetAmtX18, priceDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
242242 }
243243 else {
244- let tRes = if (isOneAsset)
245- then {
244+ let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
245+ let slippageRealX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
246+ let slippageX18 = toX18(slippage, scale8)
247+ if (if ((curPriceX18 != zeroBigInt))
248+ then (slippageRealX18 > slippageX18)
249+ else false)
250+ then throw(((("Price slippage " + toString(slippageRealX18)) + " exceeded ") + toString(slippageX18)))
251+ else {
246252 let lpEmissionX18 = toX18(lpEmission, scale8)
247- let sumInAssets = (inAmAssetAmtX18 + inPrAssetAmtX18)
248- let sumPoolBalances = (amBalanceX18 + prBalanceX18)
249- let lpAmtX18 = fraction(lpEmissionX18, sumInAssets, sumPoolBalances)
250- let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
251- $Tuple5(fromX18(lpAmtX18, scale8), inAmAmt, inPrAmt, curPriceX18, toBigInt(0))
253+ let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
254+ let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
255+ let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
256+ then $Tuple2(amViaPrX18, inPrAssetAmtX18)
257+ else $Tuple2(inAmAssetAmtX18, prViaAmX18)
258+ let expAmtAssetAmtX18 = expectedAmts._1
259+ let expPriceAssetAmtX18 = expectedAmts._2
260+ let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
261+ $Tuple5(fromX18(lpAmtX18, scale8), fromX18(expAmtAssetAmtX18, amtDcm), fromX18(expPriceAssetAmtX18, priceDcm), curPriceX18, slippageX18)
252262 }
253- else {
254- let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
255- let slippageX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
256- let slippageToleranceX18 = toX18(slippageTolerance, scale8)
257- if (if ((curPriceX18 != zeroBigInt))
258- then (slippageX18 > slippageToleranceX18)
259- else false)
260- then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
261- else {
262- let lpEmissionX18 = toX18(lpEmission, scale8)
263- let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
264- let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
265- let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
266- then $Tuple2(amViaPrX18, inPrAssetAmtX18)
267- else $Tuple2(inAmAssetAmtX18, prViaAmX18)
268- let expAmtAssetAmtX18 = expectedAmts._1
269- let expPriceAssetAmtX18 = expectedAmts._2
270- let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
271- $Tuple5(fromX18(lpAmtX18, scale8), fromX18(expAmtAssetAmtX18, amtDcm), fromX18(expPriceAssetAmtX18, priceDcm), curPriceX18, slippageX18)
272- }
273- }
274- tRes
275263 }
276264 let calcLpAmt = res._1
277265 let calcAmAssetPmt = res._2
278266 let calcPrAssetPmt = res._3
279267 let curPrice = fromX18(res._4, scale8)
280268 let slippageCalc = fromX18(res._5, scale8)
281269 if ((0 >= calcLpAmt))
282- then throw("Invalid calculations. LP calculated is less than zero.")
270+ then throw("LP is less than zero.")
283271 else {
284272 let emitLpAmt = if (!(emitLp))
285273 then 0
286274 else calcLpAmt
287275 let amDiff = (inAmAmt - calcAmAssetPmt)
288276 let prDiff = (inPrAmt - calcPrAssetPmt)
289- let commonState = [IntegerEntry(keyPriceLast(), curPrice), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), curPrice), StringEntry(keyPutActionByUser(userAddress, txId58), dataPutActionInfo(calcAmAssetPmt, calcPrAssetPmt, emitLpAmt, curPrice, slippageTolerance, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
277+ let commonState = [IntegerEntry(keyPriceLast(), curPrice), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), curPrice), StringEntry(keyPutActionByUser(userAddress, txId58), dataPutActionInfo(calcAmAssetPmt, calcPrAssetPmt, emitLpAmt, curPrice, slippage, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
290278 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpId, poolStatus, commonState, amDiff, prDiff, inAmId, inPrId)
291279 }
292280 }
293281
294282
295283 func validateMatcherOrderAllowed (order) = {
296284 let cfg = getPoolConfig()
297285 let amtAssetId = cfg[idxAmAsId]
298286 let priceAssetId = cfg[idxPrAsId]
299287 let poolStatus = parseIntValue(cfg[idxPoolStatus])
300288 let amtAssetDcm = parseIntValue(cfg[idxAmtAsDcm])
301289 let priceAssetDcm = parseIntValue(cfg[idxPriceAsDcm])
302290 let accAmtAssetBalance = getAccBalance(amtAssetId)
303291 let accPriceAssetBalance = getAccBalance(priceAssetId)
304292 let curPriceX18 = if ((order.orderType == Buy))
305293 then privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
306294 else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance - order.amount), accPriceAssetBalance)
307295 let curPrice = fromX18(curPriceX18, scale8)
308296 if (if (if (isGlobalShutdown())
309297 then true
310298 else (poolStatus == PoolMatcherDisabled))
311299 then true
312300 else (poolStatus == PoolShutdown))
313301 then throw("Exchange operations disabled")
314302 else {
315303 let orderAmtAsset = order.assetPair.amountAsset
316304 let orderAmtAssetStr = if ((orderAmtAsset == unit))
317305 then "WAVES"
318306 else toBase58String(value(orderAmtAsset))
319307 let orderPriceAsset = order.assetPair.priceAsset
320308 let orderPriceAssetStr = if ((orderPriceAsset == unit))
321309 then "WAVES"
322310 else toBase58String(value(orderPriceAsset))
323311 if (if ((orderAmtAssetStr != amtAssetId))
324312 then true
325313 else (orderPriceAssetStr != priceAssetId))
326314 then throw("Wrong order assets.")
327315 else {
328316 let orderPrice = order.price
329317 let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
330318 let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
331319 let isOrderPriceValid = if ((order.orderType == Buy))
332320 then (curPrice >= castedOrderPrice)
333321 else (castedOrderPrice >= curPrice)
334322 true
335323 }
336324 }
337325 }
338326
339327
340328 func commonGet (i) = if ((size(i.payments) != 1))
341329 then throw("exactly 1 payment is expected")
342330 else {
343331 let pmt = value(i.payments[0])
344332 let pmtAssetId = value(pmt.assetId)
345333 let pmtAmt = pmt.amount
346334 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
347335 let outAmAmt = res._1
348336 let outPrAmt = res._2
349337 let poolStatus = parseIntValue(res._9)
350338 let state = res._10
351339 if (if (isGlobalShutdown())
352340 then true
353341 else (poolStatus == PoolShutdown))
354342 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
355343 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
356344 }
357345
358346
359-func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
360- then throw("exactly 2 payments are expected")
361- else {
362- let amAssetPmt = value(i.payments[0])
363- let prAssetPmt = value(i.payments[1])
364- let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp, false)
365- let status = parseIntValue(estPut._8)
366- if (if (if (isGlobalShutdown())
367- then true
368- else (status == PoolPutDisabled))
369- then true
370- else (status == PoolShutdown))
371- then throw(("Put operation is blocked by admin. Status = " + toString(status)))
372- else estPut
373- }
347+func commonPut (caller,txId,amAsPmt,prAsPmt,slippage,emitLp) = {
348+ let estPut = estimatePutOperation(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, false, emitLp)
349+ let status = parseIntValue(estPut._8)
350+ if (if (if (isGlobalShutdown())
351+ then true
352+ else (status == PoolPutDisabled))
353+ then true
354+ else (status == PoolShutdown))
355+ then throw(("Put operation is blocked by admin. Status = " + toString(status)))
356+ else estPut
357+ }
374358
375359
376360 func calcD (a,b,lVal) = {
377361 let l = toBigInt(lVal)
378362 let val4 = toBigInt(4)
379363 let val2 = toBigInt(2)
380364 let val3 = toBigInt(3)
381365 let ApB = (a + b)
382366 let AmB = (a * b)
383367 let l41 = ((val4 * l) - oneBigInt)
384368 let lApBpow = pow((l * ApB), 0, val2, 0, 0, DOWN)
385369 let AmbL41pow = (AmB * pow((l41 / val3), 0, val3, 0, 0, DOWN))
386370 let lAmpApb = ((l * AmB) * ApB)
387371 let rPart = (AmB * pow((AmbL41pow + lApBpow), 0, toBigInt(5), 1, 0, DOWN))
388372 let M = (val2 * pow((lAmpApb + rPart), 0, toBigInt(333333), 6, 0, DOWN))
389373 let divPart = (l41 / (val3 * M))
390374 (((toBigInt(-4) * AmB) * divPart) + M)
391375 }
392376
393377
394378 @Callable(i)
395379 func constructor (factoryContract,managerPublicKey) = if ((i.caller != this))
396380 then throw("permissions denied")
397381 else [StringEntry(keyFactCntr(), factoryContract), StringEntry(keyManagerPublicKey(), managerPublicKey)]
398382
399383
400384
401385 @Callable(i)
402-func put (slippage,autoStake) = {
386+func put (slip,autoStake) = {
403387 let factCfg = getFactoryConfig()
404- let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Error. Incorrect staking address.")
405- let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Error. Incorrect slippage contract address.")
406- if ((0 > slippage))
407- then throw("Invalid slippageTolerance passed")
408- else {
409- let estPut = commonPut(i, slippage, true)
410- let emitLpAmt = estPut._2
411- let lpAssetId = estPut._7
412- let state = estPut._9
413- let amDiff = estPut._10
414- let prDiff = estPut._11
415- let amId = estPut._12
416- let prId = estPut._13
417- let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
418- if ((emitInv == emitInv))
419- then {
420- let slippageAInv = if ((amDiff > 0))
421- then invoke(slipCntr, "put", nil, [AttachedPayment(amId, amDiff)])
422- else nil
423- if ((slippageAInv == slippageAInv))
424- then {
425- let slippagePInv = if ((prDiff > 0))
426- then invoke(slipCntr, "put", nil, [AttachedPayment(prId, prDiff)])
427- else nil
428- if ((slippagePInv == slippagePInv))
429- then {
430- let lpTrnsfr = if (autoStake)
431- then {
432- let slpStakeInv = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
433- if ((slpStakeInv == slpStakeInv))
434- then nil
435- else throw("Strict value is not equal to itself.")
436- }
437- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
438- (state ++ lpTrnsfr)
439- }
440- else throw("Strict value is not equal to itself.")
441- }
442- else throw("Strict value is not equal to itself.")
443- }
444- else throw("Strict value is not equal to itself.")
445- }
388+ let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Incorrect staking address.")
389+ let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Incorrect slippage address.")
390+ if ((0 > slip))
391+ then throw("Invalid slippage.")
392+ else if ((size(i.payments) != 2))
393+ then throw("2 payments are expected")
394+ else {
395+ let estPut = commonPut(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], slip, true)
396+ let emitLpAmt = estPut._2
397+ let lpAssetId = estPut._7
398+ let state = estPut._9
399+ let amDiff = estPut._10
400+ let prDiff = estPut._11
401+ let amId = estPut._12
402+ let prId = estPut._13
403+ let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
404+ if ((emitInv == emitInv))
405+ then {
406+ let slippageAInv = if ((amDiff > 0))
407+ then invoke(slipCntr, "put", nil, [AttachedPayment(amId, amDiff)])
408+ else nil
409+ if ((slippageAInv == slippageAInv))
410+ then {
411+ let slippagePInv = if ((prDiff > 0))
412+ then invoke(slipCntr, "put", nil, [AttachedPayment(prId, prDiff)])
413+ else nil
414+ if ((slippagePInv == slippagePInv))
415+ then {
416+ let lpTrnsfr = if (autoStake)
417+ then {
418+ let slpStakeInv = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
419+ if ((slpStakeInv == slpStakeInv))
420+ then nil
421+ else throw("Strict value is not equal to itself.")
422+ }
423+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
424+ (state ++ lpTrnsfr)
425+ }
426+ else throw("Strict value is not equal to itself.")
427+ }
428+ else throw("Strict value is not equal to itself.")
429+ }
430+ else throw("Strict value is not equal to itself.")
431+ }
446432 }
447433
448434
449435
450436 @Callable(i)
451437 func putOneTkn (inAmtAmount,inPrAmount,autoStake) = {
452438 let cfg = getFactoryConfig()
453- let stakingContract = valueOrErrorMessage(addressFromString(cfg[idxFactStakCntr]), "Error. Incorrect staking address.")
439+ let stakingCntr = valueOrErrorMessage(addressFromString(cfg[idxFactStakCntr]), "Wrong staking address")
440+ let slipCntr = valueOrErrorMessage(addressFromString(cfg[idxFactSlippCntr]), "Wrong slippage address")
454441 let poolCfg = getPoolConfig()
455442 let amId = poolCfg[idxAmAsId]
456443 let prId = poolCfg[idxPrAsId]
457444 let amDcm = parseIntValue(poolCfg[idxAmtAsDcm])
458445 let prDcm = parseIntValue(poolCfg[idxPriceAsDcm])
459446 if ((size(i.payments) != 1))
460447 then throw("exactly 1 payment is expected")
461448 else {
462449 let pmt = value(i.payments[0])
463450 let pmtAssetId = toBase58String(value(pmt.assetId))
464451 let pmtAmt = pmt.amount
465452 let amAssetSwapX18 = toX18(inAmtAmount, amDcm)
466453 let prAssetSwapX18 = toX18(inPrAmount, prDcm)
467- let inPrice = calcPriceBigInt(prAssetSwapX18, amAssetSwapX18)
468454 let amBalance = getAccBalance(amId)
469- let amBalanceX18 = toX18(amBalance, amDcm)
470455 let prBalance = getAccBalance(prId)
471- let prBalanceX18 = toX18(prBalance, prDcm)
472456 let dCur = calcD(toBigInt(amBalance), toBigInt(prBalance), 50)
473457 let isValid = if ((pmtAssetId == amId))
474458 then {
475459 let pmtAmtX18 = toX18(pmtAmt, amDcm)
476460 let prAdiff = prAssetSwapX18
477461 let amAdiff = (pmtAmtX18 - amAssetSwapX18)
478- let dNew = calcD((toBigInt(amBalance) - toBigInt(fromX18(amAdiff, amDcm))), (toBigInt(prBalance) + toBigInt(fromX18(prAdiff, prDcm))), 50)
479- true
462+ let dSwap = calcD((toBigInt(amBalance) + toBigInt(fromX18(amAdiff, amDcm))), (toBigInt(prBalance) - toBigInt(fromX18(prAdiff, prDcm))), 50)
463+ if ((dSwap > dCur))
464+ then throw("Incorrect argiments passed. Deposit lead to D decrease.")
465+ else true
480466 }
481467 else {
482468 let pmtPrX18 = toX18(pmtAmt, prDcm)
483469 let prAdiff = (prAssetSwapX18 - pmtPrX18)
484470 let amAdiff = amAssetSwapX18
485- let dNew = calcD((toBigInt(amBalance) + toBigInt(fromX18(amAdiff, amDcm))), (toBigInt(prBalance) - toBigInt(fromX18(prAdiff, prDcm))), 50)
486- true
471+ let dNew = calcD((toBigInt(amBalance) - toBigInt(fromX18(amAdiff, amDcm))), (toBigInt(prBalance) + toBigInt(fromX18(prAdiff, prDcm))), 50)
472+ if ((dNew > dCur))
473+ then throw("Wrong arguments passed. D decreased.")
474+ else true
487475 }
488476 if (!(isValid))
489477 then throw("Errors.")
490478 else {
491- let estPut = estimatePutOperation(toBase58String(i.transactionId), 0, inAmtAmount, fromBase58String(amId), inPrAmount, fromBase58String(prId), toString(i.caller), false, true, true)
479+ let estPut = commonPut(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amId), inAmtAmount), AttachedPayment(fromBase58String(prId), inPrAmount), 50000000000, true)
492480 let emitLpAmt = estPut._2
493481 let lpAssetId = estPut._7
494- let status = parseIntValue(estPut._8)
495- if (if (if (isGlobalShutdown())
496- then true
497- else (status == PoolPutDisabled))
498- then true
499- else (status == PoolShutdown))
500- then throw(("Put operation is blocked by admin. Status = " + toString(status)))
501- else {
502- let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
503- if ((emitInv == emitInv))
482+ let state = estPut._9
483+ let amDiff = estPut._10
484+ let prDiff = estPut._11
485+ let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
486+ if ((emitInv == emitInv))
487+ then {
488+ let slippageAInv = if ((amDiff > 0))
489+ then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(amId), amDiff)])
490+ else nil
491+ if ((slippageAInv == slippageAInv))
504492 then {
505- let lpTrnsfr = if (autoStake)
493+ let slippagePInv = if ((prDiff > 0))
494+ then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(prId), prDiff)])
495+ else nil
496+ if ((slippagePInv == slippagePInv))
506497 then {
507- let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
508- if ((stakeInv == stakeInv))
509- then nil
510- else throw("Strict value is not equal to itself.")
498+ let lpTrnsfr = if (autoStake)
499+ then {
500+ let slpStakeInv = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
501+ if ((slpStakeInv == slpStakeInv))
502+ then nil
503+ else throw("Strict value is not equal to itself.")
504+ }
505+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
506+ (state ++ lpTrnsfr)
511507 }
512- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
513- (estPut._9 ++ lpTrnsfr)
508+ else throw("Strict value is not equal to itself.")
514509 }
515510 else throw("Strict value is not equal to itself.")
516511 }
512+ else throw("Strict value is not equal to itself.")
517513 }
518514 }
519515 }
520516
521517
522518
523519 @Callable(i)
524520 func putForFree (maxSlippage) = if ((0 > maxSlippage))
525521 then throw("Invalid value passed")
526- else {
527- let estPut = commonPut(i, maxSlippage, false)
528- estPut._9
529- }
522+ else if ((size(i.payments) != 2))
523+ then throw("exactly 2 payments are expected")
524+ else {
525+ let estPut = commonPut(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], maxSlippage, false)
526+ estPut._9
527+ }
530528
531529
532530
533531 @Callable(i)
534532 func get () = {
535533 let res = commonGet(i)
536534 let outAmtAmt = res._1
537535 let outPrAmt = res._2
538536 let pmtAmt = res._3
539537 let pmtAssetId = res._4
540538 let state = res._5
541539 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
542540 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
543541 then state
544542 else throw("Strict value is not equal to itself.")
545543 }
546544
547545
548546
549547 @Callable(i)
550548 func getOneTkn (amAssetSwap,prAssetSwap,outAmount,outAssetId) = if ((size(i.payments) != 1))
551549 then throw("exactly 1 payment is expected")
552550 else {
553551 let cfg = getPoolConfig()
554552 let lpId = cfg[idxLPAsId]
555553 let amId = cfg[idxAmAsId]
556554 let prId = cfg[idxPrAsId]
557555 let amDcm = parseIntValue(cfg[idxAmtAsDcm])
558556 let prDcm = parseIntValue(cfg[idxPriceAsDcm])
559557 let poolStatus = cfg[idxPoolStatus]
560558 if (if ((outAssetId != amId))
561559 then (outAssetId != prId)
562560 else false)
563561 then throw(("Incorrect out asset id passed: " + outAssetId))
564562 else {
565563 let resultAssetId = if ((outAssetId == amId))
566564 then amId
567565 else prId
568566 let resultAmtAmount = if ((outAssetId == amId))
569567 then outAmount
570568 else 0
571569 let resultPrAmount = if ((outAssetId == prId))
572570 then outAmount
573571 else 0
574572 let pmt = value(i.payments[0])
575573 let userAddress = i.caller
576574 let txId58 = toBase58String(i.transactionId)
577575 let pmtAssetId = value(pmt.assetId)
578576 let pmtAmt = pmt.amount
579577 if ((lpId != toBase58String(pmtAssetId)))
580578 then throw("Invalid asset passed.")
581579 else {
582580 let amAssetSwapX18 = toX18(amAssetSwap, amDcm)
583581 let prAssetSwapX18 = toX18(prAssetSwap, prDcm)
584582 let swapPriceX18 = calcPriceBigInt(prAssetSwapX18, amAssetSwapX18)
585583 let r = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
586584 let outAmAmt = r._1
587585 let outPrAmt = r._2
588586 let totalR = if ((outAssetId == amId))
589587 then {
590588 let prSwopPartInAmountAsset = (resultAmtAmount - outAmAmt)
591589 let convRes = fraction(toX18(prSwopPartInAmountAsset, amDcm), swapPriceX18, scale18)
592590 let prAssetDiff = fraction((convRes - prAssetSwapX18), scale8BigInt, prAssetSwapX18)
593591 let amtAsRes = fromX18(fraction(toX18(outPrAmt, prDcm), scale18, swapPriceX18), amDcm)
594592 if (if ((prAssetDiff > calcError))
595593 then true
596594 else (-(calcError) > prAssetDiff))
597595 then throw(((("Slippage exeeded the value " + toString(calcError)) + " and equal to ") + toString(prAssetDiff)))
598596 else (amtAsRes + outAmAmt)
599597 }
600598 else {
601599 let amSwopPartInPriceAsset = (resultPrAmount - outPrAmt)
602600 let convRes = fraction(toX18(amSwopPartInPriceAsset, amDcm), scale18, swapPriceX18)
603601 let prAsRes = fromX18(fraction(toX18(outAmAmt, amDcm), swapPriceX18, scale18), prDcm)
604602 let amAssetDiff = fraction((convRes - amAssetSwapX18), scale8BigInt, amAssetSwapX18)
605603 if (if ((amAssetDiff > calcError))
606604 then true
607605 else (-(calcError) > amAssetDiff))
608606 then throw(((("Slippage exeeded the value " + toString(calcError)) + " and equal to ") + toString(amAssetDiff)))
609607 else (prAsRes + outPrAmt)
610608 }
611609 let amBalance = getAccBalance(amId)
612610 let amBalanceX18 = toX18(amBalance, amDcm)
613611 let prBalance = getAccBalance(prId)
614612 let prBalanceX18 = toX18(prBalance, prDcm)
615613 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
616614 let curPrice = fromX18(curPriceX18, scale8)
617615 let state = [ScriptTransfer(userAddress, totalR, if ((resultAssetId == "WAVES"))
618616 then unit
619617 else fromBase58String(resultAssetId)), StringEntry(keyGetActionByUser(toString(userAddress), txId58), dataGetActionInfo(resultAmtAmount, resultPrAmount, pmtAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(keyPriceLast(), curPrice), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), curPrice)]
620618 let burn = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
621619 if ((burn == burn))
622620 then state
623621 else throw("Strict value is not equal to itself.")
624622 }
625623 }
626624 }
627625
628626
629627
630628 @Callable(i)
631629 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
632630 let res = commonGet(i)
633631 let outAmAmt = res._1
634632 let outPrAmt = res._2
635633 let pmtAmt = res._3
636634 let pmtAssetId = res._4
637635 let state = res._5
638636 if ((noLessThenAmtAsset > outAmAmt))
639637 then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
640638 else if ((noLessThenPriceAsset > outPrAmt))
641639 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
642640 else {
643641 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
644642 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
645643 then state
646644 else throw("Strict value is not equal to itself.")
647645 }
648646 }
649647
650648
651649
652650 @Callable(i)
653651 func unstakeAndGet (amount) = {
654652 let checkPayments = if ((size(i.payments) != 0))
655653 then throw("No payments are expected")
656654 else true
657655 if ((checkPayments == checkPayments))
658656 then {
659657 let cfg = getPoolConfig()
660658 let factoryCfg = getFactoryConfig()
661659 let lpAssetId = fromBase58String(cfg[idxLPAsId])
662660 let stakingContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Error. Incorrect staking address.")
663661 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
664662 if ((unstakeInv == unstakeInv))
665663 then {
666664 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
667665 let poolStatus = parseIntValue(res._9)
668666 let state = res._10
669667 let checkPoolStatus = if (if (isGlobalShutdown())
670668 then true
671669 else (poolStatus == PoolShutdown))
672670 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
673671 else true
674672 if ((checkPoolStatus == checkPoolStatus))
675673 then {
676674 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
677675 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
678676 then state
679677 else throw("Strict value is not equal to itself.")
680678 }
681679 else throw("Strict value is not equal to itself.")
682680 }
683681 else throw("Strict value is not equal to itself.")
684682 }
685683 else throw("Strict value is not equal to itself.")
686684 }
687685
688686
689687
690688 @Callable(i)
691689 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
692690 then throw("permissions denied")
693691 else $Tuple2([StringEntry(keyAmtAsset(), amtAssetStr), StringEntry(keyPriceAsset(), priceAssetStr)], "success")
694692
695693
696694
697695 @Callable(i)
698696 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
699697
700698
701699
702700 @Callable(i)
703701 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
704702
705703
706704
707705 @Callable(i)
708706 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
709707 let prices = calcPrices(amAmt, prAmt, lpAmt)
710708 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
711709 }
712710
713711
714712
715713 @Callable(i)
716714 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
717715
718716
719717
720718 @Callable(i)
721719 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
722720
723721
724722
725723 @Callable(i)
726724 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
727725
728726
729727
730728 @Callable(i)
731-func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEvaluate,emitLp,isOneAsset) = $Tuple2(nil, estimatePutOperation(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, userAddress, isEvaluate, emitLp, isOneAsset))
729+func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, userAddress, isEvaluate, emitLp))
732730
733731
734732
735733 @Callable(i)
736734 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
737735 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
738736 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
739737 }
740738
741739
742740 @Verifier(tx)
743741 func verify () = match tx {
744742 case order: Order =>
745743 let matcherPub = getMatcherPubOrFail()
746744 let orderValid = validateMatcherOrderAllowed(order)
747745 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
748746 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
749747 if (if (if (orderValid)
750748 then senderValid
751749 else false)
752750 then matcherValid
753751 else false)
754752 then true
755753 else throwOrderError(orderValid, senderValid, matcherValid)
756754 case _ =>
757755 let managerPublic = valueOrElse(getString(this, keyManagerPublicKey()), EMPTY)
758756 if ((managerPublic == EMPTY))
759757 then sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
760758 else sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(managerPublic))
761759 }
762760

github/deemru/w8io/03bedc9 
94.82 ms