tx · 8dZDzjnyYEhMN7CVUMtf2KonyGqArDMYEYLTeUUensyZ

3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy:  -0.02500000 Waves

2023.08.08 14:14 [2701545] smart account 3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy > SELF 0.00000000 Waves

{ "type": 13, "id": "8dZDzjnyYEhMN7CVUMtf2KonyGqArDMYEYLTeUUensyZ", "fee": 2500000, "feeAssetId": null, "timestamp": 1691493323456, "version": 2, "chainId": 84, "sender": "3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy", "senderPublicKey": "9W33iCCNfmFxUbiC6XZcH5x7f6xfwC7Jb3BoExT5q2PV", "proofs": [ "23ZoJrH7egtrkHLmzaoAoif9Tfz3ytzbhdL9SH87DUedJ1NQZfh2wXYfHcgS5b2KTrwE3rjbcBPvfozTVCZreRh5" ], "script": "base64:BgK4LQgCEggKBggIAQEBCBIFCgMBCAISAwoBARIECgIICBIECgIICBIECgIIARIDCgEIEgMKAQgSBAoCCAESAwoBCBIAEgASBQoDCAgEEgMKAQgSAwoBCBIECgIICBIECgIICCIDU0VQIgZTQ0FMRTgiBU1VTFQ4Ig5QT09MV0VJR0hUTVVMVCIQY29udHJhY3RGaWxlbmFtZSIHU0NBTEUxOCIGTVVMVDE4IghNVUxUMThCSSILYmxvY2tzSW5EYXkiDWJsb2Nrc0luTW9udGgiB3dyYXBFcnIiA21zZyIIdGhyb3dFcnIiD2dldFN0cmluZ09yRmFpbCIHYWRkcmVzcyIDa2V5IgxnZXRJbnRPclplcm8iD2dldEludE9yRGVmYXVsdCIKZGVmYXVsdFZhbCIMZ2V0SW50T3JGYWlsIgNhYnMiA3ZhbCIOZW5zdXJlUG9zaXRpdmUiAXYiAW0iG2tleVJlZmVycmFsc0NvbnRyYWN0QWRkcmVzcyIecmVmZXJyYWxzQ29udHJhY3RBZGRyZXNzT3JGYWlsIhZrZXlSZWZlcnJhbFByb2dyYW1OYW1lIhpyZWZlcnJhbFByb2dyYW1OYW1lRGVmYXVsdCITcmVmZXJyYWxQcm9ncmFtTmFtZSIRa2V5RmFjdG9yeUFkZHJlc3MiGElkeEZhY3RvcnlDZmdTdGFraW5nRGFwcCIZSWR4RmFjdG9yeUNmZ0Jvb3N0aW5nRGFwcCIUSWR4RmFjdG9yeUNmZ0lkb0RhcHAiFUlkeEZhY3RvcnlDZmdUZWFtRGFwcCIZSWR4RmFjdG9yeUNmZ0VtaXNzaW9uRGFwcCIVSWR4RmFjdG9yeUNmZ1Jlc3REYXBwIhlJZHhGYWN0b3J5Q2ZnU2xpcHBhZ2VEYXBwIhRJZHhGYWN0b3J5Q2ZnRGFvRGFwcCIaSWR4RmFjdG9yeUNmZ01hcmtldGluZ0RhcHAiGklkeEZhY3RvcnlDZmdHd3hSZXdhcmREYXBwIhZJZHhGYWN0b3J5Q2ZnQmlyZHNEYXBwIg1rZXlGYWN0b3J5Q2ZnIiZrZXlGYWN0b3J5THBBc3NldFRvUG9vbENvbnRyYWN0QWRkcmVzcyIKbHBBc3NldFN0ciIUa2V5RmFjdG9yeVBvb2xXZWlnaHQiD2NvbnRyYWN0QWRkcmVzcyIba2V5RmFjdG9yeVBvb2xXZWlnaHRIaXN0b3J5Igtwb29sQWRkcmVzcyIDbnVtIhhyZWFkRmFjdG9yeUFkZHJlc3NPckZhaWwiFHJlYWRGYWN0b3J5Q2ZnT3JGYWlsIgdmYWN0b3J5IhhnZXRCb29zdGluZ0FkZHJlc3NPckZhaWwiCmZhY3RvcnlDZmciGGdldEVtaXNzaW9uQWRkcmVzc09yRmFpbCIXZ2V0U3Rha2luZ0FkZHJlc3NPckZhaWwiGWdldEd3eFJld2FyZEFkZHJlc3NPckZhaWwiE2tleU1hbmFnZXJQdWJsaWNLZXkiFmtleU1hbmFnZXJWYXVsdEFkZHJlc3MiHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudCIha2V5RW1pc3Npb25SYXRlUGVyQmxvY2tNYXhDdXJyZW50IhVrZXlFbWlzc2lvblN0YXJ0QmxvY2siHWtleUJvb3N0aW5nVjJMYXN0VXBkYXRlSGVpZ2h0IhVrZXlCb29zdGluZ1YySW50ZWdyYWwiG2tleUVtaXNzaW9uRHVyYXRpb25JbkJsb2NrcyITa2V5RW1pc3Npb25FbmRCbG9jayIZa2V5TmV4dFBlcmdldEludE9yRGVmYXVsdCIfa2V5R3d4UmV3YXJkRW1pc3Npb25TdGFydEhlaWdodCINSWR4Q2ZnQXNzZXRJZCITSWR4Q2ZnTWluTG9ja0Ftb3VudCIVSWR4Q2ZnTWluTG9ja0R1cmF0aW9uIhVJZHhDZmdNYXhMb2NrRHVyYXRpb24iEklkeENmZ01hdGhDb250cmFjdCIJa2V5Q29uZmlnIhVyZWFkQ29uZmlnQXJyYXlPckZhaWwiCGNmZ0FycmF5Igdhc3NldElkIg1taW5Mb2NrQW1vdW50Ig9taW5Mb2NrRHVyYXRpb24iD21heExvY2tEdXJhdGlvbiIMbWF0aENvbnRyYWN0Ig1mb3JtYXRDb25maWdTIgxmb3JtYXRDb25maWciHGdldE1hbmFnZXJWYXVsdEFkZHJlc3NPclRoaXMiByRtYXRjaDAiAXMiFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQiE21hbmFnZXJWYXVsdEFkZHJlc3MiC211c3RNYW5hZ2VyIgFpIgJwZCICcGsiDUlkeExvY2tBbW91bnQiDElkeExvY2tTdGFydCIPSWR4TG9ja0R1cmF0aW9uIhpJZHhMb2NrTGFzdFVwZGF0ZVRpbWVzdGFtcCIQSWR4TG9ja0d3eEFtb3VudCIQSWR4TG9ja1d4Q2xhaW1lZCITa2V5TG9ja1BhcmFtc1JlY29yZCILdXNlckFkZHJlc3MiBHR4SWQiAWIiGnJlYWRMb2NrUGFyYW1zUmVjb3JkT3JGYWlsIhVrZXlVc2VyR3d4QW1vdW50VG90YWwiFmZvcm1hdExvY2tQYXJhbXNSZWNvcmQiBmFtb3VudCIFc3RhcnQiCGR1cmF0aW9uIglnd3hBbW91bnQiCXd4Q2xhaW1lZCIOa2V5TmV4dFVzZXJOdW0iEmtleVVzZXIyTnVtTWFwcGluZyISa2V5TnVtMlVzZXJNYXBwaW5nIhdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudCIga2V5U3RhdHNMb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MiEmtleVN0YXRzTG9ja3NDb3VudCISa2V5U3RhdHNVc2Vyc0NvdW50IiBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTCIHdXNlck51bSIia2V5VXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTCIJbHBBc3NldElkIhdrZXlVc2VyTWF4Qm9vc3RJTlRFR1JBTCIYa2V5VG90YWxNYXhCb29zdElOVEVHUkFMIiFrZXlVc2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWwiE2tleVVzZXJCb29zdENsYWltZWQiC2tleUd3eFRvdGFsIgdrZXlWb3RlIg1hbW91bnRBc3NldElkIgxwcmljZUFzc2V0SWQiBWVwb2NoIhVrZXlTdGFydEhlaWdodEJ5RXBvY2giEWtleUN1cnJlbnRFcG9jaFVpIhVrZXlWb3RpbmdSZXN1bHRTdGFrZWQiDGxwQXNzZXRJZFN0ciIda2V5Vm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWwiJWtleVZvdGluZ1Jlc3VsdFN0YWtlZExhc3RVcGRhdGVIZWlnaHQiIWtleVZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsTGFzdCIVa2V5Vm90ZVN0YWtlZEludGVncmFsIh1rZXlWb3RlU3Rha2VkTGFzdFVwZGF0ZUhlaWdodCIZa2V5Vm90ZVN0YWtlZEludGVncmFsTGFzdCIPa2V5U3Rha2VkQnlVc2VyIg51c2VyQWRkcmVzc1N0ciIPZmFjdG9yeUNvbnRyYWN0IhBlbWlzc2lvbkNvbnRyYWN0Ig9zdGFraW5nQ29udHJhY3QiEWd3eFJld2FyZENvbnRyYWN0IhZscFN0YWtpbmdQb29sc0NvbnRyYWN0IhlrZXlWb3RpbmdFbWlzc2lvbkNvbnRyYWN0IhZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0Ih1rZXlWb3RpbmdFbWlzc2lvblJhdGVDb250cmFjdCIKYm9vc3RDb2VmZiIBQCIZdXNlck51bWJlckJ5QWRkcmVzc09yRmFpbCIRZ2V0R3d4QW1vdW50VG90YWwiEmdldExvY2tlZEd3eEFtb3VudCIMZnVuY3Rpb25OYW1lIhp2b3RpbmdFbWlzc2lvblJhdGVDb250cmFjdCIYbG9ja2VkVm90aW5nRW1pc3Npb25SYXRlIhRsb2NrZWRWb3RpbmdFbWlzc2lvbiIGbG9ja2VkIgxIaXN0b3J5RW50cnkiBHR5cGUiBHVzZXIiCWxvY2tTdGFydCIKaGlzdG9yeUtFWSILaGlzdG9yeURBVEEiClN0YXRzRW50cnkiDnRvdGFsTG9ja2VkSW5jIgtkdXJhdGlvbkluYyIMbG9ja0NvdW50SW5jIg11c2Vyc0NvdW50SW5jIhtsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3NLRVkiDWxvY2tzQ291bnRLRVkiDXVzZXJzQ291bnRLRVkiDnRvdGFsQW1vdW50S0VZIhhsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MiCmxvY2tzQ291bnQiCnVzZXJzQ291bnQiC3RvdGFsQW1vdW50Ig9Mb2NrUGFyYW1zRW50cnkiImV4dHJhY3RPcHRpb25hbFBheW1lbnRBbW91bnRPckZhaWwiD2V4cGVjdGVkQXNzZXRJZCIDcG10IhVnZXRVc2VyR3d4QW1vdW50VG90YWwiGmdldFZvdGluZ0VtaXNzaW9uRXBvY2hJbmZvIg0kdDAxNDk5NTE1Mjg1Ig5jdXJyZW50RXBvY2hVaSISbGFzdEZpbmFsaXplZEVwb2NoIhdjdXJyZW50RXBvY2hTdGFydEhlaWdodCIYZ2V0UG9vbEFzc2V0c0J5THBBc3NldElkIhBpZHhBbW91bnRBc3NldElkIg9pZHhQcmljZUFzc2V0SWQiB3Bvb2xDZmciFGdldFVzZXJWb3RlRmluYWxpemVkIg0kdDAxNTk3NjE2MDU2Ig0kdDAxNjA1OTE2MTM0Igt1c2VyVm90ZUtleSIIdXNlclZvdGUiEWdldFVzZXJWb3RlU3Rha2VkIgxzdGFrZWRCeVVzZXIiFWdldFZvdGluZ1Jlc3VsdFN0YWtlZCINJHQwMTY2NzgxNjc1OCIXdm90aW5nUmVzdWx0U3Rha2VkU3RhcnQiEnZvdGluZ1Jlc3VsdFN0YWtlZCIdZ2V0Vm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWwiDSR0MDE3MTIwMTcyMDAiHnZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsUHJldiIidm90aW5nUmVzdWx0U3Rha2VkTGFzdFVwZGF0ZUhlaWdodCIcdm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWxEaCIadm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWwiIXJlZnJlc2hWb3RpbmdSZXN1bHRTdGFrZWRJbnRlZ3JhbCIPc3Rha2VkVm90ZURlbHRhIg0kdDAxODAzNzE4MTE3IhV2b3RpbmdSZXN1bHRTdGFrZWROZXciGWdldFVzZXJWb3RlU3Rha2VkSW50ZWdyYWwiDSR0MDE4NzI4MTg4MDgiDnVzZXJWb3RlU3Rha2VkIhp1c2VyVm90ZVN0YWtlZEludGVncmFsUHJldiIedXNlclZvdGVTdGFrZWRMYXN0VXBkYXRlSGVpZ2h0Ihh1c2VyVm90ZVN0YWtlZEludGVncmFsRGgiFnVzZXJWb3RlU3Rha2VkSW50ZWdyYWwiGXJlZnJlc2hWb3RlU3Rha2VkSW50ZWdyYWwiBGVkZ2UiDSR0MDE5NTk2MTk2NzYiEXVzZXJWb3RlRmluYWxpemVkIgdhY3Rpb25zIhN2b3RpbmdSZXN1bHRBY3Rpb25zIgt2b3RlQWN0aW9ucyIbZ2V0U3Rha2VkVm90ZXNJbnRlZ3JhbHNEaWZmIg0kdDAyMDUzMDIwNjEwIh11c2VyVm90ZVN0YWtlZEludGVncmFsTGFzdEtleSIadXNlclZvdGVTdGFrZWRJbnRlZ3JhbExhc3QiIXZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsTGFzdEtleSIedm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWxMYXN0Ihp1c2VyVm90ZVN0YWtlZEludGVncmFsRGlmZiIedm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWxEaWZmIhxyZWZyZXNoQm9vc3RFbWlzc2lvbkludGVncmFsIhJ3eEVtaXNzaW9uUGVyQmxvY2siIGJvb3N0aW5nVjJMYXN0VXBkYXRlSGVpZ2h0T3B0aW9uIhhib29zdGluZ1YySW5nZXJnYWxPcHRpb24iC2VtaXNzaW9uRW5kIgFoIgJkaCIQbGFzdFVwZGF0ZUhlaWdodCIVYm9vc3RFbWlzc2lvblBlckJsb2NrIhlib29zdEVtaXNzaW9uSW50ZWdyYWxQcmV2IhVib29zdEVtaXNzaW9uSW50ZWdyYWwiFGludGVybmFsQ2xhaW1XeEJvb3N0IghyZWFkT25seSIIRU1QVFlTVFIiCnBvb2xXZWlnaHQiDnBvb2xBZGRyZXNzU3RyIiJ1c2VyTHBCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZIiB1c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWSIddXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWwiGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwiDSR0MDI0MTUyMjQyOTEiG3N0YWtlZFZvdGVzSW50ZWdyYWxzQWN0aW9ucyIUdXNlclZvdGVJbnRlZ3JhbERpZmYiFnRvdGFsVm90ZXNJbnRlZ3JhbERpZmYiHXBvb2xVc2VyQm9vc3RFbWlzc2lvbkludGVncmFsIiF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXciCWRhdGFTdGF0ZSIFZGVidWciC2xvY2tBY3Rpb25zIg5kdXJhdGlvbk1vbnRocyIVZHVyYXRpb25Nb250aHNBbGxvd2VkIgphc3NldElkU3RyIglwbXRBbW91bnQiDm5leHRVc2VyTnVtS0VZIg51c2VySXNFeGlzdGluZyIKdXNlck51bVN0ciIHY29lZmZYOCIOZ1d4QW1vdW50U3RhcnQiDmd3eEFtb3VudFRvdGFsIhJ1c2VyR3d4QW1vdW50VG90YWwiDGd3eFJld2FyZEludiIDYXJyIhFmYWN0b3J5QWRkcmVzc1N0ciIObG9ja0Fzc2V0SWRTdHIiC21pbkR1cmF0aW9uIgttYXhEdXJhdGlvbiILY2hlY2tDYWxsZXIiD3JlZmVycmVyQWRkcmVzcyIJc2lnbmF0dXJlIg0kdDAyODI2ODI4MzMzIhFsb2NrQWN0aW9uc1Jlc3VsdCIPcmVmZXJyYWxBZGRyZXNzIgZyZWZJbnYiEXVwZGF0ZVJlZkFjdGl2aXR5Ig0kdDAyODc5MTI4ODU2Ig0kdDAyOTE2NjI5MjY4IhJ1c2VyQm9vc3RBdmFpbGFibGUiDSR0MDI5NDAwMjk1MDEiB3R4SWRTdHIiD3VzZXJSZWNvcmRBcnJheSIKdXNlckFtb3VudCIMbG9ja0R1cmF0aW9uIgdsb2NrRW5kIgF0IghleHBvbmVudCIOd3hXaXRoZHJhd2FibGUiCWd3eEJ1cm5lZCIMZ3d4UmVtYWluaW5nIg9sb2NrZWRHd3hBbW91bnQiDHRhcmdldEhlaWdodCICdHgiBnZlcmlmeSIPdGFyZ2V0UHVibGljS2V5jAEAAWECAl9fAAFiAAgAAWMAgMLXLwABZAUBYwABZQINYm9vc3RpbmcucmlkZQABZgASAAFnAICAkLu61q3wDQABaAkAtgIBBQFnAAFpAKALAAFqAJjWAgEBawEBbAkAuQkCCQDMCAIFAWUJAMwIAgICOiAJAMwIAgUBbAUDbmlsAgABAW0BAWwJAAIBCQEBawEFAWwBAW4CAW8BcAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFAW8FAXAJAQFrAQkArAICCQCsAgICD21hbmRhdG9yeSB0aGlzLgUBcAIPIGlzIG5vdCBkZWZpbmVkAQFxAgFvAXAJAQt2YWx1ZU9yRWxzZQIJAJoIAgUBbwUBcAAAAQFyAwFvAXABcwkBC3ZhbHVlT3JFbHNlAgkAmggCBQFvBQFwBQFzAQF0AgFvAXAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQFvBQFwCQEBawEJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4FAXACDyBpcyBub3QgZGVmaW5lZAEBdQEBdgMJAGYCAAAFAXYJAQEtAQUBdgUBdgEBdwIBeAF5AwkAZwIFAXgAAAUBeAkBAW0BCQCsAgIJAQt2YWx1ZU9y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AQJhSgAEAmFLCQECYUcABAJhSAkAnQgCBQJhSwkBAmFnAAMJAAECBQJhSAIGU3RyaW5nBAJhSQUCYUgJANkEAQUCYUkDCQABAgUCYUgCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgECYUwBAmFNBAJhTgkBAW0BAhFQZXJtaXNzaW9uIGRlbmllZAQCYUgJAQJhSgADCQABAgUCYUgCCkJ5dGVWZWN0b3IEAmFPBQJhSAMJAAACCAUCYU0PY2FsbGVyUHVibGljS2V5BQJhTwYFAmFOAwkAAQIFAmFIAgRVbml0AwkAAAIIBQJhTQZjYWxsZXIFBHRoaXMGBQJhTgkAAgECC01hdGNoIGVycm9yAAJhUAABAAJhUQACAAJhUgADAAJhUwAEAAJhVAAFAAJhVQAGAQJhVgICYVcCYVgJALkJAgkAzAgCAgwlcyVzJXNfX2xvY2sJAMwIAgkApQgBBQJhVwkAzAgCBAJhSAUCYVgDCQABAgUCYUgCCkJ5dGVWZWN0b3IEAmFZBQJhSAkA2AQBBQJhWQMJAAECBQJhSAIEVW5pdAIGbGVnYWN5CQACAQILTWF0Y2ggZXJyb3IFA25pbAUBYQECYVoCAmFXAmFYCQC1CQIJAQFuAgUEdGhpcwkBAmFWAgUCYVcFAmFYBQFhAQJiYQECYVcJALkJAgkAzAgCAhQlcyVzX19nd3hBbW91bnRUb3RhbAkAzAgCCQClCAEFAmFXBQNuaWwFAWEBAmJiBQJiYwJiZAJiZQJiZgJiZwkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYmMJAMwIAgkApAMBBQJiZAkAzAgCCQCkAwEFAmJlCQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkApAMBBQJiZgkAzAgCCQCkAwEFAmJnBQNuaWwFAWEBAmJoAAIPJXNfX25leHRVc2VyTnVtAQJiaQECYVcJALkJAgkAzAgCAhklcyVzJXNfX21hcHBpbmdfX3VzZXIybnVtCQDMCAIFAmFXBQNuaWwFAWEBAmJqAQFYCQC5CQIJAMwIAgIZJXMlcyVzX19tYXBwaW5nX19udW0ydXNlcgkAzAgCBQFYBQNuaWwFAWEBAmJrAAIeJXMlc19fc3RhdHNfX2FjdGl2ZVRvdGFsTG9ja2VkAQJibAACJSVzJXNfX3N0YXRzX19sb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MBAmJtAAIXJXMlc19fc3RhdHNfX2xvY2tzQ291bnQBAmJuAAIdJXMlc19fc3RhdHNfX2FjdGl2ZVVzZXJzQ291bnQBAmJvAQJicAkAuQkCCQDMCAICICVzJWRfX3VzZXJCb29zdEVtaXNzaW9uTGFzdEludFYyCQDMCAIJAKQDAQUCYnAFA25pbAUBYQECYnECAmJwAmJyCQC5CQIJAMwIAgIgJXMlZF9fdXNlckJvb3N0RW1pc3Npb25MYXN0SW50VjIJAMwIAgkApAMBBQJicAkAzAgCBQJicgUDbmlsBQFhAQJicwECYnAJALkJAgkAzAgCAhElcyVkX19tYXhCb29zdEludAkAzAgCCQCkAwEFAmJwBQNuaWwFAWEBAmJ0AAIYJXMlc19fbWF4Qm9vc3RJbnRfX3RvdGFsAQJidQECYnAJALkJAgkAzAgCAiQlcyVkX191c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWwJAMwIAgkApAMBBQJicAUDbmlsBQFhAQJidgECYnAJALkJAgkAzAgCAhYlcyVkX191c2VyQm9vc3RDbGFpbWVkCQDMCAIJAKQDAQUCYnAFA25pbAUBYQECYncAAhAlcyVzX19nd3hfX3RvdGFsAQJieAQCYnkCYnoBbwJiQQkAuQkCCQDMCAICCiVzJXMlcyVzJWQJAMwIAgIEdm90ZQkAzAgCBQJieQkAzAgCBQJiegkAzAgCCQClCAEFAW8JAMwIAgkApAMBBQJiQQUDbmlsBQFhAQJiQgECYkEJALkJAgkAzAgCAgQlcyVkCQDMCAICC3N0YXJ0SGVpZ2h0CQDMCAIJAKQDAQUCYkEFA25pbAUBYQECYkMACQC5CQIJAMwIAgICJXMJAMwIAgIOY3VycmVudEVwb2NoVWkFA25pbAUBYQECYkQCAmJFAmJBCQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICEnZvdGluZ1Jlc3VsdFN0YWtlZAkAzAgCBQJiRQkAzAgCCQCkAwEFAmJBBQNuaWwFAWEBAmJGAgJiRQJiQQkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAhp2b3RpbmdSZXN1bHRTdGFrZWRJbnRlZ3JhbAkAzAgCBQJiRQkAzAgCCQCkAwEFAmJBBQNuaWwFAWEBAmJHAgJiRQJiQQkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAip2b3RpbmdSZXN1bHRTdGFrZWRJbnRlZ3JhbExhc3RVcGRhdGVIZWlnaHQJAMwIAgUCYkUJAMwIAgkApAMBBQJiQQUDbmlsBQFhAQJiSAMCYkUBbwJiQQkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICHnZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsTGFzdAkAzAgCBQJiRQkAzAgCCQClCAEFAW8JAMwIAgkApAMBBQJiQQUDbmlsBQFhAQJiSQMCYkUBbwJiQQkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICEnZvdGVTdGFrZWRJbnRlZ3JhbAkAzAgCBQJiRQkAzAgCCQClCAEFAW8JAMwIAgkApAMBBQJiQQUDbmlsBQFhAQJiSgMCYkUBbwJiQQkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICInZvdGVTdGFrZWRJbnRlZ3JhbExhc3RVcGRhdGVIZWlnaHQJAMwIAgUCYkUJAMwIAgkApQgBBQFvCQDMCAIJAKQDAQUCYkEFA25pbAUBYQECYksDAmJFAW8CYkEJALkJAgkAzAgCAgglcyVzJXMlZAkAzAgCAhZ2b3RlU3Rha2VkSW50ZWdyYWxMYXN0CQDMCAIFAmJFCQDMCAIJAKUIAQUBbwkAzAgCCQCkAwEFAmJBBQNuaWwFAWEBAmJMAgJiTQJiRQkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgZzdGFrZWQJAMwIAgUCYk0JAMwIAgUCYkUFA25pbAUBYQACYk4JAQFZAAACYWMJAQFaAQUCYk4AAmJPCQECYWQBBQJhYwACYlAJAQJhZQEFAmFjAAJiUQkBAmFmAQUCYWMAAmJSCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJALkJAgkAzAgCAgIlcwkAzAgCAhZscFN0YWtpbmdQb29sc0NvbnRyYWN0BQNuaWwFAWEJAQFrAQIubHBfc3Rha2luZ19wb29scyBjb250cmFjdCBhZGRyZXNzIGlzIHVuZGVmaW5lZAkBAWsBAilpbnZhbGlkIGxwX3N0YWtpbmdfcG9vbHMgY29udHJhY3QgYWRkcmVzcwACYlMJALkJAgkAzAgCAgIlcwkAzAgCAhZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0BQNuaWwFAWEAAmJUCQERQGV4dHJOYXRpdmUoMTA2MikBCQERQGV4dHJOYXRpdmUoMTA1MykCBQJiTgUCYlMAAmJVCQC5CQIJAMwIAgICJXMJAMwIAgIadm90aW5nRW1pc3Npb25SYXRlQ29udHJhY3QFA25pbAUBYQACYlYKAAJiVwkA/AcEBQJiTwIVZ2V0Qm9vc3RDb2VmZlJFQURPTkxZBQNuaWwFA25pbAMJAAECBQJiVwIDSW50BQJiVwkAAgEJAKwCAgkAAwEFAmJXAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQBAmJYAQJhVwQCYUgJAJ0IAgUEdGhpcwkBAmJpAQkApQgBBQJhVwMJAAECBQJhSAIGU3RyaW5nBAJhSQUCYUgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAtgkBBQJhSQkBAWsBAhNpbnZhbGlkIHVzZXIgbnVtYmVyAwkAAQIFAmFIAgRVbml0CQEBbQECDGludmFsaWQgdXNlcgkAAgECC01hdGNoIGVycm9yAQJiWQAJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmJ3AAAAAQJiWgECYVcEAmNhAhJnZXRMb2NrZWRHd3hBbW91bnQEAmNiCQETdmFsdWVPckVycm9yTWVzc2FnZQIEAmFICQCdCAIFAmJUBQJiVQMJAAECBQJhSAIEVW5pdAUEdW5pdAMJAAECBQJhSAIGU3RyaW5nBAJhSQUCYUgJAKYIAQUCYUkJAAIBAgtNYXRjaCBlcnJvcgkBAWsBAiRpbnZhbGlkIHZvdGluZyBlbWlzc2lvbiByYXRlIGFkZHJlc3MEAmNjCgACYlcJAPwHBAUCYlQFAmNhCQDMCAIJAKUIAQUCYVcFA25pbAUDbmlsAwkAAQIFAmJXAgNJbnQFAmJXCQACAQkArAICCQADAQUCYlcCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAQCY2QKAAJiVwkA/AcEBQJjYgUCY2EJAMwIAgkApQgBBQJhVwUDbmlsBQNuaWwDCQABAgUCYlcCA0ludAUCYlcJAAIBCQCsAgIJAAMBBQJiVwIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50BAJjZQkAlgMBCQDMCAIFAmNjCQDMCAIFAmNkBQNuaWwFAmNlAQJjZgcCY2cCY2gCYmMCY2kCYmUCYmYCYU0EAmNqCQC5CQIJAMwIAgIRJXMlcyVzJXNfX2hpc3RvcnkJAMwIAgUCY2cJAMwIAgUCY2gJAMwIAgkA2AQBCAUCYU0NdHJhbnNhY3Rpb25JZAUDbmlsBQFhBAJjawkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQgFCWxhc3RCbG9jawZoZWlnaHQJAMwIAgkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQCkAwEFAmJjCQDMCAIJAKQDAQUCY2kJAMwIAgkApAMBBQJiZQkAzAgCCQCkAwEFAmJmBQNuaWwFAWEJAQtTdHJpbmdFbnRyeQIFAmNqBQJjawECY2wEAmNtAmNuAmNvAmNwBAJjcQkBAmJsAAQCY3IJAQJibQAEAmNzCQECYm4ABAJjdAkBAmJrAAQCY3UJAQFxAgUEdGhpcwUCY3EEAmN2CQEBcQIFBHRoaXMFAmNyBAJjdwkBAXECBQR0aGlzBQJjcwQCY3gJAQFxAgUEdGhpcwUCY3QJAMwIAgkBDEludGVnZXJFbnRyeQIFAmNxCQBkAgUCY3UFAmNuCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJjcgkAZAIFAmN2BQJjbwkAzAgCCQEMSW50ZWdlckVudHJ5AgUCY3MJAGQCBQJjdwUCY3AJAMwIAgkBDEludGVnZXJFbnRyeQIFAmN0CQBkAgUCY3gFAmNtBQNuaWwBAmN5BwJhVwJhWAJiYwJiZAJiZQJiZgJiZwkAzAgCCQELU3RyaW5nRW50cnkCCQECYVYCBQJhVwUCYVgJAQJiYgUFAmJjBQJiZAUCYmUFAmJmBQJiZwUDbmlsAQJjegICYU0CY0EDCQBmAgkAkAMBCAUCYU0IcGF5bWVudHMAAQkBAW0BAhtvbmx5IG9uZSBwYXltZW50IGlzIGFsbG93ZWQDCQAAAgkAkAMBCAUCYU0IcGF5bWVudHMAAAAABAJjQgkAkQMCCAUCYU0IcGF5bWVudHMAAAMJAQIhPQIJAQV2YWx1ZQEIBQJjQgdhc3NldElkBQJjQQkBAW0BAhtpbnZhbGlkIGFzc2V0IGlkIGluIHBh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bGlkIHVzZXIgYWRkcmVzcwQCYnAJAQJiWAEFAmFXAwkAAAIFAmJwBQJicAQCZFECBWVtcHR5BAJkUgMJAQIhPQIFAmJFBQJkUQQCZFMJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQJiTgkBAVIBBQJiRQkBAWsBCQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUCYkUJARFAZXh0ck5hdGl2ZSgxMDUwKQIFAmJOCQEBVAEFAmRTAwUCZFAAAAkBAW0BCQCsAgICKG5vdCByZWFkb25seSBtb2RlOiB1bnN1cHBvcnRlZCBscCBhc3NldCAFAmJFBAJkVAkBAmJxAgUCYnAFAmJFBAJkVQkBAmJvAQUCYnAEAmRWCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAmRUCQEBcQIFBHRoaXMFAmRVBAJkTggJAQJkRAACXzIEAmRXCQBlAgUCZE4FAmRWAwkAZgIAAAUCZFcJAQFtAQISd3JvbmcgY2FsY3VsYXRpb25zBAJkWAkBAmR2AgUCYkUFAmJNBAJkWQgFAmRYAl8xBAJkWggFAmRYAl8yBAJlYQgFAmRYAl8zBAJlYgkAawMFAmRXBQJkUgUBZAQCZWMDCQAAAgUCZWEAAAAACQBrAwUCZWIFAmRaBQJlYQQCZWQJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUCZFQFAmROBQNuaWwFAmRZBAJlZQkAuQkCCQDMCAIJAKQDAQUCZFYJAMwIAgkApAMBBQJkVwkAzAgCCQCkAwEFAmRSCQDMCAIJAKQDAQUCZFoJAMwIAgkApAMBBQJlYQUDbmlsAgE6CQCVCgMFAmVjBQJlZAUCZWUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmVmAgJhTQJlZwQCZWgJAMwIAgABCQDMCAIAAwkAzAgCAAYJAMwIAgAMCQDMCAIAGAkAzAgCADAFA25pbAMJAQEhAQkBD2NvbnRhaW5zRWxlbWVudAIFAmVoBQJlZwkBAW0BAhBpbnZhbGlkIGR1cmF0aW9uBAJiZQkAaAIFAmVnBQFqBAJlaQkA2AQBBQJhegMJAQIhPQIJAJADAQgFAmFNCHBheW1lbnRzAAEJAQFtAQI0aW52YWxpZCBwYXltZW50IC0gZXhhY3Qgb25lIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQCY0IJAJEDAggFAmFNCHBheW1lbnRzAAAEAmVqCAUCY0IGYW1vdW50AwkBAiE9AgUCYXoJAQV2YWx1ZQEIBQJjQgdhc3NldElkCQEBbQEJAKwCAgkArAICAh5pbnZhbGlkIGFzc2V0IGlzIGluIHBheW1lbnQgLSAFAmVpAgwgaXMgZXhwZWN0ZWQEAmVrCQECYmgABAJhVwgFAmFNBmNhbGxlcgQCYk0JAKUIAQUCYVcEAmVsCQEJaXNEZWZpbmVkAQkAoggBCQECYmkBBQJiTQQCZW0DBQJlbAkBBXZhbHVlAQkAoggBCQECYmkBBQJiTQkApAMBCQEBdAIFBHRoaXMFAmVrBAJicAkBDXBhcnNlSW50VmFsdWUBBQJlbQQCY2kFBmhlaWdodAMDCQBmAgUCYUEFAmVqCQECIT0CBQJhVwUCYlIHCQEBbQEJAKwCAgIiYW1vdW50IGlzIGxlc3MgdGhlbiBtaW5Mb2NrQW1vdW50PQkApAMBBQJhQQMJAGYCBQJhQgUCYmUJAQFtAQkArAICAi1wYXNzZWQgZHVyYXRpb24gaXMgbGVzcyB0aGVuIG1pbkxvY2tEdXJhdGlvbj0JAKQDAQUCYUIDCQBmAgUCYmUFAmFDCQEBbQEJAKwCAgIwcGFzc2VkIGR1cmF0aW9uIGlzIGdyZWF0ZXIgdGhlbiBtYXhMb2NrRHVyYXRpb249CQCkAwEFAmFDBAJlbgkAawMFAmJlBQFjBQJhQwQCZW8JAGsDBQJlagUCZW4FAWMEAmVwCQECYlkABAJkVQkBAmJvAQUCYnAEAmROCAkBAmREAAJfMgQCZXEJAQJjQwEFAmFXBAJlcgkA/AcEBQJiUQIRcmVmcmVzaFVzZXJSZXdhcmQJAMwIAggFAmFXBWJ5dGVzBQNuaWwFA25pbAMJAAACBQJlcgUCZXIEAmVzAwUCZWwFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgUCZWsJAGQCBQJicAABCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJiaQEFAmJNBQJlbQkAzAgCCQELU3RyaW5nRW50cnkCCQECYmoBBQJlbQUCYk0FA25pbAkAlAoCCQDOCAIJAM0IAgkAzggCCQDOCAIFAmVzCQECY3kHBQJhVwgFAmFNDXRyYW5zYWN0aW9uSWQFAmVqBQJjaQUCYmUFAmVvAAAJAQJjbAQFAmVqBQJiZQABAwUCZWwAAAABCQECY2YHAgRsb2NrBQJiTQUCZWoFAmNpBQJiZQUCZW8FAmFNCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJkVQUCZE4JAMwIAgkBDEludGVnZXJFbnRyeQIJAQJidwAJAGQCBQJlcAUCZW8JAMwIAgkBDEludGVnZXJFbnRyeQIJAQJiYQEFAmFXCQBkAgUCZXEFAmVvBQNuaWwFAmVvCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuEQJhTQELY29uc3RydWN0b3IGAmV0AmV1AmFBAmV2AmV3AmFEBAJleAkBAmFMAQUCYU0DCQAAAgUCZXgFAmV4CQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJiaAAAAAkAzAgCCQELU3RyaW5nRW50cnkCCQECYXcACQECYUYFBQJldQUCYUEFAmV2BQJldwUCYUQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAUUABQJldAUDbmlsCQECY2wEAAAAAAAAAAAJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYU0BB2xvY2tSZWYDAmJlAmV5AmV6BAJlQQkBAmVmAgUCYU0FAmJlBAJlQggFAmVBAl8xBAJlbwgFAmVBAl8yBAJlQwkApQgBCAUCYU0GY2FsbGVyBAJlRAMDCQAAAgUCZXkCAAYJAAACBQJlegEABQR1bml0CQD8BwQFAUECCmNyZWF0ZVBhaXIJAMwIAgUBRAkAzAgCBQJleQkAzAgCBQJlQwkAzAgCBQJlegUDbmlsBQNuaWwDCQAAAgUCZUQFAmVEBAJlRQkA/AcEBQJhRAIWdXBkYXRlUmVmZXJyYWxBY3Rpdml0eQkAzAgCCQClCAEIBQJhTQZjYWxsZXIJAMwIAgUCZW8FA25pbAUDbmlsAwkAAAIFAmVFBQJlRQkAlAoCBQJlQgUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhTQEEbG9jawECYmUEAmVGCQECZWYCBQJhTQUCYmUEAmVCCAUCZUYCXzEEAmVvCAUCZUYCXzIEAmVFCQD8BwQFAmFEAhZ1cGRhdGVSZWZlcnJhbEFjdGl2aXR5CQDMCAIJAKUIAQgFAmFNBmNhbGxlcgkAzAgCBQJlbwUDbmlsBQNuaWwDCQAAAgUCZUUFAmVFCQCUCgIFAmVCBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFNAQxjbGFpbVd4Qm9vc3QCAmJFAmJNAwkBAiE9AgUCYlAIBQJhTQZjYWxsZXIJAQFtAQIScGVybWlzc2lvbnMgZGVuaWVkBAJlRwkBAmRPAwUCYkUFAmJNBwQCZUgIBQJlRwJfMQQCZWQIBQJlRwJfMgQCZWUIBQJlRwJfMwkAlAoCBQJlZAkAzAgCBQJlSAUDbmlsAmFNARRjbGFpbVd4Qm9vc3RSRUFET05MWQICYkUCYk0EAmVJCQECZE8DBQJiRQUCYk0GBAJlSAgFAmVJAl8xBAJlZAgFAmVJAl8yBAJlZQgFAmVJAl8zCQCUCgIFA25pbAkAzAgCBQJlSAkAzAgCBQJlZQUDbmlsAmFNAQZ1bmxvY2sCAmVKAmJjBAJhVwgFAmFNBmNhbGxlcgQCYk0JAKUIAQUCYVcEAmFYCQDZBAEFAmVKBAJlSwkBAmFaAgUCYVcDCQAAAgUCZUoCAAUEdW5pdAUCYVgEAmVMCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZUsFAmFQBAJjaQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmVLBQJhUQQCZU0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJlSwUCYVIEAmVOCQBkAgUCY2kFAmVNBAJiZwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmVLBQJhVQQCYmYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJlSwUCYVQEAmVPCQBpAgkAZQIFBmhlaWdodAUCY2kFAWkEAmVQCQC8AgMJALYCAQUCZU8JALkCAgkAtgIBCQBoAgAIBQFpBQFoCQC2AgEFAmVNBAJlUQMJAGYCBQZoZWlnaHQFAmVOCQBlAgUCZUwFAmJnCQCgAwEJALwCAwkAtgIBBQJlTAkAuAICBQFoCQB2BgkAtgIBAAUAAQUCZVAFAWYFAWYFBERPV04FAWgDCQBmAgUCYmMFAmVRCQEBbQEJAKwCAgIabWF4aW11bSBhbW91bnQgdG8gdW5sb2NrOiAJAKQDAQUCZVEEAmVSCQCWAwEJAMwIAgUCYmMJAMwIAgkAawMJAGgCBQJlTwUBaQUCZUwFAmFDBQNuaWwEAmVTCQEBdwIJAGUCBQJiZgUCZVICDGd3eFJlbWFpbmluZwQCZVQJAQJiWgEFAmFXAwkAZgIFAmVUBQJlUwkBAW0BCQCsAgICE2xvY2tlZCBnd3ggYW1vdW50OiAJAKQDAQUCZVQDCQBnAgAABQJlTAkBAW0BAhFub3RoaW5nIHRvIHVubG9jawQCZXAJAQJiWQAEAmVxCQECY0MBBQJhVwQCZXIJAP0HBAUCYlECEXJlZnJlc2hVc2VyUmV3YXJkCQDMCAIIBQJhVwVieXRlcwUDbmlsBQNuaWwDCQAAAgUCZXIFAmVyCQDOCAIJAM0IAgkAzQgCCQDOCAIJAQJjeQcFAmFXBQJhWAUCZUwFAmNpBQJlTQUCZVMJAGQCBQJiZwUCYmMJAQJjbAQJAQEtAQUCZUwAAAAAAP///////////wEJAQJjZgcCBnVubG9jawUCYk0FAmVMBQJjaQUCZU0FAmVSBQJhTQkBDlNjcmlwdFRyYW5zZmVyAwUCYVcFAmVMBQJhegkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmJ3AAkBAXcCCQBlAgUCZXAFAmVSAghnd3hUb3RhbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmJhAQUCYVcJAQF3AgkAZQIFAmVxBQJlUgISdXNlckd3eEFtb3VudFRvdGFsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYU0BE2d3eFVzZXJJbmZvUkVBRE9OTFkBAmJNBAJhVwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEFAmJNCQEBawECFGludmFsaWQgdXNlciBhZGRyZXNzBAJiZgkBAmNDAQUCYVcJAJQKAgUDbmlsCQDMCAIFAmJmBQNuaWwCYU0BF3VzZXJNYXhEdXJhdGlvblJFQURPTkxZAQJiTQkAlAoCBQNuaWwJAJQKAgIMaW5jcmVhc2VMb2NrBQJhQwJhTQEgZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0UkVBRE9OTFkCAmJNAmVVBAJhVwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEFAmJNCQEBawECFGludmFsaWQgdXNlciBhZGRyZXNzBAJiZgkBAmNDAQUCYVcJAJQKAgUDbmlsBQJiZgJhTQEQZ2V0VXNlckd3eEFtb3VudAECYk0EAmFXCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQUCYk0JAQFrAQIUaW52YWxpZCB1c2VyIGFkZHJlc3MEAmJmCQECY0MBBQJhVwkAlAoCBQNuaWwFAmJmAmFNARNnZXRHd3hUb3RhbFJFQURPTkxZAAkAlAoCBQNuaWwJAQJiWQACYU0BFW9uQm9vc3RFbWlzc2lvblVwZGF0ZQAEAmV4AwkAAAIIBQJhTQZjYWxsZXIFAmJPBgkBAmFMAQUCYU0DCQAAAgUCZXgFAmV4CQECZEQACQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFNARJvblN0YWtlZFZvdGVVcGRhdGUDAmJFAmJNAmRwBAJleAMJAAACCAUCYU0GY2FsbGVyBQJiUAYJAQJhTAEFAmFNAwkAAAIFAmV4BQJleAQCZHMJAQJkbwMFAmJFBQJiTQUCZHAJAJQKAgUCZHMFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYU0BHWdldFZvdGluZ1Jlc3VsdFN0YWtlZFJFQURPTkxZAQJiRQkAlAoCBQNuaWwJAQJjVAEFAmJFAmFNASVnZXRWb3RpbmdSZXN1bHRTdGFrZWRJbnRlZ3JhbFJFQURPTkxZAQJiRQkAlAoCBQNuaWwJAQJjWAEFAmJFAmFNARxnZXRVc2VyVm90ZUZpbmFsaXplZFJFQURPTkxZAgJiRQJiTQkAlAoCBQNuaWwJAQJjTQIFAmJFBQJiTQJhTQEhZ2V0VXNlclZvdGVTdGFrZWRJbnRlZ3JhbFJFQURPTkxZAgJiRQJiTQkAlAoCBQNuaWwJAQJkaAIFAmJFBQJiTQECZVYBAmVXAAQCZVgEAmFICQECYUoAAwkAAQIFAmFIAgpCeXRlVmVjdG9yBAJhTwUCYUgFAmFPAwkAAQIFAmFIAgRVbml0CAUCZVYPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IJAPQDAwgFAmVWCWJvZHlCeXRlcwkAkQMCCAUCZVYGcHJvb2ZzAAAFAmVYxCVn7g==", "height": 2701545, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: Gjz63djpWUXYbBDxcnjh4RF8QyWA24gxc11kDhg9FAhg Next: HPqy87w685aEXfqGrxnzKVvwVTbi4BsX11xDJ3JzPRNb Diff:
OldNewDifferences
799799 else {
800800 let gwxAmountTotal = getGwxAmountTotal()
801801 let userGwxAmountTotal = getUserGwxAmountTotal(userAddress)
802- let gwxRewardInv = invoke(gwxRewardContract, "refreshUserReward", [userAddress.bytes], nil)
802+ let gwxRewardInv = reentrantInvoke(gwxRewardContract, "refreshUserReward", [userAddress.bytes], nil)
803803 if ((gwxRewardInv == gwxRewardInv))
804804 then ((((LockParamsEntry(userAddress, txId, userAmount, lockStart, lockDuration, gwxRemaining, (wxClaimed + amount)) ++ StatsEntry(-(userAmount), 0, 0, -1)) :+ HistoryEntry("unlock", userAddressStr, userAmount, lockStart, lockDuration, gwxBurned, i)) :+ ScriptTransfer(userAddress, userAmount, assetId)) ++ [IntegerEntry(keyGwxTotal(), ensurePositive((gwxAmountTotal - gwxBurned), "gwxTotal")), IntegerEntry(keyUserGwxAmountTotal(userAddress), ensurePositive((userGwxAmountTotal - gwxBurned), "userGwxAmountTotal"))])
805805 else throw("Strict value is not equal to itself.")
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
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 let contractFilename = "boosting.ride"
1313
1414 let SCALE18 = 18
1515
1616 let MULT18 = 1000000000000000000
1717
1818 let MULT18BI = toBigInt(MULT18)
1919
2020 let blocksInDay = 1440
2121
2222 let blocksInMonth = 43800
2323
2424 func wrapErr (msg) = makeString([contractFilename, ": ", msg], "")
2525
2626
2727 func throwErr (msg) = throw(wrapErr(msg))
2828
2929
3030 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), wrapErr((("mandatory this." + key) + " is not defined")))
3131
3232
3333 func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
3434
3535
3636 func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
3737
3838
3939 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), wrapErr((("mandatory this." + key) + " is not defined")))
4040
4141
4242 func abs (val) = if ((0 > val))
4343 then -(val)
4444 else val
4545
4646
4747 func ensurePositive (v,m) = if ((v >= 0))
4848 then v
4949 else throwErr((valueOrElse(m, "value") + " should be positive"))
5050
5151
5252 func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
5353
5454
5555 let referralsContractAddressOrFail = addressFromStringValue(getStringOrFail(this, keyReferralsContractAddress()))
5656
5757 let keyReferralProgramName = makeString(["%s%s", "referral", "programName"], SEP)
5858
5959 let referralProgramNameDefault = "wxlock"
6060
6161 let referralProgramName = valueOrElse(getString(this, keyReferralProgramName), referralProgramNameDefault)
6262
6363 func keyFactoryAddress () = "%s%s__config__factoryAddress"
6464
6565
6666 let IdxFactoryCfgStakingDapp = 1
6767
6868 let IdxFactoryCfgBoostingDapp = 2
6969
7070 let IdxFactoryCfgIdoDapp = 3
7171
7272 let IdxFactoryCfgTeamDapp = 4
7373
7474 let IdxFactoryCfgEmissionDapp = 5
7575
7676 let IdxFactoryCfgRestDapp = 6
7777
7878 let IdxFactoryCfgSlippageDapp = 7
7979
8080 let IdxFactoryCfgDaoDapp = 8
8181
8282 let IdxFactoryCfgMarketingDapp = 9
8383
8484 let IdxFactoryCfgGwxRewardDapp = 10
8585
8686 let IdxFactoryCfgBirdsDapp = 11
8787
8888 func keyFactoryCfg () = "%s__factoryConfig"
8989
9090
9191 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
9292
9393
9494 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
9595
9696
9797 func keyFactoryPoolWeightHistory (poolAddress,num) = ((("%s%s__poolWeight__" + poolAddress) + "__") + toString(num))
9898
9999
100100 func readFactoryAddressOrFail () = addressFromStringValue(getStringOrFail(this, keyFactoryAddress()))
101101
102102
103103 func readFactoryCfgOrFail (factory) = split(getStringOrFail(factory, keyFactoryCfg()), SEP)
104104
105105
106106 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
107107
108108
109109 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
110110
111111
112112 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
113113
114114
115115 func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp])
116116
117117
118118 func keyManagerPublicKey () = "%s__managerPublicKey"
119119
120120
121121 func keyManagerVaultAddress () = "%s__managerVaultAddress"
122122
123123
124124 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
125125
126126
127127 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
128128
129129
130130 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
131131
132132
133133 func keyBoostingV2LastUpdateHeight () = "%s%s__boostingV2__startBlock"
134134
135135
136136 func keyBoostingV2Integral () = "%s%s__boostingV2__integral"
137137
138138
139139 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
140140
141141
142142 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
143143
144144
145145 func keyNextPergetIntOrDefault () = "%s__nextPeriod"
146146
147147
148148 func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
149149
150150
151151 let IdxCfgAssetId = 1
152152
153153 let IdxCfgMinLockAmount = 2
154154
155155 let IdxCfgMinLockDuration = 3
156156
157157 let IdxCfgMaxLockDuration = 4
158158
159159 let IdxCfgMathContract = 5
160160
161161 func keyConfig () = "%s__config"
162162
163163
164164 func readConfigArrayOrFail () = split(getStringOrFail(this, keyConfig()), SEP)
165165
166166
167167 let cfgArray = readConfigArrayOrFail()
168168
169169 let assetId = fromBase58String(cfgArray[IdxCfgAssetId])
170170
171171 let minLockAmount = valueOrErrorMessage(parseInt(cfgArray[IdxCfgMinLockAmount]), wrapErr("invalid min lock amount"))
172172
173173 let minLockDuration = valueOrErrorMessage(parseInt(cfgArray[IdxCfgMinLockDuration]), wrapErr("invalid min lock duration"))
174174
175175 let maxLockDuration = valueOrErrorMessage(parseInt(cfgArray[IdxCfgMaxLockDuration]), wrapErr("invalid max lock duration"))
176176
177177 let mathContract = valueOrErrorMessage(addressFromString(cfgArray[IdxCfgMathContract]), wrapErr("invalid math contract address"))
178178
179179 func formatConfigS (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = makeString(["%s%d%d%d%s", assetId, minLockAmount, minLockDuration, maxLockDuration, mathContract], SEP)
180180
181181
182182 func formatConfig (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = formatConfigS(assetId, toString(minLockAmount), toString(minLockDuration), toString(maxLockDuration), mathContract)
183183
184184
185185 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
186186 case s: String =>
187187 addressFromStringValue(s)
188188 case _ =>
189189 this
190190 }
191191
192192
193193 func managerPublicKeyOrUnit () = {
194194 let managerVaultAddress = getManagerVaultAddressOrThis()
195195 match getString(managerVaultAddress, keyManagerPublicKey()) {
196196 case s: String =>
197197 fromBase58String(s)
198198 case _: Unit =>
199199 unit
200200 case _ =>
201201 throw("Match error")
202202 }
203203 }
204204
205205
206206 func mustManager (i) = {
207207 let pd = throwErr("Permission denied")
208208 match managerPublicKeyOrUnit() {
209209 case pk: ByteVector =>
210210 if ((i.callerPublicKey == pk))
211211 then true
212212 else pd
213213 case _: Unit =>
214214 if ((i.caller == this))
215215 then true
216216 else pd
217217 case _ =>
218218 throw("Match error")
219219 }
220220 }
221221
222222
223223 let IdxLockAmount = 1
224224
225225 let IdxLockStart = 2
226226
227227 let IdxLockDuration = 3
228228
229229 let IdxLockLastUpdateTimestamp = 4
230230
231231 let IdxLockGwxAmount = 5
232232
233233 let IdxLockWxClaimed = 6
234234
235235 func keyLockParamsRecord (userAddress,txId) = makeString(["%s%s%s__lock", toString(userAddress), match txId {
236236 case b: ByteVector =>
237237 toBase58String(b)
238238 case _: Unit =>
239239 "legacy"
240240 case _ =>
241241 throw("Match error")
242242 }], SEP)
243243
244244
245245 func readLockParamsRecordOrFail (userAddress,txId) = split(getStringOrFail(this, keyLockParamsRecord(userAddress, txId)), SEP)
246246
247247
248248 func keyUserGwxAmountTotal (userAddress) = makeString(["%s%s__gwxAmountTotal", toString(userAddress)], SEP)
249249
250250
251251 func formatLockParamsRecord (amount,start,duration,gwxAmount,wxClaimed) = makeString(["%d%d%d%d%d%d%d", toString(amount), toString(start), toString(duration), toString(lastBlock.timestamp), toString(gwxAmount), toString(wxClaimed)], SEP)
252252
253253
254254 func keyNextUserNum () = "%s__nextUserNum"
255255
256256
257257 func keyUser2NumMapping (userAddress) = makeString(["%s%s%s__mapping__user2num", userAddress], SEP)
258258
259259
260260 func keyNum2UserMapping (num) = makeString(["%s%s%s__mapping__num2user", num], SEP)
261261
262262
263263 func keyLockParamTotalAmount () = "%s%s__stats__activeTotalLocked"
264264
265265
266266 func keyStatsLocksDurationSumInBlocks () = "%s%s__stats__locksDurationSumInBlocks"
267267
268268
269269 func keyStatsLocksCount () = "%s%s__stats__locksCount"
270270
271271
272272 func keyStatsUsersCount () = "%s%s__stats__activeUsersCount"
273273
274274
275275 func keyUserBoostEmissionLastINTEGRAL (userNum) = makeString(["%s%d__userBoostEmissionLastIntV2", toString(userNum)], SEP)
276276
277277
278278 func keyUserLpBoostEmissionLastINTEGRAL (userNum,lpAssetId) = makeString(["%s%d__userBoostEmissionLastIntV2", toString(userNum), lpAssetId], SEP)
279279
280280
281281 func keyUserMaxBoostINTEGRAL (userNum) = makeString(["%s%d__maxBoostInt", toString(userNum)], SEP)
282282
283283
284284 func keyTotalMaxBoostINTEGRAL () = "%s%s__maxBoostInt__total"
285285
286286
287287 func keyUserBoostAvalaibleToClaimTotal (userNum) = makeString(["%s%d__userBoostAvaliableToClaimTotal", toString(userNum)], SEP)
288288
289289
290290 func keyUserBoostClaimed (userNum) = makeString(["%s%d__userBoostClaimed", toString(userNum)], SEP)
291291
292292
293293 func keyGwxTotal () = "%s%s__gwx__total"
294294
295295
296296 func keyVote (amountAssetId,priceAssetId,address,epoch) = makeString(["%s%s%s%s%d", "vote", amountAssetId, priceAssetId, toString(address), toString(epoch)], SEP)
297297
298298
299299 func keyStartHeightByEpoch (epoch) = makeString(["%s%d", "startHeight", toString(epoch)], SEP)
300300
301301
302302 func keyCurrentEpochUi () = makeString(["%s", "currentEpochUi"], SEP)
303303
304304
305305 func keyVotingResultStaked (lpAssetIdStr,epoch) = makeString(["%s%s%d", "votingResultStaked", lpAssetIdStr, toString(epoch)], SEP)
306306
307307
308308 func keyVotingResultStakedIntegral (lpAssetIdStr,epoch) = makeString(["%s%s%d", "votingResultStakedIntegral", lpAssetIdStr, toString(epoch)], SEP)
309309
310310
311311 func keyVotingResultStakedLastUpdateHeight (lpAssetIdStr,epoch) = makeString(["%s%s%d", "votingResultStakedIntegralLastUpdateHeight", lpAssetIdStr, toString(epoch)], SEP)
312312
313313
314314 func keyVotingResultStakedIntegralLast (lpAssetIdStr,address,epoch) = makeString(["%s%s%s%d", "votingResultStakedIntegralLast", lpAssetIdStr, toString(address), toString(epoch)], SEP)
315315
316316
317317 func keyVoteStakedIntegral (lpAssetIdStr,address,epoch) = makeString(["%s%s%s%d", "voteStakedIntegral", lpAssetIdStr, toString(address), toString(epoch)], SEP)
318318
319319
320320 func keyVoteStakedLastUpdateHeight (lpAssetIdStr,address,epoch) = makeString(["%s%s%s%d", "voteStakedIntegralLastUpdateHeight", lpAssetIdStr, toString(address), toString(epoch)], SEP)
321321
322322
323323 func keyVoteStakedIntegralLast (lpAssetIdStr,address,epoch) = makeString(["%s%s%s%d", "voteStakedIntegralLast", lpAssetIdStr, toString(address), toString(epoch)], SEP)
324324
325325
326326 func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s", "staked", userAddressStr, lpAssetIdStr], SEP)
327327
328328
329329 let factoryContract = readFactoryAddressOrFail()
330330
331331 let factoryCfg = readFactoryCfgOrFail(factoryContract)
332332
333333 let emissionContract = getEmissionAddressOrFail(factoryCfg)
334334
335335 let stakingContract = getStakingAddressOrFail(factoryCfg)
336336
337337 let gwxRewardContract = getGwxRewardAddressOrFail(factoryCfg)
338338
339339 let lpStakingPoolsContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(makeString(["%s", "lpStakingPoolsContract"], SEP)), wrapErr("lp_staking_pools contract address is undefined"))), wrapErr("invalid lp_staking_pools contract address"))
340340
341341 let keyVotingEmissionContract = makeString(["%s", "votingEmissionContract"], SEP)
342342
343343 let votingEmissionContract = addressFromStringValue(getStringValue(factoryContract, keyVotingEmissionContract))
344344
345345 let keyVotingEmissionRateContract = makeString(["%s", "votingEmissionRateContract"], SEP)
346346
347347 let boostCoeff = {
348348 let @ = invoke(emissionContract, "getBoostCoeffREADONLY", nil, nil)
349349 if ($isInstanceOf(@, "Int"))
350350 then @
351351 else throw(($getType(@) + " couldn't be cast to Int"))
352352 }
353353
354354 func userNumberByAddressOrFail (userAddress) = match getString(this, keyUser2NumMapping(toString(userAddress))) {
355355 case s: String =>
356356 valueOrErrorMessage(parseInt(s), wrapErr("invalid user number"))
357357 case _: Unit =>
358358 throwErr("invalid user")
359359 case _ =>
360360 throw("Match error")
361361 }
362362
363363
364364 func getGwxAmountTotal () = valueOrElse(getInteger(this, keyGwxTotal()), 0)
365365
366366
367367 func getLockedGwxAmount (userAddress) = {
368368 let functionName = "getLockedGwxAmount"
369369 let votingEmissionRateContract = valueOrErrorMessage( match getString(votingEmissionContract, keyVotingEmissionRateContract) {
370370 case _: Unit =>
371371 unit
372372 case s: String =>
373373 addressFromString(s)
374374 case _ =>
375375 throw("Match error")
376376 }, wrapErr("invalid voting emission rate address"))
377377 let lockedVotingEmissionRate = {
378378 let @ = invoke(votingEmissionContract, functionName, [toString(userAddress)], nil)
379379 if ($isInstanceOf(@, "Int"))
380380 then @
381381 else throw(($getType(@) + " couldn't be cast to Int"))
382382 }
383383 let lockedVotingEmission = {
384384 let @ = invoke(votingEmissionRateContract, functionName, [toString(userAddress)], nil)
385385 if ($isInstanceOf(@, "Int"))
386386 then @
387387 else throw(($getType(@) + " couldn't be cast to Int"))
388388 }
389389 let locked = max([lockedVotingEmissionRate, lockedVotingEmission])
390390 locked
391391 }
392392
393393
394394 func HistoryEntry (type,user,amount,lockStart,duration,gwxAmount,i) = {
395395 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
396396 let historyDATA = makeString(["%d%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(amount), toString(lockStart), toString(duration), toString(gwxAmount)], SEP)
397397 StringEntry(historyKEY, historyDATA)
398398 }
399399
400400
401401 func StatsEntry (totalLockedInc,durationInc,lockCountInc,usersCountInc) = {
402402 let locksDurationSumInBlocksKEY = keyStatsLocksDurationSumInBlocks()
403403 let locksCountKEY = keyStatsLocksCount()
404404 let usersCountKEY = keyStatsUsersCount()
405405 let totalAmountKEY = keyLockParamTotalAmount()
406406 let locksDurationSumInBlocks = getIntOrZero(this, locksDurationSumInBlocksKEY)
407407 let locksCount = getIntOrZero(this, locksCountKEY)
408408 let usersCount = getIntOrZero(this, usersCountKEY)
409409 let totalAmount = getIntOrZero(this, totalAmountKEY)
410410 [IntegerEntry(locksDurationSumInBlocksKEY, (locksDurationSumInBlocks + durationInc)), IntegerEntry(locksCountKEY, (locksCount + lockCountInc)), IntegerEntry(usersCountKEY, (usersCount + usersCountInc)), IntegerEntry(totalAmountKEY, (totalAmount + totalLockedInc))]
411411 }
412412
413413
414414 func LockParamsEntry (userAddress,txId,amount,start,duration,gwxAmount,wxClaimed) = [StringEntry(keyLockParamsRecord(userAddress, txId), formatLockParamsRecord(amount, start, duration, gwxAmount, wxClaimed))]
415415
416416
417417 func extractOptionalPaymentAmountOrFail (i,expectedAssetId) = if ((size(i.payments) > 1))
418418 then throwErr("only one payment is allowed")
419419 else if ((size(i.payments) == 0))
420420 then 0
421421 else {
422422 let pmt = i.payments[0]
423423 if ((value(pmt.assetId) != expectedAssetId))
424424 then throwErr("invalid asset id in payment")
425425 else pmt.amount
426426 }
427427
428428
429429 func getUserGwxAmountTotal (userAddress) = valueOrElse(getInteger(this, keyUserGwxAmountTotal(userAddress)), 0)
430430
431431
432432 func getVotingEmissionEpochInfo () = {
433433 let $t01499515285 = {
434434 let currentEpochUi = value(getInteger(votingEmissionContract, keyCurrentEpochUi()))
435435 let lastFinalizedEpoch = (currentEpochUi - 1)
436436 if ((0 > lastFinalizedEpoch))
437437 then throwErr("invalid epoch")
438438 else $Tuple2(currentEpochUi, lastFinalizedEpoch)
439439 }
440440 let currentEpochUi = $t01499515285._1
441441 let lastFinalizedEpoch = $t01499515285._2
442442 let currentEpochStartHeight = value(getInteger(votingEmissionContract, keyStartHeightByEpoch(currentEpochUi)))
443443 $Tuple2(lastFinalizedEpoch, currentEpochStartHeight)
444444 }
445445
446446
447447 func getPoolAssetsByLpAssetId (lpAssetIdStr) = {
448448 let idxAmountAssetId = 4
449449 let idxPriceAssetId = 5
450450 let poolCfg = {
451451 let @ = invoke(factoryContract, "getPoolConfigByLpAssetIdREADONLY", [lpAssetIdStr], nil)
452452 if ($isInstanceOf(@, "List[Any]"))
453453 then @
454454 else throw(($getType(@) + " couldn't be cast to List[Any]"))
455455 }
456456 let amountAssetId = {
457457 let @ = poolCfg[idxAmountAssetId]
458458 if ($isInstanceOf(@, "String"))
459459 then @
460460 else throw(($getType(@) + " couldn't be cast to String"))
461461 }
462462 let priceAssetId = {
463463 let @ = poolCfg[idxPriceAssetId]
464464 if ($isInstanceOf(@, "String"))
465465 then @
466466 else throw(($getType(@) + " couldn't be cast to String"))
467467 }
468468 $Tuple2(amountAssetId, priceAssetId)
469469 }
470470
471471
472472 func getUserVoteFinalized (lpAssetIdStr,userAddressStr) = {
473473 let userAddress = addressFromStringValue(userAddressStr)
474474 let $t01597616056 = getVotingEmissionEpochInfo()
475475 let lastFinalizedEpoch = $t01597616056._1
476476 let currentEpochStartHeight = $t01597616056._2
477477 let $t01605916134 = getPoolAssetsByLpAssetId(lpAssetIdStr)
478478 let amountAssetId = $t01605916134._1
479479 let priceAssetId = $t01605916134._2
480480 let userVoteKey = keyVote(amountAssetId, priceAssetId, userAddress, lastFinalizedEpoch)
481481 let userVote = valueOrElse(getInteger(votingEmissionContract, userVoteKey), 0)
482482 userVote
483483 }
484484
485485
486486 func getUserVoteStaked (lpAssetIdStr,userAddressStr) = {
487487 let stakedByUser = valueOrElse(getInteger(stakingContract, keyStakedByUser(userAddressStr, lpAssetIdStr)), 0)
488488 let userVote = getUserVoteFinalized(lpAssetIdStr, userAddressStr)
489489 if ((stakedByUser == 0))
490490 then 0
491491 else userVote
492492 }
493493
494494
495495 func getVotingResultStaked (lpAssetIdStr) = {
496496 let $t01667816758 = getVotingEmissionEpochInfo()
497497 let lastFinalizedEpoch = $t01667816758._1
498498 let currentEpochStartHeight = $t01667816758._2
499499 let votingResultStakedStart = valueOrElse(getInteger(votingEmissionContract, keyVotingResultStaked(lpAssetIdStr, lastFinalizedEpoch)), 0)
500500 let votingResultStaked = valueOrElse(getInteger(this, keyVotingResultStaked(lpAssetIdStr, lastFinalizedEpoch)), votingResultStakedStart)
501501 votingResultStaked
502502 }
503503
504504
505505 func getVotingResultStakedIntegral (lpAssetIdStr) = {
506506 let $t01712017200 = getVotingEmissionEpochInfo()
507507 let lastFinalizedEpoch = $t01712017200._1
508508 let currentEpochStartHeight = $t01712017200._2
509509 let votingResultStaked = getVotingResultStaked(lpAssetIdStr)
510510 let votingResultStakedIntegralPrev = valueOrElse(getInteger(this, keyVotingResultStakedIntegral(lpAssetIdStr, lastFinalizedEpoch)), 0)
511511 let votingResultStakedLastUpdateHeight = valueOrElse(getInteger(this, keyVotingResultStakedLastUpdateHeight(lpAssetIdStr, lastFinalizedEpoch)), currentEpochStartHeight)
512512 let votingResultStakedIntegralDh = (height - votingResultStakedLastUpdateHeight)
513513 let votingResultStakedIntegral = ((votingResultStakedIntegralDh * votingResultStaked) + votingResultStakedIntegralPrev)
514514 votingResultStakedIntegral
515515 }
516516
517517
518518 func refreshVotingResultStakedIntegral (lpAssetIdStr,stakedVoteDelta) = {
519519 let $t01803718117 = getVotingEmissionEpochInfo()
520520 let lastFinalizedEpoch = $t01803718117._1
521521 let currentEpochStartHeight = $t01803718117._2
522522 let votingResultStaked = getVotingResultStaked(lpAssetIdStr)
523523 let votingResultStakedNew = (votingResultStaked + stakedVoteDelta)
524524 let votingResultStakedIntegral = getVotingResultStakedIntegral(lpAssetIdStr)
525525 [IntegerEntry(keyVotingResultStaked(lpAssetIdStr, lastFinalizedEpoch), votingResultStakedNew), IntegerEntry(keyVotingResultStakedLastUpdateHeight(lpAssetIdStr, lastFinalizedEpoch), height), IntegerEntry(keyVotingResultStakedIntegral(lpAssetIdStr, lastFinalizedEpoch), votingResultStakedIntegral)]
526526 }
527527
528528
529529 func getUserVoteStakedIntegral (lpAssetIdStr,userAddressStr) = {
530530 let $t01872818808 = getVotingEmissionEpochInfo()
531531 let lastFinalizedEpoch = $t01872818808._1
532532 let currentEpochStartHeight = $t01872818808._2
533533 let userAddress = addressFromStringValue(userAddressStr)
534534 let userVoteStaked = getUserVoteStaked(lpAssetIdStr, userAddressStr)
535535 let userVoteStakedIntegralPrev = valueOrElse(getInteger(this, keyVoteStakedIntegral(lpAssetIdStr, userAddress, lastFinalizedEpoch)), 0)
536536 let userVoteStakedLastUpdateHeight = valueOrElse(getInteger(this, keyVoteStakedLastUpdateHeight(lpAssetIdStr, userAddress, lastFinalizedEpoch)), currentEpochStartHeight)
537537 let userVoteStakedIntegralDh = (height - userVoteStakedLastUpdateHeight)
538538 let userVoteStakedIntegral = ((userVoteStakedIntegralDh * userVoteStaked) + userVoteStakedIntegralPrev)
539539 userVoteStakedIntegral
540540 }
541541
542542
543543 func refreshVoteStakedIntegral (lpAssetIdStr,userAddressStr,edge) = {
544544 let $t01959619676 = getVotingEmissionEpochInfo()
545545 let lastFinalizedEpoch = $t01959619676._1
546546 let currentEpochStartHeight = $t01959619676._2
547547 let userAddress = addressFromStringValue(userAddressStr)
548548 let userVoteFinalized = getUserVoteFinalized(lpAssetIdStr, userAddressStr)
549549 let actions = if ((userVoteFinalized == 0))
550550 then nil
551551 else {
552552 let stakedVoteDelta = if (edge)
553553 then userVoteFinalized
554554 else -(userVoteFinalized)
555555 let votingResultActions = refreshVotingResultStakedIntegral(lpAssetIdStr, stakedVoteDelta)
556556 let userVoteStakedIntegral = getUserVoteStakedIntegral(lpAssetIdStr, userAddressStr)
557557 let voteActions = [IntegerEntry(keyVoteStakedLastUpdateHeight(lpAssetIdStr, userAddress, lastFinalizedEpoch), height), IntegerEntry(keyVoteStakedIntegral(lpAssetIdStr, userAddress, lastFinalizedEpoch), userVoteStakedIntegral)]
558558 (votingResultActions ++ voteActions)
559559 }
560560 actions
561561 }
562562
563563
564564 func getStakedVotesIntegralsDiff (lpAssetIdStr,userAddressStr) = {
565565 let $t02053020610 = getVotingEmissionEpochInfo()
566566 let lastFinalizedEpoch = $t02053020610._1
567567 let currentEpochStartHeight = $t02053020610._2
568568 let userAddress = addressFromStringValue(userAddressStr)
569569 let userVoteStakedIntegralLastKey = keyVoteStakedIntegralLast(lpAssetIdStr, userAddress, lastFinalizedEpoch)
570570 let userVoteStakedIntegralLast = valueOrElse(getInteger(this, userVoteStakedIntegralLastKey), 0)
571571 let votingResultStakedIntegralLastKey = keyVotingResultStakedIntegralLast(lpAssetIdStr, userAddress, lastFinalizedEpoch)
572572 let votingResultStakedIntegralLast = valueOrElse(getInteger(this, votingResultStakedIntegralLastKey), 0)
573573 let userVoteStakedIntegral = getUserVoteStakedIntegral(lpAssetIdStr, userAddressStr)
574574 let votingResultStakedIntegral = getVotingResultStakedIntegral(lpAssetIdStr)
575575 let userVoteStakedIntegralDiff = (userVoteStakedIntegral - userVoteStakedIntegralLast)
576576 let votingResultStakedIntegralDiff = (votingResultStakedIntegral - votingResultStakedIntegralLast)
577577 $Tuple3([IntegerEntry(userVoteStakedIntegralLastKey, userVoteStakedIntegral), IntegerEntry(votingResultStakedIntegralLastKey, votingResultStakedIntegral)], userVoteStakedIntegralDiff, votingResultStakedIntegralDiff)
578578 }
579579
580580
581581 func refreshBoostEmissionIntegral () = {
582582 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
583583 let boostingV2LastUpdateHeightOption = getInteger(this, keyBoostingV2LastUpdateHeight())
584584 let boostingV2IngergalOption = getInteger(this, keyBoostingV2Integral())
585585 let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
586586 let h = if ((height > emissionEnd))
587587 then emissionEnd
588588 else height
589589 let dh = match boostingV2LastUpdateHeightOption {
590590 case lastUpdateHeight: Int =>
591591 max([(h - lastUpdateHeight), 0])
592592 case _: Unit =>
593593 0
594594 case _ =>
595595 throw("Match error")
596596 }
597597 let boostEmissionPerBlock = ((wxEmissionPerBlock * (boostCoeff - 1)) / boostCoeff)
598598 let boostEmissionIntegralPrev = valueOrElse(boostingV2IngergalOption, 0)
599599 let boostEmissionIntegral = ((boostEmissionPerBlock * dh) + boostEmissionIntegralPrev)
600600 $Tuple2([IntegerEntry(keyBoostingV2Integral(), boostEmissionIntegral), IntegerEntry(keyBoostingV2LastUpdateHeight(), height)], boostEmissionIntegral)
601601 }
602602
603603
604604 func internalClaimWxBoost (lpAssetIdStr,userAddressStr,readOnly) = {
605605 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
606606 let userNum = userNumberByAddressOrFail(userAddress)
607607 if ((userNum == userNum))
608608 then {
609609 let EMPTYSTR = "empty"
610610 let poolWeight = if ((lpAssetIdStr != EMPTYSTR))
611611 then {
612612 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr)), wrapErr(("unsupported lp asset " + lpAssetIdStr)))
613613 getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
614614 }
615615 else if (readOnly)
616616 then 0
617617 else throwErr(("not readonly mode: unsupported lp asset " + lpAssetIdStr))
618618 let userLpBoostEmissionLastIntegralKEY = keyUserLpBoostEmissionLastINTEGRAL(userNum, lpAssetIdStr)
619619 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNum)
620620 let userBoostEmissionLastIntegral = valueOrElse(getInteger(this, userLpBoostEmissionLastIntegralKEY), getIntOrZero(this, userBoostEmissionLastIntegralKEY))
621621 let boostEmissionIntegral = refreshBoostEmissionIntegral()._2
622622 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
623623 if ((0 > userBoostEmissionIntegral))
624624 then throwErr("wrong calculations")
625625 else {
626626 let $t02415224291 = getStakedVotesIntegralsDiff(lpAssetIdStr, userAddressStr)
627627 let stakedVotesIntegralsActions = $t02415224291._1
628628 let userVoteIntegralDiff = $t02415224291._2
629629 let totalVotesIntegralDiff = $t02415224291._3
630630 let poolUserBoostEmissionIntegral = fraction(userBoostEmissionIntegral, poolWeight, POOLWEIGHTMULT)
631631 let userBoostAvaliableToClaimTotalNew = if ((totalVotesIntegralDiff == 0))
632632 then 0
633633 else fraction(poolUserBoostEmissionIntegral, userVoteIntegralDiff, totalVotesIntegralDiff)
634634 let dataState = ([IntegerEntry(userLpBoostEmissionLastIntegralKEY, boostEmissionIntegral)] ++ stakedVotesIntegralsActions)
635635 let debug = makeString([toString(userBoostEmissionLastIntegral), toString(userBoostEmissionIntegral), toString(poolWeight), toString(userVoteIntegralDiff), toString(totalVotesIntegralDiff)], ":")
636636 $Tuple3(userBoostAvaliableToClaimTotalNew, dataState, debug)
637637 }
638638 }
639639 else throw("Strict value is not equal to itself.")
640640 }
641641
642642
643643 func lockActions (i,durationMonths) = {
644644 let durationMonthsAllowed = [1, 3, 6, 12, 24, 48]
645645 if (!(containsElement(durationMonthsAllowed, durationMonths)))
646646 then throwErr("invalid duration")
647647 else {
648648 let duration = (durationMonths * blocksInMonth)
649649 let assetIdStr = toBase58String(assetId)
650650 if ((size(i.payments) != 1))
651651 then throwErr("invalid payment - exact one payment must be attached")
652652 else {
653653 let pmt = i.payments[0]
654654 let pmtAmount = pmt.amount
655655 if ((assetId != value(pmt.assetId)))
656656 then throwErr((("invalid asset is in payment - " + assetIdStr) + " is expected"))
657657 else {
658658 let nextUserNumKEY = keyNextUserNum()
659659 let userAddress = i.caller
660660 let userAddressStr = toString(userAddress)
661661 let userIsExisting = isDefined(getString(keyUser2NumMapping(userAddressStr)))
662662 let userNumStr = if (userIsExisting)
663663 then value(getString(keyUser2NumMapping(userAddressStr)))
664664 else toString(getIntOrFail(this, nextUserNumKEY))
665665 let userNum = parseIntValue(userNumStr)
666666 let lockStart = height
667667 if (if ((minLockAmount > pmtAmount))
668668 then (userAddress != lpStakingPoolsContract)
669669 else false)
670670 then throwErr(("amount is less then minLockAmount=" + toString(minLockAmount)))
671671 else if ((minLockDuration > duration))
672672 then throwErr(("passed duration is less then minLockDuration=" + toString(minLockDuration)))
673673 else if ((duration > maxLockDuration))
674674 then throwErr(("passed duration is greater then maxLockDuration=" + toString(maxLockDuration)))
675675 else {
676676 let coeffX8 = fraction(duration, MULT8, maxLockDuration)
677677 let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
678678 let gwxAmountTotal = getGwxAmountTotal()
679679 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNum)
680680 let boostEmissionIntegral = refreshBoostEmissionIntegral()._2
681681 let userGwxAmountTotal = getUserGwxAmountTotal(userAddress)
682682 let gwxRewardInv = invoke(gwxRewardContract, "refreshUserReward", [userAddress.bytes], nil)
683683 if ((gwxRewardInv == gwxRewardInv))
684684 then {
685685 let arr = if (userIsExisting)
686686 then nil
687687 else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
688688 $Tuple2(((((arr ++ LockParamsEntry(userAddress, i.transactionId, pmtAmount, lockStart, duration, gWxAmountStart, 0)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
689689 then 0
690690 else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, gWxAmountStart, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(keyGwxTotal(), (gwxAmountTotal + gWxAmountStart)), IntegerEntry(keyUserGwxAmountTotal(userAddress), (userGwxAmountTotal + gWxAmountStart))]), gWxAmountStart)
691691 }
692692 else throw("Strict value is not equal to itself.")
693693 }
694694 }
695695 }
696696 }
697697 }
698698
699699
700700 @Callable(i)
701701 func constructor (factoryAddressStr,lockAssetIdStr,minLockAmount,minDuration,maxDuration,mathContract) = {
702702 let checkCaller = mustManager(i)
703703 if ((checkCaller == checkCaller))
704704 then ([IntegerEntry(keyNextUserNum(), 0), StringEntry(keyConfig(), formatConfig(lockAssetIdStr, minLockAmount, minDuration, maxDuration, mathContract)), StringEntry(keyFactoryAddress(), factoryAddressStr)] ++ StatsEntry(0, 0, 0, 0))
705705 else throw("Strict value is not equal to itself.")
706706 }
707707
708708
709709
710710 @Callable(i)
711711 func lockRef (duration,referrerAddress,signature) = {
712712 let $t02826828333 = lockActions(i, duration)
713713 let lockActionsResult = $t02826828333._1
714714 let gWxAmountStart = $t02826828333._2
715715 let referralAddress = toString(i.caller)
716716 let refInv = if (if ((referrerAddress == ""))
717717 then true
718718 else (signature == base58''))
719719 then unit
720720 else invoke(referralsContractAddressOrFail, "createPair", [referralProgramName, referrerAddress, referralAddress, signature], nil)
721721 if ((refInv == refInv))
722722 then {
723723 let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
724724 if ((updateRefActivity == updateRefActivity))
725725 then $Tuple2(lockActionsResult, unit)
726726 else throw("Strict value is not equal to itself.")
727727 }
728728 else throw("Strict value is not equal to itself.")
729729 }
730730
731731
732732
733733 @Callable(i)
734734 func lock (duration) = {
735735 let $t02879128856 = lockActions(i, duration)
736736 let lockActionsResult = $t02879128856._1
737737 let gWxAmountStart = $t02879128856._2
738738 let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
739739 if ((updateRefActivity == updateRefActivity))
740740 then $Tuple2(lockActionsResult, unit)
741741 else throw("Strict value is not equal to itself.")
742742 }
743743
744744
745745
746746 @Callable(i)
747747 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
748748 then throwErr("permissions denied")
749749 else {
750750 let $t02916629268 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
751751 let userBoostAvailable = $t02916629268._1
752752 let dataState = $t02916629268._2
753753 let debug = $t02916629268._3
754754 $Tuple2(dataState, [userBoostAvailable])
755755 }
756756
757757
758758
759759 @Callable(i)
760760 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
761761 let $t02940029501 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
762762 let userBoostAvailable = $t02940029501._1
763763 let dataState = $t02940029501._2
764764 let debug = $t02940029501._3
765765 $Tuple2(nil, [userBoostAvailable, debug])
766766 }
767767
768768
769769
770770 @Callable(i)
771771 func unlock (txIdStr,amount) = {
772772 let userAddress = i.caller
773773 let userAddressStr = toString(userAddress)
774774 let txId = fromBase58String(txIdStr)
775775 let userRecordArray = readLockParamsRecordOrFail(userAddress, if ((txIdStr == ""))
776776 then unit
777777 else txId)
778778 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
779779 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
780780 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
781781 let lockEnd = (lockStart + lockDuration)
782782 let wxClaimed = parseIntValue(userRecordArray[IdxLockWxClaimed])
783783 let gwxAmount = parseIntValue(userRecordArray[IdxLockGwxAmount])
784784 let t = ((height - lockStart) / blocksInDay)
785785 let exponent = fraction(toBigInt(t), (toBigInt((8 * blocksInDay)) * MULT18BI), toBigInt(lockDuration))
786786 let wxWithdrawable = if ((height > lockEnd))
787787 then (userAmount - wxClaimed)
788788 else toInt(fraction(toBigInt(userAmount), (MULT18BI - pow(toBigInt(5), 1, exponent, SCALE18, SCALE18, DOWN)), MULT18BI))
789789 if ((amount > wxWithdrawable))
790790 then throwErr(("maximum amount to unlock: " + toString(wxWithdrawable)))
791791 else {
792792 let gwxBurned = max([amount, fraction((t * blocksInDay), userAmount, maxLockDuration)])
793793 let gwxRemaining = ensurePositive((gwxAmount - gwxBurned), "gwxRemaining")
794794 let lockedGwxAmount = getLockedGwxAmount(userAddress)
795795 if ((lockedGwxAmount > gwxRemaining))
796796 then throwErr(("locked gwx amount: " + toString(lockedGwxAmount)))
797797 else if ((0 >= userAmount))
798798 then throwErr("nothing to unlock")
799799 else {
800800 let gwxAmountTotal = getGwxAmountTotal()
801801 let userGwxAmountTotal = getUserGwxAmountTotal(userAddress)
802- let gwxRewardInv = invoke(gwxRewardContract, "refreshUserReward", [userAddress.bytes], nil)
802+ let gwxRewardInv = reentrantInvoke(gwxRewardContract, "refreshUserReward", [userAddress.bytes], nil)
803803 if ((gwxRewardInv == gwxRewardInv))
804804 then ((((LockParamsEntry(userAddress, txId, userAmount, lockStart, lockDuration, gwxRemaining, (wxClaimed + amount)) ++ StatsEntry(-(userAmount), 0, 0, -1)) :+ HistoryEntry("unlock", userAddressStr, userAmount, lockStart, lockDuration, gwxBurned, i)) :+ ScriptTransfer(userAddress, userAmount, assetId)) ++ [IntegerEntry(keyGwxTotal(), ensurePositive((gwxAmountTotal - gwxBurned), "gwxTotal")), IntegerEntry(keyUserGwxAmountTotal(userAddress), ensurePositive((userGwxAmountTotal - gwxBurned), "userGwxAmountTotal"))])
805805 else throw("Strict value is not equal to itself.")
806806 }
807807 }
808808 }
809809
810810
811811
812812 @Callable(i)
813813 func gwxUserInfoREADONLY (userAddressStr) = {
814814 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
815815 let gwxAmount = getUserGwxAmountTotal(userAddress)
816816 $Tuple2(nil, [gwxAmount])
817817 }
818818
819819
820820
821821 @Callable(i)
822822 func userMaxDurationREADONLY (userAddressStr) = $Tuple2(nil, $Tuple2("increaseLock", maxLockDuration))
823823
824824
825825
826826 @Callable(i)
827827 func getUserGwxAmountAtHeightREADONLY (userAddressStr,targetHeight) = {
828828 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
829829 let gwxAmount = getUserGwxAmountTotal(userAddress)
830830 $Tuple2(nil, gwxAmount)
831831 }
832832
833833
834834
835835 @Callable(i)
836836 func getUserGwxAmount (userAddressStr) = {
837837 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
838838 let gwxAmount = getUserGwxAmountTotal(userAddress)
839839 $Tuple2(nil, gwxAmount)
840840 }
841841
842842
843843
844844 @Callable(i)
845845 func getGwxTotalREADONLY () = $Tuple2(nil, getGwxAmountTotal())
846846
847847
848848
849849 @Callable(i)
850850 func onBoostEmissionUpdate () = {
851851 let checkCaller = if ((i.caller == emissionContract))
852852 then true
853853 else mustManager(i)
854854 if ((checkCaller == checkCaller))
855855 then refreshBoostEmissionIntegral()
856856 else throw("Strict value is not equal to itself.")
857857 }
858858
859859
860860
861861 @Callable(i)
862862 func onStakedVoteUpdate (lpAssetIdStr,userAddressStr,edge) = {
863863 let checkCaller = if ((i.caller == stakingContract))
864864 then true
865865 else mustManager(i)
866866 if ((checkCaller == checkCaller))
867867 then {
868868 let actions = refreshVoteStakedIntegral(lpAssetIdStr, userAddressStr, edge)
869869 $Tuple2(actions, unit)
870870 }
871871 else throw("Strict value is not equal to itself.")
872872 }
873873
874874
875875
876876 @Callable(i)
877877 func getVotingResultStakedREADONLY (lpAssetIdStr) = $Tuple2(nil, getVotingResultStaked(lpAssetIdStr))
878878
879879
880880
881881 @Callable(i)
882882 func getVotingResultStakedIntegralREADONLY (lpAssetIdStr) = $Tuple2(nil, getVotingResultStakedIntegral(lpAssetIdStr))
883883
884884
885885
886886 @Callable(i)
887887 func getUserVoteFinalizedREADONLY (lpAssetIdStr,userAddressStr) = $Tuple2(nil, getUserVoteFinalized(lpAssetIdStr, userAddressStr))
888888
889889
890890
891891 @Callable(i)
892892 func getUserVoteStakedIntegralREADONLY (lpAssetIdStr,userAddressStr) = $Tuple2(nil, getUserVoteStakedIntegral(lpAssetIdStr, userAddressStr))
893893
894894
895895 @Verifier(tx)
896896 func verify () = {
897897 let targetPublicKey = match managerPublicKeyOrUnit() {
898898 case pk: ByteVector =>
899899 pk
900900 case _: Unit =>
901901 tx.senderPublicKey
902902 case _ =>
903903 throw("Match error")
904904 }
905905 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
906906 }
907907

github/deemru/w8io/026f985 
126.62 ms