tx · Fxy6e2QGkatqZU7QT6sx8HAKTopY12XGXkVVoVtvm2Lm

3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz:  -0.02400000 Waves

2023.04.06 18:04 [2522859] smart account 3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz > SELF 0.00000000 Waves

{ "type": 13, "id": "Fxy6e2QGkatqZU7QT6sx8HAKTopY12XGXkVVoVtvm2Lm", "fee": 2400000, "feeAssetId": null, "timestamp": 1680793474750, "version": 2, "chainId": 84, "sender": "3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz", "senderPublicKey": "D28XoueZWsMfm8Y5pa6C5ZFuYoWgre2Wm8tzJANJgMnq", "proofs": [ "3bfEeCnhtPywUCpXTg9MbBFvFzDHPvUqTBcFijTy86xDjmq7gdR8SJuF76YRuiPTZ93zr9TWbytD8EqBFCQiMJSq" ], "script": "base64:BgLDIAgCEgMKAQgSAwoBCBIDCgEIEgASABIDCgEIEgQKAggBEgYKBAIBAgISAwoBCBIDCgEIEgUKAwgIBBIGCgQBGAgYEgQKAhgIEgQKAggIEgQKAggIEgMKAQgSAwoBCBIECgIICCIGU0NBTEU4IgVNVUxUMyIFTVVMVDgiB1NDQUxFMTgiBk1VTFQxOCIDU0VQIg5QT09MV0VJR0hUTVVMVCIKemVyb0JpZ0ludCIJb25lQmlnSW50Igd3cmFwRXJyIgNtc2ciCHRocm93RXJyIglhc0FueUxpc3QiA3ZhbCIHJG1hdGNoMCIKdmFsQW55THlzdCIFYXNJbnQiBnZhbEludCIIYXNTdHJpbmciBnZhbFN0ciIMYXNCeXRlVmVjdG9yIgZ2YWxCaW4iD2dldFN0cmluZ09yRmFpbCIHYWRkcmVzcyIDa2V5IhhnZXRTdHJpbmdCeUFkZHJlc3NPckZhaWwiDGdldEludE9yWmVybyIPZ2V0SW50T3JEZWZhdWx0IgpkZWZhdWx0VmFsIgxnZXRJbnRPckZhaWwiGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8iHGdldEJpZ0ludEZyb21TdHJpbmdPckRlZmF1bHQiAXMiBXRvWDE4IgdvcmlnVmFsIg1vcmlnU2NhbGVNdWx0Igdmcm9tWDE4Ig9yZXN1bHRTY2FsZU11bHQiEWtleUZhY3RvcnlBZGRyZXNzIhlrZXlWb3RpbmdFbWlzc2lvbkNvbnRyYWN0IhhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHAiGUlkeEZhY3RvcnlDZmdCb29zdGluZ0RhcHAiFElkeEZhY3RvcnlDZmdJZG9EYXBwIhVJZHhGYWN0b3J5Q2ZnVGVhbURhcHAiGUlkeEZhY3RvcnlDZmdFbWlzc2lvbkRhcHAiFUlkeEZhY3RvcnlDZmdSZXN0RGFwcCIZSWR4RmFjdG9yeUNmZ1NsaXBwYWdlRGFwcCINa2V5RmFjdG9yeUNmZyITa2V5TWFuYWdlclB1YmxpY0tleSIaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkiFmtleVN0YWJsZVBvb2xBZGRvbkFkZHIiDGtleUFkZG9uQWRkciIaa2V5RmFjdG9yeUxwMkFzc2V0c01hcHBpbmciCmxwQXNzZXRTdHIiEGtleUZhY3RvcnlMcExpc3QiJmtleUZhY3RvcnlMcEFzc2V0VG9Qb29sQ29udHJhY3RBZGRyZXNzIhRrZXlGYWN0b3J5UG9vbFdlaWdodCIPY29udHJhY3RBZGRyZXNzIgpyZWFkTHBMaXN0IgdmYWN0b3J5IhRyZWFkRmFjdG9yeUNmZ09yRmFpbCIYZ2V0Qm9vc3RpbmdBZGRyZXNzT3JGYWlsIgpmYWN0b3J5Q2ZnIhhnZXRFbWlzc2lvbkFkZHJlc3NPckZhaWwiF2dldFN0YWtpbmdBZGRyZXNzT3JGYWlsIh5rZXlFbWlzc2lvblJhdGVQZXJCbG9ja0N1cnJlbnQiIWtleUVtaXNzaW9uUmF0ZVBlckJsb2NrTWF4Q3VycmVudCIVa2V5RW1pc3Npb25TdGFydEJsb2NrIhtrZXlFbWlzc2lvbkR1cmF0aW9uSW5CbG9ja3MiE2tleUVtaXNzaW9uRW5kQmxvY2siD2tleVN0YWtlZEJ5VXNlciIOdXNlckFkZHJlc3NTdHIiDGxwQXNzZXRJZFN0ciIOa2V5U3Rha2VkVG90YWwiEGtleUNsYWltZWRCeVVzZXIiGWtleUNsYWltZWRCeVVzZXJNaW5SZXdhcmQiG2tleUNsYWltZWRCeVVzZXJCb29zdFJld2FyZCIPa2V5Q2xhaW1lZFRvdGFsIgpyZWFkU3Rha2VkIhVrZXlMYXN0VG90YWxMcEJhbGFuY2UiCWxwQXNzZXRJZCIUa2V5TGFzdFVzZXJMcEJhbGFuY2UiC3VzZXJBZGRyZXNzIhlrZXlUb3RhbExwQmFsYW5jZUludGVncmFsIhhrZXlVc2VyTHBCYWxhbmNlSW50ZWdyYWwiJmtleVRvdGFsTHBCYWxhbmNlSW50ZWdyYWxMYXN0VXBkSGVpZ2h0IiVrZXlVc2VyTHBCYWxhbmNlSW50ZWdyYWxMYXN0VXBkSGVpZ2h0IhJrZXlXeFBlckxwSW50ZWdyYWwiH2tleVd4UGVyTHBJbnRlZ3JhbExhc3RVcGRIZWlnaHQiEGtleVd4VG9DbGFpbVVzZXIiI2tleVd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0IgprZXlXeFBlckxwIg1rZXlXeFBlckxwWDE4IhprZXlXeFBlckxwSW50ZWdyYWxVc2VyTGFzdCIZa2V5T3BlcmF0aW9uSGlzdG9yeVJlY29yZCIEdHlwZSIGdHhJZDU4IhNmb3JtYXRIaXN0b3J5UmVjb3JkIgZhbW91bnQiFU9wZXJhdGlvbkhpc3RvcnlFbnRyeSIEdHhJZCIOZmFjdG9yeUFkZHJlc3MiD2ZhY3RvcnlDb250cmFjdCIQZW1pc3Npb25Db250cmFjdCIQYm9vc3RpbmdDb250cmFjdCIKYm9vc3RDb2VmZiIBQCIWbHBTdGFraW5nUG9vbHNDb250cmFjdCILa2V5TmV4dFVzZXIiEGdldFVzZXJzTGlzdE5hbWUiC2tleUxpc3RIZWFkIghsaXN0TmFtZSILa2V5TGlzdFNpemUiC2tleUxpc3RQcmV2IgJpZCILa2V5TGlzdE5leHQiDGNvbnRhaW5zTm9kZSIKaGVhZE9yVW5pdCIKcHJldk9yVW5pdCIKbmV4dE9yVW5pdCIRaW5zZXJ0Tm9kZUFjdGlvbnMiCGxpc3RTaXplIgljaGVja05vZGUiEWRlbGV0ZU5vZGVBY3Rpb25zIhtjYWxjV3hQZXJMcEludGVncmFsVXNlckxhc3QiDHN0YWtlZEJ5VXNlciImd3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHRPclplcm8iEnd4UGVyTHBJbnRlZ3JhbE5ldyIad3hQZXJMcEludGVncmFsVXNlckxhc3RLRVkiFHJlZnJlc2hQb29sSU5URUdSQUxTIg5wb29sQWRkcmVzc1N0ciINbHBEZWx0YUFtb3VudCIOc3Rha2VkVG90YWxLRVkiC3N0YWtlZFRvdGFsIhJub25aZXJvU3Rha2VkVG90YWwiCnBvb2xXZWlnaHQiEmVtaXNzaW9uU3RhcnRCbG9jayIUd3hFbWlzc2lvblBlckJsb2NrWDMiGHBvb2xXeEVtaXNzaW9uUGVyQmxvY2tYMyISd3hQZXJMcEludGVncmFsS0VZIh93eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0S0VZIgp3eFBlckxwS0VZIhx3eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0Ig93eFBlckxwSW50ZWdyYWwiD3d4UGVyTHBPclplcm9YMyICZGgiCXd4UGVyTHBYMyIOc3Rha2VkVG90YWxOZXciFW5vblplcm9TdGFrZWRUb3RhbE5ldyIMd3hQZXJMcFgzTmV3Ih93eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0TmV3IgVkZWJ1ZyIQcmVmcmVzaElOVEVHUkFMUyINJHQwMTQ4MTkxNDk0MSIRcG9vbEludGVncmFsU1RBVEUiCXBvb2xERUJVRyIPc3Rha2VkQnlVc2VyS0VZIhB3eFRvQ2xhaW1Vc2VyS0VZIiN3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodEtFWSINd3hUb0NsYWltVXNlciIXd3hQZXJMcEludGVncmFsVXNlckxhc3QiBk1VTFQxMSIQd3hUb0NsYWltVXNlck5ldyIad3hQZXJMcEludGVncmFsVXNlckxhc3ROZXciI3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0TmV3IhZtYW5hZ2VyUHVibGljS2V5T3JVbml0Ih1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdCIVcGVybWlzc2lvbkRlbmllZEVycm9yIghtdXN0VGhpcyIBaSILbXVzdE1hbmFnZXIiAnBrIgxzdGFrZUFjdGlvbnMiC3Bvb2xBZGRyZXNzIhFyZWZyZXNoU3Rha2VkVm90ZSINJHQwMTgxNjAxODI3NyINaW50ZWdyYWxTVEFURSILbGlzdEFjdGlvbnMiDnVuc3Rha2VBY3Rpb25zIhdscEFzc2V0UmVjaXBpZW50QWRkcmVzcyIWY2xhaW1lZEJ5VXNlck1pblJld2FyZCIQYXZhaWxhYmxlVG9DbGFpbSIVdGhyb3dJZk5vdGhpbmdUb0NsYWltIgFyIhFmYWN0b3J5QWRkcmVzc1N0ciILY2hlY2tDYWxsZXIiFnZvdGluZ0VtaXNzaW9uQ29udHJhY3QiBWNoZWtzIhdwZW5kaW5nTWFuYWdlclB1YmxpY0tleSIVY2hlY2tNYW5hZ2VyUHVibGljS2V5IgJwbSIFaGFzUE0iB2NoZWNrUE0iA3BtdCIJcG9vbEFkZG9uIgljYWxsZXJTdHIiBnJlc3VsdCIQY2xhaW1lZEJ5VXNlcktFWSIPY2xhaW1lZFRvdGFsS0VZIhljbGFpbWVkQnlVc2VyTWluUmV3YXJkS0VZIhtjbGFpbWVkQnlVc2VyQm9vc3RSZXdhcmRLRVkiDWNsYWltZWRCeVVzZXIiGGNsYWltZWRCeVVzZXJCb29zdFJld2FyZCIMY2xhaW1lZFRvdGFsIg0kdDAyNjMxNDI2NDI2IhJ3eEFtb3VudEJvb3N0VG90YWwiDW1pblJld2FyZFBhcnQiD2Jvb3N0UmV3YXJkUGFydCILdG90YWxSZXdhcmQiCXd4QXNzZXRJZCIJZW1pdEJvb3N0IhJjbGFpbWVkQnlVc2VyVmFsdWUiHmNsYWltZWRCeVVzZXJNaW5SZXdhcmRQbHVzUGFydCIrY2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkUGx1c0Jvb3N0UmV3YXJkUGFydCIgY2xhaW1lZFRvdGFsUGx1c0F2YWlsYWJsZVRvQ2xhaW0iC2N1cnJlbnRJdGVyIgpscEFzc2V0SWRzIgZyZXNBY2MiBGluZm8iCXVuY2xhaW1lZCIHY2xhaW1lZCIRdXNlclZvdGVGaW5hbGl6ZWQiA3JlcyIDaW52IhJ3eEVtaXNzaW9uUGVyQmxvY2siDHBhc3NlZEJsb2NrcyIOcG9vbFd4RW1pc3Npb24iDHVzZXJXeFJld2FyZCINJHQwMzA0NzczMDU4OSIOYm9vc3RJbnZSZXN1bHQiCmJvb3N0RGVidWciCnVzZXJPclVuaXQiByRtYXRjaDEiBGhlYWQiDm5leHRVc2VyT3JVbml0IghuZXh0VXNlciINJHQwMzMzNzkzMzQ4OSICdHgiBnZlcmlmeSIPdGFyZ2V0UHVibGljS2V5ZQABYQAIAAFiAOgHAAFjAIDC1y8AAWQAEgABZQkAtgIBAICAkLu61q3wDQABZgICX18AAWcFAWMAAWgJALYCAQAAAAFpCQC2AgEAAQEBagEBawkAuQkCCQDMCAICDXN0YWtpbmcucmlkZToJAMwIAgkApQgBBQR0aGlzCQDMCAIFAWsFA25pbAIBIAEBbAEBawkAAgEJAQFqAQUBawEBbQEBbgQBbwUBbgMJAAECBQFvAglMaXN0W0FueV0EAXAFAW8FAXAJAQFsAQIbZmFpbCB0byBjYXN0IGludG8gTGlzdFtBbnldAQFxAQFuBAFvBQFuAwkAAQIFAW8CA0ludAQBcgUBbwUBcgkBAWwBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBAXMBAW4EAW8FAW4DCQABAgUBbwIGU3RyaW5nBAF0BQFvBQF0CQEBbAECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEBdQEBbgQBbwUBbgMJAAECBQFvAgpCeXRlVmVjdG9yBAF2BQFvBQF2CQEBbAECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEBdwIBeAF5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUBeAUBeQkBAWoBCQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQF5Ag8gaXMgbm90IGRlZmluZWQBAXoCAXgBeQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFAXgFAXkJAQFqAQkArAICCQCsAgIJAKwCAgkArAICAgptYW5kYXRvcnkgCQClCAEFAXgCAS4FAXkCDyBpcyBub3QgZGVmaW5lZAEBQQIBeAF5CQELdmFsdWVPckVsc2UCCQCaCAIFAXgFAXkAAAEBQgMBeAF5AUMJAQt2YWx1ZU9yRWxzZQIJAJoIAgUBeAUBeQUBQwEBRAIBeAF5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUBeAUBeQkBAWoBCQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQF5Ag8gaXMgbm90IGRlZmluZWQBAUUCAXgBeQkBBXZhbHVlAQkAqAMBCQELdmFsdWVPckVsc2UCCQCdCAIFAXgFAXkCATABAUYDAXgBeQFDBAFvCQCdCAIFAXgFAXkDCQABAgUBbwIGU3RyaW5nBAFHBQFvCQEFdmFsdWUBCQCoAwEFAUcDCQABAgUBbwIEVW5pdAUBQwkAAgECC01hdGNoIGVycm9yAQFIAgFJAUoJALwCAwkAtgIBBQFJBQFlCQC2AgEFAUoBAUsCAW4BTAkAoAMBCQC8AgMFAW4JALYCAQUBTAUBZQEBTQACHCVzJXNfX2NvbmZpZ19fZmFjdG9yeUFkZHJlc3MBAU4AAholc19fdm90aW5nRW1pc3Npb25Db250cmFjdAABTwABAAFQAAIAAVEAAwABUgAEAAFTAAUAAVQABgABVQAHAQFWAAIRJXNfX2ZhY3RvcnlDb25maWcBAVcAAhQlc19fbWFuYWdlclB1YmxpY0tleQEBWAACGyVzX19wZW5kaW5nTWFuYWdlclB1YmxpY0tleQEBWQACFyVzX19zdGFibGVQb29sQWRkb25BZGRyAQFaAAINJXNfX2FkZG9uQWRkcgECYWEBAmFiCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFAmFiCQDMCAICHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUDbmlsBQFmAQJhYwACECVzX19scFRva2Vuc0xpc3QBAmFkAQJhYgkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQJhYgkAzAgCAh5tYXBwaW5nc19fbHBBc3NldDJQb29sQ29udHJhY3QFA25pbAUBZgECYWUBAmFmCQC5CQIJAMwIAgIEJXMlcwkAzAgCAgpwb29sV2VpZ2h0CQDMCAIFAmFmBQNuaWwFAWYBAmFnAQJhaAkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFAmFoCQECYWMAAgAFAWYBAmFpAQJhaAkAtQkCCQEBegIFAmFoCQEBVgAFAWYBAmFqAQJhawkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQJhawUBUAECYWwBAmFrCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFAmFrBQFTAQJhbQECYWsJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYWsFAU8BAmFuAAIbJXMlc19fcmF0ZVBlckJsb2NrX19jdXJyZW50AQJhbwACHiVzJXNfX3JhdGVQZXJCbG9ja01heF9fY3VycmVudAECYXAAAholcyVzX19lbWlzc2lvbl9fc3RhcnRCbG9jawECYXEAAhglcyVzX19lbWlzc2lvbl9fZHVyYXRpb24BAmFyAAIYJXMlc19fZW1pc3Npb25fX2VuZEJsb2NrAQJhcwICYXQCYXUJALkJAgkAzAgCAg4lcyVzJXNfX3N0YWtlZAkAzAgCBQJhdAkAzAgCBQJhdQUDbmlsBQFmAQJhdgECYXUJAKwCAgIXJXMlcyVzX19zdGFrZWRfX3RvdGFsX18FAmF1AQJhdwICYXUCYXQJALkJAgkAzAgCAg8lcyVzJXNfX2NsYWltZWQJAMwIAgUCYXQJAMwIAgUCYXUFA25pbAUBZgECYXgCAmF1AmF0CQC5CQIJAMwIAgIYJXMlcyVzX19jbGFpbWVkTWluUmV3YXJkCQDMCAIFAmF0CQDMCAIFAmF1BQNuaWwFAWYBAmF5AgJhdQJhdAkAuQkCCQDMCAICGiVzJXMlc19fY2xhaW1lZEJvb3N0UmV3YXJkCQDMCAIFAmF0CQDMCAIFAmF1BQNuaWwFAWYBAmF6AQJhdQkAuQkCCQDMCAICFiVzJXMlc19fY2xhaW1lZF9fdG90YWwJAMwIAgUCYXUFA25pbAUBZgECYUEBAXkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBeQAAAQJhQgECYUMJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUCYUMJAMwIAgIFdG90YWwJAMwIAgIDYmFsBQNuaWwFAWYBAmFEAgJhQwJhRQkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQJhQwkAzAgCBQJhRQkAzAgCAgNiYWwFA25pbAUBZgECYUYBAmFDCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFAmFDCQDMCAICBXRvdGFsCQDMCAICBmJhbElOVAUDbmlsBQFmAQJhRwICYUMCYUUJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUCYUMJAMwIAgUCYUUJAMwIAgIGYmFsSU5UBQNuaWwFAWYBAmFIAQJhQwkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQJhQwkAzAgCAgV0b3RhbAkAzAgCAgdsYXN0VXBkBQNuaWwFAWYBAmFJAgJhQwJhRQkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQJhQwkAzAgCBQJhRQkAzAgCAgdsYXN0VXBkBQNuaWwFAWYBAmFKAQJhQwkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFAmFDCQDMCAICBmNvbW1vbgkAzAgCAgVscEludAUDbmlsBQFmAQJhSwECYUMJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCBQJhQwkAzAgCAgZjb21tb24JAMwIAgIGbHBJbnRIBQNuaWwFAWYBAmFMAgJhQwJhRQkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFAmFDCQDMCAIFAmFFCQDMCAICBWxwSW50BQNuaWwFAWYBAmFNAgJhQwJhRQkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFAmFDCQDMCAIFAmFFCQDMCAICBmxwSW50SAUDbmlsBQFmAQJhTgECYUMJALkJAgkAzAgCAgIlcwkAzAgCBQJhQwkAzAgCAgd3eFBlckxwBQNuaWwFAWYBAmFPAQJhQwkAuQkCCQDMCAICAiVzCQDMCAIFAmFDCQDMCAICCnd4UGVyTHBYMTgFA25pbAUBZgECYVACAmFDAmFFCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgUCYUMJAMwIAgUCYUUJAMwIAgIFdUludEwFA25pbAUBZgECYVEDAmFSAmFFAmFTCQC5CQIJAMwIAgIRJXMlcyVzJXNfX2hpc3RvcnkJAMwIAgUCYVIJAMwIAgUCYUUJAMwIAgUCYVMFA25pbAUBZgECYVQEAmFFAmFDAmFSAmFVCQC5CQIJAMwIAgIMJXMlcyVzJWQlZCVkCQDMCAIFAmFFCQDMCAIFAmFDCQDMCAIFAmFSCQDMCAIJAKQDAQUGaGVpZ2h0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkApAMBBQJhVQUDbmlsBQFmAQJhVgUCYVICYUUCYUMCYVUCYVcJAQtTdHJpbmdFbnRyeQIJAQJhUQMFAmFSBQJhRQkA2AQBBQJhVwkBAmFUBAUCYUUFAmFDBQJhUgUCYVUAAmFYCQEBdwIFBHRoaXMJAQFNAAACYVkJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmFYAAJhawkBAmFpAQUCYVkAAmFaCQECYWwBBQJhawACYmEJAQJhagEFAmFrAAJiYgoAAmJjCQD8BwQFAmFaAhVnZXRCb29zdENvZWZmUkVBRE9OTFkFA25pbAUDbmlsAwkAAQIFAmJjAgNJbnQFAmJjCQACAQkArAICCQADAQUCYmMCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAACYmQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkAuQkCCQDMCAICAiVzCQDMCAICFmxwU3Rha2luZ1Bvb2xzQ29udHJhY3QFA25pbAUBZgkBAWoBAi5scF9zdGFraW5nX3Bvb2xzIGNvbnRyYWN0IGFkZHJlc3MgaXMgdW5kZWZpbmVkCQEBagECKWludmFsaWQgbHBfc3Rha2luZ19wb29scyBjb250cmFjdCBhZGRyZXNzAQJiZQECYUMJALkJAgkAzAgCAgQlcyVzCQDMCAIFAmFDCQDMCAICCG5leHRVc2VyBQNuaWwFAWYBAmJmAQJhQwkAuQkCCQDMCAICBXVzZXJzCQDMCAIFAmFDBQNuaWwFAWYBAmJnAQJiaAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQJiaAkAzAgCAgRoZWFkBQNuaWwFAWYBAmJpAQJiaAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQJiaAkAzAgCAgRzaXplBQNuaWwFAWYBAmJqAgJiaAJiawkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFAmJoCQDMCAIFAmJrCQDMCAICBHByZXYFA25pbAUBZgECYmwCAmJoAmJrCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgUCYmgJAMwIAgUCYmsJAMwIAgIEbmV4dAUDbmlsBQFmAQJibQICYmgCYmsEAmJuCQCdCAIFBHRoaXMJAQJiZwEFAmJoBAJibwkAnQgCBQR0aGlzCQECYmoCBQJiaAUCYmsEAmJwCQCdCAIFBHRoaXMJAQJibAIFAmJoBQJiawMDCQAAAgUCYmsJAQt2YWx1ZU9yRWxzZQIFAmJuAgAGCQECIT0CBQJibwUEdW5pdAYJAQIhPQIFAmJwBQR1bml0AQJicQICYmgCYmsEAmJuCQCdCAIFBHRoaXMJAQJiZwEFAmJoBAJicgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYmkBBQJiaAAABAJicwMJAQEhAQkBAmJtAgUCYmgFAmJrBgkBAWwBAgtOb2RlIGV4aXN0cwMJAAACBQJicwUCYnMJAM4IAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYmkBBQJiaAkAZAIFAmJyAAEFA25pbAMJAQIhPQIFAmJuBQR1bml0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJibAIFAmJoBQJiawkBBXZhbHVlAQUCYm4JAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmJqAgUCYmgJAQV2YWx1ZQEFAmJuBQJiawUDbmlsBQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmJnAQUCYmgFAmJrBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmJ0AgJiaAJiawQCYm4JAJ0IAgUEdGhpcwkBAmJnAQUCYmgEAmJyCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQJiaQEFAmJoAAAEAmJvCQCdCAIFBHRoaXMJAQJiagIFAmJoBQJiawQCYnAJAJ0IAgUEdGhpcwkBAmJsAgUCYmgFAmJrCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJiaQEFAmJoCQBlAgUCYnIAAQUDbmlsAwMJAQIhPQIFAmJvBQR1bml0CQECIT0CBQJicAUEdW5pdAcJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmJsAgUCYmgJAQV2YWx1ZQEFAmJvCQEFdmFsdWUBBQJicAkAzAgCCQELU3RyaW5nRW50cnkCCQECYmoCBQJiaAkBBXZhbHVlAQUCYnAJAQV2YWx1ZQEFAmJvCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJiagIFAmJoBQJiawkAzAgCCQELRGVsZXRlRW50cnkBCQECYmwCBQJiaAUCYmsFA25pbAMJAQIhPQIFAmJwBQR1bml0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJiZwEFAmJoCQEFdmFsdWUBBQJicAkAzAgCCQELRGVsZXRlRW50cnkBCQECYmwCBQJiaAUCYmsJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmJqAgUCYmgJAQV2YWx1ZQEFAmJwBQNuaWwDCQECIT0CBQJibwUEdW5pdAkAzAgCCQELRGVsZXRlRW50cnkBCQECYmoCBQJiaAUCYmsJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmJsAgUCYmgJAQV2YWx1ZQEFAmJvBQNuaWwDCQAAAgUCYmsJAQt2YWx1ZU9yRWxzZQIFAmJuAgAJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmJnAQUCYmgFA25pbAkBAWwBCQCsAgIJAKwCAgkArAICAg5pbnZhbGlkIG5vZGU6IAUCYmgCAS4FAmJrAQJidQQCYnYCYncCYngCYnkDAwkAAAIFAmJ3BQFoCQC/AgIFAmJ2BQFoBwUBaAMJAAACBQJidgUBaAUCYngDAwkAvwICBQJidwUBaAkAvwICBQJidgUBaAcJAQV2YWx1ZQEJAKgDAQkBAXcCBQR0aGlzBQJieQkBAWwBAi1jYWxjV3hQZXJMcEludGVncmFsVXNlckxhc3Q6IHVuZXhwZWN0ZWQgc3RhdGUBAmJ6AwJhdQJiQQJiQgQCYkMJAQJhdgEFAmF1BAJiRAkAtgIBCQECYUEBBQJiQwQCYkUDCQAAAgUCYkQFAWgFAWkFAmJEBAJiRgkBEUBleHRyTmF0aXZlKDEwNTApAgUCYVkJAQJhZQEFAmJBBAJiRwkBAUQCBQJhWgkBAmFwAAQCYkgJAGgCCQEBRAIFAmFaCQECYW4ABQFiBAJiSQkAawMFAmJIBQJiRgkAaAIFAWcFAmJiBAJiSgkBAmFKAQUCYXUEAmJLCQECYUsBBQJhdQQCYkwJAQJhTgEFAmF1BAJiTQkBAUIDBQR0aGlzBQJiSwUCYkcEAmJOCQEBRQIFBHRoaXMFAmJKBAJiTwAABAJiUAkAlgMBCQDMCAIJAGUCBQZoZWlnaHQFAmJNCQDMCAIAAAUDbmlsBAJiUQMJAQIhPQIFAmJPAAAJALYCAQUCYk8JALwCAwkAtgIBBQJiSQkAtgIBBQFjBQJiRQQCYlIJALcCAgUCYkQJALYCAQUCYkIEAmJTAwkAAAIFAmJSBQFoBQFpBQJiUgQCYngJALcCAgUCYk4JALkCAgUCYlEJALYCAQUCYlAEAmJUCQC6AgIJALYCAQUCYkkFAmJTBAJiVQUGaGVpZ2h0BAJiVgkAuQkCCQDMCAIJAKYDAQUCYngJAMwIAgkApAMBBQJiUAkAzAgCCQCmAwEFAmJRCQDMCAIJAKYDAQUCYkQJAMwIAgkApAMBBQJiSQkAzAgCCQCkAwEFAmJICQDMCAIJAKQDAQUCYkYFA25pbAICOjoJAJUKAwUCYngJAMwIAgkBC1N0cmluZ0VudHJ5AgUCYkoJAKYDAQUCYngJAMwIAgkBDEludGVnZXJFbnRyeQIFAmJLBQJiVQkAzAgCCQELU3RyaW5nRW50cnkCBQJiTAkApgMBBQJiVAUDbmlsBQJiVgECYlcEAmF1AmF0AmJBAmJCBAJiWAkBAmJ6AwUCYXUFAmJBBQJiQgQCYngIBQJiWAJfMQQCYlkIBQJiWAJfMgQCYloIBQJiWAJfMwQCY2EJAQJhcwIFAmF0BQJhdQQCYnYJAQJhQQEFAmNhBAJjYgkBAmFMAgUCYXUFAmF0BAJjYwkBAmFNAgUCYXUFAmF0BAJieQkBAmFQAgUCYXUFAmF0BAJjZAkBAUUCBQR0aGlzBQJjYgQCYncJAQFBAgUEdGhpcwUCY2MEAmNlCQECYnUECQC2AgEFAmJ2CQC2AgEFAmJ3BQJieAUCYnkEAmNmCQBoAgUBYwUBYgQCY2cJAJgDAQkAzAgCCQC3AgIFAmNkCQC8AgMJALgCAgUCYngFAmNlCQC2AgEFAmJ2CQC2AgEFAmNmCQDMCAIFAWgFA25pbAQCY2gFAmJ4BAJjaQUGaGVpZ2h0BAJiVgkAuQkCCQDMCAIJAKYDAQUCY2QJAMwIAgkApgMBBQJjZQkAzAgCCQCkAwEFAmJ2CQDMCAIFAmJaCQDMCAIJAKQDAQUGaGVpZ2h0BQNuaWwCAjo6CQCVCgMFAmNnCQDOCAIFAmJZCQDMCAIJAQtTdHJpbmdFbnRyeQIFAmNiCQCmAwEFAmNnCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJjYwUCY2kJAMwIAgkBC1N0cmluZ0VudHJ5AgUCYnkJAKYDAQUCY2gFA25pbAUCYlYBAmNqAAQBbwkAoggBCQEBVwADCQABAgUBbwIGU3RyaW5nBAFHBQFvCQDZBAEFAUcDCQABAgUBbwIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJjawAEAW8JAKIIAQkBAVgAAwkAAQIFAW8CBlN0cmluZwQBRwUBbwkA2QQBBQFHAwkAAQIFAW8CBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgACY2wJAQFsAQIRUGVybWlzc2lvbiBkZW5pZWQBAmNtAQJjbgMJAAACCAUCY24GY2FsbGVyBQR0aGlzBgUCY2wBAmNvAQJjbgQBbwkBAmNqAAMJAAECBQFvAgpCeXRlVmVjdG9yBAJjcAUBbwMJAAACCAUCY24PY2FsbGVyUHVibGljS2V5BQJjcAYFAmNsAwkAAQIFAW8CBFVuaXQDCQAAAggFAmNuBmNhbGxlcgUEdGhpcwYFAmNsCQACAQILTWF0Y2ggZXJyb3IBAmNxBQJjbgJhQwJjcgJhRQJhVQQCYXQJAKUIAQUCYUUEAmF1CQDYBAEFAmFDBAJiQQkApQgBBQJjcgQCY2EJAQJhcwIFAmF0BQJhdQQCYkMJAQJhdgEFAmF1BAJidgkBAmFBAQUCY2EEAmNzAwkAAAIFAmJ2AAAJAPwHBAUCYmECEm9uU3Rha2VkVm90ZVVwZGF0ZQkAzAgCBQJhdQkAzAgCBQJhdAkAzAgCBgUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCY3MFAmNzBAJiRAkBAmFBAQUCYkMEAmN0CQECYlcEBQJhdQUCYXQFAmJBBQJhVQQCY2cIBQJjdAJfMQQCY3UIBQJjdAJfMgQCYlYIBQJjdAJfMwQCYmgJAQJiZgEFAmF1BAJjdgMJAQJibQIFAmJoBQJhdAUDbmlsCQECYnECBQJiaAUCYXQJAM4IAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJjYQkAZAIFAmJ2BQJhVQkAzAgCCQEMSW50ZWdlckVudHJ5AgUCYkMJAGQCBQJiRAUCYVUJAMwIAgkBAmFWBQIFc3Rha2UFAmF0BQJhdQUCYVUIBQJjbg10cmFuc2FjdGlvbklkBQNuaWwFAmN1BQJjdgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY3cGAmNuAmFDAmNyAmFFAmN4AmFVBAJhdAkApQgBBQJhRQQCYXUJANgEAQUCYUMEAmJBCQClCAEFAmNyBAJjYQkBAmFzAgUCYXQFAmF1BAJiQwkBAmF2AQUCYXUEAmJ2CQECYUEBBQJjYQQCYkQJAQJhQQEFAmJDBAJjdQgJAQJiVwQFAmF1BQJhdAUCYkEJAQEtAQUCYVUCXzIEAmJoCQECYmYBBQJhdQQCY3YDAwkBAmJtAgUCYmgFAmF0CQAAAgUCYVUFAmJ2BwkBAmJ0AgUCYmgFAmF0BQNuaWwEAmNzAwkAAAIFAmFVBQJidgkA/AcEBQJiYQISb25TdGFrZWRWb3RlVXBkYXRlCQDMCAIFAmF1CQDMCAIFAmF0CQDMCAIHBQNuaWwFA25pbAUEdW5pdAMJAAACBQJjcwUCY3MEAmN5CQEBRQIFBHRoaXMJAQJheAIFAmF1BQJhdAQCY2cICQECYlcEBQJhdQUCYXQFAmJBAAACXzEEAmN6CQC4AgIFAmNnBQJjeQQCY0EGBAJjQgMJAL8CAgUCY3oFAWgJAPwHBAUEdGhpcwIPY2xhaW1XeElOVEVSTkFMCQDMCAIFAmF1CQDMCAIFAmF0CQDMCAIFAmNBBQNuaWwFA25pbAUEdW5pdAMJAAACBQJjQgUCY0IDCQBmAgUCYVUFAmJ2CQEBbAEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIOcGFzc2VkIGFtb3VudD0JAKQDAQUCYVUCGyBpcyBncmVhdGVyIHRoYW4gYXZhaWxhYmxlPQkApAMBBQJidgIMLiBscEFzc2V0SWQ9BQJhdQISLiBzdGFrZWRCeVVzZXJLRVk9BQJjYQkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFAmNhCQBlAgUCYnYFAmFVCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJiQwkAZQIFAmJEBQJhVQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJjeAUCYVUFAmFDCQDMCAIJAQJhVgUCB3Vuc3Rha2UFAmF0BQJhdQUCYVUIBQJjbg10cmFuc2FjdGlvbklkBQNuaWwFAmN1BQJjdgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLhICY24BC2NvbnN0cnVjdG9yAQJjQwQCY0QJAQJjbwEFAmNuAwkAAAIFAmNEBQJjRAkAzAgCCQELU3RyaW5nRW50cnkCCQEBTQAFAmNDBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CY24BDWNvbnN0cnVjdG9yVjIBAmNFBAJjRgkAzAgCCQECY28BBQJjbgkAzAgCAwkBAiE9AgkApggBBQJjRQUEdW5pdAYCKGludmFsaWQgdm90aW5nIGVtaXNzaW9uIGNvbnRyYWN0IGFkZHJlc3MFA25pbAMJAAACBQJjRgUCY0YJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAU4ABQJjRQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNuAQpzZXRNYW5hZ2VyAQJjRwQCY0QJAQJjbwEFAmNuAwkAAAIFAmNEBQJjRAQCY0gJANkEAQUCY0cDCQAAAgUCY0gFAmNICQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFYAAUCY0cFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjbgEOY29uZmlybU1hbmFnZXIABAJjSQkBAmNrAAQCY0oDCQEJaXNEZWZpbmVkAQUCY0kGCQEBbAECEk5vIHBlbmRpbmcgbWFuYWdlcgMJAAACBQJjSgUCY0oEAmNLAwkAAAIIBQJjbg9jYWxsZXJQdWJsaWNLZXkJAQV2YWx1ZQEFAmNJBgkBAWwBAhtZb3UgYXJlIG5vdCBwZW5kaW5nIG1hbmFnZXIDCQAAAgUCY0sFAmNLCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFXAAkA2AQBCQEFdmFsdWUBBQJjSQkAzAgCCQELRGVsZXRlRW50cnkBCQEBWAAFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjbgEFc3Rha2UAAwkBAiE9AgkAkAMBCAUCY24IcGF5bWVudHMAAQkBAWwBAjRpbnZhbGlkIHBheW1lbnQgLSBleGFjdCBvbmUgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBAJjTAkAkQMCCAUCY24IcGF5bWVudHMAAAQCYUMJAQV2YWx1ZQEIBQJjTAdhc3NldElkBAJhdQkA2AQBBQJhQwQCYVUIBQJjTAZhbW91bnQEAmJBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUCYVkJAQJhYQEFAmF1CQEBagEJAKwCAgIVdW5zdXBwb3J0ZWQgbHAgYXNzZXQgBQJhdQQCY3IJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmJBBAJhRQMJAAACCAUCY24GY2FsbGVyBQJjcggFAmNuDG9yaWdpbkNhbGxlcggFAmNuBmNhbGxlcgkBAmNxBQUCY24FAmFDBQJjcgUCYUUFAmFVAmNuAQhzdGFrZUZvcgECYXQDCQECIT0CCQCQAwEIBQJjbghwYXltZW50cwABCQEBbAECNGludmFsaWQgcGF5bWVudCAtIGV4YWN0IG9uZSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQEAmNMCQCRAwIIBQJjbghwYXltZW50cwAABAJhQwkBBXZhbHVlAQgFAmNMB2Fzc2V0SWQEAmF1CQDYBAEFAmFDBAJhVQgFAmNMBmFtb3VudAQCYkEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQJhWQkBAmFhAQUCYXUJAQFqAQkArAICAhV1bnN1cHBvcnRlZCBscCBhc3NldCAFAmF1BAJjcgkBEUBleHRyTmF0aXZlKDEwNjIpAQUCYkEEAmFFCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQUCYXQJAQFqAQIUaW52YWxpZCB1c2VyIGFkZHJlc3MJAQJjcQUFAmNuBQJhQwUCY3IFAmFFBQJhVQJjbgEHdW5zdGFrZQICYXUCYVUEAmFDCQDZBAEFAmF1BAJiQQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFAmFZCQECYWEBBQJhdQkBAWoBCQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUCYXUEAmNyCQERQGV4dHJOYXRpdmUoMTA2MikBBQJiQQQCY00JAQt2YWx1ZU9yRWxzZQIJAJ0IAgUCY3IJAQFaAAUCYkEEAmNOCQClCAEIBQJjbgZjYWxsZXIEAmFFAwMJAAACBQJjTgUCYkEGCQAAAgUCY04FAmNNCAUCY24Mb3JpZ2luQ2FsbGVyCAUCY24GY2FsbGVyBAJjeAgFAmNuBmNhbGxlcgkBAmN3BgUCY24FAmFDBQJjcgUCYUUFAmN4BQJhVQJjbgEPdW5zdGFrZUlOVEVSTkFMBAJhQwJhVQJhRQJjeAQCYXUJANgEAQUCYUMEAmNyCQERQGV4dHJOYXRpdmUoMTA2MikBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUCYVkJAQJhYQEFAmF1CQEBagEJAKwCAgIVdW5zdXBwb3J0ZWQgbHAgYXNzZXQgBQJhdQQCY0QDCQAAAggFAmNuBmNhbGxlcgUCY3IGBQJjbAMJAAACBQJjRAUCY0QJAQJjdwYFAmNuBQJhQwUCY3IJAQdBZGRyZXNzAQUCYUUJAQdBZGRyZXNzAQUCY3gFAmFVCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNuAQdjbGFpbVd4AQJhdQQCYXQJAKUIAQgFAmNuBmNhbGxlcgQCY0EGBAJjTwkA/AcEBQR0aGlzAg9jbGFpbVd4SU5URVJOQUwJAMwIAgUCYXUJAMwIAgUCYXQJAMwIAgUCY0EFA25pbAUDbmlsCQCUCgIFA25pbAUCY08CY24BEWNsYWltV3hEb05vdFRocm93AQJhdQQCYXQJAKUIAQgFAmNuBmNhbGxlcgQCY0EHBAJjTwkA/AcEBQR0aGlzAg9jbGFpbVd4SU5URVJOQUwJAMwIAgUCYXUJAMwIAgUCYXQJAMwIAgUCY0EFA25pbAUDbmlsCQCUCgIFA25pbAUCY08CY24BD2NsYWltV3hJTlRFUk5BTAMCYXUCYXQCY0EEAmNECQECY20BBQJjbgMJAAACBQJjRAUCY0QEAmFFCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQUCYXQJAQFqAQIlY2xhaW1XeElOVEVSTkFMOiBpbnZhbGlkIHVzZXIgYWRkcmVzcwQCYkEJAQF6AgUCYVkJAQJhZAEFAmF1BAJjUAkBAmF3AgUCYXUFAmF0BAJjUQkBAmF6AQUCYXUEAmNSCQECYXgCBQJhdQUCYXQEAmNTCQECYXkCBQJhdQUCYXQEAmNUCQEBRQIFBHRoaXMFAmNQBAJjeQkBAUUCBQR0aGlzBQJjUgQCY1UJAQFFAgUEdGhpcwUCY1MEAmNWCQEBRQIFBHRoaXMFAmNRBAJjVwkBAmJXBAUCYXUFAmF0BQJiQQAABAJjZwgFAmNXAl8xBAJjdQgFAmNXAl8yBAJiVggFAmNXAl8zBAJjegkAmAMBCQDMCAIJALgCAgUCY2cFAmN5CQDMCAIFAWgFA25pbAMJAMACAgUBaAUCY3oDBQJjQQkBAWwBAhBub3RoaW5nIHRvIGNsYWltCQCUCgIFA25pbAAABAJjWAkAlgMBCQDMCAIJAQFxAQkAkQMCCQEBbQEJAPwHBAUCYmECDGNsYWltV3hCb29zdAkAzAgCBQJhdQkAzAgCBQJhdAUDbmlsBQNuaWwAAAkAzAgCAAAFA25pbAQCY1kFAmN6BAJjWgkAmQMBCQDMCAIJALkCAgUCY1kJALYCAQkAZQIFAmJiAAEJAMwIAgkAtgIBBQJjWAUDbmlsBAJkYQkAtwICBQJjWQUCY1oEAmRiCQEBdQEJAJEDAgkBAW0BCQD8BwQFAmFaAgRlbWl0CQDMCAIJAKADAQUCY1kFA25pbAUDbmlsAAAEAmRjCQEBbQEJAPwHBAUCYVoCBGVtaXQJAMwIAgkAoAMBBQJjWgUDbmlsBQNuaWwDCQAAAgUCZGMFAmRjBAJkZAkAtwICCQC3AgIFAmNUBQJjWQUCY1oEAmRlCQC3AgIFAmN5BQJjWQQCZGYJALcCAgUCY1UFAmNaBAJkZwkAtwICBQJjVgUCY3oJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQJjUAkApgMBBQJkZAkAzAgCCQELU3RyaW5nRW50cnkCBQJjUgkApgMBBQJkZQkAzAgCCQELU3RyaW5nRW50cnkCBQJjUwkApgMBBQJkZgkAzAgCCQELU3RyaW5nRW50cnkCBQJjUQkApgMBBQJkZwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhRQkAoAMBBQJjWQUCZGIJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYUUJAKADAQUCY1oFAmRiCQDMCAIJAQJhVgUCBWNsYWltBQJhdAUCYXUJAKADAQUCY3oIBQJjbg10cmFuc2FjdGlvbklkBQNuaWwJAKADAQUCZGEJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CY24BG2NsYWltV3hCdWxrSW50ZXJuYWxSRUFET05MWQQCZGgCZGkCYXQCZGoDCQAAAgUCZGgJAJADAQUCZGkJAJQKAgUDbmlsBQJkagQCYUMJAJEDAgUCZGkFAmRoBAJkawkAtQkCCgACYmMJAPwHBAUEdGhpcwIPY2xhaW1XeFJFQURPTkxZCQDMCAIFAmFDCQDMCAIFAmF0BQNuaWwFA25pbAMJAAECBQJiYwIGU3RyaW5nBQJiYwkAAgEJAKwCAgkAAwEFAmJjAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcFAWYEAmRsCQCRAwIFAmRrAAMEAmRtCQCRAwIFAmRrAAQEAmRuCgACYmMJAPwHBAUCYmECHGdldFVzZXJWb3RlRmluYWxpemVkUkVBRE9OTFkJAMwIAgUCYUMJAMwIAgUCYXQFA25pbAUDbmlsAwkAAQIFAmJjAgNJbnQFAmJjCQACAQkArAICCQADAQUCYmMCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAQCZG8JAM0IAgUCZGoJALkJAgkAzAgCAgYlZCVkJWQJAMwIAgUCZGwJAMwIAgUCZG0JAMwIAgkApAMBBQJkbgUDbmlsBQFmBAJkcAoAAmJjCQD8BwQFBHRoaXMCG2NsYWltV3hCdWxrSW50ZXJuYWxSRUFET05MWQkAzAgCCQBkAgUCZGgAAQkAzAgCBQJkaQkAzAgCBQJhdAkAzAgCBQJkbwUDbmlsBQNuaWwDCQABAgUCYmMCCUxpc3RbQW55XQUCYmMJAAIBCQCsAgIJAAMBBQJiYwIeIGNvdWxkbid0IGJlIGNhc3QgdG8gTGlzdFtBbnldAwkAAAIFAmRwBQJkcAkAlAoCBQNuaWwFAmRwCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNuARNjbGFpbVd4QnVsa1JFQURPTkxZAgJkaQJhdAQCZG8JAPwHBAUEdGhpcwIbY2xhaW1XeEJ1bGtJbnRlcm5hbFJFQURPTkxZCQDMCAIAAAkAzAgCBQJkaQkAzAgCBQJhdAkAzAgCBQNuaWwFA25pbAUDbmlsCQCUCgIFA25pbAUCZG8CY24BD2NsYWltV3hSRUFET05MWQICYXUCYXQEAmNhCQECYXMCBQJhdAUCYXUEAmJDCQECYXYBBQJhdQQCY1AJAQJhdwIFAmF1BQJhdAQCY1IJAQJheAIFAmF1BQJhdAQCYnYJAQJhQQEFAmNhBAJiRAkBAmFBAQUCYkMEAmNUCQEBRQIFBHRoaXMFAmNQBAJjeQkBAUUCBQR0aGlzBQJjUgQCYkEJAQF6AgUCYVkJAQJhZAEFAmF1BAJiRgkBEUBleHRyTmF0aXZlKDEwNTApAgUCYVkJAQJhZQEFAmJBBAJkcQkBAUQCBQJhWgkBAmFuAAQCYkcJAQFEAgUCYVoJAQJhcAAEAmRyAwkAZgIFAmJHBQZoZWlnaHQAAAkAZQIFBmhlaWdodAUCYkcEAmRzCQBrAwkAaAIFAmRxBQJkcgUCYkYFAWcEAmR0CQBrAwUCZHMFAmJ2BQJiRAQCZHUJAQJiVwQFAmF1BQJhdAUCYkEAAAQCY2cIBQJkdQJfMQQCY3UIBQJkdQJfMgQCYlYIBQJkdQJfMwQCY3oJAJgDAQkAzAgCCQC4AgIFAmNnBQJjeQkAzAgCBQFoBQNuaWwEAmR2CQEBbQEJAPwHBAUCYmECFGNsYWltV3hCb29zdFJFQURPTkxZCQDMCAIFAmF1CQDMCAIFAmF0BQNuaWwFA25pbAQCY1gJAJYDAQkAzAgCCQEBcQEJAJEDAgUCZHYAAAkAzAgCAAAFA25pbAQCZHcJAQFzAQkAkQMCBQJkdgABBAJjWQUCY3oEAmNaCQCZAwEJAMwIAgkAuQICBQJjWQkAtgIBCQBlAgUCYmIAAQkAzAgCCQC2AgEFAmNYBQNuaWwEAmRhCQC3AgIFAmNZBQJjWgkAlAoCBQNuaWwJALkJAgkAzAgCAg4lcyVzJWQlZCVkJWQlcwkAzAgCBQJhdQkAzAgCBQJhdAkAzAgCCQCmAwEFAmRhCQDMCAIJAKYDAQUCY1QJAMwIAgkApgMBBQJjWQkAzAgCCQCmAwEFAmNaCQDMCAICBHNvb24FA25pbAUBZgJjbgEUc3Rha2VkQnlVc2VyUkVBRE9OTFkCAmF1AmF0BAJidgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQECYXMCBQJhdAUCYXUAAAkAlAoCBQNuaWwFAmJ2AmNuARNzdGFrZWRUb3RhbFJFQURPTkxZAQJhdQQCYkQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAmF2AQUCYXUAAAkAlAoCBQNuaWwFAmJEAmNuARJ1c2Vyc0xpc3RUcmF2ZXJzYWwBAmFDBAJjRAMJAAACCQDYBAEICAUCY24GY2FsbGVyBWJ5dGVzCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJAQFOAAIABgkBAmNvAQUCY24DCQAAAgUCY0QFAmNEBAJiaAkBAmJmAQUCYUMEAmR4CQCiCAEJAQJiZQEFAmFDBAJibgkAoggBCQECYmcBBQJiaAQBbwUCZHgDCQABAgUBbwIEVW5pdAQCZHkFAmJuAwkAAQIFAmR5AgRVbml0CQCUCgIFA25pbAcDCQABAgUCZHkCBlN0cmluZwQCZHoFAmR5CQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmJlAQUCYUMFAmR6BQNuaWwGCQACAQILTWF0Y2ggZXJyb3IDCQABAgUBbwIGU3RyaW5nBAJhRQUBbwQCY3kJAQFFAgUEdGhpcwkBAmF4AgUCYUMFAmFFBAJjcgkBAXoCBQJhWQkBAmFkAQUCYUMEAmNnCAkBAmJXBAUCYUMFAmFFBQJjcgAAAl8xBAJjegkAuAICBQJjZwUCY3kEAmNBBgQCY0IDCQC/AgIFAmN6BQFoCQD8BwQFBHRoaXMCD2NsYWltV3hJTlRFUk5BTAkAzAgCBQJhQwkAzAgCBQJhRQkAzAgCBQJjQQUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCY0IFAmNCBAJkQQkAoggBCQECYmwCBQJiaAUCYUUEAmR5BQJkQQMJAAECBQJkeQIEVW5pdAkAlAoCCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJiZQEFAmFDBQNuaWwHAwkAAQIFAmR5AgZTdHJpbmcEAmRCBQJkeQkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJiZQEFAmFDBQJkQgUDbmlsBgkAAgECC01hdGNoIGVycm9yCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQILTWF0Y2ggZXJyb3IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CY24BDm9uTW9kaWZ5V2VpZ2h0AgJhdQJiQQMJAQIhPQIIBQJjbgZjYWxsZXIFAmFZCQEBbAECEnBlcm1pc3Npb25zIGRlbmllZAQCZEMJAQJiegMFAmF1BQJiQQAABAJieAgFAmRDAl8xBAJiWQgFAmRDAl8yBAJiWggFAmRDAl8zBQJiWQECZEQBAmRFAAQCZEYEAW8JAQJjagADCQABAgUBbwIKQnl0ZVZlY3RvcgQCY3AFAW8FAmNwAwkAAQIFAW8CBFVuaXQIBQJkRA9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgkA9AMDCAUCZEQJYm9keUJ5dGVzCQCRAwIIBQJkRAZwcm9vZnMAAAUCZEYbPTGm", "height": 2522859, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: EbsRBQWZa8sJRpSdEuAtvhhzAdcEMshah6YSyeDUYVwo Next: Djz7ee27LvVChWjoBCadUpWCKSCUBWaybYSjtGtfcEVH Diff:
OldNewDifferences
766766
767767
768768 @Callable(i)
769+func stakedTotalREADONLY (lpAssetIdStr) = {
770+ let stakedTotal = valueOrElse(getInteger(keyStakedTotal(lpAssetIdStr)), 0)
771+ $Tuple2(nil, stakedTotal)
772+ }
773+
774+
775+
776+@Callable(i)
769777 func usersListTraversal (lpAssetId) = {
770778 let checkCaller = if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionContract()), "")))
771779 then true
820828 func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
821829 then throwErr("permissions denied")
822830 else {
823- let $t03321333323 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
824- let wxPerLpIntegralNew = $t03321333323._1
825- let poolIntegralSTATE = $t03321333323._2
826- let poolDEBUG = $t03321333323._3
831+ let $t03337933489 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
832+ let wxPerLpIntegralNew = $t03337933489._1
833+ let poolIntegralSTATE = $t03337933489._2
834+ let poolDEBUG = $t03337933489._3
827835 poolIntegralSTATE
828836 }
829837
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SCALE8 = 8
55
66 let MULT3 = 1000
77
88 let MULT8 = 100000000
99
1010 let SCALE18 = 18
1111
1212 let MULT18 = toBigInt(1000000000000000000)
1313
1414 let SEP = "__"
1515
1616 let POOLWEIGHTMULT = MULT8
1717
1818 let zeroBigInt = toBigInt(0)
1919
2020 let oneBigInt = toBigInt(1)
2121
2222 func wrapErr (msg) = makeString(["staking.ride:", toString(this), msg], " ")
2323
2424
2525 func throwErr (msg) = throw(wrapErr(msg))
2626
2727
2828 func asAnyList (val) = match val {
2929 case valAnyLyst: List[Any] =>
3030 valAnyLyst
3131 case _ =>
3232 throwErr("fail to cast into List[Any]")
3333 }
3434
3535
3636 func asInt (val) = match val {
3737 case valInt: Int =>
3838 valInt
3939 case _ =>
4040 throwErr("fail to cast into Int")
4141 }
4242
4343
4444 func asString (val) = match val {
4545 case valStr: String =>
4646 valStr
4747 case _ =>
4848 throwErr("fail to cast into Int")
4949 }
5050
5151
5252 func asByteVector (val) = match val {
5353 case valBin: ByteVector =>
5454 valBin
5555 case _ =>
5656 throwErr("fail to cast into Int")
5757 }
5858
5959
6060 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), wrapErr((("mandatory this." + key) + " is not defined")))
6161
6262
6363 func getStringByAddressOrFail (address,key) = valueOrErrorMessage(getString(address, key), wrapErr((((("mandatory " + toString(address)) + ".") + key) + " is not defined")))
6464
6565
6666 func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
6767
6868
6969 func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
7070
7171
7272 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), wrapErr((("mandatory this." + key) + " is not defined")))
7373
7474
7575 func getBigIntFromStringOrZero (address,key) = value(parseBigInt(valueOrElse(getString(address, key), "0")))
7676
7777
7878 func getBigIntFromStringOrDefault (address,key,defaultVal) = match getString(address, key) {
7979 case s: String =>
8080 value(parseBigInt(s))
8181 case _: Unit =>
8282 defaultVal
8383 case _ =>
8484 throw("Match error")
8585 }
8686
8787
8888 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULT18, toBigInt(origScaleMult))
8989
9090
9191 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULT18))
9292
9393
9494 func keyFactoryAddress () = "%s%s__config__factoryAddress"
9595
9696
9797 func keyVotingEmissionContract () = "%s__votingEmissionContract"
9898
9999
100100 let IdxFactoryCfgStakingDapp = 1
101101
102102 let IdxFactoryCfgBoostingDapp = 2
103103
104104 let IdxFactoryCfgIdoDapp = 3
105105
106106 let IdxFactoryCfgTeamDapp = 4
107107
108108 let IdxFactoryCfgEmissionDapp = 5
109109
110110 let IdxFactoryCfgRestDapp = 6
111111
112112 let IdxFactoryCfgSlippageDapp = 7
113113
114114 func keyFactoryCfg () = "%s__factoryConfig"
115115
116116
117117 func keyManagerPublicKey () = "%s__managerPublicKey"
118118
119119
120120 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
121121
122122
123123 func keyStablePoolAddonAddr () = "%s__stablePoolAddonAddr"
124124
125125
126126 func keyAddonAddr () = "%s__addonAddr"
127127
128128
129129 func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
130130
131131
132132 func keyFactoryLpList () = "%s__lpTokensList"
133133
134134
135135 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
136136
137137
138138 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
139139
140140
141141 func readLpList (factory) = split(valueOrElse(getString(factory, keyFactoryLpList()), ""), SEP)
142142
143143
144144 func readFactoryCfgOrFail (factory) = split(getStringByAddressOrFail(factory, keyFactoryCfg()), SEP)
145145
146146
147147 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
148148
149149
150150 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
151151
152152
153153 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
154154
155155
156156 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
157157
158158
159159 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
160160
161161
162162 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
163163
164164
165165 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
166166
167167
168168 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
169169
170170
171171 func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s__staked", userAddressStr, lpAssetIdStr], SEP)
172172
173173
174174 func keyStakedTotal (lpAssetIdStr) = ("%s%s%s__staked__total__" + lpAssetIdStr)
175175
176176
177177 func keyClaimedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimed", userAddressStr, lpAssetIdStr], SEP)
178178
179179
180180 func keyClaimedByUserMinReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedMinReward", userAddressStr, lpAssetIdStr], SEP)
181181
182182
183183 func keyClaimedByUserBoostReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedBoostReward", userAddressStr, lpAssetIdStr], SEP)
184184
185185
186186 func keyClaimedTotal (lpAssetIdStr) = makeString(["%s%s%s__claimed__total", lpAssetIdStr], SEP)
187187
188188
189189 func readStaked (key) = valueOrElse(getInteger(this, key), 0)
190190
191191
192192 func keyLastTotalLpBalance (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "bal"], SEP)
193193
194194
195195 func keyLastUserLpBalance (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "bal"], SEP)
196196
197197
198198 func keyTotalLpBalanceIntegral (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "balINT"], SEP)
199199
200200
201201 func keyUserLpBalanceIntegral (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "balINT"], SEP)
202202
203203
204204 func keyTotalLpBalanceIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "lastUpd"], SEP)
205205
206206
207207 func keyUserLpBalanceIntegralLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "lastUpd"], SEP)
208208
209209
210210 func keyWxPerLpIntegral (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpInt"], SEP)
211211
212212
213213 func keyWxPerLpIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpIntH"], SEP)
214214
215215
216216 func keyWxToClaimUser (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpInt"], SEP)
217217
218218
219219 func keyWxPerLpIntegralUserLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpIntH"], SEP)
220220
221221
222222 func keyWxPerLp (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLp"], SEP)
223223
224224
225225 func keyWxPerLpX18 (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLpX18"], SEP)
226226
227227
228228 func keyWxPerLpIntegralUserLast (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "uIntL"], SEP)
229229
230230
231231 func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
232232
233233
234234 func formatHistoryRecord (userAddress,lpAssetId,type,amount) = makeString(["%s%s%s%d%d%d", userAddress, lpAssetId, type, toString(height), toString(lastBlock.timestamp), toString(amount)], SEP)
235235
236236
237237 func OperationHistoryEntry (type,userAddress,lpAssetId,amount,txId) = StringEntry(keyOperationHistoryRecord(type, userAddress, toBase58String(txId)), formatHistoryRecord(userAddress, lpAssetId, type, amount))
238238
239239
240240 let factoryAddress = getStringOrFail(this, keyFactoryAddress())
241241
242242 let factoryContract = addressFromStringValue(factoryAddress)
243243
244244 let factoryCfg = readFactoryCfgOrFail(factoryContract)
245245
246246 let emissionContract = getEmissionAddressOrFail(factoryCfg)
247247
248248 let boostingContract = getBoostingAddressOrFail(factoryCfg)
249249
250250 let boostCoeff = {
251251 let @ = invoke(emissionContract, "getBoostCoeffREADONLY", nil, nil)
252252 if ($isInstanceOf(@, "Int"))
253253 then @
254254 else throw(($getType(@) + " couldn't be cast to Int"))
255255 }
256256
257257 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"))
258258
259259 func keyNextUser (lpAssetId) = makeString(["%s%s", lpAssetId, "nextUser"], SEP)
260260
261261
262262 func getUsersListName (lpAssetId) = makeString(["users", lpAssetId], SEP)
263263
264264
265265 func keyListHead (listName) = makeString(["%s%s%s", listName, "head"], SEP)
266266
267267
268268 func keyListSize (listName) = makeString(["%s%s%s", listName, "size"], SEP)
269269
270270
271271 func keyListPrev (listName,id) = makeString(["%s%s%s%s", listName, id, "prev"], SEP)
272272
273273
274274 func keyListNext (listName,id) = makeString(["%s%s%s%s", listName, id, "next"], SEP)
275275
276276
277277 func containsNode (listName,id) = {
278278 let headOrUnit = getString(this, keyListHead(listName))
279279 let prevOrUnit = getString(this, keyListPrev(listName, id))
280280 let nextOrUnit = getString(this, keyListNext(listName, id))
281281 if (if ((id == valueOrElse(headOrUnit, "")))
282282 then true
283283 else (prevOrUnit != unit))
284284 then true
285285 else (nextOrUnit != unit)
286286 }
287287
288288
289289 func insertNodeActions (listName,id) = {
290290 let headOrUnit = getString(this, keyListHead(listName))
291291 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
292292 let checkNode = if (!(containsNode(listName, id)))
293293 then true
294294 else throwErr("Node exists")
295295 if ((checkNode == checkNode))
296296 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
297297 then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
298298 else nil)) ++ [StringEntry(keyListHead(listName), id)])
299299 else throw("Strict value is not equal to itself.")
300300 }
301301
302302
303303 func deleteNodeActions (listName,id) = {
304304 let headOrUnit = getString(this, keyListHead(listName))
305305 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
306306 let prevOrUnit = getString(this, keyListPrev(listName, id))
307307 let nextOrUnit = getString(this, keyListNext(listName, id))
308308 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
309309 then (nextOrUnit != unit)
310310 else false)
311311 then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
312312 else if ((nextOrUnit != unit))
313313 then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
314314 else if ((prevOrUnit != unit))
315315 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
316316 else if ((id == valueOrElse(headOrUnit, "")))
317317 then [DeleteEntry(keyListHead(listName))]
318318 else throwErr(((("invalid node: " + listName) + ".") + id))))
319319 }
320320
321321
322322 func calcWxPerLpIntegralUserLast (stakedByUser,wxPerLpIntegralUserLastUpdHeightOrZero,wxPerLpIntegralNew,wxPerLpIntegralUserLastKEY) = if (if ((wxPerLpIntegralUserLastUpdHeightOrZero == zeroBigInt))
323323 then (stakedByUser > zeroBigInt)
324324 else false)
325325 then zeroBigInt
326326 else if ((stakedByUser == zeroBigInt))
327327 then wxPerLpIntegralNew
328328 else if (if ((wxPerLpIntegralUserLastUpdHeightOrZero > zeroBigInt))
329329 then (stakedByUser > zeroBigInt)
330330 else false)
331331 then value(parseBigInt(getStringOrFail(this, wxPerLpIntegralUserLastKEY)))
332332 else throwErr("calcWxPerLpIntegralUserLast: unexpected state")
333333
334334
335335 func refreshPoolINTEGRALS (lpAssetIdStr,poolAddressStr,lpDeltaAmount) = {
336336 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
337337 let stakedTotal = toBigInt(readStaked(stakedTotalKEY))
338338 let nonZeroStakedTotal = if ((stakedTotal == zeroBigInt))
339339 then oneBigInt
340340 else stakedTotal
341341 let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
342342 let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
343343 let wxEmissionPerBlockX3 = (getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) * MULT3)
344344 let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * boostCoeff))
345345 let wxPerLpIntegralKEY = keyWxPerLpIntegral(lpAssetIdStr)
346346 let wxPerLpIntegralLastUpdHeightKEY = keyWxPerLpIntegralLastUpdHeight(lpAssetIdStr)
347347 let wxPerLpKEY = keyWxPerLp(lpAssetIdStr)
348348 let wxPerLpIntegralLastUpdHeight = getIntOrDefault(this, wxPerLpIntegralLastUpdHeightKEY, emissionStartBlock)
349349 let wxPerLpIntegral = getBigIntFromStringOrZero(this, wxPerLpIntegralKEY)
350350 let wxPerLpOrZeroX3 = 0
351351 let dh = max([(height - wxPerLpIntegralLastUpdHeight), 0])
352352 let wxPerLpX3 = if ((wxPerLpOrZeroX3 != 0))
353353 then toBigInt(wxPerLpOrZeroX3)
354354 else fraction(toBigInt(poolWxEmissionPerBlockX3), toBigInt(MULT8), nonZeroStakedTotal)
355355 let stakedTotalNew = (stakedTotal + toBigInt(lpDeltaAmount))
356356 let nonZeroStakedTotalNew = if ((stakedTotalNew == zeroBigInt))
357357 then oneBigInt
358358 else stakedTotalNew
359359 let wxPerLpIntegralNew = (wxPerLpIntegral + (wxPerLpX3 * toBigInt(dh)))
360360 let wxPerLpX3New = (toBigInt(poolWxEmissionPerBlockX3) / nonZeroStakedTotalNew)
361361 let wxPerLpIntegralLastUpdHeightNew = height
362362 let debug = makeString([toString(wxPerLpIntegralNew), toString(dh), toString(wxPerLpX3), toString(stakedTotal), toString(poolWxEmissionPerBlockX3), toString(wxEmissionPerBlockX3), toString(poolWeight)], "::")
363363 $Tuple3(wxPerLpIntegralNew, [StringEntry(wxPerLpIntegralKEY, toString(wxPerLpIntegralNew)), IntegerEntry(wxPerLpIntegralLastUpdHeightKEY, wxPerLpIntegralLastUpdHeightNew), StringEntry(wxPerLpKEY, toString(wxPerLpX3New))], debug)
364364 }
365365
366366
367367 func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
368368 let $t01481914941 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
369369 let wxPerLpIntegralNew = $t01481914941._1
370370 let poolIntegralSTATE = $t01481914941._2
371371 let poolDEBUG = $t01481914941._3
372372 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
373373 let stakedByUser = readStaked(stakedByUserKEY)
374374 let wxToClaimUserKEY = keyWxToClaimUser(lpAssetIdStr, userAddressStr)
375375 let wxPerLpIntegralUserLastUpdHeightKEY = keyWxPerLpIntegralUserLastUpdHeight(lpAssetIdStr, userAddressStr)
376376 let wxPerLpIntegralUserLastKEY = keyWxPerLpIntegralUserLast(lpAssetIdStr, userAddressStr)
377377 let wxToClaimUser = getBigIntFromStringOrZero(this, wxToClaimUserKEY)
378378 let wxPerLpIntegralUserLastUpdHeightOrZero = getIntOrZero(this, wxPerLpIntegralUserLastUpdHeightKEY)
379379 let wxPerLpIntegralUserLast = calcWxPerLpIntegralUserLast(toBigInt(stakedByUser), toBigInt(wxPerLpIntegralUserLastUpdHeightOrZero), wxPerLpIntegralNew, wxPerLpIntegralUserLastKEY)
380380 let MULT11 = (MULT8 * MULT3)
381381 let wxToClaimUserNew = max([(wxToClaimUser + fraction((wxPerLpIntegralNew - wxPerLpIntegralUserLast), toBigInt(stakedByUser), toBigInt(MULT11))), zeroBigInt])
382382 let wxPerLpIntegralUserLastNew = wxPerLpIntegralNew
383383 let wxPerLpIntegralUserLastUpdHeightNew = height
384384 let debug = makeString([toString(wxToClaimUser), toString(wxPerLpIntegralUserLast), toString(stakedByUser), poolDEBUG, toString(height)], "::")
385385 $Tuple3(wxToClaimUserNew, (poolIntegralSTATE ++ [StringEntry(wxToClaimUserKEY, toString(wxToClaimUserNew)), IntegerEntry(wxPerLpIntegralUserLastUpdHeightKEY, wxPerLpIntegralUserLastUpdHeightNew), StringEntry(wxPerLpIntegralUserLastKEY, toString(wxPerLpIntegralUserLastNew))]), debug)
386386 }
387387
388388
389389 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
390390 case s: String =>
391391 fromBase58String(s)
392392 case _: Unit =>
393393 unit
394394 case _ =>
395395 throw("Match error")
396396 }
397397
398398
399399 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
400400 case s: String =>
401401 fromBase58String(s)
402402 case _: Unit =>
403403 unit
404404 case _ =>
405405 throw("Match error")
406406 }
407407
408408
409409 let permissionDeniedError = throwErr("Permission denied")
410410
411411 func mustThis (i) = if ((i.caller == this))
412412 then true
413413 else permissionDeniedError
414414
415415
416416 func mustManager (i) = match managerPublicKeyOrUnit() {
417417 case pk: ByteVector =>
418418 if ((i.callerPublicKey == pk))
419419 then true
420420 else permissionDeniedError
421421 case _: Unit =>
422422 if ((i.caller == this))
423423 then true
424424 else permissionDeniedError
425425 case _ =>
426426 throw("Match error")
427427 }
428428
429429
430430 func stakeActions (i,lpAssetId,poolAddress,userAddress,amount) = {
431431 let userAddressStr = toString(userAddress)
432432 let lpAssetIdStr = toBase58String(lpAssetId)
433433 let poolAddressStr = toString(poolAddress)
434434 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
435435 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
436436 let stakedByUser = readStaked(stakedByUserKEY)
437437 let refreshStakedVote = if ((stakedByUser == 0))
438438 then invoke(boostingContract, "onStakedVoteUpdate", [lpAssetIdStr, userAddressStr, true], nil)
439439 else unit
440440 if ((refreshStakedVote == refreshStakedVote))
441441 then {
442442 let stakedTotal = readStaked(stakedTotalKEY)
443443 let $t01816018277 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
444444 let wxToClaimUserNew = $t01816018277._1
445445 let integralSTATE = $t01816018277._2
446446 let debug = $t01816018277._3
447447 let listName = getUsersListName(lpAssetIdStr)
448448 let listActions = if (containsNode(listName, userAddressStr))
449449 then nil
450450 else insertNodeActions(listName, userAddressStr)
451451 (([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
452452 }
453453 else throw("Strict value is not equal to itself.")
454454 }
455455
456456
457457 func unstakeActions (i,lpAssetId,poolAddress,userAddress,lpAssetRecipientAddress,amount) = {
458458 let userAddressStr = toString(userAddress)
459459 let lpAssetIdStr = toBase58String(lpAssetId)
460460 let poolAddressStr = toString(poolAddress)
461461 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
462462 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
463463 let stakedByUser = readStaked(stakedByUserKEY)
464464 let stakedTotal = readStaked(stakedTotalKEY)
465465 let integralSTATE = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))._2
466466 let listName = getUsersListName(lpAssetIdStr)
467467 let listActions = if (if (containsNode(listName, userAddressStr))
468468 then (amount == stakedByUser)
469469 else false)
470470 then deleteNodeActions(listName, userAddressStr)
471471 else nil
472472 let refreshStakedVote = if ((amount == stakedByUser))
473473 then invoke(boostingContract, "onStakedVoteUpdate", [lpAssetIdStr, userAddressStr, false], nil)
474474 else unit
475475 if ((refreshStakedVote == refreshStakedVote))
476476 then {
477477 let claimedByUserMinReward = getBigIntFromStringOrZero(this, keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr))
478478 let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)._1
479479 let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
480480 let throwIfNothingToClaim = true
481481 let r = if ((availableToClaim > zeroBigInt))
482482 then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
483483 else unit
484484 if ((r == r))
485485 then if ((amount > stakedByUser))
486486 then throwErr(((((((("passed amount=" + toString(amount)) + " is greater than available=") + toString(stakedByUser)) + ". lpAssetId=") + lpAssetIdStr) + ". stakedByUserKEY=") + stakedByUserKEY))
487487 else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(lpAssetRecipientAddress, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
488488 else throw("Strict value is not equal to itself.")
489489 }
490490 else throw("Strict value is not equal to itself.")
491491 }
492492
493493
494494 @Callable(i)
495495 func constructor (factoryAddressStr) = {
496496 let checkCaller = mustManager(i)
497497 if ((checkCaller == checkCaller))
498498 then [StringEntry(keyFactoryAddress(), factoryAddressStr)]
499499 else throw("Strict value is not equal to itself.")
500500 }
501501
502502
503503
504504 @Callable(i)
505505 func constructorV2 (votingEmissionContract) = {
506506 let cheks = [mustManager(i), if ((addressFromString(votingEmissionContract) != unit))
507507 then true
508508 else "invalid voting emission contract address"]
509509 if ((cheks == cheks))
510510 then [StringEntry(keyVotingEmissionContract(), votingEmissionContract)]
511511 else throw("Strict value is not equal to itself.")
512512 }
513513
514514
515515
516516 @Callable(i)
517517 func setManager (pendingManagerPublicKey) = {
518518 let checkCaller = mustManager(i)
519519 if ((checkCaller == checkCaller))
520520 then {
521521 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
522522 if ((checkManagerPublicKey == checkManagerPublicKey))
523523 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
524524 else throw("Strict value is not equal to itself.")
525525 }
526526 else throw("Strict value is not equal to itself.")
527527 }
528528
529529
530530
531531 @Callable(i)
532532 func confirmManager () = {
533533 let pm = pendingManagerPublicKeyOrUnit()
534534 let hasPM = if (isDefined(pm))
535535 then true
536536 else throwErr("No pending manager")
537537 if ((hasPM == hasPM))
538538 then {
539539 let checkPM = if ((i.callerPublicKey == value(pm)))
540540 then true
541541 else throwErr("You are not pending manager")
542542 if ((checkPM == checkPM))
543543 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
544544 else throw("Strict value is not equal to itself.")
545545 }
546546 else throw("Strict value is not equal to itself.")
547547 }
548548
549549
550550
551551 @Callable(i)
552552 func stake () = if ((size(i.payments) != 1))
553553 then throwErr("invalid payment - exact one payment must be attached")
554554 else {
555555 let pmt = i.payments[0]
556556 let lpAssetId = value(pmt.assetId)
557557 let lpAssetIdStr = toBase58String(lpAssetId)
558558 let amount = pmt.amount
559559 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), wrapErr(("unsupported lp asset " + lpAssetIdStr)))
560560 let poolAddress = addressFromStringValue(poolAddressStr)
561561 let userAddress = if ((i.caller == poolAddress))
562562 then i.originCaller
563563 else i.caller
564564 stakeActions(i, lpAssetId, poolAddress, userAddress, amount)
565565 }
566566
567567
568568
569569 @Callable(i)
570570 func stakeFor (userAddressStr) = if ((size(i.payments) != 1))
571571 then throwErr("invalid payment - exact one payment must be attached")
572572 else {
573573 let pmt = i.payments[0]
574574 let lpAssetId = value(pmt.assetId)
575575 let lpAssetIdStr = toBase58String(lpAssetId)
576576 let amount = pmt.amount
577577 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), wrapErr(("unsupported lp asset " + lpAssetIdStr)))
578578 let poolAddress = addressFromStringValue(poolAddressStr)
579579 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
580580 stakeActions(i, lpAssetId, poolAddress, userAddress, amount)
581581 }
582582
583583
584584
585585 @Callable(i)
586586 func unstake (lpAssetIdStr,amount) = {
587587 let lpAssetId = fromBase58String(lpAssetIdStr)
588588 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), wrapErr(("unsupported lp asset " + lpAssetIdStr)))
589589 let poolAddress = addressFromStringValue(poolAddressStr)
590590 let poolAddon = valueOrElse(getString(poolAddress, keyAddonAddr()), poolAddressStr)
591591 let callerStr = toString(i.caller)
592592 let userAddress = if (if ((callerStr == poolAddressStr))
593593 then true
594594 else (callerStr == poolAddon))
595595 then i.originCaller
596596 else i.caller
597597 let lpAssetRecipientAddress = i.caller
598598 unstakeActions(i, lpAssetId, poolAddress, userAddress, lpAssetRecipientAddress, amount)
599599 }
600600
601601
602602
603603 @Callable(i)
604604 func unstakeINTERNAL (lpAssetId,amount,userAddress,lpAssetRecipientAddress) = {
605605 let lpAssetIdStr = toBase58String(lpAssetId)
606606 let poolAddress = addressFromStringValue(valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), wrapErr(("unsupported lp asset " + lpAssetIdStr))))
607607 let checkCaller = if ((i.caller == poolAddress))
608608 then true
609609 else permissionDeniedError
610610 if ((checkCaller == checkCaller))
611611 then unstakeActions(i, lpAssetId, poolAddress, Address(userAddress), Address(lpAssetRecipientAddress), amount)
612612 else throw("Strict value is not equal to itself.")
613613 }
614614
615615
616616
617617 @Callable(i)
618618 func claimWx (lpAssetIdStr) = {
619619 let userAddressStr = toString(i.caller)
620620 let throwIfNothingToClaim = true
621621 let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
622622 $Tuple2(nil, result)
623623 }
624624
625625
626626
627627 @Callable(i)
628628 func claimWxDoNotThrow (lpAssetIdStr) = {
629629 let userAddressStr = toString(i.caller)
630630 let throwIfNothingToClaim = false
631631 let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
632632 $Tuple2(nil, result)
633633 }
634634
635635
636636
637637 @Callable(i)
638638 func claimWxINTERNAL (lpAssetIdStr,userAddressStr,throwIfNothingToClaim) = {
639639 let checkCaller = mustThis(i)
640640 if ((checkCaller == checkCaller))
641641 then {
642642 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("claimWxINTERNAL: invalid user address"))
643643 let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
644644 let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
645645 let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr)
646646 let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
647647 let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr)
648648 let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
649649 let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
650650 let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
651651 let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
652652 let $t02631426426 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
653653 let wxToClaimUserNew = $t02631426426._1
654654 let integralSTATE = $t02631426426._2
655655 let debug = $t02631426426._3
656656 let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
657657 if ((zeroBigInt >= availableToClaim))
658658 then if (throwIfNothingToClaim)
659659 then throwErr("nothing to claim")
660660 else $Tuple2(nil, 0)
661661 else {
662662 let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
663663 let minRewardPart = availableToClaim
664664 let boostRewardPart = min([(minRewardPart * toBigInt((boostCoeff - 1))), toBigInt(wxAmountBoostTotal)])
665665 let totalReward = (minRewardPart + boostRewardPart)
666666 let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
667667 let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
668668 if ((emitBoost == emitBoost))
669669 then {
670670 let claimedByUserValue = ((claimedByUser + minRewardPart) + boostRewardPart)
671671 let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
672672 let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserBoostReward + boostRewardPart)
673673 let claimedTotalPlusAvailableToClaim = (claimedTotal + availableToClaim)
674674 $Tuple2([StringEntry(claimedByUserKEY, toString(claimedByUserValue)), StringEntry(claimedByUserMinRewardKEY, toString(claimedByUserMinRewardPlusPart)), StringEntry(claimedByUserBoostRewardKEY, toString(claimedByUserBoostRewardPlusBoostRewardPart)), StringEntry(claimedTotalKEY, toString(claimedTotalPlusAvailableToClaim)), ScriptTransfer(userAddress, toInt(minRewardPart), wxAssetId), ScriptTransfer(userAddress, toInt(boostRewardPart), wxAssetId), OperationHistoryEntry("claim", userAddressStr, lpAssetIdStr, toInt(availableToClaim), i.transactionId)], toInt(totalReward))
675675 }
676676 else throw("Strict value is not equal to itself.")
677677 }
678678 }
679679 else throw("Strict value is not equal to itself.")
680680 }
681681
682682
683683
684684 @Callable(i)
685685 func claimWxBulkInternalREADONLY (currentIter,lpAssetIds,userAddressStr,resAcc) = if ((currentIter == size(lpAssetIds)))
686686 then $Tuple2(nil, resAcc)
687687 else {
688688 let lpAssetId = lpAssetIds[currentIter]
689689 let info = split({
690690 let @ = invoke(this, "claimWxREADONLY", [lpAssetId, userAddressStr], nil)
691691 if ($isInstanceOf(@, "String"))
692692 then @
693693 else throw(($getType(@) + " couldn't be cast to String"))
694694 }, SEP)
695695 let unclaimed = info[3]
696696 let claimed = info[4]
697697 let userVoteFinalized = {
698698 let @ = invoke(boostingContract, "getUserVoteFinalizedREADONLY", [lpAssetId, userAddressStr], nil)
699699 if ($isInstanceOf(@, "Int"))
700700 then @
701701 else throw(($getType(@) + " couldn't be cast to Int"))
702702 }
703703 let res = (resAcc :+ makeString(["%d%d%d", unclaimed, claimed, toString(userVoteFinalized)], SEP))
704704 let inv = {
705705 let @ = invoke(this, "claimWxBulkInternalREADONLY", [(currentIter + 1), lpAssetIds, userAddressStr, res], nil)
706706 if ($isInstanceOf(@, "List[Any]"))
707707 then @
708708 else throw(($getType(@) + " couldn't be cast to List[Any]"))
709709 }
710710 if ((inv == inv))
711711 then $Tuple2(nil, inv)
712712 else throw("Strict value is not equal to itself.")
713713 }
714714
715715
716716
717717 @Callable(i)
718718 func claimWxBulkREADONLY (lpAssetIds,userAddressStr) = {
719719 let res = invoke(this, "claimWxBulkInternalREADONLY", [0, lpAssetIds, userAddressStr, nil], nil)
720720 $Tuple2(nil, res)
721721 }
722722
723723
724724
725725 @Callable(i)
726726 func claimWxREADONLY (lpAssetIdStr,userAddressStr) = {
727727 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
728728 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
729729 let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
730730 let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
731731 let stakedByUser = readStaked(stakedByUserKEY)
732732 let stakedTotal = readStaked(stakedTotalKEY)
733733 let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
734734 let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
735735 let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
736736 let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
737737 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
738738 let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
739739 let passedBlocks = if ((emissionStartBlock > height))
740740 then 0
741741 else (height - emissionStartBlock)
742742 let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
743743 let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
744744 let $t03047730589 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
745745 let wxToClaimUserNew = $t03047730589._1
746746 let integralSTATE = $t03047730589._2
747747 let debug = $t03047730589._3
748748 let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
749749 let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
750750 let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
751751 let boostDebug = asString(boostInvResult[1])
752752 let minRewardPart = availableToClaim
753753 let boostRewardPart = min([(minRewardPart * toBigInt((boostCoeff - 1))), toBigInt(wxAmountBoostTotal)])
754754 let totalReward = (minRewardPart + boostRewardPart)
755755 $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), "soon"], SEP))
756756 }
757757
758758
759759
760760 @Callable(i)
761761 func stakedByUserREADONLY (lpAssetIdStr,userAddressStr) = {
762762 let stakedByUser = valueOrElse(getInteger(keyStakedByUser(userAddressStr, lpAssetIdStr)), 0)
763763 $Tuple2(nil, stakedByUser)
764764 }
765765
766766
767767
768768 @Callable(i)
769+func stakedTotalREADONLY (lpAssetIdStr) = {
770+ let stakedTotal = valueOrElse(getInteger(keyStakedTotal(lpAssetIdStr)), 0)
771+ $Tuple2(nil, stakedTotal)
772+ }
773+
774+
775+
776+@Callable(i)
769777 func usersListTraversal (lpAssetId) = {
770778 let checkCaller = if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionContract()), "")))
771779 then true
772780 else mustManager(i)
773781 if ((checkCaller == checkCaller))
774782 then {
775783 let listName = getUsersListName(lpAssetId)
776784 let userOrUnit = getString(keyNextUser(lpAssetId))
777785 let headOrUnit = getString(keyListHead(listName))
778786 match userOrUnit {
779787 case _: Unit =>
780788 match headOrUnit {
781789 case _: Unit =>
782790 $Tuple2(nil, false)
783791 case head: String =>
784792 $Tuple2([StringEntry(keyNextUser(lpAssetId), head)], true)
785793 case _ =>
786794 throw("Match error")
787795 }
788796 case userAddress: String =>
789797 let claimedByUserMinReward = getBigIntFromStringOrZero(this, keyClaimedByUserMinReward(lpAssetId, userAddress))
790798 let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetId))
791799 let wxToClaimUserNew = refreshINTEGRALS(lpAssetId, userAddress, poolAddress, 0)._1
792800 let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
793801 let throwIfNothingToClaim = true
794802 let r = if ((availableToClaim > zeroBigInt))
795803 then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress, throwIfNothingToClaim], nil)
796804 else unit
797805 if ((r == r))
798806 then {
799807 let nextUserOrUnit = getString(keyListNext(listName, userAddress))
800808 match nextUserOrUnit {
801809 case _: Unit =>
802810 $Tuple2([DeleteEntry(keyNextUser(lpAssetId))], false)
803811 case nextUser: String =>
804812 $Tuple2([StringEntry(keyNextUser(lpAssetId), nextUser)], true)
805813 case _ =>
806814 throw("Match error")
807815 }
808816 }
809817 else throw("Strict value is not equal to itself.")
810818 case _ =>
811819 throw("Match error")
812820 }
813821 }
814822 else throw("Strict value is not equal to itself.")
815823 }
816824
817825
818826
819827 @Callable(i)
820828 func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
821829 then throwErr("permissions denied")
822830 else {
823- let $t03321333323 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
824- let wxPerLpIntegralNew = $t03321333323._1
825- let poolIntegralSTATE = $t03321333323._2
826- let poolDEBUG = $t03321333323._3
831+ let $t03337933489 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
832+ let wxPerLpIntegralNew = $t03337933489._1
833+ let poolIntegralSTATE = $t03337933489._2
834+ let poolDEBUG = $t03337933489._3
827835 poolIntegralSTATE
828836 }
829837
830838
831839 @Verifier(tx)
832840 func verify () = {
833841 let targetPublicKey = match managerPublicKeyOrUnit() {
834842 case pk: ByteVector =>
835843 pk
836844 case _: Unit =>
837845 tx.senderPublicKey
838846 case _ =>
839847 throw("Match error")
840848 }
841849 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
842850 }
843851

github/deemru/w8io/3ef1775 
121.34 ms