tx · EDTfHekTcBW1zB1qPbg39UYZs8ofTjfxvjxTHax4VwEQ

3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz:  -0.02600000 Waves

2023.01.11 16:51 [2400379] smart account 3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz > SELF 0.00000000 Waves

{ "type": 13, "id": "EDTfHekTcBW1zB1qPbg39UYZs8ofTjfxvjxTHax4VwEQ", "fee": 2600000, "feeAssetId": null, "timestamp": 1673445061880, "version": 2, "chainId": 84, "sender": "3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz", "senderPublicKey": "D28XoueZWsMfm8Y5pa6C5ZFuYoWgre2Wm8tzJANJgMnq", "proofs": [ "4dhrDVFyeTpwLsuBFz5fVjdpovbB82XBTVuJbwdezJrYvyseXvkWNdVxHZsGvWBZPEeZRhNtx967S6JYhrdLBWR1" ], "script": "base64:BgJLCAISAwoBCBIDCgEIEgMKAQgSABIAEgQKAggBEgMKAQgSBAoCCAgSBgoEARgIGBIECgIYCBIECgIICBIECgIICBIDCgEIEgQKAggIYQAGU0NBTEU4AAgABU1VTFQ4AIDC1y8AB1NDQUxFMTgAEgAGTVVMVDE4CQC2AgEAgICQu7rWrfANAANTRVACAl9fAA5QT09MV0VJR0hUTVVMVAUFTVVMVDgACnplcm9CaWdJbnQJALYCAQAAAAlvbmVCaWdJbnQJALYCAQABAQd3cmFwRXJyAQNtc2cJAAIBCQC5CQIJAMwIAgINc3Rha2luZy5yaWRlOgkAzAgCCQClCAEFBHRoaXMJAMwIAgUDbXNnBQNuaWwCASABCHRocm93RXJyAQNtc2cJAAIBCQEHd3JhcEVycgEFA21zZwEJYXNBbnlMaXN0AQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAglMaXN0W0FueV0ECnZhbEFueUx5c3QFByRtYXRjaDAFCnZhbEFueUx5c3QJAAIBAhtmYWlsIHRvIGNhc3QgaW50byBMaXN0W0FueV0BBWFzSW50AQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAgNJbnQEBnZhbEludAUHJG1hdGNoMAUGdmFsSW50CQACAQIVZmFpbCB0byBjYXN0IGludG8gSW50AQhhc1N0cmluZwEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAZ2YWxTdHIFByRtYXRjaDAFBnZhbFN0cgkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEMYXNCeXRlVmVjdG9yAQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAZ2YWxCaW4FByRtYXRjaDAFBnZhbEJpbgkAAgECFWZhaWwgdG8gY2FzdCBpbnRvIEludAEPZ2V0U3RyaW5nT3JGYWlsAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFB2FkZHJlc3MFA2tleQkArAICCQCsAgICD21hbmRhdG9yeSB0aGlzLgUDa2V5Ag8gaXMgbm90IGRlZmluZWQBGGdldFN0cmluZ0J5QWRkcmVzc09yRmFpbAIHYWRkcmVzcwNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQdhZGRyZXNzBQNrZXkJAKwCAgkArAICCQCsAgIJAKwCAgIKbWFuZGF0b3J5IAkApQgBBQdhZGRyZXNzAgEuBQNrZXkCDyBpcyBub3QgZGVmaW5lZAEMZ2V0SW50T3JaZXJvAgdhZGRyZXNzA2tleQkBC3ZhbHVlT3JFbHNlAgkAmggCBQdhZGRyZXNzBQNrZXkAAAEPZ2V0SW50T3JEZWZhdWx0AwdhZGRyZXNzA2tleQpkZWZhdWx0VmFsCQELdmFsdWVPckVsc2UCCQCaCAIFB2FkZHJlc3MFA2tleQUKZGVmYXVsdFZhbAEMZ2V0SW50T3JGYWlsAgdhZGRyZXNzA2tleQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFB2FkZHJlc3MFA2tleQkArAICCQCsAgICD21hbmRhdG9yeSB0aGlzLgUDa2V5Ag8gaXMgbm90IGRlZmluZWQBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CB2FkZHJlc3MDa2V5CQEFdmFsdWUBCQCoAwEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUHYWRkcmVzcwUDa2V5AgEwARxnZXRCaWdJbnRGcm9tU3RyaW5nT3JEZWZhdWx0AwdhZGRyZXNzA2tleQpkZWZhdWx0VmFsBAckbWF0Y2gwCQCdCAIFB2FkZHJlc3MFA2tleQMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJAQV2YWx1ZQEJAKgDAQUBcwMJAAECBQckbWF0Y2gwAgRVbml0BQpkZWZhdWx0VmFsCQACAQILTWF0Y2ggZXJyb3IBBXRvWDE4AgdvcmlnVmFsDW9yaWdTY2FsZU11bHQJALwCAwkAtgIBBQdvcmlnVmFsBQZNVUxUMTgJALYCAQUNb3JpZ1NjYWxlTXVsdAEHZnJvbVgxOAIDdmFsD3Jlc3VsdFNjYWxlTXVsdAkAoAMBCQC8AgMFA3ZhbAkAtgIBBQ9yZXN1bHRTY2FsZU11bHQFBk1VTFQxOAERa2V5RmFjdG9yeUFkZHJlc3MAAhwlcyVzX19jb25maWdfX2ZhY3RvcnlBZGRyZXNzARlrZXlWb3RpbmdFbWlzc2lvbkNvbnRyYWN0AAIaJXNfX3ZvdGluZ0VtaXNzaW9uQ29udHJhY3QAGElkeEZhY3RvcnlDZmdTdGFraW5nRGFwcAABABlJZHhGYWN0b3J5Q2ZnQm9vc3RpbmdEYXBwAAIAFElkeEZhY3RvcnlDZmdJZG9EYXBwAAMAFUlkeEZhY3RvcnlDZmdUZWFtRGFwcAAEABlJZHhGYWN0b3J5Q2ZnRW1pc3Npb25EYXBwAAUAFUlkeEZhY3RvcnlDZmdSZXN0RGFwcAAGABlJZHhGYWN0b3J5Q2ZnU2xpcHBhZ2VEYXBwAAcBDWtleUZhY3RvcnlDZmcAAhElc19fZmFjdG9yeUNvbmZpZwETa2V5TWFuYWdlclB1YmxpY0tleQACFCVzX19tYW5hZ2VyUHVibGljS2V5ARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQACGyVzX19wZW5kaW5nTWFuYWdlclB1YmxpY0tleQEWa2V5U3RhYmxlUG9vbEFkZG9uQWRkcgACFyVzX19zdGFibGVQb29sQWRkb25BZGRyAQxrZXlBZGRvbkFkZHIAAg0lc19fYWRkb25BZGRyARprZXlGYWN0b3J5THAyQXNzZXRzTWFwcGluZwEKbHBBc3NldFN0cgkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQpscEFzc2V0U3RyCQDMCAICHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUDbmlsBQNTRVABEGtleUZhY3RvcnlMcExpc3QAAhAlc19fbHBUb2tlbnNMaXN0ASZrZXlGYWN0b3J5THBBc3NldFRvUG9vbENvbnRyYWN0QWRkcmVzcwEKbHBBc3NldFN0cgkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQpscEFzc2V0U3RyCQDMCAICHm1hcHBpbmdzX19scEFzc2V0MlBvb2xDb250cmFjdAUDbmlsBQNTRVABFGtleUZhY3RvcnlQb29sV2VpZ2h0AQ9jb250cmFjdEFkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAICCnBvb2xXZWlnaHQJAMwIAgUPY29udHJhY3RBZGRyZXNzBQNuaWwFA1NFUAEKcmVhZExwTGlzdAEHZmFjdG9yeQkAtQkCCQELdmFsdWVPckVsc2UCCQCdCAIFB2ZhY3RvcnkJARBrZXlGYWN0b3J5THBMaXN0AAIABQNTRVABFHJlYWRGYWN0b3J5Q2ZnT3JGYWlsAQdmYWN0b3J5CQC1CQIJARhnZXRTdHJpbmdCeUFkZHJlc3NPckZhaWwCBQdmYWN0b3J5CQENa2V5RmFjdG9yeUNmZwAFA1NFUAEYZ2V0Qm9vc3RpbmdBZGRyZXNzT3JGYWlsAQpmYWN0b3J5Q2ZnCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFCmZhY3RvcnlDZmcFGUlkeEZhY3RvcnlDZmdCb29zdGluZ0RhcHABGGdldEVtaXNzaW9uQWRkcmVzc09yRmFpbAEKZmFjdG9yeUNmZwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQpmYWN0b3J5Q2ZnBRlJZHhGYWN0b3J5Q2ZnRW1pc3Npb25EYXBwARdnZXRTdGFraW5nQWRkcmVzc09yRmFpbAEKZmFjdG9yeUNmZwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQpmYWN0b3J5Q2ZnBRhJZHhGYWN0b3J5Q2ZnU3Rha2luZ0RhcHABHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAACGyVzJXNfX3JhdGVQZXJCbG9ja19fY3VycmVudAEha2V5RW1pc3Npb25SYXRlUGVyQmxvY2tNYXhDdXJyZW50AAIeJXMlc19fcmF0ZVBlckJsb2NrTWF4X19jdXJyZW50ARVrZXlFbWlzc2lvblN0YXJ0QmxvY2sAAholcyVzX19lbWlzc2lvbl9fc3RhcnRCbG9jawEba2V5RW1pc3Npb25EdXJhdGlvbkluQmxvY2tzAAIYJXMlc19fZW1pc3Npb25fX2R1cmF0aW9uARNrZXlFbWlzc2lvbkVuZEJsb2NrAAIYJXMlc19fZW1pc3Npb25fX2VuZEJsb2NrAQ9rZXlTdGFrZWRCeVVzZXICDnVzZXJBZGRyZXNzU3RyDGxwQXNzZXRJZFN0cgkAuQkCCQDMCAICDiVzJXMlc19fc3Rha2VkCQDMCAIFDnVzZXJBZGRyZXNzU3RyCQDMCAIFDGxwQXNzZXRJZFN0cgUDbmlsBQNTRVABDmtleVN0YWtlZFRvdGFsAQxscEFzc2V0SWRTdHIJAKwCAgIXJXMlcyVzX19zdGFrZWRfX3RvdGFsX18FDGxwQXNzZXRJZFN0cgEQa2V5Q2xhaW1lZEJ5VXNlcgIMbHBBc3NldElkU3RyDnVzZXJBZGRyZXNzU3RyCQC5CQIJAMwIAgIPJXMlcyVzX19jbGFpbWVkCQDMCAIFDnVzZXJBZGRyZXNzU3RyCQDMCAIFDGxwQXNzZXRJZFN0cgUDbmlsBQNTRVABGWtleUNsYWltZWRCeVVzZXJNaW5SZXdhcmQCDGxwQXNzZXRJZFN0cg51c2VyQWRkcmVzc1N0cgkAuQkCCQDMCAICGCVzJXMlc19fY2xhaW1lZE1pblJld2FyZAkAzAgCBQ51c2VyQWRkcmVzc1N0cgkAzAgCBQxscEFzc2V0SWRTdHIFA25pbAUDU0VQARtrZXlDbGFpbWVkQnlVc2VyQm9vc3RSZXdhcmQCDGxwQXNzZXRJZFN0cg51c2VyQWRkcmVzc1N0cgkAuQkCCQDMCAICGiVzJXMlc19fY2xhaW1lZEJvb3N0UmV3YXJkCQDMCAIFDnVzZXJBZGRyZXNzU3RyCQDMCAIFDGxwQXNzZXRJZFN0cgUDbmlsBQNTRVABD2tleUNsYWltZWRUb3RhbAEMbHBBc3NldElkU3RyCQC5CQIJAMwIAgIWJXMlcyVzX19jbGFpbWVkX190b3RhbAkAzAgCBQxscEFzc2V0SWRTdHIFA25pbAUDU0VQAQpyZWFkU3Rha2VkAQNrZXkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUDa2V5AAABFWtleUxhc3RUb3RhbExwQmFsYW5jZQEJbHBBc3NldElkCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCAgV0b3RhbAkAzAgCAgNiYWwFA25pbAUDU0VQARRrZXlMYXN0VXNlckxwQmFsYW5jZQIJbHBBc3NldElkC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCAgNiYWwFA25pbAUDU0VQARlrZXlUb3RhbExwQmFsYW5jZUludGVncmFsAQlscEFzc2V0SWQJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUJbHBBc3NldElkCQDMCAICBXRvdGFsCQDMCAICBmJhbElOVAUDbmlsBQNTRVABGGtleVVzZXJMcEJhbGFuY2VJbnRlZ3JhbAIJbHBBc3NldElkC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCAgZiYWxJTlQFA25pbAUDU0VQASZrZXlUb3RhbExwQmFsYW5jZUludGVncmFsTGFzdFVwZEhlaWdodAEJbHBBc3NldElkCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCAgV0b3RhbAkAzAgCAgdsYXN0VXBkBQNuaWwFA1NFUAEla2V5VXNlckxwQmFsYW5jZUludGVncmFsTGFzdFVwZEhlaWdodAIJbHBBc3NldElkC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCAgdsYXN0VXBkBQNuaWwFA1NFUAESa2V5V3hQZXJMcEludGVncmFsAQlscEFzc2V0SWQJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCBQlscEFzc2V0SWQJAMwIAgIGY29tbW9uCQDMCAICBWxwSW50BQNuaWwFA1NFUAEfa2V5V3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodAEJbHBBc3NldElkCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgUJbHBBc3NldElkCQDMCAICBmNvbW1vbgkAzAgCAgZscEludEgFA25pbAUDU0VQARBrZXlXeFRvQ2xhaW1Vc2VyAglscEFzc2V0SWQLdXNlckFkZHJlc3MJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCBQlscEFzc2V0SWQJAMwIAgULdXNlckFkZHJlc3MJAMwIAgIFbHBJbnQFA25pbAUDU0VQASNrZXlXeFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodAIJbHBBc3NldElkC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgUJbHBBc3NldElkCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAICBmxwSW50SAUDbmlsBQNTRVABCmtleVd4UGVyTHABCWxwQXNzZXRJZAkAuQkCCQDMCAICAiVzCQDMCAIFCWxwQXNzZXRJZAkAzAgCAgd3eFBlckxwBQNuaWwFA1NFUAENa2V5V3hQZXJMcFgxOAEJbHBBc3NldElkCQC5CQIJAMwIAgICJXMJAMwIAgUJbHBBc3NldElkCQDMCAICCnd4UGVyTHBYMTgFA25pbAUDU0VQARprZXlXeFBlckxwSW50ZWdyYWxVc2VyTGFzdAIJbHBBc3NldElkC3VzZXJBZGRyZXNzCQC5CQIJAMwIAgIIJXMlcyVzJXMJAMwIAgUJbHBBc3NldElkCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAICBXVJbnRMBQNuaWwFA1NFUAEZa2V5T3BlcmF0aW9uSGlzdG9yeVJlY29yZAMEdHlwZQt1c2VyQWRkcmVzcwZ0eElkNTgJALkJAgkAzAgCAhElcyVzJXMlc19faGlzdG9yeQkAzAgCBQR0eXBlCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIFBnR4SWQ1OAUDbmlsBQNTRVABE2Zvcm1hdEhpc3RvcnlSZWNvcmQEC3VzZXJBZGRyZXNzCWxwQXNzZXRJZAR0eXBlBmFtb3VudAkAuQkCCQDMCAICDCVzJXMlcyVkJWQlZAkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCBQlscEFzc2V0SWQJAMwIAgUEdHlwZQkAzAgCCQCkAwEFBmhlaWdodAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAKQDAQUGYW1vdW50BQNuaWwFA1NFUAEVT3BlcmF0aW9uSGlzdG9yeUVudHJ5BQR0eXBlC3VzZXJBZGRyZXNzCWxwQXNzZXRJZAZhbW91bnQEdHhJZAkBC1N0cmluZ0VudHJ5AgkBGWtleU9wZXJhdGlvbkhpc3RvcnlSZWNvcmQDBQR0eXBlBQt1c2VyQWRkcmVzcwkA2AQBBQR0eElkCQETZm9ybWF0SGlzdG9yeVJlY29yZAQFC3VzZXJBZGRyZXNzBQlscEFzc2V0SWQFBHR5cGUFBmFtb3VudAAOZmFjdG9yeUFkZHJlc3MJAQ9nZXRTdHJpbmdPckZhaWwCBQR0aGlzCQERa2V5RmFjdG9yeUFkZHJlc3MAAA9mYWN0b3J5Q29udHJhY3QJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDmZhY3RvcnlBZGRyZXNzAApmYWN0b3J5Q2ZnCQEUcmVhZEZhY3RvcnlDZmdPckZhaWwBBQ9mYWN0b3J5Q29udHJhY3QAEGVtaXNzaW9uQ29udHJhY3QJARhnZXRFbWlzc2lvbkFkZHJlc3NPckZhaWwBBQpmYWN0b3J5Q2ZnABBib29zdGluZ0NvbnRyYWN0CQEYZ2V0Qm9vc3RpbmdBZGRyZXNzT3JGYWlsAQUKZmFjdG9yeUNmZwAWbHBTdGFraW5nUG9vbHNDb250cmFjdAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBCQC5CQIJAMwIAgICJXMJAMwIAgIWbHBTdGFraW5nUG9vbHNDb250cmFjdAUDbmlsBQNTRVAJAQd3cmFwRXJyAQIubHBfc3Rha2luZ19wb29scyBjb250cmFjdCBhZGRyZXNzIGlzIHVuZGVmaW5lZAkBB3dyYXBFcnIBAilpbnZhbGlkIGxwX3N0YWtpbmdfcG9vbHMgY29udHJhY3QgYWRkcmVzcwELa2V5TmV4dFVzZXIBCWxwQXNzZXRJZAkAuQkCCQDMCAICBCVzJXMJAMwIAgUJbHBBc3NldElkCQDMCAICCG5leHRVc2VyBQNuaWwFA1NFUAEQZ2V0VXNlcnNMaXN0TmFtZQEJbHBBc3NldElkCQC5CQIJAMwIAgIFdXNlcnMJAMwIAgUJbHBBc3NldElkBQNuaWwFA1NFUAELa2V5TGlzdEhlYWQBCGxpc3ROYW1lCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAIFCGxpc3ROYW1lCQDMCAICBGhlYWQFA25pbAUDU0VQAQtrZXlMaXN0U2l6ZQEIbGlzdE5hbWUJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgUIbGlzdE5hbWUJAMwIAgIEc2l6ZQUDbmlsBQNTRVABC2tleUxpc3RQcmV2AghsaXN0TmFtZQJpZAkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAIFCGxpc3ROYW1lCQDMCAIFAmlkCQDMCAICBHByZXYFA25pbAUDU0VQAQtrZXlMaXN0TmV4dAIIbGlzdE5hbWUCaWQJALkJAgkAzAgCAgglcyVzJXMlcwkAzAgCBQhsaXN0TmFtZQkAzAgCBQJpZAkAzAgCAgRuZXh0BQNuaWwFA1NFUAEMY29udGFpbnNOb2RlAghsaXN0TmFtZQJpZAQKaGVhZE9yVW5pdAkAnQgCBQR0aGlzCQELa2V5TGlzdEhlYWQBBQhsaXN0TmFtZQQKcHJldk9yVW5pdAkAnQgCBQR0aGlzCQELa2V5TGlzdFByZXYCBQhsaXN0TmFtZQUCaWQECm5leHRPclVuaXQJAJ0IAgUEdGhpcwkBC2tleUxpc3ROZXh0AgUIbGlzdE5hbWUFAmlkAwMJAAACBQJpZAkBC3ZhbHVlT3JFbHNlAgUKaGVhZE9yVW5pdAIABgkBAiE9AgUKcHJldk9yVW5pdAUEdW5pdAYJAQIhPQIFCm5leHRPclVuaXQFBHVuaXQBEWluc2VydE5vZGVBY3Rpb25zAghsaXN0TmFtZQJpZAQKaGVhZE9yVW5pdAkAnQgCBQR0aGlzCQELa2V5TGlzdEhlYWQBBQhsaXN0TmFtZQQIbGlzdFNpemUJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBC2tleUxpc3RTaXplAQUIbGlzdE5hbWUAAAQJY2hlY2tOb2RlAwkBASEBCQEMY29udGFpbnNOb2RlAgUIbGlzdE5hbWUFAmlkBgkAAgECC05vZGUgZXhpc3RzAwkAAAIFCWNoZWNrTm9kZQUJY2hlY2tOb2RlCQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBC2tleUxpc3RTaXplAQUIbGlzdE5hbWUJAGQCBQhsaXN0U2l6ZQABBQNuaWwDCQECIT0CBQpoZWFkT3JVbml0BQR1bml0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQtrZXlMaXN0TmV4dAIFCGxpc3ROYW1lBQJpZAkBBXZhbHVlAQUKaGVhZE9yVW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQELa2V5TGlzdFByZXYCBQhsaXN0TmFtZQkBBXZhbHVlAQUKaGVhZE9yVW5pdAUCaWQFA25pbAUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQtrZXlMaXN0SGVhZAEFCGxpc3ROYW1lBQJpZAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuARFkZWxldGVOb2RlQWN0aW9ucwIIbGlzdE5hbWUCaWQECmhlYWRPclVuaXQJAJ0IAgUEdGhpcwkBC2tleUxpc3RIZWFkAQUIbGlzdE5hbWUECGxpc3RTaXplCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQtrZXlMaXN0U2l6ZQEFCGxpc3ROYW1lAAAECnByZXZPclVuaXQJAJ0IAgUEdGhpcwkBC2tleUxpc3RQcmV2AgUIbGlzdE5hbWUFAmlkBApuZXh0T3JVbml0CQCdCAIFBHRoaXMJAQtrZXlMaXN0TmV4dAIFCGxpc3ROYW1lBQJpZAkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQELa2V5TGlzdFNpemUBBQhsaXN0TmFtZQkAZQIFCGxpc3RTaXplAAEFA25pbAMDCQECIT0CBQpwcmV2T3JVbml0BQR1bml0CQECIT0CBQpuZXh0T3JVbml0BQR1bml0BwkAzAgCCQELU3RyaW5nRW50cnkCCQELa2V5TGlzdE5leHQCBQhsaXN0TmFtZQkBBXZhbHVlAQUKcHJldk9yVW5pdAkBBXZhbHVlAQUKbmV4dE9yVW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQELa2V5TGlzdFByZXYCBQhsaXN0TmFtZQkBBXZhbHVlAQUKbmV4dE9yVW5pdAkBBXZhbHVlAQUKcHJldk9yVW5pdAkAzAgCCQELRGVsZXRlRW50cnkBCQELa2V5TGlzdFByZXYCBQhsaXN0TmFtZQUCaWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBC2tleUxpc3ROZXh0AgUIbGlzdE5hbWUFAmlkBQNuaWwDCQECIT0CBQpuZXh0T3JVbml0BQR1bml0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQtrZXlMaXN0SGVhZAEFCGxpc3ROYW1lCQEFdmFsdWUBBQpuZXh0T3JVbml0CQDMCAIJAQtEZWxldGVFbnRyeQEJAQtrZXlMaXN0TmV4dAIFCGxpc3ROYW1lBQJpZAkAzAgCCQELRGVsZXRlRW50cnkBCQELa2V5TGlzdFByZXYCBQhsaXN0TmFtZQkBBXZhbHVlAQUKbmV4dE9yVW5pdAUDbmlsAwkBAiE9AgUKcHJldk9yVW5pdAUEdW5pdAkAzAgCCQELRGVsZXRlRW50cnkBCQELa2V5TGlzdFByZXYCBQhsaXN0TmFtZQUCaWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBC2tleUxpc3ROZXh0AgUIbGlzdE5hbWUJAQV2YWx1ZQEFCnByZXZPclVuaXQFA25pbAMJAAACBQJpZAkBC3ZhbHVlT3JFbHNlAgUKaGVhZE9yVW5pdAIACQDMCAIJAQtEZWxldGVFbnRyeQEJAQtrZXlMaXN0SGVhZAEFCGxpc3ROYW1lBQNuaWwJAAIBCQCsAgIJAKwCAgkArAICAg5pbnZhbGlkIG5vZGU6IAUIbGlzdE5hbWUCAS4FAmlkARtjYWxjV3hQZXJMcEludGVncmFsVXNlckxhc3QEDHN0YWtlZEJ5VXNlciZ3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE9yWmVybxJ3eFBlckxwSW50ZWdyYWxOZXcad3hQZXJMcEludGVncmFsVXNlckxhc3RLRVkDAwkAAAIFJnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0T3JaZXJvBQp6ZXJvQmlnSW50CQC/AgIFDHN0YWtlZEJ5VXNlcgUKemVyb0JpZ0ludAcFCnplcm9CaWdJbnQDCQAAAgUMc3Rha2VkQnlVc2VyBQp6ZXJvQmlnSW50BRJ3eFBlckxwSW50ZWdyYWxOZXcDAwkAvwICBSZ3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE9yWmVybwUKemVyb0JpZ0ludAkAvwICBQxzdGFrZWRCeVVzZXIFCnplcm9CaWdJbnQHCQEFdmFsdWUBCQCoAwEJAQ9nZXRTdHJpbmdPckZhaWwCBQR0aGlzBRp3eFBlckxwSW50ZWdyYWxVc2VyTGFzdEtFWQkAAgECLWNhbGNXeFBlckxwSW50ZWdyYWxVc2VyTGFzdDogdW5leHBlY3RlZCBzdGF0ZQEUcmVmcmVzaFBvb2xJTlRFR1JBTFMDDGxwQXNzZXRJZFN0cg5wb29sQWRkcmVzc1N0cg1scERlbHRhQW1vdW50BA5zdGFrZWRUb3RhbEtFWQkBDmtleVN0YWtlZFRvdGFsAQUMbHBBc3NldElkU3RyBAtzdGFrZWRUb3RhbAkAtgIBCQEKcmVhZFN0YWtlZAEFDnN0YWtlZFRvdGFsS0VZBBJub25aZXJvU3Rha2VkVG90YWwDCQAAAgULc3Rha2VkVG90YWwFCnplcm9CaWdJbnQFCW9uZUJpZ0ludAULc3Rha2VkVG90YWwECnBvb2xXZWlnaHQJARFAZXh0ck5hdGl2ZSgxMDUwKQIFD2ZhY3RvcnlDb250cmFjdAkBFGtleUZhY3RvcnlQb29sV2VpZ2h0AQUOcG9vbEFkZHJlc3NTdHIEEmVtaXNzaW9uU3RhcnRCbG9jawkBDGdldEludE9yRmFpbAIFEGVtaXNzaW9uQ29udHJhY3QJARVrZXlFbWlzc2lvblN0YXJ0QmxvY2sABAVNVUxUMwDoBwQUd3hFbWlzc2lvblBlckJsb2NrWDMJAGgCCQEMZ2V0SW50T3JGYWlsAgUQZW1pc3Npb25Db250cmFjdAkBHmtleUVtaXNzaW9uUmF0ZVBlckJsb2NrQ3VycmVudAAFBU1VTFQzBBhwb29sV3hFbWlzc2lvblBlckJsb2NrWDMJAGsDBRR3eEVtaXNzaW9uUGVyQmxvY2tYMwUKcG9vbFdlaWdodAkAaAIFDlBPT0xXRUlHSFRNVUxUAAMEEnd4UGVyTHBJbnRlZ3JhbEtFWQkBEmtleVd4UGVyTHBJbnRlZ3JhbAEFDGxwQXNzZXRJZFN0cgQfd3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodEtFWQkBH2tleVd4UGVyTHBJbnRlZ3JhbExhc3RVcGRIZWlnaHQBBQxscEFzc2V0SWRTdHIECnd4UGVyTHBLRVkJAQprZXlXeFBlckxwAQUMbHBBc3NldElkU3RyBBx3eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0CQEPZ2V0SW50T3JEZWZhdWx0AwUEdGhpcwUfd3hQZXJMcEludGVncmFsTGFzdFVwZEhlaWdodEtFWQUSZW1pc3Npb25TdGFydEJsb2NrBA93eFBlckxwSW50ZWdyYWwJARlnZXRCaWdJbnRGcm9tU3RyaW5nT3JaZXJvAgUEdGhpcwUSd3hQZXJMcEludGVncmFsS0VZBA93eFBlckxwT3JaZXJvWDMAAAQCZGgJAJYDAQkAzAgCCQBlAgUGaGVpZ2h0BRx3eFBlckxwSW50ZWdyYWxMYXN0VXBkSGVpZ2h0CQDMCAIAAAUDbmlsBAl3eFBlckxwWDMDCQECIT0CBQ93eFBlckxwT3JaZXJvWDMAAAkAtgIBBQ93eFBlckxwT3JaZXJvWDMJALwCAwkAtgIBBRhwb29sV3hFbWlzc2lvblBlckJsb2NrWDMJALYCAQUFTVVMVDgFEm5vblplcm9TdGFrZWRUb3RhbAQOc3Rha2VkVG90YWxOZXcJALcCAgULc3Rha2VkVG90YWwJALYCAQUNbHBEZWx0YUFtb3VudAQVbm9uWmVyb1N0YWtlZFRvdGFsTmV3AwkAAAIFDnN0YWtlZFRvdGFsTmV3BQp6ZXJvQmlnSW50BQlvbmVCaWdJbnQFDnN0YWtlZFRvdGFsTmV3BBJ3eFBlckxwSW50ZWdyYWxOZXcJALcCAgUPd3hQZXJMcEludGVncmFsCQC5AgIFCXd4UGVyTHBYMwkAtgIBBQJkaAQMd3hQZXJMcFgzTmV3CQC6AgIJALYCAQUYcG9vbFd4RW1pc3Npb25QZXJCbG9ja1gzBRVub25aZXJvU3Rha2VkVG90YWxOZXcEH3d4UGVyTHBJbnRlZ3JhbExhc3RVcGRIZWlnaHROZXcFBmhlaWdodAQFZGVidWcJALkJAgkAzAgCCQCmAwEFEnd4UGVyTHBJbnRlZ3JhbE5ldwkAzAgCCQCkAwEFAmRoCQDMCAIJAKYDAQUJd3hQZXJMcFgzCQDMCAIJAKYDAQULc3Rha2VkVG90YWwJAMwIAgkApAMBBRhwb29sV3hFbWlzc2lvblBlckJsb2NrWDMJAMwIAgkApAMBBRR3eEVtaXNzaW9uUGVyQmxvY2tYMwkAzAgCCQCkAwEFCnBvb2xXZWlnaHQFA25pbAICOjoJAJUKAwUSd3hQZXJMcEludGVncmFsTmV3CQDMCAIJAQtTdHJpbmdFbnRyeQIFEnd4UGVyTHBJbnRlZ3JhbEtFWQkApgMBBRJ3eFBlckxwSW50ZWdyYWxOZXcJAMwIAgkBDEludGVnZXJFbnRyeQIFH3d4UGVyTHBJbnRlZ3JhbExhc3RVcGRIZWlnaHRLRVkFH3d4UGVyTHBJbnRlZ3JhbExhc3RVcGRIZWlnaHROZXcJAMwIAgkBC1N0cmluZ0VudHJ5AgUKd3hQZXJMcEtFWQkApgMBBQx3eFBlckxwWDNOZXcFA25pbAUFZGVidWcBEHJlZnJlc2hJTlRFR1JBTFMEDGxwQXNzZXRJZFN0cg51c2VyQWRkcmVzc1N0cg5wb29sQWRkcmVzc1N0cg1scERlbHRhQW1vdW50BA0kdDAxNDc1ODE0ODgwCQEUcmVmcmVzaFBvb2xJTlRFR1JBTFMDBQxscEFzc2V0SWRTdHIFDnBvb2xBZGRyZXNzU3RyBQ1scERlbHRhQW1vdW50BBJ3eFBlckxwSW50ZWdyYWxOZXcIBQ0kdDAxNDc1ODE0ODgwAl8xBBFwb29sSW50ZWdyYWxTVEFURQgFDSR0MDE0NzU4MTQ4ODACXzIECXBvb2xERUJVRwgFDSR0MDE0NzU4MTQ4ODACXzMEBU1VTFQzAOgHBA9zdGFrZWRCeVVzZXJLRVkJAQ9rZXlTdGFrZWRCeVVzZXICBQ51c2VyQWRkcmVzc1N0cgUMbHBBc3NldElkU3RyBAxzdGFrZWRCeVVzZXIJAQpyZWFkU3Rha2VkAQUPc3Rha2VkQnlVc2VyS0VZBBB3eFRvQ2xhaW1Vc2VyS0VZCQEQa2V5V3hUb0NsYWltVXNlcgIFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIEI3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0S0VZCQEja2V5V3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHQCBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBBp3eFBlckxwSW50ZWdyYWxVc2VyTGFzdEtFWQkBGmtleVd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0AgUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgQNd3hUb0NsYWltVXNlcgkBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CBQR0aGlzBRB3eFRvQ2xhaW1Vc2VyS0VZBCZ3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE9yWmVybwkBDGdldEludE9yWmVybwIFBHRoaXMFI3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0S0VZBBd3eFBlckxwSW50ZWdyYWxVc2VyTGFzdAkBG2NhbGNXeFBlckxwSW50ZWdyYWxVc2VyTGFzdAQJALYCAQUMc3Rha2VkQnlVc2VyCQC2AgEFJnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0T3JaZXJvBRJ3eFBlckxwSW50ZWdyYWxOZXcFGnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0S0VZBAZNVUxUMTEJAGgCBQVNVUxUOAUFTVVMVDMEEHd4VG9DbGFpbVVzZXJOZXcJAJgDAQkAzAgCCQC3AgIFDXd4VG9DbGFpbVVzZXIJALwCAwkAuAICBRJ3eFBlckxwSW50ZWdyYWxOZXcFF3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0CQC2AgEFDHN0YWtlZEJ5VXNlcgkAtgIBBQZNVUxUMTEJAMwIAgUKemVyb0JpZ0ludAUDbmlsBBp3eFBlckxwSW50ZWdyYWxVc2VyTGFzdE5ldwUSd3hQZXJMcEludGVncmFsTmV3BCN3eFBlckxwSW50ZWdyYWxVc2VyTGFzdFVwZEhlaWdodE5ldwUGaGVpZ2h0BAVkZWJ1ZwkAuQkCCQDMCAIJAKYDAQUNd3hUb0NsYWltVXNlcgkAzAgCCQCmAwEFF3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0CQDMCAIJAKQDAQUMc3Rha2VkQnlVc2VyCQDMCAIFCXBvb2xERUJVRwkAzAgCCQCkAwEFBmhlaWdodAUDbmlsAgI6OgkAlQoDBRB3eFRvQ2xhaW1Vc2VyTmV3CQDOCAIFEXBvb2xJbnRlZ3JhbFNUQVRFCQDMCAIJAQtTdHJpbmdFbnRyeQIFEHd4VG9DbGFpbVVzZXJLRVkJAKYDAQUQd3hUb0NsYWltVXNlck5ldwkAzAgCCQEMSW50ZWdlckVudHJ5AgUjd3hQZXJMcEludGVncmFsVXNlckxhc3RVcGRIZWlnaHRLRVkFI3d4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0VXBkSGVpZ2h0TmV3CQDMCAIJAQtTdHJpbmdFbnRyeQIFGnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0S0VZCQCmAwEFGnd4UGVyTHBJbnRlZ3JhbFVzZXJMYXN0TmV3BQNuaWwFBWRlYnVnARZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAQHJG1hdGNoMAkAoggBCQETa2V5TWFuYWdlclB1YmxpY0tleQADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQDZBAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAR1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdAAEByRtYXRjaDAJAKIIAQkBGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAXMFByRtYXRjaDAJANkEAQUBcwMJAAECBQckbWF0Y2gwAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IAFXBlcm1pc3Npb25EZW5pZWRFcnJvcgkAAgECEVBlcm1pc3Npb24gZGVuaWVkAQhtdXN0VGhpcwEBaQMJAAACCAUBaQZjYWxsZXIFBHRoaXMGBRVwZXJtaXNzaW9uRGVuaWVkRXJyb3IBC211c3RNYW5hZ2VyAQFpBAckbWF0Y2gwCQEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAADCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCcGsFByRtYXRjaDADCQAAAggFAWkPY2FsbGVyUHVibGljS2V5BQJwawYFFXBlcm1pc3Npb25EZW5pZWRFcnJvcgMJAAECBQckbWF0Y2gwAgRVbml0AwkAAAIIBQFpBmNhbGxlcgUEdGhpcwYFFXBlcm1pc3Npb25EZW5pZWRFcnJvcgkAAgECC01hdGNoIGVycm9yDgFpAQtjb25zdHJ1Y3RvcgERZmFjdG9yeUFkZHJlc3NTdHIEC2NoZWNrQ2FsbGVyCQELbXVzdE1hbmFnZXIBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgkAzAgCCQELU3RyaW5nRW50cnkCCQERa2V5RmFjdG9yeUFkZHJlc3MABRFmYWN0b3J5QWRkcmVzc1N0cgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDWNvbnN0cnVjdG9yVjIBFnZvdGluZ0VtaXNzaW9uQ29udHJhY3QEBWNoZWtzCQDMCAIJAQttdXN0TWFuYWdlcgEFAWkJAMwIAgMJAQIhPQIJAKYIAQUWdm90aW5nRW1pc3Npb25Db250cmFjdAUEdW5pdAYCKGludmFsaWQgdm90aW5nIGVtaXNzaW9uIGNvbnRyYWN0IGFkZHJlc3MFA25pbAMJAAACBQVjaGVrcwUFY2hla3MJAMwIAgkBC1N0cmluZ0VudHJ5AgkBGWtleVZvdGluZ0VtaXNzaW9uQ29udHJhY3QABRZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEKc2V0TWFuYWdlcgEXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkEC2NoZWNrQ2FsbGVyCQELbXVzdE1hbmFnZXIBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQVY2hlY2tNYW5hZ2VyUHVibGljS2V5CQDZBAEFF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AwkAAAIFFWNoZWNrTWFuYWdlclB1YmxpY0tleQUVY2hlY2tNYW5hZ2VyUHVibGljS2V5CQDMCAIJAQtTdHJpbmdFbnRyeQIJARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQAFF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEOY29uZmlybU1hbmFnZXIABAJwbQkBHXBlbmRpbmdNYW5hZ2VyUHVibGljS2V5T3JVbml0AAQFaGFzUE0DCQEJaXNEZWZpbmVkAQUCcG0GCQACAQISTm8gcGVuZGluZyBtYW5hZ2VyAwkAAAIFBWhhc1BNBQVoYXNQTQQHY2hlY2tQTQMJAAACCAUBaQ9jYWxsZXJQdWJsaWNLZXkJAQV2YWx1ZQEFAnBtBgkAAgECG1lvdSBhcmUgbm90IHBlbmRpbmcgbWFuYWdlcgMJAAACBQdjaGVja1BNBQdjaGVja1BNCQDMCAIJAQtTdHJpbmdFbnRyeQIJARNrZXlNYW5hZ2VyUHVibGljS2V5AAkA2AQBCQEFdmFsdWUBBQJwbQkAzAgCCQELRGVsZXRlRW50cnkBCQEaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkABQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEFc3Rha2UAAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQI0aW52YWxpZCBwYXltZW50IC0gZXhhY3Qgb25lIHBheW1lbnQgbXVzdCBiZSBhdHRhY2hlZAQDcG10CQCRAwIIBQFpCHBheW1lbnRzAAAECWxwQXNzZXRJZAkBBXZhbHVlAQgFA3BtdAdhc3NldElkBAxscEFzc2V0SWRTdHIJANgEAQUJbHBBc3NldElkBAZhbW91bnQIBQNwbXQGYW1vdW50BA5wb29sQWRkcmVzc1N0cgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD2ZhY3RvcnlDb250cmFjdAkBGmtleUZhY3RvcnlMcDJBc3NldHNNYXBwaW5nAQUMbHBBc3NldElkU3RyCQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUMbHBBc3NldElkU3RyBAljYWxsZXJTdHIJAKUIAQgFAWkGY2FsbGVyBA51c2VyQWRkcmVzc1N0cgMJAAACBQljYWxsZXJTdHIFDnBvb2xBZGRyZXNzU3RyCQClCAEIBQFpDG9yaWdpbkNhbGxlcgUJY2FsbGVyU3RyBA9zdGFrZWRCeVVzZXJLRVkJAQ9rZXlTdGFrZWRCeVVzZXICBQ51c2VyQWRkcmVzc1N0cgUMbHBBc3NldElkU3RyBA5zdGFrZWRUb3RhbEtFWQkBDmtleVN0YWtlZFRvdGFsAQUMbHBBc3NldElkU3RyBAxzdGFrZWRCeVVzZXIJAQpyZWFkU3Rha2VkAQUPc3Rha2VkQnlVc2VyS0VZBAtzdGFrZWRUb3RhbAkBCnJlYWRTdGFrZWQBBQ5zdGFrZWRUb3RhbEtFWQQNJHQwMTkzMTYxOTQzMwkBEHJlZnJlc2hJTlRFR1JBTFMEBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBQ5wb29sQWRkcmVzc1N0cgUGYW1vdW50BBB3eFRvQ2xhaW1Vc2VyTmV3CAUNJHQwMTkzMTYxOTQzMwJfMQQNaW50ZWdyYWxTVEFURQgFDSR0MDE5MzE2MTk0MzMCXzIEBWRlYnVnCAUNJHQwMTkzMTYxOTQzMwJfMwQIbGlzdE5hbWUJARBnZXRVc2Vyc0xpc3ROYW1lAQUMbHBBc3NldElkU3RyBAtsaXN0QWN0aW9ucwMJAQxjb250YWluc05vZGUCBQhsaXN0TmFtZQUOdXNlckFkZHJlc3NTdHIFA25pbAkBEWluc2VydE5vZGVBY3Rpb25zAgUIbGlzdE5hbWUFDnVzZXJBZGRyZXNzU3RyCQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUPc3Rha2VkQnlVc2VyS0VZCQBkAgUMc3Rha2VkQnlVc2VyBQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFDnN0YWtlZFRvdGFsS0VZCQBkAgULc3Rha2VkVG90YWwFBmFtb3VudAkAzAgCCQEVT3BlcmF0aW9uSGlzdG9yeUVudHJ5BQIFc3Rha2UFDnVzZXJBZGRyZXNzU3RyBQxscEFzc2V0SWRTdHIFBmFtb3VudAgFAWkNdHJhbnNhY3Rpb25JZAUDbmlsBQ1pbnRlZ3JhbFNUQVRFBQtsaXN0QWN0aW9ucwFpAQd1bnN0YWtlAgxscEFzc2V0SWRTdHIGYW1vdW50BAlscEFzc2V0SWQJANkEAQUMbHBBc3NldElkU3RyBA5wb29sQWRkcmVzc1N0cgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFD2ZhY3RvcnlDb250cmFjdAkBGmtleUZhY3RvcnlMcDJBc3NldHNNYXBwaW5nAQUMbHBBc3NldElkU3RyCQCsAgICFXVuc3VwcG9ydGVkIGxwIGFzc2V0IAUMbHBBc3NldElkU3RyBAlwb29sQWRkb24JAQt2YWx1ZU9yRWxzZQIJAJ0IAgkBEUBleHRyTmF0aXZlKDEwNjIpAQUOcG9vbEFkZHJlc3NTdHIJAQxrZXlBZGRvbkFkZHIABQ5wb29sQWRkcmVzc1N0cgQJY2FsbGVyU3RyCQClCAEIBQFpBmNhbGxlcgQOdXNlckFkZHJlc3NTdHIDAwMJAAACBQljYWxsZXJTdHIFDnBvb2xBZGRyZXNzU3RyCQECIT0CCAUBaQxvcmlnaW5DYWxsZXIFFmxwU3Rha2luZ1Bvb2xzQ29udHJhY3QHBgkAAAIFCWNhbGxlclN0cgUJcG9vbEFkZG9uCQClCAEIBQFpDG9yaWdpbkNhbGxlcgUJY2FsbGVyU3RyAwkAAAIFDnVzZXJBZGRyZXNzU3RyBQ51c2VyQWRkcmVzc1N0cgQPc3Rha2VkQnlVc2VyS0VZCQEPa2V5U3Rha2VkQnlVc2VyAgUOdXNlckFkZHJlc3NTdHIFDGxwQXNzZXRJZFN0cgQOc3Rha2VkVG90YWxLRVkJAQ5rZXlTdGFrZWRUb3RhbAEFDGxwQXNzZXRJZFN0cgQMc3Rha2VkQnlVc2VyCQEKcmVhZFN0YWtlZAEFD3N0YWtlZEJ5VXNlcktFWQQLc3Rha2VkVG90YWwJAQpyZWFkU3Rha2VkAQUOc3Rha2VkVG90YWxLRVkEDWludGVncmFsU1RBVEUICQEQcmVmcmVzaElOVEVHUkFMUwQFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIFDnBvb2xBZGRyZXNzU3RyCQEBLQEFBmFtb3VudAJfMgQIbGlzdE5hbWUJARBnZXRVc2Vyc0xpc3ROYW1lAQUMbHBBc3NldElkU3RyBAtsaXN0QWN0aW9ucwMDCQEMY29udGFpbnNOb2RlAgUIbGlzdE5hbWUFDnVzZXJBZGRyZXNzU3RyCQAAAgUGYW1vdW50BQxzdGFrZWRCeVVzZXIHCQERZGVsZXRlTm9kZUFjdGlvbnMCBQhsaXN0TmFtZQUOdXNlckFkZHJlc3NTdHIFA25pbAQNY2xhaW1lZEJ5VXNlcgkBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CBQR0aGlzCQEQa2V5Q2xhaW1lZEJ5VXNlcgIFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIEC3Bvb2xBZGRyZXNzCQEYZ2V0U3RyaW5nQnlBZGRyZXNzT3JGYWlsAgUPZmFjdG9yeUNvbnRyYWN0CQEma2V5RmFjdG9yeUxwQXNzZXRUb1Bvb2xDb250cmFjdEFkZHJlc3MBBQxscEFzc2V0SWRTdHIEEHd4VG9DbGFpbVVzZXJOZXcICQEQcmVmcmVzaElOVEVHUkFMUwQFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIFC3Bvb2xBZGRyZXNzAAACXzEEEGF2YWlsYWJsZVRvQ2xhaW0JALgCAgUQd3hUb0NsYWltVXNlck5ldwUNY2xhaW1lZEJ5VXNlcgQBcgMJAL8CAgUQYXZhaWxhYmxlVG9DbGFpbQUKemVyb0JpZ0ludAkA/AcEBQR0aGlzAg9jbGFpbVd4SU5URVJOQUwJAMwIAgUMbHBBc3NldElkU3RyCQDMCAIFDnVzZXJBZGRyZXNzU3RyBQNuaWwFA25pbAUEdW5pdAMJAAACBQFyBQFyAwkAZgIFBmFtb3VudAUMc3Rha2VkQnlVc2VyCQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAg5wYXNzZWQgYW1vdW50PQkApAMBBQZhbW91bnQCGyBpcyBncmVhdGVyIHRoYW4gYXZhaWxhYmxlPQkApAMBBQxzdGFrZWRCeVVzZXICDC4gbHBBc3NldElkPQUMbHBBc3NldElkU3RyAhIuIHN0YWtlZEJ5VXNlcktFWT0FD3N0YWtlZEJ5VXNlcktFWQkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIFD3N0YWtlZEJ5VXNlcktFWQkAZQIFDHN0YWtlZEJ5VXNlcgUGYW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5zdGFrZWRUb3RhbEtFWQkAZQIFC3N0YWtlZFRvdGFsBQZhbW91bnQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBQZhbW91bnQFCWxwQXNzZXRJZAkAzAgCCQEVT3BlcmF0aW9uSGlzdG9yeUVudHJ5BQIHdW5zdGFrZQUOdXNlckFkZHJlc3NTdHIFDGxwQXNzZXRJZFN0cgUGYW1vdW50CAUBaQ10cmFuc2FjdGlvbklkBQNuaWwFDWludGVncmFsU1RBVEUFC2xpc3RBY3Rpb25zCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBB2NsYWltV3gBDGxwQXNzZXRJZFN0cgQOdXNlckFkZHJlc3NTdHIJAKUIAQgFAWkGY2FsbGVyBAZyZXN1bHQJAPwHBAUEdGhpcwIPY2xhaW1XeElOVEVSTkFMCQDMCAIFDGxwQXNzZXRJZFN0cgkAzAgCBQ51c2VyQWRkcmVzc1N0cgUDbmlsBQNuaWwJAJQKAgUDbmlsBQZyZXN1bHQBaQEPY2xhaW1XeElOVEVSTkFMAgxscEFzc2V0SWRTdHIOdXNlckFkZHJlc3NTdHIEC2NoZWNrQ2FsbGVyCQEIbXVzdFRoaXMBBQFpAwkAAAIFC2NoZWNrQ2FsbGVyBQtjaGVja0NhbGxlcgQLdXNlckFkZHJlc3MJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQ51c2VyQWRkcmVzc1N0cgIlY2xhaW1XeElOVEVSTkFMOiBpbnZhbGlkIHVzZXIgYWRkcmVzcwQOcG9vbEFkZHJlc3NTdHIJARhnZXRTdHJpbmdCeUFkZHJlc3NPckZhaWwCBQ9mYWN0b3J5Q29udHJhY3QJASZrZXlGYWN0b3J5THBBc3NldFRvUG9vbENvbnRyYWN0QWRkcmVzcwEFDGxwQXNzZXRJZFN0cgQQY2xhaW1lZEJ5VXNlcktFWQkBEGtleUNsYWltZWRCeVVzZXICBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBA9jbGFpbWVkVG90YWxLRVkJAQ9rZXlDbGFpbWVkVG90YWwBBQxscEFzc2V0SWRTdHIEGWNsYWltZWRCeVVzZXJNaW5SZXdhcmRLRVkJARlrZXlDbGFpbWVkQnlVc2VyTWluUmV3YXJkAgUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgQbY2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkS0VZCQEba2V5Q2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkAgUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgQNY2xhaW1lZEJ5VXNlcgkBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CBQR0aGlzBRBjbGFpbWVkQnlVc2VyS0VZBBZjbGFpbWVkQnlVc2VyTWluUmV3YXJkCQEZZ2V0QmlnSW50RnJvbVN0cmluZ09yWmVybwIFBHRoaXMFGWNsYWltZWRCeVVzZXJNaW5SZXdhcmRLRVkEGGNsYWltZWRCeVVzZXJCb29zdFJld2FyZAkBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CBQR0aGlzBRtjbGFpbWVkQnlVc2VyQm9vc3RSZXdhcmRLRVkEDGNsYWltZWRUb3RhbAkBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CBQR0aGlzBQ9jbGFpbWVkVG90YWxLRVkEDSR0MDIzMzI4MjM0NDAJARByZWZyZXNoSU5URUdSQUxTBAUMbHBBc3NldElkU3RyBQ51c2VyQWRkcmVzc1N0cgUOcG9vbEFkZHJlc3NTdHIAAAQQd3hUb0NsYWltVXNlck5ldwgFDSR0MDIzMzI4MjM0NDACXzEEDWludGVncmFsU1RBVEUIBQ0kdDAyMzMyODIzNDQwAl8yBAVkZWJ1ZwgFDSR0MDIzMzI4MjM0NDACXzMEEGF2YWlsYWJsZVRvQ2xhaW0JAJgDAQkAzAgCCQC4AgIFEHd4VG9DbGFpbVVzZXJOZXcFDWNsYWltZWRCeVVzZXIJAMwIAgUKemVyb0JpZ0ludAUDbmlsAwkAwAICBQp6ZXJvQmlnSW50BRBhdmFpbGFibGVUb0NsYWltCQACAQIQbm90aGluZyB0byBjbGFpbQQSd3hBbW91bnRCb29zdFRvdGFsCQCWAwEJAMwIAgkBBWFzSW50AQkAkQMCCQEJYXNBbnlMaXN0AQkA/AcEBRBib29zdGluZ0NvbnRyYWN0AgxjbGFpbVd4Qm9vc3QJAMwIAgUMbHBBc3NldElkU3RyCQDMCAIFDnVzZXJBZGRyZXNzU3RyBQNuaWwFA25pbAAACQDMCAIAAAUDbmlsBA1taW5SZXdhcmRQYXJ0BRBhdmFpbGFibGVUb0NsYWltBA9ib29zdFJld2FyZFBhcnQJAJkDAQkAzAgCCQC5AgIFDW1pblJld2FyZFBhcnQJALYCAQACCQDMCAIJALYCAQUSd3hBbW91bnRCb29zdFRvdGFsBQNuaWwEC3RvdGFsUmV3YXJkCQC3AgIFDW1pblJld2FyZFBhcnQFD2Jvb3N0UmV3YXJkUGFydAQJd3hBc3NldElkCQEMYXNCeXRlVmVjdG9yAQkAkQMCCQEJYXNBbnlMaXN0AQkA/AcEBRBlbWlzc2lvbkNvbnRyYWN0AgRlbWl0CQDMCAIJAKADAQUNbWluUmV3YXJkUGFydAUDbmlsBQNuaWwAAAQJZW1pdEJvb3N0CQEJYXNBbnlMaXN0AQkA/AcEBRBlbWlzc2lvbkNvbnRyYWN0AgRlbWl0CQDMCAIJAKADAQUPYm9vc3RSZXdhcmRQYXJ0BQNuaWwFA25pbAMJAAACBQllbWl0Qm9vc3QFCWVtaXRCb29zdAQSY2xhaW1lZEJ5VXNlclZhbHVlCQC3AgIFDWNsYWltZWRCeVVzZXIFEGF2YWlsYWJsZVRvQ2xhaW0EHmNsYWltZWRCeVVzZXJNaW5SZXdhcmRQbHVzUGFydAkAtwICBRZjbGFpbWVkQnlVc2VyTWluUmV3YXJkBQ1taW5SZXdhcmRQYXJ0BCtjbGFpbWVkQnlVc2VyQm9vc3RSZXdhcmRQbHVzQm9vc3RSZXdhcmRQYXJ0CQC3AgIFFmNsYWltZWRCeVVzZXJNaW5SZXdhcmQFDW1pblJld2FyZFBhcnQEIGNsYWltZWRUb3RhbFBsdXNBdmFpbGFibGVUb0NsYWltCQC3AgIFFmNsYWltZWRCeVVzZXJNaW5SZXdhcmQFDW1pblJld2FyZFBhcnQJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBRBjbGFpbWVkQnlVc2VyS0VZCQCmAwEFEmNsYWltZWRCeVVzZXJWYWx1ZQkAzAgCCQELU3RyaW5nRW50cnkCBRljbGFpbWVkQnlVc2VyTWluUmV3YXJkS0VZCQCmAwEFHmNsYWltZWRCeVVzZXJNaW5SZXdhcmRQbHVzUGFydAkAzAgCCQELU3RyaW5nRW50cnkCBRtjbGFpbWVkQnlVc2VyQm9vc3RSZXdhcmRLRVkJAKYDAQUrY2xhaW1lZEJ5VXNlckJvb3N0UmV3YXJkUGx1c0Jvb3N0UmV3YXJkUGFydAkAzAgCCQELU3RyaW5nRW50cnkCBQ9jbGFpbWVkVG90YWxLRVkJAKYDAQUgY2xhaW1lZFRvdGFsUGx1c0F2YWlsYWJsZVRvQ2xhaW0JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwULdXNlckFkZHJlc3MJAKADAQUNbWluUmV3YXJkUGFydAUJd3hBc3NldElkCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFC3VzZXJBZGRyZXNzCQCgAwEFD2Jvb3N0UmV3YXJkUGFydAUJd3hBc3NldElkCQDMCAIJARVPcGVyYXRpb25IaXN0b3J5RW50cnkFAgVjbGFpbQUOdXNlckFkZHJlc3NTdHIFDGxwQXNzZXRJZFN0cgkAoAMBBRBhdmFpbGFibGVUb0NsYWltCAUBaQ10cmFuc2FjdGlvbklkBQNuaWwJAKADAQULdG90YWxSZXdhcmQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEbY2xhaW1XeEJ1bGtJbnRlcm5hbFJFQURPTkxZBAtjdXJyZW50SXRlcgpscEFzc2V0SWRzDnVzZXJBZGRyZXNzU3RyBnJlc0FjYwMJAAACBQtjdXJyZW50SXRlcgkAkAMBBQpscEFzc2V0SWRzCQCUCgIFA25pbAUGcmVzQWNjBAlscEFzc2V0SWQJAJEDAgUKbHBBc3NldElkcwULY3VycmVudEl0ZXIEBGluZm8JALUJAgoAAUAJAPwHBAUEdGhpcwIPY2xhaW1XeFJFQURPTkxZCQDMCAIFCWxwQXNzZXRJZAkAzAgCBQ51c2VyQWRkcmVzc1N0cgUDbmlsBQNuaWwDCQABAgUBQAIGU3RyaW5nBQFACQACAQkArAICCQADAQUBQAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nBQNTRVAECXVuY2xhaW1lZAkAkQMCBQRpbmZvAAMEB2NsYWltZWQJAJEDAgUEaW5mbwAEBANyZXMJAM0IAgUGcmVzQWNjCQC5CQIJAMwIAgIEJWQlZAkAzAgCBQl1bmNsYWltZWQJAMwIAgUHY2xhaW1lZAUDbmlsBQNTRVAEA2ludgoAAUAJAPwHBAUEdGhpcwIbY2xhaW1XeEJ1bGtJbnRlcm5hbFJFQURPTkxZCQDMCAIJAGQCBQtjdXJyZW50SXRlcgABCQDMCAIFCmxwQXNzZXRJZHMJAMwIAgUOdXNlckFkZHJlc3NTdHIJAMwIAgUDcmVzBQNuaWwFA25pbAMJAAECBQFAAglMaXN0W0FueV0FAUAJAAIBCQCsAgIJAAMBBQFAAh4gY291bGRuJ3QgYmUgY2FzdCB0byBMaXN0W0FueV0DCQAAAgUDaW52BQNpbnYJAJQKAgUDbmlsBQNpbnYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQETY2xhaW1XeEJ1bGtSRUFET05MWQIKbHBBc3NldElkcw51c2VyQWRkcmVzc1N0cgQDcmVzCQD8BwQFBHRoaXMCG2NsYWltV3hCdWxrSW50ZXJuYWxSRUFET05MWQkAzAgCAAAJAMwIAgUKbHBBc3NldElkcwkAzAgCBQ51c2VyQWRkcmVzc1N0cgkAzAgCBQNuaWwFA25pbAUDbmlsCQCUCgIFA25pbAUDcmVzAWkBD2NsYWltV3hSRUFET05MWQIMbHBBc3NldElkU3RyDnVzZXJBZGRyZXNzU3RyBA9zdGFrZWRCeVVzZXJLRVkJAQ9rZXlTdGFrZWRCeVVzZXICBQ51c2VyQWRkcmVzc1N0cgUMbHBBc3NldElkU3RyBA5zdGFrZWRUb3RhbEtFWQkBDmtleVN0YWtlZFRvdGFsAQUMbHBBc3NldElkU3RyBBBjbGFpbWVkQnlVc2VyS0VZCQEQa2V5Q2xhaW1lZEJ5VXNlcgIFDGxwQXNzZXRJZFN0cgUOdXNlckFkZHJlc3NTdHIEDHN0YWtlZEJ5VXNlcgkBCnJlYWRTdGFrZWQBBQ9zdGFrZWRCeVVzZXJLRVkEC3N0YWtlZFRvdGFsCQEKcmVhZFN0YWtlZAEFDnN0YWtlZFRvdGFsS0VZBA1jbGFpbWVkQnlVc2VyCQEZZ2V0QmlnSW50RnJvbVN0cmluZ09yWmVybwIFBHRoaXMFEGNsYWltZWRCeVVzZXJLRVkEDnBvb2xBZGRyZXNzU3RyCQEYZ2V0U3RyaW5nQnlBZGRyZXNzT3JGYWlsAgUPZmFjdG9yeUNvbnRyYWN0CQEma2V5RmFjdG9yeUxwQXNzZXRUb1Bvb2xDb250cmFjdEFkZHJlc3MBBQxscEFzc2V0SWRTdHIECnBvb2xXZWlnaHQJARFAZXh0ck5hdGl2ZSgxMDUwKQIFD2ZhY3RvcnlDb250cmFjdAkBFGtleUZhY3RvcnlQb29sV2VpZ2h0AQUOcG9vbEFkZHJlc3NTdHIEEnd4RW1pc3Npb25QZXJCbG9jawkBDGdldEludE9yRmFpbAIFEGVtaXNzaW9uQ29udHJhY3QJAR5rZXlFbWlzc2lvblJhdGVQZXJCbG9ja0N1cnJlbnQABBJlbWlzc2lvblN0YXJ0QmxvY2sJAQxnZXRJbnRPckZhaWwCBRBlbWlzc2lvbkNvbnRyYWN0CQEVa2V5RW1pc3Npb25TdGFydEJsb2NrAAQMcGFzc2VkQmxvY2tzAwkAZgIFEmVtaXNzaW9uU3RhcnRCbG9jawUGaGVpZ2h0AAAJAGUCBQZoZWlnaHQFEmVtaXNzaW9uU3RhcnRCbG9jawQOcG9vbFd4RW1pc3Npb24JAGsDCQBoAgUSd3hFbWlzc2lvblBlckJsb2NrBQxwYXNzZWRCbG9ja3MFCnBvb2xXZWlnaHQFDlBPT0xXRUlHSFRNVUxUBAx1c2VyV3hSZXdhcmQJAGsDBQ5wb29sV3hFbWlzc2lvbgUMc3Rha2VkQnlVc2VyBQtzdGFrZWRUb3RhbAQNJHQwMjY5OTMyNzEwNQkBEHJlZnJlc2hJTlRFR1JBTFMEBQxscEFzc2V0SWRTdHIFDnVzZXJBZGRyZXNzU3RyBQ5wb29sQWRkcmVzc1N0cgAABBB3eFRvQ2xhaW1Vc2VyTmV3CAUNJHQwMjY5OTMyNzEwNQJfMQQNaW50ZWdyYWxTVEFURQgFDSR0MDI2OTkzMjcxMDUCXzIEBWRlYnVnCAUNJHQwMjY5OTMyNzEwNQJfMwQQYXZhaWxhYmxlVG9DbGFpbQkAmAMBCQDMCAIJALgCAgUQd3hUb0NsYWltVXNlck5ldwUNY2xhaW1lZEJ5VXNlcgkAzAgCBQp6ZXJvQmlnSW50BQNuaWwEDmJvb3N0SW52UmVzdWx0CQEJYXNBbnlMaXN0AQkA/AcEBRBib29zdGluZ0NvbnRyYWN0AhRjbGFpbVd4Qm9vc3RSRUFET05MWQkAzAgCBQxscEFzc2V0SWRTdHIJAMwIAgUOdXNlckFkZHJlc3NTdHIFA25pbAUDbmlsBBJ3eEFtb3VudEJvb3N0VG90YWwJAJYDAQkAzAgCCQEFYXNJbnQBCQCRAwIFDmJvb3N0SW52UmVzdWx0AAAJAMwIAgAABQNuaWwECmJvb3N0RGVidWcJAQhhc1N0cmluZwEJAJEDAgUOYm9vc3RJbnZSZXN1bHQAAQQNbWluUmV3YXJkUGFydAUQYXZhaWxhYmxlVG9DbGFpbQQPYm9vc3RSZXdhcmRQYXJ0CQCZAwEJAMwIAgkAuQICBQ1taW5SZXdhcmRQYXJ0CQC2AgEAAgkAzAgCCQC2AgEFEnd4QW1vdW50Qm9vc3RUb3RhbAUDbmlsBAt0b3RhbFJld2FyZAkAtwICBQ1taW5SZXdhcmRQYXJ0BQ9ib29zdFJld2FyZFBhcnQJAJQKAgUDbmlsCQC5CQIJAMwIAgIOJXMlcyVkJWQlZCVkJXMJAMwIAgUMbHBBc3NldElkU3RyCQDMCAIFDnVzZXJBZGRyZXNzU3RyCQDMCAIJAKYDAQULdG90YWxSZXdhcmQJAMwIAgkApgMBBQ1jbGFpbWVkQnlVc2VyCQDMCAIJAKYDAQUNbWluUmV3YXJkUGFydAkAzAgCCQCmAwEFD2Jvb3N0UmV3YXJkUGFydAkAzAgCAgRzb29uBQNuaWwFA1NFUAFpARRzdGFrZWRCeVVzZXJSRUFET05MWQIMbHBBc3NldElkU3RyDnVzZXJBZGRyZXNzU3RyBAxzdGFrZWRCeVVzZXIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBD2tleVN0YWtlZEJ5VXNlcgIFDnVzZXJBZGRyZXNzU3RyBQxscEFzc2V0SWRTdHIAAAkAlAoCBQNuaWwFDHN0YWtlZEJ5VXNlcgFpARJ1c2Vyc0xpc3RUcmF2ZXJzYWwBCWxwQXNzZXRJZAQLY2hlY2tDYWxsZXIDCQAAAgkA2AQBCAgFAWkGY2FsbGVyBWJ5dGVzCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJARlrZXlWb3RpbmdFbWlzc2lvbkNvbnRyYWN0AAIABgkBC211c3RNYW5hZ2VyAQUBaQMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIECGxpc3ROYW1lCQEQZ2V0VXNlcnNMaXN0TmFtZQEFCWxwQXNzZXRJZAQKdXNlck9yVW5pdAkAoggBCQELa2V5TmV4dFVzZXIBBQlscEFzc2V0SWQECmhlYWRPclVuaXQJAKIIAQkBC2tleUxpc3RIZWFkAQUIbGlzdE5hbWUEByRtYXRjaDAFCnVzZXJPclVuaXQDCQABAgUHJG1hdGNoMAIEVW5pdAQHJG1hdGNoMQUKaGVhZE9yVW5pdAMJAAECBQckbWF0Y2gxAgRVbml0CQCUCgIFA25pbAcDCQABAgUHJG1hdGNoMQIGU3RyaW5nBARoZWFkBQckbWF0Y2gxCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBC2tleU5leHRVc2VyAQUJbHBBc3NldElkBQRoZWFkBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAt1c2VyQWRkcmVzcwUHJG1hdGNoMAQNY2xhaW1lZEJ5VXNlcgkBGWdldEJpZ0ludEZyb21TdHJpbmdPclplcm8CBQR0aGlzCQEQa2V5Q2xhaW1lZEJ5VXNlcgIFCWxwQXNzZXRJZAULdXNlckFkZHJlc3MEC3Bvb2xBZGRyZXNzCQEYZ2V0U3RyaW5nQnlBZGRyZXNzT3JGYWlsAgUPZmFjdG9yeUNvbnRyYWN0CQEma2V5RmFjdG9yeUxwQXNzZXRUb1Bvb2xDb250cmFjdEFkZHJlc3MBBQlscEFzc2V0SWQEEHd4VG9DbGFpbVVzZXJOZXcICQEQcmVmcmVzaElOVEVHUkFMUwQFCWxwQXNzZXRJZAULdXNlckFkZHJlc3MFC3Bvb2xBZGRyZXNzAAACXzEEEGF2YWlsYWJsZVRvQ2xhaW0JALgCAgUQd3hUb0NsYWltVXNlck5ldwUNY2xhaW1lZEJ5VXNlcgQBcgMJAL8CAgUQYXZhaWxhYmxlVG9DbGFpbQUKemVyb0JpZ0ludAkA/AcEBQR0aGlzAg9jbGFpbVd4SU5URVJOQUwJAMwIAgUJbHBBc3NldElkCQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA25pbAUEdW5pdAMJAAACBQFyBQFyBA5uZXh0VXNlck9yVW5pdAkAoggBCQELa2V5TGlzdE5leHQCBQhsaXN0TmFtZQULdXNlckFkZHJlc3MEByRtYXRjaDEFDm5leHRVc2VyT3JVbml0AwkAAQIFByRtYXRjaDECBFVuaXQJAJQKAgkAzAgCCQELRGVsZXRlRW50cnkBCQELa2V5TmV4dFVzZXIBBQlscEFzc2V0SWQFA25pbAcDCQABAgUHJG1hdGNoMQIGU3RyaW5nBAhuZXh0VXNlcgUHJG1hdGNoMQkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQtrZXlOZXh0VXNlcgEFCWxwQXNzZXRJZAUIbmV4dFVzZXIFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECC01hdGNoIGVycm9yCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDm9uTW9kaWZ5V2VpZ2h0AgxscEFzc2V0SWRTdHIOcG9vbEFkZHJlc3NTdHIDCQECIT0CCAUBaQZjYWxsZXIFD2ZhY3RvcnlDb250cmFjdAkAAgECEnBlcm1pc3Npb25zIGRlbmllZAQNJHQwMjk2MTMyOTcyMwkBFHJlZnJlc2hQb29sSU5URUdSQUxTAwUMbHBBc3NldElkU3RyBQ5wb29sQWRkcmVzc1N0cgAABBJ3eFBlckxwSW50ZWdyYWxOZXcIBQ0kdDAyOTYxMzI5NzIzAl8xBBFwb29sSW50ZWdyYWxTVEFURQgFDSR0MDI5NjEzMjk3MjMCXzIECXBvb2xERUJVRwgFDSR0MDI5NjEzMjk3MjMCXzMFEXBvb2xJbnRlZ3JhbFNUQVRFAQJ0eAEGdmVyaWZ5AAQPdGFyZ2V0UHVibGljS2V5BAckbWF0Y2gwCQEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAADCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCcGsFByRtYXRjaDAFAnBrAwkAAQIFByRtYXRjaDACBFVuaXQIBQJ0eA9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUPdGFyZ2V0UHVibGljS2V5Qx5KZQ==", "height": 2400379, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 5F8TkD3c4fSyJZvPtrJ7MPGJgPRMHZjKH1FpjfcRpVNX Next: 5gDoQabBG3oRZAkDKXQq23Fz3Rq2xVWvQ7sBd1CRqrZA Diff:
OldNewDifferences
1717
1818 let oneBigInt = toBigInt(1)
1919
20-func wrapErr (msg) = throw(makeString(["staking.ride:", toString(this), ":", msg], " "))
20+func wrapErr (msg) = throw(makeString(["staking.ride:", toString(this), msg], " "))
2121
2222
2323 func throwErr (msg) = throw(wrapErr(msg))
245245
246246 let boostingContract = getBoostingAddressOrFail(factoryCfg)
247247
248-let lpStakingPoolsContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, makeString(["%s", "lpStakingPoolsContract"], SEP)), wrapErr("lp_staking_pools contract address is undefined"))), wrapErr("invalid lp_staking_pools contract address"))
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"))
249249
250250 func keyNextUser (lpAssetId) = makeString(["%s%s", lpAssetId, "nextUser"], SEP)
251251
357357
358358
359359 func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
360- let $t01476714889 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
361- let wxPerLpIntegralNew = $t01476714889._1
362- let poolIntegralSTATE = $t01476714889._2
363- let poolDEBUG = $t01476714889._3
360+ let $t01475814880 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
361+ let wxPerLpIntegralNew = $t01475814880._1
362+ let poolIntegralSTATE = $t01475814880._2
363+ let poolDEBUG = $t01475814880._3
364364 let MULT3 = 1000
365365 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
366366 let stakedByUser = readStaked(stakedByUserKEY)
494494 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
495495 let stakedByUser = readStaked(stakedByUserKEY)
496496 let stakedTotal = readStaked(stakedTotalKEY)
497- let $t01932519442 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
498- let wxToClaimUserNew = $t01932519442._1
499- let integralSTATE = $t01932519442._2
500- let debug = $t01932519442._3
497+ let $t01931619433 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
498+ let wxToClaimUserNew = $t01931619433._1
499+ let integralSTATE = $t01931619433._2
500+ let debug = $t01931619433._3
501501 let listName = getUsersListName(lpAssetIdStr)
502502 let listActions = if (containsNode(listName, userAddressStr))
503503 then nil
520520 else (callerStr == poolAddon))
521521 then toString(i.originCaller)
522522 else callerStr
523- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
524- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
525- let stakedByUser = readStaked(stakedByUserKEY)
526- let stakedTotal = readStaked(stakedTotalKEY)
527- let integralSTATE = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))._2
528- let listName = getUsersListName(lpAssetIdStr)
529- let listActions = if (if (containsNode(listName, userAddressStr))
530- then (amount == stakedByUser)
531- else false)
532- then deleteNodeActions(listName, userAddressStr)
533- else nil
534- let claimedByUser = getBigIntFromStringOrZero(this, keyClaimedByUser(lpAssetIdStr, userAddressStr))
535- let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
536- let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddress, 0)._1
537- let availableToClaim = (wxToClaimUserNew - claimedByUser)
538- let r = if ((availableToClaim > zeroBigInt))
539- then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil)
540- else unit
541- if ((r == r))
542- then if ((amount > stakedByUser))
543- then throw(((((((("passed amount=" + toString(amount)) + " is greater than available=") + toString(stakedByUser)) + ". lpAssetId=") + lpAssetIdStr) + ". stakedByUserKEY=") + stakedByUserKEY))
544- else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
523+ if ((userAddressStr == userAddressStr))
524+ then {
525+ let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
526+ let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
527+ let stakedByUser = readStaked(stakedByUserKEY)
528+ let stakedTotal = readStaked(stakedTotalKEY)
529+ let integralSTATE = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))._2
530+ let listName = getUsersListName(lpAssetIdStr)
531+ let listActions = if (if (containsNode(listName, userAddressStr))
532+ then (amount == stakedByUser)
533+ else false)
534+ then deleteNodeActions(listName, userAddressStr)
535+ else nil
536+ let claimedByUser = getBigIntFromStringOrZero(this, keyClaimedByUser(lpAssetIdStr, userAddressStr))
537+ let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
538+ let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddress, 0)._1
539+ let availableToClaim = (wxToClaimUserNew - claimedByUser)
540+ let r = if ((availableToClaim > zeroBigInt))
541+ then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil)
542+ else unit
543+ if ((r == r))
544+ then if ((amount > stakedByUser))
545+ then throw(((((((("passed amount=" + toString(amount)) + " is greater than available=") + toString(stakedByUser)) + ". lpAssetId=") + lpAssetIdStr) + ". stakedByUserKEY=") + stakedByUserKEY))
546+ else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
547+ else throw("Strict value is not equal to itself.")
548+ }
545549 else throw("Strict value is not equal to itself.")
546550 }
547551
571575 let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
572576 let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
573577 let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
574- let $t02333423446 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
575- let wxToClaimUserNew = $t02333423446._1
576- let integralSTATE = $t02333423446._2
577- let debug = $t02333423446._3
578+ let $t02332823440 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
579+ let wxToClaimUserNew = $t02332823440._1
580+ let integralSTATE = $t02332823440._2
581+ let debug = $t02332823440._3
578582 let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt])
579583 if ((zeroBigInt >= availableToClaim))
580584 then throw("nothing to claim")
653657 else (height - emissionStartBlock)
654658 let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
655659 let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
656- let $t02699927111 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
657- let wxToClaimUserNew = $t02699927111._1
658- let integralSTATE = $t02699927111._2
659- let debug = $t02699927111._3
660+ let $t02699327105 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
661+ let wxToClaimUserNew = $t02699327105._1
662+ let integralSTATE = $t02699327105._2
663+ let debug = $t02699327105._3
660664 let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt])
661665 let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
662666 let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
731735 func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
732736 then throw("permissions denied")
733737 else {
734- let $t02961929729 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
735- let wxPerLpIntegralNew = $t02961929729._1
736- let poolIntegralSTATE = $t02961929729._2
737- let poolDEBUG = $t02961929729._3
738+ let $t02961329723 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
739+ let wxPerLpIntegralNew = $t02961329723._1
740+ let poolIntegralSTATE = $t02961329723._2
741+ let poolDEBUG = $t02961329723._3
738742 poolIntegralSTATE
739743 }
740744
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)
1919
20-func wrapErr (msg) = throw(makeString(["staking.ride:", toString(this), ":", msg], " "))
20+func wrapErr (msg) = throw(makeString(["staking.ride:", toString(this), msg], " "))
2121
2222
2323 func throwErr (msg) = throw(wrapErr(msg))
2424
2525
2626 func asAnyList (val) = match val {
2727 case valAnyLyst: List[Any] =>
2828 valAnyLyst
2929 case _ =>
3030 throw("fail to cast into List[Any]")
3131 }
3232
3333
3434 func asInt (val) = match val {
3535 case valInt: Int =>
3636 valInt
3737 case _ =>
3838 throw("fail to cast into Int")
3939 }
4040
4141
4242 func asString (val) = match val {
4343 case valStr: String =>
4444 valStr
4545 case _ =>
4646 throw("fail to cast into Int")
4747 }
4848
4949
5050 func asByteVector (val) = match val {
5151 case valBin: ByteVector =>
5252 valBin
5353 case _ =>
5454 throw("fail to cast into Int")
5555 }
5656
5757
5858 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined"))
5959
6060
6161 func getStringByAddressOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
6262
6363
6464 func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
6565
6666
6767 func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
6868
6969
7070 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
7171
7272
7373 func getBigIntFromStringOrZero (address,key) = value(parseBigInt(valueOrElse(getString(address, key), "0")))
7474
7575
7676 func getBigIntFromStringOrDefault (address,key,defaultVal) = match getString(address, key) {
7777 case s: String =>
7878 value(parseBigInt(s))
7979 case _: Unit =>
8080 defaultVal
8181 case _ =>
8282 throw("Match error")
8383 }
8484
8585
8686 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULT18, toBigInt(origScaleMult))
8787
8888
8989 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULT18))
9090
9191
9292 func keyFactoryAddress () = "%s%s__config__factoryAddress"
9393
9494
9595 func keyVotingEmissionContract () = "%s__votingEmissionContract"
9696
9797
9898 let IdxFactoryCfgStakingDapp = 1
9999
100100 let IdxFactoryCfgBoostingDapp = 2
101101
102102 let IdxFactoryCfgIdoDapp = 3
103103
104104 let IdxFactoryCfgTeamDapp = 4
105105
106106 let IdxFactoryCfgEmissionDapp = 5
107107
108108 let IdxFactoryCfgRestDapp = 6
109109
110110 let IdxFactoryCfgSlippageDapp = 7
111111
112112 func keyFactoryCfg () = "%s__factoryConfig"
113113
114114
115115 func keyManagerPublicKey () = "%s__managerPublicKey"
116116
117117
118118 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
119119
120120
121121 func keyStablePoolAddonAddr () = "%s__stablePoolAddonAddr"
122122
123123
124124 func keyAddonAddr () = "%s__addonAddr"
125125
126126
127127 func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
128128
129129
130130 func keyFactoryLpList () = "%s__lpTokensList"
131131
132132
133133 func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
134134
135135
136136 func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
137137
138138
139139 func readLpList (factory) = split(valueOrElse(getString(factory, keyFactoryLpList()), ""), SEP)
140140
141141
142142 func readFactoryCfgOrFail (factory) = split(getStringByAddressOrFail(factory, keyFactoryCfg()), SEP)
143143
144144
145145 func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
146146
147147
148148 func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
149149
150150
151151 func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
152152
153153
154154 func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
155155
156156
157157 func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
158158
159159
160160 func keyEmissionStartBlock () = "%s%s__emission__startBlock"
161161
162162
163163 func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
164164
165165
166166 func keyEmissionEndBlock () = "%s%s__emission__endBlock"
167167
168168
169169 func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s__staked", userAddressStr, lpAssetIdStr], SEP)
170170
171171
172172 func keyStakedTotal (lpAssetIdStr) = ("%s%s%s__staked__total__" + lpAssetIdStr)
173173
174174
175175 func keyClaimedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimed", userAddressStr, lpAssetIdStr], SEP)
176176
177177
178178 func keyClaimedByUserMinReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedMinReward", userAddressStr, lpAssetIdStr], SEP)
179179
180180
181181 func keyClaimedByUserBoostReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedBoostReward", userAddressStr, lpAssetIdStr], SEP)
182182
183183
184184 func keyClaimedTotal (lpAssetIdStr) = makeString(["%s%s%s__claimed__total", lpAssetIdStr], SEP)
185185
186186
187187 func readStaked (key) = valueOrElse(getInteger(this, key), 0)
188188
189189
190190 func keyLastTotalLpBalance (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "bal"], SEP)
191191
192192
193193 func keyLastUserLpBalance (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "bal"], SEP)
194194
195195
196196 func keyTotalLpBalanceIntegral (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "balINT"], SEP)
197197
198198
199199 func keyUserLpBalanceIntegral (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "balINT"], SEP)
200200
201201
202202 func keyTotalLpBalanceIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "lastUpd"], SEP)
203203
204204
205205 func keyUserLpBalanceIntegralLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "lastUpd"], SEP)
206206
207207
208208 func keyWxPerLpIntegral (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpInt"], SEP)
209209
210210
211211 func keyWxPerLpIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpIntH"], SEP)
212212
213213
214214 func keyWxToClaimUser (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpInt"], SEP)
215215
216216
217217 func keyWxPerLpIntegralUserLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpIntH"], SEP)
218218
219219
220220 func keyWxPerLp (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLp"], SEP)
221221
222222
223223 func keyWxPerLpX18 (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLpX18"], SEP)
224224
225225
226226 func keyWxPerLpIntegralUserLast (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "uIntL"], SEP)
227227
228228
229229 func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
230230
231231
232232 func formatHistoryRecord (userAddress,lpAssetId,type,amount) = makeString(["%s%s%s%d%d%d", userAddress, lpAssetId, type, toString(height), toString(lastBlock.timestamp), toString(amount)], SEP)
233233
234234
235235 func OperationHistoryEntry (type,userAddress,lpAssetId,amount,txId) = StringEntry(keyOperationHistoryRecord(type, userAddress, toBase58String(txId)), formatHistoryRecord(userAddress, lpAssetId, type, amount))
236236
237237
238238 let factoryAddress = getStringOrFail(this, keyFactoryAddress())
239239
240240 let factoryContract = addressFromStringValue(factoryAddress)
241241
242242 let factoryCfg = readFactoryCfgOrFail(factoryContract)
243243
244244 let emissionContract = getEmissionAddressOrFail(factoryCfg)
245245
246246 let boostingContract = getBoostingAddressOrFail(factoryCfg)
247247
248-let lpStakingPoolsContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, makeString(["%s", "lpStakingPoolsContract"], SEP)), wrapErr("lp_staking_pools contract address is undefined"))), wrapErr("invalid lp_staking_pools contract address"))
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"))
249249
250250 func keyNextUser (lpAssetId) = makeString(["%s%s", lpAssetId, "nextUser"], SEP)
251251
252252
253253 func getUsersListName (lpAssetId) = makeString(["users", lpAssetId], SEP)
254254
255255
256256 func keyListHead (listName) = makeString(["%s%s%s", listName, "head"], SEP)
257257
258258
259259 func keyListSize (listName) = makeString(["%s%s%s", listName, "size"], SEP)
260260
261261
262262 func keyListPrev (listName,id) = makeString(["%s%s%s%s", listName, id, "prev"], SEP)
263263
264264
265265 func keyListNext (listName,id) = makeString(["%s%s%s%s", listName, id, "next"], SEP)
266266
267267
268268 func containsNode (listName,id) = {
269269 let headOrUnit = getString(this, keyListHead(listName))
270270 let prevOrUnit = getString(this, keyListPrev(listName, id))
271271 let nextOrUnit = getString(this, keyListNext(listName, id))
272272 if (if ((id == valueOrElse(headOrUnit, "")))
273273 then true
274274 else (prevOrUnit != unit))
275275 then true
276276 else (nextOrUnit != unit)
277277 }
278278
279279
280280 func insertNodeActions (listName,id) = {
281281 let headOrUnit = getString(this, keyListHead(listName))
282282 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
283283 let checkNode = if (!(containsNode(listName, id)))
284284 then true
285285 else throw("Node exists")
286286 if ((checkNode == checkNode))
287287 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
288288 then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
289289 else nil)) ++ [StringEntry(keyListHead(listName), id)])
290290 else throw("Strict value is not equal to itself.")
291291 }
292292
293293
294294 func deleteNodeActions (listName,id) = {
295295 let headOrUnit = getString(this, keyListHead(listName))
296296 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
297297 let prevOrUnit = getString(this, keyListPrev(listName, id))
298298 let nextOrUnit = getString(this, keyListNext(listName, id))
299299 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
300300 then (nextOrUnit != unit)
301301 else false)
302302 then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
303303 else if ((nextOrUnit != unit))
304304 then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
305305 else if ((prevOrUnit != unit))
306306 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
307307 else if ((id == valueOrElse(headOrUnit, "")))
308308 then [DeleteEntry(keyListHead(listName))]
309309 else throw(((("invalid node: " + listName) + ".") + id))))
310310 }
311311
312312
313313 func calcWxPerLpIntegralUserLast (stakedByUser,wxPerLpIntegralUserLastUpdHeightOrZero,wxPerLpIntegralNew,wxPerLpIntegralUserLastKEY) = if (if ((wxPerLpIntegralUserLastUpdHeightOrZero == zeroBigInt))
314314 then (stakedByUser > zeroBigInt)
315315 else false)
316316 then zeroBigInt
317317 else if ((stakedByUser == zeroBigInt))
318318 then wxPerLpIntegralNew
319319 else if (if ((wxPerLpIntegralUserLastUpdHeightOrZero > zeroBigInt))
320320 then (stakedByUser > zeroBigInt)
321321 else false)
322322 then value(parseBigInt(getStringOrFail(this, wxPerLpIntegralUserLastKEY)))
323323 else throw("calcWxPerLpIntegralUserLast: unexpected state")
324324
325325
326326 func refreshPoolINTEGRALS (lpAssetIdStr,poolAddressStr,lpDeltaAmount) = {
327327 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
328328 let stakedTotal = toBigInt(readStaked(stakedTotalKEY))
329329 let nonZeroStakedTotal = if ((stakedTotal == zeroBigInt))
330330 then oneBigInt
331331 else stakedTotal
332332 let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
333333 let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
334334 let MULT3 = 1000
335335 let wxEmissionPerBlockX3 = (getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) * MULT3)
336336 let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * 3))
337337 let wxPerLpIntegralKEY = keyWxPerLpIntegral(lpAssetIdStr)
338338 let wxPerLpIntegralLastUpdHeightKEY = keyWxPerLpIntegralLastUpdHeight(lpAssetIdStr)
339339 let wxPerLpKEY = keyWxPerLp(lpAssetIdStr)
340340 let wxPerLpIntegralLastUpdHeight = getIntOrDefault(this, wxPerLpIntegralLastUpdHeightKEY, emissionStartBlock)
341341 let wxPerLpIntegral = getBigIntFromStringOrZero(this, wxPerLpIntegralKEY)
342342 let wxPerLpOrZeroX3 = 0
343343 let dh = max([(height - wxPerLpIntegralLastUpdHeight), 0])
344344 let wxPerLpX3 = if ((wxPerLpOrZeroX3 != 0))
345345 then toBigInt(wxPerLpOrZeroX3)
346346 else fraction(toBigInt(poolWxEmissionPerBlockX3), toBigInt(MULT8), nonZeroStakedTotal)
347347 let stakedTotalNew = (stakedTotal + toBigInt(lpDeltaAmount))
348348 let nonZeroStakedTotalNew = if ((stakedTotalNew == zeroBigInt))
349349 then oneBigInt
350350 else stakedTotalNew
351351 let wxPerLpIntegralNew = (wxPerLpIntegral + (wxPerLpX3 * toBigInt(dh)))
352352 let wxPerLpX3New = (toBigInt(poolWxEmissionPerBlockX3) / nonZeroStakedTotalNew)
353353 let wxPerLpIntegralLastUpdHeightNew = height
354354 let debug = makeString([toString(wxPerLpIntegralNew), toString(dh), toString(wxPerLpX3), toString(stakedTotal), toString(poolWxEmissionPerBlockX3), toString(wxEmissionPerBlockX3), toString(poolWeight)], "::")
355355 $Tuple3(wxPerLpIntegralNew, [StringEntry(wxPerLpIntegralKEY, toString(wxPerLpIntegralNew)), IntegerEntry(wxPerLpIntegralLastUpdHeightKEY, wxPerLpIntegralLastUpdHeightNew), StringEntry(wxPerLpKEY, toString(wxPerLpX3New))], debug)
356356 }
357357
358358
359359 func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
360- let $t01476714889 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
361- let wxPerLpIntegralNew = $t01476714889._1
362- let poolIntegralSTATE = $t01476714889._2
363- let poolDEBUG = $t01476714889._3
360+ let $t01475814880 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
361+ let wxPerLpIntegralNew = $t01475814880._1
362+ let poolIntegralSTATE = $t01475814880._2
363+ let poolDEBUG = $t01475814880._3
364364 let MULT3 = 1000
365365 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
366366 let stakedByUser = readStaked(stakedByUserKEY)
367367 let wxToClaimUserKEY = keyWxToClaimUser(lpAssetIdStr, userAddressStr)
368368 let wxPerLpIntegralUserLastUpdHeightKEY = keyWxPerLpIntegralUserLastUpdHeight(lpAssetIdStr, userAddressStr)
369369 let wxPerLpIntegralUserLastKEY = keyWxPerLpIntegralUserLast(lpAssetIdStr, userAddressStr)
370370 let wxToClaimUser = getBigIntFromStringOrZero(this, wxToClaimUserKEY)
371371 let wxPerLpIntegralUserLastUpdHeightOrZero = getIntOrZero(this, wxPerLpIntegralUserLastUpdHeightKEY)
372372 let wxPerLpIntegralUserLast = calcWxPerLpIntegralUserLast(toBigInt(stakedByUser), toBigInt(wxPerLpIntegralUserLastUpdHeightOrZero), wxPerLpIntegralNew, wxPerLpIntegralUserLastKEY)
373373 let MULT11 = (MULT8 * MULT3)
374374 let wxToClaimUserNew = max([(wxToClaimUser + fraction((wxPerLpIntegralNew - wxPerLpIntegralUserLast), toBigInt(stakedByUser), toBigInt(MULT11))), zeroBigInt])
375375 let wxPerLpIntegralUserLastNew = wxPerLpIntegralNew
376376 let wxPerLpIntegralUserLastUpdHeightNew = height
377377 let debug = makeString([toString(wxToClaimUser), toString(wxPerLpIntegralUserLast), toString(stakedByUser), poolDEBUG, toString(height)], "::")
378378 $Tuple3(wxToClaimUserNew, (poolIntegralSTATE ++ [StringEntry(wxToClaimUserKEY, toString(wxToClaimUserNew)), IntegerEntry(wxPerLpIntegralUserLastUpdHeightKEY, wxPerLpIntegralUserLastUpdHeightNew), StringEntry(wxPerLpIntegralUserLastKEY, toString(wxPerLpIntegralUserLastNew))]), debug)
379379 }
380380
381381
382382 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
383383 case s: String =>
384384 fromBase58String(s)
385385 case _: Unit =>
386386 unit
387387 case _ =>
388388 throw("Match error")
389389 }
390390
391391
392392 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
393393 case s: String =>
394394 fromBase58String(s)
395395 case _: Unit =>
396396 unit
397397 case _ =>
398398 throw("Match error")
399399 }
400400
401401
402402 let permissionDeniedError = throw("Permission denied")
403403
404404 func mustThis (i) = if ((i.caller == this))
405405 then true
406406 else permissionDeniedError
407407
408408
409409 func mustManager (i) = match managerPublicKeyOrUnit() {
410410 case pk: ByteVector =>
411411 if ((i.callerPublicKey == pk))
412412 then true
413413 else permissionDeniedError
414414 case _: Unit =>
415415 if ((i.caller == this))
416416 then true
417417 else permissionDeniedError
418418 case _ =>
419419 throw("Match error")
420420 }
421421
422422
423423 @Callable(i)
424424 func constructor (factoryAddressStr) = {
425425 let checkCaller = mustManager(i)
426426 if ((checkCaller == checkCaller))
427427 then [StringEntry(keyFactoryAddress(), factoryAddressStr)]
428428 else throw("Strict value is not equal to itself.")
429429 }
430430
431431
432432
433433 @Callable(i)
434434 func constructorV2 (votingEmissionContract) = {
435435 let cheks = [mustManager(i), if ((addressFromString(votingEmissionContract) != unit))
436436 then true
437437 else "invalid voting emission contract address"]
438438 if ((cheks == cheks))
439439 then [StringEntry(keyVotingEmissionContract(), votingEmissionContract)]
440440 else throw("Strict value is not equal to itself.")
441441 }
442442
443443
444444
445445 @Callable(i)
446446 func setManager (pendingManagerPublicKey) = {
447447 let checkCaller = mustManager(i)
448448 if ((checkCaller == checkCaller))
449449 then {
450450 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
451451 if ((checkManagerPublicKey == checkManagerPublicKey))
452452 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
453453 else throw("Strict value is not equal to itself.")
454454 }
455455 else throw("Strict value is not equal to itself.")
456456 }
457457
458458
459459
460460 @Callable(i)
461461 func confirmManager () = {
462462 let pm = pendingManagerPublicKeyOrUnit()
463463 let hasPM = if (isDefined(pm))
464464 then true
465465 else throw("No pending manager")
466466 if ((hasPM == hasPM))
467467 then {
468468 let checkPM = if ((i.callerPublicKey == value(pm)))
469469 then true
470470 else throw("You are not pending manager")
471471 if ((checkPM == checkPM))
472472 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
473473 else throw("Strict value is not equal to itself.")
474474 }
475475 else throw("Strict value is not equal to itself.")
476476 }
477477
478478
479479
480480 @Callable(i)
481481 func stake () = if ((size(i.payments) != 1))
482482 then throw("invalid payment - exact one payment must be attached")
483483 else {
484484 let pmt = i.payments[0]
485485 let lpAssetId = value(pmt.assetId)
486486 let lpAssetIdStr = toBase58String(lpAssetId)
487487 let amount = pmt.amount
488488 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
489489 let callerStr = toString(i.caller)
490490 let userAddressStr = if ((callerStr == poolAddressStr))
491491 then toString(i.originCaller)
492492 else callerStr
493493 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
494494 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
495495 let stakedByUser = readStaked(stakedByUserKEY)
496496 let stakedTotal = readStaked(stakedTotalKEY)
497- let $t01932519442 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
498- let wxToClaimUserNew = $t01932519442._1
499- let integralSTATE = $t01932519442._2
500- let debug = $t01932519442._3
497+ let $t01931619433 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
498+ let wxToClaimUserNew = $t01931619433._1
499+ let integralSTATE = $t01931619433._2
500+ let debug = $t01931619433._3
501501 let listName = getUsersListName(lpAssetIdStr)
502502 let listActions = if (containsNode(listName, userAddressStr))
503503 then nil
504504 else insertNodeActions(listName, userAddressStr)
505505 (([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
506506 }
507507
508508
509509
510510 @Callable(i)
511511 func unstake (lpAssetIdStr,amount) = {
512512 let lpAssetId = fromBase58String(lpAssetIdStr)
513513 let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
514514 let poolAddon = valueOrElse(getString(addressFromStringValue(poolAddressStr), keyAddonAddr()), poolAddressStr)
515515 let callerStr = toString(i.caller)
516516 let userAddressStr = if (if (if ((callerStr == poolAddressStr))
517517 then (i.originCaller != lpStakingPoolsContract)
518518 else false)
519519 then true
520520 else (callerStr == poolAddon))
521521 then toString(i.originCaller)
522522 else callerStr
523- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
524- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
525- let stakedByUser = readStaked(stakedByUserKEY)
526- let stakedTotal = readStaked(stakedTotalKEY)
527- let integralSTATE = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))._2
528- let listName = getUsersListName(lpAssetIdStr)
529- let listActions = if (if (containsNode(listName, userAddressStr))
530- then (amount == stakedByUser)
531- else false)
532- then deleteNodeActions(listName, userAddressStr)
533- else nil
534- let claimedByUser = getBigIntFromStringOrZero(this, keyClaimedByUser(lpAssetIdStr, userAddressStr))
535- let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
536- let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddress, 0)._1
537- let availableToClaim = (wxToClaimUserNew - claimedByUser)
538- let r = if ((availableToClaim > zeroBigInt))
539- then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil)
540- else unit
541- if ((r == r))
542- then if ((amount > stakedByUser))
543- then throw(((((((("passed amount=" + toString(amount)) + " is greater than available=") + toString(stakedByUser)) + ". lpAssetId=") + lpAssetIdStr) + ". stakedByUserKEY=") + stakedByUserKEY))
544- else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
523+ if ((userAddressStr == userAddressStr))
524+ then {
525+ let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
526+ let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
527+ let stakedByUser = readStaked(stakedByUserKEY)
528+ let stakedTotal = readStaked(stakedTotalKEY)
529+ let integralSTATE = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))._2
530+ let listName = getUsersListName(lpAssetIdStr)
531+ let listActions = if (if (containsNode(listName, userAddressStr))
532+ then (amount == stakedByUser)
533+ else false)
534+ then deleteNodeActions(listName, userAddressStr)
535+ else nil
536+ let claimedByUser = getBigIntFromStringOrZero(this, keyClaimedByUser(lpAssetIdStr, userAddressStr))
537+ let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
538+ let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddress, 0)._1
539+ let availableToClaim = (wxToClaimUserNew - claimedByUser)
540+ let r = if ((availableToClaim > zeroBigInt))
541+ then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil)
542+ else unit
543+ if ((r == r))
544+ then if ((amount > stakedByUser))
545+ then throw(((((((("passed amount=" + toString(amount)) + " is greater than available=") + toString(stakedByUser)) + ". lpAssetId=") + lpAssetIdStr) + ". stakedByUserKEY=") + stakedByUserKEY))
546+ else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions)
547+ else throw("Strict value is not equal to itself.")
548+ }
545549 else throw("Strict value is not equal to itself.")
546550 }
547551
548552
549553
550554 @Callable(i)
551555 func claimWx (lpAssetIdStr) = {
552556 let userAddressStr = toString(i.caller)
553557 let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil)
554558 $Tuple2(nil, result)
555559 }
556560
557561
558562
559563 @Callable(i)
560564 func claimWxINTERNAL (lpAssetIdStr,userAddressStr) = {
561565 let checkCaller = mustThis(i)
562566 if ((checkCaller == checkCaller))
563567 then {
564568 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), "claimWxINTERNAL: invalid user address")
565569 let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
566570 let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
567571 let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr)
568572 let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
569573 let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr)
570574 let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
571575 let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY)
572576 let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY)
573577 let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY)
574- let $t02333423446 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
575- let wxToClaimUserNew = $t02333423446._1
576- let integralSTATE = $t02333423446._2
577- let debug = $t02333423446._3
578+ let $t02332823440 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
579+ let wxToClaimUserNew = $t02332823440._1
580+ let integralSTATE = $t02332823440._2
581+ let debug = $t02332823440._3
578582 let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt])
579583 if ((zeroBigInt >= availableToClaim))
580584 then throw("nothing to claim")
581585 else {
582586 let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0])
583587 let minRewardPart = availableToClaim
584588 let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
585589 let totalReward = (minRewardPart + boostRewardPart)
586590 let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0])
587591 let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil))
588592 if ((emitBoost == emitBoost))
589593 then {
590594 let claimedByUserValue = (claimedByUser + availableToClaim)
591595 let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
592596 let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserMinReward + minRewardPart)
593597 let claimedTotalPlusAvailableToClaim = (claimedByUserMinReward + minRewardPart)
594598 $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))
595599 }
596600 else throw("Strict value is not equal to itself.")
597601 }
598602 }
599603 else throw("Strict value is not equal to itself.")
600604 }
601605
602606
603607
604608 @Callable(i)
605609 func claimWxBulkInternalREADONLY (currentIter,lpAssetIds,userAddressStr,resAcc) = if ((currentIter == size(lpAssetIds)))
606610 then $Tuple2(nil, resAcc)
607611 else {
608612 let lpAssetId = lpAssetIds[currentIter]
609613 let info = split({
610614 let @ = invoke(this, "claimWxREADONLY", [lpAssetId, userAddressStr], nil)
611615 if ($isInstanceOf(@, "String"))
612616 then @
613617 else throw(($getType(@) + " couldn't be cast to String"))
614618 }, SEP)
615619 let unclaimed = info[3]
616620 let claimed = info[4]
617621 let res = (resAcc :+ makeString(["%d%d", unclaimed, claimed], SEP))
618622 let inv = {
619623 let @ = invoke(this, "claimWxBulkInternalREADONLY", [(currentIter + 1), lpAssetIds, userAddressStr, res], nil)
620624 if ($isInstanceOf(@, "List[Any]"))
621625 then @
622626 else throw(($getType(@) + " couldn't be cast to List[Any]"))
623627 }
624628 if ((inv == inv))
625629 then $Tuple2(nil, inv)
626630 else throw("Strict value is not equal to itself.")
627631 }
628632
629633
630634
631635 @Callable(i)
632636 func claimWxBulkREADONLY (lpAssetIds,userAddressStr) = {
633637 let res = invoke(this, "claimWxBulkInternalREADONLY", [0, lpAssetIds, userAddressStr, nil], nil)
634638 $Tuple2(nil, res)
635639 }
636640
637641
638642
639643 @Callable(i)
640644 func claimWxREADONLY (lpAssetIdStr,userAddressStr) = {
641645 let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
642646 let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
643647 let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
644648 let stakedByUser = readStaked(stakedByUserKEY)
645649 let stakedTotal = readStaked(stakedTotalKEY)
646650 let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY)
647651 let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
648652 let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
649653 let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
650654 let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
651655 let passedBlocks = if ((emissionStartBlock > height))
652656 then 0
653657 else (height - emissionStartBlock)
654658 let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
655659 let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
656- let $t02699927111 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
657- let wxToClaimUserNew = $t02699927111._1
658- let integralSTATE = $t02699927111._2
659- let debug = $t02699927111._3
660+ let $t02699327105 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
661+ let wxToClaimUserNew = $t02699327105._1
662+ let integralSTATE = $t02699327105._2
663+ let debug = $t02699327105._3
660664 let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt])
661665 let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
662666 let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0])
663667 let boostDebug = asString(boostInvResult[1])
664668 let minRewardPart = availableToClaim
665669 let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
666670 let totalReward = (minRewardPart + boostRewardPart)
667671 $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), "soon"], SEP))
668672 }
669673
670674
671675
672676 @Callable(i)
673677 func stakedByUserREADONLY (lpAssetIdStr,userAddressStr) = {
674678 let stakedByUser = valueOrElse(getInteger(keyStakedByUser(userAddressStr, lpAssetIdStr)), 0)
675679 $Tuple2(nil, stakedByUser)
676680 }
677681
678682
679683
680684 @Callable(i)
681685 func usersListTraversal (lpAssetId) = {
682686 let checkCaller = if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionContract()), "")))
683687 then true
684688 else mustManager(i)
685689 if ((checkCaller == checkCaller))
686690 then {
687691 let listName = getUsersListName(lpAssetId)
688692 let userOrUnit = getString(keyNextUser(lpAssetId))
689693 let headOrUnit = getString(keyListHead(listName))
690694 match userOrUnit {
691695 case _: Unit =>
692696 match headOrUnit {
693697 case _: Unit =>
694698 $Tuple2(nil, false)
695699 case head: String =>
696700 $Tuple2([StringEntry(keyNextUser(lpAssetId), head)], true)
697701 case _ =>
698702 throw("Match error")
699703 }
700704 case userAddress: String =>
701705 let claimedByUser = getBigIntFromStringOrZero(this, keyClaimedByUser(lpAssetId, userAddress))
702706 let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetId))
703707 let wxToClaimUserNew = refreshINTEGRALS(lpAssetId, userAddress, poolAddress, 0)._1
704708 let availableToClaim = (wxToClaimUserNew - claimedByUser)
705709 let r = if ((availableToClaim > zeroBigInt))
706710 then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress], nil)
707711 else unit
708712 if ((r == r))
709713 then {
710714 let nextUserOrUnit = getString(keyListNext(listName, userAddress))
711715 match nextUserOrUnit {
712716 case _: Unit =>
713717 $Tuple2([DeleteEntry(keyNextUser(lpAssetId))], false)
714718 case nextUser: String =>
715719 $Tuple2([StringEntry(keyNextUser(lpAssetId), nextUser)], true)
716720 case _ =>
717721 throw("Match error")
718722 }
719723 }
720724 else throw("Strict value is not equal to itself.")
721725 case _ =>
722726 throw("Match error")
723727 }
724728 }
725729 else throw("Strict value is not equal to itself.")
726730 }
727731
728732
729733
730734 @Callable(i)
731735 func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
732736 then throw("permissions denied")
733737 else {
734- let $t02961929729 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
735- let wxPerLpIntegralNew = $t02961929729._1
736- let poolIntegralSTATE = $t02961929729._2
737- let poolDEBUG = $t02961929729._3
738+ let $t02961329723 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
739+ let wxPerLpIntegralNew = $t02961329723._1
740+ let poolIntegralSTATE = $t02961329723._2
741+ let poolDEBUG = $t02961329723._3
738742 poolIntegralSTATE
739743 }
740744
741745
742746 @Verifier(tx)
743747 func verify () = {
744748 let targetPublicKey = match managerPublicKeyOrUnit() {
745749 case pk: ByteVector =>
746750 pk
747751 case _: Unit =>
748752 tx.senderPublicKey
749753 case _ =>
750754 throw("Match error")
751755 }
752756 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
753757 }
754758

github/deemru/w8io/026f985 
108.51 ms