tx · 7M8JiRPJcoT4Gzw7gvDqQJQxkXMBaMzWHzHsJTQnGLZv

3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy:  -0.01000000 Waves

2021.12.09 18:20 [1826885] smart account 3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy > SELF 0.00000000 Waves

{ "type": 13, "id": "7M8JiRPJcoT4Gzw7gvDqQJQxkXMBaMzWHzHsJTQnGLZv", "fee": 1000000, "feeAssetId": null, "timestamp": 1639063246973, "version": 1, "sender": "3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy", "senderPublicKey": "9W33iCCNfmFxUbiC6XZcH5x7f6xfwC7Jb3BoExT5q2PV", "proofs": [ "5rRnXoRkhwJA936eUJeTP3c89qFwvPzEZp4vnHqSh72dz8aAao944yx1hc9cftEVx7mybfvFrm5KrzqNLeQBoda9" ], "script": "base64:AAIFAAAAAAAAACwIAhIICgYICAEBAQgSAwoBARIDCgEBEgQKAggIEgQKAggIEgMKAQgSAwoBCAAAAFYAAAAAA1NFUAIAAAACX18AAAAABlNDQUxFOAAAAAAAAAAACAAAAAAFTVVMVDgAAAAAAAX14QAAAAAADlBPT0xXRUlHSFRNVUxUBQAAAAVNVUxUOAEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAgAAAAdhZGRyZXNzAAAAA2tleQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAAB2FkZHJlc3MFAAAAA2tleQkAASwAAAACCQABLAAAAAICAAAAD21hbmRhdG9yeSB0aGlzLgUAAAADa2V5AgAAAA8gaXMgbm90IGRlZmluZWQBAAAADGdldEludE9yWmVybwAAAAIAAAAHYWRkcmVzcwAAAANrZXkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAHYWRkcmVzcwUAAAADa2V5AAAAAAAAAAAAAQAAAA9nZXRJbnRPckRlZmF1bHQAAAADAAAAB2FkZHJlc3MAAAADa2V5AAAACmRlZmF1bHRWYWwJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAHYWRkcmVzcwUAAAADa2V5BQAAAApkZWZhdWx0VmFsAQAAAAxnZXRJbnRPckZhaWwAAAACAAAAB2FkZHJlc3MAAAADa2V5CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAHYWRkcmVzcwUAAAADa2V5CQABLAAAAAIJAAEsAAAAAgIAAAAPbWFuZGF0b3J5IHRoaXMuBQAAAANrZXkCAAAADyBpcyBub3QgZGVmaW5lZAEAAAAJYXNBbnlMaXN0AAAAAQAAAAN2YWwEAAAAByRtYXRjaDAFAAAAA3ZhbAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAJTGlzdFtBbnldBAAAAAp2YWxBbnlMeXN0BQAAAAckbWF0Y2gwBQAAAAp2YWxBbnlMeXN0CQAAAgAAAAECAAAAG2ZhaWwgdG8gY2FzdCBpbnRvIExpc3RbQW55XQEAAAAFYXNJbnQAAAABAAAAA3ZhbAQAAAAHJG1hdGNoMAUAAAADdmFsAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAANJbnQEAAAABnZhbEludAUAAAAHJG1hdGNoMAUAAAAGdmFsSW50CQAAAgAAAAECAAAAFWZhaWwgdG8gY2FzdCBpbnRvIEludAEAAAARa2V5RmFjdG9yeUFkZHJlc3MAAAAAAgAAABwlcyVzX19jb25maWdfX2ZhY3RvcnlBZGRyZXNzAAAAABhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHAAAAAAAAAAAAEAAAAAGUlkeEZhY3RvcnlDZmdCb29zdGluZ0RhcHAAAAAAAAAAAAIAAAAAFElkeEZhY3RvcnlDZmdJZG9EYXBwAAAAAAAAAAADAAAAABVJZHhGYWN0b3J5Q2ZnVGVhbURhcHAAAAAAAAAAAAQAAAAAGUlkeEZhY3RvcnlDZmdFbWlzc2lvbkRhcHAAAAAAAAAAAAUAAAAAFUlkeEZhY3RvcnlDZmdSZXN0RGFwcAAAAAAAAAAABgAAAAAZSWR4RmFjdG9yeUNmZ1NsaXBwYWdlRGFwcAAAAAAAAAAABwEAAAANa2V5RmFjdG9yeUNmZwAAAAACAAAAESVzX19mYWN0b3J5Q29uZmlnAQAAABprZXlGYWN0b3J5THAyQXNzZXRzTWFwcGluZwAAAAEAAAAKbHBBc3NldFN0cgkABLkAAAACCQAETAAAAAICAAAABiVzJXMlcwkABEwAAAACBQAAAApscEFzc2V0U3RyCQAETAAAAAICAAAAHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUAAAADbmlsBQAAAANTRVABAAAAEGtleUZhY3RvcnlMcExpc3QAAAAAAgAAABAlc19fbHBUb2tlbnNMaXN0AQAAACZrZXlGYWN0b3J5THBBc3NldFRvUG9vbENvbnRyYWN0QWRkcmVzcwAAAAEAAAAKbHBBc3NldFN0cgkABLkAAAACCQAETAAAAAICAAAABiVzJXMlcwkABEwAAAACBQAAAApscEFzc2V0U3RyCQAETAAAAAICAAAAHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUAAAADbmlsBQAAAANTRVABAAAAFGtleUZhY3RvcnlQb29sV2VpZ2h0AAAAAQAAAA9jb250cmFjdEFkZHJlc3MJAAS5AAAAAgkABEwAAAACAgAAAAQlcyVzCQAETAAAAAICAAAACnBvb2xXZWlnaHQJAARMAAAAAgUAAAAPY29udHJhY3RBZGRyZXNzBQAAAANuaWwFAAAAA1NFUAEAAAAYcmVhZEZhY3RvcnlBZGRyZXNzT3JGYWlsAAAAAAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAIFAAAABHRoaXMJAQAAABFrZXlGYWN0b3J5QWRkcmVzcwAAAAABAAAACnJlYWRMcExpc3QAAAAACQAEtQAAAAIJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgkBAAAAGHJlYWRGYWN0b3J5QWRkcmVzc09yRmFpbAAAAAAJAQAAABBrZXlGYWN0b3J5THBMaXN0AAAAAAIAAAAABQAAAANTRVABAAAAFHJlYWRGYWN0b3J5Q2ZnT3JGYWlsAAAAAQAAAAdmYWN0b3J5CQAEtQAAAAIJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAACBQAAAAdmYWN0b3J5CQEAAAANa2V5RmFjdG9yeUNmZwAAAAAFAAAAA1NFUAEAAAAYZ2V0Qm9vc3RpbmdBZGRyZXNzT3JGYWlsAAAAAQAAAApmYWN0b3J5Q2ZnCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQABkQAAAAIFAAAACmZhY3RvcnlDZmcFAAAAGUlkeEZhY3RvcnlDZmdCb29zdGluZ0RhcHABAAAAGGdldEVtaXNzaW9uQWRkcmVzc09yRmFpbAAAAAEAAAAKZmFjdG9yeUNmZwkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkAAZEAAAACBQAAAApmYWN0b3J5Q2ZnBQAAABlJZHhGYWN0b3J5Q2ZnRW1pc3Npb25EYXBwAQAAABdnZXRTdGFraW5nQWRkcmVzc09yRmFpbAAAAAEAAAAKZmFjdG9yeUNmZwkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkAAZEAAAACBQAAAApmYWN0b3J5Q2ZnBQAAABhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHABAAAAHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAAAAACAAAAGyVzJXNfX3JhdGVQZXJCbG9ja19fY3VycmVudAEAAAAha2V5RW1pc3Npb25SYXRlUGVyQmxvY2tNYXhDdXJyZW50AAAAAAIAAAAeJXMlc19fcmF0ZVBlckJsb2NrTWF4X19jdXJyZW50AQAAABVrZXlFbWlzc2lvblN0YXJ0QmxvY2sAAAAAAgAAABolcyVzX19lbWlzc2lvbl9fc3RhcnRCbG9jawEAAAAba2V5RW1pc3Npb25EdXJhdGlvbkluQmxvY2tzAAAAAAIAAAAYJXMlc19fZW1pc3Npb25fX2R1cmF0aW9uAQAAABNrZXlFbWlzc2lvbkVuZEJsb2NrAAAAAAIAAAAYJXMlc19fZW1pc3Npb25fX2VuZEJsb2NrAQAAAA1rZXlOZXh0UGVyaW9kAAAAAAIAAAAOJXNfX25leHRQZXJpb2QAAAAADUlkeENmZ0Fzc2V0SWQAAAAAAAAAAAEAAAAAE0lkeENmZ01pbkxvY2tBbW91bnQAAAAAAAAAAAIAAAAAFUlkeENmZ01pbkxvY2tEdXJhdGlvbgAAAAAAAAAAAwAAAAAVSWR4Q2ZnTWF4TG9ja0R1cmF0aW9uAAAAAAAAAAAEAAAAABJJZHhDZmdNYXRoQ29udHJhY3QAAAAAAAAAAAUBAAAACWtleUNvbmZpZwAAAAACAAAACiVzX19jb25maWcBAAAAFXJlYWRDb25maWdBcnJheU9yRmFpbAAAAAAJAAS1AAAAAgkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAIFAAAABHRoaXMJAQAAAAlrZXlDb25maWcAAAAABQAAAANTRVABAAAADWZvcm1hdENvbmZpZ1MAAAAFAAAAB2Fzc2V0SWQAAAANbWluTG9ja0Ftb3VudAAAAA9taW5Mb2NrRHVyYXRpb24AAAAPbWF4TG9ja0R1cmF0aW9uAAAADG1hdGhDb250cmFjdAkABLkAAAACCQAETAAAAAICAAAACCVzJWQlZCVkCQAETAAAAAIFAAAAB2Fzc2V0SWQJAARMAAAAAgUAAAANbWluTG9ja0Ftb3VudAkABEwAAAACBQAAAA9taW5Mb2NrRHVyYXRpb24JAARMAAAAAgUAAAAPbWF4TG9ja0R1cmF0aW9uCQAETAAAAAIFAAAADG1hdGhDb250cmFjdAUAAAADbmlsBQAAAANTRVABAAAADGZvcm1hdENvbmZpZwAAAAUAAAAHYXNzZXRJZAAAAA1taW5Mb2NrQW1vdW50AAAAD21pbkxvY2tEdXJhdGlvbgAAAA9tYXhMb2NrRHVyYXRpb24AAAAMbWF0aENvbnRyYWN0CQEAAAANZm9ybWF0Q29uZmlnUwAAAAUFAAAAB2Fzc2V0SWQJAAGkAAAAAQUAAAANbWluTG9ja0Ftb3VudAkAAaQAAAABBQAAAA9taW5Mb2NrRHVyYXRpb24JAAGkAAAAAQUAAAAPbWF4TG9ja0R1cmF0aW9uBQAAAAxtYXRoQ29udHJhY3QAAAAADklkeExvY2tVc2VyTnVtAAAAAAAAAAABAAAAAA1JZHhMb2NrQW1vdW50AAAAAAAAAAACAAAAAAxJZHhMb2NrU3RhcnQAAAAAAAAAAAMAAAAAD0lkeExvY2tEdXJhdGlvbgAAAAAAAAAABAAAAAANSWR4TG9ja1BhcmFtSwAAAAAAAAAABQAAAAANSWR4TG9ja1BhcmFtQgAAAAAAAAAABgEAAAATa2V5TG9ja1BhcmFtc1JlY29yZAAAAAEAAAALdXNlckFkZHJlc3MJAAS5AAAAAgkABEwAAAACAgAAAAolcyVzX19sb2NrCQAETAAAAAIFAAAAC3VzZXJBZGRyZXNzBQAAAANuaWwFAAAAA1NFUAEAAAAacmVhZExvY2tQYXJhbXNSZWNvcmRPckZhaWwAAAABAAAAC3VzZXJBZGRyZXNzCQAEtQAAAAIJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAACBQAAAAR0aGlzCQEAAAATa2V5TG9ja1BhcmFtc1JlY29yZAAAAAEFAAAAC3VzZXJBZGRyZXNzBQAAAANTRVABAAAAF2Zvcm1hdExvY2tQYXJhbXNSZWNvcmRTAAAACAAAAAd1c2VyTnVtAAAABmFtb3VudAAAAAVzdGFydAAAAAhkdXJhdGlvbgAAAAZwYXJhbUsAAAAGcGFyYW1CAAAAEGxhc3RVcGRUaW1lc3RhbXAAAAAJZ3d4QW1vdW50CQAEuQAAAAIJAARMAAAAAgIAAAAQJWQlZCVkJWQlZCVkJWQlZAkABEwAAAACBQAAAAd1c2VyTnVtCQAETAAAAAIFAAAABmFtb3VudAkABEwAAAACBQAAAAVzdGFydAkABEwAAAACBQAAAAhkdXJhdGlvbgkABEwAAAACBQAAAAZwYXJhbUsJAARMAAAAAgUAAAAGcGFyYW1CCQAETAAAAAIFAAAAEGxhc3RVcGRUaW1lc3RhbXAJAARMAAAAAgUAAAAJZ3d4QW1vdW50BQAAAANuaWwFAAAAA1NFUAEAAAAWZm9ybWF0TG9ja1BhcmFtc1JlY29yZAAAAAcAAAAHdXNlck51bQAAAAZhbW91bnQAAAAFc3RhcnQAAAAIZHVyYXRpb24AAAAGcGFyYW1LAAAABnBhcmFtQgAAAAlnd3hBbW91bnQJAQAAABdmb3JtYXRMb2NrUGFyYW1zUmVjb3JkUwAAAAgFAAAAB3VzZXJOdW0JAAGkAAAAAQUAAAAGYW1vdW50CQABpAAAAAEFAAAABXN0YXJ0CQABpAAAAAEFAAAACGR1cmF0aW9uCQABpAAAAAEFAAAABnBhcmFtSwkAAaQAAAABBQAAAAZwYXJhbUIJAAGkAAAAAQgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXAJAAGkAAAAAQUAAAAJZ3d4QW1vdW50AQAAAA5rZXlOZXh0VXNlck51bQAAAAACAAAADyVzX19uZXh0VXNlck51bQEAAAASa2V5VXNlcjJOdW1NYXBwaW5nAAAAAQAAAAt1c2VyQWRkcmVzcwkABLkAAAACCQAETAAAAAICAAAAGSVzJXMlc19fbWFwcGluZ19fdXNlcjJudW0JAARMAAAAAgUAAAALdXNlckFkZHJlc3MFAAAAA25pbAUAAAADU0VQAQAAABJrZXlOdW0yVXNlck1hcHBpbmcAAAABAAAAA251bQkABLkAAAACCQAETAAAAAICAAAAGSVzJXMlc19fbWFwcGluZ19fbnVtMnVzZXIJAARMAAAAAgUAAAADbnVtBQAAAANuaWwFAAAAA1NFUAEAAAAWa2V5TG9ja1BhcmFtVXNlckFtb3VudAAAAAEAAAAHdXNlck51bQkABLkAAAACCQAETAAAAAICAAAAFiVzJWQlc19fcGFyYW1CeVVzZXJOdW0JAARMAAAAAgUAAAAHdXNlck51bQkABEwAAAACAgAAAAZhbW91bnQFAAAAA25pbAUAAAADU0VQAQAAABZrZXlMb2NrUGFyYW1TdGFydEJsb2NrAAAAAQAAAAd1c2VyTnVtCQAEuQAAAAIJAARMAAAAAgIAAAAWJXMlZCVzX19wYXJhbUJ5VXNlck51bQkABEwAAAACBQAAAAd1c2VyTnVtCQAETAAAAAICAAAABXN0YXJ0BQAAAANuaWwFAAAAA1NFUAEAAAAUa2V5TG9ja1BhcmFtRHVyYXRpb24AAAABAAAAB3VzZXJOdW0JAAS5AAAAAgkABEwAAAACAgAAABYlcyVkJXNfX3BhcmFtQnlVc2VyTnVtCQAETAAAAAIFAAAAB3VzZXJOdW0JAARMAAAAAgIAAAAIZHVyYXRpb24FAAAAA25pbAUAAAADU0VQAQAAAA1rZXlMb2NrUGFyYW1LAAAAAQAAAAd1c2VyTnVtCQAEuQAAAAIJAARMAAAAAgIAAAAWJXMlZCVzX19wYXJhbUJ5VXNlck51bQkABEwAAAACBQAAAAd1c2VyTnVtCQAETAAAAAICAAAAAWsFAAAAA25pbAUAAAADU0VQAQAAAA1rZXlMb2NrUGFyYW1CAAAAAQAAAAd1c2VyTnVtCQAEuQAAAAIJAARMAAAAAgIAAAAWJXMlZCVzX19wYXJhbUJ5VXNlck51bQkABEwAAAACBQAAAAd1c2VyTnVtCQAETAAAAAICAAAAAWIFAAAAA25pbAUAAAADU0VQAQAAABVrZXlMb2NrUGFyYW1CeVBlcmlvZEsAAAACAAAAB3VzZXJOdW0AAAAGcGVyaW9kCQAEuQAAAAIJAARMAAAAAgIAAAAXJXMlZCVzJWRfX3BhcmFtQnlQZXJpb2QJAARMAAAAAgUAAAAHdXNlck51bQkABEwAAAACAgAAAAFrCQAETAAAAAIFAAAABnBlcmlvZAUAAAADbmlsBQAAAANTRVABAAAAFWtleUxvY2tQYXJhbUJ5UGVyaW9kQgAAAAIAAAAHdXNlck51bQAAAAZwZXJpb2QJAAS5AAAAAgkABEwAAAACAgAAABclcyVkJXMlZF9fcGFyYW1CeVBlcmlvZAkABEwAAAACBQAAAAd1c2VyTnVtCQAETAAAAAICAAAAAWIJAARMAAAAAgUAAAAGcGVyaW9kBQAAAANuaWwFAAAAA1NFUAEAAAAXa2V5TG9ja1BhcmFtVG90YWxBbW91bnQAAAAAAgAAAB4lcyVzX19zdGF0c19fYWN0aXZlVG90YWxMb2NrZWQBAAAAIGtleVN0YXRzTG9ja3NEdXJhdGlvblN1bUluQmxvY2tzAAAAAAIAAAAlJXMlc19fc3RhdHNfX2xvY2tzRHVyYXRpb25TdW1JbkJsb2NrcwEAAAASa2V5U3RhdHNMb2Nrc0NvdW50AAAAAAIAAAAXJXMlc19fc3RhdHNfX2xvY2tzQ291bnQBAAAAEmtleVN0YXRzVXNlcnNDb3VudAAAAAACAAAAHSVzJXNfX3N0YXRzX19hY3RpdmVVc2Vyc0NvdW50AQAAACBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAAAAAEAAAAHdXNlck51bQkABLkAAAACCQAETAAAAAICAAAAHiVzJWRfX3VzZXJCb29zdEVtaXNzaW9uTGFzdEludAkABEwAAAACBQAAAAd1c2VyTnVtBQAAAANuaWwFAAAAA1NFUAEAAAAia2V5VXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAAAAAIAAAAHdXNlck51bQAAAAlscEFzc2V0SWQJAAS5AAAAAgkABEwAAAACAgAAAB4lcyVkX191c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnQJAARMAAAAAgUAAAAHdXNlck51bQkABEwAAAACBQAAAAlscEFzc2V0SWQFAAAAA25pbAUAAAADU0VQAQAAABdrZXlVc2VyTWF4Qm9vc3RJTlRFR1JBTAAAAAEAAAAHdXNlck51bQkABLkAAAACCQAETAAAAAICAAAAESVzJWRfX21heEJvb3N0SW50CQAETAAAAAIFAAAAB3VzZXJOdW0FAAAAA25pbAUAAAADU0VQAQAAABhrZXlUb3RhbE1heEJvb3N0SU5URUdSQUwAAAAAAgAAABglcyVzX19tYXhCb29zdEludF9fdG90YWwBAAAAIWtleVVzZXJCb29zdEF2YWxhaWJsZVRvQ2xhaW1Ub3RhbAAAAAEAAAAHdXNlck51bQkABLkAAAACCQAETAAAAAICAAAAJCVzJWRfX3VzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbAkABEwAAAACBQAAAAd1c2VyTnVtBQAAAANuaWwFAAAAA1NFUAEAAAATa2V5VXNlckJvb3N0Q2xhaW1lZAAAAAEAAAAHdXNlck51bQkABLkAAAACCQAETAAAAAICAAAAFiVzJWRfX3VzZXJCb29zdENsYWltZWQJAARMAAAAAgUAAAAHdXNlck51bQUAAAADbmlsBQAAAANTRVABAAAAEWtleVRvdGFsQ2FjaGVkR3d4AAAAAAIAAAAWJXMlc19fZ3d4Q2FjaGVkX190b3RhbAAAAAAPZmFjdG9yeUNvbnRyYWN0CQEAAAAYcmVhZEZhY3RvcnlBZGRyZXNzT3JGYWlsAAAAAAAAAAAKZmFjdG9yeUNmZwkBAAAAFHJlYWRGYWN0b3J5Q2ZnT3JGYWlsAAAAAQUAAAAPZmFjdG9yeUNvbnRyYWN0AAAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAAYZ2V0RW1pc3Npb25BZGRyZXNzT3JGYWlsAAAAAQUAAAAKZmFjdG9yeUNmZwAAAAAPc3Rha2luZ0NvbnRyYWN0CQEAAAAXZ2V0U3Rha2luZ0FkZHJlc3NPckZhaWwAAAABBQAAAApmYWN0b3J5Q2ZnAQAAAAxIaXN0b3J5RW50cnkAAAAIAAAABHR5cGUAAAAEdXNlcgAAAAZhbW91bnQAAAAJbG9ja1N0YXJ0AAAACGR1cmF0aW9uAAAAAWsAAAABYgAAAAFpBAAAAApoaXN0b3J5S0VZCQAEuQAAAAIJAARMAAAAAgIAAAARJXMlcyVzJXNfX2hpc3RvcnkJAARMAAAAAgUAAAAEdHlwZQkABEwAAAACBQAAAAR1c2VyCQAETAAAAAIJAAJYAAAAAQgFAAAAAWkAAAANdHJhbnNhY3Rpb25JZAUAAAADbmlsBQAAAANTRVAEAAAAC2hpc3RvcnlEQVRBCQAEuQAAAAIJAARMAAAAAgIAAAAOJWQlZCVkJWQlZCVkJWQJAARMAAAAAgkAAaQAAAABCAUAAAAJbGFzdEJsb2NrAAAABmhlaWdodAkABEwAAAACCQABpAAAAAEIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wCQAETAAAAAIJAAGkAAAAAQUAAAAGYW1vdW50CQAETAAAAAIJAAGkAAAAAQUAAAAJbG9ja1N0YXJ0CQAETAAAAAIJAAGkAAAAAQUAAAAIZHVyYXRpb24JAARMAAAAAgkAAaQAAAABBQAAAAFrCQAETAAAAAIJAAGkAAAAAQUAAAABYgUAAAADbmlsBQAAAANTRVAJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAACmhpc3RvcnlLRVkFAAAAC2hpc3RvcnlEQVRBAQAAAApTdGF0c0VudHJ5AAAABAAAAA50b3RhbExvY2tlZEluYwAAAAtkdXJhdGlvbkluYwAAAAxsb2NrQ291bnRJbmMAAAANdXNlcnNDb3VudEluYwQAAAAbbG9ja3NEdXJhdGlvblN1bUluQmxvY2tzS0VZCQEAAAAga2V5U3RhdHNMb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MAAAAABAAAAA1sb2Nrc0NvdW50S0VZCQEAAAASa2V5U3RhdHNMb2Nrc0NvdW50AAAAAAQAAAANdXNlcnNDb3VudEtFWQkBAAAAEmtleVN0YXRzVXNlcnNDb3VudAAAAAAEAAAADnRvdGFsQW1vdW50S0VZCQEAAAAXa2V5TG9ja1BhcmFtVG90YWxBbW91bnQAAAAABAAAABhsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAABtsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3NLRVkEAAAACmxvY2tzQ291bnQJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAAA1sb2Nrc0NvdW50S0VZBAAAAAp1c2Vyc0NvdW50CQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAANdXNlcnNDb3VudEtFWQQAAAALdG90YWxBbW91bnQJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAAA50b3RhbEFtb3VudEtFWQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAbbG9ja3NEdXJhdGlvblN1bUluQmxvY2tzS0VZCQAAZAAAAAIFAAAAGGxvY2tzRHVyYXRpb25TdW1JbkJsb2NrcwUAAAALZHVyYXRpb25JbmMJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAADWxvY2tzQ291bnRLRVkJAABkAAAAAgUAAAAKbG9ja3NDb3VudAUAAAAMbG9ja0NvdW50SW5jCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA11c2Vyc0NvdW50S0VZCQAAZAAAAAIFAAAACnVzZXJzQ291bnQFAAAADXVzZXJzQ291bnRJbmMJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAADnRvdGFsQW1vdW50S0VZCQAAZAAAAAIFAAAAC3RvdGFsQW1vdW50BQAAAA50b3RhbExvY2tlZEluYwUAAAADbmlsAQAAAA1jYWxjR3d4QW1vdW50AAAAAwAAAARrUmF3AAAABGJSYXcAAAABaAQAAAAFU0NBTEUAAAAAAAAAA+gJAABpAAAAAgkAAGQAAAACCQAAaAAAAAIFAAAABGtSYXcFAAAAAWgFAAAABGJSYXcFAAAABVNDQUxFAQAAAA9Mb2NrUGFyYW1zRW50cnkAAAAIAAAAC3VzZXJBZGRyZXNzAAAAB3VzZXJOdW0AAAAGYW1vdW50AAAABXN0YXJ0AAAACGR1cmF0aW9uAAAAAWsAAAABYgAAAAZwZXJpb2QEAAAADXVzZXJBbW91bnRLRVkJAQAAABZrZXlMb2NrUGFyYW1Vc2VyQW1vdW50AAAAAQUAAAAHdXNlck51bQQAAAANc3RhcnRCbG9ja0tFWQkBAAAAFmtleUxvY2tQYXJhbVN0YXJ0QmxvY2sAAAABBQAAAAd1c2VyTnVtBAAAAAtkdXJhdGlvbktFWQkBAAAAFGtleUxvY2tQYXJhbUR1cmF0aW9uAAAAAQUAAAAHdXNlck51bQQAAAAEa0tFWQkBAAAADWtleUxvY2tQYXJhbUsAAAABBQAAAAd1c2VyTnVtBAAAAARiS0VZCQEAAAANa2V5TG9ja1BhcmFtQgAAAAEFAAAAB3VzZXJOdW0EAAAAC2tCeVBlcmlvS0VZCQEAAAAVa2V5TG9ja1BhcmFtQnlQZXJpb2RLAAAAAgUAAAAHdXNlck51bQUAAAAGcGVyaW9kBAAAAAxiQnlQZXJpb2RLRVkJAQAAABVrZXlMb2NrUGFyYW1CeVBlcmlvZEIAAAACBQAAAAd1c2VyTnVtBQAAAAZwZXJpb2QEAAAACWd3eEFtb3VudAkBAAAADWNhbGNHd3hBbW91bnQAAAADBQAAAAFrBQAAAAFiBQAAAAZoZWlnaHQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAADXVzZXJBbW91bnRLRVkFAAAABmFtb3VudAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAANc3RhcnRCbG9ja0tFWQUAAAAFc3RhcnQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2R1cmF0aW9uS0VZBQAAAAhkdXJhdGlvbgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAEa0tFWQUAAAABawkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAEYktFWQUAAAABYgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAALa0J5UGVyaW9LRVkFAAAAAWsJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAADGJCeVBlcmlvZEtFWQUAAAABYgkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAATa2V5TG9ja1BhcmFtc1JlY29yZAAAAAEFAAAAC3VzZXJBZGRyZXNzCQEAAAAWZm9ybWF0TG9ja1BhcmFtc1JlY29yZAAAAAcFAAAAB3VzZXJOdW0FAAAABmFtb3VudAUAAAAFc3RhcnQFAAAACGR1cmF0aW9uBQAAAAFrBQAAAAFiBQAAAAlnd3hBbW91bnQFAAAAA25pbAEAAAAiZXh0cmFjdE9wdGlvbmFsUGF5bWVudEFtb3VudE9yRmFpbAAAAAIAAAABaQAAAA9leHBlY3RlZEFzc2V0SWQDCQAAZgAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEJAAACAAAAAQIAAAAbb25seSBvbmUgcGF5bWVudCBpcyBhbGxvd2VkAwkAAAAAAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAAAAAAAAAAAABAAAAANwbXQJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAADCQEAAAACIT0AAAACCQEAAAAFdmFsdWUAAAABCAUAAAADcG10AAAAB2Fzc2V0SWQFAAAAD2V4cGVjdGVkQXNzZXRJZAkAAAIAAAABAgAAABtpbnZhbGlkIGFzc2V0IGlkIGluIHBheW1lbnQIBQAAAANwbXQAAAAGYW1vdW50AQAAABRjYWxjQ3VycmVudEd3eEFtb3VudAAAAAEAAAALdXNlckFkZHJlc3MEAAAABUVNUFRZAgAAAAVlbXB0eQQAAAASdXNlcjJOdW1NYXBwaW5nS0VZCQEAAAASa2V5VXNlcjJOdW1NYXBwaW5nAAAAAQUAAAALdXNlckFkZHJlc3MEAAAAB3VzZXJOdW0JAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQiAAAAAQUAAAASdXNlcjJOdW1NYXBwaW5nS0VZBQAAAAVFTVBUWQQAAAABawkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB8AAAABCQEAAAANa2V5TG9ja1BhcmFtSwAAAAEFAAAAB3VzZXJOdW0AAAAAAAAAAAAEAAAAAWIJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQfAAAAAQkBAAAADWtleUxvY2tQYXJhbUIAAAABBQAAAAd1c2VyTnVtAAAAAAAAAAAABAAAAA1nd3hBbW91bnRDYWxjCQEAAAANY2FsY0d3eEFtb3VudAAAAAMFAAAAAWsFAAAAAWIFAAAABmhlaWdodAQAAAAJZ3d4QW1vdW50AwkAAGYAAAACAAAAAAAAAAAABQAAAA1nd3hBbW91bnRDYWxjAAAAAAAAAAAABQAAAA1nd3hBbW91bnRDYWxjBQAAAAlnd3hBbW91bnQBAAAAFGludGVybmFsQ2xhaW1XeEJvb3N0AAAAAwAAAAxscEFzc2V0SWRTdHIAAAAOdXNlckFkZHJlc3NTdHIAAAAIcmVhZE9ubHkEAAAABUVNUFRZAgAAAAVFTVBUWQQAAAARdXNlclJlY29yZE9yRW1wdHkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwkBAAAAE2tleUxvY2tQYXJhbXNSZWNvcmQAAAABBQAAAA51c2VyQWRkcmVzc1N0cgUAAAAFRU1QVFkDCQAAAAAAAAIFAAAAEXVzZXJSZWNvcmRPckVtcHR5BQAAAAVFTVBUWQkABRUAAAADAAAAAAAAAAAABQAAAANuaWwCAAAAFXVzZXJSZWNvcmQ6OmlzOjplbXB0eQQAAAAPdXNlclJlY29yZEFycmF5CQAEtQAAAAIFAAAAEXVzZXJSZWNvcmRPckVtcHR5BQAAAANTRVAEAAAACnVzZXJOdW1TdHIJAAGRAAAAAgUAAAAPdXNlclJlY29yZEFycmF5BQAAAA5JZHhMb2NrVXNlck51bQQAAAAIRU1QVFlTVFICAAAABWVtcHR5BAAAAApwb29sV2VpZ2h0AwkBAAAAAiE9AAAAAgUAAAAMbHBBc3NldElkU3RyBQAAAAhFTVBUWVNUUgQAAAAOcG9vbEFkZHJlc3NTdHIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAA9mYWN0b3J5Q29udHJhY3QJAQAAABprZXlGYWN0b3J5THAyQXNzZXRzTWFwcGluZwAAAAEFAAAADGxwQXNzZXRJZFN0cgkAASwAAAACAgAAABV1bnN1cHBvcnRlZCBscCBhc3NldCAFAAAADGxwQXNzZXRJZFN0cgkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAPZmFjdG9yeUNvbnRyYWN0CQEAAAAUa2V5RmFjdG9yeVBvb2xXZWlnaHQAAAABBQAAAA5wb29sQWRkcmVzc1N0cgMFAAAACHJlYWRPbmx5AAAAAAAAAAAACQAAAgAAAAEJAAEsAAAAAgIAAAAobm90IHJlYWRvbmx5IG1vZGU6IHVuc3VwcG9ydGVkIGxwIGFzc2V0IAUAAAAMbHBBc3NldElkU3RyBAAAABJ3eEVtaXNzaW9uUGVyQmxvY2sJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAAea2V5RW1pc3Npb25SYXRlUGVyQmxvY2tDdXJyZW50AAAAAAQAAAANZW1pc3Npb25TdGFydAkBAAAADGdldEludE9yRmFpbAAAAAIFAAAAEGVtaXNzaW9uQ29udHJhY3QJAQAAABVrZXlFbWlzc2lvblN0YXJ0QmxvY2sAAAAABAAAAAtlbWlzc2lvbkVuZAkBAAAADGdldEludE9yRmFpbAAAAAIFAAAAEGVtaXNzaW9uQ29udHJhY3QJAQAAABNrZXlFbWlzc2lvbkVuZEJsb2NrAAAAAAQAAAABaAMJAABmAAAAAgUAAAAGaGVpZ2h0BQAAAAtlbWlzc2lvbkVuZAUAAAALZW1pc3Npb25FbmQFAAAABmhlaWdodAQAAAACZGgJAAGWAAAAAQkABEwAAAACCQAAZQAAAAIFAAAAAWgFAAAADWVtaXNzaW9uU3RhcnQJAARMAAAAAgAAAAAAAAAAAAUAAAADbmlsBAAAACJ1c2VyTHBCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZCQEAAAAia2V5VXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAAAAAIFAAAACnVzZXJOdW1TdHIFAAAADGxwQXNzZXRJZFN0cgQAAAAgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJAQAAACBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAAAAAEFAAAACnVzZXJOdW1TdHIEAAAAHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAInVzZXJMcEJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAACB1c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQQAAAAVYm9vc3RFbWlzc2lvbkludGVncmFsCQAAaQAAAAIJAABoAAAAAgkAAGgAAAACBQAAABJ3eEVtaXNzaW9uUGVyQmxvY2sFAAAAAmRoAAAAAAAAAAACAAAAAAAAAAADBAAAABl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsCQAAZQAAAAIFAAAAFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAUAAAAddXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWwDCQAAZgAAAAIAAAAAAAAAAAAFAAAAGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwJAAACAAAAAQIAAAASd3JvbmcgY2FsY3VsYXRpb25zBAAAABd1c2VyTWF4Qm9vc3RJbnRlZ3JhbEtFWQkBAAAAF2tleVVzZXJNYXhCb29zdElOVEVHUkFMAAAAAQUAAAAKdXNlck51bVN0cgQAAAAYdG90YWxNYXhCb29zdEludGVncmFsS0VZCQEAAAAYa2V5VG90YWxNYXhCb29zdElOVEVHUkFMAAAAAAQAAAAPdXNlck1heEJvb3N0SW50CQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAXdXNlck1heEJvb3N0SW50ZWdyYWxLRVkEAAAAEHRvdGFsTWF4Qm9vc3RJbnQJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAABh0b3RhbE1heEJvb3N0SW50ZWdyYWxLRVkEAAAAEXRvdGFsQ2FjaGVkR3d4S0VZCQEAAAARa2V5VG90YWxDYWNoZWRHd3gAAAAABAAAAA50b3RhbENhY2hlZEd3eAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAABF0b3RhbENhY2hlZEd3eEtFWQAAAAAAAAAAAAQAAAALdXNlckN1cnJHd3gJAQAAABRjYWxjQ3VycmVudEd3eEFtb3VudAAAAAEFAAAADnVzZXJBZGRyZXNzU3RyBAAAACF1c2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWxLRVkJAQAAACFrZXlVc2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWwAAAABBQAAAAp1c2VyTnVtU3RyBAAAAB51c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWwJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAACF1c2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWxLRVkEAAAAHXBvb2xVc2VyQm9vc3RFbWlzc2lvbkludGVncmFsCQAAawAAAAMFAAAAGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwFAAAACnBvb2xXZWlnaHQFAAAADlBPT0xXRUlHSFRNVUxUBAAAACF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcDCQAAAAAAAAIFAAAADnRvdGFsQ2FjaGVkR3d4AAAAAAAAAAAAAAAAAAAAAAAACQAAawAAAAMFAAAAHXBvb2xVc2VyQm9vc3RFbWlzc2lvbkludGVncmFsBQAAAAt1c2VyQ3Vyckd3eAUAAAAOdG90YWxDYWNoZWRHd3gEAAAAE3VzZXJCb29zdENsYWltZWRLRVkJAQAAABNrZXlVc2VyQm9vc3RDbGFpbWVkAAAAAQUAAAAKdXNlck51bVN0cgQAAAAQdXNlckJvb3N0Q2xhaW1lZAkBAAAADGdldEludE9yWmVybwAAAAIFAAAABHRoaXMFAAAAE3VzZXJCb29zdENsYWltZWRLRVkEAAAAEnVzZXJCb29zdEF2YWlsYWJsZQkAAGUAAAACBQAAACF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcFAAAAEHVzZXJCb29zdENsYWltZWQEAAAACWRhdGFTdGF0ZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAidXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQUAAAAVYm9vc3RFbWlzc2lvbkludGVncmFsBQAAAANuaWwEAAAABWRlYnVnCQAEuQAAAAIJAARMAAAAAgkAASwAAAACAgAAAB51c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbD0JAAGkAAAAAQUAAAAddXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWwJAARMAAAAAgkAASwAAAACAgAAABp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsPQkAAaQAAAABBQAAABl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsCQAETAAAAAIJAAEsAAAAAgIAAAAQdXNlck1heEJvb3N0SW50PQkAAaQAAAABBQAAAA91c2VyTWF4Qm9vc3RJbnQJAARMAAAAAgkAASwAAAACAgAAABF0b3RhbE1heEJvb3N0SW50PQkAAaQAAAABBQAAABB0b3RhbE1heEJvb3N0SW50CQAETAAAAAIJAAEsAAAAAgIAAAAfdXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsPQkAAaQAAAABBQAAAB51c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWwJAARMAAAAAgkAASwAAAACAgAAACJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXc9CQABpAAAAAEFAAAAIXVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbE5ldwkABEwAAAACCQABLAAAAAICAAAAEXVzZXJCb29zdENsYWltZWQ9CQABpAAAAAEFAAAAEHVzZXJCb29zdENsYWltZWQJAARMAAAAAgkAASwAAAACAgAAABN1c2VyQm9vc3RBdmFpbGFibGU9CQABpAAAAAEFAAAAEnVzZXJCb29zdEF2YWlsYWJsZQkABEwAAAACCQABLAAAAAICAAAAHnBvb2xVc2VyQm9vc3RFbWlzc2lvbkludGVncmFsPQkAAaQAAAABBQAAAB1wb29sVXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAkABEwAAAACCQABLAAAAAICAAAADHVzZXJDdXJyR3d4PQkAAaQAAAABBQAAAAt1c2VyQ3Vyckd3eAkABEwAAAACCQABLAAAAAICAAAADnRvdGFsQ2FjaGVkR3d4CQABpAAAAAEFAAAADnRvdGFsQ2FjaGVkR3d4BQAAAANuaWwCAAAAAjo6CQAFFQAAAAMFAAAAIXVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbE5ldwUAAAAJZGF0YVN0YXRlBQAAAAVkZWJ1ZwAAAAcAAAABaQEAAAALY29uc3RydWN0b3IAAAAGAAAAEWZhY3RvcnlBZGRyZXNzU3RyAAAADmxvY2tBc3NldElkU3RyAAAADW1pbkxvY2tBbW91bnQAAAALbWluRHVyYXRpb24AAAALbWF4RHVyYXRpb24AAAAMbWF0aENvbnRyYWN0AwkBAAAAAiE9AAAAAgUAAAAEdGhpcwgFAAAAAWkAAAAGY2FsbGVyCQAAAgAAAAECAAAADm5vdCBhdXRob3JpemVkCQAETgAAAAIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA5rZXlOZXh0VXNlck51bQAAAAAAAAAAAAAAAAAJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAACWtleUNvbmZpZwAAAAAJAQAAAAxmb3JtYXRDb25maWcAAAAFBQAAAA5sb2NrQXNzZXRJZFN0cgUAAAANbWluTG9ja0Ftb3VudAUAAAALbWluRHVyYXRpb24FAAAAC21heER1cmF0aW9uBQAAAAxtYXRoQ29udHJhY3QJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAEWtleUZhY3RvcnlBZGRyZXNzAAAAAAUAAAARZmFjdG9yeUFkZHJlc3NTdHIFAAAAA25pbAkBAAAAClN0YXRzRW50cnkAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWkBAAAABGxvY2sAAAABAAAACGR1cmF0aW9uBAAAAAhjZmdBcnJheQkBAAAAFXJlYWRDb25maWdBcnJheU9yRmFpbAAAAAAEAAAACmFzc2V0SWRTdHIJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAADUlkeENmZ0Fzc2V0SWQEAAAAB2Fzc2V0SWQJAAJZAAAAAQUAAAAKYXNzZXRJZFN0cgQAAAANbWluTG9ja0Ftb3VudAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABNJZHhDZmdNaW5Mb2NrQW1vdW50BAAAAA9taW5Mb2NrRHVyYXRpb24JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAhjZmdBcnJheQUAAAAVSWR4Q2ZnTWluTG9ja0R1cmF0aW9uBAAAAA9tYXhMb2NrRHVyYXRpb24JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAhjZmdBcnJheQUAAAAVSWR4Q2ZnTWF4TG9ja0R1cmF0aW9uBAAAAAxtYXRoQ29udHJhY3QJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAAEklkeENmZ01hdGhDb250cmFjdAMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEJAAACAAAAAQIAAAA0aW52YWxpZCBwYXltZW50IC0gZXhhY3Qgb25lIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQAAAADcG10CQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAABAAAAAlwbXRBbW91bnQIBQAAAANwbXQAAAAGYW1vdW50AwkBAAAAAiE9AAAAAgUAAAAHYXNzZXRJZAkBAAAABXZhbHVlAAAAAQgFAAAAA3BtdAAAAAdhc3NldElkCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAAB5pbnZhbGlkIGFzc2V0IGlzIGluIHBheW1lbnQgLSAFAAAACmFzc2V0SWRTdHICAAAADCBpcyBleHBlY3RlZAQAAAAObmV4dFVzZXJOdW1LRVkJAQAAAA5rZXlOZXh0VXNlck51bQAAAAAEAAAADnVzZXJBZGRyZXNzU3RyCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAAOdXNlcklzRXhpc3RpbmcJAQAAAAlpc0RlZmluZWQAAAABCQAEIgAAAAEJAQAAABJrZXlVc2VyMk51bU1hcHBpbmcAAAABBQAAAA51c2VyQWRkcmVzc1N0cgQAAAAKdXNlck51bVN0cgMFAAAADnVzZXJJc0V4aXN0aW5nCQEAAAAFdmFsdWUAAAABCQAEIgAAAAEJAQAAABJrZXlVc2VyMk51bU1hcHBpbmcAAAABBQAAAA51c2VyQWRkcmVzc1N0cgkAAaQAAAABCQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAEdGhpcwUAAAAObmV4dFVzZXJOdW1LRVkEAAAAB3VzZXJOdW0JAQAAAA1wYXJzZUludFZhbHVlAAAAAQUAAAAKdXNlck51bVN0cgQAAAAJbG9ja1N0YXJ0BQAAAAZoZWlnaHQEAAAADXN0YXJ0QmxvY2tLRVkJAQAAABZrZXlMb2NrUGFyYW1TdGFydEJsb2NrAAAAAQUAAAAKdXNlck51bVN0cgQAAAALZHVyYXRpb25LRVkJAQAAABRrZXlMb2NrUGFyYW1EdXJhdGlvbgAAAAEFAAAACnVzZXJOdW1TdHIEAAAADXVzZXJBbW91bnRLRVkJAQAAABZrZXlMb2NrUGFyYW1Vc2VyQW1vdW50AAAAAQUAAAAKdXNlck51bVN0cgMJAABmAAAAAgUAAAANbWluTG9ja0Ftb3VudAUAAAAJcG10QW1vdW50CQAAAgAAAAEJAAEsAAAAAgIAAAAiYW1vdW50IGlzIGxlc3MgdGhlbiBtaW5Mb2NrQW1vdW50PQkAAaQAAAABBQAAAA1taW5Mb2NrQW1vdW50AwkAAGYAAAACBQAAAA9taW5Mb2NrRHVyYXRpb24FAAAACGR1cmF0aW9uCQAAAgAAAAEJAAEsAAAAAgIAAAAtcGFzc2VkIGR1cmF0aW9uIGlzIGxlc3MgdGhlbiBtaW5Mb2NrRHVyYXRpb249CQABpAAAAAEFAAAAD21pbkxvY2tEdXJhdGlvbgMJAABmAAAAAgUAAAAIZHVyYXRpb24FAAAAD21heExvY2tEdXJhdGlvbgkAAAIAAAABCQABLAAAAAICAAAAMHBhc3NlZCBkdXJhdGlvbiBpcyBncmVhdGVyIHRoZW4gbWF4TG9ja0R1cmF0aW9uPQkAAaQAAAABBQAAAA9tYXhMb2NrRHVyYXRpb24DAwUAAAAOdXNlcklzRXhpc3RpbmcJAABnAAAAAgkAAGQAAAACCQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAEdGhpcwUAAAANc3RhcnRCbG9ja0tFWQkBAAAADGdldEludE9yRmFpbAAAAAIFAAAABHRoaXMFAAAAC2R1cmF0aW9uS0VZBQAAAAlsb2NrU3RhcnQHCQAAAgAAAAECAAAANnRoZXJlIGlzIGFuIGFjdGl2ZSBsb2NrIC0gY29uc2lkZXIgdG8gdXNlIGluY3JlYXNlTG9jawMJAABmAAAAAgkBAAAADGdldEludE9yWmVybwAAAAIFAAAABHRoaXMFAAAADXVzZXJBbW91bnRLRVkAAAAAAAAAAAAJAAACAAAAAQIAAAAzdGhlcmUgYXJlIGxvY2tlZCBXWHMgLSBjb25zaWRlciB0byB1c2UgaW5jcmVhc2VMb2NrBAAAAAdjb2VmZlg4CQAAawAAAAMFAAAACGR1cmF0aW9uBQAAAAVNVUxUOAUAAAAPbWF4TG9ja0R1cmF0aW9uBAAAAA5nV3hBbW91bnRTdGFydAkAAGsAAAADBQAAAAlwbXRBbW91bnQFAAAAB2NvZWZmWDgFAAAABU1VTFQ4BAAAABNnV3hQYXJhbXNSZXN1bHRMaXN0CQEAAAAJYXNBbnlMaXN0AAAAAQkAA/wAAAAEBQAAAAxtYXRoQ29udHJhY3QCAAAAFWNhbGNHd3hQYXJhbXNSRUFET05MWQkABEwAAAACBQAAAA5nV3hBbW91bnRTdGFydAkABEwAAAACBQAAAAlsb2NrU3RhcnQJAARMAAAAAgUAAAAIZHVyYXRpb24FAAAAA25pbAUAAAADbmlsBAAAAAFrCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAAE2dXeFBhcmFtc1Jlc3VsdExpc3QAAAAAAAAAAAAEAAAAAWIJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAATZ1d4UGFyYW1zUmVzdWx0TGlzdAAAAAAAAAAAAQQAAAAGcGVyaW9kCQABpAAAAAEJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAATZ1d4UGFyYW1zUmVzdWx0TGlzdAAAAAAAAAAAAgQAAAASd3hFbWlzc2lvblBlckJsb2NrCQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAQZW1pc3Npb25Db250cmFjdAkBAAAAHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAAAAAEAAAADWVtaXNzaW9uU3RhcnQJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAAVa2V5RW1pc3Npb25TdGFydEJsb2NrAAAAAAQAAAALZW1pc3Npb25FbmQJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAATa2V5RW1pc3Npb25FbmRCbG9jawAAAAAEAAAAAWgDCQAAZgAAAAIFAAAABmhlaWdodAUAAAALZW1pc3Npb25FbmQFAAAAC2VtaXNzaW9uRW5kBQAAAAZoZWlnaHQEAAAAAmRoCQABlgAAAAEJAARMAAAAAgkAAGUAAAACBQAAAAFoBQAAAA1lbWlzc2lvblN0YXJ0CQAETAAAAAIAAAAAAAAAAAAFAAAAA25pbAQAAAAgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJAQAAACBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAAAAAEFAAAACnVzZXJOdW1TdHIEAAAAFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAAGkAAAACCQAAaAAAAAIJAABoAAAAAgUAAAASd3hFbWlzc2lvblBlckJsb2NrBQAAAAJkaAAAAAAAAAAAAgAAAAAAAAAAAwQAAAAXdXNlck1heEJvb3N0SW50ZWdyYWxLRVkJAQAAABdrZXlVc2VyTWF4Qm9vc3RJTlRFR1JBTAAAAAEFAAAACnVzZXJOdW1TdHIEAAAAGHRvdGFsTWF4Qm9vc3RJbnRlZ3JhbEtFWQkBAAAAGGtleVRvdGFsTWF4Qm9vc3RJTlRFR1JBTAAAAAAEAAAAD3VzZXJNYXhCb29zdEludAkAAGkAAAACCQAAaAAAAAIFAAAADmdXeEFtb3VudFN0YXJ0BQAAAAhkdXJhdGlvbgAAAAAAAAAAAgQAAAAQdG90YWxNYXhCb29zdEludAkBAAAADGdldEludE9yWmVybwAAAAIFAAAABHRoaXMFAAAAGHRvdGFsTWF4Qm9vc3RJbnRlZ3JhbEtFWQQAAAARdG90YWxDYWNoZWRHd3hLRVkJAQAAABFrZXlUb3RhbENhY2hlZEd3eAAAAAAEAAAADnRvdGFsQ2FjaGVkR3d4CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAEXRvdGFsQ2FjaGVkR3d4S0VZAAAAAAAAAAAABAAAAANhcnIDBQAAAA51c2VySXNFeGlzdGluZwUAAAADbmlsCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA5uZXh0VXNlck51bUtFWQkAAGQAAAACBQAAAAd1c2VyTnVtAAAAAAAAAAABCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAABJrZXlVc2VyMk51bU1hcHBpbmcAAAABBQAAAA51c2VyQWRkcmVzc1N0cgUAAAAKdXNlck51bVN0cgkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAASa2V5TnVtMlVzZXJNYXBwaW5nAAAAAQUAAAAKdXNlck51bVN0cgUAAAAOdXNlckFkZHJlc3NTdHIFAAAAA25pbAkABE4AAAACCQAETQAAAAIJAAROAAAAAgkABE4AAAACBQAAAANhcnIJAQAAAA9Mb2NrUGFyYW1zRW50cnkAAAAIBQAAAA51c2VyQWRkcmVzc1N0cgUAAAAKdXNlck51bVN0cgUAAAAJcG10QW1vdW50BQAAAAlsb2NrU3RhcnQFAAAACGR1cmF0aW9uBQAAAAFrBQAAAAFiBQAAAAZwZXJpb2QJAQAAAApTdGF0c0VudHJ5AAAABAUAAAAJcG10QW1vdW50BQAAAAhkdXJhdGlvbgAAAAAAAAAAAQMFAAAADnVzZXJJc0V4aXN0aW5nAAAAAAAAAAAAAAAAAAAAAAABCQEAAAAMSGlzdG9yeUVudHJ5AAAACAIAAAAEbG9jawUAAAAOdXNlckFkZHJlc3NTdHIFAAAACXBtdEFtb3VudAUAAAAJbG9ja1N0YXJ0BQAAAAhkdXJhdGlvbgUAAAABawUAAAABYgUAAAABaQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkFAAAAFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARdG90YWxDYWNoZWRHd3hLRVkJAABkAAAAAgUAAAAOdG90YWxDYWNoZWRHd3gFAAAADmdXeEFtb3VudFN0YXJ0BQAAAANuaWwAAAABaQEAAAAMaW5jcmVhc2VMb2NrAAAAAQAAAA1kZWx0YUR1cmF0aW9uBAAAAAhjZmdBcnJheQkBAAAAFXJlYWRDb25maWdBcnJheU9yRmFpbAAAAAAEAAAACmFzc2V0SWRTdHIJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAADUlkeENmZ0Fzc2V0SWQEAAAAB2Fzc2V0SWQJAAJZAAAAAQUAAAAKYXNzZXRJZFN0cgQAAAAPbWluTG9ja0R1cmF0aW9uCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAAFUlkeENmZ01pbkxvY2tEdXJhdGlvbgQAAAAPbWF4TG9ja0R1cmF0aW9uCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAAFUlkeENmZ01heExvY2tEdXJhdGlvbgQAAAAMbWF0aENvbnRyYWN0CQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABJJZHhDZmdNYXRoQ29udHJhY3QEAAAACXBtdEFtb3VudAkBAAAAImV4dHJhY3RPcHRpb25hbFBheW1lbnRBbW91bnRPckZhaWwAAAACBQAAAAFpBQAAAAdhc3NldElkBAAAAA51c2VyQWRkcmVzc1N0cgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAAD3VzZXJSZWNvcmRBcnJheQkBAAAAGnJlYWRMb2NrUGFyYW1zUmVjb3JkT3JGYWlsAAAAAQUAAAAOdXNlckFkZHJlc3NTdHIEAAAACnVzZXJOdW1TdHIJAAGRAAAAAgUAAAAPdXNlclJlY29yZEFycmF5BQAAAA5JZHhMb2NrVXNlck51bQQAAAAKdXNlckFtb3VudAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAD3VzZXJSZWNvcmRBcnJheQUAAAANSWR4TG9ja0Ftb3VudAQAAAAJbG9ja1N0YXJ0CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAPdXNlclJlY29yZEFycmF5BQAAAAxJZHhMb2NrU3RhcnQEAAAADGxvY2tEdXJhdGlvbgkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAD3VzZXJSZWNvcmRBcnJheQUAAAAPSWR4TG9ja0R1cmF0aW9uBAAAAAdsb2NrRW5kCQAAZAAAAAIFAAAACWxvY2tTdGFydAUAAAAMbG9ja0R1cmF0aW9uBAAAABFyZW1haW5pbmdEdXJhdGlvbgkAAZYAAAABCQAETAAAAAIJAABlAAAAAgUAAAAHbG9ja0VuZAUAAAAGaGVpZ2h0CQAETAAAAAIAAAAAAAAAAAAFAAAAA25pbAQAAAANdXNlckFtb3VudE5ldwkAAGQAAAACBQAAAAp1c2VyQW1vdW50BQAAAAlwbXRBbW91bnQEAAAAD2xvY2tEdXJhdGlvbk5ldwkAAGQAAAACBQAAABFyZW1haW5pbmdEdXJhdGlvbgUAAAANZGVsdGFEdXJhdGlvbgMJAABmAAAAAgAAAAAAAAAAAAUAAAANZGVsdGFEdXJhdGlvbgkAAAIAAAABAgAAABpkdXJhdGlvbiBpcyBsZXNzIHRoZW4gemVybwMJAABmAAAAAgUAAAAPbWluTG9ja0R1cmF0aW9uBQAAAA9sb2NrRHVyYXRpb25OZXcJAAACAAAAAQkAASwAAAACAgAAAC1sb2NrRHVyYXRpb25OZXcgaXMgbGVzcyB0aGVuIG1pbkxvY2tEdXJhdGlvbj0JAAGkAAAAAQUAAAAPbWluTG9ja0R1cmF0aW9uAwkAAGYAAAACBQAAAA9sb2NrRHVyYXRpb25OZXcFAAAAD21heExvY2tEdXJhdGlvbgkAAAIAAAABCQABLAAAAAICAAAARGRlbHRhRHVyYXRpb24gKyBleGlzdGVkTG9ja0R1cmF0aW9uIGlzIGdyZWF0ZXIgdGhlbiBtYXhMb2NrRHVyYXRpb249CQABpAAAAAEFAAAAD21heExvY2tEdXJhdGlvbgQAAAAHY29lZmZYOAkAAGsAAAADBQAAAA9sb2NrRHVyYXRpb25OZXcFAAAABU1VTFQ4BQAAAA9tYXhMb2NrRHVyYXRpb24EAAAADmdXeEFtb3VudFN0YXJ0CQAAawAAAAMFAAAADXVzZXJBbW91bnROZXcFAAAAB2NvZWZmWDgFAAAABU1VTFQ4BAAAAAxsb2NrU3RhcnROZXcFAAAABmhlaWdodAQAAAATZ1d4UGFyYW1zUmVzdWx0TGlzdAkBAAAACWFzQW55TGlzdAAAAAEJAAP8AAAABAUAAAAMbWF0aENvbnRyYWN0AgAAABVjYWxjR3d4UGFyYW1zUkVBRE9OTFkJAARMAAAAAgUAAAAOZ1d4QW1vdW50U3RhcnQJAARMAAAAAgUAAAAMbG9ja1N0YXJ0TmV3CQAETAAAAAIFAAAAD2xvY2tEdXJhdGlvbk5ldwUAAAADbmlsBQAAAANuaWwEAAAAAWsJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAATZ1d4UGFyYW1zUmVzdWx0TGlzdAAAAAAAAAAAAAQAAAABYgkBAAAABWFzSW50AAAAAQkAAZEAAAACBQAAABNnV3hQYXJhbXNSZXN1bHRMaXN0AAAAAAAAAAABBAAAAAZwZXJpb2QJAAGkAAAAAQkBAAAABWFzSW50AAAAAQkAAZEAAAACBQAAABNnV3hQYXJhbXNSZXN1bHRMaXN0AAAAAAAAAAACBAAAABJ3eEVtaXNzaW9uUGVyQmxvY2sJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAAea2V5RW1pc3Npb25SYXRlUGVyQmxvY2tDdXJyZW50AAAAAAQAAAANZW1pc3Npb25TdGFydAkBAAAADGdldEludE9yRmFpbAAAAAIFAAAAEGVtaXNzaW9uQ29udHJhY3QJAQAAABVrZXlFbWlzc2lvblN0YXJ0QmxvY2sAAAAABAAAAAtlbWlzc2lvbkVuZAkBAAAADGdldEludE9yRmFpbAAAAAIFAAAAEGVtaXNzaW9uQ29udHJhY3QJAQAAABNrZXlFbWlzc2lvbkVuZEJsb2NrAAAAAAQAAAABaAMJAABmAAAAAgUAAAAGaGVpZ2h0BQAAAAtlbWlzc2lvbkVuZAUAAAALZW1pc3Npb25FbmQFAAAABmhlaWdodAQAAAACZGgJAAGWAAAAAQkABEwAAAACCQAAZQAAAAIFAAAAAWgFAAAADWVtaXNzaW9uU3RhcnQJAARMAAAAAgAAAAAAAAAAAAUAAAADbmlsBAAAACB1c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQkBAAAAIGtleVVzZXJCb29zdEVtaXNzaW9uTGFzdElOVEVHUkFMAAAAAQUAAAAKdXNlck51bVN0cgQAAAAddXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWwJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAACB1c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQQAAAAVYm9vc3RFbWlzc2lvbkludGVncmFsCQAAaQAAAAIJAABoAAAAAgkAAGgAAAACBQAAABJ3eEVtaXNzaW9uUGVyQmxvY2sFAAAAAmRoAAAAAAAAAAACAAAAAAAAAAADBAAAABl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsCQAAZQAAAAIFAAAAFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAUAAAAddXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWwDCQAAZgAAAAIAAAAAAAAAAAAFAAAAGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwJAAACAAAAAQIAAAASd3JvbmcgY2FsY3VsYXRpb25zBAAAABd1c2VyTWF4Qm9vc3RJbnRlZ3JhbEtFWQkBAAAAF2tleVVzZXJNYXhCb29zdElOVEVHUkFMAAAAAQUAAAAKdXNlck51bVN0cgQAAAAYdG90YWxNYXhCb29zdEludGVncmFsS0VZCQEAAAAYa2V5VG90YWxNYXhCb29zdElOVEVHUkFMAAAAAAQAAAAPdXNlck1heEJvb3N0SW50CQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAXdXNlck1heEJvb3N0SW50ZWdyYWxLRVkEAAAAEHRvdGFsTWF4Qm9vc3RJbnQJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAABh0b3RhbE1heEJvb3N0SW50ZWdyYWxLRVkEAAAAC2N1cnJVc2VyR3d4CQEAAAAUY2FsY0N1cnJlbnRHd3hBbW91bnQAAAABBQAAAA51c2VyQWRkcmVzc1N0cgQAAAAHZ3d4RGlmZgkAAGUAAAACBQAAAA5nV3hBbW91bnRTdGFydAUAAAALY3VyclVzZXJHd3gDCQAAZgAAAAIAAAAAAAAAAAAFAAAAB2d3eERpZmYJAAACAAAAAQIAAAAWZ3d4RGlmZiBpcyBsZXNzIHRoZW4gMAQAAAARdG90YWxDYWNoZWRHd3hLRVkJAQAAABFrZXlUb3RhbENhY2hlZEd3eAAAAAAEAAAADnRvdGFsQ2FjaGVkR3d4CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAEXRvdGFsQ2FjaGVkR3d4S0VZAAAAAAAAAAAABAAAACF1c2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWxLRVkJAQAAACFrZXlVc2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWwAAAABBQAAAAp1c2VyTnVtU3RyBAAAAB51c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWwJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAACF1c2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWxLRVkEAAAAIXVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbE5ldwkAAGsAAAADBQAAABl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsBQAAAAtjdXJyVXNlckd3eAUAAAAOdG90YWxDYWNoZWRHd3gEAAAAEnVzZXJNYXhCb29zdEludE5ldwkAAGkAAAACCQAAaAAAAAIFAAAADmdXeEFtb3VudFN0YXJ0BQAAAA9sb2NrRHVyYXRpb25OZXcAAAAAAAAAAAIEAAAAGHJlbWFpbmluZ1VzZXJNYXhCb29zdEludAkAAGkAAAACCQAAaAAAAAIFAAAAC2N1cnJVc2VyR3d4BQAAABFyZW1haW5pbmdEdXJhdGlvbgAAAAAAAAAAAgQAAAATdXNlck1heEJvb3N0SW50RGlmZgkAAGUAAAACBQAAABJ1c2VyTWF4Qm9vc3RJbnROZXcFAAAAGHJlbWFpbmluZ1VzZXJNYXhCb29zdEludAkABE4AAAACCQAETQAAAAIJAAROAAAAAgkBAAAAD0xvY2tQYXJhbXNFbnRyeQAAAAgFAAAADnVzZXJBZGRyZXNzU3RyBQAAAAp1c2VyTnVtU3RyBQAAAA11c2VyQW1vdW50TmV3BQAAAAxsb2NrU3RhcnROZXcFAAAAD2xvY2tEdXJhdGlvbk5ldwUAAAABawUAAAABYgUAAAAGcGVyaW9kCQEAAAAKU3RhdHNFbnRyeQAAAAQFAAAACXBtdEFtb3VudAUAAAANZGVsdGFEdXJhdGlvbgAAAAAAAAAAAAAAAAAAAAAAAAkBAAAADEhpc3RvcnlFbnRyeQAAAAgCAAAABGxvY2sFAAAADnVzZXJBZGRyZXNzU3RyBQAAAAlwbXRBbW91bnQFAAAACWxvY2tTdGFydAUAAAAPbG9ja0R1cmF0aW9uTmV3BQAAAAFrBQAAAAFiBQAAAAFpCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABF0b3RhbENhY2hlZEd3eEtFWQkAAGQAAAACBQAAAA50b3RhbENhY2hlZEd3eAUAAAAHZ3d4RGlmZgUAAAADbmlsAAAAAWkBAAAADGNsYWltV3hCb29zdAAAAAIAAAAMbHBBc3NldElkU3RyAAAADnVzZXJBZGRyZXNzU3RyAwkBAAAAAiE9AAAAAgUAAAAPc3Rha2luZ0NvbnRyYWN0CAUAAAABaQAAAAZjYWxsZXIJAAACAAAAAQIAAAAScGVybWlzc2lvbnMgZGVuaWVkBAAAAA0kdDAyNDgwNDI0OTA2CQEAAAAUaW50ZXJuYWxDbGFpbVd4Qm9vc3QAAAADBQAAAAxscEFzc2V0SWRTdHIFAAAADnVzZXJBZGRyZXNzU3RyBwQAAAASdXNlckJvb3N0QXZhaWxhYmxlCAUAAAANJHQwMjQ4MDQyNDkwNgAAAAJfMQQAAAAJZGF0YVN0YXRlCAUAAAANJHQwMjQ4MDQyNDkwNgAAAAJfMgQAAAAFZGVidWcIBQAAAA0kdDAyNDgwNDI0OTA2AAAAAl8zCQAFFAAAAAIFAAAACWRhdGFTdGF0ZQkABEwAAAACBQAAABJ1c2VyQm9vc3RBdmFpbGFibGUFAAAAA25pbAAAAAFpAQAAABRjbGFpbVd4Qm9vc3RSRUFET05MWQAAAAIAAAAMbHBBc3NldElkU3RyAAAADnVzZXJBZGRyZXNzU3RyBAAAAA0kdDAyNTAzODI1MTM5CQEAAAAUaW50ZXJuYWxDbGFpbVd4Qm9vc3QAAAADBQAAAAxscEFzc2V0SWRTdHIFAAAADnVzZXJBZGRyZXNzU3RyBgQAAAASdXNlckJvb3N0QXZhaWxhYmxlCAUAAAANJHQwMjUwMzgyNTEzOQAAAAJfMQQAAAAJZGF0YVN0YXRlCAUAAAANJHQwMjUwMzgyNTEzOQAAAAJfMgQAAAAFZGVidWcIBQAAAA0kdDAyNTAzODI1MTM5AAAAAl8zCQAFFAAAAAIFAAAAA25pbAkABEwAAAACBQAAABJ1c2VyQm9vc3RBdmFpbGFibGUJAARMAAAAAgUAAAAFZGVidWcFAAAAA25pbAAAAAFpAQAAAAZ1bmxvY2sAAAABAAAAC3VzZXJBZGRyZXNzBAAAAA91c2VyUmVjb3JkQXJyYXkJAQAAABpyZWFkTG9ja1BhcmFtc1JlY29yZE9yRmFpbAAAAAEFAAAAC3VzZXJBZGRyZXNzBAAAAAp1c2VyTnVtU3RyCQABkQAAAAIFAAAAD3VzZXJSZWNvcmRBcnJheQUAAAAOSWR4TG9ja1VzZXJOdW0EAAAACnVzZXJBbW91bnQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAA91c2VyUmVjb3JkQXJyYXkFAAAADUlkeExvY2tBbW91bnQEAAAACWxvY2tTdGFydAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAD3VzZXJSZWNvcmRBcnJheQUAAAAMSWR4TG9ja1N0YXJ0BAAAAAxsb2NrRHVyYXRpb24JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAA91c2VyUmVjb3JkQXJyYXkFAAAAD0lkeExvY2tEdXJhdGlvbgQAAAAHbG9ja0VuZAkAAGQAAAACBQAAAAlsb2NrU3RhcnQFAAAADGxvY2tEdXJhdGlvbgQAAAAIY2ZnQXJyYXkJAQAAABVyZWFkQ29uZmlnQXJyYXlPckZhaWwAAAAABAAAAAdhc3NldElkCQACWQAAAAEJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAADUlkeENmZ0Fzc2V0SWQEAAAADG1hdGhDb250cmFjdAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkAAZEAAAACBQAAAAhjZmdBcnJheQUAAAASSWR4Q2ZnTWF0aENvbnRyYWN0AwkAAGcAAAACBQAAAAdsb2NrRW5kBQAAAAZoZWlnaHQJAAACAAAAAQkAASwAAAACCQABLAAAAAICAAAABXdhaXQgCQABpAAAAAEFAAAAB2xvY2tFbmQCAAAACiB0byB1bmxvY2sDCQAAZwAAAAIAAAAAAAAAAAAFAAAACnVzZXJBbW91bnQJAAACAAAAAQIAAAARbm90aGluZyB0byB1bmxvY2sEAAAABnBlcmlvZAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAxtYXRoQ29udHJhY3QJAQAAAA1rZXlOZXh0UGVyaW9kAAAAAAAAAAAAAAAAAAkABE0AAAACCQAETQAAAAIJAAROAAAAAgkBAAAAD0xvY2tQYXJhbXNFbnRyeQAAAAgFAAAAC3VzZXJBZGRyZXNzBQAAAAp1c2VyTnVtU3RyAAAAAAAAAAAABQAAAAlsb2NrU3RhcnQFAAAADGxvY2tEdXJhdGlvbgAAAAAAAAAAAAAAAAAAAAAAAAkAAaQAAAABBQAAAAZwZXJpb2QJAQAAAApTdGF0c0VudHJ5AAAABAkBAAAAAS0AAAABBQAAAAp1c2VyQW1vdW50AAAAAAAAAAAAAAAAAAAAAAAAAP//////////CQEAAAAMSGlzdG9yeUVudHJ5AAAACAIAAAAGdW5sb2NrBQAAAAt1c2VyQWRkcmVzcwUAAAAKdXNlckFtb3VudAUAAAAJbG9ja1N0YXJ0BQAAAAxsb2NrRHVyYXRpb24AAAAAAAAAAAAAAAAAAAAAAAAFAAAAAWkJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAAC3VzZXJBZGRyZXNzBQAAAAp1c2VyQW1vdW50BQAAAAdhc3NldElkAAAAAWkBAAAAE2d3eFVzZXJJbmZvUkVBRE9OTFkAAAABAAAAC3VzZXJBZGRyZXNzBAAAAAlnd3hBbW91bnQJAQAAABRjYWxjQ3VycmVudEd3eEFtb3VudAAAAAEFAAAAC3VzZXJBZGRyZXNzCQAFFAAAAAIFAAAAA25pbAkABEwAAAACBQAAAAlnd3hBbW91bnQFAAAAA25pbAAAAADITtOE", "chainId": 84, "height": 1826885, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: AYr6etej1Uhd5noGisBoxk2Hyr98YQV1dykEVFcQRrZw Next: 3ZWpezVTnGgcvWUTckonuDj6ChvnjDnCXPzoRopTVFjy Diff:
OldNewDifferences
100100
101101
102102 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
103+
104+
105+func keyNextPeriod () = "%s__nextPeriod"
103106
104107
105108 let IdxCfgAssetId = 1
385388 then ((getIntOrFail(this, startBlockKEY) + getIntOrFail(this, durationKEY)) >= lockStart)
386389 else false)
387390 then throw("there is an active lock - consider to use increaseLock")
388- else {
389- let coeffX8 = fraction(duration, MULT8, maxLockDuration)
390- let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
391- let gWxParamsResultList = asAnyList(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStart, duration], nil))
392- let k = asInt(gWxParamsResultList[0])
393- let b = asInt(gWxParamsResultList[1])
394- let period = toString(asInt(gWxParamsResultList[2]))
395- let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
396- let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
397- let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
398- let h = if ((height > emissionEnd))
399- then emissionEnd
400- else height
401- let dh = max([(h - emissionStart), 0])
402- let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
403- let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
404- let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
405- let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
406- let userMaxBoostInt = ((gWxAmountStart * duration) / 2)
407- let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
408- let totalCachedGwxKEY = keyTotalCachedGwx()
409- let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
410- let arr = if (userIsExisting)
411- then nil
412- else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
413- ((((arr ++ LockParamsEntry(userAddressStr, userNumStr, pmtAmount, lockStart, duration, k, b, period)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
414- then 0
415- else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(totalCachedGwxKEY, (totalCachedGwx + gWxAmountStart))])
416- }
391+ else if ((getIntOrZero(this, userAmountKEY) > 0))
392+ then throw("there are locked WXs - consider to use increaseLock")
393+ else {
394+ let coeffX8 = fraction(duration, MULT8, maxLockDuration)
395+ let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
396+ let gWxParamsResultList = asAnyList(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStart, duration], nil))
397+ let k = asInt(gWxParamsResultList[0])
398+ let b = asInt(gWxParamsResultList[1])
399+ let period = toString(asInt(gWxParamsResultList[2]))
400+ let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
401+ let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
402+ let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
403+ let h = if ((height > emissionEnd))
404+ then emissionEnd
405+ else height
406+ let dh = max([(h - emissionStart), 0])
407+ let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
408+ let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
409+ let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
410+ let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
411+ let userMaxBoostInt = ((gWxAmountStart * duration) / 2)
412+ let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
413+ let totalCachedGwxKEY = keyTotalCachedGwx()
414+ let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
415+ let arr = if (userIsExisting)
416+ then nil
417+ else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
418+ ((((arr ++ LockParamsEntry(userAddressStr, userNumStr, pmtAmount, lockStart, duration, k, b, period)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
419+ then 0
420+ else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(totalCachedGwxKEY, (totalCachedGwx + gWxAmountStart))])
421+ }
417422 }
418423 }
419424 }
496501 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
497502 then throw("permissions denied")
498503 else {
499- let $t02462524727 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
500- let userBoostAvailable = $t02462524727._1
501- let dataState = $t02462524727._2
502- let debug = $t02462524727._3
504+ let $t02480424906 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
505+ let userBoostAvailable = $t02480424906._1
506+ let dataState = $t02480424906._2
507+ let debug = $t02480424906._3
503508 $Tuple2(dataState, [userBoostAvailable])
504509 }
505510
507512
508513 @Callable(i)
509514 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
510- let $t02485924960 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
511- let userBoostAvailable = $t02485924960._1
512- let dataState = $t02485924960._2
513- let debug = $t02485924960._3
515+ let $t02503825139 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
516+ let userBoostAvailable = $t02503825139._1
517+ let dataState = $t02503825139._2
518+ let debug = $t02503825139._3
514519 $Tuple2(nil, [userBoostAvailable, debug])
515520 }
516521
526531 let lockEnd = (lockStart + lockDuration)
527532 let cfgArray = readConfigArrayOrFail()
528533 let assetId = fromBase58String(cfgArray[IdxCfgAssetId])
534+ let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
529535 if ((lockEnd >= height))
530536 then throw((("wait " + toString(lockEnd)) + " to unlock"))
531537 else if ((0 >= userAmount))
532538 then throw("nothing to unlock")
533539 else {
534- let period = "0"
535- (((LockParamsEntry(userAddress, userNumStr, 0, lockStart, lockDuration, 0, 0, period) ++ StatsEntry(-(userAmount), 0, 0, -1)) :+ HistoryEntry("unlock", userAddress, userAmount, lockStart, lockDuration, 0, 0, i)) :+ ScriptTransfer(addressFromStringValue(userAddress), userAmount, assetId))
540+ let period = valueOrElse(getInteger(mathContract, keyNextPeriod()), 0)
541+ (((LockParamsEntry(userAddress, userNumStr, 0, lockStart, lockDuration, 0, 0, toString(period)) ++ StatsEntry(-(userAmount), 0, 0, -1)) :+ HistoryEntry("unlock", userAddress, userAmount, lockStart, lockDuration, 0, 0, i)) :+ ScriptTransfer(addressFromStringValue(userAddress), userAmount, assetId))
536542 }
537543 }
538544
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SEP = "__"
55
66 let SCALE8 = 8
77
88 let MULT8 = 100000000
99
1010 let POOLWEIGHTMULT = MULT8
1111
1212 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined"))
1313
1414
1515 func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
1616
1717
1818 func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
1919
2020
2121 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
2222
2323
2424 func asAnyList (val) = match val {
2525 case valAnyLyst: List[Any] =>
2626 valAnyLyst
2727 case _ =>
2828 throw("fail to cast into List[Any]")
2929 }
3030
3131
3232 func asInt (val) = match val {
3333 case valInt: Int =>
3434 valInt
3535 case _ =>
3636 throw("fail to cast into Int")
3737 }
3838
3939
4040 func keyFactoryAddress () = "%s%s__config__factoryAddress"
4141
4242
4343 let IdxFactoryCfgStakingDapp = 1
4444
4545 let IdxFactoryCfgBoostingDapp = 2
4646
4747 let IdxFactoryCfgIdoDapp = 3
4848
4949 let IdxFactoryCfgTeamDapp = 4
5050
5151 let IdxFactoryCfgEmissionDapp = 5
5252
5353 let IdxFactoryCfgRestDapp = 6
5454
5555 let IdxFactoryCfgSlippageDapp = 7
5656
5757 func keyFactoryCfg () = "%s__factoryConfig"
5858
5959
6060 func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
6161
6262
6363 func keyFactoryLpList () = "%s__lpTokensList"
6464
6565
6666 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
6767
6868
6969 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
7070
7171
7272 func readFactoryAddressOrFail () = addressFromStringValue(getStringOrFail(this, keyFactoryAddress()))
7373
7474
7575 func readLpList () = split(valueOrElse(getString(readFactoryAddressOrFail(), keyFactoryLpList()), ""), SEP)
7676
7777
7878 func readFactoryCfgOrFail (factory) = split(getStringOrFail(factory, keyFactoryCfg()), SEP)
7979
8080
8181 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
8282
8383
8484 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
8585
8686
8787 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
8888
8989
9090 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
9191
9292
9393 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
9494
9595
9696 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
9797
9898
9999 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
100100
101101
102102 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
103+
104+
105+func keyNextPeriod () = "%s__nextPeriod"
103106
104107
105108 let IdxCfgAssetId = 1
106109
107110 let IdxCfgMinLockAmount = 2
108111
109112 let IdxCfgMinLockDuration = 3
110113
111114 let IdxCfgMaxLockDuration = 4
112115
113116 let IdxCfgMathContract = 5
114117
115118 func keyConfig () = "%s__config"
116119
117120
118121 func readConfigArrayOrFail () = split(getStringOrFail(this, keyConfig()), SEP)
119122
120123
121124 func formatConfigS (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = makeString(["%s%d%d%d", assetId, minLockAmount, minLockDuration, maxLockDuration, mathContract], SEP)
122125
123126
124127 func formatConfig (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = formatConfigS(assetId, toString(minLockAmount), toString(minLockDuration), toString(maxLockDuration), mathContract)
125128
126129
127130 let IdxLockUserNum = 1
128131
129132 let IdxLockAmount = 2
130133
131134 let IdxLockStart = 3
132135
133136 let IdxLockDuration = 4
134137
135138 let IdxLockParamK = 5
136139
137140 let IdxLockParamB = 6
138141
139142 func keyLockParamsRecord (userAddress) = makeString(["%s%s__lock", userAddress], SEP)
140143
141144
142145 func readLockParamsRecordOrFail (userAddress) = split(getStringOrFail(this, keyLockParamsRecord(userAddress)), SEP)
143146
144147
145148 func formatLockParamsRecordS (userNum,amount,start,duration,paramK,paramB,lastUpdTimestamp,gwxAmount) = makeString(["%d%d%d%d%d%d%d%d", userNum, amount, start, duration, paramK, paramB, lastUpdTimestamp, gwxAmount], SEP)
146149
147150
148151 func formatLockParamsRecord (userNum,amount,start,duration,paramK,paramB,gwxAmount) = formatLockParamsRecordS(userNum, toString(amount), toString(start), toString(duration), toString(paramK), toString(paramB), toString(lastBlock.timestamp), toString(gwxAmount))
149152
150153
151154 func keyNextUserNum () = "%s__nextUserNum"
152155
153156
154157 func keyUser2NumMapping (userAddress) = makeString(["%s%s%s__mapping__user2num", userAddress], SEP)
155158
156159
157160 func keyNum2UserMapping (num) = makeString(["%s%s%s__mapping__num2user", num], SEP)
158161
159162
160163 func keyLockParamUserAmount (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "amount"], SEP)
161164
162165
163166 func keyLockParamStartBlock (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "start"], SEP)
164167
165168
166169 func keyLockParamDuration (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "duration"], SEP)
167170
168171
169172 func keyLockParamK (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "k"], SEP)
170173
171174
172175 func keyLockParamB (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "b"], SEP)
173176
174177
175178 func keyLockParamByPeriodK (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "k", period], SEP)
176179
177180
178181 func keyLockParamByPeriodB (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "b", period], SEP)
179182
180183
181184 func keyLockParamTotalAmount () = "%s%s__stats__activeTotalLocked"
182185
183186
184187 func keyStatsLocksDurationSumInBlocks () = "%s%s__stats__locksDurationSumInBlocks"
185188
186189
187190 func keyStatsLocksCount () = "%s%s__stats__locksCount"
188191
189192
190193 func keyStatsUsersCount () = "%s%s__stats__activeUsersCount"
191194
192195
193196 func keyUserBoostEmissionLastINTEGRAL (userNum) = makeString(["%s%d__userBoostEmissionLastInt", userNum], SEP)
194197
195198
196199 func keyUserLpBoostEmissionLastINTEGRAL (userNum,lpAssetId) = makeString(["%s%d__userBoostEmissionLastInt", userNum, lpAssetId], SEP)
197200
198201
199202 func keyUserMaxBoostINTEGRAL (userNum) = makeString(["%s%d__maxBoostInt", userNum], SEP)
200203
201204
202205 func keyTotalMaxBoostINTEGRAL () = "%s%s__maxBoostInt__total"
203206
204207
205208 func keyUserBoostAvalaibleToClaimTotal (userNum) = makeString(["%s%d__userBoostAvaliableToClaimTotal", userNum], SEP)
206209
207210
208211 func keyUserBoostClaimed (userNum) = makeString(["%s%d__userBoostClaimed", userNum], SEP)
209212
210213
211214 func keyTotalCachedGwx () = "%s%s__gwxCached__total"
212215
213216
214217 let factoryContract = readFactoryAddressOrFail()
215218
216219 let factoryCfg = readFactoryCfgOrFail(factoryContract)
217220
218221 let emissionContract = getEmissionAddressOrFail(factoryCfg)
219222
220223 let stakingContract = getStakingAddressOrFail(factoryCfg)
221224
222225 func HistoryEntry (type,user,amount,lockStart,duration,k,b,i) = {
223226 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
224227 let historyDATA = makeString(["%d%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(amount), toString(lockStart), toString(duration), toString(k), toString(b)], SEP)
225228 StringEntry(historyKEY, historyDATA)
226229 }
227230
228231
229232 func StatsEntry (totalLockedInc,durationInc,lockCountInc,usersCountInc) = {
230233 let locksDurationSumInBlocksKEY = keyStatsLocksDurationSumInBlocks()
231234 let locksCountKEY = keyStatsLocksCount()
232235 let usersCountKEY = keyStatsUsersCount()
233236 let totalAmountKEY = keyLockParamTotalAmount()
234237 let locksDurationSumInBlocks = getIntOrZero(this, locksDurationSumInBlocksKEY)
235238 let locksCount = getIntOrZero(this, locksCountKEY)
236239 let usersCount = getIntOrZero(this, usersCountKEY)
237240 let totalAmount = getIntOrZero(this, totalAmountKEY)
238241 [IntegerEntry(locksDurationSumInBlocksKEY, (locksDurationSumInBlocks + durationInc)), IntegerEntry(locksCountKEY, (locksCount + lockCountInc)), IntegerEntry(usersCountKEY, (usersCount + usersCountInc)), IntegerEntry(totalAmountKEY, (totalAmount + totalLockedInc))]
239242 }
240243
241244
242245 func calcGwxAmount (kRaw,bRaw,h) = {
243246 let SCALE = 1000
244247 (((kRaw * h) + bRaw) / SCALE)
245248 }
246249
247250
248251 func LockParamsEntry (userAddress,userNum,amount,start,duration,k,b,period) = {
249252 let userAmountKEY = keyLockParamUserAmount(userNum)
250253 let startBlockKEY = keyLockParamStartBlock(userNum)
251254 let durationKEY = keyLockParamDuration(userNum)
252255 let kKEY = keyLockParamK(userNum)
253256 let bKEY = keyLockParamB(userNum)
254257 let kByPerioKEY = keyLockParamByPeriodK(userNum, period)
255258 let bByPeriodKEY = keyLockParamByPeriodB(userNum, period)
256259 let gwxAmount = calcGwxAmount(k, b, height)
257260 [IntegerEntry(userAmountKEY, amount), IntegerEntry(startBlockKEY, start), IntegerEntry(durationKEY, duration), IntegerEntry(kKEY, k), IntegerEntry(bKEY, b), IntegerEntry(kByPerioKEY, k), IntegerEntry(bByPeriodKEY, b), StringEntry(keyLockParamsRecord(userAddress), formatLockParamsRecord(userNum, amount, start, duration, k, b, gwxAmount))]
258261 }
259262
260263
261264 func extractOptionalPaymentAmountOrFail (i,expectedAssetId) = if ((size(i.payments) > 1))
262265 then throw("only one payment is allowed")
263266 else if ((size(i.payments) == 0))
264267 then 0
265268 else {
266269 let pmt = i.payments[0]
267270 if ((value(pmt.assetId) != expectedAssetId))
268271 then throw("invalid asset id in payment")
269272 else pmt.amount
270273 }
271274
272275
273276 func calcCurrentGwxAmount (userAddress) = {
274277 let EMPTY = "empty"
275278 let user2NumMappingKEY = keyUser2NumMapping(userAddress)
276279 let userNum = valueOrElse(getString(user2NumMappingKEY), EMPTY)
277280 let k = valueOrElse(getInteger(keyLockParamK(userNum)), 0)
278281 let b = valueOrElse(getInteger(keyLockParamB(userNum)), 0)
279282 let gwxAmountCalc = calcGwxAmount(k, b, height)
280283 let gwxAmount = if ((0 > gwxAmountCalc))
281284 then 0
282285 else gwxAmountCalc
283286 gwxAmount
284287 }
285288
286289
287290 func internalClaimWxBoost (lpAssetIdStr,userAddressStr,readOnly) = {
288291 let EMPTY = "EMPTY"
289292 let userRecordOrEmpty = valueOrElse(getString(this, keyLockParamsRecord(userAddressStr)), EMPTY)
290293 if ((userRecordOrEmpty == EMPTY))
291294 then $Tuple3(0, nil, "userRecord::is::empty")
292295 else {
293296 let userRecordArray = split(userRecordOrEmpty, SEP)
294297 let userNumStr = userRecordArray[IdxLockUserNum]
295298 let EMPTYSTR = "empty"
296299 let poolWeight = if ((lpAssetIdStr != EMPTYSTR))
297300 then {
298301 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
299302 getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
300303 }
301304 else if (readOnly)
302305 then 0
303306 else throw(("not readonly mode: unsupported lp asset " + lpAssetIdStr))
304307 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
305308 let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
306309 let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
307310 let h = if ((height > emissionEnd))
308311 then emissionEnd
309312 else height
310313 let dh = max([(h - emissionStart), 0])
311314 let userLpBoostEmissionLastIntegralKEY = keyUserLpBoostEmissionLastINTEGRAL(userNumStr, lpAssetIdStr)
312315 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
313316 let userBoostEmissionLastIntegral = valueOrElse(getInteger(this, userLpBoostEmissionLastIntegralKEY), getIntOrZero(this, userBoostEmissionLastIntegralKEY))
314317 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
315318 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
316319 if ((0 > userBoostEmissionIntegral))
317320 then throw("wrong calculations")
318321 else {
319322 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
320323 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
321324 let userMaxBoostInt = getIntOrZero(this, userMaxBoostIntegralKEY)
322325 let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
323326 let totalCachedGwxKEY = keyTotalCachedGwx()
324327 let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
325328 let userCurrGwx = calcCurrentGwxAmount(userAddressStr)
326329 let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
327330 let userBoostAvaliableToClaimTotal = getIntOrZero(this, userBoostAvalaibleToClaimTotalKEY)
328331 let poolUserBoostEmissionIntegral = fraction(userBoostEmissionIntegral, poolWeight, POOLWEIGHTMULT)
329332 let userBoostAvaliableToClaimTotalNew = if ((totalCachedGwx == 0))
330333 then 0
331334 else fraction(poolUserBoostEmissionIntegral, userCurrGwx, totalCachedGwx)
332335 let userBoostClaimedKEY = keyUserBoostClaimed(userNumStr)
333336 let userBoostClaimed = getIntOrZero(this, userBoostClaimedKEY)
334337 let userBoostAvailable = (userBoostAvaliableToClaimTotalNew - userBoostClaimed)
335338 let dataState = [IntegerEntry(userLpBoostEmissionLastIntegralKEY, boostEmissionIntegral)]
336339 let debug = makeString([("userBoostEmissionLastIntegral=" + toString(userBoostEmissionLastIntegral)), ("userBoostEmissionIntegral=" + toString(userBoostEmissionIntegral)), ("userMaxBoostInt=" + toString(userMaxBoostInt)), ("totalMaxBoostInt=" + toString(totalMaxBoostInt)), ("userBoostAvaliableToClaimTotal=" + toString(userBoostAvaliableToClaimTotal)), ("userBoostAvaliableToClaimTotalNew=" + toString(userBoostAvaliableToClaimTotalNew)), ("userBoostClaimed=" + toString(userBoostClaimed)), ("userBoostAvailable=" + toString(userBoostAvailable)), ("poolUserBoostEmissionIntegral=" + toString(poolUserBoostEmissionIntegral)), ("userCurrGwx=" + toString(userCurrGwx)), ("totalCachedGwx" + toString(totalCachedGwx))], "::")
337340 $Tuple3(userBoostAvaliableToClaimTotalNew, dataState, debug)
338341 }
339342 }
340343 }
341344
342345
343346 @Callable(i)
344347 func constructor (factoryAddressStr,lockAssetIdStr,minLockAmount,minDuration,maxDuration,mathContract) = if ((this != i.caller))
345348 then throw("not authorized")
346349 else ([IntegerEntry(keyNextUserNum(), 0), StringEntry(keyConfig(), formatConfig(lockAssetIdStr, minLockAmount, minDuration, maxDuration, mathContract)), StringEntry(keyFactoryAddress(), factoryAddressStr)] ++ StatsEntry(0, 0, 0, 0))
347350
348351
349352
350353 @Callable(i)
351354 func lock (duration) = {
352355 let cfgArray = readConfigArrayOrFail()
353356 let assetIdStr = cfgArray[IdxCfgAssetId]
354357 let assetId = fromBase58String(assetIdStr)
355358 let minLockAmount = parseIntValue(cfgArray[IdxCfgMinLockAmount])
356359 let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
357360 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
358361 let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
359362 if ((size(i.payments) != 1))
360363 then throw("invalid payment - exact one payment must be attached")
361364 else {
362365 let pmt = i.payments[0]
363366 let pmtAmount = pmt.amount
364367 if ((assetId != value(pmt.assetId)))
365368 then throw((("invalid asset is in payment - " + assetIdStr) + " is expected"))
366369 else {
367370 let nextUserNumKEY = keyNextUserNum()
368371 let userAddressStr = toString(i.caller)
369372 let userIsExisting = isDefined(getString(keyUser2NumMapping(userAddressStr)))
370373 let userNumStr = if (userIsExisting)
371374 then value(getString(keyUser2NumMapping(userAddressStr)))
372375 else toString(getIntOrFail(this, nextUserNumKEY))
373376 let userNum = parseIntValue(userNumStr)
374377 let lockStart = height
375378 let startBlockKEY = keyLockParamStartBlock(userNumStr)
376379 let durationKEY = keyLockParamDuration(userNumStr)
377380 let userAmountKEY = keyLockParamUserAmount(userNumStr)
378381 if ((minLockAmount > pmtAmount))
379382 then throw(("amount is less then minLockAmount=" + toString(minLockAmount)))
380383 else if ((minLockDuration > duration))
381384 then throw(("passed duration is less then minLockDuration=" + toString(minLockDuration)))
382385 else if ((duration > maxLockDuration))
383386 then throw(("passed duration is greater then maxLockDuration=" + toString(maxLockDuration)))
384387 else if (if (userIsExisting)
385388 then ((getIntOrFail(this, startBlockKEY) + getIntOrFail(this, durationKEY)) >= lockStart)
386389 else false)
387390 then throw("there is an active lock - consider to use increaseLock")
388- else {
389- let coeffX8 = fraction(duration, MULT8, maxLockDuration)
390- let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
391- let gWxParamsResultList = asAnyList(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStart, duration], nil))
392- let k = asInt(gWxParamsResultList[0])
393- let b = asInt(gWxParamsResultList[1])
394- let period = toString(asInt(gWxParamsResultList[2]))
395- let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
396- let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
397- let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
398- let h = if ((height > emissionEnd))
399- then emissionEnd
400- else height
401- let dh = max([(h - emissionStart), 0])
402- let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
403- let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
404- let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
405- let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
406- let userMaxBoostInt = ((gWxAmountStart * duration) / 2)
407- let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
408- let totalCachedGwxKEY = keyTotalCachedGwx()
409- let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
410- let arr = if (userIsExisting)
411- then nil
412- else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
413- ((((arr ++ LockParamsEntry(userAddressStr, userNumStr, pmtAmount, lockStart, duration, k, b, period)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
414- then 0
415- else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(totalCachedGwxKEY, (totalCachedGwx + gWxAmountStart))])
416- }
391+ else if ((getIntOrZero(this, userAmountKEY) > 0))
392+ then throw("there are locked WXs - consider to use increaseLock")
393+ else {
394+ let coeffX8 = fraction(duration, MULT8, maxLockDuration)
395+ let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
396+ let gWxParamsResultList = asAnyList(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStart, duration], nil))
397+ let k = asInt(gWxParamsResultList[0])
398+ let b = asInt(gWxParamsResultList[1])
399+ let period = toString(asInt(gWxParamsResultList[2]))
400+ let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
401+ let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
402+ let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
403+ let h = if ((height > emissionEnd))
404+ then emissionEnd
405+ else height
406+ let dh = max([(h - emissionStart), 0])
407+ let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
408+ let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
409+ let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
410+ let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
411+ let userMaxBoostInt = ((gWxAmountStart * duration) / 2)
412+ let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
413+ let totalCachedGwxKEY = keyTotalCachedGwx()
414+ let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
415+ let arr = if (userIsExisting)
416+ then nil
417+ else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
418+ ((((arr ++ LockParamsEntry(userAddressStr, userNumStr, pmtAmount, lockStart, duration, k, b, period)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
419+ then 0
420+ else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(totalCachedGwxKEY, (totalCachedGwx + gWxAmountStart))])
421+ }
417422 }
418423 }
419424 }
420425
421426
422427
423428 @Callable(i)
424429 func increaseLock (deltaDuration) = {
425430 let cfgArray = readConfigArrayOrFail()
426431 let assetIdStr = cfgArray[IdxCfgAssetId]
427432 let assetId = fromBase58String(assetIdStr)
428433 let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
429434 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
430435 let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
431436 let pmtAmount = extractOptionalPaymentAmountOrFail(i, assetId)
432437 let userAddressStr = toString(i.caller)
433438 let userRecordArray = readLockParamsRecordOrFail(userAddressStr)
434439 let userNumStr = userRecordArray[IdxLockUserNum]
435440 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
436441 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
437442 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
438443 let lockEnd = (lockStart + lockDuration)
439444 let remainingDuration = max([(lockEnd - height), 0])
440445 let userAmountNew = (userAmount + pmtAmount)
441446 let lockDurationNew = (remainingDuration + deltaDuration)
442447 if ((0 > deltaDuration))
443448 then throw("duration is less then zero")
444449 else if ((minLockDuration > lockDurationNew))
445450 then throw(("lockDurationNew is less then minLockDuration=" + toString(minLockDuration)))
446451 else if ((lockDurationNew > maxLockDuration))
447452 then throw(("deltaDuration + existedLockDuration is greater then maxLockDuration=" + toString(maxLockDuration)))
448453 else {
449454 let coeffX8 = fraction(lockDurationNew, MULT8, maxLockDuration)
450455 let gWxAmountStart = fraction(userAmountNew, coeffX8, MULT8)
451456 let lockStartNew = height
452457 let gWxParamsResultList = asAnyList(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStartNew, lockDurationNew], nil))
453458 let k = asInt(gWxParamsResultList[0])
454459 let b = asInt(gWxParamsResultList[1])
455460 let period = toString(asInt(gWxParamsResultList[2]))
456461 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
457462 let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
458463 let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
459464 let h = if ((height > emissionEnd))
460465 then emissionEnd
461466 else height
462467 let dh = max([(h - emissionStart), 0])
463468 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
464469 let userBoostEmissionLastIntegral = getIntOrZero(this, userBoostEmissionLastIntegralKEY)
465470 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
466471 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
467472 if ((0 > userBoostEmissionIntegral))
468473 then throw("wrong calculations")
469474 else {
470475 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
471476 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
472477 let userMaxBoostInt = getIntOrZero(this, userMaxBoostIntegralKEY)
473478 let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
474479 let currUserGwx = calcCurrentGwxAmount(userAddressStr)
475480 let gwxDiff = (gWxAmountStart - currUserGwx)
476481 if ((0 > gwxDiff))
477482 then throw("gwxDiff is less then 0")
478483 else {
479484 let totalCachedGwxKEY = keyTotalCachedGwx()
480485 let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
481486 let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
482487 let userBoostAvaliableToClaimTotal = getIntOrZero(this, userBoostAvalaibleToClaimTotalKEY)
483488 let userBoostAvaliableToClaimTotalNew = fraction(userBoostEmissionIntegral, currUserGwx, totalCachedGwx)
484489 let userMaxBoostIntNew = ((gWxAmountStart * lockDurationNew) / 2)
485490 let remainingUserMaxBoostInt = ((currUserGwx * remainingDuration) / 2)
486491 let userMaxBoostIntDiff = (userMaxBoostIntNew - remainingUserMaxBoostInt)
487492 (((LockParamsEntry(userAddressStr, userNumStr, userAmountNew, lockStartNew, lockDurationNew, k, b, period) ++ StatsEntry(pmtAmount, deltaDuration, 0, 0)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, lockDurationNew, k, b, i)) ++ [IntegerEntry(totalCachedGwxKEY, (totalCachedGwx + gwxDiff))])
488493 }
489494 }
490495 }
491496 }
492497
493498
494499
495500 @Callable(i)
496501 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
497502 then throw("permissions denied")
498503 else {
499- let $t02462524727 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
500- let userBoostAvailable = $t02462524727._1
501- let dataState = $t02462524727._2
502- let debug = $t02462524727._3
504+ let $t02480424906 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
505+ let userBoostAvailable = $t02480424906._1
506+ let dataState = $t02480424906._2
507+ let debug = $t02480424906._3
503508 $Tuple2(dataState, [userBoostAvailable])
504509 }
505510
506511
507512
508513 @Callable(i)
509514 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
510- let $t02485924960 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
511- let userBoostAvailable = $t02485924960._1
512- let dataState = $t02485924960._2
513- let debug = $t02485924960._3
515+ let $t02503825139 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
516+ let userBoostAvailable = $t02503825139._1
517+ let dataState = $t02503825139._2
518+ let debug = $t02503825139._3
514519 $Tuple2(nil, [userBoostAvailable, debug])
515520 }
516521
517522
518523
519524 @Callable(i)
520525 func unlock (userAddress) = {
521526 let userRecordArray = readLockParamsRecordOrFail(userAddress)
522527 let userNumStr = userRecordArray[IdxLockUserNum]
523528 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
524529 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
525530 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
526531 let lockEnd = (lockStart + lockDuration)
527532 let cfgArray = readConfigArrayOrFail()
528533 let assetId = fromBase58String(cfgArray[IdxCfgAssetId])
534+ let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
529535 if ((lockEnd >= height))
530536 then throw((("wait " + toString(lockEnd)) + " to unlock"))
531537 else if ((0 >= userAmount))
532538 then throw("nothing to unlock")
533539 else {
534- let period = "0"
535- (((LockParamsEntry(userAddress, userNumStr, 0, lockStart, lockDuration, 0, 0, period) ++ StatsEntry(-(userAmount), 0, 0, -1)) :+ HistoryEntry("unlock", userAddress, userAmount, lockStart, lockDuration, 0, 0, i)) :+ ScriptTransfer(addressFromStringValue(userAddress), userAmount, assetId))
540+ let period = valueOrElse(getInteger(mathContract, keyNextPeriod()), 0)
541+ (((LockParamsEntry(userAddress, userNumStr, 0, lockStart, lockDuration, 0, 0, toString(period)) ++ StatsEntry(-(userAmount), 0, 0, -1)) :+ HistoryEntry("unlock", userAddress, userAmount, lockStart, lockDuration, 0, 0, i)) :+ ScriptTransfer(addressFromStringValue(userAddress), userAmount, assetId))
536542 }
537543 }
538544
539545
540546
541547 @Callable(i)
542548 func gwxUserInfoREADONLY (userAddress) = {
543549 let gwxAmount = calcCurrentGwxAmount(userAddress)
544550 $Tuple2(nil, [gwxAmount])
545551 }
546552
547553

github/deemru/w8io/169f3d6 
92.44 ms