tx · H87544fHsuWtHfMTkAcvjmHjVj3YR1yzkAXphGrUPbQt

3PPNhHYkkEy13gRWDCaruQyhNbX2GrjYSyV:  -0.03200000 Waves

2023.03.07 13:09 [3545027] smart account 3PPNhHYkkEy13gRWDCaruQyhNbX2GrjYSyV > SELF 0.00000000 Waves

{ "type": 13, "id": "H87544fHsuWtHfMTkAcvjmHjVj3YR1yzkAXphGrUPbQt", "fee": 3200000, "feeAssetId": null, "timestamp": 1678183777186, "version": 2, "chainId": 87, "sender": "3PPNhHYkkEy13gRWDCaruQyhNbX2GrjYSyV", "senderPublicKey": "EAtbDa63mS5omrvW7Pfr7DKWEVLuReJtu72vfiBLRXsx", "proofs": [ "5MSJkpjF2VqwQwcFtj23sUkiSnxunhs9sD7Lg7S5PoM3Adud9txLi5YqqUQgQQSzuQhqdztQNCyYi5Qe44p2F5CV" ], "script": "base64:BgJZCAISAwoBCBIDCgEIEgMKAQgSABIAEgQKAggBEgYKBAIBAgISAwoBCBIDCgEIEgUKAwgIBBIGCgQBGAgYEgQKAhgIEgQKAggIEgQKAggIEgMKAQgSBAoCCAhiAAZTQ0FMRTgACAAFTVVMVDgAgMLXLwAHU0NBTEUxOAASAAZNVUxUMTgJALYCAQCAgJC7utat8A0AA1NFUAICX18ADlBPT0xXRUlHSFRNVUxUBQVNVUxUOAAKemVyb0JpZ0ludAkAtgIBAAAACW9uZUJpZ0ludAkAtgIBAAEBB3dyYXBFcnIBA21zZwkAuQkCCQDMCAICDXN0YWtpbmcucmlkZToJAMwIAgkApQgBBQR0aGlzCQDMCAIFA21zZwUDbmlsAgEgAQh0aHJvd0VycgEDbXNnCQACAQkBB3dyYXBFcnIBBQNtc2cBCWFzQW55TGlzdAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIJTGlzdFtBbnldBAp2YWxBbnlMeXN0BQckbWF0Y2gwBQp2YWxBbnlMeXN0CQACAQIbZmFpbCB0byBjYXN0IGludG8gTGlzdFtBbnldAQVhc0ludAEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIDSW50BAZ2YWxJbnQFByRtYXRjaDAFBnZhbEludAkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEIYXNTdHJpbmcBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACBlN0cmluZwQGdmFsU3RyBQckbWF0Y2gwBQZ2YWxTdHIJAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBDGFzQnl0ZVZlY3RvcgEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQGdmFsQmluBQckbWF0Y2gwBQZ2YWxCaW4JAAIBAhVmYWlsIHRvIGNhc3QgaW50byBJbnQBD2dldFN0cmluZ09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4FA2tleQIPIGlzIG5vdCBkZWZpbmVkARhnZXRTdHJpbmdCeUFkZHJlc3NPckZhaWwCB2FkZHJlc3MDa2V5CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUHYWRkcmVzcwUDa2V5CQCsAgIJAKwCAgkArAICCQCsAgICCm1hbmRhdG9yeSAJAKUIAQUHYWRkcmVzcwIBLgUDa2V5Ag8gaXMgbm90IGRlZmluZWQBDGdldEludE9yWmVybwIHYWRkcmVzcwNrZXkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUHYWRkcmVzcwUDa2V5AAABD2dldEludE9yRGVmYXVsdAMHYWRkcmVzcwNrZXkKZGVmYXVsdFZhbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQdhZGRyZXNzBQNrZXkFCmRlZmF1bHRWYWwBDGdldEludE9yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQdhZGRyZXNzBQNrZXkJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4FA2tleQIPIGlzIG5vdCBkZWZpbmVkARlnZXRCaWdJbnRGcm9tU3RyaW5nT3JaZXJvAgdhZGRyZXNzA2tleQkBBXZhbHVlAQkAqAMBCQELdmFsdWVPckVsc2UCCQCdCAIFB2FkZHJlc3MFA2tleQIBMAEcZ2V0QmlnSW50RnJvbVN0cmluZ09yRGVmYXVsdAMHYWRkcmVzcwNrZXkKZGVmYXVsdFZhbAQHJG1hdGNoMAkAnQgCBQdhZGRyZXNzBQNrZXkDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQEFdmFsdWUBCQCoAwEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUKZGVmYXVsdFZhbAkAAgECC01hdGNoIGVycm9yAQV0b1gxOAIHb3JpZ1ZhbA1vcmlnU2NhbGVNdWx0CQC8AgMJALYCAQUHb3JpZ1ZhbAUGTVVMVDE4CQC2AgEFDW9yaWdTY2FsZU11bHQBB2Zyb21YMTgCA3ZhbA9yZXN1bHRTY2FsZU11bHQJAKADAQkAvAIDBQN2YWwJALYCAQUPcmVzdWx0U2NhbGVNdWx0BQZNVUxUMTgBEWtleUZhY3RvcnlBZGRyZXNzAAIcJXMlc19fY29uZmlnX19mYWN0b3J5QWRkcmVzcwEZa2V5Vm90aW5nRW1pc3Npb25Db250cmFjdAACGiVzX192b3RpbmdFbWlzc2lvbkNvbnRyYWN0ABhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHAAAQAZSWR4RmFjdG9yeUNmZ0Jvb3N0aW5nRGFwcAACABRJZHhGYWN0b3J5Q2ZnSWRvRGFwcAADABVJZHhGYWN0b3J5Q2ZnVGVhbURhcHAABAAZSWR4RmFjdG9yeUNmZ0VtaXNzaW9uRGFwcAAFABVJZHhGYWN0b3J5Q2ZnUmVzdERhcHAABgAZSWR4RmFjdG9yeUNmZ1NsaXBwYWdlRGFwcAAHAQ1rZXlGYWN0b3J5Q2ZnAAIRJXNfX2ZhY3RvcnlDb25maWcBE2tleU1hbmFnZXJQdWJsaWNLZXkAAhQlc19fbWFuYWdlclB1YmxpY0tleQEaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkAAhslc19fcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkBFmtleVN0YWJsZVBvb2xBZGRvbkFkZHIAAhclc19fc3RhYmxlUG9vbEFkZG9uQWRkcgEMa2V5QWRkb25BZGRyAAINJXNfX2FkZG9uQWRkcgEaa2V5RmFjdG9yeUxwMkFzc2V0c01hcHBpbmcBCmxwQXNzZXRTdHIJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUKbHBBc3NldFN0cgkAzAgCAh5tYXBwaW5nc19fbHBBc3NldDJQb29sQ29udHJhY3QFA25pbAUDU0VQARBrZXlGYWN0b3J5THBMaXN0AAIQJXNfX2xwVG9rZW5zTGlzdAEma2V5RmFjdG9yeUxwQXNzZXRUb1Bvb2xDb250cmFjdEFkZHJlc3MBCmxwQXNzZXRTdHIJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUKbHBBc3NldFN0cgkAzAgCAh5tYXBwaW5nc19fbHBBc3NldDJQb29sQ29udHJhY3QFA25pbAUDU0VQARRrZXlGYWN0b3J5UG9vbFdlaWdodAEPY29udHJhY3RBZGRyZXNzCQC5CQIJAMwIAgIEJXMlcwkAzAgCAgpwb29sV2VpZ2h0CQDMCAIFD2NvbnRyYWN0QWRkcmVzcwUDbmlsBQNTRVABCnJlYWRMcExpc3QBB2ZhY3RvcnkJALUJAgkBC3ZhbHVlT3JFbHNlAgkAnQgCBQdmYWN0b3J5CQEQa2V5RmFjdG9yeUxwTGlzdAACAAUDU0VQARRyZWFkRmFjdG9yeUNmZ09yRmFpbAEHZmFjdG9yeQkAtQkCCQEYZ2V0U3RyaW5nQnlBZGRyZXNzT3JGYWlsAgUHZmFjdG9yeQkBDWtleUZhY3RvcnlDZmcABQNTRVABGGdldEJvb3N0aW5nQWRkcmVzc09yRmFpbAEKZmFjdG9yeUNmZwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQpmYWN0b3J5Q2ZnBRlJZHhGYWN0b3J5Q2ZnQm9vc3RpbmdEYXBwARhnZXRFbWlzc2lvbkFkZHJlc3NPckZhaWwBCmZhY3RvcnlDZmcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUKZmFjdG9yeUNmZwUZSWR4RmFjdG9yeUNmZ0VtaXNzaW9uRGFwcAEXZ2V0U3Rha2luZ0FkZHJlc3NPckZhaWwBCmZhY3RvcnlDZmcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUKZmFjdG9yeUNmZwUYSWR4RmFjdG9yeUNmZ1N0YWtpbmdEYXBwAR5rZXlFbWlzc2lvblJhdGVQZXJCbG9ja0N1cnJlbnQAAhslcyVzX19yYXRlUGVyQmxvY2tfX2N1cnJlbnQBIWtleUVtaXNzaW9uUmF0ZVBlckJsb2NrTWF4Q3VycmVudAACHiVzJXNfX3JhdGVQZXJCbG9ja01heF9fY3VycmVudAEVa2V5RW1pc3Npb25TdGFydEJsb2NrAAIaJXMlc19fZW1pc3Npb25fX3N0YXJ0QmxvY2sBG2tleUVtaXNzaW9uRHVyYXRpb25JbkJsb2NrcwACGCVzJXNfX2VtaXNzaW9uX19kdXJhdGlvbgETa2V5RW1pc3Npb25FbmRCbG9jawACGCVzJXNfX2VtaXNzaW9uX19lbmRCbG9jawEPa2V5U3Rha2VkQnlVc2VyAg51c2VyQWRkcmVzc1N0cgxscEFzc2V0SWRTdHIJALkJAgkAzAgCAg4lcyVzJXNfX3N0YWtlZAkAzAgCBQ51c2VyQWRkcmVzc1N0cgkAzAgCBQxscEFzc2V0SWRTdHIFA25pbAUDU0VQAQ5rZXlTdGFrZWRUb3RhbAEMbHBBc3NldElkU3RyCQCsAgICFyVzJXMlc19fc3Rha2VkX190b3RhbF9fBQxscEFzc2V0SWRTdHIBEGtleUNsYWltZWRCeVVzZXICDGxwQXNzZXRJZFN0cg51c2VyQWRkcmVzc1N0cgkAuQkCCQDMCAICDyVzJXMlc19fY2xhaW1lZAkAzAgCBQ51c2VyQWRkcmVzc1N0cgkAzAgCBQxscEFzc2V0SWRTdHIFA25pbAUDU0VQARlrZXlDbGFpbWVkQnlVc2VyTWluUmV3YXJkAgxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIJALkJAgkAzAgCAhglcyVzJXNfX2NsYWltZWRNaW5SZXdhcmQJAMwIAgUOdXNlckFkZHJlc3NTdHIJAMwIAgUMbHBBc3NldElkU3RyBQNuaWwFA1NFUAEba2V5Q2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkAgxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIJALkJAgkAzAgCAholcyVzJXNfX2NsYWltZWRCb29zdFJld2FyZAkAzAgCBQ51c2VyQWRkcmVzc1N0cgkAzAgCBQxscEFzc2V0SWRTdHIFA25pbAUDU0VQAQ9rZXlDbGFpbWVkVG90YWwBDGxwQXNzZXRJZFN0cgkAuQkCCQDMCAICFiVzJXMlc19fY2xhaW1lZF9fdG90YWwJAMwIAgUMbHBBc3NldElkU3RyBQNuaWwFA1NFUAEKcmVhZFN0YWtlZAEDa2V5CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFA2tleQAAARVrZXlMYXN0VG90YWxMcEJhbGFuY2UBCWxwQXNzZXRJZAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQlscEFzc2V0SWQJAMwIAgIFdG90YWwJAMwIAgIDYmFsBQNuaWwFA1NFUAEUa2V5TGFzdFVzZXJMcEJhbGFuY2UCCWxwQXNzZXRJZAt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQlscEFzc2V0SWQJAMwIAgULdXNlckFkZHJlc3MJAMwIAgIDYmFsBQNuaWwFA1NFUAEZa2V5VG90YWxMcEJhbGFuY2VJbnRlZ3JhbAEJbHBBc3NldElkCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCAgV0b3RhbAkAzAgCAgZiYWxJTlQFA25pbAUDU0VQARhrZXlVc2VyTHBCYWxhbmNlSW50ZWdyYWwCCWxwQXNzZXRJZAt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQlscEFzc2V0SWQJAMwIAgULdXNlckFkZHJlc3MJAMwIAgIGYmFsSU5UBQNuaWwFA1NFUAEma2V5VG90YWxMcEJhbGFuY2VJbnRlZ3JhbExhc3RVcGRIZWlnaHQBCWxwQXNzZXRJZAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQlscEFzc2V0SWQJAMwIAgIFdG90YWwJAMwIAgIHbGFzdFVwZAUDbmlsBQNTRVABJWtleVVzZXJMcEJhbGFuY2VJbnRlZ3JhbExhc3RVcGRIZWlnaHQCCWxwQXNzZXRJZAt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQlscEFzc2V0SWQJAMwIAgULdXNlckFkZHJlc3MJAMwIAgIHbGFzdFVwZAUDbmlsBQNTRVABEmtleVd4UGVyTHBJbnRlZ3JhbAEJbHBBc3NldElkCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgUJbHBBc3NldElkCQDMCAICBmNvbW1vbgkAzAgCAgVscEludAUDbmlsBQNTRVABH2tleVd4UGVyTHBJbnRlZ3JhbExhc3RVcGRIZWlnaHQBCWxwQXNzZXRJZAkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCAgZjb21tb24JAMwIAgIGbHBJbnRIBQNuaWwFA1NFUAEQa2V5V3hUb0NsYWltVXNlcgIJbHBBc3NldElkC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgUJbHBBc3NldElkCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAICBWxwSW50BQNuaWwFA1NFUAEja2V5V3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHQCCWxwQXNzZXRJZAt1c2VyQWRkcmVzcwkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCAgZscEludEgFA25pbAUDU0VQAQprZXlXeFBlckxwAQlscEFzc2V0SWQJALkJAgkAzAgCAgIlcwkAzAgCBQlscEFzc2V0SWQJAMwIAgIHd3hQZXJMcAUDbmlsBQNTRVABDWtleVd4UGVyTHBYMTgBCWxwQXNzZXRJZAkAuQkCCQDMCAICAiVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCAgp3eFBlckxwWDE4BQNuaWwFA1NFUAEaa2V5V3hQZXJMcEludGVncmFsVXNlckxhc3QCCWxwQXNzZXRJZAt1c2VyQWRkcmVzcwkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCAgV1SW50TAUDbmlsBQNTRVABGWtleU9wZXJhdGlvbkhpc3RvcnlSZWNvcmQDBHR5cGULdXNlckFkZHJlc3MGdHhJZDU4CQC5CQIJAMwIAgIRJXMlcyVzJXNfX2hpc3RvcnkJAMwIAgUEdHlwZQkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCBQZ0eElkNTgFA25pbAUDU0VQARNmb3JtYXRIaXN0b3J5UmVjb3JkBAt1c2VyQWRkcmVzcwlscEFzc2V0SWQEdHlwZQZhbW91bnQJALkJAgkAzAgCAgwlcyVzJXMlZCVkJWQJAMwIAgULdXNlckFkZHJlc3MJAMwIAgUJbHBBc3NldElkCQDMCAIFBHR5cGUJAMwIAgkApAMBBQZoZWlnaHQJAMwIAgkApAMBCAUJbGFzdEJsb2NrCXRpbWVzdGFtcAkAzAgCCQCkAwEFBmFtb3VudAUDbmlsBQNTRVABFU9wZXJhdGlvbkhpc3RvcnlFbnRyeQUEdHlwZQt1c2VyQWRkcmVzcwlscEFzc2V0SWQGYW1vdW50BHR4SWQJAQtTdHJpbmdFbnRyeQIJARlrZXlPcGVyYXRpb25IaXN0b3J5UmVjb3JkAwUEdHlwZQULdXNlckFkZHJlc3MJANgEAQUEdHhJZAkBE2Zvcm1hdEhpc3RvcnlSZWNvcmQEBQt1c2VyQWRkcmVzcwUJbHBBc3NldElkBQR0eXBlBQZhbW91bnQADmZhY3RvcnlBZGRyZXNzCQEPZ2V0U3RyaW5nT3JGYWlsAgUEdGhpcwkBEWtleUZhY3RvcnlBZGRyZXNzAAAPZmFjdG9yeUNvbnRyYWN0CQERQGV4dHJOYXRpdmUoMTA2MikBBQ5mYWN0b3J5QWRkcmVzcwAKZmFjdG9yeUNmZwkBFHJlYWRGYWN0b3J5Q2ZnT3JGYWlsAQUPZmFjdG9yeUNvbnRyYWN0ABBlbWlzc2lvbkNvbnRyYWN0CQEYZ2V0RW1pc3Npb25BZGRyZXNzT3JGYWlsAQUKZmFjdG9yeUNmZwAQYm9vc3RpbmdDb250cmFjdAkBGGdldEJvb3N0aW5nQWRkcmVzc09yRmFpbAEFCmZhY3RvcnlDZmcAFmxwU3Rha2luZ1Bvb2xzQ29udHJhY3QJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKIIAQkAuQkCCQDMCAICAiVzCQDMCAICFmxwU3Rha2luZ1Bvb2xzQ29udHJhY3QFA25pbAUDU0VQCQEHd3JhcEVycgECLmxwX3N0YWtpbmdfcG9vbHMgY29udHJhY3QgYWRkcmVzcyBpcyB1bmRlZmluZWQJAQd3cmFwRXJyAQIpaW52YWxpZCBscF9zdGFraW5nX3Bvb2xzIGNvbnRyYWN0IGFkZHJlc3MBC2tleU5leHRVc2VyAQlscEFzc2V0SWQJALkJAgkAzAgCAgQlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCAghuZXh0VXNlcgUDbmlsBQNTRVABEGdldFVzZXJzTGlzdE5hbWUBCWxwQXNzZXRJZAkAuQkCCQDMCAICBXVzZXJzCQDMCAIFCWxwQXNzZXRJZAUDbmlsBQNTRVABC2tleUxpc3RIZWFkAQhsaXN0TmFtZQkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQhsaXN0TmFtZQkAzAgCAgRoZWFkBQNuaWwFA1NFUAELa2V5TGlzdFNpemUBCGxpc3ROYW1lCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCGxpc3ROYW1lCQDMCAICBHNpemUFA25pbAUDU0VQAQtrZXlMaXN0UHJldgIIbGlzdE5hbWUCaWQJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCBQhsaXN0TmFtZQkAzAgCBQJpZAkAzAgCAgRwcmV2BQNuaWwFA1NFUAELa2V5TGlzdE5leHQCCGxpc3ROYW1lAmlkCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgUIbGlzdE5hbWUJAMwIAgUCaWQJAMwIAgIEbmV4dAUDbmlsBQNTRVABDGNvbnRhaW5zTm9kZQIIbGlzdE5hbWUCaWQECmhlYWRPclVuaXQJAJ0IAgUEdGhpcwkBC2tleUxpc3RIZWFkAQUIbGlzdE5hbWUECnByZXZPclVuaXQJAJ0IAgUEdGhpcwkBC2tleUxpc3RQcmV2AgUIbGlzdE5hbWUFAmlkBApuZXh0T3JVbml0CQCdCAIFBHRoaXMJAQtrZXlMaXN0TmV4dAIFCGxpc3ROYW1lBQJpZAMDCQAAAgUCaWQJAQt2YWx1ZU9yRWxzZQIFCmhlYWRPclVuaXQCAAYJAQIhPQIFCnByZXZPclVuaXQFBHVuaXQGCQECIT0CBQpuZXh0T3JVbml0BQR1bml0ARFpbnNlcnROb2RlQWN0aW9ucwIIbGlzdE5hbWUCaWQECmhlYWRPclVuaXQJAJ0IAgUEdGhpcwkBC2tleUxpc3RIZWFkAQUIbGlzdE5hbWUECGxpc3RTaXplCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQtrZXlMaXN0U2l6ZQEFCGxpc3ROYW1lAAAECWNoZWNrTm9kZQMJAQEhAQkBDGNvbnRhaW5zTm9kZQIFCGxpc3ROYW1lBQJpZAYJAAIBAgtOb2RlIGV4aXN0cwMJAAACBQljaGVja05vZGUFCWNoZWNrTm9kZQkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQtrZXlMaXN0U2l6ZQEFCGxpc3ROYW1lCQBkAgUIbGlzdFNpemUAAQUDbmlsAwkBAiE9AgUKaGVhZE9yVW5pdAUEdW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQELa2V5TGlzdE5leHQCBQhsaXN0TmFtZQUCaWQJAQV2YWx1ZQEFCmhlYWRPclVuaXQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBC2tleUxpc3RQcmV2AgUIbGlzdE5hbWUJAQV2YWx1ZQEFCmhlYWRPclVuaXQFAmlkBQNuaWwFA25pbAkAzAgCCQELU3RyaW5nRW50cnkCCQELa2V5TGlzdEhlYWQBBQhsaXN0TmFtZQUCaWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgERZGVsZXRlTm9kZUFjdGlvbnMCCGxpc3ROYW1lAmlkBApoZWFkT3JVbml0CQCdCAIFBHRoaXMJAQtrZXlMaXN0SGVhZAEFCGxpc3ROYW1lBAhsaXN0U2l6ZQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQELa2V5TGlzdFNpemUBBQhsaXN0TmFtZQAABApwcmV2T3JVbml0CQCdCAIFBHRoaXMJAQtrZXlMaXN0UHJldgIFCGxpc3ROYW1lBQJpZAQKbmV4dE9yVW5pdAkAnQgCBQR0aGlzCQELa2V5TGlzdE5leHQCBQhsaXN0TmFtZQUCaWQJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBC2tleUxpc3RTaXplAQUIbGlzdE5hbWUJAGUCBQhsaXN0U2l6ZQABBQNuaWwDAwkBAiE9AgUKcHJldk9yVW5pdAUEdW5pdAkBAiE9AgUKbmV4dE9yVW5pdAUEdW5pdAcJAMwIAgkBC1N0cmluZ0VudHJ5AgkBC2tleUxpc3ROZXh0AgUIbGlzdE5hbWUJAQV2YWx1ZQEFCnByZXZPclVuaXQJAQV2YWx1ZQEFCm5leHRPclVuaXQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBC2tleUxpc3RQcmV2AgUIbGlzdE5hbWUJAQV2YWx1ZQEFCm5leHRPclVuaXQJAQV2YWx1ZQEFCnByZXZPclVuaXQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBC2tleUxpc3RQcmV2AgUIbGlzdE5hbWUFAmlkCQDMCAIJAQtEZWxldGVFbnRyeQEJAQtrZXlMaXN0TmV4dAIFCGxpc3ROYW1lBQJpZAUDbmlsAwkBAiE9AgUKbmV4dE9yVW5pdAUEdW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQELa2V5TGlzdEhlYWQBBQhsaXN0TmFtZQkBBXZhbHVlAQUKbmV4dE9yVW5pdAkAzAgCCQELRGVsZXRlRW50cnkBCQELa2V5TGlzdE5leHQCBQhsaXN0TmFtZQUCaWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBC2tleUxpc3RQcmV2AgUIbGlzdE5hbWUJAQV2YWx1ZQEFCm5leHRPclVuaXQFA25pbAMJAQIhPQIFCnByZXZPclVuaXQFBHVuaXQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBC2tleUxpc3RQcmV2AgUIbGlzdE5hbWUFAmlkCQDMCAIJAQtEZWxldGVFbnRyeQEJAQtrZXlMaXN0TmV4dAIFCGxpc3ROYW1lCQEFdmFsdWUBBQpwcmV2T3JVbml0BQNuaWwDCQAAAgUCaWQJAQt2YWx1ZU9yRWxzZQIFCmhlYWRPclVuaXQCAAkAzAgCCQELRGVsZXRlRW50cnkBCQELa2V5TGlzdEhlYWQBBQhsaXN0TmFtZQUDbmlsCQACAQkArAICCQCsAgIJAKwCAgIOaW52YWxpZCBub2RlOiAFCGxpc3ROYW1lAgEuBQJpZAEbY2FsY1d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0BAxzdGFrZWRCeVVzZXImd3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHRPclplcm8Sd3hQZXJMcEludGVncmFsTmV3Gnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0S0VZAwMJAAACBSZ3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE9yWmVybwUKemVyb0JpZ0ludAkAvwICBQxzdGFrZWRCeVVzZXIFCnplcm9CaWdJbnQHBQp6ZXJvQmlnSW50AwkAAAIFDHN0YWtlZEJ5VXNlcgUKemVyb0JpZ0ludAUSd3hQZXJMcEludGVncmFsTmV3AwMJAL8CAgUmd3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHRPclplcm8FCnplcm9CaWdJbnQJAL8CAgUMc3Rha2VkQnlVc2VyBQp6ZXJvQmlnSW50BwkBBXZhbHVlAQkAqAMBCQEPZ2V0U3RyaW5nT3JGYWlsAgUEdGhpcwUad3hQZXJMcEludGVncmFsVXNlckxhc3RLRVkJAAIBAi1jYWxjV3hQZXJMcEludGVncmFsVXNlckxhc3Q6IHVuZXhwZWN0ZWQgc3RhdGUBFHJlZnJlc2hQb29sSU5URUdSQUxTAwxscEFzc2V0SWRTdHIOcG9vbEFkZHJlc3NTdHINbHBEZWx0YUFtb3VudAQOc3Rha2VkVG90YWxLRVkJAQ5rZXlTdGFrZWRUb3RhbAEFDGxwQXNzZXRJZFN0cgQLc3Rha2VkVG90YWwJALYCAQkBCnJlYWRTdGFrZWQBBQ5zdGFrZWRUb3RhbEtFWQQSbm9uWmVyb1N0YWtlZFRvdGFsAwkAAAIFC3N0YWtlZFRvdGFsBQp6ZXJvQmlnSW50BQlvbmVCaWdJbnQFC3N0YWtlZFRvdGFsBApwb29sV2VpZ2h0CQERQGV4dHJOYXRpdmUoMTA1MCkCBQ9mYWN0b3J5Q29udHJhY3QJARRrZXlGYWN0b3J5UG9vbFdlaWdodAEFDnBvb2xBZGRyZXNzU3RyBBJlbWlzc2lvblN0YXJ0QmxvY2sJAQxnZXRJbnRPckZhaWwCBRBlbWlzc2lvbkNvbnRyYWN0CQEVa2V5RW1pc3Npb25TdGFydEJsb2NrAAQFTVVMVDMA6AcEFHd4RW1pc3Npb25QZXJCbG9ja1gzCQBoAgkBDGdldEludE9yRmFpbAIFEGVtaXNzaW9uQ29udHJhY3QJAR5rZXlFbWlzc2lvblJhdGVQZXJCbG9ja0N1cnJlbnQABQVNVUxUMwQYcG9vbFd4RW1pc3Npb25QZXJCbG9ja1gzCQBrAwUUd3hFbWlzc2lvblBlckJsb2NrWDMFCnBvb2xXZWlnaHQJAGgCBQ5QT09MV0VJR0hUTVVMVAADBBJ3eFBlckxwSW50ZWdyYWxLRVkJARJrZXlXeFBlckxwSW50ZWdyYWwBBQxscEFzc2V0SWRTdHIEH3d4UGVyTHBJbnRlZ3JhbExhc3RVcGRIZWlnaHRLRVkJAR9rZXlXeFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0AQUMbHBBc3NldElkU3RyBAp3eFBlckxwS0VZCQEKa2V5V3hQZXJMcAEFDGxwQXNzZXRJZFN0cgQcd3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodAkBD2dldEludE9yRGVmYXVsdAMFBHRoaXMFH3d4UGVyTHBJbnRlZ3JhbExhc3RVcGRIZWlnaHRLRVkFEmVtaXNzaW9uU3RhcnRCbG9jawQPd3hQZXJMcEludGVncmFsCQEZZ2V0QmlnSW50RnJvbVN0cmluZ09yWmVybwIFBHRoaXMFEnd4UGVyTHBJbnRlZ3JhbEtFWQQPd3hQZXJMcE9yWmVyb1gzAAAEAmRoCQCWAwEJAMwIAgkAZQIFBmhlaWdodAUcd3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodAkAzAgCAAAFA25pbAQJd3hQZXJMcFgzAwkBAiE9AgUPd3hQZXJMcE9yWmVyb1gzAAAJALYCAQUPd3hQZXJMcE9yWmVyb1gzCQC8AgMJALYCAQUYcG9vbFd4RW1pc3Npb25QZXJCbG9ja1gzCQC2AgEFBU1VTFQ4BRJub25aZXJvU3Rha2VkVG90YWwEDnN0YWtlZFRvdGFsTmV3CQC3AgIFC3N0YWtlZFRvdGFsCQC2AgEFDWxwRGVsdGFBbW91bnQEFW5vblplcm9TdGFrZWRUb3RhbE5ldwMJAAACBQ5zdGFrZWRUb3RhbE5ldwUKemVyb0JpZ0ludAUJb25lQmlnSW50BQ5zdGFrZWRUb3RhbE5ldwQSd3hQZXJMcEludGVncmFsTmV3CQC3AgIFD3d4UGVyTHBJbnRlZ3JhbAkAuQICBQl3eFBlckxwWDMJALYCAQUCZGgEDHd4UGVyTHBYM05ldwkAugICCQC2AgEFGHBvb2xXeEVtaXNzaW9uUGVyQmxvY2tYMwUVbm9uWmVyb1N0YWtlZFRvdGFsTmV3BB93eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0TmV3BQZoZWlnaHQEBWRlYnVnCQC5CQIJAMwIAgkApgMBBRJ3eFBlckxwSW50ZWdyYWxOZXcJAMwIAgkApAMBBQJkaAkAzAgCCQCmAwEFCXd4UGVyTHBYMwkAzAgCCQCmAwEFC3N0YWtlZFRvdGFsCQDMCAIJAKQDAQUYcG9vbFd4RW1pc3Npb25QZXJCbG9ja1gzCQDMCAIJAKQDAQUUd3hFbWlzc2lvblBlckJsb2NrWDMJAMwIAgkApAMBBQpwb29sV2VpZ2h0BQNuaWwCAjo6CQCVCgMFEnd4UGVyTHBJbnRlZ3JhbE5ldwkAzAgCCQELU3RyaW5nRW50cnkCBRJ3eFBlckxwSW50ZWdyYWxLRVkJAKYDAQUSd3hQZXJMcEludGVncmFsTmV3CQDMCAIJAQxJbnRlZ2VyRW50cnkCBR93eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0S0VZBR93eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0TmV3CQDMCAIJAQtTdHJpbmdFbnRyeQIFCnd4UGVyTHBLRVkJAKYDAQUMd3hQZXJMcFgzTmV3BQNuaWwFBWRlYnVnARByZWZyZXNoSU5URUdSQUxTBAxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIOcG9vbEFkZHJlc3NTdHINbHBEZWx0YUFtb3VudAQNJHQwMTQ3NTAxNDg3MgkBFHJlZnJlc2hQb29sSU5URUdSQUxTAwUMbHBBc3NldElkU3RyBQ5wb29sQWRkcmVzc1N0cgUNbHBEZWx0YUFtb3VudAQSd3hQZXJMcEludGVncmFsTmV3CAUNJHQwMTQ3NTAxNDg3MgJfMQQRcG9vbEludGVncmFsU1RBVEUIBQ0kdDAxNDc1MDE0ODcyAl8yBAlwb29sREVCVUcIBQ0kdDAxNDc1MDE0ODcyAl8zBAVNVUxUMwDoBwQPc3Rha2VkQnlVc2VyS0VZCQEPa2V5U3Rha2VkQnlVc2VyAgUOdXNlckFkZHJlc3NTdHIFDGxwQXNzZXRJZFN0cgQMc3Rha2VkQnlVc2VyCQEKcmVhZFN0YWtlZAEFD3N0YWtlZEJ5VXNlcktFWQQQd3hUb0NsYWltVXNlcktFWQkBEGtleVd4VG9DbGFpbVVzZXICBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBCN3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodEtFWQkBI2tleVd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0AgUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgQad3hQZXJMcEludGVncmFsVXNlckxhc3RLRVkJARprZXlXeFBlckxwSW50ZWdyYWxVc2VyTGFzdAIFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIEDXd4VG9DbGFpbVVzZXIJARlnZXRCaWdJbnRGcm9tU3RyaW5nT3JaZXJvAgUEdGhpcwUQd3hUb0NsYWltVXNlcktFWQQmd3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHRPclplcm8JAQxnZXRJbnRPclplcm8CBQR0aGlzBSN3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodEtFWQQXd3hQZXJMcEludGVncmFsVXNlckxhc3QJARtjYWxjV3hQZXJMcEludGVncmFsVXNlckxhc3QECQC2AgEFDHN0YWtlZEJ5VXNlcgkAtgIBBSZ3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE9yWmVybwUSd3hQZXJMcEludGVncmFsTmV3BRp3eFBlckxwSW50ZWdyYWxVc2VyTGFzdEtFWQQGTVVMVDExCQBoAgUFTVVMVDgFBU1VTFQzBBB3eFRvQ2xhaW1Vc2VyTmV3CQCYAwEJAMwIAgkAtwICBQ13eFRvQ2xhaW1Vc2VyCQC8AgMJALgCAgUSd3hQZXJMcEludGVncmFsTmV3BRd3eFBlckxwSW50ZWdyYWxVc2VyTGFzdAkAtgIBBQxzdGFrZWRCeVVzZXIJALYCAQUGTVVMVDExCQDMCAIFCnplcm9CaWdJbnQFA25pbAQad3hQZXJMcEludGVncmFsVXNlckxhc3ROZXcFEnd4UGVyTHBJbnRlZ3JhbE5ldwQjd3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHROZXcFBmhlaWdodAQFZGVidWcJALkJAgkAzAgCCQCmAwEFDXd4VG9DbGFpbVVzZXIJAMwIAgkApgMBBRd3eFBlckxwSW50ZWdyYWxVc2VyTGFzdAkAzAgCCQCkAwEFDHN0YWtlZEJ5VXNlcgkAzAgCBQlwb29sREVCVUcJAMwIAgkApAMBBQZoZWlnaHQFA25pbAICOjoJAJUKAwUQd3hUb0NsYWltVXNlck5ldwkAzggCBRFwb29sSW50ZWdyYWxTVEFURQkAzAgCCQELU3RyaW5nRW50cnkCBRB3eFRvQ2xhaW1Vc2VyS0VZCQCmAwEFEHd4VG9DbGFpbVVzZXJOZXcJAMwIAgkBDEludGVnZXJFbnRyeQIFI3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0S0VZBSN3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE5ldwkAzAgCCQELU3RyaW5nRW50cnkCBRp3eFBlckxwSW50ZWdyYWxVc2VyTGFzdEtFWQkApgMBBRp3eFBlckxwSW50ZWdyYWxVc2VyTGFzdE5ldwUDbmlsBQVkZWJ1ZwEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAAEByRtYXRjaDAJAKIIAQkBE2tleU1hbmFnZXJQdWJsaWNLZXkAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkA2QQBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgEdcGVuZGluZ01hbmFnZXJQdWJsaWNLZXlPclVuaXQABAckbWF0Y2gwCQCiCAEJARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQDZBAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yABVwZXJtaXNzaW9uRGVuaWVkRXJyb3IJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAEIbXVzdFRoaXMBAWkDCQAAAggFAWkGY2FsbGVyBQR0aGlzBgUVcGVybWlzc2lvbkRlbmllZEVycm9yAQttdXN0TWFuYWdlcgEBaQQHJG1hdGNoMAkBFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQAAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAnBrBQckbWF0Y2gwAwkAAAIIBQFpD2NhbGxlclB1YmxpY0tleQUCcGsGBRVwZXJtaXNzaW9uRGVuaWVkRXJyb3IDCQABAgUHJG1hdGNoMAIEVW5pdAMJAAACCAUBaQZjYWxsZXIFBHRoaXMGBRVwZXJtaXNzaW9uRGVuaWVkRXJyb3IJAAIBAgtNYXRjaCBlcnJvcgEOdW5zdGFrZUFjdGlvbnMGAWkJbHBBc3NldElkC3Bvb2xBZGRyZXNzC3VzZXJBZGRyZXNzF2xwQXNzZXRSZWNpcGllbnRBZGRyZXNzBmFtb3VudAQOdXNlckFkZHJlc3NTdHIJAKUIAQULdXNlckFkZHJlc3MEDGxwQXNzZXRJZFN0cgkA2AQBBQlscEFzc2V0SWQEDnBvb2xBZGRyZXNzU3RyCQClCAEFC3Bvb2xBZGRyZXNzBA9zdGFrZWRCeVVzZXJLRVkJAQ9rZXlTdGFrZWRCeVVzZXICBQ51c2VyQWRkcmVzc1N0cgUMbHBBc3NldElkU3RyBA5zdGFrZWRUb3RhbEtFWQkBDmtleVN0YWtlZFRvdGFsAQUMbHBBc3NldElkU3RyBAxzdGFrZWRCeVVzZXIJAQpyZWFkU3Rha2VkAQUPc3Rha2VkQnlVc2VyS0VZBAtzdGFrZWRUb3RhbAkBCnJlYWRTdGFrZWQBBQ5zdGFrZWRUb3RhbEtFWQQNaW50ZWdyYWxTVEFURQgJARByZWZyZXNoSU5URUdSQUxTBAUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgUOcG9vbEFkZHJlc3NTdHIJAQEtAQUGYW1vdW50Al8yBAhsaXN0TmFtZQkBEGdldFVzZXJzTGlzdE5hbWUBBQxscEFzc2V0SWRTdHIEC2xpc3RBY3Rpb25zAwMJAQxjb250YWluc05vZGUCBQhsaXN0TmFtZQUOdXNlckFkZHJlc3NTdHIJAAACBQZhbW91bnQFDHN0YWtlZEJ5VXNlcgcJARFkZWxldGVOb2RlQWN0aW9ucwIFCGxpc3ROYW1lBQ51c2VyQWRkcmVzc1N0cgUDbmlsBBZjbGFpbWVkQnlVc2VyTWluUmV3YXJkCQEZZ2V0QmlnSW50RnJvbVN0cmluZ09yWmVybwIFBHRoaXMJARlrZXlDbGFpbWVkQnlVc2VyTWluUmV3YXJkAgUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgQQd3hUb0NsYWltVXNlck5ldwgJARByZWZyZXNoSU5URUdSQUxTBAUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgUOcG9vbEFkZHJlc3NTdHIAAAJfMQQQYXZhaWxhYmxlVG9DbGFpbQkAuAICBRB3eFRvQ2xhaW1Vc2VyTmV3BRZjbGFpbWVkQnlVc2VyTWluUmV3YXJkBBV0aHJvd0lmTm90aGluZ1RvQ2xhaW0GBAFyAwkAvwICBRBhdmFpbGFibGVUb0NsYWltBQp6ZXJvQmlnSW50CQD8BwQFBHRoaXMCD2NsYWltV3hJTlRFUk5BTAkAzAgCBQxscEFzc2V0SWRTdHIJAMwIAgUOdXNlckFkZHJlc3NTdHIJAMwIAgUVdGhyb3dJZk5vdGhpbmdUb0NsYWltBQNuaWwFA25pbAUEdW5pdAMJAAACBQFyBQFyAwkAZgIFBmFtb3VudAUMc3Rha2VkQnlVc2VyCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAg5wYXNzZWQgYW1vdW50PQkApAMBBQZhbW91bnQCGyBpcyBncmVhdGVyIHRoYW4gYXZhaWxhYmxlPQkApAMBBQxzdGFrZWRCeVVzZXICDC4gbHBBc3NldElkPQUMbHBBc3NldElkU3RyAhIuIHN0YWtlZEJ5VXNlcktFWT0FD3N0YWtlZEJ5VXNlcktFWQkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFD3N0YWtlZEJ5VXNlcktFWQkAZQIFDHN0YWtlZEJ5VXNlcgUGYW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5zdGFrZWRUb3RhbEtFWQkAZQIFC3N0YWtlZFRvdGFsBQZhbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUXbHBBc3NldFJlY2lwaWVudEFkZHJlc3MFBmFtb3VudAUJbHBBc3NldElkCQDMCAIJARVPcGVyYXRpb25IaXN0b3J5RW50cnkFAgd1bnN0YWtlBQ51c2VyQWRkcmVzc1N0cgUMbHBBc3NldElkU3RyBQZhbW91bnQIBQFpDXRyYW5zYWN0aW9uSWQFA25pbAUNaW50ZWdyYWxTVEFURQULbGlzdEFjdGlvbnMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4QAWkBC2NvbnN0cnVjdG9yARFmYWN0b3J5QWRkcmVzc1N0cgQLY2hlY2tDYWxsZXIJAQttdXN0TWFuYWdlcgEFAWkDCQAAAgULY2hlY2tDYWxsZXIFC2NoZWNrQ2FsbGVyCQDMCAIJAQtTdHJpbmdFbnRyeQIJARFrZXlGYWN0b3J5QWRkcmVzcwAFEWZhY3RvcnlBZGRyZXNzU3RyBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQENY29uc3RydWN0b3JWMgEWdm90aW5nRW1pc3Npb25Db250cmFjdAQFY2hla3MJAMwIAgkBC211c3RNYW5hZ2VyAQUBaQkAzAgCAwkBAiE9AgkApggBBRZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0BQR1bml0BgIoaW52YWxpZCB2b3RpbmcgZW1pc3Npb24gY29udHJhY3QgYWRkcmVzcwUDbmlsAwkAAAIFBWNoZWtzBQVjaGVrcwkAzAgCCQELU3RyaW5nRW50cnkCCQEZa2V5Vm90aW5nRW1pc3Npb25Db250cmFjdAAFFnZvdGluZ0VtaXNzaW9uQ29udHJhY3QFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQpzZXRNYW5hZ2VyARdwZW5kaW5nTWFuYWdlclB1YmxpY0tleQQLY2hlY2tDYWxsZXIJAQttdXN0TWFuYWdlcgEFAWkDCQAAAgULY2hlY2tDYWxsZXIFC2NoZWNrQ2FsbGVyBBVjaGVja01hbmFnZXJQdWJsaWNLZXkJANkEAQUXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkDCQAAAgUVY2hlY2tNYW5hZ2VyUHVibGljS2V5BRVjaGVja01hbmFnZXJQdWJsaWNLZXkJAMwIAgkBC1N0cmluZ0VudHJ5AgkBGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAUXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQ5jb25maXJtTWFuYWdlcgAEAnBtCQEdcGVuZGluZ01hbmFnZXJQdWJsaWNLZXlPclVuaXQABAVoYXNQTQMJAQlpc0RlZmluZWQBBQJwbQYJAAIBAhJObyBwZW5kaW5nIG1hbmFnZXIDCQAAAgUFaGFzUE0FBWhhc1BNBAdjaGVja1BNAwkAAAIIBQFpD2NhbGxlclB1YmxpY0tleQkBBXZhbHVlAQUCcG0GCQACAQIbWW91IGFyZSBub3QgcGVuZGluZyBtYW5hZ2VyAwkAAAIFB2NoZWNrUE0FB2NoZWNrUE0JAMwIAgkBC1N0cmluZ0VudHJ5AgkBE2tleU1hbmFnZXJQdWJsaWNLZXkACQDYBAEJAQV2YWx1ZQEFAnBtCQDMCAIJAQtEZWxldGVFbnRyeQEJARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQAFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQVzdGFrZQADCQECIT0CCQCQAwEIBQFpCHBheW1lbnRzAAEJAAIBAjRpbnZhbGlkIHBheW1lbnQgLSBleGFjdCBvbmUgcGF5bWVudCBtdXN0IGJlIGF0dGFjaGVkBANwbXQJAJEDAggFAWkIcGF5bWVudHMAAAQJbHBBc3NldElkCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQEDGxwQXNzZXRJZFN0cgkA2AQBBQlscEFzc2V0SWQEBmFtb3VudAgFA3BtdAZhbW91bnQEDnBvb2xBZGRyZXNzU3RyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUPZmFjdG9yeUNvbnRyYWN0CQEaa2V5RmFjdG9yeUxwMkFzc2V0c01hcHBpbmcBBQxscEFzc2V0SWRTdHIJAKwCAgIVdW5zdXBwb3J0ZWQgbHAgYXNzZXQgBQxscEFzc2V0SWRTdHIECWNhbGxlclN0cgkApQgBCAUBaQZjYWxsZXIEDnVzZXJBZGRyZXNzU3RyAwkAAAIFCWNhbGxlclN0cgUOcG9vbEFkZHJlc3NTdHIJAKUIAQgFAWkMb3JpZ2luQ2FsbGVyBQljYWxsZXJTdHIED3N0YWtlZEJ5VXNlcktFWQkBD2tleVN0YWtlZEJ5VXNlcgIFDnVzZXJBZGRyZXNzU3RyBQxscEFzc2V0SWRTdHIEDnN0YWtlZFRvdGFsS0VZCQEOa2V5U3Rha2VkVG90YWwBBQxscEFzc2V0SWRTdHIEDHN0YWtlZEJ5VXNlcgkBCnJlYWRTdGFrZWQBBQ9zdGFrZWRCeVVzZXJLRVkEC3N0YWtlZFRvdGFsCQEKcmVhZFN0YWtlZAEFDnN0YWtlZFRvdGFsS0VZBA0kdDAyMTI3NjIxMzkzCQEQcmVmcmVzaElOVEVHUkFMUwQFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIFDnBvb2xBZGRyZXNzU3RyBQZhbW91bnQEEHd4VG9DbGFpbVVzZXJOZXcIBQ0kdDAyMTI3NjIxMzkzAl8xBA1pbnRlZ3JhbFNUQVRFCAUNJHQwMjEyNzYyMTM5MwJfMgQFZGVidWcIBQ0kdDAyMTI3NjIxMzkzAl8zBAhsaXN0TmFtZQkBEGdldFVzZXJzTGlzdE5hbWUBBQxscEFzc2V0SWRTdHIEC2xpc3RBY3Rpb25zAwkBDGNvbnRhaW5zTm9kZQIFCGxpc3ROYW1lBQ51c2VyQWRkcmVzc1N0cgUDbmlsCQERaW5zZXJ0Tm9kZUFjdGlvbnMCBQhsaXN0TmFtZQUOdXNlckFkZHJlc3NTdHIJAM4IAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ9zdGFrZWRCeVVzZXJLRVkJAGQCBQxzdGFrZWRCeVVzZXIFBmFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUOc3Rha2VkVG90YWxLRVkJAGQCBQtzdGFrZWRUb3RhbAUGYW1vdW50CQDMCAIJARVPcGVyYXRpb25IaXN0b3J5RW50cnkFAgVzdGFrZQUOdXNlckFkZHJlc3NTdHIFDGxwQXNzZXRJZFN0cgUGYW1vdW50CAUBaQ10cmFuc2FjdGlvbklkBQNuaWwFDWludGVncmFsU1RBVEUFC2xpc3RBY3Rpb25zAWkBB3Vuc3Rha2UCDGxwQXNzZXRJZFN0cgZhbW91bnQECWxwQXNzZXRJZAkA2QQBBQxscEFzc2V0SWRTdHIEDnBvb2xBZGRyZXNzU3RyCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUPZmFjdG9yeUNvbnRyYWN0CQEaa2V5RmFjdG9yeUxwMkFzc2V0c01hcHBpbmcBBQxscEFzc2V0SWRTdHIJAKwCAgIVdW5zdXBwb3J0ZWQgbHAgYXNzZXQgBQxscEFzc2V0SWRTdHIEC3Bvb2xBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBBQ5wb29sQWRkcmVzc1N0cgQJcG9vbEFkZG9uCQELdmFsdWVPckVsc2UCCQCdCAIFC3Bvb2xBZGRyZXNzCQEMa2V5QWRkb25BZGRyAAUOcG9vbEFkZHJlc3NTdHIECWNhbGxlclN0cgkApQgBCAUBaQZjYWxsZXIEC3VzZXJBZGRyZXNzAwMJAAACBQljYWxsZXJTdHIFDnBvb2xBZGRyZXNzU3RyBgkAAAIFCWNhbGxlclN0cgUJcG9vbEFkZG9uCAUBaQxvcmlnaW5DYWxsZXIIBQFpBmNhbGxlcgQXbHBBc3NldFJlY2lwaWVudEFkZHJlc3MIBQFpBmNhbGxlcgkBDnVuc3Rha2VBY3Rpb25zBgUBaQUJbHBBc3NldElkBQtwb29sQWRkcmVzcwULdXNlckFkZHJlc3MFF2xwQXNzZXRSZWNpcGllbnRBZGRyZXNzBQZhbW91bnQBaQEPdW5zdGFrZUlOVEVSTkFMBAlscEFzc2V0SWQGYW1vdW50C3VzZXJBZGRyZXNzF2xwQXNzZXRSZWNpcGllbnRBZGRyZXNzBAxscEFzc2V0SWRTdHIJANgEAQUJbHBBc3NldElkBAtwb29sQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD2ZhY3RvcnlDb250cmFjdAkBGmtleUZhY3RvcnlMcDJBc3NldHNNYXBwaW5nAQUMbHBBc3NldElkU3RyCQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUMbHBBc3NldElkU3RyBAtjaGVja0NhbGxlcgMJAAACCAUBaQZjYWxsZXIFC3Bvb2xBZGRyZXNzBgUVcGVybWlzc2lvbkRlbmllZEVycm9yAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgkBDnVuc3Rha2VBY3Rpb25zBgUBaQUJbHBBc3NldElkBQtwb29sQWRkcmVzcwkBB0FkZHJlc3MBBQt1c2VyQWRkcmVzcwkBB0FkZHJlc3MBBRdscEFzc2V0UmVjaXBpZW50QWRkcmVzcwUGYW1vdW50CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBB2NsYWltV3gBDGxwQXNzZXRJZFN0cgQOdXNlckFkZHJlc3NTdHIJAKUIAQgFAWkGY2FsbGVyBBV0aHJvd0lmTm90aGluZ1RvQ2xhaW0GBAZyZXN1bHQJAPwHBAUEdGhpcwIPY2xhaW1XeElOVEVSTkFMCQDMCAIFDGxwQXNzZXRJZFN0cgkAzAgCBQ51c2VyQWRkcmVzc1N0cgkAzAgCBRV0aHJvd0lmTm90aGluZ1RvQ2xhaW0FA25pbAUDbmlsCQCUCgIFA25pbAUGcmVzdWx0AWkBEWNsYWltV3hEb05vdFRocm93AQxscEFzc2V0SWRTdHIEDnVzZXJBZGRyZXNzU3RyCQClCAEIBQFpBmNhbGxlcgQVdGhyb3dJZk5vdGhpbmdUb0NsYWltBwQGcmVzdWx0CQD8BwQFBHRoaXMCD2NsYWltV3hJTlRFUk5BTAkAzAgCBQxscEFzc2V0SWRTdHIJAMwIAgUOdXNlckFkZHJlc3NTdHIJAMwIAgUVdGhyb3dJZk5vdGhpbmdUb0NsYWltBQNuaWwFA25pbAkAlAoCBQNuaWwFBnJlc3VsdAFpAQ9jbGFpbVd4SU5URVJOQUwDDGxwQXNzZXRJZFN0cg51c2VyQWRkcmVzc1N0chV0aHJvd0lmTm90aGluZ1RvQ2xhaW0EC2NoZWNrQ2FsbGVyCQEIbXVzdFRoaXMBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQLdXNlckFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQ51c2VyQWRkcmVzc1N0cgIlY2xhaW1XeElOVEVSTkFMOiBpbnZhbGlkIHVzZXIgYWRkcmVzcwQOcG9vbEFkZHJlc3NTdHIJARhnZXRTdHJpbmdCeUFkZHJlc3NPckZhaWwCBQ9mYWN0b3J5Q29udHJhY3QJASZrZXlGYWN0b3J5THBBc3NldFRvUG9vbENvbnRyYWN0QWRkcmVzcwEFDGxwQXNzZXRJZFN0cgQQY2xhaW1lZEJ5VXNlcktFWQkBEGtleUNsYWltZWRCeVVzZXICBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBA9jbGFpbWVkVG90YWxLRVkJAQ9rZXlDbGFpbWVkVG90YWwBBQxscEFzc2V0SWRTdHIEGWNsYWltZWRCeVVzZXJNaW5SZXdhcmRLRVkJARlrZXlDbGFpbWVkQnlVc2VyTWluUmV3YXJkAgUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgQbY2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkS0VZCQEba2V5Q2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkAgUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgQNY2xhaW1lZEJ5VXNlcgkBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CBQR0aGlzBRBjbGFpbWVkQnlVc2VyS0VZBBZjbGFpbWVkQnlVc2VyTWluUmV3YXJkCQEZZ2V0QmlnSW50RnJvbVN0cmluZ09yWmVybwIFBHRoaXMFGWNsYWltZWRCeVVzZXJNaW5SZXdhcmRLRVkEGGNsYWltZWRCeVVzZXJCb29zdFJld2FyZAkBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CBQR0aGlzBRtjbGFpbWVkQnlVc2VyQm9vc3RSZXdhcmRLRVkEDGNsYWltZWRUb3RhbAkBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CBQR0aGlzBQ9jbGFpbWVkVG90YWxLRVkEDSR0MDI0Nzc5MjQ4OTEJARByZWZyZXNoSU5URUdSQUxTBAUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgUOcG9vbEFkZHJlc3NTdHIAAAQQd3hUb0NsYWltVXNlck5ldwgFDSR0MDI0Nzc5MjQ4OTECXzEEDWludGVncmFsU1RBVEUIBQ0kdDAyNDc3OTI0ODkxAl8yBAVkZWJ1ZwgFDSR0MDI0Nzc5MjQ4OTECXzMEEGF2YWlsYWJsZVRvQ2xhaW0JAJgDAQkAzAgCCQC4AgIFEHd4VG9DbGFpbVVzZXJOZXcFFmNsYWltZWRCeVVzZXJNaW5SZXdhcmQJAMwIAgUKemVyb0JpZ0ludAUDbmlsAwkAwAICBQp6ZXJvQmlnSW50BRBhdmFpbGFibGVUb0NsYWltAwUVdGhyb3dJZk5vdGhpbmdUb0NsYWltCQACAQIQbm90aGluZyB0byBjbGFpbQkAlAoCBQNuaWwAAAQSd3hBbW91bnRCb29zdFRvdGFsCQCWAwEJAMwIAgkBBWFzSW50AQkAkQMCCQEJYXNBbnlMaXN0AQkA/AcEBRBib29zdGluZ0NvbnRyYWN0AgxjbGFpbVd4Qm9vc3QJAMwIAgUMbHBBc3NldElkU3RyCQDMCAIFDnVzZXJBZGRyZXNzU3RyBQNuaWwFA25pbAAACQDMCAIAAAUDbmlsBA1taW5SZXdhcmRQYXJ0BRBhdmFpbGFibGVUb0NsYWltBA9ib29zdFJld2FyZFBhcnQJAJkDAQkAzAgCCQC5AgIFDW1pblJld2FyZFBhcnQJALYCAQACCQDMCAIJALYCAQUSd3hBbW91bnRCb29zdFRvdGFsBQNuaWwEC3RvdGFsUmV3YXJkCQC3AgIFDW1pblJld2FyZFBhcnQFD2Jvb3N0UmV3YXJkUGFydAQJd3hBc3NldElkCQEMYXNCeXRlVmVjdG9yAQkAkQMCCQEJYXNBbnlMaXN0AQkA/AcEBRBlbWlzc2lvbkNvbnRyYWN0AgRlbWl0CQDMCAIJAKADAQUNbWluUmV3YXJkUGFydAUDbmlsBQNuaWwAAAQJZW1pdEJvb3N0CQEJYXNBbnlMaXN0AQkA/AcEBRBlbWlzc2lvbkNvbnRyYWN0AgRlbWl0CQDMCAIJAKADAQUPYm9vc3RSZXdhcmRQYXJ0BQNuaWwFA25pbAMJAAACBQllbWl0Qm9vc3QFCWVtaXRCb29zdAQSY2xhaW1lZEJ5VXNlclZhbHVlCQC3AgIJALcCAgUNY2xhaW1lZEJ5VXNlcgUNbWluUmV3YXJkUGFydAUPYm9vc3RSZXdhcmRQYXJ0BB5jbGFpbWVkQnlVc2VyTWluUmV3YXJkUGx1c1BhcnQJALcCAgUWY2xhaW1lZEJ5VXNlck1pblJld2FyZAUNbWluUmV3YXJkUGFydAQrY2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkUGx1c0Jvb3N0UmV3YXJkUGFydAkAtwICBRhjbGFpbWVkQnlVc2VyQm9vc3RSZXdhcmQFD2Jvb3N0UmV3YXJkUGFydAQgY2xhaW1lZFRvdGFsUGx1c0F2YWlsYWJsZVRvQ2xhaW0JALcCAgUMY2xhaW1lZFRvdGFsBRBhdmFpbGFibGVUb0NsYWltCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUQY2xhaW1lZEJ5VXNlcktFWQkApgMBBRJjbGFpbWVkQnlVc2VyVmFsdWUJAMwIAgkBC1N0cmluZ0VudHJ5AgUZY2xhaW1lZEJ5VXNlck1pblJld2FyZEtFWQkApgMBBR5jbGFpbWVkQnlVc2VyTWluUmV3YXJkUGx1c1BhcnQJAMwIAgkBC1N0cmluZ0VudHJ5AgUbY2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkS0VZCQCmAwEFK2NsYWltZWRCeVVzZXJCb29zdFJld2FyZFBsdXNCb29zdFJld2FyZFBhcnQJAMwIAgkBC1N0cmluZ0VudHJ5AgUPY2xhaW1lZFRvdGFsS0VZCQCmAwEFIGNsYWltZWRUb3RhbFBsdXNBdmFpbGFibGVUb0NsYWltCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFC3VzZXJBZGRyZXNzCQCgAwEFDW1pblJld2FyZFBhcnQFCXd4QXNzZXRJZAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQt1c2VyQWRkcmVzcwkAoAMBBQ9ib29zdFJld2FyZFBhcnQFCXd4QXNzZXRJZAkAzAgCCQEVT3BlcmF0aW9uSGlzdG9yeUVudHJ5BQIFY2xhaW0FDnVzZXJBZGRyZXNzU3RyBQxscEFzc2V0SWRTdHIJAKADAQUQYXZhaWxhYmxlVG9DbGFpbQgFAWkNdHJhbnNhY3Rpb25JZAUDbmlsCQCgAwEFC3RvdGFsUmV3YXJkCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBG2NsYWltV3hCdWxrSW50ZXJuYWxSRUFET05MWQQLY3VycmVudEl0ZXIKbHBBc3NldElkcw51c2VyQWRkcmVzc1N0cgZyZXNBY2MDCQAAAgULY3VycmVudEl0ZXIJAJADAQUKbHBBc3NldElkcwkAlAoCBQNuaWwFBnJlc0FjYwQJbHBBc3NldElkCQCRAwIFCmxwQXNzZXRJZHMFC2N1cnJlbnRJdGVyBARpbmZvCQC1CQIKAAFACQD8BwQFBHRoaXMCD2NsYWltV3hSRUFET05MWQkAzAgCBQlscEFzc2V0SWQJAMwIAgUOdXNlckFkZHJlc3NTdHIFA25pbAUDbmlsAwkAAQIFAUACBlN0cmluZwUBQAkAAgEJAKwCAgkAAwEFAUACGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwUDU0VQBAl1bmNsYWltZWQJAJEDAgUEaW5mbwADBAdjbGFpbWVkCQCRAwIFBGluZm8ABAQDcmVzCQDNCAIFBnJlc0FjYwkAuQkCCQDMCAICBCVkJWQJAMwIAgUJdW5jbGFpbWVkCQDMCAIFB2NsYWltZWQFA25pbAUDU0VQBANpbnYKAAFACQD8BwQFBHRoaXMCG2NsYWltV3hCdWxrSW50ZXJuYWxSRUFET05MWQkAzAgCCQBkAgULY3VycmVudEl0ZXIAAQkAzAgCBQpscEFzc2V0SWRzCQDMCAIFDnVzZXJBZGRyZXNzU3RyCQDMCAIFA3JlcwUDbmlsBQNuaWwDCQABAgUBQAIJTGlzdFtBbnldBQFACQACAQkArAICCQADAQUBQAIeIGNvdWxkbid0IGJlIGNhc3QgdG8gTGlzdFtBbnldAwkAAAIFA2ludgUDaW52CQCUCgIFA25pbAUDaW52CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBE2NsYWltV3hCdWxrUkVBRE9OTFkCCmxwQXNzZXRJZHMOdXNlckFkZHJlc3NTdHIEA3JlcwkA/AcEBQR0aGlzAhtjbGFpbVd4QnVsa0ludGVybmFsUkVBRE9OTFkJAMwIAgAACQDMCAIFCmxwQXNzZXRJZHMJAMwIAgUOdXNlckFkZHJlc3NTdHIJAMwIAgUDbmlsBQNuaWwFA25pbAkAlAoCBQNuaWwFA3JlcwFpAQ9jbGFpbVd4UkVBRE9OTFkCDGxwQXNzZXRJZFN0cg51c2VyQWRkcmVzc1N0cgQPc3Rha2VkQnlVc2VyS0VZCQEPa2V5U3Rha2VkQnlVc2VyAgUOdXNlckFkZHJlc3NTdHIFDGxwQXNzZXRJZFN0cgQOc3Rha2VkVG90YWxLRVkJAQ5rZXlTdGFrZWRUb3RhbAEFDGxwQXNzZXRJZFN0cgQQY2xhaW1lZEJ5VXNlcktFWQkBEGtleUNsYWltZWRCeVVzZXICBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBBljbGFpbWVkQnlVc2VyTWluUmV3YXJkS0VZCQEZa2V5Q2xhaW1lZEJ5VXNlck1pblJld2FyZAIFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIEDHN0YWtlZEJ5VXNlcgkBCnJlYWRTdGFrZWQBBQ9zdGFrZWRCeVVzZXJLRVkEC3N0YWtlZFRvdGFsCQEKcmVhZFN0YWtlZAEFDnN0YWtlZFRvdGFsS0VZBA1jbGFpbWVkQnlVc2VyCQEZZ2V0QmlnSW50RnJvbVN0cmluZ09yWmVybwIFBHRoaXMFEGNsYWltZWRCeVVzZXJLRVkEFmNsYWltZWRCeVVzZXJNaW5SZXdhcmQJARlnZXRCaWdJbnRGcm9tU3RyaW5nT3JaZXJvAgUEdGhpcwUZY2xhaW1lZEJ5VXNlck1pblJld2FyZEtFWQQOcG9vbEFkZHJlc3NTdHIJARhnZXRTdHJpbmdCeUFkZHJlc3NPckZhaWwCBQ9mYWN0b3J5Q29udHJhY3QJASZrZXlGYWN0b3J5THBBc3NldFRvUG9vbENvbnRyYWN0QWRkcmVzcwEFDGxwQXNzZXRJZFN0cgQKcG9vbFdlaWdodAkBEUBleHRyTmF0aXZlKDEwNTApAgUPZmFjdG9yeUNvbnRyYWN0CQEUa2V5RmFjdG9yeVBvb2xXZWlnaHQBBQ5wb29sQWRkcmVzc1N0cgQSd3hFbWlzc2lvblBlckJsb2NrCQEMZ2V0SW50T3JGYWlsAgUQZW1pc3Npb25Db250cmFjdAkBHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAEEmVtaXNzaW9uU3RhcnRCbG9jawkBDGdldEludE9yRmFpbAIFEGVtaXNzaW9uQ29udHJhY3QJARVrZXlFbWlzc2lvblN0YXJ0QmxvY2sABAxwYXNzZWRCbG9ja3MDCQBmAgUSZW1pc3Npb25TdGFydEJsb2NrBQZoZWlnaHQAAAkAZQIFBmhlaWdodAUSZW1pc3Npb25TdGFydEJsb2NrBA5wb29sV3hFbWlzc2lvbgkAawMJAGgCBRJ3eEVtaXNzaW9uUGVyQmxvY2sFDHBhc3NlZEJsb2NrcwUKcG9vbFdlaWdodAUOUE9PTFdFSUdIVE1VTFQEDHVzZXJXeFJld2FyZAkAawMFDnBvb2xXeEVtaXNzaW9uBQxzdGFrZWRCeVVzZXIFC3N0YWtlZFRvdGFsBA0kdDAyODcwMDI4ODEyCQEQcmVmcmVzaElOVEVHUkFMUwQFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIFDnBvb2xBZGRyZXNzU3RyAAAEEHd4VG9DbGFpbVVzZXJOZXcIBQ0kdDAyODcwMDI4ODEyAl8xBA1pbnRlZ3JhbFNUQVRFCAUNJHQwMjg3MDAyODgxMgJfMgQFZGVidWcIBQ0kdDAyODcwMDI4ODEyAl8zBBBhdmFpbGFibGVUb0NsYWltCQCYAwEJAMwIAgkAuAICBRB3eFRvQ2xhaW1Vc2VyTmV3BRZjbGFpbWVkQnlVc2VyTWluUmV3YXJkCQDMCAIFCnplcm9CaWdJbnQFA25pbAQOYm9vc3RJbnZSZXN1bHQJAQlhc0FueUxpc3QBCQD8BwQFEGJvb3N0aW5nQ29udHJhY3QCFGNsYWltV3hCb29zdFJFQURPTkxZCQDMCAIFDGxwQXNzZXRJZFN0cgkAzAgCBQ51c2VyQWRkcmVzc1N0cgUDbmlsBQNuaWwEEnd4QW1vdW50Qm9vc3RUb3RhbAkAlgMBCQDMCAIJAQVhc0ludAEJAJEDAgUOYm9vc3RJbnZSZXN1bHQAAAkAzAgCAAAFA25pbAQKYm9vc3REZWJ1ZwkBCGFzU3RyaW5nAQkAkQMCBQ5ib29zdEludlJlc3VsdAABBA1taW5SZXdhcmRQYXJ0BRBhdmFpbGFibGVUb0NsYWltBA9ib29zdFJld2FyZFBhcnQJAJkDAQkAzAgCCQC5AgIFDW1pblJld2FyZFBhcnQJALYCAQACCQDMCAIJALYCAQUSd3hBbW91bnRCb29zdFRvdGFsBQNuaWwEC3RvdGFsUmV3YXJkCQC3AgIFDW1pblJld2FyZFBhcnQFD2Jvb3N0UmV3YXJkUGFydAkAlAoCBQNuaWwJALkJAgkAzAgCAg4lcyVzJWQlZCVkJWQlcwkAzAgCBQxscEFzc2V0SWRTdHIJAMwIAgUOdXNlckFkZHJlc3NTdHIJAMwIAgkApgMBBQt0b3RhbFJld2FyZAkAzAgCCQCmAwEFDWNsYWltZWRCeVVzZXIJAMwIAgkApgMBBQ1taW5SZXdhcmRQYXJ0CQDMCAIJAKYDAQUPYm9vc3RSZXdhcmRQYXJ0CQDMCAICBHNvb24FA25pbAUDU0VQAWkBFHN0YWtlZEJ5VXNlclJFQURPTkxZAgxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIEDHN0YWtlZEJ5VXNlcgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEPa2V5U3Rha2VkQnlVc2VyAgUOdXNlckFkZHJlc3NTdHIFDGxwQXNzZXRJZFN0cgAACQCUCgIFA25pbAUMc3Rha2VkQnlVc2VyAWkBEnVzZXJzTGlzdFRyYXZlcnNhbAEJbHBBc3NldElkBAtjaGVja0NhbGxlcgMJAAACCQDYBAEICAUBaQZjYWxsZXIFYnl0ZXMJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBGWtleVZvdGluZ0VtaXNzaW9uQ29udHJhY3QAAgAGCQELbXVzdE1hbmFnZXIBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQIbGlzdE5hbWUJARBnZXRVc2Vyc0xpc3ROYW1lAQUJbHBBc3NldElkBAp1c2VyT3JVbml0CQCiCAEJAQtrZXlOZXh0VXNlcgEFCWxwQXNzZXRJZAQKaGVhZE9yVW5pdAkAoggBCQELa2V5TGlzdEhlYWQBBQhsaXN0TmFtZQQHJG1hdGNoMAUKdXNlck9yVW5pdAMJAAECBQckbWF0Y2gwAgRVbml0BAckbWF0Y2gxBQpoZWFkT3JVbml0AwkAAQIFByRtYXRjaDECBFVuaXQJAJQKAgUDbmlsBwMJAAECBQckbWF0Y2gxAgZTdHJpbmcEBGhlYWQFByRtYXRjaDEJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQELa2V5TmV4dFVzZXIBBQlscEFzc2V0SWQFBGhlYWQFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgMJAAECBQckbWF0Y2gwAgZTdHJpbmcEC3VzZXJBZGRyZXNzBQckbWF0Y2gwBBZjbGFpbWVkQnlVc2VyTWluUmV3YXJkCQEZZ2V0QmlnSW50RnJvbVN0cmluZ09yWmVybwIFBHRoaXMJARlrZXlDbGFpbWVkQnlVc2VyTWluUmV3YXJkAgUJbHBBc3NldElkBQt1c2VyQWRkcmVzcwQLcG9vbEFkZHJlc3MJARhnZXRTdHJpbmdCeUFkZHJlc3NPckZhaWwCBQ9mYWN0b3J5Q29udHJhY3QJASZrZXlGYWN0b3J5THBBc3NldFRvUG9vbENvbnRyYWN0QWRkcmVzcwEFCWxwQXNzZXRJZAQQd3hUb0NsYWltVXNlck5ldwgJARByZWZyZXNoSU5URUdSQUxTBAUJbHBBc3NldElkBQt1c2VyQWRkcmVzcwULcG9vbEFkZHJlc3MAAAJfMQQQYXZhaWxhYmxlVG9DbGFpbQkAuAICBRB3eFRvQ2xhaW1Vc2VyTmV3BRZjbGFpbWVkQnlVc2VyTWluUmV3YXJkBBV0aHJvd0lmTm90aGluZ1RvQ2xhaW0GBAFyAwkAvwICBRBhdmFpbGFibGVUb0NsYWltBQp6ZXJvQmlnSW50CQD8BwQFBHRoaXMCD2NsYWltV3hJTlRFUk5BTAkAzAgCBQlscEFzc2V0SWQJAMwIAgULdXNlckFkZHJlc3MJAMwIAgUVdGhyb3dJZk5vdGhpbmdUb0NsYWltBQNuaWwFA25pbAUEdW5pdAMJAAACBQFyBQFyBA5uZXh0VXNlck9yVW5pdAkAoggBCQELa2V5TGlzdE5leHQCBQhsaXN0TmFtZQULdXNlckFkZHJlc3MEByRtYXRjaDEFDm5leHRVc2VyT3JVbml0AwkAAQIFByRtYXRjaDECBFVuaXQJAJQKAgkAzAgCCQELRGVsZXRlRW50cnkBCQELa2V5TmV4dFVzZXIBBQlscEFzc2V0SWQFA25pbAcDCQABAgUHJG1hdGNoMQIGU3RyaW5nBAhuZXh0VXNlcgUHJG1hdGNoMQkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQtrZXlOZXh0VXNlcgEFCWxwQXNzZXRJZAUIbmV4dFVzZXIFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECC01hdGNoIGVycm9yCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDm9uTW9kaWZ5V2VpZ2h0AgxscEFzc2V0SWRTdHIOcG9vbEFkZHJlc3NTdHIDCQECIT0CCAUBaQZjYWxsZXIFD2ZhY3RvcnlDb250cmFjdAkAAgECEnBlcm1pc3Npb25zIGRlbmllZAQNJHQwMzE0MTgzMTUyOAkBFHJlZnJlc2hQb29sSU5URUdSQUxTAwUMbHBBc3NldElkU3RyBQ5wb29sQWRkcmVzc1N0cgAABBJ3eFBlckxwSW50ZWdyYWxOZXcIBQ0kdDAzMTQxODMxNTI4Al8xBBFwb29sSW50ZWdyYWxTVEFURQgFDSR0MDMxNDE4MzE1MjgCXzIECXBvb2xERUJVRwgFDSR0MDMxNDE4MzE1MjgCXzMFEXBvb2xJbnRlZ3JhbFNUQVRFAQJ0eAEGdmVyaWZ5AAQPdGFyZ2V0UHVibGljS2V5BAckbWF0Y2gwCQEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAADCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCcGsFByRtYXRjaDAFAnBrAwkAAQIFByRtYXRjaDACBFVuaXQIBQJ0eA9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUPdGFyZ2V0UHVibGljS2V5t5Oq0A==", "height": 3545027, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: oAQqRAcmBT4QAhHyMRNDWsM7eqaVWwTbbJpC6ircZo7 Next: 2P5y8aoUk2tJza7Q1MG57BZG5QPT43XCd8cUos1ZQSPv 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+
1925
2026 func asAnyList (val) = match val {
2127 case valAnyLyst: List[Any] =>
239245
240246 let boostingContract = getBoostingAddressOrFail(factoryCfg)
241247
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+
242250 func keyNextUser (lpAssetId) = makeString(["%s%s", lpAssetId, "nextUser"], SEP)
243251
244252
349357
350358
351359 func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
352- let $t01427414396 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
353- let wxPerLpIntegralNew = $t01427414396._1
354- let poolIntegralSTATE = $t01427414396._2
355- let poolDEBUG = $t01427414396._3
360+ let $t01475014872 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
361+ let wxPerLpIntegralNew = $t01475014872._1
362+ let poolIntegralSTATE = $t01475014872._2
363+ let poolDEBUG = $t01475014872._3
356364 let MULT3 = 1000
357365 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
358366 let stakedByUser = readStaked(stakedByUserKEY)
410418 case _ =>
411419 throw("Match error")
412420 }
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+ }
413451
414452
415453 @Callable(i)
486524 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
487525 let stakedByUser = readStaked(stakedByUserKEY)
488526 let stakedTotal = readStaked(stakedTotalKEY)
489- let $t01883218949 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
490- let wxToClaimUserNew = $t01883218949._1
491- let integralSTATE = $t01883218949._2
492- let debug = $t01883218949._3
527+ let $t02127621393 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
528+ let wxToClaimUserNew = $t02127621393._1
529+ let integralSTATE = $t02127621393._2
530+ let debug = $t02127621393._3
493531 let listName = getUsersListName(lpAssetIdStr)
494532 let listActions = if (containsNode(listName, userAddressStr))
495533 then nil
503541 func unstake (lpAssetIdStr,amount) = {
504542 let lpAssetId = fromBase58String(lpAssetIdStr)
505543 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
506- let poolAddon = valueOrElse(getString(addressFromStringValue(poolAddressStr), keyAddonAddr()), poolAddressStr)
544+ let poolAddress = addressFromStringValue(poolAddressStr)
545+ let poolAddon = valueOrElse(getString(poolAddress, keyAddonAddr()), poolAddressStr)
507546 let callerStr = toString(i.caller)
508- let userAddressStr = if (if ((callerStr == poolAddressStr))
547+ let userAddress = if (if ((callerStr == poolAddressStr))
509548 then true
510549 else (callerStr == poolAddon))
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)
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)
535567 else throw("Strict value is not equal to itself.")
536568 }
537569
540572 @Callable(i)
541573 func claimWx (lpAssetIdStr) = {
542574 let userAddressStr = toString(i.caller)
543- let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil)
575+ let throwIfNothingToClaim = true
576+ let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
544577 $Tuple2(nil, result)
545578 }
546579
547580
548581
549582 @Callable(i)
550-func claimWxINTERNAL (lpAssetIdStr,userAddressStr) = {
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) = {
551594 let checkCaller = mustThis(i)
552595 if ((checkCaller == checkCaller))
553596 then {
561604 let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
562605 let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
563606 let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
564- let $t02281422926 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
565- let wxToClaimUserNew = $t02281422926._1
566- let integralSTATE = $t02281422926._2
567- let debug = $t02281422926._3
607+ let $t02477924891 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
608+ let wxToClaimUserNew = $t02477924891._1
609+ let integralSTATE = $t02477924891._2
610+ let debug = $t02477924891._3
568611 let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
569612 if ((zeroBigInt >= availableToClaim))
570- then throw("nothing to claim")
613+ then if (throwIfNothingToClaim)
614+ then throw("nothing to claim")
615+ else $Tuple2(nil, 0)
571616 else {
572617 let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
573618 let minRewardPart = availableToClaim
574619 let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
620+ let totalReward = (minRewardPart + boostRewardPart)
575621 let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
576622 let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
577623 if ((emitBoost == emitBoost))
580626 let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
581627 let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserBoostReward + boostRewardPart)
582628 let claimedTotalPlusAvailableToClaim = (claimedTotal + availableToClaim)
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)]
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))
584630 }
585631 else throw("Strict value is not equal to itself.")
586632 }
644690 else (height - emissionStartBlock)
645691 let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
646692 let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
647- let $t02658426696 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
648- let wxToClaimUserNew = $t02658426696._1
649- let integralSTATE = $t02658426696._2
650- let debug = $t02658426696._3
693+ let $t02870028812 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
694+ let wxToClaimUserNew = $t02870028812._1
695+ let integralSTATE = $t02870028812._2
696+ let debug = $t02870028812._3
651697 let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
652698 let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
653699 let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
656702 let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
657703 let totalReward = (minRewardPart + boostRewardPart)
658704 $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)
659713 }
660714
661715
685739 let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetId))
686740 let wxToClaimUserNew = refreshINTEGRALS(lpAssetId, userAddress, poolAddress, 0)._1
687741 let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
742+ let throwIfNothingToClaim = true
688743 let r = if ((availableToClaim > zeroBigInt))
689- then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress], nil)
744+ then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress, throwIfNothingToClaim], nil)
690745 else unit
691746 if ((r == r))
692747 then {
714769 func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
715770 then throw("permissions denied")
716771 else {
717- let $t02903229142 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
718- let wxPerLpIntegralNew = $t02903229142._1
719- let poolIntegralSTATE = $t02903229142._2
720- let poolDEBUG = $t02903229142._3
772+ let $t03141831528 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
773+ let wxPerLpIntegralNew = $t03141831528._1
774+ let poolIntegralSTATE = $t03141831528._2
775+ let poolDEBUG = $t03141831528._3
721776 poolIntegralSTATE
722777 }
723778
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+
1925
2026 func asAnyList (val) = match val {
2127 case valAnyLyst: List[Any] =>
2228 valAnyLyst
2329 case _ =>
2430 throw("fail to cast into List[Any]")
2531 }
2632
2733
2834 func asInt (val) = match val {
2935 case valInt: Int =>
3036 valInt
3137 case _ =>
3238 throw("fail to cast into Int")
3339 }
3440
3541
3642 func asString (val) = match val {
3743 case valStr: String =>
3844 valStr
3945 case _ =>
4046 throw("fail to cast into Int")
4147 }
4248
4349
4450 func asByteVector (val) = match val {
4551 case valBin: ByteVector =>
4652 valBin
4753 case _ =>
4854 throw("fail to cast into Int")
4955 }
5056
5157
5258 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined"))
5359
5460
5561 func getStringByAddressOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
5662
5763
5864 func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
5965
6066
6167 func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
6268
6369
6470 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
6571
6672
6773 func getBigIntFromStringOrZero (address,key) = value(parseBigInt(valueOrElse(getString(address, key), "0")))
6874
6975
7076 func getBigIntFromStringOrDefault (address,key,defaultVal) = match getString(address, key) {
7177 case s: String =>
7278 value(parseBigInt(s))
7379 case _: Unit =>
7480 defaultVal
7581 case _ =>
7682 throw("Match error")
7783 }
7884
7985
8086 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULT18, toBigInt(origScaleMult))
8187
8288
8389 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULT18))
8490
8591
8692 func keyFactoryAddress () = "%s%s__config__factoryAddress"
8793
8894
8995 func keyVotingEmissionContract () = "%s__votingEmissionContract"
9096
9197
9298 let IdxFactoryCfgStakingDapp = 1
9399
94100 let IdxFactoryCfgBoostingDapp = 2
95101
96102 let IdxFactoryCfgIdoDapp = 3
97103
98104 let IdxFactoryCfgTeamDapp = 4
99105
100106 let IdxFactoryCfgEmissionDapp = 5
101107
102108 let IdxFactoryCfgRestDapp = 6
103109
104110 let IdxFactoryCfgSlippageDapp = 7
105111
106112 func keyFactoryCfg () = "%s__factoryConfig"
107113
108114
109115 func keyManagerPublicKey () = "%s__managerPublicKey"
110116
111117
112118 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
113119
114120
115121 func keyStablePoolAddonAddr () = "%s__stablePoolAddonAddr"
116122
117123
118124 func keyAddonAddr () = "%s__addonAddr"
119125
120126
121127 func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
122128
123129
124130 func keyFactoryLpList () = "%s__lpTokensList"
125131
126132
127133 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
128134
129135
130136 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
131137
132138
133139 func readLpList (factory) = split(valueOrElse(getString(factory, keyFactoryLpList()), ""), SEP)
134140
135141
136142 func readFactoryCfgOrFail (factory) = split(getStringByAddressOrFail(factory, keyFactoryCfg()), SEP)
137143
138144
139145 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
140146
141147
142148 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
143149
144150
145151 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
146152
147153
148154 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
149155
150156
151157 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
152158
153159
154160 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
155161
156162
157163 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
158164
159165
160166 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
161167
162168
163169 func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s__staked", userAddressStr, lpAssetIdStr], SEP)
164170
165171
166172 func keyStakedTotal (lpAssetIdStr) = ("%s%s%s__staked__total__" + lpAssetIdStr)
167173
168174
169175 func keyClaimedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimed", userAddressStr, lpAssetIdStr], SEP)
170176
171177
172178 func keyClaimedByUserMinReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedMinReward", userAddressStr, lpAssetIdStr], SEP)
173179
174180
175181 func keyClaimedByUserBoostReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedBoostReward", userAddressStr, lpAssetIdStr], SEP)
176182
177183
178184 func keyClaimedTotal (lpAssetIdStr) = makeString(["%s%s%s__claimed__total", lpAssetIdStr], SEP)
179185
180186
181187 func readStaked (key) = valueOrElse(getInteger(this, key), 0)
182188
183189
184190 func keyLastTotalLpBalance (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "bal"], SEP)
185191
186192
187193 func keyLastUserLpBalance (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "bal"], SEP)
188194
189195
190196 func keyTotalLpBalanceIntegral (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "balINT"], SEP)
191197
192198
193199 func keyUserLpBalanceIntegral (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "balINT"], SEP)
194200
195201
196202 func keyTotalLpBalanceIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "lastUpd"], SEP)
197203
198204
199205 func keyUserLpBalanceIntegralLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "lastUpd"], SEP)
200206
201207
202208 func keyWxPerLpIntegral (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpInt"], SEP)
203209
204210
205211 func keyWxPerLpIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpIntH"], SEP)
206212
207213
208214 func keyWxToClaimUser (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpInt"], SEP)
209215
210216
211217 func keyWxPerLpIntegralUserLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpIntH"], SEP)
212218
213219
214220 func keyWxPerLp (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLp"], SEP)
215221
216222
217223 func keyWxPerLpX18 (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLpX18"], SEP)
218224
219225
220226 func keyWxPerLpIntegralUserLast (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "uIntL"], SEP)
221227
222228
223229 func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
224230
225231
226232 func formatHistoryRecord (userAddress,lpAssetId,type,amount) = makeString(["%s%s%s%d%d%d", userAddress, lpAssetId, type, toString(height), toString(lastBlock.timestamp), toString(amount)], SEP)
227233
228234
229235 func OperationHistoryEntry (type,userAddress,lpAssetId,amount,txId) = StringEntry(keyOperationHistoryRecord(type, userAddress, toBase58String(txId)), formatHistoryRecord(userAddress, lpAssetId, type, amount))
230236
231237
232238 let factoryAddress = getStringOrFail(this, keyFactoryAddress())
233239
234240 let factoryContract = addressFromStringValue(factoryAddress)
235241
236242 let factoryCfg = readFactoryCfgOrFail(factoryContract)
237243
238244 let emissionContract = getEmissionAddressOrFail(factoryCfg)
239245
240246 let boostingContract = getBoostingAddressOrFail(factoryCfg)
241247
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+
242250 func keyNextUser (lpAssetId) = makeString(["%s%s", lpAssetId, "nextUser"], SEP)
243251
244252
245253 func getUsersListName (lpAssetId) = makeString(["users", lpAssetId], SEP)
246254
247255
248256 func keyListHead (listName) = makeString(["%s%s%s", listName, "head"], SEP)
249257
250258
251259 func keyListSize (listName) = makeString(["%s%s%s", listName, "size"], SEP)
252260
253261
254262 func keyListPrev (listName,id) = makeString(["%s%s%s%s", listName, id, "prev"], SEP)
255263
256264
257265 func keyListNext (listName,id) = makeString(["%s%s%s%s", listName, id, "next"], SEP)
258266
259267
260268 func containsNode (listName,id) = {
261269 let headOrUnit = getString(this, keyListHead(listName))
262270 let prevOrUnit = getString(this, keyListPrev(listName, id))
263271 let nextOrUnit = getString(this, keyListNext(listName, id))
264272 if (if ((id == valueOrElse(headOrUnit, "")))
265273 then true
266274 else (prevOrUnit != unit))
267275 then true
268276 else (nextOrUnit != unit)
269277 }
270278
271279
272280 func insertNodeActions (listName,id) = {
273281 let headOrUnit = getString(this, keyListHead(listName))
274282 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
275283 let checkNode = if (!(containsNode(listName, id)))
276284 then true
277285 else throw("Node exists")
278286 if ((checkNode == checkNode))
279287 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
280288 then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
281289 else nil)) ++ [StringEntry(keyListHead(listName), id)])
282290 else throw("Strict value is not equal to itself.")
283291 }
284292
285293
286294 func deleteNodeActions (listName,id) = {
287295 let headOrUnit = getString(this, keyListHead(listName))
288296 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
289297 let prevOrUnit = getString(this, keyListPrev(listName, id))
290298 let nextOrUnit = getString(this, keyListNext(listName, id))
291299 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
292300 then (nextOrUnit != unit)
293301 else false)
294302 then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
295303 else if ((nextOrUnit != unit))
296304 then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
297305 else if ((prevOrUnit != unit))
298306 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
299307 else if ((id == valueOrElse(headOrUnit, "")))
300308 then [DeleteEntry(keyListHead(listName))]
301309 else throw(((("invalid node: " + listName) + ".") + id))))
302310 }
303311
304312
305313 func calcWxPerLpIntegralUserLast (stakedByUser,wxPerLpIntegralUserLastUpdHeightOrZero,wxPerLpIntegralNew,wxPerLpIntegralUserLastKEY) = if (if ((wxPerLpIntegralUserLastUpdHeightOrZero == zeroBigInt))
306314 then (stakedByUser > zeroBigInt)
307315 else false)
308316 then zeroBigInt
309317 else if ((stakedByUser == zeroBigInt))
310318 then wxPerLpIntegralNew
311319 else if (if ((wxPerLpIntegralUserLastUpdHeightOrZero > zeroBigInt))
312320 then (stakedByUser > zeroBigInt)
313321 else false)
314322 then value(parseBigInt(getStringOrFail(this, wxPerLpIntegralUserLastKEY)))
315323 else throw("calcWxPerLpIntegralUserLast: unexpected state")
316324
317325
318326 func refreshPoolINTEGRALS (lpAssetIdStr,poolAddressStr,lpDeltaAmount) = {
319327 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
320328 let stakedTotal = toBigInt(readStaked(stakedTotalKEY))
321329 let nonZeroStakedTotal = if ((stakedTotal == zeroBigInt))
322330 then oneBigInt
323331 else stakedTotal
324332 let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
325333 let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
326334 let MULT3 = 1000
327335 let wxEmissionPerBlockX3 = (getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) * MULT3)
328336 let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * 3))
329337 let wxPerLpIntegralKEY = keyWxPerLpIntegral(lpAssetIdStr)
330338 let wxPerLpIntegralLastUpdHeightKEY = keyWxPerLpIntegralLastUpdHeight(lpAssetIdStr)
331339 let wxPerLpKEY = keyWxPerLp(lpAssetIdStr)
332340 let wxPerLpIntegralLastUpdHeight = getIntOrDefault(this, wxPerLpIntegralLastUpdHeightKEY, emissionStartBlock)
333341 let wxPerLpIntegral = getBigIntFromStringOrZero(this, wxPerLpIntegralKEY)
334342 let wxPerLpOrZeroX3 = 0
335343 let dh = max([(height - wxPerLpIntegralLastUpdHeight), 0])
336344 let wxPerLpX3 = if ((wxPerLpOrZeroX3 != 0))
337345 then toBigInt(wxPerLpOrZeroX3)
338346 else fraction(toBigInt(poolWxEmissionPerBlockX3), toBigInt(MULT8), nonZeroStakedTotal)
339347 let stakedTotalNew = (stakedTotal + toBigInt(lpDeltaAmount))
340348 let nonZeroStakedTotalNew = if ((stakedTotalNew == zeroBigInt))
341349 then oneBigInt
342350 else stakedTotalNew
343351 let wxPerLpIntegralNew = (wxPerLpIntegral + (wxPerLpX3 * toBigInt(dh)))
344352 let wxPerLpX3New = (toBigInt(poolWxEmissionPerBlockX3) / nonZeroStakedTotalNew)
345353 let wxPerLpIntegralLastUpdHeightNew = height
346354 let debug = makeString([toString(wxPerLpIntegralNew), toString(dh), toString(wxPerLpX3), toString(stakedTotal), toString(poolWxEmissionPerBlockX3), toString(wxEmissionPerBlockX3), toString(poolWeight)], "::")
347355 $Tuple3(wxPerLpIntegralNew, [StringEntry(wxPerLpIntegralKEY, toString(wxPerLpIntegralNew)), IntegerEntry(wxPerLpIntegralLastUpdHeightKEY, wxPerLpIntegralLastUpdHeightNew), StringEntry(wxPerLpKEY, toString(wxPerLpX3New))], debug)
348356 }
349357
350358
351359 func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
352- let $t01427414396 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
353- let wxPerLpIntegralNew = $t01427414396._1
354- let poolIntegralSTATE = $t01427414396._2
355- let poolDEBUG = $t01427414396._3
360+ let $t01475014872 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
361+ let wxPerLpIntegralNew = $t01475014872._1
362+ let poolIntegralSTATE = $t01475014872._2
363+ let poolDEBUG = $t01475014872._3
356364 let MULT3 = 1000
357365 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
358366 let stakedByUser = readStaked(stakedByUserKEY)
359367 let wxToClaimUserKEY = keyWxToClaimUser(lpAssetIdStr, userAddressStr)
360368 let wxPerLpIntegralUserLastUpdHeightKEY = keyWxPerLpIntegralUserLastUpdHeight(lpAssetIdStr, userAddressStr)
361369 let wxPerLpIntegralUserLastKEY = keyWxPerLpIntegralUserLast(lpAssetIdStr, userAddressStr)
362370 let wxToClaimUser = getBigIntFromStringOrZero(this, wxToClaimUserKEY)
363371 let wxPerLpIntegralUserLastUpdHeightOrZero = getIntOrZero(this, wxPerLpIntegralUserLastUpdHeightKEY)
364372 let wxPerLpIntegralUserLast = calcWxPerLpIntegralUserLast(toBigInt(stakedByUser), toBigInt(wxPerLpIntegralUserLastUpdHeightOrZero), wxPerLpIntegralNew, wxPerLpIntegralUserLastKEY)
365373 let MULT11 = (MULT8 * MULT3)
366374 let wxToClaimUserNew = max([(wxToClaimUser + fraction((wxPerLpIntegralNew - wxPerLpIntegralUserLast), toBigInt(stakedByUser), toBigInt(MULT11))), zeroBigInt])
367375 let wxPerLpIntegralUserLastNew = wxPerLpIntegralNew
368376 let wxPerLpIntegralUserLastUpdHeightNew = height
369377 let debug = makeString([toString(wxToClaimUser), toString(wxPerLpIntegralUserLast), toString(stakedByUser), poolDEBUG, toString(height)], "::")
370378 $Tuple3(wxToClaimUserNew, (poolIntegralSTATE ++ [StringEntry(wxToClaimUserKEY, toString(wxToClaimUserNew)), IntegerEntry(wxPerLpIntegralUserLastUpdHeightKEY, wxPerLpIntegralUserLastUpdHeightNew), StringEntry(wxPerLpIntegralUserLastKEY, toString(wxPerLpIntegralUserLastNew))]), debug)
371379 }
372380
373381
374382 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
375383 case s: String =>
376384 fromBase58String(s)
377385 case _: Unit =>
378386 unit
379387 case _ =>
380388 throw("Match error")
381389 }
382390
383391
384392 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
385393 case s: String =>
386394 fromBase58String(s)
387395 case _: Unit =>
388396 unit
389397 case _ =>
390398 throw("Match error")
391399 }
392400
393401
394402 let permissionDeniedError = throw("Permission denied")
395403
396404 func mustThis (i) = if ((i.caller == this))
397405 then true
398406 else permissionDeniedError
399407
400408
401409 func mustManager (i) = match managerPublicKeyOrUnit() {
402410 case pk: ByteVector =>
403411 if ((i.callerPublicKey == pk))
404412 then true
405413 else permissionDeniedError
406414 case _: Unit =>
407415 if ((i.caller == this))
408416 then true
409417 else permissionDeniedError
410418 case _ =>
411419 throw("Match error")
412420 }
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+ }
413451
414452
415453 @Callable(i)
416454 func constructor (factoryAddressStr) = {
417455 let checkCaller = mustManager(i)
418456 if ((checkCaller == checkCaller))
419457 then [StringEntry(keyFactoryAddress(), factoryAddressStr)]
420458 else throw("Strict value is not equal to itself.")
421459 }
422460
423461
424462
425463 @Callable(i)
426464 func constructorV2 (votingEmissionContract) = {
427465 let cheks = [mustManager(i), if ((addressFromString(votingEmissionContract) != unit))
428466 then true
429467 else "invalid voting emission contract address"]
430468 if ((cheks == cheks))
431469 then [StringEntry(keyVotingEmissionContract(), votingEmissionContract)]
432470 else throw("Strict value is not equal to itself.")
433471 }
434472
435473
436474
437475 @Callable(i)
438476 func setManager (pendingManagerPublicKey) = {
439477 let checkCaller = mustManager(i)
440478 if ((checkCaller == checkCaller))
441479 then {
442480 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
443481 if ((checkManagerPublicKey == checkManagerPublicKey))
444482 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
445483 else throw("Strict value is not equal to itself.")
446484 }
447485 else throw("Strict value is not equal to itself.")
448486 }
449487
450488
451489
452490 @Callable(i)
453491 func confirmManager () = {
454492 let pm = pendingManagerPublicKeyOrUnit()
455493 let hasPM = if (isDefined(pm))
456494 then true
457495 else throw("No pending manager")
458496 if ((hasPM == hasPM))
459497 then {
460498 let checkPM = if ((i.callerPublicKey == value(pm)))
461499 then true
462500 else throw("You are not pending manager")
463501 if ((checkPM == checkPM))
464502 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
465503 else throw("Strict value is not equal to itself.")
466504 }
467505 else throw("Strict value is not equal to itself.")
468506 }
469507
470508
471509
472510 @Callable(i)
473511 func stake () = if ((size(i.payments) != 1))
474512 then throw("invalid payment - exact one payment must be attached")
475513 else {
476514 let pmt = i.payments[0]
477515 let lpAssetId = value(pmt.assetId)
478516 let lpAssetIdStr = toBase58String(lpAssetId)
479517 let amount = pmt.amount
480518 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
481519 let callerStr = toString(i.caller)
482520 let userAddressStr = if ((callerStr == poolAddressStr))
483521 then toString(i.originCaller)
484522 else callerStr
485523 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
486524 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
487525 let stakedByUser = readStaked(stakedByUserKEY)
488526 let stakedTotal = readStaked(stakedTotalKEY)
489- let $t01883218949 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
490- let wxToClaimUserNew = $t01883218949._1
491- let integralSTATE = $t01883218949._2
492- let debug = $t01883218949._3
527+ let $t02127621393 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
528+ let wxToClaimUserNew = $t02127621393._1
529+ let integralSTATE = $t02127621393._2
530+ let debug = $t02127621393._3
493531 let listName = getUsersListName(lpAssetIdStr)
494532 let listActions = if (containsNode(listName, userAddressStr))
495533 then nil
496534 else insertNodeActions(listName, userAddressStr)
497535 (([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
498536 }
499537
500538
501539
502540 @Callable(i)
503541 func unstake (lpAssetIdStr,amount) = {
504542 let lpAssetId = fromBase58String(lpAssetIdStr)
505543 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
506- let poolAddon = valueOrElse(getString(addressFromStringValue(poolAddressStr), keyAddonAddr()), poolAddressStr)
544+ let poolAddress = addressFromStringValue(poolAddressStr)
545+ let poolAddon = valueOrElse(getString(poolAddress, keyAddonAddr()), poolAddressStr)
507546 let callerStr = toString(i.caller)
508- let userAddressStr = if (if ((callerStr == poolAddressStr))
547+ let userAddress = if (if ((callerStr == poolAddressStr))
509548 then true
510549 else (callerStr == poolAddon))
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)
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)
535567 else throw("Strict value is not equal to itself.")
536568 }
537569
538570
539571
540572 @Callable(i)
541573 func claimWx (lpAssetIdStr) = {
542574 let userAddressStr = toString(i.caller)
543- let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil)
575+ let throwIfNothingToClaim = true
576+ let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr, throwIfNothingToClaim], nil)
544577 $Tuple2(nil, result)
545578 }
546579
547580
548581
549582 @Callable(i)
550-func claimWxINTERNAL (lpAssetIdStr,userAddressStr) = {
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) = {
551594 let checkCaller = mustThis(i)
552595 if ((checkCaller == checkCaller))
553596 then {
554597 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), "claimWxINTERNAL: invalid user address")
555598 let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
556599 let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
557600 let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr)
558601 let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
559602 let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr)
560603 let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
561604 let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
562605 let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
563606 let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
564- let $t02281422926 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
565- let wxToClaimUserNew = $t02281422926._1
566- let integralSTATE = $t02281422926._2
567- let debug = $t02281422926._3
607+ let $t02477924891 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
608+ let wxToClaimUserNew = $t02477924891._1
609+ let integralSTATE = $t02477924891._2
610+ let debug = $t02477924891._3
568611 let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
569612 if ((zeroBigInt >= availableToClaim))
570- then throw("nothing to claim")
613+ then if (throwIfNothingToClaim)
614+ then throw("nothing to claim")
615+ else $Tuple2(nil, 0)
571616 else {
572617 let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
573618 let minRewardPart = availableToClaim
574619 let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
620+ let totalReward = (minRewardPart + boostRewardPart)
575621 let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
576622 let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
577623 if ((emitBoost == emitBoost))
578624 then {
579625 let claimedByUserValue = ((claimedByUser + minRewardPart) + boostRewardPart)
580626 let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
581627 let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserBoostReward + boostRewardPart)
582628 let claimedTotalPlusAvailableToClaim = (claimedTotal + availableToClaim)
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)]
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))
584630 }
585631 else throw("Strict value is not equal to itself.")
586632 }
587633 }
588634 else throw("Strict value is not equal to itself.")
589635 }
590636
591637
592638
593639 @Callable(i)
594640 func claimWxBulkInternalREADONLY (currentIter,lpAssetIds,userAddressStr,resAcc) = if ((currentIter == size(lpAssetIds)))
595641 then $Tuple2(nil, resAcc)
596642 else {
597643 let lpAssetId = lpAssetIds[currentIter]
598644 let info = split({
599645 let @ = invoke(this, "claimWxREADONLY", [lpAssetId, userAddressStr], nil)
600646 if ($isInstanceOf(@, "String"))
601647 then @
602648 else throw(($getType(@) + " couldn't be cast to String"))
603649 }, SEP)
604650 let unclaimed = info[3]
605651 let claimed = info[4]
606652 let res = (resAcc :+ makeString(["%d%d", unclaimed, claimed], SEP))
607653 let inv = {
608654 let @ = invoke(this, "claimWxBulkInternalREADONLY", [(currentIter + 1), lpAssetIds, userAddressStr, res], nil)
609655 if ($isInstanceOf(@, "List[Any]"))
610656 then @
611657 else throw(($getType(@) + " couldn't be cast to List[Any]"))
612658 }
613659 if ((inv == inv))
614660 then $Tuple2(nil, inv)
615661 else throw("Strict value is not equal to itself.")
616662 }
617663
618664
619665
620666 @Callable(i)
621667 func claimWxBulkREADONLY (lpAssetIds,userAddressStr) = {
622668 let res = invoke(this, "claimWxBulkInternalREADONLY", [0, lpAssetIds, userAddressStr, nil], nil)
623669 $Tuple2(nil, res)
624670 }
625671
626672
627673
628674 @Callable(i)
629675 func claimWxREADONLY (lpAssetIdStr,userAddressStr) = {
630676 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
631677 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
632678 let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
633679 let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
634680 let stakedByUser = readStaked(stakedByUserKEY)
635681 let stakedTotal = readStaked(stakedTotalKEY)
636682 let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
637683 let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
638684 let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
639685 let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
640686 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
641687 let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
642688 let passedBlocks = if ((emissionStartBlock > height))
643689 then 0
644690 else (height - emissionStartBlock)
645691 let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
646692 let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
647- let $t02658426696 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
648- let wxToClaimUserNew = $t02658426696._1
649- let integralSTATE = $t02658426696._2
650- let debug = $t02658426696._3
693+ let $t02870028812 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
694+ let wxToClaimUserNew = $t02870028812._1
695+ let integralSTATE = $t02870028812._2
696+ let debug = $t02870028812._3
651697 let availableToClaim = max([(wxToClaimUserNew - claimedByUserMinReward), zeroBigInt])
652698 let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
653699 let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
654700 let boostDebug = asString(boostInvResult[1])
655701 let minRewardPart = availableToClaim
656702 let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
657703 let totalReward = (minRewardPart + boostRewardPart)
658704 $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)
659713 }
660714
661715
662716
663717 @Callable(i)
664718 func usersListTraversal (lpAssetId) = {
665719 let checkCaller = if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionContract()), "")))
666720 then true
667721 else mustManager(i)
668722 if ((checkCaller == checkCaller))
669723 then {
670724 let listName = getUsersListName(lpAssetId)
671725 let userOrUnit = getString(keyNextUser(lpAssetId))
672726 let headOrUnit = getString(keyListHead(listName))
673727 match userOrUnit {
674728 case _: Unit =>
675729 match headOrUnit {
676730 case _: Unit =>
677731 $Tuple2(nil, false)
678732 case head: String =>
679733 $Tuple2([StringEntry(keyNextUser(lpAssetId), head)], true)
680734 case _ =>
681735 throw("Match error")
682736 }
683737 case userAddress: String =>
684738 let claimedByUserMinReward = getBigIntFromStringOrZero(this, keyClaimedByUserMinReward(lpAssetId, userAddress))
685739 let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetId))
686740 let wxToClaimUserNew = refreshINTEGRALS(lpAssetId, userAddress, poolAddress, 0)._1
687741 let availableToClaim = (wxToClaimUserNew - claimedByUserMinReward)
742+ let throwIfNothingToClaim = true
688743 let r = if ((availableToClaim > zeroBigInt))
689- then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress], nil)
744+ then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress, throwIfNothingToClaim], nil)
690745 else unit
691746 if ((r == r))
692747 then {
693748 let nextUserOrUnit = getString(keyListNext(listName, userAddress))
694749 match nextUserOrUnit {
695750 case _: Unit =>
696751 $Tuple2([DeleteEntry(keyNextUser(lpAssetId))], false)
697752 case nextUser: String =>
698753 $Tuple2([StringEntry(keyNextUser(lpAssetId), nextUser)], true)
699754 case _ =>
700755 throw("Match error")
701756 }
702757 }
703758 else throw("Strict value is not equal to itself.")
704759 case _ =>
705760 throw("Match error")
706761 }
707762 }
708763 else throw("Strict value is not equal to itself.")
709764 }
710765
711766
712767
713768 @Callable(i)
714769 func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
715770 then throw("permissions denied")
716771 else {
717- let $t02903229142 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
718- let wxPerLpIntegralNew = $t02903229142._1
719- let poolIntegralSTATE = $t02903229142._2
720- let poolDEBUG = $t02903229142._3
772+ let $t03141831528 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
773+ let wxPerLpIntegralNew = $t03141831528._1
774+ let poolIntegralSTATE = $t03141831528._2
775+ let poolDEBUG = $t03141831528._3
721776 poolIntegralSTATE
722777 }
723778
724779
725780 @Verifier(tx)
726781 func verify () = {
727782 let targetPublicKey = match managerPublicKeyOrUnit() {
728783 case pk: ByteVector =>
729784 pk
730785 case _: Unit =>
731786 tx.senderPublicKey
732787 case _ =>
733788 throw("Match error")
734789 }
735790 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
736791 }
737792

github/deemru/w8io/6500d08 
88.44 ms