tx · H2mEXAWwBDWQLFCbCgB6z3qLWtfEyz2LyJpfv95UpyyV

3NCWFHDzdPHZC6636ZkMLNDup9mjpbTLs7h:  -0.02700000 Waves

2024.11.07 15:52 [3361066] smart account 3NCWFHDzdPHZC6636ZkMLNDup9mjpbTLs7h > SELF 0.00000000 Waves

{ "type": 13, "id": "H2mEXAWwBDWQLFCbCgB6z3qLWtfEyz2LyJpfv95UpyyV", "fee": 2700000, "feeAssetId": null, "timestamp": 1730984021692, "version": 1, "sender": "3NCWFHDzdPHZC6636ZkMLNDup9mjpbTLs7h", "senderPublicKey": "3z8Q6Zu3KppVmn6fJJvrLc1Wo3krVHSvfaNcerm82md2", "proofs": [ "29wmLz6tHhzKrEFqsEfrvnkVkDovh9zMx4WmvznYCBuFHy5BhKUxJjVvWDDUSEM4aiP76buG9k1vwBup3iaCpwTX" ], "script": "base64:BgJTCAISAwoBARIAEgMKAQQSAwoBBBIDCgEIEgQKAggIEgMKAQgSBAoCCAgSAwoBCBIECgIIARIECgIIARIDCgEBEgASAwoBCBIGCgQBCAgIEgMKAQhPAAxjb250cmFjdEZpbGUCEWwybXBfbGVhc2luZy5yaWRlAANTRVACAl9fABJCTE9DS1NfSU5fSU5URVJWQUwA6AcABnNjYWxlOACAwtcvAAdzY2FsZTE2CQBoAgUGc2NhbGU4BQZzY2FsZTgBCHRocm93RXJyAQNtc2cJAAIBCQCsAgIJAKwCAgUMY29udHJhY3RGaWxlAgI6IAUDbXNnAAxrZXlMMkFzc2V0SWQJALkJAgkAzAgCAgIlcwkAzAgCAgdhc3NldElkBQNuaWwFA1NFUAAMa2V5Rm9yY2VTdG9wCQC5CQIJAMwIAgICJXMJAMwIAgIJZm9yY2VTdG9wBQNuaWwFA1NFUAAPa2V5Rm9yY2VPdXRTdG9wCQC5CQIJAMwIAgICJXMJAMwIAgIMZm9yY2VPdXRTdG9wBQNuaWwFA1NFUAAPa2V5VW5pdHNBc3NldElkCQC5CQIJAMwIAgICJXMJAMwIAgIMdW5pdHNBc3NldElkBQNuaWwFA1NFUAAXa2V5VW5pdHNQZXJCbG9ja1NjYWxlMTYJALkJAgkAzAgCAgIlcwkAzAgCAhR1bml0c1BlckJsb2NrU2NhbGUxNgUDbmlsBQNTRVAAEWtleVBlcmlvZE9mZnNldElkCQC5CQIJAMwIAgICJXMJAMwIAgIIb2Zmc2V0SWQFA25pbAUDU0VQABVrZXlQZXJpb2RPZmZzZXRIZWlnaHQJALkJAgkAzAgCAgIlcwkAzAgCAgxvZmZzZXRIZWlnaHQFA25pbAUDU0VQAA9rZXlQZXJpb2RMZW5ndGgJALkJAgkAzAgCAgIlcwkAzAgCAgxwZXJpb2RMZW5ndGgFA25pbAUDU0VQABhrZXlVbml0c0NsYWltU3RhcnRIZWlnaHQJALkJAgkAzAgCAgIlcwkAzAgCAhV1bml0c0NsYWltU3RhcnRIZWlnaHQFA25pbAUDU0VQABVrZXlVbml0c0NsYWltSW50ZXJ2YWwJALkJAgkAzAgCAgIlcwkAzAgCAhJ1bml0c0NsYWltSW50ZXJ2YWwFA25pbAUDU0VQAA5wZXJpb2RPZmZzZXRJZAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRFrZXlQZXJpb2RPZmZzZXRJZAAAAAxwZXJpb2RMZW5ndGgJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUPa2V5UGVyaW9kTGVuZ3RoAJBOABJwZXJpb2RPZmZzZXRIZWlnaHQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUVa2V5UGVyaW9kT2Zmc2V0SGVpZ2h0AP///////////wEAD2N1cnJlbnRQZXJpb2RJZAMDCQBmAgUGaGVpZ2h0BRJwZXJpb2RPZmZzZXRIZWlnaHQJAQIhPQIFEnBlcmlvZE9mZnNldEhlaWdodAD///////////8BBwkAZAIJAGkCCQBlAgUGaGVpZ2h0BRJwZXJpb2RPZmZzZXRIZWlnaHQFDHBlcmlvZExlbmd0aAUOcGVyaW9kT2Zmc2V0SWQJAJYDAQkAzAgCAAAJAMwIAgkAZQIFDnBlcmlvZE9mZnNldElkAAEFA25pbAATY3VycmVudFBlcmlvZEhlaWdodAMDCQAAAgUScGVyaW9kT2Zmc2V0SGVpZ2h0AP///////////wEGAwkAAAIFD2N1cnJlbnRQZXJpb2RJZAAACQBmAgUScGVyaW9kT2Zmc2V0SGVpZ2h0BQZoZWlnaHQHAAAJAGQCBRJwZXJpb2RPZmZzZXRIZWlnaHQJAGgCCQBlAgUPY3VycmVudFBlcmlvZElkBQ5wZXJpb2RPZmZzZXRJZAUMcGVyaW9kTGVuZ3RoABBuZXh0UGVyaW9kSGVpZ2h0AwMJAAACBRJwZXJpb2RPZmZzZXRIZWlnaHQA////////////AQYDCQAAAgUPY3VycmVudFBlcmlvZElkAAAJAGYCBRJwZXJpb2RPZmZzZXRIZWlnaHQFBmhlaWdodAcAAAkAZAIFE2N1cnJlbnRQZXJpb2RIZWlnaHQFDHBlcmlvZExlbmd0aAAVdW5pdHNDbGFpbVN0YXJ0SGVpZ2h0CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFGGtleVVuaXRzQ2xhaW1TdGFydEhlaWdodAUGaGVpZ2h0ABJ1bml0c0NsYWltSW50ZXJ2YWwJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUVa2V5VW5pdHNDbGFpbUludGVydmFsAAEBEmtleUxlYXNpbmdOb2RlRGF0YQELbm9kZUFkZHJlc3MJALkJAgkAzAgCAgIlcwkAzAgCBQtub2RlQWRkcmVzcwUDbmlsBQNTRVABFmtleVVzZXJMZWFzaW5nTm9kZURhdGECC3VzZXJBZGRyZXNzC25vZGVBZGRyZXNzCQC5CQIJAMwIAgIEJXMlcwkAzAgCBQtub2RlQWRkcmVzcwkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABDmtleVVzZXJUb0NsYWltAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIHdG9DbGFpbQkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABEmtleVVzZXJUb3RhbExvY2tlZAELdXNlckFkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAICD3VzZXJUb3RhbExvY2tlZAkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABFGtleVVuaXRzQ2xhaW1lZEJsb2NrAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIRdW5pdHNDbGFpbWVkQmxvY2sJAMwIAgULdXNlckFkZHJlc3MFA25pbAUDU0VQARBrZXlVbmxvY2tlZFVuaXRzAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgINdW5sb2NrZWRVbml0cwkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsBQNTRVABFGtleVRvdGFsVW5pdHNDbGFpbWVkAQt1c2VyQWRkcmVzcwkAuQkCCQDMCAICBCVzJXMJAMwIAgIRdG90YWxVbml0c0NsYWltZWQJAMwIAgULdXNlckFkZHJlc3MFA25pbAUDU0VQAQtrZXlMMlRvQnVybgELdXNlckFkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAICCGwyVG9CdXJuCQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwFA1NFUAEQa2V5TDJCdXJuZWRUb3RhbAELdXNlckFkZHJlc3MJALkJAgkAzAgCAgQlcyVzCQDMCAICDWwyQnVybmVkVG90YWwJAMwIAgULdXNlckFkZHJlc3MFA25pbAUDU0VQARZrZXlOb2RlTGVhc2luZ0J5SGVpZ2h0AQtub2RlQWRkcmVzcwQBaAMJAAACBRJwZXJpb2RPZmZzZXRIZWlnaHQA////////////AQAABQZoZWlnaHQJALkJAgkAzAgCAgQlcyVkCQDMCAIFC25vZGVBZGRyZXNzCQDMCAIJAKQDAQUBaAUDbmlsBQNTRVABFmtleVVzZXJMZWFzaW5nQnlIZWlnaHQCC25vZGVBZGRyZXNzC3VzZXJBZGRyZXNzBAFoAwkAAAIFEnBlcmlvZE9mZnNldEhlaWdodAD///////////8BAAAFBmhlaWdodAkAuQkCCQDMCAICBiVzJXMlZAkAzAgCBQtub2RlQWRkcmVzcwkAzAgCBQt1c2VyQWRkcmVzcwkAzAgCCQCkAwEFAWgFA25pbAUDU0VQARJhc3NldFN0cmluZ1RvQnl0ZXMBDWFzc2V0SWRTdHJpbmcDCQAAAgUNYXNzZXRJZFN0cmluZwIFV0FWRVMFBHVuaXQJANkEAQUNYXNzZXRJZFN0cmluZwESYXNzZXRCeXRlc1RvU3RyaW5nAQdhc3NldElkBAckbWF0Y2gwBQdhc3NldElkAwkAAQIFByRtYXRjaDACCkJ5dGVWZWN0b3IEAWEFByRtYXRjaDAJANgEAQUBYQIFV0FWRVMAD2wyQXNzZXRJZFN0cmluZwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQxrZXlMMkFzc2V0SWQCBVdBVkVTABJ1bml0c0Fzc2V0SWRTdHJpbmcJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUPa2V5VW5pdHNBc3NldElkAgVXQVZFUwAObDJBc3NldElkQnl0ZXMJARJhc3NldFN0cmluZ1RvQnl0ZXMBBQ9sMkFzc2V0SWRTdHJpbmcAEXVuaXRzQXNzZXRJZEJ5dGVzCQESYXNzZXRTdHJpbmdUb0J5dGVzAQUSdW5pdHNBc3NldElkU3RyaW5nAAtpc0ZvcmNlU3RvcAkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzBQxrZXlGb3JjZVN0b3AHAA5pc0ZvcmNlT3V0U3RvcAkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzBQ9rZXlGb3JjZU91dFN0b3AHAQ5pc1ZhbGlkQWRkcmVzcwEHYWRkcmVzcwQHJG1hdGNoMAkApggBBQdhZGRyZXNzAwkAAQIFByRtYXRjaDACB0FkZHJlc3MEAWEFByRtYXRjaDAGBwAPQURNSU5fTElTVF9TSVpFAAUABlFVT1JVTQADABFUWElEX0JZVEVTX0xFTkdUSAAgARhrZXlBbGxvd2VkVHhJZFZvdGVQcmVmaXgBBHR4SWQJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIJYWxsb3dUeElkCQDMCAIFBHR4SWQFA25pbAUDU0VQARBrZXlGdWxsQWRtaW5Wb3RlAgZwcmVmaXgMYWRtaW5BZGRyZXNzCQC5CQIJAMwIAgUGcHJlZml4CQDMCAIFDGFkbWluQWRkcmVzcwUDbmlsBQNTRVABE2tleUFkbWluQWRkcmVzc0xpc3QACQC5CQIJAMwIAgICJXMJAMwIAgIQYWRtaW5BZGRyZXNzTGlzdAUDbmlsBQNTRVABDmtleUFsbG93ZWRUeElkAAkAuQkCCQDMCAICAiVzCQDMCAICBHR4SWQFA25pbAUDU0VQAQxnZXRBZG1pblZvdGUCBnByZWZpeAVhZG1pbgQHdm90ZUtleQkBEGtleUZ1bGxBZG1pblZvdGUCBQZwcmVmaXgFBWFkbWluCQELdmFsdWVPckVsc2UCCQCfCAEFB3ZvdGVLZXkAAAENZ2V0QWRtaW5zTGlzdAAEByRtYXRjaDAJAJ0IAgUEdGhpcwkBE2tleUFkbWluQWRkcmVzc0xpc3QAAwkAAQIFByRtYXRjaDACBlN0cmluZwQBcwUHJG1hdGNoMAkAtQkCBQFzBQNTRVAFA25pbAENaXNJbkFkbWluTGlzdAEHYWRkcmVzcwkBD2NvbnRhaW5zRWxlbWVudAIJAQ1nZXRBZG1pbnNMaXN0AAUHYWRkcmVzcwESZ2VuVm90ZXNLZXlzSGVscGVyAgFhDGFkbWluQWRkcmVzcwQLJHQwNTE4NTUyMDkFAWEEBnJlc3VsdAgFCyR0MDUxODU1MjA5Al8xBAZwcmVmaXgIBQskdDA1MTg1NTIwOQJfMgkAlAoCCQDNCAIFBnJlc3VsdAkBEGtleUZ1bGxBZG1pblZvdGUCBQZwcmVmaXgFDGFkbWluQWRkcmVzcwUGcHJlZml4AQxnZW5Wb3Rlc0tleXMBCWtleVByZWZpeAQJYWRtaW5MaXN0CQETa2V5QWRtaW5BZGRyZXNzTGlzdAAECyR0MDUzNTY1NDQwCgACJGwJAQ1nZXRBZG1pbnNMaXN0AAoAAiRzCQCQAwEFAiRsCgAFJGFjYzAJAJQKAgUDbmlsBQlrZXlQcmVmaXgKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEmdlblZvdGVzS2V5c0hlbHBlcgIFAiRhCQCRAwIFAiRsBQIkaQoBBSRmMF8yAgIkYQIkaQMJAGcCBQIkaQUCJHMFAiRhCQACAQITTGlzdCBzaXplIGV4Y2VlZHMgNQkBBSRmMF8yAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgkBBSRmMF8xAgUFJGFjYzAAAAABAAIAAwAEAAUEBnJlc3VsdAgFCyR0MDUzNTY1NDQwAl8xBAZwcmVmaXgIBQskdDA1MzU2NTQ0MAJfMgUGcmVzdWx0ARBjb3VudFZvdGVzSGVscGVyAgZyZXN1bHQHdm90ZUtleQkAZAIFBnJlc3VsdAkBC3ZhbHVlT3JFbHNlAgkAnwgBBQd2b3RlS2V5AAABCmNvdW50Vm90ZXMBBnByZWZpeAQFdm90ZXMJAQxnZW5Wb3Rlc0tleXMBBQZwcmVmaXgKAAIkbAUFdm90ZXMKAAIkcwkAkAMBBQIkbAoABSRhY2MwAAAKAQUkZjBfMQICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkBEGNvdW50Vm90ZXNIZWxwZXICBQIkYQkAkQMCBQIkbAUCJGkKAQUkZjBfMgICJGECJGkDCQBnAgUCJGkFAiRzBQIkYQkAAgECE0xpc3Qgc2l6ZSBleGNlZWRzIDUJAQUkZjBfMgIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIJAQUkZjBfMQIFBSRhY2MwAAAAAQACAAMABAAFARBjbGVhclZvdGVzSGVscGVyAgZyZXN1bHQDa2V5CQDNCAIFBnJlc3VsdAkBC0RlbGV0ZUVudHJ5AQUDa2V5ARNnZXRDbGVhclZvdGVFbnRyaWVzAQZwcmVmaXgEBXZvdGVzCQEMZ2VuVm90ZXNLZXlzAQUGcHJlZml4CgACJGwFBXZvdGVzCgACJHMJAJADAQUCJGwKAAUkYWNjMAUDbmlsCgEFJGYwXzECAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJARBjbGVhclZvdGVzSGVscGVyAgUCJGEJAJEDAgUCJGwFAiRpCgEFJGYwXzICAiRhAiRpAwkAZwIFAiRpBQIkcwUCJGEJAAIBAhNMaXN0IHNpemUgZXhjZWVkcyA1CQEFJGYwXzICCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECCQEFJGYwXzECBQUkYWNjMAAAAAEAAgADAAQABQEMdm90ZUlOVEVSTkFMBBNjYWxsZXJBZGRyZXNzU3RyaW5nCWtleVByZWZpeAhtaW5Wb3Rlcwp2b3RlUmVzdWx0BAd2b3RlS2V5CQEQa2V5RnVsbEFkbWluVm90ZQIFCWtleVByZWZpeAUTY2FsbGVyQWRkcmVzc1N0cmluZwQQYWRtaW5DdXJyZW50Vm90ZQkBDGdldEFkbWluVm90ZQIFCWtleVByZWZpeAUTY2FsbGVyQWRkcmVzc1N0cmluZwQDZXJyAwkBASEBCQENaXNJbkFkbWluTGlzdAEFE2NhbGxlckFkZHJlc3NTdHJpbmcJAQh0aHJvd0VycgEJAKwCAgkArAICAglBZGRyZXNzOiAFE2NhbGxlckFkZHJlc3NTdHJpbmcCEiBub3QgaW4gQWRtaW4gbGlzdAMJAAACBRBhZG1pbkN1cnJlbnRWb3RlAAEJAQh0aHJvd0VycgEJAKwCAgUHdm90ZUtleQISIHlvdSBhbHJlYWR5IHZvdGVkBQR1bml0AwkAAAIFA2VycgUDZXJyBAV2b3RlcwkBCmNvdW50Vm90ZXMBBQlrZXlQcmVmaXgDCQBnAgkAZAIFBXZvdGVzAAEFCG1pblZvdGVzBBBjbGVhclZvdGVFbnRyaWVzCQETZ2V0Q2xlYXJWb3RlRW50cmllcwEFCWtleVByZWZpeAkAzggCBRBjbGVhclZvdGVFbnRyaWVzBQp2b3RlUmVzdWx0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQd2b3RlS2V5AAEFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgETZ2V0TGVhc2luZ05vZGVFbnRyeQMLbm9kZUFkZHJlc3MNY3VycmVudExlYXNlZApuZXh0TGVhc2VkBAt2YWx1ZVN0cmluZwkAuQkCCQDMCAICCCVkJWQlZCVkCQDMCAIJAKQDAQUTY3VycmVudFBlcmlvZEhlaWdodAkAzAgCCQCkAwEFDWN1cnJlbnRMZWFzZWQJAMwIAgkApAMBBRBuZXh0UGVyaW9kSGVpZ2h0CQDMCAIJAKQDAQUKbmV4dExlYXNlZAUDbmlsBQNTRVAJAQtTdHJpbmdFbnRyeQIJARJrZXlMZWFzaW5nTm9kZURhdGEBBQtub2RlQWRkcmVzcwULdmFsdWVTdHJpbmcBEmdldExlYXNpbmdOb2RlRGF0YQELbm9kZUFkZHJlc3MEGGxlYXNpbmdOb2RlRGF0YVN0cmluZ1JhdwkAnQgCBQR0aGlzCQESa2V5TGVhc2luZ05vZGVEYXRhAQULbm9kZUFkZHJlc3MEByRtYXRjaDAFGGxlYXNpbmdOb2RlRGF0YVN0cmluZ1JhdwMJAAECBQckbWF0Y2gwAgZTdHJpbmcEAmRzBQckbWF0Y2gwBAhkYXRhTGlzdAkAtQkCBQJkcwUDU0VQBBFub2RlQ3VycmVudFBlcmlvZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGRhdGFMaXN0AAEEEW5vZGVDdXJyZW50TGVhc2VkCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIZGF0YUxpc3QAAgQObm9kZU5leHRQZXJpb2QJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhkYXRhTGlzdAADBA5ub2RlTmV4dExlYXNlZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGRhdGFMaXN0AAQDAwkAZgIFDm5vZGVOZXh0UGVyaW9kBQZoZWlnaHQGCQAAAgUScGVyaW9kT2Zmc2V0SGVpZ2h0AP///////////wEJAJQKAgURbm9kZUN1cnJlbnRMZWFzZWQFDm5vZGVOZXh0TGVhc2VkCQCUCgIFDm5vZGVOZXh0TGVhc2VkBQ5ub2RlTmV4dExlYXNlZAkAlAoCAAAAAAETZ2V0VXNlckxlYXNpbmdFbnRyeQQLbm9kZUFkZHJlc3MLdXNlckFkZHJlc3MRdXNlckN1cnJlbnRMZWFzZWQOdXNlck5leHRMZWFzZWQEC3ZhbHVlU3RyaW5nCQC5CQIJAMwIAgIIJWQlZCVkJWQJAMwIAgkApAMBBRNjdXJyZW50UGVyaW9kSGVpZ2h0CQDMCAIJAKQDAQURdXNlckN1cnJlbnRMZWFzZWQJAMwIAgkApAMBBRBuZXh0UGVyaW9kSGVpZ2h0CQDMCAIJAKQDAQUOdXNlck5leHRMZWFzZWQFA25pbAUDU0VQCQELU3RyaW5nRW50cnkCCQEWa2V5VXNlckxlYXNpbmdOb2RlRGF0YQIFC3VzZXJBZGRyZXNzBQtub2RlQWRkcmVzcwULdmFsdWVTdHJpbmcBEmdldFVzZXJMZWFzaW5nRGF0YQILbm9kZUFkZHJlc3MLdXNlckFkZHJlc3MEGGxlYXNpbmdVc2VyRGF0YVN0cmluZ1JhdwkAnQgCBQR0aGlzCQEWa2V5VXNlckxlYXNpbmdOb2RlRGF0YQIFC3VzZXJBZGRyZXNzBQtub2RlQWRkcmVzcwQHJG1hdGNoMAUYbGVhc2luZ1VzZXJEYXRhU3RyaW5nUmF3AwkAAQIFByRtYXRjaDACBlN0cmluZwQCZHMFByRtYXRjaDAECGRhdGFMaXN0CQC1CQIFAmRzBQNTRVAEEXVzZXJDdXJyZW50UGVyaW9kCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIZGF0YUxpc3QAAQQRdXNlckN1cnJlbnRMZWFzZWQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhkYXRhTGlzdAACBA51c2VyTmV4dFBlcmlvZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGRhdGFMaXN0AAMEDnVzZXJOZXh0TGVhc2VkCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIZGF0YUxpc3QABAMDCQBmAgUOdXNlck5leHRQZXJpb2QFBmhlaWdodAYJAAACBRJwZXJpb2RPZmZzZXRIZWlnaHQA////////////AQkAlAoCBRF1c2VyQ3VycmVudExlYXNlZAUOdXNlck5leHRMZWFzZWQJAJQKAgUOdXNlck5leHRMZWFzZWQFDnVzZXJOZXh0TGVhc2VkCQCUCgIAAAAAARNnZXRVc2VyVG9DbGFpbUVudHJ5Awt1c2VyQWRkcmVzcwd0b0NsYWltCHRvVW5sb2NrBAt2YWx1ZVN0cmluZwkAuQkCCQDMCAICCCVkJWQlZCVkCQDMCAIJAKQDAQUTY3VycmVudFBlcmlvZEhlaWdodAkAzAgCCQCkAwEFB3RvQ2xhaW0JAMwIAgkApAMBBRBuZXh0UGVyaW9kSGVpZ2h0CQDMCAIJAKQDAQUIdG9VbmxvY2sFA25pbAUDU0VQCQELU3RyaW5nRW50cnkCCQEOa2V5VXNlclRvQ2xhaW0BBQt1c2VyQWRkcmVzcwULdmFsdWVTdHJpbmcBFWdldFVzZXJUb0NsYWltQmFsYW5jZQELdXNlckFkZHJlc3MEGHVzZXJUb0NsYWltRGF0YVN0cmluZ1JhdwkAnQgCBQR0aGlzCQEOa2V5VXNlclRvQ2xhaW0BBQt1c2VyQWRkcmVzcwQHJG1hdGNoMAUYdXNlclRvQ2xhaW1EYXRhU3RyaW5nUmF3AwkAAQIFByRtYXRjaDACBlN0cmluZwQCZHMFByRtYXRjaDAECGRhdGFMaXN0CQC1CQIFAmRzBQNTRVAEDWN1cnJlbnRQZXJpb2QJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQhkYXRhTGlzdAABBAd0b0NsYWltCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIZGF0YUxpc3QAAgQKbmV4dFBlcmlvZAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFCGRhdGFMaXN0AAMECHRvVW5sb2NrCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUIZGF0YUxpc3QABAMDCQBmAgUKbmV4dFBlcmlvZAUGaGVpZ2h0BgkAAAIFD2N1cnJlbnRQZXJpb2RJZAAACQCUCgIFB3RvQ2xhaW0FCHRvVW5sb2NrCQCUCgIJAGQCBQd0b0NsYWltBQh0b1VubG9jawAACQCUCgIAAAAAARdnZXRVc2VyVG90YWxMb2NrZWRFbnRyeQILdXNlckFkZHJlc3MPdXNlclRvdGFsTG9ja2VkCQEMSW50ZWdlckVudHJ5AgkBEmtleVVzZXJUb3RhbExvY2tlZAEFC3VzZXJBZGRyZXNzBQ91c2VyVG90YWxMb2NrZWQBEmdldFVzZXJUb3RhbExvY2tlZAELdXNlckFkZHJlc3MJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBEmtleVVzZXJUb3RhbExvY2tlZAEFC3VzZXJBZGRyZXNzAAABFWNhbGN1bGF0ZVVuaXRzVG9DbGFpbQELdXNlckFkZHJlc3MED2NsYWltZWRCbG9ja0tleQkBFGtleVVuaXRzQ2xhaW1lZEJsb2NrAQULdXNlckFkZHJlc3MEDGNsYWltZWRCbG9jawkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQ9jbGFpbWVkQmxvY2tLZXkFFXVuaXRzQ2xhaW1TdGFydEhlaWdodAQUdW5pdHNQZXJCbG9ja1NjYWxlMTYJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUXa2V5VW5pdHNQZXJCbG9ja1NjYWxlMTYAAAQMY3VycmVudEJsb2NrCQCXAwEJAMwIAgkAZAIFFXVuaXRzQ2xhaW1TdGFydEhlaWdodAUSdW5pdHNDbGFpbUludGVydmFsCQDMCAIFBmhlaWdodAUDbmlsBAxibG9ja3NQYXNzZWQJAGUCBQxjdXJyZW50QmxvY2sFDGNsYWltZWRCbG9jawQMYW1vdW50U3Rha2VkCQESZ2V0VXNlclRvdGFsTG9ja2VkAQULdXNlckFkZHJlc3MECGwyVG9CdXJuCQBrAwUMYW1vdW50U3Rha2VkBQxibG9ja3NQYXNzZWQFEnVuaXRzQ2xhaW1JbnRlcnZhbAQPdW5pdHNUb0NsYWltTm93CQBrAwUMYW1vdW50U3Rha2VkCQBoAgUUdW5pdHNQZXJCbG9ja1NjYWxlMTYFDGJsb2Nrc1Bhc3NlZAUHc2NhbGUxNgkAlgoEBQ91bml0c1RvQ2xhaW1Ob3cFCGwyVG9CdXJuBQxjdXJyZW50QmxvY2sJAJUKAwUMYmxvY2tzUGFzc2VkBRV1bml0c0NsYWltU3RhcnRIZWlnaHQFEnVuaXRzQ2xhaW1JbnRlcnZhbAEUZ2V0VW5sb2NrVW5pdHNBY3Rpb24BC3VzZXJBZGRyZXNzBA5rVW5sb2NrZWRVbml0cwkBEGtleVVubG9ja2VkVW5pdHMBBQt1c2VyQWRkcmVzcwQNdW5sb2NrZWRVbml0cwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQ5rVW5sb2NrZWRVbml0cwAABAlrTDJUb0J1cm4JAQtrZXlMMlRvQnVybgEFC3VzZXJBZGRyZXNzBAhsMlRvQnVybgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQlrTDJUb0J1cm4AAAQNdG90YWxMMkxvY2tlZAkBEmdldFVzZXJUb3RhbExvY2tlZAEFC3VzZXJBZGRyZXNzBA0kdDAxMTQ5NjExNzA2CQEVY2FsY3VsYXRlVW5pdHNUb0NsYWltAQULdXNlckFkZHJlc3MED3VuaXRzVG9DbGFpbU5vdwgFDSR0MDExNDk2MTE3MDYCXzEEC2wyVG9CdXJuTm93CAUNJHQwMTE0OTYxMTcwNgJfMgQMY3VycmVudEJsb2NrCAUNJHQwMTE0OTYxMTcwNgJfMwQEX3RtcAgFDSR0MDExNDk2MTE3MDYCXzQDCQBnAgAABQ91bml0c1RvQ2xhaW1Ob3cDCQBmAgUNdG90YWxMMkxvY2tlZAAABQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJARRrZXlVbml0c0NsYWltZWRCbG9jawEFC3VzZXJBZGRyZXNzBQxjdXJyZW50QmxvY2sFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFGtleVVuaXRzQ2xhaW1lZEJsb2NrAQULdXNlckFkZHJlc3MFDGN1cnJlbnRCbG9jawkAzAgCCQEMSW50ZWdlckVudHJ5AgUJa0wyVG9CdXJuCQBkAgUIbDJUb0J1cm4FC2wyVG9CdXJuTm93CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQ5rVW5sb2NrZWRVbml0cwkAZAIFDXVubG9ja2VkVW5pdHMFD3VuaXRzVG9DbGFpbU5vdwUDbmlsARFnZXRVbnN0YWtlQWN0aW9ucwMLbm9kZUFkZHJlc3MLdXNlckFkZHJlc3MNdW5zdGFrZUFtb3VudAQNJHQwMTIyNzcxMjM1MAkBEmdldExlYXNpbmdOb2RlRGF0YQEFC25vZGVBZGRyZXNzBBFub2RlQ3VycmVudExlYXNlZAgFDSR0MDEyMjc3MTIzNTACXzEEDm5vZGVOZXh0TGVhc2VkCAUNJHQwMTIyNzcxMjM1MAJfMgQNJHQwMTIzNTUxMjQ0MQkBEmdldFVzZXJMZWFzaW5nRGF0YQIFC25vZGVBZGRyZXNzBQt1c2VyQWRkcmVzcwQRdXNlckN1cnJlbnRMZWFzZWQIBQ0kdDAxMjM1NTEyNDQxAl8xBA51c2VyTmV4dExlYXNlZAgFDSR0MDEyMzU1MTI0NDECXzIEBmNoZWNrcwkAzAgCAwkBASEBBQtpc0ZvcmNlU3RvcAYJAQh0aHJvd0VycgECHWNvbnRyYWN0IGlzIHRlbXBvcmFyeSBzdG9wcGVkCQDMCAIDCQEBIQEFDmlzRm9yY2VPdXRTdG9wBgkBCHRocm93RXJyAQIddW5zdGFrZSBpcyB0ZW1wb3JhcnkgZGlzYWJsZWQJAMwIAgMJAGYCBQ11bnN0YWtlQW1vdW50AAAGCQEIdGhyb3dFcnIBAid1bnN0YWtlIGFtb3VudCBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIDAJAMwIAgMJAGcCBQ51c2VyTmV4dExlYXNlZAUNdW5zdGFrZUFtb3VudAYJAQh0aHJvd0VycgECOXVuc3Rha2UgYW1vdW50IHNob3VsZCBiZSBsZXNzIG9yIGVxdWFsIHVzZXIgc3Rha2VkIGFtb3VudAkAzAgCAwkAZwIFDm5vZGVOZXh0TGVhc2VkBQ11bnN0YWtlQW1vdW50BgkBCHRocm93RXJyAQI5dW5zdGFrZSBhbW91bnQgc2hvdWxkIGJlIGxlc3Mgb3IgZXF1YWwgbm9kZSBzdGFrZWQgYW1vdW50CQDMCAIDCQEOaXNWYWxpZEFkZHJlc3MBBQtub2RlQWRkcmVzcwYJAQh0aHJvd0VycgEJALkJAgkAzAgCAhpub2RlIGFkZHJlc3MgaXMgbm90IHZhbGlkOgkAzAgCBQtub2RlQWRkcmVzcwUDbmlsAgEgCQDMCAIDCQEOaXNWYWxpZEFkZHJlc3MBBQt1c2VyQWRkcmVzcwYJAQh0aHJvd0VycgEJALkJAgkAzAgCAhp1c2VyIGFkZHJlc3MgaXMgbm90IHZhbGlkOgkAzAgCBQt1c2VyQWRkcmVzcwUDbmlsAgEgBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MEEG5ld05vZGVOZXh0TGVhc2UJAGUCBQ5ub2RlTmV4dExlYXNlZAUNdW5zdGFrZUFtb3VudAQRbmV3VXNlck5leHRMZWFzZWQJAGUCBQ51c2VyTmV4dExlYXNlZAUNdW5zdGFrZUFtb3VudAQNJHQwMTMzMjUxMzM4NQkBFWdldFVzZXJUb0NsYWltQmFsYW5jZQEFC3VzZXJBZGRyZXNzBAd0b0NsYWltCAUNJHQwMTMzMjUxMzM4NQJfMQQIdG9VbmxvY2sIBQ0kdDAxMzMyNTEzMzg1Al8yBAtuZXdUb1VubG9jawkAZAIFCHRvVW5sb2NrBQ11bnN0YWtlQW1vdW50BA91c2VyVG90YWxMb2NrZWQJARJnZXRVc2VyVG90YWxMb2NrZWQBBQt1c2VyQWRkcmVzcwQSbmV3VXNlclRvdGFsTG9ja2VkCQBlAgUPdXNlclRvdGFsTG9ja2VkBQ11bnN0YWtlQW1vdW50BBR1bml0c1VubG9ja2VkQWN0aW9ucwkBFGdldFVubG9ja1VuaXRzQWN0aW9uAQULdXNlckFkZHJlc3MJAM4IAgkAzAgCCQETZ2V0TGVhc2luZ05vZGVFbnRyeQMFC25vZGVBZGRyZXNzBRFub2RlQ3VycmVudExlYXNlZAUQbmV3Tm9kZU5leHRMZWFzZQkAzAgCCQETZ2V0VXNlckxlYXNpbmdFbnRyeQQFC25vZGVBZGRyZXNzBQt1c2VyQWRkcmVzcwURdXNlckN1cnJlbnRMZWFzZWQFEW5ld1VzZXJOZXh0TGVhc2VkCQDMCAIJARNnZXRVc2VyVG9DbGFpbUVudHJ5AwULdXNlckFkZHJlc3MFB3RvQ2xhaW0FC25ld1RvVW5sb2NrCQDMCAIJARdnZXRVc2VyVG90YWxMb2NrZWRFbnRyeQIFC3VzZXJBZGRyZXNzBRJuZXdVc2VyVG90YWxMb2NrZWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlOb2RlTGVhc2luZ0J5SGVpZ2h0AQULbm9kZUFkZHJlc3MFEG5ld05vZGVOZXh0TGVhc2UJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlVc2VyTGVhc2luZ0J5SGVpZ2h0AgULbm9kZUFkZHJlc3MFC3VzZXJBZGRyZXNzBRFuZXdVc2VyTmV4dExlYXNlZAUDbmlsBRR1bml0c1VubG9ja2VkQWN0aW9ucwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEXZ2V0Q2xhaW1VbmxvY2tlZEFjdGlvbnMCC3VzZXJBZGRyZXNzC2NsYWltQW1vdW50BA0kdDAxNDIwNDE0MjY0CQEVZ2V0VXNlclRvQ2xhaW1CYWxhbmNlAQULdXNlckFkZHJlc3MEB3RvQ2xhaW0IBQ0kdDAxNDIwNDE0MjY0Al8xBAh0b1VubG9jawgFDSR0MDE0MjA0MTQyNjQCXzIEBmNoZWNrcwkAzAgCAwkBASEBBQtpc0ZvcmNlU3RvcAYJAQh0aHJvd0VycgECHWNvbnRyYWN0IGlzIHRlbXBvcmFyeSBzdG9wcGVkCQDMCAIDCQEBIQEFDmlzRm9yY2VPdXRTdG9wBgkBCHRocm93RXJyAQIbY2xhaW0gaXMgdGVtcG9yYXJ5IGRpc2FibGVkCQDMCAIDCQBmAgULY2xhaW1BbW91bnQAAAYJAQh0aHJvd0VycgECJWNsYWltIGFtb3VudCBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIDAJAMwIAgMJAGcCBQd0b0NsYWltBQtjbGFpbUFtb3VudAYJAQh0aHJvd0VycgECNGNsYWltIGFtb3VudCBzaG91bGQgYmUgbGVzcyBvciBlcXVhbCB1bmxvY2tlZCBhbW91bnQJAMwIAgMJAQ5pc1ZhbGlkQWRkcmVzcwEFC3VzZXJBZGRyZXNzBgkBCHRocm93RXJyAQkAuQkCCQDMCAICGnVzZXIgYWRkcmVzcyBpcyBub3QgdmFsaWQ6CQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwCASAFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwQKbmV3VG9DbGFpbQkAZQIFB3RvQ2xhaW0FC2NsYWltQW1vdW50CQDMCAIJARNnZXRVc2VyVG9DbGFpbUVudHJ5AwULdXNlckFkZHJlc3MFCm5ld1RvQ2xhaW0FCHRvVW5sb2NrCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFC3VzZXJBZGRyZXNzBQtjbGFpbUFtb3VudAUObDJBc3NldElkQnl0ZXMFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgESZ2V0U3Rha2VGb3JBY3Rpb25zAgt1c2VyQWRkcmVzcwFpBA0kdDAxNTAzMDE1MDkwCQEVZ2V0VXNlclRvQ2xhaW1CYWxhbmNlAQULdXNlckFkZHJlc3MEB3RvQ2xhaW0IBQ0kdDAxNTAzMDE1MDkwAl8xBAh0b1VubG9jawgFDSR0MDE1MDMwMTUwOTACXzIEBmNoZWNrcwkAzAgCAwkBASEBBQtpc0ZvcmNlU3RvcAYJAQh0aHJvd0VycgECHWNvbnRyYWN0IGlzIHRlbXBvcmFyeSBzdG9wcGVkCQDMCAIDCQBnAgABCQCQAwEIBQFpCHBheW1lbnRzBgkBCHRocm93RXJyAQIRbWF4aW11bSAxIHBheW1lbnQJAMwIAgMDCQAAAgkAkAMBCAUBaQhwYXltZW50cwAABgkAAAIICQCRAwIIBQFpCHBheW1lbnRzAAAHYXNzZXRJZAUObDJBc3NldElkQnl0ZXMGCQEIdGhyb3dFcnIBCQC5CQIJAMwIAgIacGF5bWVudCBhc3NldElkIHNob3VsZCBiZToJAMwIAgUPbDJBc3NldElkU3RyaW5nBQNuaWwCASAJAMwIAgMJAQ5pc1ZhbGlkQWRkcmVzcwEFC3VzZXJBZGRyZXNzBgkBCHRocm93RXJyAQkAuQkCCQDMCAICGnVzZXIgYWRkcmVzcyBpcyBub3QgdmFsaWQ6CQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwCASAFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwQKbmV3VG9DbGFpbQkAZAIFB3RvQ2xhaW0ICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50CQDMCAIJARNnZXRVc2VyVG9DbGFpbUVudHJ5AwULdXNlckFkZHJlc3MFCm5ld1RvQ2xhaW0FCHRvVW5sb2NrBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BD2dldFN0YWtlQWN0aW9ucwQLbm9kZUFkZHJlc3MLdXNlckFkZHJlc3MRdXNlckxlYXNpbmdBbW91bnQBaQQNJHQwMTU4MjIxNTg4MgkBFWdldFVzZXJUb0NsYWltQmFsYW5jZQEFC3VzZXJBZGRyZXNzBAd0b0NsYWltCAUNJHQwMTU4MjIxNTg4MgJfMQQIdG9VbmxvY2sIBQ0kdDAxNTgyMjE1ODgyAl8yBA1wYXltZW50QW1vdW50AwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAAAACAkAkQMCCAUBaQhwYXltZW50cwAABmFtb3VudAQJYXZhaWxhYmxlCQBkAgkAZAIFCHRvVW5sb2NrBQd0b0NsYWltBQ1wYXltZW50QW1vdW50BAZjaGVja3MJAMwIAgMJAQEhAQULaXNGb3JjZVN0b3AGCQEIdGhyb3dFcnIBAh1jb250cmFjdCBpcyB0ZW1wb3Jhcnkgc3RvcHBlZAkAzAgCAwkAZwIAAQkAkAMBCAUBaQhwYXltZW50cwYJAQh0aHJvd0VycgECEW1heGltdW0gMSBwYXltZW50CQDMCAIDAwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAAYJAAACCAkAkQMCCAUBaQhwYXltZW50cwAAB2Fzc2V0SWQFDmwyQXNzZXRJZEJ5dGVzBgkBCHRocm93RXJyAQkAuQkCCQDMCAICGnBheW1lbnQgYXNzZXRJZCBzaG91bGQgYmU6CQDMCAIFD2wyQXNzZXRJZFN0cmluZwUDbmlsAgEgCQDMCAIDCQBmAgURdXNlckxlYXNpbmdBbW91bnQAAAYJAQh0aHJvd0VycgECH2Ftb3VudCBzaG91bGQgYmUgZ3JlYXRlciB0aGFuIDAJAMwIAgMJAGcCBQlhdmFpbGFibGUFEXVzZXJMZWFzaW5nQW1vdW50BgkBCHRocm93RXJyAQI7YW1vdW50IHNob3VsZCBiZSBsZXNzIG9yIGVxdWFsIChwYXltZW50ICsgYXZhaWxhYmxlKSBhbW91bnQJAMwIAgMJAGcCBRF1c2VyTGVhc2luZ0Ftb3VudAUNcGF5bWVudEFtb3VudAYJAAIBAjBhbW91bnQgc2hvdWxkIGJlIGdyZWF0ZXIgb3IgZXF1YWwgcGF5bWVudCBhbW91bnQJAMwIAgMJAQ5pc1ZhbGlkQWRkcmVzcwEFC25vZGVBZGRyZXNzBgkBCHRocm93RXJyAQkAuQkCCQDMCAICGm5vZGUgYWRkcmVzcyBpcyBub3QgdmFsaWQ6CQDMCAIFC25vZGVBZGRyZXNzBQNuaWwCASAJAMwIAgMJAQ5pc1ZhbGlkQWRkcmVzcwEFC3VzZXJBZGRyZXNzBgkBCHRocm93RXJyAQkAuQkCCQDMCAICGnVzZXIgYWRkcmVzcyBpcyBub3QgdmFsaWQ6CQDMCAIFC3VzZXJBZGRyZXNzBQNuaWwCASAFA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwQNJHQwMTY5NTcxNzAzMAkBEmdldExlYXNpbmdOb2RlRGF0YQEFC25vZGVBZGRyZXNzBBFub2RlQ3VycmVudExlYXNlZAgFDSR0MDE2OTU3MTcwMzACXzEEDm5vZGVOZXh0TGVhc2VkCAUNJHQwMTY5NTcxNzAzMAJfMgQQbmV3Tm9kZU5leHRMZWFzZQkAZAIFDm5vZGVOZXh0TGVhc2VkBRF1c2VyTGVhc2luZ0Ftb3VudAQNJHQwMTcwOTgxNzE4NAkBEmdldFVzZXJMZWFzaW5nRGF0YQIFC25vZGVBZGRyZXNzBQt1c2VyQWRkcmVzcwQRdXNlckN1cnJlbnRMZWFzZWQIBQ0kdDAxNzA5ODE3MTg0Al8xBA51c2VyTmV4dExlYXNlZAgFDSR0MDE3MDk4MTcxODQCXzIEEW5ld1VzZXJOZXh0TGVhc2VkCQBkAgUOdXNlck5leHRMZWFzZWQFEXVzZXJMZWFzaW5nQW1vdW50BBJmcm9tVW5sb2NrZWRBbW91bnQJAGUCBRF1c2VyTGVhc2luZ0Ftb3VudAUNcGF5bWVudEFtb3VudAQLbmV3VG9VbmxvY2sJAJYDAQkAzAgCAAAJAMwIAgkAZQIFCHRvVW5sb2NrBRJmcm9tVW5sb2NrZWRBbW91bnQFA25pbAQKbmV3VG9DbGFpbQkAlwMBCQDMCAIFB3RvQ2xhaW0JAMwIAgkAZAIFB3RvQ2xhaW0JAGUCBQh0b1VubG9jawUSZnJvbVVubG9ja2VkQW1vdW50BQNuaWwED3VzZXJUb3RhbExvY2tlZAkBEmdldFVzZXJUb3RhbExvY2tlZAEFC3VzZXJBZGRyZXNzBBJuZXdVc2VyVG90YWxMb2NrZWQJAGQCBQ91c2VyVG90YWxMb2NrZWQFEXVzZXJMZWFzaW5nQW1vdW50BBR1bml0c1VubG9ja2VkQWN0aW9ucwkBFGdldFVubG9ja1VuaXRzQWN0aW9uAQULdXNlckFkZHJlc3MJAM4IAgkAzAgCCQETZ2V0TGVhc2luZ05vZGVFbnRyeQMFC25vZGVBZGRyZXNzBRFub2RlQ3VycmVudExlYXNlZAUQbmV3Tm9kZU5leHRMZWFzZQkAzAgCCQETZ2V0VXNlckxlYXNpbmdFbnRyeQQFC25vZGVBZGRyZXNzBQt1c2VyQWRkcmVzcwURdXNlckN1cnJlbnRMZWFzZWQFEW5ld1VzZXJOZXh0TGVhc2VkCQDMCAIJARNnZXRVc2VyVG9DbGFpbUVudHJ5AwULdXNlckFkZHJlc3MFCm5ld1RvQ2xhaW0FC25ld1RvVW5sb2NrCQDMCAIJARdnZXRVc2VyVG90YWxMb2NrZWRFbnRyeQIFC3VzZXJBZGRyZXNzBRJuZXdVc2VyVG90YWxMb2NrZWQJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlOb2RlTGVhc2luZ0J5SGVpZ2h0AQULbm9kZUFkZHJlc3MFEG5ld05vZGVOZXh0TGVhc2UJAMwIAgkBDEludGVnZXJFbnRyeQIJARZrZXlVc2VyTGVhc2luZ0J5SGVpZ2h0AgULbm9kZUFkZHJlc3MFC3VzZXJBZGRyZXNzBRFuZXdVc2VyTmV4dExlYXNlZAUDbmlsBRR1bml0c1VubG9ja2VkQWN0aW9ucwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEaZ2V0U3Rha2VGcm9tUGF5bWVudEFjdGlvbnMDC25vZGVBZGRyZXNzC3VzZXJBZGRyZXNzAWkEBmNoZWNrcwkAzAgCAwkAAAIJAJADAQgFAWkIcGF5bWVudHMAAQYJAQh0aHJvd0VycgECIHBheW1lbnQgc2l6ZSBzaG91bGQgYmUgZXhhY3RseSAxBQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MJAQ9nZXRTdGFrZUFjdGlvbnMEBQtub2RlQWRkcmVzcwULdXNlckFkZHJlc3MICQCRAwIIBQFpCHBheW1lbnRzAAAGYW1vdW50BQFpCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuARxnZXRTZXROZXdQZXJpb2RMZW5ndGhBY3Rpb25zAQ9uZXdQZXJpb2RMZW5ndGgEBWNoZWNrCQDMCAIDCQBmAgUPbmV3UGVyaW9kTGVuZ3RoAAAGCQEIdGhyb3dFcnIBAiZwZXJpb2QgbGVuZ3RoIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gMAUDbmlsAwkAAAIFBWNoZWNrBQVjaGVjawMJAAACBRJwZXJpb2RPZmZzZXRIZWlnaHQA////////////AQkAzAgCCQEMSW50ZWdlckVudHJ5AgUPa2V5UGVyaW9kTGVuZ3RoBQ9uZXdQZXJpb2RMZW5ndGgJAMwIAgkBDEludGVnZXJFbnRyeQIFFWtleVBlcmlvZE9mZnNldEhlaWdodAUGaGVpZ2h0BQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIFEWtleVBlcmlvZE9mZnNldElkCQBkAgUPY3VycmVudFBlcmlvZElkAAEJAMwIAgkBDEludGVnZXJFbnRyeQIFFWtleVBlcmlvZE9mZnNldEhlaWdodAUQbmV4dFBlcmlvZEhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUPa2V5UGVyaW9kTGVuZ3RoBQ9uZXdQZXJpb2RMZW5ndGgFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgERZ2V0VW5pdHNDbGFpbURhdGEBC3VzZXJBZGRyZXNzBA0kdDAxOTA2OTE5MTYwCQEVY2FsY3VsYXRlVW5pdHNUb0NsYWltAQULdXNlckFkZHJlc3MED3VubG9ja2VkVW5pdE5vdwgFDSR0MDE5MDY5MTkxNjACXzEEC2wyVG9CdXJuTm93CAUNJHQwMTkwNjkxOTE2MAJfMgQMY3VycmVudEJsb2NrCAUNJHQwMTkwNjkxOTE2MAJfMwQEX3RtcAgFDSR0MDE5MDY5MTkxNjACXzQEEXVubG9ja2VkVW5pdHNQcmV2CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJARBrZXlVbmxvY2tlZFVuaXRzAQULdXNlckFkZHJlc3MAAAQLdW5pdHNUb1NlbmQJAGQCBQ91bmxvY2tlZFVuaXROb3cFEXVubG9ja2VkVW5pdHNQcmV2BAxsMlRvQnVyblByZXYJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBC2tleUwyVG9CdXJuAQULdXNlckFkZHJlc3MAAAQIbDJUb0J1cm4JAGQCBQxsMlRvQnVyblByZXYFC2wyVG9CdXJuTm93BBF0b3RhbFVuaXRzQ2xhaW1lZAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEUa2V5VG90YWxVbml0c0NsYWltZWQBBQt1c2VyQWRkcmVzcwAABA10b3RhbEwyQnVybmVkCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJARBrZXlMMkJ1cm5lZFRvdGFsAQULdXNlckFkZHJlc3MAAAkAlwoFBQt1bml0c1RvU2VuZAURdG90YWxVbml0c0NsYWltZWQFCGwyVG9CdXJuBQ10b3RhbEwyQnVybmVkBQxjdXJyZW50QmxvY2sBFGdldENsYWltVW5pdHNBY3Rpb25zAQt1c2VyQWRkcmVzcwQNJHQwMTk3NTIxOTg2MAkBEWdldFVuaXRzQ2xhaW1EYXRhAQULdXNlckFkZHJlc3MEC3VuaXRzVG9TZW5kCAUNJHQwMTk3NTIxOTg2MAJfMQQRdG90YWxVbml0c0NsYWltZWQIBQ0kdDAxOTc1MjE5ODYwAl8yBAhsMlRvQnVybggFDSR0MDE5NzUyMTk4NjACXzMEDXRvdGFsTDJCdXJuZWQIBQ0kdDAxOTc1MjE5ODYwAl80BAxjbGFpbWVkQmxvY2sIBQ0kdDAxOTc1MjE5ODYwAl81BAVjaGVjawkAzAgCAwkAZgIFC3VuaXRzVG9TZW5kAAAGCQEIdGhyb3dFcnIBAhBub3RoaW5nIHRvIGNsYWltBQNuaWwDCQAAAgUFY2hlY2sFBWNoZWNrBApidXJuQWN0aW9uBAckbWF0Y2gwBQ5sMkFzc2V0SWRCeXRlcwMJAAECBQckbWF0Y2gwAgpCeXRlVmVjdG9yBAJpZAUHJG1hdGNoMAkAzAgCCQEEQnVybgIFAmlkBQhsMlRvQnVybgUDbmlsBQNuaWwJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFGtleVVuaXRzQ2xhaW1lZEJsb2NrAQULdXNlckFkZHJlc3MFDGNsYWltZWRCbG9jawkAzAgCCQEMSW50ZWdlckVudHJ5AgkBFGtleVRvdGFsVW5pdHNDbGFpbWVkAQULdXNlckFkZHJlc3MJAGQCBRF0b3RhbFVuaXRzQ2xhaW1lZAULdW5pdHNUb1NlbmQJAMwIAgkBDEludGVnZXJFbnRyeQIJARBrZXlMMkJ1cm5lZFRvdGFsAQULdXNlckFkZHJlc3MJAGQCBQ10b3RhbEwyQnVybmVkBQhsMlRvQnVybgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBEGtleVVubG9ja2VkVW5pdHMBBQt1c2VyQWRkcmVzcwAACQDMCAIJAQxJbnRlZ2VyRW50cnkCCQELa2V5TDJUb0J1cm4BBQt1c2VyQWRkcmVzcwAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFC3VzZXJBZGRyZXNzBQt1bml0c1RvU2VuZAURdW5pdHNBc3NldElkQnl0ZXMFA25pbAUKYnVybkFjdGlvbgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLhABaQESc2V0TmV3UGVyaW9kTGVuZ3RoAQ9uZXdQZXJpb2RMZW5ndGgEBmNoZWNrcwkAzAgCAwkBDWlzSW5BZG1pbkxpc3QBCQClCAEIBQFpBmNhbGxlcgYJAQh0aHJvd0VycgECGmNhbGxlciBpcyBub3QgaW4gYWRtaW5MaXN0BQNuaWwDCQAAAgUGY2hlY2tzBQZjaGVja3MJARxnZXRTZXROZXdQZXJpb2RMZW5ndGhBY3Rpb25zAQUPbmV3UGVyaW9kTGVuZ3RoCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBCmNsYWltVW5pdHMABAt1c2VyQWRkcmVzcwkApQgBCAUBaQZjYWxsZXIJARRnZXRDbGFpbVVuaXRzQWN0aW9ucwEFC3VzZXJBZGRyZXNzAWkBEHNldEZvcmNlU3RvcEZsYWcBBHN0b3AEBWNoZWNrCQDMCAIDCQENaXNJbkFkbWluTGlzdAEJAKUIAQgFAWkGY2FsbGVyBgkBCHRocm93RXJyAQIaY2FsbGVyIGlzIG5vdCBpbiBhZG1pbkxpc3QFA25pbAMJAAACBQVjaGVjawUFY2hlY2sJAMwIAgkBDEJvb2xlYW5FbnRyeQIFDGtleUZvcmNlU3RvcAUEc3RvcAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBE3NldEZvcmNlT3V0U3RvcEZsYWcBBHN0b3AEBWNoZWNrCQDMCAIDCQENaXNJbkFkbWluTGlzdAEJAKUIAQgFAWkGY2FsbGVyBgkBCHRocm93RXJyAQIaY2FsbGVyIGlzIG5vdCBpbiBhZG1pbkxpc3QFA25pbAMJAAACBQVjaGVjawUFY2hlY2sJAMwIAgkBDEJvb2xlYW5FbnRyeQIFD2tleUZvcmNlT3V0U3RvcAUEc3RvcAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAWkBE2dldE5vZGVEYXRhUkVBRE9OTFkBC25vZGVBZGRyZXNzBA0kdDAyMTU5MjIxNjU2CQESZ2V0TGVhc2luZ05vZGVEYXRhAQULbm9kZUFkZHJlc3MEDGN1cnJlbnRMZWFzZQgFDSR0MDIxNTkyMjE2NTYCXzEECm5leHRMZWFzZWQIBQ0kdDAyMTU5MjIxNjU2Al8yCQCUCgIFA25pbAkAlwoFBRNjdXJyZW50UGVyaW9kSGVpZ2h0BQxjdXJyZW50TGVhc2UFEG5leHRQZXJpb2RIZWlnaHQFCm5leHRMZWFzZWQFBmhlaWdodAFpARpnZXRVc2VyTGVhc2luZ0RhdGFSRUFET05MWQILbm9kZUFkZHJlc3MLdXNlckFkZHJlc3MEDSR0MDIyMDI2MjIxMDMJARJnZXRVc2VyTGVhc2luZ0RhdGECBQtub2RlQWRkcmVzcwULdXNlckFkZHJlc3MEDGN1cnJlbnRMZWFzZQgFDSR0MDIyMDI2MjIxMDMCXzEECm5leHRMZWFzZWQIBQ0kdDAyMjAyNjIyMTAzAl8yCQCUCgIFA25pbAkAlwoFBRNjdXJyZW50UGVyaW9kSGVpZ2h0BQxjdXJyZW50TGVhc2UFEG5leHRQZXJpb2RIZWlnaHQFCm5leHRMZWFzZWQFBmhlaWdodAFpARNnZXRVc2VyRGF0YVJFQURPTkxZAQt1c2VyQWRkcmVzcwQNJHQwMjI3MDcyMjc2NwkBFWdldFVzZXJUb0NsYWltQmFsYW5jZQEFC3VzZXJBZGRyZXNzBAd0b0NsYWltCAUNJHQwMjI3MDcyMjc2NwJfMQQIdG9VbmxvY2sIBQ0kdDAyMjcwNzIyNzY3Al8yBA91c2VyVG90YWxMb2NrZWQJARJnZXRVc2VyVG90YWxMb2NrZWQBBQt1c2VyQWRkcmVzcwQNJHQwMjI4MzAyMjkzOAkBEWdldFVuaXRzQ2xhaW1EYXRhAQULdXNlckFkZHJlc3MEC3VuaXRzVG9TZW5kCAUNJHQwMjI4MzAyMjkzOAJfMQQRdG90YWxVbml0c0NsYWltZWQIBQ0kdDAyMjgzMDIyOTM4Al8yBAhsMlRvQnVybggFDSR0MDIyODMwMjI5MzgCXzMEDXRvdGFsTDJCdXJuZWQIBQ0kdDAyMjgzMDIyOTM4Al80BAxjbGFpbWVkQmxvY2sIBQ0kdDAyMjgzMDIyOTM4Al81BBR1bml0c1BlckJsb2NrU2NhbGUxNgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBRdrZXlVbml0c1BlckJsb2NrU2NhbGUxNgAABA9yZW1haW5pbmdibG9ja3MJAJYDAQkAzAgCAAAJAMwIAgkAZQIJAGQCBRV1bml0c0NsYWltU3RhcnRIZWlnaHQFEnVuaXRzQ2xhaW1JbnRlcnZhbAUGaGVpZ2h0BQNuaWwJAJQKAgUDbmlsCQCfCg0FE2N1cnJlbnRQZXJpb2RIZWlnaHQFB3RvQ2xhaW0FEG5leHRQZXJpb2RIZWlnaHQFCHRvVW5sb2NrBQ91c2VyVG90YWxMb2NrZWQFBmhlaWdodAULdW5pdHNUb1NlbmQFEXRvdGFsVW5pdHNDbGFpbWVkBQhsMlRvQnVybgUNdG90YWxMMkJ1cm5lZAUMY2xhaW1lZEJsb2NrBRR1bml0c1BlckJsb2NrU2NhbGUxNgUPcmVtYWluaW5nYmxvY2tzAWkBDmxlYXNlQnlBZGRyZXNzAgtub2RlQWRkcmVzcwt1c2VyQWRkcmVzcwkBGmdldFN0YWtlRnJvbVBheW1lbnRBY3Rpb25zAwULbm9kZUFkZHJlc3MFC3VzZXJBZGRyZXNzBQFpAWkBBWxlYXNlAQtub2RlQWRkcmVzcwQLdXNlckFkZHJlc3MJAKUIAQgFAWkGY2FsbGVyCQEaZ2V0U3Rha2VGcm9tUGF5bWVudEFjdGlvbnMDBQtub2RlQWRkcmVzcwULdXNlckFkZHJlc3MFAWkBaQEPbGVhc2VGcm9tTG9ja2VkAgtub2RlQWRkcmVzcwZhbW91bnQEC3VzZXJBZGRyZXNzCQClCAEIBQFpBmNhbGxlcgkBD2dldFN0YWtlQWN0aW9ucwQFC25vZGVBZGRyZXNzBQt1c2VyQWRkcmVzcwUGYW1vdW50BQFpAWkBC2NhbmNlbExlYXNlAgtub2RlQWRkcmVzcwZhbW91bnQEC3VzZXJBZGRyZXNzCQClCAEIBQFpBmNhbGxlcgkBEWdldFVuc3Rha2VBY3Rpb25zAwULbm9kZUFkZHJlc3MFC3VzZXJBZGRyZXNzBQZhbW91bnQBaQEFY2xhaW0BBmFtb3VudAQLdXNlckFkZHJlc3MJAKUIAQgFAWkGY2FsbGVyCQEXZ2V0Q2xhaW1VbmxvY2tlZEFjdGlvbnMCBQt1c2VyQWRkcmVzcwUGYW1vdW50AWkBCGNsYWltQWxsAAQLdXNlckFkZHJlc3MJAKUIAQgFAWkGY2FsbGVyBA0kdDAyNDM2ODI0NDI4CQEVZ2V0VXNlclRvQ2xhaW1CYWxhbmNlAQULdXNlckFkZHJlc3MEB3RvQ2xhaW0IBQ0kdDAyNDM2ODI0NDI4Al8xBAh0b1VubG9jawgFDSR0MDI0MzY4MjQ0MjgCXzIEBmNoZWNrcwkAzAgCAwkAZgIFB3RvQ2xhaW0AAAYJAQh0aHJvd0VycgECEG5vdGhpbmcgdG8gY2xhaW0FA25pbAMJAAACBQZjaGVja3MFBmNoZWNrcwkBF2dldENsYWltVW5sb2NrZWRBY3Rpb25zAgULdXNlckFkZHJlc3MFB3RvQ2xhaW0JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQEIc3Rha2VGb3IBC3VzZXJBZGRyZXNzCQESZ2V0U3Rha2VGb3JBY3Rpb25zAgULdXNlckFkZHJlc3MFAWkBaQERc3RhcnRVbml0c1Zlc3RpbmcEFXVuaXRzQ2xhaW1OZXdJbnRlcnZhbA10b3RhbEwyU3RyaW5nEnVuaXRzQXNzZXRJZHN0cmluZxF1bml0c0Ftb3VudFN0cmluZwQLdW5pdHNBbW91bnQJAQ1wYXJzZUludFZhbHVlAQURdW5pdHNBbW91bnRTdHJpbmcEB3RvdGFsTDIJAQ1wYXJzZUludFZhbHVlAQUNdG90YWxMMlN0cmluZwQKdW5pdHNBc3NldAkBEmFzc2V0U3RyaW5nVG9CeXRlcwEFEnVuaXRzQXNzZXRJZHN0cmluZwQUdW5pdHNQZXJCbG9ja1NjYWxlMTYJAGkCCQBrAwULdW5pdHNBbW91bnQFB3NjYWxlMTYFB3RvdGFsTDIFFXVuaXRzQ2xhaW1OZXdJbnRlcnZhbAQFY2hlY2sJAMwIAgMJAQ1pc0luQWRtaW5MaXN0AQkApQgBCAUBaQZjYWxsZXIGCQEIdGhyb3dFcnIBAhpjYWxsZXIgaXMgbm90IGluIGFkbWluTGlzdAkAzAgCAwkAZgIFFHVuaXRzUGVyQmxvY2tTY2FsZTE2AAAGCQEIdGhyb3dFcnIBAih1bml0cyBwZXIgYmxvY2sgc2hvdWxkIGJlIGdyZWF0ZWQgdGhhbiAwCQDMCAIDCQBmAgUHdG90YWxMMgAABgkBCHRocm93RXJyAQIhdG90YWwgbDIgc2hvdWxkIGJlIGdyZWF0ZWQgdGhhbiAwBQNuaWwDCQAAAgUFY2hlY2sFBWNoZWNrCQDMCAIJAQxJbnRlZ2VyRW50cnkCBRdrZXlVbml0c1BlckJsb2NrU2NhbGUxNgUUdW5pdHNQZXJCbG9ja1NjYWxlMTYJAMwIAgkBDEludGVnZXJFbnRyeQIFGGtleVVuaXRzQ2xhaW1TdGFydEhlaWdodAUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBRVrZXlVbml0c0NsYWltSW50ZXJ2YWwFFXVuaXRzQ2xhaW1OZXdJbnRlcnZhbAkAzAgCCQELU3RyaW5nRW50cnkCBQ9rZXlVbml0c0Fzc2V0SWQJARJhc3NldEJ5dGVzVG9TdHJpbmcBBQp1bml0c0Fzc2V0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BaQELdm90ZUZvclR4SWQBBHR4SWQEE2NhbGxlckFkZHJlc3NTdHJpbmcJANgEAQgIBQFpBmNhbGxlcgVieXRlcwQJa2V5UHJlZml4CQEYa2V5QWxsb3dlZFR4SWRWb3RlUHJlZml4AQUEdHhJZAQGcmVzdWx0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQ5rZXlBbGxvd2VkVHhJZAAFBHR4SWQFA25pbAQRYWxsb3dlZFR4SWRPcHRpb24JAJ0IAgUEdGhpcwkBDmtleUFsbG93ZWRUeElkAAQDZXJyCQDMCAIDCQAAAgkAyAEBCQDZBAEFBHR4SWQFEVRYSURfQllURVNfTEVOR1RIBgkBCHRocm93RXJyAQkArAICBQR0eElkAhIgaXMgbm90IHZhbGlkIHR4SWQJAMwIAgMDCQAAAgURYWxsb3dlZFR4SWRPcHRpb24FBHVuaXQGCQECIT0CCQEFdmFsdWUBBRFhbGxvd2VkVHhJZE9wdGlvbgUEdHhJZAYJAQh0aHJvd0VycgEJAKwCAgUEdHhJZAITIGlzIGFscmVhZHkgYWxsb3dlZAUDbmlsAwkAAAIFA2VycgUDZXJyCQEMdm90ZUlOVEVSTkFMBAUTY2FsbGVyQWRkcmVzc1N0cmluZwUJa2V5UHJlZml4BQZRVU9SVU0FBnJlc3VsdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECdHgBBnZlcmlmeQAECGJ5QWRtaW5zCQAAAggFAnR4AmlkCQDZBAEJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBDmtleUFsbG93ZWRUeElkAAIABAdieU93bmVyAwkAZwIJAJADAQkBDWdldEFkbWluc0xpc3QABQZRVU9SVU0HCQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAACAUCdHgPc2VuZGVyUHVibGljS2V5AwUIYnlBZG1pbnMGBQdieU93bmVySU5AbQ==", "chainId": 84, "height": 3361066, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: HHHH878bacptRiZ3QRyzMddiLuervF1hJTvyAEyKkjbp Next: none Diff:
OldNewDifferences
725725
726726
727727 @Callable(i)
728-func startUnitsVesting (unitsClaimNewInterval,totalL2String) = {
729- let totalUnits = i.payments[0].amount
728+func startUnitsVesting (unitsClaimNewInterval,totalL2String,unitsAssetIdstring,unitsAmountString) = {
729+ let unitsAmount = parseIntValue(unitsAmountString)
730730 let totalL2 = parseIntValue(totalL2String)
731- let unitsPerBlockScale16 = (fraction(totalUnits, scale16, totalL2) / unitsClaimNewInterval)
731+ let unitsAsset = assetStringToBytes(unitsAssetIdstring)
732+ let unitsPerBlockScale16 = (fraction(unitsAmount, scale16, totalL2) / unitsClaimNewInterval)
732733 let check = [if (isInAdminList(toString(i.caller)))
733734 then true
734- else throwErr("caller is not in adminList"), if ((size(i.payments) == 1))
735- then true
736- else throwErr("should be 1 payment"), if ((unitsPerBlockScale16 > 0))
735+ else throwErr("caller is not in adminList"), if ((unitsPerBlockScale16 > 0))
737736 then true
738737 else throwErr("units per block should be greated than 0"), if ((totalL2 > 0))
739738 then true
740739 else throwErr("total l2 should be greated than 0")]
741740 if ((check == check))
742- then [IntegerEntry(keyUnitsPerBlockScale16, unitsPerBlockScale16), IntegerEntry(keyUnitsClaimStartHeight, height), IntegerEntry(keyUnitsClaimInterval, unitsClaimNewInterval), StringEntry(keyUnitsAssetId, assetBytesToString(i.payments[0].assetId))]
741+ then [IntegerEntry(keyUnitsPerBlockScale16, unitsPerBlockScale16), IntegerEntry(keyUnitsClaimStartHeight, height), IntegerEntry(keyUnitsClaimInterval, unitsClaimNewInterval), StringEntry(keyUnitsAssetId, assetBytesToString(unitsAsset))]
743742 else throw("Strict value is not equal to itself.")
744743 }
745744
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let contractFile = "l2mp_leasing.ride"
55
66 let SEP = "__"
77
88 let BLOCKS_IN_INTERVAL = 1000
99
1010 let scale8 = 100000000
1111
1212 let scale16 = (scale8 * scale8)
1313
1414 func throwErr (msg) = throw(((contractFile + ": ") + msg))
1515
1616
1717 let keyL2AssetId = makeString(["%s", "assetId"], SEP)
1818
1919 let keyForceStop = makeString(["%s", "forceStop"], SEP)
2020
2121 let keyForceOutStop = makeString(["%s", "forceOutStop"], SEP)
2222
2323 let keyUnitsAssetId = makeString(["%s", "unitsAssetId"], SEP)
2424
2525 let keyUnitsPerBlockScale16 = makeString(["%s", "unitsPerBlockScale16"], SEP)
2626
2727 let keyPeriodOffsetId = makeString(["%s", "offsetId"], SEP)
2828
2929 let keyPeriodOffsetHeight = makeString(["%s", "offsetHeight"], SEP)
3030
3131 let keyPeriodLength = makeString(["%s", "periodLength"], SEP)
3232
3333 let keyUnitsClaimStartHeight = makeString(["%s", "unitsClaimStartHeight"], SEP)
3434
3535 let keyUnitsClaimInterval = makeString(["%s", "unitsClaimInterval"], SEP)
3636
3737 let periodOffsetId = valueOrElse(getInteger(this, keyPeriodOffsetId), 0)
3838
3939 let periodLength = valueOrElse(getInteger(this, keyPeriodLength), 10000)
4040
4141 let periodOffsetHeight = valueOrElse(getInteger(this, keyPeriodOffsetHeight), -1)
4242
4343 let currentPeriodId = if (if ((height > periodOffsetHeight))
4444 then (periodOffsetHeight != -1)
4545 else false)
4646 then (((height - periodOffsetHeight) / periodLength) + periodOffsetId)
4747 else max([0, (periodOffsetId - 1)])
4848
4949 let currentPeriodHeight = if (if ((periodOffsetHeight == -1))
5050 then true
5151 else if ((currentPeriodId == 0))
5252 then (periodOffsetHeight > height)
5353 else false)
5454 then 0
5555 else (periodOffsetHeight + ((currentPeriodId - periodOffsetId) * periodLength))
5656
5757 let nextPeriodHeight = if (if ((periodOffsetHeight == -1))
5858 then true
5959 else if ((currentPeriodId == 0))
6060 then (periodOffsetHeight > height)
6161 else false)
6262 then 0
6363 else (currentPeriodHeight + periodLength)
6464
6565 let unitsClaimStartHeight = valueOrElse(getInteger(this, keyUnitsClaimStartHeight), height)
6666
6767 let unitsClaimInterval = valueOrElse(getInteger(this, keyUnitsClaimInterval), 1)
6868
6969 func keyLeasingNodeData (nodeAddress) = makeString(["%s", nodeAddress], SEP)
7070
7171
7272 func keyUserLeasingNodeData (userAddress,nodeAddress) = makeString(["%s%s", nodeAddress, userAddress], SEP)
7373
7474
7575 func keyUserToClaim (userAddress) = makeString(["%s%s", "toClaim", userAddress], SEP)
7676
7777
7878 func keyUserTotalLocked (userAddress) = makeString(["%s%s", "userTotalLocked", userAddress], SEP)
7979
8080
8181 func keyUnitsClaimedBlock (userAddress) = makeString(["%s%s", "unitsClaimedBlock", userAddress], SEP)
8282
8383
8484 func keyUnlockedUnits (userAddress) = makeString(["%s%s", "unlockedUnits", userAddress], SEP)
8585
8686
8787 func keyTotalUnitsClaimed (userAddress) = makeString(["%s%s", "totalUnitsClaimed", userAddress], SEP)
8888
8989
9090 func keyL2ToBurn (userAddress) = makeString(["%s%s", "l2ToBurn", userAddress], SEP)
9191
9292
9393 func keyL2BurnedTotal (userAddress) = makeString(["%s%s", "l2BurnedTotal", userAddress], SEP)
9494
9595
9696 func keyNodeLeasingByHeight (nodeAddress) = {
9797 let h = if ((periodOffsetHeight == -1))
9898 then 0
9999 else height
100100 makeString(["%s%d", nodeAddress, toString(h)], SEP)
101101 }
102102
103103
104104 func keyUserLeasingByHeight (nodeAddress,userAddress) = {
105105 let h = if ((periodOffsetHeight == -1))
106106 then 0
107107 else height
108108 makeString(["%s%s%d", nodeAddress, userAddress, toString(h)], SEP)
109109 }
110110
111111
112112 func assetStringToBytes (assetIdString) = if ((assetIdString == "WAVES"))
113113 then unit
114114 else fromBase58String(assetIdString)
115115
116116
117117 func assetBytesToString (assetId) = match assetId {
118118 case a: ByteVector =>
119119 toBase58String(a)
120120 case _ =>
121121 "WAVES"
122122 }
123123
124124
125125 let l2AssetIdString = valueOrElse(getString(this, keyL2AssetId), "WAVES")
126126
127127 let unitsAssetIdString = valueOrElse(getString(this, keyUnitsAssetId), "WAVES")
128128
129129 let l2AssetIdBytes = assetStringToBytes(l2AssetIdString)
130130
131131 let unitsAssetIdBytes = assetStringToBytes(unitsAssetIdString)
132132
133133 let isForceStop = valueOrElse(getBoolean(this, keyForceStop), false)
134134
135135 let isForceOutStop = valueOrElse(getBoolean(this, keyForceOutStop), false)
136136
137137 func isValidAddress (address) = match addressFromString(address) {
138138 case a: Address =>
139139 true
140140 case _ =>
141141 false
142142 }
143143
144144
145145 let ADMIN_LIST_SIZE = 5
146146
147147 let QUORUM = 3
148148
149149 let TXID_BYTES_LENGTH = 32
150150
151151 func keyAllowedTxIdVotePrefix (txId) = makeString(["%s%s%s", "allowTxId", txId], SEP)
152152
153153
154154 func keyFullAdminVote (prefix,adminAddress) = makeString([prefix, adminAddress], SEP)
155155
156156
157157 func keyAdminAddressList () = makeString(["%s", "adminAddressList"], SEP)
158158
159159
160160 func keyAllowedTxId () = makeString(["%s", "txId"], SEP)
161161
162162
163163 func getAdminVote (prefix,admin) = {
164164 let voteKey = keyFullAdminVote(prefix, admin)
165165 valueOrElse(getInteger(voteKey), 0)
166166 }
167167
168168
169169 func getAdminsList () = match getString(this, keyAdminAddressList()) {
170170 case s: String =>
171171 split(s, SEP)
172172 case _ =>
173173 nil
174174 }
175175
176176
177177 func isInAdminList (address) = containsElement(getAdminsList(), address)
178178
179179
180180 func genVotesKeysHelper (a,adminAddress) = {
181181 let $t051855209 = a
182182 let result = $t051855209._1
183183 let prefix = $t051855209._2
184184 $Tuple2((result :+ keyFullAdminVote(prefix, adminAddress)), prefix)
185185 }
186186
187187
188188 func genVotesKeys (keyPrefix) = {
189189 let adminList = keyAdminAddressList()
190190 let $t053565440 = {
191191 let $l = getAdminsList()
192192 let $s = size($l)
193193 let $acc0 = $Tuple2(nil, keyPrefix)
194194 func $f0_1 ($a,$i) = if (($i >= $s))
195195 then $a
196196 else genVotesKeysHelper($a, $l[$i])
197197
198198 func $f0_2 ($a,$i) = if (($i >= $s))
199199 then $a
200200 else throw("List size exceeds 5")
201201
202202 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
203203 }
204204 let result = $t053565440._1
205205 let prefix = $t053565440._2
206206 result
207207 }
208208
209209
210210 func countVotesHelper (result,voteKey) = (result + valueOrElse(getInteger(voteKey), 0))
211211
212212
213213 func countVotes (prefix) = {
214214 let votes = genVotesKeys(prefix)
215215 let $l = votes
216216 let $s = size($l)
217217 let $acc0 = 0
218218 func $f0_1 ($a,$i) = if (($i >= $s))
219219 then $a
220220 else countVotesHelper($a, $l[$i])
221221
222222 func $f0_2 ($a,$i) = if (($i >= $s))
223223 then $a
224224 else throw("List size exceeds 5")
225225
226226 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
227227 }
228228
229229
230230 func clearVotesHelper (result,key) = (result :+ DeleteEntry(key))
231231
232232
233233 func getClearVoteEntries (prefix) = {
234234 let votes = genVotesKeys(prefix)
235235 let $l = votes
236236 let $s = size($l)
237237 let $acc0 = nil
238238 func $f0_1 ($a,$i) = if (($i >= $s))
239239 then $a
240240 else clearVotesHelper($a, $l[$i])
241241
242242 func $f0_2 ($a,$i) = if (($i >= $s))
243243 then $a
244244 else throw("List size exceeds 5")
245245
246246 $f0_2($f0_1($f0_1($f0_1($f0_1($f0_1($acc0, 0), 1), 2), 3), 4), 5)
247247 }
248248
249249
250250 func voteINTERNAL (callerAddressString,keyPrefix,minVotes,voteResult) = {
251251 let voteKey = keyFullAdminVote(keyPrefix, callerAddressString)
252252 let adminCurrentVote = getAdminVote(keyPrefix, callerAddressString)
253253 let err = if (!(isInAdminList(callerAddressString)))
254254 then throwErr((("Address: " + callerAddressString) + " not in Admin list"))
255255 else if ((adminCurrentVote == 1))
256256 then throwErr((voteKey + " you already voted"))
257257 else unit
258258 if ((err == err))
259259 then {
260260 let votes = countVotes(keyPrefix)
261261 if (((votes + 1) >= minVotes))
262262 then {
263263 let clearVoteEntries = getClearVoteEntries(keyPrefix)
264264 (clearVoteEntries ++ voteResult)
265265 }
266266 else [IntegerEntry(voteKey, 1)]
267267 }
268268 else throw("Strict value is not equal to itself.")
269269 }
270270
271271
272272 func getLeasingNodeEntry (nodeAddress,currentLeased,nextLeased) = {
273273 let valueString = makeString(["%d%d%d%d", toString(currentPeriodHeight), toString(currentLeased), toString(nextPeriodHeight), toString(nextLeased)], SEP)
274274 StringEntry(keyLeasingNodeData(nodeAddress), valueString)
275275 }
276276
277277
278278 func getLeasingNodeData (nodeAddress) = {
279279 let leasingNodeDataStringRaw = getString(this, keyLeasingNodeData(nodeAddress))
280280 match leasingNodeDataStringRaw {
281281 case ds: String =>
282282 let dataList = split(ds, SEP)
283283 let nodeCurrentPeriod = parseIntValue(dataList[1])
284284 let nodeCurrentLeased = parseIntValue(dataList[2])
285285 let nodeNextPeriod = parseIntValue(dataList[3])
286286 let nodeNextLeased = parseIntValue(dataList[4])
287287 if (if ((nodeNextPeriod > height))
288288 then true
289289 else (periodOffsetHeight == -1))
290290 then $Tuple2(nodeCurrentLeased, nodeNextLeased)
291291 else $Tuple2(nodeNextLeased, nodeNextLeased)
292292 case _ =>
293293 $Tuple2(0, 0)
294294 }
295295 }
296296
297297
298298 func getUserLeasingEntry (nodeAddress,userAddress,userCurrentLeased,userNextLeased) = {
299299 let valueString = makeString(["%d%d%d%d", toString(currentPeriodHeight), toString(userCurrentLeased), toString(nextPeriodHeight), toString(userNextLeased)], SEP)
300300 StringEntry(keyUserLeasingNodeData(userAddress, nodeAddress), valueString)
301301 }
302302
303303
304304 func getUserLeasingData (nodeAddress,userAddress) = {
305305 let leasingUserDataStringRaw = getString(this, keyUserLeasingNodeData(userAddress, nodeAddress))
306306 match leasingUserDataStringRaw {
307307 case ds: String =>
308308 let dataList = split(ds, SEP)
309309 let userCurrentPeriod = parseIntValue(dataList[1])
310310 let userCurrentLeased = parseIntValue(dataList[2])
311311 let userNextPeriod = parseIntValue(dataList[3])
312312 let userNextLeased = parseIntValue(dataList[4])
313313 if (if ((userNextPeriod > height))
314314 then true
315315 else (periodOffsetHeight == -1))
316316 then $Tuple2(userCurrentLeased, userNextLeased)
317317 else $Tuple2(userNextLeased, userNextLeased)
318318 case _ =>
319319 $Tuple2(0, 0)
320320 }
321321 }
322322
323323
324324 func getUserToClaimEntry (userAddress,toClaim,toUnlock) = {
325325 let valueString = makeString(["%d%d%d%d", toString(currentPeriodHeight), toString(toClaim), toString(nextPeriodHeight), toString(toUnlock)], SEP)
326326 StringEntry(keyUserToClaim(userAddress), valueString)
327327 }
328328
329329
330330 func getUserToClaimBalance (userAddress) = {
331331 let userToClaimDataStringRaw = getString(this, keyUserToClaim(userAddress))
332332 match userToClaimDataStringRaw {
333333 case ds: String =>
334334 let dataList = split(ds, SEP)
335335 let currentPeriod = parseIntValue(dataList[1])
336336 let toClaim = parseIntValue(dataList[2])
337337 let nextPeriod = parseIntValue(dataList[3])
338338 let toUnlock = parseIntValue(dataList[4])
339339 if (if ((nextPeriod > height))
340340 then true
341341 else (currentPeriodId == 0))
342342 then $Tuple2(toClaim, toUnlock)
343343 else $Tuple2((toClaim + toUnlock), 0)
344344 case _ =>
345345 $Tuple2(0, 0)
346346 }
347347 }
348348
349349
350350 func getUserTotalLockedEntry (userAddress,userTotalLocked) = IntegerEntry(keyUserTotalLocked(userAddress), userTotalLocked)
351351
352352
353353 func getUserTotalLocked (userAddress) = valueOrElse(getInteger(this, keyUserTotalLocked(userAddress)), 0)
354354
355355
356356 func calculateUnitsToClaim (userAddress) = {
357357 let claimedBlockKey = keyUnitsClaimedBlock(userAddress)
358358 let claimedBlock = valueOrElse(getInteger(this, claimedBlockKey), unitsClaimStartHeight)
359359 let unitsPerBlockScale16 = valueOrElse(getInteger(this, keyUnitsPerBlockScale16), 0)
360360 let currentBlock = min([(unitsClaimStartHeight + unitsClaimInterval), height])
361361 let blocksPassed = (currentBlock - claimedBlock)
362362 let amountStaked = getUserTotalLocked(userAddress)
363363 let l2ToBurn = fraction(amountStaked, blocksPassed, unitsClaimInterval)
364364 let unitsToClaimNow = fraction(amountStaked, (unitsPerBlockScale16 * blocksPassed), scale16)
365365 $Tuple4(unitsToClaimNow, l2ToBurn, currentBlock, $Tuple3(blocksPassed, unitsClaimStartHeight, unitsClaimInterval))
366366 }
367367
368368
369369 func getUnlockUnitsAction (userAddress) = {
370370 let kUnlockedUnits = keyUnlockedUnits(userAddress)
371371 let unlockedUnits = valueOrElse(getInteger(this, kUnlockedUnits), 0)
372372 let kL2ToBurn = keyL2ToBurn(userAddress)
373373 let l2ToBurn = valueOrElse(getInteger(this, kL2ToBurn), 0)
374374 let totalL2Locked = getUserTotalLocked(userAddress)
375375 let $t01149611706 = calculateUnitsToClaim(userAddress)
376376 let unitsToClaimNow = $t01149611706._1
377377 let l2ToBurnNow = $t01149611706._2
378378 let currentBlock = $t01149611706._3
379379 let _tmp = $t01149611706._4
380380 if ((0 >= unitsToClaimNow))
381381 then if ((totalL2Locked > 0))
382382 then nil
383383 else [IntegerEntry(keyUnitsClaimedBlock(userAddress), currentBlock)]
384384 else [IntegerEntry(keyUnitsClaimedBlock(userAddress), currentBlock), IntegerEntry(kL2ToBurn, (l2ToBurn + l2ToBurnNow)), IntegerEntry(kUnlockedUnits, (unlockedUnits + unitsToClaimNow))]
385385 }
386386
387387
388388 func getUnstakeActions (nodeAddress,userAddress,unstakeAmount) = {
389389 let $t01227712350 = getLeasingNodeData(nodeAddress)
390390 let nodeCurrentLeased = $t01227712350._1
391391 let nodeNextLeased = $t01227712350._2
392392 let $t01235512441 = getUserLeasingData(nodeAddress, userAddress)
393393 let userCurrentLeased = $t01235512441._1
394394 let userNextLeased = $t01235512441._2
395395 let checks = [if (!(isForceStop))
396396 then true
397397 else throwErr("contract is temporary stopped"), if (!(isForceOutStop))
398398 then true
399399 else throwErr("unstake is temporary disabled"), if ((unstakeAmount > 0))
400400 then true
401401 else throwErr("unstake amount should be greater than 0"), if ((userNextLeased >= unstakeAmount))
402402 then true
403403 else throwErr("unstake amount should be less or equal user staked amount"), if ((nodeNextLeased >= unstakeAmount))
404404 then true
405405 else throwErr("unstake amount should be less or equal node staked amount"), if (isValidAddress(nodeAddress))
406406 then true
407407 else throwErr(makeString(["node address is not valid:", nodeAddress], " ")), if (isValidAddress(userAddress))
408408 then true
409409 else throwErr(makeString(["user address is not valid:", userAddress], " "))]
410410 if ((checks == checks))
411411 then {
412412 let newNodeNextLease = (nodeNextLeased - unstakeAmount)
413413 let newUserNextLeased = (userNextLeased - unstakeAmount)
414414 let $t01332513385 = getUserToClaimBalance(userAddress)
415415 let toClaim = $t01332513385._1
416416 let toUnlock = $t01332513385._2
417417 let newToUnlock = (toUnlock + unstakeAmount)
418418 let userTotalLocked = getUserTotalLocked(userAddress)
419419 let newUserTotalLocked = (userTotalLocked - unstakeAmount)
420420 let unitsUnlockedActions = getUnlockUnitsAction(userAddress)
421421 ([getLeasingNodeEntry(nodeAddress, nodeCurrentLeased, newNodeNextLease), getUserLeasingEntry(nodeAddress, userAddress, userCurrentLeased, newUserNextLeased), getUserToClaimEntry(userAddress, toClaim, newToUnlock), getUserTotalLockedEntry(userAddress, newUserTotalLocked), IntegerEntry(keyNodeLeasingByHeight(nodeAddress), newNodeNextLease), IntegerEntry(keyUserLeasingByHeight(nodeAddress, userAddress), newUserNextLeased)] ++ unitsUnlockedActions)
422422 }
423423 else throw("Strict value is not equal to itself.")
424424 }
425425
426426
427427 func getClaimUnlockedActions (userAddress,claimAmount) = {
428428 let $t01420414264 = getUserToClaimBalance(userAddress)
429429 let toClaim = $t01420414264._1
430430 let toUnlock = $t01420414264._2
431431 let checks = [if (!(isForceStop))
432432 then true
433433 else throwErr("contract is temporary stopped"), if (!(isForceOutStop))
434434 then true
435435 else throwErr("claim is temporary disabled"), if ((claimAmount > 0))
436436 then true
437437 else throwErr("claim amount should be greater than 0"), if ((toClaim >= claimAmount))
438438 then true
439439 else throwErr("claim amount should be less or equal unlocked amount"), if (isValidAddress(userAddress))
440440 then true
441441 else throwErr(makeString(["user address is not valid:", userAddress], " "))]
442442 if ((checks == checks))
443443 then {
444444 let newToClaim = (toClaim - claimAmount)
445445 [getUserToClaimEntry(userAddress, newToClaim, toUnlock), ScriptTransfer(addressFromStringValue(userAddress), claimAmount, l2AssetIdBytes)]
446446 }
447447 else throw("Strict value is not equal to itself.")
448448 }
449449
450450
451451 func getStakeForActions (userAddress,i) = {
452452 let $t01503015090 = getUserToClaimBalance(userAddress)
453453 let toClaim = $t01503015090._1
454454 let toUnlock = $t01503015090._2
455455 let checks = [if (!(isForceStop))
456456 then true
457457 else throwErr("contract is temporary stopped"), if ((1 >= size(i.payments)))
458458 then true
459459 else throwErr("maximum 1 payment"), if (if ((size(i.payments) == 0))
460460 then true
461461 else (i.payments[0].assetId == l2AssetIdBytes))
462462 then true
463463 else throwErr(makeString(["payment assetId should be:", l2AssetIdString], " ")), if (isValidAddress(userAddress))
464464 then true
465465 else throwErr(makeString(["user address is not valid:", userAddress], " "))]
466466 if ((checks == checks))
467467 then {
468468 let newToClaim = (toClaim + i.payments[0].amount)
469469 [getUserToClaimEntry(userAddress, newToClaim, toUnlock)]
470470 }
471471 else throw("Strict value is not equal to itself.")
472472 }
473473
474474
475475 func getStakeActions (nodeAddress,userAddress,userLeasingAmount,i) = {
476476 let $t01582215882 = getUserToClaimBalance(userAddress)
477477 let toClaim = $t01582215882._1
478478 let toUnlock = $t01582215882._2
479479 let paymentAmount = if ((size(i.payments) == 0))
480480 then 0
481481 else i.payments[0].amount
482482 let available = ((toUnlock + toClaim) + paymentAmount)
483483 let checks = [if (!(isForceStop))
484484 then true
485485 else throwErr("contract is temporary stopped"), if ((1 >= size(i.payments)))
486486 then true
487487 else throwErr("maximum 1 payment"), if (if ((size(i.payments) == 0))
488488 then true
489489 else (i.payments[0].assetId == l2AssetIdBytes))
490490 then true
491491 else throwErr(makeString(["payment assetId should be:", l2AssetIdString], " ")), if ((userLeasingAmount > 0))
492492 then true
493493 else throwErr("amount should be greater than 0"), if ((available >= userLeasingAmount))
494494 then true
495495 else throwErr("amount should be less or equal (payment + available) amount"), if ((userLeasingAmount >= paymentAmount))
496496 then true
497497 else throw("amount should be greater or equal payment amount"), if (isValidAddress(nodeAddress))
498498 then true
499499 else throwErr(makeString(["node address is not valid:", nodeAddress], " ")), if (isValidAddress(userAddress))
500500 then true
501501 else throwErr(makeString(["user address is not valid:", userAddress], " "))]
502502 if ((checks == checks))
503503 then {
504504 let $t01695717030 = getLeasingNodeData(nodeAddress)
505505 let nodeCurrentLeased = $t01695717030._1
506506 let nodeNextLeased = $t01695717030._2
507507 let newNodeNextLease = (nodeNextLeased + userLeasingAmount)
508508 let $t01709817184 = getUserLeasingData(nodeAddress, userAddress)
509509 let userCurrentLeased = $t01709817184._1
510510 let userNextLeased = $t01709817184._2
511511 let newUserNextLeased = (userNextLeased + userLeasingAmount)
512512 let fromUnlockedAmount = (userLeasingAmount - paymentAmount)
513513 let newToUnlock = max([0, (toUnlock - fromUnlockedAmount)])
514514 let newToClaim = min([toClaim, (toClaim + (toUnlock - fromUnlockedAmount))])
515515 let userTotalLocked = getUserTotalLocked(userAddress)
516516 let newUserTotalLocked = (userTotalLocked + userLeasingAmount)
517517 let unitsUnlockedActions = getUnlockUnitsAction(userAddress)
518518 ([getLeasingNodeEntry(nodeAddress, nodeCurrentLeased, newNodeNextLease), getUserLeasingEntry(nodeAddress, userAddress, userCurrentLeased, newUserNextLeased), getUserToClaimEntry(userAddress, newToClaim, newToUnlock), getUserTotalLockedEntry(userAddress, newUserTotalLocked), IntegerEntry(keyNodeLeasingByHeight(nodeAddress), newNodeNextLease), IntegerEntry(keyUserLeasingByHeight(nodeAddress, userAddress), newUserNextLeased)] ++ unitsUnlockedActions)
519519 }
520520 else throw("Strict value is not equal to itself.")
521521 }
522522
523523
524524 func getStakeFromPaymentActions (nodeAddress,userAddress,i) = {
525525 let checks = [if ((size(i.payments) == 1))
526526 then true
527527 else throwErr("payment size should be exactly 1")]
528528 if ((checks == checks))
529529 then getStakeActions(nodeAddress, userAddress, i.payments[0].amount, i)
530530 else throw("Strict value is not equal to itself.")
531531 }
532532
533533
534534 func getSetNewPeriodLengthActions (newPeriodLength) = {
535535 let check = [if ((newPeriodLength > 0))
536536 then true
537537 else throwErr("period length should be greater than 0")]
538538 if ((check == check))
539539 then if ((periodOffsetHeight == -1))
540540 then [IntegerEntry(keyPeriodLength, newPeriodLength), IntegerEntry(keyPeriodOffsetHeight, height)]
541541 else [IntegerEntry(keyPeriodOffsetId, (currentPeriodId + 1)), IntegerEntry(keyPeriodOffsetHeight, nextPeriodHeight), IntegerEntry(keyPeriodLength, newPeriodLength)]
542542 else throw("Strict value is not equal to itself.")
543543 }
544544
545545
546546 func getUnitsClaimData (userAddress) = {
547547 let $t01906919160 = calculateUnitsToClaim(userAddress)
548548 let unlockedUnitNow = $t01906919160._1
549549 let l2ToBurnNow = $t01906919160._2
550550 let currentBlock = $t01906919160._3
551551 let _tmp = $t01906919160._4
552552 let unlockedUnitsPrev = valueOrElse(getInteger(this, keyUnlockedUnits(userAddress)), 0)
553553 let unitsToSend = (unlockedUnitNow + unlockedUnitsPrev)
554554 let l2ToBurnPrev = valueOrElse(getInteger(this, keyL2ToBurn(userAddress)), 0)
555555 let l2ToBurn = (l2ToBurnPrev + l2ToBurnNow)
556556 let totalUnitsClaimed = valueOrElse(getInteger(this, keyTotalUnitsClaimed(userAddress)), 0)
557557 let totalL2Burned = valueOrElse(getInteger(this, keyL2BurnedTotal(userAddress)), 0)
558558 $Tuple5(unitsToSend, totalUnitsClaimed, l2ToBurn, totalL2Burned, currentBlock)
559559 }
560560
561561
562562 func getClaimUnitsActions (userAddress) = {
563563 let $t01975219860 = getUnitsClaimData(userAddress)
564564 let unitsToSend = $t01975219860._1
565565 let totalUnitsClaimed = $t01975219860._2
566566 let l2ToBurn = $t01975219860._3
567567 let totalL2Burned = $t01975219860._4
568568 let claimedBlock = $t01975219860._5
569569 let check = [if ((unitsToSend > 0))
570570 then true
571571 else throwErr("nothing to claim")]
572572 if ((check == check))
573573 then {
574574 let burnAction = match l2AssetIdBytes {
575575 case id: ByteVector =>
576576 [Burn(id, l2ToBurn)]
577577 case _ =>
578578 nil
579579 }
580580 ([IntegerEntry(keyUnitsClaimedBlock(userAddress), claimedBlock), IntegerEntry(keyTotalUnitsClaimed(userAddress), (totalUnitsClaimed + unitsToSend)), IntegerEntry(keyL2BurnedTotal(userAddress), (totalL2Burned + l2ToBurn)), IntegerEntry(keyUnlockedUnits(userAddress), 0), IntegerEntry(keyL2ToBurn(userAddress), 0), ScriptTransfer(addressFromStringValue(userAddress), unitsToSend, unitsAssetIdBytes)] ++ burnAction)
581581 }
582582 else throw("Strict value is not equal to itself.")
583583 }
584584
585585
586586 @Callable(i)
587587 func setNewPeriodLength (newPeriodLength) = {
588588 let checks = [if (isInAdminList(toString(i.caller)))
589589 then true
590590 else throwErr("caller is not in adminList")]
591591 if ((checks == checks))
592592 then getSetNewPeriodLengthActions(newPeriodLength)
593593 else throw("Strict value is not equal to itself.")
594594 }
595595
596596
597597
598598 @Callable(i)
599599 func claimUnits () = {
600600 let userAddress = toString(i.caller)
601601 getClaimUnitsActions(userAddress)
602602 }
603603
604604
605605
606606 @Callable(i)
607607 func setForceStopFlag (stop) = {
608608 let check = [if (isInAdminList(toString(i.caller)))
609609 then true
610610 else throwErr("caller is not in adminList")]
611611 if ((check == check))
612612 then [BooleanEntry(keyForceStop, stop)]
613613 else throw("Strict value is not equal to itself.")
614614 }
615615
616616
617617
618618 @Callable(i)
619619 func setForceOutStopFlag (stop) = {
620620 let check = [if (isInAdminList(toString(i.caller)))
621621 then true
622622 else throwErr("caller is not in adminList")]
623623 if ((check == check))
624624 then [BooleanEntry(keyForceOutStop, stop)]
625625 else throw("Strict value is not equal to itself.")
626626 }
627627
628628
629629
630630 @Callable(i)
631631 func getNodeDataREADONLY (nodeAddress) = {
632632 let $t02159221656 = getLeasingNodeData(nodeAddress)
633633 let currentLease = $t02159221656._1
634634 let nextLeased = $t02159221656._2
635635 $Tuple2(nil, $Tuple5(currentPeriodHeight, currentLease, nextPeriodHeight, nextLeased, height))
636636 }
637637
638638
639639
640640 @Callable(i)
641641 func getUserLeasingDataREADONLY (nodeAddress,userAddress) = {
642642 let $t02202622103 = getUserLeasingData(nodeAddress, userAddress)
643643 let currentLease = $t02202622103._1
644644 let nextLeased = $t02202622103._2
645645 $Tuple2(nil, $Tuple5(currentPeriodHeight, currentLease, nextPeriodHeight, nextLeased, height))
646646 }
647647
648648
649649
650650 @Callable(i)
651651 func getUserDataREADONLY (userAddress) = {
652652 let $t02270722767 = getUserToClaimBalance(userAddress)
653653 let toClaim = $t02270722767._1
654654 let toUnlock = $t02270722767._2
655655 let userTotalLocked = getUserTotalLocked(userAddress)
656656 let $t02283022938 = getUnitsClaimData(userAddress)
657657 let unitsToSend = $t02283022938._1
658658 let totalUnitsClaimed = $t02283022938._2
659659 let l2ToBurn = $t02283022938._3
660660 let totalL2Burned = $t02283022938._4
661661 let claimedBlock = $t02283022938._5
662662 let unitsPerBlockScale16 = valueOrElse(getInteger(this, keyUnitsPerBlockScale16), 0)
663663 let remainingblocks = max([0, ((unitsClaimStartHeight + unitsClaimInterval) - height)])
664664 $Tuple2(nil, $Tuple13(currentPeriodHeight, toClaim, nextPeriodHeight, toUnlock, userTotalLocked, height, unitsToSend, totalUnitsClaimed, l2ToBurn, totalL2Burned, claimedBlock, unitsPerBlockScale16, remainingblocks))
665665 }
666666
667667
668668
669669 @Callable(i)
670670 func leaseByAddress (nodeAddress,userAddress) = getStakeFromPaymentActions(nodeAddress, userAddress, i)
671671
672672
673673
674674 @Callable(i)
675675 func lease (nodeAddress) = {
676676 let userAddress = toString(i.caller)
677677 getStakeFromPaymentActions(nodeAddress, userAddress, i)
678678 }
679679
680680
681681
682682 @Callable(i)
683683 func leaseFromLocked (nodeAddress,amount) = {
684684 let userAddress = toString(i.caller)
685685 getStakeActions(nodeAddress, userAddress, amount, i)
686686 }
687687
688688
689689
690690 @Callable(i)
691691 func cancelLease (nodeAddress,amount) = {
692692 let userAddress = toString(i.caller)
693693 getUnstakeActions(nodeAddress, userAddress, amount)
694694 }
695695
696696
697697
698698 @Callable(i)
699699 func claim (amount) = {
700700 let userAddress = toString(i.caller)
701701 getClaimUnlockedActions(userAddress, amount)
702702 }
703703
704704
705705
706706 @Callable(i)
707707 func claimAll () = {
708708 let userAddress = toString(i.caller)
709709 let $t02436824428 = getUserToClaimBalance(userAddress)
710710 let toClaim = $t02436824428._1
711711 let toUnlock = $t02436824428._2
712712 let checks = [if ((toClaim > 0))
713713 then true
714714 else throwErr("nothing to claim")]
715715 if ((checks == checks))
716716 then getClaimUnlockedActions(userAddress, toClaim)
717717 else throw("Strict value is not equal to itself.")
718718 }
719719
720720
721721
722722 @Callable(i)
723723 func stakeFor (userAddress) = getStakeForActions(userAddress, i)
724724
725725
726726
727727 @Callable(i)
728-func startUnitsVesting (unitsClaimNewInterval,totalL2String) = {
729- let totalUnits = i.payments[0].amount
728+func startUnitsVesting (unitsClaimNewInterval,totalL2String,unitsAssetIdstring,unitsAmountString) = {
729+ let unitsAmount = parseIntValue(unitsAmountString)
730730 let totalL2 = parseIntValue(totalL2String)
731- let unitsPerBlockScale16 = (fraction(totalUnits, scale16, totalL2) / unitsClaimNewInterval)
731+ let unitsAsset = assetStringToBytes(unitsAssetIdstring)
732+ let unitsPerBlockScale16 = (fraction(unitsAmount, scale16, totalL2) / unitsClaimNewInterval)
732733 let check = [if (isInAdminList(toString(i.caller)))
733734 then true
734- else throwErr("caller is not in adminList"), if ((size(i.payments) == 1))
735- then true
736- else throwErr("should be 1 payment"), if ((unitsPerBlockScale16 > 0))
735+ else throwErr("caller is not in adminList"), if ((unitsPerBlockScale16 > 0))
737736 then true
738737 else throwErr("units per block should be greated than 0"), if ((totalL2 > 0))
739738 then true
740739 else throwErr("total l2 should be greated than 0")]
741740 if ((check == check))
742- then [IntegerEntry(keyUnitsPerBlockScale16, unitsPerBlockScale16), IntegerEntry(keyUnitsClaimStartHeight, height), IntegerEntry(keyUnitsClaimInterval, unitsClaimNewInterval), StringEntry(keyUnitsAssetId, assetBytesToString(i.payments[0].assetId))]
741+ then [IntegerEntry(keyUnitsPerBlockScale16, unitsPerBlockScale16), IntegerEntry(keyUnitsClaimStartHeight, height), IntegerEntry(keyUnitsClaimInterval, unitsClaimNewInterval), StringEntry(keyUnitsAssetId, assetBytesToString(unitsAsset))]
743742 else throw("Strict value is not equal to itself.")
744743 }
745744
746745
747746
748747 @Callable(i)
749748 func voteForTxId (txId) = {
750749 let callerAddressString = toBase58String(i.caller.bytes)
751750 let keyPrefix = keyAllowedTxIdVotePrefix(txId)
752751 let result = [StringEntry(keyAllowedTxId(), txId)]
753752 let allowedTxIdOption = getString(this, keyAllowedTxId())
754753 let err = [if ((size(fromBase58String(txId)) == TXID_BYTES_LENGTH))
755754 then true
756755 else throwErr((txId + " is not valid txId")), if (if ((allowedTxIdOption == unit))
757756 then true
758757 else (value(allowedTxIdOption) != txId))
759758 then true
760759 else throwErr((txId + " is already allowed"))]
761760 if ((err == err))
762761 then voteINTERNAL(callerAddressString, keyPrefix, QUORUM, result)
763762 else throw("Strict value is not equal to itself.")
764763 }
765764
766765
767766 @Verifier(tx)
768767 func verify () = {
769768 let byAdmins = (tx.id == fromBase58String(valueOrElse(getString(this, keyAllowedTxId()), "")))
770769 let byOwner = if ((size(getAdminsList()) >= QUORUM))
771770 then false
772771 else sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
773772 if (byAdmins)
774773 then true
775774 else byOwner
776775 }
777776

github/deemru/w8io/169f3d6 
112.50 ms