tx · 9zGTEQEbiEoghPBeaxnVGUGK299DNztiy5Zypb4YWedX

3NCWFHDzdPHZC6636ZkMLNDup9mjpbTLs7h:  -0.02700000 Waves

2024.10.21 16:13 [3336653] smart account 3NCWFHDzdPHZC6636ZkMLNDup9mjpbTLs7h > SELF 0.00000000 Waves

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

github/deemru/w8io/169f3d6 
68.98 ms