tx · HKdgDHNXX61vjPXbLMMJgDY5DC7GBxoF2KS8gMD2vVUE

3MqzKJcjfKxqGWSA84WR4kQwZksM5vjxiFp:  -0.36000000 Waves

2022.12.02 16:58 [2342819] smart account 3MqzKJcjfKxqGWSA84WR4kQwZksM5vjxiFp > SELF 0.00000000 Waves

{ "type": 13, "id": "HKdgDHNXX61vjPXbLMMJgDY5DC7GBxoF2KS8gMD2vVUE", "fee": 36000000, "feeAssetId": null, "timestamp": 1669989551104, "version": 2, "chainId": 84, "sender": "3MqzKJcjfKxqGWSA84WR4kQwZksM5vjxiFp", "senderPublicKey": "bS6Cchmk25EdDcapkz8W5WkZgthTHHW6sSBbcidSrCb", "proofs": [ "67WFKUgvKMBGTbvEZ9TGjp8LLrbAFG39wm7R1EtRksGziqm8mdf2Ue5ZM27PFU9Bumz5V7evRs3AjbQbp5Cv6vex" ], "script": "base64:BgItCAISCQoHAQEBAQEIARIAEgQKAggIEgMKAQgSBAoCCAgSBAoCCAgSAwoBCBIAQwEPZ2V0U3RyaW5nT3JGYWlsAQNrZXkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoggBBQNrZXkJAKwCAgkArAICAg9tYW5kYXRvcnkgdGhpcy4FA2tleQIPIGlzIG5vdCBkZWZpbmVkAANTRVACAl9fAAhCVUZTQ0FMRQkAtgIBAICAkLu61q3wDQAGc2NhbGU4AIDC1y8BCHRocm93RXJyAQNtc2cJAAIBCQC5CQIJAMwIAgIJaWRvLnJpZGU6CQDMCAIFA21zZwUDbmlsAgEgAQhhc1N0cmluZwEDdmFsBAckbWF0Y2gwBQN2YWwDCQABAgUHJG1hdGNoMAIGU3RyaW5nBAZ2YWxTdHIFByRtYXRjaDAFBnZhbFN0cgkAAgECGGZhaWwgdG8gY2FzdCBpbnRvIFN0cmluZwEdY29udmVydFByaWNlQXNzZXRJbnRvSWRvQXNzZXQFEHByaWNlQXNzZXRBbW91bnQOcHJpY2VBc3NldE1VTFQFcHJpY2UJcHJpY2VNVUxUDGlkb0Fzc2V0TVVMVAQPYlByaWNlQXNzZXRNVUxUCQC2AgEFDnByaWNlQXNzZXRNVUxUBA1iSWRvQXNzZXRNVUxUCQC2AgEFDGlkb0Fzc2V0TVVMVAQOYlByaWNlQXNzZXRCVUYJALwCAwkAtgIBBRBwcmljZUFzc2V0QW1vdW50BQhCVUZTQ0FMRQUPYlByaWNlQXNzZXRNVUxUBA9iQW1vdW50QXNzZXRCVUYJALwCAwUOYlByaWNlQXNzZXRCVUYJALYCAQUJcHJpY2VNVUxUCQC2AgEFBXByaWNlCQCgAwEJALwCAwUPYkFtb3VudEFzc2V0QlVGCQC2AgEFDGlkb0Fzc2V0TVVMVAUIQlVGU0NBTEUADklkeENmZ0lkb1N0YXJ0AAEAEUlkeENmZ0lkb0R1cmF0aW9uAAIAEElkeENmZ0NsYWltU3RhcnQAAwATSWR4Q2ZnQ2xhaW1EdXJhdGlvbgAEAAtJZHhDZmdQcmljZQAFAA9JZHhDZmdQcmljZU11bHQABgAQSWR4Q2ZnSWRvQXNzZXRJZAAHABJJZHhDZmdJZG9Bc3NldE11bHQACAASSWR4Q2ZnUHJpY2VBc3NldElkAAkAFElkeENmZ1ByaWNlQXNzZXRNdWx0AAoAFUlkeENmZ01pbkludmVzdEFtb3VudAALAQ1mcm9tYXRDb25maWdTDAhpZG9TdGFydAtpZG9EdXJhdGlvbgpjbGFpbVN0YXJ0DWNsYWltRHVyYXRpb24FcHJpY2UJcHJpY2VNdWx0DGlkb0Fzc2V0SWQ1OAxpZG9Bc3NldE11bHQOcHJpY2VBc3NldElkNTgOcHJpY2VBc3NldE11bHQPbWluSW52ZXN0QW1vdW50E3RvdGFsSWRvQXNzZXRUb1NlbGwJALkJAgkAzAgCAhglZCVkJWQlZCVkJWQlcyVkJXMlZCVkJWQJAMwIAgUIaWRvU3RhcnQJAMwIAgULaWRvRHVyYXRpb24JAMwIAgUKY2xhaW1TdGFydAkAzAgCBQ1jbGFpbUR1cmF0aW9uCQDMCAIFBXByaWNlCQDMCAIFCXByaWNlTXVsdAkAzAgCBQxpZG9Bc3NldElkNTgJAMwIAgUMaWRvQXNzZXRNdWx0CQDMCAIFDnByaWNlQXNzZXRJZDU4CQDMCAIFDnByaWNlQXNzZXRNdWx0CQDMCAIFD21pbkludmVzdEFtb3VudAkAzAgCBRN0b3RhbElkb0Fzc2V0VG9TZWxsBQNuaWwFA1NFUAEMZnJvbWF0Q29uZmlnDAhpZG9TdGFydAtpZG9EdXJhdGlvbgpjbGFpbVN0YXJ0DWNsYWltRHVyYXRpb24FcHJpY2UJcHJpY2VNdWx0DGlkb0Fzc2V0SWQ1OAxpZG9Bc3NldE11bHQOcHJpY2VBc3NldElkNTgOcHJpY2VBc3NldE11bHQPbWluSW52ZXN0QW1vdW50E3RvdGFsSWRvQXNzZXRUb1NlbGwJAQ1mcm9tYXRDb25maWdTDAkApAMBBQhpZG9TdGFydAkApAMBBQtpZG9EdXJhdGlvbgkApAMBBQpjbGFpbVN0YXJ0CQCkAwEFDWNsYWltRHVyYXRpb24JAKQDAQUFcHJpY2UJAKQDAQUJcHJpY2VNdWx0BQxpZG9Bc3NldElkNTgJAKQDAQUMaWRvQXNzZXRNdWx0BQ5wcmljZUFzc2V0SWQ1OAkApAMBBQ5wcmljZUFzc2V0TXVsdAkApAMBBQ9taW5JbnZlc3RBbW91bnQJAKQDAQUTdG90YWxJZG9Bc3NldFRvU2VsbAARSWR4SW52VG90YWxBbW91bnQAAQAVSWR4SW52UmVtYWluaW5nQW1vdW50AAIAHUlkeEludkNsYWltZWRQcmljZUFzc2V0QW1vdW50AAMAG0lkeEludkNsYWltZWRJZG9Bc3NldEFtb3VudAAEABdJZHhJbnZMYXN0Q2xhaW1lZEhlaWdodAAFAQ9mb3JtYXRJbnZlc3RvclMFC3RvdGFsQW1vdW50D3JlbWFpbmluZ0Ftb3VudBdjbGFpbWVkUHJpY2VBc3NldEFtb3VudBVjbGFpbWVkSWRvQXNzZXRBbW91bnQRbGFzdENsYWltZWRIZWlnaHQJALkJAgkAzAgCAgolZCVkJWQlZCVkCQDMCAIFC3RvdGFsQW1vdW50CQDMCAIFD3JlbWFpbmluZ0Ftb3VudAkAzAgCBRdjbGFpbWVkUHJpY2VBc3NldEFtb3VudAkAzAgCBRVjbGFpbWVkSWRvQXNzZXRBbW91bnQJAMwIAgURbGFzdENsYWltZWRIZWlnaHQFA25pbAUDU0VQAQ5mb3JtYXRJbnZlc3RvcgULdG90YWxBbW91bnQPcmVtYWluaW5nQW1vdW50F2NsYWltZWRQcmljZUFzc2V0QW1vdW50FWNsYWltZWRJZG9Bc3NldEFtb3VudBFsYXN0Q2xhaW1lZEhlaWdodAkBD2Zvcm1hdEludmVzdG9yUwUJAKQDAQULdG90YWxBbW91bnQJAKQDAQUPcmVtYWluaW5nQW1vdW50CQCkAwEFF2NsYWltZWRQcmljZUFzc2V0QW1vdW50CQCkAwEFFWNsYWltZWRJZG9Bc3NldEFtb3VudAkApAMBBRFsYXN0Q2xhaW1lZEhlaWdodAETZm9ybWF0SGlzdG9yeVJlY29yZAIQcHJpY2VBc3NldEFtb3VudA5pZG9Bc3NldEFtb3VudAkAuQkCCQDMCAICCCVkJWQlZCVkCQDMCAIJAKQDAQUGaGVpZ2h0CQDMCAIJAKQDAQgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkApAMBBRBwcmljZUFzc2V0QW1vdW50CQDMCAIJAKQDAQUOaWRvQXNzZXRBbW91bnQFA25pbAUDU0VQAQlrZXlDb25maWcAAgolc19fY29uZmlnAQtrZXlJbnZlc3RvcgELdXNlckFkZHJlc3MJAKwCAgIEJXNfXwULdXNlckFkZHJlc3MBCWtleVRvdGFscwACCiVzX190b3RhbHMBGWtleU9wZXJhdGlvbkhpc3RvcnlSZWNvcmQDBHR5cGULdXNlckFkZHJlc3MGdHhJZDU4CQC5CQIJAMwIAgIRJXMlcyVzJXNfX2hpc3RvcnkJAMwIAgUEdHlwZQkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCBQZ0eElkNTgFA25pbAUDU0VQARRrZXlVU0ROQ2xhaW1EaXNhYmxlZAACFSVzX191c2RuQ2xhaW1EaXNhYmxlZAEVa2V5VVNETkNsYWltRW5kSGVpZ2h0AAIWJXNfX3VzZG5DbGFpbUVuZEhlaWdodAEPa2V5UGVyaW9kTGVuZ3RoAAkAuQkCCQDMCAICAiVzCQDMCAICDHBlcmlvZExlbmd0aAUDbmlsBQNTRVABEGtleUN1cnJlbnRQZXJpb2QACQC5CQIJAMwIAgICJXMJAMwIAgINY3VycmVudFBlcmlvZAUDbmlsBQNTRVABFGtleVBlcmlvZFN0YXJ0SGVpZ2h0AQlwZXJpb2ROdW0JALkJAgkAzAgCAgQlcyVzCQDMCAICEXBlcmlvZFN0YXJ0SGVpZ2h0CQDMCAIJAKQDAQUJcGVyaW9kTnVtBQNuaWwFA1NFUAESa2V5UGVyaW9kRW5kSGVpZ2h0AQlwZXJpb2ROdW0JALkJAgkAzAgCAgQlcyVzCQDMCAICD3BlcmlvZEVuZEhlaWdodAkAzAgCCQCkAwEFCXBlcmlvZE51bQUDbmlsBQNTRVABH2tleVVzZHRQcmljZUFzc2V0QWxsb3dhYmxlUmF0aW8ACQC5CQIJAMwIAgICJXMJAMwIAgIcdXNkdFByaWNlQXNzZXRBbGxvd2FibGVSYXRpbwUDbmlsBQNTRVABF2tleVRvdGFsUGVyaW9kQWxsb3dhbmNlAQdhc3NldElkCQC5CQIJAMwIAgIEJXMlcwkAzAgCAhR0b3RhbFBlcmlvZEFsbG93YW5jZQkAzAgCBQdhc3NldElkBQNuaWwFA1NFUAEWa2V5VXNlclBlcmlvZEFsbG93YW5jZQEHYXNzZXRJZAkAuQkCCQDMCAICBCVzJXMJAMwIAgITdXNlclBlcmlvZEFsbG93YW5jZQkAzAgCBQdhc3NldElkBQNuaWwFA1NFUAEea2V5UGVyaW9kVG90YWxBdmFpbGFibGVUb0NsYWltAgdhc3NldElkCXBlcmlvZE51bQkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAhtwZXJpb2RUb3RhbEF2YWlsYWJsZVRvQ2xhaW0JAMwIAgUHYXNzZXRJZAkAzAgCCQCkAwEFCXBlcmlvZE51bQUDbmlsBQNTRVABHWtleVBlcmlvZFVzZXJBdmFpbGFibGVUb0NsYWltAwdhc3NldElkCXBlcmlvZE51bQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICCCVzJXMlcyVzCQDMCAICGnBlcmlvZFVzZXJBdmFpbGFibGVUb0NsYWltCQDMCAIFB2Fzc2V0SWQJAMwIAgkApAMBBQlwZXJpb2ROdW0JAMwIAgULdXNlckFkZHJlc3MFA25pbAUDU0VQARtrZXlVc2R0UHJpY2VBc3NldFN0YWJsZVBvb2wACQC5CQIJAMwIAgICJXMJAMwIAgIYdXNkdFByaWNlQXNzZXRTdGFibGVQb29sBQNuaWwFA1NFUAEOa2V5VXNkdEFzc2V0SWQACQC5CQIJAMwIAgICJXMJAMwIAgILdXNkdEFzc2V0SWQFA25pbAUDU0VQARRrZXlQcmljZUFzc2V0QmFsYW5jZQEHYWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIRcHJpY2VBc3NldEJhbGFuY2UJAMwIAgUHYWRkcmVzcwUDbmlsBQNTRVABGmtleUludmVzdG9yUmVtYWluaW5nQW1vdW50AQdhZGRyZXNzCQC5CQIJAMwIAgIEJXMlcwkAzAgCAhdpbnZlc3RvclJlbWFpbmluZ0Ftb3VudAkAzAgCBQdhZGRyZXNzBQNuaWwFA1NFUAEXa2V5VG90YWxSZW1haW5pbmdBbW91bnQACQC5CQIJAMwIAgICJXMJAMwIAgIUdG90YWxSZW1haW5pbmdBbW91bnQFA25pbAUDU0VQARNrZXlNYW5hZ2VyUHVibGljS2V5AAIUJXNfX21hbmFnZXJQdWJsaWNLZXkBGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAIbJXNfX3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AQ9yZWFkQ29uZmlnQXJyYXkACQC1CQIJAQ9nZXRTdHJpbmdPckZhaWwBCQEJa2V5Q29uZmlnAAUDU0VQASNyZWFkVG90YWxzQXJyYXlPckRlZmF1bHRCeUN1c3RvbUtleQEJY3VzdG9tS2V5CQC1CQIJAQt2YWx1ZU9yRWxzZQIJAKIIAQUJY3VzdG9tS2V5CQEPZm9ybWF0SW52ZXN0b3JTBQIBMAIBMAIBMAIBMAIBMAUDU0VQARhyZWFkVG90YWxzQXJyYXlPckRlZmF1bHQACQEjcmVhZFRvdGFsc0FycmF5T3JEZWZhdWx0QnlDdXN0b21LZXkBCQEJa2V5VG90YWxzAAEacmVhZEludmVzdG9yQXJyYXlPckRlZmF1bHQBC3VzZXJBZGRyZXNzCQEjcmVhZFRvdGFsc0FycmF5T3JEZWZhdWx0QnlDdXN0b21LZXkBCQELa2V5SW52ZXN0b3IBBQt1c2VyQWRkcmVzcwEXcmVhZEludmVzdG9yQXJyYXlPckZhaWwBC3VzZXJBZGRyZXNzCQC1CQIJAQ9nZXRTdHJpbmdPckZhaWwBCQELa2V5SW52ZXN0b3IBBQt1c2VyQWRkcmVzcwUDU0VQABVJZHhEaWZmVG90YWxJbmNyZW1lbnQAAAAkSWR4RGlmZlJlbWFpbmluZ1ByaWNlQW1vdW50SW5jcmVtZW50AAEAIklkeERpZmZDbGFpbWVkUHJpY2VBbW91bnRJbmNyZW1lbnQAAgAlSWR4RGlmZkNsYWltZWRJZG9Bc3NldEFtb3VudEluY3JlbWVudAADAQtUb3RhbHNFbnRyeQUDa2V5CW9yaWdBcnJheQ1pbmNyZW1lbnREaWZmFG5ld0xhc3RDbGFpbWVkSGVpZ2h0EXByaWNlQXNzZXRCYWxhbmNlBAt0b3RhbEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCW9yaWdBcnJheQURSWR4SW52VG90YWxBbW91bnQED3JlbWFpbmluZ0Ftb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCW9yaWdBcnJheQUVSWR4SW52UmVtYWluaW5nQW1vdW50BBdjbGFpbWVkUHJpY2VBc3NldEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCW9yaWdBcnJheQUdSWR4SW52Q2xhaW1lZFByaWNlQXNzZXRBbW91bnQEFWNsYWltZWRJZG9Bc3NldEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCW9yaWdBcnJheQUbSWR4SW52Q2xhaW1lZElkb0Fzc2V0QW1vdW50BBFsYXN0Q2xhaW1lZEhlaWdodAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCW9yaWdBcnJheQUXSWR4SW52TGFzdENsYWltZWRIZWlnaHQEDm5ld1RvdGFsQW1vdW50CQBkAgULdG90YWxBbW91bnQJAJEDAgUNaW5jcmVtZW50RGlmZgUVSWR4RGlmZlRvdGFsSW5jcmVtZW50BBJuZXdSZW1haW5pbmdBbW91bnQJAGQCBQ9yZW1haW5pbmdBbW91bnQJAJEDAgUNaW5jcmVtZW50RGlmZgUkSWR4RGlmZlJlbWFpbmluZ1ByaWNlQW1vdW50SW5jcmVtZW50BAhjZmdBcnJheQkBD3JlYWRDb25maWdBcnJheQAEDnByaWNlQXNzZXRJZDU4CQCRAwIFCGNmZ0FycmF5BRJJZHhDZmdQcmljZUFzc2V0SWQEEnByaWNlQXNzZXREZWNpbWFscwgJAQV2YWx1ZQEJAOwHAQkA2QQBBQ5wcmljZUFzc2V0SWQ1OAhkZWNpbWFscwQjcHJpY2VBc3NldEJhbGFuY2VQcmljZUFzc2V0RGVjaW1hbHMJAGsDBRFwcmljZUFzc2V0QmFsYW5jZQUGc2NhbGU4CQBsBgAKAAAFEnByaWNlQXNzZXREZWNpbWFscwAAAAAFBERPV04EGm5ld0NsYWltZWRQcmljZUFzc2V0QW1vdW50CQBlAgkAZAIFF2NsYWltZWRQcmljZUFzc2V0QW1vdW50CQCRAwIFDWluY3JlbWVudERpZmYFIklkeERpZmZDbGFpbWVkUHJpY2VBbW91bnRJbmNyZW1lbnQFEXByaWNlQXNzZXRCYWxhbmNlBBhuZXdDbGFpbWVkSWRvQXNzZXRBbW91bnQJAGQCCQBkAgUVY2xhaW1lZElkb0Fzc2V0QW1vdW50CQCRAwIFDWluY3JlbWVudERpZmYFJUlkeERpZmZDbGFpbWVkSWRvQXNzZXRBbW91bnRJbmNyZW1lbnQFI3ByaWNlQXNzZXRCYWxhbmNlUHJpY2VBc3NldERlY2ltYWxzBAdlbnRyaWVzAwkAZgIAAAUSbmV3UmVtYWluaW5nQW1vdW50BARkaWZmCQBlAgkAZQIFDm5ld1RvdGFsQW1vdW50BRpuZXdDbGFpbWVkUHJpY2VBc3NldEFtb3VudAUYbmV3Q2xhaW1lZElkb0Fzc2V0QW1vdW50BBduZXdMb2dpY1JlbWFpbmluZ0Ftb3VudAMJAGYCAAAFBGRpZmYAAAUEZGlmZgkBC1N0cmluZ0VudHJ5AgUDa2V5CQEOZm9ybWF0SW52ZXN0b3IFBQ5uZXdUb3RhbEFtb3VudAUXbmV3TG9naWNSZW1haW5pbmdBbW91bnQFGm5ld0NsYWltZWRQcmljZUFzc2V0QW1vdW50BRhuZXdDbGFpbWVkSWRvQXNzZXRBbW91bnQFFG5ld0xhc3RDbGFpbWVkSGVpZ2h0CQELU3RyaW5nRW50cnkCBQNrZXkJAQ5mb3JtYXRJbnZlc3RvcgUFDm5ld1RvdGFsQW1vdW50BRJuZXdSZW1haW5pbmdBbW91bnQFGm5ld0NsYWltZWRQcmljZUFzc2V0QW1vdW50BRhuZXdDbGFpbWVkSWRvQXNzZXRBbW91bnQFFG5ld0xhc3RDbGFpbWVkSGVpZ2h0BQdlbnRyaWVzARtJbnZlc3RPcGVyYXRpb25IaXN0b3J5RW50cnkEC3VzZXJBZGRyZXNzEHByaWNlQXNzZXRBbW91bnQOaWRvQXNzZXRBbW91bnQEdHhJZAkBC1N0cmluZ0VudHJ5AgkBGWtleU9wZXJhdGlvbkhpc3RvcnlSZWNvcmQDAgZpbnZlc3QFC3VzZXJBZGRyZXNzCQDYBAEFBHR4SWQJARNmb3JtYXRIaXN0b3J5UmVjb3JkAgUQcHJpY2VBc3NldEFtb3VudAUOaWRvQXNzZXRBbW91bnQBGkNsYWltT3BlcmF0aW9uSGlzdG9yeUVudHJ5BAt1c2VyQWRkcmVzcxBwcmljZUFzc2V0QW1vdW50Dmlkb0Fzc2V0QW1vdW50BHR4SWQJAQtTdHJpbmdFbnRyeQIJARlrZXlPcGVyYXRpb25IaXN0b3J5UmVjb3JkAwIFY2xhaW0FC3VzZXJBZGRyZXNzCQDYBAEFBHR4SWQJARNmb3JtYXRIaXN0b3J5UmVjb3JkAgUQcHJpY2VBc3NldEFtb3VudAUOaWRvQXNzZXRBbW91bnQBDWludGVybmFsQ2xhaW0DEGNsYWltZWRBc3NldElkNTgLdXNlckFkZHJlc3MEdHhJZAQIY2ZnQXJyYXkJAQ9yZWFkQ29uZmlnQXJyYXkABApjbGFpbVN0YXJ0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFEElkeENmZ0NsYWltU3RhcnQEDWNsYWltRHVyYXRpb24JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUTSWR4Q2ZnQ2xhaW1EdXJhdGlvbgQIY2xhaW1FbmQJAGQCBQpjbGFpbVN0YXJ0BQ1jbGFpbUR1cmF0aW9uBAVwcmljZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BQtJZHhDZmdQcmljZQQJcHJpY2VNdWx0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFD0lkeENmZ1ByaWNlTXVsdAQMaWRvQXNzZXRJZDU4CQCRAwIFCGNmZ0FycmF5BRBJZHhDZmdJZG9Bc3NldElkBAppZG9Bc3NldElkCQDZBAEFDGlkb0Fzc2V0SWQ1OAQMaWRvQXNzZXRNdWx0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFEklkeENmZ0lkb0Fzc2V0TXVsdAQOcHJpY2VBc3NldElkNTgJAJEDAgUIY2ZnQXJyYXkFEklkeENmZ1ByaWNlQXNzZXRJZAQMcHJpY2VBc3NldElkCQDZBAEFDnByaWNlQXNzZXRJZDU4BA5wcmljZUFzc2V0TXVsdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRRJZHhDZmdQcmljZUFzc2V0TXVsdAQNdXNlckFkZHJlc3M1OAkApQgBBQt1c2VyQWRkcmVzcwQPb3JpZ0ludmVzdEFycmF5CQEXcmVhZEludmVzdG9yQXJyYXlPckZhaWwBBQ11c2VyQWRkcmVzczU4BBFpbnZlc3RUb3RhbEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD29yaWdJbnZlc3RBcnJheQURSWR4SW52VG90YWxBbW91bnQEGmludmVzdExhc3RDbGFpbWVkSGVpZ2h0VE1QCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPb3JpZ0ludmVzdEFycmF5BRdJZHhJbnZMYXN0Q2xhaW1lZEhlaWdodAQXaW52ZXN0TGFzdENsYWltZWRIZWlnaHQDCQBnAgUKY2xhaW1TdGFydAUaaW52ZXN0TGFzdENsYWltZWRIZWlnaHRUTVAFCmNsYWltU3RhcnQFGmludmVzdExhc3RDbGFpbWVkSGVpZ2h0VE1QBBRuZXdDbGFpbVBlcmlvZEhlaWdodAMJAGYCBQZoZWlnaHQFCGNsYWltRW5kBQhjbGFpbUVuZAMJAGYCBQpjbGFpbVN0YXJ0BQZoZWlnaHQFCmNsYWltU3RhcnQFBmhlaWdodAQOY2xhaW1pbmdCbG9ja3MJAGUCBRRuZXdDbGFpbVBlcmlvZEhlaWdodAUXaW52ZXN0TGFzdENsYWltZWRIZWlnaHQEGGNsYWltaW5nUHJpY2VBc3NldEFtb3VudAkAawMFEWludmVzdFRvdGFsQW1vdW50BQ5jbGFpbWluZ0Jsb2NrcwUNY2xhaW1EdXJhdGlvbgQWY2xhaW1pbmdJZG9Bc3NldEFtb3VudAkBHWNvbnZlcnRQcmljZUFzc2V0SW50b0lkb0Fzc2V0BQUYY2xhaW1pbmdQcmljZUFzc2V0QW1vdW50BQ5wcmljZUFzc2V0TXVsdAUFcHJpY2UFCXByaWNlTXVsdAUMaWRvQXNzZXRNdWx0BAZpc1VTRE4JAAACBRBjbGFpbWVkQXNzZXRJZDU4BQ5wcmljZUFzc2V0SWQ1OAQTaXNVU0ROQ2xhaW1EaXNhYmxlZAkBC3ZhbHVlT3JFbHNlAgkAoAgBCQEUa2V5VVNETkNsYWltRGlzYWJsZWQABwQGY2hlY2tzCQDMCAIDCQEBIQEDBQZpc1VTRE4FE2lzVVNETkNsYWltRGlzYWJsZWQHBgkAAgECFlVTRE4gY2xhaW0gaXMgZGlzYWJsZWQFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwMJAAACBRBjbGFpbWVkQXNzZXRJZDU4BQ5wcmljZUFzc2V0SWQ1OAkAmAoGCQDMCAIAAAkAzAgCCQEBLQEFGGNsYWltaW5nUHJpY2VBc3NldEFtb3VudAkAzAgCBRhjbGFpbWluZ1ByaWNlQXNzZXRBbW91bnQJAMwIAgAABQNuaWwFGGNsYWltaW5nUHJpY2VBc3NldEFtb3VudAUMcHJpY2VBc3NldElkBQ9vcmlnSW52ZXN0QXJyYXkFFG5ld0NsYWltUGVyaW9kSGVpZ2h0CQDMCAIFGGNsYWltaW5nUHJpY2VBc3NldEFtb3VudAkAzAgCBRZjbGFpbWluZ0lkb0Fzc2V0QW1vdW50BQNuaWwDCQAAAgUQY2xhaW1lZEFzc2V0SWQ1OAUMaWRvQXNzZXRJZDU4CQCYCgYJAMwIAgAACQDMCAIJAQEtAQUYY2xhaW1pbmdQcmljZUFzc2V0QW1vdW50CQDMCAIAAAkAzAgCBRZjbGFpbWluZ0lkb0Fzc2V0QW1vdW50BQNuaWwFFmNsYWltaW5nSWRvQXNzZXRBbW91bnQFCmlkb0Fzc2V0SWQFD29yaWdJbnZlc3RBcnJheQUUbmV3Q2xhaW1QZXJpb2RIZWlnaHQJAMwIAgUYY2xhaW1pbmdQcmljZUFzc2V0QW1vdW50CQDMCAIFFmNsYWltaW5nSWRvQXNzZXRBbW91bnQFA25pbAkAAgEJAKwCAgIVdW5zdXBwb3J0ZWQgYXNzZXRJZDogBRBjbGFpbWVkQXNzZXRJZDU4CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQ9pbnRlcm5hbENsYWltVjIEDnByaWNlQXNzZXRJZDU4DXVzZXJBZGRyZXNzNTgJb3V0QW1vdW50GXRvdGFsVXNlckF2YWlsYWJsZVRvQ2xhaW0EHnRvdGFsUGVyaW9kUHJpY2VBc3NldEFsbG93YW5jZQkBBXZhbHVlAQkAnwgBCQEXa2V5VG90YWxQZXJpb2RBbGxvd2FuY2UBBQ5wcmljZUFzc2V0SWQ1OAQddXNlclBlcmlvZFByaWNlQXNzZXRBbGxvd2FuY2UJAQV2YWx1ZQEJAJ8IAQkBFmtleVVzZXJQZXJpb2RBbGxvd2FuY2UBBQ5wcmljZUFzc2V0SWQ1OAQMcGVyaW9kTGVuZ3RoCQEFdmFsdWUBCQCfCAEJAQ9rZXlQZXJpb2RMZW5ndGgABA1jdXJyZW50UGVyaW9kCQELdmFsdWVPckVsc2UCCQCfCAEJARBrZXlDdXJyZW50UGVyaW9kAAAABBt6ZXJvUGVyaW9kRW5kSGVpZ2hJc0RlZmluZWQJAQlpc0RlZmluZWQBCQCfCAEJARJrZXlQZXJpb2RFbmRIZWlnaHQBAAAEDSR0MDEyOTg3MTQ4NTcDCQBmAgUNY3VycmVudFBlcmlvZAAABBVsYXN0UGVyaW9kU3RhcnRIZWlnaHQJAQV2YWx1ZQEJAJ8IAQkBFGtleVBlcmlvZFN0YXJ0SGVpZ2h0AQUNY3VycmVudFBlcmlvZAQTbGFzdFBlcmlvZEVuZEhlaWdodAkBBXZhbHVlAQkAnwgBCQESa2V5UGVyaW9kRW5kSGVpZ2h0AQUNY3VycmVudFBlcmlvZAQNJHQwMTMyNDcxMzk1MgMJAGYCBQZoZWlnaHQFE2xhc3RQZXJpb2RFbmRIZWlnaHQEFHVwZGF0ZWRDdXJyZW50UGVyaW9kCQBkAgUNY3VycmVudFBlcmlvZAABBAtwZXJpb2RTdGFydAMJAGYCBQZoZWlnaHQJAGQCBRNsYXN0UGVyaW9kRW5kSGVpZ2h0BQxwZXJpb2RMZW5ndGgEF2Jsb2Nrc1RvTGFzdFBlcmlvZFN0YXJ0CQBqAgkAZQIFBmhlaWdodAUTbGFzdFBlcmlvZEVuZEhlaWdodAUMcGVyaW9kTGVuZ3RoAwkAAAIFF2Jsb2Nrc1RvTGFzdFBlcmlvZFN0YXJ0AAAJAGQCCQBlAgUGaGVpZ2h0BQxwZXJpb2RMZW5ndGgAAQkAZQIFBmhlaWdodAUXYmxvY2tzVG9MYXN0UGVyaW9kU3RhcnQJAGQCBRNsYXN0UGVyaW9kRW5kSGVpZ2h0AAEECXBlcmlvZEVuZAkAZQIJAGQCBQtwZXJpb2RTdGFydAUMcGVyaW9kTGVuZ3RoAAEJAJUKAwUUdXBkYXRlZEN1cnJlbnRQZXJpb2QFC3BlcmlvZFN0YXJ0BQlwZXJpb2RFbmQJAJUKAwUNY3VycmVudFBlcmlvZAUVbGFzdFBlcmlvZFN0YXJ0SGVpZ2h0BRNsYXN0UGVyaW9kRW5kSGVpZ2h0BBR1cGRhdGVkQ3VycmVudFBlcmlvZAgFDSR0MDEzMjQ3MTM5NTICXzEEC3BlcmlvZFN0YXJ0CAUNJHQwMTMyNDcxMzk1MgJfMgQJcGVyaW9kRW5kCAUNJHQwMTMyNDcxMzk1MgJfMwkAlQoDBRR1cGRhdGVkQ3VycmVudFBlcmlvZAULcGVyaW9kU3RhcnQFCXBlcmlvZEVuZAMFG3plcm9QZXJpb2RFbmRIZWlnaElzRGVmaW5lZAQVemVyb1BlcmlvZFN0YXJ0SGVpZ2h0CQEFdmFsdWUBCQCfCAEJARRrZXlQZXJpb2RTdGFydEhlaWdodAEAAAQTemVyb1BlcmlvZEVuZEhlaWdodAkBBXZhbHVlAQkAnwgBCQESa2V5UGVyaW9kRW5kSGVpZ2h0AQAABA0kdDAxNDIwNzE0NTg5AwkAZgIFBmhlaWdodAUTemVyb1BlcmlvZEVuZEhlaWdodAQUdXBkYXRlZEN1cnJlbnRQZXJpb2QJAGQCBQ1jdXJyZW50UGVyaW9kAAEEC3BlcmlvZFN0YXJ0CQBkAgUTemVyb1BlcmlvZEVuZEhlaWdodAABBAlwZXJpb2RFbmQJAGUCCQBkAgULcGVyaW9kU3RhcnQFDHBlcmlvZExlbmd0aAABCQCVCgMFFHVwZGF0ZWRDdXJyZW50UGVyaW9kBQtwZXJpb2RTdGFydAUJcGVyaW9kRW5kCQCVCgMFDWN1cnJlbnRQZXJpb2QFFXplcm9QZXJpb2RTdGFydEhlaWdodAUTemVyb1BlcmlvZEVuZEhlaWdodAQUdXBkYXRlZEN1cnJlbnRQZXJpb2QIBQ0kdDAxNDIwNzE0NTg5Al8xBAtwZXJpb2RTdGFydAgFDSR0MDE0MjA3MTQ1ODkCXzIECXBlcmlvZEVuZAgFDSR0MDE0MjA3MTQ1ODkCXzMJAJUKAwUUdXBkYXRlZEN1cnJlbnRQZXJpb2QFC3BlcmlvZFN0YXJ0BQlwZXJpb2RFbmQJAJUKAwUNY3VycmVudFBlcmlvZAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEUa2V5UGVyaW9kU3RhcnRIZWlnaHQBBQ1jdXJyZW50UGVyaW9kBQZoZWlnaHQJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBEmtleVBlcmlvZEVuZEhlaWdodAEFDWN1cnJlbnRQZXJpb2QJAGUCCQBkAgUGaGVpZ2h0BQxwZXJpb2RMZW5ndGgAAQQUdXBkYXRlZEN1cnJlbnRQZXJpb2QIBQ0kdDAxMjk4NzE0ODU3Al8xBAtwZXJpb2RTdGFydAgFDSR0MDEyOTg3MTQ4NTcCXzIECXBlcmlvZEVuZAgFDSR0MDEyOTg3MTQ4NTcCXzMEG3BlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEea2V5UGVyaW9kVG90YWxBdmFpbGFibGVUb0NsYWltAgUOcHJpY2VBc3NldElkNTgFFHVwZGF0ZWRDdXJyZW50UGVyaW9kBR50b3RhbFBlcmlvZFByaWNlQXNzZXRBbGxvd2FuY2UEGnBlcmlvZFVzZXJBdmFpbGFibGVUb0NsYWltCQELdmFsdWVPckVsc2UCCQCfCAEJAR1rZXlQZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQMFDnByaWNlQXNzZXRJZDU4BRR1cGRhdGVkQ3VycmVudFBlcmlvZAUNdXNlckFkZHJlc3M1OAUddXNlclBlcmlvZFByaWNlQXNzZXRBbGxvd2FuY2UEEXByaWNlQXNzZXRCYWxhbmNlCQELdmFsdWVPckVsc2UCCQCfCAEJARRrZXlQcmljZUFzc2V0QmFsYW5jZQEFDXVzZXJBZGRyZXNzNTgAAAQZcGVyaW9kTWluQXZhaWxhYmxlVG9DbGFpbQkAlwMBCQDMCAIJAGQCBQlvdXRBbW91bnQFEXByaWNlQXNzZXRCYWxhbmNlCQDMCAIFG3BlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQkAzAgCBRpwZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQUDbmlsBBx1c2R0UHJpY2VBc3NldEFsbG93YWJsZVJhdGlvCQEFdmFsdWUBCQCfCAEJAR9rZXlVc2R0UHJpY2VBc3NldEFsbG93YWJsZVJhdGlvAAQbcHV0T25lVGtuVjJQcmljZUFzc2V0QW1vdW50BQZzY2FsZTgEDSR0MDE1NjEyMTU4NjUKAAFACQD8BwQJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQV2YWx1ZQEJAKIIAQkBG2tleVVzZHRQcmljZUFzc2V0U3RhYmxlUG9vbAACIXB1dE9uZVRrblYyV2l0aG91dFRha2VGZWVSRUFET05MWQkAzAgCBRtwdXRPbmVUa25WMlByaWNlQXNzZXRBbW91bnQJAMwIAgUOcHJpY2VBc3NldElkNTgFA25pbAUDbmlsAwkAAQIFAUACDyhJbnQsIEludCwgSW50KQUBQAkAAgEJAKwCAgkAAwEFAUACJCBjb3VsZG4ndCBiZSBjYXN0IHRvIChJbnQsIEludCwgSW50KQMJAAACBQ0kdDAxNTYxMjE1ODY1BQ0kdDAxNTYxMjE1ODY1BAVib251cwgFDSR0MDE1NjEyMTU4NjUCXzMECWZlZUFtb3VudAgFDSR0MDE1NjEyMTU4NjUCXzIECGxwQW1vdW50CAUNJHQwMTU2MTIxNTg2NQJfMQQLdXNkdEFzc2V0SWQJAQV2YWx1ZQEJAKIIAQkBDmtleVVzZHRBc3NldElkAAQNJHQwMTU5MjcxNjE0NQoAAUAJAPwHBAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBBXZhbHVlAQkAoggBCQEba2V5VXNkdFByaWNlQXNzZXRTdGFibGVQb29sAAITZ2V0T25lVGtuVjJSRUFET05MWQkAzAgCBQt1c2R0QXNzZXRJZAkAzAgCBQhscEFtb3VudAUDbmlsBQNuaWwDCQABAgUBQAIKKEludCwgSW50KQUBQAkAAgEJAKwCAgkAAwEFAUACHyBjb3VsZG4ndCBiZSBjYXN0IHRvIChJbnQsIEludCkDCQAAAgUNJHQwMTU5MjcxNjE0NQUNJHQwMTU5MjcxNjE0NQQUZ2V0T25lVGtuVjJGZWVBbW91bnQIBQ0kdDAxNTkyNzE2MTQ1Al8yBAp1c2R0QW1vdW50CAUNJHQwMTU5MjcxNjE0NQJfMQQaY3VycmVudFVzZHRQcmljZUFzc2V0UmF0aW8JAGsDBRtwdXRPbmVUa25WMlByaWNlQXNzZXRBbW91bnQFBnNjYWxlOAUKdXNkdEFtb3VudAQTZW5kUGVyaW9kQmxvY2tzTGVmdAkAZQIFCXBlcmlvZEVuZAUGaGVpZ2h0CQCcCgoFGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0FG3BlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQUacGVyaW9kVXNlckF2YWlsYWJsZVRvQ2xhaW0FGXRvdGFsVXNlckF2YWlsYWJsZVRvQ2xhaW0FHHVzZHRQcmljZUFzc2V0QWxsb3dhYmxlUmF0aW8FGmN1cnJlbnRVc2R0UHJpY2VBc3NldFJhdGlvBRNlbmRQZXJpb2RCbG9ja3NMZWZ0BRR1cGRhdGVkQ3VycmVudFBlcmlvZAULcGVyaW9kU3RhcnQFCXBlcmlvZEVuZAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAAEByRtYXRjaDAJAKIIAQkBE2tleU1hbmFnZXJQdWJsaWNLZXkAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkA2QQBBQFzAwkAAQIFByRtYXRjaDACBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgEdcGVuZGluZ01hbmFnZXJQdWJsaWNLZXlPclVuaXQABAckbWF0Y2gwCQCiCAEJARprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQADCQABAgUHJG1hdGNoMAIGU3RyaW5nBAFzBQckbWF0Y2gwCQDZBAEFAXMDCQABAgUHJG1hdGNoMAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQttdXN0TWFuYWdlcgEBaQQCcGQJAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQHJG1hdGNoMAkBFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQAAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAnBrBQckbWF0Y2gwAwkAAAIIBQFpD2NhbGxlclB1YmxpY0tleQUCcGsGBQJwZAMJAAECBQckbWF0Y2gwAgRVbml0AwkAAAIIBQFpBmNhbGxlcgUEdGhpcwYFAnBkCQACAQILTWF0Y2ggZXJyb3IIAWkBC2NvbnN0cnVjdG9yBwhpZG9TdGFydAtpZG9EdXJhdGlvbgpjbGFpbVN0YXJ0DWNsYWltRHVyYXRpb24FcHJpY2UOcHJpY2VBc3NldElkNTgPbWluSW52ZXN0QW1vdW50BAlwcmljZU11bHQJAGgCCQBoAgBkAOgHAOgHBAZpZG9FbmQJAGQCBQhpZG9TdGFydAULaWRvRHVyYXRpb24DCQEJaXNEZWZpbmVkAQkAoggBCQEJa2V5Q29uZmlnAAkAAgECE2FscmVhZHkgaW5pdGlhbGl6ZWQDCQECIT0CAiMzUE1FSEx4MWo2emVyYXJaVFlmc0dxRGVlWnFRb01weHE1UwkApQgBCAUBaQZjYWxsZXIJAAIBAg5ub3QgYXV0aG9yaXplZAMJAQIhPQIJAJADAQgFAWkIcGF5bWVudHMAAQkAAgECImV4YWN0bHkgMSBwYXltZW50IG11c3QgYmUgYXR0YWNoZWQDCQBnAgUGaWRvRW5kBQpjbGFpbVN0YXJ0CQACAQImY2xhaW1TdGFydCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBpZG9FbmQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAABAppZG9Bc3NldElkCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQEDGlkb0Fzc2V0SW5mbwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFCmlkb0Fzc2V0SWQCG2ZhaWwgdG8gbG9hZCBpZG8gYXNzZXQgaW5mbwQMaWRvQXNzZXRJZDU4CQDYBAEFCmlkb0Fzc2V0SWQEDGlkb0Fzc2V0TXVsdAkAbAYACgAACAUMaWRvQXNzZXRJbmZvCGRlY2ltYWxzAAAAAAUERE9XTgQMcHJpY2VBc3NldElkCQDZBAEFDnByaWNlQXNzZXRJZDU4BA5wcmljZUFzc2V0SW5mbwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFDHByaWNlQXNzZXRJZAIdZmFpbCB0byBsb2FkIHByaWNlIGFzc2V0IGluZm8EDnByaWNlQXNzZXRNdWx0CQBsBgAKAAAIBQ5wcmljZUFzc2V0SW5mbwhkZWNpbWFscwAAAAAFBERPV04ED29yaWdUb3RhbHNBcnJheQkBGHJlYWRUb3RhbHNBcnJheU9yRGVmYXVsdAAECnRvdGFsc0RpZmYJAMwIAgAACQDMCAIAAAkAzAgCAAAJAMwIAgAABQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBCWtleUNvbmZpZwAJAQxmcm9tYXRDb25maWcMBQhpZG9TdGFydAULaWRvRHVyYXRpb24FCmNsYWltU3RhcnQFDWNsYWltRHVyYXRpb24FBXByaWNlBQlwcmljZU11bHQFDGlkb0Fzc2V0SWQ1OAUMaWRvQXNzZXRNdWx0BQ5wcmljZUFzc2V0SWQ1OAUOcHJpY2VBc3NldE11bHQFD21pbkludmVzdEFtb3VudAgFA3BtdAZhbW91bnQJAMwIAgkBC1RvdGFsc0VudHJ5BQkBCWtleVRvdGFscwAFD29yaWdUb3RhbHNBcnJheQUKdG90YWxzRGlmZgUKY2xhaW1TdGFydAAABQNuaWwBaQEGaW52ZXN0AAQIY2ZnQXJyYXkJAQ9yZWFkQ29uZmlnQXJyYXkABAhpZG9TdGFydAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BQ5JZHhDZmdJZG9TdGFydAQLaWRvRHVyYXRpb24JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQURSWR4Q2ZnSWRvRHVyYXRpb24EBmlkb0VuZAkAZAIFCGlkb1N0YXJ0BQtpZG9EdXJhdGlvbgQKY2xhaW1TdGFydAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRBJZHhDZmdDbGFpbVN0YXJ0BA1jbGFpbUR1cmF0aW9uCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFE0lkeENmZ0NsYWltRHVyYXRpb24EBXByaWNlCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFC0lkeENmZ1ByaWNlBAlwcmljZU11bHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUPSWR4Q2ZnUHJpY2VNdWx0BAxpZG9Bc3NldElkNTgJAJEDAgUIY2ZnQXJyYXkFEElkeENmZ0lkb0Fzc2V0SWQECmlkb0Fzc2V0SWQJANkEAQUMaWRvQXNzZXRJZDU4BAxpZG9Bc3NldE11bHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhjZmdBcnJheQUSSWR4Q2ZnSWRvQXNzZXRNdWx0BA5wcmljZUFzc2V0SWQ1OAkAkQMCBQhjZmdBcnJheQUSSWR4Q2ZnUHJpY2VBc3NldElkBAxwcmljZUFzc2V0SWQJANkEAQUOcHJpY2VBc3NldElkNTgEDnByaWNlQXNzZXRNdWx0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIY2ZnQXJyYXkFFElkeENmZ1ByaWNlQXNzZXRNdWx0BA5taW5JdmVzdEFtb3VudAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGNmZ0FycmF5BRVJZHhDZmdNaW5JbnZlc3RBbW91bnQEC3VzZXJBZGRyZXNzCQClCAEIBQFpBmNhbGxlcgMJAGYCBQhpZG9TdGFydAUGaGVpZ2h0CQACAQIcaWRvIGhhcyBub3QgYmVlbiBzdGFydGVkIHlldAMJAGYCBQZoZWlnaHQFBmlkb0VuZAkAAgECGmlkbyBoYXMgYmVlbiBhbHJlYWR5IGVuZGVkAwkBAiE9AgkAkAMBCAUBaQhwYXltZW50cwABCQACAQIdZXhhY3RseSAxIHBheW1lbnQgaXMgZXhwZWN0ZWQEA3BtdAkBBXZhbHVlAQkAkQMCCAUBaQhwYXltZW50cwAABApwbXRBc3NldElkCQEFdmFsdWUBCAUDcG10B2Fzc2V0SWQECXBtdEFtb3VudAgFA3BtdAZhbW91bnQDCQECIT0CBQpwbXRBc3NldElkBQxwcmljZUFzc2V0SWQJAAIBCQCsAgIJAKwCAgIaaW52YWxpZCBwYXltZW50IGFzc2V0IGlkOiAJANgEAQUKcG10QXNzZXRJZAIMIGlzIGV4cGVjdGVkBBFvcmlnSW52ZXN0b3JBcnJheQkBGnJlYWRJbnZlc3RvckFycmF5T3JEZWZhdWx0AQULdXNlckFkZHJlc3MED29yaWdUb3RhbHNBcnJheQkBGHJlYWRUb3RhbHNBcnJheU9yRGVmYXVsdAAEE25ld1ByaWNlVG90YWxBbW91bnQJAGQCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPb3JpZ1RvdGFsc0FycmF5BRFJZHhJbnZUb3RhbEFtb3VudAUJcG10QW1vdW50BBZyZXF1aXJlZElkb0Fzc2V0QW1vdW50CQBoAgUTbmV3UHJpY2VUb3RhbEFtb3VudABkAwkAZgIFFnJlcXVpcmVkSWRvQXNzZXRBbW91bnQJAPAHAgUEdGhpcwUKaWRvQXNzZXRJZAkAAgECOUlETyBhc3NldCBoYXMgYmVlbiAtIHNvbGQgY29uc2lkZXIgdG8gdXNlIHNtYWxsZXIgcGF5bWVudAQKdG90YWxzRGlmZgkAzAgCBQlwbXRBbW91bnQJAMwIAgUJcG10QW1vdW50CQDMCAIAAAkAzAgCAAAFA25pbAkAzAgCCQELVG90YWxzRW50cnkFCQELa2V5SW52ZXN0b3IBBQt1c2VyQWRkcmVzcwURb3JpZ0ludmVzdG9yQXJyYXkFCnRvdGFsc0RpZmYFCmNsYWltU3RhcnQAAAkAzAgCCQELVG90YWxzRW50cnkFCQEJa2V5VG90YWxzAAUPb3JpZ1RvdGFsc0FycmF5BQp0b3RhbHNEaWZmBQpjbGFpbVN0YXJ0AAAJAMwIAgkBG0ludmVzdE9wZXJhdGlvbkhpc3RvcnlFbnRyeQQFC3VzZXJBZGRyZXNzBQlwbXRBbW91bnQAAAgFAWkNdHJhbnNhY3Rpb25JZAUDbmlsAWkBBWNsYWltAhBjbGFpbWVkQXNzZXRJZDU4DXVzZXJBZGRyZXNzNTgED2NhbGxlckFkZHJlc3M1OAkApQgBCAUBaQZjYWxsZXIDCQECIT0CBQ11c2VyQWRkcmVzczU4BQ9jYWxsZXJBZGRyZXNzNTgJAAIBAg5ub3QgYXV0aG9yaXplZAQIY2ZnQXJyYXkJAQ9yZWFkQ29uZmlnQXJyYXkABA5wcmljZUFzc2V0SWQ1OAkAkQMCBQhjZmdBcnJheQUSSWR4Q2ZnUHJpY2VBc3NldElkBBBjbGFpbVJlc3VsdFR1cGxlCQENaW50ZXJuYWxDbGFpbQMFEGNsYWltZWRBc3NldElkNTgIBQFpBmNhbGxlcggFAWkNdHJhbnNhY3Rpb25JZAQKdG90YWxzRGlmZggFEGNsYWltUmVzdWx0VHVwbGUCXzEECW91dEFtb3VudAgFEGNsYWltUmVzdWx0VHVwbGUCXzIECm91dEFzc2V0SWQIBRBjbGFpbVJlc3VsdFR1cGxlAl8zBA9vcmlnSW52ZXN0QXJyYXkIBRBjbGFpbVJlc3VsdFR1cGxlAl80BBRuZXdDbGFpbVBlcmlvZEhlaWdodAgFEGNsYWltUmVzdWx0VHVwbGUCXzUEGmNsYWltZWRQcmljZUFtb3VudEZyb21EaWZmCQCRAwIFCnRvdGFsc0RpZmYFIklkeERpZmZDbGFpbWVkUHJpY2VBbW91bnRJbmNyZW1lbnQEHWNsYWltZWRJZG9Bc3NldEFtb3VudEZyb21EaWZmCQCRAwIFCnRvdGFsc0RpZmYFJUlkeERpZmZDbGFpbWVkSWRvQXNzZXRBbW91bnRJbmNyZW1lbnQEEXByaWNlQXNzZXRCYWxhbmNlCQELdmFsdWVPckVsc2UCCQCfCAEJARRrZXlQcmljZUFzc2V0QmFsYW5jZQEFDXVzZXJBZGRyZXNzNTgAAAQScHJpY2VBc3NldERlY2ltYWxzCAkBBXZhbHVlAQkA7AcBCQDZBAEFDnByaWNlQXNzZXRJZDU4CGRlY2ltYWxzBA0kdDAyMTk5MTIyNDAzCQEPaW50ZXJuYWxDbGFpbVYyBAUOcHJpY2VBc3NldElkNTgFDXVzZXJBZGRyZXNzNTgFCW91dEFtb3VudAkAkQMCBQp0b3RhbHNEaWZmBSJJZHhEaWZmQ2xhaW1lZFByaWNlQW1vdW50SW5jcmVtZW50BBlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltCAUNJHQwMjE5OTEyMjQwMwJfMQQbcGVyaW9kVG90YWxBdmFpbGFibGVUb0NsYWltCAUNJHQwMjE5OTEyMjQwMwJfMgQacGVyaW9kVXNlckF2YWlsYWJsZVRvQ2xhaW0IBQ0kdDAyMTk5MTIyNDAzAl8zBBl0b3RhbFVzZXJBdmFpbGFibGVUb0NsYWltCAUNJHQwMjE5OTEyMjQwMwJfNAQcdXNkdFByaWNlQXNzZXRBbGxvd2FibGVSYXRpbwgFDSR0MDIxOTkxMjI0MDMCXzUEGmN1cnJlbnRVc2R0UHJpY2VBc3NldFJhdGlvCAUNJHQwMjE5OTEyMjQwMwJfNgQTZW5kUGVyaW9kQmxvY2tzTGVmdAgFDSR0MDIxOTkxMjI0MDMCXzcEFHVwZGF0ZWRDdXJyZW50UGVyaW9kCAUNJHQwMjE5OTEyMjQwMwJfOAQLcGVyaW9kU3RhcnQIBQ0kdDAyMTk5MTIyNDAzAl85BAlwZXJpb2RFbmQIBQ0kdDAyMTk5MTIyNDAzA18xMAQOZXZhbHVhdGVSZXN1bHQJALUJAgkBCGFzU3RyaW5nAQkA/AcEBQR0aGlzAg1jbGFpbVJFQURPTkxZCQDMCAIFDnByaWNlQXNzZXRJZDU4CQDMCAIFDXVzZXJBZGRyZXNzNTgFA25pbAUDbmlsBQNTRVADCQAAAgUOZXZhbHVhdGVSZXN1bHQFDmV2YWx1YXRlUmVzdWx0BBthdmFpbGFibGVQcmljZUFtb3VudFRvQ2xhaW0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5ldmFsdWF0ZVJlc3VsdAADBBNpbnZlc3RvclRvdGFsQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPb3JpZ0ludmVzdEFycmF5BRFJZHhJbnZUb3RhbEFtb3VudAQXaW52ZXN0b3JSZW1haW5pbmdBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ9vcmlnSW52ZXN0QXJyYXkFFUlkeEludlJlbWFpbmluZ0Ftb3VudAQZaW52ZXN0b3JQcmljZUFzc2V0QmFsYW5jZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFD29yaWdJbnZlc3RBcnJheQUdSWR4SW52Q2xhaW1lZFByaWNlQXNzZXRBbW91bnQEF2ludmVzdG9ySWRvQXNzZXRCYWxhbmNlCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUPb3JpZ0ludmVzdEFycmF5BRtJZHhJbnZDbGFpbWVkSWRvQXNzZXRBbW91bnQEGWludmVzdG9yTGFzdENsYWltZWRIZWlnaHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ9vcmlnSW52ZXN0QXJyYXkFF0lkeEludkxhc3RDbGFpbWVkSGVpZ2h0BA5uZXdJbnZlc3RBcnJheQkAzAgCCQCkAwEFE2ludmVzdG9yVG90YWxBbW91bnQJAMwIAgIBMAkAzAgCCQCkAwEFGWludmVzdG9yUHJpY2VBc3NldEJhbGFuY2UJAMwIAgkApAMBBRdpbnZlc3Rvcklkb0Fzc2V0QmFsYW5jZQkAzAgCCQCkAwEFGWludmVzdG9yTGFzdENsYWltZWRIZWlnaHQFA25pbAQGdG90YWxzCQEYcmVhZFRvdGFsc0FycmF5T3JEZWZhdWx0AAQRdG90YWxzVG90YWxBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZ0b3RhbHMFEUlkeEludlRvdGFsQW1vdW50BBV0b3RhbHNSZW1haW5pbmdBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZ0b3RhbHMFFUlkeEludlJlbWFpbmluZ0Ftb3VudAQddG90YWxzQ2xhaW1lZFByaWNlQXNzZXRBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZ0b3RhbHMFFUlkeEludlJlbWFpbmluZ0Ftb3VudAQbdG90YWxzQ2xhaW1lZElkb0Fzc2V0QW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUGdG90YWxzBR1JZHhJbnZDbGFpbWVkUHJpY2VBc3NldEFtb3VudAQXdG90YWxzTGFzdENsYWltZWRIZWlnaHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZ0b3RhbHMFF0lkeEludkxhc3RDbGFpbWVkSGVpZ2h0BBhuZXdUb3RhbHNSZW1haW5pbmdBbW91bnQJAGUCBRV0b3RhbHNSZW1haW5pbmdBbW91bnQFF2ludmVzdG9yUmVtYWluaW5nQW1vdW50BA1uZXdUb3RhbEFycmF5CQDMCAIJAKQDAQURdG90YWxzVG90YWxBbW91bnQJAMwIAgkApAMBBRhuZXdUb3RhbHNSZW1haW5pbmdBbW91bnQJAMwIAgkApAMBBR10b3RhbHNDbGFpbWVkUHJpY2VBc3NldEFtb3VudAkAzAgCCQCkAwEFG3RvdGFsc0NsYWltZWRJZG9Bc3NldEFtb3VudAkAzAgCCQCkAwEFF3RvdGFsc0xhc3RDbGFpbWVkSGVpZ2h0BQNuaWwEF25ld1RvdGFsUmVtYWluaW5nQW1vdW50CQBkAgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEXa2V5VG90YWxSZW1haW5pbmdBbW91bnQAAAAFF2ludmVzdG9yUmVtYWluaW5nQW1vdW50BAdlbnRyaWVzAwkAAAIFEGNsYWltZWRBc3NldElkNTgFDnByaWNlQXNzZXRJZDU4BAZjaGVja3MJAMwIAgMJAGYCBRpwZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQAABgkBCHRocm93RXJyAQI6dW5hdmFpbGFibGUgdG8gY2xhaW0gYmVjYXVzZSB1c2VyIHBlcmlvZCBhbGxvd2FuY2UgcmVhY2hlZAkAzAgCAwkAZgIFG3BlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQAABgkBCHRocm93RXJyAQI7dW5hdmFpbGFibGUgdG8gY2xhaW0gYmVjYXVzZSB0b3RhbCBwZXJpb2QgYWxsb3dhbmNlIHJlYWNoZWQJAMwIAgMJAGYCBRlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltAAAGCQEIdGhyb3dFcnIBAhBub3RoaW5nIHRvIGNsYWltCQDMCAIDCQBmAgUcdXNkdFByaWNlQXNzZXRBbGxvd2FibGVSYXRpbwUaY3VycmVudFVzZHRQcmljZUFzc2V0UmF0aW8GCQEIdGhyb3dFcnIBAk91bmF2YWlsYWJsZSB0byBjbGFpbSBiZWNhdXNlIHVzZG4gcHJpY2UgbG93ZXIgdGhhbiB1c2R0UHJpY2VBc3NldEFsbG93YWJsZVJhdGlvBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEInVwZGF0ZWRQZXJpb2RUb3RhbEF2YWlsYWJsZVRvQ2xhaW0JAGUCBRtwZXJpb2RUb3RhbEF2YWlsYWJsZVRvQ2xhaW0FGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0EIXVwZGF0ZWRQZXJpb2RVc2VyQXZhaWxhYmxlVG9DbGFpbQkAZQIFGnBlcmlvZFVzZXJBdmFpbGFibGVUb0NsYWltBRlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltBAdlbnRyaWVzAwkAZgIFEXByaWNlQXNzZXRCYWxhbmNlBRlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQFpBmNhbGxlcgUZcGVyaW9kTWluQXZhaWxhYmxlVG9DbGFpbQUKb3V0QXNzZXRJZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFGtleVByaWNlQXNzZXRCYWxhbmNlAQUNdXNlckFkZHJlc3M1OAkAZQIFEXByaWNlQXNzZXRCYWxhbmNlBRlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltBQNuaWwEEGxhc3RDbGFpbUVudHJpZXMDCQAAAgUbYXZhaWxhYmxlUHJpY2VBbW91bnRUb0NsYWltBRlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltCQDMCAIJAQtTdHJpbmdFbnRyeQIJARprZXlJbnZlc3RvclJlbWFpbmluZ0Ftb3VudAEFDXVzZXJBZGRyZXNzNTgJAKQDAQUXaW52ZXN0b3JSZW1haW5pbmdBbW91bnQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBF2tleVRvdGFsUmVtYWluaW5nQW1vdW50AAkApAMBBRduZXdUb3RhbFJlbWFpbmluZ0Ftb3VudAkAzAgCCQELVG90YWxzRW50cnkFCQELa2V5SW52ZXN0b3IBBQ11c2VyQWRkcmVzczU4BQ5uZXdJbnZlc3RBcnJheQUKdG90YWxzRGlmZgUUbmV3Q2xhaW1QZXJpb2RIZWlnaHQAAAkAzAgCCQELVG90YWxzRW50cnkFCQEJa2V5VG90YWxzAAUNbmV3VG90YWxBcnJheQUKdG90YWxzRGlmZgUUbmV3Q2xhaW1QZXJpb2RIZWlnaHQAAAUDbmlsCQDMCAIJAQtUb3RhbHNFbnRyeQUJAQtrZXlJbnZlc3RvcgEFDXVzZXJBZGRyZXNzNTgFD29yaWdJbnZlc3RBcnJheQUKdG90YWxzRGlmZgUUbmV3Q2xhaW1QZXJpb2RIZWlnaHQAAAkAzAgCCQELVG90YWxzRW50cnkFCQEJa2V5VG90YWxzAAkBGHJlYWRUb3RhbHNBcnJheU9yRGVmYXVsdAAFCnRvdGFsc0RpZmYFFG5ld0NsYWltUGVyaW9kSGVpZ2h0AAAFA25pbAQYdXBkYXRlZFByaWNlQXNzZXRCYWxhbmNlCQBlAgkAZAIFEXByaWNlQXNzZXRCYWxhbmNlBQlvdXRBbW91bnQFGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0JAM4IAgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0FCm91dEFzc2V0SWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARRrZXlQcmljZUFzc2V0QmFsYW5jZQEFDXVzZXJBZGRyZXNzNTgFGHVwZGF0ZWRQcmljZUFzc2V0QmFsYW5jZQUDbmlsBRBsYXN0Q2xhaW1FbnRyaWVzCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEGtleUN1cnJlbnRQZXJpb2QABRR1cGRhdGVkQ3VycmVudFBlcmlvZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFGtleVBlcmlvZFN0YXJ0SGVpZ2h0AQUUdXBkYXRlZEN1cnJlbnRQZXJpb2QFC3BlcmlvZFN0YXJ0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQESa2V5UGVyaW9kRW5kSGVpZ2h0AQUUdXBkYXRlZEN1cnJlbnRQZXJpb2QFCXBlcmlvZEVuZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBHmtleVBlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQIFDnByaWNlQXNzZXRJZDU4BRR1cGRhdGVkQ3VycmVudFBlcmlvZAUidXBkYXRlZFBlcmlvZFRvdGFsQXZhaWxhYmxlVG9DbGFpbQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBHWtleVBlcmlvZFVzZXJBdmFpbGFibGVUb0NsYWltAwUOcHJpY2VBc3NldElkNTgFFHVwZGF0ZWRDdXJyZW50UGVyaW9kBQ11c2VyQWRkcmVzczU4BSF1cGRhdGVkUGVyaW9kVXNlckF2YWlsYWJsZVRvQ2xhaW0JAMwIAgkBGkNsYWltT3BlcmF0aW9uSGlzdG9yeUVudHJ5BAUNdXNlckFkZHJlc3M1OAUZcGVyaW9kTWluQXZhaWxhYmxlVG9DbGFpbQUdY2xhaW1lZElkb0Fzc2V0QW1vdW50RnJvbURpZmYIBQFpDXRyYW5zYWN0aW9uSWQFA25pbAUHZW50cmllcwUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQccHJpY2VBc3NldEJhbGFuY2VJZG9EZWNpbWFscwkAawMFEXByaWNlQXNzZXRCYWxhbmNlBQZzY2FsZTgJAGwGAAoAAAUScHJpY2VBc3NldERlY2ltYWxzAAAAAAUERE9XTgkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJARprZXlJbnZlc3RvclJlbWFpbmluZ0Ftb3VudAEFDXVzZXJBZGRyZXNzNTgJAKQDAQUXaW52ZXN0b3JSZW1haW5pbmdBbW91bnQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBF2tleVRvdGFsUmVtYWluaW5nQW1vdW50AAkApAMBBRduZXdUb3RhbFJlbWFpbmluZ0Ftb3VudAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIJAGQCBQlvdXRBbW91bnQFHHByaWNlQXNzZXRCYWxhbmNlSWRvRGVjaW1hbHMFCm91dEFzc2V0SWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARRrZXlQcmljZUFzc2V0QmFsYW5jZQEFDXVzZXJBZGRyZXNzNTgAAAkAzAgCCQELVG90YWxzRW50cnkFCQELa2V5SW52ZXN0b3IBBQ11c2VyQWRkcmVzczU4BQ5uZXdJbnZlc3RBcnJheQUKdG90YWxzRGlmZgUUbmV3Q2xhaW1QZXJpb2RIZWlnaHQFEXByaWNlQXNzZXRCYWxhbmNlCQDMCAIJAQtUb3RhbHNFbnRyeQUJAQlrZXlUb3RhbHMABQ1uZXdUb3RhbEFycmF5BQp0b3RhbHNEaWZmBRRuZXdDbGFpbVBlcmlvZEhlaWdodAURcHJpY2VBc3NldEJhbGFuY2UJAMwIAgkBGkNsYWltT3BlcmF0aW9uSGlzdG9yeUVudHJ5BAUNdXNlckFkZHJlc3M1OAUaY2xhaW1lZFByaWNlQW1vdW50RnJvbURpZmYJAGQCBR1jbGFpbWVkSWRvQXNzZXRBbW91bnRGcm9tRGlmZgUccHJpY2VBc3NldEJhbGFuY2VJZG9EZWNpbWFscwgFAWkNdHJhbnNhY3Rpb25JZAUDbmlsBQR1bml0BQdlbnRyaWVzCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBEmNsZWFuUmVtYWluZ0Ftb3VudAENdXNlckFkZHJlc3M1OAQOcHJpY2VBc3NldElkNTgJAJEDAgkBD3JlYWRDb25maWdBcnJheQAFEklkeENmZ1ByaWNlQXNzZXRJZAQOZXZhbHVhdGVSZXN1bHQJALUJAgkBCGFzU3RyaW5nAQkA/AcEBQR0aGlzAg1jbGFpbVJFQURPTkxZCQDMCAIFDnByaWNlQXNzZXRJZDU4CQDMCAIFDXVzZXJBZGRyZXNzNTgFA25pbAUDbmlsBQNTRVADCQAAAgUOZXZhbHVhdGVSZXN1bHQFDmV2YWx1YXRlUmVzdWx0BBthdmFpbGFibGVQcmljZUFtb3VudFRvQ2xhaW0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQ5ldmFsdWF0ZVJlc3VsdAACBBRjaGVja1VuY2xhaW1lZEFzc2V0cwMJAAACBRthdmFpbGFibGVQcmljZUFtb3VudFRvQ2xhaW0AAAYJAQh0aHJvd0VycgECGnVzZXIgaGF2ZSB1bmNsYWltZWQgYXNzZXRzAwkAAAIFFGNoZWNrVW5jbGFpbWVkQXNzZXRzBRRjaGVja1VuY2xhaW1lZEFzc2V0cwQIaW52ZXN0b3IJALUJAgkBBXZhbHVlAQkAoggBCQELa2V5SW52ZXN0b3IBBQ11c2VyQWRkcmVzczU4BQNTRVAEE2ludmVzdG9yVG90YWxBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhpbnZlc3RvcgURSWR4SW52VG90YWxBbW91bnQEF2ludmVzdG9yUmVtYWluaW5nQW1vdW50CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIaW52ZXN0b3IFFUlkeEludlJlbWFpbmluZ0Ftb3VudAQZaW52ZXN0b3JQcmljZUFzc2V0QmFsYW5jZQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGludmVzdG9yBR1JZHhJbnZDbGFpbWVkUHJpY2VBc3NldEFtb3VudAQXaW52ZXN0b3JJZG9Bc3NldEJhbGFuY2UJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhpbnZlc3RvcgUbSWR4SW52Q2xhaW1lZElkb0Fzc2V0QW1vdW50BBlpbnZlc3Rvckxhc3RDbGFpbWVkSGVpZ2h0CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIaW52ZXN0b3IFF0lkeEludkxhc3RDbGFpbWVkSGVpZ2h0BBxpbnZlc3RvclJlbWFpbmluZ0Ftb3VudENoZWNrAwkBAiE9AgUXaW52ZXN0b3JSZW1haW5pbmdBbW91bnQAAAYJAQh0aHJvd0VycgECJGludmVzdG9yUmVtYWluaW5nQW1vdW50IGFscmVhZHkgemVybwMJAAACBRxpbnZlc3RvclJlbWFpbmluZ0Ftb3VudENoZWNrBRxpbnZlc3RvclJlbWFpbmluZ0Ftb3VudENoZWNrBAtuZXdJbnZlc3RvcgkAuQkCCQDMCAICCiVkJWQlZCVkJWQJAMwIAgkApAMBBRNpbnZlc3RvclRvdGFsQW1vdW50CQDMCAICATAJAMwIAgkApAMBBRlpbnZlc3RvclByaWNlQXNzZXRCYWxhbmNlCQDMCAIJAKQDAQUXaW52ZXN0b3JJZG9Bc3NldEJhbGFuY2UJAMwIAgkApAMBBRlpbnZlc3Rvckxhc3RDbGFpbWVkSGVpZ2h0BQNuaWwFA1NFUAQGdG90YWxzCQC1CQIJAQV2YWx1ZQEJAKIIAQkBCWtleVRvdGFscwAFA1NFUAQRdG90YWxzVG90YWxBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZ0b3RhbHMFEUlkeEludlRvdGFsQW1vdW50BBV0b3RhbHNSZW1haW5pbmdBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZ0b3RhbHMFFUlkeEludlJlbWFpbmluZ0Ftb3VudAQddG90YWxzQ2xhaW1lZFByaWNlQXNzZXRBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZ0b3RhbHMFHUlkeEludkNsYWltZWRQcmljZUFzc2V0QW1vdW50BBt0b3RhbHNDbGFpbWVkSWRvQXNzZXRBbW91bnQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZ0b3RhbHMFG0lkeEludkNsYWltZWRJZG9Bc3NldEFtb3VudAQXdG90YWxzTGFzdENsYWltZWRIZWlnaHQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQZ0b3RhbHMFF0lkeEludkxhc3RDbGFpbWVkSGVpZ2h0BAluZXdUb3RhbHMJALkJAgkAzAgCAgolZCVkJWQlZCVkCQDMCAIJAKQDAQURdG90YWxzVG90YWxBbW91bnQJAMwIAgkApAMBCQBlAgUVdG90YWxzUmVtYWluaW5nQW1vdW50BRdpbnZlc3RvclJlbWFpbmluZ0Ftb3VudAkAzAgCCQCkAwEFHXRvdGFsc0NsYWltZWRQcmljZUFzc2V0QW1vdW50CQDMCAIJAKQDAQUbdG90YWxzQ2xhaW1lZElkb0Fzc2V0QW1vdW50CQDMCAIJAKQDAQUXdG90YWxzTGFzdENsYWltZWRIZWlnaHQFA25pbAUDU0VQBBduZXdUb3RhbFJlbWFpbmluZ0Ftb3VudAkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBF2tleVRvdGFsUmVtYWluaW5nQW1vdW50AAAABRdpbnZlc3RvclJlbWFpbmluZ0Ftb3VudAkAzAgCCQELU3RyaW5nRW50cnkCCQEaa2V5SW52ZXN0b3JSZW1haW5pbmdBbW91bnQBBQ11c2VyQWRkcmVzczU4CQCkAwEFF2ludmVzdG9yUmVtYWluaW5nQW1vdW50CQDMCAIJAQtTdHJpbmdFbnRyeQIJARdrZXlUb3RhbFJlbWFpbmluZ0Ftb3VudAAJAKQDAQUXbmV3VG90YWxSZW1haW5pbmdBbW91bnQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBC2tleUludmVzdG9yAQUNdXNlckFkZHJlc3M1OAULbmV3SW52ZXN0b3IJAMwIAgkBC1N0cmluZ0VudHJ5AgkBCWtleVRvdGFscwAFCW5ld1RvdGFscwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDWNsYWltUkVBRE9OTFkCEGNsYWltZWRBc3NldElkNTgNdXNlckFkZHJlc3M1OAQQY2xhaW1SZXN1bHRUdXBsZQkBDWludGVybmFsQ2xhaW0DBRBjbGFpbWVkQXNzZXRJZDU4CQERQGV4dHJOYXRpdmUoMTA2MikBBQ11c2VyQWRkcmVzczU4CQDZBAECAAQKdG90YWxzRGlmZggFEGNsYWltUmVzdWx0VHVwbGUCXzEECW91dEFtb3VudAgFEGNsYWltUmVzdWx0VHVwbGUCXzIECm91dEFzc2V0SWQIBRBjbGFpbVJlc3VsdFR1cGxlAl8zBA9vcmlnSW52ZXN0QXJyYXkIBRBjbGFpbVJlc3VsdFR1cGxlAl80BBRuZXdDbGFpbVBlcmlvZEhlaWdodAgFEGNsYWltUmVzdWx0VHVwbGUCXzUEFWF2YWlsYWJsZVRvQ2xhaW1BcnJheQgFEGNsYWltUmVzdWx0VHVwbGUCXzYEG2F2YWlsYWJsZVByaWNlQW1vdW50VG9DbGFpbQkAkQMCBRVhdmFpbGFibGVUb0NsYWltQXJyYXkAAAQZYXZhaWxhYmxlSWRvQW1vdW50VG9DbGFpbQkAkQMCBRVhdmFpbGFibGVUb0NsYWltQXJyYXkAAQkAlAoCBQNuaWwJALkJAgkAzAgCAgYlcyVkJWQJAMwIAgUNdXNlckFkZHJlc3M1OAkAzAgCCQCkAwEFG2F2YWlsYWJsZVByaWNlQW1vdW50VG9DbGFpbQkAzAgCCQCkAwEFGWF2YWlsYWJsZUlkb0Ftb3VudFRvQ2xhaW0FA25pbAUDU0VQAWkBD2NsYWltVjJSRUFET05MWQIQY2xhaW1lZEFzc2V0SWQ1OA11c2VyQWRkcmVzczU4BBBjbGFpbVJlc3VsdFR1cGxlCQENaW50ZXJuYWxDbGFpbQMFEGNsYWltZWRBc3NldElkNTgJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDXVzZXJBZGRyZXNzNTgJANkEAQIABAp0b3RhbHNEaWZmCAUQY2xhaW1SZXN1bHRUdXBsZQJfMQQJb3V0QW1vdW50CAUQY2xhaW1SZXN1bHRUdXBsZQJfMgQKb3V0QXNzZXRJZAgFEGNsYWltUmVzdWx0VHVwbGUCXzMED29yaWdJbnZlc3RBcnJheQgFEGNsYWltUmVzdWx0VHVwbGUCXzQEFG5ld0NsYWltUGVyaW9kSGVpZ2h0CAUQY2xhaW1SZXN1bHRUdXBsZQJfNQQVYXZhaWxhYmxlVG9DbGFpbUFycmF5CAUQY2xhaW1SZXN1bHRUdXBsZQJfNgQbYXZhaWxhYmxlUHJpY2VBbW91bnRUb0NsYWltCQCRAwIFFWF2YWlsYWJsZVRvQ2xhaW1BcnJheQAABBlhdmFpbGFibGVJZG9BbW91bnRUb0NsYWltCQCRAwIFFWF2YWlsYWJsZVRvQ2xhaW1BcnJheQABBAhjZmdBcnJheQkBD3JlYWRDb25maWdBcnJheQAEDnByaWNlQXNzZXRJZDU4CQCRAwIFCGNmZ0FycmF5BRJJZHhDZmdQcmljZUFzc2V0SWQEEXByaWNlQXNzZXRCYWxhbmNlCQELdmFsdWVPckVsc2UCCQCfCAEJARRrZXlQcmljZUFzc2V0QmFsYW5jZQEFDXVzZXJBZGRyZXNzNTgAAAQccHJpY2VBc3NldEJhbGFuY2VJZG9EZWNpbWFscwkAaAIFEXByaWNlQXNzZXRCYWxhbmNlAGQELmF2YWlsYWJsZUlkb0Ftb3VudFRvQ2xhaW1XaXRoUHJpY2VBc3NldEJhbGFuY2UJAGQCBRlhdmFpbGFibGVJZG9BbW91bnRUb0NsYWltBRxwcmljZUFzc2V0QmFsYW5jZUlkb0RlY2ltYWxzBA0kdDAzMzcwMTM0MTEzCQEPaW50ZXJuYWxDbGFpbVYyBAUOcHJpY2VBc3NldElkNTgFDXVzZXJBZGRyZXNzNTgFCW91dEFtb3VudAkAkQMCBQp0b3RhbHNEaWZmBSJJZHhEaWZmQ2xhaW1lZFByaWNlQW1vdW50SW5jcmVtZW50BBlwZXJpb2RNaW5BdmFpbGFibGVUb0NsYWltCAUNJHQwMzM3MDEzNDExMwJfMQQbcGVyaW9kVG90YWxBdmFpbGFibGVUb0NsYWltCAUNJHQwMzM3MDEzNDExMwJfMgQacGVyaW9kVXNlckF2YWlsYWJsZVRvQ2xhaW0IBQ0kdDAzMzcwMTM0MTEzAl8zBBl0b3RhbFVzZXJBdmFpbGFibGVUb0NsYWltCAUNJHQwMzM3MDEzNDExMwJfNAQcdXNkdFByaWNlQXNzZXRBbGxvd2FibGVSYXRpbwgFDSR0MDMzNzAxMzQxMTMCXzUEGmN1cnJlbnRVc2R0UHJpY2VBc3NldFJhdGlvCAUNJHQwMzM3MDEzNDExMwJfNgQTZW5kUGVyaW9kQmxvY2tzTGVmdAgFDSR0MDMzNzAxMzQxMTMCXzcEFHVwZGF0ZWRDdXJyZW50UGVyaW9kCAUNJHQwMzM3MDEzNDExMwJfOAQLcGVyaW9kU3RhcnQIBQ0kdDAzMzcwMTM0MTEzAl85BAlwZXJpb2RFbmQIBQ0kdDAzMzcwMTM0MTEzA18xMAQWY3VycmVudFBlcmlvZEVuZEhlaWdodAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQESa2V5UGVyaW9kRW5kSGVpZ2h0AQUUdXBkYXRlZEN1cnJlbnRQZXJpb2QAAAQadXNlclRvdGFsUHJpY2VBc3NldENsYWltZWQJAGUCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgkBF3JlYWRJbnZlc3RvckFycmF5T3JGYWlsAQUNdXNlckFkZHJlc3M1OAUdSWR4SW52Q2xhaW1lZFByaWNlQXNzZXRBbW91bnQFEXByaWNlQXNzZXRCYWxhbmNlBAxyZXN1bHRTdHJpbmcDCQBmAgUGaGVpZ2h0BRZjdXJyZW50UGVyaW9kRW5kSGVpZ2h0BAxwZXJpb2RMZW5naHQJAQV2YWx1ZQEJAJ8IAQkBD2tleVBlcmlvZExlbmd0aAAEE3VzZXJQZXJpb2RBbGxvd2FuY2UJAQV2YWx1ZQEJAJ8IAQkBFmtleVVzZXJQZXJpb2RBbGxvd2FuY2UBBQ5wcmljZUFzc2V0SWQ1OAQUdG90YWxQZXJpb2RBbGxvd2FuY2UJAQV2YWx1ZQEJAJ8IAQkBF2tleVRvdGFsUGVyaW9kQWxsb3dhbmNlAQUOcHJpY2VBc3NldElkNTgJALkJAgkAzAgCAgwlZCVkJWQlZCVkJWQJAMwIAgkApAMBBS5hdmFpbGFibGVJZG9BbW91bnRUb0NsYWltV2l0aFByaWNlQXNzZXRCYWxhbmNlCQDMCAIJAKQDAQUTdXNlclBlcmlvZEFsbG93YW5jZQkAzAgCCQCkAwEFFHRvdGFsUGVyaW9kQWxsb3dhbmNlCQDMCAIJAKQDAQUcdXNkdFByaWNlQXNzZXRBbGxvd2FibGVSYXRpbwkAzAgCCQCkAwEFGmN1cnJlbnRVc2R0UHJpY2VBc3NldFJhdGlvCQDMCAIJAKQDAQUMcGVyaW9kTGVuZ2h0CQDMCAIJAKQDAQUadXNlclRvdGFsUHJpY2VBc3NldENsYWltZWQFA25pbAUDU0VQCQC5CQIJAMwIAgIMJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUuYXZhaWxhYmxlSWRvQW1vdW50VG9DbGFpbVdpdGhQcmljZUFzc2V0QmFsYW5jZQkAzAgCCQCkAwEFGXBlcmlvZE1pbkF2YWlsYWJsZVRvQ2xhaW0JAMwIAgkApAMBBRtwZXJpb2RUb3RhbEF2YWlsYWJsZVRvQ2xhaW0JAMwIAgkApAMBBRx1c2R0UHJpY2VBc3NldEFsbG93YWJsZVJhdGlvCQDMCAIJAKQDAQUaY3VycmVudFVzZHRQcmljZUFzc2V0UmF0aW8JAMwIAgkApAMBBRNlbmRQZXJpb2RCbG9ja3NMZWZ0CQDMCAIJAKQDAQUadXNlclRvdGFsUHJpY2VBc3NldENsYWltZWQFA25pbAUDU0VQCQCUCgIFA25pbAUMcmVzdWx0U3RyaW5nAWkBCnNldE1hbmFnZXIBF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5BAtjaGVja0NhbGxlcgkBC211c3RNYW5hZ2VyAQUBaQMJAAACBQtjaGVja0NhbGxlcgULY2hlY2tDYWxsZXIEFWNoZWNrTWFuYWdlclB1YmxpY0tleQkA2QQBBRdwZW5kaW5nTWFuYWdlclB1YmxpY0tleQMJAAACBRVjaGVja01hbmFnZXJQdWJsaWNLZXkFFWNoZWNrTWFuYWdlclB1YmxpY0tleQkAzAgCCQELU3RyaW5nRW50cnkCCQEaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkABRdwZW5kaW5nTWFuYWdlclB1YmxpY0tleQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBDmNvbmZpcm1NYW5hZ2VyAAQCcG0JAR1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdAAEBWhhc1BNAwkBCWlzRGVmaW5lZAEFAnBtBgkAAgECEk5vIHBlbmRpbmcgbWFuYWdlcgMJAAACBQVoYXNQTQUFaGFzUE0EB2NoZWNrUE0DCQAAAggFAWkPY2FsbGVyUHVibGljS2V5CQEFdmFsdWUBBQJwbQYJAAIBAhtZb3UgYXJlIG5vdCBwZW5kaW5nIG1hbmFnZXIDCQAAAgUHY2hlY2tQTQUHY2hlY2tQTQkAzAgCCQELU3RyaW5nRW50cnkCCQETa2V5TWFuYWdlclB1YmxpY0tleQAJANgEAQkBBXZhbHVlAQUCcG0JAMwIAgkBC0RlbGV0ZUVudHJ5AQkBGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJ0eAEGdmVyaWZ5AAQPdGFyZ2V0UHVibGljS2V5BAckbWF0Y2gwCQEWbWFuYWdlclB1YmxpY0tleU9yVW5pdAADCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCcGsFByRtYXRjaDAFAnBrAwkAAQIFByRtYXRjaDACBFVuaXQIBQJ0eA9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAUPdGFyZ2V0UHVibGljS2V51FV0pw==", "height": 2342819, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: A9XvVLTXQcidGztVM8Fw4W5rFCvCDKZ5s3dUYULbPCWR Next: DLYbAQLJr25n5a2B16wLLRu5eY8uLN9h6fZZAnqwpxyi Diff:
OldNewDifferences
464464 let claimedIdoAssetAmountFromDiff = totalsDiff[IdxDiffClaimedIdoAssetAmountIncrement]
465465 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
466466 let priceAssetDecimals = value(assetInfo(fromBase58String(priceAssetId58))).decimals
467- let entries = if ((claimedAssetId58 == priceAssetId58))
467+ let $t02199122403 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
468+ let periodMinAvailableToClaim = $t02199122403._1
469+ let periodTotalAvailableToClaim = $t02199122403._2
470+ let periodUserAvailableToClaim = $t02199122403._3
471+ let totalUserAvailableToClaim = $t02199122403._4
472+ let usdtPriceAssetAllowableRatio = $t02199122403._5
473+ let currentUsdtPriceAssetRatio = $t02199122403._6
474+ let endPeriodBlocksLeft = $t02199122403._7
475+ let updatedCurrentPeriod = $t02199122403._8
476+ let periodStart = $t02199122403._9
477+ let periodEnd = $t02199122403._10
478+ let evaluateResult = split(asString(invoke(this, "claimREADONLY", [priceAssetId58, userAddress58], nil)), SEP)
479+ if ((evaluateResult == evaluateResult))
468480 then {
469- let $t02205422498 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
470- let periodMinAvailableToClaim = $t02205422498._1
471- let periodTotalAvailableToClaim = $t02205422498._2
472- let periodUserAvailableToClaim = $t02205422498._3
473- let totalUserAvailableToClaim = $t02205422498._4
474- let usdtPriceAssetAllowableRatio = $t02205422498._5
475- let currentUsdtPriceAssetRatio = $t02205422498._6
476- let endPeriodBlocksLeft = $t02205422498._7
477- let updatedCurrentPeriod = $t02205422498._8
478- let periodStart = $t02205422498._9
479- let periodEnd = $t02205422498._10
480- let checks = [if ((periodUserAvailableToClaim > 0))
481- then true
482- else throwErr("unavailable to claim because user period allowance reached"), if ((periodTotalAvailableToClaim > 0))
483- then true
484- else throwErr("unavailable to claim because total period allowance reached"), if ((periodMinAvailableToClaim > 0))
485- then true
486- else throwErr("nothing to claim"), if ((usdtPriceAssetAllowableRatio > currentUsdtPriceAssetRatio))
487- then true
488- else throwErr("unavailable to claim because usdn price lower than usdtPriceAssetAllowableRatio")]
489- if ((checks == checks))
481+ let availablePriceAmountToClaim = parseIntValue(evaluateResult[3])
482+ let investorTotalAmount = parseIntValue(origInvestArray[IdxInvTotalAmount])
483+ let investorRemainingAmount = parseIntValue(origInvestArray[IdxInvRemainingAmount])
484+ let investorPriceAssetBalance = parseIntValue(origInvestArray[IdxInvClaimedPriceAssetAmount])
485+ let investorIdoAssetBalance = parseIntValue(origInvestArray[IdxInvClaimedIdoAssetAmount])
486+ let investorLastClaimedHeight = parseIntValue(origInvestArray[IdxInvLastClaimedHeight])
487+ let newInvestArray = [toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString(investorIdoAssetBalance), toString(investorLastClaimedHeight)]
488+ let totals = readTotalsArrayOrDefault()
489+ let totalsTotalAmount = parseIntValue(totals[IdxInvTotalAmount])
490+ let totalsRemainingAmount = parseIntValue(totals[IdxInvRemainingAmount])
491+ let totalsClaimedPriceAssetAmount = parseIntValue(totals[IdxInvRemainingAmount])
492+ let totalsClaimedIdoAssetAmount = parseIntValue(totals[IdxInvClaimedPriceAssetAmount])
493+ let totalsLastClaimedHeight = parseIntValue(totals[IdxInvLastClaimedHeight])
494+ let newTotalsRemainingAmount = (totalsRemainingAmount - investorRemainingAmount)
495+ let newTotalArray = [toString(totalsTotalAmount), toString(newTotalsRemainingAmount), toString(totalsClaimedPriceAssetAmount), toString(totalsClaimedIdoAssetAmount), toString(totalsLastClaimedHeight)]
496+ let newTotalRemainingAmount = (valueOrElse(getInteger(keyTotalRemainingAmount()), 0) + investorRemainingAmount)
497+ let entries = if ((claimedAssetId58 == priceAssetId58))
490498 then {
491- let updatedPeriodTotalAvailableToClaim = (periodTotalAvailableToClaim - periodMinAvailableToClaim)
492- let updatedPeriodUserAvailableToClaim = (periodUserAvailableToClaim - periodMinAvailableToClaim)
493- let entries = if ((priceAssetBalance > periodMinAvailableToClaim))
494- then [ScriptTransfer(i.caller, periodMinAvailableToClaim, outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), (priceAssetBalance - periodMinAvailableToClaim))]
495- else {
496- let evaluateResult = split(asString(invoke(this, "claimREADONLY", [priceAssetId58, userAddress58], nil)), SEP)
497- if ((evaluateResult == evaluateResult))
498- then {
499- let availablePriceAmountToClaim = parseIntValue(evaluateResult[3])
499+ let checks = [if ((periodUserAvailableToClaim > 0))
500+ then true
501+ else throwErr("unavailable to claim because user period allowance reached"), if ((periodTotalAvailableToClaim > 0))
502+ then true
503+ else throwErr("unavailable to claim because total period allowance reached"), if ((periodMinAvailableToClaim > 0))
504+ then true
505+ else throwErr("nothing to claim"), if ((usdtPriceAssetAllowableRatio > currentUsdtPriceAssetRatio))
506+ then true
507+ else throwErr("unavailable to claim because usdn price lower than usdtPriceAssetAllowableRatio")]
508+ if ((checks == checks))
509+ then {
510+ let updatedPeriodTotalAvailableToClaim = (periodTotalAvailableToClaim - periodMinAvailableToClaim)
511+ let updatedPeriodUserAvailableToClaim = (periodUserAvailableToClaim - periodMinAvailableToClaim)
512+ let entries = if ((priceAssetBalance > periodMinAvailableToClaim))
513+ then [ScriptTransfer(i.caller, periodMinAvailableToClaim, outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), (priceAssetBalance - periodMinAvailableToClaim))]
514+ else {
500515 let lastClaimEntries = if ((availablePriceAmountToClaim == periodMinAvailableToClaim))
501- then {
502- let investorTotalAmount = parseIntValue(origInvestArray[IdxInvTotalAmount])
503- let investorRemainingAmount = parseIntValue(origInvestArray[IdxInvRemainingAmount])
504- let investorPriceAssetBalance = parseIntValue(origInvestArray[IdxInvClaimedPriceAssetAmount])
505- let investorIdoAssetBalance = parseIntValue(origInvestArray[IdxInvClaimedIdoAssetAmount])
506- let investorLastClaimedHeight = parseIntValue(origInvestArray[IdxInvLastClaimedHeight])
507- let newInvestArray = [toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString(investorIdoAssetBalance), toString(investorLastClaimedHeight)]
508- let totals = readTotalsArrayOrDefault()
509- let totalsTotalAmount = parseIntValue(totals[IdxInvTotalAmount])
510- let totalsRemainingAmount = parseIntValue(totals[IdxInvRemainingAmount])
511- let totalsClaimedPriceAssetAmount = parseIntValue(totals[IdxInvRemainingAmount])
512- let totalsClaimedIdoAssetAmount = parseIntValue(totals[IdxInvClaimedPriceAssetAmount])
513- let totalsLastClaimedHeight = parseIntValue(totals[IdxInvLastClaimedHeight])
514- let newTotalsRemainingAmount = (totalsRemainingAmount - investorRemainingAmount)
515- let newTotalArray = [toString(totalsTotalAmount), toString(newTotalsRemainingAmount), toString(totalsClaimedPriceAssetAmount), toString(totalsClaimedIdoAssetAmount), toString(totalsLastClaimedHeight)]
516- let newTotalRemainingAmount = (valueOrElse(getInteger(keyTotalRemainingAmount()), 0) + investorRemainingAmount)
517-[StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), TotalsEntry(keyInvestor(userAddress58), newInvestArray, totalsDiff, newClaimPeriodHeight, 0), TotalsEntry(keyTotals(), newTotalArray, totalsDiff, newClaimPeriodHeight, 0)]
518- }
516+ then [StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), TotalsEntry(keyInvestor(userAddress58), newInvestArray, totalsDiff, newClaimPeriodHeight, 0), TotalsEntry(keyTotals(), newTotalArray, totalsDiff, newClaimPeriodHeight, 0)]
519517 else [TotalsEntry(keyInvestor(userAddress58), origInvestArray, totalsDiff, newClaimPeriodHeight, 0), TotalsEntry(keyTotals(), readTotalsArrayOrDefault(), totalsDiff, newClaimPeriodHeight, 0)]
520518 let updatedPriceAssetBalance = ((priceAssetBalance + outAmount) - periodMinAvailableToClaim)
521519 ([ScriptTransfer(i.caller, periodMinAvailableToClaim, outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), updatedPriceAssetBalance)] ++ lastClaimEntries)
522520 }
523- else throw("Strict value is not equal to itself.")
521+ $Tuple2(([IntegerEntry(keyCurrentPeriod(), updatedCurrentPeriod), IntegerEntry(keyPeriodStartHeight(updatedCurrentPeriod), periodStart), IntegerEntry(keyPeriodEndHeight(updatedCurrentPeriod), periodEnd), IntegerEntry(keyPeriodTotalAvailableToClaim(priceAssetId58, updatedCurrentPeriod), updatedPeriodTotalAvailableToClaim), IntegerEntry(keyPeriodUserAvailableToClaim(priceAssetId58, updatedCurrentPeriod, userAddress58), updatedPeriodUserAvailableToClaim), ClaimOperationHistoryEntry(userAddress58, periodMinAvailableToClaim, claimedIdoAssetAmountFromDiff, i.transactionId)] ++ entries), unit)
524522 }
525- $Tuple2(([IntegerEntry(keyCurrentPeriod(), updatedCurrentPeriod), IntegerEntry(keyPeriodStartHeight(updatedCurrentPeriod), periodStart), IntegerEntry(keyPeriodEndHeight(updatedCurrentPeriod), periodEnd), IntegerEntry(keyPeriodTotalAvailableToClaim(priceAssetId58, updatedCurrentPeriod), updatedPeriodTotalAvailableToClaim), IntegerEntry(keyPeriodUserAvailableToClaim(priceAssetId58, updatedCurrentPeriod, userAddress58), updatedPeriodUserAvailableToClaim), ClaimOperationHistoryEntry(userAddress58, periodMinAvailableToClaim, claimedIdoAssetAmountFromDiff, i.transactionId)] ++ entries), unit)
523+ else throw("Strict value is not equal to itself.")
524+ }
525+ else {
526+ let priceAssetBalanceIdoDecimals = fraction(priceAssetBalance, scale8, pow(10, 0, priceAssetDecimals, 0, 0, DOWN))
527+ $Tuple2([StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), ScriptTransfer(i.caller, (outAmount + priceAssetBalanceIdoDecimals), outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), 0), TotalsEntry(keyInvestor(userAddress58), newInvestArray, totalsDiff, newClaimPeriodHeight, priceAssetBalance), TotalsEntry(keyTotals(), newTotalArray, totalsDiff, newClaimPeriodHeight, priceAssetBalance), ClaimOperationHistoryEntry(userAddress58, claimedPriceAmountFromDiff, (claimedIdoAssetAmountFromDiff + priceAssetBalanceIdoDecimals), i.transactionId)], unit)
528+ }
529+ entries
530+ }
531+ else throw("Strict value is not equal to itself.")
532+ }
533+ }
534+
535+
536+
537+@Callable(i)
538+func cleanRemaingAmount (userAddress58) = {
539+ let priceAssetId58 = readConfigArray()[IdxCfgPriceAssetId]
540+ let evaluateResult = split(asString(invoke(this, "claimREADONLY", [priceAssetId58, userAddress58], nil)), SEP)
541+ if ((evaluateResult == evaluateResult))
542+ then {
543+ let availablePriceAmountToClaim = parseIntValue(evaluateResult[2])
544+ let checkUnclaimedAssets = if ((availablePriceAmountToClaim == 0))
545+ then true
546+ else throwErr("user have unclaimed assets")
547+ if ((checkUnclaimedAssets == checkUnclaimedAssets))
548+ then {
549+ let investor = split(value(getString(keyInvestor(userAddress58))), SEP)
550+ let investorTotalAmount = parseIntValue(investor[IdxInvTotalAmount])
551+ let investorRemainingAmount = parseIntValue(investor[IdxInvRemainingAmount])
552+ let investorPriceAssetBalance = parseIntValue(investor[IdxInvClaimedPriceAssetAmount])
553+ let investorIdoAssetBalance = parseIntValue(investor[IdxInvClaimedIdoAssetAmount])
554+ let investorLastClaimedHeight = parseIntValue(investor[IdxInvLastClaimedHeight])
555+ let investorRemainingAmountCheck = if ((investorRemainingAmount != 0))
556+ then true
557+ else throwErr("investorRemainingAmount already zero")
558+ if ((investorRemainingAmountCheck == investorRemainingAmountCheck))
559+ then {
560+ let newInvestor = makeString(["%d%d%d%d%d", toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString(investorIdoAssetBalance), toString(investorLastClaimedHeight)], SEP)
561+ let totals = split(value(getString(keyTotals())), SEP)
562+ let totalsTotalAmount = parseIntValue(totals[IdxInvTotalAmount])
563+ let totalsRemainingAmount = parseIntValue(totals[IdxInvRemainingAmount])
564+ let totalsClaimedPriceAssetAmount = parseIntValue(totals[IdxInvClaimedPriceAssetAmount])
565+ let totalsClaimedIdoAssetAmount = parseIntValue(totals[IdxInvClaimedIdoAssetAmount])
566+ let totalsLastClaimedHeight = parseIntValue(totals[IdxInvLastClaimedHeight])
567+ let newTotals = makeString(["%d%d%d%d%d", toString(totalsTotalAmount), toString((totalsRemainingAmount - investorRemainingAmount)), toString(totalsClaimedPriceAssetAmount), toString(totalsClaimedIdoAssetAmount), toString(totalsLastClaimedHeight)], SEP)
568+ let newTotalRemainingAmount = (valueOrElse(getInteger(keyTotalRemainingAmount()), 0) + investorRemainingAmount)
569+[StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), StringEntry(keyInvestor(userAddress58), newInvestor), StringEntry(keyTotals(), newTotals)]
526570 }
527571 else throw("Strict value is not equal to itself.")
528572 }
529- else {
530- let priceAssetBalanceIdoDecimals = fraction(priceAssetBalance, scale8, pow(10, 0, priceAssetDecimals, 0, 0, DOWN))
531- $Tuple2([ScriptTransfer(i.caller, (outAmount + priceAssetBalanceIdoDecimals), outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), 0), TotalsEntry(keyInvestor(userAddress58), origInvestArray, totalsDiff, newClaimPeriodHeight, priceAssetBalance), TotalsEntry(keyTotals(), readTotalsArrayOrDefault(), totalsDiff, newClaimPeriodHeight, priceAssetBalance), ClaimOperationHistoryEntry(userAddress58, claimedPriceAmountFromDiff, (claimedIdoAssetAmountFromDiff + priceAssetBalanceIdoDecimals), i.transactionId)], unit)
532- }
533- entries
573+ else throw("Strict value is not equal to itself.")
534574 }
575+ else throw("Strict value is not equal to itself.")
535576 }
536577
537578
568609 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
569610 let priceAssetBalanceIdoDecimals = (priceAssetBalance * 100)
570611 let availableIdoAmountToClaimWithPriceAssetBalance = (availableIdoAmountToClaim + priceAssetBalanceIdoDecimals)
571- let $t03128231694 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
572- let periodMinAvailableToClaim = $t03128231694._1
573- let periodTotalAvailableToClaim = $t03128231694._2
574- let periodUserAvailableToClaim = $t03128231694._3
575- let totalUserAvailableToClaim = $t03128231694._4
576- let usdtPriceAssetAllowableRatio = $t03128231694._5
577- let currentUsdtPriceAssetRatio = $t03128231694._6
578- let endPeriodBlocksLeft = $t03128231694._7
579- let updatedCurrentPeriod = $t03128231694._8
580- let periodStart = $t03128231694._9
581- let periodEnd = $t03128231694._10
612+ let $t03370134113 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
613+ let periodMinAvailableToClaim = $t03370134113._1
614+ let periodTotalAvailableToClaim = $t03370134113._2
615+ let periodUserAvailableToClaim = $t03370134113._3
616+ let totalUserAvailableToClaim = $t03370134113._4
617+ let usdtPriceAssetAllowableRatio = $t03370134113._5
618+ let currentUsdtPriceAssetRatio = $t03370134113._6
619+ let endPeriodBlocksLeft = $t03370134113._7
620+ let updatedCurrentPeriod = $t03370134113._8
621+ let periodStart = $t03370134113._9
622+ let periodEnd = $t03370134113._10
582623 let currentPeriodEndHeight = valueOrElse(getInteger(keyPeriodEndHeight(updatedCurrentPeriod)), 0)
583624 let userTotalPriceAssetClaimed = (parseIntValue(readInvestorArrayOrFail(userAddress58)[IdxInvClaimedPriceAssetAmount]) - priceAssetBalance)
584625 let resultString = if ((height > currentPeriodEndHeight))
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func getStringOrFail (key) = valueOrErrorMessage(getString(key), (("mandatory this." + key) + " is not defined"))
55
66
77 let SEP = "__"
88
99 let BUFSCALE = toBigInt(1000000000000000000)
1010
1111 let scale8 = 100000000
1212
1313 func throwErr (msg) = throw(makeString(["ido.ride:", msg], " "))
1414
1515
1616 func asString (val) = match val {
1717 case valStr: String =>
1818 valStr
1919 case _ =>
2020 throw("fail to cast into String")
2121 }
2222
2323
2424 func convertPriceAssetIntoIdoAsset (priceAssetAmount,priceAssetMULT,price,priceMULT,idoAssetMULT) = {
2525 let bPriceAssetMULT = toBigInt(priceAssetMULT)
2626 let bIdoAssetMULT = toBigInt(idoAssetMULT)
2727 let bPriceAssetBUF = fraction(toBigInt(priceAssetAmount), BUFSCALE, bPriceAssetMULT)
2828 let bAmountAssetBUF = fraction(bPriceAssetBUF, toBigInt(priceMULT), toBigInt(price))
2929 toInt(fraction(bAmountAssetBUF, toBigInt(idoAssetMULT), BUFSCALE))
3030 }
3131
3232
3333 let IdxCfgIdoStart = 1
3434
3535 let IdxCfgIdoDuration = 2
3636
3737 let IdxCfgClaimStart = 3
3838
3939 let IdxCfgClaimDuration = 4
4040
4141 let IdxCfgPrice = 5
4242
4343 let IdxCfgPriceMult = 6
4444
4545 let IdxCfgIdoAssetId = 7
4646
4747 let IdxCfgIdoAssetMult = 8
4848
4949 let IdxCfgPriceAssetId = 9
5050
5151 let IdxCfgPriceAssetMult = 10
5252
5353 let IdxCfgMinInvestAmount = 11
5454
5555 func fromatConfigS (idoStart,idoDuration,claimStart,claimDuration,price,priceMult,idoAssetId58,idoAssetMult,priceAssetId58,priceAssetMult,minInvestAmount,totalIdoAssetToSell) = makeString(["%d%d%d%d%d%d%s%d%s%d%d%d", idoStart, idoDuration, claimStart, claimDuration, price, priceMult, idoAssetId58, idoAssetMult, priceAssetId58, priceAssetMult, minInvestAmount, totalIdoAssetToSell], SEP)
5656
5757
5858 func fromatConfig (idoStart,idoDuration,claimStart,claimDuration,price,priceMult,idoAssetId58,idoAssetMult,priceAssetId58,priceAssetMult,minInvestAmount,totalIdoAssetToSell) = fromatConfigS(toString(idoStart), toString(idoDuration), toString(claimStart), toString(claimDuration), toString(price), toString(priceMult), idoAssetId58, toString(idoAssetMult), priceAssetId58, toString(priceAssetMult), toString(minInvestAmount), toString(totalIdoAssetToSell))
5959
6060
6161 let IdxInvTotalAmount = 1
6262
6363 let IdxInvRemainingAmount = 2
6464
6565 let IdxInvClaimedPriceAssetAmount = 3
6666
6767 let IdxInvClaimedIdoAssetAmount = 4
6868
6969 let IdxInvLastClaimedHeight = 5
7070
7171 func formatInvestorS (totalAmount,remainingAmount,claimedPriceAssetAmount,claimedIdoAssetAmount,lastClaimedHeight) = makeString(["%d%d%d%d%d", totalAmount, remainingAmount, claimedPriceAssetAmount, claimedIdoAssetAmount, lastClaimedHeight], SEP)
7272
7373
7474 func formatInvestor (totalAmount,remainingAmount,claimedPriceAssetAmount,claimedIdoAssetAmount,lastClaimedHeight) = formatInvestorS(toString(totalAmount), toString(remainingAmount), toString(claimedPriceAssetAmount), toString(claimedIdoAssetAmount), toString(lastClaimedHeight))
7575
7676
7777 func formatHistoryRecord (priceAssetAmount,idoAssetAmount) = makeString(["%d%d%d%d", toString(height), toString(lastBlock.timestamp), toString(priceAssetAmount), toString(idoAssetAmount)], SEP)
7878
7979
8080 func keyConfig () = "%s__config"
8181
8282
8383 func keyInvestor (userAddress) = ("%s__" + userAddress)
8484
8585
8686 func keyTotals () = "%s__totals"
8787
8888
8989 func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
9090
9191
9292 func keyUSDNClaimDisabled () = "%s__usdnClaimDisabled"
9393
9494
9595 func keyUSDNClaimEndHeight () = "%s__usdnClaimEndHeight"
9696
9797
9898 func keyPeriodLength () = makeString(["%s", "periodLength"], SEP)
9999
100100
101101 func keyCurrentPeriod () = makeString(["%s", "currentPeriod"], SEP)
102102
103103
104104 func keyPeriodStartHeight (periodNum) = makeString(["%s%s", "periodStartHeight", toString(periodNum)], SEP)
105105
106106
107107 func keyPeriodEndHeight (periodNum) = makeString(["%s%s", "periodEndHeight", toString(periodNum)], SEP)
108108
109109
110110 func keyUsdtPriceAssetAllowableRatio () = makeString(["%s", "usdtPriceAssetAllowableRatio"], SEP)
111111
112112
113113 func keyTotalPeriodAllowance (assetId) = makeString(["%s%s", "totalPeriodAllowance", assetId], SEP)
114114
115115
116116 func keyUserPeriodAllowance (assetId) = makeString(["%s%s", "userPeriodAllowance", assetId], SEP)
117117
118118
119119 func keyPeriodTotalAvailableToClaim (assetId,periodNum) = makeString(["%s%s%s", "periodTotalAvailableToClaim", assetId, toString(periodNum)], SEP)
120120
121121
122122 func keyPeriodUserAvailableToClaim (assetId,periodNum,userAddress) = makeString(["%s%s%s%s", "periodUserAvailableToClaim", assetId, toString(periodNum), userAddress], SEP)
123123
124124
125125 func keyUsdtPriceAssetStablePool () = makeString(["%s", "usdtPriceAssetStablePool"], SEP)
126126
127127
128128 func keyUsdtAssetId () = makeString(["%s", "usdtAssetId"], SEP)
129129
130130
131131 func keyPriceAssetBalance (address) = makeString(["%s%s", "priceAssetBalance", address], SEP)
132132
133133
134134 func keyInvestorRemainingAmount (address) = makeString(["%s%s", "investorRemainingAmount", address], SEP)
135135
136136
137137 func keyTotalRemainingAmount () = makeString(["%s", "totalRemainingAmount"], SEP)
138138
139139
140140 func keyManagerPublicKey () = "%s__managerPublicKey"
141141
142142
143143 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
144144
145145
146146 func readConfigArray () = split(getStringOrFail(keyConfig()), SEP)
147147
148148
149149 func readTotalsArrayOrDefaultByCustomKey (customKey) = split(valueOrElse(getString(customKey), formatInvestorS("0", "0", "0", "0", "0")), SEP)
150150
151151
152152 func readTotalsArrayOrDefault () = readTotalsArrayOrDefaultByCustomKey(keyTotals())
153153
154154
155155 func readInvestorArrayOrDefault (userAddress) = readTotalsArrayOrDefaultByCustomKey(keyInvestor(userAddress))
156156
157157
158158 func readInvestorArrayOrFail (userAddress) = split(getStringOrFail(keyInvestor(userAddress)), SEP)
159159
160160
161161 let IdxDiffTotalIncrement = 0
162162
163163 let IdxDiffRemainingPriceAmountIncrement = 1
164164
165165 let IdxDiffClaimedPriceAmountIncrement = 2
166166
167167 let IdxDiffClaimedIdoAssetAmountIncrement = 3
168168
169169 func TotalsEntry (key,origArray,incrementDiff,newLastClaimedHeight,priceAssetBalance) = {
170170 let totalAmount = parseIntValue(origArray[IdxInvTotalAmount])
171171 let remainingAmount = parseIntValue(origArray[IdxInvRemainingAmount])
172172 let claimedPriceAssetAmount = parseIntValue(origArray[IdxInvClaimedPriceAssetAmount])
173173 let claimedIdoAssetAmount = parseIntValue(origArray[IdxInvClaimedIdoAssetAmount])
174174 let lastClaimedHeight = parseIntValue(origArray[IdxInvLastClaimedHeight])
175175 let newTotalAmount = (totalAmount + incrementDiff[IdxDiffTotalIncrement])
176176 let newRemainingAmount = (remainingAmount + incrementDiff[IdxDiffRemainingPriceAmountIncrement])
177177 let cfgArray = readConfigArray()
178178 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
179179 let priceAssetDecimals = value(assetInfo(fromBase58String(priceAssetId58))).decimals
180180 let priceAssetBalancePriceAssetDecimals = fraction(priceAssetBalance, scale8, pow(10, 0, priceAssetDecimals, 0, 0, DOWN))
181181 let newClaimedPriceAssetAmount = ((claimedPriceAssetAmount + incrementDiff[IdxDiffClaimedPriceAmountIncrement]) - priceAssetBalance)
182182 let newClaimedIdoAssetAmount = ((claimedIdoAssetAmount + incrementDiff[IdxDiffClaimedIdoAssetAmountIncrement]) + priceAssetBalancePriceAssetDecimals)
183183 let entries = if ((0 > newRemainingAmount))
184184 then {
185185 let diff = ((newTotalAmount - newClaimedPriceAssetAmount) - newClaimedIdoAssetAmount)
186186 let newLogicRemainingAmount = if ((0 > diff))
187187 then 0
188188 else diff
189189 StringEntry(key, formatInvestor(newTotalAmount, newLogicRemainingAmount, newClaimedPriceAssetAmount, newClaimedIdoAssetAmount, newLastClaimedHeight))
190190 }
191191 else StringEntry(key, formatInvestor(newTotalAmount, newRemainingAmount, newClaimedPriceAssetAmount, newClaimedIdoAssetAmount, newLastClaimedHeight))
192192 entries
193193 }
194194
195195
196196 func InvestOperationHistoryEntry (userAddress,priceAssetAmount,idoAssetAmount,txId) = StringEntry(keyOperationHistoryRecord("invest", userAddress, toBase58String(txId)), formatHistoryRecord(priceAssetAmount, idoAssetAmount))
197197
198198
199199 func ClaimOperationHistoryEntry (userAddress,priceAssetAmount,idoAssetAmount,txId) = StringEntry(keyOperationHistoryRecord("claim", userAddress, toBase58String(txId)), formatHistoryRecord(priceAssetAmount, idoAssetAmount))
200200
201201
202202 func internalClaim (claimedAssetId58,userAddress,txId) = {
203203 let cfgArray = readConfigArray()
204204 let claimStart = parseIntValue(cfgArray[IdxCfgClaimStart])
205205 let claimDuration = parseIntValue(cfgArray[IdxCfgClaimDuration])
206206 let claimEnd = (claimStart + claimDuration)
207207 let price = parseIntValue(cfgArray[IdxCfgPrice])
208208 let priceMult = parseIntValue(cfgArray[IdxCfgPriceMult])
209209 let idoAssetId58 = cfgArray[IdxCfgIdoAssetId]
210210 let idoAssetId = fromBase58String(idoAssetId58)
211211 let idoAssetMult = parseIntValue(cfgArray[IdxCfgIdoAssetMult])
212212 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
213213 let priceAssetId = fromBase58String(priceAssetId58)
214214 let priceAssetMult = parseIntValue(cfgArray[IdxCfgPriceAssetMult])
215215 let userAddress58 = toString(userAddress)
216216 let origInvestArray = readInvestorArrayOrFail(userAddress58)
217217 let investTotalAmount = parseIntValue(origInvestArray[IdxInvTotalAmount])
218218 let investLastClaimedHeightTMP = parseIntValue(origInvestArray[IdxInvLastClaimedHeight])
219219 let investLastClaimedHeight = if ((claimStart >= investLastClaimedHeightTMP))
220220 then claimStart
221221 else investLastClaimedHeightTMP
222222 let newClaimPeriodHeight = if ((height > claimEnd))
223223 then claimEnd
224224 else if ((claimStart > height))
225225 then claimStart
226226 else height
227227 let claimingBlocks = (newClaimPeriodHeight - investLastClaimedHeight)
228228 let claimingPriceAssetAmount = fraction(investTotalAmount, claimingBlocks, claimDuration)
229229 let claimingIdoAssetAmount = convertPriceAssetIntoIdoAsset(claimingPriceAssetAmount, priceAssetMult, price, priceMult, idoAssetMult)
230230 let isUSDN = (claimedAssetId58 == priceAssetId58)
231231 let isUSDNClaimDisabled = valueOrElse(getBoolean(keyUSDNClaimDisabled()), false)
232232 let checks = [if (!(if (isUSDN)
233233 then isUSDNClaimDisabled
234234 else false))
235235 then true
236236 else throw("USDN claim is disabled")]
237237 if ((checks == checks))
238238 then if ((claimedAssetId58 == priceAssetId58))
239239 then $Tuple6([0, -(claimingPriceAssetAmount), claimingPriceAssetAmount, 0], claimingPriceAssetAmount, priceAssetId, origInvestArray, newClaimPeriodHeight, [claimingPriceAssetAmount, claimingIdoAssetAmount])
240240 else if ((claimedAssetId58 == idoAssetId58))
241241 then $Tuple6([0, -(claimingPriceAssetAmount), 0, claimingIdoAssetAmount], claimingIdoAssetAmount, idoAssetId, origInvestArray, newClaimPeriodHeight, [claimingPriceAssetAmount, claimingIdoAssetAmount])
242242 else throw(("unsupported assetId: " + claimedAssetId58))
243243 else throw("Strict value is not equal to itself.")
244244 }
245245
246246
247247 func internalClaimV2 (priceAssetId58,userAddress58,outAmount,totalUserAvailableToClaim) = {
248248 let totalPeriodPriceAssetAllowance = value(getInteger(keyTotalPeriodAllowance(priceAssetId58)))
249249 let userPeriodPriceAssetAllowance = value(getInteger(keyUserPeriodAllowance(priceAssetId58)))
250250 let periodLength = value(getInteger(keyPeriodLength()))
251251 let currentPeriod = valueOrElse(getInteger(keyCurrentPeriod()), 0)
252252 let zeroPeriodEndHeighIsDefined = isDefined(getInteger(keyPeriodEndHeight(0)))
253253 let $t01298714857 = if ((currentPeriod > 0))
254254 then {
255255 let lastPeriodStartHeight = value(getInteger(keyPeriodStartHeight(currentPeriod)))
256256 let lastPeriodEndHeight = value(getInteger(keyPeriodEndHeight(currentPeriod)))
257257 let $t01324713952 = if ((height > lastPeriodEndHeight))
258258 then {
259259 let updatedCurrentPeriod = (currentPeriod + 1)
260260 let periodStart = if ((height > (lastPeriodEndHeight + periodLength)))
261261 then {
262262 let blocksToLastPeriodStart = ((height - lastPeriodEndHeight) % periodLength)
263263 if ((blocksToLastPeriodStart == 0))
264264 then ((height - periodLength) + 1)
265265 else (height - blocksToLastPeriodStart)
266266 }
267267 else (lastPeriodEndHeight + 1)
268268 let periodEnd = ((periodStart + periodLength) - 1)
269269 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
270270 }
271271 else $Tuple3(currentPeriod, lastPeriodStartHeight, lastPeriodEndHeight)
272272 let updatedCurrentPeriod = $t01324713952._1
273273 let periodStart = $t01324713952._2
274274 let periodEnd = $t01324713952._3
275275 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
276276 }
277277 else if (zeroPeriodEndHeighIsDefined)
278278 then {
279279 let zeroPeriodStartHeight = value(getInteger(keyPeriodStartHeight(0)))
280280 let zeroPeriodEndHeight = value(getInteger(keyPeriodEndHeight(0)))
281281 let $t01420714589 = if ((height > zeroPeriodEndHeight))
282282 then {
283283 let updatedCurrentPeriod = (currentPeriod + 1)
284284 let periodStart = (zeroPeriodEndHeight + 1)
285285 let periodEnd = ((periodStart + periodLength) - 1)
286286 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
287287 }
288288 else $Tuple3(currentPeriod, zeroPeriodStartHeight, zeroPeriodEndHeight)
289289 let updatedCurrentPeriod = $t01420714589._1
290290 let periodStart = $t01420714589._2
291291 let periodEnd = $t01420714589._3
292292 $Tuple3(updatedCurrentPeriod, periodStart, periodEnd)
293293 }
294294 else $Tuple3(currentPeriod, valueOrElse(getInteger(keyPeriodStartHeight(currentPeriod)), height), valueOrElse(getInteger(keyPeriodEndHeight(currentPeriod)), ((height + periodLength) - 1)))
295295 let updatedCurrentPeriod = $t01298714857._1
296296 let periodStart = $t01298714857._2
297297 let periodEnd = $t01298714857._3
298298 let periodTotalAvailableToClaim = valueOrElse(getInteger(keyPeriodTotalAvailableToClaim(priceAssetId58, updatedCurrentPeriod)), totalPeriodPriceAssetAllowance)
299299 let periodUserAvailableToClaim = valueOrElse(getInteger(keyPeriodUserAvailableToClaim(priceAssetId58, updatedCurrentPeriod, userAddress58)), userPeriodPriceAssetAllowance)
300300 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
301301 let periodMinAvailableToClaim = min([(outAmount + priceAssetBalance), periodTotalAvailableToClaim, periodUserAvailableToClaim])
302302 let usdtPriceAssetAllowableRatio = value(getInteger(keyUsdtPriceAssetAllowableRatio()))
303303 let putOneTknV2PriceAssetAmount = scale8
304304 let $t01561215865 = {
305305 let @ = invoke(addressFromStringValue(value(getString(keyUsdtPriceAssetStablePool()))), "putOneTknV2WithoutTakeFeeREADONLY", [putOneTknV2PriceAssetAmount, priceAssetId58], nil)
306306 if ($isInstanceOf(@, "(Int, Int, Int)"))
307307 then @
308308 else throw(($getType(@) + " couldn't be cast to (Int, Int, Int)"))
309309 }
310310 if (($t01561215865 == $t01561215865))
311311 then {
312312 let bonus = $t01561215865._3
313313 let feeAmount = $t01561215865._2
314314 let lpAmount = $t01561215865._1
315315 let usdtAssetId = value(getString(keyUsdtAssetId()))
316316 let $t01592716145 = {
317317 let @ = invoke(addressFromStringValue(value(getString(keyUsdtPriceAssetStablePool()))), "getOneTknV2READONLY", [usdtAssetId, lpAmount], nil)
318318 if ($isInstanceOf(@, "(Int, Int)"))
319319 then @
320320 else throw(($getType(@) + " couldn't be cast to (Int, Int)"))
321321 }
322322 if (($t01592716145 == $t01592716145))
323323 then {
324324 let getOneTknV2FeeAmount = $t01592716145._2
325325 let usdtAmount = $t01592716145._1
326326 let currentUsdtPriceAssetRatio = fraction(putOneTknV2PriceAssetAmount, scale8, usdtAmount)
327327 let endPeriodBlocksLeft = (periodEnd - height)
328328 $Tuple10(periodMinAvailableToClaim, periodTotalAvailableToClaim, periodUserAvailableToClaim, totalUserAvailableToClaim, usdtPriceAssetAllowableRatio, currentUsdtPriceAssetRatio, endPeriodBlocksLeft, updatedCurrentPeriod, periodStart, periodEnd)
329329 }
330330 else throw("Strict value is not equal to itself.")
331331 }
332332 else throw("Strict value is not equal to itself.")
333333 }
334334
335335
336336 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
337337 case s: String =>
338338 fromBase58String(s)
339339 case _: Unit =>
340340 unit
341341 case _ =>
342342 throw("Match error")
343343 }
344344
345345
346346 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
347347 case s: String =>
348348 fromBase58String(s)
349349 case _: Unit =>
350350 unit
351351 case _ =>
352352 throw("Match error")
353353 }
354354
355355
356356 func mustManager (i) = {
357357 let pd = throw("Permission denied")
358358 match managerPublicKeyOrUnit() {
359359 case pk: ByteVector =>
360360 if ((i.callerPublicKey == pk))
361361 then true
362362 else pd
363363 case _: Unit =>
364364 if ((i.caller == this))
365365 then true
366366 else pd
367367 case _ =>
368368 throw("Match error")
369369 }
370370 }
371371
372372
373373 @Callable(i)
374374 func constructor (idoStart,idoDuration,claimStart,claimDuration,price,priceAssetId58,minInvestAmount) = {
375375 let priceMult = ((100 * 1000) * 1000)
376376 let idoEnd = (idoStart + idoDuration)
377377 if (isDefined(getString(keyConfig())))
378378 then throw("already initialized")
379379 else if (("3PMEHLx1j6zerarZTYfsGqDeeZqQoMpxq5S" != toString(i.caller)))
380380 then throw("not authorized")
381381 else if ((size(i.payments) != 1))
382382 then throw("exactly 1 payment must be attached")
383383 else if ((idoEnd >= claimStart))
384384 then throw("claimStart must be greater than idoEnd")
385385 else {
386386 let pmt = value(i.payments[0])
387387 let idoAssetId = value(pmt.assetId)
388388 let idoAssetInfo = valueOrErrorMessage(assetInfo(idoAssetId), "fail to load ido asset info")
389389 let idoAssetId58 = toBase58String(idoAssetId)
390390 let idoAssetMult = pow(10, 0, idoAssetInfo.decimals, 0, 0, DOWN)
391391 let priceAssetId = fromBase58String(priceAssetId58)
392392 let priceAssetInfo = valueOrErrorMessage(assetInfo(priceAssetId), "fail to load price asset info")
393393 let priceAssetMult = pow(10, 0, priceAssetInfo.decimals, 0, 0, DOWN)
394394 let origTotalsArray = readTotalsArrayOrDefault()
395395 let totalsDiff = [0, 0, 0, 0]
396396 [StringEntry(keyConfig(), fromatConfig(idoStart, idoDuration, claimStart, claimDuration, price, priceMult, idoAssetId58, idoAssetMult, priceAssetId58, priceAssetMult, minInvestAmount, pmt.amount)), TotalsEntry(keyTotals(), origTotalsArray, totalsDiff, claimStart, 0)]
397397 }
398398 }
399399
400400
401401
402402 @Callable(i)
403403 func invest () = {
404404 let cfgArray = readConfigArray()
405405 let idoStart = parseIntValue(cfgArray[IdxCfgIdoStart])
406406 let idoDuration = parseIntValue(cfgArray[IdxCfgIdoDuration])
407407 let idoEnd = (idoStart + idoDuration)
408408 let claimStart = parseIntValue(cfgArray[IdxCfgClaimStart])
409409 let claimDuration = parseIntValue(cfgArray[IdxCfgClaimDuration])
410410 let price = parseIntValue(cfgArray[IdxCfgPrice])
411411 let priceMult = parseIntValue(cfgArray[IdxCfgPriceMult])
412412 let idoAssetId58 = cfgArray[IdxCfgIdoAssetId]
413413 let idoAssetId = fromBase58String(idoAssetId58)
414414 let idoAssetMult = parseIntValue(cfgArray[IdxCfgIdoAssetMult])
415415 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
416416 let priceAssetId = fromBase58String(priceAssetId58)
417417 let priceAssetMult = parseIntValue(cfgArray[IdxCfgPriceAssetMult])
418418 let minIvestAmount = parseIntValue(cfgArray[IdxCfgMinInvestAmount])
419419 let userAddress = toString(i.caller)
420420 if ((idoStart > height))
421421 then throw("ido has not been started yet")
422422 else if ((height > idoEnd))
423423 then throw("ido has been already ended")
424424 else if ((size(i.payments) != 1))
425425 then throw("exactly 1 payment is expected")
426426 else {
427427 let pmt = value(i.payments[0])
428428 let pmtAssetId = value(pmt.assetId)
429429 let pmtAmount = pmt.amount
430430 if ((pmtAssetId != priceAssetId))
431431 then throw((("invalid payment asset id: " + toBase58String(pmtAssetId)) + " is expected"))
432432 else {
433433 let origInvestorArray = readInvestorArrayOrDefault(userAddress)
434434 let origTotalsArray = readTotalsArrayOrDefault()
435435 let newPriceTotalAmount = (parseIntValue(origTotalsArray[IdxInvTotalAmount]) + pmtAmount)
436436 let requiredIdoAssetAmount = (newPriceTotalAmount * 100)
437437 if ((requiredIdoAssetAmount > assetBalance(this, idoAssetId)))
438438 then throw("IDO asset has been - sold consider to use smaller payment")
439439 else {
440440 let totalsDiff = [pmtAmount, pmtAmount, 0, 0]
441441 [TotalsEntry(keyInvestor(userAddress), origInvestorArray, totalsDiff, claimStart, 0), TotalsEntry(keyTotals(), origTotalsArray, totalsDiff, claimStart, 0), InvestOperationHistoryEntry(userAddress, pmtAmount, 0, i.transactionId)]
442442 }
443443 }
444444 }
445445 }
446446
447447
448448
449449 @Callable(i)
450450 func claim (claimedAssetId58,userAddress58) = {
451451 let callerAddress58 = toString(i.caller)
452452 if ((userAddress58 != callerAddress58))
453453 then throw("not authorized")
454454 else {
455455 let cfgArray = readConfigArray()
456456 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
457457 let claimResultTuple = internalClaim(claimedAssetId58, i.caller, i.transactionId)
458458 let totalsDiff = claimResultTuple._1
459459 let outAmount = claimResultTuple._2
460460 let outAssetId = claimResultTuple._3
461461 let origInvestArray = claimResultTuple._4
462462 let newClaimPeriodHeight = claimResultTuple._5
463463 let claimedPriceAmountFromDiff = totalsDiff[IdxDiffClaimedPriceAmountIncrement]
464464 let claimedIdoAssetAmountFromDiff = totalsDiff[IdxDiffClaimedIdoAssetAmountIncrement]
465465 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
466466 let priceAssetDecimals = value(assetInfo(fromBase58String(priceAssetId58))).decimals
467- let entries = if ((claimedAssetId58 == priceAssetId58))
467+ let $t02199122403 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
468+ let periodMinAvailableToClaim = $t02199122403._1
469+ let periodTotalAvailableToClaim = $t02199122403._2
470+ let periodUserAvailableToClaim = $t02199122403._3
471+ let totalUserAvailableToClaim = $t02199122403._4
472+ let usdtPriceAssetAllowableRatio = $t02199122403._5
473+ let currentUsdtPriceAssetRatio = $t02199122403._6
474+ let endPeriodBlocksLeft = $t02199122403._7
475+ let updatedCurrentPeriod = $t02199122403._8
476+ let periodStart = $t02199122403._9
477+ let periodEnd = $t02199122403._10
478+ let evaluateResult = split(asString(invoke(this, "claimREADONLY", [priceAssetId58, userAddress58], nil)), SEP)
479+ if ((evaluateResult == evaluateResult))
468480 then {
469- let $t02205422498 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
470- let periodMinAvailableToClaim = $t02205422498._1
471- let periodTotalAvailableToClaim = $t02205422498._2
472- let periodUserAvailableToClaim = $t02205422498._3
473- let totalUserAvailableToClaim = $t02205422498._4
474- let usdtPriceAssetAllowableRatio = $t02205422498._5
475- let currentUsdtPriceAssetRatio = $t02205422498._6
476- let endPeriodBlocksLeft = $t02205422498._7
477- let updatedCurrentPeriod = $t02205422498._8
478- let periodStart = $t02205422498._9
479- let periodEnd = $t02205422498._10
480- let checks = [if ((periodUserAvailableToClaim > 0))
481- then true
482- else throwErr("unavailable to claim because user period allowance reached"), if ((periodTotalAvailableToClaim > 0))
483- then true
484- else throwErr("unavailable to claim because total period allowance reached"), if ((periodMinAvailableToClaim > 0))
485- then true
486- else throwErr("nothing to claim"), if ((usdtPriceAssetAllowableRatio > currentUsdtPriceAssetRatio))
487- then true
488- else throwErr("unavailable to claim because usdn price lower than usdtPriceAssetAllowableRatio")]
489- if ((checks == checks))
481+ let availablePriceAmountToClaim = parseIntValue(evaluateResult[3])
482+ let investorTotalAmount = parseIntValue(origInvestArray[IdxInvTotalAmount])
483+ let investorRemainingAmount = parseIntValue(origInvestArray[IdxInvRemainingAmount])
484+ let investorPriceAssetBalance = parseIntValue(origInvestArray[IdxInvClaimedPriceAssetAmount])
485+ let investorIdoAssetBalance = parseIntValue(origInvestArray[IdxInvClaimedIdoAssetAmount])
486+ let investorLastClaimedHeight = parseIntValue(origInvestArray[IdxInvLastClaimedHeight])
487+ let newInvestArray = [toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString(investorIdoAssetBalance), toString(investorLastClaimedHeight)]
488+ let totals = readTotalsArrayOrDefault()
489+ let totalsTotalAmount = parseIntValue(totals[IdxInvTotalAmount])
490+ let totalsRemainingAmount = parseIntValue(totals[IdxInvRemainingAmount])
491+ let totalsClaimedPriceAssetAmount = parseIntValue(totals[IdxInvRemainingAmount])
492+ let totalsClaimedIdoAssetAmount = parseIntValue(totals[IdxInvClaimedPriceAssetAmount])
493+ let totalsLastClaimedHeight = parseIntValue(totals[IdxInvLastClaimedHeight])
494+ let newTotalsRemainingAmount = (totalsRemainingAmount - investorRemainingAmount)
495+ let newTotalArray = [toString(totalsTotalAmount), toString(newTotalsRemainingAmount), toString(totalsClaimedPriceAssetAmount), toString(totalsClaimedIdoAssetAmount), toString(totalsLastClaimedHeight)]
496+ let newTotalRemainingAmount = (valueOrElse(getInteger(keyTotalRemainingAmount()), 0) + investorRemainingAmount)
497+ let entries = if ((claimedAssetId58 == priceAssetId58))
490498 then {
491- let updatedPeriodTotalAvailableToClaim = (periodTotalAvailableToClaim - periodMinAvailableToClaim)
492- let updatedPeriodUserAvailableToClaim = (periodUserAvailableToClaim - periodMinAvailableToClaim)
493- let entries = if ((priceAssetBalance > periodMinAvailableToClaim))
494- then [ScriptTransfer(i.caller, periodMinAvailableToClaim, outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), (priceAssetBalance - periodMinAvailableToClaim))]
495- else {
496- let evaluateResult = split(asString(invoke(this, "claimREADONLY", [priceAssetId58, userAddress58], nil)), SEP)
497- if ((evaluateResult == evaluateResult))
498- then {
499- let availablePriceAmountToClaim = parseIntValue(evaluateResult[3])
499+ let checks = [if ((periodUserAvailableToClaim > 0))
500+ then true
501+ else throwErr("unavailable to claim because user period allowance reached"), if ((periodTotalAvailableToClaim > 0))
502+ then true
503+ else throwErr("unavailable to claim because total period allowance reached"), if ((periodMinAvailableToClaim > 0))
504+ then true
505+ else throwErr("nothing to claim"), if ((usdtPriceAssetAllowableRatio > currentUsdtPriceAssetRatio))
506+ then true
507+ else throwErr("unavailable to claim because usdn price lower than usdtPriceAssetAllowableRatio")]
508+ if ((checks == checks))
509+ then {
510+ let updatedPeriodTotalAvailableToClaim = (periodTotalAvailableToClaim - periodMinAvailableToClaim)
511+ let updatedPeriodUserAvailableToClaim = (periodUserAvailableToClaim - periodMinAvailableToClaim)
512+ let entries = if ((priceAssetBalance > periodMinAvailableToClaim))
513+ then [ScriptTransfer(i.caller, periodMinAvailableToClaim, outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), (priceAssetBalance - periodMinAvailableToClaim))]
514+ else {
500515 let lastClaimEntries = if ((availablePriceAmountToClaim == periodMinAvailableToClaim))
501- then {
502- let investorTotalAmount = parseIntValue(origInvestArray[IdxInvTotalAmount])
503- let investorRemainingAmount = parseIntValue(origInvestArray[IdxInvRemainingAmount])
504- let investorPriceAssetBalance = parseIntValue(origInvestArray[IdxInvClaimedPriceAssetAmount])
505- let investorIdoAssetBalance = parseIntValue(origInvestArray[IdxInvClaimedIdoAssetAmount])
506- let investorLastClaimedHeight = parseIntValue(origInvestArray[IdxInvLastClaimedHeight])
507- let newInvestArray = [toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString(investorIdoAssetBalance), toString(investorLastClaimedHeight)]
508- let totals = readTotalsArrayOrDefault()
509- let totalsTotalAmount = parseIntValue(totals[IdxInvTotalAmount])
510- let totalsRemainingAmount = parseIntValue(totals[IdxInvRemainingAmount])
511- let totalsClaimedPriceAssetAmount = parseIntValue(totals[IdxInvRemainingAmount])
512- let totalsClaimedIdoAssetAmount = parseIntValue(totals[IdxInvClaimedPriceAssetAmount])
513- let totalsLastClaimedHeight = parseIntValue(totals[IdxInvLastClaimedHeight])
514- let newTotalsRemainingAmount = (totalsRemainingAmount - investorRemainingAmount)
515- let newTotalArray = [toString(totalsTotalAmount), toString(newTotalsRemainingAmount), toString(totalsClaimedPriceAssetAmount), toString(totalsClaimedIdoAssetAmount), toString(totalsLastClaimedHeight)]
516- let newTotalRemainingAmount = (valueOrElse(getInteger(keyTotalRemainingAmount()), 0) + investorRemainingAmount)
517-[StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), TotalsEntry(keyInvestor(userAddress58), newInvestArray, totalsDiff, newClaimPeriodHeight, 0), TotalsEntry(keyTotals(), newTotalArray, totalsDiff, newClaimPeriodHeight, 0)]
518- }
516+ then [StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), TotalsEntry(keyInvestor(userAddress58), newInvestArray, totalsDiff, newClaimPeriodHeight, 0), TotalsEntry(keyTotals(), newTotalArray, totalsDiff, newClaimPeriodHeight, 0)]
519517 else [TotalsEntry(keyInvestor(userAddress58), origInvestArray, totalsDiff, newClaimPeriodHeight, 0), TotalsEntry(keyTotals(), readTotalsArrayOrDefault(), totalsDiff, newClaimPeriodHeight, 0)]
520518 let updatedPriceAssetBalance = ((priceAssetBalance + outAmount) - periodMinAvailableToClaim)
521519 ([ScriptTransfer(i.caller, periodMinAvailableToClaim, outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), updatedPriceAssetBalance)] ++ lastClaimEntries)
522520 }
523- else throw("Strict value is not equal to itself.")
521+ $Tuple2(([IntegerEntry(keyCurrentPeriod(), updatedCurrentPeriod), IntegerEntry(keyPeriodStartHeight(updatedCurrentPeriod), periodStart), IntegerEntry(keyPeriodEndHeight(updatedCurrentPeriod), periodEnd), IntegerEntry(keyPeriodTotalAvailableToClaim(priceAssetId58, updatedCurrentPeriod), updatedPeriodTotalAvailableToClaim), IntegerEntry(keyPeriodUserAvailableToClaim(priceAssetId58, updatedCurrentPeriod, userAddress58), updatedPeriodUserAvailableToClaim), ClaimOperationHistoryEntry(userAddress58, periodMinAvailableToClaim, claimedIdoAssetAmountFromDiff, i.transactionId)] ++ entries), unit)
524522 }
525- $Tuple2(([IntegerEntry(keyCurrentPeriod(), updatedCurrentPeriod), IntegerEntry(keyPeriodStartHeight(updatedCurrentPeriod), periodStart), IntegerEntry(keyPeriodEndHeight(updatedCurrentPeriod), periodEnd), IntegerEntry(keyPeriodTotalAvailableToClaim(priceAssetId58, updatedCurrentPeriod), updatedPeriodTotalAvailableToClaim), IntegerEntry(keyPeriodUserAvailableToClaim(priceAssetId58, updatedCurrentPeriod, userAddress58), updatedPeriodUserAvailableToClaim), ClaimOperationHistoryEntry(userAddress58, periodMinAvailableToClaim, claimedIdoAssetAmountFromDiff, i.transactionId)] ++ entries), unit)
523+ else throw("Strict value is not equal to itself.")
524+ }
525+ else {
526+ let priceAssetBalanceIdoDecimals = fraction(priceAssetBalance, scale8, pow(10, 0, priceAssetDecimals, 0, 0, DOWN))
527+ $Tuple2([StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), ScriptTransfer(i.caller, (outAmount + priceAssetBalanceIdoDecimals), outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), 0), TotalsEntry(keyInvestor(userAddress58), newInvestArray, totalsDiff, newClaimPeriodHeight, priceAssetBalance), TotalsEntry(keyTotals(), newTotalArray, totalsDiff, newClaimPeriodHeight, priceAssetBalance), ClaimOperationHistoryEntry(userAddress58, claimedPriceAmountFromDiff, (claimedIdoAssetAmountFromDiff + priceAssetBalanceIdoDecimals), i.transactionId)], unit)
528+ }
529+ entries
530+ }
531+ else throw("Strict value is not equal to itself.")
532+ }
533+ }
534+
535+
536+
537+@Callable(i)
538+func cleanRemaingAmount (userAddress58) = {
539+ let priceAssetId58 = readConfigArray()[IdxCfgPriceAssetId]
540+ let evaluateResult = split(asString(invoke(this, "claimREADONLY", [priceAssetId58, userAddress58], nil)), SEP)
541+ if ((evaluateResult == evaluateResult))
542+ then {
543+ let availablePriceAmountToClaim = parseIntValue(evaluateResult[2])
544+ let checkUnclaimedAssets = if ((availablePriceAmountToClaim == 0))
545+ then true
546+ else throwErr("user have unclaimed assets")
547+ if ((checkUnclaimedAssets == checkUnclaimedAssets))
548+ then {
549+ let investor = split(value(getString(keyInvestor(userAddress58))), SEP)
550+ let investorTotalAmount = parseIntValue(investor[IdxInvTotalAmount])
551+ let investorRemainingAmount = parseIntValue(investor[IdxInvRemainingAmount])
552+ let investorPriceAssetBalance = parseIntValue(investor[IdxInvClaimedPriceAssetAmount])
553+ let investorIdoAssetBalance = parseIntValue(investor[IdxInvClaimedIdoAssetAmount])
554+ let investorLastClaimedHeight = parseIntValue(investor[IdxInvLastClaimedHeight])
555+ let investorRemainingAmountCheck = if ((investorRemainingAmount != 0))
556+ then true
557+ else throwErr("investorRemainingAmount already zero")
558+ if ((investorRemainingAmountCheck == investorRemainingAmountCheck))
559+ then {
560+ let newInvestor = makeString(["%d%d%d%d%d", toString(investorTotalAmount), "0", toString(investorPriceAssetBalance), toString(investorIdoAssetBalance), toString(investorLastClaimedHeight)], SEP)
561+ let totals = split(value(getString(keyTotals())), SEP)
562+ let totalsTotalAmount = parseIntValue(totals[IdxInvTotalAmount])
563+ let totalsRemainingAmount = parseIntValue(totals[IdxInvRemainingAmount])
564+ let totalsClaimedPriceAssetAmount = parseIntValue(totals[IdxInvClaimedPriceAssetAmount])
565+ let totalsClaimedIdoAssetAmount = parseIntValue(totals[IdxInvClaimedIdoAssetAmount])
566+ let totalsLastClaimedHeight = parseIntValue(totals[IdxInvLastClaimedHeight])
567+ let newTotals = makeString(["%d%d%d%d%d", toString(totalsTotalAmount), toString((totalsRemainingAmount - investorRemainingAmount)), toString(totalsClaimedPriceAssetAmount), toString(totalsClaimedIdoAssetAmount), toString(totalsLastClaimedHeight)], SEP)
568+ let newTotalRemainingAmount = (valueOrElse(getInteger(keyTotalRemainingAmount()), 0) + investorRemainingAmount)
569+[StringEntry(keyInvestorRemainingAmount(userAddress58), toString(investorRemainingAmount)), StringEntry(keyTotalRemainingAmount(), toString(newTotalRemainingAmount)), StringEntry(keyInvestor(userAddress58), newInvestor), StringEntry(keyTotals(), newTotals)]
526570 }
527571 else throw("Strict value is not equal to itself.")
528572 }
529- else {
530- let priceAssetBalanceIdoDecimals = fraction(priceAssetBalance, scale8, pow(10, 0, priceAssetDecimals, 0, 0, DOWN))
531- $Tuple2([ScriptTransfer(i.caller, (outAmount + priceAssetBalanceIdoDecimals), outAssetId), IntegerEntry(keyPriceAssetBalance(userAddress58), 0), TotalsEntry(keyInvestor(userAddress58), origInvestArray, totalsDiff, newClaimPeriodHeight, priceAssetBalance), TotalsEntry(keyTotals(), readTotalsArrayOrDefault(), totalsDiff, newClaimPeriodHeight, priceAssetBalance), ClaimOperationHistoryEntry(userAddress58, claimedPriceAmountFromDiff, (claimedIdoAssetAmountFromDiff + priceAssetBalanceIdoDecimals), i.transactionId)], unit)
532- }
533- entries
573+ else throw("Strict value is not equal to itself.")
534574 }
575+ else throw("Strict value is not equal to itself.")
535576 }
536577
537578
538579
539580 @Callable(i)
540581 func claimREADONLY (claimedAssetId58,userAddress58) = {
541582 let claimResultTuple = internalClaim(claimedAssetId58, addressFromStringValue(userAddress58), fromBase58String(""))
542583 let totalsDiff = claimResultTuple._1
543584 let outAmount = claimResultTuple._2
544585 let outAssetId = claimResultTuple._3
545586 let origInvestArray = claimResultTuple._4
546587 let newClaimPeriodHeight = claimResultTuple._5
547588 let availableToClaimArray = claimResultTuple._6
548589 let availablePriceAmountToClaim = availableToClaimArray[0]
549590 let availableIdoAmountToClaim = availableToClaimArray[1]
550591 $Tuple2(nil, makeString(["%s%d%d", userAddress58, toString(availablePriceAmountToClaim), toString(availableIdoAmountToClaim)], SEP))
551592 }
552593
553594
554595
555596 @Callable(i)
556597 func claimV2READONLY (claimedAssetId58,userAddress58) = {
557598 let claimResultTuple = internalClaim(claimedAssetId58, addressFromStringValue(userAddress58), fromBase58String(""))
558599 let totalsDiff = claimResultTuple._1
559600 let outAmount = claimResultTuple._2
560601 let outAssetId = claimResultTuple._3
561602 let origInvestArray = claimResultTuple._4
562603 let newClaimPeriodHeight = claimResultTuple._5
563604 let availableToClaimArray = claimResultTuple._6
564605 let availablePriceAmountToClaim = availableToClaimArray[0]
565606 let availableIdoAmountToClaim = availableToClaimArray[1]
566607 let cfgArray = readConfigArray()
567608 let priceAssetId58 = cfgArray[IdxCfgPriceAssetId]
568609 let priceAssetBalance = valueOrElse(getInteger(keyPriceAssetBalance(userAddress58)), 0)
569610 let priceAssetBalanceIdoDecimals = (priceAssetBalance * 100)
570611 let availableIdoAmountToClaimWithPriceAssetBalance = (availableIdoAmountToClaim + priceAssetBalanceIdoDecimals)
571- let $t03128231694 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
572- let periodMinAvailableToClaim = $t03128231694._1
573- let periodTotalAvailableToClaim = $t03128231694._2
574- let periodUserAvailableToClaim = $t03128231694._3
575- let totalUserAvailableToClaim = $t03128231694._4
576- let usdtPriceAssetAllowableRatio = $t03128231694._5
577- let currentUsdtPriceAssetRatio = $t03128231694._6
578- let endPeriodBlocksLeft = $t03128231694._7
579- let updatedCurrentPeriod = $t03128231694._8
580- let periodStart = $t03128231694._9
581- let periodEnd = $t03128231694._10
612+ let $t03370134113 = internalClaimV2(priceAssetId58, userAddress58, outAmount, totalsDiff[IdxDiffClaimedPriceAmountIncrement])
613+ let periodMinAvailableToClaim = $t03370134113._1
614+ let periodTotalAvailableToClaim = $t03370134113._2
615+ let periodUserAvailableToClaim = $t03370134113._3
616+ let totalUserAvailableToClaim = $t03370134113._4
617+ let usdtPriceAssetAllowableRatio = $t03370134113._5
618+ let currentUsdtPriceAssetRatio = $t03370134113._6
619+ let endPeriodBlocksLeft = $t03370134113._7
620+ let updatedCurrentPeriod = $t03370134113._8
621+ let periodStart = $t03370134113._9
622+ let periodEnd = $t03370134113._10
582623 let currentPeriodEndHeight = valueOrElse(getInteger(keyPeriodEndHeight(updatedCurrentPeriod)), 0)
583624 let userTotalPriceAssetClaimed = (parseIntValue(readInvestorArrayOrFail(userAddress58)[IdxInvClaimedPriceAssetAmount]) - priceAssetBalance)
584625 let resultString = if ((height > currentPeriodEndHeight))
585626 then {
586627 let periodLenght = value(getInteger(keyPeriodLength()))
587628 let userPeriodAllowance = value(getInteger(keyUserPeriodAllowance(priceAssetId58)))
588629 let totalPeriodAllowance = value(getInteger(keyTotalPeriodAllowance(priceAssetId58)))
589630 makeString(["%d%d%d%d%d%d", toString(availableIdoAmountToClaimWithPriceAssetBalance), toString(userPeriodAllowance), toString(totalPeriodAllowance), toString(usdtPriceAssetAllowableRatio), toString(currentUsdtPriceAssetRatio), toString(periodLenght), toString(userTotalPriceAssetClaimed)], SEP)
590631 }
591632 else makeString(["%d%d%d%d%d%d", toString(availableIdoAmountToClaimWithPriceAssetBalance), toString(periodMinAvailableToClaim), toString(periodTotalAvailableToClaim), toString(usdtPriceAssetAllowableRatio), toString(currentUsdtPriceAssetRatio), toString(endPeriodBlocksLeft), toString(userTotalPriceAssetClaimed)], SEP)
592633 $Tuple2(nil, resultString)
593634 }
594635
595636
596637
597638 @Callable(i)
598639 func setManager (pendingManagerPublicKey) = {
599640 let checkCaller = mustManager(i)
600641 if ((checkCaller == checkCaller))
601642 then {
602643 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
603644 if ((checkManagerPublicKey == checkManagerPublicKey))
604645 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
605646 else throw("Strict value is not equal to itself.")
606647 }
607648 else throw("Strict value is not equal to itself.")
608649 }
609650
610651
611652
612653 @Callable(i)
613654 func confirmManager () = {
614655 let pm = pendingManagerPublicKeyOrUnit()
615656 let hasPM = if (isDefined(pm))
616657 then true
617658 else throw("No pending manager")
618659 if ((hasPM == hasPM))
619660 then {
620661 let checkPM = if ((i.callerPublicKey == value(pm)))
621662 then true
622663 else throw("You are not pending manager")
623664 if ((checkPM == checkPM))
624665 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
625666 else throw("Strict value is not equal to itself.")
626667 }
627668 else throw("Strict value is not equal to itself.")
628669 }
629670
630671
631672 @Verifier(tx)
632673 func verify () = {
633674 let targetPublicKey = match managerPublicKeyOrUnit() {
634675 case pk: ByteVector =>
635676 pk
636677 case _: Unit =>
637678 tx.senderPublicKey
638679 case _ =>
639680 throw("Match error")
640681 }
641682 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
642683 }
643684

github/deemru/w8io/026f985 
86.11 ms