2021.12.15 16:50 [2900438] smart account 3PJL8Hn8LACaSBWLQ3UVhctA5cTQLBFwBAP > SELF 0.00000000 Waves

{ "type": 13, "id": "5TCoSTQuj19LhQspv1EFqTgdExmkpPx6rhHaR7CfKYNm", "fee": 1000000, "feeAssetId": null, "timestamp": 1639576273612, "version": 1, "sender": "3PJL8Hn8LACaSBWLQ3UVhctA5cTQLBFwBAP", "senderPublicKey": "6PdA345SW1zresPEKuWiLPsh9Ku14mFDW6cZtpCQrp3E", "proofs": [ "5AvFgMtZce9eYzX85JzvmaTguNBVARRQC1JeupgKFxFfH2B5iLENeK8tmZhr8zKVwq2QoFCkZswYVtfzAicYv97m" ], "script": "base64:AAIFAAAAAAAAACwIAhIICgYICAEBAQgSAwoBARIDCgEBEgQKAggIEgQKAggIEgMKAQgSAwoBCAAAAF8AAAAAA1NFUAIAAAACX18AAAAABlNDQUxFOAAAAAAAAAAACAAAAAAFTVVMVDgAAAAAAAX14QAAAAAADlBPT0xXRUlHSFRNVUxUBQAAAAVNVUxUOAEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAgAAAAdhZGRyZXNzAAAAA2tleQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAAB2FkZHJlc3MFAAAAA2tleQkAASwAAAACCQABLAAAAAICAAAAD21hbmRhdG9yeSB0aGlzLgUAAAADa2V5AgAAAA8gaXMgbm90IGRlZmluZWQBAAAADGdldEludE9yWmVybwAAAAIAAAAHYWRkcmVzcwAAAANrZXkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAHYWRkcmVzcwUAAAADa2V5AAAAAAAAAAAAAQAAAA9nZXRJbnRPckRlZmF1bHQAAAADAAAAB2FkZHJlc3MAAAADa2V5AAAACmRlZmF1bHRWYWwJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAHYWRkcmVzcwUAAAADa2V5BQAAAApkZWZhdWx0VmFsAQAAAAxnZXRJbnRPckZhaWwAAAACAAAAB2FkZHJlc3MAAAADa2V5CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAHYWRkcmVzcwUAAAADa2V5CQABLAAAAAIJAAEsAAAAAgIAAAAPbWFuZGF0b3J5IHRoaXMuBQAAAANrZXkCAAAADyBpcyBub3QgZGVmaW5lZAEAAAADYWJzAAAAAQAAAAN2YWwDCQAAZgAAAAIAAAAAAAAAAAAFAAAAA3ZhbAkBAAAAAS0AAAABBQAAAAN2YWwFAAAAA3ZhbAEAAAAJYXNBbnlMaXN0AAAAAQAAAAN2YWwEAAAAByRtYXRjaDAFAAAAA3ZhbAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAJTGlzdFtBbnldBAAAAAp2YWxBbnlMeXN0BQAAAAckbWF0Y2gwBQAAAAp2YWxBbnlMeXN0CQAAAgAAAAECAAAAG2ZhaWwgdG8gY2FzdCBpbnRvIExpc3RbQW55XQEAAAAFYXNJbnQAAAABAAAAA3ZhbAQAAAAHJG1hdGNoMAUAAAADdmFsAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAANJbnQEAAAABnZhbEludAUAAAAHJG1hdGNoMAUAAAAGdmFsSW50CQAAAgAAAAECAAAAFWZhaWwgdG8gY2FzdCBpbnRvIEludAEAAAARa2V5RmFjdG9yeUFkZHJlc3MAAAAAAgAAABwlcyVzX19jb25maWdfX2ZhY3RvcnlBZGRyZXNzAAAAABhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHAAAAAAAAAAAAEAAAAAGUlkeEZhY3RvcnlDZmdCb29zdGluZ0RhcHAAAAAAAAAAAAIAAAAAFElkeEZhY3RvcnlDZmdJZG9EYXBwAAAAAAAAAAADAAAAABVJZHhGYWN0b3J5Q2ZnVGVhbURhcHAAAAAAAAAAAAQAAAAAGUlkeEZhY3RvcnlDZmdFbWlzc2lvbkRhcHAAAAAAAAAAAAUAAAAAFUlkeEZhY3RvcnlDZmdSZXN0RGFwcAAAAAAAAAAABgAAAAAZSWR4RmFjdG9yeUNmZ1NsaXBwYWdlRGFwcAAAAAAAAAAABwAAAAAUSWR4RmFjdG9yeUNmZ0Rhb0RhcHAAAAAAAAAAAAgAAAAAGklkeEZhY3RvcnlDZmdNYXJrZXRpbmdEYXBwAAAAAAAAAAAJAAAAABpJZHhGYWN0b3J5Q2ZnR3d4UmV3YXJkRGFwcAAAAAAAAAAACgAAAAAWSWR4RmFjdG9yeUNmZ0JpcmRzRGFwcAAAAAAAAAAACwEAAAANa2V5RmFjdG9yeUNmZwAAAAACAAAAESVzX19mYWN0b3J5Q29uZmlnAQAAABprZXlGYWN0b3J5THAyQXNzZXRzTWFwcGluZwAAAAEAAAAKbHBBc3NldFN0cgkABLkAAAACCQAETAAAAAICAAAABiVzJXMlcwkABEwAAAACBQAAAApscEFzc2V0U3RyCQAETAAAAAICAAAAHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUAAAADbmlsBQAAAANTRVABAAAAEGtleUZhY3RvcnlMcExpc3QAAAAAAgAAABAlc19fbHBUb2tlbnNMaXN0AQAAACZrZXlGYWN0b3J5THBBc3NldFRvUG9vbENvbnRyYWN0QWRkcmVzcwAAAAEAAAAKbHBBc3NldFN0cgkABLkAAAACCQAETAAAAAICAAAABiVzJXMlcwkABEwAAAACBQAAAApscEFzc2V0U3RyCQAETAAAAAICAAAAHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUAAAADbmlsBQAAAANTRVABAAAAFGtleUZhY3RvcnlQb29sV2VpZ2h0AAAAAQAAAA9jb250cmFjdEFkZHJlc3MJAAS5AAAAAgkABEwAAAACAgAAAAQlcyVzCQAETAAAAAICAAAACnBvb2xXZWlnaHQJAARMAAAAAgUAAAAPY29udHJhY3RBZGRyZXNzBQAAAANuaWwFAAAAA1NFUAEAAAAba2V5RmFjdG9yeVBvb2xXZWlnaHRIaXN0b3J5AAAAAgAAAAtwb29sQWRkcmVzcwAAAANudW0JAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAEiVzJXNfX3Bvb2xXZWlnaHRfXwUAAAALcG9vbEFkZHJlc3MCAAAAAl9fCQABpAAAAAEFAAAAA251bQEAAAAYcmVhZEZhY3RvcnlBZGRyZXNzT3JGYWlsAAAAAAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAIFAAAABHRoaXMJAQAAABFrZXlGYWN0b3J5QWRkcmVzcwAAAAABAAAACnJlYWRMcExpc3QAAAAACQAEtQAAAAIJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgkBAAAAGHJlYWRGYWN0b3J5QWRkcmVzc09yRmFpbAAAAAAJAQAAABBrZXlGYWN0b3J5THBMaXN0AAAAAAIAAAAABQAAAANTRVABAAAAFHJlYWRGYWN0b3J5Q2ZnT3JGYWlsAAAAAQAAAAdmYWN0b3J5CQAEtQAAAAIJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAACBQAAAAdmYWN0b3J5CQEAAAANa2V5RmFjdG9yeUNmZwAAAAAFAAAAA1NFUAEAAAAYZ2V0Qm9vc3RpbmdBZGRyZXNzT3JGYWlsAAAAAQAAAApmYWN0b3J5Q2ZnCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQABkQAAAAIFAAAACmZhY3RvcnlDZmcFAAAAGUlkeEZhY3RvcnlDZmdCb29zdGluZ0RhcHABAAAAGGdldEVtaXNzaW9uQWRkcmVzc09yRmFpbAAAAAEAAAAKZmFjdG9yeUNmZwkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkAAZEAAAACBQAAAApmYWN0b3J5Q2ZnBQAAABlJZHhGYWN0b3J5Q2ZnRW1pc3Npb25EYXBwAQAAABdnZXRTdGFraW5nQWRkcmVzc09yRmFpbAAAAAEAAAAKZmFjdG9yeUNmZwkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkAAZEAAAACBQAAAApmYWN0b3J5Q2ZnBQAAABhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHABAAAAGWdldEd3eFJld2FyZEFkZHJlc3NPckZhaWwAAAABAAAACmZhY3RvcnlDZmcJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAAGRAAAAAgUAAAAKZmFjdG9yeUNmZwUAAAAaSWR4RmFjdG9yeUNmZ0d3eFJld2FyZERhcHABAAAAHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAAAAACAAAAGyVzJXNfX3JhdGVQZXJCbG9ja19fY3VycmVudAEAAAAha2V5RW1pc3Npb25SYXRlUGVyQmxvY2tNYXhDdXJyZW50AAAAAAIAAAAeJXMlc19fcmF0ZVBlckJsb2NrTWF4X19jdXJyZW50AQAAABVrZXlFbWlzc2lvblN0YXJ0QmxvY2sAAAAAAgAAABolcyVzX19lbWlzc2lvbl9fc3RhcnRCbG9jawEAAAAba2V5RW1pc3Npb25EdXJhdGlvbkluQmxvY2tzAAAAAAIAAAAYJXMlc19fZW1pc3Npb25fX2R1cmF0aW9uAQAAABNrZXlFbWlzc2lvbkVuZEJsb2NrAAAAAAIAAAAYJXMlc19fZW1pc3Npb25fX2VuZEJsb2NrAQAAAA1rZXlOZXh0UGVyaW9kAAAAAAIAAAAOJXNfX25leHRQZXJpb2QBAAAAH2tleUd3eFJld2FyZEVtaXNzaW9uU3RhcnRIZWlnaHQAAAAAAgAAACglcyVzX19nd3hSZXdhcmRFbWlzc2lvblBhcnRfX3N0YXJ0SGVpZ2h0AAAAAA1JZHhDZmdBc3NldElkAAAAAAAAAAABAAAAABNJZHhDZmdNaW5Mb2NrQW1vdW50AAAAAAAAAAACAAAAABVJZHhDZmdNaW5Mb2NrRHVyYXRpb24AAAAAAAAAAAMAAAAAFUlkeENmZ01heExvY2tEdXJhdGlvbgAAAAAAAAAABAAAAAASSWR4Q2ZnTWF0aENvbnRyYWN0AAAAAAAAAAAFAQAAAAlrZXlDb25maWcAAAAAAgAAAAolc19fY29uZmlnAQAAABVyZWFkQ29uZmlnQXJyYXlPckZhaWwAAAAACQAEtQAAAAIJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAACBQAAAAR0aGlzCQEAAAAJa2V5Q29uZmlnAAAAAAUAAAADU0VQAQAAAA1mb3JtYXRDb25maWdTAAAABQAAAAdhc3NldElkAAAADW1pbkxvY2tBbW91bnQAAAAPbWluTG9ja0R1cmF0aW9uAAAAD21heExvY2tEdXJhdGlvbgAAAAxtYXRoQ29udHJhY3QJAAS5AAAAAgkABEwAAAACAgAAAAglcyVkJWQlZAkABEwAAAACBQAAAAdhc3NldElkCQAETAAAAAIFAAAADW1pbkxvY2tBbW91bnQJAARMAAAAAgUAAAAPbWluTG9ja0R1cmF0aW9uCQAETAAAAAIFAAAAD21heExvY2tEdXJhdGlvbgkABEwAAAACBQAAAAxtYXRoQ29udHJhY3QFAAAAA25pbAUAAAADU0VQAQAAAAxmb3JtYXRDb25maWcAAAAFAAAAB2Fzc2V0SWQAAAANbWluTG9ja0Ftb3VudAAAAA9taW5Mb2NrRHVyYXRpb24AAAAPbWF4TG9ja0R1cmF0aW9uAAAADG1hdGhDb250cmFjdAkBAAAADWZvcm1hdENvbmZpZ1MAAAAFBQAAAAdhc3NldElkCQABpAAAAAEFAAAADW1pbkxvY2tBbW91bnQJAAGkAAAAAQUAAAAPbWluTG9ja0R1cmF0aW9uCQABpAAAAAEFAAAAD21heExvY2tEdXJhdGlvbgUAAAAMbWF0aENvbnRyYWN0AAAAAA5JZHhMb2NrVXNlck51bQAAAAAAAAAAAQAAAAANSWR4TG9ja0Ftb3VudAAAAAAAAAAAAgAAAAAMSWR4TG9ja1N0YXJ0AAAAAAAAAAADAAAAAA9JZHhMb2NrRHVyYXRpb24AAAAAAAAAAAQAAAAADUlkeExvY2tQYXJhbUsAAAAAAAAAAAUA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BLkAAAACCQAETAAAAAICAAAAFiVzJWQlc19fcGFyYW1CeVVzZXJOdW0JAARMAAAAAgUAAAAHdXNlck51bQkABEwAAAACAgAAAAFiBQAAAANuaWwFAAAAA1NFUAEAAAAVa2V5TG9ja1BhcmFtQnlQZXJpb2RLAAAAAgAAAAd1c2VyTnVtAAAABnBlcmlvZAkABLkAAAACCQAETAAAAAICAAAAFyVzJWQlcyVkX19wYXJhbUJ5UGVyaW9kCQAETAAAAAIFAAAAB3VzZXJOdW0JAARMAAAAAgIAAAABawkABEwAAAACBQAAAAZwZXJpb2QFAAAAA25pbAUAAAADU0VQAQAAABVrZXlMb2NrUGFyYW1CeVBlcmlvZEIAAAACAAAAB3VzZXJOdW0AAAAGcGVyaW9kCQAEuQAAAAIJAARMAAAAAgIAAAAXJXMlZCVzJWRfX3BhcmFtQnlQZXJpb2QJAARMAAAAAgUAAAAHdXNlck51bQkABEwAAAACAgAAAAFiCQAETAAAAAIFAAAABnBlcmlvZAUAAAADbmlsBQAAAANTRVABAAAAF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAAAAAIAAAAeJXMlc19fc3RhdHNfX2FjdGl2ZVRvdGFsTG9ja2VkAQAAACBrZXlTdGF0c0xvY2tzRHVyYXRpb25TdW1JbkJsb2NrcwAAAAACAAAAJSVzJXNfX3N0YXRzX19sb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MBAAAAEmtleVN0YXRzTG9ja3NDb3VudAAAAAACAAAAFyVzJXNfX3N0YXRzX19sb2Nrc0NvdW50AQAAABJrZXlTdGF0c1VzZXJzQ291bnQAAAAAAgAAAB0lcyVzX19zdGF0c19fYWN0aXZlVXNlcnNDb3VudAEAAAAga2V5VXNlckJvb3N0RW1pc3Npb25MYXN0SU5URUdSQUwAAAABAAAAB3VzZXJOdW0JAAS5AAAAAgkABEwAAAACAgAAAB4lcyVkX191c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnQJAARMAAAAAgUAAAAHdXNlck51bQUAAAADbmlsBQAAAANTRVABAAAAImtleVVzZXJMcEJvb3N0RW1pc3Npb25MYXN0SU5URUdSQUwAAAACAAAAB3VzZXJOdW0AAAAJbHBBc3NldElkCQAEuQAAAAIJAARMAAAAAgIAAAAeJXMlZF9fdXNlckJvb3N0RW1pc3Npb25MYXN0SW50CQAETAAAAAIFAAAAB3VzZXJOdW0JAARMAAAAAgUAAAAJbHBBc3NldElkBQAAAANuaWwFAAAAA1NFUAEAAAAXa2V5VXNlck1heEJvb3N0SU5URUdSQUwAAAABAAAAB3VzZXJOdW0JAAS5AAAAAgkABEwAAAACAgAAABElcyVkX19tYXhCb29zdEludAkABEwAAAACBQAAAAd1c2VyTnVtBQAAAANuaWwFAAAAA1NFUAEAAAAYa2V5VG90YWxNYXhCb29zdElOVEVHUkFMAAAAAAIAAAAYJXMlc19fbWF4Qm9vc3RJbnRfX3RvdGFsAQAAACFrZXlVc2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWwAAAABAAAAB3VzZXJOdW0JAAS5AAAAAgkABEwAAAACAgAAACQlcyVkX191c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWwJAARMAAAAAgUAAAAHdXNlck51bQUAAAADbmlsBQAAAANTRVABAAAAE2tleVVzZXJCb29zdENsYWltZWQAAAABAAAAB3VzZXJOdW0JAAS5AAAAAgkABEwAAAACAgAAABYlcyVkX191c2VyQm9vc3RDbGFpbWVkCQAETAAAAAIFAAAAB3VzZXJOdW0FAAAAA25pbAUAAAADU0VQAQAAABFrZXlUb3RhbENhY2hlZEd3eAAAAAACAAAAFiVzJXNfX2d3eENhY2hlZF9fdG90YWwAAAAAD2ZhY3RvcnlDb250cmFjdAkBAAAAGHJlYWRGYWN0b3J5QWRkcmVzc09yRmFpbAAAAAAAAAAACmZhY3RvcnlDZmcJAQAAABRyZWFkRmFjdG9yeUNmZ09yRmFpbAAAAAEFAAAAD2ZhY3RvcnlDb250cmFjdAAAAAAQZW1pc3Npb25Db250cmFjdAkBAAAAGGdldEVtaXNzaW9uQWRkcmVzc09yRmFpbAAAAAEFAAAACmZhY3RvcnlDZmcAAAAAD3N0YWtpbmdDb250cmFjdAkBAAAAF2dldFN0YWtpbmdBZGRyZXNzT3JGYWlsAAAAAQUAAAAKZmFjdG9yeUNmZwAAAAARZ3d4UmV3YXJkQ29udHJhY3QJAQAAABlnZXRHd3hSZXdhcmRBZGRyZXNzT3JGYWlsAAAAAQUAAAAKZmFjdG9yeUNmZwEAAAAMSGlzdG9yeUVudHJ5AAAACAAAAAR0eXBlAAAABHVzZXIAAAAGYW1vdW50AAAACWxvY2tTdGFydAAAAAhkdXJhdGlvbgAAAAFrAAAAAWIAAAABaQQAAAAKaGlzdG9yeUtFWQkABLkAAAACCQAETAAAAAICAAAAESVzJXMlcyVzX19oaXN0b3J5CQAETAAAAAIFAAAABHR5cGUJAARMAAAAAgUAAAAEdXNlcgkABEwAAAACCQACWAAAAAEIBQAAAAFpAAAADXRyYW5zYWN0aW9uSWQFAAAAA25pbAUAAAADU0VQBAAAAAtoaXN0b3J5REFUQQkABLkAAAACCQAETAAAAAICAAAADiVkJWQlZCVkJWQlZCVkCQAETAAAAAIJAAGkAAAAAQgFAAAACWxhc3RCbG9jawAAAAZoZWlnaHQJAARMAAAAAgkAAaQAAAABCAUAAAAJbGFzdEJsb2NrAAAACXRpbWVzdGFtcAkABEwAAAACCQABpAAAAAEFAAAABmFtb3VudAkABEwAAAACCQABpAAAAAEFAAAACWxvY2tTdGFydAkABEwAAAACCQABpAAAAAEFAAAACGR1cmF0aW9uCQAETAAAAAIJAAGkAAAAAQUAAAABawkABEwAAAACCQABpAAAAAEFAAAAAWIFAAAAA25pbAUAAAADU0VQCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAApoaXN0b3J5S0VZBQAAAAtoaXN0b3J5REFUQQEAAAAKU3RhdHNFbnRyeQAAAAQAAAAOdG90YWxMb2NrZWRJbmMAAAALZHVyYXRpb25JbmMAAAAMbG9ja0NvdW50SW5jAAAADXVzZXJzQ291bnRJbmMEAAAAG2xvY2tzRHVyYXRpb25TdW1JbkJsb2Nrc0tFWQkBAAAAIGtleVN0YXRzTG9ja3NEdXJhdGlvblN1bUluQmxvY2tzAAAAAAQAAAANbG9ja3NDb3VudEtFWQkBAAAAEmtleVN0YXRzTG9ja3NDb3VudAAAAAAEAAAADXVzZXJzQ291bnRLRVkJAQAAABJrZXlTdGF0c1VzZXJzQ291bnQAAAAABAAAAA50b3RhbEFtb3VudEtFWQkBAAAAF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50AAAAAAQAAAAYbG9ja3NEdXJhdGlvblN1bUluQmxvY2tzCQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAbbG9ja3NEdXJhdGlvblN1bUluQmxvY2tzS0VZBAAAAApsb2Nrc0NvdW50CQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAANbG9ja3NDb3VudEtFWQQAAAAKdXNlcnNDb3VudAkBAAAADGdldEludE9yWmVybwAAAAIFAAAABHRoaXMFAAAADXVzZXJzQ291bnRLRVkEAAAAC3RvdGFsQW1vdW50CQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAOdG90YWxBbW91bnRLRVkJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAG2xvY2tzRHVyYXRpb25TdW1JbkJsb2Nrc0tFWQkAAGQAAAACBQAAABhsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MFAAAAC2R1cmF0aW9uSW5jCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA1sb2Nrc0NvdW50S0VZCQAAZAAAAAIFAAAACmxvY2tzQ291bnQFAAAADGxvY2tDb3VudEluYwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAANdXNlcnNDb3VudEtFWQkAAGQAAAACBQAAAAp1c2Vyc0NvdW50BQAAAA11c2Vyc0NvdW50SW5jCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA50b3RhbEFtb3VudEtFWQkAAGQAAAACBQAAAAt0b3RhbEFtb3VudAUAAAAOdG90YWxMb2NrZWRJbmMFAAAAA25pbAEAAAANY2FsY0d3eEFtb3VudAAAAAMAAAAEa1JhdwAAAARiUmF3AAAAAWgEAAAABVNDQUxFAAAAAAAAAAPoCQAAaQAAAAIJAABkAAAAAgkAAGgAAAACBQAAAARrUmF3BQAAAAFoBQAAAARiUmF3BQAAAAVTQ0FMRQEAAAAPTG9ja1BhcmFtc0VudHJ5AAAACAAAAAt1c2VyQWRkcmVzcwAAAAd1c2VyTnVtAAAABmFtb3VudAAAAAVzdGFydAAAAAhkdXJhdGlvbgAAAAFrAAAAAWIAAAAGcGVyaW9kBAAAAA11c2VyQW1vdW50S0VZCQEAAAAWa2V5TG9ja1BhcmFtVXNlckFtb3VudAAAAAEFAAAAB3VzZXJOdW0EAAAADXN0YXJ0QmxvY2tLRVkJAQAAABZrZXlMb2NrUGFyYW1TdGFydEJsb2NrAAAAAQUAAAAHdXNlck51bQQAAAALZHVyYXRpb25LRVkJAQAAABRrZXlMb2NrUGFyYW1EdXJhdGlvbgAAAAEFAAAAB3VzZXJOdW0EAAAABGtLRVkJAQAAAA1rZXlMb2NrUGFyYW1LAAAAAQUAAAAHdXNlck51bQQAAAAEYktFWQkBAAAADWtleUxvY2tQYXJhbUIAAAABBQAAAAd1c2VyTnVtBAAAAAtrQnlQZXJpb0tFWQkBAAAAFWtleUxvY2tQYXJhbUJ5UGVyaW9kSwAAAAIFAAAAB3VzZXJOdW0FAAAABnBlcmlvZAQAAAAMYkJ5UGVyaW9kS0VZCQEAAAAVa2V5TG9ja1BhcmFtQnlQZXJpb2RCAAAAAgUAAAAHdXNlck51bQUAAAAGcGVyaW9kBAAAAAlnd3hBbW91bnQJAQAAAA1jYWxjR3d4QW1vdW50AAAAAwUAAAABawUAAAABYgUAAAAGaGVpZ2h0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA11c2VyQW1vdW50S0VZBQAAAAZhbW91bnQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAADXN0YXJ0QmxvY2tLRVkFAAAABXN0YXJ0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAtkdXJhdGlvbktFWQUAAAAIZHVyYXRpb24JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAABGtLRVkFAAAAAWsJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAABGJLRVkFAAAAAWIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAC2tCeVBlcmlvS0VZBQAAAAFrCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAxiQnlQZXJpb2RLRVkFAAAAAWIJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAE2tleUxvY2tQYXJhbXNSZWNvcmQAAAABBQAAAAt1c2VyQWRkcmVzcwkBAAAAFmZvcm1hdExvY2tQYXJhbXNSZWNvcmQAAAAHBQAAAAd1c2VyTnVtBQAAAAZhbW91bnQFAAAABXN0YXJ0BQAAAAhkdXJhdGlvbgUAAAABawUAAAABYgUAAAAJZ3d4QW1vdW50BQAAAANuaWwBAAAAImV4dHJhY3RPcHRpb25hbFBheW1lbnRBbW91bnRPckZhaWwAAAACAAAAAWkAAAAPZXhwZWN0ZWRBc3NldElkAwkAAGYAAAACCQABkAAAAAEIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABCQAAAgAAAAECAAAAG29ubHkgb25lIHBheW1lbnQgaXMgYWxsb3dlZAMJAAAAAAAAAgkAAZAAAAABCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAAAAAAAAAQAAAADcG10CQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAAAAwkBAAAAAiE9AAAAAgkBAAAABXZhbHVlAAAAAQgFAAAAA3BtdAAAAAdhc3NldElkBQAAAA9leHBlY3RlZEFzc2V0SWQJAAACAAAAAQIAAAAbaW52YWxpZCBhc3NldCBpZCBpbiBwYXltZW50CAUAAAADcG10AAAABmFtb3VudAEAAAAUY2FsY0N1cnJlbnRHd3hBbW91bnQAAAABAAAAC3VzZXJBZGRyZXNzBAAAAAVFTVBUWQIAAAAFZW1wdHkEAAAAEnVzZXIyTnVtTWFwcGluZ0tFWQkBAAAAEmtleVVzZXIyTnVtTWFwcGluZwAAAAEFAAAAC3VzZXJBZGRyZXNzBAAAAAd1c2VyTnVtCQEAAAALdmFsdWVPckVsc2UAAAACCQAEIgAAAAEFAAAAEnVzZXIyTnVtTWFwcGluZ0tFWQUAAAAFRU1QVFkEAAAAAWsJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQfAAAAAQkBAAAADWtleUxvY2tQYXJhbUsAAAABBQAAAAd1c2VyTnVtAAAAAAAAAAAABAAAAAFiCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHwAAAAEJAQAAAA1rZXlMb2NrUGFyYW1CAAAAAQUAAAAHdXNlck51bQAAAAAAAAAAAAQAAAANZ3d4QW1vdW50Q2FsYwkBAAAADWNhbGNHd3hBbW91bnQAAAADBQAAAAFrBQAAAAFiBQAAAAZoZWlnaHQEAAAACWd3eEFtb3VudAMJAABmAAAAAgAAAAAAAAAAAAUAAAANZ3d4QW1vdW50Q2FsYwAAAAAAAAAAAAUAAAANZ3d4QW1vdW50Q2FsYwUAAAAJZ3d4QW1vdW50AQAAABRpbnRlcm5hbENsYWltV3hCb29zdAAAAAMAAAAMbHBBc3NldElkU3RyAAAADnVzZXJBZGRyZXNzU3RyAAAACHJlYWRPbmx5BAAAAAVFTVBUWQIAAAAFRU1QVFkEAAAAEXVzZXJSZWNvcmRPckVtcHR5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMJAQAAABNrZXlMb2NrUGFyYW1zUmVjb3JkAAAAAQUAAAAOdXNlckFkZHJlc3NTdHIFAAAABUVNUFRZAwkAAAAAAAACBQAAABF1c2VyUmVjb3JkT3JFbXB0eQUAAAAFRU1QVFkJAAUVAAAAAwAAAAAAAAAAAAUAAAADbmlsAgAAABV1c2VyUmVjb3JkOjppczo6ZW1wdHkEAAAAD3VzZXJSZWNvcmRBcnJheQkABLUAAAACBQAAABF1c2VyUmVjb3JkT3JFbXB0eQUAAAADU0VQBAAAAAp1c2VyTnVtU3RyCQABkQAAAAIFAAAAD3VzZXJSZWNvcmRBcnJheQUAAAAOSWR4TG9ja1VzZXJOdW0EAAAAHGd3eFJld2FyZEVtaXNzaW9uU3RhcnRIZWlnaHQJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAARZ3d4UmV3YXJkQ29udHJhY3QJAQAAAB9rZXlHd3hSZXdhcmRFbWlzc2lvblN0YXJ0SGVpZ2h0AAAAAAAAAAAAAAAAAAQAAAAIRU1QVFlTVFICAAAABWVtcHR5BAAAAA0kdDAxMjM3MTEyOTM5AwkBAAAAAiE9AAAAAgUAAAAMbHBBc3NldElkU3RyBQAAAAhFTVBUWVNUUgQAAAAOcG9vbEFkZHJlc3NTdHIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAA9mYWN0b3J5Q29udHJhY3QJAQAAABprZXlGYWN0b3J5THAyQXNzZXRzTWFwcGluZwAAAAEFAAAADGxwQXNzZXRJZFN0cgkAASwAAAACAgAAABV1bnN1cHBvcnRlZCBscCBhc3NldCAFAAAADGxwQXNzZXRJZFN0cgQAAAADcHcxCQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAA9mYWN0b3J5Q29udHJhY3QJAQAAABRrZXlGYWN0b3J5UG9vbFdlaWdodAAAAAEFAAAADnBvb2xBZGRyZXNzU3RyBAAAAANwdzAJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAPZmFjdG9yeUNvbnRyYWN0CQEAAAAba2V5RmFjdG9yeVBvb2xXZWlnaHRIaXN0b3J5AAAAAgUAAAAOcG9vbEFkZHJlc3NTdHIAAAAAAAAAAAAFAAAAA3B3MQkABRQAAAACBQAAAANwdzAFAAAAA3B3MQMFAAAACHJlYWRPbmx5CQAFFAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAJAAACAAAAAQkAASwAAAACAgAAAChub3QgcmVhZG9ubHkgbW9kZTogdW5zdXBwb3J0ZWQgbHAgYXNzZXQgBQAAAAxscEFzc2V0SWRTdHIEAAAAC3Bvb2xXZWlnaHQwCAUAAAANJHQwMTIzNzExMjkzOQAAAAJfMQQAAAALcG9vbFdlaWdodDEIBQAAAA0kdDAxMjM3MTEyOTM5AAAAAl8yBAAAABJ3eEVtaXNzaW9uUGVyQmxvY2sJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAAea2V5RW1pc3Npb25SYXRlUGVyQmxvY2tDdXJyZW50AAAAAAQAAAANZW1pc3Npb25TdGFydAkBAAAADGdldEludE9yRmFpbAAAAAIFAAAAEGVtaXNzaW9uQ29udHJhY3QJAQAAABVrZXlFbWlzc2lvblN0YXJ0QmxvY2sAAAAABAAAAAtlbWlzc2lvbkVuZAkBAAAADGdldEludE9yRmFpbAAAAAIFAAAAEGVtaXNzaW9uQ29udHJhY3QJAQAAABNrZXlFbWlzc2lvbkVuZEJsb2NrAAAAAAQAAAABaAMJAABmAAAAAgUAAAAGaGVpZ2h0BQAAAAtlbWlzc2lvbkVuZAUAAAALZW1pc3Npb25FbmQFAAAABmhlaWdodAQAAAACZGgJAAGWAAAAAQkABEwAAAACCQAAZQAAAAIFAAAAAWgFAAAADWVtaXNzaW9uU3RhcnQJAARMAAAAAgAAAAAAAAAAAAUAAAADbmlsBAAAACJ1c2VyTHBCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZCQEAAAAia2V5VXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAAAAAIFAAAACnVzZXJOdW1TdHIFAAAADGxwQXNzZXRJZFN0cgQAAAAgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJAQAAACBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAAAAAEFAAAACnVzZXJOdW1TdHIEAAAAHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAInVzZXJMcEJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAACB1c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWQQAAAAVYm9vc3RFbWlzc2lvbkludGVncmFsCQAAaQAAAAIJAABoAAAAAgkAAGgAAAACBQAAABJ3eEVtaXNzaW9uUGVyQmxvY2sFAAAAAmRoAAAAAAAAAAACAAAAAAAAAAADBAAAABl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsCQAAZQAAAAIFAAAAFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAUAAAAddXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWwEAAAAA3VkaAkAAGsAAAADBQAAABl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsAAAAAAAAAAADCQAAaAAAAAIAAAAAAAAAAAIFAAAAEnd4RW1pc3Npb25QZXJCbG9jawQAAAAGdUxhc3RICQAAZQAAAAIFAAAAAWgFAAAAA3VkaAQAAAAEdWRoMAkAAZYAAAABCQAETAAAAAIJAABlAAAAAgUAAAAcZ3d4UmV3YXJkRW1pc3Npb25TdGFydEhlaWdodAUAAAAGdUxhc3RICQAETAAAAAIAAAAAAAAAAAAFAAAAA25pbAQAAAAEdWRoMQkAAGUAAAACCQAAZQAAAAIFAAAAAWgFAAAABnVMYXN0SAUAAAAEdWRoMAMDAwkAAGYAAAACAAAAAAAAAAAABQAAAAZ1TGFzdEgGCQAAZgAAAAIAAAAAAAAAAAAFAAAABHVkaDEGCQAAZwAAAAIJAQAAAANhYnMAAAABCQAAZQAAAAIJAABkAAAAAgUAAAAEdWRoMAUAAAAEdWRoMQUAAAADdWRoAAAAAAAAAAABCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAWaW52YWxpZCB1ZGggY2FsYzogdWRoPQkAAaQAAAABBQAAAAN1ZGgCAAAACCB1TGFzdEg9CQABpAAAAAEFAAAABnVMYXN0SAIAAAAGIHVkaDA9CQABpAAAAAEFAAAABHVkaDACAAAABiB1ZGgxPQkAAaQAAAABBQAAAAR1ZGgxAwkAAGYAAAACAAAAAAAAAAAABQAAABl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsCQAAAgAAAAECAAAAEndyb25nIGNhbGN1bGF0aW9ucwQAAAAXdXNlck1heEJvb3N0SW50ZWdyYWxLRVkJAQAAABdrZXlVc2VyTWF4Qm9vc3RJTlRFR1JBTAAAAAEFAAAACnVzZXJOdW1TdHIEAAAAGHRvdGFsTWF4Qm9vc3RJbnRlZ3JhbEtFWQkBAAAAGGtleVRvdGFsTWF4Qm9vc3RJTlRFR1JBTAAAAAAEAAAAD3VzZXJNYXhCb29zdEludAkBAAAADGdldEludE9yWmVybwAAAAIFAAAABHRoaXMFAAAAF3VzZXJNYXhCb29zdEludGVncmFsS0VZBAAAABB0b3RhbE1heEJvb3N0SW50CQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAYdG90YWxNYXhCb29zdEludGVncmFsS0VZBAAAABF0b3RhbENhY2hlZEd3eEtFWQkBAAAAEWtleVRvdGFsQ2FjaGVkR3d4AAAAAAQAAAAOdG90YWxDYWNoZWRHd3gJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAARdG90YWxDYWNoZWRHd3hLRVkAAAAAAAAAAAAEAAAAC3VzZXJDdXJyR3d4CQEAAAAUY2FsY0N1cnJlbnRHd3hBbW91bnQAAAABBQAAAA51c2VyQWRkcmVzc1N0cgQAAAAhdXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsS0VZCQEAAAAha2V5VXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsAAAAAQUAAAAKdXNlck51bVN0cgQAAAAedXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsCQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAhdXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsS0VZBAAAABp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMAkAAGsAAAADBQAAABl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsBQAAAAR1ZGgwBQAAAAN1ZGgEAAAAGnVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwxCQAAawAAAAMFAAAAGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwFAAAABHVkaDEFAAAAA3VkaAQAAAAecG9vbFVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwwCQAAawAAAAMFAAAAGnVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwwBQAAAAtwb29sV2VpZ2h0MAUAAAAOUE9PTFdFSUdIVE1VTFQEAAAAHnBvb2xVc2VyQm9vc3RFbWlzc2lvbkludGVncmFsMQkAAGsAAAADBQAAABp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMQUAAAALcG9vbFdlaWdodDEFAAAADlBPT0xXRUlHSFRNVUxUBAAAACJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcwAwkAAAAAAAACBQAAAA50b3RhbENhY2hlZEd3eAAAAAAAAAAAAAAAAAAAAAAAAAkAAGsAAAADBQAAAB5wb29sVXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbDAFAAAAC3VzZXJDdXJyR3d4BQAAAA50b3RhbENhY2hlZEd3eAQAAAAidXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsTmV3MQMJAAAAAAAAAgUAAAAOdG90YWxDYWNoZWRHd3gAAAAAAAAAAAAAAAAAAAAAAAAJAABrAAAAAwUAAAAecG9vbFVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwxBQAAAAt1c2VyQ3Vyckd3eAUAAAAOdG90YWxDYWNoZWRHd3gEAAAAIXVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbE5ldwkAAGQAAAACBQAAACJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcwBQAAACJ1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcxBAAAABN1c2VyQm9vc3RDbGFpbWVkS0VZCQEAAAATa2V5VXNlckJvb3N0Q2xhaW1lZAAAAAEFAAAACnVzZXJOdW1TdHIEAAAAEHVzZXJCb29zdENsYWltZWQJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAABN1c2VyQm9vc3RDbGFpbWVkS0VZBAAAABJ1c2VyQm9vc3RBdmFpbGFibGUJAABlAAAAAgUAAAAhdXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsTmV3BQAAABB1c2VyQm9vc3RDbGFpbWVkBAAAAAlkYXRhU3RhdGUJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAInVzZXJMcEJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkFAAAAFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAUAAAADbmlsBAAAAAVkZWJ1ZwkABLkAAAACCQAETAAAAAIJAAEsAAAAAgIAAAAedXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWw9CQABpAAAAAEFAAAAHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsCQAETAAAAAIJAAEsAAAAAgIAAAAadXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbD0JAAGkAAAAAQUAAAAZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAkABEwAAAACCQABLAAAAAICAAAAEHVzZXJNYXhCb29zdEludD0JAAGkAAAAAQUAAAAPdXNlck1heEJvb3N0SW50CQAETAAAAAIJAAEsAAAAAgIAAAARdG90YWxNYXhCb29zdEludD0JAAGkAAAAAQUAAAAQdG90YWxNYXhCb29zdEludAkABEwAAAACCQABLAAAAAICAAAAH3VzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbD0JAAGkAAAAAQUAAAAedXNlckJvb3N0QXZhbGlh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BCIAAAABCQEAAAASa2V5VXNlcjJOdW1NYXBwaW5nAAAAAQUAAAAOdXNlckFkZHJlc3NTdHIEAAAACnVzZXJOdW1TdHIDBQAAAA51c2VySXNFeGlzdGluZwkBAAAABXZhbHVlAAAAAQkABCIAAAABCQEAAAASa2V5VXNlcjJOdW1NYXBwaW5nAAAAAQUAAAAOdXNlckFkZHJlc3NTdHIJAAGkAAAAAQkBAAAADGdldEludE9yRmFpbAAAAAIFAAAABHRoaXMFAAAADm5leHRVc2VyTnVtS0VZBAAAAAd1c2VyTnVtCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEFAAAACnVzZXJOdW1TdHIEAAAACWxvY2tTdGFydAUAAAAGaGVpZ2h0BAAAAA1zdGFydEJsb2NrS0VZCQEAAAAWa2V5TG9ja1BhcmFtU3RhcnRCbG9jawAAAAEFAAAACnVzZXJOdW1TdHIEAAAAC2R1cmF0aW9uS0VZCQEAAAAUa2V5TG9ja1BhcmFtRHVyYXRpb24AAAABBQAAAAp1c2VyTnVtU3RyBAAAAA11c2VyQW1vdW50S0VZCQEAAAAWa2V5TG9ja1BhcmFtVXNlckFtb3VudAAAAAEFAAAACnVzZXJOdW1TdHIDCQAAZgAAAAIFAAAADW1pbkxvY2tBbW91bnQFAAAACXBtdEFtb3VudAkAAAIAAAABCQABLAAAAAICAAAAImFtb3VudCBpcyBsZXNzIHRoZW4gbWluTG9ja0Ftb3VudD0JAAGkAAAAAQUAAAANbWluTG9ja0Ftb3VudAMJAABmAAAAAgUAAAAPbWluTG9ja0R1cmF0aW9uBQAAAAhkdXJhdGlvbgkAAAIAAAABCQABLAAAAAICAAAALXBhc3NlZCBkdXJhdGlvbiBpcyBsZXNzIHRoZW4gbWluTG9ja0R1cmF0aW9uPQkAAaQAAAABBQAAAA9taW5Mb2NrRHVyYXRpb24DCQAAZgAAAAIFAAAACGR1cmF0aW9uBQAAAA9tYXhMb2NrRHVyYXRpb24JAAACAAAAAQkAASwAAAACAgAAADBwYXNzZWQgZHVyYXRpb24gaXMgZ3JlYXRlciB0aGVuIG1heExvY2tEdXJhdGlvbj0JAAGkAAAAAQUAAAAPbWF4TG9ja0R1cmF0aW9uAwMFAAAADnVzZXJJc0V4aXN0aW5nCQAAZwAAAAIJAABkAAAAAgkBAAAADGdldEludE9yRmFpbAAAAAIFAAAABHRoaXMFAAAADXN0YXJ0QmxvY2tLRVkJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAAAR0aGlzBQAAAAtkdXJhdGlvbktFWQUAAAAJbG9ja1N0YXJ0BwkAAAIAAAABAgAAADZ0aGVyZSBpcyBhbiBhY3RpdmUgbG9jayAtIGNvbnNpZGVyIHRvIHVzZSBpbmNyZWFzZUxvY2sDCQAAZgAAAAIJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAAA11c2VyQW1vdW50S0VZAAAAAAAAAAAACQAAAgAAAAEJAAEsAAAAAgIAAAA0dGhlcmUgYXJlIGxvY2tlZCBXWHMgLSBjb25zaWRlciB0byB1c2UgaW5jcmVhc2VMb2NrIAUAAAANdXNlckFtb3VudEtFWQQAAAAHY29lZmZYOAkAAGsAAAADBQAAAAhkdXJhdGlvbgUAAAAFTVVMVDgFAAAAD21heExvY2tEdXJhdGlvbgQAAAAOZ1d4QW1vdW50U3RhcnQJAABrAAAAAwUAAAAJcG10QW1vdW50BQAAAAdjb2VmZlg4BQAAAAVNVUxUOAQAAAATZ1d4UGFyYW1zUmVzdWx0TGlzdAkBAAAACWFzQW55TGlzdAAAAAEJAAP8AAAABAUAAAAMbWF0aENvbnRyYWN0AgAAABVjYWxjR3d4UGFyYW1zUkVBRE9OTFkJAARMAAAAAgUAAAAOZ1d4QW1vdW50U3RhcnQJAARMAAAAAgUAAAAJbG9ja1N0YXJ0CQAETAAAAAIFAAAACGR1cmF0aW9uBQAAAANuaWwFAAAAA25pbAQAAAABawkBAAAABWFzSW50AAAAAQkAAZEAAAACBQAAABNnV3hQYXJhbXNSZXN1bHRMaXN0AAAAAAAAAAAABAAAAAFiCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAAE2dXeFBhcmFtc1Jlc3VsdExpc3QAAAAAAAAAAAEEAAAABnBlcmlvZAkAAaQAAAABCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAAE2dXeFBhcmFtc1Jlc3VsdExpc3QAAAAAAAAAAAIEAAAAEnd4RW1pc3Npb25QZXJCbG9jawkBAAAADGdldEludE9yRmFpbAAAAAIFAAAAEGVtaXNzaW9uQ29udHJhY3QJAQAAAB5rZXlFbWlzc2lvblJhdGVQZXJCbG9ja0N1cnJlbnQAAAAABAAAAA1lbWlzc2lvblN0YXJ0CQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAQZW1pc3Npb25Db250cmFjdAkBAAAAFWtleUVtaXNzaW9uU3RhcnRCbG9jawAAAAAEAAAAC2VtaXNzaW9uRW5kCQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAQZW1pc3Npb25Db250cmFjdAkBAAAAE2tleUVtaXNzaW9uRW5kQmxvY2sAAAAABAAAAAFoAwkAAGYAAAACBQAAAAZoZWlnaHQFAAAAC2VtaXNzaW9uRW5kBQAAAAtlbWlzc2lvbkVuZAUAAAAGaGVpZ2h0BAAAAAJkaAkAAZYAAAABCQAETAAAAAIJAABlAAAAAgUAAAABaAUAAAANZW1pc3Npb25TdGFydAkABEwAAAACAAAAAAAAAAAABQAAAANuaWwEAAAAIHVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZCQEAAAAga2V5VXNlckJvb3N0RW1pc3Npb25MYXN0SU5URUdSQUwAAAABBQAAAAp1c2VyTnVtU3RyBAAAABVib29zdEVtaXNzaW9uSW50ZWdyYWwJAABpAAAAAgkAAGgAAAACCQAAaAAAAAIFAAAAEnd4RW1pc3Npb25QZXJCbG9jawUAAAACZGgAAAAAAAAAAAIAAAAAAAAAAAMEAAAAF3VzZXJNYXhCb29zdEludGVncmFsS0VZCQEAAAAXa2V5VXNlck1heEJvb3N0SU5URUdSQUwAAAABBQAAAAp1c2VyTnVtU3RyBAAAABh0b3RhbE1heEJvb3N0SW50ZWdyYWxLRVkJAQAAABhrZXlUb3RhbE1heEJvb3N0SU5URUdSQUwAAAAABAAAAA91c2VyTWF4Qm9vc3RJbnQJAABpAAAAAgkAAGgAAAACBQAAAA5nV3hBbW91bnRTdGFydAUAAAAIZHVyYXRpb24AAAAAAAAAAAIEAAAAEHRvdGFsTWF4Qm9vc3RJbnQJAQAAAAxnZXRJbnRPclplcm8AAAACBQAAAAR0aGlzBQAAABh0b3RhbE1heEJvb3N0SW50ZWdyYWxLRVkEAAAAEXRvdGFsQ2FjaGVkR3d4S0VZCQEAAAARa2V5VG90YWxDYWNoZWRHd3gAAAAABAAAAA50b3RhbENhY2hlZEd3eAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAABF0b3RhbENhY2hlZEd3eEtFWQAAAAAAAAAAAAQAAAADYXJyAwUAAAAOdXNlcklzRXhpc3RpbmcFAAAAA25pbAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAObmV4dFVzZXJOdW1LRVkJAABkAAAAAgUAAAAHdXNlck51bQAAAAAAAAAAAQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAASa2V5VXNlcjJOdW1NYXBwaW5nAAAAAQUAAAAOdXNlckFkZHJlc3NTdHIFAAAACnVzZXJOdW1TdHIJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAEmtleU51bTJVc2VyTWFwcGluZwAAAAEFAAAACnVzZXJOdW1TdHIFAAAADnVzZXJBZGRyZXNzU3RyBQAAAANuaWwJAAROAAAAAgkABE0AAAACCQAETgAAAAIJAAROAAAAAgUAAAADYXJyCQEAAAAPTG9ja1BhcmFtc0VudHJ5AAAACAUAAAAOdXNlckFkZHJlc3NTdHIFAAAACnVzZXJOdW1TdHIFAAAACXBtdEFtb3VudAUAAAAJbG9ja1N0YXJ0BQAAAAhkdXJhdGlvbgUAAAABawUAAAABYgUAAAAGcGVyaW9kCQEAAAAKU3RhdHNFbnRyeQAAAAQFAAAACXBtdEFtb3VudAUAAAAIZHVyYXRpb24AAAAAAAAAAAEDBQAAAA51c2VySXNFeGlzdGluZwAAAAAAAAAAAAAAAAAAAAAAAQkBAAAADEhpc3RvcnlFbnRyeQAAAAgCAAAABGxvY2sFAAAADnVzZXJBZGRyZXNzU3RyBQAAAAlwbXRBbW91bnQFAAAACWxvY2tTdGFydAUAAAAIZHVyYXRpb24FAAAAAWsFAAAAAWIFAAAAAWkJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAIHVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZBQAAABVib29zdEVtaXNzaW9uSW50ZWdyYWwJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEXRvdGFsQ2FjaGVkR3d4S0VZCQAAZAAAAAIFAAAADnRvdGFsQ2FjaGVkR3d4BQAAAA5nV3hBbW91bnRTdGFydAUAAAADbmlsAAAAAWkBAAAADGluY3JlYXNlTG9jawAAAAEAAAANZGVsdGFEdXJhdGlvbgQAAAAIY2ZnQXJyYXkJAQAAABVyZWFkQ29uZmlnQXJyYXlPckZhaWwAAAAABAAAAAphc3NldElkU3RyCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAAA1JZHhDZmdBc3NldElkBAAAAAdhc3NldElkCQACWQAAAAEFAAAACmFzc2V0SWRTdHIEAAAAD21pbkxvY2tEdXJhdGlvbgkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABVJZHhDZmdNaW5Mb2NrRHVyYXRpb24EAAAAD21heExvY2tEdXJhdGlvbgkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAABVJZHhDZmdNYXhMb2NrRHVyYXRpb24EAAAADG1hdGhDb250cmFjdAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkAAZEAAAACBQAAAAhjZmdBcnJheQUAAAASSWR4Q2ZnTWF0aENvbnRyYWN0BAAAAAlwbXRBbW91bnQJAQAAACJleHRyYWN0T3B0aW9uYWxQYXltZW50QW1vdW50T3JGYWlsAAAAAgUAAAABaQUAAAAHYXNzZXRJZAQAAAAOdXNlckFkZHJlc3NTdHIJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAAA91c2VyUmVjb3JkQXJyYXkJAQAAABpyZWFkTG9ja1BhcmFtc1JlY29yZE9yRmFpbAAAAAEFAAAADnVzZXJBZGRyZXNzU3RyBAAAAAp1c2VyTnVtU3RyCQABkQAAAAIFAAAAD3VzZXJSZWNvcmRBcnJheQUAAAAOSWR4TG9ja1VzZXJOdW0EAAAACnVzZXJBbW91bnQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAA91c2VyUmVjb3JkQXJyYXkFAAAADUlkeExvY2tBbW91bnQEAAAACWxvY2tTdGFydAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAAD3VzZXJSZWNvcmRBcnJheQUAAAAMSWR4TG9ja1N0YXJ0BAAAAAxsb2NrRHVyYXRpb24JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAA91c2VyUmVjb3JkQXJyYXkFAAAAD0lkeExvY2tEdXJhdGlvbgQAAAAHbG9ja0VuZAkAAGQAAAACBQAAAAlsb2NrU3RhcnQFAAAADGxvY2tEdXJhdGlvbgQAAAARcmVtYWluaW5nRHVyYXRpb24JAAGWAAAAAQkABEwAAAACCQAAZQAAAAIFAAAAB2xvY2tFbmQFAAAABmhlaWdodAkABEwAAAACAAAAAAAAAAAABQAAAANuaWwEAAAADXVzZXJBbW91bnROZXcJAABkAAAAAgUAAAAKdXNlckFtb3VudAUAAAAJcG10QW1vdW50BAAAAA9sb2NrRHVyYXRpb25OZXcJAABkAAAAAgUAAAARcmVtYWluaW5nRHVyYXRpb24FAAAADWRlbHRhRHVyYXRpb24DCQAAZgAAAAIAAAAAAAAAAAAFAAAADWRlbHRhRHVyYXRpb24JAAACAAAAAQIAAAAaZHVyYXRpb24gaXMgbGVzcyB0aGVuIHplcm8DCQAAZgAAAAIFAAAAD21pbkxvY2tEdXJhdGlvbgUAAAAPbG9ja0R1cmF0aW9uTmV3CQAAAgAAAAEJAAEsAAAAAgIAAAAtbG9ja0R1cmF0aW9uTmV3IGlzIGxlc3MgdGhlbiBtaW5Mb2NrRHVyYXRpb249CQABpAAAAAEFAAAAD21pbkxvY2tEdXJhdGlvbgMJAABmAAAAAgUAAAAPbG9ja0R1cmF0aW9uTmV3BQAAAA9tYXhMb2NrRHVyYXRpb24JAAACAAAAAQkAASwAAAACAgAAAERkZWx0YUR1cmF0aW9uICsgZXhpc3RlZExvY2tEdXJhdGlvbiBpcyBncmVhdGVyIHRoZW4gbWF4TG9ja0R1cmF0aW9uPQkAAaQAAAABBQAAAA9tYXhMb2NrRHVyYXRpb24EAAAAB2NvZWZmWDgJAABrAAAAAwUAAAAPbG9ja0R1cmF0aW9uTmV3BQAAAAVNVUxUOAUAAAAPbWF4TG9ja0R1cmF0aW9uBAAAAA5nV3hBbW91bnRTdGFydAkAAGsAAAADBQAAAA11c2VyQW1vdW50TmV3BQAAAAdjb2VmZlg4BQAAAAVNVUxUOAQAAAAMbG9ja1N0YXJ0TmV3BQAAAAZoZWlnaHQEAAAAE2dXeFBhcmFtc1Jlc3VsdExpc3QJAQAAAAlhc0FueUxpc3QAAAABCQAD/AAAAAQFAAAADG1hdGhDb250cmFjdAIAAAAVY2FsY0d3eFBhcmFtc1JFQURPTkxZCQAETAAAAAIFAAAADmdXeEFtb3VudFN0YXJ0CQAETAAAAAIFAAAADGxvY2tTdGFydE5ldwkABEwAAAACBQAAAA9sb2NrRHVyYXRpb25OZXcFAAAAA25pbAUAAAADbmlsBAAAAAFrCQEAAAAFYXNJbnQAAAABCQABkQAAAAIFAAAAE2dXeFBhcmFtc1Jlc3VsdExpc3QAAAAAAAAAAAAEAAAAAWIJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAATZ1d4UGFyYW1zUmVzdWx0TGlzdAAAAAAAAAAAAQQAAAAGcGVyaW9kCQABpAAAAAEJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAATZ1d4UGFyYW1zUmVzdWx0TGlzdAAAAAAAAAAAAgQAAAASd3hFbWlzc2lvblBlckJsb2NrCQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAQZW1pc3Npb25Db250cmFjdAkBAAAAHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAAAAAEAAAADWVtaXNzaW9uU3RhcnQJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAAVa2V5RW1pc3Npb25TdGFydEJsb2NrAAAAAAQAAAALZW1pc3Npb25FbmQJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAATa2V5RW1pc3Npb25FbmRCbG9jawAAAAAEAAAAAWgDCQAAZgAAAAIFAAAABmhlaWdodAUAAAALZW1pc3Npb25FbmQFAAAAC2VtaXNzaW9uRW5kBQAAAAZoZWlnaHQEAAAAAmRoCQABlgAAAAEJAARMAAAAAgkAAGUAAAACBQAAAAFoBQAAAA1lbWlzc2lvblN0YXJ0CQAETAAAAAIAAAAAAAAAAAAFAAAAA25pbAQAAAAgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkJAQAAACBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTAAAAAEFAAAACnVzZXJOdW1TdHIEAAAAHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsCQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkEAAAAFWJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAAGkAAAACCQAAaAAAAAIJAABoAAAAAgUAAAASd3hFbWlzc2lvblBlckJsb2NrBQAAAAJkaAAAAAAAAAAAAgAAAAAAAAAAAwQAAAAZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAkAAGUAAAACBQAAABVib29zdEVtaXNzaW9uSW50ZWdyYWwFAAAAHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsAwkAAGYAAAACAAAAAAAAAAAABQAAABl1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsCQAAAgAAAAECAAAAEndyb25nIGNhbGN1bGF0aW9ucwQAAAAXdXNlck1heEJvb3N0SW50ZWdyYWxLRVkJAQAAABdrZXlVc2VyTWF4Qm9vc3RJTlRFR1JBTAAAAAEFAAAACnVzZXJOdW1TdHIEAAAAGHRvdGFsTWF4Qm9vc3RJbnRlZ3JhbEtFWQkBAAAAGGtleVRvdGFsTWF4Qm9vc3RJTlRFR1JBTAAAAAAEAAAAD3VzZXJNYXhCb29zdEludAkBAAAADGdldEludE9yWmVybwAAAAIFAAAABHRoaXMFAAAAF3VzZXJNYXhCb29zdEludGVncmFsS0VZBAAAABB0b3RhbE1heEJvb3N0SW50CQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAYdG90YWxNYXhCb29zdEludGVncmFsS0VZBAAAAAtjdXJyVXNlckd3eAkBAAAAFGNhbGNDdXJyZW50R3d4QW1vdW50AAAAAQUAAAAOdXNlckFkZHJlc3NTdHIEAAAAB2d3eERpZmYJAABlAAAAAgUAAAAOZ1d4QW1vdW50U3RhcnQFAAAAC2N1cnJVc2VyR3d4AwkAAGYAAAACAAAAAAAAAAAABQAAAAdnd3hEaWZmCQAAAgAAAAEJAAEsAAAAAgIAAAAYZ3d4RGlmZiBpcyBsZXNzIHRoZW4gMDogCQABpAAAAAEFAAAAB2d3eERpZmYEAAAAEXRvdGFsQ2FjaGVkR3d4S0VZCQEAAAARa2V5VG90YWxDYWNoZWRHd3gAAAAABAAAAA50b3RhbENhY2hlZEd3eAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAABF0b3RhbENhY2hlZEd3eEtFWQAAAAAAAAAAAAQAAAAhdXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsS0VZCQEAAAAha2V5VXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsAAAAAQUAAAAKdXNlck51bVN0cgQAAAAedXNlckJvb3N0QXZhbGlhYmxlVG9DbGFpbVRvdGFsCQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAhdXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsS0VZBAAAACF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXcJAABrAAAAAwUAAAAZdXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbAUAAAALY3VyclVzZXJHd3gFAAAADnRvdGFsQ2FjaGVkR3d4BAAAABJ1c2VyTWF4Qm9vc3RJbnROZXcJAABpAAAAAgkAAGgAAAACBQAAAA5nV3hBbW91bnRTdGFydAUAAAAPbG9ja0R1cmF0aW9uTmV3AAAAAAAAAAACBAAAABhyZW1haW5pbmdVc2VyTWF4Qm9vc3RJbnQJAABpAAAAAgkAAGgAAAACBQAAAAtjdXJyVXNlckd3eAUAAAARcmVtYWluaW5nRHVyYXRpb24AAAAAAAAAAAIEAAAAE3VzZXJNYXhCb29zdEludERpZmYJAABlAAAAAgUAAAASdXNlck1heEJvb3N0SW50TmV3BQAAABhyZW1haW5pbmdVc2VyTWF4Qm9vc3RJbnQJAAROAAAAAgkABE0AAAACCQAETgAAAAIJAQAAAA9Mb2NrUGFyYW1zRW50cnkAAAAIBQAAAA51c2VyQWRkcmVzc1N0cgUAAAAKdXNlck51bVN0cgUAAAANdXNlckFtb3VudE5ldwUAAAAMbG9ja1N0YXJ0TmV3BQAAAA9sb2NrRHVyYXRpb25OZXcFAAAAAWsFAAAAAWIFAAAABnBlcmlvZAkBAAAAClN0YXRzRW50cnkAAAAEBQAAAAlwbXRBbW91bnQFAAAADWRlbHRhRHVyYXRpb24AAAAAAAAAAAAAAAAAAAAAAAAJAQAAAAxIaXN0b3J5RW50cnkAAAAIAgAAAARsb2NrBQAAAA51c2VyQWRkcmVzc1N0cgUAAAAJcG10QW1vdW50BQAAAAlsb2NrU3RhcnQFAAAAD2xvY2tEdXJhdGlvbk5ldwUAAAABawUAAAABYgUAAAABaQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARdG90YWxDYWNoZWRHd3hLRVkJAABkAAAAAgUAAAAOdG90YWxDYWNoZWRHd3gFAAAAB2d3eERpZmYFAAAAA25pbAAAAAFpAQAAAAxjbGFpbVd4Qm9vc3QAAAACAAAADGxwQXNzZXRJZFN0cgAAAA51c2VyQWRkcmVzc1N0cgMJAQAAAAIhPQAAAAIFAAAAD3N0YWtpbmdDb250cmFjdAgFAAAAAWkAAAAGY2FsbGVyCQAAAgAAAAECAAAAEnBlcm1pc3Npb25zIGRlbmllZAQAAAANJHQwMjcxNTgyNzI2MAkBAAAAFGludGVybmFsQ2xhaW1XeEJvb3N0AAAAAwUAAAAMbHBBc3NldElkU3RyBQAAAA51c2VyQWRkcmVzc1N0cgcEAAAAEnVzZXJCb29zdEF2YWlsYWJsZQgFAAAADSR0MDI3MTU4MjcyNjAAAAACXzEEAAAACWRhdGFTdGF0ZQgFAAAADSR0MDI3MTU4MjcyNjAAAAACXzIEAAAABWRlYnVnCAUAAAANJHQwMjcxNTgyNzI2MAAAAAJfMwkABRQAAAACBQAAAAlkYXRhU3RhdGUJAARMAAAAAgUAAAASdXNlckJvb3N0QXZhaWxhYmxlBQAAAANuaWwAAAABaQEAAAAUY2xhaW1XeEJvb3N0UkVBRE9OTFkAAAACAAAADGxwQXNzZXRJZFN0cgAAAA51c2VyQWRkcmVzc1N0cgQAAAANJHQwMjczOTIyNzQ5MwkBAAAAFGludGVybmFsQ2xhaW1XeEJvb3N0AAAAAwUAAAAMbHBBc3NldElkU3RyBQAAAA51c2VyQWRkcmVzc1N0cgYEAAAAEnVzZXJCb29zdEF2YWlsYWJsZQgFAAAADSR0MDI3MzkyMjc0OTMAAAACXzEEAAAACWRhdGFTdGF0ZQgFAAAADSR0MDI3MzkyMjc0OTMAAAACXzIEAAAABWRlYnVnCAUAAAANJHQwMjczOTIyNzQ5MwAAAAJfMwkABRQAAAACBQAAAANuaWwJAARMAAAAAgUAAAASdXNlckJvb3N0QXZhaWxhYmxlCQAETAAAAAIFAAAABWRlYnVnBQAAAANuaWwAAAABaQEAAAAGdW5sb2NrAAAAAQAAAAt1c2VyQWRkcmVzcwQAAAAPdXNlclJlY29yZEFycmF5CQEAAAAacmVhZExvY2tQYXJhbXNSZWNvcmRPckZhaWwAAAABBQAAAAt1c2VyQWRkcmVzcwQAAAAKdXNlck51bVN0cgkAAZEAAAACBQAAAA91c2VyUmVjb3JkQXJyYXkFAAAADklkeExvY2tVc2VyTnVtBAAAAAp1c2VyQW1vdW50CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAPdXNlclJlY29yZEFycmF5BQAAAA1JZHhMb2NrQW1vdW50BAAAAAlsb2NrU3RhcnQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAA91c2VyUmVjb3JkQXJyYXkFAAAADElkeExvY2tTdGFydAQAAAAMbG9ja0R1cmF0aW9uCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAPdXNlclJlY29yZEFycmF5BQAAAA9JZHhMb2NrRHVyYXRpb24EAAAAB2xvY2tFbmQJAABkAAAAAgUAAAAJbG9ja1N0YXJ0BQAAAAxsb2NrRHVyYXRpb24EAAAACGNmZ0FycmF5CQEAAAAVcmVhZENvbmZpZ0FycmF5T3JGYWlsAAAAAAQAAAAHYXNzZXRJZAkAAlkAAAABCQABkQAAAAIFAAAACGNmZ0FycmF5BQAAAA1JZHhDZmdBc3NldElkBAAAAAxtYXRoQ29udHJhY3QJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAAGRAAAAAgUAAAAIY2ZnQXJyYXkFAAAAEklkeENmZ01hdGhDb250cmFjdAMJAABnAAAAAgUAAAAHbG9ja0VuZAUAAAAGaGVpZ2h0CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAAAV3YWl0IAkAAaQAAAABBQAAAAdsb2NrRW5kAgAAAAogdG8gdW5sb2NrAwkAAGcAAAACAAAAAAAAAAAABQAAAAp1c2VyQW1vdW50CQAAAgAAAAECAAAAEW5vdGhpbmcgdG8gdW5sb2NrBAAAAAZwZXJpb2QJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAMbWF0aENvbnRyYWN0CQEAAAANa2V5TmV4dFBlcmlvZAAAAAAAAAAAAAAAAAAJAARNAAAAAgkABE0AAAACCQAETgAAAAIJAQAAAA9Mb2NrUGFyYW1zRW50cnkAAAAIBQAAAAt1c2VyQWRkcmVzcwUAAAAKdXNlck51bVN0cgAAAAAAAAAAAAUAAAAJbG9ja1N0YXJ0BQAAAAxsb2NrRHVyYXRpb24AAAAAAAAAAAAAAAAAAAAAAAAJAAGkAAAAAQUAAAAGcGVyaW9kCQEAAAAKU3RhdHNFbnRyeQAAAAQJAQAAAAEtAAAAAQUAAAAKdXNlckFtb3VudAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wkBAAAADEhpc3RvcnlFbnRyeQAAAAgCAAAABnVubG9jawUAAAALdXNlckFkZHJlc3MFAAAACnVzZXJBbW91bnQFAAAACWxvY2tTdGFydAUAAAAMbG9ja0R1cmF0aW9uAAAAAAAAAAAAAAAAAAAAAAAABQAAAAFpCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAAAt1c2VyQWRkcmVzcwUAAAAKdXNlckFtb3VudAUAAAAHYXNzZXRJZAAAAAFpAQAAABNnd3hVc2VySW5mb1JFQURPTkxZAAAAAQAAAAt1c2VyQWRkcmVzcwQAAAAJZ3d4QW1vdW50CQEAAAAUY2FsY0N1cnJlbnRHd3hBbW91bnQAAAABBQAAAAt1c2VyQWRkcmVzcwkABRQAAAACBQAAAANuaWwJAARMAAAAAgUAAAAJZ3d4QW1vdW50BQAAAANuaWwAAAAAkQBSvw==", "chainId": 87, "height": 2900438, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: D8Ug7zvi2kvQvkjMJ3UhTLsgwTbmoWEKkAA7cKyT8Hxo Next: 3gawpmPFn49PyHSDWNw9f4qTfR8Ra5NgnubwCbQEDshs Diff:
OldNewDifferences
1919
2020
2121 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
22+
23+
24+func abs (val) = if ((0 > val))
25+ then -(val)
26+ else val
2227
2328
2429 func asAnyList (val) = match val {
5459
5560 let IdxFactoryCfgSlippageDapp = 7
5661
62+let IdxFactoryCfgDaoDapp = 8
63+
64+let IdxFactoryCfgMarketingDapp = 9
65+
66+let IdxFactoryCfgGwxRewardDapp = 10
67+
68+let IdxFactoryCfgBirdsDapp = 11
69+
5770 func keyFactoryCfg () = "%s__factoryConfig"
5871
5972
6780
6881
6982 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
83+
84+
85+func keyFactoryPoolWeightHistory (poolAddress,num) = ((("%s%s__poolWeight__" + poolAddress) + "__") + toString(num))
7086
7187
7288 func readFactoryAddressOrFail () = addressFromStringValue(getStringOrFail(this, keyFactoryAddress()))
87103 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
88104
89105
106+func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp])
107+
108+
90109 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
91110
92111
103122
104123
105124 func keyNextPeriod () = "%s__nextPeriod"
125+
126+
127+func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
106128
107129
108130 let IdxCfgAssetId = 1
222244
223245 let stakingContract = getStakingAddressOrFail(factoryCfg)
224246
247+let gwxRewardContract = getGwxRewardAddressOrFail(factoryCfg)
248+
225249 func HistoryEntry (type,user,amount,lockStart,duration,k,b,i) = {
226250 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
227251 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)
295319 else {
296320 let userRecordArray = split(userRecordOrEmpty, SEP)
297321 let userNumStr = userRecordArray[IdxLockUserNum]
322+ let gwxRewardEmissionStartHeight = valueOrElse(getInteger(gwxRewardContract, keyGwxRewardEmissionStartHeight()), 0)
298323 let EMPTYSTR = "empty"
299- let poolWeight = if ((lpAssetIdStr != EMPTYSTR))
324+ let $t01237112939 = if ((lpAssetIdStr != EMPTYSTR))
300325 then {
301326 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
302- getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
327+ let pw1 = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
328+ let pw0 = valueOrElse(getInteger(factoryContract, keyFactoryPoolWeightHistory(poolAddressStr, 0)), pw1)
329+ $Tuple2(pw0, pw1)
303330 }
304331 else if (readOnly)
305- then 0
332+ then $Tuple2(0, 0)
306333 else throw(("not readonly mode: unsupported lp asset " + lpAssetIdStr))
334+ let poolWeight0 = $t01237112939._1
335+ let poolWeight1 = $t01237112939._2
307336 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
308337 let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
309338 let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
316345 let userBoostEmissionLastIntegral = valueOrElse(getInteger(this, userLpBoostEmissionLastIntegralKEY), getIntOrZero(this, userBoostEmissionLastIntegralKEY))
317346 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
318347 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
319- if ((0 > userBoostEmissionIntegral))
320- then throw("wrong calculations")
321- else {
322- let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
323- let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
324- let userMaxBoostInt = getIntOrZero(this, userMaxBoostIntegralKEY)
325- let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
326- let totalCachedGwxKEY = keyTotalCachedGwx()
327- let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
328- let userCurrGwx = calcCurrentGwxAmount(userAddressStr)
329- let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
330- let userBoostAvaliableToClaimTotal = getIntOrZero(this, userBoostAvalaibleToClaimTotalKEY)
331- let poolUserBoostEmissionIntegral = fraction(userBoostEmissionIntegral, poolWeight, POOLWEIGHTMULT)
332- let userBoostAvaliableToClaimTotalNew = if ((totalCachedGwx == 0))
333- then 0
334- else fraction(poolUserBoostEmissionIntegral, userCurrGwx, totalCachedGwx)
335- let userBoostClaimedKEY = keyUserBoostClaimed(userNumStr)
336- let userBoostClaimed = getIntOrZero(this, userBoostClaimedKEY)
337- let userBoostAvailable = (userBoostAvaliableToClaimTotalNew - userBoostClaimed)
338- let dataState = [IntegerEntry(userLpBoostEmissionLastIntegralKEY, boostEmissionIntegral)]
339- 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))], "::")
340- $Tuple3(userBoostAvaliableToClaimTotalNew, dataState, debug)
341- }
348+ let udh = fraction(userBoostEmissionIntegral, 3, (2 * wxEmissionPerBlock))
349+ let uLastH = (h - udh)
350+ let udh0 = max([(gwxRewardEmissionStartHeight - uLastH), 0])
351+ let udh1 = ((h - uLastH) - udh0)
352+ if (if (if ((0 > uLastH))
353+ then true
354+ else (0 > udh1))
355+ then true
356+ else (abs(((udh0 + udh1) - udh)) >= 1))
357+ then throw(((((((("invalid udh calc: udh=" + toString(udh)) + " uLastH=") + toString(uLastH)) + " udh0=") + toString(udh0)) + " udh1=") + toString(udh1)))
358+ else if ((0 > userBoostEmissionIntegral))
359+ then throw("wrong calculations")
360+ else {
361+ let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
362+ let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
363+ let userMaxBoostInt = getIntOrZero(this, userMaxBoostIntegralKEY)
364+ let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
365+ let totalCachedGwxKEY = keyTotalCachedGwx()
366+ let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
367+ let userCurrGwx = calcCurrentGwxAmount(userAddressStr)
368+ let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
369+ let userBoostAvaliableToClaimTotal = getIntOrZero(this, userBoostAvalaibleToClaimTotalKEY)
370+ let userBoostEmissionIntegral0 = fraction(userBoostEmissionIntegral, udh0, udh)
371+ let userBoostEmissionIntegral1 = fraction(userBoostEmissionIntegral, udh1, udh)
372+ let poolUserBoostEmissionIntegral0 = fraction(userBoostEmissionIntegral0, poolWeight0, POOLWEIGHTMULT)
373+ let poolUserBoostEmissionIntegral1 = fraction(userBoostEmissionIntegral1, poolWeight1, POOLWEIGHTMULT)
374+ let userBoostAvaliableToClaimTotalNew0 = if ((totalCachedGwx == 0))
375+ then 0
376+ else fraction(poolUserBoostEmissionIntegral0, userCurrGwx, totalCachedGwx)
377+ let userBoostAvaliableToClaimTotalNew1 = if ((totalCachedGwx == 0))
378+ then 0
379+ else fraction(poolUserBoostEmissionIntegral1, userCurrGwx, totalCachedGwx)
380+ let userBoostAvaliableToClaimTotalNew = (userBoostAvaliableToClaimTotalNew0 + userBoostAvaliableToClaimTotalNew1)
381+ let userBoostClaimedKEY = keyUserBoostClaimed(userNumStr)
382+ let userBoostClaimed = getIntOrZero(this, userBoostClaimedKEY)
383+ let userBoostAvailable = (userBoostAvaliableToClaimTotalNew - userBoostClaimed)
384+ let dataState = [IntegerEntry(userLpBoostEmissionLastIntegralKEY, boostEmissionIntegral)]
385+ 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)), ("userBoostEmissionIntegral0=" + toString(userBoostEmissionIntegral0)), ("userBoostEmissionIntegral1=" + toString(userBoostEmissionIntegral1)), ("poolUserBoostEmissionIntegral0=" + toString(poolUserBoostEmissionIntegral0)), ("poolUserBoostEmissionIntegral1=" + toString(poolUserBoostEmissionIntegral1)), ("poolWeight0=" + toString(poolWeight0)), ("poolWeight1=" + toString(poolWeight1)), ("h=" + toString(h)), ("udh=" + toString(udh)), ("uLastH=" + toString(uLastH)), ("udh0=" + toString(udh0)), ("udh1=" + toString(udh1)), ("userCurrGwx=" + toString(userCurrGwx)), ("totalCachedGwx=" + toString(totalCachedGwx))], "::")
386+ $Tuple3(userBoostAvaliableToClaimTotalNew, dataState, debug)
387+ }
342388 }
343389 }
344390
501547 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
502548 then throw("permissions denied")
503549 else {
504- let $t02484424946 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
505- let userBoostAvailable = $t02484424946._1
506- let dataState = $t02484424946._2
507- let debug = $t02484424946._3
550+ let $t02715827260 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
551+ let userBoostAvailable = $t02715827260._1
552+ let dataState = $t02715827260._2
553+ let debug = $t02715827260._3
508554 $Tuple2(dataState, [userBoostAvailable])
509555 }
510556
512558
513559 @Callable(i)
514560 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
515- let $t02507825179 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
516- let userBoostAvailable = $t02507825179._1
517- let dataState = $t02507825179._2
518- let debug = $t02507825179._3
561+ let $t02739227493 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
562+ let userBoostAvailable = $t02739227493._1
563+ let dataState = $t02739227493._2
564+ let debug = $t02739227493._3
519565 $Tuple2(nil, [userBoostAvailable, debug])
520566 }
521567
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"))
22+
23+
24+func abs (val) = if ((0 > val))
25+ then -(val)
26+ else val
2227
2328
2429 func asAnyList (val) = match val {
2530 case valAnyLyst: List[Any] =>
2631 valAnyLyst
2732 case _ =>
2833 throw("fail to cast into List[Any]")
2934 }
3035
3136
3237 func asInt (val) = match val {
3338 case valInt: Int =>
3439 valInt
3540 case _ =>
3641 throw("fail to cast into Int")
3742 }
3843
3944
4045 func keyFactoryAddress () = "%s%s__config__factoryAddress"
4146
4247
4348 let IdxFactoryCfgStakingDapp = 1
4449
4550 let IdxFactoryCfgBoostingDapp = 2
4651
4752 let IdxFactoryCfgIdoDapp = 3
4853
4954 let IdxFactoryCfgTeamDapp = 4
5055
5156 let IdxFactoryCfgEmissionDapp = 5
5257
5358 let IdxFactoryCfgRestDapp = 6
5459
5560 let IdxFactoryCfgSlippageDapp = 7
5661
62+let IdxFactoryCfgDaoDapp = 8
63+
64+let IdxFactoryCfgMarketingDapp = 9
65+
66+let IdxFactoryCfgGwxRewardDapp = 10
67+
68+let IdxFactoryCfgBirdsDapp = 11
69+
5770 func keyFactoryCfg () = "%s__factoryConfig"
5871
5972
6073 func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
6174
6275
6376 func keyFactoryLpList () = "%s__lpTokensList"
6477
6578
6679 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
6780
6881
6982 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
83+
84+
85+func keyFactoryPoolWeightHistory (poolAddress,num) = ((("%s%s__poolWeight__" + poolAddress) + "__") + toString(num))
7086
7187
7288 func readFactoryAddressOrFail () = addressFromStringValue(getStringOrFail(this, keyFactoryAddress()))
7389
7490
7591 func readLpList () = split(valueOrElse(getString(readFactoryAddressOrFail(), keyFactoryLpList()), ""), SEP)
7692
7793
7894 func readFactoryCfgOrFail (factory) = split(getStringOrFail(factory, keyFactoryCfg()), SEP)
7995
8096
8197 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
8298
8399
84100 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
85101
86102
87103 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
88104
89105
106+func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp])
107+
108+
90109 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
91110
92111
93112 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
94113
95114
96115 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
97116
98117
99118 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
100119
101120
102121 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
103122
104123
105124 func keyNextPeriod () = "%s__nextPeriod"
125+
126+
127+func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
106128
107129
108130 let IdxCfgAssetId = 1
109131
110132 let IdxCfgMinLockAmount = 2
111133
112134 let IdxCfgMinLockDuration = 3
113135
114136 let IdxCfgMaxLockDuration = 4
115137
116138 let IdxCfgMathContract = 5
117139
118140 func keyConfig () = "%s__config"
119141
120142
121143 func readConfigArrayOrFail () = split(getStringOrFail(this, keyConfig()), SEP)
122144
123145
124146 func formatConfigS (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = makeString(["%s%d%d%d", assetId, minLockAmount, minLockDuration, maxLockDuration, mathContract], SEP)
125147
126148
127149 func formatConfig (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = formatConfigS(assetId, toString(minLockAmount), toString(minLockDuration), toString(maxLockDuration), mathContract)
128150
129151
130152 let IdxLockUserNum = 1
131153
132154 let IdxLockAmount = 2
133155
134156 let IdxLockStart = 3
135157
136158 let IdxLockDuration = 4
137159
138160 let IdxLockParamK = 5
139161
140162 let IdxLockParamB = 6
141163
142164 func keyLockParamsRecord (userAddress) = makeString(["%s%s__lock", userAddress], SEP)
143165
144166
145167 func readLockParamsRecordOrFail (userAddress) = split(getStringOrFail(this, keyLockParamsRecord(userAddress)), SEP)
146168
147169
148170 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)
149171
150172
151173 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))
152174
153175
154176 func keyNextUserNum () = "%s__nextUserNum"
155177
156178
157179 func keyUser2NumMapping (userAddress) = makeString(["%s%s%s__mapping__user2num", userAddress], SEP)
158180
159181
160182 func keyNum2UserMapping (num) = makeString(["%s%s%s__mapping__num2user", num], SEP)
161183
162184
163185 func keyLockParamUserAmount (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "amount"], SEP)
164186
165187
166188 func keyLockParamStartBlock (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "start"], SEP)
167189
168190
169191 func keyLockParamDuration (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "duration"], SEP)
170192
171193
172194 func keyLockParamK (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "k"], SEP)
173195
174196
175197 func keyLockParamB (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "b"], SEP)
176198
177199
178200 func keyLockParamByPeriodK (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "k", period], SEP)
179201
180202
181203 func keyLockParamByPeriodB (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "b", period], SEP)
182204
183205
184206 func keyLockParamTotalAmount () = "%s%s__stats__activeTotalLocked"
185207
186208
187209 func keyStatsLocksDurationSumInBlocks () = "%s%s__stats__locksDurationSumInBlocks"
188210
189211
190212 func keyStatsLocksCount () = "%s%s__stats__locksCount"
191213
192214
193215 func keyStatsUsersCount () = "%s%s__stats__activeUsersCount"
194216
195217
196218 func keyUserBoostEmissionLastINTEGRAL (userNum) = makeString(["%s%d__userBoostEmissionLastInt", userNum], SEP)
197219
198220
199221 func keyUserLpBoostEmissionLastINTEGRAL (userNum,lpAssetId) = makeString(["%s%d__userBoostEmissionLastInt", userNum, lpAssetId], SEP)
200222
201223
202224 func keyUserMaxBoostINTEGRAL (userNum) = makeString(["%s%d__maxBoostInt", userNum], SEP)
203225
204226
205227 func keyTotalMaxBoostINTEGRAL () = "%s%s__maxBoostInt__total"
206228
207229
208230 func keyUserBoostAvalaibleToClaimTotal (userNum) = makeString(["%s%d__userBoostAvaliableToClaimTotal", userNum], SEP)
209231
210232
211233 func keyUserBoostClaimed (userNum) = makeString(["%s%d__userBoostClaimed", userNum], SEP)
212234
213235
214236 func keyTotalCachedGwx () = "%s%s__gwxCached__total"
215237
216238
217239 let factoryContract = readFactoryAddressOrFail()
218240
219241 let factoryCfg = readFactoryCfgOrFail(factoryContract)
220242
221243 let emissionContract = getEmissionAddressOrFail(factoryCfg)
222244
223245 let stakingContract = getStakingAddressOrFail(factoryCfg)
224246
247+let gwxRewardContract = getGwxRewardAddressOrFail(factoryCfg)
248+
225249 func HistoryEntry (type,user,amount,lockStart,duration,k,b,i) = {
226250 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
227251 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)
228252 StringEntry(historyKEY, historyDATA)
229253 }
230254
231255
232256 func StatsEntry (totalLockedInc,durationInc,lockCountInc,usersCountInc) = {
233257 let locksDurationSumInBlocksKEY = keyStatsLocksDurationSumInBlocks()
234258 let locksCountKEY = keyStatsLocksCount()
235259 let usersCountKEY = keyStatsUsersCount()
236260 let totalAmountKEY = keyLockParamTotalAmount()
237261 let locksDurationSumInBlocks = getIntOrZero(this, locksDurationSumInBlocksKEY)
238262 let locksCount = getIntOrZero(this, locksCountKEY)
239263 let usersCount = getIntOrZero(this, usersCountKEY)
240264 let totalAmount = getIntOrZero(this, totalAmountKEY)
241265 [IntegerEntry(locksDurationSumInBlocksKEY, (locksDurationSumInBlocks + durationInc)), IntegerEntry(locksCountKEY, (locksCount + lockCountInc)), IntegerEntry(usersCountKEY, (usersCount + usersCountInc)), IntegerEntry(totalAmountKEY, (totalAmount + totalLockedInc))]
242266 }
243267
244268
245269 func calcGwxAmount (kRaw,bRaw,h) = {
246270 let SCALE = 1000
247271 (((kRaw * h) + bRaw) / SCALE)
248272 }
249273
250274
251275 func LockParamsEntry (userAddress,userNum,amount,start,duration,k,b,period) = {
252276 let userAmountKEY = keyLockParamUserAmount(userNum)
253277 let startBlockKEY = keyLockParamStartBlock(userNum)
254278 let durationKEY = keyLockParamDuration(userNum)
255279 let kKEY = keyLockParamK(userNum)
256280 let bKEY = keyLockParamB(userNum)
257281 let kByPerioKEY = keyLockParamByPeriodK(userNum, period)
258282 let bByPeriodKEY = keyLockParamByPeriodB(userNum, period)
259283 let gwxAmount = calcGwxAmount(k, b, height)
260284 [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))]
261285 }
262286
263287
264288 func extractOptionalPaymentAmountOrFail (i,expectedAssetId) = if ((size(i.payments) > 1))
265289 then throw("only one payment is allowed")
266290 else if ((size(i.payments) == 0))
267291 then 0
268292 else {
269293 let pmt = i.payments[0]
270294 if ((value(pmt.assetId) != expectedAssetId))
271295 then throw("invalid asset id in payment")
272296 else pmt.amount
273297 }
274298
275299
276300 func calcCurrentGwxAmount (userAddress) = {
277301 let EMPTY = "empty"
278302 let user2NumMappingKEY = keyUser2NumMapping(userAddress)
279303 let userNum = valueOrElse(getString(user2NumMappingKEY), EMPTY)
280304 let k = valueOrElse(getInteger(keyLockParamK(userNum)), 0)
281305 let b = valueOrElse(getInteger(keyLockParamB(userNum)), 0)
282306 let gwxAmountCalc = calcGwxAmount(k, b, height)
283307 let gwxAmount = if ((0 > gwxAmountCalc))
284308 then 0
285309 else gwxAmountCalc
286310 gwxAmount
287311 }
288312
289313
290314 func internalClaimWxBoost (lpAssetIdStr,userAddressStr,readOnly) = {
291315 let EMPTY = "EMPTY"
292316 let userRecordOrEmpty = valueOrElse(getString(this, keyLockParamsRecord(userAddressStr)), EMPTY)
293317 if ((userRecordOrEmpty == EMPTY))
294318 then $Tuple3(0, nil, "userRecord::is::empty")
295319 else {
296320 let userRecordArray = split(userRecordOrEmpty, SEP)
297321 let userNumStr = userRecordArray[IdxLockUserNum]
322+ let gwxRewardEmissionStartHeight = valueOrElse(getInteger(gwxRewardContract, keyGwxRewardEmissionStartHeight()), 0)
298323 let EMPTYSTR = "empty"
299- let poolWeight = if ((lpAssetIdStr != EMPTYSTR))
324+ let $t01237112939 = if ((lpAssetIdStr != EMPTYSTR))
300325 then {
301326 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
302- getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
327+ let pw1 = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
328+ let pw0 = valueOrElse(getInteger(factoryContract, keyFactoryPoolWeightHistory(poolAddressStr, 0)), pw1)
329+ $Tuple2(pw0, pw1)
303330 }
304331 else if (readOnly)
305- then 0
332+ then $Tuple2(0, 0)
306333 else throw(("not readonly mode: unsupported lp asset " + lpAssetIdStr))
334+ let poolWeight0 = $t01237112939._1
335+ let poolWeight1 = $t01237112939._2
307336 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
308337 let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
309338 let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
310339 let h = if ((height > emissionEnd))
311340 then emissionEnd
312341 else height
313342 let dh = max([(h - emissionStart), 0])
314343 let userLpBoostEmissionLastIntegralKEY = keyUserLpBoostEmissionLastINTEGRAL(userNumStr, lpAssetIdStr)
315344 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
316345 let userBoostEmissionLastIntegral = valueOrElse(getInteger(this, userLpBoostEmissionLastIntegralKEY), getIntOrZero(this, userBoostEmissionLastIntegralKEY))
317346 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
318347 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
319- if ((0 > userBoostEmissionIntegral))
320- then throw("wrong calculations")
321- else {
322- let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
323- let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
324- let userMaxBoostInt = getIntOrZero(this, userMaxBoostIntegralKEY)
325- let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
326- let totalCachedGwxKEY = keyTotalCachedGwx()
327- let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
328- let userCurrGwx = calcCurrentGwxAmount(userAddressStr)
329- let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
330- let userBoostAvaliableToClaimTotal = getIntOrZero(this, userBoostAvalaibleToClaimTotalKEY)
331- let poolUserBoostEmissionIntegral = fraction(userBoostEmissionIntegral, poolWeight, POOLWEIGHTMULT)
332- let userBoostAvaliableToClaimTotalNew = if ((totalCachedGwx == 0))
333- then 0
334- else fraction(poolUserBoostEmissionIntegral, userCurrGwx, totalCachedGwx)
335- let userBoostClaimedKEY = keyUserBoostClaimed(userNumStr)
336- let userBoostClaimed = getIntOrZero(this, userBoostClaimedKEY)
337- let userBoostAvailable = (userBoostAvaliableToClaimTotalNew - userBoostClaimed)
338- let dataState = [IntegerEntry(userLpBoostEmissionLastIntegralKEY, boostEmissionIntegral)]
339- 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))], "::")
340- $Tuple3(userBoostAvaliableToClaimTotalNew, dataState, debug)
341- }
348+ let udh = fraction(userBoostEmissionIntegral, 3, (2 * wxEmissionPerBlock))
349+ let uLastH = (h - udh)
350+ let udh0 = max([(gwxRewardEmissionStartHeight - uLastH), 0])
351+ let udh1 = ((h - uLastH) - udh0)
352+ if (if (if ((0 > uLastH))
353+ then true
354+ else (0 > udh1))
355+ then true
356+ else (abs(((udh0 + udh1) - udh)) >= 1))
357+ then throw(((((((("invalid udh calc: udh=" + toString(udh)) + " uLastH=") + toString(uLastH)) + " udh0=") + toString(udh0)) + " udh1=") + toString(udh1)))
358+ else if ((0 > userBoostEmissionIntegral))
359+ then throw("wrong calculations")
360+ else {
361+ let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
362+ let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
363+ let userMaxBoostInt = getIntOrZero(this, userMaxBoostIntegralKEY)
364+ let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
365+ let totalCachedGwxKEY = keyTotalCachedGwx()
366+ let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
367+ let userCurrGwx = calcCurrentGwxAmount(userAddressStr)
368+ let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
369+ let userBoostAvaliableToClaimTotal = getIntOrZero(this, userBoostAvalaibleToClaimTotalKEY)
370+ let userBoostEmissionIntegral0 = fraction(userBoostEmissionIntegral, udh0, udh)
371+ let userBoostEmissionIntegral1 = fraction(userBoostEmissionIntegral, udh1, udh)
372+ let poolUserBoostEmissionIntegral0 = fraction(userBoostEmissionIntegral0, poolWeight0, POOLWEIGHTMULT)
373+ let poolUserBoostEmissionIntegral1 = fraction(userBoostEmissionIntegral1, poolWeight1, POOLWEIGHTMULT)
374+ let userBoostAvaliableToClaimTotalNew0 = if ((totalCachedGwx == 0))
375+ then 0
376+ else fraction(poolUserBoostEmissionIntegral0, userCurrGwx, totalCachedGwx)
377+ let userBoostAvaliableToClaimTotalNew1 = if ((totalCachedGwx == 0))
378+ then 0
379+ else fraction(poolUserBoostEmissionIntegral1, userCurrGwx, totalCachedGwx)
380+ let userBoostAvaliableToClaimTotalNew = (userBoostAvaliableToClaimTotalNew0 + userBoostAvaliableToClaimTotalNew1)
381+ let userBoostClaimedKEY = keyUserBoostClaimed(userNumStr)
382+ let userBoostClaimed = getIntOrZero(this, userBoostClaimedKEY)
383+ let userBoostAvailable = (userBoostAvaliableToClaimTotalNew - userBoostClaimed)
384+ let dataState = [IntegerEntry(userLpBoostEmissionLastIntegralKEY, boostEmissionIntegral)]
385+ 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)), ("userBoostEmissionIntegral0=" + toString(userBoostEmissionIntegral0)), ("userBoostEmissionIntegral1=" + toString(userBoostEmissionIntegral1)), ("poolUserBoostEmissionIntegral0=" + toString(poolUserBoostEmissionIntegral0)), ("poolUserBoostEmissionIntegral1=" + toString(poolUserBoostEmissionIntegral1)), ("poolWeight0=" + toString(poolWeight0)), ("poolWeight1=" + toString(poolWeight1)), ("h=" + toString(h)), ("udh=" + toString(udh)), ("uLastH=" + toString(uLastH)), ("udh0=" + toString(udh0)), ("udh1=" + toString(udh1)), ("userCurrGwx=" + toString(userCurrGwx)), ("totalCachedGwx=" + toString(totalCachedGwx))], "::")
386+ $Tuple3(userBoostAvaliableToClaimTotalNew, dataState, debug)
387+ }
342388 }
343389 }
344390
345391
346392 @Callable(i)
347393 func constructor (factoryAddressStr,lockAssetIdStr,minLockAmount,minDuration,maxDuration,mathContract) = if ((this != i.caller))
348394 then throw("not authorized")
349395 else ([IntegerEntry(keyNextUserNum(), 0), StringEntry(keyConfig(), formatConfig(lockAssetIdStr, minLockAmount, minDuration, maxDuration, mathContract)), StringEntry(keyFactoryAddress(), factoryAddressStr)] ++ StatsEntry(0, 0, 0, 0))
350396
351397
352398
353399 @Callable(i)
354400 func lock (duration) = {
355401 let cfgArray = readConfigArrayOrFail()
356402 let assetIdStr = cfgArray[IdxCfgAssetId]
357403 let assetId = fromBase58String(assetIdStr)
358404 let minLockAmount = parseIntValue(cfgArray[IdxCfgMinLockAmount])
359405 let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
360406 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
361407 let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
362408 if ((size(i.payments) != 1))
363409 then throw("invalid payment - exact one payment must be attached")
364410 else {
365411 let pmt = i.payments[0]
366412 let pmtAmount = pmt.amount
367413 if ((assetId != value(pmt.assetId)))
368414 then throw((("invalid asset is in payment - " + assetIdStr) + " is expected"))
369415 else {
370416 let nextUserNumKEY = keyNextUserNum()
371417 let userAddressStr = toString(i.caller)
372418 let userIsExisting = isDefined(getString(keyUser2NumMapping(userAddressStr)))
373419 let userNumStr = if (userIsExisting)
374420 then value(getString(keyUser2NumMapping(userAddressStr)))
375421 else toString(getIntOrFail(this, nextUserNumKEY))
376422 let userNum = parseIntValue(userNumStr)
377423 let lockStart = height
378424 let startBlockKEY = keyLockParamStartBlock(userNumStr)
379425 let durationKEY = keyLockParamDuration(userNumStr)
380426 let userAmountKEY = keyLockParamUserAmount(userNumStr)
381427 if ((minLockAmount > pmtAmount))
382428 then throw(("amount is less then minLockAmount=" + toString(minLockAmount)))
383429 else if ((minLockDuration > duration))
384430 then throw(("passed duration is less then minLockDuration=" + toString(minLockDuration)))
385431 else if ((duration > maxLockDuration))
386432 then throw(("passed duration is greater then maxLockDuration=" + toString(maxLockDuration)))
387433 else if (if (userIsExisting)
388434 then ((getIntOrFail(this, startBlockKEY) + getIntOrFail(this, durationKEY)) >= lockStart)
389435 else false)
390436 then throw("there is an active lock - consider to use increaseLock")
391437 else if ((getIntOrZero(this, userAmountKEY) > 0))
392438 then throw(("there are locked WXs - consider to use increaseLock " + userAmountKEY))
393439 else {
394440 let coeffX8 = fraction(duration, MULT8, maxLockDuration)
395441 let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
396442 let gWxParamsResultList = asAnyList(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStart, duration], nil))
397443 let k = asInt(gWxParamsResultList[0])
398444 let b = asInt(gWxParamsResultList[1])
399445 let period = toString(asInt(gWxParamsResultList[2]))
400446 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
401447 let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
402448 let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
403449 let h = if ((height > emissionEnd))
404450 then emissionEnd
405451 else height
406452 let dh = max([(h - emissionStart), 0])
407453 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
408454 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
409455 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
410456 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
411457 let userMaxBoostInt = ((gWxAmountStart * duration) / 2)
412458 let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
413459 let totalCachedGwxKEY = keyTotalCachedGwx()
414460 let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
415461 let arr = if (userIsExisting)
416462 then nil
417463 else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
418464 ((((arr ++ LockParamsEntry(userAddressStr, userNumStr, pmtAmount, lockStart, duration, k, b, period)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
419465 then 0
420466 else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(totalCachedGwxKEY, (totalCachedGwx + gWxAmountStart))])
421467 }
422468 }
423469 }
424470 }
425471
426472
427473
428474 @Callable(i)
429475 func increaseLock (deltaDuration) = {
430476 let cfgArray = readConfigArrayOrFail()
431477 let assetIdStr = cfgArray[IdxCfgAssetId]
432478 let assetId = fromBase58String(assetIdStr)
433479 let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
434480 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
435481 let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
436482 let pmtAmount = extractOptionalPaymentAmountOrFail(i, assetId)
437483 let userAddressStr = toString(i.caller)
438484 let userRecordArray = readLockParamsRecordOrFail(userAddressStr)
439485 let userNumStr = userRecordArray[IdxLockUserNum]
440486 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
441487 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
442488 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
443489 let lockEnd = (lockStart + lockDuration)
444490 let remainingDuration = max([(lockEnd - height), 0])
445491 let userAmountNew = (userAmount + pmtAmount)
446492 let lockDurationNew = (remainingDuration + deltaDuration)
447493 if ((0 > deltaDuration))
448494 then throw("duration is less then zero")
449495 else if ((minLockDuration > lockDurationNew))
450496 then throw(("lockDurationNew is less then minLockDuration=" + toString(minLockDuration)))
451497 else if ((lockDurationNew > maxLockDuration))
452498 then throw(("deltaDuration + existedLockDuration is greater then maxLockDuration=" + toString(maxLockDuration)))
453499 else {
454500 let coeffX8 = fraction(lockDurationNew, MULT8, maxLockDuration)
455501 let gWxAmountStart = fraction(userAmountNew, coeffX8, MULT8)
456502 let lockStartNew = height
457503 let gWxParamsResultList = asAnyList(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStartNew, lockDurationNew], nil))
458504 let k = asInt(gWxParamsResultList[0])
459505 let b = asInt(gWxParamsResultList[1])
460506 let period = toString(asInt(gWxParamsResultList[2]))
461507 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
462508 let emissionStart = getIntOrFail(emissionContract, keyEmissionStartBlock())
463509 let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
464510 let h = if ((height > emissionEnd))
465511 then emissionEnd
466512 else height
467513 let dh = max([(h - emissionStart), 0])
468514 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
469515 let userBoostEmissionLastIntegral = getIntOrZero(this, userBoostEmissionLastIntegralKEY)
470516 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
471517 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
472518 if ((0 > userBoostEmissionIntegral))
473519 then throw("wrong calculations")
474520 else {
475521 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
476522 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
477523 let userMaxBoostInt = getIntOrZero(this, userMaxBoostIntegralKEY)
478524 let totalMaxBoostInt = getIntOrZero(this, totalMaxBoostIntegralKEY)
479525 let currUserGwx = calcCurrentGwxAmount(userAddressStr)
480526 let gwxDiff = (gWxAmountStart - currUserGwx)
481527 if ((0 > gwxDiff))
482528 then throw(("gwxDiff is less then 0: " + toString(gwxDiff)))
483529 else {
484530 let totalCachedGwxKEY = keyTotalCachedGwx()
485531 let totalCachedGwx = valueOrElse(getInteger(this, totalCachedGwxKEY), 0)
486532 let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
487533 let userBoostAvaliableToClaimTotal = getIntOrZero(this, userBoostAvalaibleToClaimTotalKEY)
488534 let userBoostAvaliableToClaimTotalNew = fraction(userBoostEmissionIntegral, currUserGwx, totalCachedGwx)
489535 let userMaxBoostIntNew = ((gWxAmountStart * lockDurationNew) / 2)
490536 let remainingUserMaxBoostInt = ((currUserGwx * remainingDuration) / 2)
491537 let userMaxBoostIntDiff = (userMaxBoostIntNew - remainingUserMaxBoostInt)
492538 (((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))])
493539 }
494540 }
495541 }
496542 }
497543
498544
499545
500546 @Callable(i)
501547 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
502548 then throw("permissions denied")
503549 else {
504- let $t02484424946 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
505- let userBoostAvailable = $t02484424946._1
506- let dataState = $t02484424946._2
507- let debug = $t02484424946._3
550+ let $t02715827260 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
551+ let userBoostAvailable = $t02715827260._1
552+ let dataState = $t02715827260._2
553+ let debug = $t02715827260._3
508554 $Tuple2(dataState, [userBoostAvailable])
509555 }
510556
511557
512558
513559 @Callable(i)
514560 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
515- let $t02507825179 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
516- let userBoostAvailable = $t02507825179._1
517- let dataState = $t02507825179._2
518- let debug = $t02507825179._3
561+ let $t02739227493 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
562+ let userBoostAvailable = $t02739227493._1
563+ let dataState = $t02739227493._2
564+ let debug = $t02739227493._3
519565 $Tuple2(nil, [userBoostAvailable, debug])
520566 }
521567
522568
523569
524570 @Callable(i)
525571 func unlock (userAddress) = {
526572 let userRecordArray = readLockParamsRecordOrFail(userAddress)
527573 let userNumStr = userRecordArray[IdxLockUserNum]
528574 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
529575 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
530576 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
531577 let lockEnd = (lockStart + lockDuration)
532578 let cfgArray = readConfigArrayOrFail()
533579 let assetId = fromBase58String(cfgArray[IdxCfgAssetId])
534580 let mathContract = addressFromStringValue(cfgArray[IdxCfgMathContract])
535581 if ((lockEnd >= height))
536582 then throw((("wait " + toString(lockEnd)) + " to unlock"))
537583 else if ((0 >= userAmount))
538584 then throw("nothing to unlock")
539585 else {
540586 let period = valueOrElse(getInteger(mathContract, keyNextPeriod()), 0)
541587 (((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))
542588 }
543589 }
544590
545591
546592
547593 @Callable(i)
548594 func gwxUserInfoREADONLY (userAddress) = {
549595 let gwxAmount = calcCurrentGwxAmount(userAddress)
550596 $Tuple2(nil, [gwxAmount])
551597 }
552598
553599

github/deemru/w8io/786bc32 
232.13 ms