tx · PgAt8ZTB54Va2DyYPDnsX3TuK8ZfCa1xgqVCcgVRfhp

3N4yYqBkTUq1mDdHhvAd3St7spCbm84DytS:  -0.02200000 Waves

2023.11.29 11:55 [2864480] smart account 3N4yYqBkTUq1mDdHhvAd3St7spCbm84DytS > SELF 0.00000000 Waves

{ "type": 13, "id": "PgAt8ZTB54Va2DyYPDnsX3TuK8ZfCa1xgqVCcgVRfhp", "fee": 2200000, "feeAssetId": null, "timestamp": 1701248213750, "version": 1, "sender": "3N4yYqBkTUq1mDdHhvAd3St7spCbm84DytS", "senderPublicKey": "8h7G4haeVwXKNHXNHsWkC1miUp5CQtk3WmpBKazQPxRh", "proofs": [ "57nFFtAkjRoSUsdi4vJgaojH6VdHeS84C1cvgtRjk2dLk9wsmvcnBrtL4MB6ew6LTXF1peWrgMwoVHWiLZNgee9s" ], "script": "base64:BgI0CAISAwoBARIDCgEBEgASAwoBCBIDCgEBEgMKAQgSAwoBCBIECgIYERIDCgEIEgASAwoBCEAADGNvbnRyYWN0RmlsZQIRbDJtcF9zdGFraW5nLnJpZGUAA1NFUAICX18ABnNjYWxlOACAwtcvAAdzY2FsZTE4AICAkLu61q3wDQANc2NhbGUxOEJpZ0ludAkAtgIBBQdzY2FsZTE4ABJBRERSRVNTX0JZVEVTX1NJWkUAGgANQkxPQ0tTX0lOX0RBWQCgCwEIdGhyb3dFcnIBA21zZwkAAgEJAKwCAgkArAICBQxjb250cmFjdEZpbGUCAjogBQNtc2cACmtleUFzc2V0SWQJALkJAgkAzAgCAgIlcwkAzAgCAgdhc3NldElkBQNuaWwFA1NFUAATa2V5RW1pc3Npb25QZXJCbG9jawkAuQkCCQDMCAICAiVzCQDMCAICEGVtaXNzaW9uUGVyQmxvY2sFA25pbAUDU0VQABlrZXlFbWlzc2lvblBlcmlvZEluQmxvY2tzCQC5CQIJAMwIAgICJXMJAMwIAgIWZW1pc3Npb25QZXJpb2RJbkJsb2NrcwUDbmlsBQNTRVAADWtleVN0YXJ0QmxvY2sJALkJAgkAzAgCAgIlcwkAzAgCAgpzdGFydEJsb2NrBQNuaWwFA1NFUAAQa2V5VG90YWxMcEFtb3VudAkAuQkCCQDMCAICAiVzCQDMCAICDXRvdGFsTHBBbW91bnQFA25pbAUDU0VQABNrZXlUb3RhbEFzc2V0QW1vdW50CQC5CQIJAMwIAgICJXMJAMwIAgIQdG90YWxBc3NldEFtb3VudAUDbmlsBQNTRVAAFmtleVRvdGFsTG9ja2VkTHBBbW91bnQJALkJAgkAzAgCAgIlcwkAzAgCAhN0b3RhbExvY2tlZExwQW1vdW50BQNuaWwFA1NFUAEPa2V5VXNlckxwQW1vdW50AQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIMdXNlckxwQW1vdW50CQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAEVa2V5VXNlckxvY2tlZExwQW1vdW50AQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgISdXNlckxvY2tlZExwQW1vdW50CQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAETa2V5VXNlclN0YWtpbmdOb2RlcwELdXNlckFkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAICEHVzZXJTdGFraW5nTm9kZXMJAMwIAgULdXNlckFkZHJlc3MFA25pbAUDU0VQARlrZXlVc2VyU3Rha2luZ05vZGVzU2hhcmVzAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIWdXNlclN0YWtpbmdOb2Rlc1NoYXJlcwkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABGmtleVVzZXJUb3RhbEFzc2V0V2l0aGRyYXduAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgITdG90YWxBc3NldFdpdGhkcmF3bgkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABF2tleVVzZXJUb3RhbEFzc2V0U3Rha2VkAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIQdG90YWxBc3NldFN0YWtlZAkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABCmtleUhpc3RvcnkDBHR5cGULdXNlckFkZHJlc3MEdHhJZAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCBQR0eXBlCQDMCAIFC3VzZXJBZGRyZXNzCQDMCAIJANgEAQUEdHhJZAUDbmlsBQNTRVABDWZvcm1hdEhpc3RvcnkEC3RvdGFsUHJvZml0BXByaWNlEHRvdGFsQXNzZXRBbW91bnQNdG90YWxMcEFtb3VudAkAuQkCCQDMCAICCCVkJWQlZCVkCQDMCAIJAKQDAQULdG90YWxQcm9maXQJAMwIAgkApgMBBQVwcmljZQkAzAgCCQCkAwEFEHRvdGFsQXNzZXRBbW91bnQJAMwIAgkApAMBBQ10b3RhbExwQW1vdW50BQNuaWwFA1NFUAANdG90YWxMcEFtb3VudAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRBrZXlUb3RhbExwQW1vdW50AAAAEHRvdGFsQXNzZXRBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUTa2V5VG90YWxBc3NldEFtb3VudAAAABN0b3RhbExvY2tlZExwQW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFFmtleVRvdGFsTG9ja2VkTHBBbW91bnQAAAANYXNzZXRJZFN0cmluZwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQprZXlBc3NldElkAgVXQVZFUwAMYXNzZXRJZEJ5dGVzAwkAAAIFDWFzc2V0SWRTdHJpbmcCBVdBVkVTBQR1bml0CQDZBAEFDWFzc2V0SWRTdHJpbmcAFmVtaXNzaW9uUGVyaW9kSW5CbG9ja3MJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUZa2V5RW1pc3Npb25QZXJpb2RJbkJsb2NrcwUNQkxPQ0tTX0lOX0RBWQAQZW1pc3Npb25QZXJCbG9jawkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRNrZXlFbWlzc2lvblBlckJsb2NrAAAAEWVtaXNzaW9uUGVyUGVyaW9kCQBoAgUQZW1pc3Npb25QZXJCbG9jawUWZW1pc3Npb25QZXJpb2RJbkJsb2NrcwAPQURNSU5fTElTVF9TSVpFAAUABlFVT1JVTQADABFUWElEX0JZVEVTX0xFTkdUSAAgARhrZXlBbGxvd2VkVHhJZFZvdGVQcmVmaXgBBHR4SWQJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIJYWxsb3dUeElkCQDMCAIFBHR4SWQFA25pbAUDU0VQARBrZXlGdWxsQWRtaW5Wb3RlAgZwcmVmaXgMYWRtaW5BZGRyZXNzCQC5CQIJAMwIAgUGcHJlZml4CQDMCAIFDGFkbWluQWRkcmVzcwUDbmlsBQNTRVABE2tleUFkbWluQWRkcmVzc0xpc3QACQC5CQIJAMwIAgICJXMJAMwIAgIQYWRtaW5BZGRyZXNzTGlzdAUDbmlsBQNTRVABDmtleUFsbG93ZWRUeElkAAkAuQkCCQDMCAICAiVzCQDMCAICBHR4SWQFA25pbAUDU0VQAQxnZXRBZG1pblZvdGUCBnByZWZpeAVhZG1pbgQHdm90ZUtleQkBEGtleUZ1bGxBZG1pblZvdGUCBQZwcmVmaXgFBWFkbWluCQELdmFsdWVPckVsc2UCCQCfCAEFB3ZvdGVLZXkAAAENZ2V0QWRtaW5zTGlzdAAEByRtYXRjaDAJAJ0IAgUEdGhpcwkBE2tleUFkbWluQWRkcmVzc0xpc3QAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkAtQkCBQFzBQNTRVAFA25pbAENaXNJbkFkbWluTGlzdAEHYWRkcmVzcwkBD2NvbnRhaW5zRWxlbWVudAIJAQ1nZXRBZG1pbnNMaXN0AAUHYWRkcmVzcwESZ2VuVm90ZXNLZXlzSGVscGVyAgFhDGFkbWluQWRkcmVzcwQLJHQwMzU5NTM2MTkFAWEEBnJlc3VsdAgFCyR0MDM1OTUzNjE5Al8xBAZwcmVmaXgIBQskdDAzNTk1MzYxOQJfMgkAlAoCCQDNCAIFBnJlc3VsdAkBEGtleUZ1bGxBZG1pblZvdGUCBQZwcmVmaXgFDGFkbWluQWRkcmVzcwUGcHJlZml4AQxnZW5Wb3Rlc0tleXMBCWtleVByZWZpeAQJYWRtaW5MaXN0CQETa2V5QWRtaW5BZGRyZXNzTGlzdAAECyR0MDM3NjYzODUwCgACJGwJAQ1nZXRBZG1pbnNMaXN0AAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsBQlrZXlQcmVmaXgKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEmdlblZvdGVzS2V5c0hlbHBlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUEBnJlc3VsdAgFCyR0MDM3NjYzODUwAl8xBAZwcmVmaXgIBQskdDAzNzY2Mzg1MAJfMgUGcmVzdWx0ARBjb3VudFZvdGVzSGVscGVyAgZyZXN1bHQHdm90ZUtleQkAZAIFBnJlc3VsdAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQd2b3RlS2V5AAABCmNvdW50Vm90ZXMBBnByZWZpeAQFdm90ZXMJAQxnZW5Wb3Rlc0tleXMBBQZwcmVmaXgKAAIkbAUFdm90ZXMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEGNvdW50Vm90ZXNIZWxwZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDUJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFARBjbGVhclZvdGVzSGVscGVyAgZyZXN1bHQDa2V5CQDNCAIFBnJlc3VsdAkBC0RlbGV0ZUVudHJ5AQUDa2V5ARNnZXRDbGVhclZvdGVFbnRyaWVzAQZwcmVmaXgEBXZvdGVzCQEMZ2VuVm90ZXNLZXlzAQUGcHJlZml4CgACJGwFBXZvdGVzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARBjbGVhclZvdGVzSGVscGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQEMdm90ZUlOVEVSTkFMBBNjYWxsZXJBZGRyZXNzU3RyaW5nCWtleVByZWZpeAhtaW5Wb3Rlcwp2b3RlUmVzdWx0BAd2b3RlS2V5CQEQa2V5RnVsbEFkbWluVm90ZQIFCWtleVByZWZpeAUTY2FsbGVyQWRkcmVzc1N0cmluZwQQYWRtaW5DdXJyZW50Vm90ZQkBDGdldEFkbWluVm90ZQIFCWtleVByZWZpeAUTY2FsbGVyQWRkcmVzc1N0cmluZwQDZXJyAwkBASEBCQENaXNJbkFkbWluTGlzdAEFE2NhbGxlckFkZHJlc3NTdHJpbmcJAQh0aHJvd0VycgEJAKwCAgkArAICAglBZGRyZXNzOiAFE2NhbGxlckFkZHJlc3NTdHJpbmcCEiBub3QgaW4gQWRtaW4gbGlzdAMJAAACBRBhZG1pbkN1cnJlbnRWb3RlAAEJAQh0aHJvd0VycgEJAKwCAgUHdm90ZUtleQISIHlvdSBhbHJlYWR5IHZvdGVkBQR1bml0AwkAAAIFA2VycgUDZXJyBAV2b3RlcwkBCmNvdW50Vm90ZXMBBQlrZXlQcmVmaXgDCQBnAgkAZAIFBXZvdGVzAAEFCG1pblZvdGVzBBBjbGVhclZvdGVFbnRyaWVzCQETZ2V0Q2xlYXJWb3RlRW50cmllcwEFCWtleVByZWZpeAkAzggCBRBjbGVhclZvdGVFbnRyaWVzBQp2b3RlUmVzdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQd2b3RlS2V5AAEFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEZc3RyaW5nTGlzdFRvSW50TGlzdEhlbHBlcgIDYWNjBXZhbHVlCQDNCAIFA2FjYwkBDXBhcnNlSW50VmFsdWUBBQV2YWx1ZQEYY2FsY1RvdGFsUHJvZml0Rm9ySGVpZ2h0AQFoBApzdGFydEJsb2NrCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFDWtleVN0YXJ0QmxvY2sFBmhlaWdodAQLc3RhcnRQZXJpb2QJAGsDBQpzdGFydEJsb2NrAAEFFmVtaXNzaW9uUGVyaW9kSW5CbG9ja3MEDmVsYXBzZWRQZXJpb2RzCQBlAgkAaQIFAWgFFmVtaXNzaW9uUGVyaW9kSW5CbG9ja3MFC3N0YXJ0UGVyaW9kCQCWAwEJAMwIAgAACQDMCAIJAGgCBRFlbWlzc2lvblBlclBlcmlvZAUOZWxhcHNlZFBlcmlvZHMFA25pbAEPY2FsY1RvdGFsUHJvZml0AAkBGGNhbGNUb3RhbFByb2ZpdEZvckhlaWdodAEFBmhlaWdodAEUZ2V0TWF4QXNzZXRBdmFpbGFibGUABAckbWF0Y2gwBQxhc3NldElkQnl0ZXMDCQABAgUHJG1hdGNoMAIEVW5pdAQBdQUHJG1hdGNoMAgJAO8HAQUEdGhpcwlhdmFpbGFibGUDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQBYgUHJG1hdGNoMAkA8AcCBQR0aGlzBQFiCQACAQILTWF0Y2ggZXJyb3IBK2dldFRvdGFsQXNzZXRBbW91bnRXaXRoUHJvZml0T3JNYXhBdmFpbGFibGUABBp0b3RhbEFzc2V0QW1vdW50V2l0aFByb2ZpdAkAZAIFEHRvdGFsQXNzZXRBbW91bnQJAQ9jYWxjVG90YWxQcm9maXQABAt0b3RhbEFtb3VudAkAlwMBCQDMCAIFGnRvdGFsQXNzZXRBbW91bnRXaXRoUHJvZml0CQDMCAIJARRnZXRNYXhBc3NldEF2YWlsYWJsZQAFA25pbAMJAAACBQ10b3RhbExwQW1vdW50AAAAAAULdG90YWxBbW91bnQBD2dldEN1cnJlbnRQcmljZQADCQECIT0CBQ10b3RhbExwQW1vdW50AAAJALwCAwkAtgIBCQErZ2V0VG90YWxBc3NldEFtb3VudFdpdGhQcm9maXRPck1heEF2YWlsYWJsZQAFDXNjYWxlMThCaWdJbnQJALYCAQUNdG90YWxMcEFtb3VudAUNc2NhbGUxOEJpZ0ludAESZ2V0UmVtYWluaW5nQmxvY2tzAAMJAAACBRBlbWlzc2lvblBlckJsb2NrAAAAAAkAawMJAGUCCQEUZ2V0TWF4QXNzZXRBdmFpbGFibGUACQErZ2V0VG90YWxBc3NldEFtb3VudFdpdGhQcm9maXRPck1heEF2YWlsYWJsZQAAAQUQZW1pc3Npb25QZXJCbG9jawEXZ2V0VXNlclN0YWtpbmdOb2Rlc0RhdGEBC3VzZXJBZGRyZXNzBAhub2Rlc1JhdwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQETa2V5VXNlclN0YWtpbmdOb2RlcwEFC3VzZXJBZGRyZXNzAgAECXNoYXJlc1JhdwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzCQEZa2V5VXNlclN0YWtpbmdOb2Rlc1NoYXJlcwEFC3VzZXJBZGRyZXNzAgAECW5vZGVzTGlzdAMJAAACBQhub2Rlc1JhdwIABQNuaWwJALUJAgUIbm9kZXNSYXcFA1NFUAQQc2hhcmVzU3RyaW5nTGlzdAMJAAACBQlzaGFyZXNSYXcCAAUDbmlsCQC1CQIFCXNoYXJlc1JhdwUDU0VQBApzaGFyZXNMaXN0CgACJGwFEHNoYXJlc1N0cmluZ0xpc3QKAAIkcwkAkAMBBQIkbAoABSRhY2MwBQNuaWwKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBGXN0cmluZ0xpc3RUb0ludExpc3RIZWxwZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECFExpc3Qgc2l6ZSBleGNlZWRzIDIwCQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQAGAAcACAAJAAoACwAMAA0ADgAPABAAEQASABMAFAkAlAoCBQlub2Rlc0xpc3QFCnNoYXJlc0xpc3QBD2NhbGNBc3NldEZyb21McAEIbHBBbW91bnQJAJYDAQkAzAgCAAAJAMwIAgkAoAMBCQC8AgMJALYCAQUIbHBBbW91bnQJAQ9nZXRDdXJyZW50UHJpY2UABQ1zY2FsZTE4QmlnSW50BQNuaWwBD2NhbGNMcEZyb21Bc3NldAELYXNzZXRBbW91bnQJAJYDAQkAzAgCAAAJAMwIAgkAoAMBCQC8AgMJALYCAQULYXNzZXRBbW91bnQFDXNjYWxlMThCaWdJbnQJAQ9nZXRDdXJyZW50UHJpY2UABQNuaWwBD2dldFVzZXJMcEFtb3VudAELdXNlckFkZHJlc3MJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBD2tleVVzZXJMcEFtb3VudAEFC3VzZXJBZGRyZXNzAAABFWdldFVzZXJMb2NrZWRMcEFtb3VudAELdXNlckFkZHJlc3MJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBFWtleVVzZXJMb2NrZWRMcEFtb3VudAEFC3VzZXJBZGRyZXNzAAABIGdldFVzZXJBdmFpbGFibGVBc3NldHNUb1dpdGhkcmF3AQt1c2VyQWRkcmVzcwQMdXNlckxwQW1vdW50CQEPZ2V0VXNlckxwQW1vdW50AQULdXNlckFkZHJlc3MJAQ9jYWxjQXNzZXRGcm9tTHABBQx1c2VyTHBBbW91bnQBD2dldFN0YWtlQWN0aW9ucwIBaQt1c2VyQWRkcmVzcwQGY2hlY2tzCQDMCAIDCQAAAgkAkAMBCAUBaQhwYXltZW50cwABBgkBCHRocm93RXJyAQIYc2hvdWxkIGluY2x1ZGUgMSBwYXltZW50CQDMCAIDCQAAAggJAJEDAggFAWkIcGF5bWVudHMAAAdhc3NldElkBQxhc3NldElkQnl0ZXMGCQEIdGhyb3dFcnIBCQCsAgICFXBheW1lbnQgc2hvdWxkIGJlIGluIAUNYXNzZXRJZFN0cmluZwkAzAgCAwkAZgIICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50AAAGAidwYXltZW50IGFtb3VudCBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIDAJAMwIAgMJAAACCQDIAQEJANkEAQULdXNlckFkZHJlc3MFEkFERFJFU1NfQllURVNfU0laRQYJAQh0aHJvd0VycgECGXVzZXIgYWRkcmVzcyBpcyBub3QgdmFsaWQFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwQNcGF5bWVudEFtb3VudAgJAJEDAggFAWkIcGF5bWVudHMAAAZhbW91bnQED3BheW1lbnRMcEFtb3VudAkAoAMBCQC8AgMJALYCAQUNcGF5bWVudEFtb3VudAUNc2NhbGUxOEJpZ0ludAkBD2dldEN1cnJlbnRQcmljZQAEDHVzZXJMcEFtb3VudAkBD2dldFVzZXJMcEFtb3VudAEFC3VzZXJBZGRyZXNzBBV1c2VyVG90YWxTdGFrZWRBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBF2tleVVzZXJUb3RhbEFzc2V0U3Rha2VkAQULdXNlckFkZHJlc3MAAAQQbmV3VG90YWxMcEFtb3VudAkAZAIFDXRvdGFsTHBBbW91bnQFD3BheW1lbnRMcEFtb3VudAQTbmV3VG90YWxBc3NldEFtb3VudAkAoAMBCQC8AgMJALYCAQUQbmV3VG90YWxMcEFtb3VudAkBD2dldEN1cnJlbnRQcmljZQAFDXNjYWxlMThCaWdJbnQED25ld1VzZXJMcEFtb3VudAkAZAIFDHVzZXJMcEFtb3VudAUPcGF5bWVudExwQW1vdW50BBhuZXdVc2VyVG90YWxTdGFrZWRBbW91bnQJAGQCBRV1c2VyVG90YWxTdGFrZWRBbW91bnQFDXBheW1lbnRBbW91bnQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBCmtleUhpc3RvcnkDAgVzdGFrZQULdXNlckFkZHJlc3MIBQFpDXRyYW5zYWN0aW9uSWQJAQ1mb3JtYXRIaXN0b3J5BAkBD2NhbGNUb3RhbFByb2ZpdAAJAQ9nZXRDdXJyZW50UHJpY2UABQ10b3RhbExwQW1vdW50BRB0b3RhbEFzc2V0QW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRBrZXlUb3RhbExwQW1vdW50BRBuZXdUb3RhbExwQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRNrZXlUb3RhbEFzc2V0QW1vdW50BRNuZXdUb3RhbEFzc2V0QW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEPa2V5VXNlckxwQW1vdW50AQULdXNlckFkZHJlc3MFD25ld1VzZXJMcEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBF2tleVVzZXJUb3RhbEFzc2V0U3Rha2VkAQULdXNlckFkZHJlc3MFGG5ld1VzZXJUb3RhbFN0YWtlZEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUNa2V5U3RhcnRCbG9jawUGaGVpZ2h0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BEmdldFdpdGhkcmF3QWN0aW9ucwIBaRVscEFzc2V0V2l0aGRyYXdBbW91bnQEC3VzZXJBZGRyZXNzCQClCAEIBQFpBmNhbGxlcgQMdXNlckxwQW1vdW50CQEPZ2V0VXNlckxwQW1vdW50AQULdXNlckFkZHJlc3MEBWNoZWNrCQDMCAIDCQBmAgUVbHBBc3NldFdpdGhkcmF3QW1vdW50AAAGCQEIdGhyb3dFcnIBAh9MUCBhbW91bnQgc2hvdWxkIGJlIG1vcmUgdGhhbiAwCQDMCAIDCQBnAgUMdXNlckxwQW1vdW50BRVscEFzc2V0V2l0aGRyYXdBbW91bnQGCQEIdGhyb3dFcnIBCQCsAgIJAKwCAgIoY2Fubm90IHdpdGhkcmF3IG1vcmUgdGhhbiBhdmFpbGFibGUgTFAgKAkApAMBBQx1c2VyTHBBbW91bnQCASkFA25pbAMJAAACBQVjaGVjawUFY2hlY2sED25ld1VzZXJMcEFtb3VudAkAZQIFDHVzZXJMcEFtb3VudAUVbHBBc3NldFdpdGhkcmF3QW1vdW50BBN3aXRoZHJhd0Fzc2V0QW1vdW50CQCgAwEJALwCAwkAtgIBBRVscEFzc2V0V2l0aGRyYXdBbW91bnQJAQ9nZXRDdXJyZW50UHJpY2UABQ1zY2FsZTE4QmlnSW50BBBuZXdUb3RhbExwQW1vdW50CQBlAgUNdG90YWxMcEFtb3VudAUVbHBBc3NldFdpdGhkcmF3QW1vdW50BBNuZXdUb3RhbEFzc2V0QW1vdW50CQCgAwEJALwCAwkAtgIBBRBuZXdUb3RhbExwQW1vdW50CQEPZ2V0Q3VycmVudFByaWNlAAUNc2NhbGUxOEJpZ0ludAQXdXNlclRvdGFsQXNzZXRXaXRoZHJhd24JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBGmtleVVzZXJUb3RhbEFzc2V0V2l0aGRyYXduAQULdXNlckFkZHJlc3MAAAQabmV3VXNlclRvdGFsQXNzZXRXaXRoZHJhd24JAGQCBRd1c2VyVG90YWxBc3NldFdpdGhkcmF3bgUTd2l0aGRyYXdBc3NldEFtb3VudAkAzAgCCQELU3RyaW5nRW50cnkCCQEKa2V5SGlzdG9yeQMCCHdpdGhkcmF3BQt1c2VyQWRkcmVzcwgFAWkNdHJhbnNhY3Rpb25JZAkBDWZvcm1hdEhpc3RvcnkECQEPY2FsY1RvdGFsUHJvZml0AAkBD2dldEN1cnJlbnRQcmljZQAFDXRvdGFsTHBBbW91bnQFEHRvdGFsQXNzZXRBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFEGtleVRvdGFsTHBBbW91bnQFEG5ld1RvdGFsTHBBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIFE2tleVRvdGFsQXNzZXRBbW91bnQFE25ld1RvdGFsQXNzZXRBbW91bnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQ9rZXlVc2VyTHBBbW91bnQBBQt1c2VyQWRkcmVzcwUPbmV3VXNlckxwQW1vdW50CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEaa2V5VXNlclRvdGFsQXNzZXRXaXRoZHJhd24BBQt1c2VyQWRkcmVzcwUabmV3VXNlclRvdGFsQXNzZXRXaXRoZHJhd24JAMwIAgkBDEludGVnZXJFbnRyeQIFDWtleVN0YXJ0QmxvY2sFBmhlaWdodAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUBaQZjYWxsZXIFE3dpdGhkcmF3QXNzZXRBbW91bnQFDGFzc2V0SWRCeXRlcwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuARhnZXRTZXRTdGFraW5nTm9kZUFjdGlvbnMDC3VzZXJBZGRyZXNzC25vZGVBZGRyZXNzCW5vZGVTaGFyZQQFY2hlY2sJAMwIAgMJAAACCQDIAQEJANkEAQULdXNlckFkZHJlc3MFEkFERFJFU1NfQllURVNfU0laRQYJAQh0aHJvd0VycgECGXVzZXIgYWRkcmVzcyBpcyBub3QgdmFsaWQJAMwIAgMJAAACCQDIAQEJANkEAQULbm9kZUFkZHJlc3MFEkFERFJFU1NfQllURVNfU0laRQYJAQh0aHJvd0VycgECGW5vZGUgYWRkcmVzcyBpcyBub3QgdmFsaWQFA25pbAMJAAACBQVjaGVjawUFY2hlY2sJAMwIAgkBC1N0cmluZ0VudHJ5AgkBE2tleVVzZXJTdGFraW5nTm9kZXMBBQt1c2VyQWRkcmVzcwULbm9kZUFkZHJlc3MJAMwIAgkBC1N0cmluZ0VudHJ5AgkBGWtleVVzZXJTdGFraW5nTm9kZXNTaGFyZXMBBQt1c2VyQWRkcmVzcwkApAMBBQlub2RlU2hhcmUFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgsBaQETc2V0RW1pc3Npb25QZXJCbG9jawEQZW1pc3Npb25QZXJCbG9jawQFY2hlY2sJAMwIAgMJAAACCAUBaQZjYWxsZXIFBHRoaXMGCQEIdGhyb3dFcnIBAhFwZXJtaXNzaW9uIGRlbmllZAUDbmlsAwkAAAIFBWNoZWNrBQVjaGVjawkAzAgCCQEMSW50ZWdlckVudHJ5AgUTa2V5VG90YWxBc3NldEFtb3VudAkBK2dldFRvdGFsQXNzZXRBbW91bnRXaXRoUHJvZml0T3JNYXhBdmFpbGFibGUACQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ1rZXlTdGFydEJsb2NrBQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFE2tleUVtaXNzaW9uUGVyQmxvY2sJAJYDAQkAzAgCAAAJAMwIAgUQZW1pc3Npb25QZXJCbG9jawUDbmlsBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEZc2V0RW1pc3Npb25QZXJpb2RJbkJsb2NrcwEBcAQFY2hlY2sJAMwIAgMJAGYCBQFwAAAGCQEIdGhyb3dFcnIBAihlbWlzc2lvbiBwZXJpb2Qgc2hvdWxkIGJlIGdyZWF0ZXIgdGhhbiAwCQDMCAIDCQAAAggFAWkGY2FsbGVyBQR0aGlzBgkBCHRocm93RXJyAQIRcGVybWlzc2lvbiBkZW5pZWQFA25pbAMJAAACBQVjaGVjawUFY2hlY2sJAMwIAgkBDEludGVnZXJFbnRyeQIFE2tleVRvdGFsQXNzZXRBbW91bnQJAStnZXRUb3RhbEFzc2V0QW1vdW50V2l0aFByb2ZpdE9yTWF4QXZhaWxhYmxlAAkAzAgCCQEMSW50ZWdlckVudHJ5AgUNa2V5U3RhcnRCbG9jawUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRlrZXlFbWlzc2lvblBlcmlvZEluQmxvY2tzBQFwBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEFc3Rha2UABAt1c2VyQWRkcmVzcwkApQgBCAUBaQZjYWxsZXIJAQ9nZXRTdGFrZUFjdGlvbnMCBQFpBQt1c2VyQWRkcmVzcwFpAQhzdGFrZUZvcgELdXNlckFkZHJlc3MJAQ9nZXRTdGFrZUFjdGlvbnMCBQFpBQt1c2VyQWRkcmVzcwFpAQh3aXRoZHJhdwETd2l0aGRyYXdBc3NldEFtb3VudAQLdXNlckFkZHJlc3MJAKUIAQgFAWkGY2FsbGVyBAx1c2VyTHBBbW91bnQJAQ9nZXRVc2VyTHBBbW91bnQBBQt1c2VyQWRkcmVzcwQSbHBBbW91bnRUb1dpdGhkcmF3CQCgAwEJALwCAwkAtgIBBRN3aXRoZHJhd0Fzc2V0QW1vdW50BQ1zY2FsZTE4QmlnSW50CQEPZ2V0Q3VycmVudFByaWNlAAQcdXNlckF2YWlsYWJsZUFzc2V0VG9XaXRoZHJhdwkBIGdldFVzZXJBdmFpbGFibGVBc3NldHNUb1dpdGhkcmF3AQULdXNlckFkZHJlc3MEFm1pbldpdGhkcmF3QXNzZXRBbW91bnQJAKADAQkAvQIECQEPZ2V0Q3VycmVudFByaWNlAAkAtgIBAAEFDXNjYWxlMThCaWdJbnQFB0NFSUxJTkcEBWNoZWNrCQDMCAIDCQBmAgUTd2l0aGRyYXdBc3NldEFtb3VudAAABgkBCHRocm93RXJyAQIld2l0aGRyYXcgYW1vdW50IHNob3VsZCBiZSBtb3JlIHRoYW4gMAkAzAgCAwkAZwIFHHVzZXJBdmFpbGFibGVBc3NldFRvV2l0aGRyYXcFE3dpdGhkcmF3QXNzZXRBbW91bnQGCQEIdGhyb3dFcnIBCQCsAgIJAKwCAgIlY2Fubm90IHdpdGhkcmF3IG1vcmUgdGhhbiBhdmFpbGFibGUgKAkApAMBBRx1c2VyQXZhaWxhYmxlQXNzZXRUb1dpdGhkcmF3AgEpCQDMCAIDCQBnAgUTd2l0aGRyYXdBc3NldEFtb3VudAUWbWluV2l0aGRyYXdBc3NldEFtb3VudAYJAQh0aHJvd0VycgEJAKwCAgkArAICAiR3aXRoZHJhdyBhbW91bnQgaXMgdG9vIHNtYWxsLiBNaW46ICgJAKQDAQUWbWluV2l0aGRyYXdBc3NldEFtb3VudAIBKQUDbmlsAwkAAAIFBWNoZWNrBQVjaGVjawkBEmdldFdpdGhkcmF3QWN0aW9ucwIFAWkJAJcDAQkAzAgCBQx1c2VyTHBBbW91bnQJAMwIAgkAZAIFEmxwQW1vdW50VG9XaXRoZHJhdwABBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEOc2V0U3Rha2luZ05vZGUBC25vZGVBZGRyZXNzBAt1c2VyQWRkcmVzcwkApQgBCAUBaQZjYWxsZXIJARhnZXRTZXRTdGFraW5nTm9kZUFjdGlvbnMDBQt1c2VyQWRkcmVzcwULbm9kZUFkZHJlc3MAZAFpARZzdGFrZUFuZFNldFN0YWtpbmdOb2RlAQtub2RlQWRkcmVzcwQLdXNlckFkZHJlc3MJAKUIAQgFAWkGY2FsbGVyCQDOCAIJAQ9nZXRTdGFrZUFjdGlv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b3VudExpc3QFA25pbAMJAAACBQVjaGVjawUFY2hlY2sKARZnZXRBaXJkcm9wU3RhdGVDaGFuZ2VzAgVhY2N1bQthc3NldEFtb3VudAQNJHQwMTQ0OTExNDUyNwUFYWNjdW0EBnJlc3VsdAgFDSR0MDE0NDkxMTQ1MjcCXzEEBWluZGV4CAUNJHQwMTQ0OTExNDUyNwJfMgQHdG90YWxMcAgFDSR0MDE0NDkxMTQ1MjcCXzMEDWFkZGVkTHBBbW91bnQJAQ9jYWxjTHBGcm9tQXNzZXQBBQthc3NldEFtb3VudAQPdXNlckxvY2tlZExwS2V5CQEVa2V5VXNlckxvY2tlZExwQW1vdW50AQkAkQMCBQthZGRyZXNzTGlzdAUFaW5kZXgEC29sZExwQW1vdW50CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFD3VzZXJMb2NrZWRMcEtleQAACQCVCgMJAM0IAgUGcmVzdWx0CQEMSW50ZWdlckVudHJ5AgUPdXNlckxvY2tlZExwS2V5CQBkAgULb2xkTHBBbW91bnQFDWFkZGVkTHBBbW91bnQJAGQCBQVpbmRleAABCQBkAgUHdG90YWxMcAUNYWRkZWRMcEFtb3VudAQNJHQwMTQ4NTgxNDk2NwoAAiRsBQphbW91bnRMaXN0CgACJHMJAJADAQUCJGwKAAUkYWNjMAkAlQoDBQNuaWwAAAAACgEFJGYxXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARZnZXRBaXJkcm9wU3RhdGVDaGFuZ2VzAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYxXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhRMaXN0IHNpemUgZXhjZWVkcyA5MAkBBSRmMV8yAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgkBBSRmMV8xAgUFJGFjYzAAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATABQAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAAxADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0ATgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgQOYWlyZHJvcEVudHJpZXMIBQ0kdDAxNDg1ODE0OTY3Al8xBAJfYQgFDSR0MDE0ODU4MTQ5NjcCXzIEGGFkZGVkVG90YWxMb2NrZWRMcEFtb3VudAgFDSR0MDE0ODU4MTQ5NjcCXzMJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUWa2V5VG90YWxMb2NrZWRMcEFtb3VudAkAZAIFE3RvdGFsTG9ja2VkTHBBbW91bnQFGGFkZGVkVG90YWxMb2NrZWRMcEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUQa2V5VG90YWxMcEFtb3VudAkAZAIFDXRvdGFsTHBBbW91bnQFGGFkZGVkVG90YWxMb2NrZWRMcEFtb3VudAkAzAgCCQEMSW50ZWdlckVudHJ5AgUTa2V5VG90YWxBc3NldEFtb3VudAkAZAIFEHRvdGFsQXNzZXRBbW91bnQFDWFtb3VudExpc3RTdW0FA25pbAUOYWlyZHJvcEVudHJpZXMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEVZ2V0VXNlckFzc2V0c1JFQURPTkxZAQt1c2VyQWRkcmVzcwQMdXNlckxwQW1vdW50CQEPZ2V0VXNlckxwQW1vdW50AQULdXNlckFkZHJlc3MEEnVzZXJMb2NrZWRMcEFtb3VudAkBFWdldFVzZXJMb2NrZWRMcEFtb3VudAEFC3VzZXJBZGRyZXNzBBV1c2VyTG9ja2VkQXNzZXRBbW91bnQJAQ9jYWxjQXNzZXRGcm9tTHABBRJ1c2VyTG9ja2VkTHBBbW91bnQEHHVzZXJBdmFpbGFibGVBc3NldFRvV2l0aGRyYXcJASBnZXRVc2VyQXZhaWxhYmxlQXNzZXRzVG9XaXRoZHJhdwEFC3VzZXJBZGRyZXNzBBV1c2VyVG90YWxTdGFrZWRBbW91bnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBF2tleVVzZXJUb3RhbEFzc2V0U3Rha2VkAQULdXNlckFkZHJlc3MAAAQXdXNlclRvdGFsQXNzZXRXaXRoZHJhd24JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBGmtleVVzZXJUb3RhbEFzc2V0V2l0aGRyYXduAQULdXNlckFkZHJlc3MAAAQNJHQwMTYxNTUxNjI0NwkBF2dldFVzZXJTdGFraW5nTm9kZXNEYXRhAQULdXNlckFkZHJlc3MEFHVzZXJTdGFraW5nTm9kZXNMaXN0CAUNJHQwMTYxNTUxNjI0NwJfMQQZdXNlclN0YWtpbmdOb2RlU2hhcmVzTGlzdAgFDSR0MDE2MTU1MTYyNDcCXzIJAJQKAgUDbmlsCQCbCgkFDHVzZXJMcEFtb3VudAUcdXNlckF2YWlsYWJsZUFzc2V0VG9XaXRoZHJhdwkBD2dldEN1cnJlbnRQcmljZQAFFXVzZXJUb3RhbFN0YWtlZEFtb3VudAUXdXNlclRvdGFsQXNzZXRXaXRoZHJhd24FEnVzZXJMb2NrZWRMcEFtb3VudAUVdXNlckxvY2tlZEFzc2V0QW1vdW50BRR1c2VyU3Rha2luZ05vZGVzTGlzdAUZdXNlclN0YWtpbmdOb2RlU2hhcmVzTGlzdAFpARZnZXRUb3RhbEFzc2V0c1JFQURPTkxZAAkAlAoCBQNuaWwJAJgKBgUNdG90YWxMcEFtb3VudAkBK2dldFRvdGFsQXNzZXRBbW91bnRXaXRoUHJvZml0T3JNYXhBdmFpbGFibGUACQEPZ2V0Q3VycmVudFByaWNlAAUTdG90YWxMb2NrZWRMcEFtb3VudAkBD2NhbGNBc3NldEZyb21McAEFE3RvdGFsTG9ja2VkTHBBbW91bnQJARJnZXRSZW1haW5pbmdCbG9ja3MAAWkBC3ZvdGVGb3JUeElkAQR0eElkBBNjYWxsZXJBZGRyZXNzU3RyaW5nCQDYBAEICAUBaQZjYWxsZXIFYnl0ZXMECWtleVByZWZpeAkBGGtleUFsbG93ZWRUeElkVm90ZVByZWZpeAEFBHR4SWQEBnJlc3VsdAkAzAgCCQELU3RyaW5nRW50cnkCCQEOa2V5QWxsb3dlZFR4SWQABQR0eElkBQNuaWwEEWFsbG93ZWRUeElkT3B0aW9uCQCdCAIFBHRoaXMJAQ5rZXlBbGxvd2VkVHhJZAAEA2VycgkAzAgCAwkAAAIJAMgBAQkA2QQBBQR0eElkBRFUWElEX0JZVEVTX0xFTkdUSAYJAQh0aHJvd0VycgEJAKwCAgUEdHhJZAISIGlzIG5vdCB2YWxpZCB0eElkCQDMCAIDAwkAAAIFEWFsbG93ZWRUeElkT3B0aW9uBQR1bml0BgkBAiE9AgkBBXZhbHVlAQURYWxsb3dlZFR4SWRPcHRpb24FBHR4SWQGCQEIdGhyb3dFcnIBCQCsAgIFBHR4SWQCEyBpcyBhbHJlYWR5IGFsbG93ZWQFA25pbAMJAAACBQNlcnIFA2VycgkBDHZvdGVJTlRFUk5BTAQFE2NhbGxlckFkZHJlc3NTdHJpbmcFCWtleVByZWZpeAUGUVVPUlVNBQZyZXN1bHQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAnR4AQZ2ZXJpZnkABAhieUFkbWlucwkAAAIIBQJ0eAJpZAkA2QQBCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJAQ5rZXlBbGxvd2VkVHhJZAACAAQHYnlPd25lcgMJAGcCCQCQAwEJAQ1nZXRBZG1pbnNMaXN0AAUGUVVPUlVNBwkA9AMDCAUCdHgJYm9keUJ5dGVzCQCRAwIIBQJ0eAZwcm9vZnMAAAgFAnR4D3NlbmRlclB1YmxpY0tleQMFCGJ5QWRtaW5zBgUHYnlPd25lcrqZpXk=", "chainId": 84, "height": 2864480, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 9aragTtCWGYsryKUKA59HJUjQhce68XyNSEapChTyZ6H Next: J4Grg3KAFzWz6BRLjFozgvfhG2DzZQtL8uo4HD7zLT8w Diff:
OldNewDifferences
7070
7171 let emissionPeriodInBlocks = valueOrElse(getInteger(this, keyEmissionPeriodInBlocks), BLOCKS_IN_DAY)
7272
73-let emissionPerPeriod = (valueOrElse(getInteger(this, keyEmissionPerBlock), 0) * emissionPeriodInBlocks)
73+let emissionPerBlock = valueOrElse(getInteger(this, keyEmissionPerBlock), 0)
74+
75+let emissionPerPeriod = (emissionPerBlock * emissionPeriodInBlocks)
7476
7577 let ADMIN_LIST_SIZE = 5
7678
108110
109111
110112 func genVotesKeysHelper (a,adminAddress) = {
111- let $t035553579 = a
112- let result = $t035553579._1
113- let prefix = $t035553579._2
113+ let $t035953619 = a
114+ let result = $t035953619._1
115+ let prefix = $t035953619._2
114116 $Tuple2((result :+ keyFullAdminVote(prefix, adminAddress)), prefix)
115117 }
116118
117119
118120 func genVotesKeys (keyPrefix) = {
119121 let adminList = keyAdminAddressList()
120- let $t037263810 = {
122+ let $t037663850 = {
121123 let $l = getAdminsList()
122124 let $s = size($l)
123125 let $acc0 = $Tuple2(nil, keyPrefix)
131133
132134 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
133135 }
134- let result = $t037263810._1
135- let prefix = $t037263810._2
136+ let result = $t037663850._1
137+ let prefix = $t037663850._2
136138 result
137139 }
138140
213215 func calcTotalProfit () = calcTotalProfitForHeight(height)
214216
215217
218+func getMaxAssetAvailable () = match assetIdBytes {
219+ case u: Unit =>
220+ wavesBalance(this).available
221+ case b: ByteVector =>
222+ assetBalance(this, b)
223+ case _ =>
224+ throw("Match error")
225+}
226+
227+
216228 func getTotalAssetAmountWithProfitOrMaxAvailable () = {
217229 let totalAssetAmountWithProfit = (totalAssetAmount + calcTotalProfit())
218- let totalAmount = match assetIdBytes {
219- case u: Unit =>
220- min([totalAssetAmountWithProfit, wavesBalance(this).available])
221- case b: ByteVector =>
222- min([totalAssetAmountWithProfit, assetBalance(this, b)])
223- case _ =>
224- throw("Match error")
225- }
230+ let totalAmount = min([totalAssetAmountWithProfit, getMaxAssetAvailable()])
226231 if ((totalLpAmount == 0))
227232 then 0
228233 else totalAmount
232237 func getCurrentPrice () = if ((totalLpAmount != 0))
233238 then fraction(toBigInt(getTotalAssetAmountWithProfitOrMaxAvailable()), scale18BigInt, toBigInt(totalLpAmount))
234239 else scale18BigInt
240+
241+
242+func getRemainingBlocks () = if ((emissionPerBlock == 0))
243+ then 0
244+ else fraction((getMaxAssetAvailable() - getTotalAssetAmountWithProfitOrMaxAvailable()), 1, emissionPerBlock)
235245
236246
237247 func getUserStakingNodesData (userAddress) = {
447457 if ((check == check))
448458 then {
449459 func getAirdropStateChanges (accum,assetAmount) = {
450- let $t01422714263 = accum
451- let result = $t01422714263._1
452- let index = $t01422714263._2
453- let totalLp = $t01422714263._3
460+ let $t01449114527 = accum
461+ let result = $t01449114527._1
462+ let index = $t01449114527._2
463+ let totalLp = $t01449114527._3
454464 let addedLpAmount = calcLpFromAsset(assetAmount)
455465 let userLockedLpKey = keyUserLockedLpAmount(addressList[index])
456466 let oldLpAmount = valueOrElse(getInteger(this, userLockedLpKey), 0)
457467 $Tuple3((result :+ IntegerEntry(userLockedLpKey, (oldLpAmount + addedLpAmount))), (index + 1), (totalLp + addedLpAmount))
458468 }
459469
460- let $t01459414703 = {
470+ let $t01485814967 = {
461471 let $l = amountList
462472 let $s = size($l)
463473 let $acc0 = $Tuple3(nil, 0, 0)
471481
472482 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90)
473483 }
474- let airdropEntries = $t01459414703._1
475- let _a = $t01459414703._2
476- let addedTotalLockedLpAmount = $t01459414703._3
484+ let airdropEntries = $t01485814967._1
485+ let _a = $t01485814967._2
486+ let addedTotalLockedLpAmount = $t01485814967._3
477487 ([IntegerEntry(keyTotalLockedLpAmount, (totalLockedLpAmount + addedTotalLockedLpAmount)), IntegerEntry(keyTotalLpAmount, (totalLpAmount + addedTotalLockedLpAmount)), IntegerEntry(keyTotalAssetAmount, (totalAssetAmount + amountListSum))] ++ airdropEntries)
478488 }
479489 else throw("Strict value is not equal to itself.")
489499 let userAvailableAssetToWithdraw = getUserAvailableAssetsToWithdraw(userAddress)
490500 let userTotalStakedAmount = valueOrElse(getInteger(this, keyUserTotalAssetStaked(userAddress)), 0)
491501 let userTotalAssetWithdrawn = valueOrElse(getInteger(this, keyUserTotalAssetWithdrawn(userAddress)), 0)
492- let $t01589115983 = getUserStakingNodesData(userAddress)
493- let userStakingNodesList = $t01589115983._1
494- let userStakingNodeSharesList = $t01589115983._2
502+ let $t01615516247 = getUserStakingNodesData(userAddress)
503+ let userStakingNodesList = $t01615516247._1
504+ let userStakingNodeSharesList = $t01615516247._2
495505 $Tuple2(nil, $Tuple9(userLpAmount, userAvailableAssetToWithdraw, getCurrentPrice(), userTotalStakedAmount, userTotalAssetWithdrawn, userLockedLpAmount, userLockedAssetAmount, userStakingNodesList, userStakingNodeSharesList))
496506 }
497507
498508
499509
500510 @Callable(i)
501-func getTotalAssetsREADONLY () = $Tuple2(nil, $Tuple5(totalLpAmount, getTotalAssetAmountWithProfitOrMaxAvailable(), getCurrentPrice(), totalLockedLpAmount, calcAssetFromLp(totalLockedLpAmount)))
511+func getTotalAssetsREADONLY () = $Tuple2(nil, $Tuple6(totalLpAmount, getTotalAssetAmountWithProfitOrMaxAvailable(), getCurrentPrice(), totalLockedLpAmount, calcAssetFromLp(totalLockedLpAmount), getRemainingBlocks()))
502512
503513
504514
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let contractFile = "l2mp_staking.ride"
55
66 let SEP = "__"
77
88 let scale8 = 100000000
99
1010 let scale18 = 1000000000000000000
1111
1212 let scale18BigInt = toBigInt(scale18)
1313
1414 let ADDRESS_BYTES_SIZE = 26
1515
1616 let BLOCKS_IN_DAY = 1440
1717
1818 func throwErr (msg) = throw(((contractFile + ": ") + msg))
1919
2020
2121 let keyAssetId = makeString(["%s", "assetId"], SEP)
2222
2323 let keyEmissionPerBlock = makeString(["%s", "emissionPerBlock"], SEP)
2424
2525 let keyEmissionPeriodInBlocks = makeString(["%s", "emissionPeriodInBlocks"], SEP)
2626
2727 let keyStartBlock = makeString(["%s", "startBlock"], SEP)
2828
2929 let keyTotalLpAmount = makeString(["%s", "totalLpAmount"], SEP)
3030
3131 let keyTotalAssetAmount = makeString(["%s", "totalAssetAmount"], SEP)
3232
3333 let keyTotalLockedLpAmount = makeString(["%s", "totalLockedLpAmount"], SEP)
3434
3535 func keyUserLpAmount (userAddress) = makeString(["%s%s", "userLpAmount", userAddress], SEP)
3636
3737
3838 func keyUserLockedLpAmount (userAddress) = makeString(["%s%s", "userLockedLpAmount", userAddress], SEP)
3939
4040
4141 func keyUserStakingNodes (userAddress) = makeString(["%s%s", "userStakingNodes", userAddress], SEP)
4242
4343
4444 func keyUserStakingNodesShares (userAddress) = makeString(["%s%s", "userStakingNodesShares", userAddress], SEP)
4545
4646
4747 func keyUserTotalAssetWithdrawn (userAddress) = makeString(["%s%s", "totalAssetWithdrawn", userAddress], SEP)
4848
4949
5050 func keyUserTotalAssetStaked (userAddress) = makeString(["%s%s", "totalAssetStaked", userAddress], SEP)
5151
5252
5353 func keyHistory (type,userAddress,txId) = makeString(["%s%s%s", type, userAddress, toBase58String(txId)], SEP)
5454
5555
5656 func formatHistory (totalProfit,price,totalAssetAmount,totalLpAmount) = makeString(["%d%d%d%d", toString(totalProfit), toString(price), toString(totalAssetAmount), toString(totalLpAmount)], SEP)
5757
5858
5959 let totalLpAmount = valueOrElse(getInteger(this, keyTotalLpAmount), 0)
6060
6161 let totalAssetAmount = valueOrElse(getInteger(this, keyTotalAssetAmount), 0)
6262
6363 let totalLockedLpAmount = valueOrElse(getInteger(this, keyTotalLockedLpAmount), 0)
6464
6565 let assetIdString = valueOrElse(getString(this, keyAssetId), "WAVES")
6666
6767 let assetIdBytes = if ((assetIdString == "WAVES"))
6868 then unit
6969 else fromBase58String(assetIdString)
7070
7171 let emissionPeriodInBlocks = valueOrElse(getInteger(this, keyEmissionPeriodInBlocks), BLOCKS_IN_DAY)
7272
73-let emissionPerPeriod = (valueOrElse(getInteger(this, keyEmissionPerBlock), 0) * emissionPeriodInBlocks)
73+let emissionPerBlock = valueOrElse(getInteger(this, keyEmissionPerBlock), 0)
74+
75+let emissionPerPeriod = (emissionPerBlock * emissionPeriodInBlocks)
7476
7577 let ADMIN_LIST_SIZE = 5
7678
7779 let QUORUM = 3
7880
7981 let TXID_BYTES_LENGTH = 32
8082
8183 func keyAllowedTxIdVotePrefix (txId) = makeString(["%s%s%s", "allowTxId", txId], SEP)
8284
8385
8486 func keyFullAdminVote (prefix,adminAddress) = makeString([prefix, adminAddress], SEP)
8587
8688
8789 func keyAdminAddressList () = makeString(["%s", "adminAddressList"], SEP)
8890
8991
9092 func keyAllowedTxId () = makeString(["%s", "txId"], SEP)
9193
9294
9395 func getAdminVote (prefix,admin) = {
9496 let voteKey = keyFullAdminVote(prefix, admin)
9597 valueOrElse(getInteger(voteKey), 0)
9698 }
9799
98100
99101 func getAdminsList () = match getString(this, keyAdminAddressList()) {
100102 case s: String =>
101103 split(s, SEP)
102104 case _ =>
103105 nil
104106 }
105107
106108
107109 func isInAdminList (address) = containsElement(getAdminsList(), address)
108110
109111
110112 func genVotesKeysHelper (a,adminAddress) = {
111- let $t035553579 = a
112- let result = $t035553579._1
113- let prefix = $t035553579._2
113+ let $t035953619 = a
114+ let result = $t035953619._1
115+ let prefix = $t035953619._2
114116 $Tuple2((result :+ keyFullAdminVote(prefix, adminAddress)), prefix)
115117 }
116118
117119
118120 func genVotesKeys (keyPrefix) = {
119121 let adminList = keyAdminAddressList()
120- let $t037263810 = {
122+ let $t037663850 = {
121123 let $l = getAdminsList()
122124 let $s = size($l)
123125 let $acc0 = $Tuple2(nil, keyPrefix)
124126 func $f0_1 ($a,$i) = if (($i >= $s))
125127 then $a
126128 else genVotesKeysHelper($a, $l[$i])
127129
128130 func $f0_2 ($a,$i) = if (($i >= $s))
129131 then $a
130132 else throw("List size exceeds 5")
131133
132134 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
133135 }
134- let result = $t037263810._1
135- let prefix = $t037263810._2
136+ let result = $t037663850._1
137+ let prefix = $t037663850._2
136138 result
137139 }
138140
139141
140142 func countVotesHelper (result,voteKey) = (result + valueOrElse(getInteger(voteKey), 0))
141143
142144
143145 func countVotes (prefix) = {
144146 let votes = genVotesKeys(prefix)
145147 let $l = votes
146148 let $s = size($l)
147149 let $acc0 = 0
148150 func $f0_1 ($a,$i) = if (($i >= $s))
149151 then $a
150152 else countVotesHelper($a, $l[$i])
151153
152154 func $f0_2 ($a,$i) = if (($i >= $s))
153155 then $a
154156 else throw("List size exceeds 5")
155157
156158 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
157159 }
158160
159161
160162 func clearVotesHelper (result,key) = (result :+ DeleteEntry(key))
161163
162164
163165 func getClearVoteEntries (prefix) = {
164166 let votes = genVotesKeys(prefix)
165167 let $l = votes
166168 let $s = size($l)
167169 let $acc0 = nil
168170 func $f0_1 ($a,$i) = if (($i >= $s))
169171 then $a
170172 else clearVotesHelper($a, $l[$i])
171173
172174 func $f0_2 ($a,$i) = if (($i >= $s))
173175 then $a
174176 else throw("List size exceeds 5")
175177
176178 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
177179 }
178180
179181
180182 func voteINTERNAL (callerAddressString,keyPrefix,minVotes,voteResult) = {
181183 let voteKey = keyFullAdminVote(keyPrefix, callerAddressString)
182184 let adminCurrentVote = getAdminVote(keyPrefix, callerAddressString)
183185 let err = if (!(isInAdminList(callerAddressString)))
184186 then throwErr((("Address: " + callerAddressString) + " not in Admin list"))
185187 else if ((adminCurrentVote == 1))
186188 then throwErr((voteKey + " you already voted"))
187189 else unit
188190 if ((err == err))
189191 then {
190192 let votes = countVotes(keyPrefix)
191193 if (((votes + 1) >= minVotes))
192194 then {
193195 let clearVoteEntries = getClearVoteEntries(keyPrefix)
194196 (clearVoteEntries ++ voteResult)
195197 }
196198 else [IntegerEntry(voteKey, 1)]
197199 }
198200 else throw("Strict value is not equal to itself.")
199201 }
200202
201203
202204 func stringListToIntListHelper (acc,value) = (acc :+ parseIntValue(value))
203205
204206
205207 func calcTotalProfitForHeight (h) = {
206208 let startBlock = valueOrElse(getInteger(this, keyStartBlock), height)
207209 let startPeriod = fraction(startBlock, 1, emissionPeriodInBlocks)
208210 let elapsedPeriods = ((h / emissionPeriodInBlocks) - startPeriod)
209211 max([0, (emissionPerPeriod * elapsedPeriods)])
210212 }
211213
212214
213215 func calcTotalProfit () = calcTotalProfitForHeight(height)
214216
215217
218+func getMaxAssetAvailable () = match assetIdBytes {
219+ case u: Unit =>
220+ wavesBalance(this).available
221+ case b: ByteVector =>
222+ assetBalance(this, b)
223+ case _ =>
224+ throw("Match error")
225+}
226+
227+
216228 func getTotalAssetAmountWithProfitOrMaxAvailable () = {
217229 let totalAssetAmountWithProfit = (totalAssetAmount + calcTotalProfit())
218- let totalAmount = match assetIdBytes {
219- case u: Unit =>
220- min([totalAssetAmountWithProfit, wavesBalance(this).available])
221- case b: ByteVector =>
222- min([totalAssetAmountWithProfit, assetBalance(this, b)])
223- case _ =>
224- throw("Match error")
225- }
230+ let totalAmount = min([totalAssetAmountWithProfit, getMaxAssetAvailable()])
226231 if ((totalLpAmount == 0))
227232 then 0
228233 else totalAmount
229234 }
230235
231236
232237 func getCurrentPrice () = if ((totalLpAmount != 0))
233238 then fraction(toBigInt(getTotalAssetAmountWithProfitOrMaxAvailable()), scale18BigInt, toBigInt(totalLpAmount))
234239 else scale18BigInt
240+
241+
242+func getRemainingBlocks () = if ((emissionPerBlock == 0))
243+ then 0
244+ else fraction((getMaxAssetAvailable() - getTotalAssetAmountWithProfitOrMaxAvailable()), 1, emissionPerBlock)
235245
236246
237247 func getUserStakingNodesData (userAddress) = {
238248 let nodesRaw = valueOrElse(getString(this, keyUserStakingNodes(userAddress)), "")
239249 let sharesRaw = valueOrElse(getString(this, keyUserStakingNodesShares(userAddress)), "")
240250 let nodesList = if ((nodesRaw == ""))
241251 then nil
242252 else split(nodesRaw, SEP)
243253 let sharesStringList = if ((sharesRaw == ""))
244254 then nil
245255 else split(sharesRaw, SEP)
246256 let sharesList = {
247257 let $l = sharesStringList
248258 let $s = size($l)
249259 let $acc0 = nil
250260 func $f0_1 ($a,$i) = if (($i >= $s))
251261 then $a
252262 else stringListToIntListHelper($a, $l[$i])
253263
254264 func $f0_2 ($a,$i) = if (($i >= $s))
255265 then $a
256266 else throw("List size exceeds 20")
257267
258268 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20)
259269 }
260270 $Tuple2(nodesList, sharesList)
261271 }
262272
263273
264274 func calcAssetFromLp (lpAmount) = max([0, toInt(fraction(toBigInt(lpAmount), getCurrentPrice(), scale18BigInt))])
265275
266276
267277 func calcLpFromAsset (assetAmount) = max([0, toInt(fraction(toBigInt(assetAmount), scale18BigInt, getCurrentPrice()))])
268278
269279
270280 func getUserLpAmount (userAddress) = valueOrElse(getInteger(this, keyUserLpAmount(userAddress)), 0)
271281
272282
273283 func getUserLockedLpAmount (userAddress) = valueOrElse(getInteger(this, keyUserLockedLpAmount(userAddress)), 0)
274284
275285
276286 func getUserAvailableAssetsToWithdraw (userAddress) = {
277287 let userLpAmount = getUserLpAmount(userAddress)
278288 calcAssetFromLp(userLpAmount)
279289 }
280290
281291
282292 func getStakeActions (i,userAddress) = {
283293 let checks = [if ((size(i.payments) == 1))
284294 then true
285295 else throwErr("should include 1 payment"), if ((i.payments[0].assetId == assetIdBytes))
286296 then true
287297 else throwErr(("payment should be in " + assetIdString)), if ((i.payments[0].amount > 0))
288298 then true
289299 else "payment amount should be greater than 0", if ((size(fromBase58String(userAddress)) == ADDRESS_BYTES_SIZE))
290300 then true
291301 else throwErr("user address is not valid")]
292302 if ((checks == checks))
293303 then {
294304 let paymentAmount = i.payments[0].amount
295305 let paymentLpAmount = toInt(fraction(toBigInt(paymentAmount), scale18BigInt, getCurrentPrice()))
296306 let userLpAmount = getUserLpAmount(userAddress)
297307 let userTotalStakedAmount = valueOrElse(getInteger(this, keyUserTotalAssetStaked(userAddress)), 0)
298308 let newTotalLpAmount = (totalLpAmount + paymentLpAmount)
299309 let newTotalAssetAmount = toInt(fraction(toBigInt(newTotalLpAmount), getCurrentPrice(), scale18BigInt))
300310 let newUserLpAmount = (userLpAmount + paymentLpAmount)
301311 let newUserTotalStakedAmount = (userTotalStakedAmount + paymentAmount)
302312 [StringEntry(keyHistory("stake", userAddress, i.transactionId), formatHistory(calcTotalProfit(), getCurrentPrice(), totalLpAmount, totalAssetAmount)), IntegerEntry(keyTotalLpAmount, newTotalLpAmount), IntegerEntry(keyTotalAssetAmount, newTotalAssetAmount), IntegerEntry(keyUserLpAmount(userAddress), newUserLpAmount), IntegerEntry(keyUserTotalAssetStaked(userAddress), newUserTotalStakedAmount), IntegerEntry(keyStartBlock, height)]
303313 }
304314 else throw("Strict value is not equal to itself.")
305315 }
306316
307317
308318 func getWithdrawActions (i,lpAssetWithdrawAmount) = {
309319 let userAddress = toString(i.caller)
310320 let userLpAmount = getUserLpAmount(userAddress)
311321 let check = [if ((lpAssetWithdrawAmount > 0))
312322 then true
313323 else throwErr("LP amount should be more than 0"), if ((userLpAmount >= lpAssetWithdrawAmount))
314324 then true
315325 else throwErr((("cannot withdraw more than available LP (" + toString(userLpAmount)) + ")"))]
316326 if ((check == check))
317327 then {
318328 let newUserLpAmount = (userLpAmount - lpAssetWithdrawAmount)
319329 let withdrawAssetAmount = toInt(fraction(toBigInt(lpAssetWithdrawAmount), getCurrentPrice(), scale18BigInt))
320330 let newTotalLpAmount = (totalLpAmount - lpAssetWithdrawAmount)
321331 let newTotalAssetAmount = toInt(fraction(toBigInt(newTotalLpAmount), getCurrentPrice(), scale18BigInt))
322332 let userTotalAssetWithdrawn = valueOrElse(getInteger(this, keyUserTotalAssetWithdrawn(userAddress)), 0)
323333 let newUserTotalAssetWithdrawn = (userTotalAssetWithdrawn + withdrawAssetAmount)
324334 [StringEntry(keyHistory("withdraw", userAddress, i.transactionId), formatHistory(calcTotalProfit(), getCurrentPrice(), totalLpAmount, totalAssetAmount)), IntegerEntry(keyTotalLpAmount, newTotalLpAmount), IntegerEntry(keyTotalAssetAmount, newTotalAssetAmount), IntegerEntry(keyUserLpAmount(userAddress), newUserLpAmount), IntegerEntry(keyUserTotalAssetWithdrawn(userAddress), newUserTotalAssetWithdrawn), IntegerEntry(keyStartBlock, height), ScriptTransfer(i.caller, withdrawAssetAmount, assetIdBytes)]
325335 }
326336 else throw("Strict value is not equal to itself.")
327337 }
328338
329339
330340 func getSetStakingNodeActions (userAddress,nodeAddress,nodeShare) = {
331341 let check = [if ((size(fromBase58String(userAddress)) == ADDRESS_BYTES_SIZE))
332342 then true
333343 else throwErr("user address is not valid"), if ((size(fromBase58String(nodeAddress)) == ADDRESS_BYTES_SIZE))
334344 then true
335345 else throwErr("node address is not valid")]
336346 if ((check == check))
337347 then [StringEntry(keyUserStakingNodes(userAddress), nodeAddress), StringEntry(keyUserStakingNodesShares(userAddress), toString(nodeShare))]
338348 else throw("Strict value is not equal to itself.")
339349 }
340350
341351
342352 @Callable(i)
343353 func setEmissionPerBlock (emissionPerBlock) = {
344354 let check = [if ((i.caller == this))
345355 then true
346356 else throwErr("permission denied")]
347357 if ((check == check))
348358 then [IntegerEntry(keyTotalAssetAmount, getTotalAssetAmountWithProfitOrMaxAvailable()), IntegerEntry(keyStartBlock, height), IntegerEntry(keyEmissionPerBlock, max([0, emissionPerBlock]))]
349359 else throw("Strict value is not equal to itself.")
350360 }
351361
352362
353363
354364 @Callable(i)
355365 func setEmissionPeriodInBlocks (p) = {
356366 let check = [if ((p > 0))
357367 then true
358368 else throwErr("emission period should be greater than 0"), if ((i.caller == this))
359369 then true
360370 else throwErr("permission denied")]
361371 if ((check == check))
362372 then [IntegerEntry(keyTotalAssetAmount, getTotalAssetAmountWithProfitOrMaxAvailable()), IntegerEntry(keyStartBlock, height), IntegerEntry(keyEmissionPeriodInBlocks, p)]
363373 else throw("Strict value is not equal to itself.")
364374 }
365375
366376
367377
368378 @Callable(i)
369379 func stake () = {
370380 let userAddress = toString(i.caller)
371381 getStakeActions(i, userAddress)
372382 }
373383
374384
375385
376386 @Callable(i)
377387 func stakeFor (userAddress) = getStakeActions(i, userAddress)
378388
379389
380390
381391 @Callable(i)
382392 func withdraw (withdrawAssetAmount) = {
383393 let userAddress = toString(i.caller)
384394 let userLpAmount = getUserLpAmount(userAddress)
385395 let lpAmountToWithdraw = toInt(fraction(toBigInt(withdrawAssetAmount), scale18BigInt, getCurrentPrice()))
386396 let userAvailableAssetToWithdraw = getUserAvailableAssetsToWithdraw(userAddress)
387397 let minWithdrawAssetAmount = toInt(fraction(getCurrentPrice(), toBigInt(1), scale18BigInt, CEILING))
388398 let check = [if ((withdrawAssetAmount > 0))
389399 then true
390400 else throwErr("withdraw amount should be more than 0"), if ((userAvailableAssetToWithdraw >= withdrawAssetAmount))
391401 then true
392402 else throwErr((("cannot withdraw more than available (" + toString(userAvailableAssetToWithdraw)) + ")")), if ((withdrawAssetAmount >= minWithdrawAssetAmount))
393403 then true
394404 else throwErr((("withdraw amount is too small. Min: (" + toString(minWithdrawAssetAmount)) + ")"))]
395405 if ((check == check))
396406 then getWithdrawActions(i, min([userLpAmount, (lpAmountToWithdraw + 1)]))
397407 else throw("Strict value is not equal to itself.")
398408 }
399409
400410
401411
402412 @Callable(i)
403413 func setStakingNode (nodeAddress) = {
404414 let userAddress = toString(i.caller)
405415 getSetStakingNodeActions(userAddress, nodeAddress, 100)
406416 }
407417
408418
409419
410420 @Callable(i)
411421 func stakeAndSetStakingNode (nodeAddress) = {
412422 let userAddress = toString(i.caller)
413423 (getStakeActions(i, userAddress) ++ getSetStakingNodeActions(userAddress, nodeAddress, 100))
414424 }
415425
416426
417427
418428 @Callable(i)
419429 func airdrop (addressList,amountList) = {
420430 func sum (accum,next) = (accum + next)
421431
422432 let amountListSum = {
423433 let $l = amountList
424434 let $s = size($l)
425435 let $acc0 = 0
426436 func $f0_1 ($a,$i) = if (($i >= $s))
427437 then $a
428438 else sum($a, $l[$i])
429439
430440 func $f0_2 ($a,$i) = if (($i >= $s))
431441 then $a
432442 else throw("List size exceeds 90")
433443
434444 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90)
435445 }
436446 let check = [if ((size(i.payments) == 1))
437447 then true
438448 else throwErr("should include 1 payment"), if ((i.payments[0].assetId == assetIdBytes))
439449 then true
440450 else throwErr(("payment should be in " + assetIdString)), if ((i.payments[0].amount > 0))
441451 then true
442452 else "payment amount should be greater than 0", if ((size(addressList) == size(amountList)))
443453 then true
444454 else throwErr("addressList should be same size as amountList"), if ((i.payments[0].amount >= amountListSum))
445455 then true
446456 else throwErr("payment amount is less than sum of amountList")]
447457 if ((check == check))
448458 then {
449459 func getAirdropStateChanges (accum,assetAmount) = {
450- let $t01422714263 = accum
451- let result = $t01422714263._1
452- let index = $t01422714263._2
453- let totalLp = $t01422714263._3
460+ let $t01449114527 = accum
461+ let result = $t01449114527._1
462+ let index = $t01449114527._2
463+ let totalLp = $t01449114527._3
454464 let addedLpAmount = calcLpFromAsset(assetAmount)
455465 let userLockedLpKey = keyUserLockedLpAmount(addressList[index])
456466 let oldLpAmount = valueOrElse(getInteger(this, userLockedLpKey), 0)
457467 $Tuple3((result :+ IntegerEntry(userLockedLpKey, (oldLpAmount + addedLpAmount))), (index + 1), (totalLp + addedLpAmount))
458468 }
459469
460- let $t01459414703 = {
470+ let $t01485814967 = {
461471 let $l = amountList
462472 let $s = size($l)
463473 let $acc0 = $Tuple3(nil, 0, 0)
464474 func $f1_1 ($a,$i) = if (($i >= $s))
465475 then $a
466476 else getAirdropStateChanges($a, $l[$i])
467477
468478 func $f1_2 ($a,$i) = if (($i >= $s))
469479 then $a
470480 else throw("List size exceeds 90")
471481
472482 $f1_2($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($f1_1($acc0, 0), 1), 2), 3), 4), 5), 6), 7), 8), 9), 10), 11), 12), 13), 14), 15), 16), 17), 18), 19), 20), 21), 22), 23), 24), 25), 26), 27), 28), 29), 30), 31), 32), 33), 34), 35), 36), 37), 38), 39), 40), 41), 42), 43), 44), 45), 46), 47), 48), 49), 50), 51), 52), 53), 54), 55), 56), 57), 58), 59), 60), 61), 62), 63), 64), 65), 66), 67), 68), 69), 70), 71), 72), 73), 74), 75), 76), 77), 78), 79), 80), 81), 82), 83), 84), 85), 86), 87), 88), 89), 90)
473483 }
474- let airdropEntries = $t01459414703._1
475- let _a = $t01459414703._2
476- let addedTotalLockedLpAmount = $t01459414703._3
484+ let airdropEntries = $t01485814967._1
485+ let _a = $t01485814967._2
486+ let addedTotalLockedLpAmount = $t01485814967._3
477487 ([IntegerEntry(keyTotalLockedLpAmount, (totalLockedLpAmount + addedTotalLockedLpAmount)), IntegerEntry(keyTotalLpAmount, (totalLpAmount + addedTotalLockedLpAmount)), IntegerEntry(keyTotalAssetAmount, (totalAssetAmount + amountListSum))] ++ airdropEntries)
478488 }
479489 else throw("Strict value is not equal to itself.")
480490 }
481491
482492
483493
484494 @Callable(i)
485495 func getUserAssetsREADONLY (userAddress) = {
486496 let userLpAmount = getUserLpAmount(userAddress)
487497 let userLockedLpAmount = getUserLockedLpAmount(userAddress)
488498 let userLockedAssetAmount = calcAssetFromLp(userLockedLpAmount)
489499 let userAvailableAssetToWithdraw = getUserAvailableAssetsToWithdraw(userAddress)
490500 let userTotalStakedAmount = valueOrElse(getInteger(this, keyUserTotalAssetStaked(userAddress)), 0)
491501 let userTotalAssetWithdrawn = valueOrElse(getInteger(this, keyUserTotalAssetWithdrawn(userAddress)), 0)
492- let $t01589115983 = getUserStakingNodesData(userAddress)
493- let userStakingNodesList = $t01589115983._1
494- let userStakingNodeSharesList = $t01589115983._2
502+ let $t01615516247 = getUserStakingNodesData(userAddress)
503+ let userStakingNodesList = $t01615516247._1
504+ let userStakingNodeSharesList = $t01615516247._2
495505 $Tuple2(nil, $Tuple9(userLpAmount, userAvailableAssetToWithdraw, getCurrentPrice(), userTotalStakedAmount, userTotalAssetWithdrawn, userLockedLpAmount, userLockedAssetAmount, userStakingNodesList, userStakingNodeSharesList))
496506 }
497507
498508
499509
500510 @Callable(i)
501-func getTotalAssetsREADONLY () = $Tuple2(nil, $Tuple5(totalLpAmount, getTotalAssetAmountWithProfitOrMaxAvailable(), getCurrentPrice(), totalLockedLpAmount, calcAssetFromLp(totalLockedLpAmount)))
511+func getTotalAssetsREADONLY () = $Tuple2(nil, $Tuple6(totalLpAmount, getTotalAssetAmountWithProfitOrMaxAvailable(), getCurrentPrice(), totalLockedLpAmount, calcAssetFromLp(totalLockedLpAmount), getRemainingBlocks()))
502512
503513
504514
505515 @Callable(i)
506516 func voteForTxId (txId) = {
507517 let callerAddressString = toBase58String(i.caller.bytes)
508518 let keyPrefix = keyAllowedTxIdVotePrefix(txId)
509519 let result = [StringEntry(keyAllowedTxId(), txId)]
510520 let allowedTxIdOption = getString(this, keyAllowedTxId())
511521 let err = [if ((size(fromBase58String(txId)) == TXID_BYTES_LENGTH))
512522 then true
513523 else throwErr((txId + " is not valid txId")), if (if ((allowedTxIdOption == unit))
514524 then true
515525 else (value(allowedTxIdOption) != txId))
516526 then true
517527 else throwErr((txId + " is already allowed"))]
518528 if ((err == err))
519529 then voteINTERNAL(callerAddressString, keyPrefix, QUORUM, result)
520530 else throw("Strict value is not equal to itself.")
521531 }
522532
523533
524534 @Verifier(tx)
525535 func verify () = {
526536 let byAdmins = (tx.id == fromBase58String(valueOrElse(getString(this, keyAllowedTxId()), "")))
527537 let byOwner = if ((size(getAdminsList()) >= QUORUM))
528538 then false
529539 else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
530540 if (byAdmins)
531541 then true
532542 else byOwner
533543 }
534544

github/deemru/w8io/3ef1775 
98.04 ms