tx · GL9kJKSTJswuHRxcWnZuSZikRskFLmDWWaxfsobkfGYv

3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy:  -0.02300000 Waves

2022.12.02 18:35 [2342912] smart account 3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy > SELF 0.00000000 Waves

{ "type": 13, "id": "GL9kJKSTJswuHRxcWnZuSZikRskFLmDWWaxfsobkfGYv", "fee": 2300000, "feeAssetId": null, "timestamp": 1669995327546, "version": 1, "sender": "3Myn55vLkduxbX3ZXfiDCZhaQsLxYp1kmCy", "senderPublicKey": "9W33iCCNfmFxUbiC6XZcH5x7f6xfwC7Jb3BoExT5q2PV", "proofs": [ "2tRne2ANc913SsjJdodGRts6kfNSEtDmD9FTWGqDCYDkL11DmBSTucS6oqEQUawXse7qRjApGosdjFJPodgBvvUt" ], "script": "base64:BgLnJQgCEggKBggIAQEBCBIFCgMBCAISAwoBARIDCgEBEgQKAggIEgQKAggIEgMKAQgSAwoBCBIECgIIARIAEgMKAQgSACIDU0VQIgZTQ0FMRTgiBU1VTFQ4Ig5QT09MV0VJR0hUTVVMVCIEc3RyZiIHYWRkcmVzcyIDa2V5IgNpb3oiA2lvZCIKZGVmYXVsdFZhbCIDaW9mIgNhYnMiA3ZhbCIDYWFsIgckbWF0Y2gwIgp2YWxBbnlMeXN0IgJhaSIGdmFsSW50IhtrZXlSZWZlcnJhbHNDb250cmFjdEFkZHJlc3MiHnJlZmVycmFsc0NvbnRyYWN0QWRkcmVzc09yRmFpbCIWa2V5UmVmZXJyYWxQcm9ncmFtTmFtZSIacmVmZXJyYWxQcm9ncmFtTmFtZURlZmF1bHQiE3JlZmVycmFsUHJvZ3JhbU5hbWUiEWtleUZhY3RvcnlBZGRyZXNzIhhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHAiGUlkeEZhY3RvcnlDZmdCb29zdGluZ0RhcHAiFElkeEZhY3RvcnlDZmdJZG9EYXBwIhVJZHhGYWN0b3J5Q2ZnVGVhbURhcHAiGUlkeEZhY3RvcnlDZmdFbWlzc2lvbkRhcHAiFUlkeEZhY3RvcnlDZmdSZXN0RGFwcCIZSWR4RmFjdG9yeUNmZ1NsaXBwYWdlRGFwcCIUSWR4RmFjdG9yeUNmZ0Rhb0RhcHAiGklkeEZhY3RvcnlDZmdNYXJrZXRpbmdEYXBwIhpJZHhGYWN0b3J5Q2ZnR3d4UmV3YXJkRGFwcCIWSWR4RmFjdG9yeUNmZ0JpcmRzRGFwcCINa2V5RmFjdG9yeUNmZyIaa2V5RmFjdG9yeUxwMkFzc2V0c01hcHBpbmciCmxwQXNzZXRTdHIiEGtleUZhY3RvcnlMcExpc3QiJmtleUZhY3RvcnlMcEFzc2V0VG9Qb29sQ29udHJhY3RBZGRyZXNzIhRrZXlGYWN0b3J5UG9vbFdlaWdodCIPY29udHJhY3RBZGRyZXNzIhtrZXlGYWN0b3J5UG9vbFdlaWdodEhpc3RvcnkiC3Bvb2xBZGRyZXNzIgNudW0iGHJlYWRGYWN0b3J5QWRkcmVzc09yRmFpbCIKcmVhZExwTGlzdCIUcmVhZEZhY3RvcnlDZmdPckZhaWwiB2ZhY3RvcnkiGGdldEJvb3N0aW5nQWRkcmVzc09yRmFpbCIKZmFjdG9yeUNmZyIYZ2V0RW1pc3Npb25BZGRyZXNzT3JGYWlsIhdnZXRTdGFraW5nQWRkcmVzc09yRmFpbCIZZ2V0R3d4UmV3YXJkQWRkcmVzc09yRmFpbCITa2V5TWFuYWdlclB1YmxpY0tleSIaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkiHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudCIha2V5RW1pc3Npb25SYXRlUGVyQmxvY2tNYXhDdXJyZW50IhVrZXlFbWlzc2lvblN0YXJ0QmxvY2siG2tleUVtaXNzaW9uRHVyYXRpb25JbkJsb2NrcyITa2V5RW1pc3Npb25FbmRCbG9jayINa2V5TmV4dFBlcmlvZCIfa2V5R3d4UmV3YXJkRW1pc3Npb25TdGFydEhlaWdodCINSWR4Q2ZnQXNzZXRJZCITSWR4Q2ZnTWluTG9ja0Ftb3VudCIVSWR4Q2ZnTWluTG9ja0R1cmF0aW9uIhVJZHhDZmdNYXhMb2NrRHVyYXRpb24iEklkeENmZ01hdGhDb250cmFjdCIJa2V5Q29uZmlnIhVyZWFkQ29uZmlnQXJyYXlPckZhaWwiDG1hdGhDb250cmFjdCINZm9ybWF0Q29uZmlnUyIHYXNzZXRJZCINbWluTG9ja0Ftb3VudCIPbWluTG9ja0R1cmF0aW9uIg9tYXhMb2NrRHVyYXRpb24iDGZvcm1hdENvbmZpZyIWbWFuYWdlclB1YmxpY0tleU9yVW5pdCIBcyIdcGVuZGluZ01hbmFnZXJQdWJsaWNLZXlPclVuaXQiC211c3RNYW5hZ2VyIgFpIgJwZCICcGsiDklkeExvY2tVc2VyTnVtIg1JZHhMb2NrQW1vdW50IgxJZHhMb2NrU3RhcnQiD0lkeExvY2tEdXJhdGlvbiINSWR4TG9ja1BhcmFtSyINSWR4TG9ja1BhcmFtQiITa2V5TG9ja1BhcmFtc1JlY29yZCILdXNlckFkZHJlc3MiGnJlYWRMb2NrUGFyYW1zUmVjb3JkT3JGYWlsIhdmb3JtYXRMb2NrUGFyYW1zUmVjb3JkUyIHdXNlck51bSIGYW1vdW50IgVzdGFydCIIZHVyYXRpb24iBnBhcmFtSyIGcGFyYW1CIhBsYXN0VXBkVGltZXN0YW1wIglnd3hBbW91bnQiFmZvcm1hdExvY2tQYXJhbXNSZWNvcmQiDmtleU5leHRVc2VyTnVtIhJrZXlVc2VyMk51bU1hcHBpbmciEmtleU51bTJVc2VyTWFwcGluZyIWa2V5TG9ja1BhcmFtVXNlckFtb3VudCIWa2V5TG9ja1BhcmFtU3RhcnRCbG9jayIUa2V5TG9ja1BhcmFtRHVyYXRpb24iDWtleUxvY2tQYXJhbUsiDWtleUxvY2tQYXJhbUIiFWtleUxvY2tQYXJhbUJ5UGVyaW9kSyIGcGVyaW9kIhVrZXlMb2NrUGFyYW1CeVBlcmlvZEIiF2tleUxvY2tQYXJhbVRvdGFsQW1vdW50IiBrZXlTdGF0c0xvY2tzRHVyYXRpb25TdW1JbkJsb2NrcyISa2V5U3RhdHNMb2Nrc0NvdW50IhJrZXlTdGF0c1VzZXJzQ291bnQiIGtleVVzZXJCb29zdEVtaXNzaW9uTGFzdElOVEVHUkFMIiJrZXlVc2VyTHBCb29zdEVtaXNzaW9uTGFzdElOVEVHUkFMIglscEFzc2V0SWQiF2tleVVzZXJNYXhCb29zdElOVEVHUkFMIhhrZXlUb3RhbE1heEJvb3N0SU5URUdSQUwiIWtleVVzZXJCb29zdEF2YWxhaWJsZVRvQ2xhaW1Ub3RhbCITa2V5VXNlckJvb3N0Q2xhaW1lZCIRa2V5VG90YWxDYWNoZWRHd3giG2tleVRvdGFsQ2FjaGVkR3d4Q29ycmVjdGl2ZSIPZmFjdG9yeUNvbnRyYWN0IhBlbWlzc2lvbkNvbnRyYWN0Ig9zdGFraW5nQ29udHJhY3QiEWd3eFJld2FyZENvbnRyYWN0IhFnZXRUb3RhbENhY2hlZEd3eCIHY29ycmVjdCIZa2V5Vm90aW5nRW1pc3Npb25Db250cmFjdCIWdm90aW5nRW1pc3Npb25Db250cmFjdCIRa2V5Q3VycmVudEVwb2NoVWkiDmN1cnJlbnRFcG9jaFVpIg5rZXlUYXJnZXRFcG9jaCIRdGFyZ2V0RXBvY2hPcHRpb24iEXRvdGFsQ2FjaGVkR3d4UmF3IhVpc0NvcnJlY3Rpb25BY3RpdmF0ZWQiCmNvcnJlY3RpdmUiDEhpc3RvcnlFbnRyeSIEdHlwZSIEdXNlciIJbG9ja1N0YXJ0IgFrIgFiIgpoaXN0b3J5S0VZIgtoaXN0b3J5REFUQSIKU3RhdHNFbnRyeSIOdG90YWxMb2NrZWRJbmMiC2R1cmF0aW9uSW5jIgxsb2NrQ291bnRJbmMiDXVzZXJzQ291bnRJbmMiG2xvY2tzRHVyYXRpb25TdW1JbkJsb2Nrc0tFWSINbG9ja3NDb3VudEtFWSINdXNlcnNDb3VudEtFWSIOdG90YWxBbW91bnRLRVkiGGxvY2tzRHVyYXRpb25TdW1JbkJsb2NrcyIKbG9ja3NDb3VudCIKdXNlcnNDb3VudCILdG90YWxBbW91bnQiDWNhbGNHd3hBbW91bnQiBGtSYXciBGJSYXciAWgiBVNDQUxFIg9Mb2NrUGFyYW1zRW50cnkiDXVzZXJBbW91bnRLRVkiDXN0YXJ0QmxvY2tLRVkiC2R1cmF0aW9uS0VZIgRrS0VZIgRiS0VZIgxrQnlQZXJpb2RLRVkiDGJCeVBlcmlvZEtFWSIiZXh0cmFjdE9wdGlvbmFsUGF5bWVudEFtb3VudE9yRmFpbCIPZXhwZWN0ZWRBc3NldElkIgNwbXQiGWNhbGNVc2VyR3d4QW1vdW50QXRIZWlnaHQiDHRhcmdldEhlaWdodCIFRU1QVFkiEnVzZXIyTnVtTWFwcGluZ0tFWSINZ3d4QW1vdW50Q2FsYyIUY2FsY0N1cnJlbnRHd3hBbW91bnQiFGludGVybmFsQ2xhaW1XeEJvb3N0IgxscEFzc2V0SWRTdHIiDnVzZXJBZGRyZXNzU3RyIghyZWFkT25seSIRdXNlclJlY29yZE9yRW1wdHkiD3VzZXJSZWNvcmRBcnJheSIKdXNlck51bVN0ciIcZ3d4UmV3YXJkRW1pc3Npb25TdGFydEhlaWdodCIIRU1QVFlTVFIiDSR0MDE0OTYzMTU1MzEiDnBvb2xBZGRyZXNzU3RyIgNwdzEiA3B3MCILcG9vbFdlaWdodDAiC3Bvb2xXZWlnaHQxIhJ3eEVtaXNzaW9uUGVyQmxvY2siDWVtaXNzaW9uU3RhcnQiC2VtaXNzaW9uRW5kIgJkaCIidXNlckxwQm9vc3RFbWlzc2lvbkxhc3RJbnRlZ3JhbEtFWSIgdXNlckJvb3N0RW1pc3Npb25MYXN0SW50ZWdyYWxLRVkiHXVzZXJCb29zdEVtaXNzaW9uTGFzdEludGVncmFsIhVib29zdEVtaXNzaW9uSW50ZWdyYWwiGXVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwiA3VkaCIGdUxhc3RIIgR1ZGgwIgR1ZGgxIhd1c2VyTWF4Qm9vc3RJbnRlZ3JhbEtFWSIYdG90YWxNYXhCb29zdEludGVncmFsS0VZIg91c2VyTWF4Qm9vc3RJbnQiEHRvdGFsTWF4Qm9vc3RJbnQiF3RvdGFsQ2FjaGVkR3d4Q29ycmVjdGVkIgt1c2VyQ3Vyckd3eCIhdXNlckJvb3N0QXZhbGFpYmxlVG9DbGFpbVRvdGFsS0VZIh51c2VyQm9vc3RBdmFsaWFibGVUb0NsYWltVG90YWwiGnVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwwIhp1c2VyQm9vc3RFbWlzc2lvbkludGVncmFsMSIecG9vbFVzZXJCb29zdEVtaXNzaW9uSW50ZWdyYWwwIh5wb29sVXNlckJvb3N0RW1pc3Npb25JbnRlZ3JhbDEiInVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbE5ldzAiInVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbE5ldzEiIXVzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbE5ldyITdXNlckJvb3N0Q2xhaW1lZEtFWSIQdXNlckJvb3N0Q2xhaW1lZCISdXNlckJvb3N0QXZhaWxhYmxlIglkYXRhU3RhdGUiBWRlYnVnIgtsb2NrQWN0aW9ucyIIY2ZnQXJyYXkiCmFzc2V0SWRTdHIiCXBtdEFtb3VudCIObmV4dFVzZXJOdW1LRVkiDnVzZXJJc0V4aXN0aW5nIgdjb2VmZlg4Ig5nV3hBbW91bnRTdGFydCITZ1d4UGFyYW1zUmVzdWx0TGlzdCIDYXJyIhFmYWN0b3J5QWRkcmVzc1N0ciIObG9ja0Fzc2V0SWRTdHIiC21pbkR1cmF0aW9uIgttYXhEdXJhdGlvbiILY2hlY2tDYWxsZXIiD3JlZmVycmVyQWRkcmVzcyIJc2lnbmF0dXJlIg0kdDAyMzg5MDIzOTU1IhFsb2NrQWN0aW9uc1Jlc3VsdCIPcmVmZXJyYWxBZGRyZXNzIgZyZWZJbnYiEXVwZGF0ZVJlZkFjdGl2aXR5Ig0kdDAyNDQxMzI0NDc4Ig1kZWx0YUR1cmF0aW9uIgp1c2VyQW1vdW50Igxsb2NrRHVyYXRpb24iB2xvY2tFbmQiEXJlbWFpbmluZ0R1cmF0aW9uIg11c2VyQW1vdW50TmV3Ig9sb2NrRHVyYXRpb25OZXciDGxvY2tTdGFydE5ldyILY3VyclVzZXJHd3giB2d3eERpZmYiEnVzZXJNYXhCb29zdEludE5ldyIYcmVtYWluaW5nVXNlck1heEJvb3N0SW50IhN1c2VyTWF4Qm9vc3RJbnREaWZmIg0kdDAyOTQ1OTI5NTYxIg0kdDAyOTY5MzI5Nzk0IhdwZW5kaW5nTWFuYWdlclB1YmxpY0tleSIVY2hlY2tNYW5hZ2VyUHVibGljS2V5IgJwbSIFaGFzUE0iB2NoZWNrUE0iAnR4IgZ2ZXJpZnkiD3RhcmdldFB1YmxpY0tleW4AAWECAl9fAAFiAAgAAWMAgMLXLwABZAUBYwEBZQIBZgFnCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUBZgUBZwkArAICCQCsAgICD21hbmRhdG9yeSB0aGlzLgUBZwIPIGlzIG5vdCBkZWZpbmVkAQFoAgFmAWcJAQt2YWx1ZU9yRWxzZQIJAJoIAgUBZgUBZwAAAQFpAwFmAWcBagkBC3ZhbHVlT3JFbHNlAgkAmggCBQFmBQFnBQFqAQFrAgFmAWcJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQFmBQFnCQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQFnAg8gaXMgbm90IGRlZmluZWQBAWwBAW0DCQBmAgAABQFtCQEBLQEFAW0FAW0BAW4BAW0EAW8FAW0DCQABAgUBbwIJTGlzdFtBbnldBAFwBQFvBQFwCQACAQIbZmFpbCB0byBjYXN0IGludG8gTGlzdFtBbnldAQFxAQFtBAFvBQFtAwkAAQIFAW8CA0ludAQBcgUBbwUBcgkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEBcwAJALkJAgkAzAgCAgQlcyVzCQDMCAICBmNvbmZpZwkAzAgCAhhyZWZlcnJhbHNDb250cmFjdEFkZHJlc3MFA25pbAUBYQABdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAWUCBQR0aGlzCQEBcwAAAXUJALkJAgkAzAgCAgQlcyVzCQDMCAICCHJlZmVycmFsCQDMCAICC3Byb2dyYW1OYW1lBQNuaWwFAWEAAXYCBnd4bG9jawABdwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQF1BQF2AQF4AAIcJXMlc19fY29uZmlnX19mYWN0b3J5QWRkcmVzcwABeQABAAF6AAIAAUEAAwABQgAEAAFDAAUAAUQABgABRQAHAAFGAAgAAUcACQABSAAKAAFJAAsBAUoAAhElc19fZmFjdG9yeUNvbmZpZwEBSwEBTAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQFMCQDMCAICHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUDbmlsBQFhAQFNAAIQJXNfX2xwVG9rZW5zTGlzdAEBTgEBTAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQFMCQDMCAICHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUDbmlsBQFhAQFPAQFQCQC5CQIJAMwIAgIEJXMlcwkAzAgCAgpwb29sV2VpZ2h0CQDMCAIFAVAFA25pbAUBYQEBUQIBUgFTCQCsAgIJAKwCAgkArAICAhIlcyVzX19wb29sV2VpZ2h0X18FAVICAl9fCQCkAwEFAVMBAVQACQERQGV4dHJOYXRpdmUoMTA2MikBCQEBZQIFBHRoaXMJAQF4AAEBVQAJALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCCQEBVAAJAQFNAAIABQFhAQFWAQFXCQC1CQIJAQFlAgUBVwkBAUoABQFhAQFYAQFZCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFAVkFAXoBAVoBAVkJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUBWQUBQwECYWEBAVkJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUBWQUBeQECYWIBAVkJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUBWQUBSAECYWMAAhQlc19fbWFuYWdlclB1YmxpY0tleQECYWQAAhslc19fcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkBAmFlAAIbJXMlc19fcmF0ZVBlckJsb2NrX19jdXJyZW50AQJhZgACHiVzJXNfX3JhdGVQZXJCbG9ja01heF9fY3VycmVudAECYWcAAholcyVzX19lbWlzc2lvbl9fc3RhcnRCbG9jawECYWgAAhglcyVzX19lbWlzc2lvbl9fZHVyYXRpb24BAmFpAAIYJXMlc19fZW1pc3Npb25fX2VuZEJsb2NrAQJhagACDiVzX19uZXh0UGVyaW9kAQJhawACKCVzJXNfX2d3eFJld2FyZEVtaXNzaW9uUGFydF9fc3RhcnRIZWlnaHQAAmFsAAEAAmFtAAIAAmFuAAMAAmFvAAQAAmFwAAUBAmFxAAIKJXNfX2NvbmZpZwECYXIACQC1CQIJAQFlAgUEdGhpcwkBAmFxAAUBYQACYXMJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgkBAmFyAAUCYXABAmF0BQJhdQJhdgJhdwJheAJhcwkAuQkCCQDMCAICCCVzJWQlZCVkCQDMCAIFAmF1CQDMCAIFAmF2CQDMCAIFAmF3CQDMCAIFAmF4CQDMCAIFAmFzBQNuaWwFAWEBAmF5BQJhdQJhdgJhdwJheAJhcwkBAmF0BQUCYXUJAKQDAQUCYXYJAKQDAQUCYXcJAKQDAQUCYXgFAmFzAQJhegAEAW8JAKIIAQkBAmFjAAMJAAECBQFvAgZTdHJpbmcEAmFBBQFvCQDZBAEFAmFBAwkAAQIFAW8CBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgECYUIABAFvCQCiCAEJAQJhZAADCQABAgUBbwIGU3RyaW5nBAJhQQUBbwkA2QQBBQJhQQMJAAECBQFvAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmFDAQJhRAQCYUUJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQBbwkBAmF6AAMJAAECBQFvAgpCeXRlVmVjdG9yBAJhRgUBbwMJAAACCAUCYUQPY2FsbGVyUHVibGljS2V5BQJhRgYFAmFFAwkAAQIFAW8CBFVuaXQDCQAAAggFAmFEBmNhbGxlcgUEdGhpcwYFAmFFCQACAQILTWF0Y2ggZXJyb3IAAmFHAAEAAmFIAAIAAmFJAAMAAmFKAAQAAmFLAAUAAmFMAAYBAmFNAQJhTgkAuQkCCQDMCAICCiVzJXNfX2xvY2sJAMwIAgUCYU4FA25pbAUBYQECYU8BAmFOCQC1CQIJAQFlAgUEdGhpcwkBAmFNAQUCYU4FAWEBAmFQCAJhUQJhUgJhUwJhVAJhVQJhVgJhVwJhWAkAuQkCCQDMCAICECVkJWQlZCVkJWQlZCVkJWQJAMwIAgUCYVEJAMwIAgUCYVIJAMwIAgUCYVMJAMwIAgUCYVQJAMwIAgUCYVUJAMwIAgUCYVYJAMwIAgUCYVcJAMwIAgUCYVgFA25pbAUBYQECYVkHAmFRAmFSAmFTAmFUAmFVAmFWAmFYCQECYVAIBQJhUQkApAMBBQJhUgkApAMBBQJhUwkApAMBBQJhVAkApAMBBQJhVQkApAMBBQJhVgkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkApAMBBQJhWAECYVoAAg8lc19fbmV4dFVzZXJOdW0BAmJhAQJhTgkAuQkCCQDMCAICGSVzJXMlc19fbWFwcGluZ19fdXNlcjJudW0JAMwIAgUCYU4FA25pbAUBYQECYmIBAVMJALkJAgkAzAgCAhklcyVzJXNfX21hcHBpbmdfX251bTJ1c2VyCQDMCAIFAVMFA25pbAUBYQECYmMBAmFRCQC5CQIJAMwIAgIWJXMlZCVzX19wYXJhbUJ5VXNlck51bQkAzAgCBQJhUQkAzAgCAgZhbW91bnQFA25pbAUBYQECYmQBAmFRCQC5CQIJAMwIAgIWJXMlZCVzX19wYXJhbUJ5VXNlck51bQkAzAgCBQJhUQkAzAgCAgVzdGFydAUDbmlsBQFhAQJiZQECYVEJALkJAgkAzAgCAhYlcyVkJXNfX3BhcmFtQnlVc2VyTnVtCQDMCAIFAmFRCQDMCAICCGR1cmF0aW9uBQNuaWwFAWEBAmJmAQJhUQkAuQkCCQDMCAICFiVzJWQlc19fcGFyYW1CeVVzZXJOdW0JAMwIAgUCYVEJAMwIAgIBawUDbmlsBQFhAQJiZwECYVEJALkJAgkAzAgCAhYlcyVkJXNfX3BhcmFtQnlVc2VyTnVtCQDMCAIFAmFRCQDMCAICAWIFA25pbAUBYQECYmgCAmFRAmJpCQC5CQIJAMwIAgIXJXMlZCVzJWRfX3BhcmFtQnlQZXJpb2QJAMwIAgUCYVEJAMwIAgIBawkAzAgCBQJiaQUDbmlsBQFhAQJiagICYVECYmkJALkJAgkAzAgCAhclcyVkJXMlZF9fcGFyYW1CeVBlcmlvZAkAzAgCBQJhUQkAzAgCAgFiCQDMCAIFAmJpBQNuaWwFAWEBAmJrAAIeJXMlc19fc3RhdHNfX2FjdGl2ZVRvdGFsTG9ja2VkAQJibAACJSVzJXNfX3N0YXRzX19sb2Nrc0R1cmF0aW9uU3VtSW5CbG9ja3MBAmJtAAIXJXMlc19fc3RhdHNfX2xvY2tzQ291bnQBAmJuAAIdJXMlc19fc3RhdHNfX2FjdGl2ZVVzZXJzQ291bnQBAmJvAQJhUQkAuQkCCQDMCAICHiVzJWRfX3VzZXJCb29zdEVtaXNzaW9uTGFzdEludAkAzAgCBQJhUQUDbmlsBQFhAQJicAICYVECYnEJALkJAgkAzAgCAh4lcyVkX191c2VyQm9vc3RFbWlzc2lvbkxhc3RJbnQJAMwIAgUCYVEJAMwIAgUCYnEFA25pbAUBYQECYnIBAmFRCQC5CQIJAMwIAgIRJXMlZF9fbWF4Qm9vc3RJbnQJAMwIAgUCYVEFA25pbAUBYQECYnMAAhglcyVzX19tYXhCb29zdEludF9fdG90YWwBAmJ0AQJhUQkAuQkCCQDMCAICJCVzJWRfX3VzZXJCb29zdEF2YWxpYWJsZVRvQ2xhaW1Ub3RhbAkAzAgCBQJhUQUDbmlsBQFhAQJidQECYVEJALkJAgkAzAgCAhYlcyVkX191c2VyQm9vc3RDbGFpbWVkCQDMCAIFAmFRBQNuaWwFAWEBAmJ2AAIWJXMlc19fZ3d4Q2FjaGVkX190b3RhbAECYncAAhwlc19fZ3d4Q2FjaGVkVG90YWxDb3JyZWN0aXZlAAJieAkBAVQAAAFZCQEBVgEFAmJ4AAJieQkBAVoBBQFZAAJiegkBAmFhAQUBWQACYkEJAQJhYgEFAVkBAmJCAQJiQwQCYkQJALkJAgkAzAgCAgIlcwkAzAgCAhZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0BQNuaWwFAWEEAmJFCQERQGV4dHJOYXRpdmUoMTA2MikBCQERQGV4dHJOYXRpdmUoMTA1MykCBQJieAUCYkQEAmJGCQC5CQIJAMwIAgICJXMJAMwIAgIOY3VycmVudEVwb2NoVWkFA25pbAUBYQQCYkcJARFAZXh0ck5hdGl2ZSgxMDUwKQIFAmJFBQJiRgQCYkgJALkJAgkAzAgCAgIlcwkAzAgCAil0b3RhbENhY2hlZEd3eENvcnJlY3Rpb25fX2FjdGl2YXRpb25FcG9jaAUDbmlsBQFhBAJiSQkAmggCBQR0aGlzBQJiSAQCYkoJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmJ2AAAABAJiSwMJAQlpc0RlZmluZWQBBQJiSQkAZwIFAmJHCQEFdmFsdWUBBQJiSQcEAmJMAwMFAmJLBQJiQwcJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmJ3AAAAAAAJAJYDAQkAzAgCAAAJAMwIAgkAZAIFAmJKBQJiTAUDbmlsAQJiTQgCYk4CYk8CYVICYlACYVQCYlECYlICYUQEAmJTCQC5CQIJAMwIAgIRJXMlcyVzJXNfX2hpc3RvcnkJAMwIAgUCYk4JAMwIAgUCYk8JAMwIAgkA2AQBCAUCYUQNdHJhbnNhY3Rpb25JZAUDbmlsBQFhBAJiVAkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQgFCWxhc3RCbG9jawZoZWlnaHQJAMwIAgkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQCkAwEFAmFSCQDMCAIJAKQDAQUCYlAJAMwIAgkApAMBBQJhVAkAzAgCCQCkAwEFAmJRCQDMCAIJAKQDAQUCYlIFA25pbAUBYQkBC1N0cmluZ0VudHJ5AgUCYlMFAmJUAQJiVQQCYlYCYlcCYlgCYlkEAmJaCQECYmwABAJjYQkBAmJtAAQCY2IJAQJibgAEAmNjCQECYmsABAJjZAkBAWgCBQR0aGlzBQJiWgQCY2UJAQFoAgUEdGhpcwUCY2EEAmNmCQEBaAIFBHRoaXMFAmNiBAJjZwkBAWgCBQR0aGlzBQJjYwkAzAgCCQEMSW50ZWdlckVudHJ5AgUCYloJAGQCBQJjZAUCYlcJAMwIAgkBDEludGVnZXJFbnRyeQIFAmNhCQBkAgUCY2UFAmJYCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJjYgkAZAIFAmNmBQJiWQkAzAgCCQEMSW50ZWdlckVudHJ5AgUCY2MJAGQCBQJjZwUCYlYFA25pbAECY2gDAmNpAmNqAmNrBAJjbADoBwkAaQIJAGQCCQBoAgUCY2kFAmNrBQJjagUCY2wBAmNtCAJhTgJhUQJhUgJhUwJhVAJiUQJiUgJiaQQCY24JAQJiYwEFAmFRBAJjbwkBAmJkAQUCYVEEAmNwCQECYmUBBQJhUQQCY3EJAQJiZgEFAmFRBAJjcgkBAmJnAQUCYVEEAmNzCQECYmgCBQJhUQUCYmkEAmN0CQECYmoCBQJhUQUCYmkEAmFYCQECY2gDBQJiUQUCYlIFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUCY24FAmFSCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJjbwUCYVMJAMwIAgkBDEludGVnZXJFbnRyeQIFAmNwBQJhVAkAzAgCCQEMSW50ZWdlckVudHJ5AgUCY3EFAmJRCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJjcgUCYlIJAMwIAgkBDEludGVnZXJFbnRyeQIFAmNzBQJiUQkAzAgCCQEMSW50ZWdlckVudHJ5AgUCY3QFAmJSCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhTQEFAmFOCQECYVkHBQJhUQUCYVIFAmFTBQJhVAUCYlEFAmJSBQJhWAUDbmlsAQJjdQICYUQCY3YDCQBmAgkAkAMBCAUCYUQIcGF5bWVudHMAAQkAAgECG29ubHkgb25lIHBheW1lbnQgaXMgYWxsb3dlZAMJAAACCQCQAwEIBQJhRAhwYXltZW50cwAAAAAEAmN3CQCRAwIIBQJhRAhwYXltZW50cwAAAwkBAiE9AgkBBXZhbHVlAQgFAmN3B2Fzc2V0SWQFAmN2CQACAQIbaW52YWxpZCBhc3NldCBpZCBpbiBwYXltZW50CAUCY3cGYW1vdW50AQJjeAICYU4CY3kEAmN6AgVlbXB0eQQCY0EJAQJiYQEFAmFOBAJhUQkBC3ZhbHVlT3JFbHNlAgkAoggBBQJjQQUCY3oEAmJRCQELdmFsdWVPckVsc2UCCQCfCAEJAQJiZgEFAmFRAAAEAmJSCQELdmFsdWVPckVsc2UCCQCfCAEJAQJiZwEFAmFRAAAEAmNCCQECY2gDBQJiUQUCYlIFAmN5BAJhWAMJAGYCAAAFAmNCAAAFAmNCBQJhWAECY0MBAmFOCQECY3gCBQJhTgUGaGVpZ2h0AQJjRAMCY0UCY0YCY0cEAmN6AgVFTVBUWQQCY0gJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBAmFNAQUCY0YFAmN6AwkAAAIFAmNIBQJjegkAlQoDAAAFA25pbAIVdXNlclJlY29yZDo6aXM6OmVtcHR5BAJjSQkAtQkCBQJjSAUBYQQCY0oJAJEDAgUCY0kFAmFHBAJjSwkBC3ZhbHVlT3JFbHNlAgkAmggCBQJiQQkBAmFrAAAABAJjTAIFZW1wdHkEAmNNAwkBAiE9AgUCY0UFAmNMBAJjTgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFAmJ4CQEBSwEFAmNFCQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUCY0UEAmNPCQERQGV4dHJOYXRpdmUoMTA1MCkCBQJieAkBAU8BBQJjTgQCY1AJAQt2YWx1ZU9yRWxzZQIJAJoIAgUCYngJAQFRAgUCY04AAAUCY08JAJQKAgUCY1AFAmNPAwUCY0cJAJQKAgAAAAAJAAIBCQCsAgICKG5vdCByZWFkb25seSBtb2RlOiB1bnN1cHBvcnRlZCBscCBhc3NldCAFAmNFBAJjUQgFAmNNAl8xBAJjUggFAmNNAl8yBAJjUwkBAWsCBQJieQkBAmFlAAQCY1QJAQFrAgUCYnkJAQJhZwAEAmNVCQEBawIFAmJ5CQECYWkABAJjawMJAGYCBQZoZWlnaHQFAmNVBQJjVQUGaGVpZ2h0BAJjVgkAlgMBCQDMCAIJAGUCBQJjawUCY1QJAMwIAgAABQNuaWwEAmNXCQECYnACBQJjSgUCY0UEAmNYCQECYm8BBQJjSgQCY1kJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUCY1cJAQFoAgUEdGhpcwUCY1gEAmNaCQBpAgkAaAIJAGgCBQJjUwUCY1YAAgADBAJkYQkAZQIFAmNaBQJjWQQCZGIJAGsDBQJkYQADCQBoAgACBQJjUwQCZGMJAGUCBQJjawUCZGIEAmRkCQCWAwEJAMwIAgkAZQIFAmNLBQJkYwkAzAgCAAAFA25pbAQCZGUJAGUCCQBlAgUCY2sFAmRjBQJkZAMDAwkAZgIAAAUCZGMGCQBmAgAABQJkZQYJAGcCCQEBbAEJAGUCCQBkAgUCZGQFAmRlBQJkYgABCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAhZpbnZhbGlkIHVkaCBjYWxjOiB1ZGg9CQCkAwEFAmRiAgggdUxhc3RIPQkApAMBBQJkYwIGIHVkaDA9CQCkAwEFAmRkAgYgdWRoMT0JAKQDAQUCZGUDCQBmAgAABQJkYQkAAgECEndyb25nIGNhbGN1bGF0aW9ucwQCZGYJAQJicgEFAmNKBAJkZwkBAmJzAAQCZGgJAQFoAgUEdGhpcwUCZGYEAmRpCQEBaAIFBHRoaXMFAmRnBAJkagkBAmJCAQYEAmRrCQECY0MBBQJjRgQCZGwJAQJidAEFAmNKBAJkbQkBAWgCBQR0aGlzBQJkbAQCZG4DCQAAAgUCZGIAAAAACQBrAwUCZGEFAmRkBQJkYgQCZG8DCQAAAgUCZGIAAAAACQBrAwUCZGEFAmRlBQJkYgQCZHAJAGsDBQJkbgUCY1EFAWQEAmRxCQBrAwUCZG8FAmNSBQFkBAJkcgMJAAACBQJkagAAAAAJAGsDBQJkcAUCZGsFAmRqBAJkcwMJAAACBQJkagAAAAAJAGsDBQJkcQUCZGsFAmRqBAJkdAkAZAIFAmRyBQJkcwQCZHUJAQJidQEFAmNKBAJkdgkBAWgCBQR0aGlzBQJkdQQCZHcJAGUCBQJkdAUCZHYEAmR4CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJjVwUCY1oFA25pbAQCZHkJALkJAgkAzAgCCQCkAwEFAmNZCQDMCAIJAKQDAQUCZGEJAMwIAgkApAMBBQJkdgkAzAgCCQCkAwEFAmR3CQDMCAIJAKQDAQUCY1EJAMwIAgkApAMBBQJjUgkAzAgCCQCkAwEFAmNrCQDMCAIJAKQDAQUCZGIJAMwIAgkApAMBBQJkYwkAzAgCCQCkAwEFAmRkCQDMCAIJAKQDAQUCZGUJAMwIAgkApAMBBQJkawkAzAgCCQCkAwEFAmRqBQNuaWwCAToJAJUKAwUCZHQFAmR4BQJkeQECZHoCAmFEAmFUBAJkQQkBAmFyAAQCZEIJAJEDAgUCZEEFAmFsBAJhdQkA2QQBBQJkQgQCYXYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkQQUCYW0EAmF3CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZEEFAmFuBAJheAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmRBBQJhbwMJAQIhPQIJAJADAQgFAmFECHBheW1lbnRzAAEJAAIBAjRpbnZhbGlkIHBheW1lbnQgLSBleGFjdCBvbmUgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBAJjdwkAkQMCCAUCYUQIcGF5bWVudHMAAAQCZEMIBQJjdwZhbW91bnQDCQECIT0CBQJhdQkBBXZhbHVlAQgFAmN3B2Fzc2V0SWQJAAIBCQCsAgIJAKwCAgIeaW52YWxpZCBhc3NldCBpcyBpbiBwYXltZW50IC0gBQJkQgIMIGlzIGV4cGVjdGVkBAJkRAkBAmFaAAQCY0YJAKUIAQgFAmFEBmNhbGxlcgQCZEUJAQlpc0RlZmluZWQBCQCiCAEJAQJiYQEFAmNGBAJjSgMFAmRFCQEFdmFsdWUBCQCiCAEJAQJiYQEFAmNGCQCkAwEJAQFrAgUEdGhpcwUCZEQEAmFRCQENcGFyc2VJbnRWYWx1ZQEFAmNKBAJiUAUGaGVpZ2h0BAJjbwkBAmJkAQUCY0oEAmNwCQECYmUBBQJjSgQCY24JAQJiYwEFAmNKAwkAZgIFAmF2BQJkQwkAAgEJAKwCAgIiYW1vdW50IGlzIGxlc3MgdGhlbiBtaW5Mb2NrQW1vdW50PQkApAMBBQJhdgMJAGYCBQJhdwUCYVQJAAIBCQCsAgICLXBhc3NlZCBkdXJhdGlvbiBpcyBsZXNzIHRoZW4gbWluTG9ja0R1cmF0aW9uPQkApAMBBQJhdwMJAGYCBQJhVAUCYXgJAAIBCQCsAgICMHBhc3NlZCBkdXJhdGlvbiBpcyBncmVhdGVyIHRoZW4gbWF4TG9ja0R1cmF0aW9uPQkApAMBBQJheAMDBQJkRQkAZwIJAGQCCQEBawIFBHRoaXMFAmNvCQEBawIFBHRoaXMFAmNwBQJiUAcJAAIBAjZ0aGVyZSBpcyBhbiBhY3RpdmUgbG9jayAtIGNvbnNpZGVyIHRvIHVzZSBpbmNyZWFzZUxvY2sDCQBmAgkBAWgCBQR0aGlzBQJjbgAACQACAQkArAICAjR0aGVyZSBhcmUgbG9ja2VkIFdYcyAtIGNvbnNpZGVyIHRvIHVzZSBpbmNyZWFzZUxvY2sgBQJjbgQCZEYJAGsDBQJhVAUBYwUCYXgEAmRHCQBrAwUCZEMFAmRGBQFjBAJkSAkBAW4BCQD8BwQFAmFzAhVjYWxjR3d4UGFyYW1zUkVBRE9OTFkJAMwIAgUCZEcJAMwIAgUCYlAJAMwIAgUCYVQFA25pbAUDbmlsBAJiUQkBAXEBCQCRAwIFAmRIAAAEAmJSCQEBcQEJAJEDAgUCZEgAAQQCYmkJAKQDAQkBAXEBCQCRAwIFAmRIAAIEAmNTCQEBawIFAmJ5CQECYWUABAJjVAkBAWsCBQJieQkBAmFnAAQCY1UJAQFrAgUCYnkJAQJhaQAEAmNrAwkAZgIFBmhlaWdodAUCY1UFAmNVBQZoZWlnaHQEAmNWCQCWAwEJAMwIAgkAZQIFAmNrBQJjVAkAzAgCAAAFA25pbAQCY1gJAQJibwEFAmNKBAJjWgkAaQIJAGgCCQBoAgUCY1MFAmNWAAIAAwQCZGYJAQJicgEFAmNKBAJkZwkBAmJzAAQCZGgJAGkCCQBoAgUCZEcFAmFUAAIEAmRpCQEBaAIFBHRoaXMFAmRnBAJiSgkBAmJCAQcEAmRJAwUCZEUFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgUCZEQJAGQCBQJhUQABCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJiYQEFAmNGBQJjSgkAzAgCCQELU3RyaW5nRW50cnkCCQECYmIBBQJjSgUCY0YFA25pbAkAlAoCCQDOCAIJAM0IAgkAzggCCQDOCAIFAmRJCQECY20IBQJjRgUCY0oFAmRDBQJiUAUCYVQFAmJRBQJiUgUCYmkJAQJiVQQFAmRDBQJhVAABAwUCZEUAAAABCQECYk0IAgRsb2NrBQJjRgUCZEMFAmJQBQJhVAUCYlEFAmJSBQJhRAkAzAgCCQEMSW50ZWdlckVudHJ5AgUCY1gFAmNaCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYnYACQBkAgUCYkoFAmRHBQNuaWwFAmRHDAJhRAELY29uc3RydWN0b3IGAmRKAmRLAmF2AmRMAmRNAmFzBAJkTgkBAmFDAQUCYUQDCQAAAgUCZE4FAmROCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhWgAAAAkAzAgCCQELU3RyaW5nRW50cnkCCQECYXEACQECYXkFBQJkSwUCYXYFAmRMBQJkTQUCYXMJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAXgABQJkSgUDbmlsCQECYlUEAAAAAAAAAAAJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYUQBB2xvY2tSZWYDAmFUAmRPAmRQBAJkUQkBAmR6AgUCYUQFAmFUBAJkUggFAmRRAl8xBAJkRwgFAmRRAl8yBAJkUwkApQgBCAUCYUQGY2FsbGVyBAJkVAMDCQAAAgUCZE8CAAYJAAACBQJkUAEABQR1bml0CQD8BwQFAXQCCmNyZWF0ZVBhaXIJAMwIAgUBdwkAzAgCBQJkTwkAzAgCBQJkUwkAzAgCBQJkUAUDbmlsBQNuaWwDCQAAAgUCZFQFAmRUBAJkVQkA/AcEBQJhcwIWdXBkYXRlUmVmZXJyYWxBY3Rpdml0eQkAzAgCCQClCAEIBQJhRAZjYWxsZXIJAMwIAgUCZEcFA25pbAUDbmlsAwkAAAIFAmRVBQJkVQkAlAoCBQJkUgUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhRAEEbG9jawECYVQEAmRWCQECZHoCBQJhRAUCYVQEAmRSCAUCZFYCXzEEAmRHCAUCZFYCXzIEAmRVCQD8BwQFAmFzAhZ1cGRhdGVSZWZlcnJhbEFjdGl2aXR5CQDMCAIJAKUIAQgFAmFEBmNhbGxlcgkAzAgCBQJkRwUDbmlsBQNuaWwDCQAAAgUCZFUFAmRVCQCUCgIFAmRSBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFEAQxpbmNyZWFzZUxvY2sBAmRXBAJkQQkBAmFyAAQCZEIJAJEDAgUCZEEFAmFsBAJhdQkA2QQBBQJkQgQCYXcJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJkQQUCYW4EAmF4CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZEEFAmFvBAJkQwkBAmN1AgUCYUQFAmF1BAJjRgkApQgBCAUCYUQGY2FsbGVyBAJjSQkBAmFPAQUCY0YEAmNKCQCRAwIFAmNJBQJhRwQCZFgJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJjSQUCYUgEAmJQCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCY0kFAmFJBAJkWQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmNJBQJhSgQCZFoJAGQCBQJiUAUCZFkEAmVhCQCWAwEJAMwIAgkAZQIFAmRaBQZoZWlnaHQJAMwIAgAABQNuaWwEAmViCQBkAgUCZFgFAmRDBAJlYwkAZAIFAmVhBQJkVwMJAGYCAAAFAmRXCQACAQIaZHVyYXRpb24gaXMgbGVzcyB0aGVuIHplcm8DCQBmAgUCYXcFAmVjCQACAQkArAICAi1sb2NrRHVyYXRpb25OZXcgaXMgbGVzcyB0aGVuIG1pbkxvY2tEdXJhdGlvbj0JAKQDAQUCYXcDCQBmAgUCZWMFAmF4CQACAQkArAICAkRkZWx0YUR1cmF0aW9uICsgZXhpc3RlZExvY2tEdXJhdGlvbiBpcyBncmVhdGVyIHRoZW4gbWF4TG9ja0R1cmF0aW9uPQkApAMBBQJheAQCZEYJAGsDBQJlYwUBYwUCYXgEAmRHCQBrAwUCZWIFAmRGBQFjBAJkVQkA/AcEBQJhcwIWdXBkYXRlUmVmZXJyYWxBY3Rpdml0eQkAzAgCCQClCAEIBQJhRAZjYWxsZXIJAMwIAgUCZEcFA25pbAUDbmlsAwkAAAIFAmRVBQJkVQQCZWQFBmhlaWdodAQCZEgJAQFuAQkA/AcEBQJhcwIVY2FsY0d3eFBhcmFtc1JFQURPTkxZCQDMCAIFAmRHCQDMCAIFAmVkCQDMCAIFAmVjBQNuaWwFA25pbAQCYlEJAQFxAQkAkQMCBQJkSAAABAJiUgkBAXEBCQCRAwIFAmRIAAEEAmJpCQCkAwEJAQFxAQkAkQMCBQJkSAACBAJjUwkBAWsCBQJieQkBAmFlAAQCY1QJAQFrAgUCYnkJAQJhZwAEAmNVCQEBawIFAmJ5CQECYWkABAJjawMJAGYCBQZoZWlnaHQFAmNVBQJjVQUGaGVpZ2h0BAJjVgkAlgMBCQDMCAIJAGUCBQJjawUCY1QJAMwIAgAABQNuaWwEAmNYCQECYm8BBQJjSgQCY1kJAQFoAgUEdGhpcwUCY1gEAmNaCQBpAgkAaAIJAGgCBQJjUwUCY1YAAgADBAJkYQkAZQIFAmNaBQJjWQMJAGYCAAAFAmRhCQACAQISd3JvbmcgY2FsY3VsYXRpb25zBAJkZgkBAmJyAQUCY0oEAmRnCQECYnMABAJkaAkBAWgCBQR0aGlzBQJkZgQCZGkJAQFoAgUEdGhpcwUCZGcEAmVlCQECY0MBBQJjRgQCZWYJAGUCBQJkRwUCZWUDCQBmAgAABQJlZgkAAgEJAKwCAgIYZ3d4RGlmZiBpcyBsZXNzIHRoZW4gMDogCQCkAwEFAmVmBAJiSgkBAmJCAQcEAmRqCQECYkIBBgQCZGwJAQJidAEFAmNKBAJkbQkBAWgCBQR0aGlzBQJkbAQCZHQJAGsDBQJkYQUCZWUFAmRqBAJlZwkAaQIJAGgCBQJkRwUCZWMAAgQCZWgJAGkCCQBoAgUCZWUFAmVhAAIEAmVpCQBlAgUCZWcFAmVoCQDOCAIJAM0IAgkAzggCCQECY20IBQJjRgUCY0oFAmViBQJlZAUCZWMFAmJRBQJiUgUCYmkJAQJiVQQFAmRDBQJkVwAAAAAJAQJiTQgCBGxvY2sFAmNGBQJkQwUCYlAFAmVjBQJiUQUCYlIFAmFECQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYnYACQBkAgUCYkoFAmVmBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYUQBDGNsYWltV3hCb29zdAICY0UCY0YDCQECIT0CBQJieggFAmFEBmNhbGxlcgkAAgECEnBlcm1pc3Npb25zIGRlbmllZAQCZWoJAQJjRAMFAmNFBQJjRgcEAmR3CAUCZWoCXzEEAmR4CAUCZWoCXzIEAmR5CAUCZWoCXzMJAJQKAgUCZHgJAMwIAgUCZHcFA25pbAJhRAEUY2xhaW1XeEJvb3N0UkVBRE9OTFkCAmNFAmNGBAJlawkBAmNEAwUCY0UFAmNGBgQCZHcIBQJlawJfMQQCZHgIBQJlawJfMgQCZHkIBQJlawJfMwkAlAoCBQNuaWwJAMwIAgUCZHcJAMwIAgUCZHkFA25pbAJhRAEGdW5sb2NrAQJhTgQCY0kJAQJhTwEFAmFOBAJjSgkAkQMCBQJjSQUCYUcEAmRYCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCY0kFAmFIBAJiUAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmNJBQJhSQQCZFkJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJjSQUCYUoEAmRaCQBkAgUCYlAFAmRZBAJkQQkBAmFyAAQCYXUJANkEAQkAkQMCBQJkQQUCYWwDCQBnAgUCZFoFBmhlaWdodAkAAgEJAKwCAgkArAICAgV3YWl0IAkApAMBBQJkWgIKIHRvIHVubG9jawMJAGcCAAAFAmRYCQACAQIRbm90aGluZyB0byB1bmxvY2sEAmJpCQELdmFsdWVPckVsc2UCCQCaCAIFAmFzCQECYWoAAAAJAM0IAgkAzQgCCQDOCAIJAQJjbQgFAmFOBQJjSgAABQJiUAUCZFkAAAAACQCkAwEFAmJpCQECYlUECQEBLQEFAmRYAAAAAAD///////////8BCQECYk0IAgZ1bmxvY2sFAmFOBQJkWAUCYlAFAmRZAAAAAAUCYUQJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmFOBQJkWAUCYXUCYUQBE2d3eFVzZXJJbmZvUkVBRE9OTFkBAmFOBAJhWAkBAmNDAQUCYU4JAJQKAgUDbmlsCQDMCAIFAmFYBQNuaWwCYUQBIGdldFVzZXJHd3hBbW91bnRBdEhlaWdodFJFQURPTkxZAgJhTgJjeQQCYVgJAQJjeAIFAmFOBQJjeQkAlAoCBQNuaWwFAmFYAmFEARlnZXRUb3RhbENhY2hlZEd3eFJFQURPTkxZAAkAlAoCBQNuaWwJAQJiQgEGAmFEAQpzZXRNYW5hZ2VyAQJlbAQCZE4JAQJhQwEFAmFEAwkAAAIFAmROBQJkTgQCZW0JANkEAQUCZWwDCQAAAgUCZW0FAmVtCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZAAFAmVsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYUQBDmNvbmZpcm1NYW5hZ2VyAAQCZW4JAQJhQgAEAmVvAwkBCWlzRGVmaW5lZAEFAmVuBgkAAgECEk5vIHBlbmRpbmcgbWFuYWdlcgMJAAACBQJlbwUCZW8EAmVwAwkAAAIIBQJhRA9jYWxsZXJQdWJsaWNLZXkJAQV2YWx1ZQEFAmVuBgkAAgECG1lvdSBhcmUgbm90IHBlbmRpbmcgbWFuYWdlcgMJAAACBQJlcAUCZXAJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFjAAkA2AQBCQEFdmFsdWUBBQJlbgkAzAgCCQELRGVsZXRlRW50cnkBCQECYWQABQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmVxAQJlcgAEAmVzBAFvCQECYXoAAwkAAQIFAW8CCkJ5dGVWZWN0b3IEAmFGBQFvBQJhRgMJAAECBQFvAgRVbml0CAUCZXEPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IJAPQDAwgFAmVxCWJvZHlCeXRlcwkAkQMCCAUCZXEGcHJvb2ZzAAAFAmVz4t4b9w==", "chainId": 84, "height": 2342912, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 3w5fMivBRZeY46AN91sL18eDv5NzibAxhB9Z67QywU7v Next: 2fEEN3q6s94quRF4Wh34BHKjkFUnvdo9nbCzk29pccJs Diff:
OldNewDifferences
305305
306306 let gwxRewardContract = getGwxRewardAddressOrFail(factoryCfg)
307307
308-func getTotalCachedGwx () = {
308+func getTotalCachedGwx (correct) = {
309309 let keyVotingEmissionContract = makeString(["%s", "votingEmissionContract"], SEP)
310310 let votingEmissionContract = addressFromStringValue(getStringValue(factoryContract, keyVotingEmissionContract))
311311 let keyCurrentEpochUi = makeString(["%s", "currentEpochUi"], SEP)
316316 let isCorrectionActivated = if (isDefined(targetEpochOption))
317317 then (currentEpochUi >= value(targetEpochOption))
318318 else false
319- let corrective = if (isCorrectionActivated)
319+ let corrective = if (if (isCorrectionActivated)
320+ then correct
321+ else false)
320322 then valueOrElse(getInteger(this, keyTotalCachedGwxCorrective()), 0)
321323 else 0
322324 max([0, (totalCachedGwxRaw + corrective)])
401403 let userNumStr = userRecordArray[IdxLockUserNum]
402404 let gwxRewardEmissionStartHeight = valueOrElse(getInteger(gwxRewardContract, keyGwxRewardEmissionStartHeight()), 0)
403405 let EMPTYSTR = "empty"
404- let $t01493615504 = if ((lpAssetIdStr != EMPTYSTR))
406+ let $t01496315531 = if ((lpAssetIdStr != EMPTYSTR))
405407 then {
406408 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
407409 let pw1 = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
411413 else if (readOnly)
412414 then $Tuple2(0, 0)
413415 else throw(("not readonly mode: unsupported lp asset " + lpAssetIdStr))
414- let poolWeight0 = $t01493615504._1
415- let poolWeight1 = $t01493615504._2
416+ let poolWeight0 = $t01496315531._1
417+ let poolWeight1 = $t01496315531._2
416418 let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
417419 let emissionStart = iof(emissionContract, keyEmissionStartBlock())
418420 let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
442444 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
443445 let userMaxBoostInt = ioz(this, userMaxBoostIntegralKEY)
444446 let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
445- let totalCachedGwx = getTotalCachedGwx()
447+ let totalCachedGwxCorrected = getTotalCachedGwx(true)
446448 let userCurrGwx = calcCurrentGwxAmount(userAddressStr)
447449 let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
448450 let userBoostAvaliableToClaimTotal = ioz(this, userBoostAvalaibleToClaimTotalKEY)
454456 else fraction(userBoostEmissionIntegral, udh1, udh)
455457 let poolUserBoostEmissionIntegral0 = fraction(userBoostEmissionIntegral0, poolWeight0, POOLWEIGHTMULT)
456458 let poolUserBoostEmissionIntegral1 = fraction(userBoostEmissionIntegral1, poolWeight1, POOLWEIGHTMULT)
457- let userBoostAvaliableToClaimTotalNew0 = if ((totalCachedGwx == 0))
459+ let userBoostAvaliableToClaimTotalNew0 = if ((totalCachedGwxCorrected == 0))
458460 then 0
459- else fraction(poolUserBoostEmissionIntegral0, userCurrGwx, totalCachedGwx)
460- let userBoostAvaliableToClaimTotalNew1 = if ((totalCachedGwx == 0))
461+ else fraction(poolUserBoostEmissionIntegral0, userCurrGwx, totalCachedGwxCorrected)
462+ let userBoostAvaliableToClaimTotalNew1 = if ((totalCachedGwxCorrected == 0))
461463 then 0
462- else fraction(poolUserBoostEmissionIntegral1, userCurrGwx, totalCachedGwx)
464+ else fraction(poolUserBoostEmissionIntegral1, userCurrGwx, totalCachedGwxCorrected)
463465 let userBoostAvaliableToClaimTotalNew = (userBoostAvaliableToClaimTotalNew0 + userBoostAvaliableToClaimTotalNew1)
464466 let userBoostClaimedKEY = keyUserBoostClaimed(userNumStr)
465467 let userBoostClaimed = ioz(this, userBoostClaimedKEY)
466468 let userBoostAvailable = (userBoostAvaliableToClaimTotalNew - userBoostClaimed)
467469 let dataState = [IntegerEntry(userLpBoostEmissionLastIntegralKEY, boostEmissionIntegral)]
468- let debug = makeString([toString(userBoostEmissionLastIntegral), toString(userBoostEmissionIntegral), toString(userBoostClaimed), toString(userBoostAvailable), toString(poolWeight0), toString(poolWeight1), toString(h), toString(udh), toString(uLastH), toString(udh0), toString(udh1), toString(userCurrGwx), toString(totalCachedGwx)], ":")
470+ let debug = makeString([toString(userBoostEmissionLastIntegral), toString(userBoostEmissionIntegral), toString(userBoostClaimed), toString(userBoostAvailable), toString(poolWeight0), toString(poolWeight1), toString(h), toString(udh), toString(uLastH), toString(udh0), toString(udh1), toString(userCurrGwx), toString(totalCachedGwxCorrected)], ":")
469471 $Tuple3(userBoostAvaliableToClaimTotalNew, dataState, debug)
470472 }
471473 }
530532 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
531533 let userMaxBoostInt = ((gWxAmountStart * duration) / 2)
532534 let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
533- let totalCachedGwx = getTotalCachedGwx()
535+ let totalCachedGwxRaw = getTotalCachedGwx(false)
534536 let arr = if (userIsExisting)
535537 then nil
536538 else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
537539 $Tuple2(((((arr ++ LockParamsEntry(userAddressStr, userNumStr, pmtAmount, lockStart, duration, k, b, period)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
538540 then 0
539- else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(keyTotalCachedGwx(), (totalCachedGwx + gWxAmountStart))]), gWxAmountStart)
541+ else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(keyTotalCachedGwx(), (totalCachedGwxRaw + gWxAmountStart))]), gWxAmountStart)
540542 }
541543 }
542544 }
555557
556558 @Callable(i)
557559 func lockRef (duration,referrerAddress,signature) = {
558- let $t02379423859 = lockActions(i, duration)
559- let lockActionsResult = $t02379423859._1
560- let gWxAmountStart = $t02379423859._2
560+ let $t02389023955 = lockActions(i, duration)
561+ let lockActionsResult = $t02389023955._1
562+ let gWxAmountStart = $t02389023955._2
561563 let referralAddress = toString(i.caller)
562564 let refInv = if (if ((referrerAddress == ""))
563565 then true
578580
579581 @Callable(i)
580582 func lock (duration) = {
581- let $t02431724382 = lockActions(i, duration)
582- let lockActionsResult = $t02431724382._1
583- let gWxAmountStart = $t02431724382._2
583+ let $t02441324478 = lockActions(i, duration)
584+ let lockActionsResult = $t02441324478._1
585+ let gWxAmountStart = $t02441324478._2
584586 let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
585587 if ((updateRefActivity == updateRefActivity))
586588 then $Tuple2(lockActionsResult, unit)
647649 if ((0 > gwxDiff))
648650 then throw(("gwxDiff is less then 0: " + toString(gwxDiff)))
649651 else {
650- let totalCachedGwx = getTotalCachedGwx()
652+ let totalCachedGwxRaw = getTotalCachedGwx(false)
653+ let totalCachedGwxCorrected = getTotalCachedGwx(true)
651654 let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
652655 let userBoostAvaliableToClaimTotal = ioz(this, userBoostAvalaibleToClaimTotalKEY)
653- let userBoostAvaliableToClaimTotalNew = fraction(userBoostEmissionIntegral, currUserGwx, totalCachedGwx)
656+ let userBoostAvaliableToClaimTotalNew = fraction(userBoostEmissionIntegral, currUserGwx, totalCachedGwxCorrected)
654657 let userMaxBoostIntNew = ((gWxAmountStart * lockDurationNew) / 2)
655658 let remainingUserMaxBoostInt = ((currUserGwx * remainingDuration) / 2)
656659 let userMaxBoostIntDiff = (userMaxBoostIntNew - remainingUserMaxBoostInt)
657- (((LockParamsEntry(userAddressStr, userNumStr, userAmountNew, lockStartNew, lockDurationNew, k, b, period) ++ StatsEntry(pmtAmount, deltaDuration, 0, 0)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, lockDurationNew, k, b, i)) ++ [IntegerEntry(keyTotalCachedGwx(), (totalCachedGwx + gwxDiff))])
660+ (((LockParamsEntry(userAddressStr, userNumStr, userAmountNew, lockStartNew, lockDurationNew, k, b, period) ++ StatsEntry(pmtAmount, deltaDuration, 0, 0)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, lockDurationNew, k, b, i)) ++ [IntegerEntry(keyTotalCachedGwx(), (totalCachedGwxRaw + gwxDiff))])
658661 }
659662 }
660663 }
668671 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
669672 then throw("permissions denied")
670673 else {
671- let $t02928729389 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
672- let userBoostAvailable = $t02928729389._1
673- let dataState = $t02928729389._2
674- let debug = $t02928729389._3
674+ let $t02945929561 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
675+ let userBoostAvailable = $t02945929561._1
676+ let dataState = $t02945929561._2
677+ let debug = $t02945929561._3
675678 $Tuple2(dataState, [userBoostAvailable])
676679 }
677680
679682
680683 @Callable(i)
681684 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
682- let $t02952129622 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
683- let userBoostAvailable = $t02952129622._1
684- let dataState = $t02952129622._2
685- let debug = $t02952129622._3
685+ let $t02969329794 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
686+ let userBoostAvailable = $t02969329794._1
687+ let dataState = $t02969329794._2
688+ let debug = $t02969329794._3
686689 $Tuple2(nil, [userBoostAvailable, debug])
687690 }
688691
727730
728731
729732 @Callable(i)
730-func getTotalCachedGwxREADONLY () = $Tuple2(nil, getTotalCachedGwx())
733+func getTotalCachedGwxREADONLY () = $Tuple2(nil, getTotalCachedGwx(true))
731734
732735
733736
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 func strf (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined"))
1313
1414
1515 func ioz (address,key) = valueOrElse(getInteger(address, key), 0)
1616
1717
1818 func iod (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
1919
2020
2121 func iof (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
2222
2323
2424 func abs (val) = if ((0 > val))
2525 then -(val)
2626 else val
2727
2828
2929 func aal (val) = match val {
3030 case valAnyLyst: List[Any] =>
3131 valAnyLyst
3232 case _ =>
3333 throw("fail to cast into List[Any]")
3434 }
3535
3636
3737 func ai (val) = match val {
3838 case valInt: Int =>
3939 valInt
4040 case _ =>
4141 throw("fail to cast into Int")
4242 }
4343
4444
4545 func keyReferralsContractAddress () = makeString(["%s%s", "config", "referralsContractAddress"], SEP)
4646
4747
4848 let referralsContractAddressOrFail = addressFromStringValue(strf(this, keyReferralsContractAddress()))
4949
5050 let keyReferralProgramName = makeString(["%s%s", "referral", "programName"], SEP)
5151
5252 let referralProgramNameDefault = "wxlock"
5353
5454 let referralProgramName = valueOrElse(getString(this, keyReferralProgramName), referralProgramNameDefault)
5555
5656 func keyFactoryAddress () = "%s%s__config__factoryAddress"
5757
5858
5959 let IdxFactoryCfgStakingDapp = 1
6060
6161 let IdxFactoryCfgBoostingDapp = 2
6262
6363 let IdxFactoryCfgIdoDapp = 3
6464
6565 let IdxFactoryCfgTeamDapp = 4
6666
6767 let IdxFactoryCfgEmissionDapp = 5
6868
6969 let IdxFactoryCfgRestDapp = 6
7070
7171 let IdxFactoryCfgSlippageDapp = 7
7272
7373 let IdxFactoryCfgDaoDapp = 8
7474
7575 let IdxFactoryCfgMarketingDapp = 9
7676
7777 let IdxFactoryCfgGwxRewardDapp = 10
7878
7979 let IdxFactoryCfgBirdsDapp = 11
8080
8181 func keyFactoryCfg () = "%s__factoryConfig"
8282
8383
8484 func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
8585
8686
8787 func keyFactoryLpList () = "%s__lpTokensList"
8888
8989
9090 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
9191
9292
9393 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
9494
9595
9696 func keyFactoryPoolWeightHistory (poolAddress,num) = ((("%s%s__poolWeight__" + poolAddress) + "__") + toString(num))
9797
9898
9999 func readFactoryAddressOrFail () = addressFromStringValue(strf(this, keyFactoryAddress()))
100100
101101
102102 func readLpList () = split(valueOrElse(getString(readFactoryAddressOrFail(), keyFactoryLpList()), ""), SEP)
103103
104104
105105 func readFactoryCfgOrFail (factory) = split(strf(factory, keyFactoryCfg()), SEP)
106106
107107
108108 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
109109
110110
111111 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
112112
113113
114114 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
115115
116116
117117 func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp])
118118
119119
120120 func keyManagerPublicKey () = "%s__managerPublicKey"
121121
122122
123123 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
124124
125125
126126 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
127127
128128
129129 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
130130
131131
132132 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
133133
134134
135135 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
136136
137137
138138 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
139139
140140
141141 func keyNextPeriod () = "%s__nextPeriod"
142142
143143
144144 func keyGwxRewardEmissionStartHeight () = "%s%s__gwxRewardEmissionPart__startHeight"
145145
146146
147147 let IdxCfgAssetId = 1
148148
149149 let IdxCfgMinLockAmount = 2
150150
151151 let IdxCfgMinLockDuration = 3
152152
153153 let IdxCfgMaxLockDuration = 4
154154
155155 let IdxCfgMathContract = 5
156156
157157 func keyConfig () = "%s__config"
158158
159159
160160 func readConfigArrayOrFail () = split(strf(this, keyConfig()), SEP)
161161
162162
163163 let mathContract = addressFromStringValue(readConfigArrayOrFail()[IdxCfgMathContract])
164164
165165 func formatConfigS (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = makeString(["%s%d%d%d", assetId, minLockAmount, minLockDuration, maxLockDuration, mathContract], SEP)
166166
167167
168168 func formatConfig (assetId,minLockAmount,minLockDuration,maxLockDuration,mathContract) = formatConfigS(assetId, toString(minLockAmount), toString(minLockDuration), toString(maxLockDuration), mathContract)
169169
170170
171171 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
172172 case s: String =>
173173 fromBase58String(s)
174174 case _: Unit =>
175175 unit
176176 case _ =>
177177 throw("Match error")
178178 }
179179
180180
181181 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
182182 case s: String =>
183183 fromBase58String(s)
184184 case _: Unit =>
185185 unit
186186 case _ =>
187187 throw("Match error")
188188 }
189189
190190
191191 func mustManager (i) = {
192192 let pd = throw("Permission denied")
193193 match managerPublicKeyOrUnit() {
194194 case pk: ByteVector =>
195195 if ((i.callerPublicKey == pk))
196196 then true
197197 else pd
198198 case _: Unit =>
199199 if ((i.caller == this))
200200 then true
201201 else pd
202202 case _ =>
203203 throw("Match error")
204204 }
205205 }
206206
207207
208208 let IdxLockUserNum = 1
209209
210210 let IdxLockAmount = 2
211211
212212 let IdxLockStart = 3
213213
214214 let IdxLockDuration = 4
215215
216216 let IdxLockParamK = 5
217217
218218 let IdxLockParamB = 6
219219
220220 func keyLockParamsRecord (userAddress) = makeString(["%s%s__lock", userAddress], SEP)
221221
222222
223223 func readLockParamsRecordOrFail (userAddress) = split(strf(this, keyLockParamsRecord(userAddress)), SEP)
224224
225225
226226 func formatLockParamsRecordS (userNum,amount,start,duration,paramK,paramB,lastUpdTimestamp,gwxAmount) = makeString(["%d%d%d%d%d%d%d%d", userNum, amount, start, duration, paramK, paramB, lastUpdTimestamp, gwxAmount], SEP)
227227
228228
229229 func formatLockParamsRecord (userNum,amount,start,duration,paramK,paramB,gwxAmount) = formatLockParamsRecordS(userNum, toString(amount), toString(start), toString(duration), toString(paramK), toString(paramB), toString(lastBlock.timestamp), toString(gwxAmount))
230230
231231
232232 func keyNextUserNum () = "%s__nextUserNum"
233233
234234
235235 func keyUser2NumMapping (userAddress) = makeString(["%s%s%s__mapping__user2num", userAddress], SEP)
236236
237237
238238 func keyNum2UserMapping (num) = makeString(["%s%s%s__mapping__num2user", num], SEP)
239239
240240
241241 func keyLockParamUserAmount (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "amount"], SEP)
242242
243243
244244 func keyLockParamStartBlock (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "start"], SEP)
245245
246246
247247 func keyLockParamDuration (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "duration"], SEP)
248248
249249
250250 func keyLockParamK (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "k"], SEP)
251251
252252
253253 func keyLockParamB (userNum) = makeString(["%s%d%s__paramByUserNum", userNum, "b"], SEP)
254254
255255
256256 func keyLockParamByPeriodK (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "k", period], SEP)
257257
258258
259259 func keyLockParamByPeriodB (userNum,period) = makeString(["%s%d%s%d__paramByPeriod", userNum, "b", period], SEP)
260260
261261
262262 func keyLockParamTotalAmount () = "%s%s__stats__activeTotalLocked"
263263
264264
265265 func keyStatsLocksDurationSumInBlocks () = "%s%s__stats__locksDurationSumInBlocks"
266266
267267
268268 func keyStatsLocksCount () = "%s%s__stats__locksCount"
269269
270270
271271 func keyStatsUsersCount () = "%s%s__stats__activeUsersCount"
272272
273273
274274 func keyUserBoostEmissionLastINTEGRAL (userNum) = makeString(["%s%d__userBoostEmissionLastInt", userNum], SEP)
275275
276276
277277 func keyUserLpBoostEmissionLastINTEGRAL (userNum,lpAssetId) = makeString(["%s%d__userBoostEmissionLastInt", userNum, lpAssetId], SEP)
278278
279279
280280 func keyUserMaxBoostINTEGRAL (userNum) = makeString(["%s%d__maxBoostInt", userNum], SEP)
281281
282282
283283 func keyTotalMaxBoostINTEGRAL () = "%s%s__maxBoostInt__total"
284284
285285
286286 func keyUserBoostAvalaibleToClaimTotal (userNum) = makeString(["%s%d__userBoostAvaliableToClaimTotal", userNum], SEP)
287287
288288
289289 func keyUserBoostClaimed (userNum) = makeString(["%s%d__userBoostClaimed", userNum], SEP)
290290
291291
292292 func keyTotalCachedGwx () = "%s%s__gwxCached__total"
293293
294294
295295 func keyTotalCachedGwxCorrective () = "%s__gwxCachedTotalCorrective"
296296
297297
298298 let factoryContract = readFactoryAddressOrFail()
299299
300300 let factoryCfg = readFactoryCfgOrFail(factoryContract)
301301
302302 let emissionContract = getEmissionAddressOrFail(factoryCfg)
303303
304304 let stakingContract = getStakingAddressOrFail(factoryCfg)
305305
306306 let gwxRewardContract = getGwxRewardAddressOrFail(factoryCfg)
307307
308-func getTotalCachedGwx () = {
308+func getTotalCachedGwx (correct) = {
309309 let keyVotingEmissionContract = makeString(["%s", "votingEmissionContract"], SEP)
310310 let votingEmissionContract = addressFromStringValue(getStringValue(factoryContract, keyVotingEmissionContract))
311311 let keyCurrentEpochUi = makeString(["%s", "currentEpochUi"], SEP)
312312 let currentEpochUi = getIntegerValue(votingEmissionContract, keyCurrentEpochUi)
313313 let keyTargetEpoch = makeString(["%s", "totalCachedGwxCorrection__activationEpoch"], SEP)
314314 let targetEpochOption = getInteger(this, keyTargetEpoch)
315315 let totalCachedGwxRaw = valueOrElse(getInteger(this, keyTotalCachedGwx()), 0)
316316 let isCorrectionActivated = if (isDefined(targetEpochOption))
317317 then (currentEpochUi >= value(targetEpochOption))
318318 else false
319- let corrective = if (isCorrectionActivated)
319+ let corrective = if (if (isCorrectionActivated)
320+ then correct
321+ else false)
320322 then valueOrElse(getInteger(this, keyTotalCachedGwxCorrective()), 0)
321323 else 0
322324 max([0, (totalCachedGwxRaw + corrective)])
323325 }
324326
325327
326328 func HistoryEntry (type,user,amount,lockStart,duration,k,b,i) = {
327329 let historyKEY = makeString(["%s%s%s%s__history", type, user, toBase58String(i.transactionId)], SEP)
328330 let historyDATA = makeString(["%d%d%d%d%d%d%d", toString(lastBlock.height), toString(lastBlock.timestamp), toString(amount), toString(lockStart), toString(duration), toString(k), toString(b)], SEP)
329331 StringEntry(historyKEY, historyDATA)
330332 }
331333
332334
333335 func StatsEntry (totalLockedInc,durationInc,lockCountInc,usersCountInc) = {
334336 let locksDurationSumInBlocksKEY = keyStatsLocksDurationSumInBlocks()
335337 let locksCountKEY = keyStatsLocksCount()
336338 let usersCountKEY = keyStatsUsersCount()
337339 let totalAmountKEY = keyLockParamTotalAmount()
338340 let locksDurationSumInBlocks = ioz(this, locksDurationSumInBlocksKEY)
339341 let locksCount = ioz(this, locksCountKEY)
340342 let usersCount = ioz(this, usersCountKEY)
341343 let totalAmount = ioz(this, totalAmountKEY)
342344 [IntegerEntry(locksDurationSumInBlocksKEY, (locksDurationSumInBlocks + durationInc)), IntegerEntry(locksCountKEY, (locksCount + lockCountInc)), IntegerEntry(usersCountKEY, (usersCount + usersCountInc)), IntegerEntry(totalAmountKEY, (totalAmount + totalLockedInc))]
343345 }
344346
345347
346348 func calcGwxAmount (kRaw,bRaw,h) = {
347349 let SCALE = 1000
348350 (((kRaw * h) + bRaw) / SCALE)
349351 }
350352
351353
352354 func LockParamsEntry (userAddress,userNum,amount,start,duration,k,b,period) = {
353355 let userAmountKEY = keyLockParamUserAmount(userNum)
354356 let startBlockKEY = keyLockParamStartBlock(userNum)
355357 let durationKEY = keyLockParamDuration(userNum)
356358 let kKEY = keyLockParamK(userNum)
357359 let bKEY = keyLockParamB(userNum)
358360 let kByPeriodKEY = keyLockParamByPeriodK(userNum, period)
359361 let bByPeriodKEY = keyLockParamByPeriodB(userNum, period)
360362 let gwxAmount = calcGwxAmount(k, b, height)
361363 [IntegerEntry(userAmountKEY, amount), IntegerEntry(startBlockKEY, start), IntegerEntry(durationKEY, duration), IntegerEntry(kKEY, k), IntegerEntry(bKEY, b), IntegerEntry(kByPeriodKEY, k), IntegerEntry(bByPeriodKEY, b), StringEntry(keyLockParamsRecord(userAddress), formatLockParamsRecord(userNum, amount, start, duration, k, b, gwxAmount))]
362364 }
363365
364366
365367 func extractOptionalPaymentAmountOrFail (i,expectedAssetId) = if ((size(i.payments) > 1))
366368 then throw("only one payment is allowed")
367369 else if ((size(i.payments) == 0))
368370 then 0
369371 else {
370372 let pmt = i.payments[0]
371373 if ((value(pmt.assetId) != expectedAssetId))
372374 then throw("invalid asset id in payment")
373375 else pmt.amount
374376 }
375377
376378
377379 func calcUserGwxAmountAtHeight (userAddress,targetHeight) = {
378380 let EMPTY = "empty"
379381 let user2NumMappingKEY = keyUser2NumMapping(userAddress)
380382 let userNum = valueOrElse(getString(user2NumMappingKEY), EMPTY)
381383 let k = valueOrElse(getInteger(keyLockParamK(userNum)), 0)
382384 let b = valueOrElse(getInteger(keyLockParamB(userNum)), 0)
383385 let gwxAmountCalc = calcGwxAmount(k, b, targetHeight)
384386 let gwxAmount = if ((0 > gwxAmountCalc))
385387 then 0
386388 else gwxAmountCalc
387389 gwxAmount
388390 }
389391
390392
391393 func calcCurrentGwxAmount (userAddress) = calcUserGwxAmountAtHeight(userAddress, height)
392394
393395
394396 func internalClaimWxBoost (lpAssetIdStr,userAddressStr,readOnly) = {
395397 let EMPTY = "EMPTY"
396398 let userRecordOrEmpty = valueOrElse(getString(this, keyLockParamsRecord(userAddressStr)), EMPTY)
397399 if ((userRecordOrEmpty == EMPTY))
398400 then $Tuple3(0, nil, "userRecord::is::empty")
399401 else {
400402 let userRecordArray = split(userRecordOrEmpty, SEP)
401403 let userNumStr = userRecordArray[IdxLockUserNum]
402404 let gwxRewardEmissionStartHeight = valueOrElse(getInteger(gwxRewardContract, keyGwxRewardEmissionStartHeight()), 0)
403405 let EMPTYSTR = "empty"
404- let $t01493615504 = if ((lpAssetIdStr != EMPTYSTR))
406+ let $t01496315531 = if ((lpAssetIdStr != EMPTYSTR))
405407 then {
406408 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
407409 let pw1 = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
408410 let pw0 = valueOrElse(getInteger(factoryContract, keyFactoryPoolWeightHistory(poolAddressStr, 0)), pw1)
409411 $Tuple2(pw0, pw1)
410412 }
411413 else if (readOnly)
412414 then $Tuple2(0, 0)
413415 else throw(("not readonly mode: unsupported lp asset " + lpAssetIdStr))
414- let poolWeight0 = $t01493615504._1
415- let poolWeight1 = $t01493615504._2
416+ let poolWeight0 = $t01496315531._1
417+ let poolWeight1 = $t01496315531._2
416418 let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
417419 let emissionStart = iof(emissionContract, keyEmissionStartBlock())
418420 let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
419421 let h = if ((height > emissionEnd))
420422 then emissionEnd
421423 else height
422424 let dh = max([(h - emissionStart), 0])
423425 let userLpBoostEmissionLastIntegralKEY = keyUserLpBoostEmissionLastINTEGRAL(userNumStr, lpAssetIdStr)
424426 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
425427 let userBoostEmissionLastIntegral = valueOrElse(getInteger(this, userLpBoostEmissionLastIntegralKEY), ioz(this, userBoostEmissionLastIntegralKEY))
426428 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
427429 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
428430 let udh = fraction(userBoostEmissionIntegral, 3, (2 * wxEmissionPerBlock))
429431 let uLastH = (h - udh)
430432 let udh0 = max([(gwxRewardEmissionStartHeight - uLastH), 0])
431433 let udh1 = ((h - uLastH) - udh0)
432434 if (if (if ((0 > uLastH))
433435 then true
434436 else (0 > udh1))
435437 then true
436438 else (abs(((udh0 + udh1) - udh)) >= 1))
437439 then throw(((((((("invalid udh calc: udh=" + toString(udh)) + " uLastH=") + toString(uLastH)) + " udh0=") + toString(udh0)) + " udh1=") + toString(udh1)))
438440 else if ((0 > userBoostEmissionIntegral))
439441 then throw("wrong calculations")
440442 else {
441443 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
442444 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
443445 let userMaxBoostInt = ioz(this, userMaxBoostIntegralKEY)
444446 let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
445- let totalCachedGwx = getTotalCachedGwx()
447+ let totalCachedGwxCorrected = getTotalCachedGwx(true)
446448 let userCurrGwx = calcCurrentGwxAmount(userAddressStr)
447449 let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
448450 let userBoostAvaliableToClaimTotal = ioz(this, userBoostAvalaibleToClaimTotalKEY)
449451 let userBoostEmissionIntegral0 = if ((udh == 0))
450452 then 0
451453 else fraction(userBoostEmissionIntegral, udh0, udh)
452454 let userBoostEmissionIntegral1 = if ((udh == 0))
453455 then 0
454456 else fraction(userBoostEmissionIntegral, udh1, udh)
455457 let poolUserBoostEmissionIntegral0 = fraction(userBoostEmissionIntegral0, poolWeight0, POOLWEIGHTMULT)
456458 let poolUserBoostEmissionIntegral1 = fraction(userBoostEmissionIntegral1, poolWeight1, POOLWEIGHTMULT)
457- let userBoostAvaliableToClaimTotalNew0 = if ((totalCachedGwx == 0))
459+ let userBoostAvaliableToClaimTotalNew0 = if ((totalCachedGwxCorrected == 0))
458460 then 0
459- else fraction(poolUserBoostEmissionIntegral0, userCurrGwx, totalCachedGwx)
460- let userBoostAvaliableToClaimTotalNew1 = if ((totalCachedGwx == 0))
461+ else fraction(poolUserBoostEmissionIntegral0, userCurrGwx, totalCachedGwxCorrected)
462+ let userBoostAvaliableToClaimTotalNew1 = if ((totalCachedGwxCorrected == 0))
461463 then 0
462- else fraction(poolUserBoostEmissionIntegral1, userCurrGwx, totalCachedGwx)
464+ else fraction(poolUserBoostEmissionIntegral1, userCurrGwx, totalCachedGwxCorrected)
463465 let userBoostAvaliableToClaimTotalNew = (userBoostAvaliableToClaimTotalNew0 + userBoostAvaliableToClaimTotalNew1)
464466 let userBoostClaimedKEY = keyUserBoostClaimed(userNumStr)
465467 let userBoostClaimed = ioz(this, userBoostClaimedKEY)
466468 let userBoostAvailable = (userBoostAvaliableToClaimTotalNew - userBoostClaimed)
467469 let dataState = [IntegerEntry(userLpBoostEmissionLastIntegralKEY, boostEmissionIntegral)]
468- let debug = makeString([toString(userBoostEmissionLastIntegral), toString(userBoostEmissionIntegral), toString(userBoostClaimed), toString(userBoostAvailable), toString(poolWeight0), toString(poolWeight1), toString(h), toString(udh), toString(uLastH), toString(udh0), toString(udh1), toString(userCurrGwx), toString(totalCachedGwx)], ":")
470+ let debug = makeString([toString(userBoostEmissionLastIntegral), toString(userBoostEmissionIntegral), toString(userBoostClaimed), toString(userBoostAvailable), toString(poolWeight0), toString(poolWeight1), toString(h), toString(udh), toString(uLastH), toString(udh0), toString(udh1), toString(userCurrGwx), toString(totalCachedGwxCorrected)], ":")
469471 $Tuple3(userBoostAvaliableToClaimTotalNew, dataState, debug)
470472 }
471473 }
472474 }
473475
474476
475477 func lockActions (i,duration) = {
476478 let cfgArray = readConfigArrayOrFail()
477479 let assetIdStr = cfgArray[IdxCfgAssetId]
478480 let assetId = fromBase58String(assetIdStr)
479481 let minLockAmount = parseIntValue(cfgArray[IdxCfgMinLockAmount])
480482 let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
481483 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
482484 if ((size(i.payments) != 1))
483485 then throw("invalid payment - exact one payment must be attached")
484486 else {
485487 let pmt = i.payments[0]
486488 let pmtAmount = pmt.amount
487489 if ((assetId != value(pmt.assetId)))
488490 then throw((("invalid asset is in payment - " + assetIdStr) + " is expected"))
489491 else {
490492 let nextUserNumKEY = keyNextUserNum()
491493 let userAddressStr = toString(i.caller)
492494 let userIsExisting = isDefined(getString(keyUser2NumMapping(userAddressStr)))
493495 let userNumStr = if (userIsExisting)
494496 then value(getString(keyUser2NumMapping(userAddressStr)))
495497 else toString(iof(this, nextUserNumKEY))
496498 let userNum = parseIntValue(userNumStr)
497499 let lockStart = height
498500 let startBlockKEY = keyLockParamStartBlock(userNumStr)
499501 let durationKEY = keyLockParamDuration(userNumStr)
500502 let userAmountKEY = keyLockParamUserAmount(userNumStr)
501503 if ((minLockAmount > pmtAmount))
502504 then throw(("amount is less then minLockAmount=" + toString(minLockAmount)))
503505 else if ((minLockDuration > duration))
504506 then throw(("passed duration is less then minLockDuration=" + toString(minLockDuration)))
505507 else if ((duration > maxLockDuration))
506508 then throw(("passed duration is greater then maxLockDuration=" + toString(maxLockDuration)))
507509 else if (if (userIsExisting)
508510 then ((iof(this, startBlockKEY) + iof(this, durationKEY)) >= lockStart)
509511 else false)
510512 then throw("there is an active lock - consider to use increaseLock")
511513 else if ((ioz(this, userAmountKEY) > 0))
512514 then throw(("there are locked WXs - consider to use increaseLock " + userAmountKEY))
513515 else {
514516 let coeffX8 = fraction(duration, MULT8, maxLockDuration)
515517 let gWxAmountStart = fraction(pmtAmount, coeffX8, MULT8)
516518 let gWxParamsResultList = aal(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStart, duration], nil))
517519 let k = ai(gWxParamsResultList[0])
518520 let b = ai(gWxParamsResultList[1])
519521 let period = toString(ai(gWxParamsResultList[2]))
520522 let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
521523 let emissionStart = iof(emissionContract, keyEmissionStartBlock())
522524 let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
523525 let h = if ((height > emissionEnd))
524526 then emissionEnd
525527 else height
526528 let dh = max([(h - emissionStart), 0])
527529 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
528530 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
529531 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
530532 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
531533 let userMaxBoostInt = ((gWxAmountStart * duration) / 2)
532534 let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
533- let totalCachedGwx = getTotalCachedGwx()
535+ let totalCachedGwxRaw = getTotalCachedGwx(false)
534536 let arr = if (userIsExisting)
535537 then nil
536538 else [IntegerEntry(nextUserNumKEY, (userNum + 1)), StringEntry(keyUser2NumMapping(userAddressStr), userNumStr), StringEntry(keyNum2UserMapping(userNumStr), userAddressStr)]
537539 $Tuple2(((((arr ++ LockParamsEntry(userAddressStr, userNumStr, pmtAmount, lockStart, duration, k, b, period)) ++ StatsEntry(pmtAmount, duration, 1, if (userIsExisting)
538540 then 0
539- else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(keyTotalCachedGwx(), (totalCachedGwx + gWxAmountStart))]), gWxAmountStart)
541+ else 1)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, duration, k, b, i)) ++ [IntegerEntry(userBoostEmissionLastIntegralKEY, boostEmissionIntegral), IntegerEntry(keyTotalCachedGwx(), (totalCachedGwxRaw + gWxAmountStart))]), gWxAmountStart)
540542 }
541543 }
542544 }
543545 }
544546
545547
546548 @Callable(i)
547549 func constructor (factoryAddressStr,lockAssetIdStr,minLockAmount,minDuration,maxDuration,mathContract) = {
548550 let checkCaller = mustManager(i)
549551 if ((checkCaller == checkCaller))
550552 then ([IntegerEntry(keyNextUserNum(), 0), StringEntry(keyConfig(), formatConfig(lockAssetIdStr, minLockAmount, minDuration, maxDuration, mathContract)), StringEntry(keyFactoryAddress(), factoryAddressStr)] ++ StatsEntry(0, 0, 0, 0))
551553 else throw("Strict value is not equal to itself.")
552554 }
553555
554556
555557
556558 @Callable(i)
557559 func lockRef (duration,referrerAddress,signature) = {
558- let $t02379423859 = lockActions(i, duration)
559- let lockActionsResult = $t02379423859._1
560- let gWxAmountStart = $t02379423859._2
560+ let $t02389023955 = lockActions(i, duration)
561+ let lockActionsResult = $t02389023955._1
562+ let gWxAmountStart = $t02389023955._2
561563 let referralAddress = toString(i.caller)
562564 let refInv = if (if ((referrerAddress == ""))
563565 then true
564566 else (signature == base58''))
565567 then unit
566568 else invoke(referralsContractAddressOrFail, "createPair", [referralProgramName, referrerAddress, referralAddress, signature], nil)
567569 if ((refInv == refInv))
568570 then {
569571 let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
570572 if ((updateRefActivity == updateRefActivity))
571573 then $Tuple2(lockActionsResult, unit)
572574 else throw("Strict value is not equal to itself.")
573575 }
574576 else throw("Strict value is not equal to itself.")
575577 }
576578
577579
578580
579581 @Callable(i)
580582 func lock (duration) = {
581- let $t02431724382 = lockActions(i, duration)
582- let lockActionsResult = $t02431724382._1
583- let gWxAmountStart = $t02431724382._2
583+ let $t02441324478 = lockActions(i, duration)
584+ let lockActionsResult = $t02441324478._1
585+ let gWxAmountStart = $t02441324478._2
584586 let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
585587 if ((updateRefActivity == updateRefActivity))
586588 then $Tuple2(lockActionsResult, unit)
587589 else throw("Strict value is not equal to itself.")
588590 }
589591
590592
591593
592594 @Callable(i)
593595 func increaseLock (deltaDuration) = {
594596 let cfgArray = readConfigArrayOrFail()
595597 let assetIdStr = cfgArray[IdxCfgAssetId]
596598 let assetId = fromBase58String(assetIdStr)
597599 let minLockDuration = parseIntValue(cfgArray[IdxCfgMinLockDuration])
598600 let maxLockDuration = parseIntValue(cfgArray[IdxCfgMaxLockDuration])
599601 let pmtAmount = extractOptionalPaymentAmountOrFail(i, assetId)
600602 let userAddressStr = toString(i.caller)
601603 let userRecordArray = readLockParamsRecordOrFail(userAddressStr)
602604 let userNumStr = userRecordArray[IdxLockUserNum]
603605 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
604606 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
605607 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
606608 let lockEnd = (lockStart + lockDuration)
607609 let remainingDuration = max([(lockEnd - height), 0])
608610 let userAmountNew = (userAmount + pmtAmount)
609611 let lockDurationNew = (remainingDuration + deltaDuration)
610612 if ((0 > deltaDuration))
611613 then throw("duration is less then zero")
612614 else if ((minLockDuration > lockDurationNew))
613615 then throw(("lockDurationNew is less then minLockDuration=" + toString(minLockDuration)))
614616 else if ((lockDurationNew > maxLockDuration))
615617 then throw(("deltaDuration + existedLockDuration is greater then maxLockDuration=" + toString(maxLockDuration)))
616618 else {
617619 let coeffX8 = fraction(lockDurationNew, MULT8, maxLockDuration)
618620 let gWxAmountStart = fraction(userAmountNew, coeffX8, MULT8)
619621 let updateRefActivity = invoke(mathContract, "updateReferralActivity", [toString(i.caller), gWxAmountStart], nil)
620622 if ((updateRefActivity == updateRefActivity))
621623 then {
622624 let lockStartNew = height
623625 let gWxParamsResultList = aal(invoke(mathContract, "calcGwxParamsREADONLY", [gWxAmountStart, lockStartNew, lockDurationNew], nil))
624626 let k = ai(gWxParamsResultList[0])
625627 let b = ai(gWxParamsResultList[1])
626628 let period = toString(ai(gWxParamsResultList[2]))
627629 let wxEmissionPerBlock = iof(emissionContract, keyEmissionRatePerBlockCurrent())
628630 let emissionStart = iof(emissionContract, keyEmissionStartBlock())
629631 let emissionEnd = iof(emissionContract, keyEmissionEndBlock())
630632 let h = if ((height > emissionEnd))
631633 then emissionEnd
632634 else height
633635 let dh = max([(h - emissionStart), 0])
634636 let userBoostEmissionLastIntegralKEY = keyUserBoostEmissionLastINTEGRAL(userNumStr)
635637 let userBoostEmissionLastIntegral = ioz(this, userBoostEmissionLastIntegralKEY)
636638 let boostEmissionIntegral = (((wxEmissionPerBlock * dh) * 2) / 3)
637639 let userBoostEmissionIntegral = (boostEmissionIntegral - userBoostEmissionLastIntegral)
638640 if ((0 > userBoostEmissionIntegral))
639641 then throw("wrong calculations")
640642 else {
641643 let userMaxBoostIntegralKEY = keyUserMaxBoostINTEGRAL(userNumStr)
642644 let totalMaxBoostIntegralKEY = keyTotalMaxBoostINTEGRAL()
643645 let userMaxBoostInt = ioz(this, userMaxBoostIntegralKEY)
644646 let totalMaxBoostInt = ioz(this, totalMaxBoostIntegralKEY)
645647 let currUserGwx = calcCurrentGwxAmount(userAddressStr)
646648 let gwxDiff = (gWxAmountStart - currUserGwx)
647649 if ((0 > gwxDiff))
648650 then throw(("gwxDiff is less then 0: " + toString(gwxDiff)))
649651 else {
650- let totalCachedGwx = getTotalCachedGwx()
652+ let totalCachedGwxRaw = getTotalCachedGwx(false)
653+ let totalCachedGwxCorrected = getTotalCachedGwx(true)
651654 let userBoostAvalaibleToClaimTotalKEY = keyUserBoostAvalaibleToClaimTotal(userNumStr)
652655 let userBoostAvaliableToClaimTotal = ioz(this, userBoostAvalaibleToClaimTotalKEY)
653- let userBoostAvaliableToClaimTotalNew = fraction(userBoostEmissionIntegral, currUserGwx, totalCachedGwx)
656+ let userBoostAvaliableToClaimTotalNew = fraction(userBoostEmissionIntegral, currUserGwx, totalCachedGwxCorrected)
654657 let userMaxBoostIntNew = ((gWxAmountStart * lockDurationNew) / 2)
655658 let remainingUserMaxBoostInt = ((currUserGwx * remainingDuration) / 2)
656659 let userMaxBoostIntDiff = (userMaxBoostIntNew - remainingUserMaxBoostInt)
657- (((LockParamsEntry(userAddressStr, userNumStr, userAmountNew, lockStartNew, lockDurationNew, k, b, period) ++ StatsEntry(pmtAmount, deltaDuration, 0, 0)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, lockDurationNew, k, b, i)) ++ [IntegerEntry(keyTotalCachedGwx(), (totalCachedGwx + gwxDiff))])
660+ (((LockParamsEntry(userAddressStr, userNumStr, userAmountNew, lockStartNew, lockDurationNew, k, b, period) ++ StatsEntry(pmtAmount, deltaDuration, 0, 0)) :+ HistoryEntry("lock", userAddressStr, pmtAmount, lockStart, lockDurationNew, k, b, i)) ++ [IntegerEntry(keyTotalCachedGwx(), (totalCachedGwxRaw + gwxDiff))])
658661 }
659662 }
660663 }
661664 else throw("Strict value is not equal to itself.")
662665 }
663666 }
664667
665668
666669
667670 @Callable(i)
668671 func claimWxBoost (lpAssetIdStr,userAddressStr) = if ((stakingContract != i.caller))
669672 then throw("permissions denied")
670673 else {
671- let $t02928729389 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
672- let userBoostAvailable = $t02928729389._1
673- let dataState = $t02928729389._2
674- let debug = $t02928729389._3
674+ let $t02945929561 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, false)
675+ let userBoostAvailable = $t02945929561._1
676+ let dataState = $t02945929561._2
677+ let debug = $t02945929561._3
675678 $Tuple2(dataState, [userBoostAvailable])
676679 }
677680
678681
679682
680683 @Callable(i)
681684 func claimWxBoostREADONLY (lpAssetIdStr,userAddressStr) = {
682- let $t02952129622 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
683- let userBoostAvailable = $t02952129622._1
684- let dataState = $t02952129622._2
685- let debug = $t02952129622._3
685+ let $t02969329794 = internalClaimWxBoost(lpAssetIdStr, userAddressStr, true)
686+ let userBoostAvailable = $t02969329794._1
687+ let dataState = $t02969329794._2
688+ let debug = $t02969329794._3
686689 $Tuple2(nil, [userBoostAvailable, debug])
687690 }
688691
689692
690693
691694 @Callable(i)
692695 func unlock (userAddress) = {
693696 let userRecordArray = readLockParamsRecordOrFail(userAddress)
694697 let userNumStr = userRecordArray[IdxLockUserNum]
695698 let userAmount = parseIntValue(userRecordArray[IdxLockAmount])
696699 let lockStart = parseIntValue(userRecordArray[IdxLockStart])
697700 let lockDuration = parseIntValue(userRecordArray[IdxLockDuration])
698701 let lockEnd = (lockStart + lockDuration)
699702 let cfgArray = readConfigArrayOrFail()
700703 let assetId = fromBase58String(cfgArray[IdxCfgAssetId])
701704 if ((lockEnd >= height))
702705 then throw((("wait " + toString(lockEnd)) + " to unlock"))
703706 else if ((0 >= userAmount))
704707 then throw("nothing to unlock")
705708 else {
706709 let period = valueOrElse(getInteger(mathContract, keyNextPeriod()), 0)
707710 (((LockParamsEntry(userAddress, userNumStr, 0, lockStart, lockDuration, 0, 0, toString(period)) ++ StatsEntry(-(userAmount), 0, 0, -1)) :+ HistoryEntry("unlock", userAddress, userAmount, lockStart, lockDuration, 0, 0, i)) :+ ScriptTransfer(addressFromStringValue(userAddress), userAmount, assetId))
708711 }
709712 }
710713
711714
712715
713716 @Callable(i)
714717 func gwxUserInfoREADONLY (userAddress) = {
715718 let gwxAmount = calcCurrentGwxAmount(userAddress)
716719 $Tuple2(nil, [gwxAmount])
717720 }
718721
719722
720723
721724 @Callable(i)
722725 func getUserGwxAmountAtHeightREADONLY (userAddress,targetHeight) = {
723726 let gwxAmount = calcUserGwxAmountAtHeight(userAddress, targetHeight)
724727 $Tuple2(nil, gwxAmount)
725728 }
726729
727730
728731
729732 @Callable(i)
730-func getTotalCachedGwxREADONLY () = $Tuple2(nil, getTotalCachedGwx())
733+func getTotalCachedGwxREADONLY () = $Tuple2(nil, getTotalCachedGwx(true))
731734
732735
733736
734737 @Callable(i)
735738 func setManager (pendingManagerPublicKey) = {
736739 let checkCaller = mustManager(i)
737740 if ((checkCaller == checkCaller))
738741 then {
739742 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
740743 if ((checkManagerPublicKey == checkManagerPublicKey))
741744 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
742745 else throw("Strict value is not equal to itself.")
743746 }
744747 else throw("Strict value is not equal to itself.")
745748 }
746749
747750
748751
749752 @Callable(i)
750753 func confirmManager () = {
751754 let pm = pendingManagerPublicKeyOrUnit()
752755 let hasPM = if (isDefined(pm))
753756 then true
754757 else throw("No pending manager")
755758 if ((hasPM == hasPM))
756759 then {
757760 let checkPM = if ((i.callerPublicKey == value(pm)))
758761 then true
759762 else throw("You are not pending manager")
760763 if ((checkPM == checkPM))
761764 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
762765 else throw("Strict value is not equal to itself.")
763766 }
764767 else throw("Strict value is not equal to itself.")
765768 }
766769
767770
768771 @Verifier(tx)
769772 func verify () = {
770773 let targetPublicKey = match managerPublicKeyOrUnit() {
771774 case pk: ByteVector =>
772775 pk
773776 case _: Unit =>
774777 tx.senderPublicKey
775778 case _ =>
776779 throw("Match error")
777780 }
778781 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
779782 }
780783

github/deemru/w8io/026f985 
101.22 ms