tx · 8enY1DccBCEnJqyPrSPE419gACgopHfUPmjahFojd7xx 3PFKZDRSFv5QPbe4b6Q22fLZniqAc8u9MLp: -0.02500000 Waves 2023.04.13 18:16 [3598581] smart account 3PFKZDRSFv5QPbe4b6Q22fLZniqAc8u9MLp > SELF 0.00000000 Waves
{ "type": 13, "id": "8enY1DccBCEnJqyPrSPE419gACgopHfUPmjahFojd7xx", "fee": 2500000, "feeAssetId": null, "timestamp": 1681399029512, "version": 2, "chainId": 87, "sender": "3PFKZDRSFv5QPbe4b6Q22fLZniqAc8u9MLp", "senderPublicKey": "BU38Szr6CXwv8YFSUKV7XbdQyMU7qb2wGvpeHAE2i5HX", "proofs": [ "4BqNDtM3TkSYF6B2YZQEHP7NybssDT7PBVVfhe4MRWpsxE1Ni54yL6G55JEzby2XyhimZHRSifKisa45w24NPH4v" ], "script": "base64:BgI1CAISABIAEgMKAQESABIAEgASABIAEgASABIAEggKBgEBAQEBAhIAEgoKCAEBAQEBAQECEgA8AANTRVACAl9fAAltaW5BbW91bnQAoI0GAAVNVUxUNgDAhD0ABU1VTFQ4AIDC1y8ADHdhdmVzQXNzZXRJZAkA2QQBAgVXQVZFUwAJd3hBc3NldElkASCTARyrqcduJVfOZp5xtr2qa/g86FgLKu7ZoE67PNwUsQALc3VyZkFzc2V0SWQBIJLR9EriEQEr9H7q3iGOPcX7yfJ9zoey7VIZ8DpOJFj1AAp4dG5Bc3NldElkASC2JinDBPXOU5GkDkt1JC9kjFGx+t+vVCm9SNIdKrKq0QALZGV4Q29udHJhY3QBGgFXymv8n9fLujU9O2aaHo6wilKnNKKaQ5SCABduZXV0cmlub0NvbnRyYWN0QWRkcmVzcwEaAVdwBGKmR5vprVZolMvvhYwwgiAomggUlrIAFm5ldXRyaW5vU3Rha2luZ0FkZHJlc3MBGgFXa2g44QPUmoyfEhvGLLwjBzkLze0S1wpfABluZXV0cmlub1ByaWNlSW5kZXhBZGRyZXNzARoBVyOzrRJck6TK7Dn+T0bWzVZNLfsQ+2OYegAUY2FzZVh0blN3YXBTdGF0ZUlkbGUAAAAcY2FzZVh0blN3YXBTdGF0ZVh0blRvUmV3YXJkcwABACRjYXNlWHRuU3dhcFN0YXRlRXhjaGFuZ2VSZXdhcmRzT25EZXgAAgAOY29uc3RydWN0ZWRLZXkCC2NvbnN0cnVjdGVkABN4dG5Td2FwU3RhdGVFbnVtS2V5AhB4dG5Td2FwU3RhdGVFbnVtABJ0b3RhbFN1cmZTdGFrZWRLZXkCD3RvdGFsU3VyZlN0YWtlZAAlcGVuZGluZ1RvdGFsU3VyZkFtb3VudFRvV2l0aGRyYXdhbEtleQIicGVuZGluZ1RvdGFsU3VmdEFtb3VudFRvV2l0aGRyYXdhbAASZGV2c1dhdmVzQW1vdW50S2V5Ag9kZXZzV2F2ZXNBbW91bnQAEWRldnNTdXJmQW1vdW50S2V5Ag5kZXZzU3VyZkFtb3VudAAPZGV2c1d4QW1vdW50S2V5AgxkZXZzV3hBbW91bnQAEGRldnNYdG5BbW91bnRLZXkCEGRldnNYdG5BbW91bnRLZXkAEXh0blN3YXBCbG9ja0lkS2V5Ag54dG5Td2FwQmxvY2tJZAAXeHRuU3dhcFRyYW5zYWN0aW9uSWRLZXkCFHh0blN3YXBUcmFuc2FjdGlvbklkABR4dG5Td2FwUHJpY2VJbmRleEtleQIReHRuU3dhcFByaWNlSW5kZXgAGnh0blN3YXBYdG5Td2FwcGVkQW1vdW50S2V5Ahd4dG5Td2FwWHRuU3dhcHBlZEFtb3VudAAceHRuU3dhcFdhdmVzQmFsYW5jZUF0U3dhcEtleQIZeHRuU3dhcFdhdmVzQmFsYW5jZUF0U3dhcAAZeHRuU3dhcFd4QmFsYW5jZUF0U3dhcEtleQIWeHRuU3dhcFd4QmFsYW5jZUF0U3dhcAAeeHRuU3dhcFh0bkJhbGFuY2VBdEV4Y2hhbmdlS2V5Aht4dG5Td2FwWHRuQmFsYW5jZUF0RXhjaGFuZ2UAGXh0blN3YXBFeGNoYW5nZUJsb2NrSWRLZXkCFnh0blN3YXBFeGNoYW5nZUJsb2NrSWQAGmxhc3RTdWNjZXNzU3dhcEJsb2NrSGVpZ2h0AhpsYXN0U3VjY2Vzc1N3YXBCbG9ja0hlaWdodAAcY3VycmVudFdpdGhkcmF3YWxQZXJpb2RJZEtleQIZY3VycmVudFdpdGhkcmF3YWxQZXJpb2RJZAAZY3VycmVudFhUTlN3YXBQZXJpb2RJZEtleQIWY3VycmVudFhUTlN3YXBQZXJpb2RJZAAkY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkS2V5AiRjdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kSWRLZXkBKmtleUN1cnJlbnRYdG5Td2FwUGVyaW9kWHRuQW1vdW50Rm9yT25lU3VyZgEIcGVyaW9kSWQJAKwCAgkArAICAhRjdXJyZW50WFROU3dhcFBlcmlvZAUDU0VQCQCkAwEFCHBlcmlvZElkATZrZXlDdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RXYXZlc0Ftb3VudEZvck9uZVN1cmYBCHBlcmlvZElkCQCsAgIJAKwCAgIpY3VycmVudFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kV2F2ZXNBbW91bnQFA1NFUAkApAMBBQhwZXJpb2RJZAEza2V5Q3VycmVudFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kV3hBbW91bnRGb3JPbmVTdXJmAQhwZXJpb2RJZAkArAICCQCsAgICJmN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZFd3QW1vdW50BQNTRVAJAKQDAQUIcGVyaW9kSWQBNGtleUN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZFh0bkFtb3VudEZvck9uZVN1cmYBCHBlcmlvZElkCQCsAgIJAKwCAgInY3VycmVudFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kWHRuQW1vdW50BQNTRVAJAKQDAQUIcGVyaW9kSWQBHWtleUN1cnJlbnRVc2VyVG90YWxTdXJmU3Rha2VkAQdhZGRyZXNzCQCsAgIJAKwCAgIaY3VycmVudFVzZXJUb3RhbFN1cmZTdGFrZWQFA1NFUAUHYWRkcmVzcwEsa2V5Q3VycmVudFVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQBB2FkZHJlc3MJAKwCAgkArAICAiljdXJyZW50VXNlclVuY2xhaW1lZFh0blN3YXBSZXdhcmRQZXJpb2RJZAUDU0VQBQdhZGRyZXNzATBrZXlDdXJyZW50VXNlclVuY2xhaW1lZFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kSWQBB2FkZHJlc3MJAKwCAgkArAICAi1jdXJyZW50VXNlclVuY2xhaW1lZFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kSWQFA1NFUAUHYWRkcmVzcwEna2V5Q3VycmVudFVzZXJQZW5kaW5nV2l0aGRyYXdhbFBlcmlvZElkAQdhZGRyZXNzCQCsAgIJAKwCAgIkY3VycmVudFVzZXJQZW5kaW5nV2l0aGRyYXdhbFBlcmlvZElkBQNTRVAFB2FkZHJlc3MBK2tleUN1cnJlbnRVc2VyVG90YWxTdXJmUGVuZGluZ0ZvcldpdGhkcmF3YWwBB2FkZHJlc3MJAKwCAgkArAICAihjdXJyZW50VXNlclRvdGFsU3VyZlBlbmRpbmdGb3JXaXRoZHJhd2FsBQNTRVAFB2FkZHJlc3MBCWFzUGF5bWVudAEBdgQHJG1hdGNoMAUBdgMJAAECBQckbWF0Y2gwAg9BdHRhY2hlZFBheW1lbnQEAXAFByRtYXRjaDAFAXAJAAIBAiFmYWlsIHRvIGNhc3QgaW50byBBdHRhY2hlZFBheW1lbnQBBWFzSW50AQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAgNJbnQEBnZhbEludAUHJG1hdGNoMAUGdmFsSW50CQACAQIVZmFpbCB0byBjYXN0IGludG8gSW50AQxhc0ludE9yVGhyb3cCA3ZhbAdtZXNzYWdlBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIDSW50BAZ2YWxJbnQFByRtYXRjaDAFBnZhbEludAkAAgEFB21lc3NhZ2UBCmFzSW50T3JEZWYCA3ZhbAdkZWZhdWx0BAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIDSW50BAZ2YWxJbnQFByRtYXRjaDAFBnZhbEludAUHZGVmYXVsdAEIYXNTdHJpbmcBA3ZhbAQHJG1hdGNoMAUDdmFsAwkAAQIFByRtYXRjaDACBlN0cmluZwQJdmFsU3RyaW5nBQckbWF0Y2gwBQl2YWxTdHJpbmcJAAIBAhhmYWlsIHRvIGNhc3QgaW50byBTdHJpbmcBDWFzU3RyaW5nT3JEZWYCA3ZhbAdkZWZhdWx0BAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAl2YWxTdHJpbmcFByRtYXRjaDAFCXZhbFN0cmluZwUHZGVmYXVsdAEJYXNCb29sZWFuAQN2YWwEByRtYXRjaDAFA3ZhbAMJAAECBQckbWF0Y2gwAgdCb29sZWFuBAd2YWxCb29sBQckbWF0Y2gwBQd2YWxCb29sCQACAQIZZmFpbCB0byBjYXN0IGludG8gQm9vbGVhbgEOYXNCb29sZWFuT3JEZWYCA3ZhbAdkZWZhdWx0BAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIHQm9vbGVhbgQHdmFsQm9vbAUHJG1hdGNoMAUHdmFsQm9vbAUHZGVmYXVsdAERY3VycmVudFByb3BvcnRpb24BD3h0blN3YXBMaW1pdE1heAQPdG90YWxTdXJmU3Rha2VkCQERQGV4dHJOYXRpdmUoMTA1NSkBBRJ0b3RhbFN1cmZTdGFrZWRLZXkJAL0CBAkAtgIBBQ90b3RhbFN1cmZTdGFrZWQJALYCAQUFTVVMVDYJALYCAQUPeHRuU3dhcExpbWl0TWF4BQZIQUxGVVABD2NoZWNrUHJvcG9ydGlvbgMPeHRuU3dhcExpbWl0TWF4CnN1cmZBbW91bnQJeG50QW1vdW50BApwcm9wb3J0aW9uCQERY3VycmVudFByb3BvcnRpb24BBQ94dG5Td2FwTGltaXRNYXgEEmV4cGVjdGVkU3VyZkFtb3VudAkAoAMBCQC9AgQFCnByb3BvcnRpb24JALYCAQUJeG50QW1vdW50CQC2AgEFBU1VTFQ2BQZIQUxGVVADCQAAAgUSZXhwZWN0ZWRTdXJmQW1vdW50BQpzdXJmQW1vdW50BgkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgIFV2l0aCAJAKQDAQUPeHRuU3dhcExpbWl0TWF4Ah8gWE5UIGFtb3VudCB5b3Ugc2hvdWxkIHByb3ZpZGUgCQCkAwEFEmV4cGVjdGVkU3VyZkFtb3VudAIVIFNVUkYgYW1vdW50IHRvIHN0YWtlAAVFTVBUWQIBXgEZa2V5T3BlcmF0aW9uSGlzdG9yeVJlY29yZAMEdHlwZQt1c2VyQWRkcmVzcwZ0eElkNTgJALkJAgkAzAgCAhElcyVzJXMlc19faGlzdG9yeQkAzAgCBQR0eXBlCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIFBnR4SWQ1OAUDbmlsBQNTRVABE2Zvcm1hdEhpc3RvcnlSZWNvcmQEC3VzZXJBZGRyZXNzCWxwQXNzZXRJZAR0eXBlBmFtb3VudAkAuQkCCQDMCAICDCVzJXMlcyVkJWQlZAkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCBQlscEFzc2V0SWQJAMwIAgUEdHlwZQkAzAgCCQCkAwEFBmhlaWdodAkAzAgCCQCkAwEIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAKQDAQUGYW1vdW50BQNuaWwFA1NFUAEVT3BlcmF0aW9uSGlzdG9yeUVudHJ5BQR0eXBlC3VzZXJBZGRyZXNzCWxwQXNzZXRJZAZhbW91bnQEdHhJZAkBC1N0cmluZ0VudHJ5AgkBGWtleU9wZXJhdGlvbkhpc3RvcnlSZWNvcmQDBQR0eXBlBQt1c2VyQWRkcmVzcwkA2AQBBQR0eElkCQETZm9ybWF0SGlzdG9yeVJlY29yZAQFC3VzZXJBZGRyZXNzBQlscEFzc2V0SWQFBHR5cGUFBmFtb3VudAEcaW50ZXJhY3RXaXRoU3dhcFBhcmFtc0J5VXNlcgAEBnJlc3VsdAkA/AcECQEHQWRkcmVzcwEFFm5ldXRyaW5vU3Rha2luZ0FkZHJlc3MCG3N3YXBQYXJhbXNCeVVzZXJTWVNSRUFET05MWQkAzAgCBQR0aGlzCQDMCAIAAAUDbmlsBQNuaWwDCQAAAgUGcmVzdWx0BQZyZXN1bHQEByRtYXRjaDAFBnJlc3VsdAMJAAECBQckbWF0Y2gwAiMoSW50LCBJbnQsIEludCwgSW50LCBJbnQsIEludCwgSW50KQQFdHVwbGUFByRtYXRjaDAJAMwIAggFBXR1cGxlAl8xCQDMCAIIBQV0dXBsZQJfMgkAzAgCCAUFdHVwbGUCXzMJAMwIAggFBXR1cGxlAl80CQDMCAIIBQV0dXBsZQJfNQkAzAgCCAUFdHVwbGUCXzYJAMwIAggFBXR1cGxlAl83BQNuaWwJAAIBAi5GQVRBTDogQ2FuJ3QgZmV0Y2ggZGF0YSBmcm9tIG5ldXRyaW5vIGNvbnRyYWN0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuASppc1VzZXJIYXNVbmNsYWltZWRSZXdhcmRzSW5QcmV2aW91c1BlcmlvZHMBB2FkZHJlc3MEInVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQJAQphc0ludE9yRGVmAgkAnwgBCQEsa2V5Q3VycmVudFVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQBBQdhZGRyZXNzAP///////////wEEJ3VzZXJVbmNsYWltZWRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAkBCmFzSW50T3JEZWYCCQCfCAEJATBrZXlDdXJyZW50VXNlclVuY2xhaW1lZFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kSWQBBQdhZGRyZXNzAP///////////wEEFGN1cnJlbnRYVE5Td2FwUGVyaW9kCQEKYXNJbnRPckRlZgIJAJ8IAQUZY3VycmVudFhUTlN3YXBQZXJpb2RJZEtleQAABB9jdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kCQEKYXNJbnRPckRlZgIJAJ8IAQUkY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkS2V5AAADAwkAZgIFInVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQA////////////AQkAZgIFFGN1cnJlbnRYVE5Td2FwUGVyaW9kBSJ1c2VyVW5jbGFpbWVkWHRuU3dhcFJld2FyZFBlcmlvZElkBwYDAwkAZgIFJ3VzZXJVbmNsYWltZWRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAD///////////8BCQBmAgUfY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZAUndXNlclVuY2xhaW1lZFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkBwYHDwFpAQtjb25zdHJ1Y3RvcgAEByRtYXRjaDAJAKAIAQUOY29uc3RydWN0ZWRLZXkDCQABAgUHJG1hdGNoMAIHQm9vbGVhbgkAAgECI0NvbnN0cnVjdG9yIGNhbiBiZSBjYWxsZWQganVzdCBvbmNlCQDMCAIJAQxCb29sZWFuRW50cnkCBQ5jb25zdHJ1Y3RlZEtleQYJAMwIAgkBDEludGVnZXJFbnRyeQIFHGN1cnJlbnRXaXRoZHJhd2FsUGVyaW9kSWRLZXkAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgUZY3VycmVudFhUTlN3YXBQZXJpb2RJZEtleQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBSVwZW5kaW5nVG90YWxTdXJmQW1vdW50VG9XaXRoZHJhd2FsS2V5AAAJAMwIAgkBDEludGVnZXJFbnRyeQIFEmRldnNXYXZlc0Ftb3VudEtleQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBRFkZXZzU3VyZkFtb3VudEtleQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ9kZXZzV3hBbW91bnRLZXkAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgUQZGV2c1h0bkFtb3VudEtleQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBRpsYXN0U3VjY2Vzc1N3YXBCbG9ja0hlaWdodAAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBRN4dG5Td2FwU3RhdGVFbnVtS2V5BRRjYXNlWHRuU3dhcFN0YXRlSWRsZQUDbmlsAWkBBXN0YWtlAAMJAQIhPQIJARFAZXh0ck5hdGl2ZSgxMDU1KQEFE3h0blN3YXBTdGF0ZUVudW1LZXkFFGNhc2VYdG5Td2FwU3RhdGVJZGxlCQACAQIzWFROIHN3YXAgaW4gcHJvZ3Jlc3MsIHdhaXQgYXBwcm94aW1hdGVsbHkgMyBtaW51dGVzAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIzWW91IG11c3QgaW5jbHVkZSBleGFjdGx5IG9uZSBwYXltZW50IGluIHRyYW5zYWN0aW9uBAdwYXltZW50CQEJYXNQYXltZW50AQkAkQMCCAUBaQhwYXltZW50cwAAAwMJAQIhPQIIBQdwYXltZW50B2Fzc2V0SWQFC3N1cmZBc3NldElkBgkAZgIFCW1pbkFtb3VudAgFB3BheW1lbnQGYW1vdW50CQACAQIXV3JvbmcgYXNzZXRJZCBvciBhbW91bnQEE2NhbGxlckFkZHJlc3NTdHJpbmcJANgEAQgIBQFpBmNhbGxlcgVieXRlcwMJASppc1VzZXJIYXNVbmNsYWltZWRSZXdhcmRzSW5QcmV2aW91c1BlcmlvZHMBBRNjYWxsZXJBZGRyZXNzU3RyaW5nCQACAQI+WW91IGhhdmUgdW5jbGFpbWVkIHJld2FyZHMsIGNsYWltIHRoZW0gZmlyc3QsIHRoZW4gc3Rha2UgYWdhaW4EBnJlc3VsdAkA/AcECQEHQWRkcmVzcwEFFm5ldXRyaW5vU3Rha2luZ0FkZHJlc3MCBXN0YWtlBQNuaWwJAMwIAgUHcGF5bWVudAUDbmlsAwkAAAIFBnJlc3VsdAUGcmVzdWx0BBJuZXdUb3RhbFN1cmZTdGFrZWQEByRtYXRjaDAJAJ8IAQUSdG90YWxTdXJmU3Rha2VkS2V5AwkAAQIFByRtYXRjaDACA0ludAQBdgUHJG1hdGNoMAkAZAIFAXYIBQdwYXltZW50BmFtb3VudAgFB3BheW1lbnQGYW1vdW50BBhjYWxsZXJUb3RhbFN1cmZTdGFrZWRLZXkJAR1rZXlDdXJyZW50VXNlclRvdGFsU3VyZlN0YWtlZAEFE2NhbGxlckFkZHJlc3NTdHJpbmcEGG5ld0NhbGxlclRvdGFsU3VyZlN0YWtlZAQHJG1hdGNoMAkAnwgBBRhjYWxsZXJUb3RhbFN1cmZTdGFrZWRLZXkDCQABAgUHJG1hdGNoMAIDSW50BAF2BQckbWF0Y2gwCQBkAgUBdggFB3BheW1lbnQGYW1vdW50CAUHcGF5bWVudAZhbW91bnQEFGN1cnJlbnRYVE5Td2FwUGVyaW9kCQEKYXNJbnRPckRlZgIJAJ8IAQUZY3VycmVudFhUTlN3YXBQZXJpb2RJZEtleQAABB9jdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kCQEKYXNJbnRPckRlZgIJAJ8IAQUkY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkS2V5AAAJAMwIAgkBDEludGVnZXJFbnRyeQIFEnRvdGFsU3VyZlN0YWtlZEtleQUSbmV3VG90YWxTdXJmU3Rha2VkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRhjYWxsZXJUb3RhbFN1cmZTdGFrZWRLZXkFGG5ld0NhbGxlclRvdGFsU3VyZlN0YWtlZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBLGtleUN1cnJlbnRVc2VyVW5jbGFpbWVkWHRuU3dhcFJld2FyZFBlcmlvZElkAQUTY2FsbGVyQWRkcmVzc1N0cmluZwUUY3VycmVudFhUTlN3YXBQZXJpb2QJAMwIAgkBDEludGVnZXJFbnRyeQIJATBrZXlDdXJyZW50VXNlclVuY2xhaW1lZFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kSWQBBRNjYWxsZXJBZGRyZXNzU3RyaW5nBR9jdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEXYXBwbHlGb3JQZW5kaW5nV2l0aGRyYXcBBmFtb3VudAMJAQIhPQIJARFAZXh0ck5hdGl2ZSgxMDU1KQEFE3h0blN3YXBTdGF0ZUVudW1LZXkFFGNhc2VYdG5Td2FwU3RhdGVJZGxlCQACAQIzWFROIHN3YXAgaW4gcHJvZ3Jlc3MsIHdhaXQgYXBwcm94aW1hdGVsbHkgMyBtaW51dGVzAwkAZgIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECJlRoaXMgZnVuY3Rpb24gZG9lcyBub3QgYWNjZXB0IHBheW1lbnRzAwkAZwIAAAUGYW1vdW50CQACAQIXQW1vdW50IG11c3QgYmUgcG9zaXRpdmUEE2NhbGxlckFkZHJlc3NTdHJpbmcJANgEAQgIBQFpBmNhbGxlcgVieXRlcwQVY2FsbGVyVG90YWxTdXJmU3Rha2VkCQERQGV4dHJOYXRpdmUoMTA1NSkBCQEda2V5Q3VycmVudFVzZXJUb3RhbFN1cmZTdGFrZWQBBRNjYWxsZXJBZGRyZXNzU3RyaW5nAwkAZgIFBmFtb3VudAUVY2FsbGVyVG90YWxTdXJmU3Rha2VkCQACAQIgSW5zdWZmaWNpZW50IGJhbGFuY2UgdG8gd2l0aGRyYXcDCQEqaXNVc2VySGFzVW5jbGFpbWVkUmV3YXJkc0luUHJldmlvdXNQZXJpb2RzAQUTY2FsbGVyQWRkcmVzc1N0cmluZwkAAgECPFlvdSBoYXZlIHVuY2xhaW1lZCByZXdhcmRzLCBjbGFpbSB0aGVtIGZpcnN0LCB0aGVuIHRyeSBhZ2FpbgQTY3VycmVudFdpdGhkcmF3YWxJZAkBEUBleHRyTmF0aXZlKDEwNTUpAQUcY3VycmVudFdpdGhkcmF3YWxQZXJpb2RJZEtleQQlcGVuZGluZ1RvdGFsU3VyZlRvVW5zdGFrZUZyb21OZXV0cmlubwkBEUBleHRyTmF0aXZlKDEwNTUpAQUlcGVuZGluZ1RvdGFsU3VyZkFtb3VudFRvV2l0aGRyYXdhbEtleQQddXNlclBlbmRpbmdXaXRoZHJhd2FsUGVyaW9kSWQJAQphc0ludE9yRGVmAgkAnwgBCQEna2V5Q3VycmVudFVzZXJQZW5kaW5nV2l0aGRyYXdhbFBlcmlvZElkAQUTY2FsbGVyQWRkcmVzc1N0cmluZwD///////////8BBCF1c2VyVG90YWxTdXJmUGVuZGluZ0ZvcldpdGhkcmF3YWwJAQphc0ludE9yRGVmAgkAnwgBCQEra2V5Q3VycmVudFVzZXJUb3RhbFN1cmZQZW5kaW5nRm9yV2l0aGRyYXdhbAEFE2NhbGxlckFkZHJlc3NTdHJpbmcAAAMDCQBmAgUddXNlclBlbmRpbmdXaXRoZHJhd2FsUGVyaW9kSWQA////////////AQkAZgIFE2N1cnJlbnRXaXRoZHJhd2FsSWQFHXVzZXJQZW5kaW5nV2l0aGRyYXdhbFBlcmlvZElkBwkAAgECP1lvdSBoYXZlIHVuY2xhaW1lZCBzdWZ0IG9uIGNvbnRyYWN0LCBwbGVhc2UgcGVyZm9ybSBjbGFpbSBmaXJzdAQcdXNlck5ld1RvdGFsU3VyZlN0YWtlZEFtb3VudAkAZQIFFWNhbGxlclRvdGFsU3VyZlN0YWtlZAUGYW1vdW50BCR1c2VyTmV3VG90YWxTdXJmUGVuZGluZ0ZvcldpdGhkcmF3YWwJAGQCBSF1c2VyVG90YWxTdXJmUGVuZGluZ0ZvcldpdGhkcmF3YWwFBmFtb3VudAQobmV3UGVuZGluZ1RvdGFsU3VyZlRvVW5zdGFrZUZyb21OZXV0cmlubwkAZAIFJXBlbmRpbmdUb3RhbFN1cmZUb1Vuc3Rha2VGcm9tTmV1dHJpbm8FBmFtb3VudAQYbmV3VG90YWxTdXJmU3Rha2VkQW1vdW50CQBlAgkBEUBleHRyTmF0aXZlKDEwNTUpAQUSdG90YWxTdXJmU3Rha2VkS2V5BQZhbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAR1rZXlDdXJyZW50VXNlclRvdGFsU3VyZlN0YWtlZAEFE2NhbGxlckFkZHJlc3NTdHJpbmcFHHVzZXJOZXdUb3RhbFN1cmZTdGFrZWRBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJASdrZXlDdXJyZW50VXNlclBlbmRpbmdXaXRoZHJhd2FsUGVyaW9kSWQBBRNjYWxsZXJBZGRyZXNzU3RyaW5nBRNjdXJyZW50V2l0aGRyYXdhbElkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEra2V5Q3VycmVudFVzZXJUb3RhbFN1cmZQZW5kaW5nRm9yV2l0aGRyYXdhbAEFE2NhbGxlckFkZHJlc3NTdHJpbmcFJHVzZXJOZXdUb3RhbFN1cmZQZW5kaW5nRm9yV2l0aGRyYXdhbAkAzAgCCQEMSW50ZWdlckVudHJ5AgUlcGVuZGluZ1RvdGFsU3VyZkFtb3VudFRvV2l0aGRyYXdhbEtleQUobmV3UGVuZGluZ1RvdGFsU3VyZlRvVW5zdGFrZUZyb21OZXV0cmlubwkAzAgCCQEMSW50ZWdlckVudHJ5AgUSdG90YWxTdXJmU3Rha2VkS2V5BRhuZXdUb3RhbFN1cmZTdGFrZWRBbW91bnQFA25pbAFpARpwZXJmb3JtRGlzdHJpYnV0ZWRXaXRoZHJhdwADCQBmAgkAkAMBCAUBaQhwYXltZW50cwAACQACAQImVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBhY2NlcHQgcGF5bWVudHMEE2N1cnJlbnRXaXRoZHJhd2FsSWQJARFAZXh0ck5hdGl2ZSgxMDU1KQEFHGN1cnJlbnRXaXRoZHJhd2FsUGVyaW9kSWRLZXkEJXBlbmRpbmdUb3RhbFN1cmZUb1Vuc3Rha2VGcm9tTmV1dHJpbm8JARFAZXh0ck5hdGl2ZSgxMDU1KQEFJXBlbmRpbmdUb3RhbFN1cmZBbW91bnRUb1dpdGhkcmF3YWxLZXkDCQBnAgAABSVwZW5kaW5nVG90YWxTdXJmVG9VbnN0YWtlRnJvbU5ldXRyaW5vBQNuaWwEBnJlc3VsdAkA/AcECQEHQWRkcmVzcwEFFm5ldXRyaW5vU3Rha2luZ0FkZHJlc3MCB3Vuc3Rha2UJAMwIAgUlcGVuZGluZ1RvdGFsU3VyZlRvVW5zdGFrZUZyb21OZXV0cmlubwUDbmlsBQNuaWwDCQAAAgUGcmVzdWx0BQZyZXN1bHQJAMwIAgkBDEludGVnZXJFbnRyeQIFHGN1cnJlbnRXaXRoZHJhd2FsUGVyaW9kSWRLZXkJAGQCBRNjdXJyZW50V2l0aGRyYXdhbElkAAEJAMwIAgkBDEludGVnZXJFbnRyeQIFJXBlbmRpbmdUb3RhbFN1cmZBbW91bnRUb1dpdGhkcmF3YWxLZXkAAAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCWNsYWltU3VyZgADCQBmAgkAkAMBCAUBaQhwYXltZW50cwAACQACAQImVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBhY2NlcHQgcGF5bWVudHMEE2NhbGxlckFkZHJlc3NTdHJpbmcJANgEAQgIBQFpBmNhbGxlcgVieXRlcwQZY3VycmVudFdpdGhkcmF3YWxQZXJpb2RJZAkBEUBleHRyTmF0aXZlKDEwNTUpAQUcY3VycmVudFdpdGhkcmF3YWxQZXJpb2RJZEtleQQWdXNlcldpdGhkcmF3YWxQZXJpb2RJZAkBCmFzSW50T3JEZWYCCQCfCAEJASdrZXlDdXJyZW50VXNlclBlbmRpbmdXaXRoZHJhd2FsUGVyaW9kSWQBBRNjYWxsZXJBZGRyZXNzU3RyaW5nAP///////////wEEIXVzZXJUb3RhbFN1cmZQZW5kaW5nRm9yV2l0aGRyYXdhbAkBCmFzSW50T3JEZWYCCQCfCAEJAStrZXlDdXJyZW50VXNlclRvdGFsU3VyZlBlbmRpbmdGb3JXaXRoZHJhd2FsAQUTY2FsbGVyQWRkcmVzc1N0cmluZwAAAwMJAAACBRZ1c2VyV2l0aGRyYXdhbFBlcmlvZElkAP///////////wEGCQAAAgUhdXNlclRvdGFsU3VyZlBlbmRpbmdGb3JXaXRoZHJhd2FsAAAJAAIBAhNOb3RoaW5nIHRvIHdpdGhkcmF3AwkAAAIFFnVzZXJXaXRoZHJhd2FsUGVyaW9kSWQFGWN1cnJlbnRXaXRoZHJhd2FsUGVyaW9kSWQJAAIBAiRZb3UgbXVzdCB3YWl0IGZvciBwZXJpb2QgdG8gY29tcGxldGUJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAWkGY2FsbGVyBSF1c2VyVG90YWxTdXJmUGVuZGluZ0ZvcldpdGhkcmF3YWwFC3N1cmZBc3NldElkCQDMCAIJAQtEZWxldGVFbnRyeQEJASdrZXlDdXJyZW50VXNlclBlbmRpbmdXaXRoZHJhd2FsUGVyaW9kSWQBBRNjYWxsZXJBZGRyZXNzU3RyaW5nCQDMCAIJAQtEZWxldGVFbnRyeQEJAStrZXlDdXJyZW50VXNlclRvdGFsU3VyZlBlbmRpbmdGb3JXaXRoZHJhd2FsAQUTY2FsbGVyQWRkcmVzc1N0cmluZwUDbmlsAWkBH3h0blN3YXBQYXJ0MXN3YXBYVE5Gcm9tTmV1dHJpbm8AAwkBAiE9AgkBEUBleHRyTmF0aXZlKDEwNTUpAQUTeHRuU3dhcFN0YXRlRW51bUtleQUUY2FzZVh0blN3YXBTdGF0ZUlkbGUJAAIBAhlXcm9uZyBzdGF0ZSwgbXVzdCBiZSBJZGxlBA53aXRoZHJhd1Jlc3VsdAkA/AcEBQR0aGlzAhpwZXJmb3JtRGlzdHJpYnV0ZWRXaXRoZHJhdwUDbmlsBQNuaWwDCQAAAgUOd2l0aGRyYXdSZXN1bHQFDndpdGhkcmF3UmVzdWx0BAZyZXN1bHQJAPwHBAkBB0FkZHJlc3MBBRduZXV0cmlub0NvbnRyYWN0QWRkcmVzcwIbc3dhcFBhcmFtc0J5VXNlclNZU1JFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwkAzAgCAAAFA25pbAUDbmlsAwkAAAIFBnJlc3VsdAUGcmVzdWx0BAckbWF0Y2gwBQZyZXN1bHQDCQABAgUHJG1hdGNoMAIjKEludCwgSW50LCBJbnQsIEludCwgSW50LCBJbnQsIEludCkEBXR1cGxlBQckbWF0Y2gwAwkAZgIIBQV0dXBsZQJfMwAACQACAQkArAICCQCsAgICJ1RpbWUgaXMgbm90IGNvbWUgeWV0LCB5b3UgbmVlZCB0byB3YWl0IAkApAMBCAUFdHVwbGUCXzMCByBibG9ja3MEDW1heFN3YXBBbW91bnQIBQV0dXBsZQJfNwMJAGYCAMCEPQUNbWF4U3dhcEFtb3VudAkAAgECLE1pbiBYVE4gYW1vdW50IHRvIHN3YXAgaXMgMSwgc3Rha2UgbW9yZSBTVVJGAwkAZgIFDW1heFN3YXBBbW91bnQJAPAHAgUEdGhpcwUKeHRuQXNzZXRJZAkAAgECVlhUTiBCYWxhbmNlIG9uIGNvbnRyYWN0IGlzIHNtYWxsZXIgdGhhbiBtYXggc3dhcCBhbW91bnQsIGluY3JlYXNlIFhUTiBjb250cmFjdCBiYWxhbmNlBBNjdXJyZW50V2F2ZXNCYWxhbmNlCQDvBwEFBHRoaXMEEGN1cnJlbnRXWEJhbGFuY2UJAPAHAgUEdGhpcwUJd3hBc3NldElkBBRzd2FwTmV1dHJpbm9Ub0Fzc2V0cwkA/AcECQEHQWRkcmVzcwEFF25ldXRyaW5vQ29udHJhY3RBZGRyZXNzAhRzd2FwTmV1dHJpbm9Ub0Jhc2tldAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQp4dG5Bc3NldElkBQ1tYXhTd2FwQW1vdW50BQNuaWwDCQAAAgUUc3dhcE5ldXRyaW5vVG9Bc3NldHMFFHN3YXBOZXV0cmlub1RvQXNzZXRzBApwcmljZUluZGV4CQBkAgkBEUBleHRyTmF0aXZlKDEwNTApAgkBB0FkZHJlc3MBBRluZXV0cmlub1ByaWNlSW5kZXhBZGRyZXNzAgtwcmljZV9pbmRleAABCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRF4dG5Td2FwQmxvY2tJZEtleQUGaGVpZ2h0CQDMCAIJAQtTdHJpbmdFbnRyeQIFF3h0blN3YXBUcmFuc2FjdGlvbklkS2V5CQDYBAEIBQFpDXRyYW5zYWN0aW9uSWQJAMwIAgkBDEludGVnZXJFbnRyeQIFFHh0blN3YXBQcmljZUluZGV4S2V5BQpwcmljZUluZGV4CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRp4dG5Td2FwWHRuU3dhcHBlZEFtb3VudEtleQUNbWF4U3dhcEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUceHRuU3dhcFdhdmVzQmFsYW5jZUF0U3dhcEtleQgFE2N1cnJlbnRXYXZlc0JhbGFuY2UJYXZhaWxhYmxlCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRl4dG5Td2FwV3hCYWxhbmNlQXRTd2FwS2V5BRBjdXJyZW50V1hCYWxhbmNlCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRN4dG5Td2FwU3RhdGVFbnVtS2V5BRxjYXNlWHRuU3dhcFN0YXRlWHRuVG9SZXdhcmRzBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAitJbmNvcnJlY3QgZGF0YSBmcm9tIG5ldXRyaW5vIHNtYXJ0IGNvbnRyYWN0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBJ3h0blN3YXBQYXJ0MmV4Y2hhbmdlWHRuU3dhcFJld2FyZHNPbkRleAADCQECIT0CCQERQGV4dHJOYXRpdmUoMTA1NSkBBRN4dG5Td2FwU3RhdGVFbnVtS2V5BRxjYXNlWHRuU3dhcFN0YXRlWHRuVG9SZXdhcmRzCQACAQIhV3Jvbmcgc3RhdGUsIG11c3QgYmUgWHRuVG9SZXdhcmRzAwkAZwIJARFAZXh0ck5hdGl2ZSgxMDU1KQEFEXh0blN3YXBCbG9ja0lkS2V5BQZoZWlnaHQJAAIBAhVNdXN0IHdhaXQgZm9yIDEgYmxvY2sEEHN3YXBUcmFuc2F0aW9uSWQJARFAZXh0ck5hdGl2ZSgxMDU4KQEFF3h0blN3YXBUcmFuc2FjdGlvbklkS2V5BA5zd2FwUHJpY2VJbmRleAkBEUBleHRyTmF0aXZlKDEwNTUpAQUUeHRuU3dhcFByaWNlSW5kZXhLZXkEDHdpdGhkcmF3X3JlcwkA/AcECQEHQWRkcmVzcwEFF25ldXRyaW5vQ29udHJhY3RBZGRyZXNzAgh3aXRoZHJhdwkAzAgCCQClCAEFBHRoaXMJAMwIAgUOc3dhcFByaWNlSW5kZXgJAMwIAgUQc3dhcFRyYW5zYXRpb25JZAUDbmlsBQNuaWwDCQAAAgUMd2l0aGRyYXdfcmVzBQx3aXRoZHJhd19yZXMEEndhdmVzQmFsYW5jZUF0U3dhcAkBEUBleHRyTmF0aXZlKDEwNTUpAQUceHRuU3dhcFdhdmVzQmFsYW5jZUF0U3dhcEtleQQPd3hCYWxhbmNlQXRTd2FwCQERQGV4dHJOYXRpdmUoMTA1NSkBBRl4dG5Td2FwV3hCYWxhbmNlQXRTd2FwS2V5BBNjdXJyZW50V2F2ZXNCYWxhbmNlCQDvBwEFBHRoaXMEEGN1cnJlbnRXWEJhbGFuY2UJAPAHAgUEdGhpcwUJd3hBc3NldElkBAx3YXZlc1Jld2FyZHMJAGUCCAUTY3VycmVudFdhdmVzQmFsYW5jZQlhdmFpbGFibGUFEndhdmVzQmFsYW5jZUF0U3dhcAQJd3hSZXdhcmRzCQBlAgUQY3VycmVudFdYQmFsYW5jZQUPd3hCYWxhbmNlQXRTd2FwBA1leGNoYW5nZVdhdmVzAwkAZwIAAAUMd2F2ZXNSZXdhcmRzBQNuaWwECXdhdmVzU3dhcAkA/AcECQEHQWRkcmVzcwEFC2RleENvbnRyYWN0AhRleGNoYW5nZVRoZW5UcmFuc2ZlcgkAzAgCCQClCAEJAQdBZGRyZXNzAQUKeHRuQXNzZXRJZAkAzAgCCQClCAEFBHRoaXMJAMwIAgAABQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFBHVuaXQFDHdhdmVzUmV3YXJkcwUDbmlsAwkAAAIFCXdhdmVzU3dhcAUJd2F2ZXNTd2FwBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DCQAAAgUNZXhjaGFuZ2VXYXZlcwUNZXhjaGFuZ2VXYXZlcwQGd3hTd2FwCQD8BwQJAQdBZGRyZXNzAQULZGV4Q29udHJhY3QCFGV4Y2hhbmdlVGhlblRyYW5zZmVyCQDMCAIJAKUIAQkBB0FkZHJlc3MBBQp4dG5Bc3NldElkCQDMCAIJAKUIAQUEdGhpcwkAzAgCAAAFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUJd3hBc3NldElkBQl3eFJld2FyZHMFA25pbAMJAAACBQZ3eFN3YXAFBnd4U3dhcAkAzAgCCQEMSW50ZWdlckVudHJ5AgIWV0FWRVNfUkVXQVJEU19GT1JfU1dBUAUMd2F2ZXNSZXdhcmRzCQDMCAIJAQxJbnRlZ2VyRW50cnkCAhNXWF9SRVdBUkRTX0ZPUl9TV0FQBQl3eFJld2FyZHMJAMwIAgkBDEludGVnZXJFbnRyeQIFHnh0blN3YXBYdG5CYWxhbmNlQXRFeGNoYW5nZUtleQkA8AcCBQR0aGlzBQp4dG5Bc3NldElkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRl4dG5Td2FwRXhjaGFuZ2VCbG9ja0lkS2V5BQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFE3h0blN3YXBTdGF0ZUVudW1LZXkFJGNhc2VYdG5Td2FwU3RhdGVFeGNoYW5nZVJld2FyZHNPbkRleAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBGHh0blN3YXBQYXJ0M0ZpbmFsaXplU3dhcAADCQECIT0CCQERQGV4dHJOYXRpdmUoMTA1NSkBBRN4dG5Td2FwU3RhdGVFbnVtS2V5BSRjYXNlWHRuU3dhcFN0YXRlRXhjaGFuZ2VSZXdhcmRzT25EZXgJAAIBAiVXcm9uZyBzdGF0ZSwgbXVzdCBiZSBFeGNoYW5nZSByZXdhcmRzAwkAZwIJARFAZXh0ck5hdGl2ZSgxMDU1KQEFGXh0blN3YXBFeGNoYW5nZUJsb2NrSWRLZXkFBmhlaWdodAkAAgECFU11c3Qgd2FpdCBmb3IgMSBibG9jawMJAGYCCQCQAwEIBQFpCHBheW1lbnRzAAAJAAIBAiZUaGlzIGZ1bmN0aW9uIGRvZXMgbm90IGFjY2VwdCBwYXltZW50cwQXeHRuQW1vdW50QmVmb3JlRXhjaGFuZ2UJARFAZXh0ck5hdGl2ZSgxMDU1KQEFHnh0blN3YXBYdG5CYWxhbmNlQXRFeGNoYW5nZUtleQQKeHRuU3dhcHBlZAkBEUBleHRyTmF0aXZlKDEwNTUpAQUaeHRuU3dhcFh0blN3YXBwZWRBbW91bnRLZXkEEGN1cnJlbnRYdG5BbW91bnQJAPAHAgUEdGhpcwUKeHRuQXNzZXRJZAQYeHRuUmV3YXJkQW1vdW50Rm9yUGVyaW9kCQBlAgUQY3VycmVudFh0bkFtb3VudAkAZAIFF3h0bkFtb3VudEJlZm9yZUV4Y2hhbmdlBQp4dG5Td2FwcGVkBBZjdXJyZW50WHRuU3dhcFBlcmlvZElkCQERQGV4dHJOYXRpdmUoMTA1NSkBBRljdXJyZW50WFROU3dhcFBlcmlvZElkS2V5BA90b3RhbFN1cmZTdGFrZWQJAQphc0ludE9yRGVmAgkAnwgBBRJ0b3RhbFN1cmZTdGFrZWRLZXkAAAQceHRuUmV3YXJkUGVyT25lU3VyZkZvclBlcmlvZAMJAGcCAAAFGHh0blJld2FyZEFtb3VudEZvclBlcmlvZAAACQBuBAUYeHRuUmV3YXJkQW1vdW50Rm9yUGVyaW9kBQVNVUxUNgUPdG90YWxTdXJmU3Rha2VkBQZIQUxGVVAJAMwIAgkBDEludGVnZXJFbnRyeQIJASprZXlDdXJyZW50WHRuU3dhcFBlcmlvZFh0bkFtb3VudEZvck9uZVN1cmYBBRZjdXJyZW50WHRuU3dhcFBlcmlvZElkBRx4dG5SZXdhcmRQZXJPbmVTdXJmRm9yUGVyaW9kCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRljdXJyZW50WFROU3dhcFBlcmlvZElkS2V5CQBkAgUWY3VycmVudFh0blN3YXBQZXJpb2RJZAABCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRN4dG5Td2FwU3RhdGVFbnVtS2V5BRRjYXNlWHRuU3dhcFN0YXRlSWRsZQUDbmlsAWkBBWNsYWltAAQJeHRuUmVzdWx0CQD8BwQFBHRoaXMCE2NsYWltWHRuU3dhcFJld2FyZHMFA25pbAUDbmlsAwkAAAIFCXh0blJlc3VsdAUJeHRuUmVzdWx0BApzdXJmUmVzdWx0CQD8BwQFBHRoaXMCF2NsYWltU3VyZlN0YWtpbmdSZXdhcmRzBQNuaWwFA25pbAMJAAACBQpzdXJmUmVzdWx0BQpzdXJmUmVzdWx0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQETY2xhaW1YdG5Td2FwUmV3YXJkcwADCQBmAgkAkAMBCAUBaQhwYXltZW50cwAACQACAQImVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBhY2NlcHQgcGF5bWVudHMEE2NhbGxlckFkZHJlc3NTdHJpbmcJANgEAQgIBQFpBmNhbGxlcgVieXRlcwQWY3VycmVudFh0blN3YXBQZXJpb2RJZAkBCmFzSW50T3JEZWYCCQCfCAEFGWN1cnJlbnRYVE5Td2FwUGVyaW9kSWRLZXkAAAQpY3VycmVudFVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQJAQphc0ludE9yRGVmAgkAnwgBCQEsa2V5Q3VycmVudFVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQBBRNjYWxsZXJBZGRyZXNzU3RyaW5nAP///////////wEDCQAAAgUpY3VycmVudFVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQA////////////AQkAlAoCBQNuaWwA////////////AQMJAAACBSljdXJyZW50VXNlclVuY2xhaW1lZFh0blN3YXBSZXdhcmRQZXJpb2RJZAUWY3VycmVudFh0blN3YXBQZXJpb2RJZAkAAgECMllvdSBuZWVkIHRvIHdhaXQgZm9yIGN1cnJlbnQgc3dhcCBwZXJpb2QgdG8gZmluaXNoBBZ1bmNsYWltZWRYdG5Td2Fwc0NvdW50CQBlAgUWY3VycmVudFh0blN3YXBQZXJpb2RJZAUpY3VycmVudFVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQEE3VzZXJUb3RhbFN1cmZTdGFrZWQJARFAZXh0ck5hdGl2ZSgxMDU1KQEJAR1rZXlDdXJyZW50VXNlclRvdGFsU3VyZlN0YWtlZAEFE2NhbGxlckFkZHJlc3NTdHJpbmcELG5ld0N1cnJlbnRVc2VyVW5jbGFpbWVkWHRuU3dhcFJld2FyZFBlcmlvZElkAwkAZgIFFnVuY2xhaW1lZFh0blN3YXBzQ291bnQALQkAZAIFKWN1cnJlbnRVc2VyVW5jbGFpbWVkWHRuU3dhcFJld2FyZFBlcmlvZElkAC0FFmN1cnJlbnRYdG5Td2FwUGVyaW9kSWQECml0ZXJhdGlvbnMDCQBmAgAtBRZ1bmNsYWltZWRYdG5Td2Fwc0NvdW50BRZ1bmNsYWltZWRYdG5Td2Fwc0NvdW50AC0EBnJlc3VsdAkA/AcEBQR0aGlzAiBpbnRlcm5hbEFjY3VtdWxhdGVYdG5Td2FwUmV3YXJkcwkAzAgCBQppdGVyYXRpb25zCQDMCAIAAAkAzAgCBSljdXJyZW50VXNlclVuY2xhaW1lZFh0blN3YXBSZXdhcmRQZXJpb2RJZAkAzAgCAAAJAMwIAgUTdXNlclRvdGFsU3VyZlN0YWtlZAkAzAgCCAgFAWkGY2FsbGVyBWJ5dGVzBQNuaWwFA25pbAMJAAACBQZyZXN1bHQFBnJlc3VsdAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBLGtleUN1cnJlbnRVc2VyVW5jbGFpbWVkWHRuU3dhcFJld2FyZFBlcmlvZElkAQUTY2FsbGVyQWRkcmVzc1N0cmluZwUsbmV3Q3VycmVudFVzZXJVbmNsYWltZWRYdG5Td2FwUmV3YXJkUGVyaW9kSWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpAQZmaXhLZXkACQDMCAIJAQxJbnRlZ2VyRW50cnkCAk5jdXJyZW50VXNlclVuY2xhaW1lZFh0blN3YXBSZXdhcmRQZXJpb2RJZF9fM1BBdjQyc2tOTVdlZE1TTng3NWZNRHVNY0Z6Z2dhRUxZcUsAAAUDbmlsAWkBIGludGVybmFsQWNjdW11bGF0ZVh0blN3YXBSZXdhcmRzBgppdGVyYXRpb25zB2N1cnJlbnQUc3RhcnRYdG5Td2FwUGVyaW9kSWQUYWNjdW11bGF0ZWRSZXdhcmRYdG4OdXNlclN1cmZBbW91bnQHYWRkcmVzcwMJAQIhPQIFBHRoaXMIBQFpBmNhbGxlcgkAAgECEUludGVybmFsIGZ1bmN0aW9uAwkAZwIFB2N1cnJlbnQFCml0ZXJhdGlvbnMDCQBmAgUUYWNjdW11bGF0ZWRSZXdhcmRYdG4AAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQEHQWRkcmVzcwEFB2FkZHJlc3MFFGFjY3VtdWxhdGVkUmV3YXJkWHRuBQp4dG5Bc3NldElkBQNuaWwFA25pbAQQeHRuQW1vdW50UGVyU3VyZgkBCmFzSW50T3JEZWYCCQCfCAEJASprZXlDdXJyZW50WHRuU3dhcFBlcmlvZFh0bkFtb3VudEZvck9uZVN1cmYBCQBkAgUUc3RhcnRYdG5Td2FwUGVyaW9kSWQFB2N1cnJlbnQAAAQGcmV3YXJkAwkAAAIFEHh0bkFtb3VudFBlclN1cmYAAAAACQBuBAUQeHRuQW1vdW50UGVyU3VyZgUOdXNlclN1cmZBbW91bnQFBU1VTFQ2BQZIQUxGVVAEBnJlc3VsdAkA/AcEBQR0aGlzAiBpbnRlcm5hbEFjY3VtdWxhdGVYdG5Td2FwUmV3YXJkcwkAzAgCBQppdGVyYXRpb25zCQDMCAIJAGQCBQdjdXJyZW50AAEJAMwIAgkAZAIFFHN0YXJ0WHRuU3dhcFBlcmlvZElkBQdjdXJyZW50CQDMCAIJAGQCBRRhY2N1bXVsYXRlZFJld2FyZFh0bgUGcmV3YXJkCQDMCAIFDnVzZXJTdXJmQW1vdW50CQDMCAIFB2FkZHJlc3MFA25pbAUDbmlsAwkAAAIFBnJlc3VsdAUGcmVzdWx0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEXY2xhaW1TdXJmU3Rha2luZ1Jld2FyZHMAAwkAZgIJAJADAQgFAWkIcGF5bWVudHMAAAkAAgECJlRoaXMgZnVuY3Rpb24gZG9lcyBub3QgYWNjZXB0IHBheW1lbnRzBBNjYWxsZXJBZGRyZXNzU3RyaW5nCQDYBAEICAUBaQZjYWxsZXIFYnl0ZXMEIWN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAkBCmFzSW50T3JEZWYCCQCfCAEFJGN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZEtleQAABC1jdXJyZW50VXNlclVuY2xhaW1lZFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kSWQJAQphc0ludE9yRGVmAgkAnwgBCQEwa2V5Q3VycmVudFVzZXJVbmNsYWltZWRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZElkAQUTY2FsbGVyQWRkcmVzc1N0cmluZwD///////////8BAwkAAAIFLWN1cnJlbnRVc2VyVW5jbGFpbWVkU3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RJZAD///////////8BCQCUCgIFA25pbAD///////////8BAwkAAAIFLWN1cnJlbnRVc2VyVW5jbGFpbWVkU3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RJZAUhY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkCQACAQIyWW91IG5lZWQgdG8gd2FpdCBmb3IgY3VycmVudCBzd2FwIHBlcmlvZCB0byBmaW5pc2gEGnVuY2xhaW1lZFN1cmZTdGFraW5nc0NvdW50CQBlAgUhY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkBS1jdXJyZW50VXNlclVuY2xhaW1lZFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kSWQEE3VzZXJUb3RhbFN1cmZTdGFrZWQJARFAZXh0ck5hdGl2ZSgxMDU1KQEJAR1rZXlDdXJyZW50VXNlclRvdGFsU3VyZlN0YWtlZAEFE2NhbGxlckFkZHJlc3NTdHJpbmcEMG5ld0N1cnJlbnRVc2VyVW5jbGFpbWVkU3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RJZAMJAGYCBRp1bmNsYWltZWRTdXJmU3Rha2luZ3NDb3VudAAtCQBkAgUtY3VycmVudFVzZXJVbmNsYWltZWRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZElkAC0FIWN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAQKaXRlcmF0aW9ucwMJAGYCAC0FGnVuY2xhaW1lZFN1cmZTdGFraW5nc0NvdW50BRp1bmNsYWltZWRTdXJmU3Rha2luZ3NDb3VudAAtBAZyZXN1bHQJAPwHBAUEdGhpcwIkaW50ZXJuYWxBY2N1bXVsYXRlU3VyZlN0YWtpbmdSZXdhcmRzCQDMCAIFCml0ZXJhdGlvbnMJAMwIAgAACQDMCAIFLWN1cnJlbnRVc2VyVW5jbGFpbWVkU3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RJZAkAzAgCAAAJAMwIAgAACQDMCAIAAAkAzAgCBRN1c2VyVG90YWxTdXJmU3Rha2VkCQDMCAIICAUBaQZjYWxsZXIFYnl0ZXMFA25pbAUDbmlsAwkAAAIFBnJlc3VsdAUGcmVzdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEwa2V5Q3VycmVudFVzZXJVbmNsYWltZWRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZElkAQUTY2FsbGVyQWRkcmVzc1N0cmluZwUwbmV3Q3VycmVudFVzZXJVbmNsYWltZWRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZElkBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEkaW50ZXJuYWxBY2N1bXVsYXRlU3VyZlN0YWtpbmdSZXdhcmRzCAppdGVyYXRpb25zB2N1cnJlbnQVc3RhcnRTdXJmU3dhcFBlcmlvZElkFmFjY3VtdWxhdGVkUmV3YXJkV2F2ZXMTYWNjdW11bGF0ZWRSZXdhcmRXeBRhY2N1bXVsYXRlZFJld2FyZFh0bg51c2VyU3VyZkFtb3VudAdhZGRyZXNzAwkBAiE9AgUEdGhpcwgFAWkGY2FsbGVyCQACAQIRSW50ZXJuYWwgZnVuY3Rpb24DCQBnAgUHY3VycmVudAUKaXRlcmF0aW9ucwMDAwkAZgIFFGFjY3VtdWxhdGVkUmV3YXJkWHRuAAAGCQBmAgUWYWNjdW11bGF0ZWRSZXdhcmRXYXZlcwAABgkAZgIFE2FjY3VtdWxhdGVkUmV3YXJkV3gAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQEHQWRkcmVzcwEFB2FkZHJlc3MFFGFjY3VtdWxhdGVkUmV3YXJkWHRuBQp4dG5Bc3NldElkCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJAQdBZGRyZXNzAQUHYWRkcmVzcwUWYWNjdW11bGF0ZWRSZXdhcmRXYXZlcwUMd2F2ZXNBc3NldElkCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJAQdBZGRyZXNzAQUHYWRkcmVzcwUTYWNjdW11bGF0ZWRSZXdhcmRXeAUJd3hBc3NldElkBQNuaWwFA25pbAQQeHRuQW1vdW50UGVyU3VyZgkBCmFzSW50T3JEZWYCCQCfCAEJATRrZXlDdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RYdG5BbW91bnRGb3JPbmVTdXJmAQkAZAIFFXN0YXJ0U3VyZlN3YXBQZXJpb2RJZAUHY3VycmVudAAABBJ3YXZlc0Ftb3VudFBlclN1cmYJAQphc0ludE9yRGVmAgkAnwgBCQE2a2V5Q3VycmVudFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kV2F2ZXNBbW91bnRGb3JPbmVTdXJmAQkAZAIFFXN0YXJ0U3VyZlN3YXBQZXJpb2RJZAUHY3VycmVudAAABA93eEFtb3VudFBlclN1cmYJAQphc0ludE9yRGVmAgkAnwgBCQEza2V5Q3VycmVudFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kV3hBbW91bnRGb3JPbmVTdXJmAQkAZAIFFXN0YXJ0U3VyZlN3YXBQZXJpb2RJZAUHY3VycmVudAAABAl4dG5SZXdhcmQDCQAAAgUQeHRuQW1vdW50UGVyU3VyZgAAAAAJAG4EBRB4dG5BbW91bnRQZXJTdXJmBQ51c2VyU3VyZkFtb3VudAUFTVVMVDYFBkhBTEZVUAQLd2F2ZXNSZXdhcmQDCQAAAgUSd2F2ZXNBbW91bnRQZXJTdXJmAAAAAAkAbgQFEndhdmVzQW1vdW50UGVyU3VyZgUOdXNlclN1cmZBbW91bnQFBU1VTFQ2BQZIQUxGVVAECHd4UmV3YXJkAwkAAAIFD3d4QW1vdW50UGVyU3VyZgAAAAAJAG4EBQ93eEFtb3VudFBlclN1cmYFDnVzZXJTdXJmQW1vdW50BQVNVUxUNgUGSEFMRlVQBAZyZXN1bHQJAPwHBAUEdGhpcwIkaW50ZXJuYWxBY2N1bXVsYXRlU3VyZlN0YWtpbmdSZXdhcmRzCQDMCAIFCml0ZXJhdGlvbnMJAMwIAgkAZAIFB2N1cnJlbnQAAQkAzAgCCQBkAgUVc3RhcnRTdXJmU3dhcFBlcmlvZElkBQdjdXJyZW50CQDMCAIJAGQCBRZhY2N1bXVsYXRlZFJld2FyZFdhdmVzBQt3YXZlc1Jld2FyZAkAzAgCCQBkAgUTYWNjdW11bGF0ZWRSZXdhcmRXeAUId3hSZXdhcmQJAMwIAgkAZAIFFGFjY3VtdWxhdGVkUmV3YXJkWHRuBQl4dG5SZXdhcmQJAMwIAgUOdXNlclN1cmZBbW91bnQJAMwIAgUHYWRkcmVzcwUDbmlsBQNuaWwDCQAAAgUGcmVzdWx0BQZyZXN1bHQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgFpASNzdXJmU3Rha2luZ1Jld2FyZHNDbGFpbUZyb21OZXV0cmlubwADCQBmAgkAkAMBCAUBaQhwYXltZW50cwAACQACAQImVGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBhY2NlcHQgcGF5bWVudHMEFmN1cnJlbnRXYXZlc09uQ29udHJhY3QJAPAHAgUEdGhpcwUMd2F2ZXNBc3NldElkAwkAAAIFFmN1cnJlbnRXYXZlc09uQ29udHJhY3QFFmN1cnJlbnRXYXZlc09uQ29udHJhY3QEE2N1cnJlbnRXeE9uQ29udHJhY3QJAPAHAgUEdGhpcwUJd3hBc3NldElkAwkAAAIFE2N1cnJlbnRXeE9uQ29udHJhY3QFE2N1cnJlbnRXeE9uQ29udHJhY3QEFGN1cnJlbnRYdG5PbkNvbnRyYWN0CQDwBwIFBHRoaXMFCnh0bkFzc2V0SWQDCQAAAgUUY3VycmVudFh0bk9uQ29udHJhY3QFFGN1cnJlbnRYdG5PbkNvbnRyYWN0BAZyZXN1bHQJAPwHBAkBB0FkZHJlc3MBBRZuZXV0cmlub1N0YWtpbmdBZGRyZXNzAgxjbGFpbVJld2FyZHMFA25pbAUDbmlsAwkAAAIFBnJlc3VsdAUGcmVzdWx0BBJuZXdXYXZlc09uQ29udHJhY3QJAPAHAgUEdGhpcwUMd2F2ZXNBc3NldElkBA9uZXdXeE9uQ29udHJhY3QJAPAHAgUEdGhpcwUJd3hBc3NldElkBBBuZXdYdG5PbkNvbnRyYWN0CQDwBwIFBHRoaXMFCnh0bkFzc2V0SWQEGndhdmVzUmV3YXJkQW1vdW50Rm9yUGVyaW9kCQBlAgUSbmV3V2F2ZXNPbkNvbnRyYWN0BRZjdXJyZW50V2F2ZXNPbkNvbnRyYWN0BBd3eFJld2FyZEFtb3VudEZvclBlcmlvZAkAZQIFD25ld1d4T25Db250cmFjdAUTY3VycmVudFd4T25Db250cmFjdAQYeHRuUmV3YXJkQW1vdW50Rm9yUGVyaW9kCQBlAgUQbmV3WHRuT25Db250cmFjdAUUY3VycmVudFh0bk9uQ29udHJhY3QEIWN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAkBEUBleHRyTmF0aXZlKDEwNTUpAQUkY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkS2V5BA90b3RhbFN1cmZTdGFrZWQJAQphc0ludE9yRGVmAgkAnwgBBRJ0b3RhbFN1cmZTdGFrZWRLZXkAAAMDCQAAAgUPdG90YWxTdXJmU3Rha2VkAAADAwkBAiE9AgUad2F2ZXNSZXdhcmRBbW91bnRGb3JQZXJpb2QAAAYJAQIhPQIFF3d4UmV3YXJkQW1vdW50Rm9yUGVyaW9kAAAGCQECIT0CBRh4dG5SZXdhcmRBbW91bnRGb3JQZXJpb2QAAAcEHG5ld0RldnNXYXZlc0Ftb3VudEF0Q29udHJhY3QJAGQCCQERQGV4dHJOYXRpdmUoMTA1NSkBBRJkZXZzV2F2ZXNBbW91bnRLZXkFGndhdmVzUmV3YXJkQW1vdW50Rm9yUGVyaW9kBBluZXdEZXZzV3hBbW91bnRBdENvbnRyYWN0CQBkAgkBEUBleHRyTmF0aXZlKDEwNTUpAQUPZGV2c1d4QW1vdW50S2V5BRd3eFJld2FyZEFtb3VudEZvclBlcmlvZAQabmV3RGV2c1h0bkFtb3VudEF0Q29udHJhY3QJAGQCCQERQGV4dHJOYXRpdmUoMTA1NSkBBRBkZXZzWHRuQW1vdW50S2V5BRh4dG5SZXdhcmRBbW91bnRGb3JQZXJpb2QJAMwIAgkBDEludGVnZXJFbnRyeQIJATZrZXlDdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RXYXZlc0Ftb3VudEZvck9uZVN1cmYBBSFjdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kSWQAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBM2tleUN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZFd4QW1vdW50Rm9yT25lU3VyZgEFIWN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAAACQDMCAIJAQxJbnRlZ2VyRW50cnkCCQE0a2V5Q3VycmVudFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kWHRuQW1vdW50Rm9yT25lU3VyZgEFIWN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBSRjdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kSWRLZXkJAGQCBSFjdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kSWQAAQkAzAgCCQEMSW50ZWdlckVudHJ5AgUSZGV2c1dhdmVzQW1vdW50S2V5BRxuZXdEZXZzV2F2ZXNBbW91bnRBdENvbnRyYWN0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ9kZXZzV3hBbW91bnRLZXkFGW5ld0RldnNXeEFtb3VudEF0Q29udHJhY3QJAMwIAgkBDEludGVnZXJFbnRyeQIFEGRldnNYdG5BbW91bnRLZXkFGm5ld0RldnNYdG5BbW91bnRBdENvbnRyYWN0BQNuaWwDCQAAAgUPdG90YWxTdXJmU3Rha2VkAAAFA25pbAQed2F2ZXNSZXdhcmRQZXJPbmVTdXJmRm9yUGVyaW9kAwkAAAIFGndhdmVzUmV3YXJkQW1vdW50Rm9yUGVyaW9kAAAAAAkAbgQFGndhdmVzUmV3YXJkQW1vdW50Rm9yUGVyaW9kBQVNVUxUNgUPdG90YWxTdXJmU3Rha2VkBQZIQUxGVVAEG3d4UmV3YXJkUGVyT25lU3VyZkZvclBlcmlvZAMJAAACBRd3eFJld2FyZEFtb3VudEZvclBlcmlvZAAAAAAJAG4EBRd3eFJld2FyZEFtb3VudEZvclBlcmlvZAUFTVVMVDYFD3RvdGFsU3VyZlN0YWtlZAUGSEFMRlVQBBx4dG5SZXdhcmRQZXJPbmVTdXJmRm9yUGVyaW9kAwkAAAIFGHh0blJld2FyZEFtb3VudEZvclBlcmlvZAAAAAAJAG4EBRh4dG5SZXdhcmRBbW91bnRGb3JQZXJpb2QFBU1VTFQ2BQ90b3RhbFN1cmZTdGFrZWQFBkhBTEZVUAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBNmtleUN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZFBlcmlvZFdhdmVzQW1vdW50Rm9yT25lU3VyZgEFIWN1cnJlbnRTdXJmU3Rha2luZ1Jld2FyZHNQZXJpb2RJZAUed2F2ZXNSZXdhcmRQZXJPbmVTdXJmRm9yUGVyaW9kCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEza2V5Q3VycmVudFN1cmZTdGFraW5nUmV3YXJkUGVyaW9kV3hBbW91bnRGb3JPbmVTdXJmAQUhY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkBRt3eFJld2FyZFBlck9uZVN1cmZGb3JQZXJpb2QJAMwIAgkBDEludGVnZXJFbnRyeQIJATRrZXlDdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRQZXJpb2RYdG5BbW91bnRGb3JPbmVTdXJmAQUhY3VycmVudFN1cmZTdGFraW5nUmV3YXJkc1BlcmlvZElkBRx4dG5SZXdhcmRQZXJPbmVTdXJmRm9yUGVyaW9kCQDMCAIJAQxJbnRlZ2VyRW50cnkCBSRjdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kSWRLZXkJAGQCBSFjdXJyZW50U3VyZlN0YWtpbmdSZXdhcmRzUGVyaW9kSWQAAQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJ0eAEGdmVyaWZ5AAkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAgFAnR4D3NlbmRlclB1YmxpY0tleRVxl5c=", "height": 3598581, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 2tX5s9AYza71shnLs6iP4poZKsoWJ9C1od5ygnhyeqE4 Next: 33FFMKymaLuQhqEzDiEDoSzhUA9JM2s6QhAPFZBFQUaX Diff:
Old | New | Differences | |
---|---|---|---|
490 | 490 | ||
491 | 491 | ||
492 | 492 | @Callable(i) | |
493 | - | func | |
493 | + | func fixKey () = [IntegerEntry("currentUserUnclaimedXtnSwapRewardPeriodId__3PAv42skNMWedMSNx75fMDuMcFzggaELYqK", 0)] | |
494 | 494 | ||
495 | 495 | ||
496 | 496 |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 6 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let SEP = "__" | |
5 | 5 | ||
6 | 6 | let minAmount = 100000 | |
7 | 7 | ||
8 | 8 | let MULT6 = 1000000 | |
9 | 9 | ||
10 | 10 | let MULT8 = 100000000 | |
11 | 11 | ||
12 | 12 | let wavesAssetId = fromBase58String("WAVES") | |
13 | 13 | ||
14 | 14 | let wxAssetId = base58'Atqv59EYzjFGuitKVnMRk6H8FukjoV3ktPorbEys25on' | |
15 | 15 | ||
16 | 16 | let surfAssetId = base58'At8D6NFFpheCbvKVnjVoeLL84Eo8NZn6ovManxfLaFWL' | |
17 | 17 | ||
18 | 18 | let xtnAssetId = base58'DG2xFkPdDwKUoBkzGAhQtLpSGzfXLiCYPEzeKH2Ad24p' | |
19 | 19 | ||
20 | 20 | let dexContract = base58'3PLPCb3wF2H2gtzohoAjeWcGaMKEiJvtE5X' | |
21 | 21 | ||
22 | 22 | let neutrinoContractAddress = base58'3PC9BfRwJWWiw9AREE2B3eWzCks3CYtg4yo' | |
23 | 23 | ||
24 | 24 | let neutrinoStakingAddress = base58'3PBiotFpqjRMkkeFBccnQNUXUopy7KFez5C' | |
25 | 25 | ||
26 | 26 | let neutrinoPriceIndexAddress = base58'3P5Bfd58PPfNvBM2Hy8QfbcDqMeNtzg7KfP' | |
27 | 27 | ||
28 | 28 | let caseXtnSwapStateIdle = 0 | |
29 | 29 | ||
30 | 30 | let caseXtnSwapStateXtnToRewards = 1 | |
31 | 31 | ||
32 | 32 | let caseXtnSwapStateExchangeRewardsOnDex = 2 | |
33 | 33 | ||
34 | 34 | let constructedKey = "constructed" | |
35 | 35 | ||
36 | 36 | let xtnSwapStateEnumKey = "xtnSwapStateEnum" | |
37 | 37 | ||
38 | 38 | let totalSurfStakedKey = "totalSurfStaked" | |
39 | 39 | ||
40 | 40 | let pendingTotalSurfAmountToWithdrawalKey = "pendingTotalSuftAmountToWithdrawal" | |
41 | 41 | ||
42 | 42 | let devsWavesAmountKey = "devsWavesAmount" | |
43 | 43 | ||
44 | 44 | let devsSurfAmountKey = "devsSurfAmount" | |
45 | 45 | ||
46 | 46 | let devsWxAmountKey = "devsWxAmount" | |
47 | 47 | ||
48 | 48 | let devsXtnAmountKey = "devsXtnAmountKey" | |
49 | 49 | ||
50 | 50 | let xtnSwapBlockIdKey = "xtnSwapBlockId" | |
51 | 51 | ||
52 | 52 | let xtnSwapTransactionIdKey = "xtnSwapTransactionId" | |
53 | 53 | ||
54 | 54 | let xtnSwapPriceIndexKey = "xtnSwapPriceIndex" | |
55 | 55 | ||
56 | 56 | let xtnSwapXtnSwappedAmountKey = "xtnSwapXtnSwappedAmount" | |
57 | 57 | ||
58 | 58 | let xtnSwapWavesBalanceAtSwapKey = "xtnSwapWavesBalanceAtSwap" | |
59 | 59 | ||
60 | 60 | let xtnSwapWxBalanceAtSwapKey = "xtnSwapWxBalanceAtSwap" | |
61 | 61 | ||
62 | 62 | let xtnSwapXtnBalanceAtExchangeKey = "xtnSwapXtnBalanceAtExchange" | |
63 | 63 | ||
64 | 64 | let xtnSwapExchangeBlockIdKey = "xtnSwapExchangeBlockId" | |
65 | 65 | ||
66 | 66 | let lastSuccessSwapBlockHeight = "lastSuccessSwapBlockHeight" | |
67 | 67 | ||
68 | 68 | let currentWithdrawalPeriodIdKey = "currentWithdrawalPeriodId" | |
69 | 69 | ||
70 | 70 | let currentXTNSwapPeriodIdKey = "currentXTNSwapPeriodId" | |
71 | 71 | ||
72 | 72 | let currentSurfStakingRewardsPeriodIdKey = "currentSurfStakingRewardsPeriodIdKey" | |
73 | 73 | ||
74 | 74 | func keyCurrentXtnSwapPeriodXtnAmountForOneSurf (periodId) = (("currentXTNSwapPeriod" + SEP) + toString(periodId)) | |
75 | 75 | ||
76 | 76 | ||
77 | 77 | func keyCurrentSurfStakingRewardPeriodWavesAmountForOneSurf (periodId) = (("currentSurfStakingRewardPeriodWavesAmount" + SEP) + toString(periodId)) | |
78 | 78 | ||
79 | 79 | ||
80 | 80 | func keyCurrentSurfStakingRewardPeriodWxAmountForOneSurf (periodId) = (("currentSurfStakingRewardPeriodWwAmount" + SEP) + toString(periodId)) | |
81 | 81 | ||
82 | 82 | ||
83 | 83 | func keyCurrentSurfStakingRewardPeriodXtnAmountForOneSurf (periodId) = (("currentSurfStakingRewardPeriodXtnAmount" + SEP) + toString(periodId)) | |
84 | 84 | ||
85 | 85 | ||
86 | 86 | func keyCurrentUserTotalSurfStaked (address) = (("currentUserTotalSurfStaked" + SEP) + address) | |
87 | 87 | ||
88 | 88 | ||
89 | 89 | func keyCurrentUserUnclaimedXtnSwapRewardPeriodId (address) = (("currentUserUnclaimedXtnSwapRewardPeriodId" + SEP) + address) | |
90 | 90 | ||
91 | 91 | ||
92 | 92 | func keyCurrentUserUnclaimedSurfStakingRewardPeriodId (address) = (("currentUserUnclaimedSurfStakingRewardPeriodId" + SEP) + address) | |
93 | 93 | ||
94 | 94 | ||
95 | 95 | func keyCurrentUserPendingWithdrawalPeriodId (address) = (("currentUserPendingWithdrawalPeriodId" + SEP) + address) | |
96 | 96 | ||
97 | 97 | ||
98 | 98 | func keyCurrentUserTotalSurfPendingForWithdrawal (address) = (("currentUserTotalSurfPendingForWithdrawal" + SEP) + address) | |
99 | 99 | ||
100 | 100 | ||
101 | 101 | func asPayment (v) = match v { | |
102 | 102 | case p: AttachedPayment => | |
103 | 103 | p | |
104 | 104 | case _ => | |
105 | 105 | throw("fail to cast into AttachedPayment") | |
106 | 106 | } | |
107 | 107 | ||
108 | 108 | ||
109 | 109 | func asInt (val) = match val { | |
110 | 110 | case valInt: Int => | |
111 | 111 | valInt | |
112 | 112 | case _ => | |
113 | 113 | throw("fail to cast into Int") | |
114 | 114 | } | |
115 | 115 | ||
116 | 116 | ||
117 | 117 | func asIntOrThrow (val,message) = match val { | |
118 | 118 | case valInt: Int => | |
119 | 119 | valInt | |
120 | 120 | case _ => | |
121 | 121 | throw(message) | |
122 | 122 | } | |
123 | 123 | ||
124 | 124 | ||
125 | 125 | func asIntOrDef (val,default) = match val { | |
126 | 126 | case valInt: Int => | |
127 | 127 | valInt | |
128 | 128 | case _ => | |
129 | 129 | default | |
130 | 130 | } | |
131 | 131 | ||
132 | 132 | ||
133 | 133 | func asString (val) = match val { | |
134 | 134 | case valString: String => | |
135 | 135 | valString | |
136 | 136 | case _ => | |
137 | 137 | throw("fail to cast into String") | |
138 | 138 | } | |
139 | 139 | ||
140 | 140 | ||
141 | 141 | func asStringOrDef (val,default) = match val { | |
142 | 142 | case valString: String => | |
143 | 143 | valString | |
144 | 144 | case _ => | |
145 | 145 | default | |
146 | 146 | } | |
147 | 147 | ||
148 | 148 | ||
149 | 149 | func asBoolean (val) = match val { | |
150 | 150 | case valBool: Boolean => | |
151 | 151 | valBool | |
152 | 152 | case _ => | |
153 | 153 | throw("fail to cast into Boolean") | |
154 | 154 | } | |
155 | 155 | ||
156 | 156 | ||
157 | 157 | func asBooleanOrDef (val,default) = match val { | |
158 | 158 | case valBool: Boolean => | |
159 | 159 | valBool | |
160 | 160 | case _ => | |
161 | 161 | default | |
162 | 162 | } | |
163 | 163 | ||
164 | 164 | ||
165 | 165 | func currentProportion (xtnSwapLimitMax) = { | |
166 | 166 | let totalSurfStaked = getIntegerValue(totalSurfStakedKey) | |
167 | 167 | fraction(toBigInt(totalSurfStaked), toBigInt(MULT6), toBigInt(xtnSwapLimitMax), HALFUP) | |
168 | 168 | } | |
169 | 169 | ||
170 | 170 | ||
171 | 171 | func checkProportion (xtnSwapLimitMax,surfAmount,xntAmount) = { | |
172 | 172 | let proportion = currentProportion(xtnSwapLimitMax) | |
173 | 173 | let expectedSurfAmount = toInt(fraction(proportion, toBigInt(xntAmount), toBigInt(MULT6), HALFUP)) | |
174 | 174 | if ((expectedSurfAmount == surfAmount)) | |
175 | 175 | then true | |
176 | 176 | else throw((((("With " + toString(xtnSwapLimitMax)) + " XNT amount you should provide ") + toString(expectedSurfAmount)) + " SURF amount to stake")) | |
177 | 177 | } | |
178 | 178 | ||
179 | 179 | ||
180 | 180 | let EMPTY = "^" | |
181 | 181 | ||
182 | 182 | func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP) | |
183 | 183 | ||
184 | 184 | ||
185 | 185 | func formatHistoryRecord (userAddress,lpAssetId,type,amount) = makeString(["%s%s%s%d%d%d", userAddress, lpAssetId, type, toString(height), toString(lastBlock.timestamp), toString(amount)], SEP) | |
186 | 186 | ||
187 | 187 | ||
188 | 188 | func OperationHistoryEntry (type,userAddress,lpAssetId,amount,txId) = StringEntry(keyOperationHistoryRecord(type, userAddress, toBase58String(txId)), formatHistoryRecord(userAddress, lpAssetId, type, amount)) | |
189 | 189 | ||
190 | 190 | ||
191 | 191 | func interactWithSwapParamsByUser () = { | |
192 | 192 | let result = invoke(Address(neutrinoStakingAddress), "swapParamsByUserSYSREADONLY", [this, 0], nil) | |
193 | 193 | if ((result == result)) | |
194 | 194 | then match result { | |
195 | 195 | case tuple: (Int, Int, Int, Int, Int, Int, Int) => | |
196 | 196 | [tuple._1, tuple._2, tuple._3, tuple._4, tuple._5, tuple._6, tuple._7] | |
197 | 197 | case _ => | |
198 | 198 | throw("FATAL: Can't fetch data from neutrino contract") | |
199 | 199 | } | |
200 | 200 | else throw("Strict value is not equal to itself.") | |
201 | 201 | } | |
202 | 202 | ||
203 | 203 | ||
204 | 204 | func isUserHasUnclaimedRewardsInPreviousPeriods (address) = { | |
205 | 205 | let userUnclaimedXtnSwapRewardPeriodId = asIntOrDef(getInteger(keyCurrentUserUnclaimedXtnSwapRewardPeriodId(address)), -1) | |
206 | 206 | let userUnclaimedSurfStakingRewardsPeriodId = asIntOrDef(getInteger(keyCurrentUserUnclaimedSurfStakingRewardPeriodId(address)), -1) | |
207 | 207 | let currentXTNSwapPeriod = asIntOrDef(getInteger(currentXTNSwapPeriodIdKey), 0) | |
208 | 208 | let currentSurfStakingRewardsPeriod = asIntOrDef(getInteger(currentSurfStakingRewardsPeriodIdKey), 0) | |
209 | 209 | if (if ((userUnclaimedXtnSwapRewardPeriodId > -1)) | |
210 | 210 | then (currentXTNSwapPeriod > userUnclaimedXtnSwapRewardPeriodId) | |
211 | 211 | else false) | |
212 | 212 | then true | |
213 | 213 | else if (if ((userUnclaimedSurfStakingRewardsPeriodId > -1)) | |
214 | 214 | then (currentSurfStakingRewardsPeriod > userUnclaimedSurfStakingRewardsPeriodId) | |
215 | 215 | else false) | |
216 | 216 | then true | |
217 | 217 | else false | |
218 | 218 | } | |
219 | 219 | ||
220 | 220 | ||
221 | 221 | @Callable(i) | |
222 | 222 | func constructor () = match getBoolean(constructedKey) { | |
223 | 223 | case _: Boolean => | |
224 | 224 | throw("Constructor can be called just once") | |
225 | 225 | case _ => | |
226 | 226 | [BooleanEntry(constructedKey, true), IntegerEntry(currentWithdrawalPeriodIdKey, 0), IntegerEntry(currentXTNSwapPeriodIdKey, 0), IntegerEntry(pendingTotalSurfAmountToWithdrawalKey, 0), IntegerEntry(devsWavesAmountKey, 0), IntegerEntry(devsSurfAmountKey, 0), IntegerEntry(devsWxAmountKey, 0), IntegerEntry(devsXtnAmountKey, 0), IntegerEntry(lastSuccessSwapBlockHeight, 0), IntegerEntry(xtnSwapStateEnumKey, caseXtnSwapStateIdle)] | |
227 | 227 | } | |
228 | 228 | ||
229 | 229 | ||
230 | 230 | ||
231 | 231 | @Callable(i) | |
232 | 232 | func stake () = if ((getIntegerValue(xtnSwapStateEnumKey) != caseXtnSwapStateIdle)) | |
233 | 233 | then throw("XTN swap in progress, wait approximatelly 3 minutes") | |
234 | 234 | else if ((size(i.payments) != 1)) | |
235 | 235 | then throw("You must include exactly one payment in transaction") | |
236 | 236 | else { | |
237 | 237 | let payment = asPayment(i.payments[0]) | |
238 | 238 | if (if ((payment.assetId != surfAssetId)) | |
239 | 239 | then true | |
240 | 240 | else (minAmount > payment.amount)) | |
241 | 241 | then throw("Wrong assetId or amount") | |
242 | 242 | else { | |
243 | 243 | let callerAddressString = toBase58String(i.caller.bytes) | |
244 | 244 | if (isUserHasUnclaimedRewardsInPreviousPeriods(callerAddressString)) | |
245 | 245 | then throw("You have unclaimed rewards, claim them first, then stake again") | |
246 | 246 | else { | |
247 | 247 | let result = invoke(Address(neutrinoStakingAddress), "stake", nil, [payment]) | |
248 | 248 | if ((result == result)) | |
249 | 249 | then { | |
250 | 250 | let newTotalSurfStaked = match getInteger(totalSurfStakedKey) { | |
251 | 251 | case v: Int => | |
252 | 252 | (v + payment.amount) | |
253 | 253 | case _ => | |
254 | 254 | payment.amount | |
255 | 255 | } | |
256 | 256 | let callerTotalSurfStakedKey = keyCurrentUserTotalSurfStaked(callerAddressString) | |
257 | 257 | let newCallerTotalSurfStaked = match getInteger(callerTotalSurfStakedKey) { | |
258 | 258 | case v: Int => | |
259 | 259 | (v + payment.amount) | |
260 | 260 | case _ => | |
261 | 261 | payment.amount | |
262 | 262 | } | |
263 | 263 | let currentXTNSwapPeriod = asIntOrDef(getInteger(currentXTNSwapPeriodIdKey), 0) | |
264 | 264 | let currentSurfStakingRewardsPeriod = asIntOrDef(getInteger(currentSurfStakingRewardsPeriodIdKey), 0) | |
265 | 265 | [IntegerEntry(totalSurfStakedKey, newTotalSurfStaked), IntegerEntry(callerTotalSurfStakedKey, newCallerTotalSurfStaked), IntegerEntry(keyCurrentUserUnclaimedXtnSwapRewardPeriodId(callerAddressString), currentXTNSwapPeriod), IntegerEntry(keyCurrentUserUnclaimedSurfStakingRewardPeriodId(callerAddressString), currentSurfStakingRewardsPeriod)] | |
266 | 266 | } | |
267 | 267 | else throw("Strict value is not equal to itself.") | |
268 | 268 | } | |
269 | 269 | } | |
270 | 270 | } | |
271 | 271 | ||
272 | 272 | ||
273 | 273 | ||
274 | 274 | @Callable(i) | |
275 | 275 | func applyForPendingWithdraw (amount) = if ((getIntegerValue(xtnSwapStateEnumKey) != caseXtnSwapStateIdle)) | |
276 | 276 | then throw("XTN swap in progress, wait approximatelly 3 minutes") | |
277 | 277 | else if ((size(i.payments) > 0)) | |
278 | 278 | then throw("This function does not accept payments") | |
279 | 279 | else if ((0 >= amount)) | |
280 | 280 | then throw("Amount must be positive") | |
281 | 281 | else { | |
282 | 282 | let callerAddressString = toBase58String(i.caller.bytes) | |
283 | 283 | let callerTotalSurfStaked = getIntegerValue(keyCurrentUserTotalSurfStaked(callerAddressString)) | |
284 | 284 | if ((amount > callerTotalSurfStaked)) | |
285 | 285 | then throw("Insufficient balance to withdraw") | |
286 | 286 | else if (isUserHasUnclaimedRewardsInPreviousPeriods(callerAddressString)) | |
287 | 287 | then throw("You have unclaimed rewards, claim them first, then try again") | |
288 | 288 | else { | |
289 | 289 | let currentWithdrawalId = getIntegerValue(currentWithdrawalPeriodIdKey) | |
290 | 290 | let pendingTotalSurfToUnstakeFromNeutrino = getIntegerValue(pendingTotalSurfAmountToWithdrawalKey) | |
291 | 291 | let userPendingWithdrawalPeriodId = asIntOrDef(getInteger(keyCurrentUserPendingWithdrawalPeriodId(callerAddressString)), -1) | |
292 | 292 | let userTotalSurfPendingForWithdrawal = asIntOrDef(getInteger(keyCurrentUserTotalSurfPendingForWithdrawal(callerAddressString)), 0) | |
293 | 293 | if (if ((userPendingWithdrawalPeriodId > -1)) | |
294 | 294 | then (currentWithdrawalId > userPendingWithdrawalPeriodId) | |
295 | 295 | else false) | |
296 | 296 | then throw("You have unclaimed suft on contract, please perform claim first") | |
297 | 297 | else { | |
298 | 298 | let userNewTotalSurfStakedAmount = (callerTotalSurfStaked - amount) | |
299 | 299 | let userNewTotalSurfPendingForWithdrawal = (userTotalSurfPendingForWithdrawal + amount) | |
300 | 300 | let newPendingTotalSurfToUnstakeFromNeutrino = (pendingTotalSurfToUnstakeFromNeutrino + amount) | |
301 | 301 | let newTotalSurfStakedAmount = (getIntegerValue(totalSurfStakedKey) - amount) | |
302 | 302 | [IntegerEntry(keyCurrentUserTotalSurfStaked(callerAddressString), userNewTotalSurfStakedAmount), IntegerEntry(keyCurrentUserPendingWithdrawalPeriodId(callerAddressString), currentWithdrawalId), IntegerEntry(keyCurrentUserTotalSurfPendingForWithdrawal(callerAddressString), userNewTotalSurfPendingForWithdrawal), IntegerEntry(pendingTotalSurfAmountToWithdrawalKey, newPendingTotalSurfToUnstakeFromNeutrino), IntegerEntry(totalSurfStakedKey, newTotalSurfStakedAmount)] | |
303 | 303 | } | |
304 | 304 | } | |
305 | 305 | } | |
306 | 306 | ||
307 | 307 | ||
308 | 308 | ||
309 | 309 | @Callable(i) | |
310 | 310 | func performDistributedWithdraw () = if ((size(i.payments) > 0)) | |
311 | 311 | then throw("This function does not accept payments") | |
312 | 312 | else { | |
313 | 313 | let currentWithdrawalId = getIntegerValue(currentWithdrawalPeriodIdKey) | |
314 | 314 | let pendingTotalSurfToUnstakeFromNeutrino = getIntegerValue(pendingTotalSurfAmountToWithdrawalKey) | |
315 | 315 | if ((0 >= pendingTotalSurfToUnstakeFromNeutrino)) | |
316 | 316 | then nil | |
317 | 317 | else { | |
318 | 318 | let result = invoke(Address(neutrinoStakingAddress), "unstake", [pendingTotalSurfToUnstakeFromNeutrino], nil) | |
319 | 319 | if ((result == result)) | |
320 | 320 | then [IntegerEntry(currentWithdrawalPeriodIdKey, (currentWithdrawalId + 1)), IntegerEntry(pendingTotalSurfAmountToWithdrawalKey, 0)] | |
321 | 321 | else throw("Strict value is not equal to itself.") | |
322 | 322 | } | |
323 | 323 | } | |
324 | 324 | ||
325 | 325 | ||
326 | 326 | ||
327 | 327 | @Callable(i) | |
328 | 328 | func claimSurf () = if ((size(i.payments) > 0)) | |
329 | 329 | then throw("This function does not accept payments") | |
330 | 330 | else { | |
331 | 331 | let callerAddressString = toBase58String(i.caller.bytes) | |
332 | 332 | let currentWithdrawalPeriodId = getIntegerValue(currentWithdrawalPeriodIdKey) | |
333 | 333 | let userWithdrawalPeriodId = asIntOrDef(getInteger(keyCurrentUserPendingWithdrawalPeriodId(callerAddressString)), -1) | |
334 | 334 | let userTotalSurfPendingForWithdrawal = asIntOrDef(getInteger(keyCurrentUserTotalSurfPendingForWithdrawal(callerAddressString)), 0) | |
335 | 335 | if (if ((userWithdrawalPeriodId == -1)) | |
336 | 336 | then true | |
337 | 337 | else (userTotalSurfPendingForWithdrawal == 0)) | |
338 | 338 | then throw("Nothing to withdraw") | |
339 | 339 | else if ((userWithdrawalPeriodId == currentWithdrawalPeriodId)) | |
340 | 340 | then throw("You must wait for period to complete") | |
341 | 341 | else [ScriptTransfer(i.caller, userTotalSurfPendingForWithdrawal, surfAssetId), DeleteEntry(keyCurrentUserPendingWithdrawalPeriodId(callerAddressString)), DeleteEntry(keyCurrentUserTotalSurfPendingForWithdrawal(callerAddressString))] | |
342 | 342 | } | |
343 | 343 | ||
344 | 344 | ||
345 | 345 | ||
346 | 346 | @Callable(i) | |
347 | 347 | func xtnSwapPart1swapXTNFromNeutrino () = if ((getIntegerValue(xtnSwapStateEnumKey) != caseXtnSwapStateIdle)) | |
348 | 348 | then throw("Wrong state, must be Idle") | |
349 | 349 | else { | |
350 | 350 | let withdrawResult = invoke(this, "performDistributedWithdraw", nil, nil) | |
351 | 351 | if ((withdrawResult == withdrawResult)) | |
352 | 352 | then { | |
353 | 353 | let result = invoke(Address(neutrinoContractAddress), "swapParamsByUserSYSREADONLY", [toString(this), 0], nil) | |
354 | 354 | if ((result == result)) | |
355 | 355 | then match result { | |
356 | 356 | case tuple: (Int, Int, Int, Int, Int, Int, Int) => | |
357 | 357 | if ((tuple._3 > 0)) | |
358 | 358 | then throw((("Time is not come yet, you need to wait " + toString(tuple._3)) + " blocks")) | |
359 | 359 | else { | |
360 | 360 | let maxSwapAmount = tuple._7 | |
361 | 361 | if ((1000000 > maxSwapAmount)) | |
362 | 362 | then throw("Min XTN amount to swap is 1, stake more SURF") | |
363 | 363 | else if ((maxSwapAmount > assetBalance(this, xtnAssetId))) | |
364 | 364 | then throw("XTN Balance on contract is smaller than max swap amount, increase XTN contract balance") | |
365 | 365 | else { | |
366 | 366 | let currentWavesBalance = wavesBalance(this) | |
367 | 367 | let currentWXBalance = assetBalance(this, wxAssetId) | |
368 | 368 | let swapNeutrinoToAssets = invoke(Address(neutrinoContractAddress), "swapNeutrinoToBasket", nil, [AttachedPayment(xtnAssetId, maxSwapAmount)]) | |
369 | 369 | if ((swapNeutrinoToAssets == swapNeutrinoToAssets)) | |
370 | 370 | then { | |
371 | 371 | let priceIndex = (getIntegerValue(Address(neutrinoPriceIndexAddress), "price_index") + 1) | |
372 | 372 | [IntegerEntry(xtnSwapBlockIdKey, height), StringEntry(xtnSwapTransactionIdKey, toBase58String(i.transactionId)), IntegerEntry(xtnSwapPriceIndexKey, priceIndex), IntegerEntry(xtnSwapXtnSwappedAmountKey, maxSwapAmount), IntegerEntry(xtnSwapWavesBalanceAtSwapKey, currentWavesBalance.available), IntegerEntry(xtnSwapWxBalanceAtSwapKey, currentWXBalance), IntegerEntry(xtnSwapStateEnumKey, caseXtnSwapStateXtnToRewards)] | |
373 | 373 | } | |
374 | 374 | else throw("Strict value is not equal to itself.") | |
375 | 375 | } | |
376 | 376 | } | |
377 | 377 | case _ => | |
378 | 378 | throw("Incorrect data from neutrino smart contract") | |
379 | 379 | } | |
380 | 380 | else throw("Strict value is not equal to itself.") | |
381 | 381 | } | |
382 | 382 | else throw("Strict value is not equal to itself.") | |
383 | 383 | } | |
384 | 384 | ||
385 | 385 | ||
386 | 386 | ||
387 | 387 | @Callable(i) | |
388 | 388 | func xtnSwapPart2exchangeXtnSwapRewardsOnDex () = if ((getIntegerValue(xtnSwapStateEnumKey) != caseXtnSwapStateXtnToRewards)) | |
389 | 389 | then throw("Wrong state, must be XtnToRewards") | |
390 | 390 | else if ((getIntegerValue(xtnSwapBlockIdKey) >= height)) | |
391 | 391 | then throw("Must wait for 1 block") | |
392 | 392 | else { | |
393 | 393 | let swapTransationId = getStringValue(xtnSwapTransactionIdKey) | |
394 | 394 | let swapPriceIndex = getIntegerValue(xtnSwapPriceIndexKey) | |
395 | 395 | let withdraw_res = invoke(Address(neutrinoContractAddress), "withdraw", [toString(this), swapPriceIndex, swapTransationId], nil) | |
396 | 396 | if ((withdraw_res == withdraw_res)) | |
397 | 397 | then { | |
398 | 398 | let wavesBalanceAtSwap = getIntegerValue(xtnSwapWavesBalanceAtSwapKey) | |
399 | 399 | let wxBalanceAtSwap = getIntegerValue(xtnSwapWxBalanceAtSwapKey) | |
400 | 400 | let currentWavesBalance = wavesBalance(this) | |
401 | 401 | let currentWXBalance = assetBalance(this, wxAssetId) | |
402 | 402 | let wavesRewards = (currentWavesBalance.available - wavesBalanceAtSwap) | |
403 | 403 | let wxRewards = (currentWXBalance - wxBalanceAtSwap) | |
404 | 404 | let exchangeWaves = if ((0 >= wavesRewards)) | |
405 | 405 | then nil | |
406 | 406 | else { | |
407 | 407 | let wavesSwap = invoke(Address(dexContract), "exchangeThenTransfer", [toString(Address(xtnAssetId)), toString(this), 0], [AttachedPayment(unit, wavesRewards)]) | |
408 | 408 | if ((wavesSwap == wavesSwap)) | |
409 | 409 | then nil | |
410 | 410 | else throw("Strict value is not equal to itself.") | |
411 | 411 | } | |
412 | 412 | if ((exchangeWaves == exchangeWaves)) | |
413 | 413 | then { | |
414 | 414 | let wxSwap = invoke(Address(dexContract), "exchangeThenTransfer", [toString(Address(xtnAssetId)), toString(this), 0], [AttachedPayment(wxAssetId, wxRewards)]) | |
415 | 415 | if ((wxSwap == wxSwap)) | |
416 | 416 | then [IntegerEntry("WAVES_REWARDS_FOR_SWAP", wavesRewards), IntegerEntry("WX_REWARDS_FOR_SWAP", wxRewards), IntegerEntry(xtnSwapXtnBalanceAtExchangeKey, assetBalance(this, xtnAssetId)), IntegerEntry(xtnSwapExchangeBlockIdKey, height), IntegerEntry(xtnSwapStateEnumKey, caseXtnSwapStateExchangeRewardsOnDex)] | |
417 | 417 | else throw("Strict value is not equal to itself.") | |
418 | 418 | } | |
419 | 419 | else throw("Strict value is not equal to itself.") | |
420 | 420 | } | |
421 | 421 | else throw("Strict value is not equal to itself.") | |
422 | 422 | } | |
423 | 423 | ||
424 | 424 | ||
425 | 425 | ||
426 | 426 | @Callable(i) | |
427 | 427 | func xtnSwapPart3FinalizeSwap () = if ((getIntegerValue(xtnSwapStateEnumKey) != caseXtnSwapStateExchangeRewardsOnDex)) | |
428 | 428 | then throw("Wrong state, must be Exchange rewards") | |
429 | 429 | else if ((getIntegerValue(xtnSwapExchangeBlockIdKey) >= height)) | |
430 | 430 | then throw("Must wait for 1 block") | |
431 | 431 | else if ((size(i.payments) > 0)) | |
432 | 432 | then throw("This function does not accept payments") | |
433 | 433 | else { | |
434 | 434 | let xtnAmountBeforeExchange = getIntegerValue(xtnSwapXtnBalanceAtExchangeKey) | |
435 | 435 | let xtnSwapped = getIntegerValue(xtnSwapXtnSwappedAmountKey) | |
436 | 436 | let currentXtnAmount = assetBalance(this, xtnAssetId) | |
437 | 437 | let xtnRewardAmountForPeriod = (currentXtnAmount - (xtnAmountBeforeExchange + xtnSwapped)) | |
438 | 438 | let currentXtnSwapPeriodId = getIntegerValue(currentXTNSwapPeriodIdKey) | |
439 | 439 | let totalSurfStaked = asIntOrDef(getInteger(totalSurfStakedKey), 0) | |
440 | 440 | let xtnRewardPerOneSurfForPeriod = if ((0 >= xtnRewardAmountForPeriod)) | |
441 | 441 | then 0 | |
442 | 442 | else fraction(xtnRewardAmountForPeriod, MULT6, totalSurfStaked, HALFUP) | |
443 | 443 | [IntegerEntry(keyCurrentXtnSwapPeriodXtnAmountForOneSurf(currentXtnSwapPeriodId), xtnRewardPerOneSurfForPeriod), IntegerEntry(currentXTNSwapPeriodIdKey, (currentXtnSwapPeriodId + 1)), IntegerEntry(xtnSwapStateEnumKey, caseXtnSwapStateIdle)] | |
444 | 444 | } | |
445 | 445 | ||
446 | 446 | ||
447 | 447 | ||
448 | 448 | @Callable(i) | |
449 | 449 | func claim () = { | |
450 | 450 | let xtnResult = invoke(this, "claimXtnSwapRewards", nil, nil) | |
451 | 451 | if ((xtnResult == xtnResult)) | |
452 | 452 | then { | |
453 | 453 | let surfResult = invoke(this, "claimSurfStakingRewards", nil, nil) | |
454 | 454 | if ((surfResult == surfResult)) | |
455 | 455 | then nil | |
456 | 456 | else throw("Strict value is not equal to itself.") | |
457 | 457 | } | |
458 | 458 | else throw("Strict value is not equal to itself.") | |
459 | 459 | } | |
460 | 460 | ||
461 | 461 | ||
462 | 462 | ||
463 | 463 | @Callable(i) | |
464 | 464 | func claimXtnSwapRewards () = if ((size(i.payments) > 0)) | |
465 | 465 | then throw("This function does not accept payments") | |
466 | 466 | else { | |
467 | 467 | let callerAddressString = toBase58String(i.caller.bytes) | |
468 | 468 | let currentXtnSwapPeriodId = asIntOrDef(getInteger(currentXTNSwapPeriodIdKey), 0) | |
469 | 469 | let currentUserUnclaimedXtnSwapRewardPeriodId = asIntOrDef(getInteger(keyCurrentUserUnclaimedXtnSwapRewardPeriodId(callerAddressString)), -1) | |
470 | 470 | if ((currentUserUnclaimedXtnSwapRewardPeriodId == -1)) | |
471 | 471 | then $Tuple2(nil, -1) | |
472 | 472 | else if ((currentUserUnclaimedXtnSwapRewardPeriodId == currentXtnSwapPeriodId)) | |
473 | 473 | then throw("You need to wait for current swap period to finish") | |
474 | 474 | else { | |
475 | 475 | let unclaimedXtnSwapsCount = (currentXtnSwapPeriodId - currentUserUnclaimedXtnSwapRewardPeriodId) | |
476 | 476 | let userTotalSurfStaked = getIntegerValue(keyCurrentUserTotalSurfStaked(callerAddressString)) | |
477 | 477 | let newCurrentUserUnclaimedXtnSwapRewardPeriodId = if ((unclaimedXtnSwapsCount > 45)) | |
478 | 478 | then (currentUserUnclaimedXtnSwapRewardPeriodId + 45) | |
479 | 479 | else currentXtnSwapPeriodId | |
480 | 480 | let iterations = if ((45 > unclaimedXtnSwapsCount)) | |
481 | 481 | then unclaimedXtnSwapsCount | |
482 | 482 | else 45 | |
483 | 483 | let result = invoke(this, "internalAccumulateXtnSwapRewards", [iterations, 0, currentUserUnclaimedXtnSwapRewardPeriodId, 0, userTotalSurfStaked, i.caller.bytes], nil) | |
484 | 484 | if ((result == result)) | |
485 | 485 | then [IntegerEntry(keyCurrentUserUnclaimedXtnSwapRewardPeriodId(callerAddressString), newCurrentUserUnclaimedXtnSwapRewardPeriodId)] | |
486 | 486 | else throw("Strict value is not equal to itself.") | |
487 | 487 | } | |
488 | 488 | } | |
489 | 489 | ||
490 | 490 | ||
491 | 491 | ||
492 | 492 | @Callable(i) | |
493 | - | func | |
493 | + | func fixKey () = [IntegerEntry("currentUserUnclaimedXtnSwapRewardPeriodId__3PAv42skNMWedMSNx75fMDuMcFzggaELYqK", 0)] | |
494 | 494 | ||
495 | 495 | ||
496 | 496 | ||
497 | 497 | @Callable(i) | |
498 | 498 | func internalAccumulateXtnSwapRewards (iterations,current,startXtnSwapPeriodId,accumulatedRewardXtn,userSurfAmount,address) = if ((this != i.caller)) | |
499 | 499 | then throw("Internal function") | |
500 | 500 | else if ((current >= iterations)) | |
501 | 501 | then if ((accumulatedRewardXtn > 0)) | |
502 | 502 | then [ScriptTransfer(Address(address), accumulatedRewardXtn, xtnAssetId)] | |
503 | 503 | else nil | |
504 | 504 | else { | |
505 | 505 | let xtnAmountPerSurf = asIntOrDef(getInteger(keyCurrentXtnSwapPeriodXtnAmountForOneSurf((startXtnSwapPeriodId + current))), 0) | |
506 | 506 | let reward = if ((xtnAmountPerSurf == 0)) | |
507 | 507 | then 0 | |
508 | 508 | else fraction(xtnAmountPerSurf, userSurfAmount, MULT6, HALFUP) | |
509 | 509 | let result = invoke(this, "internalAccumulateXtnSwapRewards", [iterations, (current + 1), (startXtnSwapPeriodId + current), (accumulatedRewardXtn + reward), userSurfAmount, address], nil) | |
510 | 510 | if ((result == result)) | |
511 | 511 | then nil | |
512 | 512 | else throw("Strict value is not equal to itself.") | |
513 | 513 | } | |
514 | 514 | ||
515 | 515 | ||
516 | 516 | ||
517 | 517 | @Callable(i) | |
518 | 518 | func claimSurfStakingRewards () = if ((size(i.payments) > 0)) | |
519 | 519 | then throw("This function does not accept payments") | |
520 | 520 | else { | |
521 | 521 | let callerAddressString = toBase58String(i.caller.bytes) | |
522 | 522 | let currentSurfStakingRewardsPeriodId = asIntOrDef(getInteger(currentSurfStakingRewardsPeriodIdKey), 0) | |
523 | 523 | let currentUserUnclaimedSurfStakingRewardPeriodId = asIntOrDef(getInteger(keyCurrentUserUnclaimedSurfStakingRewardPeriodId(callerAddressString)), -1) | |
524 | 524 | if ((currentUserUnclaimedSurfStakingRewardPeriodId == -1)) | |
525 | 525 | then $Tuple2(nil, -1) | |
526 | 526 | else if ((currentUserUnclaimedSurfStakingRewardPeriodId == currentSurfStakingRewardsPeriodId)) | |
527 | 527 | then throw("You need to wait for current swap period to finish") | |
528 | 528 | else { | |
529 | 529 | let unclaimedSurfStakingsCount = (currentSurfStakingRewardsPeriodId - currentUserUnclaimedSurfStakingRewardPeriodId) | |
530 | 530 | let userTotalSurfStaked = getIntegerValue(keyCurrentUserTotalSurfStaked(callerAddressString)) | |
531 | 531 | let newCurrentUserUnclaimedSurfStakingRewardPeriodId = if ((unclaimedSurfStakingsCount > 45)) | |
532 | 532 | then (currentUserUnclaimedSurfStakingRewardPeriodId + 45) | |
533 | 533 | else currentSurfStakingRewardsPeriodId | |
534 | 534 | let iterations = if ((45 > unclaimedSurfStakingsCount)) | |
535 | 535 | then unclaimedSurfStakingsCount | |
536 | 536 | else 45 | |
537 | 537 | let result = invoke(this, "internalAccumulateSurfStakingRewards", [iterations, 0, currentUserUnclaimedSurfStakingRewardPeriodId, 0, 0, 0, userTotalSurfStaked, i.caller.bytes], nil) | |
538 | 538 | if ((result == result)) | |
539 | 539 | then [IntegerEntry(keyCurrentUserUnclaimedSurfStakingRewardPeriodId(callerAddressString), newCurrentUserUnclaimedSurfStakingRewardPeriodId)] | |
540 | 540 | else throw("Strict value is not equal to itself.") | |
541 | 541 | } | |
542 | 542 | } | |
543 | 543 | ||
544 | 544 | ||
545 | 545 | ||
546 | 546 | @Callable(i) | |
547 | 547 | func internalAccumulateSurfStakingRewards (iterations,current,startSurfSwapPeriodId,accumulatedRewardWaves,accumulatedRewardWx,accumulatedRewardXtn,userSurfAmount,address) = if ((this != i.caller)) | |
548 | 548 | then throw("Internal function") | |
549 | 549 | else if ((current >= iterations)) | |
550 | 550 | then if (if (if ((accumulatedRewardXtn > 0)) | |
551 | 551 | then true | |
552 | 552 | else (accumulatedRewardWaves > 0)) | |
553 | 553 | then true | |
554 | 554 | else (accumulatedRewardWx > 0)) | |
555 | 555 | then [ScriptTransfer(Address(address), accumulatedRewardXtn, xtnAssetId), ScriptTransfer(Address(address), accumulatedRewardWaves, wavesAssetId), ScriptTransfer(Address(address), accumulatedRewardWx, wxAssetId)] | |
556 | 556 | else nil | |
557 | 557 | else { | |
558 | 558 | let xtnAmountPerSurf = asIntOrDef(getInteger(keyCurrentSurfStakingRewardPeriodXtnAmountForOneSurf((startSurfSwapPeriodId + current))), 0) | |
559 | 559 | let wavesAmountPerSurf = asIntOrDef(getInteger(keyCurrentSurfStakingRewardPeriodWavesAmountForOneSurf((startSurfSwapPeriodId + current))), 0) | |
560 | 560 | let wxAmountPerSurf = asIntOrDef(getInteger(keyCurrentSurfStakingRewardPeriodWxAmountForOneSurf((startSurfSwapPeriodId + current))), 0) | |
561 | 561 | let xtnReward = if ((xtnAmountPerSurf == 0)) | |
562 | 562 | then 0 | |
563 | 563 | else fraction(xtnAmountPerSurf, userSurfAmount, MULT6, HALFUP) | |
564 | 564 | let wavesReward = if ((wavesAmountPerSurf == 0)) | |
565 | 565 | then 0 | |
566 | 566 | else fraction(wavesAmountPerSurf, userSurfAmount, MULT6, HALFUP) | |
567 | 567 | let wxReward = if ((wxAmountPerSurf == 0)) | |
568 | 568 | then 0 | |
569 | 569 | else fraction(wxAmountPerSurf, userSurfAmount, MULT6, HALFUP) | |
570 | 570 | let result = invoke(this, "internalAccumulateSurfStakingRewards", [iterations, (current + 1), (startSurfSwapPeriodId + current), (accumulatedRewardWaves + wavesReward), (accumulatedRewardWx + wxReward), (accumulatedRewardXtn + xtnReward), userSurfAmount, address], nil) | |
571 | 571 | if ((result == result)) | |
572 | 572 | then nil | |
573 | 573 | else throw("Strict value is not equal to itself.") | |
574 | 574 | } | |
575 | 575 | ||
576 | 576 | ||
577 | 577 | ||
578 | 578 | @Callable(i) | |
579 | 579 | func surfStakingRewardsClaimFromNeutrino () = if ((size(i.payments) > 0)) | |
580 | 580 | then throw("This function does not accept payments") | |
581 | 581 | else { | |
582 | 582 | let currentWavesOnContract = assetBalance(this, wavesAssetId) | |
583 | 583 | if ((currentWavesOnContract == currentWavesOnContract)) | |
584 | 584 | then { | |
585 | 585 | let currentWxOnContract = assetBalance(this, wxAssetId) | |
586 | 586 | if ((currentWxOnContract == currentWxOnContract)) | |
587 | 587 | then { | |
588 | 588 | let currentXtnOnContract = assetBalance(this, xtnAssetId) | |
589 | 589 | if ((currentXtnOnContract == currentXtnOnContract)) | |
590 | 590 | then { | |
591 | 591 | let result = invoke(Address(neutrinoStakingAddress), "claimRewards", nil, nil) | |
592 | 592 | if ((result == result)) | |
593 | 593 | then { | |
594 | 594 | let newWavesOnContract = assetBalance(this, wavesAssetId) | |
595 | 595 | let newWxOnContract = assetBalance(this, wxAssetId) | |
596 | 596 | let newXtnOnContract = assetBalance(this, xtnAssetId) | |
597 | 597 | let wavesRewardAmountForPeriod = (newWavesOnContract - currentWavesOnContract) | |
598 | 598 | let wxRewardAmountForPeriod = (newWxOnContract - currentWxOnContract) | |
599 | 599 | let xtnRewardAmountForPeriod = (newXtnOnContract - currentXtnOnContract) | |
600 | 600 | let currentSurfStakingRewardsPeriodId = getIntegerValue(currentSurfStakingRewardsPeriodIdKey) | |
601 | 601 | let totalSurfStaked = asIntOrDef(getInteger(totalSurfStakedKey), 0) | |
602 | 602 | if (if ((totalSurfStaked == 0)) | |
603 | 603 | then if (if ((wavesRewardAmountForPeriod != 0)) | |
604 | 604 | then true | |
605 | 605 | else (wxRewardAmountForPeriod != 0)) | |
606 | 606 | then true | |
607 | 607 | else (xtnRewardAmountForPeriod != 0) | |
608 | 608 | else false) | |
609 | 609 | then { | |
610 | 610 | let newDevsWavesAmountAtContract = (getIntegerValue(devsWavesAmountKey) + wavesRewardAmountForPeriod) | |
611 | 611 | let newDevsWxAmountAtContract = (getIntegerValue(devsWxAmountKey) + wxRewardAmountForPeriod) | |
612 | 612 | let newDevsXtnAmountAtContract = (getIntegerValue(devsXtnAmountKey) + xtnRewardAmountForPeriod) | |
613 | 613 | [IntegerEntry(keyCurrentSurfStakingRewardPeriodWavesAmountForOneSurf(currentSurfStakingRewardsPeriodId), 0), IntegerEntry(keyCurrentSurfStakingRewardPeriodWxAmountForOneSurf(currentSurfStakingRewardsPeriodId), 0), IntegerEntry(keyCurrentSurfStakingRewardPeriodXtnAmountForOneSurf(currentSurfStakingRewardsPeriodId), 0), IntegerEntry(currentSurfStakingRewardsPeriodIdKey, (currentSurfStakingRewardsPeriodId + 1)), IntegerEntry(devsWavesAmountKey, newDevsWavesAmountAtContract), IntegerEntry(devsWxAmountKey, newDevsWxAmountAtContract), IntegerEntry(devsXtnAmountKey, newDevsXtnAmountAtContract)] | |
614 | 614 | } | |
615 | 615 | else if ((totalSurfStaked == 0)) | |
616 | 616 | then nil | |
617 | 617 | else { | |
618 | 618 | let wavesRewardPerOneSurfForPeriod = if ((wavesRewardAmountForPeriod == 0)) | |
619 | 619 | then 0 | |
620 | 620 | else fraction(wavesRewardAmountForPeriod, MULT6, totalSurfStaked, HALFUP) | |
621 | 621 | let wxRewardPerOneSurfForPeriod = if ((wxRewardAmountForPeriod == 0)) | |
622 | 622 | then 0 | |
623 | 623 | else fraction(wxRewardAmountForPeriod, MULT6, totalSurfStaked, HALFUP) | |
624 | 624 | let xtnRewardPerOneSurfForPeriod = if ((xtnRewardAmountForPeriod == 0)) | |
625 | 625 | then 0 | |
626 | 626 | else fraction(xtnRewardAmountForPeriod, MULT6, totalSurfStaked, HALFUP) | |
627 | 627 | [IntegerEntry(keyCurrentSurfStakingRewardPeriodWavesAmountForOneSurf(currentSurfStakingRewardsPeriodId), wavesRewardPerOneSurfForPeriod), IntegerEntry(keyCurrentSurfStakingRewardPeriodWxAmountForOneSurf(currentSurfStakingRewardsPeriodId), wxRewardPerOneSurfForPeriod), IntegerEntry(keyCurrentSurfStakingRewardPeriodXtnAmountForOneSurf(currentSurfStakingRewardsPeriodId), xtnRewardPerOneSurfForPeriod), IntegerEntry(currentSurfStakingRewardsPeriodIdKey, (currentSurfStakingRewardsPeriodId + 1))] | |
628 | 628 | } | |
629 | 629 | } | |
630 | 630 | else throw("Strict value is not equal to itself.") | |
631 | 631 | } | |
632 | 632 | else throw("Strict value is not equal to itself.") | |
633 | 633 | } | |
634 | 634 | else throw("Strict value is not equal to itself.") | |
635 | 635 | } | |
636 | 636 | else throw("Strict value is not equal to itself.") | |
637 | 637 | } | |
638 | 638 | ||
639 | 639 | ||
640 | 640 | @Verifier(tx) | |
641 | 641 | func verify () = sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
642 | 642 |
github/deemru/w8io/6500d08 61.95 ms ◑