2022.06.30 19:57 [3185025] smart account 3PPNhHYkkEy13gRWDCaruQyhNbX2GrjYSyV > SELF 0.00000000 Waves

{ "type": 13, "id": "AzdTZRddiHLAbdrjC2vatiK5HvXE4EQyHJCt1pdan6fD", "fee": 3000000, "feeAssetId": null, "timestamp": 1656608192876, "version": 1, "sender": "3PPNhHYkkEy13gRWDCaruQyhNbX2GrjYSyV", "senderPublicKey": "EAtbDa63mS5omrvW7Pfr7DKWEVLuReJtu72vfiBLRXsx", "proofs": [ "5PKjYvi3wZu3Zmvnu7z52Te7mVLtsKi3UsFHdrLT6eByjQTMsJEediu1iQCE6WPqJaQ3622bsSqMuasz6wnr22CM" ], "script": "base64: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YXRjaDAJAAQdAAAAAgUAAAAHYWRkcmVzcwUAAAADa2V5AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAAZTdHJpbmcEAAAAAXMFAAAAByRtYXRjaDAJAQAAAAV2YWx1ZQAAAAEJAAGoAAAAAQUAAAABcwMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAEVW5pdAUAAAAKZGVmYXVsdFZhbAkAAAIAAAABAgAAAAtNYXRjaCBlcnJvcgEAAAAFdG9YMTgAAAACAAAAB29yaWdWYWwAAAANb3JpZ1NjYWxlTXVsdAkAATwAAAADCQABNgAAAAEFAAAAB29yaWdWYWwFAAAABk1VTFQxOAkAATYAAAABBQAAAA1vcmlnU2NhbGVNdWx0AQAAAAdmcm9tWDE4AAAAAgAAAAN2YWwAAAAPcmVzdWx0U2NhbGVNdWx0CQABoAAAAAEJAAE8AAAAAwUAAAADdmFsCQABNgAAAAEFAAAAD3Jlc3VsdFNjYWxlTXVsdAUAAAAGTVVMVDE4AQAAABFrZXlGYWN0b3J5QWRkcmVzcwAAAAACAAAAHCVzJXNfX2NvbmZpZ19fZmFjdG9yeUFkZHJlc3MAAAAAGElkeEZhY3RvcnlDZmdTdGFraW5nRGFwcAAAAAAAAAAAAQAAAAAZSWR4RmFjdG9yeUNmZ0Jvb3N0aW5nRGFwcAAAAAAAAAAAAgAAAAAUSWR4RmFjdG9yeUNmZ0lkb0RhcHAAAAAAAAAAAAMAAAAAFUlkeEZhY3RvcnlDZmdUZWFtRGFwcAAAAAAAAAAABAAAAAAZSWR4RmFjdG9yeUNmZ0VtaXNzaW9uRGFwcAAAAAAAAAAABQAAAAAVSWR4RmFjdG9yeUNmZ1Jlc3REYXBwAAAAAAAAAAAGAAAAABlJZHhGYWN0b3J5Q2ZnU2xpcHBhZ2VEYXBwAAAAAAAAAAAHAQAAAA1rZXlGYWN0b3J5Q2ZnAAAAAAIAAAARJXNfX2ZhY3RvcnlDb25maWcBAAAAE2tleU1hbmFnZXJQdWJsaWNLZXkAAAAAAgAAABQlc19fbWFuYWdlclB1YmxpY0tleQEAAAAaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkAAAAAAgAAABslc19fcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkBAAAAFmtleVN0YWJsZVBvb2xBZGRvbkFkZHIAAAAAAgAAABclc19fc3RhYmxlUG9vbEFkZG9uQWRkcgEAAAAaa2V5RmFjdG9yeUxwMkFzc2V0c01hcHBpbmcAAAABAAAACmxwQXNzZXRTdHIJAAS5AAAAAgkABEwAAAACAgAAAAYlcyVzJXMJAARMAAAAAgUAAAAKbHBBc3NldFN0cgkABEwAAAACAgAAAB5tYXBwaW5nc19fbHBBc3NldDJQb29sQ29udHJhY3QFAAAAA25pbAUAAAADU0VQAQAAABBrZXlGYWN0b3J5THBMaXN0AAAAAAIAAAAQJXNfX2xwVG9rZW5zTGlzdAEAAAAma2V5RmFjdG9yeUxwQXNzZXRUb1Bvb2xDb250cmFjdEFkZHJlc3MAAAABAAAACmxwQXNzZXRTdHIJAAS5AAAAAgkABEwAAAACAgAAAAYlcyVzJXMJAARMAAAAAgUAAAAKbHBBc3NldFN0cgkABEwAAAACAgAAAB5tYXBwaW5nc19fbHBBc3NldDJQb29sQ29udHJhY3QFAAAAA25pbAUAAAADU0VQAQAAABRrZXlGYWN0b3J5UG9vbFdlaWdodAAAAAEAAAAPY29udHJhY3RBZGRyZXNzCQAEuQAAAAIJAARMAAAAAgIAAAAEJXMlcwkABEwAAAACAgAAAApwb29sV2VpZ2h0CQAETAAAAAIFAAAAD2NvbnRyYWN0QWRkcmVzcwUAAAADbmlsBQAAAANTRVABAAAACnJlYWRMcExpc3QAAAABAAAAB2ZhY3RvcnkJAAS1AAAAAgkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACBQAAAAdmYWN0b3J5CQEAAAAQa2V5RmFjdG9yeUxwTGlzdAAAAAACAAAAAAUAAAADU0VQAQAAABRyZWFkRmFjdG9yeUNmZ09yRmFpbAAAAAEAAAAHZmFjdG9yeQkABLUAAAACCQEAAAAYZ2V0U3RyaW5nQnlBZGRyZXNzT3JGYWlsAAAAAgUAAAAHZmFjdG9yeQkBAAAADWtleUZhY3RvcnlDZmcAAAAABQAAAANTRVABAAAAGGdldEJvb3N0aW5nQWRkcmVzc09yRmFpbAAAAAEAAAAKZmFjdG9yeUNmZwkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkAAZEAAAACBQAAAApmYWN0b3J5Q2ZnBQAAABlJZHhGYWN0b3J5Q2ZnQm9vc3RpbmdEYXBwAQAAABhnZXRFbWlzc2lvbkFkZHJlc3NPckZhaWwAAAABAAAACmZhY3RvcnlDZmcJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAAGRAAAAAgUAAAAKZmFjdG9yeUNmZwUAAAAZSWR4RmFjdG9yeUNmZ0VtaXNzaW9uRGFwcAEAAAAXZ2V0U3Rha2luZ0FkZHJlc3NPckZhaWwAAAABAAAACmZhY3RvcnlDZmcJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAAGRAAAAAgUAAAAKZmFjdG9yeUNmZwUAAAAYSWR4RmFjdG9yeUNmZ1N0YWtpbmdEYXBwAQAAAB5rZXlFbWlzc2lvblJhdGVQZXJCbG9ja0N1cnJlbnQAAAAAAgAAABslcyVzX19yYXRlUGVyQmxvY2tfX2N1cnJlbnQBAAAAIWtleUVtaXNzaW9uUmF0ZVBlckJsb2NrTWF4Q3VycmVudAAAAAACAAAAHiVzJXNfX3JhdGVQZXJCbG9ja01heF9fY3VycmVudAEAAAAVa2V5RW1pc3Npb25TdGFydEJsb2NrAAAAAAIAAAAaJXMlc19fZW1pc3Npb25fX3N0YXJ0QmxvY2sBAAAAG2tleUVtaXNzaW9uRHVyYXRpb25JbkJsb2NrcwAAAAACAAAAGCVzJXNfX2VtaXNzaW9uX19kdXJhdGlvbgEAAAATa2V5RW1pc3Npb25FbmRCbG9jawAAAAACAAAAGCVzJXNfX2VtaXNzaW9uX19lbmRCbG9jawEAAAAPa2V5U3Rha2VkQnlVc2VyAAAAAgAAAA51c2VyQWRkcmVzc1N0cgAAAAxscEFzc2V0SWRTdHIJAAS5AAAAAgkABEwAAAACAgAAAA4lcyVzJXNfX3N0YWtlZAkABEwAAAACBQAAAA51c2VyQWRkcmVzc1N0cgkABEwAAAACBQAAAAxscEFzc2V0SWRTdHIFAAAAA25pbAUAAAADU0VQAQAAAA5rZXlTdGFrZWRUb3RhbAAAAAEAAAAMbHBBc3NldElkU3RyCQABLAAAAAICAAAAFyVzJXMlc19fc3Rha2VkX190b3RhbF9fBQAAAAxscEFzc2V0SWRTdHIBAAAAEGtleUNsYWltZWRCeVVzZXIAAAACAAAADGxwQXNzZXRJZFN0cgAAAA51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ZWFkRmFjdG9yeUNmZ09yRmFpbAAAAAEFAAAAD2ZhY3RvcnlDb250cmFjdAAAAAAQZW1pc3Npb25Db250cmFjdAkBAAAAGGdldEVtaXNzaW9uQWRkcmVzc09yRmFpbAAAAAEFAAAACmZhY3RvcnlDZmcAAAAAEGJvb3N0aW5nQ29udHJhY3QJAQAAABhnZXRCb29zdGluZ0FkZHJlc3NPckZhaWwAAAABBQAAAApmYWN0b3J5Q2ZnAQAAABtjYWxjV3hQZXJMcEludGVncmFsVXNlckxhc3QAAAAEAAAADHN0YWtlZEJ5VXNlcgAAACZ3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE9yWmVybwAAABJ3eFBlckxwSW50ZWdyYWxOZXcAAAAad3hQZXJMcEludGVncmFsVXNlckxhc3RLRVkDAwkAAAAAAAACBQAAACZ3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE9yWmVybwUAAAAKemVyb0JpZ0ludAkAAT8AAAACBQAAAAxzdGFrZWRCeVVzZXIFAAAACnplcm9CaWdJbnQHBQAAAAp6ZXJvQmlnSW50AwkAAAAAAAACBQAAAAxzdGFrZWRCeVVzZXIFAAAACnplcm9CaWdJbnQFAAAAEnd4UGVyTHBJbnRlZ3JhbE5ldwMDCQABPwAAAAIFAAAAJnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0T3JaZXJvBQAAAAp6ZXJvQmlnSW50CQABPwAAAAIFAAAADHN0YWtlZEJ5VXNlcgUAAAAKemVyb0JpZ0ludAcJAQAAAAV2YWx1ZQAAAAEJAAGoAAAAAQkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAIFAAAABHRoaXMFAAAAGnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0S0VZCQAAAgAAAAECAAAALWNhbGNXeFBlckxwSW50ZWdyYWxVc2VyTGFzdDogdW5leHBlY3RlZCBzdGF0ZQEAAAAUcmVmcmVzaFBvb2xJTlRFR1JBTFMAAAADAAAADGxwQXNzZXRJZFN0cgAAAA5wb29sQWRkcmVzc1N0cgAAAA1scERlbHRhQW1vdW50BAAAAA5zdGFrZWRUb3RhbEtFWQkBAAAADmtleVN0YWtlZFRvdGFsAAAAAQUAAAAMbHBBc3NldElkU3RyBAAAAAtzdGFrZWRUb3RhbAkAATYAAAABCQEAAAAKcmVhZFN0YWtlZAAAAAEFAAAADnN0YWtlZFRvdGFsS0VZBAAAABJub25aZXJvU3Rha2VkVG90YWwDCQAAAAAAAAIFAAAAC3N0YWtlZFRvdGFsBQAAAAp6ZXJvQmlnSW50BQAAAAlvbmVCaWdJbnQFAAAAC3N0YWtlZFRvdGFsBAAAAApwb29sV2VpZ2h0CQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAA9mYWN0b3J5Q29udHJhY3QJAQAAABRrZXlGYWN0b3J5UG9vbFdlaWdodAAAAAEFAAAADnBvb2xBZGRyZXNzU3RyBAAAABJlbWlzc2lvblN0YXJ0QmxvY2sJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAAVa2V5RW1pc3Npb25TdGFydEJsb2NrAAAAAAQAAAAFTVVMVDMAAAAAAAAAA+gEAAAAFHd4RW1pc3Npb25QZXJCbG9ja1gzCQAAaAAAAAIJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAAea2V5RW1pc3Npb25SYXRlUGVyQmxvY2tDdXJyZW50AAAAAAUAAAAFTVVMVDMEAAAAGHBvb2xXeEVtaXNzaW9uUGVyQmxvY2tYMwkAAGsAAAADBQAAABR3eEVtaXNzaW9uUGVyQmxvY2tYMwUAAAAKcG9vbFdlaWdodAkAAGgAAAACBQAAAA5QT09MV0VJR0hUTVVMVAAAAAAAAAAAAwQAAAASd3hQZXJMcEludGVncmFsS0VZCQEAAAASa2V5V3hQZXJMcEludGVncmFsAAAAAQUAAAAMbHBBc3NldElkU3RyBAAAAB93eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0S0VZCQEAAAAfa2V5V3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodAAAAAEFAAAADGxwQXNzZXRJZFN0cgQAAAAKd3hQZXJMcEtFWQkBAAAACmtleVd4UGVyTHAAAAABBQAAAAxscEFzc2V0SWRTdHIEAAAAHHd4UGVyTHBJbnRlZ3JhbExhc3RVcGRIZWlnaHQJAQAAAA9nZXRJbnRPckRlZmF1bHQAAAADBQAAAAR0aGlzBQAAAB93eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0S0VZBQAAABJlbWlzc2lvblN0YXJ0QmxvY2sEAAAAD3d4UGVyTHBJbnRlZ3JhbAkBAAAAGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8AAAACBQAAAAR0aGlzBQAAABJ3eFBlckxwSW50ZWdyYWxLRVkEAAAAD3d4UGVyTHBPclplcm9YMwAAAAAAAAAAAAQAAAACZGgJAAGWAAAAAQkABEwAAAACCQAAZQAAAAIFAAAABmhlaWdodAUAAAAcd3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodAkABEwAAAACAAAAAAAAAAAABQAAAANuaWwEAAAACXd4UGVyTHBYMwMJAQAAAAIhPQAAAAIFAAAAD3d4UGVyTHBPclplcm9YMwAAAAAAAAAAAAkAATYAAAABBQAAAA93eFBlckxwT3JaZXJvWDMJAAE8AAAAAwkAATYAAAABBQAAABhwb29sV3hFbWlzc2lvblBlckJsb2NrWDMJAAE2AAAAAQUAAAAFTVVMVDgFAAAAEm5vblplcm9TdGFrZWRUb3RhbAQAAAAOc3Rha2VkVG90YWxOZXcJAAE3AAAAAgUAAAALc3Rha2VkVG90YWwJAAE2AAAAAQUAAAANbHBEZWx0YUFtb3VudAQAAAAVbm9uWmVyb1N0YWtlZFRvdGFsTmV3AwkAAAAAAAACBQAAAA5zdGFrZWRUb3RhbE5ldwUAAAAKemVyb0JpZ0ludAUAAAAJb25lQmlnSW50BQAAAA5zdGFrZWRUb3RhbE5ldwQAAAASd3hQZXJMcEludGVncmFsTmV3CQABNwAAAAIFAAAAD3d4UGVyTHBJbnRlZ3JhbAkAATkAAAACBQAAAAl3eFBlckxwWDMJAAE2AAAAAQUAAAACZGgEAAAADHd4UGVyTHBYM05ldwkAAToAAAACCQABNgAAAAEFAAAAGHBvb2xXeEVtaXNzaW9uUGVyQmxvY2tYMwUAAAAVbm9uWmVyb1N0YWtlZFRvdGFsTmV3BAAAAB93eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0TmV3BQAAAAZoZWlnaHQEAAAABWRlYnVnCQAEuQAAAAIJAARMAAAAAgkAAaYAAAABBQAAABJ3eFBlckxwSW50ZWdyYWxOZXcJAARMAAAAAgIAAAADZGg9CQAETAAAAAIJAAGkAAAAAQUAAAACZGgJAARMAAAAAgIAAAAKd3hQZXJMcFgzPQkABEwAAAACCQABpgAAAAEFAAAACXd4UGVyTHBYMwkABEwAAAACAgAAAAxzdGFrZWRUb3RhbD0JAARMAAAAAgkAAaYAAAABBQAAAAtzdGFrZWRUb3RhbAkABEwAAAACCQABpAAAAAEFAAAAGHBvb2xXeEVtaXNzaW9uUGVyQmxvY2tYMwkABEwAAAACCQABpAAAAAEFAAAAFHd4RW1pc3Npb25QZXJCbG9ja1gzCQAETAAAAAICAAAAC3Bvb2xXZWlnaHQ9CQAETAAAAAIJAAGkAAAAAQUAAAAKcG9vbFdlaWdodAUAAAADbmlsAgAAAAI6OgkABRUAAAADBQAAABJ3eFBlckxwSW50ZWdyYWxOZXcJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAASd3hQZXJMcEludGVncmFsS0VZCQABpgAAAAEFAAAAEnd4UGVyTHBJbnRlZ3JhbE5ldwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAfd3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodEtFWQUAAAAfd3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodE5ldwkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAAp3eFBlckxwS0VZCQABpgAAAAEFAAAADHd4UGVyTHBYM05ldwUAAAADbmlsBQAAAAVkZWJ1ZwEAAAAQcmVmcmVzaElOVEVHUkFMUwAAAAQAAAAMbHBBc3NldElkU3RyAAAADnVzZXJBZGRyZXNzU3RyAAAADnBvb2xBZGRyZXNzU3RyAAAADWxwRGVsdGFBbW91bnQEAAAADSR0MDExNDIxMTE1NDMJAQAAABRyZWZyZXNoUG9vbElOVEVHUkFMUwAAAAMFAAAADGxwQXNzZXRJZFN0cgUAAAAOcG9vbEFkZHJlc3NTdHIFAAAADWxwRGVsdGFBbW91bnQEAAAAEnd4UGVyTHBJbnRlZ3JhbE5ldwgFAAAADSR0MDExNDIxMTE1NDMAAAACXzEEAAAAEXBvb2xJbnRlZ3JhbFNUQVRFCAUAAAANJHQwMTE0MjExMTU0MwAAAAJfMgQAAAAJcG9vbERFQlVHCAUAAAANJHQwMTE0MjExMTU0MwAAAAJfMwQAAAAFTVVMVDMAAAAAAAAAA+gEAAAAD3N0YWtlZEJ5VXNlcktFWQkBAAAAD2tleVN0YWtlZEJ5VXNlcgAAAAIFAAAADnVzZXJBZGRyZXNzU3RyBQAAAAxscEFzc2V0SWRTdHIEAAAADHN0YWtlZEJ5VXNlcgkBAAAACnJlYWRTdGFrZWQAAAABBQAAAA9zdGFrZWRCeVVzZXJLRVkEAAAAEHd4VG9DbGFpbVVzZXJLRVkJAQAAABBrZXlXeFRvQ2xhaW1Vc2VyAAAAAgUAAAAMbHBBc3NldElkU3RyBQAAAA51c2VyQWRkcmVzc1N0cgQAAAAjd3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHRLRVkJAQAAACNrZXlXeFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodAAAAAIFAAAADGxwQXNzZXRJZFN0cgUAAAAOdXNlckFkZHJlc3NTdHIEAAAAGnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0S0VZCQEAAAAaa2V5V3hQZXJMcEludGVncmFsVXNlckxhc3QAAAACBQAAAAxscEFzc2V0SWRTdHIFAAAADnVzZXJBZGRyZXNzU3RyBAAAAA13eFRvQ2xhaW1Vc2VyCQEAAAAZZ2V0QmlnSW50RnJvbVN0cmluZ09yWmVybwAAAAIFAAAABHRoaXMFAAAAEHd4VG9DbGFpbVVzZXJLRVkEAAAAJnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0T3JaZXJvCQEAAAAMZ2V0SW50T3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAjd3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHRLRVkEAAAAF3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0CQEAAAAbY2FsY1d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0AAAABAkAATYAAAABBQAAAAxzdGFrZWRCeVVzZXIJAAE2AAAAAQUAAAAmd3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHRPclplcm8FAAAAEnd4UGVyTHBJbnRlZ3JhbE5ldwUAAAAad3hQZXJMcEludGVncmFsVXNlckxhc3RLRVkEAAAABk1VTFQxMQkAAGgAAAACBQAAAAVNVUxUOAUAAAAFTVVMVDMEAAAAEHd4VG9DbGFpbVVzZXJOZXcJAAGYAAAAAQkABEwAAAACCQABNwAAAAIFAAAADXd4VG9DbGFpbVVzZXIJAAE8AAAAAwkAATgAAAACBQAAABJ3eFBlckxwSW50ZWdyYWxOZXcFAAAAF3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0CQABNgAAAAEFAAAADHN0YWtlZEJ5VXNlcgkAATYAAAABBQAAAAZNVUxUMTEJAARMAAAAAgUAAAAKemVyb0JpZ0ludAUAAAADbmlsBAAAABp3eFBlckxwSW50ZWdyYWxVc2VyTGFzdE5ldwUAAAASd3hQZXJMcEludGVncmFsTmV3BAAAACN3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE5ldwUAAAAGaGVpZ2h0BAAAAAVkZWJ1ZwkABLkAAAACCQAETAAAAAICAAAADXd4VG9DbGFpbVVzZXIJAARMAAAAAgkAAaYAAAABBQAAAA13eFRvQ2xhaW1Vc2VyCQAETAAAAAICAAAADHd4UGVyTHBJbnRlZwkABEwAAAACCQABpAAAAAEFAAAAJnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0T3JaZXJvCQAETAAAAAICAAAADnRoaXMuZ2V0U3RyaW5nCQAETAAAAAIJAAGmAAAAAQkBAAAABXZhbHVlAAAAAQkAAagAAAABCQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAgUAAAAEdGhpcwUAAAAad3hQZXJMcEludGVncmFsVXNlckxhc3RLRVkJAARMAAAAAgIAAAASd3hQZXJMcEludGVncmFsTmV3CQAETAAAAAIJAAGmAAAAAQUAAAASd3hQZXJMcEludGVncmFsTmV3CQAETAAAAAICAAAAEHd4VG9DbGFpbVVzZXJOZXcJAARMAAAAAgkAAaYAAAABBQAAABB3eFRvQ2xhaW1Vc2VyTmV3CQAETAAAAAICAAAAF3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0CQAETAAAAAIJAAGmAAAAAQUAAAAXd3hQZXJMcEludGVncmFsVXNlckxhc3QJAARMAAAAAgkAAaQAAAABBQAAAAxzdGFrZWRCeVVzZXIJAARMAAAAAgIAAAAKcG9vbERFQlVHPQkABEwAAAACBQAAAAlwb29sREVCVUcJAARMAAAAAgIAAAAHaGVpZ2h0PQkABEwAAAACCQABpAAAAAEFAAAABmhlaWdodAUAAAADbmlsAgAAAAI6OgkABRUAAAADBQAAABB3eFRvQ2xhaW1Vc2VyTmV3CQAETgAAAAIFAAAAEXBvb2xJbnRlZ3JhbFNUQVRFCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAEHd4VG9DbGFpbVVzZXJLRVkJAAGmAAAAAQUAAAAQd3hUb0NsYWltVXNlck5ldwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAjd3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHRLRVkFAAAAI3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0TmV3CQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAGnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0S0VZCQABpgAAAAEFAAAAGnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0TmV3BQAAAANuaWwFAAAABWRlYnVnAQAAABZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAAAAAQAAAAHJG1hdGNoMAkABCIAAAABCQEAAAATa2V5TWFuYWdlclB1YmxpY0tleQAAAAADCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABcwUAAAAHJG1hdGNoMAkAAlkAAAABBQAAAAFzAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAARVbml0BQAAAAR1bml0CQAAAgAAAAECAAAAC01hdGNoIGVycm9yAQAAAB1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdAAAAAAEAAAAByRtYXRjaDAJAAQiAAAAAQkBAAAAGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAAAAAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAGU3RyaW5nBAAAAAFzBQAAAAckbWF0Y2gwCQACWQAAAAEFAAAAAXMDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABFVuaXQFAAAABHVuaXQJAAACAAAAAQIAAAALTWF0Y2ggZXJyb3IBAAAAC211c3RNYW5hZ2VyAAAAAQAAAAFpBAAAAAJwZAkAAAIAAAABAgAAABFQZXJtaXNzaW9uIGRlbmllZAQAAAAHJG1hdGNoMAkBAAAAFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQAAAAAAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAApCeXRlVmVjdG9yBAAAAAJwawUAAAAHJG1hdGNoMAMJAAAAAAAAAggFAAAAAWkAAAAPY2FsbGVyUHVibGljS2V5BQAAAAJwawYFAAAAAnBkAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAARVbml0AwkAAAAAAAACCAUAAAABaQAAAAZjYWxsZXIFAAAABHRoaXMGBQAAAAJwZAkAAAIAAAABAgAAAAtNYXRjaCBlcnJvcgAAAAgAAAABaQEAAAALY29uc3RydWN0b3IAAAABAAAAEWZhY3RvcnlBZGRyZXNzU3RyBAAAAAtjaGVja0NhbGxlcgkBAAAAC211c3RNYW5hZ2VyAAAAAQUAAAABaQMJAAAAAAAAAgUAAAALY2hlY2tDYWxsZXIFAAAAC2NoZWNrQ2FsbGVyCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAABFrZXlGYWN0b3J5QWRkcmVzcwAAAAAFAAAAEWZhY3RvcnlBZGRyZXNzU3RyBQAAAANuaWwJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAACnNldE1hbmFnZXIAAAABAAAAF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5BAAAAAtjaGVja0NhbGxlcgkBAAAAC211c3RNYW5hZ2VyAAAAAQUAAAABaQMJAAAAAAAAAgUAAAALY2hlY2tDYWxsZXIFAAAAC2NoZWNrQ2FsbGVyBAAAABVjaGVja01hbmFnZXJQdWJsaWNLZXkJAAJZAAAAAQUAAAAXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkDCQAAAAAAAAIFAAAAFWNoZWNrTWFuYWdlclB1YmxpY0tleQUAAAAVY2hlY2tNYW5hZ2VyUHVibGljS2V5CQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAABprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQAAAAAFAAAAF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5BQAAAANuaWwJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAA5jb25maXJtTWFuYWdlcgAAAAAEAAAAAnBtCQEAAAAdcGVuZGluZ01hbmFnZXJQdWJsaWNLZXlPclVuaXQAAAAABAAAAAVoYXNQTQMJAQAAAAlpc0RlZmluZWQAAAABBQAAAAJwbQYJAAACAAAAAQIAAAASTm8gcGVuZGluZyBtYW5hZ2VyAwkAAAAAAAACBQAAAAVoYXNQTQUAAAAFaGFzUE0EAAAAB2NoZWNrUE0DCQAAAAAAAAIIBQAAAAFpAAAAD2NhbGxlclB1YmxpY0tleQkBAAAABXZhbHVlAAAAAQUAAAACcG0GCQAAAgAAAAECAAAAG1lvdSBhcmUgbm90IHBlbmRpbmcgbWFuYWdlcgMJAAAAAAAAAgUAAAAHY2hlY2tQTQUAAAAHY2hlY2tQTQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAATa2V5TWFuYWdlclB1YmxpY0tleQAAAAAJAAJYAAAAAQkBAAAABXZhbHVlAAAAAQUAAAACcG0JAARMAAAAAgkBAAAAC0RlbGV0ZUVudHJ5AAAAAQkBAAAAGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAAAAAUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAFc3Rha2UAAAAAAwkBAAAAAiE9AAAAAgkAAZAAAAABCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAQkAAAIAAAABAgAAADRpbnZhbGlkIHBheW1lbnQgLSBleGFjdCBvbmUgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBAAAAANwbXQJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAEAAAACWxwQXNzZXRJZAkBAAAABXZhbHVlAAAAAQgFAAAAA3BtdAAAAAdhc3NldElkBAAAAAxscEFzc2V0SWRTdHIJAAJYAAAAAQUAAAAJbHBBc3NldElkBAAAAAZhbW91bnQIBQAAAANwbXQAAAAGYW1vdW50BAAAAA5wb29sQWRkcmVzc1N0cgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAAD2ZhY3RvcnlDb250cmFjdAkBAAAAGmtleUZhY3RvcnlMcDJBc3NldHNNYXBwaW5nAAAAAQUAAAAMbHBBc3NldElkU3RyCQABLAAAAAICAAAAFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUAAAAMbHBBc3NldElkU3RyBAAAAAljYWxsZXJTdHIJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAAA51c2VyQWRkcmVzc1N0cgMJAAAAAAAAAgUAAAAJY2FsbGVyU3RyBQAAAA5wb29sQWRkcmVzc1N0cgkABCUAAAABCAUAAAABaQAAAAxvcmlnaW5DYWxsZXIFAAAACWNhbGxlclN0cgQAAAAPc3Rha2VkQnlVc2VyS0VZCQEAAAAPa2V5U3Rha2VkQnlVc2VyAAAAAgUAAAAOdXNlckFkZHJlc3NTdHIFAAAADGxwQXNzZXRJZFN0cgQAAAAOc3Rha2VkVG90YWxLRVkJAQAAAA5rZXlTdGFrZWRUb3RhbAAAAAEFAAAADGxwQXNzZXRJZFN0cgQAAAAMc3Rha2VkQnlVc2VyCQEAAAAKcmVhZFN0YWtlZAAAAAEFAAAAD3N0YWtlZEJ5VXNlcktFWQQAAAALc3Rha2VkVG90YWwJAQAAAApyZWFkU3Rha2VkAAAAAQUAAAAOc3Rha2VkVG90YWxLRVkEAAAADSR0MDE1OTM3MTYwNTQJAQAAABByZWZyZXNoSU5URUdSQUxTAAAABAUAAAAMbHBBc3NldElkU3RyBQAAAA51c2VyQWRkcmVzc1N0cgUAAAAOcG9vbEFkZHJlc3NTdHIFAAAABmFtb3VudAQAAAAQd3hUb0NsYWltVXNlck5ldwgFAAAADSR0MDE1OTM3MTYwNTQAAAACXzEEAAAADWludGVncmFsU1RBVEUIBQAAAA0kdDAxNTkzNzE2MDU0AAAAAl8yBAAAAAVkZWJ1ZwgFAAAADSR0MDE1OTM3MTYwNTQAAAACXzMJAAROAAAAAgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAPc3Rha2VkQnlVc2VyS0VZCQAAZAAAAAIFAAAADHN0YWtlZEJ5VXNlcgUAAAAGYW1vdW50CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA5zdGFrZWRUb3RhbEtFWQkAAGQAAAACBQAAAAtzdGFrZWRUb3RhbAUAAAAGYW1vdW50CQAETAAAAAIJAQAAABVPcGVyYXRpb25IaXN0b3J5RW50cnkAAAAFAgAAAAVzdGFrZQUAAAAOdXNlckFkZHJlc3NTdHIFAAAADGxwQXNzZXRJZFN0cgUAAAAGYW1vdW50CAUAAAABaQAAAA10cmFuc2FjdGlvbklkBQAAAANuaWwFAAAADWludGVncmFsU1RBVEUAAAABaQEAAAAHdW5zdGFrZQAAAAIAAAAMbHBBc3NldElkU3RyAAAABmFtb3VudAQAAAAJbHBBc3NldElkCQACWQAAAAEFAAAADGxwQXNzZXRJZFN0cgQAAAAOcG9vbEFkZHJlc3NTdHIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAA9mYWN0b3J5Q29udHJhY3QJAQAAABprZXlGYWN0b3J5THAyQXNzZXRzTWFwcGluZwAAAAEFAAAADGxwQXNzZXRJZFN0cgkAASwAAAACAgAAABV1bnN1cHBvcnRlZCBscCBhc3NldCAFAAAADGxwQXNzZXRJZFN0cgQAAAAJcG9vbEFkZG9uCQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMJAQAAABZrZXlTdGFibGVQb29sQWRkb25BZGRyAAAAAAUAAAAOcG9vbEFkZHJlc3NTdHIEAAAACWNhbGxlclN0cgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAADnVzZXJBZGRyZXNzU3RyAwMJAAAAAAAAAgUAAAAJY2FsbGVyU3RyBQAAAA5wb29sQWRkcmVzc1N0cgYJAAAAAAAAAgUAAAAJY2FsbGVyU3RyBQAAAAlwb29sQWRkb24JAAQlAAAAAQgFAAAAAWkAAAAMb3JpZ2luQ2FsbGVyBQAAAAljYWxsZXJTdHIEAAAAD3N0YWtlZEJ5VXNlcktFWQkBAAAAD2tleVN0YWtlZEJ5VXNlcgAAAAIFAAAADnVzZXJBZGRyZXNzU3RyBQAAAAxscEFzc2V0SWRTdHIEAAAADnN0YWtlZFRvdGFsS0VZCQEAAAAOa2V5U3Rha2VkVG90YWwAAAABBQAAAAxscEFzc2V0SWRTdHIEAAAADHN0YWtlZEJ5VXNlcgkBAAAACnJlYWRTdGFrZWQAAAABBQAAAA9zdGFrZWRCeVVzZXJLRVkEAAAAC3N0YWtlZFRvdGFsCQEAAAAKcmVhZFN0YWtlZAAAAAEFAAAADnN0YWtlZFRvdGFsS0VZBAAAAA0kdDAxNzE5MTE3MzA5CQEAAAAQcmVmcmVzaElOVEVHUkFMUwAAAAQFAAAADGxwQXNzZXRJZFN0cgUAAAAOdXNlckFkZHJlc3NTdHIFAAAADnBvb2xBZGRyZXNzU3RyCQEAAAABLQAAAAEFAAAABmFtb3VudAQAAAAQd3hUb0NsYWltVXNlck5ldwgFAAAADSR0MDE3MTkxMTczMDkAAAACXzEEAAAADWludGVncmFsU1RBVEUIBQAAAA0kdDAxNzE5MTE3MzA5AAAAAl8yBAAAAAVkZWJ1ZwgFAAAADSR0MDE3MTkxMTczMDkAAAACXzMDCQAAZgAAAAIFAAAABmFtb3VudAUAAAAMc3Rha2VkQnlVc2VyCQAAAgAAAAECAAAAJHBhc3NlZCBhbW91bnQgaXMgbGVzcyB0aGVuIGF2YWlsYWJsZQkABE4AAAACCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAA9zdGFrZWRCeVVzZXJLRVkJAABlAAAAAgUAAAAMc3Rha2VkQnlVc2VyBQAAAAZhbW91bnQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAADnN0YWtlZFRvdGFsS0VZCQAAZQAAAAIFAAAAC3N0YWtlZFRvdGFsBQAAAAZhbW91bnQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAZhbW91bnQFAAAACWxwQXNzZXRJZAkABEwAAAACCQEAAAAVT3BlcmF0aW9uSGlzdG9yeUVudHJ5AAAABQIAAAAHdW5zdGFrZQUAAAAOdXNlckFkZHJlc3NTdHIFAAAADGxwQXNzZXRJZFN0cgUAAAAGYW1vdW50CAUAAAABaQAAAA10cmFuc2FjdGlvbklkBQAAAANuaWwFAAAADWludGVncmFsU1RBVEUAAAABaQEAAAAHY2xhaW1XeAAAAAEAAAAMbHBBc3NldElkU3RyBAAAAAt1c2VyQWRkcmVzcwgFAAAAAWkAAAAGY2FsbGVyBAAAAA51c2VyQWRkcmVzc1N0cgkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAADnBvb2xBZGRyZXNzU3RyCQEAAAAYZ2V0U3RyaW5nQnlBZGRyZXNzT3JGYWlsAAAAAgUAAAAPZmFjdG9yeUNvbnRyYWN0CQEAAAAma2V5RmFjdG9yeUxwQXNzZXRUb1Bvb2xDb250cmFjdEFkZHJlc3MAAAABBQAAAAxscEFzc2V0SWRTdHIEAAAAEGNsYWltZWRCeVVzZXJLRVkJAQAAABBrZXlDbGFpbWVkQnlVc2VyAAAAAgUAAAAMbHBBc3NldElkU3RyBQAAAA51c2VyQWRkcmVzc1N0cgQAAAAPY2xhaW1lZFRvdGFsS0VZCQEAAAAPa2V5Q2xhaW1lZFRvdGFsAAAAAQUAAAAMbHBBc3NldElkU3RyBAAAABljbGFpbWVkQnlVc2VyTWluUmV3YXJkS0VZCQEAAAAZa2V5Q2xhaW1lZEJ5VXNlck1pblJld2FyZAAAAAIFAAAADGxwQXNzZXRJZFN0cgUAAAAOdXNlckFkZHJlc3NTdHIEAAAAG2NsYWltZWRCeVVzZXJCb29zdFJld2FyZEtFWQkBAAAAG2tleUNsYWltZWRCeVVzZXJCb29zdFJld2FyZAAAAAIFAAAADGxwQXNzZXRJZFN0cgUAAAAOdXNlckFkZHJlc3NTdHIEAAAADWNsYWltZWRCeVVzZXIJAQAAABlnZXRCaWdJbnRGcm9tU3RyaW5nT3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAQY2xhaW1lZEJ5VXNlcktFWQQAAAAWY2xhaW1lZEJ5VXNlck1pblJld2FyZAkBAAAAGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8AAAACBQAAAAR0aGlzBQAAABljbGFpbWVkQnlVc2VyTWluUmV3YXJkS0VZBAAAABhjbGFpbWVkQnlVc2VyQm9vc3RSZXdhcmQJAQAAABlnZXRCaWdJbnRGcm9tU3RyaW5nT3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAbY2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkS0VZBAAAAAxjbGFpbWVkVG90YWwJAQAAABlnZXRCaWdJbnRGcm9tU3RyaW5nT3JaZXJvAAAAAgUAAAAEdGhpcwUAAAAPY2xhaW1lZFRvdGFsS0VZBAAAAA0kdDAxODU1MzE4NjY1CQEAAAAQcmVmcmVzaElOVEVHUkFMUwAAAAQFAAAADGxwQXNzZXRJZFN0cgUAAAAOdXNlckFkZHJlc3NTdHIFAAAADnBvb2xBZGRyZXNzU3RyAAAAAAAAAAAABAAAABB3eFRvQ2xhaW1Vc2VyTmV3CAUAAAANJHQwMTg1NTMxODY2NQAAAAJfMQQAAAANaW50ZWdyYWxTVEFURQgFAAAADSR0MDE4NTUzMTg2NjUAAAACXzIEAAAABWRlYnVnCAUAAAANJHQwMTg1NTMxODY2NQAAAAJfMwQAAAAQYXZhaWxhYmxlVG9DbGFpbQkAAZgAAAABCQAETAAAAAIJAAE4AAAAAgUAAAAQd3hUb0NsYWltVXNlck5ldwUAAAANY2xhaW1lZEJ5VXNlcgkABEwAAAACBQAAAAp6ZXJvQmlnSW50BQAAAANuaWwDCQABQAAAAAIFAAAACnplcm9CaWdJbnQFAAAAEGF2YWlsYWJsZVRvQ2xhaW0JAAACAAAAAQIAAAAQbm90aGluZyB0byBjbGFpbQQAAAASd3hBbW91bnRCb29zdFRvdGFsCQABlgAAAAEJAARMAAAAAgkBAAAABWFzSW50AAAAAQkAAZEAAAACCQEAAAAJYXNBbnlMaXN0AAAAAQkAA/wAAAAEBQAAABBib29zdGluZ0NvbnRyYWN0AgAAAAxjbGFpbVd4Qm9vc3QJAARMAAAAAgUAAAAMbHBBc3NldElkU3RyCQAETAAAAAIFAAAADnVzZXJBZGRyZXNzU3RyBQAAAANuaWwFAAAAA25pbAAAAAAAAAAAAAkABEwAAAACAAAAAAAAAAAABQAAAANuaWwEAAAADW1pblJld2FyZFBhcnQFAAAAEGF2YWlsYWJsZVRvQ2xhaW0EAAAAD2Jvb3N0UmV3YXJkUGFydAkAAZkAAAABCQAETAAAAAIJAAE5AAAAAgUAAAANbWluUmV3YXJkUGFydAkAATYAAAABAAAAAAAAAAACCQAETAAAAAIJAAE2AAAAAQUAAAASd3hBbW91bnRCb29zdFRvdGFsBQAAAANuaWwEAAAACXd4QXNzZXRJZAkBAAAADGFzQnl0ZVZlY3RvcgAAAAEJAAGRAAAAAgkBAAAACWFzQW55TGlzdAAAAAEJAAP8AAAABAUAAAAQZW1pc3Npb25Db250cmFjdAIAAAAEZW1pdAkABEwAAAACCQABoAAAAAEFAAAADW1pblJld2FyZFBhcnQFAAAAA25pbAUAAAADbmlsAAAAAAAAAAAABAAAAAllbWl0Qm9vc3QJAQAAAAlhc0FueUxpc3QAAAABCQAD/AAAAAQFAAAAEGVtaXNzaW9uQ29udHJhY3QCAAAABGVtaXQJAARMAAAAAgkAAaAAAAABBQAAAA9ib29zdFJld2FyZFBhcnQFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAAAllbWl0Qm9vc3QFAAAACWVtaXRCb29zdAQAAAASY2xhaW1lZEJ5VXNlclZhbHVlCQABNwAAAAIFAAAADWNsYWltZWRCeVVzZXIFAAAAEGF2YWlsYWJsZVRvQ2xhaW0EAAAAHmNsYWltZWRCeVVzZXJNaW5SZXdhcmRQbHVzUGFydAkAATcAAAACBQAAABZjbGFpbWVkQnlVc2VyTWluUmV3YXJkBQAAAA1taW5SZXdhcmRQYXJ0BAAAACtjbGFpbWVkQnlVc2VyQm9vc3RSZXdhcmRQbHVzQm9vc3RSZXdhcmRQYXJ0CQABNwAAAAIFAAAAFmNsYWltZWRCeVVzZXJNaW5SZXdhcmQFAAAADW1pblJld2FyZFBhcnQEAAAAIGNsYWltZWRUb3RhbFBsdXNBdmFpbGFibGVUb0NsYWltCQABNwAAAAIFAAAAFmNsYWltZWRCeVVzZXJNaW5SZXdhcmQFAAAADW1pblJld2FyZFBhcnQJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAQY2xhaW1lZEJ5VXNlcktFWQkAAaYAAAABBQAAABJjbGFpbWVkQnlVc2VyVmFsdWUJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAZY2xhaW1lZEJ5VXNlck1pblJld2FyZEtFWQkAAaYAAAABBQAAAB5jbGFpbWVkQnlVc2VyTWluUmV3YXJkUGx1c1BhcnQJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAbY2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkS0VZCQABpgAAAAEFAAAAK2NsYWltZWRCeVVzZXJCb29zdFJld2FyZFBsdXNCb29zdFJld2FyZFBhcnQJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAPY2xhaW1lZFRvdGFsS0VZCQABpgAAAAEFAAAAIGNsYWltZWRUb3RhbFBsdXNBdmFpbGFibGVUb0NsYWltCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMFAAAAC3VzZXJBZGRyZXNzCQABoAAAAAEFAAAADW1pblJld2FyZFBhcnQFAAAACXd4QXNzZXRJZAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAAt1c2VyQWRkcmVzcwkAAaAAAAABBQAAAA9ib29zdFJld2FyZFBhcnQFAAAACXd4QXNzZXRJZAkABEwAAAACCQEAAAAVT3BlcmF0aW9uSGlzdG9yeUVudHJ5AAAABQIAAAAFY2xhaW0FAAAADnVzZXJBZGRyZXNzU3RyBQAAAAxscEFzc2V0SWRTdHIJAAGgAAAAAQUAAAAQYXZhaWxhYmxlVG9DbGFpbQgFAAAAAWkAAAANdHJhbnNhY3Rpb25JZAUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAA9jbGFpbVd4UkVBRE9OTFkAAAACAAAADGxwQXNzZXRJZFN0cgAAAA51c2VyQWRkcmVzc1N0cgQAAAAPc3Rha2VkQnlVc2VyS0VZCQEAAAAPa2V5U3Rha2VkQnlVc2VyAAAAAgUAAAAOdXNlckFkZHJlc3NTdHIFAAAADGxwQXNzZXRJZFN0cgQAAAAOc3Rha2VkVG90YWxLRVkJAQAAAA5rZXlTdGFrZWRUb3RhbAAAAAEFAAAADGxwQXNzZXRJZFN0cgQAAAAQY2xhaW1lZEJ5VXNlcktFWQkBAAAAEGtleUNsYWltZWRCeVVzZXIAAAACBQAAAAxscEFzc2V0SWRTdHIFAAAADnVzZXJBZGRyZXNzU3RyBAAAAAxzdGFrZWRCeVVzZXIJAQAAAApyZWFkU3Rha2VkAAAAAQUAAAAPc3Rha2VkQnlVc2VyS0VZBAAAAAtzdGFrZWRUb3RhbAkBAAAACnJlYWRTdGFrZWQAAAABBQAAAA5zdGFrZWRUb3RhbEtFWQQAAAANY2xhaW1lZEJ5VXNlcgkBAAAAGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8AAAACBQAAAAR0aGlzBQAAABBjbGFpbWVkQnlVc2VyS0VZBAAAAA5wb29sQWRkcmVzc1N0cgkBAAAAGGdldFN0cmluZ0J5QWRkcmVzc09yRmFpbAAAAAIFAAAAD2ZhY3RvcnlDb250cmFjdAkBAAAAJmtleUZhY3RvcnlMcEFzc2V0VG9Qb29sQ29udHJhY3RBZGRyZXNzAAAAAQUAAAAMbHBBc3NldElkU3RyBAAAAApwb29sV2VpZ2h0CQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAA9mYWN0b3J5Q29udHJhY3QJAQAAABRrZXlGYWN0b3J5UG9vbFdlaWdodAAAAAEFAAAADnBvb2xBZGRyZXNzU3RyBAAAABJ3eEVtaXNzaW9uUGVyQmxvY2sJAQAAAAxnZXRJbnRPckZhaWwAAAACBQAAABBlbWlzc2lvbkNvbnRyYWN0CQEAAAAea2V5RW1pc3Npb25SYXRlUGVyQmxvY2tDdXJyZW50AAAAAAQAAAASZW1pc3Npb25TdGFydEJsb2NrCQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAQZW1pc3Npb25Db250cmFjdAkBAAAAFWtleUVtaXNzaW9uU3RhcnRCbG9jawAAAAAEAAAADHBhc3NlZEJsb2NrcwMJAABmAAAAAgUAAAASZW1pc3Npb25TdGFydEJsb2NrBQAAAAZoZWlnaHQAAAAAAAAAAAAJAABlAAAAAgUAAAAGaGVpZ2h0BQAAABJlbWlzc2lvblN0YXJ0QmxvY2sEAAAADnBvb2xXeEVtaXNzaW9uCQAAawAAAAMJAABoAAAAAgUAAAASd3hFbWlzc2lvblBlckJsb2NrBQAAAAxwYXNzZWRCbG9ja3MFAAAACnBvb2xXZWlnaHQFAAAADlBPT0xXRUlHSFRNVUxUBAAAAAx1c2VyV3hSZXdhcmQJAABrAAAAAwUAAAAOcG9vbFd4RW1pc3Npb24FAAAADHN0YWtlZEJ5VXNlcgUAAAALc3Rha2VkVG90YWwEAAAADSR0MDIxMzA3MjE0MTkJAQAAABByZWZyZXNoSU5URUdSQUxTAAAABAUAAAAMbHBBc3NldElkU3RyBQAAAA51c2VyQWRkcmVzc1N0cgUAAAAOcG9vbEFkZHJlc3NTdHIAAAAAAAAAAAAEAAAAEHd4VG9DbGFpbVVzZXJOZXcIBQAAAA0kdDAyMTMwNzIxNDE5AAAAAl8xBAAAAA1pbnRlZ3JhbFNUQVRFCAUAAAANJHQwMjEzMDcyMTQxOQAAAAJfMgQAAAAFZGVidWcIBQAAAA0kdDAyMTMwNzIxNDE5AAAAAl8zBAAAABBhdmFpbGFibGVUb0NsYWltCQABmAAAAAEJAARMAAAAAgkAATgAAAACBQAAABB3eFRvQ2xhaW1Vc2VyTmV3BQAAAA1jbGFpbWVkQnlVc2VyCQAETAAAAAIFAAAACnplcm9CaWdJbnQFAAAAA25pbAQAAAAOYm9vc3RJbnZSZXN1bHQJAQAAAAlhc0FueUxpc3QAAAABCQAD/AAAAAQFAAAAEGJvb3N0aW5nQ29udHJhY3QCAAAAFGNsYWltV3hCb29zdFJFQURPTkxZCQAETAAAAAIFAAAADGxwQXNzZXRJZFN0cgkABEwAAAACBQAAAA51c2VyQWRkcmVzc1N0cgUAAAADbmlsBQAAAANuaWwEAAAAEnd4QW1vdW50Qm9vc3RUb3RhbAkAAZYAAAABCQAETAAAAAIJAQAAAAVhc0ludAAAAAEJAAGRAAAAAgUAAAAOYm9vc3RJbnZSZXN1bHQAAAAAAAAAAAAJAARMAAAAAgAAAAAAAAAAAAUAAAADbmlsBAAAAApib29zdERlYnVnCQEAAAAIYXNTdHJpbmcAAAABCQABkQAAAAIFAAAADmJvb3N0SW52UmVzdWx0AAAAAAAAAAABBAAAAA1taW5SZXdhcmRQYXJ0BQAAABBhdmFpbGFibGVUb0NsYWltBAAAAA9ib29zdFJld2FyZFBhcnQJAAGZAAAAAQkABEwAAAACCQABOQAAAAIFAAAADW1pblJld2FyZFBhcnQJAAE2AAAAAQAAAAAAAAAAAgkABEwAAAACCQABNgAAAAEFAAAAEnd4QW1vdW50Qm9vc3RUb3RhbAUAAAADbmlsBAAAAAt0b3RhbFJld2FyZAkAATcAAAACBQAAAA1taW5SZXdhcmRQYXJ0BQAAAA9ib29zdFJld2FyZFBhcnQJAAUUAAAAAgUAAAADbmlsCQAEuQAAAAIJAARMAAAAAgIAAAAOJXMlcyVkJWQlZCVkJXMJAARMAAAAAgUAAAAMbHBBc3NldElkU3RyCQAETAAAAAIFAAAADnVzZXJBZGRyZXNzU3RyCQAETAAAAAIJAAGmAAAAAQUAAAALdG90YWxSZXdhcmQJAARMAAAAAgkAAaYAAAABBQAAAA1jbGFpbWVkQnlVc2VyCQAETAAAAAIJAAGmAAAAAQUAAAANbWluUmV3YXJkUGFydAkABEwAAAACCQABpgAAAAEFAAAAD2Jvb3N0UmV3YXJkUGFydAkABEwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIFAAAABWRlYnVnAgAAAAI6OgkAAaQAAAABBQAAAAx1c2VyV3hSZXdhcmQCAAAADjo6Qk9PU1RERUJVRzo6BQAAAApib29zdERlYnVnBQAAAANuaWwFAAAAA1NFUAAAAAFpAQAAAA5vbk1vZGlmeVdlaWdodAAAAAIAAAAMbHBBc3NldElkU3RyAAAADnBvb2xBZGRyZXNzU3RyAwkBAAAAAiE9AAAAAggFAAAAAWkAAAAGY2FsbGVyBQAAAA9mYWN0b3J5Q29udHJhY3QJAAACAAAAAQIAAAAScGVybWlzc2lvbnMgZGVuaWVkBAAAAA0kdDAyMjM1MDIyNDYwCQEAAAAUcmVmcmVzaFBvb2xJTlRFR1JBTFMAAAADBQAAAAxscEFzc2V0SWRTdHIFAAAADnBvb2xBZGRyZXNzU3RyAAAAAAAAAAAABAAAABJ3eFBlckxwSW50ZWdyYWxOZXcIBQAAAA0kdDAyMjM1MDIyNDYwAAAAAl8xBAAAABFwb29sSW50ZWdyYWxTVEFURQgFAAAADSR0MDIyMzUwMjI0NjAAAAACXzIEAAAACXBvb2xERUJVRwgFAAAADSR0MDIyMzUwMjI0NjAAAAACXzMFAAAAEXBvb2xJbnRlZ3JhbFNUQVRFAAAAAQAAAAJ0eAEAAAAGdmVyaWZ5AAAAAAQAAAAPdGFyZ2V0UHVibGljS2V5BAAAAAckbWF0Y2gwCQEAAAAWbWFuYWdlclB1YmxpY0tleU9yVW5pdAAAAAADCQAAAQAAAAIFAAAAByRtYXRjaDACAAAACkJ5dGVWZWN0b3IEAAAAAnBrBQAAAAckbWF0Y2gwBQAAAAJwawMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAEVW5pdAgFAAAAAnR4AAAAD3NlbmRlclB1YmxpY0tleQkAAAIAAAABAgAAAAtNYXRjaCBlcnJvcgkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAFAAAAD3RhcmdldFB1YmxpY0tleRBufU8=", "chainId": 87, "height": 3185025, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: HFrEovcdgHTCxW6uFaRgBnMqAPY7pBonkfdgoizMRMCc Next: 3dUnFm6Be3sbGAyqh3cUmsUs55oo1nCsWhmDsQD6xzwc Diff:
OldNewDifferences
104104
105105
106106 func keyManagerPublicKey () = "%s__managerPublicKey"
107-
108-
109-func keyMigratorPublicKey () = "%s__migratorPublicKey"
110107
111108
112109 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
283280
284281
285282 func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
286- let $t01150611628 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
287- let wxPerLpIntegralNew = $t01150611628._1
288- let poolIntegralSTATE = $t01150611628._2
289- let poolDEBUG = $t01150611628._3
283+ let $t01142111543 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
284+ let wxPerLpIntegralNew = $t01142111543._1
285+ let poolIntegralSTATE = $t01142111543._2
286+ let poolDEBUG = $t01142111543._3
290287 let MULT3 = 1000
291288 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
292289 let stakedByUser = readStaked(stakedByUserKEY)
306303
307304
308305 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
309- case s: String =>
310- fromBase58String(s)
311- case _: Unit =>
312- unit
313- case _ =>
314- throw("Match error")
315-}
316-
317-
318-func migratorPublicKeyOrUnit () = match getString(keyMigratorPublicKey()) {
319306 case s: String =>
320307 fromBase58String(s)
321308 case _: Unit =>
398385
399386
400387 @Callable(i)
401-func stake () = {
402- let offError = throw("off")
403- if ((offError == offError))
404- then if ((size(i.payments) != 1))
405- then throw("invalid payment - exact one payment must be attached")
406- else {
407- let pmt = i.payments[0]
408- let lpAssetId = value(pmt.assetId)
409- let lpAssetIdStr = toBase58String(lpAssetId)
410- let amount = pmt.amount
411- let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
412- let callerStr = toString(i.caller)
413- let userAddressStr = if ((callerStr == poolAddressStr))
414- then toString(i.originCaller)
415- else callerStr
416- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
417- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
418- let stakedByUser = readStaked(stakedByUserKEY)
419- let stakedTotal = readStaked(stakedTotalKEY)
420- let $t01623016347 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
421- let wxToClaimUserNew = $t01623016347._1
422- let integralSTATE = $t01623016347._2
423- let debug = $t01623016347._3
424- ([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE)
425- }
426- else throw("Strict value is not equal to itself.")
427- }
388+func stake () = if ((size(i.payments) != 1))
389+ then throw("invalid payment - exact one payment must be attached")
390+ else {
391+ let pmt = i.payments[0]
392+ let lpAssetId = value(pmt.assetId)
393+ let lpAssetIdStr = toBase58String(lpAssetId)
394+ let amount = pmt.amount
395+ let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
396+ let callerStr = toString(i.caller)
397+ let userAddressStr = if ((callerStr == poolAddressStr))
398+ then toString(i.originCaller)
399+ else callerStr
400+ let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
401+ let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
402+ let stakedByUser = readStaked(stakedByUserKEY)
403+ let stakedTotal = readStaked(stakedTotalKEY)
404+ let $t01593716054 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
405+ let wxToClaimUserNew = $t01593716054._1
406+ let integralSTATE = $t01593716054._2
407+ let debug = $t01593716054._3
408+ ([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE)
409+ }
428410
429411
430412
431413 @Callable(i)
432414 func unstake (lpAssetIdStr,amount) = {
433- let offError = throw("off")
434- if ((offError == offError))
435- then {
436- let lpAssetId = fromBase58String(lpAssetIdStr)
437- let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
438- let poolAddon = valueOrElse(getString(this, keyStablePoolAddonAddr()), poolAddressStr)
439- let callerStr = toString(i.caller)
440- let userAddressStr = if (if ((callerStr == poolAddressStr))
441- then true
442- else (callerStr == poolAddon))
443- then toString(i.originCaller)
444- else callerStr
445- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
446- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
447- let stakedByUser = readStaked(stakedByUserKEY)
448- let stakedTotal = readStaked(stakedTotalKEY)
449- let $t01751817636 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))
450- let wxToClaimUserNew = $t01751817636._1
451- let integralSTATE = $t01751817636._2
452- let debug = $t01751817636._3
453- if ((amount > stakedByUser))
454- then throw("passed amount is less then available")
455- else ([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE)
456- }
457- else throw("Strict value is not equal to itself.")
415+ let lpAssetId = fromBase58String(lpAssetIdStr)
416+ let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
417+ let poolAddon = valueOrElse(getString(this, keyStablePoolAddonAddr()), poolAddressStr)
418+ let callerStr = toString(i.caller)
419+ let userAddressStr = if (if ((callerStr == poolAddressStr))
420+ then true
421+ else (callerStr == poolAddon))
422+ then toString(i.originCaller)
423+ else callerStr
424+ let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
425+ let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
426+ let stakedByUser = readStaked(stakedByUserKEY)
427+ let stakedTotal = readStaked(stakedTotalKEY)
428+ let $t01719117309 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))
429+ let wxToClaimUserNew = $t01719117309._1
430+ let integralSTATE = $t01719117309._2
431+ let debug = $t01719117309._3
432+ if ((amount > stakedByUser))
433+ then throw("passed amount is less then available")
434+ else ([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE)
458435 }
459436
460437
461438
462439 @Callable(i)
463440 func claimWx (lpAssetIdStr) = {
464- let offError = throw("off")
465- if ((offError == offError))
466- then {
467- let userAddress = i.caller
468- let userAddressStr = toString(i.caller)
469- let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
470- let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
471- let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr)
472- let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
473- let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr)
474- let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
475- let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
476- let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
477- let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
478- let $t01891419026 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
479- let wxToClaimUserNew = $t01891419026._1
480- let integralSTATE = $t01891419026._2
481- let debug = $t01891419026._3
482- let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt])
483- if ((zeroBigInt >= availableToClaim))
484- then throw("nothing to claim")
485- else {
486- let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
487- let minRewardPart = availableToClaim
488- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
489- let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
490- let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
491- if ((emitBoost == emitBoost))
492- then {
493- let claimedByUserValue = (claimedByUser + availableToClaim)
494- let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
495- let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserMinReward + minRewardPart)
496- let claimedTotalPlusAvailableToClaim = (claimedByUserMinReward + minRewardPart)
441+ let userAddress = i.caller
442+ let userAddressStr = toString(i.caller)
443+ let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
444+ let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
445+ let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr)
446+ let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
447+ let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr)
448+ let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
449+ let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
450+ let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
451+ let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
452+ let $t01855318665 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
453+ let wxToClaimUserNew = $t01855318665._1
454+ let integralSTATE = $t01855318665._2
455+ let debug = $t01855318665._3
456+ let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt])
457+ if ((zeroBigInt >= availableToClaim))
458+ then throw("nothing to claim")
459+ else {
460+ let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
461+ let minRewardPart = availableToClaim
462+ let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
463+ let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
464+ let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
465+ if ((emitBoost == emitBoost))
466+ then {
467+ let claimedByUserValue = (claimedByUser + availableToClaim)
468+ let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
469+ let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserMinReward + minRewardPart)
470+ let claimedTotalPlusAvailableToClaim = (claimedByUserMinReward + minRewardPart)
497471 [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)]
498- }
499- else throw("Strict value is not equal to itself.")
500472 }
473+ else throw("Strict value is not equal to itself.")
501474 }
502- else throw("Strict value is not equal to itself.")
503475 }
504476
505477
506478
507479 @Callable(i)
508480 func claimWxREADONLY (lpAssetIdStr,userAddressStr) = {
509- let offError = throw("off")
510- if ((offError == offError))
511- then {
512- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
513- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
514- let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
515- let stakedByUser = readStaked(stakedByUserKEY)
516- let stakedTotal = readStaked(stakedTotalKEY)
517- let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
518- let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
519- let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
520- let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
521- let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
522- let passedBlocks = if ((emissionStartBlock > height))
523- then 0
524- else (height - emissionStartBlock)
525- let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
526- let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
527- let $t02170221814 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
528- let wxToClaimUserNew = $t02170221814._1
529- let integralSTATE = $t02170221814._2
530- let debug = $t02170221814._3
531- let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt])
532- let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
533- let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
534- let boostDebug = asString(boostInvResult[1])
535- let minRewardPart = availableToClaim
536- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
537- let totalReward = (minRewardPart + boostRewardPart)
538- $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), ((((debug + "::") + toString(userWxReward)) + "::BOOSTDEBUG::") + boostDebug)], SEP))
539- }
540- else throw("Strict value is not equal to itself.")
481+ let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
482+ let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
483+ let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
484+ let stakedByUser = readStaked(stakedByUserKEY)
485+ let stakedTotal = readStaked(stakedTotalKEY)
486+ let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
487+ let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
488+ let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
489+ let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
490+ let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
491+ let passedBlocks = if ((emissionStartBlock > height))
492+ then 0
493+ else (height - emissionStartBlock)
494+ let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
495+ let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
496+ let $t02130721419 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
497+ let wxToClaimUserNew = $t02130721419._1
498+ let integralSTATE = $t02130721419._2
499+ let debug = $t02130721419._3
500+ let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt])
501+ let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
502+ let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
503+ let boostDebug = asString(boostInvResult[1])
504+ let minRewardPart = availableToClaim
505+ let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
506+ let totalReward = (minRewardPart + boostRewardPart)
507+ $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), ((((debug + "::") + toString(userWxReward)) + "::BOOSTDEBUG::") + boostDebug)], SEP))
541508 }
542509
543510
546513 func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
547514 then throw("permissions denied")
548515 else {
549- let $t02274522855 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
550- let wxPerLpIntegralNew = $t02274522855._1
551- let poolIntegralSTATE = $t02274522855._2
552- let poolDEBUG = $t02274522855._3
516+ let $t02235022460 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
517+ let wxPerLpIntegralNew = $t02235022460._1
518+ let poolIntegralSTATE = $t02235022460._2
519+ let poolDEBUG = $t02235022460._3
553520 poolIntegralSTATE
554521 }
555522
564531 case _ =>
565532 throw("Match error")
566533 }
567- let migratorPublicKey = match migratorPublicKeyOrUnit() {
568- case pk: ByteVector =>
569- pk
570- case _: Unit =>
571- tx.senderPublicKey
572- case _ =>
573- throw("Match error")
574- }
575- if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
576- then true
577- else sigVerify(tx.bodyBytes, tx.proofs[0], migratorPublicKey)
534+ sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
578535 }
579536
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
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)
1919
2020 func asAnyList (val) = match val {
2121 case valAnyLyst: List[Any] =>
2222 valAnyLyst
2323 case _ =>
2424 throw("fail to cast into List[Any]")
2525 }
2626
2727
2828 func asInt (val) = match val {
2929 case valInt: Int =>
3030 valInt
3131 case _ =>
3232 throw("fail to cast into Int")
3333 }
3434
3535
3636 func asString (val) = match val {
3737 case valStr: String =>
3838 valStr
3939 case _ =>
4040 throw("fail to cast into Int")
4141 }
4242
4343
4444 func asByteVector (val) = match val {
4545 case valBin: ByteVector =>
4646 valBin
4747 case _ =>
4848 throw("fail to cast into Int")
4949 }
5050
5151
5252 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined"))
5353
5454
5555 func getStringByAddressOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
5656
5757
5858 func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
5959
6060
6161 func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
6262
6363
6464 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
6565
6666
6767 func getBigIntFromStringOrZero (address,key) = value(parseBigInt(valueOrElse(getString(address, key), "0")))
6868
6969
7070 func getBigIntFromStringOrDefault (address,key,defaultVal) = match getString(address, key) {
7171 case s: String =>
7272 value(parseBigInt(s))
7373 case _: Unit =>
7474 defaultVal
7575 case _ =>
7676 throw("Match error")
7777 }
7878
7979
8080 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULT18, toBigInt(origScaleMult))
8181
8282
8383 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULT18))
8484
8585
8686 func keyFactoryAddress () = "%s%s__config__factoryAddress"
8787
8888
8989 let IdxFactoryCfgStakingDapp = 1
9090
9191 let IdxFactoryCfgBoostingDapp = 2
9292
9393 let IdxFactoryCfgIdoDapp = 3
9494
9595 let IdxFactoryCfgTeamDapp = 4
9696
9797 let IdxFactoryCfgEmissionDapp = 5
9898
9999 let IdxFactoryCfgRestDapp = 6
100100
101101 let IdxFactoryCfgSlippageDapp = 7
102102
103103 func keyFactoryCfg () = "%s__factoryConfig"
104104
105105
106106 func keyManagerPublicKey () = "%s__managerPublicKey"
107-
108-
109-func keyMigratorPublicKey () = "%s__migratorPublicKey"
110107
111108
112109 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
113110
114111
115112 func keyStablePoolAddonAddr () = "%s__stablePoolAddonAddr"
116113
117114
118115 func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
119116
120117
121118 func keyFactoryLpList () = "%s__lpTokensList"
122119
123120
124121 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
125122
126123
127124 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
128125
129126
130127 func readLpList (factory) = split(valueOrElse(getString(factory, keyFactoryLpList()), ""), SEP)
131128
132129
133130 func readFactoryCfgOrFail (factory) = split(getStringByAddressOrFail(factory, keyFactoryCfg()), SEP)
134131
135132
136133 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
137134
138135
139136 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
140137
141138
142139 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
143140
144141
145142 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
146143
147144
148145 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
149146
150147
151148 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
152149
153150
154151 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
155152
156153
157154 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
158155
159156
160157 func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s__staked", userAddressStr, lpAssetIdStr], SEP)
161158
162159
163160 func keyStakedTotal (lpAssetIdStr) = ("%s%s%s__staked__total__" + lpAssetIdStr)
164161
165162
166163 func keyClaimedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimed", userAddressStr, lpAssetIdStr], SEP)
167164
168165
169166 func keyClaimedByUserMinReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedMinReward", userAddressStr, lpAssetIdStr], SEP)
170167
171168
172169 func keyClaimedByUserBoostReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedBoostReward", userAddressStr, lpAssetIdStr], SEP)
173170
174171
175172 func keyClaimedTotal (lpAssetIdStr) = makeString(["%s%s%s__claimed__total", lpAssetIdStr], SEP)
176173
177174
178175 func readStaked (key) = valueOrElse(getInteger(this, key), 0)
179176
180177
181178 func keyLastTotalLpBalance (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "bal"], SEP)
182179
183180
184181 func keyLastUserLpBalance (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "bal"], SEP)
185182
186183
187184 func keyTotalLpBalanceIntegral (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "balINT"], SEP)
188185
189186
190187 func keyUserLpBalanceIntegral (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "balINT"], SEP)
191188
192189
193190 func keyTotalLpBalanceIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "lastUpd"], SEP)
194191
195192
196193 func keyUserLpBalanceIntegralLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "lastUpd"], SEP)
197194
198195
199196 func keyWxPerLpIntegral (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpInt"], SEP)
200197
201198
202199 func keyWxPerLpIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpIntH"], SEP)
203200
204201
205202 func keyWxToClaimUser (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpInt"], SEP)
206203
207204
208205 func keyWxPerLpIntegralUserLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpIntH"], SEP)
209206
210207
211208 func keyWxPerLp (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLp"], SEP)
212209
213210
214211 func keyWxPerLpX18 (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLpX18"], SEP)
215212
216213
217214 func keyWxPerLpIntegralUserLast (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "uIntL"], SEP)
218215
219216
220217 func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
221218
222219
223220 func formatHistoryRecord (userAddress,lpAssetId,type,amount) = makeString(["%s%s%s%d%d%d", userAddress, lpAssetId, type, toString(height), toString(lastBlock.timestamp), toString(amount)], SEP)
224221
225222
226223 func OperationHistoryEntry (type,userAddress,lpAssetId,amount,txId) = StringEntry(keyOperationHistoryRecord(type, userAddress, toBase58String(txId)), formatHistoryRecord(userAddress, lpAssetId, type, amount))
227224
228225
229226 let factoryAddress = getStringOrFail(this, keyFactoryAddress())
230227
231228 let factoryContract = addressFromStringValue(factoryAddress)
232229
233230 let factoryCfg = readFactoryCfgOrFail(factoryContract)
234231
235232 let emissionContract = getEmissionAddressOrFail(factoryCfg)
236233
237234 let boostingContract = getBoostingAddressOrFail(factoryCfg)
238235
239236 func calcWxPerLpIntegralUserLast (stakedByUser,wxPerLpIntegralUserLastUpdHeightOrZero,wxPerLpIntegralNew,wxPerLpIntegralUserLastKEY) = if (if ((wxPerLpIntegralUserLastUpdHeightOrZero == zeroBigInt))
240237 then (stakedByUser > zeroBigInt)
241238 else false)
242239 then zeroBigInt
243240 else if ((stakedByUser == zeroBigInt))
244241 then wxPerLpIntegralNew
245242 else if (if ((wxPerLpIntegralUserLastUpdHeightOrZero > zeroBigInt))
246243 then (stakedByUser > zeroBigInt)
247244 else false)
248245 then value(parseBigInt(getStringOrFail(this, wxPerLpIntegralUserLastKEY)))
249246 else throw("calcWxPerLpIntegralUserLast: unexpected state")
250247
251248
252249 func refreshPoolINTEGRALS (lpAssetIdStr,poolAddressStr,lpDeltaAmount) = {
253250 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
254251 let stakedTotal = toBigInt(readStaked(stakedTotalKEY))
255252 let nonZeroStakedTotal = if ((stakedTotal == zeroBigInt))
256253 then oneBigInt
257254 else stakedTotal
258255 let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
259256 let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
260257 let MULT3 = 1000
261258 let wxEmissionPerBlockX3 = (getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) * MULT3)
262259 let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * 3))
263260 let wxPerLpIntegralKEY = keyWxPerLpIntegral(lpAssetIdStr)
264261 let wxPerLpIntegralLastUpdHeightKEY = keyWxPerLpIntegralLastUpdHeight(lpAssetIdStr)
265262 let wxPerLpKEY = keyWxPerLp(lpAssetIdStr)
266263 let wxPerLpIntegralLastUpdHeight = getIntOrDefault(this, wxPerLpIntegralLastUpdHeightKEY, emissionStartBlock)
267264 let wxPerLpIntegral = getBigIntFromStringOrZero(this, wxPerLpIntegralKEY)
268265 let wxPerLpOrZeroX3 = 0
269266 let dh = max([(height - wxPerLpIntegralLastUpdHeight), 0])
270267 let wxPerLpX3 = if ((wxPerLpOrZeroX3 != 0))
271268 then toBigInt(wxPerLpOrZeroX3)
272269 else fraction(toBigInt(poolWxEmissionPerBlockX3), toBigInt(MULT8), nonZeroStakedTotal)
273270 let stakedTotalNew = (stakedTotal + toBigInt(lpDeltaAmount))
274271 let nonZeroStakedTotalNew = if ((stakedTotalNew == zeroBigInt))
275272 then oneBigInt
276273 else stakedTotalNew
277274 let wxPerLpIntegralNew = (wxPerLpIntegral + (wxPerLpX3 * toBigInt(dh)))
278275 let wxPerLpX3New = (toBigInt(poolWxEmissionPerBlockX3) / nonZeroStakedTotalNew)
279276 let wxPerLpIntegralLastUpdHeightNew = height
280277 let debug = makeString([toString(wxPerLpIntegralNew), "dh=", toString(dh), "wxPerLpX3=", toString(wxPerLpX3), "stakedTotal=", toString(stakedTotal), toString(poolWxEmissionPerBlockX3), toString(wxEmissionPerBlockX3), "poolWeight=", toString(poolWeight)], "::")
281278 $Tuple3(wxPerLpIntegralNew, [StringEntry(wxPerLpIntegralKEY, toString(wxPerLpIntegralNew)), IntegerEntry(wxPerLpIntegralLastUpdHeightKEY, wxPerLpIntegralLastUpdHeightNew), StringEntry(wxPerLpKEY, toString(wxPerLpX3New))], debug)
282279 }
283280
284281
285282 func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
286- let $t01150611628 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
287- let wxPerLpIntegralNew = $t01150611628._1
288- let poolIntegralSTATE = $t01150611628._2
289- let poolDEBUG = $t01150611628._3
283+ let $t01142111543 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
284+ let wxPerLpIntegralNew = $t01142111543._1
285+ let poolIntegralSTATE = $t01142111543._2
286+ let poolDEBUG = $t01142111543._3
290287 let MULT3 = 1000
291288 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
292289 let stakedByUser = readStaked(stakedByUserKEY)
293290 let wxToClaimUserKEY = keyWxToClaimUser(lpAssetIdStr, userAddressStr)
294291 let wxPerLpIntegralUserLastUpdHeightKEY = keyWxPerLpIntegralUserLastUpdHeight(lpAssetIdStr, userAddressStr)
295292 let wxPerLpIntegralUserLastKEY = keyWxPerLpIntegralUserLast(lpAssetIdStr, userAddressStr)
296293 let wxToClaimUser = getBigIntFromStringOrZero(this, wxToClaimUserKEY)
297294 let wxPerLpIntegralUserLastUpdHeightOrZero = getIntOrZero(this, wxPerLpIntegralUserLastUpdHeightKEY)
298295 let wxPerLpIntegralUserLast = calcWxPerLpIntegralUserLast(toBigInt(stakedByUser), toBigInt(wxPerLpIntegralUserLastUpdHeightOrZero), wxPerLpIntegralNew, wxPerLpIntegralUserLastKEY)
299296 let MULT11 = (MULT8 * MULT3)
300297 let wxToClaimUserNew = max([(wxToClaimUser + fraction((wxPerLpIntegralNew - wxPerLpIntegralUserLast), toBigInt(stakedByUser), toBigInt(MULT11))), zeroBigInt])
301298 let wxPerLpIntegralUserLastNew = wxPerLpIntegralNew
302299 let wxPerLpIntegralUserLastUpdHeightNew = height
303300 let debug = makeString(["wxToClaimUser", toString(wxToClaimUser), "wxPerLpInteg", toString(wxPerLpIntegralUserLastUpdHeightOrZero), "this.getString", toString(value(parseBigInt(getStringOrFail(this, wxPerLpIntegralUserLastKEY)))), "wxPerLpIntegralNew", toString(wxPerLpIntegralNew), "wxToClaimUserNew", toString(wxToClaimUserNew), "wxPerLpIntegralUserLast", toString(wxPerLpIntegralUserLast), toString(stakedByUser), "poolDEBUG=", poolDEBUG, "height=", toString(height)], "::")
304301 $Tuple3(wxToClaimUserNew, (poolIntegralSTATE ++ [StringEntry(wxToClaimUserKEY, toString(wxToClaimUserNew)), IntegerEntry(wxPerLpIntegralUserLastUpdHeightKEY, wxPerLpIntegralUserLastUpdHeightNew), StringEntry(wxPerLpIntegralUserLastKEY, toString(wxPerLpIntegralUserLastNew))]), debug)
305302 }
306303
307304
308305 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
309- case s: String =>
310- fromBase58String(s)
311- case _: Unit =>
312- unit
313- case _ =>
314- throw("Match error")
315-}
316-
317-
318-func migratorPublicKeyOrUnit () = match getString(keyMigratorPublicKey()) {
319306 case s: String =>
320307 fromBase58String(s)
321308 case _: Unit =>
322309 unit
323310 case _ =>
324311 throw("Match error")
325312 }
326313
327314
328315 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
329316 case s: String =>
330317 fromBase58String(s)
331318 case _: Unit =>
332319 unit
333320 case _ =>
334321 throw("Match error")
335322 }
336323
337324
338325 func mustManager (i) = {
339326 let pd = throw("Permission denied")
340327 match managerPublicKeyOrUnit() {
341328 case pk: ByteVector =>
342329 if ((i.callerPublicKey == pk))
343330 then true
344331 else pd
345332 case _: Unit =>
346333 if ((i.caller == this))
347334 then true
348335 else pd
349336 case _ =>
350337 throw("Match error")
351338 }
352339 }
353340
354341
355342 @Callable(i)
356343 func constructor (factoryAddressStr) = {
357344 let checkCaller = mustManager(i)
358345 if ((checkCaller == checkCaller))
359346 then [StringEntry(keyFactoryAddress(), factoryAddressStr)]
360347 else throw("Strict value is not equal to itself.")
361348 }
362349
363350
364351
365352 @Callable(i)
366353 func setManager (pendingManagerPublicKey) = {
367354 let checkCaller = mustManager(i)
368355 if ((checkCaller == checkCaller))
369356 then {
370357 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
371358 if ((checkManagerPublicKey == checkManagerPublicKey))
372359 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
373360 else throw("Strict value is not equal to itself.")
374361 }
375362 else throw("Strict value is not equal to itself.")
376363 }
377364
378365
379366
380367 @Callable(i)
381368 func confirmManager () = {
382369 let pm = pendingManagerPublicKeyOrUnit()
383370 let hasPM = if (isDefined(pm))
384371 then true
385372 else throw("No pending manager")
386373 if ((hasPM == hasPM))
387374 then {
388375 let checkPM = if ((i.callerPublicKey == value(pm)))
389376 then true
390377 else throw("You are not pending manager")
391378 if ((checkPM == checkPM))
392379 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
393380 else throw("Strict value is not equal to itself.")
394381 }
395382 else throw("Strict value is not equal to itself.")
396383 }
397384
398385
399386
400387 @Callable(i)
401-func stake () = {
402- let offError = throw("off")
403- if ((offError == offError))
404- then if ((size(i.payments) != 1))
405- then throw("invalid payment - exact one payment must be attached")
406- else {
407- let pmt = i.payments[0]
408- let lpAssetId = value(pmt.assetId)
409- let lpAssetIdStr = toBase58String(lpAssetId)
410- let amount = pmt.amount
411- let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
412- let callerStr = toString(i.caller)
413- let userAddressStr = if ((callerStr == poolAddressStr))
414- then toString(i.originCaller)
415- else callerStr
416- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
417- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
418- let stakedByUser = readStaked(stakedByUserKEY)
419- let stakedTotal = readStaked(stakedTotalKEY)
420- let $t01623016347 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
421- let wxToClaimUserNew = $t01623016347._1
422- let integralSTATE = $t01623016347._2
423- let debug = $t01623016347._3
424- ([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE)
425- }
426- else throw("Strict value is not equal to itself.")
427- }
388+func stake () = if ((size(i.payments) != 1))
389+ then throw("invalid payment - exact one payment must be attached")
390+ else {
391+ let pmt = i.payments[0]
392+ let lpAssetId = value(pmt.assetId)
393+ let lpAssetIdStr = toBase58String(lpAssetId)
394+ let amount = pmt.amount
395+ let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
396+ let callerStr = toString(i.caller)
397+ let userAddressStr = if ((callerStr == poolAddressStr))
398+ then toString(i.originCaller)
399+ else callerStr
400+ let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
401+ let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
402+ let stakedByUser = readStaked(stakedByUserKEY)
403+ let stakedTotal = readStaked(stakedTotalKEY)
404+ let $t01593716054 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
405+ let wxToClaimUserNew = $t01593716054._1
406+ let integralSTATE = $t01593716054._2
407+ let debug = $t01593716054._3
408+ ([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE)
409+ }
428410
429411
430412
431413 @Callable(i)
432414 func unstake (lpAssetIdStr,amount) = {
433- let offError = throw("off")
434- if ((offError == offError))
435- then {
436- let lpAssetId = fromBase58String(lpAssetIdStr)
437- let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
438- let poolAddon = valueOrElse(getString(this, keyStablePoolAddonAddr()), poolAddressStr)
439- let callerStr = toString(i.caller)
440- let userAddressStr = if (if ((callerStr == poolAddressStr))
441- then true
442- else (callerStr == poolAddon))
443- then toString(i.originCaller)
444- else callerStr
445- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
446- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
447- let stakedByUser = readStaked(stakedByUserKEY)
448- let stakedTotal = readStaked(stakedTotalKEY)
449- let $t01751817636 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))
450- let wxToClaimUserNew = $t01751817636._1
451- let integralSTATE = $t01751817636._2
452- let debug = $t01751817636._3
453- if ((amount > stakedByUser))
454- then throw("passed amount is less then available")
455- else ([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE)
456- }
457- else throw("Strict value is not equal to itself.")
415+ let lpAssetId = fromBase58String(lpAssetIdStr)
416+ let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
417+ let poolAddon = valueOrElse(getString(this, keyStablePoolAddonAddr()), poolAddressStr)
418+ let callerStr = toString(i.caller)
419+ let userAddressStr = if (if ((callerStr == poolAddressStr))
420+ then true
421+ else (callerStr == poolAddon))
422+ then toString(i.originCaller)
423+ else callerStr
424+ let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
425+ let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
426+ let stakedByUser = readStaked(stakedByUserKEY)
427+ let stakedTotal = readStaked(stakedTotalKEY)
428+ let $t01719117309 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))
429+ let wxToClaimUserNew = $t01719117309._1
430+ let integralSTATE = $t01719117309._2
431+ let debug = $t01719117309._3
432+ if ((amount > stakedByUser))
433+ then throw("passed amount is less then available")
434+ else ([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE)
458435 }
459436
460437
461438
462439 @Callable(i)
463440 func claimWx (lpAssetIdStr) = {
464- let offError = throw("off")
465- if ((offError == offError))
466- then {
467- let userAddress = i.caller
468- let userAddressStr = toString(i.caller)
469- let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
470- let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
471- let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr)
472- let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
473- let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr)
474- let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
475- let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
476- let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
477- let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
478- let $t01891419026 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
479- let wxToClaimUserNew = $t01891419026._1
480- let integralSTATE = $t01891419026._2
481- let debug = $t01891419026._3
482- let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt])
483- if ((zeroBigInt >= availableToClaim))
484- then throw("nothing to claim")
485- else {
486- let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
487- let minRewardPart = availableToClaim
488- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
489- let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
490- let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
491- if ((emitBoost == emitBoost))
492- then {
493- let claimedByUserValue = (claimedByUser + availableToClaim)
494- let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
495- let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserMinReward + minRewardPart)
496- let claimedTotalPlusAvailableToClaim = (claimedByUserMinReward + minRewardPart)
441+ let userAddress = i.caller
442+ let userAddressStr = toString(i.caller)
443+ let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
444+ let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
445+ let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr)
446+ let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
447+ let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr)
448+ let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
449+ let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
450+ let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
451+ let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
452+ let $t01855318665 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
453+ let wxToClaimUserNew = $t01855318665._1
454+ let integralSTATE = $t01855318665._2
455+ let debug = $t01855318665._3
456+ let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt])
457+ if ((zeroBigInt >= availableToClaim))
458+ then throw("nothing to claim")
459+ else {
460+ let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
461+ let minRewardPart = availableToClaim
462+ let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
463+ let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
464+ let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
465+ if ((emitBoost == emitBoost))
466+ then {
467+ let claimedByUserValue = (claimedByUser + availableToClaim)
468+ let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
469+ let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserMinReward + minRewardPart)
470+ let claimedTotalPlusAvailableToClaim = (claimedByUserMinReward + minRewardPart)
497471 [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)]
498- }
499- else throw("Strict value is not equal to itself.")
500472 }
473+ else throw("Strict value is not equal to itself.")
501474 }
502- else throw("Strict value is not equal to itself.")
503475 }
504476
505477
506478
507479 @Callable(i)
508480 func claimWxREADONLY (lpAssetIdStr,userAddressStr) = {
509- let offError = throw("off")
510- if ((offError == offError))
511- then {
512- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
513- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
514- let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
515- let stakedByUser = readStaked(stakedByUserKEY)
516- let stakedTotal = readStaked(stakedTotalKEY)
517- let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
518- let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
519- let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
520- let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
521- let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
522- let passedBlocks = if ((emissionStartBlock > height))
523- then 0
524- else (height - emissionStartBlock)
525- let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
526- let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
527- let $t02170221814 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
528- let wxToClaimUserNew = $t02170221814._1
529- let integralSTATE = $t02170221814._2
530- let debug = $t02170221814._3
531- let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt])
532- let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
533- let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
534- let boostDebug = asString(boostInvResult[1])
535- let minRewardPart = availableToClaim
536- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
537- let totalReward = (minRewardPart + boostRewardPart)
538- $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), ((((debug + "::") + toString(userWxReward)) + "::BOOSTDEBUG::") + boostDebug)], SEP))
539- }
540- else throw("Strict value is not equal to itself.")
481+ let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
482+ let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
483+ let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
484+ let stakedByUser = readStaked(stakedByUserKEY)
485+ let stakedTotal = readStaked(stakedTotalKEY)
486+ let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
487+ let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
488+ let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
489+ let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
490+ let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
491+ let passedBlocks = if ((emissionStartBlock > height))
492+ then 0
493+ else (height - emissionStartBlock)
494+ let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
495+ let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
496+ let $t02130721419 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
497+ let wxToClaimUserNew = $t02130721419._1
498+ let integralSTATE = $t02130721419._2
499+ let debug = $t02130721419._3
500+ let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt])
501+ let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
502+ let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
503+ let boostDebug = asString(boostInvResult[1])
504+ let minRewardPart = availableToClaim
505+ let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
506+ let totalReward = (minRewardPart + boostRewardPart)
507+ $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), ((((debug + "::") + toString(userWxReward)) + "::BOOSTDEBUG::") + boostDebug)], SEP))
541508 }
542509
543510
544511
545512 @Callable(i)
546513 func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
547514 then throw("permissions denied")
548515 else {
549- let $t02274522855 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
550- let wxPerLpIntegralNew = $t02274522855._1
551- let poolIntegralSTATE = $t02274522855._2
552- let poolDEBUG = $t02274522855._3
516+ let $t02235022460 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
517+ let wxPerLpIntegralNew = $t02235022460._1
518+ let poolIntegralSTATE = $t02235022460._2
519+ let poolDEBUG = $t02235022460._3
553520 poolIntegralSTATE
554521 }
555522
556523
557524 @Verifier(tx)
558525 func verify () = {
559526 let targetPublicKey = match managerPublicKeyOrUnit() {
560527 case pk: ByteVector =>
561528 pk
562529 case _: Unit =>
563530 tx.senderPublicKey
564531 case _ =>
565532 throw("Match error")
566533 }
567- let migratorPublicKey = match migratorPublicKeyOrUnit() {
568- case pk: ByteVector =>
569- pk
570- case _: Unit =>
571- tx.senderPublicKey
572- case _ =>
573- throw("Match error")
574- }
575- if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey))
576- then true
577- else sigVerify(tx.bodyBytes, tx.proofs[0], migratorPublicKey)
534+ sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
578535 }
579536

github/deemru/w8io/786bc32 
73.76 ms