tx · ALtC3XNS9GqZwkD4e9R528GegaScZPP52ExxmxjFf7Q2

3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz:  -0.02200000 Waves

2023.02.28 14:15 [2469479] smart account 3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz > SELF 0.00000000 Waves

{ "type": 13, "id": "ALtC3XNS9GqZwkD4e9R528GegaScZPP52ExxmxjFf7Q2", "fee": 2200000, "feeAssetId": null, "timestamp": 1677582965057, "version": 2, "chainId": 84, "sender": "3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz", "senderPublicKey": "D28XoueZWsMfm8Y5pa6C5ZFuYoWgre2Wm8tzJANJgMnq", "proofs": [ "3RroqkMjTHaLPmPgyQetQPRuo7QoqRc38WmHPuLSCrfTANWasaKoPt86hQNvtECHywb1GK7Bm2a7tPgWuBAjcz4T" ], "script": "base64:BgL1HggCEgMKAQgSAwoBCBIDCgEIEgASABIECgIIARIDCgEIEgQKAggIEgYKBAEYCBgSBAoCGAgSBAoCCAgSAwoBCBIECgIICCIGU0NBTEU4IgVNVUxUOCIHU0NBTEUxOCIGTVVMVDE4IgNTRVAiDlBPT0xXRUlHSFRNVUxUIgp6ZXJvQmlnSW50IglvbmVCaWdJbnQiCWFzQW55TGlzdCIDdmFsIgckbWF0Y2gwIgp2YWxBbnlMeXN0IgVhc0ludCIGdmFsSW50Ighhc1N0cmluZyIGdmFsU3RyIgxhc0J5dGVWZWN0b3IiBnZhbEJpbiIPZ2V0U3RyaW5nT3JGYWlsIgdhZGRyZXNzIgNrZXkiGGdldFN0cmluZ0J5QWRkcmVzc09yRmFpbCIMZ2V0SW50T3JaZXJvIg9nZXRJbnRPckRlZmF1bHQiCmRlZmF1bHRWYWwiDGdldEludE9yRmFpbCIZZ2V0QmlnSW50RnJvbVN0cmluZ09yWmVybyIcZ2V0QmlnSW50RnJvbVN0cmluZ09yRGVmYXVsdCIBcyIFdG9YMTgiB29yaWdWYWwiDW9yaWdTY2FsZU11bHQiB2Zyb21YMTgiD3Jlc3VsdFNjYWxlTXVsdCIRa2V5RmFjdG9yeUFkZHJlc3MiGWtleVZvdGluZ0VtaXNzaW9uQ29udHJhY3QiGElkeEZhY3RvcnlDZmdTdGFraW5nRGFwcCIZSWR4RmFjdG9yeUNmZ0Jvb3N0aW5nRGFwcCIUSWR4RmFjdG9yeUNmZ0lkb0RhcHAiFUlkeEZhY3RvcnlDZmdUZWFtRGFwcCIZSWR4RmFjdG9yeUNmZ0VtaXNzaW9uRGFwcCIVSWR4RmFjdG9yeUNmZ1Jlc3REYXBwIhlJZHhGYWN0b3J5Q2ZnU2xpcHBhZ2VEYXBwIg1rZXlGYWN0b3J5Q2ZnIhNrZXlNYW5hZ2VyUHVibGljS2V5IhprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleSIWa2V5U3RhYmxlUG9vbEFkZG9uQWRkciIMa2V5QWRkb25BZGRyIhprZXlGYWN0b3J5THAyQXNzZXRzTWFwcGluZyIKbHBBc3NldFN0ciIQa2V5RmFjdG9yeUxwTGlzdCIma2V5RmFjdG9yeUxwQXNzZXRUb1Bvb2xDb250cmFjdEFkZHJlc3MiFGtleUZhY3RvcnlQb29sV2VpZ2h0Ig9jb250cmFjdEFkZHJlc3MiCnJlYWRMcExpc3QiB2ZhY3RvcnkiFHJlYWRGYWN0b3J5Q2ZnT3JGYWlsIhhnZXRCb29zdGluZ0FkZHJlc3NPckZhaWwiCmZhY3RvcnlDZmciGGdldEVtaXNzaW9uQWRkcmVzc09yRmFpbCIXZ2V0U3Rha2luZ0FkZHJlc3NPckZhaWwiHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudCIha2V5RW1pc3Npb25SYXRlUGVyQmxvY2tNYXhDdXJyZW50IhVrZXlFbWlzc2lvblN0YXJ0QmxvY2siG2tleUVtaXNzaW9uRHVyYXRpb25JbkJsb2NrcyITa2V5RW1pc3Npb25FbmRCbG9jayIPa2V5U3Rha2VkQnlVc2VyIg51c2VyQWRkcmVzc1N0ciIMbHBBc3NldElkU3RyIg5rZXlTdGFrZWRUb3RhbCIQa2V5Q2xhaW1lZEJ5VXNlciIZa2V5Q2xhaW1lZEJ5VXNlck1pblJld2FyZCIba2V5Q2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkIg9rZXlDbGFpbWVkVG90YWwiCnJlYWRTdGFrZWQiFWtleUxhc3RUb3RhbExwQmFsYW5jZSIJbHBBc3NldElkIhRrZXlMYXN0VXNlckxwQmFsYW5jZSILdXNlckFkZHJlc3MiGWtleVRvdGFsTHBCYWxhbmNlSW50ZWdyYWwiGGtleVVzZXJMcEJhbGFuY2VJbnRlZ3JhbCIma2V5VG90YWxMcEJhbGFuY2VJbnRlZ3JhbExhc3RVcGRIZWlnaHQiJWtleVVzZXJMcEJhbGFuY2VJbnRlZ3JhbExhc3RVcGRIZWlnaHQiEmtleVd4UGVyTHBJbnRlZ3JhbCIfa2V5V3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodCIQa2V5V3hUb0NsYWltVXNlciIja2V5V3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHQiCmtleVd4UGVyTHAiDWtleVd4UGVyTHBYMTgiGmtleVd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0IhlrZXlPcGVyYXRpb25IaXN0b3J5UmVjb3JkIgR0eXBlIgZ0eElkNTgiE2Zvcm1hdEhpc3RvcnlSZWNvcmQiBmFtb3VudCIVT3BlcmF0aW9uSGlzdG9yeUVudHJ5IgR0eElkIg5mYWN0b3J5QWRkcmVzcyIPZmFjdG9yeUNvbnRyYWN0IhBlbWlzc2lvbkNvbnRyYWN0IhBib29zdGluZ0NvbnRyYWN0IgtrZXlOZXh0VXNlciIQZ2V0VXNlcnNMaXN0TmFtZSILa2V5TGlzdEhlYWQiCGxpc3ROYW1lIgtrZXlMaXN0U2l6ZSILa2V5TGlzdFByZXYiAmlkIgtrZXlMaXN0TmV4dCIMY29udGFpbnNOb2RlIgpoZWFkT3JVbml0IgpwcmV2T3JVbml0IgpuZXh0T3JVbml0IhFpbnNlcnROb2RlQWN0aW9ucyIIbGlzdFNpemUiCWNoZWNrTm9kZSIRZGVsZXRlTm9kZUFjdGlvbnMiG2NhbGNXeFBlckxwSW50ZWdyYWxVc2VyTGFzdCIMc3Rha2VkQnlVc2VyIiZ3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE9yWmVybyISd3hQZXJMcEludGVncmFsTmV3Ihp3eFBlckxwSW50ZWdyYWxVc2VyTGFzdEtFWSIUcmVmcmVzaFBvb2xJTlRFR1JBTFMiDnBvb2xBZGRyZXNzU3RyIg1scERlbHRhQW1vdW50Ig5zdGFrZWRUb3RhbEtFWSILc3Rha2VkVG90YWwiEm5vblplcm9TdGFrZWRUb3RhbCIKcG9vbFdlaWdodCISZW1pc3Npb25TdGFydEJsb2NrIgVNVUxUMyIUd3hFbWlzc2lvblBlckJsb2NrWDMiGHBvb2xXeEVtaXNzaW9uUGVyQmxvY2tYMyISd3hQZXJMcEludGVncmFsS0VZIh93eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0S0VZIgp3eFBlckxwS0VZIhx3eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0Ig93eFBlckxwSW50ZWdyYWwiD3d4UGVyTHBPclplcm9YMyICZGgiCXd4UGVyTHBYMyIOc3Rha2VkVG90YWxOZXciFW5vblplcm9TdGFrZWRUb3RhbE5ldyIMd3hQZXJMcFgzTmV3Ih93eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0TmV3IgVkZWJ1ZyIQcmVmcmVzaElOVEVHUkFMUyINJHQwMTQyNzQxNDM5NiIRcG9vbEludGVncmFsU1RBVEUiCXBvb2xERUJVRyIPc3Rha2VkQnlVc2VyS0VZIhB3eFRvQ2xhaW1Vc2VyS0VZIiN3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodEtFWSINd3hUb0NsYWltVXNlciIXd3hQZXJMcEludGVncmFsVXNlckxhc3QiBk1VTFQxMSIQd3hUb0NsYWltVXNlck5ldyIad3hQZXJMcEludGVncmFsVXNlckxhc3ROZXciI3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0TmV3IhZtYW5hZ2VyUHVibGljS2V5T3JVbml0Ih1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdCIVcGVybWlzc2lvbkRlbmllZEVycm9yIghtdXN0VGhpcyIBaSILbXVzdE1hbmFnZXIiAnBrIhFmYWN0b3J5QWRkcmVzc1N0ciILY2hlY2tDYWxsZXIiFnZvdGluZ0VtaXNzaW9uQ29udHJhY3QiBWNoZWtzIhdwZW5kaW5nTWFuYWdlclB1YmxpY0tleSIVY2hlY2tNYW5hZ2VyUHVibGljS2V5IgJwbSIFaGFzUE0iB2NoZWNrUE0iA3BtdCIJY2FsbGVyU3RyIg0kdDAxODgzMjE4OTQ5Ig1pbnRlZ3JhbFNUQVRFIgtsaXN0QWN0aW9ucyIJcG9vbEFkZG9uIhZjbGFpbWVkQnlVc2VyTWluUmV3YXJkIgtwb29sQWRkcmVzcyIQYXZhaWxhYmxlVG9DbGFpbSIBciIGcmVzdWx0IhBjbGFpbWVkQnlVc2VyS0VZIg9jbGFpbWVkVG90YWxLRVkiGWNsYWltZWRCeVVzZXJNaW5SZXdhcmRLRVkiG2NsYWltZWRCeVVzZXJCb29zdFJld2FyZEtFWSINY2xhaW1lZEJ5VXNlciIYY2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkIgxjbGFpbWVkVG90YWwiDSR0MDIyODE0MjI5MjYiEnd4QW1vdW50Qm9vc3RUb3RhbCINbWluUmV3YXJkUGFydCIPYm9vc3RSZXdhcmRQYXJ0Igl3eEFzc2V0SWQiCWVtaXRCb29zdCISY2xhaW1lZEJ5VXNlclZhbHVlIh5jbGFpbWVkQnlVc2VyTWluUmV3YXJkUGx1c1BhcnQiK2NsYWltZWRCeVVzZXJCb29zdFJld2FyZFBsdXNCb29zdFJld2FyZFBhcnQiIGNsYWltZWRUb3RhbFBsdXNBdmFpbGFibGVUb0NsYWltIgtjdXJyZW50SXRlciIKbHBBc3NldElkcyIGcmVzQWNjIgRpbmZvIgFAIgl1bmNsYWltZWQiB2NsYWltZWQiA3JlcyIDaW52IhJ3eEVtaXNzaW9uUGVyQmxvY2siDHBhc3NlZEJsb2NrcyIOcG9vbFd4RW1pc3Npb24iDHVzZXJXeFJld2FyZCINJHQwMjY1ODQyNjY5NiIOYm9vc3RJbnZSZXN1bHQiCmJvb3N0RGVidWciC3RvdGFsUmV3YXJkIgp1c2VyT3JVbml0IgckbWF0Y2gxIgRoZWFkIg5uZXh0VXNlck9yVW5pdCIIbmV4dFVzZXIiDSR0MDI5MDMyMjkxNDIiAnR4IgZ2ZXJpZnkiD3RhcmdldFB1YmxpY0tleV4AAWEACAABYgCAwtcvAAFjABIAAWQJALYCAQCAgJC7utat8A0AAWUCAl9fAAFmBQFiAAFnCQC2AgEAAAABaAkAtgIBAAEBAWkBAWoEAWsFAWoDCQABAgUBawIJTGlzdFtBbnldBAFsBQFrBQFsCQACAQIbZmFpbCB0byBjYXN0IGludG8gTGlzdFtBbnldAQFtAQFqBAFrBQFqAwkAAQIFAWsCA0ludAQBbgUBawUBbgkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEBbwEBagQBawUBagMJAAECBQFrAgZTdHJpbmcEAXAFAWsFAXAJAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBAXEBAWoEAWsFAWoDCQABAgUBawIKQnl0ZVZlY3RvcgQBcgUBawUBcgkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEBcwIBdAF1CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUBdAUBdQkArAICCQCsAgICD21hbmRhdG9yeSB0aGlzLgUBdQIPIGlzIG5vdCBkZWZpbmVkAQF2AgF0AXUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQF0BQF1CQCsAgIJAKwCAgkArAICCQCsAgICCm1hbmRhdG9yeSAJAKUIAQUBdAIBLgUBdQIPIGlzIG5vdCBkZWZpbmVkAQF3AgF0AXUJAQt2YWx1ZU9yRWxzZQIJAJoIAgUBdAUBdQAAAQF4AwF0AXUBeQkBC3ZhbHVlT3JFbHNlAgkAmggCBQF0BQF1BQF5AQF6AgF0AXUJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQF0BQF1CQCsAgIJAKwCAgIPbWFuZGF0b3J5IHRoaXMuBQF1Ag8gaXMgbm90IGRlZmluZWQBAUECAXQBdQkBBXZhbHVlAQkAqAMBCQELdmFsdWVPckVsc2UCCQCdCAIFAXQFAXUCATABAUIDAXQBdQF5BAFrCQCdCAIFAXQFAXUDCQABAgUBawIGU3RyaW5nBAFDBQFrCQEFdmFsdWUBCQCoAwEFAUMDCQABAgUBawIEVW5pdAUBeQkAAgECC01hdGNoIGVycm9yAQFEAgFFAUYJALwCAwkAtgIBBQFFBQFkCQC2AgEFAUYBAUcCAWoBSAkAoAMBCQC8AgMFAWoJALYCAQUBSAUBZAEBSQACHCVzJXNfX2NvbmZpZ19fZmFjdG9yeUFkZHJlc3MBAUoAAholc19fdm90aW5nRW1pc3Npb25Db250cmFjdAABSwABAAFMAAIAAU0AAwABTgAEAAFPAAUAAVAABgABUQAHAQFSAAIRJXNfX2ZhY3RvcnlDb25maWcBAVMAAhQlc19fbWFuYWdlclB1YmxpY0tleQEBVAACGyVzX19wZW5kaW5nTWFuYWdlclB1YmxpY0tleQEBVQACFyVzX19zdGFibGVQb29sQWRkb25BZGRyAQFWAAINJXNfX2FkZG9uQWRkcgEBVwEBWAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQFYCQDMCAICHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUDbmlsBQFlAQFZAAIQJXNfX2xwVG9rZW5zTGlzdAEBWgEBWAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQFYCQDMCAICHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUDbmlsBQFlAQJhYQECYWIJALkJAgkAzAgCAgQlcyVzCQDMCAICCnBvb2xXZWlnaHQJAMwIAgUCYWIFA25pbAUBZQECYWMBAmFkCQC1CQIJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUCYWQJAQFZAAIABQFlAQJhZQECYWQJALUJAgkBAXYCBQJhZAkBAVIABQFlAQJhZgECYWcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYWcFAUwBAmFoAQJhZwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQJhZwUBTwECYWkBAmFnCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFAmFnBQFLAQJhagACGyVzJXNfX3JhdGVQZXJCbG9ja19fY3VycmVudAECYWsAAh4lcyVzX19yYXRlUGVyQmxvY2tNYXhfX2N1cnJlbnQBAmFsAAIaJXMlc19fZW1pc3Npb25fX3N0YXJ0QmxvY2sBAmFtAAIYJXMlc19fZW1pc3Npb25fX2R1cmF0aW9uAQJhbgACGCVzJXNfX2VtaXNzaW9uX19lbmRCbG9jawECYW8CAmFwAmFxCQC5CQIJAMwIAgIOJXMlcyVzX19zdGFrZWQJAMwIAgUCYXAJAMwIAgUCYXEFA25pbAUBZQECYXIBAmFxCQCsAgICFyVzJXMlc19fc3Rha2VkX190b3RhbF9fBQJhcQECYXMCAmFxAmFwCQC5CQIJAMwIAgIPJXMlcyVzX19jbGFpbWVkCQDMCAIFAmFwCQDMCAIFAmFxBQNuaWwFAWUBAmF0AgJhcQJhcAkAuQkCCQDMCAICGCVzJXMlc19fY2xhaW1lZE1pblJld2FyZAkAzAgCBQJhcAkAzAgCBQJhcQUDbmlsBQFlAQJhdQICYXECYXAJALkJAgkAzAgCAholcyVzJXNfX2NsYWltZWRCb29zdFJld2FyZAkAzAgCBQJhcAkAzAgCBQJhcQUDbmlsBQFlAQJhdgECYXEJALkJAgkAzAgCAhYlcyVzJXNfX2NsYWltZWRfX3RvdGFsCQDMCAIFAmFxBQNuaWwFAWUBAmF3AQF1CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAXUAAAECYXgBAmF5CQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFAmF5CQDMCAICBXRvdGFsCQDMCAICA2JhbAUDbmlsBQFlAQJhegICYXkCYUEJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUCYXkJAMwIAgUCYUEJAMwIAgIDYmFsBQNuaWwFAWUBAmFCAQJheQkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQJheQkAzAgCAgV0b3RhbAkAzAgCAgZiYWxJTlQFA25pbAUBZQECYUMCAmF5AmFBCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFAmF5CQDMCAIFAmFBCQDMCAICBmJhbElOVAUDbmlsBQFlAQJhRAECYXkJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUCYXkJAMwIAgIFdG90YWwJAMwIAgIHbGFzdFVwZAUDbmlsBQFlAQJhRQICYXkCYUEJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUCYXkJAMwIAgUCYUEJAMwIAgIHbGFzdFVwZAUDbmlsBQFlAQJhRgECYXkJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCBQJheQkAzAgCAgZjb21tb24JAMwIAgIFbHBJbnQFA25pbAUBZQECYUcBAmF5CQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgUCYXkJAMwIAgIGY29tbW9uCQDMCAICBmxwSW50SAUDbmlsBQFlAQJhSAICYXkCYUEJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCBQJheQkAzAgCBQJhQQkAzAgCAgVscEludAUDbmlsBQFlAQJhSQICYXkCYUEJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCBQJheQkAzAgCBQJhQQkAzAgCAgZscEludEgFA25pbAUBZQECYUoBAmF5CQC5CQIJAMwIAgICJXMJAMwIAgUCYXkJAMwIAgIHd3hQZXJMcAUDbmlsBQFlAQJhSwECYXkJALkJAgkAzAgCAgIlcwkAzAgCBQJheQkAzAgCAgp3eFBlckxwWDE4BQNuaWwFAWUBAmFMAgJheQJhQQkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFAmF5CQDMCAIFAmFBCQDMCAICBXVJbnRMBQNuaWwFAWUBAmFNAwJhTgJhQQJhTwkAuQkCCQDMCAICESVzJXMlcyVzX19oaXN0b3J5CQDMCAIFAmFOCQDMCAIFAmFBCQDMCAIFAmFPBQNuaWwFAWUBAmFQBAJhQQJheQJhTgJhUQkAuQkCCQDMCAICDCVzJXMlcyVkJWQlZAkAzAgCBQJhQQkAzAgCBQJheQkAzAgCBQJhTgkAzAgCCQCkAwEFBmhlaWdodAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAKQDAQUCYVEFA25pbAUBZQECYVIFAmFOAmFBAmF5AmFRAmFTCQELU3RyaW5nRW50cnkCCQECYU0DBQJhTgUCYUEJANgEAQUCYVMJAQJhUAQFAmFBBQJheQUCYU4FAmFRAAJhVAkBAXMCBQR0aGlzCQEBSQAAAmFVCQERQGV4dHJOYXRpdmUoMTA2MikBBQJhVAACYWcJAQJhZQEFAmFVAAJhVgkBAmFoAQUCYWcAAmFXCQECYWYBBQJhZwECYVgBAmF5CQC5CQIJAMwIAgIEJXMlcwkAzAgCBQJheQkAzAgCAghuZXh0VXNlcgUDbmlsBQFlAQJhWQECYXkJALkJAgkAzAgCAgV1c2VycwkAzAgCBQJheQUDbmlsBQFlAQJhWgECYmEJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUCYmEJAMwIAgIEaGVhZAUDbmlsBQFlAQJiYgECYmEJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUCYmEJAMwIAgIEc2l6ZQUDbmlsBQFlAQJiYwICYmECYmQJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCBQJiYQkAzAgCBQJiZAkAzAgCAgRwcmV2BQNuaWwFAWUBAmJlAgJiYQJiZAkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFAmJhCQDMCAIFAmJkCQDMCAICBG5leHQFA25pbAUBZQECYmYCAmJhAmJkBAJiZwkAnQgCBQR0aGlzCQECYVoBBQJiYQQCYmgJAJ0IAgUEdGhpcwkBAmJjAgUCYmEFAmJkBAJiaQkAnQgCBQR0aGlzCQECYmUCBQJiYQUCYmQDAwkAAAIFAmJkCQELdmFsdWVPckVsc2UCBQJiZwIABgkBAiE9AgUCYmgFBHVuaXQGCQECIT0CBQJiaQUEdW5pdAECYmoCAmJhAmJkBAJiZwkAnQgCBQR0aGlzCQECYVoBBQJiYQQCYmsJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmJiAQUCYmEAAAQCYmwDCQEBIQEJAQJiZgIFAmJhBQJiZAYJAAIBAgtOb2RlIGV4aXN0cwMJAAACBQJibAUCYmwJAM4IAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYmIBBQJiYQkAZAIFAmJrAAEFA25pbAMJAQIhPQIFAmJnBQR1bml0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJiZQIFAmJhBQJiZAkBBXZhbHVlAQUCYmcJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmJjAgUCYmEJAQV2YWx1ZQEFAmJnBQJiZAUDbmlsBQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFaAQUCYmEFAmJkBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmJtAgJiYQJiZAQCYmcJAJ0IAgUEdGhpcwkBAmFaAQUCYmEEAmJrCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQJiYgEFAmJhAAAEAmJoCQCdCAIFBHRoaXMJAQJiYwIFAmJhBQJiZAQCYmkJAJ0IAgUEdGhpcwkBAmJlAgUCYmEFAmJkCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJiYgEFAmJhCQBlAgUCYmsAAQUDbmlsAwMJAQIhPQIFAmJoBQR1bml0CQECIT0CBQJiaQUEdW5pdAcJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmJlAgUCYmEJAQV2YWx1ZQEFAmJoCQEFdmFsdWUBBQJiaQkAzAgCCQELU3RyaW5nRW50cnkCCQECYmMCBQJiYQkBBXZhbHVlAQUCYmkJAQV2YWx1ZQEFAmJoCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJiYwIFAmJhBQJiZAkAzAgCCQELRGVsZXRlRW50cnkBCQECYmUCBQJiYQUCYmQFA25pbAMJAQIhPQIFAmJpBQR1bml0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhWgEFAmJhCQEFdmFsdWUBBQJiaQkAzAgCCQELRGVsZXRlRW50cnkBCQECYmUCBQJiYQUCYmQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmJjAgUCYmEJAQV2YWx1ZQEFAmJpBQNuaWwDCQECIT0CBQJiaAUEdW5pdAkAzAgCCQELRGVsZXRlRW50cnkBCQECYmMCBQJiYQUCYmQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmJlAgUCYmEJAQV2YWx1ZQEFAmJoBQNuaWwDCQAAAgUCYmQJAQt2YWx1ZU9yRWxzZQIFAmJnAgAJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFaAQUCYmEFA25pbAkAAgEJAKwCAgkArAICCQCsAgICDmludmFsaWQgbm9kZTogBQJiYQIBLgUCYmQBAmJuBAJibwJicAJicQJicgMDCQAAAgUCYnAFAWcJAL8CAgUCYm8FAWcHBQFnAwkAAAIFAmJvBQFnBQJicQMDCQC/AgIFAmJwBQFnCQC/AgIFAmJvBQFnBwkBBXZhbHVlAQkAqAMBCQEBcwIFBHRoaXMFAmJyCQACAQItY2FsY1d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0OiB1bmV4cGVjdGVkIHN0YXRlAQJicwMCYXECYnQCYnUEAmJ2CQECYXIBBQJhcQQCYncJALYCAQkBAmF3AQUCYnYEAmJ4AwkAAAIFAmJ3BQFnBQFoBQJidwQCYnkJARFAZXh0ck5hdGl2ZSgxMDUwKQIFAmFVCQECYWEBBQJidAQCYnoJAQF6AgUCYVYJAQJhbAAEAmJBAOgHBAJiQgkAaAIJAQF6AgUCYVYJAQJhagAFAmJBBAJiQwkAawMFAmJCBQJieQkAaAIFAWYAAwQCYkQJAQJhRgEFAmFxBAJiRQkBAmFHAQUCYXEEAmJGCQECYUoBBQJhcQQCYkcJAQF4AwUEdGhpcwUCYkUFAmJ6BAJiSAkBAUECBQR0aGlzBQJiRAQCYkkAAAQCYkoJAJYDAQkAzAgCCQBlAgUGaGVpZ2h0BQJiRwkAzAgCAAAFA25pbAQCYksDCQECIT0CBQJiSQAACQC2AgEFAmJJCQC8AgMJALYCAQUCYkMJALYCAQUBYgUCYngEAmJMCQC3AgIFAmJ3CQC2AgEFAmJ1BAJiTQMJAAACBQJiTAUBZwUBaAUCYkwEAmJxCQC3AgIFAmJICQC5AgIFAmJLCQC2AgEFAmJKBAJiTgkAugICCQC2AgEFAmJDBQJiTQQCYk8FBmhlaWdodAQCYlAJALkJAgkAzAgCCQCmAwEFAmJxCQDMCAIJAKQDAQUCYkoJAMwIAgkApgMBBQJiSwkAzAgCCQCmAwEFAmJ3CQDMCAIJAKQDAQUCYkMJAMwIAgkApAMBBQJiQgkAzAgCCQCkAwEFAmJ5BQNuaWwCAjo6CQCVCgMFAmJxCQDMCAIJAQtTdHJpbmdFbnRyeQIFAmJECQCmAwEFAmJxCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJiRQUCYk8JAMwIAgkBC1N0cmluZ0VudHJ5AgUCYkYJAKYDAQUCYk4FA25pbAUCYlABAmJRBAJhcQJhcAJidAJidQQCYlIJAQJicwMFAmFxBQJidAUCYnUEAmJxCAUCYlICXzEEAmJTCAUCYlICXzIEAmJUCAUCYlICXzMEAmJBAOgHBAJiVQkBAmFvAgUCYXAFAmFxBAJibwkBAmF3AQUCYlUEAmJWCQECYUgCBQJhcQUCYXAEAmJXCQECYUkCBQJhcQUCYXAEAmJyCQECYUwCBQJhcQUCYXAEAmJYCQEBQQIFBHRoaXMFAmJWBAJicAkBAXcCBQR0aGlzBQJiVwQCYlkJAQJibgQJALYCAQUCYm8JALYCAQUCYnAFAmJxBQJicgQCYloJAGgCBQFiBQJiQQQCY2EJAJgDAQkAzAgCCQC3AgIFAmJYCQC8AgMJALgCAgUCYnEFAmJZCQC2AgEFAmJvCQC2AgEFAmJaCQDMCAIFAWcFA25pbAQCY2IFAmJxBAJjYwUGaGVpZ2h0BAJiUAkAuQkCCQDMCAIJAKYDAQUCYlgJAMwIAgkApgMBBQJiWQkAzAgCCQCkAwEFAmJvCQDMCAIFAmJUCQDMCAIJAKQDAQUGaGVpZ2h0BQNuaWwCAjo6CQCVCgMFAmNhCQDOCAIFAmJTCQDMCAIJAQtTdHJpbmdFbnRyeQIFAmJWCQCmAwEFAmNhCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJiVwUCY2MJAMwIAgkBC1N0cmluZ0VudHJ5AgUCYnIJAKYDAQUCY2IFA25pbAUCYlABAmNkAAQBawkAoggBCQEBUwADCQABAgUBawIGU3RyaW5nBAFDBQFrCQDZBAEFAUMDCQABAgUBawIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJjZQAEAWsJAKIIAQkBAVQAAwkAAQIFAWsCBlN0cmluZwQBQwUBawkA2QQBBQFDAwkAAQIFAWsCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgACY2YJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAECY2cBAmNoAwkAAAIIBQJjaAZjYWxsZXIFBHRoaXMGBQJjZgECY2kBAmNoBAFrCQECY2QAAwkAAQIFAWsCCkJ5dGVWZWN0b3IEAmNqBQFrAwkAAAIIBQJjaA9jYWxsZXJQdWJsaWNLZXkFAmNqBgUCY2YDCQABAgUBawIEVW5pdAMJAAACCAUCY2gGY2FsbGVyBQR0aGlzBgUCY2YJAAIBAgtNYXRjaCBlcnJvcg0CY2gBC2NvbnN0cnVjdG9yAQJjawQCY2wJAQJjaQEFAmNoAwkAAAIFAmNsBQJjbAkAzAgCCQELU3RyaW5nRW50cnkCCQEBSQAFAmNrBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CY2gBDWNvbnN0cnVjdG9yVjIBAmNtBAJjbgkAzAgCCQECY2kBBQJjaAkAzAgCAwkBAiE9AgkApggBBQJjbQUEdW5pdAYCKGludmFsaWQgdm90aW5nIGVtaXNzaW9uIGNvbnRyYWN0IGFkZHJlc3MFA25pbAMJAAACBQJjbgUCY24JAMwIAgkBC1N0cmluZ0VudHJ5AgkBAUoABQJjbQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNoAQpzZXRNYW5hZ2VyAQJjbwQCY2wJAQJjaQEFAmNoAwkAAAIFAmNsBQJjbAQCY3AJANkEAQUCY28DCQAAAgUCY3AFAmNwCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFUAAUCY28FA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjaAEOY29uZmlybU1hbmFnZXIABAJjcQkBAmNlAAQCY3IDCQEJaXNEZWZpbmVkAQUCY3EGCQACAQISTm8gcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmNyBQJjcgQCY3MDCQAAAggFAmNoD2NhbGxlclB1YmxpY0tleQkBBXZhbHVlAQUCY3EGCQACAQIbWW91IGFyZSBub3QgcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmNzBQJjcwkAzAgCCQELU3RyaW5nRW50cnkCCQEBUwAJANgEAQkBBXZhbHVlAQUCY3EJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAVQABQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CY2gBBXN0YWtlAAMJAQIhPQIJAJADAQgFAmNoCHBheW1lbnRzAAEJAAIBAjRpbnZhbGlkIHBheW1lbnQgLSBleGFjdCBvbmUgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBAJjdAkAkQMCCAUCY2gIcGF5bWVudHMAAAQCYXkJAQV2YWx1ZQEIBQJjdAdhc3NldElkBAJhcQkA2AQBBQJheQQCYVEIBQJjdAZhbW91bnQEAmJ0CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUCYVUJAQFXAQUCYXEJAKwCAgIVdW5zdXBwb3J0ZWQgbHAgYXNzZXQgBQJhcQQCY3UJAKUIAQgFAmNoBmNhbGxlcgQCYXADCQAAAgUCY3UFAmJ0CQClCAEIBQJjaAxvcmlnaW5DYWxsZXIFAmN1BAJiVQkBAmFvAgUCYXAFAmFxBAJidgkBAmFyAQUCYXEEAmJvCQECYXcBBQJiVQQCYncJAQJhdwEFAmJ2BAJjdgkBAmJRBAUCYXEFAmFwBQJidAUCYVEEAmNhCAUCY3YCXzEEAmN3CAUCY3YCXzIEAmJQCAUCY3YCXzMEAmJhCQECYVkBBQJhcQQCY3gDCQECYmYCBQJiYQUCYXAFA25pbAkBAmJqAgUCYmEFAmFwCQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUCYlUJAGQCBQJibwUCYVEJAMwIAgkBDEludGVnZXJFbnRyeQIFAmJ2CQBkAgUCYncFAmFRCQDMCAIJAQJhUgUCBXN0YWtlBQJhcAUCYXEFAmFRCAUCY2gNdHJhbnNhY3Rpb25JZAUDbmlsBQJjdwUCY3gCY2gBB3Vuc3Rha2UCAmFxAmFRBAJheQkA2QQBBQJhcQQCYnQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQJhVQkBAVcBBQJhcQkArAICAhV1bnN1cHBvcnRlZCBscCBhc3NldCAFAmFxBAJjeQkBC3ZhbHVlT3JFbHNlAgkAnQgCCQERQGV4dHJOYXRpdmUoMTA2MikBBQJidAkBAVYABQJidAQCY3UJAKUIAQgFAmNoBmNhbGxlcgQCYXADAwkAAAIFAmN1BQJidAYJAAACBQJjdQUCY3kJAKUIAQgFAmNoDG9yaWdpbkNhbGxlcgUCY3UEAmJVCQECYW8CBQJhcAUCYXEEAmJ2CQECYXIBBQJhcQQCYm8JAQJhdwEFAmJVBAJidwkBAmF3AQUCYnYEAmN3CAkBAmJRBAUCYXEFAmFwBQJidAkBAS0BBQJhUQJfMgQCYmEJAQJhWQEFAmFxBAJjeAMDCQECYmYCBQJiYQUCYXAJAAACBQJhUQUCYm8HCQECYm0CBQJiYQUCYXAFA25pbAQCY3oJAQFBAgUEdGhpcwkBAmF0AgUCYXEFAmFwBAJjQQkBAXYCBQJhVQkBAVoBBQJhcQQCY2EICQECYlEEBQJhcQUCYXAFAmNBAAACXzEEAmNCCQC4AgIFAmNhBQJjegQCY0MDCQC/AgIFAmNCBQFnCQD8BwQFBHRoaXMCD2NsYWltV3hJTlRFUk5BTAkAzAgCBQJhcQkAzAgCBQJhcAUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCY0MFAmNDAwkAZgIFAmFRBQJibwkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIOcGFzc2VkIGFtb3VudD0JAKQDAQUCYVECGyBpcyBncmVhdGVyIHRoYW4gYXZhaWxhYmxlPQkApAMBBQJibwIMLiBscEFzc2V0SWQ9BQJhcQISLiBzdGFrZWRCeVVzZXJLRVk9BQJiVQkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFAmJVCQBlAgUCYm8FAmFRCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJidgkAZQIFAmJ3BQJhUQkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCY2gGY2FsbGVyBQJhUQUCYXkJAMwIAgkBAmFSBQIHdW5zdGFrZQUCYXAFAmFxBQJhUQgFAmNoDXRyYW5zYWN0aW9uSWQFA25pbAUCY3cFAmN4CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNoAQdjbGFpbVd4AQJhcQQCYXAJAKUIAQgFAmNoBmNhbGxlcgQCY0QJAPwHBAUEdGhpcwIPY2xhaW1XeElOVEVSTkFMCQDMCAIFAmFxCQDMCAIFAmFwBQNuaWwFA25pbAkAlAoCBQNuaWwFAmNEAmNoAQ9jbGFpbVd4SU5URVJOQUwCAmFxAmFwBAJjbAkBAmNnAQUCY2gDCQAAAgUCY2wFAmNsBAJhQQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEFAmFwAiVjbGFpbVd4SU5URVJOQUw6IGludmFsaWQgdXNlciBhZGRyZXNzBAJidAkBAXYCBQJhVQkBAVoBBQJhcQQCY0UJAQJhcwIFAmFxBQJhcAQCY0YJAQJhdgEFAmFxBAJjRwkBAmF0AgUCYXEFAmFwBAJjSAkBAmF1AgUCYXEFAmFwBAJjSQkBAUECBQR0aGlzBQJjRQQCY3oJAQFBAgUEdGhpcwUCY0cEAmNKCQEBQQIFBHRoaXMFAmNIBAJjSwkBAUECBQR0aGlzBQJjRgQCY0wJAQJiUQQFAmFxBQJhcAUCYnQAAAQCY2EIBQJjTAJfMQQCY3cIBQJjTAJfMgQCYlAIBQJjTAJfMwQCY0IJAJgDAQkAzAgCCQC4AgIFAmNhBQJjegkAzAgCBQFnBQNuaWwDCQDAAgIFAWcFAmNCCQACAQIQbm90aGluZyB0byBjbGFpbQQCY00JAJYDAQkAzAgCCQEBbQEJAJEDAgkBAWkBCQD8BwQFAmFXAgxjbGFpbVd4Qm9vc3QJAMwIAgUCYXEJAMwIAgUCYXAFA25pbAUDbmlsAAAJAMwIAgAABQNuaWwEAmNOBQJjQgQCY08JAJkDAQkAzAgCCQC5AgIFAmNOCQC2AgEAAgkAzAgCCQC2AgEFAmNNBQNuaWwEAmNQCQEBcQEJAJEDAgkBAWkBCQD8BwQFAmFWAgRlbWl0CQDMCAIJAKADAQUCY04FA25pbAUDbmlsAAAEAmNRCQEBaQEJAPwHBAUCYVYCBGVtaXQJAMwIAgkAoAMBBQJjTwUDbmlsBQNuaWwDCQAAAgUCY1EFAmNRBAJjUgkAtwICCQC3AgIFAmNJBQJjTgUCY08EAmNTCQC3AgIFAmN6BQJjTgQCY1QJALcCAgUCY0oFAmNPBAJjVQkAtwICBQJjSwUCY0IJAMwIAgkBC1N0cmluZ0VudHJ5AgUCY0UJAKYDAQUCY1IJAMwIAgkBC1N0cmluZ0VudHJ5AgUCY0cJAKYDAQUCY1MJAMwIAgkBC1N0cmluZ0VudHJ5AgUCY0gJAKYDAQUCY1QJAMwIAgkBC1N0cmluZ0VudHJ5AgUCY0YJAKYDAQUCY1UJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYUEJAKADAQUCY04FAmNQCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFBCQCgAwEFAmNPBQJjUAkAzAgCCQECYVIFAgVjbGFpbQUCYXAFAmFxCQCgAwEFAmNCCAUCY2gNdHJhbnNhY3Rpb25JZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmNoARtjbGFpbVd4QnVsa0ludGVybmFsUkVBRE9OTFkEAmNWAmNXAmFwAmNYAwkAAAIFAmNWCQCQAwEFAmNXCQCUCgIFA25pbAUCY1gEAmF5CQCRAwIFAmNXBQJjVgQCY1kJALUJAgoAAmNaCQD8BwQFBHRoaXMCD2NsYWltV3hSRUFET05MWQkAzAgCBQJheQkAzAgCBQJhcAUDbmlsBQNuaWwDCQABAgUCY1oCBlN0cmluZwUCY1oJAAIBCQCsAgIJAAMBBQJjWgIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nBQFlBAJkYQkAkQMCBQJjWQADBAJkYgkAkQMCBQJjWQAEBAJkYwkAzQgCBQJjWAkAuQkCCQDMCAICBCVkJWQJAMwIAgUCZGEJAMwIAgUCZGIFA25pbAUBZQQCZGQKAAJjWgkA/AcEBQR0aGlzAhtjbGFpbVd4QnVsa0ludGVybmFsUkVBRE9OTFkJAMwIAgkAZAIFAmNWAAEJAMwIAgUCY1cJAMwIAgUCYXAJAMwIAgUCZGMFA25pbAUDbmlsAwkAAQIFAmNaAglMaXN0W0FueV0FAmNaCQACAQkArAICCQADAQUCY1oCHiBjb3VsZG4ndCBiZSBjYXN0IHRvIExpc3RbQW55XQMJAAACBQJkZAUCZGQJAJQKAgUDbmlsBQJkZAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjaAETY2xhaW1XeEJ1bGtSRUFET05MWQICY1cCYXAEAmRjCQD8BwQFBHRoaXMCG2NsYWltV3hCdWxrSW50ZXJuYWxSRUFET05MWQkAzAgCAAAJAMwIAgUCY1cJAMwIAgUCYXAJAMwIAgUDbmlsBQNuaWwFA25pbAkAlAoCBQNuaWwFAmRjAmNoAQ9jbGFpbVd4UkVBRE9OTFkCAmFxAmFwBAJiVQkBAmFvAgUCYXAFAmFxBAJidgkBAmFyAQUCYXEEAmNFCQECYXMCBQJhcQUCYXAEAmNHCQECYXQCBQJhcQUCYXAEAmJvCQECYXcBBQJiVQQCYncJAQJhdwEFAmJ2BAJjSQkBAUECBQR0aGlzBQJjRQQCY3oJAQFBAgUEdGhpcwUCY0cEAmJ0CQEBdgIFAmFVCQEBWgEFAmFxBAJieQkBEUBleHRyTmF0aXZlKDEwNTApAgUCYVUJAQJhYQEFAmJ0BAJkZQkBAXoCBQJhVgkBAmFqAAQCYnoJAQF6AgUCYVYJAQJhbAAEAmRmAwkAZgIFAmJ6BQZoZWlnaHQAAAkAZQIFBmhlaWdodAUCYnoEAmRnCQBrAwkAaAIFAmRlBQJkZgUCYnkFAWYEAmRoCQBrAwUCZGcFAmJvBQJidwQCZGkJAQJiUQQFAmFxBQJhcAUCYnQAAAQCY2EIBQJkaQJfMQQCY3cIBQJkaQJfMgQCYlAIBQJkaQJfMwQCY0IJAJgDAQkAzAgCCQC4AgIFAmNhBQJjegkAzAgCBQFnBQNuaWwEAmRqCQEBaQEJAPwHBAUCYVcCFGNsYWltV3hCb29zdFJFQURPTkxZCQDMCAIFAmFxCQDMCAIFAmFwBQNuaWwFA25pbAQCY00JAJYDAQkAzAgCCQEBbQEJAJEDAgUCZGoAAAkAzAgCAAAFA25pbAQCZGsJAQFvAQkAkQMCBQJkagABBAJjTgUCY0IEAmNPCQCZAwEJAMwIAgkAuQICBQJjTgkAtgIBAAIJAMwIAgkAtgIBBQJjTQUDbmlsBAJkbAkAtwICBQJjTgUCY08JAJQKAgUDbmlsCQC5CQIJAMwIAgIOJXMlcyVkJWQlZCVkJXMJAMwIAgUCYXEJAMwIAgUCYXAJAMwIAgkApgMBBQJkbAkAzAgCCQCmAwEFAmNJCQDMCAIJAKYDAQUCY04JAMwIAgkApgMBBQJjTwkAzAgCAgRzb29uBQNuaWwFAWUCY2gBEnVzZXJzTGlzdFRyYXZlcnNhbAECYXkEAmNsAwkAAAIJANgEAQgIBQJjaAZjYWxsZXIFYnl0ZXMJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBAUoAAgAGCQECY2kBBQJjaAMJAAACBQJjbAUCY2wEAmJhCQECYVkBBQJheQQCZG0JAKIIAQkBAmFYAQUCYXkEAmJnCQCiCAEJAQJhWgEFAmJhBAFrBQJkbQMJAAECBQFrAgRVbml0BAJkbgUCYmcDCQABAgUCZG4CBFVuaXQJAJQKAgUDbmlsBwMJAAECBQJkbgIGU3RyaW5nBAJkbwUCZG4JAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQECYVgBBQJheQUCZG8FA25pbAYJAAIBAgtNYXRjaCBlcnJvcgMJAAECBQFrAgZTdHJpbmcEAmFBBQFrBAJjegkBAUECBQR0aGlzCQECYXQCBQJheQUCYUEEAmNBCQEBdgIFAmFVCQEBWgEFAmF5BAJjYQgJAQJiUQQFAmF5BQJhQQUCY0EAAAJfMQQCY0IJALgCAgUCY2EFAmN6BAJjQwMJAL8CAgUCY0IFAWcJAPwHBAUEdGhpcwIPY2xhaW1XeElOVEVSTkFMCQDMCAIFAmF5CQDMCAIFAmFBBQNuaWwFA25pbAUEdW5pdAMJAAACBQJjQwUCY0MEAmRwCQCiCAEJAQJiZQIFAmJhBQJhQQQCZG4FAmRwAwkAAQIFAmRuAgRVbml0CQCUCgIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFYAQUCYXkFA25pbAcDCQABAgUCZG4CBlN0cmluZwQCZHEFAmRuCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFYAQUCYXkFAmRxBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAgtNYXRjaCBlcnJvcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJjaAEOb25Nb2RpZnlXZWlnaHQCAmFxAmJ0AwkBAiE9AggFAmNoBmNhbGxlcgUCYVUJAAIBAhJwZXJtaXNzaW9ucyBkZW5pZWQEAmRyCQECYnMDBQJhcQUCYnQAAAQCYnEIBQJkcgJfMQQCYlMIBQJkcgJfMgQCYlQIBQJkcgJfMwUCYlMBAmRzAQJkdAAEAmR1BAFrCQECY2QAAwkAAQIFAWsCCkJ5dGVWZWN0b3IEAmNqBQFrBQJjagMJAAECBQFrAgRVbml0CAUCZHMPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IJAPQDAwgFAmRzCWJvZHlCeXRlcwkAkQMCCAUCZHMGcHJvb2ZzAAAFAmR1A+fPaQ==", "height": 2469479, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 4bAHMDZPDfjo93XqDJejLHZaJBkRXbaNhT6iXn2zzfkZ Next: DNvSMRFDobjtEsCMh7HiyYVbXfbMeNsc8TdmnjMo3Fyq Diff:
OldNewDifferences
1616 let zeroBigInt = toBigInt(0)
1717
1818 let oneBigInt = toBigInt(1)
19-
20-func wrapErr (msg) = makeString(["staking.ride:", toString(this), msg], " ")
21-
22-
23-func throwErr (msg) = throw(wrapErr(msg))
24-
2519
2620 func asAnyList (val) = match val {
2721 case valAnyLyst: List[Any] =>
245239
246240 let boostingContract = getBoostingAddressOrFail(factoryCfg)
247241
248-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"))
249-
250242 func keyNextUser (lpAssetId) = makeString(["%s%s", lpAssetId, "nextUser"], SEP)
251243
252244
357349
358350
359351 func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
360- let $t01475014872 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
361- let wxPerLpIntegralNew = $t01475014872._1
362- let poolIntegralSTATE = $t01475014872._2
363- let poolDEBUG = $t01475014872._3
352+ let $t01427414396 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
353+ let wxPerLpIntegralNew = $t01427414396._1
354+ let poolIntegralSTATE = $t01427414396._2
355+ let poolDEBUG = $t01427414396._3
364356 let MULT3 = 1000
365357 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
366358 let stakedByUser = readStaked(stakedByUserKEY)
418410 case _ =>
419411 throw("Match error")
420412 }
421-
422-
423-func unstakeActions (i,lpAssetId,poolAddress,userAddress,lpAssetRecipientAddress,amount) = {
424- let userAddressStr = toString(userAddress)
425- let lpAssetIdStr = toBase58String(lpAssetId)
426- let poolAddressStr = toString(poolAddress)
427- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
428- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
429- let stakedByUser = readStaked(stakedByUserKEY)
430- let stakedTotal = readStaked(stakedTotalKEY)
431- let integralSTATE = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))._2
432- let listName = getUsersListName(lpAssetIdStr)
433- let listActions = if (if (containsNode(listName, userAddressStr))
434- then (amount == stakedByUser)
435- else false)
436- then deleteNodeActions(listName, userAddressStr)
437- else nil
438- let claimedByUserMinReward = getBigIntFromStringOrZero(this, keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr))
439- let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)._1
440- let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
441- let throwIfNothingToClaim = true
442- let r = if ((availableToClaim > zeroBigInt))
443- then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
444- else unit
445- if ((r == r))
446- then if ((amount > stakedByUser))
447- then throw(((((((("passed amount=" + toString(amount)) + " is greater than available=") + toString(stakedByUser)) + ". lpAssetId=") + lpAssetIdStr) + ". stakedByUserKEY=") + stakedByUserKEY))
448- else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(lpAssetRecipientAddress, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
449- else throw("Strict value is not equal to itself.")
450- }
451413
452414
453415 @Callable(i)
524486 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
525487 let stakedByUser = readStaked(stakedByUserKEY)
526488 let stakedTotal = readStaked(stakedTotalKEY)
527- let $t02127621393 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
528- let wxToClaimUserNew = $t02127621393._1
529- let integralSTATE = $t02127621393._2
530- let debug = $t02127621393._3
489+ let $t01883218949 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
490+ let wxToClaimUserNew = $t01883218949._1
491+ let integralSTATE = $t01883218949._2
492+ let debug = $t01883218949._3
531493 let listName = getUsersListName(lpAssetIdStr)
532494 let listActions = if (containsNode(listName, userAddressStr))
533495 then nil
541503 func unstake (lpAssetIdStr,amount) = {
542504 let lpAssetId = fromBase58String(lpAssetIdStr)
543505 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
544- let poolAddress = addressFromStringValue(poolAddressStr)
545- let poolAddon = valueOrElse(getString(poolAddress, keyAddonAddr()), poolAddressStr)
506+ let poolAddon = valueOrElse(getString(addressFromStringValue(poolAddressStr), keyAddonAddr()), poolAddressStr)
546507 let callerStr = toString(i.caller)
547- let userAddress = if (if ((callerStr == poolAddressStr))
508+ let userAddressStr = if (if ((callerStr == poolAddressStr))
548509 then true
549510 else (callerStr == poolAddon))
550- then i.originCaller
551- else i.caller
552- let lpAssetRecipientAddress = i.caller
553- unstakeActions(i, lpAssetId, poolAddress, userAddress, lpAssetRecipientAddress, amount)
554- }
555-
556-
557-
558-@Callable(i)
559-func unstakeINTERNAL (lpAssetId,amount,userAddress,lpAssetRecipientAddress) = {
560- let lpAssetIdStr = toBase58String(lpAssetId)
561- let poolAddress = addressFromStringValue(valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr)))
562- let checkCaller = if ((i.caller == poolAddress))
563- then true
564- else permissionDeniedError
565- if ((checkCaller == checkCaller))
566- then unstakeActions(i, lpAssetId, poolAddress, Address(userAddress), Address(lpAssetRecipientAddress), amount)
511+ then toString(i.originCaller)
512+ else callerStr
513+ let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
514+ let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
515+ let stakedByUser = readStaked(stakedByUserKEY)
516+ let stakedTotal = readStaked(stakedTotalKEY)
517+ let integralSTATE = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))._2
518+ let listName = getUsersListName(lpAssetIdStr)
519+ let listActions = if (if (containsNode(listName, userAddressStr))
520+ then (amount == stakedByUser)
521+ else false)
522+ then deleteNodeActions(listName, userAddressStr)
523+ else nil
524+ let claimedByUserMinReward = getBigIntFromStringOrZero(this, keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr))
525+ let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
526+ let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddress, 0)._1
527+ let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
528+ let r = if ((availableToClaim > zeroBigInt))
529+ then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil)
530+ else unit
531+ if ((r == r))
532+ then if ((amount > stakedByUser))
533+ then throw(((((((("passed amount=" + toString(amount)) + " is greater than available=") + toString(stakedByUser)) + ". lpAssetId=") + lpAssetIdStr) + ". stakedByUserKEY=") + stakedByUserKEY))
534+ else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
567535 else throw("Strict value is not equal to itself.")
568536 }
569537
572540 @Callable(i)
573541 func claimWx (lpAssetIdStr) = {
574542 let userAddressStr = toString(i.caller)
575- let throwIfNothingToClaim = true
576- let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
543+ let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil)
577544 $Tuple2(nil, result)
578545 }
579546
580547
581548
582549 @Callable(i)
583-func claimWxDoNotThrow (lpAssetIdStr) = {
584- let userAddressStr = toString(i.caller)
585- let throwIfNothingToClaim = false
586- let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
587- $Tuple2(nil, result)
588- }
589-
590-
591-
592-@Callable(i)
593-func claimWxINTERNAL (lpAssetIdStr,userAddressStr,throwIfNothingToClaim) = {
550+func claimWxINTERNAL (lpAssetIdStr,userAddressStr) = {
594551 let checkCaller = mustThis(i)
595552 if ((checkCaller == checkCaller))
596553 then {
604561 let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
605562 let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
606563 let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
607- let $t02477924891 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
608- let wxToClaimUserNew = $t02477924891._1
609- let integralSTATE = $t02477924891._2
610- let debug = $t02477924891._3
564+ let $t02281422926 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
565+ let wxToClaimUserNew = $t02281422926._1
566+ let integralSTATE = $t02281422926._2
567+ let debug = $t02281422926._3
611568 let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
612569 if ((zeroBigInt >= availableToClaim))
613- then if (throwIfNothingToClaim)
614- then throw("nothing to claim")
615- else $Tuple2(nil, 0)
570+ then throw("nothing to claim")
616571 else {
617572 let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
618573 let minRewardPart = availableToClaim
619574 let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
620- let totalReward = (minRewardPart + boostRewardPart)
621575 let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
622576 let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
623577 if ((emitBoost == emitBoost))
626580 let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
627581 let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserBoostReward + boostRewardPart)
628582 let claimedTotalPlusAvailableToClaim = (claimedTotal + availableToClaim)
629- $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))
583+[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)]
630584 }
631585 else throw("Strict value is not equal to itself.")
632586 }
690644 else (height - emissionStartBlock)
691645 let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
692646 let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
693- let $t02870028812 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
694- let wxToClaimUserNew = $t02870028812._1
695- let integralSTATE = $t02870028812._2
696- let debug = $t02870028812._3
647+ let $t02658426696 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
648+ let wxToClaimUserNew = $t02658426696._1
649+ let integralSTATE = $t02658426696._2
650+ let debug = $t02658426696._3
697651 let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
698652 let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
699653 let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
702656 let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
703657 let totalReward = (minRewardPart + boostRewardPart)
704658 $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), "soon"], SEP))
705- }
706-
707-
708-
709-@Callable(i)
710-func stakedByUserREADONLY (lpAssetIdStr,userAddressStr) = {
711- let stakedByUser = valueOrElse(getInteger(keyStakedByUser(userAddressStr, lpAssetIdStr)), 0)
712- $Tuple2(nil, stakedByUser)
713659 }
714660
715661
739685 let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetId))
740686 let wxToClaimUserNew = refreshINTEGRALS(lpAssetId, userAddress, poolAddress, 0)._1
741687 let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
742- let throwIfNothingToClaim = true
743688 let r = if ((availableToClaim > zeroBigInt))
744- then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress, throwIfNothingToClaim], nil)
689+ then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress], nil)
745690 else unit
746691 if ((r == r))
747692 then {
769714 func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
770715 then throw("permissions denied")
771716 else {
772- let $t03141831528 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
773- let wxPerLpIntegralNew = $t03141831528._1
774- let poolIntegralSTATE = $t03141831528._2
775- let poolDEBUG = $t03141831528._3
717+ let $t02903229142 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
718+ let wxPerLpIntegralNew = $t02903229142._1
719+ let poolIntegralSTATE = $t02903229142._2
720+ let poolDEBUG = $t02903229142._3
776721 poolIntegralSTATE
777722 }
778723
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let SCALE8 = 8
55
66 let MULT8 = 100000000
77
88 let SCALE18 = 18
99
1010 let MULT18 = toBigInt(1000000000000000000)
1111
1212 let SEP = "__"
1313
1414 let POOLWEIGHTMULT = MULT8
1515
1616 let zeroBigInt = toBigInt(0)
1717
1818 let oneBigInt = toBigInt(1)
19-
20-func wrapErr (msg) = makeString(["staking.ride:", toString(this), msg], " ")
21-
22-
23-func throwErr (msg) = throw(wrapErr(msg))
24-
2519
2620 func asAnyList (val) = match val {
2721 case valAnyLyst: List[Any] =>
2822 valAnyLyst
2923 case _ =>
3024 throw("fail to cast into List[Any]")
3125 }
3226
3327
3428 func asInt (val) = match val {
3529 case valInt: Int =>
3630 valInt
3731 case _ =>
3832 throw("fail to cast into Int")
3933 }
4034
4135
4236 func asString (val) = match val {
4337 case valStr: String =>
4438 valStr
4539 case _ =>
4640 throw("fail to cast into Int")
4741 }
4842
4943
5044 func asByteVector (val) = match val {
5145 case valBin: ByteVector =>
5246 valBin
5347 case _ =>
5448 throw("fail to cast into Int")
5549 }
5650
5751
5852 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined"))
5953
6054
6155 func getStringByAddressOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
6256
6357
6458 func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
6559
6660
6761 func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
6862
6963
7064 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
7165
7266
7367 func getBigIntFromStringOrZero (address,key) = value(parseBigInt(valueOrElse(getString(address, key), "0")))
7468
7569
7670 func getBigIntFromStringOrDefault (address,key,defaultVal) = match getString(address, key) {
7771 case s: String =>
7872 value(parseBigInt(s))
7973 case _: Unit =>
8074 defaultVal
8175 case _ =>
8276 throw("Match error")
8377 }
8478
8579
8680 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULT18, toBigInt(origScaleMult))
8781
8882
8983 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULT18))
9084
9185
9286 func keyFactoryAddress () = "%s%s__config__factoryAddress"
9387
9488
9589 func keyVotingEmissionContract () = "%s__votingEmissionContract"
9690
9791
9892 let IdxFactoryCfgStakingDapp = 1
9993
10094 let IdxFactoryCfgBoostingDapp = 2
10195
10296 let IdxFactoryCfgIdoDapp = 3
10397
10498 let IdxFactoryCfgTeamDapp = 4
10599
106100 let IdxFactoryCfgEmissionDapp = 5
107101
108102 let IdxFactoryCfgRestDapp = 6
109103
110104 let IdxFactoryCfgSlippageDapp = 7
111105
112106 func keyFactoryCfg () = "%s__factoryConfig"
113107
114108
115109 func keyManagerPublicKey () = "%s__managerPublicKey"
116110
117111
118112 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
119113
120114
121115 func keyStablePoolAddonAddr () = "%s__stablePoolAddonAddr"
122116
123117
124118 func keyAddonAddr () = "%s__addonAddr"
125119
126120
127121 func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
128122
129123
130124 func keyFactoryLpList () = "%s__lpTokensList"
131125
132126
133127 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
134128
135129
136130 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
137131
138132
139133 func readLpList (factory) = split(valueOrElse(getString(factory, keyFactoryLpList()), ""), SEP)
140134
141135
142136 func readFactoryCfgOrFail (factory) = split(getStringByAddressOrFail(factory, keyFactoryCfg()), SEP)
143137
144138
145139 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
146140
147141
148142 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
149143
150144
151145 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
152146
153147
154148 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
155149
156150
157151 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
158152
159153
160154 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
161155
162156
163157 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
164158
165159
166160 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
167161
168162
169163 func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s__staked", userAddressStr, lpAssetIdStr], SEP)
170164
171165
172166 func keyStakedTotal (lpAssetIdStr) = ("%s%s%s__staked__total__" + lpAssetIdStr)
173167
174168
175169 func keyClaimedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimed", userAddressStr, lpAssetIdStr], SEP)
176170
177171
178172 func keyClaimedByUserMinReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedMinReward", userAddressStr, lpAssetIdStr], SEP)
179173
180174
181175 func keyClaimedByUserBoostReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedBoostReward", userAddressStr, lpAssetIdStr], SEP)
182176
183177
184178 func keyClaimedTotal (lpAssetIdStr) = makeString(["%s%s%s__claimed__total", lpAssetIdStr], SEP)
185179
186180
187181 func readStaked (key) = valueOrElse(getInteger(this, key), 0)
188182
189183
190184 func keyLastTotalLpBalance (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "bal"], SEP)
191185
192186
193187 func keyLastUserLpBalance (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "bal"], SEP)
194188
195189
196190 func keyTotalLpBalanceIntegral (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "balINT"], SEP)
197191
198192
199193 func keyUserLpBalanceIntegral (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "balINT"], SEP)
200194
201195
202196 func keyTotalLpBalanceIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "lastUpd"], SEP)
203197
204198
205199 func keyUserLpBalanceIntegralLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "lastUpd"], SEP)
206200
207201
208202 func keyWxPerLpIntegral (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpInt"], SEP)
209203
210204
211205 func keyWxPerLpIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpIntH"], SEP)
212206
213207
214208 func keyWxToClaimUser (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpInt"], SEP)
215209
216210
217211 func keyWxPerLpIntegralUserLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpIntH"], SEP)
218212
219213
220214 func keyWxPerLp (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLp"], SEP)
221215
222216
223217 func keyWxPerLpX18 (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLpX18"], SEP)
224218
225219
226220 func keyWxPerLpIntegralUserLast (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "uIntL"], SEP)
227221
228222
229223 func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
230224
231225
232226 func formatHistoryRecord (userAddress,lpAssetId,type,amount) = makeString(["%s%s%s%d%d%d", userAddress, lpAssetId, type, toString(height), toString(lastBlock.timestamp), toString(amount)], SEP)
233227
234228
235229 func OperationHistoryEntry (type,userAddress,lpAssetId,amount,txId) = StringEntry(keyOperationHistoryRecord(type, userAddress, toBase58String(txId)), formatHistoryRecord(userAddress, lpAssetId, type, amount))
236230
237231
238232 let factoryAddress = getStringOrFail(this, keyFactoryAddress())
239233
240234 let factoryContract = addressFromStringValue(factoryAddress)
241235
242236 let factoryCfg = readFactoryCfgOrFail(factoryContract)
243237
244238 let emissionContract = getEmissionAddressOrFail(factoryCfg)
245239
246240 let boostingContract = getBoostingAddressOrFail(factoryCfg)
247241
248-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"))
249-
250242 func keyNextUser (lpAssetId) = makeString(["%s%s", lpAssetId, "nextUser"], SEP)
251243
252244
253245 func getUsersListName (lpAssetId) = makeString(["users", lpAssetId], SEP)
254246
255247
256248 func keyListHead (listName) = makeString(["%s%s%s", listName, "head"], SEP)
257249
258250
259251 func keyListSize (listName) = makeString(["%s%s%s", listName, "size"], SEP)
260252
261253
262254 func keyListPrev (listName,id) = makeString(["%s%s%s%s", listName, id, "prev"], SEP)
263255
264256
265257 func keyListNext (listName,id) = makeString(["%s%s%s%s", listName, id, "next"], SEP)
266258
267259
268260 func containsNode (listName,id) = {
269261 let headOrUnit = getString(this, keyListHead(listName))
270262 let prevOrUnit = getString(this, keyListPrev(listName, id))
271263 let nextOrUnit = getString(this, keyListNext(listName, id))
272264 if (if ((id == valueOrElse(headOrUnit, "")))
273265 then true
274266 else (prevOrUnit != unit))
275267 then true
276268 else (nextOrUnit != unit)
277269 }
278270
279271
280272 func insertNodeActions (listName,id) = {
281273 let headOrUnit = getString(this, keyListHead(listName))
282274 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
283275 let checkNode = if (!(containsNode(listName, id)))
284276 then true
285277 else throw("Node exists")
286278 if ((checkNode == checkNode))
287279 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
288280 then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
289281 else nil)) ++ [StringEntry(keyListHead(listName), id)])
290282 else throw("Strict value is not equal to itself.")
291283 }
292284
293285
294286 func deleteNodeActions (listName,id) = {
295287 let headOrUnit = getString(this, keyListHead(listName))
296288 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
297289 let prevOrUnit = getString(this, keyListPrev(listName, id))
298290 let nextOrUnit = getString(this, keyListNext(listName, id))
299291 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
300292 then (nextOrUnit != unit)
301293 else false)
302294 then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
303295 else if ((nextOrUnit != unit))
304296 then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
305297 else if ((prevOrUnit != unit))
306298 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
307299 else if ((id == valueOrElse(headOrUnit, "")))
308300 then [DeleteEntry(keyListHead(listName))]
309301 else throw(((("invalid node: " + listName) + ".") + id))))
310302 }
311303
312304
313305 func calcWxPerLpIntegralUserLast (stakedByUser,wxPerLpIntegralUserLastUpdHeightOrZero,wxPerLpIntegralNew,wxPerLpIntegralUserLastKEY) = if (if ((wxPerLpIntegralUserLastUpdHeightOrZero == zeroBigInt))
314306 then (stakedByUser > zeroBigInt)
315307 else false)
316308 then zeroBigInt
317309 else if ((stakedByUser == zeroBigInt))
318310 then wxPerLpIntegralNew
319311 else if (if ((wxPerLpIntegralUserLastUpdHeightOrZero > zeroBigInt))
320312 then (stakedByUser > zeroBigInt)
321313 else false)
322314 then value(parseBigInt(getStringOrFail(this, wxPerLpIntegralUserLastKEY)))
323315 else throw("calcWxPerLpIntegralUserLast: unexpected state")
324316
325317
326318 func refreshPoolINTEGRALS (lpAssetIdStr,poolAddressStr,lpDeltaAmount) = {
327319 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
328320 let stakedTotal = toBigInt(readStaked(stakedTotalKEY))
329321 let nonZeroStakedTotal = if ((stakedTotal == zeroBigInt))
330322 then oneBigInt
331323 else stakedTotal
332324 let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
333325 let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
334326 let MULT3 = 1000
335327 let wxEmissionPerBlockX3 = (getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) * MULT3)
336328 let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * 3))
337329 let wxPerLpIntegralKEY = keyWxPerLpIntegral(lpAssetIdStr)
338330 let wxPerLpIntegralLastUpdHeightKEY = keyWxPerLpIntegralLastUpdHeight(lpAssetIdStr)
339331 let wxPerLpKEY = keyWxPerLp(lpAssetIdStr)
340332 let wxPerLpIntegralLastUpdHeight = getIntOrDefault(this, wxPerLpIntegralLastUpdHeightKEY, emissionStartBlock)
341333 let wxPerLpIntegral = getBigIntFromStringOrZero(this, wxPerLpIntegralKEY)
342334 let wxPerLpOrZeroX3 = 0
343335 let dh = max([(height - wxPerLpIntegralLastUpdHeight), 0])
344336 let wxPerLpX3 = if ((wxPerLpOrZeroX3 != 0))
345337 then toBigInt(wxPerLpOrZeroX3)
346338 else fraction(toBigInt(poolWxEmissionPerBlockX3), toBigInt(MULT8), nonZeroStakedTotal)
347339 let stakedTotalNew = (stakedTotal + toBigInt(lpDeltaAmount))
348340 let nonZeroStakedTotalNew = if ((stakedTotalNew == zeroBigInt))
349341 then oneBigInt
350342 else stakedTotalNew
351343 let wxPerLpIntegralNew = (wxPerLpIntegral + (wxPerLpX3 * toBigInt(dh)))
352344 let wxPerLpX3New = (toBigInt(poolWxEmissionPerBlockX3) / nonZeroStakedTotalNew)
353345 let wxPerLpIntegralLastUpdHeightNew = height
354346 let debug = makeString([toString(wxPerLpIntegralNew), toString(dh), toString(wxPerLpX3), toString(stakedTotal), toString(poolWxEmissionPerBlockX3), toString(wxEmissionPerBlockX3), toString(poolWeight)], "::")
355347 $Tuple3(wxPerLpIntegralNew, [StringEntry(wxPerLpIntegralKEY, toString(wxPerLpIntegralNew)), IntegerEntry(wxPerLpIntegralLastUpdHeightKEY, wxPerLpIntegralLastUpdHeightNew), StringEntry(wxPerLpKEY, toString(wxPerLpX3New))], debug)
356348 }
357349
358350
359351 func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
360- let $t01475014872 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
361- let wxPerLpIntegralNew = $t01475014872._1
362- let poolIntegralSTATE = $t01475014872._2
363- let poolDEBUG = $t01475014872._3
352+ let $t01427414396 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
353+ let wxPerLpIntegralNew = $t01427414396._1
354+ let poolIntegralSTATE = $t01427414396._2
355+ let poolDEBUG = $t01427414396._3
364356 let MULT3 = 1000
365357 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
366358 let stakedByUser = readStaked(stakedByUserKEY)
367359 let wxToClaimUserKEY = keyWxToClaimUser(lpAssetIdStr, userAddressStr)
368360 let wxPerLpIntegralUserLastUpdHeightKEY = keyWxPerLpIntegralUserLastUpdHeight(lpAssetIdStr, userAddressStr)
369361 let wxPerLpIntegralUserLastKEY = keyWxPerLpIntegralUserLast(lpAssetIdStr, userAddressStr)
370362 let wxToClaimUser = getBigIntFromStringOrZero(this, wxToClaimUserKEY)
371363 let wxPerLpIntegralUserLastUpdHeightOrZero = getIntOrZero(this, wxPerLpIntegralUserLastUpdHeightKEY)
372364 let wxPerLpIntegralUserLast = calcWxPerLpIntegralUserLast(toBigInt(stakedByUser), toBigInt(wxPerLpIntegralUserLastUpdHeightOrZero), wxPerLpIntegralNew, wxPerLpIntegralUserLastKEY)
373365 let MULT11 = (MULT8 * MULT3)
374366 let wxToClaimUserNew = max([(wxToClaimUser + fraction((wxPerLpIntegralNew - wxPerLpIntegralUserLast), toBigInt(stakedByUser), toBigInt(MULT11))), zeroBigInt])
375367 let wxPerLpIntegralUserLastNew = wxPerLpIntegralNew
376368 let wxPerLpIntegralUserLastUpdHeightNew = height
377369 let debug = makeString([toString(wxToClaimUser), toString(wxPerLpIntegralUserLast), toString(stakedByUser), poolDEBUG, toString(height)], "::")
378370 $Tuple3(wxToClaimUserNew, (poolIntegralSTATE ++ [StringEntry(wxToClaimUserKEY, toString(wxToClaimUserNew)), IntegerEntry(wxPerLpIntegralUserLastUpdHeightKEY, wxPerLpIntegralUserLastUpdHeightNew), StringEntry(wxPerLpIntegralUserLastKEY, toString(wxPerLpIntegralUserLastNew))]), debug)
379371 }
380372
381373
382374 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
383375 case s: String =>
384376 fromBase58String(s)
385377 case _: Unit =>
386378 unit
387379 case _ =>
388380 throw("Match error")
389381 }
390382
391383
392384 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
393385 case s: String =>
394386 fromBase58String(s)
395387 case _: Unit =>
396388 unit
397389 case _ =>
398390 throw("Match error")
399391 }
400392
401393
402394 let permissionDeniedError = throw("Permission denied")
403395
404396 func mustThis (i) = if ((i.caller == this))
405397 then true
406398 else permissionDeniedError
407399
408400
409401 func mustManager (i) = match managerPublicKeyOrUnit() {
410402 case pk: ByteVector =>
411403 if ((i.callerPublicKey == pk))
412404 then true
413405 else permissionDeniedError
414406 case _: Unit =>
415407 if ((i.caller == this))
416408 then true
417409 else permissionDeniedError
418410 case _ =>
419411 throw("Match error")
420412 }
421-
422-
423-func unstakeActions (i,lpAssetId,poolAddress,userAddress,lpAssetRecipientAddress,amount) = {
424- let userAddressStr = toString(userAddress)
425- let lpAssetIdStr = toBase58String(lpAssetId)
426- let poolAddressStr = toString(poolAddress)
427- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
428- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
429- let stakedByUser = readStaked(stakedByUserKEY)
430- let stakedTotal = readStaked(stakedTotalKEY)
431- let integralSTATE = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))._2
432- let listName = getUsersListName(lpAssetIdStr)
433- let listActions = if (if (containsNode(listName, userAddressStr))
434- then (amount == stakedByUser)
435- else false)
436- then deleteNodeActions(listName, userAddressStr)
437- else nil
438- let claimedByUserMinReward = getBigIntFromStringOrZero(this, keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr))
439- let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)._1
440- let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
441- let throwIfNothingToClaim = true
442- let r = if ((availableToClaim > zeroBigInt))
443- then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
444- else unit
445- if ((r == r))
446- then if ((amount > stakedByUser))
447- then throw(((((((("passed amount=" + toString(amount)) + " is greater than available=") + toString(stakedByUser)) + ". lpAssetId=") + lpAssetIdStr) + ". stakedByUserKEY=") + stakedByUserKEY))
448- else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(lpAssetRecipientAddress, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
449- else throw("Strict value is not equal to itself.")
450- }
451413
452414
453415 @Callable(i)
454416 func constructor (factoryAddressStr) = {
455417 let checkCaller = mustManager(i)
456418 if ((checkCaller == checkCaller))
457419 then [StringEntry(keyFactoryAddress(), factoryAddressStr)]
458420 else throw("Strict value is not equal to itself.")
459421 }
460422
461423
462424
463425 @Callable(i)
464426 func constructorV2 (votingEmissionContract) = {
465427 let cheks = [mustManager(i), if ((addressFromString(votingEmissionContract) != unit))
466428 then true
467429 else "invalid voting emission contract address"]
468430 if ((cheks == cheks))
469431 then [StringEntry(keyVotingEmissionContract(), votingEmissionContract)]
470432 else throw("Strict value is not equal to itself.")
471433 }
472434
473435
474436
475437 @Callable(i)
476438 func setManager (pendingManagerPublicKey) = {
477439 let checkCaller = mustManager(i)
478440 if ((checkCaller == checkCaller))
479441 then {
480442 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
481443 if ((checkManagerPublicKey == checkManagerPublicKey))
482444 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
483445 else throw("Strict value is not equal to itself.")
484446 }
485447 else throw("Strict value is not equal to itself.")
486448 }
487449
488450
489451
490452 @Callable(i)
491453 func confirmManager () = {
492454 let pm = pendingManagerPublicKeyOrUnit()
493455 let hasPM = if (isDefined(pm))
494456 then true
495457 else throw("No pending manager")
496458 if ((hasPM == hasPM))
497459 then {
498460 let checkPM = if ((i.callerPublicKey == value(pm)))
499461 then true
500462 else throw("You are not pending manager")
501463 if ((checkPM == checkPM))
502464 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
503465 else throw("Strict value is not equal to itself.")
504466 }
505467 else throw("Strict value is not equal to itself.")
506468 }
507469
508470
509471
510472 @Callable(i)
511473 func stake () = if ((size(i.payments) != 1))
512474 then throw("invalid payment - exact one payment must be attached")
513475 else {
514476 let pmt = i.payments[0]
515477 let lpAssetId = value(pmt.assetId)
516478 let lpAssetIdStr = toBase58String(lpAssetId)
517479 let amount = pmt.amount
518480 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
519481 let callerStr = toString(i.caller)
520482 let userAddressStr = if ((callerStr == poolAddressStr))
521483 then toString(i.originCaller)
522484 else callerStr
523485 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
524486 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
525487 let stakedByUser = readStaked(stakedByUserKEY)
526488 let stakedTotal = readStaked(stakedTotalKEY)
527- let $t02127621393 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
528- let wxToClaimUserNew = $t02127621393._1
529- let integralSTATE = $t02127621393._2
530- let debug = $t02127621393._3
489+ let $t01883218949 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
490+ let wxToClaimUserNew = $t01883218949._1
491+ let integralSTATE = $t01883218949._2
492+ let debug = $t01883218949._3
531493 let listName = getUsersListName(lpAssetIdStr)
532494 let listActions = if (containsNode(listName, userAddressStr))
533495 then nil
534496 else insertNodeActions(listName, userAddressStr)
535497 (([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
536498 }
537499
538500
539501
540502 @Callable(i)
541503 func unstake (lpAssetIdStr,amount) = {
542504 let lpAssetId = fromBase58String(lpAssetIdStr)
543505 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
544- let poolAddress = addressFromStringValue(poolAddressStr)
545- let poolAddon = valueOrElse(getString(poolAddress, keyAddonAddr()), poolAddressStr)
506+ let poolAddon = valueOrElse(getString(addressFromStringValue(poolAddressStr), keyAddonAddr()), poolAddressStr)
546507 let callerStr = toString(i.caller)
547- let userAddress = if (if ((callerStr == poolAddressStr))
508+ let userAddressStr = if (if ((callerStr == poolAddressStr))
548509 then true
549510 else (callerStr == poolAddon))
550- then i.originCaller
551- else i.caller
552- let lpAssetRecipientAddress = i.caller
553- unstakeActions(i, lpAssetId, poolAddress, userAddress, lpAssetRecipientAddress, amount)
554- }
555-
556-
557-
558-@Callable(i)
559-func unstakeINTERNAL (lpAssetId,amount,userAddress,lpAssetRecipientAddress) = {
560- let lpAssetIdStr = toBase58String(lpAssetId)
561- let poolAddress = addressFromStringValue(valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr)))
562- let checkCaller = if ((i.caller == poolAddress))
563- then true
564- else permissionDeniedError
565- if ((checkCaller == checkCaller))
566- then unstakeActions(i, lpAssetId, poolAddress, Address(userAddress), Address(lpAssetRecipientAddress), amount)
511+ then toString(i.originCaller)
512+ else callerStr
513+ let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
514+ let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
515+ let stakedByUser = readStaked(stakedByUserKEY)
516+ let stakedTotal = readStaked(stakedTotalKEY)
517+ let integralSTATE = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))._2
518+ let listName = getUsersListName(lpAssetIdStr)
519+ let listActions = if (if (containsNode(listName, userAddressStr))
520+ then (amount == stakedByUser)
521+ else false)
522+ then deleteNodeActions(listName, userAddressStr)
523+ else nil
524+ let claimedByUserMinReward = getBigIntFromStringOrZero(this, keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr))
525+ let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
526+ let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddress, 0)._1
527+ let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
528+ let r = if ((availableToClaim > zeroBigInt))
529+ then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil)
530+ else unit
531+ if ((r == r))
532+ then if ((amount > stakedByUser))
533+ then throw(((((((("passed amount=" + toString(amount)) + " is greater than available=") + toString(stakedByUser)) + ". lpAssetId=") + lpAssetIdStr) + ". stakedByUserKEY=") + stakedByUserKEY))
534+ else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
567535 else throw("Strict value is not equal to itself.")
568536 }
569537
570538
571539
572540 @Callable(i)
573541 func claimWx (lpAssetIdStr) = {
574542 let userAddressStr = toString(i.caller)
575- let throwIfNothingToClaim = true
576- let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
543+ let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil)
577544 $Tuple2(nil, result)
578545 }
579546
580547
581548
582549 @Callable(i)
583-func claimWxDoNotThrow (lpAssetIdStr) = {
584- let userAddressStr = toString(i.caller)
585- let throwIfNothingToClaim = false
586- let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
587- $Tuple2(nil, result)
588- }
589-
590-
591-
592-@Callable(i)
593-func claimWxINTERNAL (lpAssetIdStr,userAddressStr,throwIfNothingToClaim) = {
550+func claimWxINTERNAL (lpAssetIdStr,userAddressStr) = {
594551 let checkCaller = mustThis(i)
595552 if ((checkCaller == checkCaller))
596553 then {
597554 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), "claimWxINTERNAL: invalid user address")
598555 let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
599556 let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
600557 let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr)
601558 let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
602559 let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr)
603560 let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
604561 let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
605562 let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
606563 let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
607- let $t02477924891 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
608- let wxToClaimUserNew = $t02477924891._1
609- let integralSTATE = $t02477924891._2
610- let debug = $t02477924891._3
564+ let $t02281422926 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
565+ let wxToClaimUserNew = $t02281422926._1
566+ let integralSTATE = $t02281422926._2
567+ let debug = $t02281422926._3
611568 let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
612569 if ((zeroBigInt >= availableToClaim))
613- then if (throwIfNothingToClaim)
614- then throw("nothing to claim")
615- else $Tuple2(nil, 0)
570+ then throw("nothing to claim")
616571 else {
617572 let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
618573 let minRewardPart = availableToClaim
619574 let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
620- let totalReward = (minRewardPart + boostRewardPart)
621575 let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
622576 let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
623577 if ((emitBoost == emitBoost))
624578 then {
625579 let claimedByUserValue = ((claimedByUser + minRewardPart) + boostRewardPart)
626580 let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
627581 let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserBoostReward + boostRewardPart)
628582 let claimedTotalPlusAvailableToClaim = (claimedTotal + availableToClaim)
629- $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))
583+[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)]
630584 }
631585 else throw("Strict value is not equal to itself.")
632586 }
633587 }
634588 else throw("Strict value is not equal to itself.")
635589 }
636590
637591
638592
639593 @Callable(i)
640594 func claimWxBulkInternalREADONLY (currentIter,lpAssetIds,userAddressStr,resAcc) = if ((currentIter == size(lpAssetIds)))
641595 then $Tuple2(nil, resAcc)
642596 else {
643597 let lpAssetId = lpAssetIds[currentIter]
644598 let info = split({
645599 let @ = invoke(this, "claimWxREADONLY", [lpAssetId, userAddressStr], nil)
646600 if ($isInstanceOf(@, "String"))
647601 then @
648602 else throw(($getType(@) + " couldn't be cast to String"))
649603 }, SEP)
650604 let unclaimed = info[3]
651605 let claimed = info[4]
652606 let res = (resAcc :+ makeString(["%d%d", unclaimed, claimed], SEP))
653607 let inv = {
654608 let @ = invoke(this, "claimWxBulkInternalREADONLY", [(currentIter + 1), lpAssetIds, userAddressStr, res], nil)
655609 if ($isInstanceOf(@, "List[Any]"))
656610 then @
657611 else throw(($getType(@) + " couldn't be cast to List[Any]"))
658612 }
659613 if ((inv == inv))
660614 then $Tuple2(nil, inv)
661615 else throw("Strict value is not equal to itself.")
662616 }
663617
664618
665619
666620 @Callable(i)
667621 func claimWxBulkREADONLY (lpAssetIds,userAddressStr) = {
668622 let res = invoke(this, "claimWxBulkInternalREADONLY", [0, lpAssetIds, userAddressStr, nil], nil)
669623 $Tuple2(nil, res)
670624 }
671625
672626
673627
674628 @Callable(i)
675629 func claimWxREADONLY (lpAssetIdStr,userAddressStr) = {
676630 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
677631 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
678632 let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
679633 let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
680634 let stakedByUser = readStaked(stakedByUserKEY)
681635 let stakedTotal = readStaked(stakedTotalKEY)
682636 let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
683637 let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
684638 let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
685639 let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
686640 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
687641 let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
688642 let passedBlocks = if ((emissionStartBlock > height))
689643 then 0
690644 else (height - emissionStartBlock)
691645 let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
692646 let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
693- let $t02870028812 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
694- let wxToClaimUserNew = $t02870028812._1
695- let integralSTATE = $t02870028812._2
696- let debug = $t02870028812._3
647+ let $t02658426696 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
648+ let wxToClaimUserNew = $t02658426696._1
649+ let integralSTATE = $t02658426696._2
650+ let debug = $t02658426696._3
697651 let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
698652 let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
699653 let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
700654 let boostDebug = asString(boostInvResult[1])
701655 let minRewardPart = availableToClaim
702656 let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
703657 let totalReward = (minRewardPart + boostRewardPart)
704658 $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), "soon"], SEP))
705- }
706-
707-
708-
709-@Callable(i)
710-func stakedByUserREADONLY (lpAssetIdStr,userAddressStr) = {
711- let stakedByUser = valueOrElse(getInteger(keyStakedByUser(userAddressStr, lpAssetIdStr)), 0)
712- $Tuple2(nil, stakedByUser)
713659 }
714660
715661
716662
717663 @Callable(i)
718664 func usersListTraversal (lpAssetId) = {
719665 let checkCaller = if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionContract()), "")))
720666 then true
721667 else mustManager(i)
722668 if ((checkCaller == checkCaller))
723669 then {
724670 let listName = getUsersListName(lpAssetId)
725671 let userOrUnit = getString(keyNextUser(lpAssetId))
726672 let headOrUnit = getString(keyListHead(listName))
727673 match userOrUnit {
728674 case _: Unit =>
729675 match headOrUnit {
730676 case _: Unit =>
731677 $Tuple2(nil, false)
732678 case head: String =>
733679 $Tuple2([StringEntry(keyNextUser(lpAssetId), head)], true)
734680 case _ =>
735681 throw("Match error")
736682 }
737683 case userAddress: String =>
738684 let claimedByUserMinReward = getBigIntFromStringOrZero(this, keyClaimedByUserMinReward(lpAssetId, userAddress))
739685 let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetId))
740686 let wxToClaimUserNew = refreshINTEGRALS(lpAssetId, userAddress, poolAddress, 0)._1
741687 let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
742- let throwIfNothingToClaim = true
743688 let r = if ((availableToClaim > zeroBigInt))
744- then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress, throwIfNothingToClaim], nil)
689+ then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress], nil)
745690 else unit
746691 if ((r == r))
747692 then {
748693 let nextUserOrUnit = getString(keyListNext(listName, userAddress))
749694 match nextUserOrUnit {
750695 case _: Unit =>
751696 $Tuple2([DeleteEntry(keyNextUser(lpAssetId))], false)
752697 case nextUser: String =>
753698 $Tuple2([StringEntry(keyNextUser(lpAssetId), nextUser)], true)
754699 case _ =>
755700 throw("Match error")
756701 }
757702 }
758703 else throw("Strict value is not equal to itself.")
759704 case _ =>
760705 throw("Match error")
761706 }
762707 }
763708 else throw("Strict value is not equal to itself.")
764709 }
765710
766711
767712
768713 @Callable(i)
769714 func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
770715 then throw("permissions denied")
771716 else {
772- let $t03141831528 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
773- let wxPerLpIntegralNew = $t03141831528._1
774- let poolIntegralSTATE = $t03141831528._2
775- let poolDEBUG = $t03141831528._3
717+ let $t02903229142 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
718+ let wxPerLpIntegralNew = $t02903229142._1
719+ let poolIntegralSTATE = $t02903229142._2
720+ let poolDEBUG = $t02903229142._3
776721 poolIntegralSTATE
777722 }
778723
779724
780725 @Verifier(tx)
781726 func verify () = {
782727 let targetPublicKey = match managerPublicKeyOrUnit() {
783728 case pk: ByteVector =>
784729 pk
785730 case _: Unit =>
786731 tx.senderPublicKey
787732 case _ =>
788733 throw("Match error")
789734 }
790735 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
791736 }
792737

github/deemru/w8io/3ef1775 
127.83 ms