tx · 2Ffjmi2GLxHceearzriaH7EhJFqXDzxcQdQWjCdgjfir 3N2wEQGk9SJyw6miZiLG66wqECUcdHXCYXH: -0.03000000 Waves 2025.03.12 15:05 [3540795] smart account 3N2wEQGk9SJyw6miZiLG66wqECUcdHXCYXH > SELF 0.00000000 Waves
{ "type": 13, "id": "2Ffjmi2GLxHceearzriaH7EhJFqXDzxcQdQWjCdgjfir", "fee": 3000000, "feeAssetId": null, "timestamp": 1741781177198, "version": 2, "chainId": 84, "sender": "3N2wEQGk9SJyw6miZiLG66wqECUcdHXCYXH", "senderPublicKey": "49pJcBuD9hnPFw7NTHkGEb6m25uVZTteuJtPFNBMgs7G", "proofs": [ "4hneHVxj8GNsyoWPtwwxAX4RF173ATby6YVPrH2qm96ry5jUfrwuZBBMF3P98HnQD7DXZQs8K6cFGQ1XMxxZRFCq" ], "script": "base64:BwJVCAISCAoGAggICAgIEgASAwoBCBIDCgEIEgMKAQgSAwoBARIFCgMIAQESAwoBCBIAEgASABIDCgEIEgASBAoCCAESAwoBARIDCgEIEgMKAQgSAwoBAXUAAkJQAJBOABFyZXF1aXJlZFdYWEFtb3VudACAyK+gJQAVY3ljbGVEdXJhdGlvbkluQmxvY2tzAOgHAB5jeWNsZUR1cmF0aW9uSW5CbG9ja3NTcXJ0Rmxvb3IAAwAUbWluVm90ZUN5Y2xlSW50ZXJ2YWwAAQAPbWluVm90ZUludGVydmFsCQBoAgUVY3ljbGVEdXJhdGlvbkluQmxvY2tzBRRtaW5Wb3RlQ3ljbGVJbnRlcnZhbAAUbWF4Vm90ZUN5Y2xlSW50ZXJ2YWwAkgQAD21heFZvdGVJbnRlcnZhbAkAaAIFFWN5Y2xlRHVyYXRpb25JbkJsb2NrcwUUbWF4Vm90ZUN5Y2xlSW50ZXJ2YWwAGGVtZXJnZW5jeVZvdGluZ1RocmVzaG9sZAAKABtlbWVyZ2VuY3lWb3RpbmdMb2NrSW5DeWNsZXMACgATZW1lcmdlbmN5Vm90aW5nTG9jawkAaAIFG2VtZXJnZW5jeVZvdGluZ0xvY2tJbkN5Y2xlcwUVY3ljbGVEdXJhdGlvbkluQmxvY2tzABd2YWxpZGF0b3JTdGF0dXNFbnRyeUtleQIQdmFsaWRhdG9yU3RhdHVzOgAYYWN0aXZlVmFsaWRhdG9yc0VudHJ5S2V5AhBhY3RpdmVWYWxpZGF0b3JzABJhZG1pbkZlZUJQRW50cnlLZXkCCmFkbWluRmVlQlAAGGxlYXNpbmdQb29sVmFsdWVFbnRyeUtleQIRbGVhc2luZ1Bvb2xWYWx1ZToAHWN5Y2xlRHVyYXRpb25JbkJsb2Nrc0VudHJ5S2V5AhVjeWNsZUR1cmF0aW9uSW5CbG9ja3MAGmVtZXJnZW5jeVVzZXJWb3Rlc0VudHJ5S2V5AhNlbWVyZ2VuY3lVc2VyVm90ZXM6ABZlbWVyZ2VuY3lWb3Rlc0VudHJ5S2V5Ag9lbWVyZ2VuY3lWb3RlczoAIGVtZXJnZW5jeVZvdGluZ1RocmVzaG9sZEVudHJ5S2V5AhhlbWVyZ2VuY3lWb3RpbmdUaHJlc2hvbGQAGWVtZXJnZW5jeVVzZXJMb2NrRW50cnlLZXkCEmVtZXJnZW5jeVVzZXJMb2NrOgAbaXNMZWFzaW5nSW5Qcm9ncmVzc0VudHJ5S2V5AhRpc0xlYXNpbmdJblByb2dyZXNzOgAabGF0ZXN0TGVhc2luZ0N5Y2xlRW50cnlLZXkCEmxhdGVzdExlYXNpbmdDeWNsZQAjbGF0ZXN0VmFsaWRhdG9yTGVhc2luZ0N5Y2xlRW50cnlLZXkCE2xhdGVzdExlYXNpbmdDeWNsZToAGXJlZ2lzdHJhdGlvbkN5Y2xlRW50cnlLZXkCEnJlZ2lzdHJhdGlvbkN5Y2xlOgAPbGVhc2VJZEVudHJ5S2V5AghsZWFzZUlkOgAXcHJvY2Vzc2VkTGVhc2VzRW50cnlLZXkCEHByb2Nlc3NlZExlYXNlczoAH3JlcXVlc3RlZFhXYXZlc1dpdGhkcmF3RW50cnlLZXkCGHJlcXVlc3RlZFhXYXZlc1dpdGhkcmF3OgAecmVxdWVzdGVkV2F2ZXNXaXRoZHJhd0VudHJ5S2V5AhdyZXF1ZXN0ZWRXYXZlc1dpdGhkcmF3OgAZcmVxdWlyZWRXWFhBbW91bnRFbnRyeUtleQIRcmVxdWlyZWRXWFhBbW91bnQAEnN0YXJ0QmxvY2tFbnRyeUtleQIKc3RhcnRCbG9jawAWY29udHJhY3RTdGF0dXNFbnRyeUtleQIOY29udHJhY3RTdGF0dXMAE3N0b3BNYW5hZ2VyRW50cnlLZXkCC3N0b3BNYW5hZ2VyACN0b3RhbFJlcXVlc3RlZFdhdmVzV2l0aGRyYXdFbnRyeUtleQIbdG90YWxSZXF1ZXN0ZWRXYXZlc1dpdGhkcmF3ABJ0b3RhbFZvdGVzRW50cnlLZXkCCnRvdGFsVm90ZXMAE3VubG9ja0Jsb2NrRW50cnlLZXkCDHVubG9ja0Jsb2NrOgAQdXNlckxvY2tFbnRyeUtleQIJdXNlckxvY2s6ABB1c2VyVm90ZUVudHJ5S2V5Agl1c2VyVm90ZToAFXZhbGlkYXRvck1ldGFFbnRyeUtleQIOdmFsaWRhdG9yTWV0YToAGHZhbGlkYXRvckFkZHJlc3NFbnRyeUtleQIRdmFsaWRhdG9yQWRkcmVzczoAE3ZhbGlkYXRvcklkRW50cnlLZXkCDHZhbGlkYXRvcklkOgAXdmFsaWRhdG9yTGVhc2VzRW50cnlLZXkCEHZhbGlkYXRvckxlYXNlczoADXZvdGVzRW50cnlLZXkCBnZvdGVzOgAjd2l0aGRyYXdYV2F2ZXhRdWFudGl0eVN0YXRlRW50cnlLZXkCG3dpdGhkcmF3WFdhdmV4UXVhbnRpdHlTdGF0ZQAhd2l0aGRyYXdXYXZlc0JhbGFuY2VTdGF0ZUVudHJ5S2V5Ahl3aXRoZHJhd1dhdmVzQmFsYW5jZVN0YXRlABJ3eHhBc3NldElkRW50cnlLZXkCCnd4eEFzc2V0SWQAFXhXYXZlc0Fzc2V0SWRFbnRyeUtleQINeFdhdmVzQXNzZXRJZAAVeFdhdmVzV3JhcHBlckVudHJ5S2V5Ag14V2F2ZXNXcmFwcGVyABlhZG1pbkZlZUNvbGxlY3RvckVudHJ5S2V5AhFhZG1pbkZlZUNvbGxlY3RvcgAUaWdub3JlZFZvdGVzRW50cnlLZXkCDGlnbm9yZVZvdGVzOgAZaWdub3JlZFZhbGlkYXRvcnNFbnRyeUtleQISaWdub3JlZFZhbGlkYXRvcnM6AA1hZG1pbkVudHJ5S2V5AgVhZG1pbgAWeFdhdmV4UXVhbnRpdHlFbnRyeUtleQIOeFdhdmV4UXVhbnRpdHkAEnB1enpsZVN3YXBFbnRyeUtleQIKcHV6emxlU3dhcAAXZXJyb3JNZXNzYWdlVW5yZWFjaGFibGUCC1VucmVhY2hhYmxlAB5lcnJvck1lc3NhZ2VBbHJlYWR5SW5pdGlhbGl6ZWQCE0FscmVhZHkgaW5pdGlhbGl6ZWQAGWVycm9yTWVzc2FnZUFscmVhZHlMZWFzZWQCDkFscmVhZHkgbGVhc2VkAB1lcnJvck1lc3NhZ2VBbHJlYWR5UmVnaXN0ZXJlZAISQWxyZWFkeSByZWdpc3RlcmVkAB1lcnJvck1lc3NhZ2VDb250cmFjdE5vdEFjdGl2ZQIWQ29udHJhY3QgaXMgbm90IGFjdGl2ZQAbZXJyb3JNZXNzYWdlSW52YWxpZEludGVydmFsAhBJbnZhbGlkIGludGVydmFsABxlcnJvck1lc3NhZ2VJbnZhbGlkV1hYQW1vdW50AhJJbnZhbGlkIFdYWCBhbW91bnQAHWVycm9yTWVzc2FnZUxlYXNpbmdJblByb2dyZXNzAhNMZWFzaW5nIGluIHByb2dyZXNzABxlcnJvck1lc3NhZ2VOb0VtZXJnZW5jeVZvdGVzAhtObyBlbWVyZ2VuY3kgdm90ZXMgZm9yIHVzZXIAH2Vycm9yTWVzc2FnZU5vUmVxdWVzdGVkV2l0aGRyYXcCFU5vIHJlcXVlc3RlZCB3aXRoZHJhdwAZZXJyb3JNZXNzYWdlTm90T25lUGF5bWVudAIPTm90IG9uZSBwYXltZW50ABRlcnJvck1lc3NhZ2VUb29FYXJseQIJVG9vIGVhcmx5ABhlcnJvck1lc3NhZ2VVbmF1dGhvcml6ZWQCDFVuYXV0aG9yaXplZAAdZXJyb3JNZXNzYWdlVW5leHBlY3RlZEFzc2V0SWQCE1VuZXhwZWN0ZWQgYXNzZXQgaWQAF2Vycm9yTWVzc2FnZVVua25vd25Mb2NrAgxVbmtub3duIGxvY2sAHGVycm9yTWVzc2FnZVVua25vd25WYWxpZGF0b3ICEVVua25vd24gdmFsaWRhdG9yACRlcnJvck1lc3NhZ2VWYWxpZGF0b3JOb3RSZWFkeVRvTGVhc2UCH1ZhbGlkYXRvciBpcyBub3QgcmVhZHkgdG8gbGVhc2UAIWVycm9yTWVzc2FnZVdhdmVzQmFsYW5jZU5vdEVub3VnaAIiTm90IGVub3VnaCBXQVZFUy4gUGxlYXNlIHRyeSBsYXRlcgAeZXJyb3JNZXNzYWdlVmFsaWRhdG9yV2FzS2lja2VkAhRWYWxpZGF0b3Igd2FzIGtpY2tlZAAdZXJyb3JNZXNzYWdlSW52YWxpZEFkbWluRmVlQlACEkludmFsaWQgYWRtaW5GZWVCUAAXZXJyb3JNZXNzYWdlSW52YWxpZFVpbnQCDEludmFsaWQgVWludAAJYXZhaWxhYmxlCAkA7wcBBQR0aGlzCWF2YWlsYWJsZQAKd3h4QXNzZXRJZAkBEUBleHRyTmF0aXZlKDEwNTcpAQUSd3h4QXNzZXRJZEVudHJ5S2V5AA14V2F2ZXNBc3NldElkCQERQGV4dHJOYXRpdmUoMTA1NykBBRV4V2F2ZXNBc3NldElkRW50cnlLZXkADXhXYXZlc1dyYXBwZXIJAQdBZGRyZXNzAQkBEUBleHRyTmF0aXZlKDEwNTcpAQUVeFdhdmVzV3JhcHBlckVudHJ5S2V5AAx3eHhBc3NldEluZm8JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQp3eHhBc3NldElkBRdlcnJvck1lc3NhZ2VVbnJlYWNoYWJsZQAOeFdhdmV4UXVhbnRpdHkJARFAZXh0ck5hdGl2ZSgxMDU1KQEFFnhXYXZleFF1YW50aXR5RW50cnlLZXkADGN1cnJlbnRDeWNsZQkAaQIJAGUCCAUJbGFzdEJsb2NrBmhlaWdodAkBEUBleHRyTmF0aXZlKDEwNTUpAQUSc3RhcnRCbG9ja0VudHJ5S2V5BRVjeWNsZUR1cmF0aW9uSW5CbG9ja3MAGXdpdGhkcmF3V2F2ZXNCYWxhbmNlU3RhdGUJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUhd2l0aGRyYXdXYXZlc0JhbGFuY2VTdGF0ZUVudHJ5S2V5CAkA7wcBBQR0aGlzB3JlZ3VsYXIAG3dpdGhkcmF3WFdhdmV4UXVhbnRpdHlTdGF0ZQkBC3ZhbHVlT3JFbHNlAgkAnwgBBSN3aXRoZHJhd1hXYXZleFF1YW50aXR5U3RhdGVFbnRyeUtleQUOeFdhdmV4UXVhbnRpdHkAG2N1cnJlbnRDeWNsZUlnbm9yZWRWb3Rlc0tleQkArAICBRRpZ25vcmVkVm90ZXNFbnRyeUtleQkApAMBBQxjdXJyZW50Q3ljbGUAIGN1cnJlbnRDeWNsZUlnbm9yZWRWYWxpZGF0b3JzS2V5CQCsAgIFGWlnbm9yZWRWYWxpZGF0b3JzRW50cnlLZXkJAKQDAQUMY3VycmVudEN5Y2xlABhjdXJyZW50Q3ljbGVJZ25vcmVkVm90ZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUbY3VycmVudEN5Y2xlSWdub3JlZFZvdGVzS2V5AAAAHWN1cnJlbnRDeWNsZUlnbm9yZWRWYWxpZGF0b3JzCQELdmFsdWVPckVsc2UCCQCfCAEFIGN1cnJlbnRDeWNsZUlnbm9yZWRWYWxpZGF0b3JzS2V5AAAACnRvdGFsVm90ZXMJARFAZXh0ck5hdGl2ZSgxMDU1KQEFEnRvdGFsVm90ZXNFbnRyeUtleQAddG90YWxWb3Rlc1dpdGhvdXRJZ25vcmVkVm90ZXMJAGUCBQp0b3RhbFZvdGVzBRhjdXJyZW50Q3ljbGVJZ25vcmVkVm90ZXMAG3RvdGFsUmVxdWVzdGVkV2F2ZXNXaXRoZHJhdwkBC3ZhbHVlT3JFbHNlAgkAnwgBBSN0b3RhbFJlcXVlc3RlZFdhdmVzV2l0aGRyYXdFbnRyeUtleQAAAA5jb250cmFjdFN0YXR1cwkBEUBleHRyTmF0aXZlKDEwNTYpAQUWY29udHJhY3RTdGF0dXNFbnRyeUtleQALc3RvcE1hbmFnZXIJARFAZXh0ck5hdGl2ZSgxMDU3KQEFE3N0b3BNYW5hZ2VyRW50cnlLZXkABWFkbWluCQERQGV4dHJOYXRpdmUoMTA1NykBBQ1hZG1pbkVudHJ5S2V5AAphZG1pbkZlZUJQCQELdmFsdWVPckVsc2UCCQCfCAEFEmFkbWluRmVlQlBFbnRyeUtleQAyABBhY3RpdmVWYWxpZGF0b3JzCQELdmFsdWVPckVsc2UCCQCfCAEFGGFjdGl2ZVZhbGlkYXRvcnNFbnRyeUtleQAAAB5hY3RpdmVWYWxpZGF0b3JzV2l0aG91dElnbm9yZWQJAGUCBRBhY3RpdmVWYWxpZGF0b3JzBR1jdXJyZW50Q3ljbGVJZ25vcmVkVmFsaWRhdG9ycwAKcHV6emxlU3dhcAkBB0FkZHJlc3MBCQERQGV4dHJOYXRpdmUoMTA1NykBBRJwdXp6bGVTd2FwRW50cnlLZXkBBmFzc2VydAIBdgFlAwUBdgUEdW5pdAkAAgEFAWUBCVVpbnRFbnRyeQIDa2V5AXYEC19hc3NlcnRVaW50CQEGYXNzZXJ0AgkAZwIFAXYAAAUXZXJyb3JNZXNzYWdlSW52YWxpZFVpbnQDCQAAAgULX2Fzc2VydFVpbnQFC19hc3NlcnRVaW50CQEMSW50ZWdlckVudHJ5AgUDa2V5BQF2CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuARJnZXRWYWxpZGF0b3JTdGF0dXMBEHZhbGlkYXRvckFkZHJlc3MJAKAIAQkArAICBRd2YWxpZGF0b3JTdGF0dXNFbnRyeUtleQkApQgBBRB2YWxpZGF0b3JBZGRyZXNzARdnZXRWYWxpZGF0b3JTdGF0dXNWYWx1ZQEQdmFsaWRhdG9yQWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQESZ2V0VmFsaWRhdG9yU3RhdHVzAQUQdmFsaWRhdG9yQWRkcmVzcwUcZXJyb3JNZXNzYWdlVW5rbm93blZhbGlkYXRvcgEaZ2V0Q2FuY2VsTGVhc2VGb3JWYWxpZGF0b3IBEHZhbGlkYXRvckFkZHJlc3MEE3ZhbGlkYXRvckxlYXNlSWRLZXkJAKwCAgUPbGVhc2VJZEVudHJ5S2V5CQDYBAEIBRB2YWxpZGF0b3JBZGRyZXNzBWJ5dGVzBAckbWF0Y2gwCQChCAEFE3ZhbGlkYXRvckxlYXNlSWRLZXkDCQABAgUHJG1hdGNoMAIKQnl0ZVZlY3RvcgQCaWQFByRtYXRjaDAJAMwIAgkBC0xlYXNlQ2FuY2VsAQUCaWQFA25pbAMJAAECBQckbWF0Y2gwAgRVbml0BQNuaWwJAAIBAgtNYXRjaCBlcnJvcgEZZ2V0UmVnaXN0cmF0aW9uQ3ljbGVWYWx1ZQEQdmFsaWRhdG9yQWRkcmVzcwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEJAKwCAgUZcmVnaXN0cmF0aW9uQ3ljbGVFbnRyeUtleQkApQgBBRB2YWxpZGF0b3JBZGRyZXNzBRxlcnJvck1lc3NhZ2VVbmtub3duVmFsaWRhdG9yARZnZXRWYWxpZGF0b3JJZHNDaGFuZ2VzARB2YWxpZGF0b3JBZGRyZXNzBBJ0aGlzVmFsaWRhdG9ySWRLZXkJAKwCAgUTdmFsaWRhdG9ySWRFbnRyeUtleQkApQgBBRB2YWxpZGF0b3JBZGRyZXNzBA90aGlzVmFsaWRhdG9ySWQJARFAZXh0ck5hdGl2ZSgxMDU1KQEFEnRoaXNWYWxpZGF0b3JJZEtleQQXdGhpc1ZhbGlkYXRvckFkZHJlc3NLZXkJAKwCAgUYdmFsaWRhdG9yQWRkcmVzc0VudHJ5S2V5CQCkAwEFD3RoaXNWYWxpZGF0b3JJZAMDCQAAAgUPdGhpc1ZhbGlkYXRvcklkBRBhY3RpdmVWYWxpZGF0b3JzBgkAAAIFEGFjdGl2ZVZhbGlkYXRvcnMAAQkAzAgCCQELRGVsZXRlRW50cnkBBRJ0aGlzVmFsaWRhdG9ySWRLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQUXdGhpc1ZhbGlkYXRvckFkZHJlc3NLZXkFA25pbAQXbGFzdFZhbGlkYXRvckFkZHJlc3NLZXkJAKwCAgUYdmFsaWRhdG9yQWRkcmVzc0VudHJ5S2V5CQCkAwEFEGFjdGl2ZVZhbGlkYXRvcnMEEmxhc3RWYWxpZGF0b3JCeXRlcwkBEUBleHRyTmF0aXZlKDEwNTcpAQUXbGFzdFZhbGlkYXRvckFkZHJlc3NLZXkEEmxhc3RWYWxpZGF0b3JJZEtleQkArAICBRN2YWxpZGF0b3JJZEVudHJ5S2V5CQDYBAEFEmxhc3RWYWxpZGF0b3JCeXRlcwkAzAgCCQEMSW50ZWdlckVudHJ5AgUSbGFzdFZhbGlkYXRvcklkS2V5BQ90aGlzVmFsaWRhdG9ySWQJAMwIAgkBC0JpbmFyeUVudHJ5AgUXdGhpc1ZhbGlkYXRvckFkZHJlc3NLZXkFEmxhc3RWYWxpZGF0b3JCeXRlcwkAzAgCCQELRGVsZXRlRW50cnkBBRJ0aGlzVmFsaWRhdG9ySWRLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQUXbGFzdFZhbGlkYXRvckFkZHJlc3NLZXkFA25pbAEWYXNzZXJ0VmFsaWRhdG9yQWRkcmVzcwEQdmFsaWRhdG9yQWRkcmVzcwkBBmFzc2VydAIJAQlpc0RlZmluZWQBCQCiCAEJAKwCAgUVdmFsaWRhdG9yTWV0YUVudHJ5S2V5CQClCAEFEHZhbGlkYXRvckFkZHJlc3MFHGVycm9yTWVzc2FnZVVua25vd25WYWxpZGF0b3IBEGFzc2VydE9uZVBheW1lbnQBCmludm9jYXRpb24JAQZhc3NlcnQCCQAAAgkAkAMBCAUKaW52b2NhdGlvbghwYXltZW50cwABBRllcnJvck1lc3NhZ2VOb3RPbmVQYXltZW50ARphc3NlcnRMZWFzaW5nTm90SW5Qcm9ncmVzcwAEE2lzTGVhc2luZ0luUHJvZ3Jlc3MJAQt2YWx1ZU9yRWxzZQIJAKAIAQkArAICBRtpc0xlYXNpbmdJblByb2dyZXNzRW50cnlLZXkJAKQDAQUMY3VycmVudEN5Y2xlBwkBBmFzc2VydAIJAQEhAQUTaXNMZWFzaW5nSW5Qcm9ncmVzcwUdZXJyb3JNZXNzYWdlTGVhc2luZ0luUHJvZ3Jlc3MBEmFzc2VydFBheW1lbnRBc3NldAIKaW52b2NhdGlvbg1leHBlY3RlZFRva2VuCQEGYXNzZXJ0AgkAAAIICQCRAwIIBQppbnZvY2F0aW9uCHBheW1lbnRzAAAHYXNzZXRJZAUNZXhwZWN0ZWRUb2tlbgUdZXJyb3JNZXNzYWdlVW5leHBlY3RlZEFzc2V0SWQBFWFzc2VydE9uZVBheW1lbnRBc3NldAIKaW52b2NhdGlvbg1leHBlY3RlZFRva2VuBBFfYXNzZXJ0T25lUGF5bWVudAkBEGFzc2VydE9uZVBheW1lbnQBBQppbnZvY2F0aW9uAwkAAAIFEV9hc3NlcnRPbmVQYXltZW50BRFfYXNzZXJ0T25lUGF5bWVudAQTX2Fzc2VydFBheW1lbnRBc3NldAkBEmFzc2VydFBheW1lbnRBc3NldAIFCmludm9jYXRpb24FDWV4cGVjdGVkVG9rZW4DCQAAAgUTX2Fzc2VydFBheW1lbnRBc3NldAUTX2Fzc2VydFBheW1lbnRBc3NldAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgEeYXNzZXJ0Tm90S2lja2VkVmFsaWRhdG9yU3RhdHVzARB2YWxpZGF0b3JBZGRyZXNzCQEGYXNzZXJ0AgkBF2dldFZhbGlkYXRvclN0YXR1c1ZhbHVlAQUQdmFsaWRhdG9yQWRkcmVzcwUeZXJyb3JNZXNzYWdlVmFsaWRhdG9yV2FzS2lja2VkARphc3NlcnRWYWxpZGF0b3JJc0xlYXNlYWJsZQEQdmFsaWRhdG9yQWRkcmVzcwkBBmFzc2VydAIJAGYCBQxjdXJyZW50Q3ljbGUJARlnZXRSZWdpc3RyYXRpb25DeWNsZVZhbHVlAQUQdmFsaWRhdG9yQWRkcmVzcwUkZXJyb3JNZXNzYWdlVmFsaWRhdG9yTm90UmVhZHlUb0xlYXNlARphc3NlcnRDb250cmFjdEFjdGl2ZVN0YXR1cwAJAQZhc3NlcnQCBQ5jb250cmFjdFN0YXR1cwUdZXJyb3JNZXNzYWdlQ29udHJhY3ROb3RBY3RpdmUBDGFzc2VydENhbGxlcgIKaW52b2NhdGlvbghleHBlY3RlZAkBBmFzc2VydAIJAAACBQhleHBlY3RlZAgIBQppbnZvY2F0aW9uBmNhbGxlcgVieXRlcwUYZXJyb3JNZXNzYWdlVW5hdXRob3JpemVkARZhc3NlcnRDYWxsZXJJc0NvbnRyYWN0AQppbnZvY2F0aW9uCQEMYXNzZXJ0Q2FsbGVyAgUKaW52b2NhdGlvbggFBHRoaXMFYnl0ZXMBGWFzc2VydENhbGxlcklzU3RvcE1hbmFnZXIBCmludm9jYXRpb24JAQxhc3NlcnRDYWxsZXICBQppbnZvY2F0aW9uBQtzdG9wTWFuYWdlcgETYXNzZXJ0Q2FsbGVySXNBZG1pbgEKaW52b2NhdGlvbgkBDGFzc2VydENhbGxlcgIFCmludm9jYXRpb24FBWFkbWluAQ9hc3NlcnRDYW5VbmxvY2sCC3VubG9ja0Jsb2NrCXZhbGlkYXRvcgkBBmFzc2VydAIDCQBnAggFCWxhc3RCbG9jawZoZWlnaHQFC3VubG9ja0Jsb2NrBgkBASEBCQELdmFsdWVPckVsc2UCCQESZ2V0VmFsaWRhdG9yU3RhdHVzAQUJdmFsaWRhdG9yBwUUZXJyb3JNZXNzYWdlVG9vRWFybHkSCmludm9jYXRpb24BBGluaXQGCnd4eFRva2VuSWQFYWRtaW4Lc3RvcE1hbmFnZXIMZmVlQ29sbGVjdG9yCnB1enpsZVN3YXANeFdhdmVzV3JhcHBlcgQLY2FsbGVyQ2hlY2sJARZhc3NlcnRDYWxsZXJJc0NvbnRyYWN0AQUKaW52b2NhdGlvbgMJAAACBQtjYWxsZXJDaGVjawULY2FsbGVyQ2hlY2sEDl9hc3NlcnROb3RJbml0CQEGYXNzZXJ0AgkBASEBCQEJaXNEZWZpbmVkAQkAnwgBBRJzdGFydEJsb2NrRW50cnlLZXkFHmVycm9yTWVzc2FnZUFscmVhZHlJbml0aWFsaXplZAMJAAACBQ5fYXNzZXJ0Tm90SW5pdAUOX2Fzc2VydE5vdEluaXQEEnN0b3BNYW5hZ2VyQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQULc3RvcE1hbmFnZXIEDGFkbWluQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQUFYWRtaW4EE2ZlZUNvbGxlY3RvckFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDGZlZUNvbGxlY3RvcgQRcHV6emxlU3dhcEFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDYyKQEFCnB1enpsZVN3YXAEFHhXYXZlc1dyYXBwZXJBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBBQ14V2F2ZXNXcmFwcGVyBAh4V2F2ZXNJZAkBEUBleHRyTmF0aXZlKDEwNTIpAgUUeFdhdmVzV3JhcHBlckFkZHJlc3MCDXhXYXZlc0Fzc2V0SWQJAMwIAgkBCVVpbnRFbnRyeQIFEnRvdGFsVm90ZXNFbnRyeUtleQAACQDMCAIJAQlVaW50RW50cnkCBRZ4V2F2ZXhRdWFudGl0eUVudHJ5S2V5AAAJAMwIAgkBDEJvb2xlYW5FbnRyeQIFFmNvbnRyYWN0U3RhdHVzRW50cnlLZXkGCQDMCAIJAQtCaW5hcnlFbnRyeQIFEnd4eEFzc2V0SWRFbnRyeUtleQUKd3h4VG9rZW5JZAkAzAgCCQELQmluYXJ5RW50cnkCBRV4V2F2ZXNBc3NldElkRW50cnlLZXkFCHhXYXZlc0lkCQDMCAIJAQlVaW50RW50cnkCBRJhZG1pbkZlZUJQRW50cnlLZXkFCmFkbWluRmVlQlAJAMwIAgkBCVVpbnRFbnRyeQIFI3RvdGFsUmVxdWVzdGVkV2F2ZXNXaXRoZHJhd0VudHJ5S2V5AAAJAMwIAgkBCVVpbnRFbnRyeQIFEnN0YXJ0QmxvY2tFbnRyeUtleQgFCWxhc3RCbG9jawZoZWlnaHQJAMwIAgkBCVVpbnRFbnRyeQIFGXJlcXVpcmVkV1hYQW1vdW50RW50cnlLZXkFEXJlcXVpcmVkV1hYQW1vdW50CQDMCAIJAQtCaW5hcnlFbnRyeQIFE3N0b3BNYW5hZ2VyRW50cnlLZXkIBRJzdG9wTWFuYWdlckFkZHJlc3MFYnl0ZXMJAMwIAgkBCVVpbnRFbnRyeQIFHWN5Y2xlRHVyYXRpb25JbkJsb2Nrc0VudHJ5S2V5BRVjeWNsZUR1cmF0aW9uSW5CbG9ja3MJAMwIAgkBC0JpbmFyeUVudHJ5AgUZYWRtaW5GZWVDb2xsZWN0b3JFbnRyeUtleQgFE2ZlZUNvbGxlY3RvckFkZHJlc3MFYnl0ZXMJAMwIAgkBC0JpbmFyeUVudHJ5AgUNYWRtaW5FbnRyeUtleQgFDGFkbWluQWRkcmVzcwVieXRlcwkAzAgCCQEJVWludEVudHJ5AgUgZW1lcmdlbmN5Vm90aW5nVGhyZXNob2xkRW50cnlLZXkFGGVtZXJnZW5jeVZvdGluZ1RocmVzaG9sZAkAzAgCCQELQmluYXJ5RW50cnkCBRJwdXp6bGVTd2FwRW50cnlLZXkIBRFwdXp6bGVTd2FwQWRkcmVzcwVieXRlcwkAzAgCCQELQmluYXJ5RW50cnkCBRV4V2F2ZXNXcmFwcGVyRW50cnlLZXkIBRR4V2F2ZXNXcmFwcGVyQWRkcmVzcwVieXRlcwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCmludm9jYXRpb24BBHN0b3AABAtjYWxsZXJDaGVjawkBGWFzc2VydENhbGxlcklzU3RvcE1hbmFnZXIBBQppbnZvY2F0aW9uAwkAAAIFC2NhbGxlckNoZWNrBQtjYWxsZXJDaGVjawkAzAgCCQEMQm9vbGVhbkVudHJ5AgUWY29udHJhY3RTdGF0dXNFbnRyeUtleQcFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgppbnZvY2F0aW9uAQ5zZXRTdG9wTWFuYWdlcgEObmV3U3RvcE1hbmFnZXIEC2NhbGxlckNoZWNrCQETYXNzZXJ0Q2FsbGVySXNBZG1pbgEFCmludm9jYXRpb24DCQAAAgULY2FsbGVyQ2hlY2sFC2NhbGxlckNoZWNrBBVuZXdTdG9wTWFuYWdlckFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDYyKQEFDm5ld1N0b3BNYW5hZ2VyCQDMCAIJAQtCaW5hcnlFbnRyeQIFE3N0b3BNYW5hZ2VyRW50cnlLZXkIBRVuZXdTdG9wTWFuYWdlckFkZHJlc3MFYnl0ZXMFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgppbnZvY2F0aW9uAQ9zZXRGZWVDb2xsZWN0b3IBD25ld0ZlZUNvbGxlY3RvcgQLY2FsbGVyQ2hlY2sJARNhc3NlcnRDYWxsZXJJc0FkbWluAQUKaW52b2NhdGlvbgMJAAACBQtjYWxsZXJDaGVjawULY2FsbGVyQ2hlY2sEFm5ld0ZlZUNvbGxlY3RvckFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDYyKQEFD25ld0ZlZUNvbGxlY3RvcgkAzAgCCQELQmluYXJ5RW50cnkCBRlhZG1pbkZlZUNvbGxlY3RvckVudHJ5S2V5CAUWbmV3RmVlQ29sbGVjdG9yQWRkcmVzcwVieXRlcwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCmludm9jYXRpb24BCHNldEFkbWluAQhuZXdBZG1pbgQLY2FsbGVyQ2hlY2sJARNhc3NlcnRDYWxsZXJJc0FkbWluAQUKaW52b2NhdGlvbgMJAAACBQtjYWxsZXJDaGVjawULY2FsbGVyQ2hlY2sED25ld0FkbWluQWRkcmVzcwkBEUBleHRyTmF0aXZlKDEwNjIpAQUIbmV3QWRtaW4JAMwIAgkBC0JpbmFyeUVudHJ5AgUNYWRtaW5FbnRyeUtleQgFD25ld0FkbWluQWRkcmVzcwVieXRlcwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCmludm9jYXRpb24BDXNldEFkbWluRmVlQlABDW5ld0FkbWluRmVlQlAEC2NhbGxlckNoZWNrCQETYXNzZXJ0Q2FsbGVySXNBZG1pbgEFCmludm9jYXRpb24DCQAAAgULY2FsbGVyQ2hlY2sFC2NhbGxlckNoZWNrBBBfY2hlY2tBZG1pbkZlZUJQCQEGYXNzZXJ0AgMJAGcCBQ1uZXdBZG1pbkZlZUJQAAAJAGcCBQJCUAUNbmV3QWRtaW5GZWVCUAcFHWVycm9yTWVzc2FnZUludmFsaWRBZG1pbkZlZUJQAwkAAAIFEF9jaGVja0FkbWluRmVlQlAFEF9jaGVja0FkbWluRmVlQlAJAMwIAgkBCVVpbnRFbnRyeQIFEmFkbWluRmVlQlBFbnRyeUtleQUNbmV3QWRtaW5GZWVCUAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCmludm9jYXRpb24BEHN3YXBSZXdhcmRUb2tlbnMDCXJvdXRlc1N0cgZhbW91bnQMbWluVG9SZWNlaXZlBAtjYWxsZXJDaGVjawkBE2Fzc2VydENhbGxlcklzQWRtaW4BBQppbnZvY2F0aW9uAwkAAAIFC2NhbGxlckNoZWNrBQtjYWxsZXJDaGVjawQNc3BsaXR0ZWRSb3V0ZQkAtQkCCQCyAgIFCXJvdXRlc1N0cgAyAgEsBAlhc3NldDFTdHIJAJEDAgUNc3BsaXR0ZWRSb3V0ZQkAZQIJAJADAQUNc3BsaXR0ZWRSb3V0ZQABBAZhc3NldDEJANkEAQUJYXNzZXQxU3RyBAZzd2FwZWQJAPwHBAUKcHV6emxlU3dhcAIEc3dhcAkAzAgCBQlyb3V0ZXNTdHIJAMwIAgUMbWluVG9SZWNlaXZlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFBmFzc2V0MQUGYW1vdW50BQNuaWwDCQAAAgUGc3dhcGVkBQZzd2FwZWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgppbnZvY2F0aW9uAQhyZWdpc3RlcgELbWV0YWRhdGFVcmwEG19hc3NlcnRDb250cmFjdEFjdGl2ZVN0YXR1cwkBGmFzc2VydENvbnRyYWN0QWN0aXZlU3RhdHVzAAMJAAACBRtfYXNzZXJ0Q29udHJhY3RBY3RpdmVTdGF0dXMFG19hc3NlcnRDb250cmFjdEFjdGl2ZVN0YXR1cwQbX2Fzc2VydExlYXNpbmdOb3RJblByb2dyZXNzCQEaYXNzZXJ0TGVhc2luZ05vdEluUHJvZ3Jlc3MAAwkAAAIFG19hc3NlcnRMZWFzaW5nTm90SW5Qcm9ncmVzcwUbX2Fzc2VydExlYXNpbmdOb3RJblByb2dyZXNzBBZfYXNzZXJ0T25lUGF5bWVudEFzc2V0CQEVYXNzZXJ0T25lUGF5bWVudEFzc2V0AgUKaW52b2NhdGlvbgUKd3h4QXNzZXRJZAMJAAACBRZfYXNzZXJ0T25lUGF5bWVudEFzc2V0BRZfYXNzZXJ0T25lUGF5bWVudEFzc2V0BAl2YWxpZGF0b3IJAKUIAQgFCmludm9jYXRpb24GY2FsbGVyBAl3eHhBbW91bnQICQCRAwIIBQppbnZvY2F0aW9uCHBheW1lbnRzAAAGYW1vdW50BAx2YWxpZGF0b3JLZXkJAKwCAgUVdmFsaWRhdG9yTWV0YUVudHJ5S2V5BQl2YWxpZGF0b3IEFHJlZ2lzdGVyZWRJbkN5Y2xlS2V5CQCsAgIFGXJlZ2lzdHJhdGlvbkN5Y2xlRW50cnlLZXkFCXZhbGlkYXRvcgQCaWQJAGQCBRBhY3RpdmVWYWxpZGF0b3JzAAEEDnZhbGlkYXRvcklkS2V5CQCsAgIFE3ZhbGlkYXRvcklkRW50cnlLZXkFCXZhbGlkYXRvcgQTdmFsaWRhdG9yQWRkcmVzc0tleQkArAICBRh2YWxpZGF0b3JBZGRyZXNzRW50cnlLZXkJAKQDAQUCaWQEFF9hc3NlcnROb3RSZWdpc3RlcmVkCQEGYXNzZXJ0AgkBASEBCQEJaXNEZWZpbmVkAQkAoggBBQx2YWxpZGF0b3JLZXkFHWVycm9yTWVzc2FnZUFscmVhZHlSZWdpc3RlcmVkAwkAAAIFFF9hc3NlcnROb3RSZWdpc3RlcmVkBRRfYXNzZXJ0Tm90UmVnaXN0ZXJlZAQQX2Fzc2VydEVub3VnaFdYWAkBBmFzc2VydAIJAAACBRFyZXF1aXJlZFdYWEFtb3VudAUJd3h4QW1vdW50BRxlcnJvck1lc3NhZ2VJbnZhbGlkV1hYQW1vdW50AwkAAAIFEF9hc3NlcnRFbm91Z2hXWFgFEF9hc3NlcnRFbm91Z2hXWFgJAMwIAgkBCVVpbnRFbnRyeQIFFHJlZ2lzdGVyZWRJbkN5Y2xlS2V5BQxjdXJyZW50Q3ljbGUJAMwIAgkBC1N0cmluZ0VudHJ5AgUMdmFsaWRhdG9yS2V5BQttZXRhZGF0YVVybAkAzAgCCQEMQm9vbGVhbkVudHJ5AgkArAICBRd2YWxpZGF0b3JTdGF0dXNFbnRyeUtleQUJdmFsaWRhdG9yBgkAzAgCCQEJVWludEVudHJ5AgUgY3VycmVudEN5Y2xlSWdub3JlZFZhbGlkYXRvcnNLZXkJAGQCBR1jdXJyZW50Q3ljbGVJZ25vcmVkVmFsaWRhdG9ycwABCQDMCAIJAQlVaW50RW50cnkCBRhhY3RpdmVWYWxpZGF0b3JzRW50cnlLZXkJAGQCBRBhY3RpdmVWYWxpZGF0b3JzAAEJAMwIAgkBDEludGVnZXJFbnRyeQIFDnZhbGlkYXRvcklkS2V5BQJpZAkAzAgCCQELQmluYXJ5RW50cnkCBRN2YWxpZGF0b3JBZGRyZXNzS2V5CAgFCmludm9jYXRpb24GY2FsbGVyBWJ5dGVzBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4KaW52b2NhdGlvbgEKZGVyZWdpc3RlcgAEG19hc3NlcnRMZWFzaW5nTm90SW5Qcm9ncmVzcwkBGmFzc2VydExlYXNpbmdOb3RJblByb2dyZXNzAAMJAAACBRtfYXNzZXJ0TGVhc2luZ05vdEluUHJvZ3Jlc3MFG19hc3NlcnRMZWFzaW5nTm90SW5Qcm9ncmVzcwQQdmFsaWRhdG9yQWRkcmVzcwgFCmludm9jYXRpb24GY2FsbGVyBAl2YWxpZGF0b3IJAKUIAQgFCmludm9jYXRpb24GY2FsbGVyBBJ2YWxpZGF0b3JTdGF0dXNLZXkJAKwCAgUXdmFsaWRhdG9yU3RhdHVzRW50cnlLZXkFCXZhbGlkYXRvcgQRdmFsaWRhdG9yVm90ZXNLZXkJAKwCAgUNdm90ZXNFbnRyeUtleQUJdmFsaWRhdG9yBBRyZWdpc3RlcmVkSW5DeWNsZUtleQkArAICBRlyZWdpc3RyYXRpb25DeWNsZUVudHJ5S2V5BQl2YWxpZGF0b3IEF19hc3NlcnRWYWxpZGF0b3JBZGRyZXNzCQEWYXNzZXJ0VmFsaWRhdG9yQWRkcmVzcwEFEHZhbGlkYXRvckFkZHJlc3MDCQAAAgUXX2Fzc2VydFZhbGlkYXRvckFkZHJlc3MFF19hc3NlcnRWYWxpZGF0b3JBZGRyZXNzBBN2YWxpZGF0b3JJZHNDaGFuZ2VzCQEWZ2V0VmFsaWRhdG9ySWRzQ2hhbmdlcwEFEHZhbGlkYXRvckFkZHJlc3MEE3ZhbGlkYXRvckxlYXNlSWRLZXkJAKwCAgUPbGVhc2VJZEVudHJ5S2V5BQl2YWxpZGF0b3IEBmNhbmNlbAkBGmdldENhbmNlbExlYXNlRm9yVmFsaWRhdG9yAQUQdmFsaWRhdG9yQWRkcmVzcwQQbm9uS2lja2VkQ2hhbmdlcwMJARdnZXRWYWxpZGF0b3JTdGF0dXNWYWx1ZQEFEHZhbGlkYXRvckFkZHJlc3MEDnZhbGlkYXRvclZvdGVzCQELdmFsdWVPckVsc2UCCQCfCAEFEXZhbGlkYXRvclZvdGVzS2V5AAAJAM4IAgUTdmFsaWRhdG9ySWRzQ2hhbmdlcwkAzAgCCQEJVWludEVudHJ5AgUYYWN0aXZlVmFsaWRhdG9yc0VudHJ5S2V5CQBlAgUQYWN0aXZlVmFsaWRhdG9ycwABCQDMCAIJAQlVaW50RW50cnkCBRJ0b3RhbFZvdGVzRW50cnlLZXkJAGUCBQp0b3RhbFZvdGVzBQ52YWxpZGF0b3JWb3RlcwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBRB2YWxpZGF0b3JBZGRyZXNzBRFyZXF1aXJlZFdYWEFtb3VudAUKd3h4QXNzZXRJZAUDbmlsBQNuaWwEGGlnbm9yZWRWYWxpZGF0b3JzQ2hhbmdlcwMJAAACCQEZZ2V0UmVnaXN0cmF0aW9uQ3ljbGVWYWx1ZQEFEHZhbGlkYXRvckFkZHJlc3MFDGN1cnJlbnRDeWNsZQkAzAgCCQEJVWludEVudHJ5AgUgY3VycmVudEN5Y2xlSWdub3JlZFZhbGlkYXRvcnNLZXkJAGUCBR1jdXJyZW50Q3ljbGVJZ25vcmVkVmFsaWRhdG9ycwABBQNuaWwFA25pbAkAzggCCQDOCAIJAM4IAgUQbm9uS2lja2VkQ2hhbmdlcwUYaWdub3JlZFZhbGlkYXRvcnNDaGFuZ2VzBQZjYW5jZWwJAMwIAgkBC0RlbGV0ZUVudHJ5AQURdmFsaWRhdG9yVm90ZXNLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQUUcmVnaXN0ZXJlZEluQ3ljbGVLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQUSdmFsaWRhdG9yU3RhdHVzS2V5CQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgUVdmFsaWRhdG9yTWV0YUVudHJ5S2V5BQl2YWxpZGF0b3IJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICBRd2YWxpZGF0b3JMZWFzZXNFbnRyeUtleQUJdmFsaWRhdG9yCQDMCAIJAQtEZWxldGVFbnRyeQEFE3ZhbGlkYXRvckxlYXNlSWRLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQkArAICBSNsYXRlc3RWYWxpZGF0b3JMZWFzaW5nQ3ljbGVFbnRyeUtleQUJdmFsaWRhdG9yBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4KaW52b2NhdGlvbgEHZGVwb3NpdAAEG19hc3NlcnRDb250cmFjdEFjdGl2ZVN0YXR1cwkBGmFzc2VydENvbnRyYWN0QWN0aXZlU3RhdHVzAAMJAAACBRtfYXNzZXJ0Q29udHJhY3RBY3RpdmVTdGF0dXMFG19hc3NlcnRDb250cmFjdEFjdGl2ZVN0YXR1cwQbX2Fzc2VydExlYXNpbmdOb3RJblByb2dyZXNzCQEaYXNzZXJ0TGVhc2luZ05vdEluUHJvZ3Jlc3MAAwkAAAIFG19hc3NlcnRMZWFzaW5nTm90SW5Qcm9ncmVzcwUbX2Fzc2VydExlYXNpbmdOb3RJblByb2dyZXNzBBZfYXNzZXJ0T25lUGF5bWVudEFzc2V0CQEVYXNzZXJ0T25lUGF5bWVudEFzc2V0AgUKaW52b2NhdGlvbgUEdW5pdAMJAAACBRZfYXNzZXJ0T25lUGF5bWVudEFzc2V0BRZfYXNzZXJ0T25lUGF5bWVudEFzc2V0BAt3YXZlc0Ftb3VudAgJAJEDAggFCmludm9jYXRpb24IcGF5bWVudHMAAAZhbW91bnQEDHhXYXZlc0Ftb3VudAMJAAACBQ54V2F2ZXhRdWFudGl0eQAABQt3YXZlc0Ftb3VudAkAawMFC3dhdmVzQW1vdW50BQ54V2F2ZXhRdWFudGl0eQkAZQIICQDvBwEFBHRoaXMHcmVndWxhcgULd2F2ZXNBbW91bnQEEWFkbWluWFdhdmVzQW1vdW50CQBuBAUMeFdhdmVzQW1vdW50BQphZG1pbkZlZUJQBQJCUAUHQ0VJTElORwQbeFdhdmVzQW1vdW50V2l0aG91dEFkbWluRmVlCQBlAgUMeFdhdmVzQW1vdW50BRFhZG1pblhXYXZlc0Ftb3VudAQYYWRtaW5GZWVDb2xsZWN0b3JBZGRyZXNzCQEHQWRkcmVzcwEJARFAZXh0ck5hdGl2ZSgxMDU3KQEFGWFkbWluRmVlQ29sbGVjdG9yRW50cnlLZXkEBG1pbnQJAPwHBAUNeFdhdmVzV3JhcHBlcgIEbWludAkAzAgCBQx4V2F2ZXNBbW91bnQFA25pbAUDbmlsAwkAAAIFBG1pbnQFBG1pbnQJAMwIAgkBCVVpbnRFbnRyeQIFFnhXYXZleFF1YW50aXR5RW50cnlLZXkJAGQCBQ54V2F2ZXhRdWFudGl0eQUMeFdhdmVzQW1vdW50CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQppbnZvY2F0aW9uBmNhbGxlcgUbeFdhdmVzQW1vdW50V2l0aG91dEFkbWluRmVlBQ14V2F2ZXNBc3NldElkCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFGGFkbWluRmVlQ29sbGVjdG9yQWRkcmVzcwURYWRtaW5YV2F2ZXNBbW91bnQFDXhXYXZlc0Fzc2V0SWQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgppbnZvY2F0aW9uAQ9yZXF1ZXN0V2l0aGRyYXcABBtfYXNzZXJ0TGVhc2luZ05vdEluUHJvZ3Jlc3MJARphc3NlcnRMZWFzaW5nTm90SW5Qcm9ncmVzcwADCQAAAgUbX2Fzc2VydExlYXNpbmdOb3RJblByb2dyZXNzBRtfYXNzZXJ0TGVhc2luZ05vdEluUHJvZ3Jlc3MEFl9hc3NlcnRPbmVQYXltZW50QXNzZXQJARVhc3NlcnRPbmVQYXltZW50QXNzZXQCBQppbnZvY2F0aW9uBQ14V2F2ZXNBc3NldElkAwkAAAIFFl9hc3NlcnRPbmVQYXltZW50QXNzZXQFFl9hc3NlcnRPbmVQYXltZW50QXNzZXQEDHhXYXZlc0Ftb3VudAgJAJEDAggFCmludm9jYXRpb24IcGF5bWVudHMAAAZhbW91bnQEC3dhdmVzQW1vdW50CQBrAwUMeFdhdmVzQW1vdW50BRl3aXRoZHJhd1dhdmVzQmFsYW5jZVN0YXRlBRt3aXRoZHJhd1hXYXZleFF1YW50aXR5U3RhdGUECWNhbGxlcktleQkApQgBCAUKaW52b2NhdGlvbgZjYWxsZXIEGnJlcXVlc3RlZFhXYXZlc1dpdGhkcmF3S2V5CQCsAgIFH3JlcXVlc3RlZFhXYXZlc1dpdGhkcmF3RW50cnlLZXkFCWNhbGxlcktleQQZcmVxdWVzdGVkV2F2ZXNXaXRoZHJhd0tleQkArAICBR5yZXF1ZXN0ZWRXYXZlc1dpdGhkcmF3RW50cnlLZXkFCWNhbGxlcktleQQgcmVxdWVzdGVkWFdhdmVzV2l0aGRyYXdGb3JDYWxsZXIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUacmVxdWVzdGVkWFdhdmVzV2l0aGRyYXdLZXkAAAQfcmVxdWVzdGVkV2F2ZXNXaXRoZHJhd0ZvckNhbGxlcgkBC3ZhbHVlT3JFbHNlAgkAnwgBBRlyZXF1ZXN0ZWRXYXZlc1dpdGhkcmF3S2V5AAAJAMwIAgkBCVVpbnRFbnRyeQIFGnJlcXVlc3RlZFhXYXZlc1dpdGhkcmF3S2V5CQBkAgUgcmVxdWVzdGVkWFdhdmVzV2l0aGRyYXdGb3JDYWxsZXIFDHhXYXZlc0Ftb3VudAkAzAgCCQEJVWludEVudHJ5AgUZcmVxdWVzdGVkV2F2ZXNXaXRoZHJhd0tleQkAZAIFH3JlcXVlc3RlZFdhdmVzV2l0aGRyYXdGb3JDYWxsZXIFC3dhdmVzQW1vdW50CQDMCAIJAQlVaW50RW50cnkCBSN0b3RhbFJlcXVlc3RlZFdhdmVzV2l0aGRyYXdFbnRyeUtleQkAZAIFG3RvdGFsUmVxdWVzdGVkV2F2ZXNXaXRoZHJhdwULd2F2ZXNBbW91bnQFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgppbnZvY2F0aW9uAQ9wcm9jZXNzV2l0aGRyYXcBCXJlY2lwaWVudAQbX2Fzc2VydExlYXNpbmdOb3RJblByb2dyZXNzCQEaYXNzZXJ0TGVhc2luZ05vdEluUHJvZ3Jlc3MAAwkAAAIFG19hc3NlcnRMZWFzaW5nTm90SW5Qcm9ncmVzcwUbX2Fzc2VydExlYXNpbmdOb3RJblByb2dyZXNzBBByZWNpcGllbnRBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBBQlyZWNpcGllbnQEGnJlcXVlc3RlZFhXYXZlc1dpdGhkcmF3S2V5CQCsAgIFH3JlcXVlc3RlZFhXYXZlc1dpdGhkcmF3RW50cnlLZXkFCXJlY2lwaWVudAQZcmVxdWVzdGVkV2F2ZXNXaXRoZHJhd0tleQkArAICBR5yZXF1ZXN0ZWRXYXZlc1dpdGhkcmF3RW50cnlLZXkFCXJlY2lwaWVudAQWcmVxdWVzdGVkV2F2ZXNXaXRoZHJhdwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFGXJlcXVlc3RlZFdhdmVzV2l0aGRyYXdLZXkFH2Vycm9yTWVzc2FnZU5vUmVxdWVzdGVkV2l0aGRyYXcEF3JlcXVlc3RlZFhXYXZlc1dpdGhkcmF3CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUacmVxdWVzdGVkWFdhdmVzV2l0aGRyYXdLZXkFH2Vycm9yTWVzc2FnZU5vUmVxdWVzdGVkV2l0aGRyYXcED19hc3NlckF2YWlsYWJsZQkBBmFzc2VydAIJAGcCBQlhdmFpbGFibGUFFnJlcXVlc3RlZFdhdmVzV2l0aGRyYXcFIWVycm9yTWVzc2FnZVdhdmVzQmFsYW5jZU5vdEVub3VnaAMJAAACBQ9fYXNzZXJBdmFpbGFibGUFD19hc3NlckF2YWlsYWJsZQQEYnVybgkA/AcEBQ14V2F2ZXNXcmFwcGVyAgRidXJuBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFDXhXYXZlc0Fzc2V0SWQFF3JlcXVlc3RlZFhXYXZlc1dpdGhkcmF3BQNuaWwDCQAAAgUEYnVybgUEYnVybgkAzAgCCQEJVWludEVudHJ5AgUjdG90YWxSZXF1ZXN0ZWRXYXZlc1dpdGhkcmF3RW50cnlLZXkJAGUCBRt0b3RhbFJlcXVlc3RlZFdhdmVzV2l0aGRyYXcFFnJlcXVlc3RlZFdhdmVzV2l0aGRyYXcJAMwIAgkBC0RlbGV0ZUVudHJ5AQUacmVxdWVzdGVkWFdhdmVzV2l0aGRyYXdLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQUZcmVxdWVzdGVkV2F2ZXNXaXRoZHJhd0tleQkAzAgCCQEJVWludEVudHJ5AgUWeFdhdmV4UXVhbnRpdHlFbnRyeUtleQkAZQIFDnhXYXZleFF1YW50aXR5BRdyZXF1ZXN0ZWRYV2F2ZXNXaXRoZHJhdwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBRByZWNpcGllbnRBZGRyZXNzBRZyZXF1ZXN0ZWRXYXZlc1dpdGhkcmF3BQR1bml0BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4KaW52b2NhdGlvbgEOcmV2b2tlV2l0aGRyYXcABBtfYXNzZXJ0TGVhc2luZ05vdEluUHJvZ3Jlc3MJARphc3NlcnRMZWFzaW5nTm90SW5Qcm9ncmVzcwADCQAAAgUbX2Fzc2VydExlYXNpbmdOb3RJblByb2dyZXNzBRtfYXNzZXJ0TGVhc2luZ05vdEluUHJvZ3Jlc3MECXJlY2lwaWVudAkApQgBCAUKaW52b2NhdGlvbgZjYWxsZXIEGnJlcXVlc3RlZFhXYXZlc1dpdGhkcmF3S2V5CQCsAgIFH3JlcXVlc3RlZFhXYXZlc1dpdGhkcmF3RW50cnlLZXkFCXJlY2lwaWVudAQZcmVxdWVzdGVkV2F2ZXNXaXRoZHJhd0tleQkArAICBR5yZXF1ZXN0ZWRXYXZlc1dpdGhkcmF3RW50cnlLZXkFCXJlY2lwaWVudAQWcmVxdWVzdGVkV2F2ZXNXaXRoZHJhdwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEFGXJlcXVlc3RlZFdhdmVzV2l0aGRyYXdLZXkFH2Vycm9yTWVzc2FnZU5vUmVxdWVzdGVkV2l0aGRyYXcEF3JlcXVlc3RlZFhXYXZlc1dpdGhkcmF3CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUacmVxdWVzdGVkWFdhdmVzV2l0aGRyYXdLZXkFH2Vycm9yTWVzc2FnZU5vUmVxdWVzdGVkV2l0aGRyYXcJAMwIAgkBCVVpbnRFbnRyeQIFI3RvdGFsUmVxdWVzdGVkV2F2ZXNXaXRoZHJhd0VudHJ5S2V5CQBlAgUbdG90YWxSZXF1ZXN0ZWRXYXZlc1dpdGhkcmF3BRZyZXF1ZXN0ZWRXYXZlc1dpdGhkcmF3CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQppbnZvY2F0aW9uBmNhbGxlcgUXcmVxdWVzdGVkWFdhdmVzV2l0aGRyYXcFDXhXYXZlc0Fzc2V0SWQJAMwIAgkBC0RlbGV0ZUVudHJ5AQUacmVxdWVzdGVkWFdhdmVzV2l0aGRyYXdLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQUZcmVxdWVzdGVkV2F2ZXNXaXRoZHJhd0tleQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCmludm9jYXRpb24BBHZvdGUCCXZhbGlkYXRvcghpbnRlcnZhbAQbX2Fzc2VydENvbnRyYWN0QWN0aXZlU3RhdHVzCQEaYXNzZXJ0Q29udHJhY3RBY3RpdmVTdGF0dXMAAwkAAAIFG19hc3NlcnRDb250cmFjdEFjdGl2ZVN0YXR1cwUbX2Fzc2VydENvbnRyYWN0QWN0aXZlU3RhdHVzBBtfYXNzZXJ0TGVhc2luZ05vdEluUHJvZ3Jlc3MJARphc3NlcnRMZWFzaW5nTm90SW5Qcm9ncmVzcwADCQAAAgUbX2Fzc2VydExlYXNpbmdOb3RJblByb2dyZXNzBRtfYXNzZXJ0TGVhc2luZ05vdEluUHJvZ3Jlc3MEEHZhbGlkYXRvckFkZHJlc3MJARFAZXh0ck5hdGl2ZSgxMDYyKQEFCXZhbGlkYXRvcgQVX2Fzc2V0VmFsaWRhdG9yU3RhdHVzCQEeYXNzZXJ0Tm90S2lja2VkVmFsaWRhdG9yU3RhdHVzAQUQdmFsaWRhdG9yQWRkcmVzcwMJAAACBRVfYXNzZXRWYWxpZGF0b3JTdGF0dXMFFV9hc3NldFZhbGlkYXRvclN0YXR1cwQWX2Fzc2VydE9uZVBheW1lbnRBc3NldAkBFWFzc2VydE9uZVBheW1lbnRBc3NldAIFCmludm9jYXRpb24FCnd4eEFzc2V0SWQDCQAAAgUWX2Fzc2VydE9uZVBheW1lbnRBc3NldAUWX2Fzc2VydE9uZVBheW1lbnRBc3NldAQUX2Fzc2VydFZhbGlkSW50ZXJ2YWwJAQZhc3NlcnQCAwkAZwIFCGludGVydmFsBQ9taW5Wb3RlSW50ZXJ2YWwJAGcCBQ9tYXhWb3RlSW50ZXJ2YWwFCGludGVydmFsBwUbZXJyb3JNZXNzYWdlSW52YWxpZEludGVydmFsAwkAAAIFFF9hc3NlcnRWYWxpZEludGVydmFsBRRfYXNzZXJ0VmFsaWRJbnRlcnZhbAQLdW5sb2NrQmxvY2sJAGQCCAUJbGFzdEJsb2NrBmhlaWdodAUIaW50ZXJ2YWwEC25ld1VzZXJMb2NrCAkAkQMCCAUKaW52b2NhdGlvbghwYXltZW50cwAABmFtb3VudAQMbmV3VXNlclZvdGVzCQBrAwULbmV3VXNlckxvY2sJAQRzcXJ0BAUIaW50ZXJ2YWwAAAAABQVGTE9PUgUeY3ljbGVEdXJhdGlvbkluQmxvY2tzU3FydEZsb29yBBNjYWxsZXJVbmxvY2tLZXlQYXJ0CQCsAgIJAKwCAgkApQgBCAUKaW52b2NhdGlvbgZjYWxsZXICAXwJAKQDAQULdW5sb2NrQmxvY2sEDnVubG9ja0Jsb2NrS2V5CQCsAgIFE3VubG9ja0Jsb2NrRW50cnlLZXkFE2NhbGxlclVubG9ja0tleVBhcnQEFnRvdGFsVmFsaWRhdG9yVm90ZXNLZXkJAKwCAgUNdm90ZXNFbnRyeUtleQUJdmFsaWRhdG9yBAt1c2VyVm90ZUtleQkArAICBRB1c2VyVm90ZUVudHJ5S2V5BRNjYWxsZXJVbmxvY2tLZXlQYXJ0BAt1c2VyTG9ja0tleQkArAICBRB1c2VyTG9ja0VudHJ5S2V5BRNjYWxsZXJVbmxvY2tLZXlQYXJ0BAh1c2VyTG9jawkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQULdXNlclZvdGVLZXkAAAULbmV3VXNlckxvY2sECXVzZXJWb3RlcwkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQULdXNlckxvY2tLZXkAAAUMbmV3VXNlclZvdGVzBBN0b3RhbFZhbGlkYXRvclZvdGVzCQELdmFsdWVPckVsc2UCCQCfCAEFFnRvdGFsVmFsaWRhdG9yVm90ZXNLZXkAAAQXaWdub3JlVmFsaWRhdG9yc0NoYW5nZXMDCQAAAgkBGWdldFJlZ2lzdHJhdGlvbkN5Y2xlVmFsdWUBBRB2YWxpZGF0b3JBZGRyZXNzBQxjdXJyZW50Q3ljbGUJAMwIAgkBCVVpbnRFbnRyeQIFG2N1cnJlbnRDeWNsZUlnbm9yZWRWb3Rlc0tleQkAZAIFGGN1cnJlbnRDeWNsZUlnbm9yZWRWb3RlcwUMbmV3VXNlclZvdGVzBQNuaWwFA25pbAkAzggCBRdpZ25vcmVWYWxpZGF0b3JzQ2hhbmdlcwkAzAgCCQEJVWludEVudHJ5AgULdXNlclZvdGVLZXkFCXVzZXJWb3RlcwkAzAgCCQEJVWludEVudHJ5AgULdXNlckxvY2tLZXkFCHVzZXJMb2NrCQDMCAIJAQtCaW5hcnlFbnRyeQIFDnVubG9ja0Jsb2NrS2V5CAUQdmFsaWRhdG9yQWRkcmVzcwVieXRlcwkAzAgCCQEJVWludEVudHJ5AgUWdG90YWxWYWxpZGF0b3JWb3Rlc0tleQkAZAIFE3RvdGFsVmFsaWRhdG9yVm90ZXMFDG5ld1VzZXJWb3RlcwkAzAgCCQEJVWludEVudHJ5AgUSdG90YWxWb3Rlc0VudHJ5S2V5CQBkAgUKdG90YWxWb3RlcwUMbmV3VXNlclZvdGVzBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4KaW52b2NhdGlvbgEGcmVkZWVtAQt1bmxvY2tCbG9jawQbX2Fzc2VydExlYXNpbmdOb3RJblByb2dyZXNzCQEaYXNzZXJ0TGVhc2luZ05vdEluUHJvZ3Jlc3MAAwkAAAIFG19hc3NlcnRMZWFzaW5nTm90SW5Qcm9ncmVzcwUbX2Fzc2VydExlYXNpbmdOb3RJblByb2dyZXNzBBNjYWxsZXJVbmxvY2tLZXlQYXJ0CQCsAgIJAKwCAgkApQgBCAUKaW52b2NhdGlvbgZjYWxsZXICAXwJAKQDAQULdW5sb2NrQmxvY2sEDnVubG9ja0Jsb2NrS2V5CQCsAgIFE3VubG9ja0Jsb2NrRW50cnlLZXkFE2NhbGxlclVubG9ja0tleVBhcnQEC3VzZXJWb3RlS2V5CQCsAgIFEHVzZXJWb3RlRW50cnlLZXkFE2NhbGxlclVubG9ja0tleVBhcnQEC3VzZXJMb2NrS2V5CQCsAgIFEHVzZXJMb2NrRW50cnlLZXkFE2NhbGxlclVubG9ja0tleVBhcnQEEHZhbGlkYXRvckFkZHJlc3MJAQdBZGRyZXNzAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQChCAEFDnVubG9ja0Jsb2NrS2V5BRdlcnJvck1lc3NhZ2VVbmtub3duTG9jawQRdmFsaWRhdG9yVm90ZXNLZXkJAKwCAgUNdm90ZXNFbnRyeUtleQkA2AQBCAUQdmFsaWRhdG9yQWRkcmVzcwVieXRlcwQQX2Fzc2VydENhblVubG9jawkBD2Fzc2VydENhblVubG9jawIFC3VubG9ja0Jsb2NrBRB2YWxpZGF0b3JBZGRyZXNzAwkAAAIFEF9hc3NlcnRDYW5VbmxvY2sFEF9hc3NlcnRDYW5VbmxvY2sECXVzZXJWb3RlcwkBEUBleHRyTmF0aXZlKDEwNTUpAQULdXNlclZvdGVLZXkECHVzZXJMb2NrCQERQGV4dHJOYXRpdmUoMTA1NSkBBQt1c2VyTG9ja0tleQQGc3RhdHVzCQELdmFsdWVPckVsc2UCCQESZ2V0VmFsaWRhdG9yU3RhdHVzAQUQdmFsaWRhdG9yQWRkcmVzcwcEDHZvdGVzQ2hhbmdlcwMFBnN0YXR1cwkAzAgCCQEJVWludEVudHJ5AgURdmFsaWRhdG9yVm90ZXNLZXkJAGUCCQERQGV4dHJOYXRpdmUoMTA1NSkBBRF2YWxpZGF0b3JWb3Rlc0tleQUJdXNlclZvdGVzCQDMCAIJAQlVaW50RW50cnkCBRJ0b3RhbFZvdGVzRW50cnlLZXkJAGUCBQp0b3RhbFZvdGVzBQl1c2VyVm90ZXMFA25pbAUDbmlsCQDOCAIFDHZvdGVzQ2hhbmdlcwkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUKaW52b2NhdGlvbgZjYWxsZXIFCHVzZXJMb2NrBQp3eHhBc3NldElkCQDMCAIJAQtEZWxldGVFbnRyeQEFC3VzZXJWb3RlS2V5CQDMCAIJAQtEZWxldGVFbnRyeQEFDnVubG9ja0Jsb2NrS2V5CQDMCAIJAQtEZWxldGVFbnRyeQEFC3VzZXJMb2NrS2V5BQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4KaW52b2NhdGlvbgEHbGVhc2luZwEJdmFsaWRhdG9yBBB2YWxpZGF0b3JBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBBQl2YWxpZGF0b3IEG19hc3NlcnRWYWxpZGF0b3JJc05vdEtpY2tlZAkBHmFzc2VydE5vdEtpY2tlZFZhbGlkYXRvclN0YXR1cwEFEHZhbGlkYXRvckFkZHJlc3MDCQAAAgUbX2Fzc2VydFZhbGlkYXRvcklzTm90S2lja2VkBRtfYXNzZXJ0VmFsaWRhdG9ySXNOb3RLaWNrZWQEG19hc3NlcnRWYWxpZGF0b3JJc0xlYXNlYWJsZQkBGmFzc2VydFZhbGlkYXRvcklzTGVhc2VhYmxlAQUQdmFsaWRhdG9yQWRkcmVzcwMJAAACBRtfYXNzZXJ0VmFsaWRhdG9ySXNMZWFzZWFibGUFG19hc3NlcnRWYWxpZGF0b3JJc0xlYXNlYWJsZQQTdmFsaWRhdG9yTGVhc2VJZEtleQkArAICBQ9sZWFzZUlkRW50cnlLZXkFCXZhbGlkYXRvcgQVbGF0ZXN0TGVhc2luZ0N5Y2xlS2V5CQCsAgIFI2xhdGVzdFZhbGlkYXRvckxlYXNpbmdDeWNsZUVudHJ5S2V5BQl2YWxpZGF0b3IEEnZhbGlkYXRvckxlYXNlc0tleQkArAICBRd2YWxpZGF0b3JMZWFzZXNFbnRyeUtleQUJdmFsaWRhdG9yBA9jdXJyZW50Q3ljbGVLZXkJAKQDAQUMY3VycmVudEN5Y2xlBB5jdXJyZW50UHJvY2Vzc2VkTGVhc2VzRW50cnlLZXkJAKwCAgUXcHJvY2Vzc2VkTGVhc2VzRW50cnlLZXkFD2N1cnJlbnRDeWNsZUtleQQfY3VycmVudExlYXNpbmdQb29sVmFsdWVFbnRyeUtleQkArAICBRhsZWFzaW5nUG9vbFZhbHVlRW50cnlLZXkFD2N1cnJlbnRDeWNsZUtleQQiaXNDdXJyZW50TGVhc2luZ0luUHJvZ3Jlc3NFbnRyeUtleQkArAICBRtpc0xlYXNpbmdJblByb2dyZXNzRW50cnlLZXkFD2N1cnJlbnRDeWNsZUtleQQOdmFsaWRhdG9yVm90ZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkArAICBQ12b3Rlc0VudHJ5S2V5BQl2YWxpZGF0b3IAAAQSY3VycmVudExlYXNlQW1vdW50CQELdmFsdWVPckVsc2UCCQCfCAEFEnZhbGlkYXRvckxlYXNlc0tleQAABAtjYW5jZWxMZWFzZQkBGmdldENhbmNlbExlYXNlRm9yVmFsaWRhdG9yAQUQdmFsaWRhdG9yQWRkcmVzcwQTX2NoZWNrTGVhc2luZ1N0YXR1cwkBBmFzc2VydAIJAQIhPQIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUVbGF0ZXN0TGVhc2luZ0N5Y2xlS2V5AP///////////wEFDGN1cnJlbnRDeWNsZQUZZXJyb3JNZXNzYWdlQWxyZWFkeUxlYXNlZAMJAAACBRNfY2hlY2tMZWFzaW5nU3RhdHVzBRNfY2hlY2tMZWFzaW5nU3RhdHVzBBdwcm9jY2Vzc2VkTGVhc2VzRW50cmllcwkAZAIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUeY3VycmVudFByb2Nlc3NlZExlYXNlc0VudHJ5S2V5AAAAAQQQbGVhc2luZ1Bvb2xWYWx1ZQkBC3ZhbHVlT3JFbHNlAgkAnwgBBR9jdXJyZW50TGVhc2luZ1Bvb2xWYWx1ZUVudHJ5S2V5CAkA7wcBBQR0aGlzB3JlZ3VsYXIEE2FmdGVyTGVhc2luZ1Byb2Nlc3MDCQBmAgUeYWN0aXZlVmFsaWRhdG9yc1dpdGhvdXRJZ25vcmVkBRdwcm9jY2Vzc2VkTGVhc2VzRW50cmllcwkAzAgCCQEMQm9vbGVhbkVudHJ5AgUiaXNDdXJyZW50TGVhc2luZ0luUHJvZ3Jlc3NFbnRyeUtleQYJAMwIAgkBCVVpbnRFbnRyeQIFHmN1cnJlbnRQcm9jZXNzZWRMZWFzZXNFbnRyeUtleQUXcHJvY2Nlc3NlZExlYXNlc0VudHJpZXMJAMwIAgkBCVVpbnRFbnRyeQIFH2N1cnJlbnRMZWFzaW5nUG9vbFZhbHVlRW50cnlLZXkFEGxlYXNpbmdQb29sVmFsdWUFA25pbAkAzAgCCQEJVWludEVudHJ5AgUhd2l0aGRyYXdXYXZlc0JhbGFuY2VTdGF0ZUVudHJ5S2V5BRBsZWFzaW5nUG9vbFZhbHVlCQDMCAIJAQlVaW50RW50cnkCBSN3aXRoZHJhd1hXYXZleFF1YW50aXR5U3RhdGVFbnRyeUtleQUOeFdhdmV4UXVhbnRpdHkJAMwIAgkBDEludGVnZXJFbnRyeQIFGmxhdGVzdExlYXNpbmdDeWNsZUVudHJ5S2V5BQxjdXJyZW50Q3ljbGUJAMwIAgkBC0RlbGV0ZUVudHJ5AQUiaXNDdXJyZW50TGVhc2luZ0luUHJvZ3Jlc3NFbnRyeUtleQkAzAgCCQELRGVsZXRlRW50cnkBBR5jdXJyZW50UHJvY2Vzc2VkTGVhc2VzRW50cnlLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQUfY3VycmVudExlYXNpbmdQb29sVmFsdWVFbnRyeUtleQkAzAgCCQELRGVsZXRlRW50cnkBBSBjdXJyZW50Q3ljbGVJZ25vcmVkVmFsaWRhdG9yc0tleQkAzAgCCQELRGVsZXRlRW50cnkBBRtjdXJyZW50Q3ljbGVJZ25vcmVkVm90ZXNLZXkFA25pbAQSZGVsZXRlTGVhc2VFbnRyaWVzAwkBCWlzRGVmaW5lZAEJAJ8IAQUSdmFsaWRhdG9yTGVhc2VzS2V5CQDMCAIJAQtEZWxldGVFbnRyeQEFEnZhbGlkYXRvckxlYXNlc0tleQkAzAgCCQELRGVsZXRlRW50cnkBBRN2YWxpZGF0b3JMZWFzZUlkS2V5BQNuaWwFA25pbAQRdGFyZ2V0TGVhc2VBbW91bnQJAGsDCQBlAgUQbGVhc2luZ1Bvb2xWYWx1ZQUbdG90YWxSZXF1ZXN0ZWRXYXZlc1dpdGhkcmF3BQ52YWxpZGF0b3JWb3RlcwUddG90YWxWb3Rlc1dpdGhvdXRJZ25vcmVkVm90ZXMDAwkBASEBBQ5jb250cmFjdFN0YXR1cwYJAAACBR10b3RhbFZvdGVzV2l0aG91dElnbm9yZWRWb3RlcwAACQDOCAIJAM4IAgULY2FuY2VsTGVhc2UFEmRlbGV0ZUxlYXNlRW50cmllcwUTYWZ0ZXJMZWFzaW5nUHJvY2VzcwMJAQIhPQIFEXRhcmdldExlYXNlQW1vdW50BRJjdXJyZW50TGVhc2VBbW91bnQEBWxlYXNlCQDECAIFEHZhbGlkYXRvckFkZHJlc3MFEXRhcmdldExlYXNlQW1vdW50BA5sZWFzaW5nUHJvY2VzcwMJAAACBRF0YXJnZXRMZWFzZUFtb3VudAAABRJkZWxldGVMZWFzZUVudHJpZXMJAMwIAgUFbGVhc2UJAMwIAgkBC0JpbmFyeUVudHJ5AgUTdmFsaWRhdG9yTGVhc2VJZEtleQkAuQgBBQVsZWFzZQkAzAgCCQEJVWludEVudHJ5AgUSdmFsaWRhdG9yTGVhc2VzS2V5BRF0YXJnZXRMZWFzZUFtb3VudAUDbmlsCQDNCAIJAM4IAgkAzggCBQtjYW5jZWxMZWFzZQUObGVhc2luZ1Byb2Nlc3MFE2FmdGVyTGVhc2luZ1Byb2Nlc3MJAQlVaW50RW50cnkCBRVsYXRlc3RMZWFzaW5nQ3ljbGVLZXkFDGN1cnJlbnRDeWNsZQkAzQgCBRNhZnRlckxlYXNpbmdQcm9jZXNzCQEJVWludEVudHJ5AgUVbGF0ZXN0TGVhc2luZ0N5Y2xlS2V5BQxjdXJyZW50Q3ljbGUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4KaW52b2NhdGlvbgEPZW1lcmdlbmN5Vm90aW5nAQl2YWxpZGF0b3IEG19hc3NlcnRMZWFzaW5nTm90SW5Qcm9ncmVzcwkBGmFzc2VydExlYXNpbmdOb3RJblByb2dyZXNzAAMJAAACBRtfYXNzZXJ0TGVhc2luZ05vdEluUHJvZ3Jlc3MFG19hc3NlcnRMZWFzaW5nTm90SW5Qcm9ncmVzcwQbX2Fzc2VydENvbnRyYWN0QWN0aXZlU3RhdHVzCQEaYXNzZXJ0Q29udHJhY3RBY3RpdmVTdGF0dXMAAwkAAAIFG19hc3NlcnRDb250cmFjdEFjdGl2ZVN0YXR1cwUbX2Fzc2VydENvbnRyYWN0QWN0aXZlU3RhdHVzBBB2YWxpZGF0b3JBZGRyZXNzCQERQGV4dHJOYXRpdmUoMTA2MikBBQl2YWxpZGF0b3IEFV9hc3NldFZhbGlkYXRvclN0YXR1cwkBHmFzc2VydE5vdEtpY2tlZFZhbGlkYXRvclN0YXR1cwEFEHZhbGlkYXRvckFkZHJlc3MDCQAAAgUVX2Fzc2V0VmFsaWRhdG9yU3RhdHVzBRVfYXNzZXRWYWxpZGF0b3JTdGF0dXMEFl9hc3NlcnRPbmVQYXltZW50QXNzZXQJARVhc3NlcnRPbmVQYXltZW50QXNzZXQCBQppbnZvY2F0aW9uBQ14V2F2ZXNBc3NldElkAwkAAAIFFl9hc3NlcnRPbmVQYXltZW50QXNzZXQFFl9hc3NlcnRPbmVQYXltZW50QXNzZXQECnZvdGVBbW91bnQICQCRAwIIBQppbnZvY2F0aW9uCHBheW1lbnRzAAAGYW1vdW50BAljYWxsZXJLZXkJAKUIAQgFCmludm9jYXRpb24GY2FsbGVyBAt1bmxvY2tCbG9jawkAZAIIBQlsYXN0QmxvY2sGaGVpZ2h0BRNlbWVyZ2VuY3lWb3RpbmdMb2NrBBFlbWVyZ2VuY3lWb3Rlc0tleQkArAICBRZlbWVyZ2VuY3lWb3Rlc0VudHJ5S2V5BQl2YWxpZGF0b3IEFWVtZXJnZW5jeVVzZXJWb3Rlc0tleQkArAICCQCsAgIJAKwCAgUaZW1lcmdlbmN5VXNlclZvdGVzRW50cnlLZXkFCWNhbGxlcktleQIBfAUJdmFsaWRhdG9yBBF2YWxpZGF0b3JWb3Rlc0tleQkArAICBQ12b3Rlc0VudHJ5S2V5BQl2YWxpZGF0b3IEE3ZhbGlkYXRvckxlYXNlSWRLZXkJAKwCAgUPbGVhc2VJZEVudHJ5S2V5BQl2YWxpZGF0b3IEFGVtZXJnZW5jeVVzZXJMb2NrS2V5CQCsAgIJAKwCAgkArAICBRllbWVyZ2VuY3lVc2VyTG9ja0VudHJ5S2V5BQljYWxsZXJLZXkCAXwJAKQDAQULdW5sb2NrQmxvY2sEDmVtZXJnZW5jeVZvdGVzCQBkAgUKdm90ZUFtb3VudAkBC3ZhbHVlT3JFbHNlAgkAnwgBBRFlbWVyZ2VuY3lWb3Rlc0tleQAABA5pc1ZhbGlkYXRvckJhZAkAZgIJAGkCCQBoAgUOZW1lcmdlbmN5Vm90ZXMAZAUOeFdhdmV4UXVhbnRpdHkFGGVtZXJnZW5jeVZvdGluZ1RocmVzaG9sZAQKcHVuaXNobWVudAMFDmlzVmFsaWRhdG9yQmFkBAZjYW5jZWwJARpnZXRDYW5jZWxMZWFzZUZvclZhbGlkYXRvcgEFEHZhbGlkYXRvckFkZHJlc3MEE3RvdGFsVmFsaWRhdG9yVm90ZXMJAQt2YWx1ZU9yRWxzZQIJAJ8IAQURdmFsaWRhdG9yVm90ZXNLZXkAAAQNY3VycmVudFN0YXR1cwkBF2dldFZhbGlkYXRvclN0YXR1c1ZhbHVlAQUQdmFsaWRhdG9yQWRkcmVzcwQabGVhc2VhYmxlVmFsaWRhdG9yc0NoYW5nZXMDBQ1jdXJyZW50U3RhdHVzCQDMCAIJAQlVaW50RW50cnkCBRhhY3RpdmVWYWxpZGF0b3JzRW50cnlLZXkJAGUCBRBhY3RpdmVWYWxpZGF0b3JzAAEFA25pbAUDbmlsBBN2YWxpZGF0b3JJZHNDaGFuZ2VzCQEWZ2V0VmFsaWRhdG9ySWRzQ2hhbmdlcwEFEHZhbGlkYXRvckFkZHJlc3MJAM4IAgkAzggCCQDOCAIFE3ZhbGlkYXRvcklkc0NoYW5nZXMFGmxlYXNlYWJsZVZhbGlkYXRvcnNDaGFuZ2VzBQZjYW5jZWwJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFDHd4eEFzc2V0SW5mbwZpc3N1ZXIFEXJlcXVpcmVkV1hYQW1vdW50BQp3eHhBc3NldElkCQDMCAIJAQlVaW50RW50cnkCBRJ0b3RhbFZvdGVzRW50cnlLZXkJAGUCBQp0b3RhbFZvdGVzBRN0b3RhbFZhbGlkYXRvclZvdGVzCQDMCAIJAQxCb29sZWFuRW50cnkCCQCsAgIFF3ZhbGlkYXRvclN0YXR1c0VudHJ5S2V5BQl2YWxpZGF0b3IHCQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgUXdmFsaWRhdG9yTGVhc2VzRW50cnlLZXkFCXZhbGlkYXRvcgkAzAgCCQELRGVsZXRlRW50cnkBBRN2YWxpZGF0b3JMZWFzZUlkS2V5CQDMCAIJAQtEZWxldGVFbnRyeQEJAKwCAgUjbGF0ZXN0VmFsaWRhdG9yTGVhc2luZ0N5Y2xlRW50cnlLZXkFCXZhbGlkYXRvcgUDbmlsBQNuaWwJAM4IAgUKcHVuaXNobWVudAkAzAgCCQELQmluYXJ5RW50cnkCBRRlbWVyZ2VuY3lVc2VyTG9ja0tleQgFEHZhbGlkYXRvckFkZHJlc3MFYnl0ZXMJAMwIAgkBCVVpbnRFbnRyeQIFEWVtZXJnZW5jeVZvdGVzS2V5BQ5lbWVyZ2VuY3lWb3RlcwkAzAgCCQEJVWludEVudHJ5AgUVZW1lcmdlbmN5VXNlclZvdGVzS2V5CQBkAgkBC3ZhbHVlT3JFbHNlAgkAnwgBBRVlbWVyZ2VuY3lVc2VyVm90ZXNLZXkAAAUKdm90ZUFtb3VudAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCmludm9jYXRpb24BE3JlZGVlbUVtZXJnZW5jeVZvdGUBC3VubG9ja0Jsb2NrBAljYWxsZXJLZXkJAKUIAQgFCmludm9jYXRpb24GY2FsbGVyBBRlbWVyZ2VuY3lVc2VyTG9ja0tleQkArAICCQCsAgIJAKwCAgUZZW1lcmdlbmN5VXNlckxvY2tFbnRyeUtleQUJY2FsbGVyS2V5AgF8CQCkAwEFC3VubG9ja0Jsb2NrBBB2YWxpZGF0b3JBZGRyZXNzCQEHQWRkcmVzcwEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAoQgBBRRlbWVyZ2VuY3lVc2VyTG9ja0tleQUXZXJyb3JNZXNzYWdlVW5rbm93bkxvY2sECXZhbGlkYXRvcgkApQgBBRB2YWxpZGF0b3JBZGRyZXNzBBBfYXNzZXJ0Q2FuVW5sb2NrCQEPYXNzZXJ0Q2FuVW5sb2NrAgULdW5sb2NrQmxvY2sFEHZhbGlkYXRvckFkZHJlc3MDCQAAAgUQX2Fzc2VydENhblVubG9jawUQX2Fzc2VydENhblVubG9jawQRZW1lcmdlbmN5Vm90ZXNLZXkJAKwCAgUWZW1lcmdlbmN5Vm90ZXNFbnRyeUtleQUJdmFsaWRhdG9yBBVlbWVyZ2VuY3lVc2VyVm90ZXNLZXkJAKwCAgkArAICCQCsAgIFGmVtZXJnZW5jeVVzZXJWb3Rlc0VudHJ5S2V5BQljYWxsZXJLZXkCAXwFCXZhbGlkYXRvcgQSZW1lcmdlbmN5VXNlclZvdGVzCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQUVZW1lcmdlbmN5VXNlclZvdGVzS2V5BRxlcnJvck1lc3NhZ2VOb0VtZXJnZW5jeVZvdGVzBA5lbWVyZ2VuY3lWb3RlcwkAZQIJARFAZXh0ck5hdGl2ZSgxMDU1KQEFEWVtZXJnZW5jeVZvdGVzS2V5BRJlbWVyZ2VuY3lVc2VyVm90ZXMJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFCmludm9jYXRpb24GY2FsbGVyBRJlbWVyZ2VuY3lVc2VyVm90ZXMFDXhXYXZlc0Fzc2V0SWQJAMwIAgkBCVVpbnRFbnRyeQIFEWVtZXJnZW5jeVZvdGVzS2V5BQ5lbWVyZ2VuY3lWb3RlcwkAzAgCCQELRGVsZXRlRW50cnkBBRVlbWVyZ2VuY3lVc2VyVm90ZXNLZXkJAMwIAgkBC0RlbGV0ZUVudHJ5AQUUZW1lcmdlbmN5VXNlckxvY2tLZXkFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECdHgBBnZlcmlmeQAEByRtYXRjaDAFAnR4AwkAAQIFByRtYXRjaDACFFNldFNjcmlwdFRyYW5zYWN0aW9uBAN0dHgFByRtYXRjaDAJAQEhAQkBCWlzRGVmaW5lZAEJAJ8IAQUSc3RhcnRCbG9ja0VudHJ5S2V5CQD0AwMIBQJ0eAlib2R5Qnl0ZXMJAJEDAggFAnR4BnByb29mcwAACAUCdHgPc2VuZGVyUHVibGljS2V58FzQ+w==", "height": 3540795, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
Old | New | Differences | |
---|---|---|---|
1 | - | # no script | |
1 | + | {-# STDLIB_VERSION 7 #-} | |
2 | + | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | + | {-# CONTENT_TYPE DAPP #-} | |
4 | + | let BP = 10000 | |
5 | + | ||
6 | + | let requiredWXXAmount = 10000000000 | |
7 | + | ||
8 | + | let cycleDurationInBlocks = 1000 | |
9 | + | ||
10 | + | let cycleDurationInBlocksSqrtFloor = 3 | |
11 | + | ||
12 | + | let minVoteCycleInterval = 1 | |
13 | + | ||
14 | + | let minVoteInterval = (cycleDurationInBlocks * minVoteCycleInterval) | |
15 | + | ||
16 | + | let maxVoteCycleInterval = 530 | |
17 | + | ||
18 | + | let maxVoteInterval = (cycleDurationInBlocks * maxVoteCycleInterval) | |
19 | + | ||
20 | + | let emergencyVotingThreshold = 10 | |
21 | + | ||
22 | + | let emergencyVotingLockInCycles = 10 | |
23 | + | ||
24 | + | let emergencyVotingLock = (emergencyVotingLockInCycles * cycleDurationInBlocks) | |
25 | + | ||
26 | + | let validatorStatusEntryKey = "validatorStatus:" | |
27 | + | ||
28 | + | let activeValidatorsEntryKey = "activeValidators" | |
29 | + | ||
30 | + | let adminFeeBPEntryKey = "adminFeeBP" | |
31 | + | ||
32 | + | let leasingPoolValueEntryKey = "leasingPoolValue:" | |
33 | + | ||
34 | + | let cycleDurationInBlocksEntryKey = "cycleDurationInBlocks" | |
35 | + | ||
36 | + | let emergencyUserVotesEntryKey = "emergencyUserVotes:" | |
37 | + | ||
38 | + | let emergencyVotesEntryKey = "emergencyVotes:" | |
39 | + | ||
40 | + | let emergencyVotingThresholdEntryKey = "emergencyVotingThreshold" | |
41 | + | ||
42 | + | let emergencyUserLockEntryKey = "emergencyUserLock:" | |
43 | + | ||
44 | + | let isLeasingInProgressEntryKey = "isLeasingInProgress:" | |
45 | + | ||
46 | + | let latestLeasingCycleEntryKey = "latestLeasingCycle" | |
47 | + | ||
48 | + | let latestValidatorLeasingCycleEntryKey = "latestLeasingCycle:" | |
49 | + | ||
50 | + | let registrationCycleEntryKey = "registrationCycle:" | |
51 | + | ||
52 | + | let leaseIdEntryKey = "leaseId:" | |
53 | + | ||
54 | + | let processedLeasesEntryKey = "processedLeases:" | |
55 | + | ||
56 | + | let requestedXWavesWithdrawEntryKey = "requestedXWavesWithdraw:" | |
57 | + | ||
58 | + | let requestedWavesWithdrawEntryKey = "requestedWavesWithdraw:" | |
59 | + | ||
60 | + | let requiredWXXAmountEntryKey = "requiredWXXAmount" | |
61 | + | ||
62 | + | let startBlockEntryKey = "startBlock" | |
63 | + | ||
64 | + | let contractStatusEntryKey = "contractStatus" | |
65 | + | ||
66 | + | let stopManagerEntryKey = "stopManager" | |
67 | + | ||
68 | + | let totalRequestedWavesWithdrawEntryKey = "totalRequestedWavesWithdraw" | |
69 | + | ||
70 | + | let totalVotesEntryKey = "totalVotes" | |
71 | + | ||
72 | + | let unlockBlockEntryKey = "unlockBlock:" | |
73 | + | ||
74 | + | let userLockEntryKey = "userLock:" | |
75 | + | ||
76 | + | let userVoteEntryKey = "userVote:" | |
77 | + | ||
78 | + | let validatorMetaEntryKey = "validatorMeta:" | |
79 | + | ||
80 | + | let validatorAddressEntryKey = "validatorAddress:" | |
81 | + | ||
82 | + | let validatorIdEntryKey = "validatorId:" | |
83 | + | ||
84 | + | let validatorLeasesEntryKey = "validatorLeases:" | |
85 | + | ||
86 | + | let votesEntryKey = "votes:" | |
87 | + | ||
88 | + | let withdrawXWavexQuantityStateEntryKey = "withdrawXWavexQuantityState" | |
89 | + | ||
90 | + | let withdrawWavesBalanceStateEntryKey = "withdrawWavesBalanceState" | |
91 | + | ||
92 | + | let wxxAssetIdEntryKey = "wxxAssetId" | |
93 | + | ||
94 | + | let xWavesAssetIdEntryKey = "xWavesAssetId" | |
95 | + | ||
96 | + | let xWavesWrapperEntryKey = "xWavesWrapper" | |
97 | + | ||
98 | + | let adminFeeCollectorEntryKey = "adminFeeCollector" | |
99 | + | ||
100 | + | let ignoredVotesEntryKey = "ignoreVotes:" | |
101 | + | ||
102 | + | let ignoredValidatorsEntryKey = "ignoredValidators:" | |
103 | + | ||
104 | + | let adminEntryKey = "admin" | |
105 | + | ||
106 | + | let xWavexQuantityEntryKey = "xWavexQuantity" | |
107 | + | ||
108 | + | let puzzleSwapEntryKey = "puzzleSwap" | |
109 | + | ||
110 | + | let errorMessageUnreachable = "Unreachable" | |
111 | + | ||
112 | + | let errorMessageAlreadyInitialized = "Already initialized" | |
113 | + | ||
114 | + | let errorMessageAlreadyLeased = "Already leased" | |
115 | + | ||
116 | + | let errorMessageAlreadyRegistered = "Already registered" | |
117 | + | ||
118 | + | let errorMessageContractNotActive = "Contract is not active" | |
119 | + | ||
120 | + | let errorMessageInvalidInterval = "Invalid interval" | |
121 | + | ||
122 | + | let errorMessageInvalidWXXAmount = "Invalid WXX amount" | |
123 | + | ||
124 | + | let errorMessageLeasingInProgress = "Leasing in progress" | |
125 | + | ||
126 | + | let errorMessageNoEmergencyVotes = "No emergency votes for user" | |
127 | + | ||
128 | + | let errorMessageNoRequestedWithdraw = "No requested withdraw" | |
129 | + | ||
130 | + | let errorMessageNotOnePayment = "Not one payment" | |
131 | + | ||
132 | + | let errorMessageTooEarly = "Too early" | |
133 | + | ||
134 | + | let errorMessageUnauthorized = "Unauthorized" | |
135 | + | ||
136 | + | let errorMessageUnexpectedAssetId = "Unexpected asset id" | |
137 | + | ||
138 | + | let errorMessageUnknownLock = "Unknown lock" | |
139 | + | ||
140 | + | let errorMessageUnknownValidator = "Unknown validator" | |
141 | + | ||
142 | + | let errorMessageValidatorNotReadyToLease = "Validator is not ready to lease" | |
143 | + | ||
144 | + | let errorMessageWavesBalanceNotEnough = "Not enough WAVES. Please try later" | |
145 | + | ||
146 | + | let errorMessageValidatorWasKicked = "Validator was kicked" | |
147 | + | ||
148 | + | let errorMessageInvalidAdminFeeBP = "Invalid adminFeeBP" | |
149 | + | ||
150 | + | let errorMessageInvalidUint = "Invalid Uint" | |
151 | + | ||
152 | + | let available = wavesBalance(this).available | |
153 | + | ||
154 | + | let wxxAssetId = getBinaryValue(wxxAssetIdEntryKey) | |
155 | + | ||
156 | + | let xWavesAssetId = getBinaryValue(xWavesAssetIdEntryKey) | |
157 | + | ||
158 | + | let xWavesWrapper = Address(getBinaryValue(xWavesWrapperEntryKey)) | |
159 | + | ||
160 | + | let wxxAssetInfo = valueOrErrorMessage(assetInfo(wxxAssetId), errorMessageUnreachable) | |
161 | + | ||
162 | + | let xWavexQuantity = getIntegerValue(xWavexQuantityEntryKey) | |
163 | + | ||
164 | + | let currentCycle = ((lastBlock.height - getIntegerValue(startBlockEntryKey)) / cycleDurationInBlocks) | |
165 | + | ||
166 | + | let withdrawWavesBalanceState = valueOrElse(getInteger(withdrawWavesBalanceStateEntryKey), wavesBalance(this).regular) | |
167 | + | ||
168 | + | let withdrawXWavexQuantityState = valueOrElse(getInteger(withdrawXWavexQuantityStateEntryKey), xWavexQuantity) | |
169 | + | ||
170 | + | let currentCycleIgnoredVotesKey = (ignoredVotesEntryKey + toString(currentCycle)) | |
171 | + | ||
172 | + | let currentCycleIgnoredValidatorsKey = (ignoredValidatorsEntryKey + toString(currentCycle)) | |
173 | + | ||
174 | + | let currentCycleIgnoredVotes = valueOrElse(getInteger(currentCycleIgnoredVotesKey), 0) | |
175 | + | ||
176 | + | let currentCycleIgnoredValidators = valueOrElse(getInteger(currentCycleIgnoredValidatorsKey), 0) | |
177 | + | ||
178 | + | let totalVotes = getIntegerValue(totalVotesEntryKey) | |
179 | + | ||
180 | + | let totalVotesWithoutIgnoredVotes = (totalVotes - currentCycleIgnoredVotes) | |
181 | + | ||
182 | + | let totalRequestedWavesWithdraw = valueOrElse(getInteger(totalRequestedWavesWithdrawEntryKey), 0) | |
183 | + | ||
184 | + | let contractStatus = getBooleanValue(contractStatusEntryKey) | |
185 | + | ||
186 | + | let stopManager = getBinaryValue(stopManagerEntryKey) | |
187 | + | ||
188 | + | let admin = getBinaryValue(adminEntryKey) | |
189 | + | ||
190 | + | let adminFeeBP = valueOrElse(getInteger(adminFeeBPEntryKey), 50) | |
191 | + | ||
192 | + | let activeValidators = valueOrElse(getInteger(activeValidatorsEntryKey), 0) | |
193 | + | ||
194 | + | let activeValidatorsWithoutIgnored = (activeValidators - currentCycleIgnoredValidators) | |
195 | + | ||
196 | + | let puzzleSwap = Address(getBinaryValue(puzzleSwapEntryKey)) | |
197 | + | ||
198 | + | func assert (v,e) = if (v) | |
199 | + | then unit | |
200 | + | else throw(e) | |
201 | + | ||
202 | + | ||
203 | + | func UintEntry (key,v) = { | |
204 | + | let _assertUint = assert((v >= 0), errorMessageInvalidUint) | |
205 | + | if ((_assertUint == _assertUint)) | |
206 | + | then IntegerEntry(key, v) | |
207 | + | else throw("Strict value is not equal to itself.") | |
208 | + | } | |
209 | + | ||
210 | + | ||
211 | + | func getValidatorStatus (validatorAddress) = getBoolean((validatorStatusEntryKey + toString(validatorAddress))) | |
212 | + | ||
213 | + | ||
214 | + | func getValidatorStatusValue (validatorAddress) = valueOrErrorMessage(getValidatorStatus(validatorAddress), errorMessageUnknownValidator) | |
215 | + | ||
216 | + | ||
217 | + | func getCancelLeaseForValidator (validatorAddress) = { | |
218 | + | let validatorLeaseIdKey = (leaseIdEntryKey + toBase58String(validatorAddress.bytes)) | |
219 | + | match getBinary(validatorLeaseIdKey) { | |
220 | + | case id: ByteVector => | |
221 | + | [LeaseCancel(id)] | |
222 | + | case _: Unit => | |
223 | + | nil | |
224 | + | case _ => | |
225 | + | throw("Match error") | |
226 | + | } | |
227 | + | } | |
228 | + | ||
229 | + | ||
230 | + | func getRegistrationCycleValue (validatorAddress) = valueOrErrorMessage(getInteger((registrationCycleEntryKey + toString(validatorAddress))), errorMessageUnknownValidator) | |
231 | + | ||
232 | + | ||
233 | + | func getValidatorIdsChanges (validatorAddress) = { | |
234 | + | let thisValidatorIdKey = (validatorIdEntryKey + toString(validatorAddress)) | |
235 | + | let thisValidatorId = getIntegerValue(thisValidatorIdKey) | |
236 | + | let thisValidatorAddressKey = (validatorAddressEntryKey + toString(thisValidatorId)) | |
237 | + | if (if ((thisValidatorId == activeValidators)) | |
238 | + | then true | |
239 | + | else (activeValidators == 1)) | |
240 | + | then [DeleteEntry(thisValidatorIdKey), DeleteEntry(thisValidatorAddressKey)] | |
241 | + | else { | |
242 | + | let lastValidatorAddressKey = (validatorAddressEntryKey + toString(activeValidators)) | |
243 | + | let lastValidatorBytes = getBinaryValue(lastValidatorAddressKey) | |
244 | + | let lastValidatorIdKey = (validatorIdEntryKey + toBase58String(lastValidatorBytes)) | |
245 | + | [IntegerEntry(lastValidatorIdKey, thisValidatorId), BinaryEntry(thisValidatorAddressKey, lastValidatorBytes), DeleteEntry(thisValidatorIdKey), DeleteEntry(lastValidatorAddressKey)] | |
246 | + | } | |
247 | + | } | |
248 | + | ||
249 | + | ||
250 | + | func assertValidatorAddress (validatorAddress) = assert(isDefined(getString((validatorMetaEntryKey + toString(validatorAddress)))), errorMessageUnknownValidator) | |
251 | + | ||
252 | + | ||
253 | + | func assertOnePayment (invocation) = assert((size(invocation.payments) == 1), errorMessageNotOnePayment) | |
254 | + | ||
255 | + | ||
256 | + | func assertLeasingNotInProgress () = { | |
257 | + | let isLeasingInProgress = valueOrElse(getBoolean((isLeasingInProgressEntryKey + toString(currentCycle))), false) | |
258 | + | assert(!(isLeasingInProgress), errorMessageLeasingInProgress) | |
259 | + | } | |
260 | + | ||
261 | + | ||
262 | + | func assertPaymentAsset (invocation,expectedToken) = assert((invocation.payments[0].assetId == expectedToken), errorMessageUnexpectedAssetId) | |
263 | + | ||
264 | + | ||
265 | + | func assertOnePaymentAsset (invocation,expectedToken) = { | |
266 | + | let _assertOnePayment = assertOnePayment(invocation) | |
267 | + | if ((_assertOnePayment == _assertOnePayment)) | |
268 | + | then { | |
269 | + | let _assertPaymentAsset = assertPaymentAsset(invocation, expectedToken) | |
270 | + | if ((_assertPaymentAsset == _assertPaymentAsset)) | |
271 | + | then unit | |
272 | + | else throw("Strict value is not equal to itself.") | |
273 | + | } | |
274 | + | else throw("Strict value is not equal to itself.") | |
275 | + | } | |
276 | + | ||
277 | + | ||
278 | + | func assertNotKickedValidatorStatus (validatorAddress) = assert(getValidatorStatusValue(validatorAddress), errorMessageValidatorWasKicked) | |
279 | + | ||
280 | + | ||
281 | + | func assertValidatorIsLeaseable (validatorAddress) = assert((currentCycle > getRegistrationCycleValue(validatorAddress)), errorMessageValidatorNotReadyToLease) | |
282 | + | ||
283 | + | ||
284 | + | func assertContractActiveStatus () = assert(contractStatus, errorMessageContractNotActive) | |
285 | + | ||
286 | + | ||
287 | + | func assertCaller (invocation,expected) = assert((expected == invocation.caller.bytes), errorMessageUnauthorized) | |
288 | + | ||
289 | + | ||
290 | + | func assertCallerIsContract (invocation) = assertCaller(invocation, this.bytes) | |
291 | + | ||
292 | + | ||
293 | + | func assertCallerIsStopManager (invocation) = assertCaller(invocation, stopManager) | |
294 | + | ||
295 | + | ||
296 | + | func assertCallerIsAdmin (invocation) = assertCaller(invocation, admin) | |
297 | + | ||
298 | + | ||
299 | + | func assertCanUnlock (unlockBlock,validator) = assert(if ((lastBlock.height >= unlockBlock)) | |
300 | + | then true | |
301 | + | else !(valueOrElse(getValidatorStatus(validator), false)), errorMessageTooEarly) | |
302 | + | ||
303 | + | ||
304 | + | @Callable(invocation) | |
305 | + | func init (wxxTokenId,admin,stopManager,feeCollector,puzzleSwap,xWavesWrapper) = { | |
306 | + | let callerCheck = assertCallerIsContract(invocation) | |
307 | + | if ((callerCheck == callerCheck)) | |
308 | + | then { | |
309 | + | let _assertNotInit = assert(!(isDefined(getInteger(startBlockEntryKey))), errorMessageAlreadyInitialized) | |
310 | + | if ((_assertNotInit == _assertNotInit)) | |
311 | + | then { | |
312 | + | let stopManagerAddress = addressFromStringValue(stopManager) | |
313 | + | let adminAddress = addressFromStringValue(admin) | |
314 | + | let feeCollectorAddress = addressFromStringValue(feeCollector) | |
315 | + | let puzzleSwapAddress = addressFromStringValue(puzzleSwap) | |
316 | + | let xWavesWrapperAddress = addressFromStringValue(xWavesWrapper) | |
317 | + | let xWavesId = getBinaryValue(xWavesWrapperAddress, "xWavesAssetId") | |
318 | + | [UintEntry(totalVotesEntryKey, 0), UintEntry(xWavexQuantityEntryKey, 0), BooleanEntry(contractStatusEntryKey, true), BinaryEntry(wxxAssetIdEntryKey, wxxTokenId), BinaryEntry(xWavesAssetIdEntryKey, xWavesId), UintEntry(adminFeeBPEntryKey, adminFeeBP), UintEntry(totalRequestedWavesWithdrawEntryKey, 0), UintEntry(startBlockEntryKey, lastBlock.height), UintEntry(requiredWXXAmountEntryKey, requiredWXXAmount), BinaryEntry(stopManagerEntryKey, stopManagerAddress.bytes), UintEntry(cycleDurationInBlocksEntryKey, cycleDurationInBlocks), BinaryEntry(adminFeeCollectorEntryKey, feeCollectorAddress.bytes), BinaryEntry(adminEntryKey, adminAddress.bytes), UintEntry(emergencyVotingThresholdEntryKey, emergencyVotingThreshold), BinaryEntry(puzzleSwapEntryKey, puzzleSwapAddress.bytes), BinaryEntry(xWavesWrapperEntryKey, xWavesWrapperAddress.bytes)] | |
319 | + | } | |
320 | + | else throw("Strict value is not equal to itself.") | |
321 | + | } | |
322 | + | else throw("Strict value is not equal to itself.") | |
323 | + | } | |
324 | + | ||
325 | + | ||
326 | + | ||
327 | + | @Callable(invocation) | |
328 | + | func stop () = { | |
329 | + | let callerCheck = assertCallerIsStopManager(invocation) | |
330 | + | if ((callerCheck == callerCheck)) | |
331 | + | then [BooleanEntry(contractStatusEntryKey, false)] | |
332 | + | else throw("Strict value is not equal to itself.") | |
333 | + | } | |
334 | + | ||
335 | + | ||
336 | + | ||
337 | + | @Callable(invocation) | |
338 | + | func setStopManager (newStopManager) = { | |
339 | + | let callerCheck = assertCallerIsAdmin(invocation) | |
340 | + | if ((callerCheck == callerCheck)) | |
341 | + | then { | |
342 | + | let newStopManagerAddress = addressFromStringValue(newStopManager) | |
343 | + | [BinaryEntry(stopManagerEntryKey, newStopManagerAddress.bytes)] | |
344 | + | } | |
345 | + | else throw("Strict value is not equal to itself.") | |
346 | + | } | |
347 | + | ||
348 | + | ||
349 | + | ||
350 | + | @Callable(invocation) | |
351 | + | func setFeeCollector (newFeeCollector) = { | |
352 | + | let callerCheck = assertCallerIsAdmin(invocation) | |
353 | + | if ((callerCheck == callerCheck)) | |
354 | + | then { | |
355 | + | let newFeeCollectorAddress = addressFromStringValue(newFeeCollector) | |
356 | + | [BinaryEntry(adminFeeCollectorEntryKey, newFeeCollectorAddress.bytes)] | |
357 | + | } | |
358 | + | else throw("Strict value is not equal to itself.") | |
359 | + | } | |
360 | + | ||
361 | + | ||
362 | + | ||
363 | + | @Callable(invocation) | |
364 | + | func setAdmin (newAdmin) = { | |
365 | + | let callerCheck = assertCallerIsAdmin(invocation) | |
366 | + | if ((callerCheck == callerCheck)) | |
367 | + | then { | |
368 | + | let newAdminAddress = addressFromStringValue(newAdmin) | |
369 | + | [BinaryEntry(adminEntryKey, newAdminAddress.bytes)] | |
370 | + | } | |
371 | + | else throw("Strict value is not equal to itself.") | |
372 | + | } | |
373 | + | ||
374 | + | ||
375 | + | ||
376 | + | @Callable(invocation) | |
377 | + | func setAdminFeeBP (newAdminFeeBP) = { | |
378 | + | let callerCheck = assertCallerIsAdmin(invocation) | |
379 | + | if ((callerCheck == callerCheck)) | |
380 | + | then { | |
381 | + | let _checkAdminFeeBP = assert(if ((newAdminFeeBP >= 0)) | |
382 | + | then (BP >= newAdminFeeBP) | |
383 | + | else false, errorMessageInvalidAdminFeeBP) | |
384 | + | if ((_checkAdminFeeBP == _checkAdminFeeBP)) | |
385 | + | then [UintEntry(adminFeeBPEntryKey, newAdminFeeBP)] | |
386 | + | else throw("Strict value is not equal to itself.") | |
387 | + | } | |
388 | + | else throw("Strict value is not equal to itself.") | |
389 | + | } | |
390 | + | ||
391 | + | ||
392 | + | ||
393 | + | @Callable(invocation) | |
394 | + | func swapRewardTokens (routesStr,amount,minToReceive) = { | |
395 | + | let callerCheck = assertCallerIsAdmin(invocation) | |
396 | + | if ((callerCheck == callerCheck)) | |
397 | + | then { | |
398 | + | let splittedRoute = split(takeRight(routesStr, 50), ",") | |
399 | + | let asset1Str = splittedRoute[(size(splittedRoute) - 1)] | |
400 | + | let asset1 = fromBase58String(asset1Str) | |
401 | + | let swaped = invoke(puzzleSwap, "swap", [routesStr, minToReceive], [AttachedPayment(asset1, amount)]) | |
402 | + | if ((swaped == swaped)) | |
403 | + | then nil | |
404 | + | else throw("Strict value is not equal to itself.") | |
405 | + | } | |
406 | + | else throw("Strict value is not equal to itself.") | |
407 | + | } | |
408 | + | ||
409 | + | ||
410 | + | ||
411 | + | @Callable(invocation) | |
412 | + | func register (metadataUrl) = { | |
413 | + | let _assertContractActiveStatus = assertContractActiveStatus() | |
414 | + | if ((_assertContractActiveStatus == _assertContractActiveStatus)) | |
415 | + | then { | |
416 | + | let _assertLeasingNotInProgress = assertLeasingNotInProgress() | |
417 | + | if ((_assertLeasingNotInProgress == _assertLeasingNotInProgress)) | |
418 | + | then { | |
419 | + | let _assertOnePaymentAsset = assertOnePaymentAsset(invocation, wxxAssetId) | |
420 | + | if ((_assertOnePaymentAsset == _assertOnePaymentAsset)) | |
421 | + | then { | |
422 | + | let validator = toString(invocation.caller) | |
423 | + | let wxxAmount = invocation.payments[0].amount | |
424 | + | let validatorKey = (validatorMetaEntryKey + validator) | |
425 | + | let registeredInCycleKey = (registrationCycleEntryKey + validator) | |
426 | + | let id = (activeValidators + 1) | |
427 | + | let validatorIdKey = (validatorIdEntryKey + validator) | |
428 | + | let validatorAddressKey = (validatorAddressEntryKey + toString(id)) | |
429 | + | let _assertNotRegistered = assert(!(isDefined(getString(validatorKey))), errorMessageAlreadyRegistered) | |
430 | + | if ((_assertNotRegistered == _assertNotRegistered)) | |
431 | + | then { | |
432 | + | let _assertEnoughWXX = assert((requiredWXXAmount == wxxAmount), errorMessageInvalidWXXAmount) | |
433 | + | if ((_assertEnoughWXX == _assertEnoughWXX)) | |
434 | + | then [UintEntry(registeredInCycleKey, currentCycle), StringEntry(validatorKey, metadataUrl), BooleanEntry((validatorStatusEntryKey + validator), true), UintEntry(currentCycleIgnoredValidatorsKey, (currentCycleIgnoredValidators + 1)), UintEntry(activeValidatorsEntryKey, (activeValidators + 1)), IntegerEntry(validatorIdKey, id), BinaryEntry(validatorAddressKey, invocation.caller.bytes)] | |
435 | + | else throw("Strict value is not equal to itself.") | |
436 | + | } | |
437 | + | else throw("Strict value is not equal to itself.") | |
438 | + | } | |
439 | + | else throw("Strict value is not equal to itself.") | |
440 | + | } | |
441 | + | else throw("Strict value is not equal to itself.") | |
442 | + | } | |
443 | + | else throw("Strict value is not equal to itself.") | |
444 | + | } | |
445 | + | ||
446 | + | ||
447 | + | ||
448 | + | @Callable(invocation) | |
449 | + | func deregister () = { | |
450 | + | let _assertLeasingNotInProgress = assertLeasingNotInProgress() | |
451 | + | if ((_assertLeasingNotInProgress == _assertLeasingNotInProgress)) | |
452 | + | then { | |
453 | + | let validatorAddress = invocation.caller | |
454 | + | let validator = toString(invocation.caller) | |
455 | + | let validatorStatusKey = (validatorStatusEntryKey + validator) | |
456 | + | let validatorVotesKey = (votesEntryKey + validator) | |
457 | + | let registeredInCycleKey = (registrationCycleEntryKey + validator) | |
458 | + | let _assertValidatorAddress = assertValidatorAddress(validatorAddress) | |
459 | + | if ((_assertValidatorAddress == _assertValidatorAddress)) | |
460 | + | then { | |
461 | + | let validatorIdsChanges = getValidatorIdsChanges(validatorAddress) | |
462 | + | let validatorLeaseIdKey = (leaseIdEntryKey + validator) | |
463 | + | let cancel = getCancelLeaseForValidator(validatorAddress) | |
464 | + | let nonKickedChanges = if (getValidatorStatusValue(validatorAddress)) | |
465 | + | then { | |
466 | + | let validatorVotes = valueOrElse(getInteger(validatorVotesKey), 0) | |
467 | + | (validatorIdsChanges ++ [UintEntry(activeValidatorsEntryKey, (activeValidators - 1)), UintEntry(totalVotesEntryKey, (totalVotes - validatorVotes)), ScriptTransfer(validatorAddress, requiredWXXAmount, wxxAssetId)]) | |
468 | + | } | |
469 | + | else nil | |
470 | + | let ignoredValidatorsChanges = if ((getRegistrationCycleValue(validatorAddress) == currentCycle)) | |
471 | + | then [UintEntry(currentCycleIgnoredValidatorsKey, (currentCycleIgnoredValidators - 1))] | |
472 | + | else nil | |
473 | + | (((nonKickedChanges ++ ignoredValidatorsChanges) ++ cancel) ++ [DeleteEntry(validatorVotesKey), DeleteEntry(registeredInCycleKey), DeleteEntry(validatorStatusKey), DeleteEntry((validatorMetaEntryKey + validator)), DeleteEntry((validatorLeasesEntryKey + validator)), DeleteEntry(validatorLeaseIdKey), DeleteEntry((latestValidatorLeasingCycleEntryKey + validator))]) | |
474 | + | } | |
475 | + | else throw("Strict value is not equal to itself.") | |
476 | + | } | |
477 | + | else throw("Strict value is not equal to itself.") | |
478 | + | } | |
479 | + | ||
480 | + | ||
481 | + | ||
482 | + | @Callable(invocation) | |
483 | + | func deposit () = { | |
484 | + | let _assertContractActiveStatus = assertContractActiveStatus() | |
485 | + | if ((_assertContractActiveStatus == _assertContractActiveStatus)) | |
486 | + | then { | |
487 | + | let _assertLeasingNotInProgress = assertLeasingNotInProgress() | |
488 | + | if ((_assertLeasingNotInProgress == _assertLeasingNotInProgress)) | |
489 | + | then { | |
490 | + | let _assertOnePaymentAsset = assertOnePaymentAsset(invocation, unit) | |
491 | + | if ((_assertOnePaymentAsset == _assertOnePaymentAsset)) | |
492 | + | then { | |
493 | + | let wavesAmount = invocation.payments[0].amount | |
494 | + | let xWavesAmount = if ((xWavexQuantity == 0)) | |
495 | + | then wavesAmount | |
496 | + | else fraction(wavesAmount, xWavexQuantity, (wavesBalance(this).regular - wavesAmount)) | |
497 | + | let adminXWavesAmount = fraction(xWavesAmount, adminFeeBP, BP, CEILING) | |
498 | + | let xWavesAmountWithoutAdminFee = (xWavesAmount - adminXWavesAmount) | |
499 | + | let adminFeeCollectorAddress = Address(getBinaryValue(adminFeeCollectorEntryKey)) | |
500 | + | let mint = invoke(xWavesWrapper, "mint", [xWavesAmount], nil) | |
501 | + | if ((mint == mint)) | |
502 | + | then [UintEntry(xWavexQuantityEntryKey, (xWavexQuantity + xWavesAmount)), ScriptTransfer(invocation.caller, xWavesAmountWithoutAdminFee, xWavesAssetId), ScriptTransfer(adminFeeCollectorAddress, adminXWavesAmount, xWavesAssetId)] | |
503 | + | else throw("Strict value is not equal to itself.") | |
504 | + | } | |
505 | + | else throw("Strict value is not equal to itself.") | |
506 | + | } | |
507 | + | else throw("Strict value is not equal to itself.") | |
508 | + | } | |
509 | + | else throw("Strict value is not equal to itself.") | |
510 | + | } | |
511 | + | ||
512 | + | ||
513 | + | ||
514 | + | @Callable(invocation) | |
515 | + | func requestWithdraw () = { | |
516 | + | let _assertLeasingNotInProgress = assertLeasingNotInProgress() | |
517 | + | if ((_assertLeasingNotInProgress == _assertLeasingNotInProgress)) | |
518 | + | then { | |
519 | + | let _assertOnePaymentAsset = assertOnePaymentAsset(invocation, xWavesAssetId) | |
520 | + | if ((_assertOnePaymentAsset == _assertOnePaymentAsset)) | |
521 | + | then { | |
522 | + | let xWavesAmount = invocation.payments[0].amount | |
523 | + | let wavesAmount = fraction(xWavesAmount, withdrawWavesBalanceState, withdrawXWavexQuantityState) | |
524 | + | let callerKey = toString(invocation.caller) | |
525 | + | let requestedXWavesWithdrawKey = (requestedXWavesWithdrawEntryKey + callerKey) | |
526 | + | let requestedWavesWithdrawKey = (requestedWavesWithdrawEntryKey + callerKey) | |
527 | + | let requestedXWavesWithdrawForCaller = valueOrElse(getInteger(requestedXWavesWithdrawKey), 0) | |
528 | + | let requestedWavesWithdrawForCaller = valueOrElse(getInteger(requestedWavesWithdrawKey), 0) | |
529 | + | [UintEntry(requestedXWavesWithdrawKey, (requestedXWavesWithdrawForCaller + xWavesAmount)), UintEntry(requestedWavesWithdrawKey, (requestedWavesWithdrawForCaller + wavesAmount)), UintEntry(totalRequestedWavesWithdrawEntryKey, (totalRequestedWavesWithdraw + wavesAmount))] | |
530 | + | } | |
531 | + | else throw("Strict value is not equal to itself.") | |
532 | + | } | |
533 | + | else throw("Strict value is not equal to itself.") | |
534 | + | } | |
535 | + | ||
536 | + | ||
537 | + | ||
538 | + | @Callable(invocation) | |
539 | + | func processWithdraw (recipient) = { | |
540 | + | let _assertLeasingNotInProgress = assertLeasingNotInProgress() | |
541 | + | if ((_assertLeasingNotInProgress == _assertLeasingNotInProgress)) | |
542 | + | then { | |
543 | + | let recipientAddress = addressFromStringValue(recipient) | |
544 | + | let requestedXWavesWithdrawKey = (requestedXWavesWithdrawEntryKey + recipient) | |
545 | + | let requestedWavesWithdrawKey = (requestedWavesWithdrawEntryKey + recipient) | |
546 | + | let requestedWavesWithdraw = valueOrErrorMessage(getInteger(requestedWavesWithdrawKey), errorMessageNoRequestedWithdraw) | |
547 | + | let requestedXWavesWithdraw = valueOrErrorMessage(getInteger(requestedXWavesWithdrawKey), errorMessageNoRequestedWithdraw) | |
548 | + | let _asserAvailable = assert((available >= requestedWavesWithdraw), errorMessageWavesBalanceNotEnough) | |
549 | + | if ((_asserAvailable == _asserAvailable)) | |
550 | + | then { | |
551 | + | let burn = invoke(xWavesWrapper, "burn", nil, [AttachedPayment(xWavesAssetId, requestedXWavesWithdraw)]) | |
552 | + | if ((burn == burn)) | |
553 | + | then [UintEntry(totalRequestedWavesWithdrawEntryKey, (totalRequestedWavesWithdraw - requestedWavesWithdraw)), DeleteEntry(requestedXWavesWithdrawKey), DeleteEntry(requestedWavesWithdrawKey), UintEntry(xWavexQuantityEntryKey, (xWavexQuantity - requestedXWavesWithdraw)), ScriptTransfer(recipientAddress, requestedWavesWithdraw, unit)] | |
554 | + | else throw("Strict value is not equal to itself.") | |
555 | + | } | |
556 | + | else throw("Strict value is not equal to itself.") | |
557 | + | } | |
558 | + | else throw("Strict value is not equal to itself.") | |
559 | + | } | |
560 | + | ||
561 | + | ||
562 | + | ||
563 | + | @Callable(invocation) | |
564 | + | func revokeWithdraw () = { | |
565 | + | let _assertLeasingNotInProgress = assertLeasingNotInProgress() | |
566 | + | if ((_assertLeasingNotInProgress == _assertLeasingNotInProgress)) | |
567 | + | then { | |
568 | + | let recipient = toString(invocation.caller) | |
569 | + | let requestedXWavesWithdrawKey = (requestedXWavesWithdrawEntryKey + recipient) | |
570 | + | let requestedWavesWithdrawKey = (requestedWavesWithdrawEntryKey + recipient) | |
571 | + | let requestedWavesWithdraw = valueOrErrorMessage(getInteger(requestedWavesWithdrawKey), errorMessageNoRequestedWithdraw) | |
572 | + | let requestedXWavesWithdraw = valueOrErrorMessage(getInteger(requestedXWavesWithdrawKey), errorMessageNoRequestedWithdraw) | |
573 | + | [UintEntry(totalRequestedWavesWithdrawEntryKey, (totalRequestedWavesWithdraw - requestedWavesWithdraw)), ScriptTransfer(invocation.caller, requestedXWavesWithdraw, xWavesAssetId), DeleteEntry(requestedXWavesWithdrawKey), DeleteEntry(requestedWavesWithdrawKey)] | |
574 | + | } | |
575 | + | else throw("Strict value is not equal to itself.") | |
576 | + | } | |
577 | + | ||
578 | + | ||
579 | + | ||
580 | + | @Callable(invocation) | |
581 | + | func vote (validator,interval) = { | |
582 | + | let _assertContractActiveStatus = assertContractActiveStatus() | |
583 | + | if ((_assertContractActiveStatus == _assertContractActiveStatus)) | |
584 | + | then { | |
585 | + | let _assertLeasingNotInProgress = assertLeasingNotInProgress() | |
586 | + | if ((_assertLeasingNotInProgress == _assertLeasingNotInProgress)) | |
587 | + | then { | |
588 | + | let validatorAddress = addressFromStringValue(validator) | |
589 | + | let _assetValidatorStatus = assertNotKickedValidatorStatus(validatorAddress) | |
590 | + | if ((_assetValidatorStatus == _assetValidatorStatus)) | |
591 | + | then { | |
592 | + | let _assertOnePaymentAsset = assertOnePaymentAsset(invocation, wxxAssetId) | |
593 | + | if ((_assertOnePaymentAsset == _assertOnePaymentAsset)) | |
594 | + | then { | |
595 | + | let _assertValidInterval = assert(if ((interval >= minVoteInterval)) | |
596 | + | then (maxVoteInterval >= interval) | |
597 | + | else false, errorMessageInvalidInterval) | |
598 | + | if ((_assertValidInterval == _assertValidInterval)) | |
599 | + | then { | |
600 | + | let unlockBlock = (lastBlock.height + interval) | |
601 | + | let newUserLock = invocation.payments[0].amount | |
602 | + | let newUserVotes = fraction(newUserLock, sqrt(interval, 0, 0, FLOOR), cycleDurationInBlocksSqrtFloor) | |
603 | + | let callerUnlockKeyPart = ((toString(invocation.caller) + "|") + toString(unlockBlock)) | |
604 | + | let unlockBlockKey = (unlockBlockEntryKey + callerUnlockKeyPart) | |
605 | + | let totalValidatorVotesKey = (votesEntryKey + validator) | |
606 | + | let userVoteKey = (userVoteEntryKey + callerUnlockKeyPart) | |
607 | + | let userLockKey = (userLockEntryKey + callerUnlockKeyPart) | |
608 | + | let userLock = (valueOrElse(getInteger(userVoteKey), 0) + newUserLock) | |
609 | + | let userVotes = (valueOrElse(getInteger(userLockKey), 0) + newUserVotes) | |
610 | + | let totalValidatorVotes = valueOrElse(getInteger(totalValidatorVotesKey), 0) | |
611 | + | let ignoreValidatorsChanges = if ((getRegistrationCycleValue(validatorAddress) == currentCycle)) | |
612 | + | then [UintEntry(currentCycleIgnoredVotesKey, (currentCycleIgnoredVotes + newUserVotes))] | |
613 | + | else nil | |
614 | + | (ignoreValidatorsChanges ++ [UintEntry(userVoteKey, userVotes), UintEntry(userLockKey, userLock), BinaryEntry(unlockBlockKey, validatorAddress.bytes), UintEntry(totalValidatorVotesKey, (totalValidatorVotes + newUserVotes)), UintEntry(totalVotesEntryKey, (totalVotes + newUserVotes))]) | |
615 | + | } | |
616 | + | else throw("Strict value is not equal to itself.") | |
617 | + | } | |
618 | + | else throw("Strict value is not equal to itself.") | |
619 | + | } | |
620 | + | else throw("Strict value is not equal to itself.") | |
621 | + | } | |
622 | + | else throw("Strict value is not equal to itself.") | |
623 | + | } | |
624 | + | else throw("Strict value is not equal to itself.") | |
625 | + | } | |
626 | + | ||
627 | + | ||
628 | + | ||
629 | + | @Callable(invocation) | |
630 | + | func redeem (unlockBlock) = { | |
631 | + | let _assertLeasingNotInProgress = assertLeasingNotInProgress() | |
632 | + | if ((_assertLeasingNotInProgress == _assertLeasingNotInProgress)) | |
633 | + | then { | |
634 | + | let callerUnlockKeyPart = ((toString(invocation.caller) + "|") + toString(unlockBlock)) | |
635 | + | let unlockBlockKey = (unlockBlockEntryKey + callerUnlockKeyPart) | |
636 | + | let userVoteKey = (userVoteEntryKey + callerUnlockKeyPart) | |
637 | + | let userLockKey = (userLockEntryKey + callerUnlockKeyPart) | |
638 | + | let validatorAddress = Address(valueOrErrorMessage(getBinary(unlockBlockKey), errorMessageUnknownLock)) | |
639 | + | let validatorVotesKey = (votesEntryKey + toBase58String(validatorAddress.bytes)) | |
640 | + | let _assertCanUnlock = assertCanUnlock(unlockBlock, validatorAddress) | |
641 | + | if ((_assertCanUnlock == _assertCanUnlock)) | |
642 | + | then { | |
643 | + | let userVotes = getIntegerValue(userVoteKey) | |
644 | + | let userLock = getIntegerValue(userLockKey) | |
645 | + | let status = valueOrElse(getValidatorStatus(validatorAddress), false) | |
646 | + | let votesChanges = if (status) | |
647 | + | then [UintEntry(validatorVotesKey, (getIntegerValue(validatorVotesKey) - userVotes)), UintEntry(totalVotesEntryKey, (totalVotes - userVotes))] | |
648 | + | else nil | |
649 | + | (votesChanges ++ [ScriptTransfer(invocation.caller, userLock, wxxAssetId), DeleteEntry(userVoteKey), DeleteEntry(unlockBlockKey), DeleteEntry(userLockKey)]) | |
650 | + | } | |
651 | + | else throw("Strict value is not equal to itself.") | |
652 | + | } | |
653 | + | else throw("Strict value is not equal to itself.") | |
654 | + | } | |
655 | + | ||
656 | + | ||
657 | + | ||
658 | + | @Callable(invocation) | |
659 | + | func leasing (validator) = { | |
660 | + | let validatorAddress = addressFromStringValue(validator) | |
661 | + | let _assertValidatorIsNotKicked = assertNotKickedValidatorStatus(validatorAddress) | |
662 | + | if ((_assertValidatorIsNotKicked == _assertValidatorIsNotKicked)) | |
663 | + | then { | |
664 | + | let _assertValidatorIsLeaseable = assertValidatorIsLeaseable(validatorAddress) | |
665 | + | if ((_assertValidatorIsLeaseable == _assertValidatorIsLeaseable)) | |
666 | + | then { | |
667 | + | let validatorLeaseIdKey = (leaseIdEntryKey + validator) | |
668 | + | let latestLeasingCycleKey = (latestValidatorLeasingCycleEntryKey + validator) | |
669 | + | let validatorLeasesKey = (validatorLeasesEntryKey + validator) | |
670 | + | let currentCycleKey = toString(currentCycle) | |
671 | + | let currentProcessedLeasesEntryKey = (processedLeasesEntryKey + currentCycleKey) | |
672 | + | let currentLeasingPoolValueEntryKey = (leasingPoolValueEntryKey + currentCycleKey) | |
673 | + | let isCurrentLeasingInProgressEntryKey = (isLeasingInProgressEntryKey + currentCycleKey) | |
674 | + | let validatorVotes = valueOrElse(getInteger((votesEntryKey + validator)), 0) | |
675 | + | let currentLeaseAmount = valueOrElse(getInteger(validatorLeasesKey), 0) | |
676 | + | let cancelLease = getCancelLeaseForValidator(validatorAddress) | |
677 | + | let _checkLeasingStatus = assert((valueOrElse(getInteger(latestLeasingCycleKey), -1) != currentCycle), errorMessageAlreadyLeased) | |
678 | + | if ((_checkLeasingStatus == _checkLeasingStatus)) | |
679 | + | then { | |
680 | + | let proccessedLeasesEntries = (valueOrElse(getInteger(currentProcessedLeasesEntryKey), 0) + 1) | |
681 | + | let leasingPoolValue = valueOrElse(getInteger(currentLeasingPoolValueEntryKey), wavesBalance(this).regular) | |
682 | + | let afterLeasingProcess = if ((activeValidatorsWithoutIgnored > proccessedLeasesEntries)) | |
683 | + | then [BooleanEntry(isCurrentLeasingInProgressEntryKey, true), UintEntry(currentProcessedLeasesEntryKey, proccessedLeasesEntries), UintEntry(currentLeasingPoolValueEntryKey, leasingPoolValue)] | |
684 | + | else [UintEntry(withdrawWavesBalanceStateEntryKey, leasingPoolValue), UintEntry(withdrawXWavexQuantityStateEntryKey, xWavexQuantity), IntegerEntry(latestLeasingCycleEntryKey, currentCycle), DeleteEntry(isCurrentLeasingInProgressEntryKey), DeleteEntry(currentProcessedLeasesEntryKey), DeleteEntry(currentLeasingPoolValueEntryKey), DeleteEntry(currentCycleIgnoredValidatorsKey), DeleteEntry(currentCycleIgnoredVotesKey)] | |
685 | + | let deleteLeaseEntries = if (isDefined(getInteger(validatorLeasesKey))) | |
686 | + | then [DeleteEntry(validatorLeasesKey), DeleteEntry(validatorLeaseIdKey)] | |
687 | + | else nil | |
688 | + | let targetLeaseAmount = fraction((leasingPoolValue - totalRequestedWavesWithdraw), validatorVotes, totalVotesWithoutIgnoredVotes) | |
689 | + | if (if (!(contractStatus)) | |
690 | + | then true | |
691 | + | else (totalVotesWithoutIgnoredVotes == 0)) | |
692 | + | then ((cancelLease ++ deleteLeaseEntries) ++ afterLeasingProcess) | |
693 | + | else if ((targetLeaseAmount != currentLeaseAmount)) | |
694 | + | then { | |
695 | + | let lease = Lease(validatorAddress, targetLeaseAmount) | |
696 | + | let leasingProcess = if ((targetLeaseAmount == 0)) | |
697 | + | then deleteLeaseEntries | |
698 | + | else [lease, BinaryEntry(validatorLeaseIdKey, calculateLeaseId(lease)), UintEntry(validatorLeasesKey, targetLeaseAmount)] | |
699 | + | (((cancelLease ++ leasingProcess) ++ afterLeasingProcess) :+ UintEntry(latestLeasingCycleKey, currentCycle)) | |
700 | + | } | |
701 | + | else (afterLeasingProcess :+ UintEntry(latestLeasingCycleKey, currentCycle)) | |
702 | + | } | |
703 | + | else throw("Strict value is not equal to itself.") | |
704 | + | } | |
705 | + | else throw("Strict value is not equal to itself.") | |
706 | + | } | |
707 | + | else throw("Strict value is not equal to itself.") | |
708 | + | } | |
709 | + | ||
710 | + | ||
711 | + | ||
712 | + | @Callable(invocation) | |
713 | + | func emergencyVoting (validator) = { | |
714 | + | let _assertLeasingNotInProgress = assertLeasingNotInProgress() | |
715 | + | if ((_assertLeasingNotInProgress == _assertLeasingNotInProgress)) | |
716 | + | then { | |
717 | + | let _assertContractActiveStatus = assertContractActiveStatus() | |
718 | + | if ((_assertContractActiveStatus == _assertContractActiveStatus)) | |
719 | + | then { | |
720 | + | let validatorAddress = addressFromStringValue(validator) | |
721 | + | let _assetValidatorStatus = assertNotKickedValidatorStatus(validatorAddress) | |
722 | + | if ((_assetValidatorStatus == _assetValidatorStatus)) | |
723 | + | then { | |
724 | + | let _assertOnePaymentAsset = assertOnePaymentAsset(invocation, xWavesAssetId) | |
725 | + | if ((_assertOnePaymentAsset == _assertOnePaymentAsset)) | |
726 | + | then { | |
727 | + | let voteAmount = invocation.payments[0].amount | |
728 | + | let callerKey = toString(invocation.caller) | |
729 | + | let unlockBlock = (lastBlock.height + emergencyVotingLock) | |
730 | + | let emergencyVotesKey = (emergencyVotesEntryKey + validator) | |
731 | + | let emergencyUserVotesKey = (((emergencyUserVotesEntryKey + callerKey) + "|") + validator) | |
732 | + | let validatorVotesKey = (votesEntryKey + validator) | |
733 | + | let validatorLeaseIdKey = (leaseIdEntryKey + validator) | |
734 | + | let emergencyUserLockKey = (((emergencyUserLockEntryKey + callerKey) + "|") + toString(unlockBlock)) | |
735 | + | let emergencyVotes = (voteAmount + valueOrElse(getInteger(emergencyVotesKey), 0)) | |
736 | + | let isValidatorBad = (((emergencyVotes * 100) / xWavexQuantity) > emergencyVotingThreshold) | |
737 | + | let punishment = if (isValidatorBad) | |
738 | + | then { | |
739 | + | let cancel = getCancelLeaseForValidator(validatorAddress) | |
740 | + | let totalValidatorVotes = valueOrElse(getInteger(validatorVotesKey), 0) | |
741 | + | let currentStatus = getValidatorStatusValue(validatorAddress) | |
742 | + | let leaseableValidatorsChanges = if (currentStatus) | |
743 | + | then [UintEntry(activeValidatorsEntryKey, (activeValidators - 1))] | |
744 | + | else nil | |
745 | + | let validatorIdsChanges = getValidatorIdsChanges(validatorAddress) | |
746 | + | (((validatorIdsChanges ++ leaseableValidatorsChanges) ++ cancel) ++ [ScriptTransfer(wxxAssetInfo.issuer, requiredWXXAmount, wxxAssetId), UintEntry(totalVotesEntryKey, (totalVotes - totalValidatorVotes)), BooleanEntry((validatorStatusEntryKey + validator), false), DeleteEntry((validatorLeasesEntryKey + validator)), DeleteEntry(validatorLeaseIdKey), DeleteEntry((latestValidatorLeasingCycleEntryKey + validator))]) | |
747 | + | } | |
748 | + | else nil | |
749 | + | (punishment ++ [BinaryEntry(emergencyUserLockKey, validatorAddress.bytes), UintEntry(emergencyVotesKey, emergencyVotes), UintEntry(emergencyUserVotesKey, (valueOrElse(getInteger(emergencyUserVotesKey), 0) + voteAmount))]) | |
750 | + | } | |
751 | + | else throw("Strict value is not equal to itself.") | |
752 | + | } | |
753 | + | else throw("Strict value is not equal to itself.") | |
754 | + | } | |
755 | + | else throw("Strict value is not equal to itself.") | |
756 | + | } | |
757 | + | else throw("Strict value is not equal to itself.") | |
758 | + | } | |
759 | + | ||
760 | + | ||
761 | + | ||
762 | + | @Callable(invocation) | |
763 | + | func redeemEmergencyVote (unlockBlock) = { | |
764 | + | let callerKey = toString(invocation.caller) | |
765 | + | let emergencyUserLockKey = (((emergencyUserLockEntryKey + callerKey) + "|") + toString(unlockBlock)) | |
766 | + | let validatorAddress = Address(valueOrErrorMessage(getBinary(emergencyUserLockKey), errorMessageUnknownLock)) | |
767 | + | let validator = toString(validatorAddress) | |
768 | + | let _assertCanUnlock = assertCanUnlock(unlockBlock, validatorAddress) | |
769 | + | if ((_assertCanUnlock == _assertCanUnlock)) | |
770 | + | then { | |
771 | + | let emergencyVotesKey = (emergencyVotesEntryKey + validator) | |
772 | + | let emergencyUserVotesKey = (((emergencyUserVotesEntryKey + callerKey) + "|") + validator) | |
773 | + | let emergencyUserVotes = valueOrErrorMessage(getInteger(emergencyUserVotesKey), errorMessageNoEmergencyVotes) | |
774 | + | let emergencyVotes = (getIntegerValue(emergencyVotesKey) - emergencyUserVotes) | |
775 | + | [ScriptTransfer(invocation.caller, emergencyUserVotes, xWavesAssetId), UintEntry(emergencyVotesKey, emergencyVotes), DeleteEntry(emergencyUserVotesKey), DeleteEntry(emergencyUserLockKey)] | |
776 | + | } | |
777 | + | else throw("Strict value is not equal to itself.") | |
778 | + | } | |
779 | + | ||
780 | + | ||
781 | + | @Verifier(tx) | |
782 | + | func verify () = match tx { | |
783 | + | case ttx: SetScriptTransaction => | |
784 | + | !(isDefined(getInteger(startBlockEntryKey))) | |
785 | + | case _ => | |
786 | + | sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
787 | + | } | |
788 | + |
github/deemru/w8io/169f3d6 46.92 ms ◑![]()