tx · 6gUf9V65bJaJXkj7VHiYcaEZuT6YeFkLf3vqncJxFPyQ

3NAefciWv6f9fWvEXdGgpHfanJFG8HqfjuT:  -0.01400000 Waves

2021.12.24 23:17 [1848825] smart account 3NAefciWv6f9fWvEXdGgpHfanJFG8HqfjuT > SELF 0.00000000 Waves

{ "type": 13, "id": "6gUf9V65bJaJXkj7VHiYcaEZuT6YeFkLf3vqncJxFPyQ", "fee": 1400000, "feeAssetId": null, "timestamp": 1640377076214, "version": 1, "sender": "3NAefciWv6f9fWvEXdGgpHfanJFG8HqfjuT", "senderPublicKey": "D1BL65meykxFZTCuq7jq9HSGLLnWvQamQPUNrguW5w39", "proofs": [ "2jn8RPMEtKY5AsP99icP8a1xqkALd4ENcTt7ZtpRKMPnmJUY3zSjEQdkxy44RDU5kGuoMJMKJNWcPEaCwB21Ajh8" ], "script": "base64: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bmZpZwAAAAACAAAAESVzX19mYWN0b3J5Q29uZmlnAQAAAA1rZXlNYXRjaGVyUHViAAAAAAIAAAAYJXMlc19fbWF0Y2hlcl9fcHVibGljS2V5AQAAAA1rZXlQb29sQ29uZmlnAAAAAgAAAAlpQW10QXNzZXQAAAALaVByaWNlQXNzZXQJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAIJWQlZCVzX18FAAAACWlBbXRBc3NldAIAAAACX18FAAAAC2lQcmljZUFzc2V0AgAAAAhfX2NvbmZpZwEAAAAfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZAAAAAEAAAAMYmFzZUFzc2V0U3RyCQABLAAAAAICAAAAKCVzJXMlc19fbWFwcGluZ3NfX2Jhc2VBc3NldDJpbnRlcm5hbElkX18FAAAADGJhc2VBc3NldFN0cgEAAAATa2V5QWxsUG9vbHNTaHV0ZG93bgAAAAACAAAADCVzX19zaHV0ZG93bgEAAAANa2V5UG9vbFdlaWdodAAAAAEAAAAPY29udHJhY3RBZGRyZXNzCQABLAAAAAICAAAAEiVzJXNfX3Bvb2xXZWlnaHRfXwUAAAAPY29udHJhY3RBZGRyZXNzAQAAAA90aHJvd09yZGVyRXJyb3IAAAADAAAACm9yZGVyVmFsaWQAAAALc2VuZGVyVmFsaWQAAAAMbWF0Y2hlclZhbGlkCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAB5WYWxpZGF0aW9uIGZhaWxlZDogb3JkZXJWYWxpZD0JAAGlAAAAAQUAAAAKb3JkZXJWYWxpZAIAAAANIHNlbmRlclZhbGlkPQkAAaUAAAABBQAAAAtzZW5kZXJWYWxpZAIAAAAOIG1hdGNoZXJWYWxpZD0JAAGlAAAAAQUAAAAMbWF0Y2hlclZhbGlkAQAAAAhhc1N0cmluZwAAAAEAAAADdmFsBAAAAAckbWF0Y2gwBQAAAAN2YWwDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAAGdmFsU3RyBQAAAAckbWF0Y2gwBQAAAAZ2YWxTdHIJAAACAAAAAQIAAAATZmFpbCBjYXN0IHRvIFN0cmluZwEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAgAAAAdhZGRyZXNzAAAAA2tleQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAAB2FkZHJlc3MFAAAAA2tleQkABLkAAAACCQAETAAAAAICAAAACm1hbmRhdG9yeSAJAARMAAAAAgkABCUAAAABBQAAAAdhZGRyZXNzCQAETAAAAAICAAAAAS4JAARMAAAAAgUAAAADa2V5CQAETAAAAAICAAAADyBpcyBub3QgZGVmaW5lZAUAAAADbmlsAgAAAAABAAAADGdldEludE9yRmFpbAAAAAIAAAAHYWRkcmVzcwAAAANrZXkJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAdhZGRyZXNzBQAAAANrZXkJAAS5AAAAAgkABEwAAAACAgAAAAptYW5kYXRvcnkgCQAETAAAAAIJAAQlAAAAAQUAAAAHYWRkcmVzcwkABEwAAAACAgAAAAEuCQAETAAAAAIFAAAAA2tleQkABEwAAAACAgAAAA8gaXMgbm90IGRlZmluZWQFAAAAA25pbAIAAAAAAAAAAA9mYWN0b3J5Q29udHJhY3QJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAACBQAAAAR0aGlzCQEAAAALa2V5RmFjdENudHIAAAAAAQAAABBpc0dsb2JhbFNodXRkb3duAAAAAAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBsAAAACBQAAAA9mYWN0b3J5Q29udHJhY3QJAQAAABNrZXlBbGxQb29sc1NodXRkb3duAAAAAAcBAAAAE2dldE1hdGNoZXJQdWJPckZhaWwAAAAACQACWQAAAAEJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAACBQAAAA9mYWN0b3J5Q29udHJhY3QJAQAAAA1rZXlNYXRjaGVyUHViAAAAAAEAAAANZ2V0UG9vbENvbmZpZwAAAAAEAAAABWFtdEFzCQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAgUAAAAEdGhpcwkBAAAAC2tleUFtdEFzc2V0AAAAAAQAAAAHcHJpY2VBcwkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAIFAAAABHRoaXMJAQAAAA1rZXlQcmljZUFzc2V0AAAAAAQAAAAIaVByaWNlQXMJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAAA9mYWN0b3J5Q29udHJhY3QJAQAAAB9rZXlNYXBwaW5nc0Jhc2VBc3NldDJpbnRlcm5hbElkAAAAAQUAAAAHcHJpY2VBcwQAAAAGaUFtdEFzCQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAPZmFjdG9yeUNvbnRyYWN0CQEAAAAfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZAAAAAEFAAAABWFtdEFzCQAEtQAAAAIJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAACBQAAAA9mYWN0b3J5Q29udHJhY3QJAQAAAA1rZXlQb29sQ29uZmlnAAAAAgkAAaQAAAABBQAAAAZpQW10QXMJAAGkAAAAAQUAAAAIaVByaWNlQXMFAAAAA1NFUAEAAAAQZ2V0RmFjdG9yeUNvbmZpZwAAAAAJAAS1AAAAAgkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAIFAAAAD2ZhY3RvcnlDb250cmFjdAkBAAAAEGtleUZhY3RvcnlDb25maWcAAAAABQAAAANTRVABAAAAEWRhdGFQdXRBY3Rpb25JbmZvAAAACgAAAA1pbkFtdEFzc2V0QW10AAAAD2luUHJpY2VBc3NldEFtdAAAAAhvdXRMcEFtdAAAAAVwcmljZQAAAA5zbGlwcGFnZUJ5VXNlcgAAAAxzbGlwcGFnZVJlYWwAAAAIdHhIZWlnaHQAAAALdHhUaW1lc3RhbXAAAAAMc2xpcGFnZUFtQW10AAAADHNsaXBhZ2VQckFtdAkABLkAAAACCQAETAAAAAICAAAAFCVkJWQlZCVkJWQlZCVkJWQlZCVkCQAETAAAAAIJAAGkAAAAAQUAAAANaW5BbXRBc3NldEFtdAkABEwAAAACCQABpAAAAAEFAAAAD2luUHJpY2VBc3NldEFtdAkABEwAAAACCQABpAAAAAEFAAAACG91dExwQW10CQAETAAAAAIJAAGkAAAAAQUAAAAFcHJpY2UJAARMAAAAAgkAAaQAAAABBQAAAA5zbGlwcGFnZUJ5VXNlcgkABEwAAAACCQABpAAAAAEFAAAADHNsaXBwYWdlUmVhbAkABEwAAAACCQABpAAAAAEFAAAACHR4SGVpZ2h0CQAETAAAAAIJAAGkAAAAAQUAAAALdHhUaW1lc3RhbXAJAARMAAAAAgkAAaQAAAABBQAAAAxzbGlwYWdlQW1BbXQJAARMAAAAAgkAAaQAAAABBQAAAAxzbGlwYWdlUHJBbXQFAAAAA25pbAUAAAADU0VQAQAAABFkYXRhR2V0QWN0aW9uSW5mbwAAAAYAAAAOb3V0QW10QXNzZXRBbXQAAAAQb3V0UHJpY2VBc3NldEFtdAAAAAdpbkxwQW10AAAABXByaWNlAAAACHR4SGVpZ2h0AAAAC3R4VGltZXN0YW1wCQAEuQAAAAIJAARMAAAAAgIAAAAMJWQlZCVkJWQlZCVkCQAETAAAAAIJAAGkAAAAAQUAAAAOb3V0QW10QXNzZXRBbXQJAARMAAAAAgkAAaQAAAABBQAAABBvdXRQcmljZUFzc2V0QW10CQAETAAAAAIJAAGkAAAAAQUAAAAHaW5McEFtdAkABEwAAAACCQABpAAAAAEFAAAABXByaWNlCQAETAAAAAIJAAGkAAAAAQUAAAAIdHhIZWlnaHQJAARMAAAAAgkAAaQAAAABBQAAAAt0eFRpbWVzdGFtcAUAAAADbmlsBQAAAANTRVABAAAADWdldEFjY0JhbGFuY2UAAAABAAAAB2Fzc2V0SWQDCQAAAAAAAAIFAAAAB2Fzc2V0SWQCAAAABVdBVkVTCAkAA+8AAAABBQAAAAR0aGlzAAAACWF2YWlsYWJsZQkAA/AAAAACBQAAAAR0aGlzCQACWQAAAAEFAAAAB2Fzc2V0SWQBAAAAD2NhbGNQcmljZUJpZ0ludAAAAAIAAAAIcHJBbXRYMTgAAAAIYW1BbXRYMTgJAAE8AAAAAwUAAAAIcHJBbXRYMTgFAAAAB3NjYWxlMTgFAAAACGFtQW10WDE4AQAAAAtjYWxjQWJzRGlmZgAAAAMAAAAHcmVhbEFtdAAAAAtleHBlY3RlZEFtdAAAAAhzbGlwcGFnZQQAAAAEZGlmZgkAATwAAAADCQABOAAAAAIFAAAAB3JlYWxBbXQFAAAAC2V4cGVjdGVkQW10BQAAAAxzY2FsZThCaWdJbnQFAAAAC2V4cGVjdGVkQW10CQAFFQAAAAMJAAE/AAAAAgkAATgAAAACBQAAAAhzbGlwcGFnZQkBAAAAA2FicwAAAAEFAAAABGRpZmYFAAAACnplcm9CaWdJbnQJAAGZAAAAAQkABEwAAAACBQAAAAdyZWFsQW10CQAETAAAAAIFAAAAC2V4cGVjdGVkQW10BQAAAANuaWwFAAAABGRpZmYBAAAAEHByaXZhdGVDYWxjUHJpY2UAAAAEAAAACmFtQXNzZXREY20AAAAKcHJBc3NldERjbQAAAAVhbUFtdAAAAAVwckFtdAQAAAALYW10QXNBbXRYMTgJAQAAAAV0b1gxOAAAAAIFAAAABWFtQW10BQAAAAphbUFzc2V0RGNtBAAAAApwckFzQW10WDE4CQEAAAAFdG9YMTgAAAACBQAAAAVwckFtdAUAAAAKcHJBc3NldERjbQkBAAAAD2NhbGNQcmljZUJpZ0ludAAAAAIFAAAACnByQXNBbXRYMTgFAAAAC2FtdEFzQW10WDE4AQAAAApjYWxjUHJpY2VzAAAAAwAAAAVhbUFtdAAAAAVwckFtdAAAAAVscEFtdAQAAAADY2ZnCQEAAAANZ2V0UG9vbENvbmZpZwAAAAAEAAAACGFtdEFzRGNtCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAADY2ZnBQAAAAtpZHhBbXRBc0RjbQQAAAAHcHJBc0RjbQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAA2NmZwUAAAANaWR4UHJpY2VBc0RjbQQAAAAIcHJpY2VYMTgJAQAAABBwcml2YXRlQ2FsY1ByaWNlAAAABAUAAAAIYW10QXNEY20FAAAAB3ByQXNEY20FAAAABWFtQW10BQAAAAVwckFtdAQAAAAIYW1BbXRYMTgJAQAAAAV0b1gxOAAAAAIFAAAABWFtQW10BQAAAAhhbXRBc0RjbQQAAAAIcHJBbXRYMTgJAQAAAAV0b1gxOAAAAAIFAAAABXByQW10BQAAAAdwckFzRGNtBAAAAAhscEFtdFgxOAkBAAAABXRvWDE4AAAAAgUAAAAFbHBBbXQFAAAABnNjYWxlOAQAAAANbHBQckluQW1Bc1gxOAkBAAAAD2NhbGNQcmljZUJpZ0ludAAAAAIFAAAACGFtQW10WDE4BQAAAAhscEFtdFgxOAQAAAANbHBQckluUHJBc1gxOAkBAAAAD2NhbGNQcmljZUJpZ0ludAAAAAIFAAAACHByQW10WDE4BQAAAAhscEFtdFgxOAkABEwAAAACBQAAAAhwcmljZVgxOAkABEwAAAACBQAAAA1scFBySW5BbUFzWDE4CQAETAAAAAIFAAAADWxwUHJJblByQXNYMTgFAAAAA25pbAEAAAAPY2FsY3VsYXRlUHJpY2VzAAAAAwAAAAVhbUFtdAAAAAVwckFtdAAAAAVscEFtdAQAAAAGcHJpY2VzCQEAAAAKY2FsY1ByaWNlcwAAAAMFAAAABWFtQW10BQAAAAVwckFtdAUAAAAFbHBBbXQJAARMAAAAAgkBAAAAB2Zyb21YMTgAAAACCQABkQAAAAIFAAAABnByaWNlcwAAAAAAAAAAAAUAAAAGc2NhbGU4CQAETAAAAAIJAQAAAAdmcm9tWDE4AAAAAgkAAZEAAAACBQAAAAZwcmljZXMAAAAAAAAAAAEFAAAABnNjYWxlOAkABEwAAAACCQEAAAAHZnJvbVgxOAAAAAIJAAGRAAAAAgUAAAAGcHJpY2VzAAAAAAAAAAACBQAAAAZzY2FsZTgFAAAAA25pbAEAAAAUZXN0aW1hdGVHZXRPcGVyYXRpb24AAAAEAAAABnR4SWQ1OAAAAApwbXRBc3NldElkAAAACHBtdExwQW10AAAAC3VzZXJBZGRyZXNzBAAAAANjZmcJAQAAAA1nZXRQb29sQ29uZmlnAAAAAAQAAAAEbHBJZAkAAZEAAAACBQAAAANjZmcFAAAACWlkeExQQXNJZAQAAAAEYW1JZAkAAZEAAAACBQAAAANjZmcFAAAACWlkeEFtQXNJZAQAAAAEcHJJZAkAAZEAAAACBQAAAANjZmcFAAAACWlkeFByQXNJZAQAAAAFYW1EY20JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAANjZmcFAAAAC2lkeEFtdEFzRGNtBAAAAAVwckRjbQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAA2NmZwUAAAANaWR4UHJpY2VBc0RjbQQAAAAKcG9vbFN0YXR1cwkAAZEAAAACBQAAAANjZmcFAAAADWlkeFBvb2xTdGF0dXMEAAAACmxwRW1pc3Npb24ICQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAPsAAAAAQkAAlkAAAABBQAAAARscElkAgAAAA1JbnZhbGlkIExQIGlkAAAACHF1YW50aXR5AwkBAAAAAiE9AAAAAgUAAAAEbHBJZAUAAAAKcG10QXNzZXRJZAkAAAIAAAABAgAAABFJbnZhbGlkIHBtdCBhc3NldAQAAAAJYW1CYWxhbmNlCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAABGFtSWQEAAAADGFtQmFsYW5jZVgxOAkBAAAABXRvWDE4AAAAAgUAAAAJYW1CYWxhbmNlBQAAAAVhbURjbQQAAAAJcHJCYWxhbmNlCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAABHBySWQEAAAADHByQmFsYW5jZVgxOAkBAAAABXRvWDE4AAAAAgUAAAAJcHJCYWxhbmNlBQAAAAVwckRjbQQAAAALY3VyUHJpY2VYMTgJAQAAAA9jYWxjUHJpY2VCaWdJbnQAAAACBQAAAAxwckJhbGFuY2VYMTgFAAAADGFtQmFsYW5jZVgxOAQAAAAIY3VyUHJpY2UJAQAAAAdmcm9tWDE4AAAAAgUAAAALY3VyUHJpY2VYMTgFAAAABnNjYWxlOAQAAAALcG10THBBbXRYMTgJAQAAAAV0b1gxOAAAAAIFAAAACHBtdExwQW10BQAAAAZzY2FsZTgEAAAADWxwRW1pc3Npb25YMTgJAQAAAAV0b1gxOAAAAAIFAAAACmxwRW1pc3Npb24FAAAABnNjYWxlOAQAAAALb3V0QW1BbXRYMTgJAAE8AAAAAwUAAAAMYW1CYWxhbmNlWDE4BQAAAAtwbXRMcEFtdFgxOAUAAAANbHBFbWlzc2lvblgxOAQAAAALb3V0UHJBbXRYMTgJAAE8AAAAAwUAAAAMcHJCYWxhbmNlWDE4BQAAAAtwbXRMcEFtdFgxOAUAAAANbHBFbWlzc2lvblgxOAQAAAAIb3V0QW1BbXQJAQAAAAdmcm9tWDE4AAAAAgUAAAALb3V0QW1BbXRYMTgFAAAABWFtRGNtBAAAAAhvdXRQckFtdAkBAAAAB2Zyb21YMTgAAAACBQAAAAtvdXRQckFtdFgxOAUAAAAFcHJEY20EAAAABXN0YXRlAwkAAAAAAAACBQAAAAZ0eElkNTgCAAAAAAUAAAADbmlsCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMFAAAAC3VzZXJBZGRyZXNzBQAAAAhvdXRBbUFtdAMJAAAAAAAAAgUAAAAEYW1JZAIAAAAFV0FWRVMFAAAABHVuaXQJAAJZAAAAAQUAAAAEYW1JZAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAAt1c2VyQWRkcmVzcwUAAAAIb3V0UHJBbXQDCQAAAAAAAAIFAAAABHBySWQCAAAABVdBVkVTBQAAAAR1bml0CQACWQAAAAEFAAAABHBySWQJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAEmtleUdldEFjdGlvbkJ5VXNlcgAAAAIJAAQlAAAAAQUAAAALdXNlckFkZHJlc3MFAAAABnR4SWQ1OAkBAAAAEWRhdGFHZXRBY3Rpb25JbmZvAAAABgUAAAAIb3V0QW1BbXQFAAAACG91dFByQW10BQAAAAhwbXRMcEFtdAUAAAAIY3VyUHJpY2UFAAAABmhlaWdodAgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAAxrZXlQcmljZUxhc3QAAAAABQAAAAhjdXJQcmljZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAD2tleVByaWNlSGlzdG9yeQAAAAIFAAAABmhlaWdodAgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAFAAAACGN1clByaWNlBQAAAANuaWwJAAUcAAAACgUAAAAIb3V0QW1BbXQFAAAACG91dFByQW10BQAAAARhbUlkBQAAAARwcklkBQAAAAlhbUJhbGFuY2UFAAAACXByQmFsYW5jZQUAAAAKbHBFbWlzc2lvbgUAAAALY3VyUHJpY2VYMTgFAAAACnBvb2xTdGF0dXMFAAAABXN0YXRlAQAAABRlc3RpbWF0ZVB1dE9wZXJhdGlvbgAAAAkAAAAGdHhJZDU4AAAACHNsaXBwYWdlAAAAB2luQW1BbXQAAAAGaW5BbUlkAAAAB2luUHJBbXQAAAAGaW5QcklkAAAAC3VzZXJBZGRyZXNzAAAACmlzRXZhbHVhdGUAAAAGZW1pdExwBAAAAANjZmcJAQAAAA1nZXRQb29sQ29uZmlnAAAAAAQAAAAEbHBJZAkAAlkAAAABCQABkQAAAAIFAAAAA2NmZwUAAAAJaWR4TFBBc0lkBAAAAAdhbUlkU3RyCQABkQAAAAIFAAAAA2NmZwUAAAAJaWR4QW1Bc0lkBAAAAAdwcklkU3RyCQABkQAAAAIFAAAAA2NmZwUAAAAJaWR4UHJBc0lkBAAAAAlpbkFtSWRTdHIJAAGRAAAAAgUAAAADY2ZnBQAAAAtpZHhJQW10QXNJZAQAAAAJaW5QcklkU3RyCQABkQAAAAIFAAAAA2NmZwUAAAANaWR4SVByaWNlQXNJZAQAAAAGYW10RGNtCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAADY2ZnBQAAAAtpZHhBbXRBc0RjbQQAAAAIcHJpY2VEY20JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAANjZmcFAAAADWlkeFByaWNlQXNEY20EAAAACnBvb2xTdGF0dXMJAAGRAAAAAgUAAAADY2ZnBQAAAA1pZHhQb29sU3RhdHVzBAAAAApscEVtaXNzaW9uCAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAD7AAAAAEFAAAABGxwSWQCAAAADldyb25nIGxwIGFzc2V0AAAACHF1YW50aXR5BAAAAAlhbUJhbGFuY2UDBQAAAAppc0V2YWx1YXRlCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAAB2FtSWRTdHIJAABlAAAAAgkBAAAADWdldEFjY0JhbGFuY2UAAAABBQAAAAdhbUlkU3RyBQAAAAdpbkFtQW10BAAAAAlwckJhbGFuY2UDBQAAAAppc0V2YWx1YXRlCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAAB3BySWRTdHIJAABlAAAAAgkBAAAADWdldEFjY0JhbGFuY2UAAAABBQAAAAdwcklkU3RyBQAAAAdpblByQW10BAAAAA9pbkFtQXNzZXRBbXRYMTgJAQAAAAV0b1gxOAAAAAIFAAAAB2luQW1BbXQFAAAABmFtdERjbQQAAAAPaW5QckFzc2V0QW10WDE4CQEAAAAFdG9YMTgAAAACBQAAAAdpblByQW10BQAAAAhwcmljZURjbQQAAAAMdXNlclByaWNlWDE4CQEAAAAPY2FsY1ByaWNlQmlnSW50AAAAAgUAAAAPaW5QckFzc2V0QW10WDE4BQAAAA9pbkFtQXNzZXRBbXRYMTgEAAAADGFtQmFsYW5jZVgxOAkBAAAABXRvWDE4AAAAAgUAAAAJYW1CYWxhbmNlBQAAAAZhbXREY20EAAAADHByQmFsYW5jZVgxOAkBAAAABXRvWDE4AAAAAgUAAAAJcHJCYWxhbmNlBQAAAAhwcmljZURjbQQAAAADcmVzAwkAAAAAAAACBQAAAApscEVtaXNzaW9uAAAAAAAAAAAABAAAAAtjdXJQcmljZVgxOAUAAAAKemVyb0JpZ0ludAQAAAALc2xpcHBhZ2VYMTgFAAAACnplcm9CaWdJbnQEAAAACGxwQW10WDE4CQAAdgAAAAYJAAE5AAAAAgUAAAAPaW5BbUFzc2V0QW10WDE4BQAAAA9pblByQXNzZXRBbXRYMTgAAAAAAAAAAAAJAAE2AAAAAQAAAAAAAAAABQAAAAAAAAAAAQAAAAAAAAAAAAUAAAAERE9XTgkABRcAAAAFCQEAAAAHZnJvbVgxOAAAAAIFAAAACGxwQW10WDE4BQAAAAZzY2FsZTgJAQAAAAdmcm9tWDE4AAAAAgUAAAAPaW5BbUFzc2V0QW10WDE4BQAAAAZhbXREY20JAQAAAAdmcm9tWDE4AAAAAgUAAAAPaW5QckFzc2V0QW10WDE4BQAAAAhwcmljZURjbQkBAAAAD2NhbGNQcmljZUJpZ0ludAAAAAIJAAE3AAAAAgUAAAAMcHJCYWxhbmNlWDE4BQAAAA9pblByQXNzZXRBbXRYMTgJAAE3AAAAAgUAAAAMYW1CYWxhbmNlWDE4BQAAAA9pbkFtQXNzZXRBbXRYMTgFAAAAC3NsaXBwYWdlWDE4BAAAAAtjdXJQcmljZVgxOAkBAAAAD2NhbGNQcmljZUJpZ0ludAAAAAIFAAAADHByQmFsYW5jZVgxOAUAAAAMYW1CYWxhbmNlWDE4BAAAAA9zbGlwcGFnZVJlYWxYMTgJAAE8AAAAAwkBAAAAA2FicwAAAAEJAAE4AAAAAgUAAAALY3VyUHJpY2VYMTgFAAAADHVzZXJQcmljZVgxOAUAAAAHc2NhbGUxOAUAAAALY3VyUHJpY2VYMTgEAAAAC3NsaXBwYWdlWDE4CQEAAAAFdG9YMTgAAAACBQAAAAhzbGlwcGFnZQUAAAAGc2NhbGU4AwMJAQAAAAIhPQAAAAIFAAAAC2N1clByaWNlWDE4BQAAAAp6ZXJvQmlnSW50CQABPwAAAAIFAAAAD3NsaXBwYWdlUmVhbFgxOAUAAAALc2xpcHBhZ2VYMTgHCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAD1ByaWNlIHNsaXBwYWdlIAkAAaYAAAABBQAAAA9zbGlwcGFnZVJlYWxYMTgCAAAACiBleGNlZWRlZCAJAAGmAAAAAQUAAAALc2xpcHBhZ2VYMTgEAAAADWxwRW1pc3Npb25YMTgJAQAAAAV0b1gxOAAAAAIFAAAACmxwRW1pc3Npb24FAAAABnNjYWxlOAQAAAAKcHJWaWFBbVgxOAkAATwAAAADBQAAAA9pbkFtQXNzZXRBbXRYMTgFAAAAC2N1clByaWNlWDE4BQAAAAdzY2FsZTE4BAAAAAphbVZpYVByWDE4CQABPAAAAAMFAAAAD2luUHJBc3NldEFtdFgxOAUAAAAHc2NhbGUxOAUAAAALY3VyUHJpY2VYMTgEAAAADGV4cGVjdGVkQW10cwMJAAE/AAAAAgUAAAAKcHJWaWFBbVgxOAUAAAAPaW5QckFzc2V0QW10WDE4CQAFFAAAAAIFAAAACmFtVmlhUHJYMTgFAAAAD2luUHJBc3NldEFtdFgxOAkABRQAAAACBQAAAA9pbkFtQXNzZXRBbXRYMTgFAAAACnByVmlhQW1YMTgEAAAAEWV4cEFtdEFzc2V0QW10WDE4CAUAAAAMZXhwZWN0ZWRBbXRzAAAAAl8xBAAAABNleHBQcmljZUFzc2V0QW10WDE4CAUAAAAMZXhwZWN0ZWRBbXRzAAAAAl8yBAAAAAhscEFtdFgxOAkAATwAAAADBQAAAA1scEVtaXNzaW9uWDE4BQAAABNleHBQcmljZUFzc2V0QW10WDE4BQAAAAxwckJhbGFuY2VYMTgJAAUXAAAABQkBAAAAB2Zyb21YMTgAAAACBQAAAAhscEFtdFgxOAUAAAAGc2NhbGU4CQEAAAAHZnJvbVgxOAAAAAIFAAAAEWV4cEFtdEFzc2V0QW10WDE4BQAAAAZhbXREY20JAQAAAAdmcm9tWDE4AAAAAgUAAAATZXhwUHJpY2VBc3NldEFtdFgxOAUAAAAIcHJpY2VEY20FAAAAC2N1clByaWNlWDE4BQAAAAtzbGlwcGFnZVgxOAQAAAAJY2FsY0xwQW10CAUAAAADcmVzAAAAAl8xBAAAAA5jYWxjQW1Bc3NldFBtdAgFAAAAA3JlcwAAAAJfMgQAAAAOY2FsY1ByQXNzZXRQbXQIBQAAAANyZXMAAAACXzMEAAAACGN1clByaWNlCQEAAAAHZnJvbVgxOAAAAAIIBQAAAANyZXMAAAACXzQFAAAABnNjYWxlOAQAAAAMc2xpcHBhZ2VDYWxjCQEAAAAHZnJvbVgxOAAAAAIIBQAAAANyZXMAAAACXzUFAAAABnNjYWxlOAMJAABnAAAAAgAAAAAAAAAAAAUAAAAJY2FsY0xwQW10CQAAAgAAAAECAAAABkxQIDwgMAQAAAAJZW1pdExwQW10AwkBAAAAASEAAAABBQAAAAZlbWl0THAAAAAAAAAAAAAFAAAACWNhbGNMcEFtdAQAAAAGYW1EaWZmCQAAZQAAAAIFAAAAB2luQW1BbXQFAAAADmNhbGNBbUFzc2V0UG10BAAAAAZwckRpZmYJAABlAAAAAgUAAAAHaW5QckFtdAUAAAAOY2FsY1ByQXNzZXRQbXQEAAAAC2NvbW1vblN0YXRlCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAMa2V5UHJpY2VMYXN0AAAAAAUAAAAIY3VyUHJpY2UJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA9rZXlQcmljZUhpc3RvcnkAAAACBQAAAAZoZWlnaHQIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wBQAAAAhjdXJQcmljZQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAASa2V5UHV0QWN0aW9uQnlVc2VyAAAAAgUAAAALdXNlckFkZHJlc3MFAAAABnR4SWQ1OAkBAAAAEWRhdGFQdXRBY3Rpb25JbmZvAAAACgUAAAAOY2FsY0FtQXNzZXRQbXQFAAAADmNhbGNQckFzc2V0UG10BQAAAAllbWl0THBBbXQFAAAACGN1clByaWNlBQAAAAhzbGlwcGFnZQUAAAAMc2xpcHBhZ2VDYWxjBQAAAAZoZWlnaHQIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wBQAAAAZhbURpZmYFAAAABnByRGlmZgUAAAADbmlsCQAFHwAAAA0FAAAACWNhbGNMcEFtdAUAAAAJZW1pdExwQW10BQAAAAhjdXJQcmljZQUAAAAJYW1CYWxhbmNlBQAAAAlwckJhbGFuY2UFAAAACmxwRW1pc3Npb24FAAAABGxwSWQFAAAACnBvb2xTdGF0dXMFAAAAC2NvbW1vblN0YXRlBQAAAAZhbURpZmYFAAAABnByRGlmZgUAAAAGaW5BbUlkBQAAAAZpblBySWQBAAAAG3ZhbGlkYXRlTWF0Y2hlck9yZGVyQWxsb3dlZAAAAAEAAAAFb3JkZXIEAAAAA2NmZwkBAAAADWdldFBvb2xDb25maWcAAAAABAAAAAdhbXRBc0lkCQABkQAAAAIFAAAAA2NmZwUAAAAJaWR4QW1Bc0lkBAAAAAZwckFzSWQJAAGRAAAAAgUAAAADY2ZnBQAAAAlpZHhQckFzSWQEAAAACnBvb2xTdGF0dXMJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAANjZmcFAAAADWlkeFBvb2xTdGF0dXMEAAAACGFtdEFzRGNtCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAADY2ZnBQAAAAtpZHhBbXRBc0RjbQQAAAAHcHJBc0RjbQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAA2NmZwUAAAANaWR4UHJpY2VBc0RjbQQAAAAPYWNjQW10QXNCYWxhbmNlCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAAB2FtdEFzSWQEAAAADmFjY1ByQXNCYWxhbmNlCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAABnByQXNJZAQAAAALY3VyUHJpY2VYMTgDCQAAAAAAAAIIBQAAAAVvcmRlcgAAAAlvcmRlclR5cGUFAAAAA0J1eQkBAAAAEHByaXZhdGVDYWxjUHJpY2UAAAAEBQAAAAhhbXRBc0RjbQUAAAAHcHJBc0RjbQkAAGQAAAACBQAAAA9hY2NBbXRBc0JhbGFuY2UIBQAAAAVvcmRlcgAAAAZhbW91bnQFAAAADmFjY1ByQXNCYWxhbmNlCQEAAAAQcHJpdmF0ZUNhbGNQcmljZQAAAAQFAAAACGFtdEFzRGNtBQAAAAdwckFzRGNtCQAAZQAAAAIFAAAAD2FjY0FtdEFzQmFsYW5jZQgFAAAABW9yZGVyAAAABmFtb3VudAUAAAAOYWNjUHJBc0JhbGFuY2UEAAAACGN1clByaWNlCQEAAAAHZnJvbVgxOAAAAAIFAAAAC2N1clByaWNlWDE4BQAAAAZzY2FsZTgDAwMJAQAAABBpc0dsb2JhbFNodXRkb3duAAAAAAYJAAAAAAAAAgUAAAAKcG9vbFN0YXR1cwUAAAATUG9vbE1hdGNoZXJEaXNhYmxlZAYJAAAAAAAAAgUAAAAKcG9vbFN0YXR1cwUAAAAMUG9vbFNodXRkb3duCQAAAgAAAAECAAAAEEJsb2NrZWQgYnkgYWRtaW4EAAAACm9yQW10QXNzZXQICAUAAAAFb3JkZXIAAAAJYXNzZXRQYWlyAAAAC2Ftb3VudEFzc2V0BAAAAApvckFtdEFzU3RyAwkAAAAAAAACBQAAAApvckFtdEFzc2V0BQAAAAR1bml0AgAAAAVXQVZFUwkAAlgAAAABCQEAAAAFdmFsdWUAAAABBQAAAApvckFtdEFzc2V0BAAAAAlvclByQXNzZXQICAUAAAAFb3JkZXIAAAAJYXNzZXRQYWlyAAAACnByaWNlQXNzZXQEAAAACW9yUHJBc1N0cgMJAAAAAAAAAgUAAAAJb3JQckFzc2V0BQAAAAR1bml0AgAAAAVXQVZFUwkAAlgAAAABCQEAAAAFdmFsdWUAAAABBQAAAAlvclByQXNzZXQDAwkBAAAAAiE9AAAAAgUAAAAKb3JBbXRBc1N0cgUAAAAHYW10QXNJZAYJAQAAAAIhPQAAAAIFAAAACW9yUHJBc1N0cgUAAAAGcHJBc0lkCQAAAgAAAAECAAAAEldyb25nIG9yZGVyIGFzc2V0cwQAAAAKb3JkZXJQcmljZQgFAAAABW9yZGVyAAAABXByaWNlBAAAAAhwcmljZURjbQkAAGsAAAADBQAAAAZzY2FsZTgFAAAAB3ByQXNEY20FAAAACGFtdEFzRGNtBAAAAA5jYXN0T3JkZXJQcmljZQkBAAAAB3RvU2NhbGUAAAADBQAAAApvcmRlclByaWNlBQAAAAZzY2FsZTgFAAAACHByaWNlRGNtBAAAABFpc09yZGVyUHJpY2VWYWxpZAMJAAAAAAAAAggFAAAABW9yZGVyAAAACW9yZGVyVHlwZQUAAAADQnV5CQAAZwAAAAIFAAAACGN1clByaWNlBQAAAA5jYXN0T3JkZXJQcmljZQkAAGcAAAACBQAAAA5jYXN0T3JkZXJQcmljZQUAAAAIY3VyUHJpY2UGAQAAAAljb21tb25HZXQAAAABAAAAAWkDCQEAAAACIT0AAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABCQAAAgAAAAECAAAAEjEgcGF5bWVudCBleHBlY3RlZAQAAAADcG10CQEAAAAFdmFsdWUAAAABCQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAABAAAAApwbXRBc3NldElkCQEAAAAFdmFsdWUAAAABCAUAAAADcG10AAAAB2Fzc2V0SWQEAAAABnBtdEFtdAgFAAAAA3BtdAAAAAZhbW91bnQEAAAAA3JlcwkBAAAAFGVzdGltYXRlR2V0T3BlcmF0aW9uAAAABAkAAlgAAAABCAUAAAABaQAAAA10cmFuc2FjdGlvbklkCQACWAAAAAEFAAAACnBtdEFzc2V0SWQFAAAABnBtdEFtdAgFAAAAAWkAAAAGY2FsbGVyBAAAAAhvdXRBbUFtdAgFAAAAA3JlcwAAAAJfMQQAAAAIb3V0UHJBbXQIBQAAAANyZXMAAAACXzIEAAAACnBvb2xTdGF0dXMJAQAAAA1wYXJzZUludFZhbHVlAAAAAQgFAAAAA3JlcwAAAAJfOQQAAAAFc3RhdGUIBQAAAANyZXMAAAADXzEwAwMJAQAAABBpc0dsb2JhbFNodXRkb3duAAAAAAYJAAAAAAAAAgUAAAAKcG9vbFN0YXR1cwUAAAAMUG9vbFNodXRkb3duCQAAAgAAAAEJAAEsAAAAAgIAAAASQmxvY2tlZCBieSBhZG1pbjogCQABpAAAAAEFAAAACnBvb2xTdGF0dXMJAAUXAAAABQUAAAAIb3V0QW1BbXQFAAAACG91dFByQW10BQAAAAZwbXRBbXQFAAAACnBtdEFzc2V0SWQFAAAABXN0YXRlAQAAAAljb21tb25QdXQAAAAGAAAABmNhbGxlcgAAAAR0eElkAAAAB2FtQXNQbXQAAAAHcHJBc1BtdAAAAAhzbGlwcGFnZQAAAAZlbWl0THAEAAAAAXIJAQAAABRlc3RpbWF0ZVB1dE9wZXJhdGlvbgAAAAkFAAAABHR4SWQFAAAACHNsaXBwYWdlCAkBAAAABXZhbHVlAAAAAQUAAAAHYW1Bc1BtdAAAAAZhbW91bnQICQEAAAAFdmFsdWUAAAABBQAAAAdhbUFzUG10AAAAB2Fzc2V0SWQICQEAAAAFdmFsdWUAAAABBQAAAAdwckFzUG10AAAABmFtb3VudAgJAQAAAAV2YWx1ZQAAAAEFAAAAB3ByQXNQbXQAAAAHYXNzZXRJZAUAAAAGY2FsbGVyBwUAAAAGZW1pdExwBAAAAAZzdGF0dXMJAQAAAA1wYXJzZUludFZhbHVlAAAAAQgFAAAAAXIAAAACXzgDAwMJAQAAABBpc0dsb2JhbFNodXRkb3duAAAAAAYJAAAAAAAAAgUAAAAGc3RhdHVzBQAAAA9Qb29sUHV0RGlzYWJsZWQGCQAAAAAAAAIFAAAABnN0YXR1cwUAAAAMUG9vbFNodXRkb3duCQAAAgAAAAEJAAEsAAAAAgIAAAASQmxvY2tlZCBieSBhZG1pbjogCQABpAAAAAEFAAAABnN0YXR1cwUAAAABcgAAABEAAAABaQEAAAALY29uc3RydWN0b3IAAAACAAAAD2ZhY3RvcnlDb250cmFjdAAAABBtYW5hZ2VyUHVibGljS2V5AwkBAAAAAiE9AAAAAggFAAAAAWkAAAAGY2FsbGVyBQAAAAR0aGlzCQAAAgAAAAECAAAAEnBlcm1pc3Npb25zIGRlbmllZAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAALa2V5RmFjdENudHIAAAAABQAAAA9mYWN0b3J5Q29udHJhY3QJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAE2tleU1hbmFnZXJQdWJsaWNLZXkAAAAABQAAABBtYW5hZ2VyUHVibGljS2V5BQAAAANuaWwAAAABaQEAAAADcHV0AAAAAgAAAARzbGlwAAAACWF1dG9TdGFrZQQAAAAHZmFjdENmZwkBAAAAEGdldEZhY3RvcnlDb25maWcAAAAABAAAAAtzdGFraW5nQ250cgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEJAAGRAAAAAgUAAAAHZmFjdENmZwUAAAAPaWR4RmFjdFN0YWtDbnRyAgAAABZJbmNvcnJlY3Qgc3Rha2luZyBhZGRyBAAAAAhzbGlwQ250cgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEJAAGRAAAAAgUAAAAHZmFjdENmZwUAAAAQaWR4RmFjdFNsaXBwQ250cgIAAAAXSW5jb3JyZWN0IHNsaXBwYWdlIGFkZHIDCQAAZgAAAAIAAAAAAAAAAAAFAAAABHNsaXAJAAACAAAAAQIAAAARSW52YWxpZCBzbGlwcGFnZS4DCQEAAAACIT0AAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAACCQAAAgAAAAECAAAAEzIgcGF5bWVudHMgZXhwZWN0ZWQEAAAABmVzdFB1dAkBAAAACWNvbW1vblB1dAAAAAYJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyCQACWAAAAAEIBQAAAAFpAAAADXRyYW5zYWN0aW9uSWQJAQAAAA9BdHRhY2hlZFBheW1lbnQAAAACCAkBAAAABXZhbHVlAAAAAQkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAdhc3NldElkCAkBAAAABXZhbHVlAAAAAQkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAZhbW91bnQJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEFAAAABHNsaXAGBAAAAAllbWl0THBBbXQIBQAAAAZlc3RQdXQAAAACXzIEAAAACWxwQXNzZXRJZAgFAAAABmVzdFB1dAAAAAJfNwQAAAAFc3RhdGUIBQAAAAZlc3RQdXQAAAACXzkEAAAABmFtRGlmZggFAAAABmVzdFB1dAAAAANfMTAEAAAABnByRGlmZggFAAAABmVzdFB1dAAAAANfMTEEAAAABGFtSWQIBQAAAAZlc3RQdXQAAAADXzEyBAAAAARwcklkCAUAAAAGZXN0UHV0AAAAA18xMwQAAAAHZW1pdEludgkAA/wAAAAEBQAAAA9mYWN0b3J5Q29udHJhY3QCAAAABGVtaXQJAARMAAAAAgUAAAAJZW1pdExwQW10BQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAAHZW1pdEludgUAAAAHZW1pdEludgQAAAAMc2xpcHBhZ2VBSW52AwkAAGYAAAACBQAAAAZhbURpZmYAAAAAAAAAAAAJAAP8AAAABAUAAAAIc2xpcENudHICAAAAA3B1dAUAAAADbmlsCQAETAAAAAIJAQAAAA9BdHRhY2hlZFBheW1lbnQAAAACBQAAAARhbUlkBQAAAAZhbURpZmYFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAAAxzbGlwcGFnZUFJbnYFAAAADHNsaXBwYWdlQUludgQAAAAMc2xpcHBhZ2VQSW52AwkAAGYAAAACBQAAAAZwckRpZmYAAAAAAAAAAAAJAAP8AAAABAUAAAAIc2xpcENudHICAAAAA3B1dAUAAAADbmlsCQAETAAAAAIJAQAAAA9BdHRhY2hlZFBheW1lbnQAAAACBQAAAARwcklkBQAAAAZwckRpZmYFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAAAxzbGlwcGFnZVBJbnYFAAAADHNsaXBwYWdlUEludgQAAAAIbHBUcm5zZnIDBQAAAAlhdXRvU3Rha2UEAAAAC3NscFN0YWtlSW52CQAD/AAAAAQFAAAAC3N0YWtpbmdDbnRyAgAAAAVzdGFrZQUAAAADbmlsCQAETAAAAAIJAQAAAA9BdHRhY2hlZFBheW1lbnQAAAACBQAAAAlscEFzc2V0SWQFAAAACWVtaXRMcEFtdAUAAAADbmlsAwkAAAAAAAACBQAAAAtzbHBTdGFrZUludgUAAAALc2xwU3Rha2VJbnYFAAAAA25pbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAllbWl0THBBbXQFAAAACWxwQXNzZXRJZAUAAAADbmlsCQAETgAAAAIFAAAABXN0YXRlBQAAAAhscFRybnNmcgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAAlwdXRPbmVUa24AAAAFAAAAC2luQW10QW1vdW50AAAACmluUHJBbW91bnQAAAAFb3V0THAAAAAIc2xpcHBhZ2UAAAAJYXV0b1N0YWtlBAAAAANjZmcJAQAAABBnZXRGYWN0b3J5Q29uZmlnAAAAAAQAAAALc3Rha2luZ0NudHIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABCQABkQAAAAIFAAAAA2NmZwUAAAAPaWR4RmFjdFN0YWtDbnRyAgAAABJXcm9uZyBzdGFraW5nIGFkZHIEAAAACHNsaXBDbnRyCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQmAAAAAQkAAZEAAAACBQAAAANjZmcFAAAAEGlkeEZhY3RTbGlwcENudHICAAAAE1dyb25nIHNsaXBwYWdlIGFkZHIEAAAAB2d3eENudHIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABCQABkQAAAAIFAAAAA2NmZwUAAAARaWR4RmFjdEd3eFJld0NudHICAAAAE1dyb25nIHNsaXBwYWdlIGFkZHIEAAAAB3Bvb2xDZmcJAQAAAA1nZXRQb29sQ29uZmlnAAAAAAQAAAAEYW1JZAkAAZEAAAACBQAAAAdwb29sQ2ZnBQAAAAlpZHhBbUFzSWQEAAAABHBySWQJAAGRAAAAAgUAAAAHcG9vbENmZwUAAAAJaWR4UHJBc0lkBAAAAAVhbURjbQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAB3Bvb2xDZmcFAAAAC2lkeEFtdEFzRGNtBAAAAAVwckRjbQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAB3Bvb2xDZmcFAAAADWlkeFByaWNlQXNEY20DCQEAAAACIT0AAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABCQAAAgAAAAECAAAAEjEgcGF5bWVudCBleHBlY3RlZAQAAAADcG10CQEAAAAFdmFsdWUAAAABCQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAABAAAAApwbXRBc3NldElkCQACWAAAAAEJAQAAAAV2YWx1ZQAAAAEIBQAAAANwbXQAAAAHYXNzZXRJZAQAAAAGcG10QW10CAUAAAADcG10AAAABmFtb3VudAQAAAAOYW1Bc3NldFN3YXBYMTgJAQAAAAV0b1gxOAAAAAIFAAAAC2luQW10QW1vdW50BQAAAAVhbURjbQQAAAAOcHJBc3NldFN3YXBYMTgJAQAAAAV0b1gxOAAAAAIFAAAACmluUHJBbW91bnQFAAAABXByRGNtBAAAAAlhbUJhbGFuY2UJAQAAAA1nZXRBY2NCYWxhbmNlAAAAAQUAAAAEYW1JZAQAAAAMYW1CYWxhbmNlWDE4CQEAAAAFdG9YMTgAAAACBQAAAAlhbUJhbGFuY2UFAAAABWFtRGNtBAAAAAlwckJhbGFuY2UJAQAAAA1nZXRBY2NCYWxhbmNlAAAAAQUAAAAEcHJJZAQAAAAMcHJCYWxhbmNlWDE4CQEAAAAFdG9YMTgAAAACBQAAAAlwckJhbGFuY2UFAAAABXByRGNtBAAAAAxhbUJhbGFuY2VOb3cDCQAAAAAAAAIFAAAACnBtdEFzc2V0SWQFAAAABGFtSWQJAABlAAAAAgUAAAAJYW1CYWxhbmNlBQAAAAZwbXRBbXQFAAAACWFtQmFsYW5jZQQAAAAMcHJCYWxhbmNlTm93AwkAAAAAAAACBQAAAApwbXRBc3NldElkBQAAAARwcklkCQAAZQAAAAIFAAAACXByQmFsYW5jZQUAAAAGcG10QW10BQAAAAlwckJhbGFuY2UEAAAABGRDdXIJAAP8AAAABAUAAAAHZ3d4Q250cgIAAAAFY2FsY0QJAARMAAAAAgkAAaQAAAABBQAAAAxhbUJhbGFuY2VOb3cJAARMAAAAAgkAAaQAAAABBQAAAAxwckJhbGFuY2VOb3cJAARMAAAAAgIAAAACNTAJAARMAAAAAgIAAAAJMTAwMDAwMDAwCQAETAAAAAICAAAAATEFAAAAA25pbAUAAAADbmlsBAAAAAdpbnZMZWZ0CQABpwAAAAEJAQAAAAhhc1N0cmluZwAAAAEFAAAABGRDdXIEAAAACGludlJpZ2h0AwkAAAAAAAACBQAAAApwbXRBc3NldElkBQAAAARhbUlkBAAAAAlwbXRBbXRYMTgJAQAAAAV0b1gxOAAAAAIFAAAABnBtdEFtdAUAAAAFYW1EY20EAAAAB3ByQWRpZmYFAAAADnByQXNzZXRTd2FwWDE4BAAAAAdhbUFkaWZmCQABOAAAAAIFAAAACXBtdEFtdFgxOAUAAAAOYW1Bc3NldFN3YXBYMTgEAAAABWRTd2FwCQAD/AAAAAQFAAAAB2d3eENudHICAAAABWNhbGNECQAETAAAAAIJAAGmAAAAAQkAATcAAAACCQABNgAAAAEFAAAADGFtQmFsYW5jZU5vdwkAATYAAAABCQEAAAAHZnJvbVgxOAAAAAIFAAAAB2FtQWRpZmYFAAAABWFtRGNtCQAETAAAAAIJAAGmAAAAAQkAATgAAAACCQABNgAAAAEFAAAADHByQmFsYW5jZU5vdwkAATYAAAABCQEAAAAHZnJvbVgxOAAAAAIFAAAAB3ByQWRpZmYFAAAABXByRGNtCQAETAAAAAICAAAAAjUwCQAETAAAAAICAAAACTEwMDAwMDAwMAkABEwAAAACAgAAAAExBQAAAANuaWwFAAAAA25pbAkAAacAAAABCQEAAAAIYXNTdHJpbmcAAAABBQAAAAVkU3dhcAQAAAAIcG10UHJYMTgJAQAAAAV0b1gxOAAAAAIFAAAABnBtdEFtdAUAAAAFcHJEY20EAAAAB3ByQWRpZmYJAAE4AAAAAgUAAAAIcG10UHJYMTgFAAAADnByQXNzZXRTd2FwWDE4BAAAAAdhbUFkaWZmBQAAAA5hbUFzc2V0U3dhcFgxOAQAAAAFZFN3YXAJAAP8AAAABAUAAAAHZ3d4Q250cgIAAAAFY2FsY0QJAARMAAAAAgkAAaYAAAABCQABOAAAAAIJAAE2AAAAAQUAAAAMYW1CYWxhbmNlTm93CQABNgAAAAEJAQAAAAdmcm9tWDE4AAAAAgUAAAAHYW1BZGlmZgUAAAAFYW1EY20JAARMAAAAAgkAAaYAAAABCQABNwAAAAIJAAE2AAAAAQUAAAAMcHJCYWxhbmNlTm93CQABNgAAAAEJAQAAAAdmcm9tWDE4AAAAAgUAAAAHcHJBZGlmZgUAAAAFcHJEY20JAARMAAAAAgIAAAACNTAJAARMAAAAAgIAAAAJMTAwMDAwMDAwCQAETAAAAAICAAAAATEFAAAAA25pbAUAAAADbmlsCQABpwAAAAEJAQAAAAhhc1N0cmluZwAAAAEFAAAABWRTd2FwAwkBAAAAASEAAAABCAkBAAAAC2NhbGNBYnNEaWZmAAAAAwUAAAAIaW52UmlnaHQFAAAAB2ludkxlZnQJAAE2AAAAAQAAAAAAAAAD6AAAAAJfMQkAAAIAAAABAgAAAAtEIG1pc21hdGNoLgQAAAAGZXN0UHV0CQEAAAAJY29tbW9uUHV0AAAABgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIJAAJYAAAAAQgFAAAAAWkAAAANdHJhbnNhY3Rpb25JZAkBAAAAD0F0dGFjaGVkUGF5bWVudAAAAAIJAAJZAAAAAQUAAAAEYW1JZAUAAAALaW5BbXRBbW91bnQJAQAAAA9BdHRhY2hlZFBheW1lbnQAAAACCQACWQAAAAEFAAAABHBySWQFAAAACmluUHJBbW91bnQAAAAAC6Q7dAAGBAAAAAdlc3RpbUxQCAUAAAAGZXN0UHV0AAAAAl8yBAAAAAlscEFzc2V0SWQIBQAAAAZlc3RQdXQAAAACXzcEAAAABXN0YXRlCAUAAAAGZXN0UHV0AAAAAl85BAAAAAZhbURpZmYIBQAAAAZlc3RQdXQAAAADXzEwBAAAAAZwckRpZmYIBQAAAAZlc3RQdXQAAAADXzExBAAAAAlscENhbGNSZXMJAQAAAAtjYWxjQWJzRGlmZgAAAAMJAAE2AAAAAQUAAAAHZXN0aW1MUAkAATYAAAABBQAAAAVvdXRMcAkAATYAAAABBQAAAAhzbGlwcGFnZQMJAQAAAAEhAAAAAQgFAAAACWxwQ2FsY1JlcwAAAAJfMQkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABJUb28gYmlnIHNsaXBwYWdlOiAJAAGmAAAAAQgFAAAACWxwQ2FsY1JlcwAAAAJfMwIAAAAEIHZzIAkAAaQAAAABBQAAAAhzbGlwcGFnZQQAAAAJZW1pdExwQW10CQABoAAAAAEIBQAAAAlscENhbGNSZXMAAAACXzIEAAAAB2VtaXRJbnYJAAP8AAAABAUAAAAPZmFjdG9yeUNvbnRyYWN0AgAAAARlbWl0CQAETAAAAAIFAAAACWVtaXRMcEFtdAUAAAADbmlsBQAAAANuaWwDCQAAAAAAAAIFAAAAB2VtaXRJbnYFAAAAB2VtaXRJbnYEAAAADHNsaXBwYWdlQUludgMJAABmAAAAAgUAAAAGYW1EaWZmAAAAAAAAAAAACQAD/AAAAAQFAAAACHNsaXBDbnRyAgAAAANwdXQFAAAAA25pbAkABEwAAAACCQEAAAAPQXR0YWNoZWRQYXltZW50AAAAAgkAAlkAAAABBQAAAARhbUlkBQAAAAZhbURpZmYFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAAAxzbGlwcGFnZUFJbnYFAAAADHNsaXBwYWdlQUludgQAAAAMc2xpcHBhZ2VQSW52AwkAAGYAAAACBQAAAAZwckRpZmYAAAAAAAAAAAAJAAP8AAAABAUAAAAIc2xpcENudHICAAAAA3B1dAUAAAADbmlsCQAETAAAAAIJAQAAAA9BdHRhY2hlZFBheW1lbnQAAAACCQACWQAAAAEFAAAABHBySWQFAAAABnByRGlmZgUAAAADbmlsBQAAAANuaWwDCQAAAAAAAAIFAAAADHNsaXBwYWdlUEludgUAAAAMc2xpcHBhZ2VQSW52BAAAAAhscFRybnNmcgMFAAAACWF1dG9TdGFrZQQAAAALc2xwU3Rha2VJbnYJAAP8AAAABAUAAAALc3Rha2luZ0NudHICAAAABXN0YWtlBQAAAANuaWwJAARMAAAAAgkBAAAAD0F0dGFjaGVkUGF5bWVudAAAAAIFAAAACWxwQXNzZXRJZAUAAAAJZW1pdExwQW10BQAAAANuaWwDCQAAAAAAAAIFAAAAC3NscFN0YWtlSW52BQAAAAtzbHBTdGFrZUludgUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAACWVtaXRMcEFtdAUAAAAJbHBBc3NldElkBQAAAANuaWwJAAROAAAAAgUAAAAFc3RhdGUFAAAACGxwVHJuc2ZyCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAACnB1dEZvckZyZWUAAAABAAAAC21heFNsaXBwYWdlAwkAAGYAAAACAAAAAAAAAAAABQAAAAttYXhTbGlwcGFnZQkAAAIAAAABAgAAABBJbnZhbGlkIHNsaXBwYWdlAwkBAAAAAiE9AAAAAgkAAZAAAAABCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAgkAAAIAAAABAgAAABMyIHBheW1lbnRzIGV4cGVjdGVkBAAAAAZlc3RQdXQJAQAAAAljb21tb25QdXQAAAAGCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgkAAlgAAAABCAUAAAABaQAAAA10cmFuc2FjdGlvbklkCQEAAAAPQXR0YWNoZWRQYXltZW50AAAAAggJAQAAAAV2YWx1ZQAAAAEJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAHYXNzZXRJZAgJAQAAAAV2YWx1ZQAAAAEJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAGYW1vdW50CQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABBQAAAAttYXhTbGlwcGFnZQcIBQAAAAZlc3RQdXQAAAACXzkAAAABaQEAAAADZ2V0AAAAAAQAAAADcmVzCQEAAAAJY29tbW9uR2V0AAAAAQUAAAABaQQAAAAJb3V0QW10QW10CAUAAAADcmVzAAAAAl8xBAAAAAhvdXRQckFtdAgFAAAAA3JlcwAAAAJfMgQAAAAGcG10QW10CAUAAAADcmVzAAAAAl8zBAAAAApwbXRBc3NldElkCAUAAAADcmVzAAAAAl80BAAAAAVzdGF0ZQgFAAAAA3JlcwAAAAJfNQQAAAAUYnVybkxQQXNzZXRPbkZhY3RvcnkJAAP8AAAABAUAAAAPZmFjdG9yeUNvbnRyYWN0AgAAAARidXJuCQAETAAAAAIFAAAABnBtdEFtdAUAAAADbmlsCQAETAAAAAIJAQAAAA9BdHRhY2hlZFBheW1lbnQAAAACBQAAAApwbXRBc3NldElkBQAAAAZwbXRBbXQFAAAAA25pbAMJAAAAAAAAAgUAAAAUYnVybkxQQXNzZXRPbkZhY3RvcnkFAAAAFGJ1cm5MUEFzc2V0T25GYWN0b3J5BQAAAAVzdGF0ZQkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAJZ2V0T25lVGtuAAAABQAAAAthbUFzc2V0U3dhcAAAAAtwckFzc2V0U3dhcAAAAAlvdXRBbW91bnQAAAAKb3V0QXNzZXRJZAAAAAhzbGlwcGFnZQMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEJAAACAAAAAQIAAAASMSBwYXltZW50IGV4cGVjdGVkBAAAAANjZmcJAQAAAA1nZXRQb29sQ29uZmlnAAAAAAQAAAAEbHBJZAkAAZEAAAACBQAAAANjZmcFAAAACWlkeExQQXNJZAQAAAAEYW1JZAkAAZEAAAACBQAAAANjZmcFAAAACWlkeEFtQXNJZAQAAAAEcHJJZAkAAZEAAAACBQAAAANjZmcFAAAACWlkeFByQXNJZAQAAAAFYW1EY20JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAANjZmcFAAAAC2lkeEFtdEFzRGNtBAAAAAVwckRjbQkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAA2NmZwUAAAANaWR4UHJpY2VBc0RjbQQAAAAKcG9vbFN0YXR1cwkAAZEAAAACBQAAAANjZmcFAAAADWlkeFBvb2xTdGF0dXMEAAAABGZjZmcJAQAAABBnZXRGYWN0b3J5Q29uZmlnAAAAAAQAAAAHZ3d4Q250cgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEJAAGRAAAAAgUAAAAEZmNmZwUAAAARaWR4RmFjdEd3eFJld0NudHICAAAAFldyb25nIHNsaXBwYWdlIGFkZHJlc3MDAwkBAAAAAiE9AAAAAgUAAAAKb3V0QXNzZXRJZAUAAAAEYW1JZAkBAAAAAiE9AAAAAgUAAAAKb3V0QXNzZXRJZAUAAAAEcHJJZAcJAAACAAAAAQIAAAARSW52YWxpZCBvdXQgYXNzZXQEAAAADXJlc3VsdEFzc2V0SWQDCQAAAAAAAAIFAAAACm91dEFzc2V0SWQFAAAABGFtSWQFAAAABGFtSWQFAAAABHBySWQEAAAAA3BtdAkBAAAABXZhbHVlAAAAAQkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAQAAAALdXNlckFkZHJlc3MIBQAAAAFpAAAABmNhbGxlcgQAAAAGdHhJZDU4CQACWAAAAAEIBQAAAAFpAAAADXRyYW5zYWN0aW9uSWQEAAAACnBtdEFzc2V0SWQJAQAAAAV2YWx1ZQAAAAEIBQAAAANwbXQAAAAHYXNzZXRJZAQAAAAGcG10QW10CAUAAAADcG10AAAABmFtb3VudAMJAQAAAAIhPQAAAAIFAAAABGxwSWQJAAJYAAAAAQUAAAAKcG10QXNzZXRJZAkAAAIAAAABAgAAAApJbnZhbGlkIExQBAAAAAFyCQEAAAAUZXN0aW1hdGVHZXRPcGVyYXRpb24AAAAECQACWAAAAAEIBQAAAAFpAAAADXRyYW5zYWN0aW9uSWQJAAJYAAAAAQUAAAAKcG10QXNzZXRJZAUAAAAGcG10QW10CAUAAAABaQAAAAZjYWxsZXIEAAAACmVzdGltQW1BbXQIBQAAAAFyAAAAAl8xBAAAAAplc3RpbVByQW10CAUAAAABcgAAAAJfMgQAAAAJYW1CYWxhbmNlCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAABGFtSWQEAAAADGFtQmFsYW5jZVgxOAkBAAAABXRvWDE4AAAAAgUAAAAJYW1CYWxhbmNlBQAAAAVhbURjbQQAAAAJcHJCYWxhbmNlCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAABHBySWQEAAAADHByQmFsYW5jZVgxOAkBAAAABXRvWDE4AAAAAgUAAAAJcHJCYWxhbmNlBQAAAAVwckRjbQQAAAAHaW52TGVmdAkAA/wAAAAEBQAAAAdnd3hDbnRyAgAAAAVjYWxjRAkABEwAAAACCQABpAAAAAEFAAAACWFtQmFsYW5jZQkABEwAAAACCQABpAAAAAEFAAAACXByQmFsYW5jZQkABEwAAAACAgAAAAI1MAkABEwAAAACAgAAAAkxMDAwMDAwMDAJAARMAAAAAgIAAAABMQUAAAADbmlsBQAAAANuaWwEAAAAC3Jlc3VsdFR1cGxlAwkAAAAAAAACBQAAAApvdXRBc3NldElkBQAAAARhbUlkBAAAAAthbUFzc2V0RGlmZgkAAGUAAAACBQAAAAlvdXRBbW91bnQFAAAACmVzdGltQW1BbXQEAAAACGludlJpZ2h0CQAD/AAAAAQFAAAAB2d3eENudHICAAAABWNhbGNECQAETAAAAAIJAAGkAAAAAQkAAGQAAAACBQAAAAlhbUJhbGFuY2UFAAAAC2FtQXNzZXREaWZmCQAETAAAAAIJAAGkAAAAAQkAAGUAAAACBQAAAAlwckJhbGFuY2UFAAAAC3ByQXNzZXRTd2FwCQAETAAAAAICAAAAAjUwCQAETAAAAAICAAAACTEwMDAwMDAwMAkABEwAAAACAgAAAAExBQAAAANuaWwFAAAAA25pbAMJAQAAAAEhAAAAAQgJAQAAAAtjYWxjQWJzRGlmZgAAAAMJAAGnAAAAAQkBAAAACGFzU3RyaW5nAAAAAQUAAAAIaW52UmlnaHQJAAGnAAAAAQkBAAAACGFzU3RyaW5nAAAAAQUAAAAHaW52TGVmdAkAATYAAAABAAAAAAAAAAPoAAAAAl8xCQAAAgAAAAECAAAACkQgbWlzbWF0Y2gEAAAACXJlc3VsdEFtdAkAAGQAAAACBQAAAAplc3RpbUFtQW10BQAAAAthbUFzc2V0U3dhcAQAAAAJbHBDYWxjUmVzCQEAAAALY2FsY0Fic0RpZmYAAAADCQABNgAAAAEFAAAACXJlc3VsdEFtdAkAATYAAAABBQAAAAlvdXRBbW91bnQJAAE2AAAAAQUAAAAIc2xpcHBhZ2UDCQEAAAABIQAAAAEIBQAAAAlscENhbGNSZXMAAAACXzEJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAASVG9vIGJpZyBzbGlwcGFnZTogCQABpgAAAAEIBQAAAAlscENhbGNSZXMAAAACXzMCAAAABCB2cyAJAAGkAAAAAQUAAAAIc2xpcHBhZ2UJAAUUAAAAAgkAAaAAAAABCAUAAAAJbHBDYWxjUmVzAAAAAl8yAAAAAAAAAAAABAAAAAtwckFzc2V0RGlmZgkAAGUAAAACBQAAAAlvdXRBbW91bnQFAAAACmVzdGltUHJBbXQEAAAACGludlJpZ2h0CQAD/AAAAAQFAAAAB2d3eENudHICAAAABWNhbGNECQAETAAAAAIJAAGkAAAAAQkAAGUAAAACBQAAAAlhbUJhbGFuY2UFAAAAC2FtQXNzZXRTd2FwCQAETAAAAAIJAAGkAAAAAQkAAGQAAAACBQAAAAlwckJhbGFuY2UFAAAAC3ByQXNzZXREaWZmCQAETAAAAAICAAAAAjUwCQAETAAAAAICAAAACTEwMDAwMDAwMAkABEwAAAACAgAAAAExBQAAAANuaWwFAAAAA25pbAMJAQAAAAEhAAAAAQgJAQAAAAtjYWxjQWJzRGlmZgAAAAMJAAGnAAAAAQkBAAAACGFzU3RyaW5nAAAAAQUAAAAIaW52UmlnaHQJAAGnAAAAAQkBAAAACGFzU3RyaW5nAAAAAQUAAAAHaW52TGVmdAkAATYAAAABAAAAAAAAAAPoAAAAAl8xCQAAAgAAAAECAAAAC0QgbWlzbWF0Y2guBAAAAAlyZXN1bHRBbXQJAABkAAAAAgUAAAAKZXN0aW1QckFtdAUAAAALcHJBc3NldFN3YXAEAAAACWxwQ2FsY1JlcwkBAAAAC2NhbGNBYnNEaWZmAAAAAwkAATYAAAABBQAAAAlyZXN1bHRBbXQJAAE2AAAAAQUAAAAJb3V0QW1vdW50CQABNgAAAAEFAAAACHNsaXBwYWdlAwkBAAAAASEAAAABCAUAAAAJbHBDYWxjUmVzAAAAAl8xCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAElRvbyBiaWcgc2xpcHBhZ2U6IAkAAaYAAAABCAUAAAAJbHBDYWxjUmVzAAAAAl8zAgAAAAQgdnMgCQABpAAAAAEFAAAACHNsaXBwYWdlCQAFFAAAAAIAAAAAAAAAAAAJAAGgAAAAAQgFAAAACWxwQ2FsY1JlcwAAAAJfMgQAAAALY3VyUHJpY2VYMTgJAQAAAA9jYWxjUHJpY2VCaWdJbnQAAAACBQAAAAxwckJhbGFuY2VYMTgFAAAADGFtQmFsYW5jZVgxOAQAAAAIY3VyUHJpY2UJAQAAAAdmcm9tWDE4AAAAAgUAAAALY3VyUHJpY2VYMTgFAAAABnNjYWxlOAQAAAAFc3RhdGUJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAALdXNlckFkZHJlc3MDCQAAAAAAAAIFAAAADXJlc3VsdEFzc2V0SWQFAAAABGFtSWQIBQAAAAtyZXN1bHRUdXBsZQAAAAJfMQgFAAAAC3Jlc3VsdFR1cGxlAAAAAl8yAwkAAAAAAAACBQAAAA1yZXN1bHRBc3NldElkAgAAAAVXQVZFUwUAAAAEdW5pdAkAAlkAAAABBQAAAA1yZXN1bHRBc3NldElkCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAABJrZXlHZXRBY3Rpb25CeVVzZXIAAAACCQAEJQAAAAEFAAAAC3VzZXJBZGRyZXNzBQAAAAZ0eElkNTgJAQAAABFkYXRhR2V0QWN0aW9uSW5mbwAAAAYIBQAAAAtyZXN1bHRUdXBsZQAAAAJfMQgFAAAAC3Jlc3VsdFR1cGxlAAAAAl8yBQAAAAZwbXRBbXQFAAAACGN1clByaWNlBQAAAAZoZWlnaHQIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAMa2V5UHJpY2VMYXN0AAAAAAUAAAAIY3VyUHJpY2UJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA9rZXlQcmljZUhpc3RvcnkAAAACBQAAAAZoZWlnaHQIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wBQAAAAhjdXJQcmljZQUAAAADbmlsBAAAAARidXJuCQAD/AAAAAQFAAAAD2ZhY3RvcnlDb250cmFjdAIAAAAEYnVybgkABEwAAAACBQAAAAZwbXRBbXQFAAAAA25pbAkABEwAAAACCQEAAAAPQXR0YWNoZWRQYXltZW50AAAAAgUAAAAKcG10QXNzZXRJZAUAAAAGcG10QW10BQAAAANuaWwDCQAAAAAAAAIFAAAABGJ1cm4FAAAABGJ1cm4FAAAABXN0YXRlCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAAlnZXROb0xlc3MAAAACAAAAEm5vTGVzc1RoZW5BbXRBc3NldAAAABRub0xlc3NUaGVuUHJpY2VBc3NldAQAAAADcmVzCQEAAAAJY29tbW9uR2V0AAAAAQUAAAABaQQAAAAIb3V0QW1BbXQIBQAAAANyZXMAAAACXzEEAAAACG91dFByQW10CAUAAAADcmVzAAAAAl8yBAAAAAZwbXRBbXQIBQAAAANyZXMAAAACXzMEAAAACnBtdEFzc2V0SWQIBQAAAANyZXMAAAACXzQEAAAABXN0YXRlCAUAAAADcmVzAAAAAl81AwkAAGYAAAACBQAAABJub0xlc3NUaGVuQW10QXNzZXQFAAAACG91dEFtQW10CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAACUZhaWxlZDogIAkAAaQAAAABBQAAAAhvdXRBbUFtdAIAAAADIDwgCQABpAAAAAEFAAAAEm5vTGVzc1RoZW5BbXRBc3NldAMJAABmAAAAAgUAAAAUbm9MZXNzVGhlblByaWNlQXNzZXQFAAAACG91dFByQW10CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAACEZhaWxlZDogCQABpAAAAAEFAAAACG91dFByQW10AgAAAAMgPCAJAAGkAAAAAQUAAAAUbm9MZXNzVGhlblByaWNlQXNzZXQEAAAAFGJ1cm5MUEFzc2V0T25GYWN0b3J5CQAD/AAAAAQFAAAAD2ZhY3RvcnlDb250cmFjdAIAAAAEYnVybgkABEwAAAACBQAAAAZwbXRBbXQFAAAAA25pbAkABEwAAAACCQEAAAAPQXR0YWNoZWRQYXltZW50AAAAAgUAAAAKcG10QXNzZXRJZAUAAAAGcG10QW10BQAAAANuaWwDCQAAAAAAAAIFAAAAFGJ1cm5MUEFzc2V0T25GYWN0b3J5BQAAABRidXJuTFBBc3NldE9uRmFjdG9yeQUAAAAFc3RhdGUJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAADXVuc3Rha2VBbmRHZXQAAAABAAAABmFtb3VudAQAAAANY2hlY2tQYXltZW50cwMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAJAAACAAAAAQIAAAAUTm8gcGF5bWVudHMgZXhwZWN0ZWQGAwkAAAAAAAACBQAAAA1jaGVja1BheW1lbnRzBQAAAA1jaGVja1BheW1lbnRzBAAAAANjZmcJAQAAAA1nZXRQb29sQ29uZmlnAAAAAAQAAAAKZmFjdG9yeUNmZwkBAAAAEGdldEZhY3RvcnlDb25maWcAAAAABAAAAAlscEFzc2V0SWQJAAJZAAAAAQkAAZEAAAACBQAAAANjZmcFAAAACWlkeExQQXNJZAQAAAAPc3Rha2luZ0NvbnRyYWN0CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQmAAAAAQkAAZEAAAACBQAAAApmYWN0b3J5Q2ZnBQAAAA9pZHhGYWN0U3Rha0NudHICAAAAFldyb25nIHN0YWtpbmcgYWRkcmVzcy4EAAAACnVuc3Rha2VJbnYJAAP8AAAABAUAAAAPc3Rha2luZ0NvbnRyYWN0AgAAAAd1bnN0YWtlCQAETAAAAAIJAAJYAAAAAQUAAAAJbHBBc3NldElkCQAETAAAAAIFAAAABmFtb3VudAUAAAADbmlsBQAAAANuaWwDCQAAAAAAAAIFAAAACnVuc3Rha2VJbnYFAAAACnVuc3Rha2VJbnYEAAAAAXIJAQAAABRlc3RpbWF0ZUdldE9wZXJhdGlvbgAAAAQJAAJYAAAAAQgFAAAAAWkAAAANdHJhbnNhY3Rpb25JZAkAAlgAAAABBQAAAAlscEFzc2V0SWQFAAAABmFtb3VudAgFAAAAAWkAAAAGY2FsbGVyBAAAAApwb29sU3RhdHVzCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEIBQAAAAFyAAAAAl85BAAAAAVzdGF0ZQgFAAAAAXIAAAADXzEwBAAAAA9jaGVja1Bvb2xTdGF0dXMDAwkBAAAAEGlzR2xvYmFsU2h1dGRvd24AAAAABgkAAAAAAAACBQAAAApwb29sU3RhdHVzBQAAAAxQb29sU2h1dGRvd24JAAACAAAAAQkAASwAAAACAgAAABJCbG9ja2VkIGJ5IGFkbWluOiAJAAGkAAAAAQUAAAAKcG9vbFN0YXR1cwYDCQAAAAAAAAIFAAAAD2NoZWNrUG9vbFN0YXR1cwUAAAAPY2hlY2tQb29sU3RhdHVzBAAAABRidXJuTFBBc3NldE9uRmFjdG9yeQkAA/wAAAAEBQAAAA9mYWN0b3J5Q29udHJhY3QCAAAABGJ1cm4JAARMAAAAAgUAAAAGYW1vdW50BQAAAANuaWwJAARMAAAAAgkBAAAAD0F0dGFjaGVkUGF5bWVudAAAAAIFAAAACWxwQXNzZXRJZAUAAAAGYW1vdW50BQAAAANuaWwDCQAAAAAAAAIFAAAAFGJ1cm5MUEFzc2V0T25GYWN0b3J5BQAAABRidXJuTFBBc3NldE9uRmFjdG9yeQUAAAAFc3RhdGUJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAACGFjdGl2YXRlAAAAAgAAAAthbXRBc3NldFN0cgAAAA1wcmljZUFzc2V0U3RyAwkBAAAAAiE9AAAAAgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIJAAQlAAAAAQUAAAAPZmFjdG9yeUNvbnRyYWN0CQAAAgAAAAECAAAAEnBlcm1pc3Npb25zIGRlbmllZAkABRQAAAACCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAAtrZXlBbXRBc3NldAAAAAAFAAAAC2FtdEFzc2V0U3RyCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAA1rZXlQcmljZUFzc2V0AAAAAAUAAAANcHJpY2VBc3NldFN0cgUAAAADbmlsAgAAAAdzdWNjZXNzAAAAAWkBAAAAHGdldFBvb2xDb25maWdXcmFwcGVyUkVBRE9OTFkAAAAACQAFFAAAAAIFAAAAA25pbAkBAAAADWdldFBvb2xDb25maWcAAAAAAAAAAWkBAAAAHGdldEFjY0JhbGFuY2VXcmFwcGVyUkVBRE9OTFkAAAABAAAAB2Fzc2V0SWQJAAUUAAAAAgUAAAADbmlsCQEAAAANZ2V0QWNjQmFsYW5jZQAAAAEFAAAAB2Fzc2V0SWQAAAABaQEAAAAZY2FsY1ByaWNlc1dyYXBwZXJSRUFET05MWQAAAAMAAAAFYW1BbXQAAAAFcHJBbXQAAAAFbHBBbXQEAAAABnByaWNlcwkBAAAACmNhbGNQcmljZXMAAAADBQAAAAVhbUFtdAUAAAAFcHJBbXQFAAAABWxwQW10CQAFFAAAAAIFAAAAA25pbAkABEwAAAACCQABpgAAAAEJAAGRAAAAAgUAAAAGcHJpY2VzAAAAAAAAAAAACQAETAAAAAIJAAGmAAAAAQkAAZEAAAACBQAAAAZwcmljZXMAAAAAAAAAAAEJAARMAAAAAgkAAaYAAAABCQABkQAAAAIFAAAABnByaWNlcwAAAAAAAAAAAgUAAAADbmlsAAAAAWkBAAAAFmZyb21YMThXcmFwcGVyUkVBRE9OTFkAAAACAAAAA3ZhbAAAAA9yZXN1bHRTY2FsZU11bHQJAAUUAAAAAgUAAAADbmlsCQEAAAAHZnJvbVgxOAAAAAIJAAGnAAAAAQUAAAADdmFsBQAAAA9yZXN1bHRTY2FsZU11bHQAAAABaQEAAAAUdG9YMThXcmFwcGVyUkVBRE9OTFkAAAACAAAAB29yaWdWYWwAAAANb3JpZ1NjYWxlTXVsdAkABRQAAAACBQAAAANuaWwJAAGmAAAAAQkBAAAABXRvWDE4AAAAAgUAAAAHb3JpZ1ZhbAUAAAANb3JpZ1NjYWxlTXVsdAAAAAFpAQAAAB5jYWxjUHJpY2VCaWdJbnRXcmFwcGVyUkVBRE9OTFkAAAACAAAACHByQW10WDE4AAAACGFtQW10WDE4CQAFFAAAAAIFAAAAA25pbAkAAaYAAAABCQEAAAAPY2FsY1ByaWNlQmlnSW50AAAAAgkAAacAAAABBQAAAAhwckFtdFgxOAkAAacAAAABBQAAAAhhbUFtdFgxOAAAAAFpAQAAACNlc3RpbWF0ZVB1dE9wZXJhdGlvbldyYXBwZXJSRUFET05MWQAAAAkAAAAGdHhJZDU4AAAACHNsaXBwYWdlAAAAB2luQW1BbXQAAAAGaW5BbUlkAAAAB2luUHJBbXQAAAAGaW5QcklkAAAAC3VzZXJBZGRyZXNzAAAACmlzRXZhbHVhdGUAAAAGZW1pdExwCQAFFAAAAAIFAAAAA25pbAkBAAAAFGVzdGltYXRlUHV0T3BlcmF0aW9uAAAACQUAAAAGdHhJZDU4BQAAAAhzbGlwcGFnZQUAAAAHaW5BbUFtdAUAAAAGaW5BbUlkBQAAAAdpblByQW10BQAAAAZpblBySWQFAAAAC3VzZXJBZGRyZXNzBQAAAAppc0V2YWx1YXRlBQAAAAZlbWl0THAAAAABaQEAAAAjZXN0aW1hdGVHZXRPcGVyYXRpb25XcmFwcGVyUkVBRE9OTFkAAAAEAAAABnR4SWQ1OAAAAApwbXRBc3NldElkAAAACHBtdExwQW10AAAAC3VzZXJBZGRyZXNzBAAAAANyZXMJAQAAABRlc3RpbWF0ZUdldE9wZXJhdGlvbgAAAAQFAAAABnR4SWQ1OAUAAAAKcG10QXNzZXRJZAUAAAAIcG10THBBbXQJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAAC3VzZXJBZGRyZXNzCQAFFAAAAAIFAAAAA25pbAkABRwAAAAKCAUAAAADcmVzAAAAAl8xCAUAAAADcmVzAAAAAl8yCAUAAAADcmVzAAAAAl8zCAUAAAADcmVzAAAAAl80CAUAAAADcmVzAAAAAl81CAUAAAADcmVzAAAAAl82CAUAAAADcmVzAAAAAl83CQABpgAAAAEIBQAAAANyZXMAAAACXzgIBQAAAANyZXMAAAACXzkIBQAAAANyZXMAAAADXzEwAAAAAQAAAAJ0eAEAAAAGdmVyaWZ5AAAAAAQAAAAHJG1hdGNoMAUAAAACdHgDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABU9yZGVyBAAAAAVvcmRlcgUAAAAHJG1hdGNoMAQAAAAKbWF0Y2hlclB1YgkBAAAAE2dldE1hdGNoZXJQdWJPckZhaWwAAAAABAAAAApvcmRlclZhbGlkCQEAAAAbdmFsaWRhdGVNYXRjaGVyT3JkZXJBbGxvd2VkAAAAAQUAAAAFb3JkZXIEAAAAC3NlbmRlclZhbGlkCQAB9AAAAAMIBQAAAAVvcmRlcgAAAAlib2R5Qnl0ZXMJAAGRAAAAAggFAAAABW9yZGVyAAAABnByb29mcwAAAAAAAAAAAAgFAAAABW9yZGVyAAAAD3NlbmRlclB1YmxpY0tleQQAAAAMbWF0Y2hlclZhbGlkCQAB9AAAAAMIBQAAAAVvcmRlcgAAAAlib2R5Qnl0ZXMJAAGRAAAAAggFAAAABW9yZGVyAAAABnByb29mcwAAAAAAAAAAAQUAAAAKbWF0Y2hlclB1YgMDAwUAAAAKb3JkZXJWYWxpZAUAAAALc2VuZGVyVmFsaWQHBQAAAAxtYXRjaGVyVmFsaWQHBgkBAAAAD3Rocm93T3JkZXJFcnJvcgAAAAMFAAAACm9yZGVyVmFsaWQFAAAAC3NlbmRlclZhbGlkBQAAAAxtYXRjaGVyVmFsaWQEAAAADW1hbmFnZXJQdWJsaWMJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwkBAAAAE2tleU1hbmFnZXJQdWJsaWNLZXkAAAAABQAAAAVFTVBUWQMJAAAAAAAAAgUAAAANbWFuYWdlclB1YmxpYwUAAAAFRU1QVFkJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAACAUAAAACdHgAAAAPc2VuZGVyUHVibGljS2V5CQAB9AAAAAMIBQAAAAJ0eAAAAAlib2R5Qnl0ZXMJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAAkAAlkAAAABBQAAAA1tYW5hZ2VyUHVibGlje1B4fA==", "chainId": 84, "height": 1848825, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 47SqymnnVXkGCHvf4px1E9P9zCDYhmjgfkRtqQioRh84 Next: 26NF1ySGgjHuoHvzsFaHJZs4tz5VJLsv92gD7BJbXeFX Diff:
OldNewDifferences
107107 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
108108
109109
110-func throwOrderError (orderValid,senderValid,matcherValid) = throw(((((("order validation failed: orderValid=" + toString(orderValid)) + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
110+func throwOrderError (orderValid,senderValid,matcherValid) = throw(((((("Validation failed: orderValid=" + toString(orderValid)) + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
111111
112112
113113 func asString (val) = match val {
114114 case valStr: String =>
115115 valStr
116116 case _ =>
117- throw("fail to cast into Int")
117+ throw("fail cast to String")
118118 }
119119
120120
158158 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
159159
160160
161+func calcAbsDiff (realAmt,expectedAmt,slippage) = {
162+ let diff = fraction((realAmt - expectedAmt), scale8BigInt, expectedAmt)
163+ $Tuple3(((slippage - abs(diff)) > zeroBigInt), min([realAmt, expectedAmt]), diff)
164+ }
165+
166+
161167 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
162168 let amtAsAmtX18 = toX18(amAmt, amAssetDcm)
163169 let prAsAmtX18 = toX18(prAmt, prAssetDcm)
193199 let amDcm = parseIntValue(cfg[idxAmtAsDcm])
194200 let prDcm = parseIntValue(cfg[idxPriceAsDcm])
195201 let poolStatus = cfg[idxPoolStatus]
196- let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpId)), (("Asset " + lpId) + " doesn't exist")).quantity
202+ let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "Invalid LP id").quantity
197203 if ((lpId != pmtAssetId))
198- then throw("Invalid asset passed.")
204+ then throw("Invalid pmt asset")
199205 else {
200206 let amBalance = getAccBalance(amId)
201207 let amBalanceX18 = toX18(amBalance, amDcm)
231237 let amtDcm = parseIntValue(cfg[idxAmtAsDcm])
232238 let priceDcm = parseIntValue(cfg[idxPriceAsDcm])
233239 let poolStatus = cfg[idxPoolStatus]
234- let lpEmission = valueOrErrorMessage(assetInfo(lpId), "Wrong lp asset.").quantity
240+ let lpEmission = valueOrErrorMessage(assetInfo(lpId), "Wrong lp asset").quantity
235241 let amBalance = if (isEvaluate)
236242 then getAccBalance(amIdStr)
237243 else (getAccBalance(amIdStr) - inAmAmt)
277283 let curPrice = fromX18(res._4, scale8)
278284 let slippageCalc = fromX18(res._5, scale8)
279285 if ((0 >= calcLpAmt))
280- then throw("LP is less than zero.")
286+ then throw("LP < 0")
281287 else {
282288 let emitLpAmt = if (!(emitLp))
283289 then 0
292298
293299 func validateMatcherOrderAllowed (order) = {
294300 let cfg = getPoolConfig()
295- let amtAssetId = cfg[idxAmAsId]
296- let priceAssetId = cfg[idxPrAsId]
301+ let amtAsId = cfg[idxAmAsId]
302+ let prAsId = cfg[idxPrAsId]
297303 let poolStatus = parseIntValue(cfg[idxPoolStatus])
298- let amtAssetDcm = parseIntValue(cfg[idxAmtAsDcm])
299- let priceAssetDcm = parseIntValue(cfg[idxPriceAsDcm])
300- let accAmtAssetBalance = getAccBalance(amtAssetId)
301- let accPriceAssetBalance = getAccBalance(priceAssetId)
304+ let amtAsDcm = parseIntValue(cfg[idxAmtAsDcm])
305+ let prAsDcm = parseIntValue(cfg[idxPriceAsDcm])
306+ let accAmtAsBalance = getAccBalance(amtAsId)
307+ let accPrAsBalance = getAccBalance(prAsId)
302308 let curPriceX18 = if ((order.orderType == Buy))
303- then privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
304- else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance - order.amount), accPriceAssetBalance)
309+ then privateCalcPrice(amtAsDcm, prAsDcm, (accAmtAsBalance + order.amount), accPrAsBalance)
310+ else privateCalcPrice(amtAsDcm, prAsDcm, (accAmtAsBalance - order.amount), accPrAsBalance)
305311 let curPrice = fromX18(curPriceX18, scale8)
306312 if (if (if (isGlobalShutdown())
307313 then true
308314 else (poolStatus == PoolMatcherDisabled))
309315 then true
310316 else (poolStatus == PoolShutdown))
311- then throw("Exchange operations disabled")
317+ then throw("Blocked by admin")
312318 else {
313- let orderAmtAsset = order.assetPair.amountAsset
314- let orderAmtAssetStr = if ((orderAmtAsset == unit))
319+ let orAmtAsset = order.assetPair.amountAsset
320+ let orAmtAsStr = if ((orAmtAsset == unit))
315321 then "WAVES"
316- else toBase58String(value(orderAmtAsset))
317- let orderPriceAsset = order.assetPair.priceAsset
318- let orderPriceAssetStr = if ((orderPriceAsset == unit))
322+ else toBase58String(value(orAmtAsset))
323+ let orPrAsset = order.assetPair.priceAsset
324+ let orPrAsStr = if ((orPrAsset == unit))
319325 then "WAVES"
320- else toBase58String(value(orderPriceAsset))
321- if (if ((orderAmtAssetStr != amtAssetId))
326+ else toBase58String(value(orPrAsset))
327+ if (if ((orAmtAsStr != amtAsId))
322328 then true
323- else (orderPriceAssetStr != priceAssetId))
324- then throw("Wrong order assets.")
329+ else (orPrAsStr != prAsId))
330+ then throw("Wrong order assets")
325331 else {
326332 let orderPrice = order.price
327- let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
328- let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
333+ let priceDcm = fraction(scale8, prAsDcm, amtAsDcm)
334+ let castOrderPrice = toScale(orderPrice, scale8, priceDcm)
329335 let isOrderPriceValid = if ((order.orderType == Buy))
330- then (curPrice >= castedOrderPrice)
331- else (castedOrderPrice >= curPrice)
336+ then (curPrice >= castOrderPrice)
337+ else (castOrderPrice >= curPrice)
332338 true
333339 }
334340 }
336342
337343
338344 func commonGet (i) = if ((size(i.payments) != 1))
339- then throw("exactly 1 payment is expected")
345+ then throw("1 payment expected")
340346 else {
341347 let pmt = value(i.payments[0])
342348 let pmtAssetId = value(pmt.assetId)
349355 if (if (isGlobalShutdown())
350356 then true
351357 else (poolStatus == PoolShutdown))
352- then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
358+ then throw(("Blocked by admin: " + toString(poolStatus)))
353359 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
354360 }
355361
356362
357363 func commonPut (caller,txId,amAsPmt,prAsPmt,slippage,emitLp) = {
358- let estPut = estimatePutOperation(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, false, emitLp)
359- let status = parseIntValue(estPut._8)
364+ let r = estimatePutOperation(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, false, emitLp)
365+ let status = parseIntValue(r._8)
360366 if (if (if (isGlobalShutdown())
361367 then true
362368 else (status == PoolPutDisabled))
363369 then true
364370 else (status == PoolShutdown))
365- then throw(("Put operation is blocked by admin. Status = " + toString(status)))
366- else estPut
371+ then throw(("Blocked by admin: " + toString(status)))
372+ else r
367373 }
368374
369375
377383 @Callable(i)
378384 func put (slip,autoStake) = {
379385 let factCfg = getFactoryConfig()
380- let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Incorrect staking address.")
381- let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Incorrect slippage address.")
386+ let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Incorrect staking addr")
387+ let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Incorrect slippage addr")
382388 if ((0 > slip))
383389 then throw("Invalid slippage.")
384390 else if ((size(i.payments) != 2))
385- then throw("2 payments are expected")
391+ then throw("2 payments expected")
386392 else {
387393 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)
388394 let emitLpAmt = estPut._2
426432
427433
428434 @Callable(i)
429-func putOneTkn (inAmtAmount,inPrAmount,autoStake) = {
435+func putOneTkn (inAmtAmount,inPrAmount,outLp,slippage,autoStake) = {
430436 let cfg = getFactoryConfig()
431- let stakingCntr = valueOrErrorMessage(addressFromString(cfg[idxFactStakCntr]), "Wrong staking address")
432- let slipCntr = valueOrErrorMessage(addressFromString(cfg[idxFactSlippCntr]), "Wrong slippage address")
433- let gwxCntr = valueOrErrorMessage(addressFromString(cfg[idxFactGwxRewCntr]), "Wrong slippage address")
437+ let stakingCntr = valueOrErrorMessage(addressFromString(cfg[idxFactStakCntr]), "Wrong staking addr")
438+ let slipCntr = valueOrErrorMessage(addressFromString(cfg[idxFactSlippCntr]), "Wrong slippage addr")
439+ let gwxCntr = valueOrErrorMessage(addressFromString(cfg[idxFactGwxRewCntr]), "Wrong slippage addr")
434440 let poolCfg = getPoolConfig()
435441 let amId = poolCfg[idxAmAsId]
436442 let prId = poolCfg[idxPrAsId]
437443 let amDcm = parseIntValue(poolCfg[idxAmtAsDcm])
438444 let prDcm = parseIntValue(poolCfg[idxPriceAsDcm])
439445 if ((size(i.payments) != 1))
440- then throw("exactly 1 payment is expected")
446+ then throw("1 payment expected")
441447 else {
442448 let pmt = value(i.payments[0])
443449 let pmtAssetId = toBase58String(value(pmt.assetId))
456462 else prBalance
457463 let dCur = invoke(gwxCntr, "calcD", [toString(amBalanceNow), toString(prBalanceNow), "50", "100000000", "1"], nil)
458464 let invLeft = parseBigIntValue(asString(dCur))
459- let isValid = if ((pmtAssetId == amId))
465+ let invRight = if ((pmtAssetId == amId))
460466 then {
461467 let pmtAmtX18 = toX18(pmtAmt, amDcm)
462468 let prAdiff = prAssetSwapX18
463469 let amAdiff = (pmtAmtX18 - amAssetSwapX18)
464470 let dSwap = invoke(gwxCntr, "calcD", [toString((toBigInt(amBalanceNow) + toBigInt(fromX18(amAdiff, amDcm)))), toString((toBigInt(prBalanceNow) - toBigInt(fromX18(prAdiff, prDcm)))), "50", "100000000", "1"], nil)
465- let invRight = parseBigIntValue(asString(dSwap))
466- let invDiff = abs(fraction((invRight - invLeft), scale8BigInt, invLeft))
467- if ((invDiff > toBigInt(1000)))
468- then throw("Wrong arguments passed. D decreased.")
469- else true
471+ parseBigIntValue(asString(dSwap))
470472 }
471473 else {
472474 let pmtPrX18 = toX18(pmtAmt, prDcm)
473475 let prAdiff = (pmtPrX18 - prAssetSwapX18)
474476 let amAdiff = amAssetSwapX18
475477 let dSwap = invoke(gwxCntr, "calcD", [toString((toBigInt(amBalanceNow) - toBigInt(fromX18(amAdiff, amDcm)))), toString((toBigInt(prBalanceNow) + toBigInt(fromX18(prAdiff, prDcm)))), "50", "100000000", "1"], nil)
476- let invRight = parseBigIntValue(asString(dSwap))
477- let invDiff = abs(fraction((invRight - invLeft), scale8BigInt, invLeft))
478- if ((invDiff > toBigInt(1000)))
479- then throw("Wrong arguments passed. D decreased.")
480- else true
478+ parseBigIntValue(asString(dSwap))
481479 }
482- if (!(isValid))
483- then throw("Errors.")
480+ if (!(calcAbsDiff(invRight, invLeft, toBigInt(1000))._1))
481+ then throw("D mismatch.")
484482 else {
485483 let estPut = commonPut(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amId), inAmtAmount), AttachedPayment(fromBase58String(prId), inPrAmount), 50000000000, true)
486- let emitLpAmt = estPut._2
484+ let estimLP = estPut._2
487485 let lpAssetId = estPut._7
488486 let state = estPut._9
489487 let amDiff = estPut._10
490488 let prDiff = estPut._11
491- let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
492- if ((emitInv == emitInv))
493- then {
494- let slippageAInv = if ((amDiff > 0))
495- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(amId), amDiff)])
496- else nil
497- if ((slippageAInv == slippageAInv))
489+ let lpCalcRes = calcAbsDiff(toBigInt(estimLP), toBigInt(outLp), toBigInt(slippage))
490+ if (!(lpCalcRes._1))
491+ then throw(((("Too big slippage: " + toString(lpCalcRes._3)) + " vs ") + toString(slippage)))
492+ else {
493+ let emitLpAmt = toInt(lpCalcRes._2)
494+ let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
495+ if ((emitInv == emitInv))
498496 then {
499- let slippagePInv = if ((prDiff > 0))
500- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(prId), prDiff)])
497+ let slippageAInv = if ((amDiff > 0))
498+ then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(amId), amDiff)])
501499 else nil
502- if ((slippagePInv == slippagePInv))
500+ if ((slippageAInv == slippageAInv))
503501 then {
504- let lpTrnsfr = if (autoStake)
502+ let slippagePInv = if ((prDiff > 0))
503+ then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(prId), prDiff)])
504+ else nil
505+ if ((slippagePInv == slippagePInv))
505506 then {
506- let slpStakeInv = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
507- if ((slpStakeInv == slpStakeInv))
508- then nil
509- else throw("Strict value is not equal to itself.")
507+ let lpTrnsfr = if (autoStake)
508+ then {
509+ let slpStakeInv = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
510+ if ((slpStakeInv == slpStakeInv))
511+ then nil
512+ else throw("Strict value is not equal to itself.")
513+ }
514+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
515+ (state ++ lpTrnsfr)
510516 }
511- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
512- (state ++ lpTrnsfr)
517+ else throw("Strict value is not equal to itself.")
513518 }
514519 else throw("Strict value is not equal to itself.")
515520 }
516521 else throw("Strict value is not equal to itself.")
517522 }
518- else throw("Strict value is not equal to itself.")
519523 }
520524 }
521525 }
524528
525529 @Callable(i)
526530 func putForFree (maxSlippage) = if ((0 > maxSlippage))
527- then throw("Invalid value passed")
531+ then throw("Invalid slippage")
528532 else if ((size(i.payments) != 2))
529- then throw("exactly 2 payments are expected")
533+ then throw("2 payments expected")
530534 else {
531535 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)
532536 estPut._9
551555
552556
553557 @Callable(i)
554-func getOneTkn (amAssetSwap,prAssetSwap,outAmount,outAssetId) = if ((size(i.payments) != 1))
555- then throw("exactly 1 payment is expected")
558+func getOneTkn (amAssetSwap,prAssetSwap,outAmount,outAssetId,slippage) = if ((size(i.payments) != 1))
559+ then throw("1 payment expected")
556560 else {
557561 let cfg = getPoolConfig()
558562 let lpId = cfg[idxLPAsId]
561565 let amDcm = parseIntValue(cfg[idxAmtAsDcm])
562566 let prDcm = parseIntValue(cfg[idxPriceAsDcm])
563567 let poolStatus = cfg[idxPoolStatus]
568+ let fcfg = getFactoryConfig()
569+ let gwxCntr = valueOrErrorMessage(addressFromString(fcfg[idxFactGwxRewCntr]), "Wrong slippage address")
564570 if (if ((outAssetId != amId))
565571 then (outAssetId != prId)
566572 else false)
567- then throw(("Incorrect out asset id passed: " + outAssetId))
573+ then throw("Invalid out asset")
568574 else {
569575 let resultAssetId = if ((outAssetId == amId))
570576 then amId
571577 else prId
572- let resultAmtAmount = if ((outAssetId == amId))
573- then outAmount
574- else 0
575- let resultPrAmount = if ((outAssetId == prId))
576- then outAmount
577- else 0
578578 let pmt = value(i.payments[0])
579579 let userAddress = i.caller
580580 let txId58 = toBase58String(i.transactionId)
581581 let pmtAssetId = value(pmt.assetId)
582582 let pmtAmt = pmt.amount
583583 if ((lpId != toBase58String(pmtAssetId)))
584- then throw("Invalid asset passed.")
584+ then throw("Invalid LP")
585585 else {
586- let amAssetSwapX18 = toX18(amAssetSwap, amDcm)
587- let prAssetSwapX18 = toX18(prAssetSwap, prDcm)
588- let swapPriceX18 = calcPriceBigInt(prAssetSwapX18, amAssetSwapX18)
589586 let r = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
590- let outAmAmt = r._1
591- let outPrAmt = r._2
592- let totalR = if ((outAssetId == amId))
593- then {
594- let amtAsRes = fromX18(fraction(toX18(outPrAmt, prDcm), scale18, swapPriceX18), amDcm)
595- (amtAsRes + outAmAmt)
596- }
597- else {
598- let amSwopPartInPriceAsset = (resultPrAmount - outPrAmt)
599- let convRes = fraction(toX18(amSwopPartInPriceAsset, amDcm), scale18, swapPriceX18)
600- let prAsRes = fromX18(fraction(toX18(outAmAmt, amDcm), swapPriceX18, scale18), prDcm)
601- let amAssetDiff = fraction((convRes - amAssetSwapX18), scale8BigInt, amAssetSwapX18)
602- (prAsRes + outPrAmt)
603- }
587+ let estimAmAmt = r._1
588+ let estimPrAmt = r._2
604589 let amBalance = getAccBalance(amId)
605590 let amBalanceX18 = toX18(amBalance, amDcm)
606591 let prBalance = getAccBalance(prId)
607592 let prBalanceX18 = toX18(prBalance, prDcm)
593+ let invLeft = invoke(gwxCntr, "calcD", [toString(amBalance), toString(prBalance), "50", "100000000", "1"], nil)
594+ let resultTuple = if ((outAssetId == amId))
595+ then {
596+ let amAssetDiff = (outAmount - estimAmAmt)
597+ let invRight = invoke(gwxCntr, "calcD", [toString((amBalance + amAssetDiff)), toString((prBalance - prAssetSwap)), "50", "100000000", "1"], nil)
598+ if (!(calcAbsDiff(parseBigIntValue(asString(invRight)), parseBigIntValue(asString(invLeft)), toBigInt(1000))._1))
599+ then throw("D mismatch")
600+ else {
601+ let resultAmt = (estimAmAmt + amAssetSwap)
602+ let lpCalcRes = calcAbsDiff(toBigInt(resultAmt), toBigInt(outAmount), toBigInt(slippage))
603+ if (!(lpCalcRes._1))
604+ then throw(((("Too big slippage: " + toString(lpCalcRes._3)) + " vs ") + toString(slippage)))
605+ else $Tuple2(toInt(lpCalcRes._2), 0)
606+ }
607+ }
608+ else {
609+ let prAssetDiff = (outAmount - estimPrAmt)
610+ let invRight = invoke(gwxCntr, "calcD", [toString((amBalance - amAssetSwap)), toString((prBalance + prAssetDiff)), "50", "100000000", "1"], nil)
611+ if (!(calcAbsDiff(parseBigIntValue(asString(invRight)), parseBigIntValue(asString(invLeft)), toBigInt(1000))._1))
612+ then throw("D mismatch.")
613+ else {
614+ let resultAmt = (estimPrAmt + prAssetSwap)
615+ let lpCalcRes = calcAbsDiff(toBigInt(resultAmt), toBigInt(outAmount), toBigInt(slippage))
616+ if (!(lpCalcRes._1))
617+ then throw(((("Too big slippage: " + toString(lpCalcRes._3)) + " vs ") + toString(slippage)))
618+ else $Tuple2(0, toInt(lpCalcRes._2))
619+ }
620+ }
608621 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
609622 let curPrice = fromX18(curPriceX18, scale8)
610- let state = [ScriptTransfer(userAddress, totalR, if ((resultAssetId == "WAVES"))
623+ let state = [ScriptTransfer(userAddress, if ((resultAssetId == amId))
624+ then resultTuple._1
625+ else resultTuple._2, if ((resultAssetId == "WAVES"))
611626 then unit
612- 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)]
627+ else fromBase58String(resultAssetId)), StringEntry(keyGetActionByUser(toString(userAddress), txId58), dataGetActionInfo(resultTuple._1, resultTuple._2, pmtAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(keyPriceLast(), curPrice), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), curPrice)]
613628 let burn = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
614629 if ((burn == burn))
615630 then state
629644 let pmtAssetId = res._4
630645 let state = res._5
631646 if ((noLessThenAmtAsset > outAmAmt))
632- then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
647+ then throw(((("Failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
633648 else if ((noLessThenPriceAsset > outPrAmt))
634- then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
649+ then throw(((("Failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
635650 else {
636651 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
637652 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
645660 @Callable(i)
646661 func unstakeAndGet (amount) = {
647662 let checkPayments = if ((size(i.payments) != 0))
648- then throw("No payments are expected")
663+ then throw("No payments expected")
649664 else true
650665 if ((checkPayments == checkPayments))
651666 then {
652667 let cfg = getPoolConfig()
653668 let factoryCfg = getFactoryConfig()
654669 let lpAssetId = fromBase58String(cfg[idxLPAsId])
655- let stakingContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Error. Incorrect staking address.")
670+ let stakingContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wrong staking address.")
656671 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
657672 if ((unstakeInv == unstakeInv))
658673 then {
659- let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
660- let poolStatus = parseIntValue(res._9)
661- let state = res._10
674+ let r = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
675+ let poolStatus = parseIntValue(r._9)
676+ let state = r._10
662677 let checkPoolStatus = if (if (isGlobalShutdown())
663678 then true
664679 else (poolStatus == PoolShutdown))
665- then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
680+ then throw(("Blocked by admin: " + toString(poolStatus)))
666681 else true
667682 if ((checkPoolStatus == checkPoolStatus))
668683 then {
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 let idxFactGwxRewCntr = 10
5353
5454 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
5555
5656
5757 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
5858
5959
6060 func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
6161
6262
6363 func abs (val) = if ((zeroBigInt > val))
6464 then -(val)
6565 else val
6666
6767
6868 func keyFactCntr () = "%s__factoryContract"
6969
7070
7171 func keyManagerPublicKey () = "%s__managerPublicKey"
7272
7373
7474 func keyPriceLast () = "%s%s__price__last"
7575
7676
7777 func keyPriceHistory (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
7878
7979
8080 func keyPutActionByUser (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
8181
8282
8383 func keyGetActionByUser (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
8484
8585
8686 func keyAmtAsset () = "%s__amountAsset"
8787
8888
8989 func keyPriceAsset () = "%s__priceAsset"
9090
9191
9292 func keyFactoryConfig () = "%s__factoryConfig"
9393
9494
9595 func keyMatcherPub () = "%s%s__matcher__publicKey"
9696
9797
9898 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
9999
100100
101101 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
102102
103103
104104 func keyAllPoolsShutdown () = "%s__shutdown"
105105
106106
107107 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
108108
109109
110-func throwOrderError (orderValid,senderValid,matcherValid) = throw(((((("order validation failed: orderValid=" + toString(orderValid)) + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
110+func throwOrderError (orderValid,senderValid,matcherValid) = throw(((((("Validation failed: orderValid=" + toString(orderValid)) + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
111111
112112
113113 func asString (val) = match val {
114114 case valStr: String =>
115115 valStr
116116 case _ =>
117- throw("fail to cast into Int")
117+ throw("fail cast to String")
118118 }
119119
120120
121121 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
122122
123123
124124 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
125125
126126
127127 let factoryContract = addressFromStringValue(getStringOrFail(this, keyFactCntr()))
128128
129129 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
130130
131131
132132 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
133133
134134
135135 func getPoolConfig () = {
136136 let amtAs = getStringOrFail(this, keyAmtAsset())
137137 let priceAs = getStringOrFail(this, keyPriceAsset())
138138 let iPriceAs = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAs))
139139 let iAmtAs = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAs))
140140 split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAs), toString(iPriceAs))), SEP)
141141 }
142142
143143
144144 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
145145
146146
147147 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)
148148
149149
150150 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)
151151
152152
153153 func getAccBalance (assetId) = if ((assetId == "WAVES"))
154154 then wavesBalance(this).available
155155 else assetBalance(this, fromBase58String(assetId))
156156
157157
158158 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
159159
160160
161+func calcAbsDiff (realAmt,expectedAmt,slippage) = {
162+ let diff = fraction((realAmt - expectedAmt), scale8BigInt, expectedAmt)
163+ $Tuple3(((slippage - abs(diff)) > zeroBigInt), min([realAmt, expectedAmt]), diff)
164+ }
165+
166+
161167 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
162168 let amtAsAmtX18 = toX18(amAmt, amAssetDcm)
163169 let prAsAmtX18 = toX18(prAmt, prAssetDcm)
164170 calcPriceBigInt(prAsAmtX18, amtAsAmtX18)
165171 }
166172
167173
168174 func calcPrices (amAmt,prAmt,lpAmt) = {
169175 let cfg = getPoolConfig()
170176 let amtAsDcm = parseIntValue(cfg[idxAmtAsDcm])
171177 let prAsDcm = parseIntValue(cfg[idxPriceAsDcm])
172178 let priceX18 = privateCalcPrice(amtAsDcm, prAsDcm, amAmt, prAmt)
173179 let amAmtX18 = toX18(amAmt, amtAsDcm)
174180 let prAmtX18 = toX18(prAmt, prAsDcm)
175181 let lpAmtX18 = toX18(lpAmt, scale8)
176182 let lpPrInAmAsX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
177183 let lpPrInPrAsX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
178184 [priceX18, lpPrInAmAsX18, lpPrInPrAsX18]
179185 }
180186
181187
182188 func calculatePrices (amAmt,prAmt,lpAmt) = {
183189 let prices = calcPrices(amAmt, prAmt, lpAmt)
184190 [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
185191 }
186192
187193
188194 func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
189195 let cfg = getPoolConfig()
190196 let lpId = cfg[idxLPAsId]
191197 let amId = cfg[idxAmAsId]
192198 let prId = cfg[idxPrAsId]
193199 let amDcm = parseIntValue(cfg[idxAmtAsDcm])
194200 let prDcm = parseIntValue(cfg[idxPriceAsDcm])
195201 let poolStatus = cfg[idxPoolStatus]
196- let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpId)), (("Asset " + lpId) + " doesn't exist")).quantity
202+ let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpId)), "Invalid LP id").quantity
197203 if ((lpId != pmtAssetId))
198- then throw("Invalid asset passed.")
204+ then throw("Invalid pmt asset")
199205 else {
200206 let amBalance = getAccBalance(amId)
201207 let amBalanceX18 = toX18(amBalance, amDcm)
202208 let prBalance = getAccBalance(prId)
203209 let prBalanceX18 = toX18(prBalance, prDcm)
204210 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
205211 let curPrice = fromX18(curPriceX18, scale8)
206212 let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
207213 let lpEmissionX18 = toX18(lpEmission, scale8)
208214 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
209215 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
210216 let outAmAmt = fromX18(outAmAmtX18, amDcm)
211217 let outPrAmt = fromX18(outPrAmtX18, prDcm)
212218 let state = if ((txId58 == ""))
213219 then nil
214220 else [ScriptTransfer(userAddress, outAmAmt, if ((amId == "WAVES"))
215221 then unit
216222 else fromBase58String(amId)), ScriptTransfer(userAddress, outPrAmt, if ((prId == "WAVES"))
217223 then unit
218224 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)]
219225 $Tuple10(outAmAmt, outPrAmt, amId, prId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
220226 }
221227 }
222228
223229
224230 func estimatePutOperation (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEvaluate,emitLp) = {
225231 let cfg = getPoolConfig()
226232 let lpId = fromBase58String(cfg[idxLPAsId])
227233 let amIdStr = cfg[idxAmAsId]
228234 let prIdStr = cfg[idxPrAsId]
229235 let inAmIdStr = cfg[idxIAmtAsId]
230236 let inPrIdStr = cfg[idxIPriceAsId]
231237 let amtDcm = parseIntValue(cfg[idxAmtAsDcm])
232238 let priceDcm = parseIntValue(cfg[idxPriceAsDcm])
233239 let poolStatus = cfg[idxPoolStatus]
234- let lpEmission = valueOrErrorMessage(assetInfo(lpId), "Wrong lp asset.").quantity
240+ let lpEmission = valueOrErrorMessage(assetInfo(lpId), "Wrong lp asset").quantity
235241 let amBalance = if (isEvaluate)
236242 then getAccBalance(amIdStr)
237243 else (getAccBalance(amIdStr) - inAmAmt)
238244 let prBalance = if (isEvaluate)
239245 then getAccBalance(prIdStr)
240246 else (getAccBalance(prIdStr) - inPrAmt)
241247 let inAmAssetAmtX18 = toX18(inAmAmt, amtDcm)
242248 let inPrAssetAmtX18 = toX18(inPrAmt, priceDcm)
243249 let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
244250 let amBalanceX18 = toX18(amBalance, amtDcm)
245251 let prBalanceX18 = toX18(prBalance, priceDcm)
246252 let res = if ((lpEmission == 0))
247253 then {
248254 let curPriceX18 = zeroBigInt
249255 let slippageX18 = zeroBigInt
250256 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
251257 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtDcm), fromX18(inPrAssetAmtX18, priceDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
252258 }
253259 else {
254260 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
255261 let slippageRealX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
256262 let slippageX18 = toX18(slippage, scale8)
257263 if (if ((curPriceX18 != zeroBigInt))
258264 then (slippageRealX18 > slippageX18)
259265 else false)
260266 then throw(((("Price slippage " + toString(slippageRealX18)) + " exceeded ") + toString(slippageX18)))
261267 else {
262268 let lpEmissionX18 = toX18(lpEmission, scale8)
263269 let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
264270 let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
265271 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
266272 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
267273 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
268274 let expAmtAssetAmtX18 = expectedAmts._1
269275 let expPriceAssetAmtX18 = expectedAmts._2
270276 let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
271277 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(expAmtAssetAmtX18, amtDcm), fromX18(expPriceAssetAmtX18, priceDcm), curPriceX18, slippageX18)
272278 }
273279 }
274280 let calcLpAmt = res._1
275281 let calcAmAssetPmt = res._2
276282 let calcPrAssetPmt = res._3
277283 let curPrice = fromX18(res._4, scale8)
278284 let slippageCalc = fromX18(res._5, scale8)
279285 if ((0 >= calcLpAmt))
280- then throw("LP is less than zero.")
286+ then throw("LP < 0")
281287 else {
282288 let emitLpAmt = if (!(emitLp))
283289 then 0
284290 else calcLpAmt
285291 let amDiff = (inAmAmt - calcAmAssetPmt)
286292 let prDiff = (inPrAmt - calcPrAssetPmt)
287293 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))]
288294 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpId, poolStatus, commonState, amDiff, prDiff, inAmId, inPrId)
289295 }
290296 }
291297
292298
293299 func validateMatcherOrderAllowed (order) = {
294300 let cfg = getPoolConfig()
295- let amtAssetId = cfg[idxAmAsId]
296- let priceAssetId = cfg[idxPrAsId]
301+ let amtAsId = cfg[idxAmAsId]
302+ let prAsId = cfg[idxPrAsId]
297303 let poolStatus = parseIntValue(cfg[idxPoolStatus])
298- let amtAssetDcm = parseIntValue(cfg[idxAmtAsDcm])
299- let priceAssetDcm = parseIntValue(cfg[idxPriceAsDcm])
300- let accAmtAssetBalance = getAccBalance(amtAssetId)
301- let accPriceAssetBalance = getAccBalance(priceAssetId)
304+ let amtAsDcm = parseIntValue(cfg[idxAmtAsDcm])
305+ let prAsDcm = parseIntValue(cfg[idxPriceAsDcm])
306+ let accAmtAsBalance = getAccBalance(amtAsId)
307+ let accPrAsBalance = getAccBalance(prAsId)
302308 let curPriceX18 = if ((order.orderType == Buy))
303- then privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
304- else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance - order.amount), accPriceAssetBalance)
309+ then privateCalcPrice(amtAsDcm, prAsDcm, (accAmtAsBalance + order.amount), accPrAsBalance)
310+ else privateCalcPrice(amtAsDcm, prAsDcm, (accAmtAsBalance - order.amount), accPrAsBalance)
305311 let curPrice = fromX18(curPriceX18, scale8)
306312 if (if (if (isGlobalShutdown())
307313 then true
308314 else (poolStatus == PoolMatcherDisabled))
309315 then true
310316 else (poolStatus == PoolShutdown))
311- then throw("Exchange operations disabled")
317+ then throw("Blocked by admin")
312318 else {
313- let orderAmtAsset = order.assetPair.amountAsset
314- let orderAmtAssetStr = if ((orderAmtAsset == unit))
319+ let orAmtAsset = order.assetPair.amountAsset
320+ let orAmtAsStr = if ((orAmtAsset == unit))
315321 then "WAVES"
316- else toBase58String(value(orderAmtAsset))
317- let orderPriceAsset = order.assetPair.priceAsset
318- let orderPriceAssetStr = if ((orderPriceAsset == unit))
322+ else toBase58String(value(orAmtAsset))
323+ let orPrAsset = order.assetPair.priceAsset
324+ let orPrAsStr = if ((orPrAsset == unit))
319325 then "WAVES"
320- else toBase58String(value(orderPriceAsset))
321- if (if ((orderAmtAssetStr != amtAssetId))
326+ else toBase58String(value(orPrAsset))
327+ if (if ((orAmtAsStr != amtAsId))
322328 then true
323- else (orderPriceAssetStr != priceAssetId))
324- then throw("Wrong order assets.")
329+ else (orPrAsStr != prAsId))
330+ then throw("Wrong order assets")
325331 else {
326332 let orderPrice = order.price
327- let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
328- let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
333+ let priceDcm = fraction(scale8, prAsDcm, amtAsDcm)
334+ let castOrderPrice = toScale(orderPrice, scale8, priceDcm)
329335 let isOrderPriceValid = if ((order.orderType == Buy))
330- then (curPrice >= castedOrderPrice)
331- else (castedOrderPrice >= curPrice)
336+ then (curPrice >= castOrderPrice)
337+ else (castOrderPrice >= curPrice)
332338 true
333339 }
334340 }
335341 }
336342
337343
338344 func commonGet (i) = if ((size(i.payments) != 1))
339- then throw("exactly 1 payment is expected")
345+ then throw("1 payment expected")
340346 else {
341347 let pmt = value(i.payments[0])
342348 let pmtAssetId = value(pmt.assetId)
343349 let pmtAmt = pmt.amount
344350 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
345351 let outAmAmt = res._1
346352 let outPrAmt = res._2
347353 let poolStatus = parseIntValue(res._9)
348354 let state = res._10
349355 if (if (isGlobalShutdown())
350356 then true
351357 else (poolStatus == PoolShutdown))
352- then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
358+ then throw(("Blocked by admin: " + toString(poolStatus)))
353359 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
354360 }
355361
356362
357363 func commonPut (caller,txId,amAsPmt,prAsPmt,slippage,emitLp) = {
358- let estPut = estimatePutOperation(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, false, emitLp)
359- let status = parseIntValue(estPut._8)
364+ let r = estimatePutOperation(txId, slippage, value(amAsPmt).amount, value(amAsPmt).assetId, value(prAsPmt).amount, value(prAsPmt).assetId, caller, false, emitLp)
365+ let status = parseIntValue(r._8)
360366 if (if (if (isGlobalShutdown())
361367 then true
362368 else (status == PoolPutDisabled))
363369 then true
364370 else (status == PoolShutdown))
365- then throw(("Put operation is blocked by admin. Status = " + toString(status)))
366- else estPut
371+ then throw(("Blocked by admin: " + toString(status)))
372+ else r
367373 }
368374
369375
370376 @Callable(i)
371377 func constructor (factoryContract,managerPublicKey) = if ((i.caller != this))
372378 then throw("permissions denied")
373379 else [StringEntry(keyFactCntr(), factoryContract), StringEntry(keyManagerPublicKey(), managerPublicKey)]
374380
375381
376382
377383 @Callable(i)
378384 func put (slip,autoStake) = {
379385 let factCfg = getFactoryConfig()
380- let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Incorrect staking address.")
381- let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Incorrect slippage address.")
386+ let stakingCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Incorrect staking addr")
387+ let slipCntr = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Incorrect slippage addr")
382388 if ((0 > slip))
383389 then throw("Invalid slippage.")
384390 else if ((size(i.payments) != 2))
385- then throw("2 payments are expected")
391+ then throw("2 payments expected")
386392 else {
387393 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)
388394 let emitLpAmt = estPut._2
389395 let lpAssetId = estPut._7
390396 let state = estPut._9
391397 let amDiff = estPut._10
392398 let prDiff = estPut._11
393399 let amId = estPut._12
394400 let prId = estPut._13
395401 let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
396402 if ((emitInv == emitInv))
397403 then {
398404 let slippageAInv = if ((amDiff > 0))
399405 then invoke(slipCntr, "put", nil, [AttachedPayment(amId, amDiff)])
400406 else nil
401407 if ((slippageAInv == slippageAInv))
402408 then {
403409 let slippagePInv = if ((prDiff > 0))
404410 then invoke(slipCntr, "put", nil, [AttachedPayment(prId, prDiff)])
405411 else nil
406412 if ((slippagePInv == slippagePInv))
407413 then {
408414 let lpTrnsfr = if (autoStake)
409415 then {
410416 let slpStakeInv = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
411417 if ((slpStakeInv == slpStakeInv))
412418 then nil
413419 else throw("Strict value is not equal to itself.")
414420 }
415421 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
416422 (state ++ lpTrnsfr)
417423 }
418424 else throw("Strict value is not equal to itself.")
419425 }
420426 else throw("Strict value is not equal to itself.")
421427 }
422428 else throw("Strict value is not equal to itself.")
423429 }
424430 }
425431
426432
427433
428434 @Callable(i)
429-func putOneTkn (inAmtAmount,inPrAmount,autoStake) = {
435+func putOneTkn (inAmtAmount,inPrAmount,outLp,slippage,autoStake) = {
430436 let cfg = getFactoryConfig()
431- let stakingCntr = valueOrErrorMessage(addressFromString(cfg[idxFactStakCntr]), "Wrong staking address")
432- let slipCntr = valueOrErrorMessage(addressFromString(cfg[idxFactSlippCntr]), "Wrong slippage address")
433- let gwxCntr = valueOrErrorMessage(addressFromString(cfg[idxFactGwxRewCntr]), "Wrong slippage address")
437+ let stakingCntr = valueOrErrorMessage(addressFromString(cfg[idxFactStakCntr]), "Wrong staking addr")
438+ let slipCntr = valueOrErrorMessage(addressFromString(cfg[idxFactSlippCntr]), "Wrong slippage addr")
439+ let gwxCntr = valueOrErrorMessage(addressFromString(cfg[idxFactGwxRewCntr]), "Wrong slippage addr")
434440 let poolCfg = getPoolConfig()
435441 let amId = poolCfg[idxAmAsId]
436442 let prId = poolCfg[idxPrAsId]
437443 let amDcm = parseIntValue(poolCfg[idxAmtAsDcm])
438444 let prDcm = parseIntValue(poolCfg[idxPriceAsDcm])
439445 if ((size(i.payments) != 1))
440- then throw("exactly 1 payment is expected")
446+ then throw("1 payment expected")
441447 else {
442448 let pmt = value(i.payments[0])
443449 let pmtAssetId = toBase58String(value(pmt.assetId))
444450 let pmtAmt = pmt.amount
445451 let amAssetSwapX18 = toX18(inAmtAmount, amDcm)
446452 let prAssetSwapX18 = toX18(inPrAmount, prDcm)
447453 let amBalance = getAccBalance(amId)
448454 let amBalanceX18 = toX18(amBalance, amDcm)
449455 let prBalance = getAccBalance(prId)
450456 let prBalanceX18 = toX18(prBalance, prDcm)
451457 let amBalanceNow = if ((pmtAssetId == amId))
452458 then (amBalance - pmtAmt)
453459 else amBalance
454460 let prBalanceNow = if ((pmtAssetId == prId))
455461 then (prBalance - pmtAmt)
456462 else prBalance
457463 let dCur = invoke(gwxCntr, "calcD", [toString(amBalanceNow), toString(prBalanceNow), "50", "100000000", "1"], nil)
458464 let invLeft = parseBigIntValue(asString(dCur))
459- let isValid = if ((pmtAssetId == amId))
465+ let invRight = if ((pmtAssetId == amId))
460466 then {
461467 let pmtAmtX18 = toX18(pmtAmt, amDcm)
462468 let prAdiff = prAssetSwapX18
463469 let amAdiff = (pmtAmtX18 - amAssetSwapX18)
464470 let dSwap = invoke(gwxCntr, "calcD", [toString((toBigInt(amBalanceNow) + toBigInt(fromX18(amAdiff, amDcm)))), toString((toBigInt(prBalanceNow) - toBigInt(fromX18(prAdiff, prDcm)))), "50", "100000000", "1"], nil)
465- let invRight = parseBigIntValue(asString(dSwap))
466- let invDiff = abs(fraction((invRight - invLeft), scale8BigInt, invLeft))
467- if ((invDiff > toBigInt(1000)))
468- then throw("Wrong arguments passed. D decreased.")
469- else true
471+ parseBigIntValue(asString(dSwap))
470472 }
471473 else {
472474 let pmtPrX18 = toX18(pmtAmt, prDcm)
473475 let prAdiff = (pmtPrX18 - prAssetSwapX18)
474476 let amAdiff = amAssetSwapX18
475477 let dSwap = invoke(gwxCntr, "calcD", [toString((toBigInt(amBalanceNow) - toBigInt(fromX18(amAdiff, amDcm)))), toString((toBigInt(prBalanceNow) + toBigInt(fromX18(prAdiff, prDcm)))), "50", "100000000", "1"], nil)
476- let invRight = parseBigIntValue(asString(dSwap))
477- let invDiff = abs(fraction((invRight - invLeft), scale8BigInt, invLeft))
478- if ((invDiff > toBigInt(1000)))
479- then throw("Wrong arguments passed. D decreased.")
480- else true
478+ parseBigIntValue(asString(dSwap))
481479 }
482- if (!(isValid))
483- then throw("Errors.")
480+ if (!(calcAbsDiff(invRight, invLeft, toBigInt(1000))._1))
481+ then throw("D mismatch.")
484482 else {
485483 let estPut = commonPut(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amId), inAmtAmount), AttachedPayment(fromBase58String(prId), inPrAmount), 50000000000, true)
486- let emitLpAmt = estPut._2
484+ let estimLP = estPut._2
487485 let lpAssetId = estPut._7
488486 let state = estPut._9
489487 let amDiff = estPut._10
490488 let prDiff = estPut._11
491- let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
492- if ((emitInv == emitInv))
493- then {
494- let slippageAInv = if ((amDiff > 0))
495- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(amId), amDiff)])
496- else nil
497- if ((slippageAInv == slippageAInv))
489+ let lpCalcRes = calcAbsDiff(toBigInt(estimLP), toBigInt(outLp), toBigInt(slippage))
490+ if (!(lpCalcRes._1))
491+ then throw(((("Too big slippage: " + toString(lpCalcRes._3)) + " vs ") + toString(slippage)))
492+ else {
493+ let emitLpAmt = toInt(lpCalcRes._2)
494+ let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
495+ if ((emitInv == emitInv))
498496 then {
499- let slippagePInv = if ((prDiff > 0))
500- then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(prId), prDiff)])
497+ let slippageAInv = if ((amDiff > 0))
498+ then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(amId), amDiff)])
501499 else nil
502- if ((slippagePInv == slippagePInv))
500+ if ((slippageAInv == slippageAInv))
503501 then {
504- let lpTrnsfr = if (autoStake)
502+ let slippagePInv = if ((prDiff > 0))
503+ then invoke(slipCntr, "put", nil, [AttachedPayment(fromBase58String(prId), prDiff)])
504+ else nil
505+ if ((slippagePInv == slippagePInv))
505506 then {
506- let slpStakeInv = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
507- if ((slpStakeInv == slpStakeInv))
508- then nil
509- else throw("Strict value is not equal to itself.")
507+ let lpTrnsfr = if (autoStake)
508+ then {
509+ let slpStakeInv = invoke(stakingCntr, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
510+ if ((slpStakeInv == slpStakeInv))
511+ then nil
512+ else throw("Strict value is not equal to itself.")
513+ }
514+ else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
515+ (state ++ lpTrnsfr)
510516 }
511- else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
512- (state ++ lpTrnsfr)
517+ else throw("Strict value is not equal to itself.")
513518 }
514519 else throw("Strict value is not equal to itself.")
515520 }
516521 else throw("Strict value is not equal to itself.")
517522 }
518- else throw("Strict value is not equal to itself.")
519523 }
520524 }
521525 }
522526
523527
524528
525529 @Callable(i)
526530 func putForFree (maxSlippage) = if ((0 > maxSlippage))
527- then throw("Invalid value passed")
531+ then throw("Invalid slippage")
528532 else if ((size(i.payments) != 2))
529- then throw("exactly 2 payments are expected")
533+ then throw("2 payments expected")
530534 else {
531535 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)
532536 estPut._9
533537 }
534538
535539
536540
537541 @Callable(i)
538542 func get () = {
539543 let res = commonGet(i)
540544 let outAmtAmt = res._1
541545 let outPrAmt = res._2
542546 let pmtAmt = res._3
543547 let pmtAssetId = res._4
544548 let state = res._5
545549 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
546550 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
547551 then state
548552 else throw("Strict value is not equal to itself.")
549553 }
550554
551555
552556
553557 @Callable(i)
554-func getOneTkn (amAssetSwap,prAssetSwap,outAmount,outAssetId) = if ((size(i.payments) != 1))
555- then throw("exactly 1 payment is expected")
558+func getOneTkn (amAssetSwap,prAssetSwap,outAmount,outAssetId,slippage) = if ((size(i.payments) != 1))
559+ then throw("1 payment expected")
556560 else {
557561 let cfg = getPoolConfig()
558562 let lpId = cfg[idxLPAsId]
559563 let amId = cfg[idxAmAsId]
560564 let prId = cfg[idxPrAsId]
561565 let amDcm = parseIntValue(cfg[idxAmtAsDcm])
562566 let prDcm = parseIntValue(cfg[idxPriceAsDcm])
563567 let poolStatus = cfg[idxPoolStatus]
568+ let fcfg = getFactoryConfig()
569+ let gwxCntr = valueOrErrorMessage(addressFromString(fcfg[idxFactGwxRewCntr]), "Wrong slippage address")
564570 if (if ((outAssetId != amId))
565571 then (outAssetId != prId)
566572 else false)
567- then throw(("Incorrect out asset id passed: " + outAssetId))
573+ then throw("Invalid out asset")
568574 else {
569575 let resultAssetId = if ((outAssetId == amId))
570576 then amId
571577 else prId
572- let resultAmtAmount = if ((outAssetId == amId))
573- then outAmount
574- else 0
575- let resultPrAmount = if ((outAssetId == prId))
576- then outAmount
577- else 0
578578 let pmt = value(i.payments[0])
579579 let userAddress = i.caller
580580 let txId58 = toBase58String(i.transactionId)
581581 let pmtAssetId = value(pmt.assetId)
582582 let pmtAmt = pmt.amount
583583 if ((lpId != toBase58String(pmtAssetId)))
584- then throw("Invalid asset passed.")
584+ then throw("Invalid LP")
585585 else {
586- let amAssetSwapX18 = toX18(amAssetSwap, amDcm)
587- let prAssetSwapX18 = toX18(prAssetSwap, prDcm)
588- let swapPriceX18 = calcPriceBigInt(prAssetSwapX18, amAssetSwapX18)
589586 let r = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
590- let outAmAmt = r._1
591- let outPrAmt = r._2
592- let totalR = if ((outAssetId == amId))
593- then {
594- let amtAsRes = fromX18(fraction(toX18(outPrAmt, prDcm), scale18, swapPriceX18), amDcm)
595- (amtAsRes + outAmAmt)
596- }
597- else {
598- let amSwopPartInPriceAsset = (resultPrAmount - outPrAmt)
599- let convRes = fraction(toX18(amSwopPartInPriceAsset, amDcm), scale18, swapPriceX18)
600- let prAsRes = fromX18(fraction(toX18(outAmAmt, amDcm), swapPriceX18, scale18), prDcm)
601- let amAssetDiff = fraction((convRes - amAssetSwapX18), scale8BigInt, amAssetSwapX18)
602- (prAsRes + outPrAmt)
603- }
587+ let estimAmAmt = r._1
588+ let estimPrAmt = r._2
604589 let amBalance = getAccBalance(amId)
605590 let amBalanceX18 = toX18(amBalance, amDcm)
606591 let prBalance = getAccBalance(prId)
607592 let prBalanceX18 = toX18(prBalance, prDcm)
593+ let invLeft = invoke(gwxCntr, "calcD", [toString(amBalance), toString(prBalance), "50", "100000000", "1"], nil)
594+ let resultTuple = if ((outAssetId == amId))
595+ then {
596+ let amAssetDiff = (outAmount - estimAmAmt)
597+ let invRight = invoke(gwxCntr, "calcD", [toString((amBalance + amAssetDiff)), toString((prBalance - prAssetSwap)), "50", "100000000", "1"], nil)
598+ if (!(calcAbsDiff(parseBigIntValue(asString(invRight)), parseBigIntValue(asString(invLeft)), toBigInt(1000))._1))
599+ then throw("D mismatch")
600+ else {
601+ let resultAmt = (estimAmAmt + amAssetSwap)
602+ let lpCalcRes = calcAbsDiff(toBigInt(resultAmt), toBigInt(outAmount), toBigInt(slippage))
603+ if (!(lpCalcRes._1))
604+ then throw(((("Too big slippage: " + toString(lpCalcRes._3)) + " vs ") + toString(slippage)))
605+ else $Tuple2(toInt(lpCalcRes._2), 0)
606+ }
607+ }
608+ else {
609+ let prAssetDiff = (outAmount - estimPrAmt)
610+ let invRight = invoke(gwxCntr, "calcD", [toString((amBalance - amAssetSwap)), toString((prBalance + prAssetDiff)), "50", "100000000", "1"], nil)
611+ if (!(calcAbsDiff(parseBigIntValue(asString(invRight)), parseBigIntValue(asString(invLeft)), toBigInt(1000))._1))
612+ then throw("D mismatch.")
613+ else {
614+ let resultAmt = (estimPrAmt + prAssetSwap)
615+ let lpCalcRes = calcAbsDiff(toBigInt(resultAmt), toBigInt(outAmount), toBigInt(slippage))
616+ if (!(lpCalcRes._1))
617+ then throw(((("Too big slippage: " + toString(lpCalcRes._3)) + " vs ") + toString(slippage)))
618+ else $Tuple2(0, toInt(lpCalcRes._2))
619+ }
620+ }
608621 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
609622 let curPrice = fromX18(curPriceX18, scale8)
610- let state = [ScriptTransfer(userAddress, totalR, if ((resultAssetId == "WAVES"))
623+ let state = [ScriptTransfer(userAddress, if ((resultAssetId == amId))
624+ then resultTuple._1
625+ else resultTuple._2, if ((resultAssetId == "WAVES"))
611626 then unit
612- 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)]
627+ else fromBase58String(resultAssetId)), StringEntry(keyGetActionByUser(toString(userAddress), txId58), dataGetActionInfo(resultTuple._1, resultTuple._2, pmtAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(keyPriceLast(), curPrice), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), curPrice)]
613628 let burn = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
614629 if ((burn == burn))
615630 then state
616631 else throw("Strict value is not equal to itself.")
617632 }
618633 }
619634 }
620635
621636
622637
623638 @Callable(i)
624639 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
625640 let res = commonGet(i)
626641 let outAmAmt = res._1
627642 let outPrAmt = res._2
628643 let pmtAmt = res._3
629644 let pmtAssetId = res._4
630645 let state = res._5
631646 if ((noLessThenAmtAsset > outAmAmt))
632- then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
647+ then throw(((("Failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
633648 else if ((noLessThenPriceAsset > outPrAmt))
634- then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
649+ then throw(((("Failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
635650 else {
636651 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
637652 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
638653 then state
639654 else throw("Strict value is not equal to itself.")
640655 }
641656 }
642657
643658
644659
645660 @Callable(i)
646661 func unstakeAndGet (amount) = {
647662 let checkPayments = if ((size(i.payments) != 0))
648- then throw("No payments are expected")
663+ then throw("No payments expected")
649664 else true
650665 if ((checkPayments == checkPayments))
651666 then {
652667 let cfg = getPoolConfig()
653668 let factoryCfg = getFactoryConfig()
654669 let lpAssetId = fromBase58String(cfg[idxLPAsId])
655- let stakingContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Error. Incorrect staking address.")
670+ let stakingContract = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wrong staking address.")
656671 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
657672 if ((unstakeInv == unstakeInv))
658673 then {
659- let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
660- let poolStatus = parseIntValue(res._9)
661- let state = res._10
674+ let r = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
675+ let poolStatus = parseIntValue(r._9)
676+ let state = r._10
662677 let checkPoolStatus = if (if (isGlobalShutdown())
663678 then true
664679 else (poolStatus == PoolShutdown))
665- then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
680+ then throw(("Blocked by admin: " + toString(poolStatus)))
666681 else true
667682 if ((checkPoolStatus == checkPoolStatus))
668683 then {
669684 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
670685 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
671686 then state
672687 else throw("Strict value is not equal to itself.")
673688 }
674689 else throw("Strict value is not equal to itself.")
675690 }
676691 else throw("Strict value is not equal to itself.")
677692 }
678693 else throw("Strict value is not equal to itself.")
679694 }
680695
681696
682697
683698 @Callable(i)
684699 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
685700 then throw("permissions denied")
686701 else $Tuple2([StringEntry(keyAmtAsset(), amtAssetStr), StringEntry(keyPriceAsset(), priceAssetStr)], "success")
687702
688703
689704
690705 @Callable(i)
691706 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
692707
693708
694709
695710 @Callable(i)
696711 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
697712
698713
699714
700715 @Callable(i)
701716 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
702717 let prices = calcPrices(amAmt, prAmt, lpAmt)
703718 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
704719 }
705720
706721
707722
708723 @Callable(i)
709724 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
710725
711726
712727
713728 @Callable(i)
714729 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
715730
716731
717732
718733 @Callable(i)
719734 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
720735
721736
722737
723738 @Callable(i)
724739 func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmAmt,inAmId,inPrAmt,inPrId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippage, inAmAmt, inAmId, inPrAmt, inPrId, userAddress, isEvaluate, emitLp))
725740
726741
727742
728743 @Callable(i)
729744 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
730745 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
731746 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
732747 }
733748
734749
735750 @Verifier(tx)
736751 func verify () = match tx {
737752 case order: Order =>
738753 let matcherPub = getMatcherPubOrFail()
739754 let orderValid = validateMatcherOrderAllowed(order)
740755 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
741756 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
742757 if (if (if (orderValid)
743758 then senderValid
744759 else false)
745760 then matcherValid
746761 else false)
747762 then true
748763 else throwOrderError(orderValid, senderValid, matcherValid)
749764 case _ =>
750765 let managerPublic = valueOrElse(getString(this, keyManagerPublicKey()), EMPTY)
751766 if ((managerPublic == EMPTY))
752767 then sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
753768 else sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(managerPublic))
754769 }
755770

github/deemru/w8io/169f3d6 
155.17 ms