tx · J4yBN261bq3dkFdNev3X6agcLXU6hredbUo21P4Q1UL1

3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy:  -0.02600000 Waves

2023.08.11 18:05 [2706081] smart account 3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy > SELF 0.00000000 Waves

{ "type": 13, "id": "J4yBN261bq3dkFdNev3X6agcLXU6hredbUo21P4Q1UL1", "fee": 2600000, "feeAssetId": null, "timestamp": 1691766319364, "version": 2, "chainId": 84, "sender": "3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy", "senderPublicKey": "9W33iCCNfmFxUbiC6XZcH5x7f6xfwC7Jb3BoExT5q2PV", "proofs": [ "4YxyoBSM6fnZtqt8Atxp1FRfPKZqH5FexfPG6zvP9Ug5d95yvUYhKUwvysTa1iNdCzdcSZV4a4nFRzDP73Lyqp1C" ], "script": "base64:BgKKLggCEggKBggIAQEBCBIFCgMBCAISAwoBARIECgIICBIECgIICBIDCgEIEgMKAQgSAwoBCBIECgIIARIDCgEIEgASABIFCgMICAQSAwoBCBIDCgEIEgQKAggIEgQKAggIIgNTRVAiBlNDQUxFOCIFTVVMVDgiDlBPT0xXRUlHSFRNVUxUIhBjb250cmFjdEZpbGVuYW1lIgdTQ0FMRTE4IgZNVUxUMTgiCE1VTFQxOEJJIhVkdXJhdGlvbk1vbnRoc0FsbG93ZWQiC2Jsb2Nrc0luRGF5Ig1ibG9ja3NJbk1vbnRoIgd3cmFwRXJyIgNtc2ciCHRocm93RXJyIg9nZXRTdHJpbmdPckZhaWwiB2FkZHJlc3MiA2tleSIMZ2V0SW50T3JaZXJvIg9nZXRJbnRPckRlZmF1bHQiCmRlZmF1bHRWYWwiDGdldEludE9yRmFpbCIDYWJzIgN2YWwiDmVuc3VyZVBvc2l0aXZlIgF2IgFtIhtrZXlSZWZlcnJhbHNDb250cmFjdEFkZHJlc3MiHnJlZmVycmFsc0NvbnRyYWN0QWRkcmVzc09yRmFpbCIWa2V5UmVmZXJyYWxQcm9ncmFtTmFtZSIacmVmZXJyYWxQcm9ncmFtTmFtZURlZmF1bHQiE3JlZmVycmFsUHJvZ3JhbU5hbWUiEWtleUZhY3RvcnlBZGRyZXNzIhhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHAiGUlkeEZhY3RvcnlDZmdCb29zdGluZ0RhcHAiFElkeEZhY3RvcnlDZmdJZG9EYXBwIhVJZHhGYWN0b3J5Q2ZnVGVhbURhcHAiGUlkeEZhY3RvcnlDZmdFbWlzc2lvbkRhcHAiFUlkeEZhY3RvcnlDZmdSZXN0RGFwcCIZSWR4RmFjdG9yeUNmZ1NsaXBwYWdlRGFwcCIUSWR4RmFjdG9yeUNmZ0Rhb0RhcHAiGklkeEZhY3RvcnlDZmdNYXJrZXRpbmdEYXBwIhpJZHhGYWN0b3J5Q2ZnR3d4UmV3YXJkRGFwcCIWSWR4RmFjdG9yeUNmZ0JpcmRzRGFwcCINa2V5RmFjdG9yeUNmZyIma2V5RmFjdG9yeUxwQXNzZXRUb1Bvb2xDb250cmFjdEFkZHJlc3MiCmxwQXNzZXRTdHIiFGtleUZhY3RvcnlQb29sV2VpZ2h0Ig9jb250cmFjdEFkZHJlc3MiG2tleUZhY3RvcnlQb29sV2VpZ2h0SGlzdG9yeSILcG9vbEFkZHJlc3MiA251bSIYcmVhZEZhY3RvcnlBZGRyZXNzT3JGYWlsIhRyZWFkRmFjdG9yeUNmZ09yRmFpbCIHZmFjdG9yeSIYZ2V0Qm9vc3RpbmdBZGRyZXNzT3JGYWlsIgpmYWN0b3J5Q2ZnIhhnZXRFbWlzc2lvbkFkZHJlc3NPckZhaWwiF2dldFN0YWtpbmdBZGRyZXNzT3JGYWlsIhlnZXRHd3hSZXdhcmRBZGRyZXNzT3JGYWlsIhNrZXlNYW5hZ2VyUHVibGljS2V5IhZrZXlNYW5hZ2VyVmF1bHRBZGRyZXNzIh5rZXlFbWlzc2lvblJhdGVQZXJCbG9ja0N1cnJlbnQiIWtleUVtaXNzaW9uUmF0ZVBlckJsb2NrTWF4Q3VycmVudCIVa2V5RW1pc3Npb25TdGFydEJsb2NrIh1rZXlCb29zdGluZ1YyTGFzdFVwZGF0ZUhlaWdodCIVa2V5Qm9vc3RpbmdWMkludGVncmFsIhtrZXlFbWlzc2lvbkR1cmF0aW9uSW5CbG9ja3MiE2tleUVtaXNzaW9uRW5kQmxvY2siGWtleU5leHRQZXJnZXRJbnRPckRlZmF1bHQiH2tleUd3eFJld2FyZEVtaXNzaW9uU3RhcnRIZWlnaHQiDUlkeENmZ0Fzc2V0SWQiE0lkeENmZ01pbkxvY2tBbW91bnQiFUlkeENmZ01pbkxvY2tEdXJhdGlvbiIVSWR4Q2ZnTWF4TG9ja0R1cmF0aW9uIhJJZHhDZmdNYXRoQ29udHJhY3QiFElkeENmZ0Jsb2Nrc0luUGVyaW9kIglrZXlDb25maWciFXJlYWRDb25maWdBcnJheU9yRmFpbCIIY2ZnQXJyYXkiB2Fzc2V0SWQiDW1pbkxvY2tBbW91bnQiD21pbkxvY2tEdXJhdGlvbiIPbWF4TG9ja0R1cmF0aW9uIgxtYXRoQ29udHJhY3QiDmJsb2Nrc0luUGVyaW9kIg1mb3JtYXRDb25maWdTIgxmb3JtYXRDb25maWciHGdldE1hbmFnZXJWYXVsdEFkZHJlc3NPclRoaXMiByRtYXRjaDAiAXMiFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQiE21hbmFnZXJWYXVsdEFkZHJlc3MiC211c3RNYW5hZ2VyIgFpIgJwZCICcGsiDUlkeExvY2tBbW91bnQiDElkeExvY2tTdGFydCIPSWR4TG9ja0R1cmF0aW9uIhpJZHhMb2NrTGFzdFVwZGF0ZVRpbWVzdGFtcCIQSWR4TG9ja0d3eEFtb3VudCIQSWR4TG9ja1d4Q2xhaW1lZCITa2V5TG9ja1BhcmFtc1JlY29yZCILdXNlckFkZHJlc3MiBHR4SWQiAWIiGnJlYWRMb2NrUGFyYW1zUmVjb3JkT3JGYWlsIhVrZXlVc2VyR3d4QW1vdW50VG90YWwiFmZvcm1hdExvY2tQYXJhbXNSZWNvcmQiBmFtb3VudCIFc3RhcnQiCGR1cmF0aW9uIglnd3hBbW91bnQiCXd4Q2xhaW1lZCIOa2V5TmV4dFVzZXJOdW0iEmtleVVzZXIyTnVtTWFwcGluZyISa2V5TnVtMlVzZXJNYXBwaW5nIhdrZXlMb2NrUGFyYW1Ub3RhbEFtb3VudCIga2V5U3RhdHNMb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MiEmtleVN0YXRzTG9ja3NDb3VudCISa2V5U3RhdHNVc2Vyc0NvdW50IiBrZXlVc2VyQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTCIHdXNlck51bSIia2V5VXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJTlRFR1JBTCIJbHBBc3NldElkIhdrZXlVc2VyTWF4Qm9vc3RJTlRFR1JBTCIYa2V5VG90YWxNYXhCb29zdElOVEVHUkFMIiFrZXlVc2VyQm9vc3RBdmFsYWlibGVUb0NsYWltVG90YWwiE2tleVVzZXJCb29zdENsYWltZWQiC2tleUd3eFRvdGFsIgdrZXlWb3RlIg1hbW91bnRBc3NldElkIgxwcmljZUFzc2V0SWQiBWVwb2NoIhVrZXlTdGFydEhlaWdodEJ5RXBvY2giEWtleUN1cnJlbnRFcG9jaFVpIhVrZXlWb3RpbmdSZXN1bHRTdGFrZWQiDGxwQXNzZXRJZFN0ciIda2V5Vm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWwiJWtleVZvdGluZ1Jlc3VsdFN0YWtlZExhc3RVcGRhdGVIZWlnaHQiIWtleVZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsTGFzdCIVa2V5Vm90ZVN0YWtlZEludGVncmFsIh1rZXlWb3RlU3Rha2VkTGFzdFVwZGF0ZUhlaWdodCIZa2V5Vm90ZVN0YWtlZEludGVncmFsTGFzdCIPa2V5U3Rha2VkQnlVc2VyIg51c2VyQWRkcmVzc1N0ciIPZmFjdG9yeUNvbnRyYWN0IhBlbWlzc2lvbkNvbnRyYWN0Ig9zdGFraW5nQ29udHJhY3QiEWd3eFJld2FyZENvbnRyYWN0IhZscFN0YWtpbmdQb29sc0NvbnRyYWN0IhlrZXlWb3RpbmdFbWlzc2lvbkNvbnRyYWN0IhZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0Ih1rZXlWb3RpbmdFbWlzc2lvblJhdGVDb250cmFjdCIKYm9vc3RDb2VmZiIBQCIZdXNlck51bWJlckJ5QWRkcmVzc09yRmFpbCIRZ2V0R3d4QW1vdW50VG90YWwiEmdldExvY2tlZEd3eEFtb3VudCIMZnVuY3Rpb25OYW1lIhp2b3RpbmdFbWlzc2lvblJhdGVDb250cmFjdCIYbG9ja2VkVm90aW5nRW1pc3Npb25SYXRlIhRsb2NrZWRWb3RpbmdFbWlzc2lvbiIGbG9ja2VkIgxIaXN0b3J5RW50cnkiBHR5cGUiBHVzZXIiCWxvY2tTdGFydCIKaGlzdG9yeUtFWSILaGlzdG9yeURBVEEiClN0YXRzRW50cnkiDnRvdGFsTG9ja2VkSW5jIgtkdXJhdGlvbkluYyIMbG9ja0NvdW50SW5jIg11c2Vyc0NvdW50SW5jIhtsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3NLRVkiDWxvY2tzQ291bnRLRVkiDXVzZXJzQ291bnRLRVkiDnRvdGFsQW1vdW50S0VZIhhsb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MiCmxvY2tzQ291bnQiCnVzZXJzQ291bnQiC3RvdGFsQW1vdW50Ig9Mb2NrUGFyYW1zRW50cnkiImV4dHJhY3RPcHRpb25hbFBheW1lbnRBbW91bnRPckZhaWwiD2V4cGVjdGVkQXNzZXRJZCIDcG10IhVnZXRVc2VyR3d4QW1vdW50VG90YWwiGmdldFZvdGluZ0VtaXNzaW9uRXBvY2hJbmZvIg0kdDAxNTIxNDE1NTA0Ig5jdXJyZW50RXBvY2hVaSISbGFzdEZpbmFsaXplZEVwb2NoIhdjdXJyZW50RXBvY2hTdGFydEhlaWdodCIYZ2V0UG9vbEFzc2V0c0J5THBBc3NldElkIhBpZHhBbW91bnRBc3NldElkIg9pZHhQcmljZUFzc2V0SWQiB3Bvb2xDZmciFGdldFVzZXJWb3RlRmluYWxpemVkIg0kdDAxNjE5NTE2Mjc1Ig0kdDAxNjI3ODE2MzUzIgt1c2VyVm90ZUtleSIIdXNlclZvdGUiEWdldFVzZXJWb3RlU3Rha2VkIgxzdGFrZWRCeVVzZXIiFWdldFZvdGluZ1Jlc3VsdFN0YWtlZCINJHQwMTY4OTcxNjk3NyIXdm90aW5nUmVzdWx0U3Rha2VkU3RhcnQiEnZvdGluZ1Jlc3VsdFN0YWtlZCIdZ2V0Vm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWwiDSR0MDE3MzM5MTc0MTkiHnZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsUHJldiIidm90aW5nUmVzdWx0U3Rha2VkTGFzdFVwZGF0ZUhlaWdodCIcdm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWxEaCIadm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWwiIXJlZnJlc2hWb3RpbmdSZXN1bHRTdGFrZWRJbnRlZ3JhbCIPc3Rha2VkVm90ZURlbHRhIg0kdDAxODI1NjE4MzM2IhV2b3RpbmdSZXN1bHRTdGFrZWROZXciGWdldFVzZXJWb3RlU3Rha2VkSW50ZWdyYWwiDSR0MDE4OTQ3MTkwMjciDnVzZXJWb3RlU3Rha2VkIhp1c2VyVm90ZVN0YWtlZEludGVncmFsUHJldiIedXNlclZvdGVTdGFrZWRMYXN0VXBkYXRlSGVpZ2h0Ihh1c2VyVm90ZVN0YWtlZEludGVncmFsRGgiFnVzZXJWb3RlU3Rha2VkSW50ZWdyYWwiGXJlZnJlc2hWb3RlU3Rha2VkSW50ZWdyYWwiBGVkZ2UiDSR0MDE5ODE1MTk4OTUiEXVzZXJWb3RlRmluYWxpemVkIgdhY3Rpb25zIhN2b3RpbmdSZXN1bHRBY3Rpb25zIgt2b3RlQWN0aW9ucyIbZ2V0U3Rha2VkVm90ZXNJbnRlZ3JhbHNEaWZmIg0kdDAyMDc0OTIwODI5Ih11c2VyVm90ZVN0YWtlZEludGVncmFsTGFzdEtleSIadXNlclZvdGVTdGFrZWRJbnRlZ3JhbExhc3QiIXZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsTGFzdEtleSIedm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWxMYXN0Ihp1c2VyVm90ZVN0YWtlZEludGVncmFsRGlmZiIedm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWxEaWZmIhxyZWZyZXNoQm9vc3RFbWlzc2lvbkludGVncmFsIhJ3eEVtaXNzaW9uUGVyQmxvY2siIGJvb3N0aW5nVjJMYXN0VXBkYXRlSGVpZ2h0T3B0aW9uIhhib29zdGluZ1YySW5nZXJnYWxPcHRpb24iC2VtaXNzaW9uRW5kIgFoIgJkaCIQbGFzdFVwZGF0ZUhlaWdodCIVYm9vc3RFbWlzc2lvblBlckJsb2NrIhlib29zdEVtaXNzaW9uSW50ZWdyYWxQcmV2IhVib29zdEVtaXNzaW9uSW50ZWdyYWwiFGludGVybmFsQ2xhaW1XeEJvb3N0IghyZWFkT25seSIIRU1QVFlTVFIiCnBvb2xXZWlnaHQiDnBvb2xBZGRyZXNzU3RyIiJ1c2VyTHBCb29zdEVtaXNzaW9uTGFzdEludGVncmFsS0VZIiB1c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWSIddXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWwiGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwiDSR0MDI0MzcxMjQ1MTAiG3N0YWtlZFZvdGVzSW50ZWdyYWxzQWN0aW9ucyIUdXNlclZvdGVJbnRlZ3JhbERpZmYiFnRvdGFsVm90ZXNJbnRlZ3JhbERpZmYiHXBvb2xVc2VyQm9vc3RFbWlzc2lvbkludGVncmFsIiF1c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWxOZXciCWRhdGFTdGF0ZSIFZGVidWciC2xvY2tBY3Rpb25zIg5kdXJhdGlvbk1vbnRocyIKYXNzZXRJZFN0ciIJcG10QW1vdW50Ig5uZXh0VXNlck51bUtFWSIOdXNlcklzRXhpc3RpbmciCnVzZXJOdW1TdHIiDmdXeEFtb3VudFN0YXJ0Ig5nd3hBbW91bnRUb3RhbCISdXNlckd3eEFtb3VudFRvdGFsIgxnd3hSZXdhcmRJbnYiA2FyciIRZ2V0V3hXaXRoZHJhd2FibGUiCnR4SWRPcHRpb24iD3VzZXJSZWNvcmRBcnJheSIKdXNlckFtb3VudCIMbG9ja0R1cmF0aW9uIgdsb2NrRW5kIgF0IghleHBvbmVudCIOd3hXaXRoZHJhd2FibGUiEWZhY3RvcnlBZGRyZXNzU3RyIg5sb2NrQXNzZXRJZFN0ciILbWluRHVyYXRpb24iC21heER1cmF0aW9uIgtjaGVja0NhbGxlciIPcmVmZXJyZXJBZGRyZXNzIglzaWduYXR1cmUiDSR0MDI5MzA5MjkzNzQiEWxvY2tBY3Rpb25zUmVzdWx0Ig9yZWZlcnJhbEFkZHJlc3MiBnJlZkludiIRdXBkYXRlUmVmQWN0aXZpdHkiDSR0MDI5ODMyMjk4OTciDSR0MDMwMjA3MzAzMDkiEnVzZXJCb29zdEF2YWlsYWJsZSINJHQwMzA0NDEzMDU0MiIHdHhJZFN0ciIJZ3d4QnVybmVkIgxnd3hSZW1haW5pbmciD2xvY2tlZEd3eEFtb3VudCIVdXNlckd3eEFtb3VudFRvdGFsTmV3Igx0YXJnZXRIZWlnaHQiAnR4IgZ2ZXJpZnkiD3RhcmdldFB1YmxpY0tleZABAAFhAgJfXwABYgAIAAFjAIDC1y8AAWQFAWMAAWUCDWJvb3N0aW5nLnJpZGUAAWYAEgABZwCAgJC7utat8A0AAWgJALYCAQUBZwABaQkAzAgCAAEJAMwIAgADCQDMCAIABgkAzAgCAAwJAMwIAgAYCQDMCAIAMAUDbmlsAAFqAKALAAFrAJjWAgEBbAEBbQkAuQkCCQDMCAIFAWUJAMwIAgICOiAJAMwIAgUBbQUDbmlsAgABAW4BAW0JAAIBCQEBbAEFAW0BAW8CAXABcQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFAXAFAXEJAQFsAQkArAICCQCsAgICD21hbmRhdG9yeSB0aGlzLgUBcQIPIGlzIG5vdCBkZWZpbmVkAQFyAgFwAXEJAQt2YWx1ZU9yRWxzZQIJAJoIAgUBcAUBcQAAAQFzAwFwAXEBdAkBC3ZhbHVlT3JFbHNlAgkAmggCBQFwBQFxBQF0AQF1AgFwAXEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQFwBQFxCQEBbAEJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4FAXECDyBpcyBub3QgZGVmaW5lZAEBdgEBdwMJAGYCAAAFAXcJAQEtAQUBdwUBdwEBeAIBeQF6AwkAZwIFAXkAAAUBeQkBAW4BCQCsAgIJAQt2YWx1ZU9yRWxzZQIFAXoCBXZhbHVlAhMgc2hvdWxkIGJlIHBvc2l0aXZlAQFBAAkAuQkCCQDMCAICBCVzJXMJAMwIAgIGY29uZmlnCQDMCAICGHJlZmVycmFsc0NvbnRyYWN0QWRkcmVzcwUDbmlsBQFhAAFCCQERQGV4dHJOYXRpdmUoMTA2MikBCQEBbwIFBHRoaXMJAQFBAAABQwkAuQkCCQDMCAICBCVzJXMJAMwIAgIIcmVmZXJyYWwJAMwIAgILcHJvZ3JhbU5hbWUFA25pbAUBYQABRAIGd3hsb2NrAAFFCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAUMFAUQBAUYAAhwlcyVzX19jb25maWdfX2ZhY3RvcnlBZGRyZXNzAAFHAAEAAUgAAgABSQADAAFKAAQAAUsABQABTAAGAAFNAAcAAU4ACAABTwAJAAFQAAoAAVEACwEBUgACESVzX19mYWN0b3J5Q29uZmlnAQFTAQFUCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFAVQJAMwIAgIebWFwcGluZ3NfX2xwQXNzZXQyUG9vbENvbnRyYWN0BQNuaWwFAWEBAVUBAVYJALkJAgkAzAgCAgQlcyVzCQDMCAICCnBvb2xXZWlnaHQJAMwIAgUBVgUDbmlsBQFhAQFXAgFYAVkJAKwCAgkArAICCQCsAgICEiVzJXNfX3Bvb2xXZWlnaHRfXwUBWAICX18JAKQDAQUBWQEBWgAJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQFvAgUEdGhpcwkBAUYAAQJhYQECYWIJALUJAgkBAW8CBQJhYgkBAVIABQFhAQJhYwECYWQJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYWQFAUgBAmFlAQJhZAkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQJhZAUBSwECYWYBAmFkCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFAmFkBQFHAQJhZwECYWQJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYWQFAVABAmFoAAIUJXNfX21hbmFnZXJQdWJsaWNLZXkBAmFpAAIXJXNfX21hbmFnZXJWYXVsdEFkZHJlc3MBAmFqAAIbJXMlc19fcmF0ZVBlckJsb2NrX19jdXJyZW50AQJhawACHiVzJXNfX3JhdGVQZXJCbG9ja01heF9fY3VycmVudAECYWwAAholcyVzX19lbWlzc2lvbl9fc3RhcnRCbG9jawECYW0AAhwlcyVzX19ib29zdGluZ1YyX19zdGFydEJsb2NrAQJhbgACGiVzJXNfX2Jvb3N0aW5nVjJfX2ludGVncmFsAQJhbwACGCVzJXNfX2VtaXNzaW9uX19kdXJhdGlvbgECYXAAAhglcyVzX19lbWlzc2lvbl9fZW5kQmxvY2sBAmFxAAIOJXNfX25leHRQZXJpb2QBAmFyAAIoJXMlc19fZ3d4UmV3YXJkRW1pc3Npb25QYXJ0X19zdGFydEhlaWdodAACYXMAAQACYXQAAgACYXUAAwACYXYABAACYXcABQACYXgABgECYXkAAgolc19fY29uZmlnAQJhegAJALUJAgkBAW8CBQR0aGlzCQECYXkABQFhAAJhQQkBAmF6AAACYUIJANkEAQkAkQMCBQJhQQUCYXMAAmFDCQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQkAkQMCBQJhQQUCYXQJAQFsAQIXaW52YWxpZCBtaW4gbG9jayBhbW91bnQAAmFECQETdmFsdWVPckVycm9yTWVzc2FnZQIJALYJAQkAkQMCBQJhQQUCYXUJAQFsAQIZaW52YWxpZCBtaW4gbG9jayBkdXJhdGlvbgACYUUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAtgkBCQCRAwIFAmFBBQJhdgkBAWwBAhlpbnZhbGlkIG1heCBsb2NrIGR1cmF0aW9uAAJhRgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUCYUEFAmF3CQEBbAECHWludmFsaWQgbWF0aCBjb250cmFjdCBhZGRyZXNzAAJhRwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQC2CQEJAJEDAgUCYUEFAmF4CQEBbAECGGludmFsaWQgYmxvY2tzIGluIHBlcmlvZAECYUgFAmFCAmFDAmFEAmFF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RAUDbmlsBQFhAQJiRgAJALkJAgkAzAgCAgIlcwkAzAgCAg5jdXJyZW50RXBvY2hVaQUDbmlsBQFhAQJiRwICYkgCYkQJALkJAgkAzAgCAgYlcyVzJWQJAMwIAgISdm90aW5nUmVzdWx0U3Rha2VkCQDMCAIFAmJICQDMCAIJAKQDAQUCYkQFA25pbAUBYQECYkkCAmJIAmJECQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICGnZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsCQDMCAIFAmJICQDMCAIJAKQDAQUCYkQFA25pbAUBYQECYkoCAmJIAmJECQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICKnZvdGluZ1Jlc3VsdFN0YWtlZEludGVncmFsTGFzdFVwZGF0ZUhlaWdodAkAzAgCBQJiSAkAzAgCCQCkAwEFAmJEBQNuaWwFAWEBAmJLAwJiSAFwAmJECQC5CQIJAMwIAgIIJXMlcyVzJWQJAMwIAgIedm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWxMYXN0CQDMCAIFAmJICQDMCAIJAKUIAQUBcAkAzAgCCQCkAwEFAmJEBQNuaWwFAWEBAmJMAwJiSAFwAmJECQC5CQIJAMwIAgIIJXMlcyVzJWQJAMwIAgISdm90ZVN0YWtlZEludGVncmFsCQDMCAIFAmJICQDMCAIJAKUIAQUBcAkAzAgCCQCkAwEFAmJEBQNuaWwFAWEBAmJNAwJiSAFwAmJECQC5CQIJAMwIAgIIJXMlcyVzJWQJAMwIAgIidm90ZVN0YWtlZEludGVncmFsTGFzdFVwZGF0ZUhlaWdodAkAzAgCBQJiSAkAzAgCCQClCAEFAXAJAMwIAgkApAMBBQJiRAUDbmlsBQFhAQJiTgMCYkgBcAJiRAkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICFnZvdGVTdGFrZWRJbnRlZ3JhbExhc3QJAMwIAgUCYkgJAMwIAgkApQgBBQFwCQDMCAIJAKQDAQUCYkQFA25pbAUBYQECYk8CAmJQAmJICQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICBnN0YWtlZAkAzAgCBQJiUAkAzAgCBQJiSAUDbmlsBQFhAAJiUQkBAVoAAAJhZAkBAmFhAQUCYlEAAmJSCQECYWUBBQJhZAACYlMJAQJhZgEFAmFkAAJiVAkBAmFnAQUCYWQAAmJVCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCiCAEJALkJAgkAzAgCAgIlcwkAzAgCAhZscFN0YWtpbmdQb29sc0NvbnRyYWN0BQNuaWwFAWEJAQFsAQIubHBfc3Rha2luZ19wb29scyBjb250cmFjdCBhZGRyZXNzIGlzIHVuZGVmaW5lZAkBAWwBAilpbnZhbGlkIGxwX3N0YWtpbmdfcG9vbHMgY29udHJhY3QgYWRkcmVzcwACYlYJALkJAgkAzAgCAgIlcwkAzAgCAhZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0BQNuaWwFAWEAAmJXCQERQGV4dHJOYXRpdmUoMTA2MikBCQERQGV4dHJOYXRpdmUoMTA1MykCBQJiUQUCYlYAAmJYCQC5CQIJAMwIAgICJXMJAMwIAgIadm90aW5nRW1pc3Npb25SYXRlQ29udHJhY3QFA25pbAUBYQACYlkKAAJiWgkA/AcEBQJiUgIVZ2V0Qm9vc3RDb2VmZlJFQURPTkxZBQNuaWwFA25pbAMJAAECBQJiWgIDSW50BQJiWgkAAgEJAKwCAgkAAwEFAmJaAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQBAmNhAQJhWgQCYUsJAJ0IAgUEdGhpcwkBAmJsAQkApQgBBQJhWgMJAAECBQJhSwIGU3RyaW5nBAJhTAUCYUsJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAtgkBBQJhTAkBAWwBAhNpbnZhbGlkIHVzZXIgbnVtYmVyAwkAAQIFAmFLAgRVbml0CQEBbgECDGludmFsaWQgdXNlcgkAAgECC01hdGNoIGVycm9yAQJjYgAJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmJ6AAAAAQJjYwECYVoEAmNkAhJnZXRMb2NrZWRHd3hBbW91bnQEAmNlCQETdmFsdWVPckVycm9yTWVzc2FnZQIEAmFLCQCdCAIFAmJXBQJiWAMJAAECBQJhSwIEVW5pdAUEdW5pdAMJAAECBQJhSwIGU3RyaW5nBAJhTAUCYUsJAKYIAQUCYUwJAAIBAgtNYXRjaCBlcnJvcgkBAWwBAiRpbnZhbGlkIHZvdGluZyBlbWlzc2lvbiByYXRlIGFkZHJlc3MEAmNmCgACYloJAPwHBAUCYlcFAmNkCQDMCAIJAKUIAQUCYVoFA25pbAUDbmlsAwkAAQIFAmJaAgNJbnQFAmJaCQACAQkArAICCQADAQUCYloCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAQCY2cKAAJiWgkA/AcEBQJjZQUCY2QJAMwIAgkApQgBBQJhWgUDbmlsBQNuaWwDCQABAgUCYloCA0ludAUCYloJAAIBCQCsAgIJAAMBBQJiWgIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50BAJjaAkAlgMBCQDMCAIFAmNmCQDMCAIFAmNnBQNuaWwFAmNoAQJjaQcCY2oCY2sCYmYCY2wCYmgCYmkCYVAEAmNtCQC5CQIJAMwIAgIRJXMlcyVzJXNfX2hpc3RvcnkJAMwIAgUCY2oJAMwIAgUCY2sJAMwIAgkA2AQBCAUCYVANdHJhbnNhY3Rpb25JZAUDbmlsBQFhBAJjbgkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQgFCWxhc3RCbG9jawZoZWlnaHQJAMwIAgkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQCkAwEFAmJmCQDMCAIJAKQDAQUCY2wJAMwIAgkApAMBBQJiaAkAzAgCCQCkAwEFAmJpBQNuaWwFAWEJAQtTdHJpbmdFbnRyeQIFAmNtBQJjbgECY28EAmNwAmNxAmNyAmNzBAJjdAkBAmJvAAQCY3UJAQJicAAEAmN2CQECYnEABAJjdwkBAmJuAAQCY3gJAQFyAgUEdGhpcwUCY3QEAmN5CQEBcgIFBHRoaXMFAmN1BAJjegkBAXICBQR0aGlzBQJjdgQCY0EJAQFyAgUEdGhpcwUCY3cJAMwIAgkBDEludGVnZXJFbnRyeQIFAmN0CQBkAgUCY3gFAmNxCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJjdQkAZAIFAmN5BQJjcgkAzAgCCQEMSW50ZWdlckVudHJ5AgUCY3YJAGQCBQJjegUCY3MJAMwIAgkBDEludGVnZXJFbnRyeQIFAmN3CQBkAgUCY0EFAmNwBQNuaWwBAmNCBwJhWgJiYQJiZgJiZwJiaAJiaQJiagkAzAgCCQELU3RyaW5nRW50cnkCCQECYVkCBQJhWgUCYmEJAQJiZQUFAmJmBQJiZwUCYmgFAmJpBQJiagUDbmlsAQJjQwICYVACY0QDCQBmAgkAkAMBCAUCYVAIcGF5bWVudHMAAQkBAW4BAhtvbmx5IG9uZSBwYXltZW50IGlzIGFsbG93ZWQDCQAAAgkAkAMBCAUCYVAIcGF5bWVudHMAAAAABAJjRQkAkQMCCAUCYVAIcGF5bWVudHMAAAMJAQIhPQIJAQV2YWx1ZQEIBQJjRQdhc3NldElkBQJjRAkBAW4BAhtpbnZhbGlkIGFzc2V0IGlkIGluIHBheW1lbnQIBQJjRQZhbW91bnQBAmNGAQJhWgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYmQBBQJhWgAAAQJjRwAEAmNIBAJjSQkBBXZhbHVlAQkAmggCBQJiVwkBAmJGAAQCY0oJAGUCBQJjSQABAwkAZgIAAAUCY0oJAQFuAQINaW52YWxpZCBlcG9jaAkAlAoCBQJjSQUCY0oEAmNJCAUCY0gCXzEEAmNKCAUCY0gCXzIEAmNLCQEFdmFsdWUBCQCaCAIFAmJXCQECYkUBBQJjSQkAlAoCBQJjSgUCY0sBAmNMAQJiSAQCY00ABAQCY04ABQQCY08KAAJiWgkA/AcEBQJiUQIgZ2V0UG9vbENvbmZpZ0J5THBBc3NldElkUkVBRE9OTFkJAMwIAgUCYkgFA25pbAUDbmlsAwkAAQIFAmJaAglMaXN0W0FueV0FAmJaCQACAQkArAICCQADAQUCYloCHiBjb3VsZG4ndCBiZSBjYXN0IHRvIExpc3RbQW55XQQCYkIKAAJiWgkAkQMCBQJjTwUCY00DCQABAgUCYloCBlN0cmluZwUCYloJAAIBCQCsAgIJAAMBBQJiWgIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nBAJiQwoAAmJaCQCRAwIFAmNPBQJjTgMJAAECBQJiWgIGU3RyaW5nBQJiWgkAAgEJAKwCAgkAAwEFAmJaAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcJAJQKAgUCYkIFAmJDAQJjUAICYkgCYlAEAmFaCQERQGV4dHJOYXRpdmUoMTA2MikBBQJiUAQCY1EJAQJjRwAEAmNKCAUCY1ECXzEEAmNLCAUCY1ECXzIEAmNSCQECY0wBBQJiSAQCYkIIBQJjUgJfMQQCYkMIBQJjUgJfMgQCY1MJAQJiQQQFAmJCBQJiQwUCYVoFAmNKBAJjVAkBC3ZhbHVlT3JFbHNlAgkAmggCBQJiVwUCY1MAAAUCY1QBAmNVAgJiSAJiUAQCY1YJAQt2YWx1ZU9yRWxzZQIJAJoIAgUCYlMJAQJiTwIFAmJQBQJiSAAABAJjVAkBAmNQAgUCYkgFAmJQAwkAAAIFAmNWAAAAAAUCY1QBAmNXAQJiSAQCY1gJAQJjRwAEAmNKCAUCY1gCXzEEAmNLCAUCY1gCXzIEAmNZCQELdmFsdWVPckVsc2UCCQCaCAIFAmJXCQECYkcCBQJiSAUCY0oAAAQCY1oJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmJHAgUCYkgFAmNKBQJjWQUCY1oBAmRhAQJiSAQCZGIJAQJjRwAEAmNKCAUCZGICXzEEAmNLCAUCZGICXzIEAmNaCQECY1cBBQJiSAQCZGMJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmJJAgUCYkgFAmNKAAAEAmRkCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQJiSgIFAmJIBQJjSgUCY0sEAmRlCQBlAgUGaGVpZ2h0BQJkZAQCZGYJAGQCCQBoAgUCZGUFAmNaBQJkYwUCZGYBAmRnAgJiSAJkaAQCZGkJAQJjRwAEAmNKCAUCZGkCXzEEAmNLCAUCZGkCXzIEAmNaCQECY1cBBQJiSAQCZGoJAGQCBQJjWgUCZGgEAmRmCQECZGEBBQJiSAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmJHAgUCYkgFAmNKBQJkagkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmJKAgUCYkgFAmNKBQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJiSQIFAmJIBQJjSgUCZGYFA25pbAECZGsCAmJIAmJQBAJkbAkBAmNHAAQCY0oIBQJkbAJfMQQCY0sIBQJkbAJfMgQCYVoJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmJQBAJkbQkBAmNVAgUCYkgFAmJQBAJkbgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYkwDBQJiSAUCYVoFAmNKAAAEAmRvCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQJiTQMFAmJIBQJhWgUCY0oFAmNLBAJkcAkAZQIFBmhlaWdodAUCZG8EAmRxCQBkAgkAaAIFAmRwBQJkbQUCZG4FAmRxAQJkcgMCYkgCYlACZHMEAmR0CQECY0cABAJjSggFAmR0Al8xBAJjSwgFAmR0Al8yBAJhWgkBEUBleHRyTmF0aXZlKDEwNjIpAQUCYlAEAmR1CQECY1ACBQJiSAUCYlAEAmR2AwkAAAIFAmR1AAAFA25pbAQCZGgDBQJkcwUCZHUJAQEtAQUCZHUEAmR3CQECZGcCBQJiSAUCZGgEAmRxCQECZGsCBQJiSAUCYlAEAmR4CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYk0DBQJiSAUCYVoFAmNKBQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJiTAMFAmJIBQJhWgUCY0oFAmRxBQNuaWwJAM4IAgUCZHcFAmR4BQJkdgECZHkCAmJIAmJQBAJkegkBAmNHAAQCY0oIBQJkegJfMQQCY0sIBQJkegJfMgQCYVoJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmJQBAJkQQkBAmJOAwUCYkgFAmFaBQJjSgQCZEIJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUCZEEAAAQCZEMJAQJiSwMFAmJIBQJhWgUCY0oEAmRECQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAmRDAAAEAmRxCQECZGsCBQJiSAUCYlAEAmRmCQECZGEBBQJiSAQCZEUJAGUCBQJkcQUCZEIEAmRGCQBlAgUCZGYFAmRECQCVCgMJAMwIAgkBDEludGVnZXJFbnRyeQIFAmRBBQJkcQkAzAgCCQEMSW50ZWdlckVudHJ5AgUCZEMFAmRmBQNuaWwFAmRFBQJkRgECZEcABAJkSAkBAXUCBQJiUgkBAmFqAAQCZEkJAJoIAgUEdGhpcwkBAmFtAAQCZEoJAJoIAgUEdGhpcwkBAmFuAAQCZEsJAQF1AgUCYlIJAQJhcAAEAmRMAwkAZgIFBmhlaWdodAUCZEsFAmRLBQZoZWlnaHQEAmRNBAJhSwUCZEkDCQABAgUCYUsCA0ludAQCZE4FAmFLCQCWAwEJAMwIAgkAZQIFAmRMBQJkTgkAzAgCAAAFA25pbAMJAAECBQJhSwIEVW5pdAAACQACAQILTWF0Y2ggZXJyb3IEAmRPCQBpAgkAaAIFAmRICQBlAgUCYlkAAQUCYlkEAmRQCQELdmFsdWVPckVsc2UCBQJkSgAABAJkUQkAZAIJAGgCBQJkTwUCZE0FAmRQCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhbgAFAmRRCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYW0ABQZoZWlnaHQFA25pbAUCZFEBAmRSAwJiSAJiUAJkUwQCYVoJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQJiUAkBAWwBAhRpbnZhbGlkIHVzZXIgYWRkcmVzcwQCYnMJAQJjYQEFAmFaAwkAAAIFAmJzBQJicwQCZFQCBWVtcHR5BAJkVQMJAQIhPQIFAmJIBQJkVAQCZFYJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQJiUQkBAVMBBQJiSAkBAWwBCQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUCYkgJARFAZXh0ck5hdGl2ZSgxMDUwKQIFAmJRCQEBVQEFAmRWAwUCZFMAAAkBAW4BCQCsAgICKG5vdCByZWFkb25seSBtb2RlOiB1bnN1cHBvcnRlZCBscCBhc3NldCAFAmJIBAJkVwkBAmJ0AgUCYnMFAmJIBAJkWAkBAmJyAQUCYnMEAmRZCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAmRXCQEBcgIFBHRoaXMFAmRYBAJkUQgJAQJkRwACXzIEAmRaCQBlAgUCZFEFAmRZAwkAZgIAAAUCZFoJAQFuAQISd3JvbmcgY2FsY3VsYXRpb25zBAJlYQkBAmR5AgUCYkgFAmJQBAJlYggFAmVhAl8xBAJlYwgFAmVhAl8yBAJlZAgFAmVhAl8zBAJlZQkAawMFAmRaBQJkVQUBZAQCZWYDCQAAAgUCZWQAAAAACQBrAwUCZWUFAmVjBQJlZAQCZWcJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUCZFcFAmRRBQNuaWwFAmViBAJlaAkAuQkCCQDMCAIJAKQDAQUCZFkJAMwIAgkApAMBBQJkWgkAzAgCCQCkAwEFAmRVCQDMCAIJAKQDAQUCZWMJAMwIAgkApAMBBQJlZAUDbmlsAgE6CQCVCgMFAmVmBQJlZwUCZWgJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmVpAgJhUAJlagMJAQEhAQkBD2NvbnRhaW5zRWxlbWVudAIFAWkFAmVqCQEBbgECEGludmFsaWQgZHVyYXRpb24EAmJoCQBoAgUCZWoFAWsEAmVrCQDYBAEFAmFCAwkBAiE9AgkAkAMBCAUCYVAIcGF5bWVudHMAAQkBAW4BAjRpbnZhbGlkIHBheW1lbnQgLSBleGFjdCBvbmUgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBAJjRQkAkQMCCAUCYVAIcGF5bWVudHMAAAQCZWwIBQJjRQZhbW91bnQDCQECIT0CBQJhQgkBBXZhbHVlAQgFAmNFB2Fzc2V0SWQJAQFuAQkArAICCQCsAgICHmludmFsaWQgYXNzZXQgaXMgaW4gcGF5bWVudCAtIAUCZWsCDCBpcyBleHBlY3RlZAQCZW0JAQJiawAEAmFaCAUCYVAGY2FsbGVyBAJiUAkApQgBBQJhWgQCZW4JAQlpc0RlZmluZWQBCQCiCAEJAQJibAEFAmJQBAJlbwMFAmVuCQEFdmFsdWUBCQCiCAEJAQJibAEFAmJQCQCkAwEJAQF1AgUEdGhpcwUCZW0EAmJzCQENcGFyc2VJbnRWYWx1ZQEFAmVvBAJjbAUGaGVpZ2h0AwMJAGYCBQJhQwUCZWwJAQIhPQIFAmFaBQJiVQcJAQFuAQkArAICAiJhbW91bnQgaXMgbGVzcyB0aGVuIG1pbkxvY2tBbW91bnQ9CQCkAwEFAmFDAwkAZgIFAmFEBQJiaAkBAW4BCQCsAgICLXBhc3NlZCBkdXJhdGlvbiBpcyBsZXNzIHRoZW4gbWluTG9ja0R1cmF0aW9uPQkApAMBBQJhRAMJAGYCBQJiaAUCYUUJAQFuAQkArAICAjBwYXNzZWQgZHVyYXRpb24gaXMgZ3JlYXRlciB0aGVuIG1heExvY2tEdXJhdGlvbj0JAKQDAQUCYUUEAmVwCQBrAwUCZWwFAmJoBQJhRQQCZXEJAQJjYgAEAmRYCQECYnIBBQJicwQCZFEICQECZEcAAl8yBAJlcgkBAmNGAQUCYVoEAmVzCQD9BwQFAmJUAhFyZWZyZXNoVXNlclJld2FyZAkAzAgCCAUCYVoFYnl0ZXMFA25pbAUDbmlsAwkAAAIFAmVzBQJlcwQCZXQDBQJlbgUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJlbQkAZAIFAmJzAAEJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmJsAQUCYlAFAmVvCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJibQEFAmVvBQJiUAUDbmlsCQCUCgIJAM4IAgkAzQgCCQDOCAIJAM4IAgUCZXQJAQJjQgcFAmFaCAUCYVANdHJhbnNhY3Rpb25JZAUCZWwFAmNsBQJiaAUCZXAAAAkBAmNvBAUCZWwFAmJoAAEDBQJlbgAAAAEJAQJjaQcCBGxvY2sFAmJQBQJlbAUCY2wFAmJoBQJlcAUCYVAJAMwIAgkBDEludGVnZXJFbnRyeQIFAmRYBQJkUQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmJ6AAkAZAIFAmVxBQJlcAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmJkAQUCYVoJAGQCBQJlcgUCZXAFA25pbAUCZXAJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmV1AgJhWgJldgQCZXcJAQJiYwIFAmFaBQJldgQCZXgJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJldwUCYVMEAmNsCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZXcFAmFUBAJleQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmV3BQJhVQQCZXoJAGQCBQJjbAUCZXkEAmJqCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZXcFAmFYBAJlQQkAaQIJAGUCBQZoZWlnaHQFAmNsBQJhRwQCZUIJALwCAwkAtgIBBQJlQQkAuQICCQC2AgEJAGgCAAgFAmFHBQFoCQC2AgEFAmV5BAJlQwMJAGYCBQZoZWlnaHQFAmV6BQJleAkAZQIJAKADAQkAvAIDCQC2AgEFAmV4CQC4AgIFAWgJAHYGCQC2AgEABQABBQJlQgUBZgUBZgUERE9XTgUBaAUCYmoFAmVDEQJhUAELY29uc3RydWN0b3IGAmVEAmVFAmFDAmVGAmVHAmFGBAJlSAkBAmFPAQUCYVADCQAAAgUCZUgFAmVICQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJiawAAAAkAzAgCCQELU3RyaW5nRW50cnkCCQECYXkACQECYUkFBQJlRQUCYUMFAmVGBQJlRwUCYUYJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAUYABQJlRAUDbmlsCQECY28EAAAAAAAAAAAJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYVABB2xvY2tSZWYDAmJoAmVJAmVKBAJlSwkBAmVpAgUCYVAFAmJoBAJlTAgFAmVLAl8xBAJlcAgFAmVLAl8yBAJlTQkApQgBCAUCYVAGY2FsbGVyBAJlTgMDCQAAAgUCZUkCAAYJAAACBQJlSgEABQR1bml0CQD8BwQFAUICCmNyZWF0ZVBhaXIJAMwIAgUBRQkAzAgCBQJlSQkAzAgCBQJlTQkAzAgCBQJlSgUDbmlsBQNuaWwDCQAAAgUCZU4FAmVOBAJlTwkA/AcEBQJhRgIWdXBkYXRlUmVmZXJyYWxBY3Rpdml0eQkAzAgCCQClCAEIBQJhUAZjYWxsZXIJAMwIAgUCZXAFA25pbAUDbmlsAwkAAAIFAmVPBQJlTwkAlAoCBQJlTAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhUAEEbG9jawECYmgEAmVQCQECZWkCBQJhUAUCYmgEAmVMCAUCZVACXzEEAmVwCAUCZVACXzIEAmVPCQD8BwQFAmFGAhZ1cGRhdGVSZWZlcnJhbEFjdGl2aXR5CQDMCAIJAKUIAQgFAmFQBmNhbGxlcgkAzAgCBQJlcAUDbmlsBQNuaWwDCQAAAgUCZU8FAmVPCQCUCgIFAmVMBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFQAQxjbGFpbVd4Qm9vc3QCAmJIAmJQAwkBAiE9AgUCYlMIBQJhUAZjYWxsZXIJAQFuAQIScGVybWlzc2lvbnMgZGVuaWVkBAJlUQkBAmRSAwUCYkgFAmJQBwQCZVIIBQJlUQJfMQQCZWcIBQJlUQJfMgQCZWgIBQJlUQJfMwkAlAoCBQJlZwkAzAgCBQJlUgUDbmlsAmFQARRjbGFpbVd4Qm9vc3RSRUFET05MWQICYkgCYlAEAmVTCQECZFIDBQJiSAUCYlAGBAJlUggFAmVTAl8xBAJlZwgFAmVTAl8yBAJlaAgFAmVTAl8zCQCUCgIFA25pbAkAzAgCBQJlUgkAzAgCBQJlaAUDbmlsAmFQAQZ1bmxvY2sBAmVUBAJhWggFAmFQBmNhbGxlcgQCYlAJAKUIAQUCYVoEAmJhCQDZBAEFAmVUBAJldwkBAmJjAgUCYVoDCQAAAgUCZVQCAAUEdW5pdAUCYmEEAmV4CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZXcFAmFTBAJjbAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmV3BQJhVAQCZXkJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJldwUCYVUEAmJqCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZXcFAmFYBAJiaQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmV3BQJhVwQCZUEJAGkCCQBlAgUGaGVpZ2h0BQJjbAUCYUcEAmVDCQECZXUCBQJhWgMJAAACBQJlVAIABQR1bml0BQJiYQQCZXAJAGsDBQJleAUCZXkFAmFFBAJlVQkAlwMBCQDMCAIJAGsDCQBoAgUCZUEFAmFHBQJlcAUCYUUJAMwIAgUCYmkFA25pbAQCZVYJAQF4AgkAZQIFAmJpBQJlVQIMZ3d4UmVtYWluaW5nBAJlVwkBAmNjAQUCYVoDCQBnAgAABQJleAkBAW4BAhFub3RoaW5nIHRvIHVubG9jawQCZXEJAQJjYgAEAmVyCQECY0YBBQJhWgQCZVgJAQF4AgkAZQIFAmVyBQJlVQIVdXNlckd3eEFtb3VudFRvdGFsTmV3AwkAZgIFAmVXBQJlWAkBAW4BCQCsAgICE2xvY2tlZCBnd3ggYW1vdW50OiAJAKQDAQUCZVcEAmVzCQD9BwQFAmJUAhFyZWZyZXNoVXNlclJld2FyZAkAzAgCCAUCYVoFYnl0ZXMFA25pbAUDbmlsAwkAAAIFAmVzBQJlcwkAzggCCQDNCAIJAM0IAgkAzggCCQECY0IHBQJhWgUCYmEFAmV4BQJjbAUCZXkFAmVWCQBkAgUCYmoFAmVDCQECY28ECQEBLQEFAmVDAAAAAAAACQECY2kHAgZ1bmxvY2sFAmJQBQJlQwUCY2wFAmV5BQJlVQUCYVAJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFaBQJlQwUCYUIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJiegAJAQF4AgkAZQIFAmVxBQJlVQIIZ3d4VG90YWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJiZAEFAmFaBQJlWAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFQARNnd3hVc2VySW5mb1JFQURPTkxZAQJiUAQCYVoJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQJiUAkBAWwBAhRpbnZhbGlkIHVzZXIgYWRkcmVzcwQCYmkJAQJjRgEFAmFaCQCUCgIFA25pbAkAzAgCBQJiaQUDbmlsAmFQARd1c2VyTWF4RHVyYXRpb25SRUFET05MWQECYlAJAJQKAgUDbmlsCQCUCgICDGluY3JlYXNlTG9jawUCYUUCYVABIGdldFVzZXJHd3hBbW91bnRBdEhlaWdodFJFQURPTkxZAgJiUAJlWQQCYVoJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQJiUAkBAWwBAhRpbnZhbGlkIHVzZXIgYWRkcmVzcwQCYmkJAQJjRgEFAmFaCQCUCgIFA25pbAUCYmkCYVABEGdldFVzZXJHd3hBbW91bnQBAmJQBAJhWgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEFAmJQCQEBbAECFGludmFsaWQgdXNlciBhZGRyZXNzBAJiaQkBAmNGAQUCYVoJAJQKAgUDbmlsBQJiaQJhUAETZ2V0R3d4VG90YWxSRUFET05MWQAJAJQKAgUDbmlsCQECY2IAAmFQARVvbkJvb3N0RW1pc3Npb25VcGRhdGUABAJlSAMJAAACCAUCYVAGY2FsbGVyBQJiUgYJAQJhTwEFAmFQAwkAAAIFAmVIBQJlSAkBAmRHAAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhUAESb25TdGFrZWRWb3RlVXBkYXRlAwJiSAJiUAJkcwQCZUgDCQAAAggFAmFQBmNhbGxlcgUCYlMGCQECYU8BBQJhUAMJAAACBQJlSAUCZUgEAmR2CQECZHIDBQJiSAUCYlAFAmRzCQCUCgIFAmR2BQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFQAR1nZXRWb3RpbmdSZXN1bHRTdGFrZWRSRUFET05MWQECYkgJAJQKAgUDbmlsCQECY1cBBQJiSAJhUAElZ2V0Vm90aW5nUmVzdWx0U3Rha2VkSW50ZWdyYWxSRUFET05MWQECYkgJAJQKAgUDbmlsCQECZGEBBQJiSAJhUAEcZ2V0VXNlclZvdGVGaW5hbGl6ZWRSRUFET05MWQICYkgCYlAJAJQKAgUDbmlsCQECY1ACBQJiSAUCYlACYVABIWdldFVzZXJWb3RlU3Rha2VkSW50ZWdyYWxSRUFET05MWQICYkgCYlAJAJQKAgUDbmlsCQECZGsCBQJiSAUCYlABAmVaAQJmYQAEAmZiBAJhSwkBAmFNAAMJAAECBQJhSwIKQnl0ZVZlY3RvcgQCYVIFAmFLBQJhUgMJAAECBQJhSwIEVW5pdAgFAmVaD3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yCQD0AwMIBQJlWglib2R5Qnl0ZXMJAJEDAggFAmVaBnByb29mcwAABQJmYvMpV50=", "height": 2706081, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 5mLpGSjrJ9FY9CnVPpc53f3Rku6vtNeMtpswhY5LcNi6 Next: HNuyo542xzNyJZ8fWbNgw4Y9zsDqt61JkAmxSk7M3QJc Diff:
OldNewDifferences
1616 let MULT18 = 1000000000000000000
1717
1818 let MULT18BI = toBigInt(MULT18)
19+
20+let durationMonthsAllowed = [1, 3, 6, 12, 24, 48]
1921
2022 let blocksInDay = 1440
2123
434436
435437
436438 func getVotingEmissionEpochInfo () = {
437- let $t01516415454 = {
439+ let $t01521415504 = {
438440 let currentEpochUi = value(getInteger(votingEmissionContract, keyCurrentEpochUi()))
439441 let lastFinalizedEpoch = (currentEpochUi - 1)
440442 if ((0 > lastFinalizedEpoch))
441443 then throwErr("invalid epoch")
442444 else $Tuple2(currentEpochUi, lastFinalizedEpoch)
443445 }
444- let currentEpochUi = $t01516415454._1
445- let lastFinalizedEpoch = $t01516415454._2
446+ let currentEpochUi = $t01521415504._1
447+ let lastFinalizedEpoch = $t01521415504._2
446448 let currentEpochStartHeight = value(getInteger(votingEmissionContract, keyStartHeightByEpoch(currentEpochUi)))
447449 $Tuple2(lastFinalizedEpoch, currentEpochStartHeight)
448450 }
475477
476478 func getUserVoteFinalized (lpAssetIdStr,userAddressStr) = {
477479 let userAddress = addressFromStringValue(userAddressStr)
478- let $t01614516225 = getVotingEmissionEpochInfo()
479- let lastFinalizedEpoch = $t01614516225._1
480- let currentEpochStartHeight = $t01614516225._2
481- let $t01622816303 = getPoolAssetsByLpAssetId(lpAssetIdStr)
482- let amountAssetId = $t01622816303._1
483- let priceAssetId = $t01622816303._2
480+ let $t01619516275 = getVotingEmissionEpochInfo()
481+ let lastFinalizedEpoch = $t01619516275._1
482+ let currentEpochStartHeight = $t01619516275._2
483+ let $t01627816353 = getPoolAssetsByLpAssetId(lpAssetIdStr)
484+ let amountAssetId = $t01627816353._1
485+ let priceAssetId = $t01627816353._2
484486 let userVoteKey = keyVote(amountAssetId, priceAssetId, userAddress, lastFinalizedEpoch)
485487 let userVote = valueOrElse(getInteger(votingEmissionContract, userVoteKey), 0)
486488 userVote
497499
498500
499501 func getVotingResultStaked (lpAssetIdStr) = {
500- let $t01684716927 = getVotingEmissionEpochInfo()
501- let lastFinalizedEpoch = $t01684716927._1
502- let currentEpochStartHeight = $t01684716927._2
502+ let $t01689716977 = getVotingEmissionEpochInfo()
503+ let lastFinalizedEpoch = $t01689716977._1
504+ let currentEpochStartHeight = $t01689716977._2
503505 let votingResultStakedStart = valueOrElse(getInteger(votingEmissionContract, keyVotingResultStaked(lpAssetIdStr, lastFinalizedEpoch)), 0)
504506 let votingResultStaked = valueOrElse(getInteger(this, keyVotingResultStaked(lpAssetIdStr, lastFinalizedEpoch)), votingResultStakedStart)
505507 votingResultStaked
507509
508510
509511 func getVotingResultStakedIntegral (lpAssetIdStr) = {
510- let $t01728917369 = getVotingEmissionEpochInfo()
511- let lastFinalizedEpoch = $t01728917369._1
512- let currentEpochStartHeight = $t01728917369._2
512+ let $t01733917419 = getVotingEmissionEpochInfo()
513+ let lastFinalizedEpoch = $t01733917419._1
514+ let currentEpochStartHeight = $t01733917419._2
513515 let votingResultStaked = getVotingResultStaked(lpAssetIdStr)
514516 let votingResultStakedIntegralPrev = valueOrElse(getInteger(this, keyVotingResultStakedIntegral(lpAssetIdStr, lastFinalizedEpoch)), 0)
515517 let votingResultStakedLastUpdateHeight = valueOrElse(getInteger(this, keyVotingResultStakedLastUpdateHeight(lpAssetIdStr, lastFinalizedEpoch)), currentEpochStartHeight)
520522
521523
522524 func refreshVotingResultStakedIntegral (lpAssetIdStr,stakedVoteDelta) = {
523- let $t01820618286 = getVotingEmissionEpochInfo()
524- let lastFinalizedEpoch = $t01820618286._1
525- let currentEpochStartHeight = $t01820618286._2
525+ let $t01825618336 = getVotingEmissionEpochInfo()
526+ let lastFinalizedEpoch = $t01825618336._1
527+ let currentEpochStartHeight = $t01825618336._2
526528 let votingResultStaked = getVotingResultStaked(lpAssetIdStr)
527529 let votingResultStakedNew = (votingResultStaked + stakedVoteDelta)
528530 let votingResultStakedIntegral = getVotingResultStakedIntegral(lpAssetIdStr)
531533
532534
533535 func getUserVoteStakedIntegral (lpAssetIdStr,userAddressStr) = {
534- let $t01889718977 = getVotingEmissionEpochInfo()
535- let lastFinalizedEpoch = $t01889718977._1
536- let currentEpochStartHeight = $t01889718977._2
536+ let $t01894719027 = getVotingEmissionEpochInfo()
537+ let lastFinalizedEpoch = $t01894719027._1
538+ let currentEpochStartHeight = $t01894719027._2
537539 let userAddress = addressFromStringValue(userAddressStr)
538540 let userVoteStaked = getUserVoteStaked(lpAssetIdStr, userAddressStr)
539541 let userVoteStakedIntegralPrev = valueOrElse(getInteger(this, keyVoteStakedIntegral(lpAssetIdStr, userAddress, lastFinalizedEpoch)), 0)
545547
546548
547549 func refreshVoteStakedIntegral (lpAssetIdStr,userAddressStr,edge) = {
548- let $t01976519845 = getVotingEmissionEpochInfo()
549- let lastFinalizedEpoch = $t01976519845._1
550- let currentEpochStartHeight = $t01976519845._2
550+ let $t01981519895 = getVotingEmissionEpochInfo()
551+ let lastFinalizedEpoch = $t01981519895._1
552+ let currentEpochStartHeight = $t01981519895._2
551553 let userAddress = addressFromStringValue(userAddressStr)
552554 let userVoteFinalized = getUserVoteFinalized(lpAssetIdStr, userAddressStr)
553555 let actions = if ((userVoteFinalized == 0))
566568
567569
568570 func getStakedVotesIntegralsDiff (lpAssetIdStr,userAddressStr) = {
569- let $t02069920779 = getVotingEmissionEpochInfo()
570- let lastFinalizedEpoch = $t02069920779._1
571- let currentEpochStartHeight = $t02069920779._2
571+ let $t02074920829 = getVotingEmissionEpochInfo()
572+ let lastFinalizedEpoch = $t02074920829._1
573+ let currentEpochStartHeight = $t02074920829._2
572574 let userAddress = addressFromStringValue(userAddressStr)
573575 let userVoteStakedIntegralLastKey = keyVoteStakedIntegralLast(lpAssetIdStr, userAddress, lastFinalizedEpoch)
574576 let userVoteStakedIntegralLast = valueOrElse(getInteger(this, userVoteStakedIntegralLastKey), 0)
627629 if ((0 > userBoostEmissionIntegral))
628630 then throwErr("wrong calculations")
629631 else {
630- let $t02432124460 = getStakedVotesIntegralsDiff(lpAssetIdStr, userAddressStr)
631- let stakedVotesIntegralsActions = $t02432124460._1
632- let userVoteIntegralDiff = $t02432124460._2
633- let totalVotesIntegralDiff = $t02432124460._3
632+ let $t02437124510 = getStakedVotesIntegralsDiff(lpAssetIdStr, userAddressStr)
633+ let stakedVotesIntegralsActions = $t02437124510._1
634+ let userVoteIntegralDiff = $t02437124510._2
635+ let totalVotesIntegralDiff = $t02437124510._3
634636 let poolUserBoostEmissionIntegral = fraction(userBoostEmissionIntegral, poolWeight, POOLWEIGHTMULT)
635637 let userBoostAvaliableToClaimTotalNew = if ((totalVotesIntegralDiff == 0))
636638 then 0
644646 }
645647
646648
647-func lockActions (i,durationMonths) = {
648- let durationMonthsAllowed = [1, 3, 6, 12, 24, 48]
649- if (!(containsElement(durationMonthsAllowed, durationMonths)))
650- then throwErr("invalid duration")
651- else {
652- let duration = (durationMonths * blocksInMonth)
653- let assetIdStr = toBase58String(assetId)
654- if ((size(i.payments) != 1))
655- then throwErr("invalid payment - exact one payment must be attached")
656- else {
657- let pmt = i.payments[0]
658- let pmtAmount = pmt.amount
659- if ((assetId != value(pmt.assetId)))
660- then throwErr((("invalid asset is in payment - " + assetIdStr) + " is expected"))
661- else {
662- let nextUserNumKEY = keyNextUserNum()
663- let userAddress = i.caller
664- let userAddressStr = toString(userAddress)
665- let userIsExisting = isDefined(getString(keyUser2NumMapping(userAddressStr)))
666- let userNumStr = if (userIsExisting)
667- then value(getString(keyUser2NumMapping(userAddressStr)))
668- else toString(getIntOrFail(this, nextUserNumKEY))
669- let userNum = parseIntValue(userNumStr)
670- let lockStart = height
671- if (if ((minLockAmount > pmtAmount))
672- then (userAddress != lpStakingPoolsContract)
673- else false)
674- then throwErr(("amount is less then minLockAmount=" + toString(minLockAmount)))
675- else if ((minLockDuration > duration))
676- then throwErr(("passed duration is less then minLockDuration=" + toString(minLockDuration)))
677- else if ((duration > maxLockDuration))
678- then throwErr(("passed duration is greater then maxLockDuration=" + toString(maxLockDuration)))
679- else {
680- let coeffX8 = fraction(duration, MULT8, maxLockDuration)
681- let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
682- let gwxAmountTotal = getGwxAmountTotal()
683- let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNum)
684- let boostEmissionIntegral = refreshBoostEmissionIntegral()._2
685- let userGwxAmountTotal = getUserGwxAmountTotal(userAddress)
686- let gwxRewardInv = reentrantInvoke(gwxRewardContract, "refreshUserReward", [userAddress.bytes], nil)
687- if ((gwxRewardInv == gwxRewardInv))
688- then {
689- let arr = if (userIsExisting)
690- then nil
691- else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
692- $Tuple2(((((arr ++ LockParamsEntry(userAddress, i.transactionId, pmtAmount, lockStart, duration, gWxAmountStart, 0)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
693- then 0
694- else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, gWxAmountStart, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(keyGwxTotal(), (gwxAmountTotal + gWxAmountStart)), IntegerEntry(keyUserGwxAmountTotal(userAddress), (userGwxAmountTotal + gWxAmountStart))]), gWxAmountStart)
695- }
696- else throw("Strict value is not equal to itself.")
697- }
698- }
699- }
700- }
701- }
649+func lockActions (i,durationMonths) = if (!(containsElement(durationMonthsAllowed, durationMonths)))
650+ then throwErr("invalid duration")
651+ else {
652+ let duration = (durationMonths * blocksInMonth)
653+ let assetIdStr = toBase58String(assetId)
654+ if ((size(i.payments) != 1))
655+ then throwErr("invalid payment - exact one payment must be attached")
656+ else {
657+ let pmt = i.payments[0]
658+ let pmtAmount = pmt.amount
659+ if ((assetId != value(pmt.assetId)))
660+ then throwErr((("invalid asset is in payment - " + assetIdStr) + " is expected"))
661+ else {
662+ let nextUserNumKEY = keyNextUserNum()
663+ let userAddress = i.caller
664+ let userAddressStr = toString(userAddress)
665+ let userIsExisting = isDefined(getString(keyUser2NumMapping(userAddressStr)))
666+ let userNumStr = if (userIsExisting)
667+ then value(getString(keyUser2NumMapping(userAddressStr)))
668+ else toString(getIntOrFail(this, nextUserNumKEY))
669+ let userNum = parseIntValue(userNumStr)
670+ let lockStart = height
671+ if (if ((minLockAmount > pmtAmount))
672+ then (userAddress != lpStakingPoolsContract)
673+ else false)
674+ then throwErr(("amount is less then minLockAmount=" + toString(minLockAmount)))
675+ else if ((minLockDuration > duration))
676+ then throwErr(("passed duration is less then minLockDuration=" + toString(minLockDuration)))
677+ else if ((duration > maxLockDuration))
678+ then throwErr(("passed duration is greater then maxLockDuration=" + toString(maxLockDuration)))
679+ else {
680+ let gWxAmountStart = fraction(pmtAmount, duration, maxLockDuration)
681+ let gwxAmountTotal = getGwxAmountTotal()
682+ let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNum)
683+ let boostEmissionIntegral = refreshBoostEmissionIntegral()._2
684+ let userGwxAmountTotal = getUserGwxAmountTotal(userAddress)
685+ let gwxRewardInv = reentrantInvoke(gwxRewardContract, "refreshUserReward", [userAddress.bytes], nil)
686+ if ((gwxRewardInv == gwxRewardInv))
687+ then {
688+ let arr = if (userIsExisting)
689+ then nil
690+ else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
691+ $Tuple2(((((arr ++ LockParamsEntry(userAddress, i.transactionId, pmtAmount, lockStart, duration, gWxAmountStart, 0)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
692+ then 0
693+ else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, gWxAmountStart, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(keyGwxTotal(), (gwxAmountTotal + gWxAmountStart)), IntegerEntry(keyUserGwxAmountTotal(userAddress), (userGwxAmountTotal + gWxAmountStart))]), gWxAmountStart)
694+ }
695+ else throw("Strict value is not equal to itself.")
696+ }
697+ }
698+ }
699+ }
702700
703701
704702 func getWxWithdrawable (userAddress,txIdOption) = {
708706 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
709707 let lockEnd = (lockStart + lockDuration)
710708 let wxClaimed = parseIntValue(userRecordArray[IdxLockWxClaimed])
711- let gwxAmount = parseIntValue(userRecordArray[IdxLockGwxAmount])
712709 let t = ((height - lockStart) / blocksInPeriod)
713710 let exponent = fraction(toBigInt(t), (toBigInt((8 * blocksInPeriod)) * MULT18BI), toBigInt(lockDuration))
714711 let wxWithdrawable = if ((height > lockEnd))
730727
731728 @Callable(i)
732729 func lockRef (duration,referrerAddress,signature) = {
733- let $t02942729492 = lockActions(i, duration)
734- let lockActionsResult = $t02942729492._1
735- let gWxAmountStart = $t02942729492._2
730+ let $t02930929374 = lockActions(i, duration)
731+ let lockActionsResult = $t02930929374._1
732+ let gWxAmountStart = $t02930929374._2
736733 let referralAddress = toString(i.caller)
737734 let refInv = if (if ((referrerAddress == ""))
738735 then true
753750
754751 @Callable(i)
755752 func lock (duration) = {
756- let $t02995030015 = lockActions(i, duration)
757- let lockActionsResult = $t02995030015._1
758- let gWxAmountStart = $t02995030015._2
753+ let $t02983229897 = lockActions(i, duration)
754+ let lockActionsResult = $t02983229897._1
755+ let gWxAmountStart = $t02983229897._2
759756 let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
760757 if ((updateRefActivity == updateRefActivity))
761758 then $Tuple2(lockActionsResult, unit)
768765 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
769766 then throwErr("permissions denied")
770767 else {
771- let $t03032530427 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
772- let userBoostAvailable = $t03032530427._1
773- let dataState = $t03032530427._2
774- let debug = $t03032530427._3
768+ let $t03020730309 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
769+ let userBoostAvailable = $t03020730309._1
770+ let dataState = $t03020730309._2
771+ let debug = $t03020730309._3
775772 $Tuple2(dataState, [userBoostAvailable])
776773 }
777774
779776
780777 @Callable(i)
781778 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
782- let $t03055930660 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
783- let userBoostAvailable = $t03055930660._1
784- let dataState = $t03055930660._2
785- let debug = $t03055930660._3
779+ let $t03044130542 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
780+ let userBoostAvailable = $t03044130542._1
781+ let dataState = $t03044130542._2
782+ let debug = $t03044130542._3
786783 $Tuple2(nil, [userBoostAvailable, debug])
787784 }
788785
799796 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
800797 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
801798 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
802- let lockEnd = (lockStart + lockDuration)
803799 let wxClaimed = parseIntValue(userRecordArray[IdxLockWxClaimed])
804800 let gwxAmount = parseIntValue(userRecordArray[IdxLockGwxAmount])
805801 let t = ((height - lockStart) / blocksInPeriod)
806802 let wxWithdrawable = getWxWithdrawable(userAddress, if ((txIdStr == ""))
807803 then unit
808804 else txId)
809- let coeffX8 = fraction(lockDuration, MULT8, maxLockDuration)
810- let gWxAmountStart = fraction(userAmount, coeffX8, MULT8)
805+ let gWxAmountStart = fraction(userAmount, lockDuration, maxLockDuration)
811806 let gwxBurned = min([fraction((t * blocksInPeriod), gWxAmountStart, maxLockDuration), gwxAmount])
812807 let gwxRemaining = ensurePositive((gwxAmount - gwxBurned), "gwxRemaining")
813808 let lockedGwxAmount = getLockedGwxAmount(userAddress)
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)
19+
20+let durationMonthsAllowed = [1, 3, 6, 12, 24, 48]
1921
2022 let blocksInDay = 1440
2123
2224 let blocksInMonth = 43800
2325
2426 func wrapErr (msg) = makeString([contractFilename, ": ", msg], "")
2527
2628
2729 func throwErr (msg) = throw(wrapErr(msg))
2830
2931
3032 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), wrapErr((("mandatory this." + key) + " is not defined")))
3133
3234
3335 func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
3436
3537
3638 func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
3739
3840
3941 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), wrapErr((("mandatory this." + key) + " is not defined")))
4042
4143
4244 func abs (val) = if ((0 > val))
4345 then -(val)
4446 else val
4547
4648
4749 func ensurePositive (v,m) = if ((v >= 0))
4850 then v
4951 else throwErr((valueOrElse(m, "value") + " should be positive"))
5052
5153
5254 func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
5355
5456
5557 let referralsContractAddressOrFail = addressFromStringValue(getStringOrFail(this, keyReferralsContractAddress()))
5658
5759 let keyReferralProgramName = makeString(["%s%s", "referral", "programName"], SEP)
5860
5961 let referralProgramNameDefault = "wxlock"
6062
6163 let referralProgramName = valueOrElse(getString(this, keyReferralProgramName), referralProgramNameDefault)
6264
6365 func keyFactoryAddress () = "%s%s__config__factoryAddress"
6466
6567
6668 let IdxFactoryCfgStakingDapp = 1
6769
6870 let IdxFactoryCfgBoostingDapp = 2
6971
7072 let IdxFactoryCfgIdoDapp = 3
7173
7274 let IdxFactoryCfgTeamDapp = 4
7375
7476 let IdxFactoryCfgEmissionDapp = 5
7577
7678 let IdxFactoryCfgRestDapp = 6
7779
7880 let IdxFactoryCfgSlippageDapp = 7
7981
8082 let IdxFactoryCfgDaoDapp = 8
8183
8284 let IdxFactoryCfgMarketingDapp = 9
8385
8486 let IdxFactoryCfgGwxRewardDapp = 10
8587
8688 let IdxFactoryCfgBirdsDapp = 11
8789
8890 func keyFactoryCfg () = "%s__factoryConfig"
8991
9092
9193 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
9294
9395
9496 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
9597
9698
9799 func keyFactoryPoolWeightHistory (poolAddress,num) = ((("%s%s__poolWeight__" + poolAddress) + "__") + toString(num))
98100
99101
100102 func readFactoryAddressOrFail () = addressFromStringValue(getStringOrFail(this, keyFactoryAddress()))
101103
102104
103105 func readFactoryCfgOrFail (factory) = split(getStringOrFail(factory, keyFactoryCfg()), SEP)
104106
105107
106108 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
107109
108110
109111 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
110112
111113
112114 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
113115
114116
115117 func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp])
116118
117119
118120 func keyManagerPublicKey () = "%s__managerPublicKey"
119121
120122
121123 func keyManagerVaultAddress () = "%s__managerVaultAddress"
122124
123125
124126 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
125127
126128
127129 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
128130
129131
130132 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
131133
132134
133135 func keyBoostingV2LastUpdateHeight () = "%s%s__boostingV2__startBlock"
134136
135137
136138 func keyBoostingV2Integral () = "%s%s__boostingV2__integral"
137139
138140
139141 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
140142
141143
142144 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
143145
144146
145147 func keyNextPergetIntOrDefault () = "%s__nextPeriod"
146148
147149
148150 func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
149151
150152
151153 let IdxCfgAssetId = 1
152154
153155 let IdxCfgMinLockAmount = 2
154156
155157 let IdxCfgMinLockDuration = 3
156158
157159 let IdxCfgMaxLockDuration = 4
158160
159161 let IdxCfgMathContract = 5
160162
161163 let IdxCfgBlocksInPeriod = 6
162164
163165 func keyConfig () = "%s__config"
164166
165167
166168 func readConfigArrayOrFail () = split(getStringOrFail(this, keyConfig()), SEP)
167169
168170
169171 let cfgArray = readConfigArrayOrFail()
170172
171173 let assetId = fromBase58String(cfgArray[IdxCfgAssetId])
172174
173175 let minLockAmount = valueOrErrorMessage(parseInt(cfgArray[IdxCfgMinLockAmount]), wrapErr("invalid min lock amount"))
174176
175177 let minLockDuration = valueOrErrorMessage(parseInt(cfgArray[IdxCfgMinLockDuration]), wrapErr("invalid min lock duration"))
176178
177179 let maxLockDuration = valueOrErrorMessage(parseInt(cfgArray[IdxCfgMaxLockDuration]), wrapErr("invalid max lock duration"))
178180
179181 let mathContract = valueOrErrorMessage(addressFromString(cfgArray[IdxCfgMathContract]), wrapErr("invalid math contract address"))
180182
181183 let blocksInPeriod = valueOrErrorMessage(parseInt(cfgArray[IdxCfgBlocksInPeriod]), wrapErr("invalid blocks in period"))
182184
183185 func formatConfigS (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = makeString(["%s%d%d%d%s", assetId, minLockAmount, minLockDuration, maxLockDuration, mathContract], SEP)
184186
185187
186188 func formatConfig (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = formatConfigS(assetId, toString(minLockAmount), toString(minLockDuration), toString(maxLockDuration), mathContract)
187189
188190
189191 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
190192 case s: String =>
191193 addressFromStringValue(s)
192194 case _ =>
193195 this
194196 }
195197
196198
197199 func managerPublicKeyOrUnit () = {
198200 let managerVaultAddress = getManagerVaultAddressOrThis()
199201 match getString(managerVaultAddress, keyManagerPublicKey()) {
200202 case s: String =>
201203 fromBase58String(s)
202204 case _: Unit =>
203205 unit
204206 case _ =>
205207 throw("Match error")
206208 }
207209 }
208210
209211
210212 func mustManager (i) = {
211213 let pd = throwErr("Permission denied")
212214 match managerPublicKeyOrUnit() {
213215 case pk: ByteVector =>
214216 if ((i.callerPublicKey == pk))
215217 then true
216218 else pd
217219 case _: Unit =>
218220 if ((i.caller == this))
219221 then true
220222 else pd
221223 case _ =>
222224 throw("Match error")
223225 }
224226 }
225227
226228
227229 let IdxLockAmount = 1
228230
229231 let IdxLockStart = 2
230232
231233 let IdxLockDuration = 3
232234
233235 let IdxLockLastUpdateTimestamp = 4
234236
235237 let IdxLockGwxAmount = 5
236238
237239 let IdxLockWxClaimed = 6
238240
239241 func keyLockParamsRecord (userAddress,txId) = makeString(["%s%s%s__lock", toString(userAddress), match txId {
240242 case b: ByteVector =>
241243 toBase58String(b)
242244 case _: Unit =>
243245 "legacy"
244246 case _ =>
245247 throw("Match error")
246248 }], SEP)
247249
248250
249251 func readLockParamsRecordOrFail (userAddress,txId) = split(getStringOrFail(this, keyLockParamsRecord(userAddress, txId)), SEP)
250252
251253
252254 func keyUserGwxAmountTotal (userAddress) = makeString(["%s%s__gwxAmountTotal", toString(userAddress)], SEP)
253255
254256
255257 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)
256258
257259
258260 func keyNextUserNum () = "%s__nextUserNum"
259261
260262
261263 func keyUser2NumMapping (userAddress) = makeString(["%s%s%s__mapping__user2num", userAddress], SEP)
262264
263265
264266 func keyNum2UserMapping (num) = makeString(["%s%s%s__mapping__num2user", num], SEP)
265267
266268
267269 func keyLockParamTotalAmount () = "%s%s__stats__activeTotalLocked"
268270
269271
270272 func keyStatsLocksDurationSumInBlocks () = "%s%s__stats__locksDurationSumInBlocks"
271273
272274
273275 func keyStatsLocksCount () = "%s%s__stats__locksCount"
274276
275277
276278 func keyStatsUsersCount () = "%s%s__stats__activeUsersCount"
277279
278280
279281 func keyUserBoostEmissionLastINTEGRAL (userNum) = makeString(["%s%d__userBoostEmissionLastIntV2", toString(userNum)], SEP)
280282
281283
282284 func keyUserLpBoostEmissionLastINTEGRAL (userNum,lpAssetId) = makeString(["%s%d__userBoostEmissionLastIntV2", toString(userNum), lpAssetId], SEP)
283285
284286
285287 func keyUserMaxBoostINTEGRAL (userNum) = makeString(["%s%d__maxBoostInt", toString(userNum)], SEP)
286288
287289
288290 func keyTotalMaxBoostINTEGRAL () = "%s%s__maxBoostInt__total"
289291
290292
291293 func keyUserBoostAvalaibleToClaimTotal (userNum) = makeString(["%s%d__userBoostAvaliableToClaimTotal", toString(userNum)], SEP)
292294
293295
294296 func keyUserBoostClaimed (userNum) = makeString(["%s%d__userBoostClaimed", toString(userNum)], SEP)
295297
296298
297299 func keyGwxTotal () = "%s%s__gwx__total"
298300
299301
300302 func keyVote (amountAssetId,priceAssetId,address,epoch) = makeString(["%s%s%s%s%d", "vote", amountAssetId, priceAssetId, toString(address), toString(epoch)], SEP)
301303
302304
303305 func keyStartHeightByEpoch (epoch) = makeString(["%s%d", "startHeight", toString(epoch)], SEP)
304306
305307
306308 func keyCurrentEpochUi () = makeString(["%s", "currentEpochUi"], SEP)
307309
308310
309311 func keyVotingResultStaked (lpAssetIdStr,epoch) = makeString(["%s%s%d", "votingResultStaked", lpAssetIdStr, toString(epoch)], SEP)
310312
311313
312314 func keyVotingResultStakedIntegral (lpAssetIdStr,epoch) = makeString(["%s%s%d", "votingResultStakedIntegral", lpAssetIdStr, toString(epoch)], SEP)
313315
314316
315317 func keyVotingResultStakedLastUpdateHeight (lpAssetIdStr,epoch) = makeString(["%s%s%d", "votingResultStakedIntegralLastUpdateHeight", lpAssetIdStr, toString(epoch)], SEP)
316318
317319
318320 func keyVotingResultStakedIntegralLast (lpAssetIdStr,address,epoch) = makeString(["%s%s%s%d", "votingResultStakedIntegralLast", lpAssetIdStr, toString(address), toString(epoch)], SEP)
319321
320322
321323 func keyVoteStakedIntegral (lpAssetIdStr,address,epoch) = makeString(["%s%s%s%d", "voteStakedIntegral", lpAssetIdStr, toString(address), toString(epoch)], SEP)
322324
323325
324326 func keyVoteStakedLastUpdateHeight (lpAssetIdStr,address,epoch) = makeString(["%s%s%s%d", "voteStakedIntegralLastUpdateHeight", lpAssetIdStr, toString(address), toString(epoch)], SEP)
325327
326328
327329 func keyVoteStakedIntegralLast (lpAssetIdStr,address,epoch) = makeString(["%s%s%s%d", "voteStakedIntegralLast", lpAssetIdStr, toString(address), toString(epoch)], SEP)
328330
329331
330332 func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s", "staked", userAddressStr, lpAssetIdStr], SEP)
331333
332334
333335 let factoryContract = readFactoryAddressOrFail()
334336
335337 let factoryCfg = readFactoryCfgOrFail(factoryContract)
336338
337339 let emissionContract = getEmissionAddressOrFail(factoryCfg)
338340
339341 let stakingContract = getStakingAddressOrFail(factoryCfg)
340342
341343 let gwxRewardContract = getGwxRewardAddressOrFail(factoryCfg)
342344
343345 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"))
344346
345347 let keyVotingEmissionContract = makeString(["%s", "votingEmissionContract"], SEP)
346348
347349 let votingEmissionContract = addressFromStringValue(getStringValue(factoryContract, keyVotingEmissionContract))
348350
349351 let keyVotingEmissionRateContract = makeString(["%s", "votingEmissionRateContract"], SEP)
350352
351353 let boostCoeff = {
352354 let @ = invoke(emissionContract, "getBoostCoeffREADONLY", nil, nil)
353355 if ($isInstanceOf(@, "Int"))
354356 then @
355357 else throw(($getType(@) + " couldn't be cast to Int"))
356358 }
357359
358360 func userNumberByAddressOrFail (userAddress) = match getString(this, keyUser2NumMapping(toString(userAddress))) {
359361 case s: String =>
360362 valueOrErrorMessage(parseInt(s), wrapErr("invalid user number"))
361363 case _: Unit =>
362364 throwErr("invalid user")
363365 case _ =>
364366 throw("Match error")
365367 }
366368
367369
368370 func getGwxAmountTotal () = valueOrElse(getInteger(this, keyGwxTotal()), 0)
369371
370372
371373 func getLockedGwxAmount (userAddress) = {
372374 let functionName = "getLockedGwxAmount"
373375 let votingEmissionRateContract = valueOrErrorMessage( match getString(votingEmissionContract, keyVotingEmissionRateContract) {
374376 case _: Unit =>
375377 unit
376378 case s: String =>
377379 addressFromString(s)
378380 case _ =>
379381 throw("Match error")
380382 }, wrapErr("invalid voting emission rate address"))
381383 let lockedVotingEmissionRate = {
382384 let @ = invoke(votingEmissionContract, functionName, [toString(userAddress)], nil)
383385 if ($isInstanceOf(@, "Int"))
384386 then @
385387 else throw(($getType(@) + " couldn't be cast to Int"))
386388 }
387389 let lockedVotingEmission = {
388390 let @ = invoke(votingEmissionRateContract, functionName, [toString(userAddress)], nil)
389391 if ($isInstanceOf(@, "Int"))
390392 then @
391393 else throw(($getType(@) + " couldn't be cast to Int"))
392394 }
393395 let locked = max([lockedVotingEmissionRate, lockedVotingEmission])
394396 locked
395397 }
396398
397399
398400 func HistoryEntry (type,user,amount,lockStart,duration,gwxAmount,i) = {
399401 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
400402 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)
401403 StringEntry(historyKEY, historyDATA)
402404 }
403405
404406
405407 func StatsEntry (totalLockedInc,durationInc,lockCountInc,usersCountInc) = {
406408 let locksDurationSumInBlocksKEY = keyStatsLocksDurationSumInBlocks()
407409 let locksCountKEY = keyStatsLocksCount()
408410 let usersCountKEY = keyStatsUsersCount()
409411 let totalAmountKEY = keyLockParamTotalAmount()
410412 let locksDurationSumInBlocks = getIntOrZero(this, locksDurationSumInBlocksKEY)
411413 let locksCount = getIntOrZero(this, locksCountKEY)
412414 let usersCount = getIntOrZero(this, usersCountKEY)
413415 let totalAmount = getIntOrZero(this, totalAmountKEY)
414416 [IntegerEntry(locksDurationSumInBlocksKEY, (locksDurationSumInBlocks + durationInc)), IntegerEntry(locksCountKEY, (locksCount + lockCountInc)), IntegerEntry(usersCountKEY, (usersCount + usersCountInc)), IntegerEntry(totalAmountKEY, (totalAmount + totalLockedInc))]
415417 }
416418
417419
418420 func LockParamsEntry (userAddress,txId,amount,start,duration,gwxAmount,wxClaimed) = [StringEntry(keyLockParamsRecord(userAddress, txId), formatLockParamsRecord(amount, start, duration, gwxAmount, wxClaimed))]
419421
420422
421423 func extractOptionalPaymentAmountOrFail (i,expectedAssetId) = if ((size(i.payments) > 1))
422424 then throwErr("only one payment is allowed")
423425 else if ((size(i.payments) == 0))
424426 then 0
425427 else {
426428 let pmt = i.payments[0]
427429 if ((value(pmt.assetId) != expectedAssetId))
428430 then throwErr("invalid asset id in payment")
429431 else pmt.amount
430432 }
431433
432434
433435 func getUserGwxAmountTotal (userAddress) = valueOrElse(getInteger(this, keyUserGwxAmountTotal(userAddress)), 0)
434436
435437
436438 func getVotingEmissionEpochInfo () = {
437- let $t01516415454 = {
439+ let $t01521415504 = {
438440 let currentEpochUi = value(getInteger(votingEmissionContract, keyCurrentEpochUi()))
439441 let lastFinalizedEpoch = (currentEpochUi - 1)
440442 if ((0 > lastFinalizedEpoch))
441443 then throwErr("invalid epoch")
442444 else $Tuple2(currentEpochUi, lastFinalizedEpoch)
443445 }
444- let currentEpochUi = $t01516415454._1
445- let lastFinalizedEpoch = $t01516415454._2
446+ let currentEpochUi = $t01521415504._1
447+ let lastFinalizedEpoch = $t01521415504._2
446448 let currentEpochStartHeight = value(getInteger(votingEmissionContract, keyStartHeightByEpoch(currentEpochUi)))
447449 $Tuple2(lastFinalizedEpoch, currentEpochStartHeight)
448450 }
449451
450452
451453 func getPoolAssetsByLpAssetId (lpAssetIdStr) = {
452454 let idxAmountAssetId = 4
453455 let idxPriceAssetId = 5
454456 let poolCfg = {
455457 let @ = invoke(factoryContract, "getPoolConfigByLpAssetIdREADONLY", [lpAssetIdStr], nil)
456458 if ($isInstanceOf(@, "List[Any]"))
457459 then @
458460 else throw(($getType(@) + " couldn't be cast to List[Any]"))
459461 }
460462 let amountAssetId = {
461463 let @ = poolCfg[idxAmountAssetId]
462464 if ($isInstanceOf(@, "String"))
463465 then @
464466 else throw(($getType(@) + " couldn't be cast to String"))
465467 }
466468 let priceAssetId = {
467469 let @ = poolCfg[idxPriceAssetId]
468470 if ($isInstanceOf(@, "String"))
469471 then @
470472 else throw(($getType(@) + " couldn't be cast to String"))
471473 }
472474 $Tuple2(amountAssetId, priceAssetId)
473475 }
474476
475477
476478 func getUserVoteFinalized (lpAssetIdStr,userAddressStr) = {
477479 let userAddress = addressFromStringValue(userAddressStr)
478- let $t01614516225 = getVotingEmissionEpochInfo()
479- let lastFinalizedEpoch = $t01614516225._1
480- let currentEpochStartHeight = $t01614516225._2
481- let $t01622816303 = getPoolAssetsByLpAssetId(lpAssetIdStr)
482- let amountAssetId = $t01622816303._1
483- let priceAssetId = $t01622816303._2
480+ let $t01619516275 = getVotingEmissionEpochInfo()
481+ let lastFinalizedEpoch = $t01619516275._1
482+ let currentEpochStartHeight = $t01619516275._2
483+ let $t01627816353 = getPoolAssetsByLpAssetId(lpAssetIdStr)
484+ let amountAssetId = $t01627816353._1
485+ let priceAssetId = $t01627816353._2
484486 let userVoteKey = keyVote(amountAssetId, priceAssetId, userAddress, lastFinalizedEpoch)
485487 let userVote = valueOrElse(getInteger(votingEmissionContract, userVoteKey), 0)
486488 userVote
487489 }
488490
489491
490492 func getUserVoteStaked (lpAssetIdStr,userAddressStr) = {
491493 let stakedByUser = valueOrElse(getInteger(stakingContract, keyStakedByUser(userAddressStr, lpAssetIdStr)), 0)
492494 let userVote = getUserVoteFinalized(lpAssetIdStr, userAddressStr)
493495 if ((stakedByUser == 0))
494496 then 0
495497 else userVote
496498 }
497499
498500
499501 func getVotingResultStaked (lpAssetIdStr) = {
500- let $t01684716927 = getVotingEmissionEpochInfo()
501- let lastFinalizedEpoch = $t01684716927._1
502- let currentEpochStartHeight = $t01684716927._2
502+ let $t01689716977 = getVotingEmissionEpochInfo()
503+ let lastFinalizedEpoch = $t01689716977._1
504+ let currentEpochStartHeight = $t01689716977._2
503505 let votingResultStakedStart = valueOrElse(getInteger(votingEmissionContract, keyVotingResultStaked(lpAssetIdStr, lastFinalizedEpoch)), 0)
504506 let votingResultStaked = valueOrElse(getInteger(this, keyVotingResultStaked(lpAssetIdStr, lastFinalizedEpoch)), votingResultStakedStart)
505507 votingResultStaked
506508 }
507509
508510
509511 func getVotingResultStakedIntegral (lpAssetIdStr) = {
510- let $t01728917369 = getVotingEmissionEpochInfo()
511- let lastFinalizedEpoch = $t01728917369._1
512- let currentEpochStartHeight = $t01728917369._2
512+ let $t01733917419 = getVotingEmissionEpochInfo()
513+ let lastFinalizedEpoch = $t01733917419._1
514+ let currentEpochStartHeight = $t01733917419._2
513515 let votingResultStaked = getVotingResultStaked(lpAssetIdStr)
514516 let votingResultStakedIntegralPrev = valueOrElse(getInteger(this, keyVotingResultStakedIntegral(lpAssetIdStr, lastFinalizedEpoch)), 0)
515517 let votingResultStakedLastUpdateHeight = valueOrElse(getInteger(this, keyVotingResultStakedLastUpdateHeight(lpAssetIdStr, lastFinalizedEpoch)), currentEpochStartHeight)
516518 let votingResultStakedIntegralDh = (height - votingResultStakedLastUpdateHeight)
517519 let votingResultStakedIntegral = ((votingResultStakedIntegralDh * votingResultStaked) + votingResultStakedIntegralPrev)
518520 votingResultStakedIntegral
519521 }
520522
521523
522524 func refreshVotingResultStakedIntegral (lpAssetIdStr,stakedVoteDelta) = {
523- let $t01820618286 = getVotingEmissionEpochInfo()
524- let lastFinalizedEpoch = $t01820618286._1
525- let currentEpochStartHeight = $t01820618286._2
525+ let $t01825618336 = getVotingEmissionEpochInfo()
526+ let lastFinalizedEpoch = $t01825618336._1
527+ let currentEpochStartHeight = $t01825618336._2
526528 let votingResultStaked = getVotingResultStaked(lpAssetIdStr)
527529 let votingResultStakedNew = (votingResultStaked + stakedVoteDelta)
528530 let votingResultStakedIntegral = getVotingResultStakedIntegral(lpAssetIdStr)
529531 [IntegerEntry(keyVotingResultStaked(lpAssetIdStr, lastFinalizedEpoch), votingResultStakedNew), IntegerEntry(keyVotingResultStakedLastUpdateHeight(lpAssetIdStr, lastFinalizedEpoch), height), IntegerEntry(keyVotingResultStakedIntegral(lpAssetIdStr, lastFinalizedEpoch), votingResultStakedIntegral)]
530532 }
531533
532534
533535 func getUserVoteStakedIntegral (lpAssetIdStr,userAddressStr) = {
534- let $t01889718977 = getVotingEmissionEpochInfo()
535- let lastFinalizedEpoch = $t01889718977._1
536- let currentEpochStartHeight = $t01889718977._2
536+ let $t01894719027 = getVotingEmissionEpochInfo()
537+ let lastFinalizedEpoch = $t01894719027._1
538+ let currentEpochStartHeight = $t01894719027._2
537539 let userAddress = addressFromStringValue(userAddressStr)
538540 let userVoteStaked = getUserVoteStaked(lpAssetIdStr, userAddressStr)
539541 let userVoteStakedIntegralPrev = valueOrElse(getInteger(this, keyVoteStakedIntegral(lpAssetIdStr, userAddress, lastFinalizedEpoch)), 0)
540542 let userVoteStakedLastUpdateHeight = valueOrElse(getInteger(this, keyVoteStakedLastUpdateHeight(lpAssetIdStr, userAddress, lastFinalizedEpoch)), currentEpochStartHeight)
541543 let userVoteStakedIntegralDh = (height - userVoteStakedLastUpdateHeight)
542544 let userVoteStakedIntegral = ((userVoteStakedIntegralDh * userVoteStaked) + userVoteStakedIntegralPrev)
543545 userVoteStakedIntegral
544546 }
545547
546548
547549 func refreshVoteStakedIntegral (lpAssetIdStr,userAddressStr,edge) = {
548- let $t01976519845 = getVotingEmissionEpochInfo()
549- let lastFinalizedEpoch = $t01976519845._1
550- let currentEpochStartHeight = $t01976519845._2
550+ let $t01981519895 = getVotingEmissionEpochInfo()
551+ let lastFinalizedEpoch = $t01981519895._1
552+ let currentEpochStartHeight = $t01981519895._2
551553 let userAddress = addressFromStringValue(userAddressStr)
552554 let userVoteFinalized = getUserVoteFinalized(lpAssetIdStr, userAddressStr)
553555 let actions = if ((userVoteFinalized == 0))
554556 then nil
555557 else {
556558 let stakedVoteDelta = if (edge)
557559 then userVoteFinalized
558560 else -(userVoteFinalized)
559561 let votingResultActions = refreshVotingResultStakedIntegral(lpAssetIdStr, stakedVoteDelta)
560562 let userVoteStakedIntegral = getUserVoteStakedIntegral(lpAssetIdStr, userAddressStr)
561563 let voteActions = [IntegerEntry(keyVoteStakedLastUpdateHeight(lpAssetIdStr, userAddress, lastFinalizedEpoch), height), IntegerEntry(keyVoteStakedIntegral(lpAssetIdStr, userAddress, lastFinalizedEpoch), userVoteStakedIntegral)]
562564 (votingResultActions ++ voteActions)
563565 }
564566 actions
565567 }
566568
567569
568570 func getStakedVotesIntegralsDiff (lpAssetIdStr,userAddressStr) = {
569- let $t02069920779 = getVotingEmissionEpochInfo()
570- let lastFinalizedEpoch = $t02069920779._1
571- let currentEpochStartHeight = $t02069920779._2
571+ let $t02074920829 = getVotingEmissionEpochInfo()
572+ let lastFinalizedEpoch = $t02074920829._1
573+ let currentEpochStartHeight = $t02074920829._2
572574 let userAddress = addressFromStringValue(userAddressStr)
573575 let userVoteStakedIntegralLastKey = keyVoteStakedIntegralLast(lpAssetIdStr, userAddress, lastFinalizedEpoch)
574576 let userVoteStakedIntegralLast = valueOrElse(getInteger(this, userVoteStakedIntegralLastKey), 0)
575577 let votingResultStakedIntegralLastKey = keyVotingResultStakedIntegralLast(lpAssetIdStr, userAddress, lastFinalizedEpoch)
576578 let votingResultStakedIntegralLast = valueOrElse(getInteger(this, votingResultStakedIntegralLastKey), 0)
577579 let userVoteStakedIntegral = getUserVoteStakedIntegral(lpAssetIdStr, userAddressStr)
578580 let votingResultStakedIntegral = getVotingResultStakedIntegral(lpAssetIdStr)
579581 let userVoteStakedIntegralDiff = (userVoteStakedIntegral - userVoteStakedIntegralLast)
580582 let votingResultStakedIntegralDiff = (votingResultStakedIntegral - votingResultStakedIntegralLast)
581583 $Tuple3([IntegerEntry(userVoteStakedIntegralLastKey, userVoteStakedIntegral), IntegerEntry(votingResultStakedIntegralLastKey, votingResultStakedIntegral)], userVoteStakedIntegralDiff, votingResultStakedIntegralDiff)
582584 }
583585
584586
585587 func refreshBoostEmissionIntegral () = {
586588 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
587589 let boostingV2LastUpdateHeightOption = getInteger(this, keyBoostingV2LastUpdateHeight())
588590 let boostingV2IngergalOption = getInteger(this, keyBoostingV2Integral())
589591 let emissionEnd = getIntOrFail(emissionContract, keyEmissionEndBlock())
590592 let h = if ((height > emissionEnd))
591593 then emissionEnd
592594 else height
593595 let dh = match boostingV2LastUpdateHeightOption {
594596 case lastUpdateHeight: Int =>
595597 max([(h - lastUpdateHeight), 0])
596598 case _: Unit =>
597599 0
598600 case _ =>
599601 throw("Match error")
600602 }
601603 let boostEmissionPerBlock = ((wxEmissionPerBlock * (boostCoeff - 1)) / boostCoeff)
602604 let boostEmissionIntegralPrev = valueOrElse(boostingV2IngergalOption, 0)
603605 let boostEmissionIntegral = ((boostEmissionPerBlock * dh) + boostEmissionIntegralPrev)
604606 $Tuple2([IntegerEntry(keyBoostingV2Integral(), boostEmissionIntegral), IntegerEntry(keyBoostingV2LastUpdateHeight(), height)], boostEmissionIntegral)
605607 }
606608
607609
608610 func internalClaimWxBoost (lpAssetIdStr,userAddressStr,readOnly) = {
609611 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
610612 let userNum = userNumberByAddressOrFail(userAddress)
611613 if ((userNum == userNum))
612614 then {
613615 let EMPTYSTR = "empty"
614616 let poolWeight = if ((lpAssetIdStr != EMPTYSTR))
615617 then {
616618 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr)), wrapErr(("unsupported lp asset " + lpAssetIdStr)))
617619 getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
618620 }
619621 else if (readOnly)
620622 then 0
621623 else throwErr(("not readonly mode: unsupported lp asset " + lpAssetIdStr))
622624 let userLpBoostEmissionLastIntegralKEY = keyUserLpBoostEmissionLastINTEGRAL(userNum, lpAssetIdStr)
623625 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNum)
624626 let userBoostEmissionLastIntegral = valueOrElse(getInteger(this, userLpBoostEmissionLastIntegralKEY), getIntOrZero(this, userBoostEmissionLastIntegralKEY))
625627 let boostEmissionIntegral = refreshBoostEmissionIntegral()._2
626628 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
627629 if ((0 > userBoostEmissionIntegral))
628630 then throwErr("wrong calculations")
629631 else {
630- let $t02432124460 = getStakedVotesIntegralsDiff(lpAssetIdStr, userAddressStr)
631- let stakedVotesIntegralsActions = $t02432124460._1
632- let userVoteIntegralDiff = $t02432124460._2
633- let totalVotesIntegralDiff = $t02432124460._3
632+ let $t02437124510 = getStakedVotesIntegralsDiff(lpAssetIdStr, userAddressStr)
633+ let stakedVotesIntegralsActions = $t02437124510._1
634+ let userVoteIntegralDiff = $t02437124510._2
635+ let totalVotesIntegralDiff = $t02437124510._3
634636 let poolUserBoostEmissionIntegral = fraction(userBoostEmissionIntegral, poolWeight, POOLWEIGHTMULT)
635637 let userBoostAvaliableToClaimTotalNew = if ((totalVotesIntegralDiff == 0))
636638 then 0
637639 else fraction(poolUserBoostEmissionIntegral, userVoteIntegralDiff, totalVotesIntegralDiff)
638640 let dataState = ([IntegerEntry(userLpBoostEmissionLastIntegralKEY, boostEmissionIntegral)] ++ stakedVotesIntegralsActions)
639641 let debug = makeString([toString(userBoostEmissionLastIntegral), toString(userBoostEmissionIntegral), toString(poolWeight), toString(userVoteIntegralDiff), toString(totalVotesIntegralDiff)], ":")
640642 $Tuple3(userBoostAvaliableToClaimTotalNew, dataState, debug)
641643 }
642644 }
643645 else throw("Strict value is not equal to itself.")
644646 }
645647
646648
647-func lockActions (i,durationMonths) = {
648- let durationMonthsAllowed = [1, 3, 6, 12, 24, 48]
649- if (!(containsElement(durationMonthsAllowed, durationMonths)))
650- then throwErr("invalid duration")
651- else {
652- let duration = (durationMonths * blocksInMonth)
653- let assetIdStr = toBase58String(assetId)
654- if ((size(i.payments) != 1))
655- then throwErr("invalid payment - exact one payment must be attached")
656- else {
657- let pmt = i.payments[0]
658- let pmtAmount = pmt.amount
659- if ((assetId != value(pmt.assetId)))
660- then throwErr((("invalid asset is in payment - " + assetIdStr) + " is expected"))
661- else {
662- let nextUserNumKEY = keyNextUserNum()
663- let userAddress = i.caller
664- let userAddressStr = toString(userAddress)
665- let userIsExisting = isDefined(getString(keyUser2NumMapping(userAddressStr)))
666- let userNumStr = if (userIsExisting)
667- then value(getString(keyUser2NumMapping(userAddressStr)))
668- else toString(getIntOrFail(this, nextUserNumKEY))
669- let userNum = parseIntValue(userNumStr)
670- let lockStart = height
671- if (if ((minLockAmount > pmtAmount))
672- then (userAddress != lpStakingPoolsContract)
673- else false)
674- then throwErr(("amount is less then minLockAmount=" + toString(minLockAmount)))
675- else if ((minLockDuration > duration))
676- then throwErr(("passed duration is less then minLockDuration=" + toString(minLockDuration)))
677- else if ((duration > maxLockDuration))
678- then throwErr(("passed duration is greater then maxLockDuration=" + toString(maxLockDuration)))
679- else {
680- let coeffX8 = fraction(duration, MULT8, maxLockDuration)
681- let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
682- let gwxAmountTotal = getGwxAmountTotal()
683- let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNum)
684- let boostEmissionIntegral = refreshBoostEmissionIntegral()._2
685- let userGwxAmountTotal = getUserGwxAmountTotal(userAddress)
686- let gwxRewardInv = reentrantInvoke(gwxRewardContract, "refreshUserReward", [userAddress.bytes], nil)
687- if ((gwxRewardInv == gwxRewardInv))
688- then {
689- let arr = if (userIsExisting)
690- then nil
691- else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
692- $Tuple2(((((arr ++ LockParamsEntry(userAddress, i.transactionId, pmtAmount, lockStart, duration, gWxAmountStart, 0)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
693- then 0
694- else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, gWxAmountStart, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(keyGwxTotal(), (gwxAmountTotal + gWxAmountStart)), IntegerEntry(keyUserGwxAmountTotal(userAddress), (userGwxAmountTotal + gWxAmountStart))]), gWxAmountStart)
695- }
696- else throw("Strict value is not equal to itself.")
697- }
698- }
699- }
700- }
701- }
649+func lockActions (i,durationMonths) = if (!(containsElement(durationMonthsAllowed, durationMonths)))
650+ then throwErr("invalid duration")
651+ else {
652+ let duration = (durationMonths * blocksInMonth)
653+ let assetIdStr = toBase58String(assetId)
654+ if ((size(i.payments) != 1))
655+ then throwErr("invalid payment - exact one payment must be attached")
656+ else {
657+ let pmt = i.payments[0]
658+ let pmtAmount = pmt.amount
659+ if ((assetId != value(pmt.assetId)))
660+ then throwErr((("invalid asset is in payment - " + assetIdStr) + " is expected"))
661+ else {
662+ let nextUserNumKEY = keyNextUserNum()
663+ let userAddress = i.caller
664+ let userAddressStr = toString(userAddress)
665+ let userIsExisting = isDefined(getString(keyUser2NumMapping(userAddressStr)))
666+ let userNumStr = if (userIsExisting)
667+ then value(getString(keyUser2NumMapping(userAddressStr)))
668+ else toString(getIntOrFail(this, nextUserNumKEY))
669+ let userNum = parseIntValue(userNumStr)
670+ let lockStart = height
671+ if (if ((minLockAmount > pmtAmount))
672+ then (userAddress != lpStakingPoolsContract)
673+ else false)
674+ then throwErr(("amount is less then minLockAmount=" + toString(minLockAmount)))
675+ else if ((minLockDuration > duration))
676+ then throwErr(("passed duration is less then minLockDuration=" + toString(minLockDuration)))
677+ else if ((duration > maxLockDuration))
678+ then throwErr(("passed duration is greater then maxLockDuration=" + toString(maxLockDuration)))
679+ else {
680+ let gWxAmountStart = fraction(pmtAmount, duration, maxLockDuration)
681+ let gwxAmountTotal = getGwxAmountTotal()
682+ let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNum)
683+ let boostEmissionIntegral = refreshBoostEmissionIntegral()._2
684+ let userGwxAmountTotal = getUserGwxAmountTotal(userAddress)
685+ let gwxRewardInv = reentrantInvoke(gwxRewardContract, "refreshUserReward", [userAddress.bytes], nil)
686+ if ((gwxRewardInv == gwxRewardInv))
687+ then {
688+ let arr = if (userIsExisting)
689+ then nil
690+ else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
691+ $Tuple2(((((arr ++ LockParamsEntry(userAddress, i.transactionId, pmtAmount, lockStart, duration, gWxAmountStart, 0)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
692+ then 0
693+ else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, gWxAmountStart, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(keyGwxTotal(), (gwxAmountTotal + gWxAmountStart)), IntegerEntry(keyUserGwxAmountTotal(userAddress), (userGwxAmountTotal + gWxAmountStart))]), gWxAmountStart)
694+ }
695+ else throw("Strict value is not equal to itself.")
696+ }
697+ }
698+ }
699+ }
702700
703701
704702 func getWxWithdrawable (userAddress,txIdOption) = {
705703 let userRecordArray = readLockParamsRecordOrFail(userAddress, txIdOption)
706704 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
707705 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
708706 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
709707 let lockEnd = (lockStart + lockDuration)
710708 let wxClaimed = parseIntValue(userRecordArray[IdxLockWxClaimed])
711- let gwxAmount = parseIntValue(userRecordArray[IdxLockGwxAmount])
712709 let t = ((height - lockStart) / blocksInPeriod)
713710 let exponent = fraction(toBigInt(t), (toBigInt((8 * blocksInPeriod)) * MULT18BI), toBigInt(lockDuration))
714711 let wxWithdrawable = if ((height > lockEnd))
715712 then userAmount
716713 else (toInt(fraction(toBigInt(userAmount), (MULT18BI - pow(toBigInt(5), 1, exponent, SCALE18, SCALE18, DOWN)), MULT18BI)) - wxClaimed)
717714 wxWithdrawable
718715 }
719716
720717
721718 @Callable(i)
722719 func constructor (factoryAddressStr,lockAssetIdStr,minLockAmount,minDuration,maxDuration,mathContract) = {
723720 let checkCaller = mustManager(i)
724721 if ((checkCaller == checkCaller))
725722 then ([IntegerEntry(keyNextUserNum(), 0), StringEntry(keyConfig(), formatConfig(lockAssetIdStr, minLockAmount, minDuration, maxDuration, mathContract)), StringEntry(keyFactoryAddress(), factoryAddressStr)] ++ StatsEntry(0, 0, 0, 0))
726723 else throw("Strict value is not equal to itself.")
727724 }
728725
729726
730727
731728 @Callable(i)
732729 func lockRef (duration,referrerAddress,signature) = {
733- let $t02942729492 = lockActions(i, duration)
734- let lockActionsResult = $t02942729492._1
735- let gWxAmountStart = $t02942729492._2
730+ let $t02930929374 = lockActions(i, duration)
731+ let lockActionsResult = $t02930929374._1
732+ let gWxAmountStart = $t02930929374._2
736733 let referralAddress = toString(i.caller)
737734 let refInv = if (if ((referrerAddress == ""))
738735 then true
739736 else (signature == base58''))
740737 then unit
741738 else invoke(referralsContractAddressOrFail, "createPair", [referralProgramName, referrerAddress, referralAddress, signature], nil)
742739 if ((refInv == refInv))
743740 then {
744741 let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
745742 if ((updateRefActivity == updateRefActivity))
746743 then $Tuple2(lockActionsResult, unit)
747744 else throw("Strict value is not equal to itself.")
748745 }
749746 else throw("Strict value is not equal to itself.")
750747 }
751748
752749
753750
754751 @Callable(i)
755752 func lock (duration) = {
756- let $t02995030015 = lockActions(i, duration)
757- let lockActionsResult = $t02995030015._1
758- let gWxAmountStart = $t02995030015._2
753+ let $t02983229897 = lockActions(i, duration)
754+ let lockActionsResult = $t02983229897._1
755+ let gWxAmountStart = $t02983229897._2
759756 let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
760757 if ((updateRefActivity == updateRefActivity))
761758 then $Tuple2(lockActionsResult, unit)
762759 else throw("Strict value is not equal to itself.")
763760 }
764761
765762
766763
767764 @Callable(i)
768765 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
769766 then throwErr("permissions denied")
770767 else {
771- let $t03032530427 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
772- let userBoostAvailable = $t03032530427._1
773- let dataState = $t03032530427._2
774- let debug = $t03032530427._3
768+ let $t03020730309 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
769+ let userBoostAvailable = $t03020730309._1
770+ let dataState = $t03020730309._2
771+ let debug = $t03020730309._3
775772 $Tuple2(dataState, [userBoostAvailable])
776773 }
777774
778775
779776
780777 @Callable(i)
781778 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
782- let $t03055930660 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
783- let userBoostAvailable = $t03055930660._1
784- let dataState = $t03055930660._2
785- let debug = $t03055930660._3
779+ let $t03044130542 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
780+ let userBoostAvailable = $t03044130542._1
781+ let dataState = $t03044130542._2
782+ let debug = $t03044130542._3
786783 $Tuple2(nil, [userBoostAvailable, debug])
787784 }
788785
789786
790787
791788 @Callable(i)
792789 func unlock (txIdStr) = {
793790 let userAddress = i.caller
794791 let userAddressStr = toString(userAddress)
795792 let txId = fromBase58String(txIdStr)
796793 let userRecordArray = readLockParamsRecordOrFail(userAddress, if ((txIdStr == ""))
797794 then unit
798795 else txId)
799796 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
800797 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
801798 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
802- let lockEnd = (lockStart + lockDuration)
803799 let wxClaimed = parseIntValue(userRecordArray[IdxLockWxClaimed])
804800 let gwxAmount = parseIntValue(userRecordArray[IdxLockGwxAmount])
805801 let t = ((height - lockStart) / blocksInPeriod)
806802 let wxWithdrawable = getWxWithdrawable(userAddress, if ((txIdStr == ""))
807803 then unit
808804 else txId)
809- let coeffX8 = fraction(lockDuration, MULT8, maxLockDuration)
810- let gWxAmountStart = fraction(userAmount, coeffX8, MULT8)
805+ let gWxAmountStart = fraction(userAmount, lockDuration, maxLockDuration)
811806 let gwxBurned = min([fraction((t * blocksInPeriod), gWxAmountStart, maxLockDuration), gwxAmount])
812807 let gwxRemaining = ensurePositive((gwxAmount - gwxBurned), "gwxRemaining")
813808 let lockedGwxAmount = getLockedGwxAmount(userAddress)
814809 if ((0 >= userAmount))
815810 then throwErr("nothing to unlock")
816811 else {
817812 let gwxAmountTotal = getGwxAmountTotal()
818813 let userGwxAmountTotal = getUserGwxAmountTotal(userAddress)
819814 let userGwxAmountTotalNew = ensurePositive((userGwxAmountTotal - gwxBurned), "userGwxAmountTotalNew")
820815 if ((lockedGwxAmount > userGwxAmountTotalNew))
821816 then throwErr(("locked gwx amount: " + toString(lockedGwxAmount)))
822817 else {
823818 let gwxRewardInv = reentrantInvoke(gwxRewardContract, "refreshUserReward", [userAddress.bytes], nil)
824819 if ((gwxRewardInv == gwxRewardInv))
825820 then ((((LockParamsEntry(userAddress, txId, userAmount, lockStart, lockDuration, gwxRemaining, (wxClaimed + wxWithdrawable)) ++ StatsEntry(-(wxWithdrawable), 0, 0, 0)) :+ HistoryEntry("unlock", userAddressStr, wxWithdrawable, lockStart, lockDuration, gwxBurned, i)) :+ ScriptTransfer(userAddress, wxWithdrawable, assetId)) ++ [IntegerEntry(keyGwxTotal(), ensurePositive((gwxAmountTotal - gwxBurned), "gwxTotal")), IntegerEntry(keyUserGwxAmountTotal(userAddress), userGwxAmountTotalNew)])
826821 else throw("Strict value is not equal to itself.")
827822 }
828823 }
829824 }
830825
831826
832827
833828 @Callable(i)
834829 func gwxUserInfoREADONLY (userAddressStr) = {
835830 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
836831 let gwxAmount = getUserGwxAmountTotal(userAddress)
837832 $Tuple2(nil, [gwxAmount])
838833 }
839834
840835
841836
842837 @Callable(i)
843838 func userMaxDurationREADONLY (userAddressStr) = $Tuple2(nil, $Tuple2("increaseLock", maxLockDuration))
844839
845840
846841
847842 @Callable(i)
848843 func getUserGwxAmountAtHeightREADONLY (userAddressStr,targetHeight) = {
849844 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
850845 let gwxAmount = getUserGwxAmountTotal(userAddress)
851846 $Tuple2(nil, gwxAmount)
852847 }
853848
854849
855850
856851 @Callable(i)
857852 func getUserGwxAmount (userAddressStr) = {
858853 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
859854 let gwxAmount = getUserGwxAmountTotal(userAddress)
860855 $Tuple2(nil, gwxAmount)
861856 }
862857
863858
864859
865860 @Callable(i)
866861 func getGwxTotalREADONLY () = $Tuple2(nil, getGwxAmountTotal())
867862
868863
869864
870865 @Callable(i)
871866 func onBoostEmissionUpdate () = {
872867 let checkCaller = if ((i.caller == emissionContract))
873868 then true
874869 else mustManager(i)
875870 if ((checkCaller == checkCaller))
876871 then refreshBoostEmissionIntegral()
877872 else throw("Strict value is not equal to itself.")
878873 }
879874
880875
881876
882877 @Callable(i)
883878 func onStakedVoteUpdate (lpAssetIdStr,userAddressStr,edge) = {
884879 let checkCaller = if ((i.caller == stakingContract))
885880 then true
886881 else mustManager(i)
887882 if ((checkCaller == checkCaller))
888883 then {
889884 let actions = refreshVoteStakedIntegral(lpAssetIdStr, userAddressStr, edge)
890885 $Tuple2(actions, unit)
891886 }
892887 else throw("Strict value is not equal to itself.")
893888 }
894889
895890
896891
897892 @Callable(i)
898893 func getVotingResultStakedREADONLY (lpAssetIdStr) = $Tuple2(nil, getVotingResultStaked(lpAssetIdStr))
899894
900895
901896
902897 @Callable(i)
903898 func getVotingResultStakedIntegralREADONLY (lpAssetIdStr) = $Tuple2(nil, getVotingResultStakedIntegral(lpAssetIdStr))
904899
905900
906901
907902 @Callable(i)
908903 func getUserVoteFinalizedREADONLY (lpAssetIdStr,userAddressStr) = $Tuple2(nil, getUserVoteFinalized(lpAssetIdStr, userAddressStr))
909904
910905
911906
912907 @Callable(i)
913908 func getUserVoteStakedIntegralREADONLY (lpAssetIdStr,userAddressStr) = $Tuple2(nil, getUserVoteStakedIntegral(lpAssetIdStr, userAddressStr))
914909
915910
916911 @Verifier(tx)
917912 func verify () = {
918913 let targetPublicKey = match managerPublicKeyOrUnit() {
919914 case pk: ByteVector =>
920915 pk
921916 case _: Unit =>
922917 tx.senderPublicKey
923918 case _ =>
924919 throw("Match error")
925920 }
926921 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
927922 }
928923

github/deemru/w8io/026f985 
171.64 ms