tx · EJUHr7jSppSwQkf45TYcWhLryTd7J2dLckt1u7kcp85r

3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy:  -0.01000000 Waves

2021.12.02 09:54 [1816325] smart account 3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy > SELF 0.00000000 Waves

{ "type": 13, "id": "EJUHr7jSppSwQkf45TYcWhLryTd7J2dLckt1u7kcp85r", "fee": 1000000, "feeAssetId": null, "timestamp": 1638428077466, "version": 1, "sender": "3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy", "senderPublicKey": "9W33iCCNfmFxUbiC6XZcH5x7f6xfwC7Jb3BoExT5q2PV", "proofs": [ "bLthqDavSb8K1cXCcs3sAds92Y39U6y9ZkVAjCNzEau6KQnY1bb32i9H8KArtRKQTiVfoxejAm6E28HzxByRtGv" ], "script": "base64:AAIFAAAAAAAAACoIAhIICgYICAEBAQgSAwoBARIDCgEBEgMKAQgSAwoBCBIDCgEIEgMKAQgAAABTAAAAAANTRVACAAAAAl9fAAAAAAZTQ0FMRTgAAAAAAAAAAAgAAAAABU1VTFQ4AAAAAAAF9eEAAQAAAA9nZXRTdHJpbmdPckZhaWwAAAACAAAAB2FkZHJlc3MAAAADa2V5CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAHYWRkcmVzcwUAAAADa2V5CQABLAAAAAIJAAEsAAAAAgIAAAAPbWFuZGF0b3J5IHRoaXMuBQAAAANrZXkCAAAADyBpcyBub3QgZGVmaW5lZAEAAAAMZ2V0SW50T3JaZXJvAAAAAgAAAAdhZGRyZXNzAAAAA2tleQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAdhZGRyZXNzBQAAAANrZXkAAAAAAAAAAAABAAAAD2dldEludE9yRGVmYXVsdAAAAAMAAAAHYWRkcmVzcwAAAANrZXkAAAAKZGVmYXVsdFZhbAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAdhZGRyZXNzBQAAAANrZXkFAAAACmRlZmF1bHRWYWwBAAAADGdldEludE9yRmFpbAAAAAIAAAAHYWRkcmVzcwAAAANrZXkJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAdhZGRyZXNzBQAAAANrZXkJAAEsAAAAAgkAASwAAAACAgAAAA9tYW5kYXRvcnkgdGhpcy4FAAAAA2tleQIAAAAPIGlzIG5vdCBkZWZpbmVkAQAAAAlhc0FueUxpc3QAAAABAAAAA3ZhbAQAAAAHJG1hdGNoMAUAAAADdmFsAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAAlMaXN0W0FueV0EAAAACnZhbEFueUx5c3QFAAAAByRtYXRjaDAFAAAACnZhbEFueUx5c3QJAAACAAAAAQIAAAAbZmFpbCB0byBjYXN0IGludG8gTGlzdFtBbnldAQAAAAVhc0ludAAAAAEAAAADdmFsBAAAAAckbWF0Y2gwBQAAAAN2YWwDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAAGdmFsSW50BQAAAAckbWF0Y2gwBQAAAAZ2YWxJbnQJAAACAAAAAQIAAAAVZmFpbCB0byBjYXN0IGludG8gSW50AQAAABFrZXlGYWN0b3J5QWRkcmVzcwAAAAACAAAAHCVzJXNfX2NvbmZpZ19fZmFjdG9yeUFkZHJlc3MAAAAAGElkeEZhY3RvcnlDZmdTdGFraW5nRGFwcAAAAAAAAAAAAQAAAAAZSWR4RmFjdG9yeUNmZ0Jvb3N0aW5nRGFwcAAAAAAAAAAAAgAAAAAUSWR4RmFjdG9yeUNmZ0lkb0RhcHAAAAAAAAAAAAMAAAAAFUlkeEZhY3RvcnlDZmdUZWFtRGFwcAAAAAAAAAAABAAAAAAZSWR4RmFjdG9yeUNmZ0VtaXNzaW9uRGFwcAAAAAAAAAAABQAAAAAVSWR4RmFjdG9yeUNmZ1Jlc3REYXBwAAAAAAAAAAAGAAAAABlJZHhGYWN0b3J5Q2ZnU2xpcHBhZ2VEYXBwAAAAAAAAAAAHAQAAAA1rZXlGYWN0b3J5Q2ZnAAAAAAIAAAARJXNfX2ZhY3RvcnlDb25maWcBAAAAGmtleUZhY3RvcnlMcDJBc3NldHNNYXBwaW5nAAAAAQAAAApscEFzc2V0U3RyCQAEuQAAAAIJAARMAAAAAgIAAAAGJXMlcyVzCQAETAAAAAIFAAAACmxwQXNzZXRTdHIJAARMAAAAAgIAAAAebWFwcGluZ3NfX2xwQXNzZXQyUG9vbENvbnRyYWN0BQAAAANuaWwFAAAAA1NFUAEAAAAQa2V5RmFjdG9yeUxwTGlzdAAAAAACAAAAECVzX19scFRva2Vuc0xpc3QBAAAAJmtleUZhY3RvcnlMcEFzc2V0VG9Qb29sQ29udHJhY3RBZGRyZXNzAAAAAQAAAApscEFzc2V0U3RyCQAEuQAAAAIJAARMAAAAAgIAAAAGJXMlcyVzCQAETAAAAAIFAAAACmxwQXNzZXRTdHIJAARMAAAAAgIAAAAebWFwcGluZ3NfX2xwQXNzZXQyUG9vbENvbnRyYWN0BQAAAANuaWwFAAAAA1NFUAEAAAAUa2V5RmFjdG9yeVBvb2xXZWlnaHQAAAABAAAAD2NvbnRyYWN0QWRkcmVzcwkABLkAAAACCQAETAAAAAICAAAABCVzJXMJAARMAAAAAgIAAAAKcG9vbFdlaWdodAkABEwAAAACBQAAAA9jb250cmFjdEFkZHJlc3MFAAAAA25pbAUAAAADU0VQAQAAABhyZWFkRmFjdG9yeUFkZHJlc3NPckZhaWwAAAAACQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAgUAAAAEdGhpcwkBAAAAEWtleUZhY3RvcnlBZGRyZXNzAAAAAAEAAAAKcmVhZExwTGlzdAAAAAAJAAS1AAAAAgkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACCQEAAAAYcmVhZEZhY3RvcnlBZGRyZXNzT3JGYWlsAAAAAAkBAAAAEGtleUZhY3RvcnlMcExpc3QAAAAAAgAAAAAFAAAAA1NFUAEAAAAUcmVhZEZhY3RvcnlDZmdPckZhaWwAAAABAAAAB2ZhY3RvcnkJAAS1AAAAAgkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAIFAAAAB2ZhY3RvcnkJAQAAAA1rZXlGYWN0b3J5Q2ZnAAAAAAUAAAADU0VQAQAAABhnZXRCb29zdGluZ0FkZHJlc3NPckZhaWwAAAABAAAACmZhY3RvcnlDZmcJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAAGRAAAAAgUAAAAKZmFjdG9yeUNmZwUAAAAZSWR4RmFjdG9yeUNmZ0Jvb3N0aW5nRGFwcAEAAAAYZ2V0RW1pc3Npb25BZGRyZXNzT3JGYWlsAAAAAQAAAApmYWN0b3J5Q2ZnCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQABkQAAAAIFAAAACmZhY3RvcnlDZmcFAAAAGUlkeEZhY3RvcnlDZmdFbWlzc2lvbkRhcHABAAAAF2dldFN0YWtpbmdBZGRyZXNzT3JGYWlsAAAAAQAAAApmYWN0b3J5Q2ZnCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQABkQAAAAIFAAAACmZhY3RvcnlDZmcFAAAAGElkeEZhY3RvcnlDZmdTdGFraW5nRGFwcAEAAAAea2V5RW1pc3Npb25SYXRlUGVyQmxvY2tDdXJyZW50AAAAAAIAAAAbJXMlc19fcmF0ZVBlckJsb2NrX19jdXJyZW50AQAAACFrZXlFbWlzc2lvblJhdGVQZXJCbG9ja01heEN1cnJlbnQAAAAAAgAAAB4lcyVzX19yYXRlUGVyQmxvY2tNYXhfX2N1cnJlbnQBAAAAFWtleUVtaXNzaW9uU3RhcnRCbG9jawAAAAACAAAAGiVzJXNfX2VtaXNzaW9uX19zdGFydEJsb2NrAQAAABtrZXlFbWlzc2lvbkR1cmF0aW9uSW5CbG9ja3MAAAAAAgAAABglcyVzX19lbWlzc2lvbl9fZHVyYXRpb24BAAAAE2tleUVtaXNzaW9uRW5kQmxvY2sAAAAAAgAAABglcyVzX19lbWlzc2lvbl9fZW5kQmxvY2sAAAAADUlkeENmZ0Fzc2V0SWQAAAAAAAAAAAEAAAAAE0lkeENmZ01pbkxvY2tBbW91bnQAAAAAAAAAAAIAAAAAFUlkeENmZ01pbkxvY2tEdXJhdGlvbgAAAAAAAAAAAwAAAAAVSWR4Q2ZnTWF4TG9ja0R1cmF0aW9uAAAAAAAAAAAEAAAAABJJZHhDZmdNYXRoQ29udHJhY3QAAAAAAAAAAAUBAAAACWtleUNvbmZpZwAAAAACAAAACiVzX19jb25maWcBAAAAFXJlYWRDb25maWdBcnJheU9yRmFpbAAAAAAJAAS1AAAAAgkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAIFAAAABHRoaXMJAQAAAAlrZXlDb25maWcAAAAABQAAAANTRVABAAAADWZvcm1hdENvbmZpZ1MAAAAFAAAAB2Fzc2V0SWQAAAANbWluTG9ja0Ftb3VudAAAAA9taW5Mb2NrRHVyYXRpb24AAAAPbWF4TG9ja0R1cmF0aW9uAAAADG1hdGhDb250cmFjdAkABLkAAAACCQAETAAAAAICAAAACCVzJWQlZCVkCQAETAAAAAIFAAAAB2Fzc2V0SWQJAARMAAAAAgUAAAANbWluTG9ja0Ftb3VudAkABEwAAAACBQAAAA9taW5Mb2NrRHVyYXRpb24JAARMAAAAAgUAAAAPbWF4TG9ja0R1cmF0aW9uCQAETAAAAAIFAAAADG1hdGhDb250cmFjdAUAAAADbmlsBQAAAANTRVABAAAADGZvcm1hdENvbmZpZwAAAAUAAAAHYXNzZXRJZAAAAA1taW5Mb2NrQW1vdW50AAAAD21pbkxvY2tEdXJhdGlvbgAAAA9tYXhMb2NrRHVyYXRpb24AAAAMbWF0aENvbnRyYWN0CQEAAAANZm9ybWF0Q29uZmlnUwAAAAUF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AAAAHSVzJXNfX3N0YXRzX19hY3RpdmVVc2Vyc0NvdW50AQAAACBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAAAAAEAAAAHdXNlck51bQkABLkAAAACCQAETAAAAAICAAAAHiVzJWRfX3VzZXJCb29zdEVtaXNzaW9uTGFzdEludAkABEwAAAACBQAAAAd1c2VyTnVtBQAAAANuaWwFAAAAA1NFUAEAAAAXa2V5VXNlck1heEJvb3N0SU5URUdSQUwAAAABAAAAB3VzZXJOdW0JAAS5AAAAAgkABEwAAAACAgAAABElcyVkX19tYXhCb29zdEludAkABEwAAAACBQAAAAd1c2VyTnVtBQAAAANuaWwFAAAAA1NFUAEAAAAYa2V5VG90YWxNYXhCb29zdElOVEVHUkFMAAAAAAIAAAAYJXMlc19fbWF4Qm9vc3RJbnRfX3RvdGFsAQAAACFrZXlVc2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWwAAAABAAAAB3VzZXJOdW0JAAS5AAAAAgkABEwAAAACAgAAACQlcyVkX191c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWwJAARMAAAAAgUAAAAHdXNlck51bQUAAAADbmlsBQAAAANTRVABAAAAE2tleVVzZXJCb29zdENsYWltZWQAAAABAAAAB3VzZXJOdW0JAAS5AAAAAgkABEwAAAACAgAAABYlcyVkX191c2VyQm9vc3RDbGFpbWVkCQAETAAAAAIFAAAAB3VzZXJOdW0FAAAAA25pbAUAAAADU0VQAQAAABFrZXlUb3RhbENhY2hlZEd3eAAAAAACAAAAFiVzJXNfX2d3eENhY2hlZF9fdG90YWwAAAAAD2ZhY3RvcnlDb250cmFjdAkBAAAAGHJlYWRGYWN0b3J5QWRkcmVzc09yRmFpbAAAAAAAAAAACmZhY3RvcnlDZmcJAQAAABRyZWFkRmFjdG9yeUNmZ09yRmFpbAAAAAEFAAAAD2ZhY3RvcnlDb250cmFjdAAAAAAQZW1pc3Npb25Db250cmFjdAkBAAAAGGdldEVtaXNzaW9uQWRkcmVzc09yRmFpbAAAAAEFAAAACmZhY3RvcnlDZmcAAAAAD3N0YWtpbmdDb250cmFjdAkBAAAAF2dldFN0YWtpbmdBZGRyZXNzT3JGYWlsAAAAAQUAAAAKZmFjdG9yeUNmZwEAAAAMSGlzdG9yeUVudHJ5AAAACAAAAAR0eXBlAAAABHVzZXIAAAAGYW1vdW50AAAACWxvY2tTdGFydAAAAAhkdXJhdGlvbgAAAAFrAAAAAWIAAAABaQQAAAAKaGlzdG9yeUtFWQkABLkAAAACCQAETAAAAAICAAAAESVzJXMlcyVzX19oaXN0b3J5CQAETAAAAAIFAAAABHR5cGUJAARMAAAAAgUAAAAEdXNlcgkABEwAAAACCQACWAAAAAEIBQAAAAFpAAAADXRyYW5zYWN0aW9uSWQFAAAAA25pbAUAAAADU0VQBAAAAAtoaXN0b3J5REFUQQkABLkAAAACCQAETAAAAAICAAAADiVkJWQlZCVkJWQlZCVkCQAETAAAAAIJAAGkAAAAAQgFAAAACWxhc3RCbG9jawAAAAZoZWlnaHQJAARMAAAAAgkAAaQAAAABCAUAAAAJbGFzdEJsb2NrAAAACXRpbWVzdGFtcAkABEwAAAACCQABpAAAAAEFAAAABmFtb3VudAkABEwAAAACCQABpAAAAAEFAAAACWxvY2tTdGFydAkABEwAAAACCQABpAAAAAEFAAAACGR1cmF0aW9uCQAETAAAAAIJAAGkAAAAAQUAAAABawkABEwAAAACCQABpAAAAAEFAAAAAWIFAAAAA25pbAUAAAADU0VQCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAApoaXN0b3J5S0VZBQAAAAtoaXN0b3J5REFUQQEAAAAKU3RhdHNFbnRyeQAAAAQAAAAOdG90YWxMb2NrZWRJbmMAAAALZHVyYXRpb25JbmMAAAAMbG9ja0NvdW50SW5jAAAADXVzZXJzQ291bnRJbmMEAAAAG2xvY2tzRHVyYXRpb25TdW1JbkJsb2Nrc0tFWQkBAAAAIGtleVN0YXRzTG9ja3NEdXJhdGlvblN1bUluQmxvY2tzAAAAAAQAAAANbG9ja3NDb3VudEtFWQkBAAAAEmtleVN0YXRzTG9ja3NDb3VudAAAAAAEAAAADXVzZXJzQ291bnRLRVkJAQAAABJrZXlTdGF0c1VzZXJzQ291bnQAAAAABAAAAA50b3RhbEFtb3VudEtFWQkBAAAAF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAAAAAQAAAAYbG9ja3NEdXJhdGlvblN1bUluQmxvY2tzCQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAbbG9ja3NEdXJhdGlvblN1bUluQmxvY2tzS0VZBAAAAApsb2Nrc0NvdW50CQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAANbG9ja3NDb3VudEtFWQQAAAAKdXNlcnNDb3VudAkBAAAADGdldEludE9yWmVybwAAAAIFAAAABHRoaXMFAAAADXVzZXJzQ291bnRLRVkEAAAAC3RvdGFsQW1vdW50CQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAOdG90YWxBbW91bnRLRVkJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAG2xvY2tzRHVyYXRpb25TdW1JbkJsb2Nrc0tFWQkAAGQAAAACBQAAABhsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MFAAAAC2R1cmF0aW9uSW5jCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA1sb2Nrc0NvdW50S0VZCQAAZAAAAAIFAAAACmxvY2tzQ291bnQFAAAADGxvY2tDb3VudEluYwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAANdXNlcnNDb3VudEtFWQkAAGQAAAACBQAAAAp1c2Vyc0NvdW50BQAAAA11c2Vyc0NvdW50SW5jCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA50b3RhbEFtb3VudEtFWQkAAGQAAAACBQAAAAt0b3RhbEFtb3VudAUAAAAOdG90YWxMb2NrZWRJbmMFAAAAA25pbAEAAAANY2FsY0d3eEFtb3VudAAAAAMAAAAEa1JhdwAAAARiUmF3AAAAAWgEAAAABVNDQUxFAAAAAAAAAAPoCQAAaQAAAAIJAABkAAAAAgkAAGgAAAACBQAAAARrUmF3BQAAAAFoBQAAAARiUmF3BQAAAAVTQ0FMRQEAAAAPTG9ja1BhcmFtc0VudHJ5AAAACAAAAAt1c2VyQWRkcmVzcwAAAAd1c2VyTnVtAAAABmFtb3VudAAAAAVzdGFydAAAAAhkdXJhdGlvbgAAAAFrAAAAAWIAAAAGcGVyaW9kBAAAAA11c2VyQW1vdW50S0VZCQEAAAAWa2V5TG9ja1BhcmFtVXNlckFtb3VudAAAAAEFAAAAB3VzZXJOdW0EAAAADXN0YXJ0QmxvY2tLRVkJAQAAABZrZXlMb2NrUGFyYW1TdGFydEJsb2NrAAAAAQUAAAAHdXNlck51bQQAAAALZHVyYXRpb25LRVkJAQAAABRrZXlMb2NrUGFyYW1EdXJhdGlvbgAAAAEFAAAAB3VzZXJOdW0EAAAABGtLRVkJAQAAAA1rZXlMb2NrUGFyYW1LAAAAAQUAAAAHdXNlck51bQQAAAAEYktFWQkBAAAADWtleUxvY2tQYXJhbUIAAAABBQAAAAd1c2VyTnVtBAAAAAtrQnlQZXJpb0tFWQkBAAAAFWtleUxvY2tQYXJhbUJ5UGVyaW9kSwAAAAIFAAAAB3VzZXJOdW0FAAAABnBlcmlvZAQAAAAMYkJ5UGVyaW9kS0VZCQEAAAAVa2V5TG9ja1BhcmFtQnlQZXJpb2RCAAAAAgUAAAAHdXNlck51bQUAAAAGcGVyaW9kBAAAAAlnd3hBbW91bnQJAQAAAA1jYWxjR3d4QW1vdW50AAAAAwUAAAABawUAAAABYgUAAAAGaGVpZ2h0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA11c2VyQW1vdW50S0VZBQAAAAZhbW91bnQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAADXN0YXJ0QmxvY2tLRVkFAAAABXN0YXJ0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtkdXJhdGlvbktFWQUAAAAIZHVyYXRpb24JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAABGtLRVkFAAAAAWsJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAABGJLRVkFAAAAAWIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tCeVBlcmlvS0VZBQAAAAFrCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAxiQnlQZXJpb2RLRVkFAAAAAWIJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAE2tleUxvY2tQYXJhbXNSZWNvcmQAAAABBQAAAAt1c2VyQWRkcmVzcwkBAAAAFmZvcm1hdExvY2tQYXJhbXNSZWNvcmQAAAAHBQAAAAd1c2VyTnVtBQAAAAZhbW91bnQFAAAABXN0YXJ0BQAAAAhkdXJhdGlvbgUAAAABawUAAAABYgUAAAAJZ3d4QW1vdW50BQAAAANuaWwBAAAAImV4dHJhY3RPcHRpb25hbFBheW1lbnRBbW91bnRPckZhaWwAAAACAAAAAWkAAAAPZXhwZWN0ZWRBc3NldElkAwkAAGYAAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABCQAAAgAAAAECAAAAG29ubHkgb25lIHBheW1lbnQgaXMgYWxsb3dlZAMJAAAAAAAAAgkAAZAAAAABCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAAAAAAAAAQAAAADcG10CQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAwkBAAAAAiE9AAAAAgkBAAAABXZhbHVlAAAAAQgFAAAAA3BtdAAAAAdhc3NldElkBQAAAA9leHBlY3RlZEFzc2V0SWQJAAACAAAAAQIAAAAbaW52YWxpZCBhc3NldCBpZCBpbiBwYXltZW50CAUAAAADcG10AAAABmFtb3VudAEAAAAUY2FsY0N1cnJlbnRHd3hBbW91bnQAAAABAAAAC3VzZXJBZGRyZXNzBAAAAAVFTVBUWQIAAAAFZW1wdHkEAAAAEnVzZXIyTnVtTWFwcGluZ0tFWQkBAAAAEmtleVVzZXIyTnVtTWFwcGluZwAAAAEFAAAAC3VzZXJBZGRyZXNzBAAAAAd1c2VyTnVtCQEAAAALdmFsdWVPckVsc2UAAAACCQAEIgAAAAEFAAAAEnVzZXIyTnVtTWFwcGluZ0tFWQUAAAAFRU1QVFkEAAAAAWsJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQfAAAAAQkBAAAADWtleUxvY2tQYXJhbUsAAAABBQAAAAd1c2VyTnVtAAAAAAAAAAAABAAAAAFiCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHwAAAAEJAQAAAA1rZXlMb2NrUGFyYW1CAAAAAQUAAAAHdXNlck51bQAAAAAAAAAAAAQAAAANZ3d4QW1vdW50Q2FsYwkBAAAADWNhbGNHd3hBbW91bnQAAAADBQAAAAFrBQAAAAFiBQAAAAZoZWlnaHQEAAAACWd3eEFtb3VudAMJAABmAAAAAgAAAAAAAAAAAAUAAAANZ3d4QW1vdW50Q2FsYwAAAAAAAAAAAAUAAAANZ3d4QW1vdW50Q2FsYwUAAAAJZ3d4QW1vdW50AQAAABRpbnRlcm5hbENsYWltV3hCb29zdAAAAAEAAAAOdXNlckFkZHJlc3NTdHIEAAAABUVNUFRZAgAAAAVFTVBUWQQAAAARdXNlclJlY29yZE9yRW1wdHkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwkBAAAAE2tleUxvY2tQYXJhbXNSZWNvcmQAAAABBQAAAA51c2VyQWRkcmVzc1N0cgUAAAAFRU1QVFkDCQAAAAAAAAIFAAAAEXVzZXJSZWNvcmRPckVtcHR5BQAAAAVFTVBUWQkABRUAAAADAAAAAAAAAAAABQAAAANuaWwCAAAAFXVzZXJSZWNvcmQ6OmlzOjplbXB0eQQAAAAPdXNlclJlY29yZEFycmF5CQAEtQAAAAIFAAAAEXVzZXJSZWNvcmRPckVtcHR5BQAAAANTRVAEAAAACnVzZXJOdW1TdHIJAAGRAAAAAgUAAAAPdXNlclJlY29yZEFycmF5BQAAAA5JZHhMb2NrVXNlck51bQQAAAASd3hFbWlzc2lvblBlckJsb2NrCQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAQZW1pc3Npb25Db250cmFjdAkBAAAAHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAAAAAEAAAADWVtaXNzaW9uU3RhcnQJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAAVa2V5RW1pc3Npb25TdGFydEJsb2NrAAAAAAQAAAALZW1pc3Npb25FbmQJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAATa2V5RW1pc3Npb25FbmRCbG9jawAAAAAEAAAAAWgDCQAAZgAAAAIFAAAABmhlaWdodAUAAAALZW1pc3Npb25FbmQFAAAAC2VtaXNzaW9uRW5kBQAAAAZoZWlnaHQEAAAAAmRoCQABlgAAAAEJAARMAAAAAgkAAGUAAAACBQAAAAFoBQAAAA1lbWlzc2lvblN0YXJ0CQAETAAAAAIAAAAAAAAAAAAFAAAAA25pbAQAAAAgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJAQAAACBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAAAAAEFAAAACnVzZXJOdW1TdHIEAAAAHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsCQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkEAAAAFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAAGkAAAACCQAAaAAAAAIJAABoAAAAAgUAAAASd3hFbWlzc2lvblBlckJsb2NrBQAAAAJkaAAAAAAAAAAAAgAAAAAAAAAAAwQAAAAZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAAGUAAAACBQAAABVib29zdEVtaXNzaW9uSW50ZWdyYWwFAAAAHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsAwkAAGYAAAACAAAAAAAAAAAABQAAABl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsCQAAAgAAAAECAAAAEndyb25nIGNhbGN1bGF0aW9ucwQAAAAXdXNlck1heEJvb3N0SW50ZWdyYWxLRVkJAQAAABdrZXlVc2VyTWF4Qm9vc3RJTlRFR1JBTAAAAAEFAAAACnVzZXJOdW1TdHIEAAAAGHRvdGFsTWF4Qm9vc3RJbnRlZ3JhbEtFWQkBAAAAGGtleVRvdGFsTWF4Qm9vc3RJTlRFR1JBTAAAAAAEAAAAD3VzZXJNYXhCb29zdEludAkBAAAADGdldEludE9yWmVybwAAAAIFAAAABHRoaXMFAAAAF3VzZXJNYXhCb29zdEludGVncmFsS0VZBAAAABB0b3RhbE1heEJvb3N0SW50CQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAYdG90YWxNYXhCb29zdEludGVncmFsS0VZBAAAABF0b3RhbENhY2hlZEd3eEtFWQkBAAAAEWtleVRvdGFsQ2FjaGVkR3d4AAAAAAQAAAAOdG90YWxDYWNoZWRHd3gJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAARdG90YWxDYWNoZWRHd3hLRVkAAAAAAAAAAAAEAAAAC3VzZXJDdXJyR3d4CQEAAAAUY2FsY0N1cnJlbnRHd3hBbW91bnQAAAABBQAAAA51c2VyQWRkcmVzc1N0cgQAAAAhdXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsS0VZCQEAAAAha2V5VXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsAAAAAQUAAAAKdXNlck51bVN0cgQAAAAedXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsCQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAhdXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsS0VZBAAAACF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcJAABkAAAAAgUAAAAedXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsAwkAAAAAAAACBQAAAA50b3RhbENhY2hlZEd3eAAAAAAAAAAAAAAAAAAAAAAAAAkAAGsAAAADBQAAABl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsBQAAAAt1c2VyQ3Vyckd3eAUAAAAOdG90YWxDYWNoZWRHd3gEAAAAE3VzZXJCb29zdENsYWltZWRLRVkJAQAAABNrZXlVc2VyQm9vc3RDbGFpbWVkAAAAAQUAAAAKdXNlck51bVN0cgQAAAAQdXNlckJvb3N0Q2xhaW1lZAkBAAAADGdldEludE9yWmVybwAAAAIFAAAABHRoaXMFAAAAE3VzZXJCb29zdENsYWltZWRLRVkEAAAAEnVzZXJCb29zdEF2YWlsYWJsZQkAAGUAAAACBQAAACF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcFAAAAEHVzZXJCb29zdENsYWltZWQEAAAACWRhdGFTdGF0ZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAhdXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsS0VZBQAAACF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAIHVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZBQAAABVib29zdEVtaXNzaW9uSW50ZWdyYWwFAAAAA25pbAQAAAAFZGVidWcJAAS5AAAAAgkABEwAAAACCQABLAAAAAICAAAAHnVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsPQkAAaQAAAABBQAAAB11c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbAkABEwAAAACCQABLAAAAAICAAAAGnVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWw9CQABpAAAAAEFAAAAGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwJAARMAAAAAgkAASwAAAACAgAAABB1c2VyTWF4Qm9vc3RJbnQ9CQABpAAAAAEFAAAAD3VzZXJNYXhCb29zdEludAkABEwAAAACCQABLAAAAAICAAAAEXRvdGFsTWF4Qm9vc3RJbnQ9CQABpAAAAAEFAAAAEHRvdGFsTWF4Qm9vc3RJbnQJAARMAAAAAgkAASwAAAACAgAAAB91c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWw9CQABpAAAAAEFAAAAHnVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbAkABEwAAAACCQABLAAAAAICAAAAInVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbE5ldz0JAAGkAAAAAQUAAAAhdXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsTmV3CQAETAAAAAIJAAEsAAAAAgIAAAARdXNlckJvb3N0Q2xhaW1lZD0JAAGkAAAAAQUAAAAQdXNlckJvb3N0Q2xhaW1lZAkABEwAAAACCQABLAAAAAICAAAAE3VzZXJCb29zdEF2YWlsYWJsZT0JAAGkAAAAAQUAAAASdXNlckJvb3N0QXZhaWxhYmxlBQAAAANuaWwCAAAAAjo6CQAFFQAAAAMFAAAAEnVzZXJCb29zdEF2YWlsYWJsZQUAAAAJZGF0YVN0YXRlBQAAAAVkZWJ1ZwAAAAcAAAABaQEAAAALY29uc3RydWN0b3IAAAAGAAAAEWZhY3RvcnlBZGRyZXNzU3RyAAAADmxvY2tBc3NldElkU3RyAAAADW1pbkxvY2tBbW91bnQAAAALbWluRHVyYXRpb24AAAALbWF4RHVyYXRpb24AAAAMbWF0aENvbnRyYWN0AwkBAAAAAiE9AAAAAgUAAAAEdGhpcwgFAAAAAWkAAAAGY2FsbGVyCQAAAgAAAAECAAAADm5vdCBhdXRob3JpemVkCQAETgAAAAIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA5rZXlOZXh0VXNlck51bQAAAAAAAAAAAAAAAAAJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAACWtleUNvbmZpZwAAAAAJAQAAAAxmb3JtYXRDb25maWcAAAAFBQAAAA5sb2NrQXNzZXRJZFN0cgUAAAANbWluTG9ja0Ftb3VudAUAAAALbWluRHVyYXRpb24FAAAAC21heER1cmF0aW9uBQAAAAxtYXRoQ29udHJhY3QJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAEWtleUZhY3RvcnlBZGRyZXNzAAAAAAUAAAARZmFjdG9yeUFkZHJlc3NTdHIFAAAAA25pbAkBAAAAClN0YXRzRW50cnkAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWkBAAAABGxvY2sAAAABAAAACGR1cmF0aW9uBAAAAAhjZmdBcnJheQkBAAAAFXJlYWRDb25maWdBcnJheU9yRmFpbAAAAAAEAAAACmFzc2V0SWRTdHIJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAADUlkeENmZ0Fzc2V0SWQEAAAAB2Fzc2V0SWQJAAJZAAAAAQUAAAAKYXNzZXRJZFN0cgQAAAANbWluTG9ja0Ftb3VudAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABNJZHhDZmdNaW5Mb2NrQW1vdW50BAAAAA9taW5Mb2NrRHVyYXRpb24JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAhjZmdBcnJheQUAAAAVSWR4Q2ZnTWluTG9ja0R1cmF0aW9uBAAAAA9tYXhMb2NrRHVyYXRpb24JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAhjZmdBcnJheQUAAAAVSWR4Q2ZnTWF4TG9ja0R1cmF0aW9uBAAAAAxtYXRoQ29udHJhY3QJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAAEklkeENmZ01hdGhDb250cmFjdAMJAQAAAAIhPQAAAAIJAAGQAAAAAQgFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAEJAAACAAAAAQIAAAA0aW52YWxpZCBwYXltZW50IC0gZXhhY3Qgb25lIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQAAAADcG10CQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAABAAAAAlwbXRBbW91bnQIBQAAAANwbXQAAAAGYW1vdW50AwkBAAAAAiE9AAAAAgUAAAAHYXNzZXRJZAkBAAAABXZhbHVlAAAAAQgFAAAAA3BtdAAAAAdhc3NldElkCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAAB5pbnZhbGlkIGFzc2V0IGlzIGluIHBheW1lbnQgLSAFAAAACmFzc2V0SWRTdHICAAAADCBpcyBleHBlY3RlZAQAAAAObmV4dFVzZXJOdW1LRVkJAQAAAA5rZXlOZXh0VXNlck51bQAAAAAEAAAADnVzZXJBZGRyZXNzU3RyCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAAOdXNlcklzRXhpc3RpbmcJAQAAAAlpc0RlZmluZWQAAAABCQAEIgAAAAEJAQAAABJrZXlVc2VyMk51bU1hcHBpbmcAAAABBQAAAA51c2VyQWRkcmVzc1N0cgQAAAAKdXNlck51bVN0cgMFAAAADnVzZXJJc0V4aXN0aW5nCQEAAAAFdmFsdWUAAAABCQAEIgAAAAEJAQAAABJrZXlVc2VyMk51bU1hcHBpbmcAAAABBQAAAA51c2VyQWRkcmVzc1N0cgkAAaQAAAABCQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAEdGhpcwUAAAAObmV4dFVzZXJOdW1LRVkEAAAAB3VzZXJOdW0JAQAAAA1wYXJzZUludFZhbHVlAAAAAQUAAAAKdXNlck51bVN0cgQAAAAJbG9ja1N0YXJ0BQAAAAZoZWlnaHQEAAAADXN0YXJ0QmxvY2tLRVkJAQAAABZrZXlMb2NrUGFyYW1TdGFydEJsb2NrAAAAAQUAAAAKdXNlck51bVN0cgQAAAALZHVyYXRpb25LRVkJAQAAABRrZXlMb2NrUGFyYW1EdXJhdGlvbgAAAAEFAAAACnVzZXJOdW1TdHIEAAAADXVzZXJBbW91bnRLRVkJAQAAABZrZXlMb2NrUGFyYW1Vc2VyQW1vdW50AAAAAQUAAAAKdXNlck51bVN0cgMJAABmAAAAAgUAAAANbWluTG9ja0Ftb3VudAUAAAAJcG10QW1vdW50CQAAAgAAAAEJAAEsAAAAAgIAAAAiYW1vdW50IGlzIGxlc3MgdGhlbiBtaW5Mb2NrQW1vdW50PQkAAaQAAAABBQAAAA1taW5Mb2NrQW1vdW50AwkAAGYAAAACBQAAAA9taW5Mb2NrRHVyYXRpb24FAAAACGR1cmF0aW9uCQAAAgAAAAEJAAEsAAAAAgIAAAAtcGFzc2VkIGR1cmF0aW9uIGlzIGxlc3MgdGhlbiBtaW5Mb2NrRHVyYXRpb249CQABpAAAAAEFAAAAD21pbkxvY2tEdXJhdGlvbgMJAABmAAAAAgUAAAAIZHVyYXRpb24FAAAAD21heExvY2tEdXJhdGlvbgkAAAIAAAABCQABLAAAAAICAAAAMHBhc3NlZCBkdXJhdGlvbiBpcyBncmVhdGVyIHRoZW4gbWF4TG9ja0R1cmF0aW9uPQkAAaQAAAABBQAAAA9tYXhMb2NrRHVyYXRpb24DAwUAAAAOdXNlcklzRXhpc3RpbmcJAABnAAAAAgkAAGQAAAACCQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAEdGhpcwUAAAANc3RhcnRCbG9ja0tFWQkBAAAADGdldEludE9yRmFpbAAAAAIFAAAABHRoaXMFAAAAC2R1cmF0aW9uS0VZBQAAAAlsb2NrU3RhcnQHCQAAAgAAAAECAAAANnRoZXJlIGlzIGFuIGFjdGl2ZSBsb2NrIC0gY29uc2lkZXIgdG8gdXNlIGluY3JlYXNlTG9jawQAAAAHY29lZmZYOAkAAGsAAAADBQAAAAhkdXJhdGlvbgUAAAAFTVVMVDgFAAAAD21heExvY2tEdXJhdGlvbgQAAAAOZ1d4QW1vdW50U3RhcnQJAABrAAAAAwUAAAAJcG10QW1vdW50BQAAAAdjb2VmZlg4BQAAAAVNVUxUOAQAAAATZ1d4UGFyYW1zUmVzdWx0TGlzdAkBAAAACWFzQW55TGlzdAAAAAEJAAP8AAAABAUAAAAMbWF0aENvbnRyYWN0AgAAABVjYWxjR3d4UGFyYW1zUkVBRE9OTFkJAARMAAAAAgUAAAAOZ1d4QW1vdW50U3RhcnQJAARMAAAAAgUAAAAJbG9ja1N0YXJ0CQAETAAAAAIFAAAACGR1cmF0aW9uBQAAAANuaWwFAAAAA25pbAQAAAABawkBAAAABWFzSW50AAAAAQkAAZEAAAACBQAAABNnV3hQYXJhbXNSZXN1bHRMaXN0AAAAAAAAAAAABAAAAAFiCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAAE2dXeFBhcmFtc1Jlc3VsdExpc3QAAAAAAAAAAAEEAAAABnBlcmlvZAkAAaQAAAABCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAAE2dXeFBhcmFtc1Jlc3VsdExpc3QAAAAAAAAAAAIEAAAAEnd4RW1pc3Npb25QZXJCbG9jawkBAAAADGdldEludE9yRmFpbAAAAAIFAAAAEGVtaXNzaW9uQ29udHJhY3QJAQAAAB5rZXlFbWlzc2lvblJhdGVQZXJCbG9ja0N1cnJlbnQAAAAABAAAAA1lbWlzc2lvblN0YXJ0CQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAQZW1pc3Npb25Db250cmFjdAkBAAAAFWtleUVtaXNzaW9uU3RhcnRCbG9jawAAAAAEAAAAC2VtaXNzaW9uRW5kCQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAQZW1pc3Npb25Db250cmFjdAkBAAAAE2tleUVtaXNzaW9uRW5kQmxvY2sAAAAABAAAAAFoAwkAAGYAAAACBQAAAAZoZWlnaHQFAAAAC2VtaXNzaW9uRW5kBQAAAAtlbWlzc2lvbkVuZAUAAAAGaGVpZ2h0BAAAAAJkaAkAAZYAAAABCQAETAAAAAIJAABlAAAAAgUAAAABaAUAAAANZW1pc3Npb25TdGFydAkABEwAAAACAAAAAAAAAAAABQAAAANuaWwEAAAAIHVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZCQEAAAAga2V5VXNlckJvb3N0RW1pc3Npb25MYXN0SU5URUdSQUwAAAABBQAAAAp1c2VyTnVtU3RyBAAAABVib29zdEVtaXNzaW9uSW50ZWdyYWwJAABpAAAAAgkAAGgAAAACCQAAaAAAAAIFAAAAEnd4RW1pc3Npb25QZXJCbG9jawUAAAACZGgAAAAAAAAAAAIAAAAAAAAAAAMEAAAAF3VzZXJNYXhCb29zdEludGVncmFsS0VZCQEAAAAXa2V5VXNlck1heEJvb3N0SU5URUdSQUwAAAABBQAAAAp1c2VyTnVtU3RyBAAAABh0b3RhbE1heEJvb3N0SW50ZWdyYWxLRVkJAQAAABhrZXlUb3RhbE1heEJvb3N0SU5URUdSQUwAAAAABAAAAA91c2VyTWF4Qm9vc3RJbnQJAABpAAAAAgkAAGgAAAACBQAAAA5nV3hBbW91bnRTdGFydAUAAAAIZHVyYXRpb24AAAAAAAAAAAIEAAAAEHRvdGFsTWF4Qm9vc3RJbnQJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAABh0b3RhbE1heEJvb3N0SW50ZWdyYWxLRVkEAAAAEXRvdGFsQ2FjaGVkR3d4S0VZCQEAAAARa2V5VG90YWxDYWNoZWRHd3gAAAAABAAAAA50b3RhbENhY2hlZEd3eAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAABF0b3RhbENhY2hlZEd3eEtFWQAAAAAAAAAAAAQAAAADYXJyAwUAAAAOdXNlcklzRXhpc3RpbmcFAAAAA25pbAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAObmV4dFVzZXJOdW1LRVkJAABkAAAAAgUAAAAHdXNlck51bQAAAAAAAAAAAQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAASa2V5VXNlcjJOdW1NYXBwaW5nAAAAAQUAAAAOdXNlckFkZHJlc3NTdHIFAAAACnVzZXJOdW1TdHIJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAEmtleU51bTJVc2VyTWFwcGluZwAAAAEFAAAACnVzZXJOdW1TdHIFAAAADnVzZXJBZGRyZXNzU3RyBQAAAANuaWwJAAROAAAAAgkABE0AAAACCQAETgAAAAIJAAROAAAAAgUAAAADYXJyCQEAAAAPTG9ja1BhcmFtc0VudHJ5AAAACAUAAAAOdXNlckFkZHJlc3NTdHIFAAAACnVzZXJOdW1TdHIFAAAACXBtdEFtb3VudAUAAAAJbG9ja1N0YXJ0BQAAAAhkdXJhdGlvbgUAAAABawUAAAABYgUAAAAGcGVyaW9kCQEAAAAKU3RhdHNFbnRyeQAAAAQFAAAACXBtdEFtb3VudAUAAAAIZHVyYXRpb24AAAAAAAAAAAEDBQAAAA51c2VySXNFeGlzdGluZwAAAAAAAAAAAAAAAAAAAAAAAQkBAAAADEhpc3RvcnlFbnRyeQAAAAgCAAAABGxvY2sFAAAADnVzZXJBZGRyZXNzU3RyBQAAAAlwbXRBbW91bnQFAAAACWxvY2tTdGFydAUAAAAIZHVyYXRpb24FAAAAAWsFAAAAAWIFAAAAAWkJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAIHVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZBQAAABVib29zdEVtaXNzaW9uSW50ZWdyYWwJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEXRvdGFsQ2FjaGVkR3d4S0VZCQAAZAAAAAIFAAAADnRvdGFsQ2FjaGVkR3d4BQAAAA5nV3hBbW91bnRTdGFydAUAAAADbmlsAAAAAWkBAAAADGluY3JlYXNlTG9jawAAAAEAAAANZGVsdGFEdXJhdGlvbgQAAAAIY2ZnQXJyYXkJAQAAABVyZWFkQ29uZmlnQXJyYXlPckZhaWwAAAAABAAAAAphc3NldElkU3RyCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAAA1JZHhDZmdBc3NldElkBAAAAAdhc3NldElkCQACWQAAAAEFAAAACmFzc2V0SWRTdHIEAAAAD21pbkxvY2tEdXJhdGlvbgkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABVJZHhDZmdNaW5Mb2NrRHVyYXRpb24EAAAAD21heExvY2tEdXJhdGlvbgkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABVJZHhDZmdNYXhMb2NrRHVyYXRpb24EAAAADG1hdGhDb250cmFjdAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkAAZEAAAACBQAAAAhjZmdBcnJheQUAAAASSWR4Q2ZnTWF0aENvbnRyYWN0BAAAAAlwbXRBbW91bnQJAQAAACJleHRyYWN0T3B0aW9uYWxQYXltZW50QW1vdW50T3JGYWlsAAAAAgUAAAABaQUAAAAHYXNzZXRJZAQAAAAOdXNlckFkZHJlc3NTdHIJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAAA91c2VyUmVjb3JkQXJyYXkJAQAAABpyZWFkTG9ja1BhcmFtc1JlY29yZE9yRmFpbAAAAAEFAAAADnVzZXJBZGRyZXNzU3RyBAAAAAp1c2VyTnVtU3RyCQABkQAAAAIFAAAAD3VzZXJSZWNvcmRBcnJheQUAAAAOSWR4TG9ja1VzZXJOdW0EAAAACnVzZXJBbW91bnQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAA91c2VyUmVjb3JkQXJyYXkFAAAADUlkeExvY2tBbW91bnQEAAAACWxvY2tTdGFydAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAD3VzZXJSZWNvcmRBcnJheQUAAAAMSWR4TG9ja1N0YXJ0BAAAAAxsb2NrRHVyYXRpb24JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAA91c2VyUmVjb3JkQXJyYXkFAAAAD0lkeExvY2tEdXJhdGlvbgQAAAAHbG9ja0VuZAkAAGQAAAACBQAAAAlsb2NrU3RhcnQFAAAADGxvY2tEdXJhdGlvbgQAAAARcmVtYWluaW5nRHVyYXRpb24JAAGWAAAAAQkABEwAAAACCQAAZQAAAAIFAAAAB2xvY2tFbmQFAAAABmhlaWdodAkABEwAAAACAAAAAAAAAAAABQAAAANuaWwEAAAADXVzZXJBbW91bnROZXcJAABkAAAAAgUAAAAKdXNlckFtb3VudAUAAAAJcG10QW1vdW50BAAAAA9sb2NrRHVyYXRpb25OZXcJAABkAAAAAgUAAAARcmVtYWluaW5nRHVyYXRpb24FAAAADWRlbHRhRHVyYXRpb24DCQAAZgAAAAIAAAAAAAAAAAAFAAAADWRlbHRhRHVyYXRpb24JAAACAAAAAQIAAAAaZHVyYXRpb24gaXMgbGVzcyB0aGVuIHplcm8DCQAAZgAAAAIFAAAAD21pbkxvY2tEdXJhdGlvbgUAAAAPbG9ja0R1cmF0aW9uTmV3CQAAAgAAAAEJAAEsAAAAAgIAAAAtbG9ja0R1cmF0aW9uTmV3IGlzIGxlc3MgdGhlbiBtaW5Mb2NrRHVyYXRpb249CQABpAAAAAEFAAAAD21pbkxvY2tEdXJhdGlvbgMJAABmAAAAAgUAAAAPbG9ja0R1cmF0aW9uTmV3BQAAAA9tYXhMb2NrRHVyYXRpb24JAAACAAAAAQkAASwAAAACAgAAAERkZWx0YUR1cmF0aW9uICsgZXhpc3RlZExvY2tEdXJhdGlvbiBpcyBncmVhdGVyIHRoZW4gbWF4TG9ja0R1cmF0aW9uPQkAAaQAAAABBQAAAA9tYXhMb2NrRHVyYXRpb24DAwkAAGcAAAACBQAAAAZoZWlnaHQFAAAAB2xvY2tFbmQJAABmAAAAAgUAAAAKdXNlckFtb3VudAAAAAAAAAAAAAcJAAACAAAAAQIAAAA5dGhlcmUgaXMgYW4gZXhwaXJlZCBsb2NrIC0gbmVlZCB0byB1bmxvY2sgYmVmb3JlIG5ldyBsb2NrBAAAAAdjb2VmZlg4CQAAawAAAAMFAAAAD2xvY2tEdXJhdGlvbk5ldwUAAAAFTVVMVDgFAAAAD21heExvY2tEdXJhdGlvbgQAAAAOZ1d4QW1vdW50U3RhcnQJAABrAAAAAwUAAAANdXNlckFtb3VudE5ldwUAAAAHY29lZmZYOAUAAAAFTVVMVDgEAAAAE2dXeFBhcmFtc1Jlc3VsdExpc3QJAQAAAAlhc0FueUxpc3QAAAABCQAD/AAAAAQFAAAADG1hdGhDb250cmFjdAIAAAAVY2FsY0d3eFBhcmFtc1JFQURPTkxZCQAETAAAAAIFAAAADmdXeEFtb3VudFN0YXJ0CQAETAAAAAIFAAAABmhlaWdodAkABEwAAAACBQAAAA9sb2NrRHVyYXRpb25OZXcFAAAAA25pbAUAAAADbmlsBAAAAAFrCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAAE2dXeFBhcmFtc1Jlc3VsdExpc3QAAAAAAAAAAAAEAAAAAWIJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAATZ1d4UGFyYW1zUmVzdWx0TGlzdAAAAAAAAAAAAQQAAAAGcGVyaW9kCQABpAAAAAEJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAATZ1d4UGFyYW1zUmVzdWx0TGlzdAAAAAAAAAAAAgQAAAASd3hFbWlzc2lvblBlckJsb2NrCQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAQZW1pc3Npb25Db250cmFjdAkBAAAAHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAAAAAEAAAADWVtaXNzaW9uU3RhcnQJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAAVa2V5RW1pc3Npb25TdGFydEJsb2NrAAAAAAQAAAALZW1pc3Npb25FbmQJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAATa2V5RW1pc3Npb25FbmRCbG9jawAAAAAEAAAAAWgDCQAAZgAAAAIFAAAABmhlaWdodAUAAAALZW1pc3Npb25FbmQFAAAAC2VtaXNzaW9uRW5kBQAAAAZoZWlnaHQEAAAAAmRoCQABlgAAAAEJAARMAAAAAgkAAGUAAAACBQAAAAFoBQAAAA1lbWlzc2lvblN0YXJ0CQAETAAAAAIAAAAAAAAAAAAFAAAAA25pbAQAAAAgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJAQAAACBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAAAAAEFAAAACnVzZXJOdW1TdHIEAAAAHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsCQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkEAAAAFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAAGkAAAACCQAAaAAAAAIJAABoAAAAAgUAAAASd3hFbWlzc2lvblBlckJsb2NrBQAAAAJkaAAAAAAAAAAAAgAAAAAAAAAAAwQAAAAZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAAGUAAAACBQAAABVib29zdEVtaXNzaW9uSW50ZWdyYWwFAAAAHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsAwkAAGYAAAACAAAAAAAAAAAABQAAABl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsCQAAAgAAAAECAAAAEndyb25nIGNhbGN1bGF0aW9ucwQAAAAXdXNlck1heEJvb3N0SW50ZWdyYWxLRVkJAQAAABdrZXlVc2VyTWF4Qm9vc3RJTlRFR1JBTAAAAAEFAAAACnVzZXJOdW1TdHIEAAAAGHRvdGFsTWF4Qm9vc3RJbnRlZ3JhbEtFWQkBAAAAGGtleVRvdGFsTWF4Qm9vc3RJTlRFR1JBTAAAAAAEAAAAIXVzZXJCb29zdEF2YWxhaWJsZVRvQ2xhaW1Ub3RhbEtFWQkBAAAAIWtleVVzZXJCb29zdEF2YWxhaWJsZVRvQ2xhaW1Ub3RhbAAAAAEFAAAACnVzZXJOdW1TdHIEAAAAD3VzZXJNYXhCb29zdEludAkBAAAADGdldEludE9yWmVybwAAAAIFAAAABHRoaXMFAAAAF3VzZXJNYXhCb29zdEludGVncmFsS0VZBAAAABB0b3RhbE1heEJvb3N0SW50CQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAYdG90YWxNYXhCb29zdEludGVncmFsS0VZBAAAAB51c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWwJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAACF1c2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWxLRVkEAAAAIXVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbE5ldwkAAGQAAAACBQAAAB51c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWwJAABrAAAAAwUAAAAZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAUAAAAPdXNlck1heEJvb3N0SW50BQAAABB0b3RhbE1heEJvb3N0SW50BAAAABJ1c2VyTWF4Qm9vc3RJbnROZXcJAABpAAAAAgkAAGgAAAACBQAAAA5nV3hBbW91bnRTdGFydAUAAAAPbG9ja0R1cmF0aW9uTmV3AAAAAAAAAAACBAAAAAtjdXJyVXNlckd3eAkBAAAAFGNhbGNDdXJyZW50R3d4QW1vdW50AAAAAQUAAAAOdXNlckFkZHJlc3NTdHIEAAAAGHJlbWFpbmluZ1VzZXJNYXhCb29zdEludAkAAGkAAAACCQAAaAAAAAIFAAAAC2N1cnJVc2VyR3d4BQAAABFyZW1haW5pbmdEdXJhdGlvbgAAAAAAAAAAAgQAAAATdXNlck1heEJvb3N0SW50RGlmZgkAAGUAAAACBQAAABJ1c2VyTWF4Qm9vc3RJbnROZXcFAAAAGHJlbWFpbmluZ1VzZXJNYXhCb29zdEludAMJAABmAAAAAgAAAAAAAAAAAAUAAAATdXNlck1heEJvb3N0SW50RGlmZgkAAAIAAAABAgAAABJ3cm9uZyBjYWxjdWxhdGlvbnMEAAAAB2d3eERpZmYJAABlAAAAAgUAAAAOZ1d4QW1vdW50U3RhcnQFAAAAC2N1cnJVc2VyR3d4AwkAAGYAAAACAAAAAAAAAAAABQAAAAdnd3hEaWZmCQAAAgAAAAECAAAAFmd3eERpZmYgaXMgbGVzcyB0aGVuIDAEAAAAEXRvdGFsQ2FjaGVkR3d4S0VZCQEAAAARa2V5VG90YWxDYWNoZWRHd3gAAAAABAAAAA50b3RhbENhY2hlZEd3eAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAABF0b3RhbENhY2hlZEd3eEtFWQAAAAAAAAAAAAkABE4AAAACCQAETQAAAAIJAAROAAAAAgkBAAAAD0xvY2tQYXJhbXNFbnRyeQAAAAgFAAAADnVzZXJBZGRyZXNzU3RyBQAAAAp1c2VyTnVtU3RyBQAAAA11c2VyQW1vdW50TmV3BQAAAAlsb2NrU3RhcnQFAAAAD2xvY2tEdXJhdGlvbk5ldwUAAAABawUAAAABYgUAAAAGcGVyaW9kCQEAAAAKU3RhdHNFbnRyeQAAAAQFAAAACXBtdEFtb3VudAUAAAANZGVsdGFEdXJhdGlvbgAAAAAAAAAAAAAAAAAAAAAAAAkBAAAADEhpc3RvcnlFbnRyeQAAAAgCAAAABGxvY2sFAAAADnVzZXJBZGRyZXNzU3RyBQAAAAlwbXRBbW91bnQFAAAACWxvY2tTdGFydAUAAAAPbG9ja0R1cmF0aW9uTmV3BQAAAAFrBQAAAAFiBQAAAAFpCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAACF1c2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWxLRVkFAAAAIXVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbE5ldwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkFAAAAFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARdG90YWxDYWNoZWRHd3hLRVkJAABkAAAAAgUAAAAOdG90YWxDYWNoZWRHd3gFAAAAB2d3eERpZmYFAAAAA25pbAAAAAFpAQAAAAxjbGFpbVd4Qm9vc3QAAAABAAAADnVzZXJBZGRyZXNzU3RyAwkBAAAAAiE9AAAAAgUAAAAPc3Rha2luZ0NvbnRyYWN0CAUAAAABaQAAAAZjYWxsZXIJAAACAAAAAQIAAAAScGVybWlzc2lvbnMgZGVuaWVkBAAAAA0kdDAyMzQ2MjIzNTQzCQEAAAAUaW50ZXJuYWxDbGFpbVd4Qm9vc3QAAAABBQAAAA51c2VyQWRkcmVzc1N0cgQAAAASdXNlckJvb3N0QXZhaWxhYmxlCAUAAAANJHQwMjM0NjIyMzU0MwAAAAJfMQQAAAAJZGF0YVN0YXRlCAUAAAANJHQwMjM0NjIyMzU0MwAAAAJfMgQAAAAFZGVidWcIBQAAAA0kdDAyMzQ2MjIzNTQzAAAAAl8zCQAFFAAAAAIFAAAACWRhdGFTdGF0ZQkABEwAAAACBQAAABJ1c2VyQm9vc3RBdmFpbGFibGUFAAAAA25pbAAAAAFpAQAAABRjbGFpbVd4Qm9vc3RSRUFET05MWQAAAAEAAAAOdXNlckFkZHJlc3NTdHIEAAAADSR0MDIzNjUzMjM3MzQJAQAAABRpbnRlcm5hbENsYWltV3hCb29zdAAAAAEFAAAADnVzZXJBZGRyZXNzU3RyBAAAABJ1c2VyQm9vc3RBdmFpbGFibGUIBQAAAA0kdDAyMzY1MzIzNzM0AAAAAl8xBAAAAAlkYXRhU3RhdGUIBQAAAA0kdDAyMzY1MzIzNzM0AAAAAl8yBAAAAAVkZWJ1ZwgFAAAADSR0MDIzNjUzMjM3MzQAAAACXzMJAAUUAAAAAgUAAAADbmlsCQAETAAAAAIFAAAAEnVzZXJCb29zdEF2YWlsYWJsZQkABEwAAAACBQAAAAVkZWJ1ZwUAAAADbmlsAAAAAWkBAAAABnVubG9jawAAAAEAAAALdXNlckFkZHJlc3MEAAAAD3VzZXJSZWNvcmRBcnJheQkBAAAAGnJlYWRMb2NrUGFyYW1zUmVjb3JkT3JGYWlsAAAAAQUAAAALdXNlckFkZHJlc3MEAAAACnVzZXJOdW1TdHIJAAGRAAAAAgUAAAAPdXNlclJlY29yZEFycmF5BQAAAA5JZHhMb2NrVXNlck51bQQAAAAKdXNlckFtb3VudAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAD3VzZXJSZWNvcmRBcnJheQUAAAANSWR4TG9ja0Ftb3VudAQAAAAJbG9ja1N0YXJ0CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAPdXNlclJlY29yZEFycmF5BQAAAAxJZHhMb2NrU3RhcnQEAAAADGxvY2tEdXJhdGlvbgkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAD3VzZXJSZWNvcmRBcnJheQUAAAAPSWR4TG9ja0R1cmF0aW9uBAAAAAdsb2NrRW5kCQAAZAAAAAIFAAAACWxvY2tTdGFydAUAAAAMbG9ja0R1cmF0aW9uBAAAAAhjZmdBcnJheQkBAAAAFXJlYWRDb25maWdBcnJheU9yRmFpbAAAAAAEAAAAB2Fzc2V0SWQJAAJZAAAAAQkAAZEAAAACBQAAAAhjZmdBcnJheQUAAAANSWR4Q2ZnQXNzZXRJZAMJAABnAAAAAgUAAAAHbG9ja0VuZAUAAAAGaGVpZ2h0CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAAAV3YWl0IAkAAaQAAAABBQAAAAdsb2NrRW5kAgAAAAogdG8gdW5sb2NrAwkAAGcAAAACAAAAAAAAAAAABQAAAAp1c2VyQW1vdW50CQAAAgAAAAECAAAAEW5vdGhpbmcgdG8gdW5sb2NrBAAAAAZwZXJpb2QCAAAAATAJAARNAAAAAgkABE0AAAACCQAETgAAAAIJAQAAAA9Mb2NrUGFyYW1zRW50cnkAAAAIBQAAAAt1c2VyQWRkcmVzcwUAAAAKdXNlck51bVN0cgAAAAAAAAAAAAUAAAAJbG9ja1N0YXJ0BQAAAAxsb2NrRHVyYXRpb24AAAAAAAAAAAAAAAAAAAAAAAAFAAAABnBlcmlvZAkBAAAAClN0YXRzRW50cnkAAAAECQEAAAABLQAAAAEFAAAACnVzZXJBbW91bnQAAAAAAAAAAAAAAAAAAAAAAAAA//////////8JAQAAAAxIaXN0b3J5RW50cnkAAAAIAgAAAAZ1bmxvY2sFAAAAC3VzZXJBZGRyZXNzBQAAAAp1c2VyQW1vdW50BQAAAAlsb2NrU3RhcnQFAAAADGxvY2tEdXJhdGlvbgAAAAAAAAAAAAAAAAAAAAAAAAUAAAABaQkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAALdXNlckFkZHJlc3MFAAAACnVzZXJBbW91bnQFAAAAB2Fzc2V0SWQAAAABaQEAAAATZ3d4VXNlckluZm9SRUFET05MWQAAAAEAAAALdXNlckFkZHJlc3MEAAAACWd3eEFtb3VudAkBAAAAFGNhbGNDdXJyZW50R3d4QW1vdW50AAAAAQUAAAALdXNlckFkZHJlc3MJAAUUAAAAAgUAAAADbmlsCQAETAAAAAIFAAAACWd3eEFtb3VudAUAAAADbmlsAAAAAIWgDRg=", "chainId": 84, "height": 1816325, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: C1HJd4QMoE19e9JTF8pMAvT5jGdmaFLswbEmsTZ8pja9 Next: AkxFVWFQrYPSAVPouQo5m9z3aXGP4AatVbMDh4iNxcyo Diff:
OldNewDifferences
203203 func keyUserBoostClaimed (userNum) = makeString(["%s%d__userBoostClaimed", userNum], SEP)
204204
205205
206+func keyTotalCachedGwx () = "%s%s__gwxCached__total"
207+
208+
206209 let factoryContract = readFactoryAddressOrFail()
207210
208211 let factoryCfg = readFactoryCfgOrFail(factoryContract)
300303 else {
301304 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
302305 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
303- let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
304306 let userMaxBoostInt = getIntOrZero(this, userMaxBoostIntegralKEY)
305307 let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
308+ let totalCachedGwxKEY = keyTotalCachedGwx()
309+ let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
310+ let userCurrGwx = calcCurrentGwxAmount(userAddressStr)
311+ let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
306312 let userBoostAvaliableToClaimTotal = getIntOrZero(this, userBoostAvalaibleToClaimTotalKEY)
307- let userBoostAvaliableToClaimTotalNew = (userBoostAvaliableToClaimTotal + fraction(userBoostEmissionIntegral, userMaxBoostInt, totalMaxBoostInt))
313+ let userBoostAvaliableToClaimTotalNew = (userBoostAvaliableToClaimTotal + (if ((totalCachedGwx == 0))
314+ then 0
315+ else fraction(userBoostEmissionIntegral, userCurrGwx, totalCachedGwx)))
308316 let userBoostClaimedKEY = keyUserBoostClaimed(userNumStr)
309317 let userBoostClaimed = getIntOrZero(this, userBoostClaimedKEY)
310318 let userBoostAvailable = (userBoostAvaliableToClaimTotalNew - userBoostClaimed)
381389 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
382390 let userMaxBoostInt = ((gWxAmountStart * duration) / 2)
383391 let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
392+ let totalCachedGwxKEY = keyTotalCachedGwx()
393+ let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
384394 let arr = if (userIsExisting)
385395 then nil
386396 else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
387397 ((((arr ++ LockParamsEntry(userAddressStr, userNumStr, pmtAmount, lockStart, duration, k, b, period)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
388398 then 0
389- else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(userMaxBoostIntegralKEY, userMaxBoostInt), IntegerEntry(totalMaxBoostIntegralKEY, (totalMaxBoostInt + userMaxBoostInt))])
399+ else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(totalCachedGwxKEY, (totalCachedGwx + gWxAmountStart))])
390400 }
391401 }
392402 }
457467 let userMaxBoostIntDiff = (userMaxBoostIntNew - remainingUserMaxBoostInt)
458468 if ((0 > userMaxBoostIntDiff))
459469 then throw("wrong calculations")
460- else (((LockParamsEntry(userAddressStr, userNumStr, userAmountNew, lockStart, lockDurationNew, k, b, period) ++ StatsEntry(pmtAmount, deltaDuration, 0, 0)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, lockDurationNew, k, b, i)) ++ [IntegerEntry(userMaxBoostIntegralKEY, (userMaxBoostInt + userMaxBoostIntDiff)), IntegerEntry(totalMaxBoostIntegralKEY, (totalMaxBoostInt + userMaxBoostIntDiff)), IntegerEntry(userBoostAvalaibleToClaimTotalKEY, userBoostAvaliableToClaimTotalNew), IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral)])
470+ else {
471+ let gwxDiff = (gWxAmountStart - currUserGwx)
472+ if ((0 > gwxDiff))
473+ then throw("gwxDiff is less then 0")
474+ else {
475+ let totalCachedGwxKEY = keyTotalCachedGwx()
476+ let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
477+ (((LockParamsEntry(userAddressStr, userNumStr, userAmountNew, lockStart, lockDurationNew, k, b, period) ++ StatsEntry(pmtAmount, deltaDuration, 0, 0)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, lockDurationNew, k, b, i)) ++ [IntegerEntry(userBoostAvalaibleToClaimTotalKEY, userBoostAvaliableToClaimTotalNew), IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(totalCachedGwxKEY, (totalCachedGwx + gwxDiff))])
478+ }
479+ }
461480 }
462481 }
463482 }
468487 func claimWxBoost (userAddressStr) = if ((stakingContract != i.caller))
469488 then throw("permissions denied")
470489 else {
471- let $t02254322624 = internalClaimWxBoost(userAddressStr)
472- let userBoostAvailable = $t02254322624._1
473- let dataState = $t02254322624._2
474- let debug = $t02254322624._3
490+ let $t02346223543 = internalClaimWxBoost(userAddressStr)
491+ let userBoostAvailable = $t02346223543._1
492+ let dataState = $t02346223543._2
493+ let debug = $t02346223543._3
475494 $Tuple2(dataState, [userBoostAvailable])
476495 }
477496
479498
480499 @Callable(i)
481500 func claimWxBoostREADONLY (userAddressStr) = {
482- let $t02273422815 = internalClaimWxBoost(userAddressStr)
483- let userBoostAvailable = $t02273422815._1
484- let dataState = $t02273422815._2
485- let debug = $t02273422815._3
501+ let $t02365323734 = internalClaimWxBoost(userAddressStr)
502+ let userBoostAvailable = $t02365323734._1
503+ let dataState = $t02365323734._2
504+ let debug = $t02365323734._3
486505 $Tuple2(nil, [userBoostAvailable, debug])
487506 }
488507
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 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined"))
1111
1212
1313 func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
1414
1515
1616 func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
1717
1818
1919 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
2020
2121
2222 func asAnyList (val) = match val {
2323 case valAnyLyst: List[Any] =>
2424 valAnyLyst
2525 case _ =>
2626 throw("fail to cast into List[Any]")
2727 }
2828
2929
3030 func asInt (val) = match val {
3131 case valInt: Int =>
3232 valInt
3333 case _ =>
3434 throw("fail to cast into Int")
3535 }
3636
3737
3838 func keyFactoryAddress () = "%s%s__config__factoryAddress"
3939
4040
4141 let IdxFactoryCfgStakingDapp = 1
4242
4343 let IdxFactoryCfgBoostingDapp = 2
4444
4545 let IdxFactoryCfgIdoDapp = 3
4646
4747 let IdxFactoryCfgTeamDapp = 4
4848
4949 let IdxFactoryCfgEmissionDapp = 5
5050
5151 let IdxFactoryCfgRestDapp = 6
5252
5353 let IdxFactoryCfgSlippageDapp = 7
5454
5555 func keyFactoryCfg () = "%s__factoryConfig"
5656
5757
5858 func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
5959
6060
6161 func keyFactoryLpList () = "%s__lpTokensList"
6262
6363
6464 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
6565
6666
6767 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
6868
6969
7070 func readFactoryAddressOrFail () = addressFromStringValue(getStringOrFail(this, keyFactoryAddress()))
7171
7272
7373 func readLpList () = split(valueOrElse(getString(readFactoryAddressOrFail(), keyFactoryLpList()), ""), SEP)
7474
7575
7676 func readFactoryCfgOrFail (factory) = split(getStringOrFail(factory, keyFactoryCfg()), SEP)
7777
7878
7979 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
8080
8181
8282 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
8383
8484
8585 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
8686
8787
8888 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
8989
9090
9191 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
9292
9393
9494 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
9595
9696
9797 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
9898
9999
100100 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
101101
102102
103103 let IdxCfgAssetId = 1
104104
105105 let IdxCfgMinLockAmount = 2
106106
107107 let IdxCfgMinLockDuration = 3
108108
109109 let IdxCfgMaxLockDuration = 4
110110
111111 let IdxCfgMathContract = 5
112112
113113 func keyConfig () = "%s__config"
114114
115115
116116 func readConfigArrayOrFail () = split(getStringOrFail(this, keyConfig()), SEP)
117117
118118
119119 func formatConfigS (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = makeString(["%s%d%d%d", assetId, minLockAmount, minLockDuration, maxLockDuration, mathContract], SEP)
120120
121121
122122 func formatConfig (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = formatConfigS(assetId, toString(minLockAmount), toString(minLockDuration), toString(maxLockDuration), mathContract)
123123
124124
125125 let IdxLockUserNum = 1
126126
127127 let IdxLockAmount = 2
128128
129129 let IdxLockStart = 3
130130
131131 let IdxLockDuration = 4
132132
133133 let IdxLockParamK = 5
134134
135135 let IdxLockParamB = 6
136136
137137 func keyLockParamsRecord (userAddress) = makeString(["%s%s__lock", userAddress], SEP)
138138
139139
140140 func readLockParamsRecordOrFail (userAddress) = split(getStringOrFail(this, keyLockParamsRecord(userAddress)), SEP)
141141
142142
143143 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)
144144
145145
146146 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))
147147
148148
149149 func keyNextUserNum () = "%s__nextUserNum"
150150
151151
152152 func keyUser2NumMapping (userAddress) = makeString(["%s%s%s__mapping__user2num", userAddress], SEP)
153153
154154
155155 func keyNum2UserMapping (num) = makeString(["%s%s%s__mapping__num2user", num], SEP)
156156
157157
158158 func keyLockParamUserAmount (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "amount"], SEP)
159159
160160
161161 func keyLockParamStartBlock (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "start"], SEP)
162162
163163
164164 func keyLockParamDuration (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "duration"], SEP)
165165
166166
167167 func keyLockParamK (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "k"], SEP)
168168
169169
170170 func keyLockParamB (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "b"], SEP)
171171
172172
173173 func keyLockParamByPeriodK (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "k", period], SEP)
174174
175175
176176 func keyLockParamByPeriodB (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "b", period], SEP)
177177
178178
179179 func keyLockParamTotalAmount () = "%s%s__stats__activeTotalLocked"
180180
181181
182182 func keyStatsLocksDurationSumInBlocks () = "%s%s__stats__locksDurationSumInBlocks"
183183
184184
185185 func keyStatsLocksCount () = "%s%s__stats__locksCount"
186186
187187
188188 func keyStatsUsersCount () = "%s%s__stats__activeUsersCount"
189189
190190
191191 func keyUserBoostEmissionLastINTEGRAL (userNum) = makeString(["%s%d__userBoostEmissionLastInt", userNum], SEP)
192192
193193
194194 func keyUserMaxBoostINTEGRAL (userNum) = makeString(["%s%d__maxBoostInt", userNum], SEP)
195195
196196
197197 func keyTotalMaxBoostINTEGRAL () = "%s%s__maxBoostInt__total"
198198
199199
200200 func keyUserBoostAvalaibleToClaimTotal (userNum) = makeString(["%s%d__userBoostAvaliableToClaimTotal", userNum], SEP)
201201
202202
203203 func keyUserBoostClaimed (userNum) = makeString(["%s%d__userBoostClaimed", userNum], SEP)
204204
205205
206+func keyTotalCachedGwx () = "%s%s__gwxCached__total"
207+
208+
206209 let factoryContract = readFactoryAddressOrFail()
207210
208211 let factoryCfg = readFactoryCfgOrFail(factoryContract)
209212
210213 let emissionContract = getEmissionAddressOrFail(factoryCfg)
211214
212215 let stakingContract = getStakingAddressOrFail(factoryCfg)
213216
214217 func HistoryEntry (type,user,amount,lockStart,duration,k,b,i) = {
215218 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
216219 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)
217220 StringEntry(historyKEY, historyDATA)
218221 }
219222
220223
221224 func StatsEntry (totalLockedInc,durationInc,lockCountInc,usersCountInc) = {
222225 let locksDurationSumInBlocksKEY = keyStatsLocksDurationSumInBlocks()
223226 let locksCountKEY = keyStatsLocksCount()
224227 let usersCountKEY = keyStatsUsersCount()
225228 let totalAmountKEY = keyLockParamTotalAmount()
226229 let locksDurationSumInBlocks = getIntOrZero(this, locksDurationSumInBlocksKEY)
227230 let locksCount = getIntOrZero(this, locksCountKEY)
228231 let usersCount = getIntOrZero(this, usersCountKEY)
229232 let totalAmount = getIntOrZero(this, totalAmountKEY)
230233 [IntegerEntry(locksDurationSumInBlocksKEY, (locksDurationSumInBlocks + durationInc)), IntegerEntry(locksCountKEY, (locksCount + lockCountInc)), IntegerEntry(usersCountKEY, (usersCount + usersCountInc)), IntegerEntry(totalAmountKEY, (totalAmount + totalLockedInc))]
231234 }
232235
233236
234237 func calcGwxAmount (kRaw,bRaw,h) = {
235238 let SCALE = 1000
236239 (((kRaw * h) + bRaw) / SCALE)
237240 }
238241
239242
240243 func LockParamsEntry (userAddress,userNum,amount,start,duration,k,b,period) = {
241244 let userAmountKEY = keyLockParamUserAmount(userNum)
242245 let startBlockKEY = keyLockParamStartBlock(userNum)
243246 let durationKEY = keyLockParamDuration(userNum)
244247 let kKEY = keyLockParamK(userNum)
245248 let bKEY = keyLockParamB(userNum)
246249 let kByPerioKEY = keyLockParamByPeriodK(userNum, period)
247250 let bByPeriodKEY = keyLockParamByPeriodB(userNum, period)
248251 let gwxAmount = calcGwxAmount(k, b, height)
249252 [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))]
250253 }
251254
252255
253256 func extractOptionalPaymentAmountOrFail (i,expectedAssetId) = if ((size(i.payments) > 1))
254257 then throw("only one payment is allowed")
255258 else if ((size(i.payments) == 0))
256259 then 0
257260 else {
258261 let pmt = i.payments[0]
259262 if ((value(pmt.assetId) != expectedAssetId))
260263 then throw("invalid asset id in payment")
261264 else pmt.amount
262265 }
263266
264267
265268 func calcCurrentGwxAmount (userAddress) = {
266269 let EMPTY = "empty"
267270 let user2NumMappingKEY = keyUser2NumMapping(userAddress)
268271 let userNum = valueOrElse(getString(user2NumMappingKEY), EMPTY)
269272 let k = valueOrElse(getInteger(keyLockParamK(userNum)), 0)
270273 let b = valueOrElse(getInteger(keyLockParamB(userNum)), 0)
271274 let gwxAmountCalc = calcGwxAmount(k, b, height)
272275 let gwxAmount = if ((0 > gwxAmountCalc))
273276 then 0
274277 else gwxAmountCalc
275278 gwxAmount
276279 }
277280
278281
279282 func internalClaimWxBoost (userAddressStr) = {
280283 let EMPTY = "EMPTY"
281284 let userRecordOrEmpty = valueOrElse(getString(this, keyLockParamsRecord(userAddressStr)), EMPTY)
282285 if ((userRecordOrEmpty == EMPTY))
283286 then $Tuple3(0, nil, "userRecord::is::empty")
284287 else {
285288 let userRecordArray = split(userRecordOrEmpty, SEP)
286289 let userNumStr = userRecordArray[IdxLockUserNum]
287290 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
288291 let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
289292 let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
290293 let h = if ((height > emissionEnd))
291294 then emissionEnd
292295 else height
293296 let dh = max([(h - emissionStart), 0])
294297 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
295298 let userBoostEmissionLastIntegral = getIntOrZero(this, userBoostEmissionLastIntegralKEY)
296299 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
297300 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
298301 if ((0 > userBoostEmissionIntegral))
299302 then throw("wrong calculations")
300303 else {
301304 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
302305 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
303- let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
304306 let userMaxBoostInt = getIntOrZero(this, userMaxBoostIntegralKEY)
305307 let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
308+ let totalCachedGwxKEY = keyTotalCachedGwx()
309+ let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
310+ let userCurrGwx = calcCurrentGwxAmount(userAddressStr)
311+ let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
306312 let userBoostAvaliableToClaimTotal = getIntOrZero(this, userBoostAvalaibleToClaimTotalKEY)
307- let userBoostAvaliableToClaimTotalNew = (userBoostAvaliableToClaimTotal + fraction(userBoostEmissionIntegral, userMaxBoostInt, totalMaxBoostInt))
313+ let userBoostAvaliableToClaimTotalNew = (userBoostAvaliableToClaimTotal + (if ((totalCachedGwx == 0))
314+ then 0
315+ else fraction(userBoostEmissionIntegral, userCurrGwx, totalCachedGwx)))
308316 let userBoostClaimedKEY = keyUserBoostClaimed(userNumStr)
309317 let userBoostClaimed = getIntOrZero(this, userBoostClaimedKEY)
310318 let userBoostAvailable = (userBoostAvaliableToClaimTotalNew - userBoostClaimed)
311319 let dataState = [IntegerEntry(userBoostAvalaibleToClaimTotalKEY, userBoostAvaliableToClaimTotalNew), IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral)]
312320 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))], "::")
313321 $Tuple3(userBoostAvailable, dataState, debug)
314322 }
315323 }
316324 }
317325
318326
319327 @Callable(i)
320328 func constructor (factoryAddressStr,lockAssetIdStr,minLockAmount,minDuration,maxDuration,mathContract) = if ((this != i.caller))
321329 then throw("not authorized")
322330 else ([IntegerEntry(keyNextUserNum(), 0), StringEntry(keyConfig(), formatConfig(lockAssetIdStr, minLockAmount, minDuration, maxDuration, mathContract)), StringEntry(keyFactoryAddress(), factoryAddressStr)] ++ StatsEntry(0, 0, 0, 0))
323331
324332
325333
326334 @Callable(i)
327335 func lock (duration) = {
328336 let cfgArray = readConfigArrayOrFail()
329337 let assetIdStr = cfgArray[IdxCfgAssetId]
330338 let assetId = fromBase58String(assetIdStr)
331339 let minLockAmount = parseIntValue(cfgArray[IdxCfgMinLockAmount])
332340 let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
333341 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
334342 let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
335343 if ((size(i.payments) != 1))
336344 then throw("invalid payment - exact one payment must be attached")
337345 else {
338346 let pmt = i.payments[0]
339347 let pmtAmount = pmt.amount
340348 if ((assetId != value(pmt.assetId)))
341349 then throw((("invalid asset is in payment - " + assetIdStr) + " is expected"))
342350 else {
343351 let nextUserNumKEY = keyNextUserNum()
344352 let userAddressStr = toString(i.caller)
345353 let userIsExisting = isDefined(getString(keyUser2NumMapping(userAddressStr)))
346354 let userNumStr = if (userIsExisting)
347355 then value(getString(keyUser2NumMapping(userAddressStr)))
348356 else toString(getIntOrFail(this, nextUserNumKEY))
349357 let userNum = parseIntValue(userNumStr)
350358 let lockStart = height
351359 let startBlockKEY = keyLockParamStartBlock(userNumStr)
352360 let durationKEY = keyLockParamDuration(userNumStr)
353361 let userAmountKEY = keyLockParamUserAmount(userNumStr)
354362 if ((minLockAmount > pmtAmount))
355363 then throw(("amount is less then minLockAmount=" + toString(minLockAmount)))
356364 else if ((minLockDuration > duration))
357365 then throw(("passed duration is less then minLockDuration=" + toString(minLockDuration)))
358366 else if ((duration > maxLockDuration))
359367 then throw(("passed duration is greater then maxLockDuration=" + toString(maxLockDuration)))
360368 else if (if (userIsExisting)
361369 then ((getIntOrFail(this, startBlockKEY) + getIntOrFail(this, durationKEY)) >= lockStart)
362370 else false)
363371 then throw("there is an active lock - consider to use increaseLock")
364372 else {
365373 let coeffX8 = fraction(duration, MULT8, maxLockDuration)
366374 let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
367375 let gWxParamsResultList = asAnyList(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStart, duration], nil))
368376 let k = asInt(gWxParamsResultList[0])
369377 let b = asInt(gWxParamsResultList[1])
370378 let period = toString(asInt(gWxParamsResultList[2]))
371379 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
372380 let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
373381 let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
374382 let h = if ((height > emissionEnd))
375383 then emissionEnd
376384 else height
377385 let dh = max([(h - emissionStart), 0])
378386 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
379387 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
380388 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
381389 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
382390 let userMaxBoostInt = ((gWxAmountStart * duration) / 2)
383391 let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
392+ let totalCachedGwxKEY = keyTotalCachedGwx()
393+ let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
384394 let arr = if (userIsExisting)
385395 then nil
386396 else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
387397 ((((arr ++ LockParamsEntry(userAddressStr, userNumStr, pmtAmount, lockStart, duration, k, b, period)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
388398 then 0
389- else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(userMaxBoostIntegralKEY, userMaxBoostInt), IntegerEntry(totalMaxBoostIntegralKEY, (totalMaxBoostInt + userMaxBoostInt))])
399+ else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(totalCachedGwxKEY, (totalCachedGwx + gWxAmountStart))])
390400 }
391401 }
392402 }
393403 }
394404
395405
396406
397407 @Callable(i)
398408 func increaseLock (deltaDuration) = {
399409 let cfgArray = readConfigArrayOrFail()
400410 let assetIdStr = cfgArray[IdxCfgAssetId]
401411 let assetId = fromBase58String(assetIdStr)
402412 let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
403413 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
404414 let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
405415 let pmtAmount = extractOptionalPaymentAmountOrFail(i, assetId)
406416 let userAddressStr = toString(i.caller)
407417 let userRecordArray = readLockParamsRecordOrFail(userAddressStr)
408418 let userNumStr = userRecordArray[IdxLockUserNum]
409419 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
410420 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
411421 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
412422 let lockEnd = (lockStart + lockDuration)
413423 let remainingDuration = max([(lockEnd - height), 0])
414424 let userAmountNew = (userAmount + pmtAmount)
415425 let lockDurationNew = (remainingDuration + deltaDuration)
416426 if ((0 > deltaDuration))
417427 then throw("duration is less then zero")
418428 else if ((minLockDuration > lockDurationNew))
419429 then throw(("lockDurationNew is less then minLockDuration=" + toString(minLockDuration)))
420430 else if ((lockDurationNew > maxLockDuration))
421431 then throw(("deltaDuration + existedLockDuration is greater then maxLockDuration=" + toString(maxLockDuration)))
422432 else if (if ((height >= lockEnd))
423433 then (userAmount > 0)
424434 else false)
425435 then throw("there is an expired lock - need to unlock before new lock")
426436 else {
427437 let coeffX8 = fraction(lockDurationNew, MULT8, maxLockDuration)
428438 let gWxAmountStart = fraction(userAmountNew, coeffX8, MULT8)
429439 let gWxParamsResultList = asAnyList(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, height, lockDurationNew], nil))
430440 let k = asInt(gWxParamsResultList[0])
431441 let b = asInt(gWxParamsResultList[1])
432442 let period = toString(asInt(gWxParamsResultList[2]))
433443 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
434444 let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
435445 let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
436446 let h = if ((height > emissionEnd))
437447 then emissionEnd
438448 else height
439449 let dh = max([(h - emissionStart), 0])
440450 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
441451 let userBoostEmissionLastIntegral = getIntOrZero(this, userBoostEmissionLastIntegralKEY)
442452 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
443453 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
444454 if ((0 > userBoostEmissionIntegral))
445455 then throw("wrong calculations")
446456 else {
447457 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
448458 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
449459 let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
450460 let userMaxBoostInt = getIntOrZero(this, userMaxBoostIntegralKEY)
451461 let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
452462 let userBoostAvaliableToClaimTotal = getIntOrZero(this, userBoostAvalaibleToClaimTotalKEY)
453463 let userBoostAvaliableToClaimTotalNew = (userBoostAvaliableToClaimTotal + fraction(userBoostEmissionIntegral, userMaxBoostInt, totalMaxBoostInt))
454464 let userMaxBoostIntNew = ((gWxAmountStart * lockDurationNew) / 2)
455465 let currUserGwx = calcCurrentGwxAmount(userAddressStr)
456466 let remainingUserMaxBoostInt = ((currUserGwx * remainingDuration) / 2)
457467 let userMaxBoostIntDiff = (userMaxBoostIntNew - remainingUserMaxBoostInt)
458468 if ((0 > userMaxBoostIntDiff))
459469 then throw("wrong calculations")
460- else (((LockParamsEntry(userAddressStr, userNumStr, userAmountNew, lockStart, lockDurationNew, k, b, period) ++ StatsEntry(pmtAmount, deltaDuration, 0, 0)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, lockDurationNew, k, b, i)) ++ [IntegerEntry(userMaxBoostIntegralKEY, (userMaxBoostInt + userMaxBoostIntDiff)), IntegerEntry(totalMaxBoostIntegralKEY, (totalMaxBoostInt + userMaxBoostIntDiff)), IntegerEntry(userBoostAvalaibleToClaimTotalKEY, userBoostAvaliableToClaimTotalNew), IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral)])
470+ else {
471+ let gwxDiff = (gWxAmountStart - currUserGwx)
472+ if ((0 > gwxDiff))
473+ then throw("gwxDiff is less then 0")
474+ else {
475+ let totalCachedGwxKEY = keyTotalCachedGwx()
476+ let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
477+ (((LockParamsEntry(userAddressStr, userNumStr, userAmountNew, lockStart, lockDurationNew, k, b, period) ++ StatsEntry(pmtAmount, deltaDuration, 0, 0)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, lockDurationNew, k, b, i)) ++ [IntegerEntry(userBoostAvalaibleToClaimTotalKEY, userBoostAvaliableToClaimTotalNew), IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(totalCachedGwxKEY, (totalCachedGwx + gwxDiff))])
478+ }
479+ }
461480 }
462481 }
463482 }
464483
465484
466485
467486 @Callable(i)
468487 func claimWxBoost (userAddressStr) = if ((stakingContract != i.caller))
469488 then throw("permissions denied")
470489 else {
471- let $t02254322624 = internalClaimWxBoost(userAddressStr)
472- let userBoostAvailable = $t02254322624._1
473- let dataState = $t02254322624._2
474- let debug = $t02254322624._3
490+ let $t02346223543 = internalClaimWxBoost(userAddressStr)
491+ let userBoostAvailable = $t02346223543._1
492+ let dataState = $t02346223543._2
493+ let debug = $t02346223543._3
475494 $Tuple2(dataState, [userBoostAvailable])
476495 }
477496
478497
479498
480499 @Callable(i)
481500 func claimWxBoostREADONLY (userAddressStr) = {
482- let $t02273422815 = internalClaimWxBoost(userAddressStr)
483- let userBoostAvailable = $t02273422815._1
484- let dataState = $t02273422815._2
485- let debug = $t02273422815._3
501+ let $t02365323734 = internalClaimWxBoost(userAddressStr)
502+ let userBoostAvailable = $t02365323734._1
503+ let dataState = $t02365323734._2
504+ let debug = $t02365323734._3
486505 $Tuple2(nil, [userBoostAvailable, debug])
487506 }
488507
489508
490509
491510 @Callable(i)
492511 func unlock (userAddress) = {
493512 let userRecordArray = readLockParamsRecordOrFail(userAddress)
494513 let userNumStr = userRecordArray[IdxLockUserNum]
495514 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
496515 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
497516 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
498517 let lockEnd = (lockStart + lockDuration)
499518 let cfgArray = readConfigArrayOrFail()
500519 let assetId = fromBase58String(cfgArray[IdxCfgAssetId])
501520 if ((lockEnd >= height))
502521 then throw((("wait " + toString(lockEnd)) + " to unlock"))
503522 else if ((0 >= userAmount))
504523 then throw("nothing to unlock")
505524 else {
506525 let period = "0"
507526 (((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))
508527 }
509528 }
510529
511530
512531
513532 @Callable(i)
514533 func gwxUserInfoREADONLY (userAddress) = {
515534 let gwxAmount = calcCurrentGwxAmount(userAddress)
516535 $Tuple2(nil, [gwxAmount])
517536 }
518537
519538

github/deemru/w8io/169f3d6 
77.24 ms