tx · EjkFSoUoPGSGJ9MVocpWhprmUAxfRN88nZ36ADbougno

3My4X8CeomEKpg7tb2FXqGm9XFr4NsaaJD1:  -0.01000000 Waves

2022.01.24 15:27 [1892991] smart account 3My4X8CeomEKpg7tb2FXqGm9XFr4NsaaJD1 > SELF 0.00000000 Waves

{ "type": 13, "id": "EjkFSoUoPGSGJ9MVocpWhprmUAxfRN88nZ36ADbougno", "fee": 1000000, "feeAssetId": null, "timestamp": 1643027231678, "version": 2, "chainId": 84, "sender": "3My4X8CeomEKpg7tb2FXqGm9XFr4NsaaJD1", "senderPublicKey": "jnkGDMmQZKfXRcNuAxtWptqPWpQ3ht8fL6HYVrJNT4s", "proofs": [ "7hDS2qs2hzSaBna9wgs1jRRmQ7nEXfwei7d5hHFEnBARPNxEDW1yDP26aEtBhBTaFMDQY68QpuFdRgpN9aHX1Kj" ], "script": "base64:AAIFAAAAAAAAAFwIAhIDCgEBEhAKDggICAgICAgIAQEBAQEBEggKBggICAEBARIGCgQIAQgIEgYKBAgBCAISBAoCCAQSBAoCCAgSBQoDCAEIEgYKBAgBCAISABIAEgMKAQESAwoBCAAAAH4BAAAADmdldE51bWJlckJ5S2V5AAAAAQAAAANrZXkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAADa2V5AAAAAAAAAAAAAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEAAAADa2V5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAA2tleQIAAAAAAQAAAAxnZXRCb29sQnlLZXkAAAABAAAAA2tleQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBsAAAACBQAAAAR0aGlzBQAAAANrZXkHAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACAAAAB2FkZHJlc3MAAAADa2V5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAAB2FkZHJlc3MFAAAAA2tleQAAAAAAAAAAAAEAAAAYZ2V0U3RyaW5nQnlBZGRyZXNzQW5kS2V5AAAAAgAAAAdhZGRyZXNzAAAAA2tleQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAAAdhZGRyZXNzBQAAAANrZXkCAAAAAAEAAAAWZ2V0Qm9vbEJ5QWRkcmVzc0FuZEtleQAAAAIAAAAHYWRkcmVzcwAAAANrZXkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQbAAAAAgkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAAHYWRkcmVzcwUAAAADa2V5BwAAAAAQcHViS2V5QWRtaW5zTGlzdAkABEwAAAACAgAAACxHSmRMU2FMaXY1Szd4dWVqYWM4bWNSY0hveW8zZFByRVNydmt0RzNhNk1BUgkABEwAAAACAgAAACxGV1ZmZllyMkFMbUhNZWpabTNXcWVMejZTZHltM2dMRkd0Sm40S1R3eVU1eAkABEwAAAACAgAAACwzV2gyTGFXY2I1Z2c3SzJwUGNXM0VwNkVBdVJCellrQWdyZHB0NDNqVERGYQkABEwAAAACAgAAACw1V1JYRlNqd2NUYk5mS2NKczhacVhtU1NXWXNTVkpVdE12TXFaajVoSDROYwUAAAADbmlsAQAAAAVhc0ludAAAAAEAAAADdmFsBAAAAAckbWF0Y2gwBQAAAAN2YWwDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAAA0ludAQAAAAGdmFsSW50BQAAAAckbWF0Y2gwBQAAAAZ2YWxJbnQJAAACAAAAAQIAAAAXRmFpbGVkIHRvIGNhc3QgaW50byBJbnQAAAAAA1NFUAIAAAACX18AAAAAB1dBVkVMRVQAAAAAAAX14QAAAAAABVBBVUxJAAAAAAAAD0JAAAAAAAhQUklDRUxFVAAAAAAAAA9CQAAAAAAOREVGQVVMVFNXQVBGRUUAAAAAAAAATiAAAAAADElkeE5ldEFtb3VudAAAAAAAAAAAAAAAAAAMSWR4RmVlQW1vdW50AAAAAAAAAAABAAAAAA5JZHhHcm9zc0Ftb3VudAAAAAAAAAAAAgAAAAAPZG9yYTJOc2J0U3ltYm9sAgAAAAlOU0JULVVTRFQAAAAAB21pblJhbmQAAAAAAAAAADwAAAAAB21heFJhbmQAAAAAAAAABaAAAAAAEk5ldXRyaW5vQXNzZXRJZEtleQIAAAARbmV1dHJpbm9fYXNzZXRfaWQAAAAADkJvbmRBc3NldElkS2V5AgAAAA1ib25kX2Fzc2V0X2lkAAAAABJBdWN0aW9uQ29udHJhY3RLZXkCAAAAEGF1Y3Rpb25fY29udHJhY3QAAAAAFkxpcXVpZGF0aW9uQ29udHJhY3RLZXkCAAAAFGxpcXVpZGF0aW9uX2NvbnRyYWN0AAAAAA5SUERDb250cmFjdEtleQIAAAAMcnBkX2NvbnRyYWN0AAAAABJDb250cm9sQ29udHJhY3RLZXkCAAAAEGNvbnRyb2xfY29udHJhY3QAAAAAG0JhbGFuY2VXYXZlc0xvY2tJbnRlcnZhbEtleQIAAAAbYmFsYW5jZV93YXZlc19sb2NrX2ludGVydmFsAAAAAB5CYWxhbmNlTmV1dHJpbm9Mb2NrSW50ZXJ2YWxLZXkCAAAAHmJhbGFuY2VfbmV1dHJpbm9fbG9ja19pbnRlcnZhbAAAAAAVTWluV2F2ZXNTd2FwQW1vdW50S2V5AgAAABVtaW5fd2F2ZXNfc3dhcF9hbW91bnQAAAAAGE1pbk5ldXRyaW5vU3dhcEFtb3VudEtleQIAAAAYbWluX25ldXRyaW5vX3N3YXBfYW1vdW50AAAAABtOb2RlT3JhY2xlUHJvdmlkZXJQdWJLZXlLZXkCAAAAFG5vZGVfb3JhY2xlX3Byb3ZpZGVyAAAAABVOZXV0cmlub091dEZlZVBhcnRLZXkCAAAAGG5ldXRyaW5vT3V0X3N3YXBfZmVlUGFydAAAAAASV2F2ZXNPdXRGZWVQYXJ0S2V5AgAAABV3YXZlc091dF9zd2FwX2ZlZVBhcnQAAAAAElJzYVJhbmRQdWJsaWM1OEtleQIAAAAPcmFuZF9yc2FfcHVibGljAAAAABBrZXlHTnNidENvbnRyYWN0AgAAABElc19fZ05zYnRDb250cmFjdAAAAAATa2V5TnNidExvY2tDb250cmFjdAIAAAAUJXNfX25zYnRMb2NrQ29udHJhY3QAAAAAEGtleURvcmEyQ29udHJhY3QCAAAAESVzX19kb3JhMkNvbnRyYWN0AAAAABFrZXlRdWlja1N3YXBEZWxheQIAAAASJXNfX3F1aWNrU3dhcERlbGF5AAAAABlrZXlRdWlja1N3YXBMaW1pdER1cmF0aW9uAgAAABolc19fcXVpY2tTd2FwTGltaXREdXJhdGlvbgAAAAAXa2V5RG9yYTJMYXN0SGVpZ2h0TGltaXQCAAAAGCVzX19kb3JhMkxhc3RIZWlnaHRMaW1pdAAAAAAIUHJpY2VLZXkCAAAABXByaWNlAAAAAA1QcmljZUluZGV4S2V5AgAAAAtwcmljZV9pbmRleAAAAAAMSXNCbG9ja2VkS2V5AgAAAAppc19ibG9ja2VkAQAAABJnZXRQcmljZUhpc3RvcnlLZXkAAAABAAAABWJsb2NrCQABLAAAAAIJAAEsAAAAAgUAAAAIUHJpY2VLZXkCAAAAAV8JAAGkAAAAAQUAAAAFYmxvY2sBAAAAGGdldEhlaWdodFByaWNlQnlJbmRleEtleQAAAAEAAAAFaW5kZXgJAAEsAAAAAgkAASwAAAACBQAAAA1QcmljZUluZGV4S2V5AgAAAAFfCQABpAAAAAEFAAAABWluZGV4AQAAABVnZXRTdGFraW5nTm9kZUJ5SW5kZXgAAAABAAAAA2lkeAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQkABLkAAAACCQAETAAAAAICAAAABiVzJWQlcwkABEwAAAACAgAAAAVsZWFzZQkABEwAAAACCQABpAAAAAEFAAAAA2lkeAkABEwAAAACAgAAAAtub2RlQWRkcmVzcwUAAAADbmlsBQAAAANTRVABAAAAHGdldFN0YWtpbmdOb2RlQWRkcmVzc0J5SW5kZXgAAAABAAAAA2lkeAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkBAAAAFWdldFN0YWtpbmdOb2RlQnlJbmRleAAAAAEFAAAAA2lkeAEAAAAfZ2V0UmVzZXJ2ZWRBbW91bnRGb3JTcG9uc29yc2hpcAAAAAAJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwkABLkAAAACCQAETAAAAAICAAAABCVzJXMJAARMAAAAAgIAAAAFbGVhc2UJAARMAAAAAgIAAAAXc3BvbnNvcnNoaXBXYXZlc1Jlc2VydmUFAAAAA25pbAUAAAADU0VQCQAAaAAAAAIAAAAAAAAAA+gFAAAAB1dBVkVMRVQBAAAAGGdldEJhbGFuY2VVbmxvY2tCbG9ja0tleQAAAAEAAAAFb3duZXIJAAEsAAAAAgIAAAAVYmFsYW5jZV91bmxvY2tfYmxvY2tfBQAAAAVvd25lcgEAAAANZ2V0TGVhc2VJZEtleQAAAAEAAAAJbm9kZUluZGV4CQAEuQAAAAIJAARMAAAAAgIAAAAGJXMlZCVzCQAETAAAAAICAAAABWxlYXNlCQAETAAAAAIJAAGkAAAAAQUAAAAJbm9kZUluZGV4CQAETAAAAAICAAAAAmlkBQAAAANuaWwFAAAAA1NFUAEAAAARZ2V0TGVhc2VBbW91bnRLZXkAAAABAAAACW5vZGVJbmRleAkABLkAAAACCQAETAAAAAICAAAABiVzJWQlcwkABEwAAAACAgAAAAVsZWFzZQkABEwAAAACCQABpAAAAAEFAAAACW5vZGVJbmRleAkABEwAAAACAgAAAAZhbW91bnQFAAAAA25pbAUAAAADU0VQAQAAABBtaW5Td2FwQW1vdW50S0VZAAAAAQAAAAhzd2FwVHlwZQkAASwAAAACCQABLAAAAAICAAAABG1pbl8FAAAACHN3YXBUeXBlAgAAAAxfc3dhcF9hbW91bnQBAAAADnRvdGFsTG9ja2VkS0VZAAAAAQAAAAhzd2FwVHlwZQkAASwAAAACAgAAAA1iYWxhbmNlX2xvY2tfBQAAAAhzd2FwVHlwZQEAAAAUdG90YWxMb2NrZWRCeVVzZXJLRVkAAAACAAAACHN3YXBUeXBlAAAABW93bmVyCQAEuQAAAAIJAARMAAAAAgIAAAAMYmFsYW5jZV9sb2NrCQAETAAAAAIFAAAACHN3YXBUeXBlCQAETAAAAAIFAAAABW93bmVyBQAAAANuaWwCAAAAAV8BAAAAFmJhbGFuY2VMb2NrSW50ZXJ2YWxLRVkAAAABAAAACHN3YXBUeXBlCQABLAAAAAIJAAEsAAAAAgIAAAAIYmFsYW5jZV8FAAAACHN3YXBUeXBlAgAAAA5fbG9ja19pbnRlcnZhbAEAAAAZbWluQmFsYW5jZUxvY2tJbnRlcnZhbEtFWQAAAAEAAAAIc3dhcFR5cGUJAAEsAAAAAgkAASwAAAACAgAAAAhiYWxhbmNlXwUAAAAIc3dhcFR5cGUCAAAAFl9sb2NrX2ludGVydmFsX21pbmltdW0BAAAAGm5vZGVCYWxhbmNlTG9ja0ludGVydmFsS0VZAAAAAAIAAAAaYmFsYW5jZV9ub2RlX2xvY2tfaW50ZXJ2YWwBAAAADW91dEZlZVBhcnRLRVkAAAABAAAACHN3YXBUeXBlCQABLAAAAAIFAAAACHN3YXBUeXBlAgAAABBPdXRfc3dhcF9mZWVQYXJ0AQAAAB1rZXlRdWlja1N3YXBVc2VyU3BlbnRJblBlcmlvZAAAAAEAAAALdXNlckFkZHJlc3MJAAS5AAAAAgkABEwAAAACAgAAAAQlcyVzCQAETAAAAAICAAAAGnF1aWNrU3dhcFVzZXJTcGVudEluUGVyaW9kCQAETAAAAAIJAAQlAAAAAQUAAAALdXNlckFkZHJlc3MFAAAAA25pbAUAAAADU0VQAQAAABprZXlVc2VyTGFzdFF1aWNrU3dhcEhlaWdodAAAAAEAAAALdXNlckFkZHJlc3MJAAS5AAAAAgkABEwAAAACAgAAAAQlcyVzCQAETAAAAAICAAAAF3VzZXJMYXN0UXVpY2tTd2FwSGVpZ2h0CQAETAAAAAIJAAQlAAAAAQUAAAALdXNlckFkZHJlc3MFAAAAA25pbAUAAAADU0VQAQAAAA1rZXlEb3JhMlByaWNlAAAAAQAAAAZzeW1ib2wJAAS5AAAAAgkABEwAAAACAgAAAAQlcyVzCQAETAAAAAICAAAABXByaWNlCQAETAAAAAIFAAAABnN5bWJvbAUAAAADbmlsBQAAAANTRVABAAAAEmtleURvcmEyTGFzdEhlaWdodAAAAAEAAAAGc3ltYm9sCQAEuQAAAAIJAARMAAAAAgIAAAAEJXMlcwkABEwAAAACAgAAAApsYXN0SGVpZ2h0CQAETAAAAAIFAAAABnN5bWJvbAUAAAADbmlsBQAAAANTRVABAAAAEW1pblN3YXBBbW91bnRSRUFEAAAAAQAAAAhzd2FwVHlwZQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAQbWluU3dhcEFtb3VudEtFWQAAAAEFAAAACHN3YXBUeXBlAAAAAAAAAAAAAQAAAA90b3RhbExvY2tlZFJFQUQAAAABAAAACHN3YXBUeXBlCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAAA50b3RhbExvY2tlZEtFWQAAAAEFAAAACHN3YXBUeXBlAAAAAAAAAAAAAQAAABV0b3RhbExvY2tlZEJ5VXNlclJFQUQAAAACAAAACHN3YXBUeXBlAAAABW93bmVyCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAABR0b3RhbExvY2tlZEJ5VXNlcktFWQAAAAIFAAAACHN3YXBUeXBlBQAAAAVvd25lcgAAAAAAAAAAAAEAAAAXYmFsYW5jZUxvY2tJbnRlcnZhbFJFQUQAAAABAAAACHN3YXBUeXBlCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAABZiYWxhbmNlTG9ja0ludGVydmFsS0VZAAAAAQUAAAAIc3dhcFR5cGUFAAAAB21heFJhbmQBAAAAGm1pbkJhbGFuY2VMb2NrSW50ZXJ2YWxSRUFEAAAAAQAAAAhzd2FwVHlwZQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAZbWluQmFsYW5jZUxvY2tJbnRlcnZhbEtFWQAAAAEFAAAACHN3YXBUeXBlBQAAAAdtaW5SYW5kAQAAABtub2RlQmFsYW5jZUxvY2tJbnRlcnZhbFJFQUQAAAAACQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAABpub2RlQmFsYW5jZUxvY2tJbnRlcnZhbEtFWQAAAAAAAAAAAAAAAAEBAAAAFmNvbnZlcnROZXV0cmlub1RvV2F2ZXMAAAACAAAABmFtb3VudAAAAAVwcmljZQkAAGsAAAADCQAAawAAAAMFAAAABmFtb3VudAUAAAAIUFJJQ0VMRVQFAAAABXByaWNlBQAAAAdXQVZFTEVUBQAAAAVQQVVMSQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAIAAAAGYW1vdW50AAAABXByaWNlCQAAawAAAAMJAABrAAAAAwUAAAAGYW1vdW50BQAAAAVwcmljZQUAAAAIUFJJQ0VMRVQFAAAABVBBVUxJBQAAAAdXQVZFTEVUAQAAABJjb252ZXJ0V2F2ZXNUb0JvbmQAAAACAAAABmFtb3VudAAAAAVwcmljZQkBAAAAFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8AAAACBQAAAAZhbW91bnQFAAAABXByaWNlAQAAABZjb252ZXJ0SnNvbkFycmF5VG9MaXN0AAAAAQAAAAlqc29uQXJyYXkJAAS1AAAAAgUAAAAJanNvbkFycmF5AgAAAAEsAQAAABFtaW5Td2FwQW1vdW50RkFJTAAAAAIAAAAIc3dhcFR5cGUAAAANbWluU3dhcEFtb3VudAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABhUaGUgc3BlY2lmaWVkIGFtb3VudCBpbiAFAAAACHN3YXBUeXBlAgAAACsgc3dhcCBpcyBsZXNzIHRoYW4gdGhlIHJlcXVpcmVkIG1pbmltdW0gb2YgCQABpAAAAAEFAAAADW1pblN3YXBBbW91bnQBAAAAFWVtZXJnZW5jeVNodXRkb3duRkFJTAAAAAAJAAACAAAAAQIAAABaY29udHJhY3QgaXMgYmxvY2tlZCBieSBFTUVSR0VOQ1kgU0hVVERPV04gYWN0aW9ucyB1bnRpbGwgcmVhY3RpdmF0aW9uIGJ5IGVtZXJnZW5jeSBvcmFjbGVzAQAAAA5wcmljZUluZGV4RkFJTAAAAAUAAAAFaW5kZXgAAAAKcHJpY2VJbmRleAAAAAtpbmRleEhlaWdodAAAAAx1bmxvY2tIZWlnaHQAAAAPcHJldkluZGV4SGVpZ2h0CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAI2ludmFsaWQgcHJpY2UgaGlzdG9yeSBpbmRleDogaW5kZXg9CQABpAAAAAEFAAAABWluZGV4AgAAAAwgcHJpY2VJbmRleD0JAAGkAAAAAQUAAAAKcHJpY2VJbmRleAIAAAANIGluZGV4SGVpZ2h0PQkAAaQAAAABBQAAAAtpbmRleEhlaWdodAIAAAAOIHVubG9ja0hlaWdodD0JAAGkAAAAAQUAAAAMdW5sb2NrSGVpZ2h0AgAAABEgcHJldkluZGV4SGVpZ2h0PQkAAaQAAAABBQAAAA9wcmV2SW5kZXhIZWlnaHQAAAAAE2xpcXVpZGF0aW9uQ29udHJhY3QJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAAFkxpcXVpZGF0aW9uQ29udHJhY3RLZXkAAAAAD25ldXRyaW5vQXNzZXRJZAkAAlkAAAABCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAABJOZXV0cmlub0Fzc2V0SWRLZXkAAAAAD2F1Y3Rpb25Db250cmFjdAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAASQXVjdGlvbkNvbnRyYWN0S2V5AAAAAAtycGRDb250cmFjdAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAAOUlBEQ29udHJhY3RLZXkAAAAAD2NvbnRyb2xDb250cmFjdAkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAASQ29udHJvbENvbnRyYWN0S2V5AAAAAApwcmljZUluZGV4CQEAAAAYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0BQAAAA1QcmljZUluZGV4S2V5AAAAAAlpc0Jsb2NrZWQJAQAAABZnZXRCb29sQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0BQAAAAxJc0Jsb2NrZWRLZXkAAAAAGG5vZGVPcmFjbGVQcm92aWRlclB1YktleQkAAlkAAAABCQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAABtOb2RlT3JhY2xlUHJvdmlkZXJQdWJLZXlLZXkAAAAAC2JvbmRBc3NldElkCQACWQAAAAECAAAALDZuU3BWeU5IN3lNNjllZzQ0NndyUVI5NGlwYmJjbVpNVTFFTlB3YW5DOTdnAAAAABVkZXByZWNhdGVkQm9uZEFzc2V0SWQJAAJZAAAAAQIAAAAsOTc1YWtaQmZuTWo1MTNVN01aYUhLelFybXNFeDVhRTN3ZFdLVHJIQmhiakYAAAAABnJzYVB1YgkAAlsAAAABCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAASUnNhUmFuZFB1YmxpYzU4S2V5AgAAACVSU0EgcHVibGljIGtleSBoYXMgbm90IGJlZW4gc3BlY2lmaWVkAAAAABBuZXV0cmlub0NvbnRyYWN0BQAAAAR0aGlzAAAAAAxjdXJyZW50UHJpY2UJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACBQAAAA9jb250cm9sQ29udHJhY3QFAAAACFByaWNlS2V5AAAAABVuZXV0cmlub0xvY2tlZEJhbGFuY2UJAQAAAA90b3RhbExvY2tlZFJFQUQAAAABAgAAAAhuZXV0cmlubwAAAAASd2F2ZXNMb2NrZWRCYWxhbmNlCQEAAAAPdG90YWxMb2NrZWRSRUFEAAAAAQIAAAAFd2F2ZXMAAAAAB3Jlc2VydmUJAABlAAAAAggJAAPvAAAAAQUAAAAQbmV1dHJpbm9Db250cmFjdAAAAAdyZWd1bGFyBQAAABJ3YXZlc0xvY2tlZEJhbGFuY2UAAAAADm5ldXRyaW5vU3VwcGx5CQAAZQAAAAIJAABlAAAAAgkAAGQAAAACBQAAABVuZXV0cmlub0xvY2tlZEJhbGFuY2UICQEAAAAFdmFsdWUAAAABCQAD7AAAAAEFAAAAD25ldXRyaW5vQXNzZXRJZAAAAAhxdWFudGl0eQkAA/AAAAACBQAAABBuZXV0cmlub0NvbnRyYWN0BQAAAA9uZXV0cmlub0Fzc2V0SWQJAAPwAAAAAgkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAATbGlxdWlkYXRpb25Db250cmFjdAUAAAAPbmV1dHJpbm9Bc3NldElkAAAAAAdzdXJwbHVzCQAAZQAAAAIJAQAAABZjb252ZXJ0V2F2ZXNUb05ldXRyaW5vAAAAAgUAAAAHcmVzZXJ2ZQUAAAAMY3VycmVudFByaWNlBQAAAA5uZXV0cmlub1N1cHBseQAAAAAHZGVmaWNpdAkAAGUAAAACBQAAAA5uZXV0cmlub1N1cHBseQkBAAAAFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8AAAACBQAAAAdyZXNlcnZlBQAAAAxjdXJyZW50UHJpY2UBAAAAG2NoZWNrSXNWYWxpZE1pblNwb25zb3JlZEZlZQAAAAEAAAACdHgEAAAADk1JTlRSQU5TRkVSRkVFAAAAAAAAAYagBAAAABZTcG9uc29yZWRGZWVVcHBlckJvdW5kAAAAAAAAAAPoBAAAAA9yZWFsTmV1dHJpbm9GZWUJAQAAABZjb252ZXJ0V2F2ZXNUb05ldXRyaW5vAAAAAgUAAAAOTUlOVFJBTlNGRVJGRUUFAAAADGN1cnJlbnRQcmljZQQAAAAObWluTmV1dHJpbm9GZWUJAABoAAAAAgUAAAAPcmVhbE5ldXRyaW5vRmVlAAAAAAAAAAACBAAAAA5tYXhOZXV0cmlub0ZlZQkAAGsAAAADBQAAAA9yZWFsTmV1dHJpbm9GZWUFAAAAFlNwb25zb3JlZEZlZVVwcGVyQm91bmQAAAAAAAAAAGQEAAAACGlucHV0RmVlCQEAAAAFdmFsdWUAAAABCAUAAAACdHgAAAAUbWluU3BvbnNvcmVkQXNzZXRGZWUDAwkAAGcAAAACBQAAAAhpbnB1dEZlZQUAAAAObWluTmV1dHJpbm9GZWUJAABnAAAAAgUAAAAObWF4TmV1dHJpbm9GZWUFAAAACGlucHV0RmVlBwkAAAAAAAACCAUAAAACdHgAAAAHYXNzZXRJZAUAAAAPbmV1dHJpbm9Bc3NldElkBwEAAAAPZ2V0UHJpY2VIaXN0b3J5AAAAAQAAAAVibG9jawkBAAAAGGdldE51bWJlckJ5QWRkcmVzc0FuZEtleQAAAAIFAAAAD2NvbnRyb2xDb250cmFjdAkBAAAAEmdldFByaWNlSGlzdG9yeUtleQAAAAEFAAAABWJsb2NrAQAAABVnZXRIZWlnaHRQcmljZUJ5SW5kZXgAAAABAAAABWluZGV4CQEAAAAYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0CQEAAAAYZ2V0SGVpZ2h0UHJpY2VCeUluZGV4S2V5AAAAAQUAAAAFaW5kZXgAAAAADHNJZHhTd2FwVHlwZQAAAAAAAAAAAQAAAAAKc0lkeFN0YXR1cwAAAAAAAAAAAgAAAAAMc0lkeEluQW1vdW50AAAAAAAAAAADAAAAAAlzSWR4UHJpY2UAAAAAAAAAAAQAAAAAEHNJZHhPdXROZXRBbW91bnQAAAAAAAAAAAUAAAAAEHNJZHhPdXRGZWVBbW91bnQAAAAAAAAAAAYAAAAAD3NJZHhTdGFydEhlaWdodAAAAAAAAAAABwAAAAASc0lkeFN0YXJ0VGltZXN0YW1wAAAAAAAAAAAIAAAAAA1zSWR4RW5kSGVpZ2h0AAAAAAAAAAAJAAAAABBzSWR4RW5kVGltZXN0YW1wAAAAAAAAAAAKAAAAABRzSWR4U2VsZlVubG9ja0hlaWdodAAAAAAAAAAACwAAAAAUc0lkeFJhbmRVbmxvY2tIZWlnaHQAAAAAAAAAAAwAAAAACXNJZHhJbmRleAAAAAAAAAAADQAAAAAQc0lkeFdpdGhkcmF3VHhJZAAAAAAAAAAADgAAAAALc0lkeE1pblJhbmQAAAAAAAAAAA8AAAAAC3NJZHhNYXhSYW5kAAAAAAAAAAAQAAAAAAtzSWR4SXNRdWljawAAAAAAAAAAEQEAAAAHc3dhcEtFWQAAAAIAAAALdXNlckFkZHJlc3MAAAAEdHhJZAkABLkAAAACCQAETAAAAAICAAAABCVzJXMJAARMAAAAAgUAAAALdXNlckFkZHJlc3MJAARMAAAAAgUAAAAEdHhJZAUAAAADbmlsBQAAAANTRVABAAAAC3N0clN3YXBEQVRBAAAAEQAAAAhzd2FwVHlwZQAAAAZzdGF0dXMAAAAIaW5BbW91bnQAAAAFcHJpY2UAAAAMb3V0TmV0QW1vdW50AAAADG91dEZlZUFtb3VudAAAAAtzdGFydEhlaWdodAAAAA5zdGFydFRpbWVzdGFtcAAAAAllbmRIZWlnaHQAAAAMZW5kVGltZXN0YW1wAAAAEHNlbGZVbmxvY2tIZWlnaHQAAAAQcmFuZFVubG9ja0hlaWdodAAAAAVpbmRleAAAAAx3aXRoZHJhd1R4SWQAAAAHcmFuZE1pbgAAAAdyYW5kTWF4AAAAB2lzUXVpY2sJAAS5AAAAAgkABEwAAAACAgAAABwlcyVzJWQlZCVkJWQlZCVkJWQlZCVkJWQlZCVzCQAETAAAAAIFAAAACHN3YXBUeXBlCQAETAAAAAIFAAAABnN0YXR1cwkABEwAAAACBQAAAAhpbkFtb3VudAkABEwAAAACBQAAAAVwcmljZQkABEwAAAACBQAAAAxvdXROZXRBbW91bnQJAARMAAAAAgUAAAAMb3V0RmVlQW1vdW50CQAETAAAAAIFAAAAC3N0YXJ0SGVpZ2h0CQAETAAAAAIFAAAADnN0YXJ0VGltZXN0YW1wCQAETAAAAAIFAAAACWVuZEhlaWdodAkABEwAAAACBQAAAAxlbmRUaW1lc3RhbXAJAARMAAAAAgUAAAAQc2VsZlVubG9ja0hlaWdodAkABEwAAAACBQAAABByYW5kVW5sb2NrSGVpZ2h0CQAETAAAAAIFAAAABWluZGV4CQAETAAAAAIFAAAADHdpdGhkcmF3VHhJZAkABEwAAAACBQAAAAdyYW5kTWluCQAETAAAAAIFAAAAB3JhbmRNYXgJAARMAAAAAgUAAAAHaXNRdWljawUAAAADbmlsBQAAAANTRVABAAAAD3BlbmRpbmdTd2FwREFUQQAAAAMAAAAIc3dhcFR5cGUAAAANaW5Bc3NldEFtb3VudAAAABBzZWxmVW5sb2NrSGVpZ2h0CQEAAAALc3RyU3dhcERBVEEAAAARBQAAAAhzd2FwVHlwZQIAAAAHUEVORElORwkAAaQAAAABBQAAAA1pbkFzc2V0QW1vdW50AgAAAAEwAgAAAAEwAgAAAAEwCQABpAAAAAEFAAAABmhlaWdodAkAAaQAAAABCAUAAAAJbGFzdEJsb2NrAAAACXRpbWVzdGFtcAIAAAABMAIAAAABMAkAAaQAAAABBQAAABBzZWxmVW5sb2NrSGVpZ2h0AgAAAAEwAgAAAAEwAgAAAAROVUxMCQABpAAAAAEJAQAAABptaW5CYWxhbmNlTG9ja0ludGVydmFsUkVBRAAAAAEFAAAACHN3YXBUeXBlCQABpAAAAAEJAQAAABdiYWxhbmNlTG9ja0ludGVydmFsUkVBRAAAAAEFAAAACHN3YXBUeXBlCQABpQAAAAEHAQAAABJhY2NlbGVyYXRlU3dhcERBVEEAAAABAAAACWRhdGFBcnJheQkBAAAAC3N0clN3YXBEQVRBAAAAEQkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAADHNJZHhTd2FwVHlwZQkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAACnNJZHhTdGF0dXMJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAAxzSWR4SW5BbW91bnQJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAAlzSWR4UHJpY2UJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAABBzSWR4T3V0TmV0QW1vdW50CQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAQc0lkeE91dEZlZUFtb3VudAkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAD3NJZHhTdGFydEhlaWdodAkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAEnNJZHhTdGFydFRpbWVzdGFtcAkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAADXNJZHhFbmRIZWlnaHQJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAABBzSWR4RW5kVGltZXN0YW1wCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAUc0lkeFNlbGZVbmxvY2tIZWlnaHQJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAABRzSWR4UmFuZFVubG9ja0hlaWdodAkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAACXNJZHhJbmRleAkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAEHNJZHhXaXRoZHJhd1R4SWQJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAAtzSWR4TWluUmFuZAkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAC3NJZHhNYXhSYW5kCQABpQAAAAEGAQAAAA5maW5pc2hTd2FwREFUQQAAAAcAAAAJZGF0YUFycmF5AAAABXByaWNlAAAADG91dE5ldEFtb3VudAAAAAxvdXRGZWVBbW91bnQAAAAQcmFuZFVubG9ja0hlaWdodAAAAAVpbmRleAAAAAx3aXRoZHJhd1R4SWQJAQAAAAtzdHJTd2FwREFUQQAAABEJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAAxzSWR4U3dhcFR5cGUCAAAACEZJTklTSEVECQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAMc0lkeEluQW1vdW50CQABpAAAAAEFAAAABXByaWNlCQABpAAAAAEFAAAADG91dE5ldEFtb3VudAkAAaQAAAABBQAAAAxvdXRGZWVBbW91bnQJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAA9zSWR4U3RhcnRIZWlnaHQJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAABJzSWR4U3RhcnRUaW1lc3RhbXAJAAGkAAAAAQUAAAAGaGVpZ2h0CQABpAAAAAEIBQAAAAlsYXN0QmxvY2sAAAAJdGltZXN0YW1wCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAUc0lkeFNlbGZVbmxvY2tIZWlnaHQJAAGkAAAAAQUAAAAQcmFuZFVubG9ja0hlaWdodAkAAaQAAAABBQAAAAVpbmRleAUAAAAMd2l0aGRyYXdUeElkCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAALc0lkeE1pblJhbmQJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAAtzSWR4TWF4UmFuZAkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAC3NJZHhJc1F1aWNrAQAAABJzd2FwRGF0YUZhaWxPclJFQUQAAAACAAAAC3VzZXJBZGRyZXNzAAAACHN3YXBUeElkBAAAAAdzd2FwS2V5CQEAAAAHc3dhcEtFWQAAAAIFAAAAC3VzZXJBZGRyZXNzBQAAAAhzd2FwVHhJZAkABLUAAAACCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAAHc3dhcEtleQkAASwAAAACAgAAABFubyBzd2FwIGRhdGEgZm9yIAUAAAAHc3dhcEtleQUAAAADU0VQAQAAAAlhcHBseUZlZXMAAAACAAAAC2Ftb3VudEdyb3NzAAAAB2ZlZVBhcnQEAAAACWZlZUFtb3VudAkAAGsAAAADBQAAAAthbW91bnRHcm9zcwUAAAAHZmVlUGFydAUAAAAFUEFVTEkJAARMAAAAAgkAAGUAAAACBQAAAAthbW91bnRHcm9zcwUAAAAJZmVlQW1vdW50CQAETAAAAAIFAAAACWZlZUFtb3VudAkABEwAAAACBQAAAAthbW91bnRHcm9zcwUAAAADbmlsAQAAABZyYW5kVW5sb2NrSGVpZ2h0T3JGYWlsAAAABQAAAAR0eElkAAAABnJzYVNpZwAAAAhzd2FwVHlwZQAAAAtzdGFydEhlaWdodAAAABBtaW5NYXhSYW5kc1R1cGxlBAAAAAppc1JzYVZhbGlkCQAKKAAAAAQFAAAABlNIQTI1NgkAAZsAAAABBQAAAAR0eElkBQAAAAZyc2FTaWcFAAAABnJzYVB1YgMJAQAAAAEhAAAAAQUAAAAKaXNSc2FWYWxpZAkAAAIAAAABAgAAABVpbnZhbGlkIFJTQSBzaWduYXR1cmUEAAAAFm1pbkJhbGFuY2VMb2NrSW50ZXJ2YWwIBQAAABBtaW5NYXhSYW5kc1R1cGxlAAAAAl8xBAAAABZtYXhCYWxhbmNlTG9ja0ludGVydmFsCAUAAAAQbWluTWF4UmFuZHNUdXBsZQAAAAJfMgQAAAAEcmFuZAkAAGoAAAACCQAEsQAAAAEJAAtUAAAAAQUAAAAGcnNhU2lnCQAAZQAAAAIFAAAAFm1heEJhbGFuY2VMb2NrSW50ZXJ2YWwFAAAAFm1pbkJhbGFuY2VMb2NrSW50ZXJ2YWwEAAAAEHJhbmRMb2NrSW50ZXJ2YWwJAABkAAAAAgUAAAAWbWluQmFsYW5jZUxvY2tJbnRlcnZhbAMJAABmAAAAAgAAAAAAAAAAAAUAAAAEcmFuZAkBAAAAAS0AAAABBQAAAARyYW5kBQAAAARyYW5kCQAAZAAAAAIFAAAAC3N0YXJ0SGVpZ2h0BQAAABByYW5kTG9ja0ludGVydmFsAQAAAANhYnMAAAABAAAAAXgDCQAAZgAAAAIAAAAAAAAAAAAFAAAAAXgJAQAAAAEtAAAAAQUAAAABeAUAAAABeAEAAAAKc2VsZWN0Tm9kZQAAAAEAAAANdW5sZWFzZUFtb3VudAQAAAANYW1vdW50VG9MZWFzZQkAAGUAAAACCQAAZQAAAAIICQAD7wAAAAEFAAAAEG5ldXRyaW5vQ29udHJhY3QAAAAJYXZhaWxhYmxlBQAAAA11bmxlYXNlQW1vdW50CQEAAAAfZ2V0UmVzZXJ2ZWRBbW91bnRGb3JTcG9uc29yc2hpcAAAAAAEAAAACm9sZExlYXNlZDAJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABFnZXRMZWFzZUFtb3VudEtleQAAAAEAAAAAAAAAAAAEAAAACm9sZExlYXNlZDEJAQAAAA5nZXROdW1iZXJCeUtleQAAAAEJAQAAABFnZXRMZWFzZUFtb3VudEtleQAAAAEAAAAAAAAAAAEEAAAACm5ld0xlYXNlZDAJAABkAAAAAgUAAAANYW1vdW50VG9MZWFzZQUAAAAKb2xkTGVhc2VkMAQAAAAKbmV3TGVhc2VkMQkAAGQAAAACBQAAAA1hbW91bnRUb0xlYXNlBQAAAApvbGRMZWFzZWQxAwMJAABmAAAAAgUAAAAKbmV3TGVhc2VkMAAAAAAAAAAAAAYJAABmAAAAAgUAAAAKbmV3TGVhc2VkMQAAAAAAAAAAAAQAAAAGZGVsdGEwCQEAAAADYWJzAAAAAQkAAGUAAAACBQAAAApuZXdMZWFzZWQwBQAAAApvbGRMZWFzZWQxBAAAAAZkZWx0YTEJAQAAAANhYnMAAAABCQAAZQAAAAIFAAAACm5ld0xlYXNlZDEFAAAACm9sZExlYXNlZDADCQAAZwAAAAIFAAAABmRlbHRhMQUAAAAGZGVsdGEwCQAFFAAAAAIAAAAAAAAAAAAFAAAACm5ld0xlYXNlZDAJAAUUAAAAAgAAAAAAAAAAAQUAAAAKbmV3TGVhc2VkMQkABRQAAAACAP//////////AAAAAAAAAAAAAQAAABZwcmVwYXJlVW5sZWFzZUFuZExlYXNlAAAAAQAAAA11bmxlYXNlQW1vdW50BAAAAA0kdDAxNjIxMjE2MzAwCQEAAAAKc2VsZWN0Tm9kZQAAAAEFAAAADXVubGVhc2VBbW91bnQEAAAACW5vZGVJbmRleAgFAAAADSR0MDE2MjEyMTYzMDAAAAACXzEEAAAADm5ld0xlYXNlQW1vdW50CAUAAAANJHQwMTYyMTIxNjMwMAAAAAJfMgMJAABmAAAAAgUAAAAObmV3TGVhc2VBbW91bnQAAAAAAAAAAAAEAAAACmxlYXNlSWRLZXkJAQAAAA1nZXRMZWFzZUlkS2V5AAAAAQUAAAAJbm9kZUluZGV4BAAAAAhvbGRMZWFzZQkABBwAAAACBQAAAAR0aGlzBQAAAApsZWFzZUlkS2V5BAAAAA51bmxlYXNlT3JFbXB0eQMJAQAAAAlpc0RlZmluZWQAAAABBQAAAAhvbGRMZWFzZQkABEwAAAACCQEAAAALTGVhc2VDYW5jZWwAAAABCQEAAAAFdmFsdWUAAAABBQAAAAhvbGRMZWFzZQUAAAADbmlsBQAAAANuaWwEAAAADmxlYXNlQW1vdW50S2V5CQEAAAARZ2V0TGVhc2VBbW91bnRLZXkAAAABBQAAAAlub2RlSW5kZXgEAAAABWxlYXNlCQAERAAAAAIJAQAAABxnZXRTdGFraW5nTm9kZUFkZHJlc3NCeUluZGV4AAAAAQUAAAAJbm9kZUluZGV4BQAAAA5uZXdMZWFzZUFtb3VudAkABE4AAAACBQAAAA51bmxlYXNlT3JFbXB0eQkABEwAAAACBQAAAAVsZWFzZQkABEwAAAACCQEAAAALQmluYXJ5RW50cnkAAAACBQAAAApsZWFzZUlkS2V5CQAEOQAAAAEFAAAABWxlYXNlCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAARZ2V0TGVhc2VBbW91bnRLZXkAAAABBQAAAAlub2RlSW5kZXgFAAAADm5ld0xlYXNlQW1vdW50BQAAAANuaWwFAAAAA25pbAEAAAAQZ2V0RG9yYTJOU0JUSW5mbwAAAAAEAAAADWRvcmEyQ29udHJhY3QJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAQAAABFAZXh0ck5hdGl2ZSgxMDUzKQAAAAIFAAAABHRoaXMFAAAAEGtleURvcmEyQ29udHJhY3QJAAUUAAAAAgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAADWRvcmEyQ29udHJhY3QJAQAAAA1rZXlEb3JhMlByaWNlAAAAAQUAAAAPZG9yYTJOc2J0U3ltYm9sAgAAABdOU0JUIHByaWNlIGlzIHVuZGVmaW5lZAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAA1kb3JhMkNvbnRyYWN0CQEAAAASa2V5RG9yYTJMYXN0SGVpZ2h0AAAAAQUAAAAPZG9yYTJOc2J0U3ltYm9sAAAAAAAAAAAAAQAAAAh0aGlzT25seQAAAAEAAAABaQMJAQAAAAIhPQAAAAIIBQAAAAFpAAAABmNhbGxlcgUAAAAEdGhpcwkAAAIAAAABAgAAAC1QZXJtaXNzaW9uIGRlbmllZDogdGhpcyBjb250cmFjdCBvbmx5IGFsbG93ZWQGAAAADQAAAAFpAQAAAB1wcmVwYXJlVW5sZWFzZUFuZExlYXNlV3JhcHBlcgAAAAEAAAANdW5sZWFzZUFtb3VudAQAAAALY2hlY2tDYWxsZXIJAARMAAAAAgkBAAAACHRoaXNPbmx5AAAAAQUAAAABaQUAAAADbmlsAwkAAAAAAAACBQAAAAtjaGVja0NhbGxlcgUAAAALY2hlY2tDYWxsZXIJAQAAABZwcmVwYXJlVW5sZWFzZUFuZExlYXNlAAAAAQUAAAANdW5sZWFzZUFtb3VudAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAALY29uc3RydWN0b3IAAAAOAAAAEm5ldXRyaW5vQXNzZXRJZFBybQAAAA5ib25kQXNzZXRJZFBybQAAABJhdWN0aW9uQ29udHJhY3RQcm0AAAAWbGlxdWlkYXRpb25Db250cmFjdFBybQAAAA5ycGRDb250cmFjdFBybQAAABJjb250cm9sQ29udHJhY3RQcm0AAAAbbm9kZU9yYWNsZVByb3ZpZGVyUHViS2V5UHJtAAAAE3JzYVJhbmRQdWJsaWNLZXlQcm0AAAAbYmFsYW5jZVdhdmVzTG9ja0ludGVydmFsUHJtAAAAHmJhbGFuY2VOZXV0cmlub0xvY2tJbnRlcnZhbFBybQAAABVtaW5XYXZlc1N3YXBBbW91bnRQcm0AAAAYbWluTmV1dHJpbm9Td2FwQW1vdW50UHJtAAAAFW5ldXRyaW5vT3V0RmVlUGFydFBybQAAABJ3YXZlc091dEZlZVBhcnRQcm0EAAAAC2NoZWNrQ2FsbGVyCQEAAAAIdGhpc09ubHkAAAABBQAAAAFpAwkAAAAAAAACBQAAAAtjaGVja0NhbGxlcgUAAAALY2hlY2tDYWxsZXIJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAASTmV1dHJpbm9Bc3NldElkS2V5BQAAABJuZXV0cmlub0Fzc2V0SWRQcm0JAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAOQm9uZEFzc2V0SWRLZXkFAAAADmJvbmRBc3NldElkUHJtCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAEkF1Y3Rpb25Db250cmFjdEtleQUAAAASYXVjdGlvbkNvbnRyYWN0UHJtCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAFkxpcXVpZGF0aW9uQ29udHJhY3RLZXkFAAAAFmxpcXVpZGF0aW9uQ29udHJhY3RQcm0JAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAOUlBEQ29udHJhY3RLZXkFAAAADnJwZENvbnRyYWN0UHJtCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAEkNvbnRyb2xDb250cmFjdEtleQUAAAASY29udHJvbENvbnRyYWN0UHJtCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAG05vZGVPcmFjbGVQcm92aWRlclB1YktleUtleQUAAAAbbm9kZU9yYWNsZVByb3ZpZGVyUHViS2V5UHJtCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAElJzYVJhbmRQdWJsaWM1OEtleQUAAAATcnNhUmFuZFB1YmxpY0tleVBybQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAbQmFsYW5jZVdhdmVzTG9ja0ludGVydmFsS2V5BQAAABtiYWxhbmNlV2F2ZXNMb2NrSW50ZXJ2YWxQcm0JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAHkJhbGFuY2VOZXV0cmlub0xvY2tJbnRlcnZhbEtleQUAAAAeYmFsYW5jZU5ldXRyaW5vTG9ja0ludGVydmFsUHJtCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABVNaW5XYXZlc1N3YXBBbW91bnRLZXkFAAAAFW1pbldhdmVzU3dhcEFtb3VudFBybQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAYTWluTmV1dHJpbm9Td2FwQW1vdW50S2V5BQAAABhtaW5OZXV0cmlub1N3YXBBbW91bnRQcm0JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAFU5ldXRyaW5vT3V0RmVlUGFydEtleQUAAAAVbmV1dHJpbm9PdXRGZWVQYXJ0UHJtCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJXYXZlc091dEZlZVBhcnRLZXkFAAAAEndhdmVzT3V0RmVlUGFydFBybQUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAA1jb25zdHJ1Y3RvclYyAAAABgAAAA1nTnNidENvbnRyYWN0AAAAEG5zYnRMb2NrQ29udHJhY3QAAAANZG9yYTJDb250cmFjdAAAAA5xdWlja1N3YXBEZWxheQAAABZxdWlja1N3YXBMaW1pdER1cmF0aW9uAAAAFGRvcmEyTGFzdEhlaWdodExpbWl0BAAAAAtjaGVja0NhbGxlcgkBAAAACHRoaXNPbmx5AAAAAQUAAAABaQMJAAAAAAAAAgUAAAALY2hlY2tDYWxsZXIFAAAAC2NoZWNrQ2FsbGVyCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAEGtleUdOc2J0Q29udHJhY3QFAAAADWdOc2J0Q29udHJhY3QJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAATa2V5TnNidExvY2tDb250cmFjdAUAAAAQbnNidExvY2tDb250cmFjdAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAABBrZXlEb3JhMkNvbnRyYWN0BQAAAA1kb3JhMkNvbnRyYWN0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABFrZXlRdWlja1N3YXBEZWxheQUAAAAOcXVpY2tTd2FwRGVsYXkJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAGWtleVF1aWNrU3dhcExpbWl0RHVyYXRpb24FAAAAFnF1aWNrU3dhcExpbWl0RHVyYXRpb24JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAF2tleURvcmEyTGFzdEhlaWdodExpbWl0BQAAABRkb3JhMkxhc3RIZWlnaHRMaW1pdAUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAApjb21tb25Td2FwAAAABAAAAAhzd2FwVHlwZQAAAAZhbW91bnQAAAAHYWNjb3VudAAAAAR0eElkBAAAAAtjaGVja0NhbGxlcgkBAAAACHRoaXNPbmx5AAAAAQUAAAABaQMJAAAAAAAAAgUAAAALY2hlY2tDYWxsZXIFAAAAC2NoZWNrQ2FsbGVyBAAAAA1taW5Td2FwQW1vdW50CQEAAAARbWluU3dhcEFtb3VudFJFQUQAAAABBQAAAAhzd2FwVHlwZQQAAAALdG90YWxMb2NrZWQJAQAAAA90b3RhbExvY2tlZFJFQUQAAAABBQAAAAhzd2FwVHlwZQQAAAARdG90YWxMb2NrZWRCeVVzZXIJAQAAABV0b3RhbExvY2tlZEJ5VXNlclJFQUQAAAACBQAAAAhzd2FwVHlwZQUAAAAHYWNjb3VudAQAAAALbm9kZUFkZHJlc3MJAQAAABVnZXRTdGFraW5nTm9kZUJ5SW5kZXgAAAABAAAAAAAAAAAABAAAABZiYWxhbmNlTG9ja01heEludGVydmFsAwkAAAAAAAACBQAAAAtub2RlQWRkcmVzcwUAAAAHYWNjb3VudAkBAAAAG25vZGVCYWxhbmNlTG9ja0ludGVydmFsUkVBRAAAAAAJAQAAABdiYWxhbmNlTG9ja0ludGVydmFsUkVBRAAAAAEFAAAACHN3YXBUeXBlBAAAABBzZWxmVW5sb2NrSGVpZ2h0CQAAZAAAAAIFAAAABmhlaWdodAUAAAAWYmFsYW5jZUxvY2tNYXhJbnRlcnZhbAMJAABmAAAAAgUAAAANbWluU3dhcEFtb3VudAUAAAAGYW1vdW50CQEAAAARbWluU3dhcEFtb3VudEZBSUwAAAACBQAAAAhzd2FwVHlwZQUAAAANbWluU3dhcEFtb3VudAMFAAAACWlzQmxvY2tlZAkBAAAAFWVtZXJnZW5jeVNodXRkb3duRkFJTAAAAAAEAAAACWxlYXNlUGFydAMJAAAAAAAAAgUAAAAIc3dhcFR5cGUCAAAABXdhdmVzCQEAAAAWcHJlcGFyZVVubGVhc2VBbmRMZWFzZQAAAAEAAAAAAAAAAAAFAAAAA25pbAkABE4AAAACCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAUdG90YWxMb2NrZWRCeVVzZXJLRVkAAAACBQAAAAhzd2FwVHlwZQUAAAAHYWNjb3VudAkAAGQAAAACBQAAABF0b3RhbExvY2tlZEJ5VXNlcgUAAAAGYW1vdW50CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAYZ2V0QmFsYW5jZVVubG9ja0Jsb2NrS2V5AAAAAQUAAAAHYWNjb3VudAUAAAAQc2VsZlVubG9ja0hlaWdodAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAADnRvdGFsTG9ja2VkS0VZAAAAAQUAAAAIc3dhcFR5cGUJAABkAAAAAgUAAAALdG90YWxMb2NrZWQFAAAABmFtb3VudAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAHc3dhcEtFWQAAAAIFAAAAB2FjY291bnQFAAAABHR4SWQJAQAAAA9wZW5kaW5nU3dhcERBVEEAAAADBQAAAAhzd2FwVHlwZQUAAAAGYW1vdW50BQAAABBzZWxmVW5sb2NrSGVpZ2h0BQAAAANuaWwFAAAACWxlYXNlUGFydAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAOY29tbW9uV2l0aGRyYXcAAAAEAAAAB2FjY291bnQAAAAFaW5kZXgAAAAIc3dhcFR4SWQAAAAGcnNhU2lnBAAAAAt1c2VyQWRkcmVzcwkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAAHYWNjb3VudAQAAAALY2hlY2tDYWxsZXIJAQAAAAh0aGlzT25seQAAAAEFAAAAAWkDCQAAAAAAAAIFAAAAC2NoZWNrQ2FsbGVyBQAAAAtjaGVja0NhbGxlcgQAAAAJZGF0YUFycmF5CQEAAAASc3dhcERhdGFGYWlsT3JSRUFEAAAAAgUAAAAHYWNjb3VudAUAAAAIc3dhcFR4SWQEAAAAEHNlbGZVbmxvY2tIZWlnaHQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAFHNJZHhTZWxmVW5sb2NrSGVpZ2h0BAAAAAhzd2FwVHlwZQkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAADHNJZHhTd2FwVHlwZQQAAAAIaW5BbW91bnQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAADHNJZHhJbkFtb3VudAQAAAAKc3dhcFN0YXR1cwkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAACnNJZHhTdGF0dXMEAAAAC3N0YXJ0SGVpZ2h0CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAA9zSWR4U3RhcnRIZWlnaHQEAAAAB2lzUXVpY2sJAAAAAAAAAgkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAC3NJZHhJc1F1aWNrAgAAAAR0cnVlBAAAAA1jaGVja1N3YXBUeXBlAwMJAQAAAAIhPQAAAAIFAAAACHN3YXBUeXBlAgAAAAV3YXZlcwkBAAAAAiE9AAAAAgUAAAAIc3dhcFR5cGUCAAAACG5ldXRyaW5vBwkAAAIAAAABCQABLAAAAAICAAAAFlVuc3VwcG9ydGVkIHN3YXAgdHlwZSAFAAAACHN3YXBUeXBlBgMJAAAAAAAAAgUAAAANY2hlY2tTd2FwVHlwZQUAAAANY2hlY2tTd2FwVHlwZQQAAAAKb3V0RmVlUGFydAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAANb3V0RmVlUGFydEtFWQAAAAEFAAAACHN3YXBUeXBlBQAAAA5ERUZBVUxUU1dBUEZFRQQAAAALdG90YWxMb2NrZWQJAQAAAA90b3RhbExvY2tlZFJFQUQAAAABBQAAAAhzd2FwVHlwZQQAAAARdG90YWxMb2NrZWRCeVVzZXIJAQAAABV0b3RhbExvY2tlZEJ5VXNlclJFQUQAAAACBQAAAAhzd2FwVHlwZQUAAAAHYWNjb3VudAQAAAAMdW5sb2NrSGVpZ2h0AwUAAAAHaXNRdWljawkAAGQAAAACBQAAAAtzdGFydEhlaWdodAkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwUAAAARa2V5UXVpY2tTd2FwRGVsYXkDCQAAAAAAAAIFAAAABnJzYVNpZwEAAAAABQAAABBzZWxmVW5sb2NrSGVpZ2h0CQEAAAAWcmFuZFVubG9ja0hlaWdodE9yRmFpbAAAAAUFAAAACHN3YXBUeElkBQAAAAZyc2FTaWcFAAAACHN3YXBUeXBlBQAAAAtzdGFydEhlaWdodAkABRQAAAACCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAAtzSWR4TWluUmFuZAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAALc0lkeE1heFJhbmQEAAAAC2luZGV4SGVpZ2h0CQEAAAAVZ2V0SGVpZ2h0UHJpY2VCeUluZGV4AAAAAQUAAAAFaW5kZXgEAAAAD3ByZXZJbmRleEhlaWdodAkBAAAAFWdldEhlaWdodFByaWNlQnlJbmRleAAAAAEJAABlAAAAAgUAAAAFaW5kZXgAAAAAAAAAAAEEAAAADHByaWNlQnlJbmRleAkBAAAAD2dldFByaWNlSGlzdG9yeQAAAAEFAAAAC2luZGV4SGVpZ2h0BAAAAA0kdDAyMjM0MzIyNTM5AwkAAAAAAAACBQAAAAhzd2FwVHlwZQIAAAAFd2F2ZXMJAAUUAAAAAgkBAAAAFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8AAAACBQAAAAhpbkFtb3VudAUAAAAMcHJpY2VCeUluZGV4BQAAAA9uZXV0cmlub0Fzc2V0SWQJAAUUAAAAAgkBAAAAFmNvbnZlcnROZXV0cmlub1RvV2F2ZXMAAAACBQAAAAhpbkFtb3VudAUAAAAMcHJpY2VCeUluZGV4BQAAAAR1bml0BAAAAA5vdXRBbW91bnRHcm9zcwgFAAAADSR0MDIyMzQzMjI1MzkAAAACXzEEAAAACG91dEFzc2V0CAUAAAANJHQwMjIzNDMyMjUzOQAAAAJfMgQAAAAMcGF5b3V0c0FycmF5CQEAAAAJYXBwbHlGZWVzAAAAAgUAAAAOb3V0QW1vdW50R3Jvc3MFAAAACm91dEZlZVBhcnQEAAAADG91dE5ldEFtb3VudAkAAZEAAAACBQAAAAxwYXlvdXRzQXJyYXkFAAAADElkeE5ldEFtb3VudAQAAAAMb3V0RmVlQW1vdW50CQABkQAAAAIFAAAADHBheW91dHNBcnJheQUAAAAMSWR4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dAUAAAAIc3dhcFR4SWQEAAAACHN3YXBUeXBlCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAMc0lkeFN3YXBUeXBlBAAAAAhpbkFtb3VudAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAMc0lkeEluQW1vdW50BAAAAApzd2FwU3RhdHVzCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAKc0lkeFN0YXR1cwQAAAAHaXNRdWljawkAAAAAAAACCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAALc0lkeElzUXVpY2sCAAAABHRydWUEAAAADSR0MDI1NTA3MjU3MTUEAAAAByRtYXRjaDAJAAP8AAAABAUAAAAEdGhpcwIAAAAWcXVpY2tTd2FwTGltaXRSRUFET05MWQkABEwAAAACCQAEJQAAAAEFAAAAC3VzZXJBZGRyZXNzBQAAAANuaWwFAAAAA25pbAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAKKEludCwgSW50KQQAAAABcgUAAAAHJG1hdGNoMAkABRQAAAACCAUAAAABcgAAAAJfMQgFAAAAAXIAAAACXzIJAAACAAAAAQIAAAASVHlwZSBjYXN0aW5nIGVycm9yBAAAABNxdWlja1N3YXBMaW1pdFRvdGFsCAUAAAANJHQwMjU1MDcyNTcxNQAAAAJfMQQAAAAScXVpY2tTd2FwVXNlclNwZW50CAUAAAANJHQwMjU1MDcyNTcxNQAAAAJfMgQAAAAOcXVpY2tTd2FwTGltaXQJAABlAAAAAgUAAAATcXVpY2tTd2FwTGltaXRUb3RhbAUAAAAScXVpY2tTd2FwVXNlclNwZW50BAAAAAxwcmljZUJ5SW5kZXgJAQAAAA9nZXRQcmljZUhpc3RvcnkAAAABCQEAAAAVZ2V0SGVpZ2h0UHJpY2VCeUluZGV4AAAAAQUAAAAKcHJpY2VJbmRleAQAAAAOc3dhcFVzZG5Wb2x1bWUDCQAAAAAAAAIFAAAACHN3YXBUeXBlAgAAAAhuZXV0cmlubwUAAAAIaW5BbW91bnQJAQAAABZjb252ZXJ0V2F2ZXNUb05ldXRyaW5vAAAAAgUAAAAIaW5BbW91bnQFAAAADHByaWNlQnlJbmRleAQAAAAGY2hlY2tz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dWlja1N3YXBMaW1pdFJFQURPTkxZAAAAAQAAAAtnTnNidEFtb3VudAQAAAANJHQwMjg3NjYyODgyMwkBAAAAEGdldERvcmEyTlNCVEluZm8AAAAABAAAAAluc2J0UHJpY2UIBQAAAA0kdDAyODc2NjI4ODIzAAAAAl8xBAAAABNuc2J0UHJpY2VMYXN0SGVpZ2h0CAUAAAANJHQwMjg3NjYyODgyMwAAAAJfMgQAAAAFY2hlY2sDCQAAZgAAAAIJAABlAAAAAgUAAAAGaGVpZ2h0BQAAABNuc2J0UHJpY2VMYXN0SGVpZ2h0CQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAAR0aGlzBQAAABdrZXlEb3JhMkxhc3RIZWlnaHRMaW1pdAkAAAIAAAABAgAAABZOU0JUIHByaWNlIGlzIG91dGRhdGVkBgMJAAAAAAAAAgUAAAAFY2hlY2sFAAAABWNoZWNrCQAFFAAAAAIFAAAAA25pbAkAAGsAAAADBQAAAAtnTnNidEFtb3VudAUAAAAJbnNidFByaWNlBQAAAAdXQVZFTEVUCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAABZxdWlja1N3YXBMaW1pdFJFQURPTkxZAAAAAQAAAA51c2VyQWRkcmVzc1N0cgQAAAALdXNlckFkZHJlc3MJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAADnVzZXJBZGRyZXNzU3RyBAAAAA91c2VyR05zYnRBbW91bnQJAQAAAAVhc0ludAAAAAEJAAP8AAAABAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkBAAAAEUBleHRyTmF0aXZlKDEwNTMpAAAAAgUAAAAEdGhpcwUAAAATa2V5TnNidExvY2tDb250cmFjdAIAAAATZ05zYnRBbW91bnRSRUFET05MWQkABEwAAAACCQAEJQAAAAEFAAAAC3VzZXJBZGRyZXNzBQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAAPdXNlckdOc2J0QW1vdW50BQAAAA91c2VyR05zYnRBbW91bnQEAAAAE3F1aWNrU3dhcExpbWl0VG90YWwJAQAAAAVhc0ludAAAAAEJAAP8AAAABAUAAAAEdGhpcwIAAAAfY2FsY1RvdGFsUXVpY2tTd2FwTGltaXRSRUFET05MWQkABEwAAAACBQAAAA91c2VyR05zYnRBbW91bnQFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAABNxdWlja1N3YXBMaW1pdFRvdGFsBQAAABNxdWlja1N3YXBMaW1pdFRvdGFsBAAAABRpc05ld1F1aWNrU3dhcFBlcmlvZAkAAGYAAAACCQAAZQAAAAIFAAAABmhlaWdodAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAaa2V5VXNlckxhc3RRdWlja1N3YXBIZWlnaHQAAAABBQAAAAt1c2VyQWRkcmVzcwAAAAAAAAAAAAkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwUAAAAZa2V5UXVpY2tTd2FwTGltaXREdXJhdGlvbgQAAAAScXVpY2tTd2FwVXNlclNwZW50AwUAAAAUaXNOZXdRdWlja1N3YXBQZXJpb2QAAAAAAAAAAAAJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwkBAAAAHWtleVF1aWNrU3dhcFVzZXJTcGVudEluUGVyaW9kAAAAAQUAAAALdXNlckFkZHJlc3MAAAAAAAAAAAAJAAUUAAAAAgUAAAADbmlsCQAFFAAAAAIFAAAAE3F1aWNrU3dhcExpbWl0VG90YWwFAAAAEnF1aWNrU3dhcFVzZXJTcGVudAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAABZ6T2g=", "height": 1892991, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 2UyNt5M12f8q5fVhJ6wWmYpaNmJDZ7y6oCEykA991VQT Next: none Diff:
OldNewDifferences
284284
285285 let sIdxMaxRand = 16
286286
287+let sIdxIsQuick = 17
288+
287289 func swapKEY (userAddress,txId) = makeString(["%s%s", userAddress, txId], SEP)
288290
289291
290-func strSwapDATA (swapType,status,inAmount,price,outNetAmount,outFeeAmount,startHeight,startTimestamp,endHeight,endTimestamp,selfUnlockHeight,randUnlockHeight,index,withdrawTxId,randMin,randMax) = makeString(["%s%s%d%d%d%d%d%d%d%d%d%d%d%s", swapType, status, inAmount, price, outNetAmount, outFeeAmount, startHeight, startTimestamp, endHeight, endTimestamp, selfUnlockHeight, randUnlockHeight, index, withdrawTxId, randMin, randMax], SEP)
292+func strSwapDATA (swapType,status,inAmount,price,outNetAmount,outFeeAmount,startHeight,startTimestamp,endHeight,endTimestamp,selfUnlockHeight,randUnlockHeight,index,withdrawTxId,randMin,randMax,isQuick) = makeString(["%s%s%d%d%d%d%d%d%d%d%d%d%d%s", swapType, status, inAmount, price, outNetAmount, outFeeAmount, startHeight, startTimestamp, endHeight, endTimestamp, selfUnlockHeight, randUnlockHeight, index, withdrawTxId, randMin, randMax, isQuick], SEP)
291293
292294
293-func pendingSwapDATA (swapType,inAssetAmount,selfUnlockHeight) = strSwapDATA(swapType, "PENDING", toString(inAssetAmount), "0", "0", "0", toString(height), toString(lastBlock.timestamp), "0", "0", toString(selfUnlockHeight), "0", "0", "NULL", toString(minBalanceLockIntervalREAD(swapType)), toString(balanceLockIntervalREAD(swapType)))
295+func pendingSwapDATA (swapType,inAssetAmount,selfUnlockHeight) = strSwapDATA(swapType, "PENDING", toString(inAssetAmount), "0", "0", "0", toString(height), toString(lastBlock.timestamp), "0", "0", toString(selfUnlockHeight), "0", "0", "NULL", toString(minBalanceLockIntervalREAD(swapType)), toString(balanceLockIntervalREAD(swapType)), toString(false))
294296
295297
296-func finishSwapDATA (dataArray,price,outNetAmount,outFeeAmount,randUnlockHeight,index,withdrawTxId) = strSwapDATA(dataArray[sIdxSwapType], "FINISHED", dataArray[sIdxInAmount], toString(price), toString(outNetAmount), toString(outFeeAmount), dataArray[sIdxStartHeight], dataArray[sIdxStartTimestamp], toString(height), toString(lastBlock.timestamp), dataArray[sIdxSelfUnlockHeight], toString(randUnlockHeight), toString(index), withdrawTxId, if ((15 >= size(dataArray)))
297- then toString(minRand)
298- else dataArray[sIdxMinRand], if ((15 >= size(dataArray)))
299- then toString(maxRand)
300- else dataArray[sIdxMaxRand])
298+func accelerateSwapDATA (dataArray) = strSwapDATA(dataArray[sIdxSwapType], dataArray[sIdxStatus], dataArray[sIdxInAmount], dataArray[sIdxPrice], dataArray[sIdxOutNetAmount], dataArray[sIdxOutFeeAmount], dataArray[sIdxStartHeight], dataArray[sIdxStartTimestamp], dataArray[sIdxEndHeight], dataArray[sIdxEndTimestamp], dataArray[sIdxSelfUnlockHeight], dataArray[sIdxRandUnlockHeight], dataArray[sIdxIndex], dataArray[sIdxWithdrawTxId], dataArray[sIdxMinRand], dataArray[sIdxMaxRand], toString(true))
299+
300+
301+func finishSwapDATA (dataArray,price,outNetAmount,outFeeAmount,randUnlockHeight,index,withdrawTxId) = strSwapDATA(dataArray[sIdxSwapType], "FINISHED", dataArray[sIdxInAmount], toString(price), toString(outNetAmount), toString(outFeeAmount), dataArray[sIdxStartHeight], dataArray[sIdxStartTimestamp], toString(height), toString(lastBlock.timestamp), dataArray[sIdxSelfUnlockHeight], toString(randUnlockHeight), toString(index), withdrawTxId, dataArray[sIdxMinRand], dataArray[sIdxMaxRand], dataArray[sIdxIsQuick])
301302
302303
303304 func swapDataFailOrREAD (userAddress,swapTxId) = {
354355
355356
356357 func prepareUnleaseAndLease (unleaseAmount) = {
357- let $t01536515453 = selectNode(unleaseAmount)
358- let nodeIndex = $t01536515453._1
359- let newLeaseAmount = $t01536515453._2
358+ let $t01621216300 = selectNode(unleaseAmount)
359+ let nodeIndex = $t01621216300._1
360+ let newLeaseAmount = $t01621216300._2
360361 if ((newLeaseAmount > 0))
361362 then {
362363 let leaseIdKey = getLeaseIdKey(nodeIndex)
374375
375376 func getDora2NSBTInfo () = {
376377 let dora2Contract = addressFromStringValue(getStringValue(this, keyDora2Contract))
377- let price = valueOrErrorMessage(getInteger(dora2Contract, keyDora2Price(dora2NsbtSymbol)), "NSBT price is undefined")
378- let lastHeight = valueOrElse(getInteger(dora2Contract, keyDora2LastHeight(dora2NsbtSymbol)), 0)
379- $Tuple2(price, lastHeight)
380- }
381-
382-
383-func getNSBTPrice () = {
384- let $t01641116455 = getDora2NSBTInfo()
385- let price = $t01641116455._1
386- let lastHeight = $t01641116455._2
387- price
388- }
389-
390-
391-func commonSwap (swapType,i) = {
392- let pmt = value(i.payments[0])
393- let account = toString(i.caller)
394- let txId58 = toBase58String(i.transactionId)
395- let minSwapAmount = minSwapAmountREAD(swapType)
396- let totalLocked = totalLockedREAD(swapType)
397- let totalLockedByUser = totalLockedByUserREAD(swapType, account)
398- let nodeAddress = getStakingNodeByIndex(0)
399- let balanceLockMaxInterval = if ((nodeAddress == account))
400- then nodeBalanceLockIntervalREAD()
401- else balanceLockIntervalREAD(swapType)
402- let selfUnlockHeight = (height + balanceLockMaxInterval)
403- if ((minSwapAmount > pmt.amount))
404- then minSwapAmountFAIL(swapType, minSwapAmount)
405- else if (isBlocked)
406- then emergencyShutdownFAIL()
407- else {
408- let leasePart = if ((swapType == "waves"))
409- then prepareUnleaseAndLease(0)
410- else nil
411- $Tuple2(([IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser + pmt.amount)), IntegerEntry(getBalanceUnlockBlockKey(account), selfUnlockHeight), IntegerEntry(totalLockedKEY(swapType), (totalLocked + pmt.amount)), StringEntry(swapKEY(account, txId58), pendingSwapDATA(swapType, pmt.amount, selfUnlockHeight))] ++ leasePart), unit)
412- }
378+ $Tuple2(valueOrErrorMessage(getInteger(dora2Contract, keyDora2Price(dora2NsbtSymbol)), "NSBT price is undefined"), valueOrElse(getInteger(dora2Contract, keyDora2LastHeight(dora2NsbtSymbol)), 0))
413379 }
414380
415381
449415
450416
451417 @Callable(i)
452-func commonWithdraw (account,index,swapTxId,rsaSig,isQuick) = {
418+func commonSwap (swapType,amount,account,txId) = {
419+ let checkCaller = thisOnly(i)
420+ if ((checkCaller == checkCaller))
421+ then {
422+ let minSwapAmount = minSwapAmountREAD(swapType)
423+ let totalLocked = totalLockedREAD(swapType)
424+ let totalLockedByUser = totalLockedByUserREAD(swapType, account)
425+ let nodeAddress = getStakingNodeByIndex(0)
426+ let balanceLockMaxInterval = if ((nodeAddress == account))
427+ then nodeBalanceLockIntervalREAD()
428+ else balanceLockIntervalREAD(swapType)
429+ let selfUnlockHeight = (height + balanceLockMaxInterval)
430+ if ((minSwapAmount > amount))
431+ then minSwapAmountFAIL(swapType, minSwapAmount)
432+ else if (isBlocked)
433+ then emergencyShutdownFAIL()
434+ else {
435+ let leasePart = if ((swapType == "waves"))
436+ then prepareUnleaseAndLease(0)
437+ else nil
438+ ([IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser + amount)), IntegerEntry(getBalanceUnlockBlockKey(account), selfUnlockHeight), IntegerEntry(totalLockedKEY(swapType), (totalLocked + amount)), StringEntry(swapKEY(account, txId), pendingSwapDATA(swapType, amount, selfUnlockHeight))] ++ leasePart)
439+ }
440+ }
441+ else throw("Strict value is not equal to itself.")
442+ }
443+
444+
445+
446+@Callable(i)
447+func commonWithdraw (account,index,swapTxId,rsaSig) = {
453448 let userAddress = addressFromStringValue(account)
454- let checkCaller = [thisOnly(i), if (if (isQuick)
455- then (i.originCaller != userAddress)
456- else false)
457- then throw(((("Permission denied: originCaller=" + toString(i.originCaller)) + ", account=") + account))
458- else true]
449+ let checkCaller = thisOnly(i)
459450 if ((checkCaller == checkCaller))
460451 then {
461452 let dataArray = swapDataFailOrREAD(account, swapTxId)
464455 let inAmount = parseIntValue(dataArray[sIdxInAmount])
465456 let swapStatus = dataArray[sIdxStatus]
466457 let startHeight = parseIntValue(dataArray[sIdxStartHeight])
458+ let isQuick = (dataArray[sIdxIsQuick] == "true")
467459 let checkSwapType = if (if ((swapType != "waves"))
468460 then (swapType != "neutrino")
469461 else false)
474466 let outFeePart = valueOrElse(getInteger(this, outFeePartKEY(swapType)), DEFAULTSWAPFEE)
475467 let totalLocked = totalLockedREAD(swapType)
476468 let totalLockedByUser = totalLockedByUserREAD(swapType, account)
477- let minMaxRandsTuple = if ((15 >= size(dataArray)))
478- then $Tuple2(minRand, maxRand)
479- else $Tuple2(parseIntValue(dataArray[sIdxMinRand]), parseIntValue(dataArray[sIdxMaxRand]))
480469 let unlockHeight = if (isQuick)
481- then {
482- let quickSwapDelay = getIntegerValue(this, keyQuickSwapDelay)
483- (startHeight + quickSwapDelay)
484- }
470+ then (startHeight + getIntegerValue(this, keyQuickSwapDelay))
485471 else if ((rsaSig == base58''))
486472 then selfUnlockHeight
487- else randUnlockHeightOrFail(swapTxId, rsaSig, swapType, startHeight, minMaxRandsTuple)
473+ else randUnlockHeightOrFail(swapTxId, rsaSig, swapType, startHeight, $Tuple2(parseIntValue(dataArray[sIdxMinRand]), parseIntValue(dataArray[sIdxMaxRand])))
488474 let indexHeight = getHeightPriceByIndex(index)
489475 let prevIndexHeight = getHeightPriceByIndex((index - 1))
490476 let priceByIndex = getPriceHistory(indexHeight)
491- let $t02196622162 = if ((swapType == "waves"))
477+ let $t02234322539 = if ((swapType == "waves"))
492478 then $Tuple2(convertWavesToNeutrino(inAmount, priceByIndex), neutrinoAssetId)
493479 else $Tuple2(convertNeutrinoToWaves(inAmount, priceByIndex), unit)
494- let outAmountGross = $t02196622162._1
495- let outAsset = $t02196622162._2
480+ let outAmountGross = $t02234322539._1
481+ let outAsset = $t02234322539._2
496482 let payoutsArray = applyFees(outAmountGross, outFeePart)
497483 let outNetAmount = payoutsArray[IdxNetAmount]
498484 let outFeeAmount = payoutsArray[IdxFeeAmount]
499- let quickSwapLimitDuration = getIntegerValue(this, keyQuickSwapLimitDuration)
500- let quickSwapUserSpentInPeriod = valueOrElse(getInteger(this, keyQuickSwapUserSpentInPeriod(userAddress)), 0)
501- let userLastQuickSwapHeight = valueOrElse(getInteger(this, keyUserLastQuickSwapHeight(userAddress)), 0)
502- let nsbtLockContract = addressFromStringValue(getStringValue(this, keyNsbtLockContract))
503- let userGNsbtAmountResult = invoke(nsbtLockContract, "gNsbtAmountREADONLY", [toString(userAddress)], nil)
504- if ((userGNsbtAmountResult == userGNsbtAmountResult))
485+ let checks = [if (isBlocked)
486+ then emergencyShutdownFAIL()
487+ else true, if ((swapStatus != "PENDING"))
488+ then throw("swap has been already processed")
489+ else true, if ((unlockHeight > height))
490+ then throw((("please wait for: " + toString(unlockHeight)) + " block height to withdraw funds"))
491+ else true, if (if (if ((index > priceIndex))
492+ then true
493+ else (unlockHeight > indexHeight))
494+ then true
495+ else if ((prevIndexHeight != 0))
496+ then (prevIndexHeight >= unlockHeight)
497+ else false)
498+ then priceIndexFAIL(index, priceIndex, indexHeight, unlockHeight, prevIndexHeight)
499+ else true, if ((0 >= payoutsArray[IdxGrossAmount]))
500+ then throw("balance equals zero")
501+ else true, if (if ((0 > outFeePart))
502+ then true
503+ else (outFeePart >= PAULI))
504+ then throw(((("invalid outFeePart config for " + swapType) + " swap: outFeePart=") + toString(outFeePart)))
505+ else true]
506+ if ((checks == checks))
505507 then {
506- let userGNsbtAmount = asInt(userGNsbtAmountResult)
507- let $t02287422931 = getDora2NSBTInfo()
508- let nsbtPrice = $t02287422931._1
509- let nsbtPriceLastHeight = $t02287422931._2
510- let lastHeightLimit = getIntegerValue(this, keyDora2LastHeightLimit)
511- let isNewQuickSwapPeriod = ((height - userLastQuickSwapHeight) > quickSwapLimitDuration)
512- let quickSwapUserSpent = if (isNewQuickSwapPeriod)
513- then 0
514- else quickSwapUserSpentInPeriod
515- let quickSwapLimitTotal = fraction(userGNsbtAmount, nsbtPrice, WAVELET)
516- let quickSwapLimit = (quickSwapLimitTotal - quickSwapUserSpent)
517- let swapUsdnVolume = if ((swapType == "neutrino"))
518- then inAmount
519- else outAmountGross
520- let checks = [if (if (isQuick)
521- then ((height - nsbtPriceLastHeight) > lastHeightLimit)
508+ let leasePart = if (if ((swapType == "neutrino"))
509+ then (outAmountGross > 0)
522510 else false)
523- then throw("NSBT price is outdated")
524- else true, if (if (isQuick)
525- then (swapUsdnVolume > quickSwapLimit)
526- else false)
527- then throw(((("You have exceeded the quick swaps limit: limit=" + toString(quickSwapLimit)) + ", attemptedAmount=") + toString(swapUsdnVolume)))
528- else true, if (isBlocked)
529- then emergencyShutdownFAIL()
530- else true, if ((swapStatus != "PENDING"))
531- then throw("swap has been already processed")
532- else true, if ((unlockHeight > height))
533- then throw((("please wait for: " + toString(unlockHeight)) + " block height to withdraw funds"))
534- else true, if (if (if ((index > priceIndex))
535- then true
536- else (unlockHeight > indexHeight))
537- then true
538- else if ((prevIndexHeight != 0))
539- then (prevIndexHeight >= unlockHeight)
540- else false)
541- then priceIndexFAIL(index, priceIndex, indexHeight, unlockHeight, prevIndexHeight)
542- else true, if ((0 >= payoutsArray[IdxGrossAmount]))
543- then throw("balance equals zero")
544- else true, if (if ((0 > outFeePart))
545- then true
546- else (outFeePart >= PAULI))
547- then throw(((("invalid outFeePart config for " + swapType) + " swap: outFeePart=") + toString(outFeePart)))
548- else true]
549- if ((checks == checks))
511+ then invoke(this, "prepareUnleaseAndLeaseWrapper", [outAmountGross], nil)
512+ else unit
513+ if ((leasePart == leasePart))
550514 then {
551- let leasePart = if (if ((swapType == "neutrino"))
552- then (outAmountGross > 0)
553- else false)
554- then invoke(this, "prepareUnleaseAndLeaseWrapper", [outAmountGross], nil)
555- else unit
556- if ((leasePart == leasePart))
557- then {
558- let gNsbtContract = addressFromStringValue(getStringValue(this, keyGNsbtContract))
559- let sendFee = invoke(gNsbtContract, "deposit", nil, [AttachedPayment(outAsset, outFeeAmount)])
560- if ((sendFee == sendFee))
561- then {
562- let quickSwapPart = if (isQuick)
563- then [IntegerEntry(keyQuickSwapUserSpentInPeriod(userAddress), (swapUsdnVolume + quickSwapUserSpent)), IntegerEntry(keyUserLastQuickSwapHeight(userAddress), height)]
564- else nil
565- (quickSwapPart ++ [IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser - inAmount)), IntegerEntry(totalLockedKEY(swapType), (totalLocked - inAmount)), ScriptTransfer(userAddress, outNetAmount, outAsset), StringEntry(swapKEY(account, swapTxId), finishSwapDATA(dataArray, priceByIndex, outNetAmount, outFeeAmount, unlockHeight, index, toBase58String(i.transactionId)))])
566- }
567- else throw("Strict value is not equal to itself.")
568- }
515+ let sendFee = invoke(addressFromStringValue(getStringValue(this, keyGNsbtContract)), "deposit", nil, [AttachedPayment(outAsset, outFeeAmount)])
516+ if ((sendFee == sendFee))
517+ then [IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser - inAmount)), IntegerEntry(totalLockedKEY(swapType), (totalLocked - inAmount)), ScriptTransfer(userAddress, outNetAmount, outAsset), StringEntry(swapKEY(account, swapTxId), finishSwapDATA(dataArray, priceByIndex, outNetAmount, outFeeAmount, unlockHeight, index, toBase58String(i.transactionId)))]
569518 else throw("Strict value is not equal to itself.")
570519 }
571520 else throw("Strict value is not equal to itself.")
580529
581530
582531 @Callable(i)
583-func swapWavesToNeutrino () = {
532+func swap (swapType,accelerate) = {
533+ let wavesToNeutrino = (swapType == "waves")
534+ let neutrinoToWaves = (swapType == "neutrino")
584535 let pmt = value(i.payments[0])
585- if (isDefined(pmt.assetId))
536+ let account = toString(i.caller)
537+ let swapTxId = toBase58String(i.transactionId)
538+ if (if (wavesToNeutrino)
539+ then (pmt.assetId != unit)
540+ else false)
586541 then throw("Only Waves token is allowed for swapping.")
587- else commonSwap("waves", i)
542+ else if (if (neutrinoToWaves)
543+ then (pmt.assetId != neutrinoAssetId)
544+ else false)
545+ then throw("Only appropriate Neutrino tokens are allowed for swapping.")
546+ else if (if (!(wavesToNeutrino))
547+ then !(neutrinoToWaves)
548+ else false)
549+ then throw("Invalid swap type")
550+ else {
551+ let commonSwapInv = invoke(this, "commonSwap", [swapType, pmt.amount, account, swapTxId], nil)
552+ if ((commonSwapInv == commonSwapInv))
553+ then {
554+ let accelerateInv = if (accelerate)
555+ then invoke(this, "accelerate", [account, swapTxId], nil)
556+ else true
557+ if ((accelerateInv == accelerateInv))
558+ then nil
559+ else throw("Strict value is not equal to itself.")
560+ }
561+ else throw("Strict value is not equal to itself.")
562+ }
588563 }
589564
590565
591566
592567 @Callable(i)
593-func swapNeutrinoToWaves () = {
594- let pmt = value(i.payments[0])
595- if ((pmt.assetId != neutrinoAssetId))
596- then throw("Only appropriate Neutrino tokens are allowed for swapping.")
597- else commonSwap("neutrino", i)
568+func accelerate (account,swapTxId) = {
569+ let userAddress = addressFromStringValue(account)
570+ let checkCaller = if ((i.originCaller != userAddress))
571+ then throw("Permission denied")
572+ else true
573+ if ((checkCaller == checkCaller))
574+ then {
575+ let dataArray = swapDataFailOrREAD(account, swapTxId)
576+ let swapType = dataArray[sIdxSwapType]
577+ let inAmount = parseIntValue(dataArray[sIdxInAmount])
578+ let swapStatus = dataArray[sIdxStatus]
579+ let isQuick = (dataArray[sIdxIsQuick] == "true")
580+ let $t02550725715 = match invoke(this, "quickSwapLimitREADONLY", [toString(userAddress)], nil) {
581+ case r: (Int, Int) =>
582+ $Tuple2(r._1, r._2)
583+ case _ =>
584+ throw("Type casting error")
585+ }
586+ let quickSwapLimitTotal = $t02550725715._1
587+ let quickSwapUserSpent = $t02550725715._2
588+ let quickSwapLimit = (quickSwapLimitTotal - quickSwapUserSpent)
589+ let priceByIndex = getPriceHistory(getHeightPriceByIndex(priceIndex))
590+ let swapUsdnVolume = if ((swapType == "neutrino"))
591+ then inAmount
592+ else convertWavesToNeutrino(inAmount, priceByIndex)
593+ let checks = [if ((swapStatus != "PENDING"))
594+ then throw("Swap has been already processed")
595+ else true, if (isQuick)
596+ then throw("Swap has been already accelerated")
597+ else true, if ((swapUsdnVolume > quickSwapLimit))
598+ then throw(((("You have exceeded the quick swaps limit! Requested: " + toString(swapUsdnVolume)) + ", available: ") + toString(quickSwapLimit)))
599+ else true]
600+ if ((checks == checks))
601+ then [IntegerEntry(keyQuickSwapUserSpentInPeriod(userAddress), (swapUsdnVolume + quickSwapUserSpent)), IntegerEntry(keyUserLastQuickSwapHeight(userAddress), height), StringEntry(swapKEY(account, swapTxId), accelerateSwapDATA(dataArray))]
602+ else throw("Strict value is not equal to itself.")
603+ }
604+ else throw("Strict value is not equal to itself.")
598605 }
599606
600607
601608
602609 @Callable(i)
603610 func withdraw (account,index,swapTxId) = {
604- let result = invoke(this, "commonWithdraw", [account, index, swapTxId, base58'', false], nil)
605- if ((result == result))
606- then nil
607- else throw("Strict value is not equal to itself.")
608- }
609-
610-
611-
612-@Callable(i)
613-func withdrawV2 (account,index,swapTxId,isQuick) = {
614- let result = invoke(this, "commonWithdraw", [account, index, swapTxId, base58'', isQuick], nil)
611+ let result = invoke(this, "commonWithdraw", [account, index, swapTxId, base58''], nil)
615612 if ((result == result))
616613 then nil
617614 else throw("Strict value is not equal to itself.")
621618
622619 @Callable(i)
623620 func withdrawRand (account,index,swapTxId,rsaSig) = {
624- let result = invoke(this, "commonWithdraw", [account, index, swapTxId, rsaSig, false], nil)
621+ let result = invoke(this, "commonWithdraw", [account, index, swapTxId, rsaSig], nil)
625622 if ((result == result))
626623 then nil
627624 else throw("Strict value is not equal to itself.")
652649
653650
654651 @Callable(i)
655-func quickSwapLimitREADONLY (gNsbtAmount) = $Tuple2(nil, (gNsbtAmount * getNSBTPrice()))
652+func calcTotalQuickSwapLimitREADONLY (gNsbtAmount) = {
653+ let $t02876628823 = getDora2NSBTInfo()
654+ let nsbtPrice = $t02876628823._1
655+ let nsbtPriceLastHeight = $t02876628823._2
656+ let check = if (((height - nsbtPriceLastHeight) > getIntegerValue(this, keyDora2LastHeightLimit)))
657+ then throw("NSBT price is outdated")
658+ else true
659+ if ((check == check))
660+ then $Tuple2(nil, fraction(gNsbtAmount, nsbtPrice, WAVELET))
661+ else throw("Strict value is not equal to itself.")
662+ }
663+
664+
665+
666+@Callable(i)
667+func quickSwapLimitREADONLY (userAddressStr) = {
668+ let userAddress = addressFromStringValue(userAddressStr)
669+ let userGNsbtAmount = asInt(invoke(addressFromStringValue(getStringValue(this, keyNsbtLockContract)), "gNsbtAmountREADONLY", [toString(userAddress)], nil))
670+ if ((userGNsbtAmount == userGNsbtAmount))
671+ then {
672+ let quickSwapLimitTotal = asInt(invoke(this, "calcTotalQuickSwapLimitREADONLY", [userGNsbtAmount], nil))
673+ if ((quickSwapLimitTotal == quickSwapLimitTotal))
674+ then {
675+ let isNewQuickSwapPeriod = ((height - valueOrElse(getInteger(this, keyUserLastQuickSwapHeight(userAddress)), 0)) > getIntegerValue(this, keyQuickSwapLimitDuration))
676+ let quickSwapUserSpent = if (isNewQuickSwapPeriod)
677+ then 0
678+ else valueOrElse(getInteger(this, keyQuickSwapUserSpentInPeriod(userAddress)), 0)
679+ $Tuple2(nil, $Tuple2(quickSwapLimitTotal, quickSwapUserSpent))
680+ }
681+ else throw("Strict value is not equal to itself.")
682+ }
683+ else throw("Strict value is not equal to itself.")
684+ }
656685
657686
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0)
55
66
77 func getStringByKey (key) = valueOrElse(getString(this, key), "")
88
99
1010 func getBoolByKey (key) = valueOrElse(getBoolean(this, key), false)
1111
1212
1313 func getNumberByAddressAndKey (address,key) = valueOrElse(getInteger(addressFromStringValue(address), key), 0)
1414
1515
1616 func getStringByAddressAndKey (address,key) = valueOrElse(getString(addressFromStringValue(address), key), "")
1717
1818
1919 func getBoolByAddressAndKey (address,key) = valueOrElse(getBoolean(addressFromStringValue(address), key), false)
2020
2121
2222 let pubKeyAdminsList = ["GJdLSaLiv5K7xuejac8mcRcHoyo3dPrESrvktG3a6MAR", "FWVffYr2ALmHMejZm3WqeLz6Sdym3gLFGtJn4KTwyU5x", "3Wh2LaWcb5gg7K2pPcW3Ep6EAuRBzYkAgrdpt43jTDFa", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
2323
2424 func asInt (val) = match val {
2525 case valInt: Int =>
2626 valInt
2727 case _ =>
2828 throw("Failed to cast into Int")
2929 }
3030
3131
3232 let SEP = "__"
3333
3434 let WAVELET = 100000000
3535
3636 let PAULI = 1000000
3737
3838 let PRICELET = 1000000
3939
4040 let DEFAULTSWAPFEE = 20000
4141
4242 let IdxNetAmount = 0
4343
4444 let IdxFeeAmount = 1
4545
4646 let IdxGrossAmount = 2
4747
4848 let dora2NsbtSymbol = "NSBT-USDT"
4949
5050 let minRand = 60
5151
5252 let maxRand = 1440
5353
5454 let NeutrinoAssetIdKey = "neutrino_asset_id"
5555
5656 let BondAssetIdKey = "bond_asset_id"
5757
5858 let AuctionContractKey = "auction_contract"
5959
6060 let LiquidationContractKey = "liquidation_contract"
6161
6262 let RPDContractKey = "rpd_contract"
6363
6464 let ControlContractKey = "control_contract"
6565
6666 let BalanceWavesLockIntervalKey = "balance_waves_lock_interval"
6767
6868 let BalanceNeutrinoLockIntervalKey = "balance_neutrino_lock_interval"
6969
7070 let MinWavesSwapAmountKey = "min_waves_swap_amount"
7171
7272 let MinNeutrinoSwapAmountKey = "min_neutrino_swap_amount"
7373
7474 let NodeOracleProviderPubKeyKey = "node_oracle_provider"
7575
7676 let NeutrinoOutFeePartKey = "neutrinoOut_swap_feePart"
7777
7878 let WavesOutFeePartKey = "wavesOut_swap_feePart"
7979
8080 let RsaRandPublic58Key = "rand_rsa_public"
8181
8282 let keyGNsbtContract = "%s__gNsbtContract"
8383
8484 let keyNsbtLockContract = "%s__nsbtLockContract"
8585
8686 let keyDora2Contract = "%s__dora2Contract"
8787
8888 let keyQuickSwapDelay = "%s__quickSwapDelay"
8989
9090 let keyQuickSwapLimitDuration = "%s__quickSwapLimitDuration"
9191
9292 let keyDora2LastHeightLimit = "%s__dora2LastHeightLimit"
9393
9494 let PriceKey = "price"
9595
9696 let PriceIndexKey = "price_index"
9797
9898 let IsBlockedKey = "is_blocked"
9999
100100 func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block))
101101
102102
103103 func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index))
104104
105105
106106 func getStakingNodeByIndex (idx) = getStringByKey(makeString(["%s%d%s", "lease", toString(idx), "nodeAddress"], SEP))
107107
108108
109109 func getStakingNodeAddressByIndex (idx) = addressFromStringValue(getStakingNodeByIndex(idx))
110110
111111
112112 func getReservedAmountForSponsorship () = valueOrElse(getInteger(this, makeString(["%s%s", "lease", "sponsorshipWavesReserve"], SEP)), (1000 * WAVELET))
113113
114114
115115 func getBalanceUnlockBlockKey (owner) = ("balance_unlock_block_" + owner)
116116
117117
118118 func getLeaseIdKey (nodeIndex) = makeString(["%s%d%s", "lease", toString(nodeIndex), "id"], SEP)
119119
120120
121121 func getLeaseAmountKey (nodeIndex) = makeString(["%s%d%s", "lease", toString(nodeIndex), "amount"], SEP)
122122
123123
124124 func minSwapAmountKEY (swapType) = (("min_" + swapType) + "_swap_amount")
125125
126126
127127 func totalLockedKEY (swapType) = ("balance_lock_" + swapType)
128128
129129
130130 func totalLockedByUserKEY (swapType,owner) = makeString(["balance_lock", swapType, owner], "_")
131131
132132
133133 func balanceLockIntervalKEY (swapType) = (("balance_" + swapType) + "_lock_interval")
134134
135135
136136 func minBalanceLockIntervalKEY (swapType) = (("balance_" + swapType) + "_lock_interval_minimum")
137137
138138
139139 func nodeBalanceLockIntervalKEY () = "balance_node_lock_interval"
140140
141141
142142 func outFeePartKEY (swapType) = (swapType + "Out_swap_feePart")
143143
144144
145145 func keyQuickSwapUserSpentInPeriod (userAddress) = makeString(["%s%s", "quickSwapUserSpentInPeriod", toString(userAddress)], SEP)
146146
147147
148148 func keyUserLastQuickSwapHeight (userAddress) = makeString(["%s%s", "userLastQuickSwapHeight", toString(userAddress)], SEP)
149149
150150
151151 func keyDora2Price (symbol) = makeString(["%s%s", "price", symbol], SEP)
152152
153153
154154 func keyDora2LastHeight (symbol) = makeString(["%s%s", "lastHeight", symbol], SEP)
155155
156156
157157 func minSwapAmountREAD (swapType) = valueOrElse(getInteger(this, minSwapAmountKEY(swapType)), 0)
158158
159159
160160 func totalLockedREAD (swapType) = valueOrElse(getInteger(this, totalLockedKEY(swapType)), 0)
161161
162162
163163 func totalLockedByUserREAD (swapType,owner) = valueOrElse(getInteger(this, totalLockedByUserKEY(swapType, owner)), 0)
164164
165165
166166 func balanceLockIntervalREAD (swapType) = valueOrElse(getInteger(this, balanceLockIntervalKEY(swapType)), maxRand)
167167
168168
169169 func minBalanceLockIntervalREAD (swapType) = valueOrElse(getInteger(this, minBalanceLockIntervalKEY(swapType)), minRand)
170170
171171
172172 func nodeBalanceLockIntervalREAD () = valueOrElse(getInteger(this, nodeBalanceLockIntervalKEY()), 1)
173173
174174
175175 func convertNeutrinoToWaves (amount,price) = fraction(fraction(amount, PRICELET, price), WAVELET, PAULI)
176176
177177
178178 func convertWavesToNeutrino (amount,price) = fraction(fraction(amount, price, PRICELET), PAULI, WAVELET)
179179
180180
181181 func convertWavesToBond (amount,price) = convertWavesToNeutrino(amount, price)
182182
183183
184184 func convertJsonArrayToList (jsonArray) = split(jsonArray, ",")
185185
186186
187187 func minSwapAmountFAIL (swapType,minSwapAmount) = throw(((("The specified amount in " + swapType) + " swap is less than the required minimum of ") + toString(minSwapAmount)))
188188
189189
190190 func emergencyShutdownFAIL () = throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
191191
192192
193193 func priceIndexFAIL (index,priceIndex,indexHeight,unlockHeight,prevIndexHeight) = throw(((((((((("invalid price history index: index=" + toString(index)) + " priceIndex=") + toString(priceIndex)) + " indexHeight=") + toString(indexHeight)) + " unlockHeight=") + toString(unlockHeight)) + " prevIndexHeight=") + toString(prevIndexHeight)))
194194
195195
196196 let liquidationContract = getStringByKey(LiquidationContractKey)
197197
198198 let neutrinoAssetId = fromBase58String(getStringByKey(NeutrinoAssetIdKey))
199199
200200 let auctionContract = getStringByKey(AuctionContractKey)
201201
202202 let rpdContract = getStringByKey(RPDContractKey)
203203
204204 let controlContract = getStringByKey(ControlContractKey)
205205
206206 let priceIndex = getNumberByAddressAndKey(controlContract, PriceIndexKey)
207207
208208 let isBlocked = getBoolByAddressAndKey(controlContract, IsBlockedKey)
209209
210210 let nodeOracleProviderPubKey = fromBase58String(getStringByKey(NodeOracleProviderPubKeyKey))
211211
212212 let bondAssetId = fromBase58String("6nSpVyNH7yM69eg446wrQR94ipbbcmZMU1ENPwanC97g")
213213
214214 let deprecatedBondAssetId = fromBase58String("975akZBfnMj513U7MZaHKzQrmsEx5aE3wdWKTrHBhbjF")
215215
216216 let rsaPub = fromBase64String(valueOrErrorMessage(getString(this, RsaRandPublic58Key), "RSA public key has not been specified"))
217217
218218 let neutrinoContract = this
219219
220220 let currentPrice = getNumberByAddressAndKey(controlContract, PriceKey)
221221
222222 let neutrinoLockedBalance = totalLockedREAD("neutrino")
223223
224224 let wavesLockedBalance = totalLockedREAD("waves")
225225
226226 let reserve = (wavesBalance(neutrinoContract).regular - wavesLockedBalance)
227227
228228 let neutrinoSupply = (((neutrinoLockedBalance + value(assetInfo(neutrinoAssetId)).quantity) - assetBalance(neutrinoContract, neutrinoAssetId)) - assetBalance(addressFromStringValue(liquidationContract), neutrinoAssetId))
229229
230230 let surplus = (convertWavesToNeutrino(reserve, currentPrice) - neutrinoSupply)
231231
232232 let deficit = (neutrinoSupply - convertWavesToNeutrino(reserve, currentPrice))
233233
234234 func checkIsValidMinSponsoredFee (tx) = {
235235 let MINTRANSFERFEE = 100000
236236 let SponsoredFeeUpperBound = 1000
237237 let realNeutrinoFee = convertWavesToNeutrino(MINTRANSFERFEE, currentPrice)
238238 let minNeutrinoFee = (realNeutrinoFee * 2)
239239 let maxNeutrinoFee = fraction(realNeutrinoFee, SponsoredFeeUpperBound, 100)
240240 let inputFee = value(tx.minSponsoredAssetFee)
241241 if (if ((inputFee >= minNeutrinoFee))
242242 then (maxNeutrinoFee >= inputFee)
243243 else false)
244244 then (tx.assetId == neutrinoAssetId)
245245 else false
246246 }
247247
248248
249249 func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block))
250250
251251
252252 func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index))
253253
254254
255255 let sIdxSwapType = 1
256256
257257 let sIdxStatus = 2
258258
259259 let sIdxInAmount = 3
260260
261261 let sIdxPrice = 4
262262
263263 let sIdxOutNetAmount = 5
264264
265265 let sIdxOutFeeAmount = 6
266266
267267 let sIdxStartHeight = 7
268268
269269 let sIdxStartTimestamp = 8
270270
271271 let sIdxEndHeight = 9
272272
273273 let sIdxEndTimestamp = 10
274274
275275 let sIdxSelfUnlockHeight = 11
276276
277277 let sIdxRandUnlockHeight = 12
278278
279279 let sIdxIndex = 13
280280
281281 let sIdxWithdrawTxId = 14
282282
283283 let sIdxMinRand = 15
284284
285285 let sIdxMaxRand = 16
286286
287+let sIdxIsQuick = 17
288+
287289 func swapKEY (userAddress,txId) = makeString(["%s%s", userAddress, txId], SEP)
288290
289291
290-func strSwapDATA (swapType,status,inAmount,price,outNetAmount,outFeeAmount,startHeight,startTimestamp,endHeight,endTimestamp,selfUnlockHeight,randUnlockHeight,index,withdrawTxId,randMin,randMax) = makeString(["%s%s%d%d%d%d%d%d%d%d%d%d%d%s", swapType, status, inAmount, price, outNetAmount, outFeeAmount, startHeight, startTimestamp, endHeight, endTimestamp, selfUnlockHeight, randUnlockHeight, index, withdrawTxId, randMin, randMax], SEP)
292+func strSwapDATA (swapType,status,inAmount,price,outNetAmount,outFeeAmount,startHeight,startTimestamp,endHeight,endTimestamp,selfUnlockHeight,randUnlockHeight,index,withdrawTxId,randMin,randMax,isQuick) = makeString(["%s%s%d%d%d%d%d%d%d%d%d%d%d%s", swapType, status, inAmount, price, outNetAmount, outFeeAmount, startHeight, startTimestamp, endHeight, endTimestamp, selfUnlockHeight, randUnlockHeight, index, withdrawTxId, randMin, randMax, isQuick], SEP)
291293
292294
293-func pendingSwapDATA (swapType,inAssetAmount,selfUnlockHeight) = strSwapDATA(swapType, "PENDING", toString(inAssetAmount), "0", "0", "0", toString(height), toString(lastBlock.timestamp), "0", "0", toString(selfUnlockHeight), "0", "0", "NULL", toString(minBalanceLockIntervalREAD(swapType)), toString(balanceLockIntervalREAD(swapType)))
295+func pendingSwapDATA (swapType,inAssetAmount,selfUnlockHeight) = strSwapDATA(swapType, "PENDING", toString(inAssetAmount), "0", "0", "0", toString(height), toString(lastBlock.timestamp), "0", "0", toString(selfUnlockHeight), "0", "0", "NULL", toString(minBalanceLockIntervalREAD(swapType)), toString(balanceLockIntervalREAD(swapType)), toString(false))
294296
295297
296-func finishSwapDATA (dataArray,price,outNetAmount,outFeeAmount,randUnlockHeight,index,withdrawTxId) = strSwapDATA(dataArray[sIdxSwapType], "FINISHED", dataArray[sIdxInAmount], toString(price), toString(outNetAmount), toString(outFeeAmount), dataArray[sIdxStartHeight], dataArray[sIdxStartTimestamp], toString(height), toString(lastBlock.timestamp), dataArray[sIdxSelfUnlockHeight], toString(randUnlockHeight), toString(index), withdrawTxId, if ((15 >= size(dataArray)))
297- then toString(minRand)
298- else dataArray[sIdxMinRand], if ((15 >= size(dataArray)))
299- then toString(maxRand)
300- else dataArray[sIdxMaxRand])
298+func accelerateSwapDATA (dataArray) = strSwapDATA(dataArray[sIdxSwapType], dataArray[sIdxStatus], dataArray[sIdxInAmount], dataArray[sIdxPrice], dataArray[sIdxOutNetAmount], dataArray[sIdxOutFeeAmount], dataArray[sIdxStartHeight], dataArray[sIdxStartTimestamp], dataArray[sIdxEndHeight], dataArray[sIdxEndTimestamp], dataArray[sIdxSelfUnlockHeight], dataArray[sIdxRandUnlockHeight], dataArray[sIdxIndex], dataArray[sIdxWithdrawTxId], dataArray[sIdxMinRand], dataArray[sIdxMaxRand], toString(true))
299+
300+
301+func finishSwapDATA (dataArray,price,outNetAmount,outFeeAmount,randUnlockHeight,index,withdrawTxId) = strSwapDATA(dataArray[sIdxSwapType], "FINISHED", dataArray[sIdxInAmount], toString(price), toString(outNetAmount), toString(outFeeAmount), dataArray[sIdxStartHeight], dataArray[sIdxStartTimestamp], toString(height), toString(lastBlock.timestamp), dataArray[sIdxSelfUnlockHeight], toString(randUnlockHeight), toString(index), withdrawTxId, dataArray[sIdxMinRand], dataArray[sIdxMaxRand], dataArray[sIdxIsQuick])
301302
302303
303304 func swapDataFailOrREAD (userAddress,swapTxId) = {
304305 let swapKey = swapKEY(userAddress, swapTxId)
305306 split(valueOrErrorMessage(getString(this, swapKey), ("no swap data for " + swapKey)), SEP)
306307 }
307308
308309
309310 func applyFees (amountGross,feePart) = {
310311 let feeAmount = fraction(amountGross, feePart, PAULI)
311312 [(amountGross - feeAmount), feeAmount, amountGross]
312313 }
313314
314315
315316 func randUnlockHeightOrFail (txId,rsaSig,swapType,startHeight,minMaxRandsTuple) = {
316317 let isRsaValid = rsaVerify_16Kb(SHA256, toBytes(txId), rsaSig, rsaPub)
317318 if (!(isRsaValid))
318319 then throw("invalid RSA signature")
319320 else {
320321 let minBalanceLockInterval = minMaxRandsTuple._1
321322 let maxBalanceLockInterval = minMaxRandsTuple._2
322323 let rand = (toInt(sha256_16Kb(rsaSig)) % (maxBalanceLockInterval - minBalanceLockInterval))
323324 let randLockInterval = (minBalanceLockInterval + (if ((0 > rand))
324325 then -(rand)
325326 else rand))
326327 (startHeight + randLockInterval)
327328 }
328329 }
329330
330331
331332 func abs (x) = if ((0 > x))
332333 then -(x)
333334 else x
334335
335336
336337 func selectNode (unleaseAmount) = {
337338 let amountToLease = ((wavesBalance(neutrinoContract).available - unleaseAmount) - getReservedAmountForSponsorship())
338339 let oldLeased0 = getNumberByKey(getLeaseAmountKey(0))
339340 let oldLeased1 = getNumberByKey(getLeaseAmountKey(1))
340341 let newLeased0 = (amountToLease + oldLeased0)
341342 let newLeased1 = (amountToLease + oldLeased1)
342343 if (if ((newLeased0 > 0))
343344 then true
344345 else (newLeased1 > 0))
345346 then {
346347 let delta0 = abs((newLeased0 - oldLeased1))
347348 let delta1 = abs((newLeased1 - oldLeased0))
348349 if ((delta1 >= delta0))
349350 then $Tuple2(0, newLeased0)
350351 else $Tuple2(1, newLeased1)
351352 }
352353 else $Tuple2(-1, 0)
353354 }
354355
355356
356357 func prepareUnleaseAndLease (unleaseAmount) = {
357- let $t01536515453 = selectNode(unleaseAmount)
358- let nodeIndex = $t01536515453._1
359- let newLeaseAmount = $t01536515453._2
358+ let $t01621216300 = selectNode(unleaseAmount)
359+ let nodeIndex = $t01621216300._1
360+ let newLeaseAmount = $t01621216300._2
360361 if ((newLeaseAmount > 0))
361362 then {
362363 let leaseIdKey = getLeaseIdKey(nodeIndex)
363364 let oldLease = getBinary(this, leaseIdKey)
364365 let unleaseOrEmpty = if (isDefined(oldLease))
365366 then [LeaseCancel(value(oldLease))]
366367 else nil
367368 let leaseAmountKey = getLeaseAmountKey(nodeIndex)
368369 let lease = Lease(getStakingNodeAddressByIndex(nodeIndex), newLeaseAmount)
369370 (unleaseOrEmpty ++ [lease, BinaryEntry(leaseIdKey, calculateLeaseId(lease)), IntegerEntry(getLeaseAmountKey(nodeIndex), newLeaseAmount)])
370371 }
371372 else nil
372373 }
373374
374375
375376 func getDora2NSBTInfo () = {
376377 let dora2Contract = addressFromStringValue(getStringValue(this, keyDora2Contract))
377- let price = valueOrErrorMessage(getInteger(dora2Contract, keyDora2Price(dora2NsbtSymbol)), "NSBT price is undefined")
378- let lastHeight = valueOrElse(getInteger(dora2Contract, keyDora2LastHeight(dora2NsbtSymbol)), 0)
379- $Tuple2(price, lastHeight)
380- }
381-
382-
383-func getNSBTPrice () = {
384- let $t01641116455 = getDora2NSBTInfo()
385- let price = $t01641116455._1
386- let lastHeight = $t01641116455._2
387- price
388- }
389-
390-
391-func commonSwap (swapType,i) = {
392- let pmt = value(i.payments[0])
393- let account = toString(i.caller)
394- let txId58 = toBase58String(i.transactionId)
395- let minSwapAmount = minSwapAmountREAD(swapType)
396- let totalLocked = totalLockedREAD(swapType)
397- let totalLockedByUser = totalLockedByUserREAD(swapType, account)
398- let nodeAddress = getStakingNodeByIndex(0)
399- let balanceLockMaxInterval = if ((nodeAddress == account))
400- then nodeBalanceLockIntervalREAD()
401- else balanceLockIntervalREAD(swapType)
402- let selfUnlockHeight = (height + balanceLockMaxInterval)
403- if ((minSwapAmount > pmt.amount))
404- then minSwapAmountFAIL(swapType, minSwapAmount)
405- else if (isBlocked)
406- then emergencyShutdownFAIL()
407- else {
408- let leasePart = if ((swapType == "waves"))
409- then prepareUnleaseAndLease(0)
410- else nil
411- $Tuple2(([IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser + pmt.amount)), IntegerEntry(getBalanceUnlockBlockKey(account), selfUnlockHeight), IntegerEntry(totalLockedKEY(swapType), (totalLocked + pmt.amount)), StringEntry(swapKEY(account, txId58), pendingSwapDATA(swapType, pmt.amount, selfUnlockHeight))] ++ leasePart), unit)
412- }
378+ $Tuple2(valueOrErrorMessage(getInteger(dora2Contract, keyDora2Price(dora2NsbtSymbol)), "NSBT price is undefined"), valueOrElse(getInteger(dora2Contract, keyDora2LastHeight(dora2NsbtSymbol)), 0))
413379 }
414380
415381
416382 func thisOnly (i) = if ((i.caller != this))
417383 then throw("Permission denied: this contract only allowed")
418384 else true
419385
420386
421387 @Callable(i)
422388 func prepareUnleaseAndLeaseWrapper (unleaseAmount) = {
423389 let checkCaller = [thisOnly(i)]
424390 if ((checkCaller == checkCaller))
425391 then prepareUnleaseAndLease(unleaseAmount)
426392 else throw("Strict value is not equal to itself.")
427393 }
428394
429395
430396
431397 @Callable(i)
432398 func constructor (neutrinoAssetIdPrm,bondAssetIdPrm,auctionContractPrm,liquidationContractPrm,rpdContractPrm,controlContractPrm,nodeOracleProviderPubKeyPrm,rsaRandPublicKeyPrm,balanceWavesLockIntervalPrm,balanceNeutrinoLockIntervalPrm,minWavesSwapAmountPrm,minNeutrinoSwapAmountPrm,neutrinoOutFeePartPrm,wavesOutFeePartPrm) = {
433399 let checkCaller = thisOnly(i)
434400 if ((checkCaller == checkCaller))
435401 then [StringEntry(NeutrinoAssetIdKey, neutrinoAssetIdPrm), StringEntry(BondAssetIdKey, bondAssetIdPrm), StringEntry(AuctionContractKey, auctionContractPrm), StringEntry(LiquidationContractKey, liquidationContractPrm), StringEntry(RPDContractKey, rpdContractPrm), StringEntry(ControlContractKey, controlContractPrm), StringEntry(NodeOracleProviderPubKeyKey, nodeOracleProviderPubKeyPrm), StringEntry(RsaRandPublic58Key, rsaRandPublicKeyPrm), IntegerEntry(BalanceWavesLockIntervalKey, balanceWavesLockIntervalPrm), IntegerEntry(BalanceNeutrinoLockIntervalKey, balanceNeutrinoLockIntervalPrm), IntegerEntry(MinWavesSwapAmountKey, minWavesSwapAmountPrm), IntegerEntry(MinNeutrinoSwapAmountKey, minNeutrinoSwapAmountPrm), IntegerEntry(NeutrinoOutFeePartKey, neutrinoOutFeePartPrm), IntegerEntry(WavesOutFeePartKey, wavesOutFeePartPrm)]
436402 else throw("Strict value is not equal to itself.")
437403 }
438404
439405
440406
441407 @Callable(i)
442408 func constructorV2 (gNsbtContract,nsbtLockContract,dora2Contract,quickSwapDelay,quickSwapLimitDuration,dora2LastHeightLimit) = {
443409 let checkCaller = thisOnly(i)
444410 if ((checkCaller == checkCaller))
445411 then [StringEntry(keyGNsbtContract, gNsbtContract), StringEntry(keyNsbtLockContract, nsbtLockContract), StringEntry(keyDora2Contract, dora2Contract), IntegerEntry(keyQuickSwapDelay, quickSwapDelay), IntegerEntry(keyQuickSwapLimitDuration, quickSwapLimitDuration), IntegerEntry(keyDora2LastHeightLimit, dora2LastHeightLimit)]
446412 else throw("Strict value is not equal to itself.")
447413 }
448414
449415
450416
451417 @Callable(i)
452-func commonWithdraw (account,index,swapTxId,rsaSig,isQuick) = {
418+func commonSwap (swapType,amount,account,txId) = {
419+ let checkCaller = thisOnly(i)
420+ if ((checkCaller == checkCaller))
421+ then {
422+ let minSwapAmount = minSwapAmountREAD(swapType)
423+ let totalLocked = totalLockedREAD(swapType)
424+ let totalLockedByUser = totalLockedByUserREAD(swapType, account)
425+ let nodeAddress = getStakingNodeByIndex(0)
426+ let balanceLockMaxInterval = if ((nodeAddress == account))
427+ then nodeBalanceLockIntervalREAD()
428+ else balanceLockIntervalREAD(swapType)
429+ let selfUnlockHeight = (height + balanceLockMaxInterval)
430+ if ((minSwapAmount > amount))
431+ then minSwapAmountFAIL(swapType, minSwapAmount)
432+ else if (isBlocked)
433+ then emergencyShutdownFAIL()
434+ else {
435+ let leasePart = if ((swapType == "waves"))
436+ then prepareUnleaseAndLease(0)
437+ else nil
438+ ([IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser + amount)), IntegerEntry(getBalanceUnlockBlockKey(account), selfUnlockHeight), IntegerEntry(totalLockedKEY(swapType), (totalLocked + amount)), StringEntry(swapKEY(account, txId), pendingSwapDATA(swapType, amount, selfUnlockHeight))] ++ leasePart)
439+ }
440+ }
441+ else throw("Strict value is not equal to itself.")
442+ }
443+
444+
445+
446+@Callable(i)
447+func commonWithdraw (account,index,swapTxId,rsaSig) = {
453448 let userAddress = addressFromStringValue(account)
454- let checkCaller = [thisOnly(i), if (if (isQuick)
455- then (i.originCaller != userAddress)
456- else false)
457- then throw(((("Permission denied: originCaller=" + toString(i.originCaller)) + ", account=") + account))
458- else true]
449+ let checkCaller = thisOnly(i)
459450 if ((checkCaller == checkCaller))
460451 then {
461452 let dataArray = swapDataFailOrREAD(account, swapTxId)
462453 let selfUnlockHeight = parseIntValue(dataArray[sIdxSelfUnlockHeight])
463454 let swapType = dataArray[sIdxSwapType]
464455 let inAmount = parseIntValue(dataArray[sIdxInAmount])
465456 let swapStatus = dataArray[sIdxStatus]
466457 let startHeight = parseIntValue(dataArray[sIdxStartHeight])
458+ let isQuick = (dataArray[sIdxIsQuick] == "true")
467459 let checkSwapType = if (if ((swapType != "waves"))
468460 then (swapType != "neutrino")
469461 else false)
470462 then throw(("Unsupported swap type " + swapType))
471463 else true
472464 if ((checkSwapType == checkSwapType))
473465 then {
474466 let outFeePart = valueOrElse(getInteger(this, outFeePartKEY(swapType)), DEFAULTSWAPFEE)
475467 let totalLocked = totalLockedREAD(swapType)
476468 let totalLockedByUser = totalLockedByUserREAD(swapType, account)
477- let minMaxRandsTuple = if ((15 >= size(dataArray)))
478- then $Tuple2(minRand, maxRand)
479- else $Tuple2(parseIntValue(dataArray[sIdxMinRand]), parseIntValue(dataArray[sIdxMaxRand]))
480469 let unlockHeight = if (isQuick)
481- then {
482- let quickSwapDelay = getIntegerValue(this, keyQuickSwapDelay)
483- (startHeight + quickSwapDelay)
484- }
470+ then (startHeight + getIntegerValue(this, keyQuickSwapDelay))
485471 else if ((rsaSig == base58''))
486472 then selfUnlockHeight
487- else randUnlockHeightOrFail(swapTxId, rsaSig, swapType, startHeight, minMaxRandsTuple)
473+ else randUnlockHeightOrFail(swapTxId, rsaSig, swapType, startHeight, $Tuple2(parseIntValue(dataArray[sIdxMinRand]), parseIntValue(dataArray[sIdxMaxRand])))
488474 let indexHeight = getHeightPriceByIndex(index)
489475 let prevIndexHeight = getHeightPriceByIndex((index - 1))
490476 let priceByIndex = getPriceHistory(indexHeight)
491- let $t02196622162 = if ((swapType == "waves"))
477+ let $t02234322539 = if ((swapType == "waves"))
492478 then $Tuple2(convertWavesToNeutrino(inAmount, priceByIndex), neutrinoAssetId)
493479 else $Tuple2(convertNeutrinoToWaves(inAmount, priceByIndex), unit)
494- let outAmountGross = $t02196622162._1
495- let outAsset = $t02196622162._2
480+ let outAmountGross = $t02234322539._1
481+ let outAsset = $t02234322539._2
496482 let payoutsArray = applyFees(outAmountGross, outFeePart)
497483 let outNetAmount = payoutsArray[IdxNetAmount]
498484 let outFeeAmount = payoutsArray[IdxFeeAmount]
499- let quickSwapLimitDuration = getIntegerValue(this, keyQuickSwapLimitDuration)
500- let quickSwapUserSpentInPeriod = valueOrElse(getInteger(this, keyQuickSwapUserSpentInPeriod(userAddress)), 0)
501- let userLastQuickSwapHeight = valueOrElse(getInteger(this, keyUserLastQuickSwapHeight(userAddress)), 0)
502- let nsbtLockContract = addressFromStringValue(getStringValue(this, keyNsbtLockContract))
503- let userGNsbtAmountResult = invoke(nsbtLockContract, "gNsbtAmountREADONLY", [toString(userAddress)], nil)
504- if ((userGNsbtAmountResult == userGNsbtAmountResult))
485+ let checks = [if (isBlocked)
486+ then emergencyShutdownFAIL()
487+ else true, if ((swapStatus != "PENDING"))
488+ then throw("swap has been already processed")
489+ else true, if ((unlockHeight > height))
490+ then throw((("please wait for: " + toString(unlockHeight)) + " block height to withdraw funds"))
491+ else true, if (if (if ((index > priceIndex))
492+ then true
493+ else (unlockHeight > indexHeight))
494+ then true
495+ else if ((prevIndexHeight != 0))
496+ then (prevIndexHeight >= unlockHeight)
497+ else false)
498+ then priceIndexFAIL(index, priceIndex, indexHeight, unlockHeight, prevIndexHeight)
499+ else true, if ((0 >= payoutsArray[IdxGrossAmount]))
500+ then throw("balance equals zero")
501+ else true, if (if ((0 > outFeePart))
502+ then true
503+ else (outFeePart >= PAULI))
504+ then throw(((("invalid outFeePart config for " + swapType) + " swap: outFeePart=") + toString(outFeePart)))
505+ else true]
506+ if ((checks == checks))
505507 then {
506- let userGNsbtAmount = asInt(userGNsbtAmountResult)
507- let $t02287422931 = getDora2NSBTInfo()
508- let nsbtPrice = $t02287422931._1
509- let nsbtPriceLastHeight = $t02287422931._2
510- let lastHeightLimit = getIntegerValue(this, keyDora2LastHeightLimit)
511- let isNewQuickSwapPeriod = ((height - userLastQuickSwapHeight) > quickSwapLimitDuration)
512- let quickSwapUserSpent = if (isNewQuickSwapPeriod)
513- then 0
514- else quickSwapUserSpentInPeriod
515- let quickSwapLimitTotal = fraction(userGNsbtAmount, nsbtPrice, WAVELET)
516- let quickSwapLimit = (quickSwapLimitTotal - quickSwapUserSpent)
517- let swapUsdnVolume = if ((swapType == "neutrino"))
518- then inAmount
519- else outAmountGross
520- let checks = [if (if (isQuick)
521- then ((height - nsbtPriceLastHeight) > lastHeightLimit)
508+ let leasePart = if (if ((swapType == "neutrino"))
509+ then (outAmountGross > 0)
522510 else false)
523- then throw("NSBT price is outdated")
524- else true, if (if (isQuick)
525- then (swapUsdnVolume > quickSwapLimit)
526- else false)
527- then throw(((("You have exceeded the quick swaps limit: limit=" + toString(quickSwapLimit)) + ", attemptedAmount=") + toString(swapUsdnVolume)))
528- else true, if (isBlocked)
529- then emergencyShutdownFAIL()
530- else true, if ((swapStatus != "PENDING"))
531- then throw("swap has been already processed")
532- else true, if ((unlockHeight > height))
533- then throw((("please wait for: " + toString(unlockHeight)) + " block height to withdraw funds"))
534- else true, if (if (if ((index > priceIndex))
535- then true
536- else (unlockHeight > indexHeight))
537- then true
538- else if ((prevIndexHeight != 0))
539- then (prevIndexHeight >= unlockHeight)
540- else false)
541- then priceIndexFAIL(index, priceIndex, indexHeight, unlockHeight, prevIndexHeight)
542- else true, if ((0 >= payoutsArray[IdxGrossAmount]))
543- then throw("balance equals zero")
544- else true, if (if ((0 > outFeePart))
545- then true
546- else (outFeePart >= PAULI))
547- then throw(((("invalid outFeePart config for " + swapType) + " swap: outFeePart=") + toString(outFeePart)))
548- else true]
549- if ((checks == checks))
511+ then invoke(this, "prepareUnleaseAndLeaseWrapper", [outAmountGross], nil)
512+ else unit
513+ if ((leasePart == leasePart))
550514 then {
551- let leasePart = if (if ((swapType == "neutrino"))
552- then (outAmountGross > 0)
553- else false)
554- then invoke(this, "prepareUnleaseAndLeaseWrapper", [outAmountGross], nil)
555- else unit
556- if ((leasePart == leasePart))
557- then {
558- let gNsbtContract = addressFromStringValue(getStringValue(this, keyGNsbtContract))
559- let sendFee = invoke(gNsbtContract, "deposit", nil, [AttachedPayment(outAsset, outFeeAmount)])
560- if ((sendFee == sendFee))
561- then {
562- let quickSwapPart = if (isQuick)
563- then [IntegerEntry(keyQuickSwapUserSpentInPeriod(userAddress), (swapUsdnVolume + quickSwapUserSpent)), IntegerEntry(keyUserLastQuickSwapHeight(userAddress), height)]
564- else nil
565- (quickSwapPart ++ [IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser - inAmount)), IntegerEntry(totalLockedKEY(swapType), (totalLocked - inAmount)), ScriptTransfer(userAddress, outNetAmount, outAsset), StringEntry(swapKEY(account, swapTxId), finishSwapDATA(dataArray, priceByIndex, outNetAmount, outFeeAmount, unlockHeight, index, toBase58String(i.transactionId)))])
566- }
567- else throw("Strict value is not equal to itself.")
568- }
515+ let sendFee = invoke(addressFromStringValue(getStringValue(this, keyGNsbtContract)), "deposit", nil, [AttachedPayment(outAsset, outFeeAmount)])
516+ if ((sendFee == sendFee))
517+ then [IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser - inAmount)), IntegerEntry(totalLockedKEY(swapType), (totalLocked - inAmount)), ScriptTransfer(userAddress, outNetAmount, outAsset), StringEntry(swapKEY(account, swapTxId), finishSwapDATA(dataArray, priceByIndex, outNetAmount, outFeeAmount, unlockHeight, index, toBase58String(i.transactionId)))]
569518 else throw("Strict value is not equal to itself.")
570519 }
571520 else throw("Strict value is not equal to itself.")
572521 }
573522 else throw("Strict value is not equal to itself.")
574523 }
575524 else throw("Strict value is not equal to itself.")
576525 }
577526 else throw("Strict value is not equal to itself.")
578527 }
579528
580529
581530
582531 @Callable(i)
583-func swapWavesToNeutrino () = {
532+func swap (swapType,accelerate) = {
533+ let wavesToNeutrino = (swapType == "waves")
534+ let neutrinoToWaves = (swapType == "neutrino")
584535 let pmt = value(i.payments[0])
585- if (isDefined(pmt.assetId))
536+ let account = toString(i.caller)
537+ let swapTxId = toBase58String(i.transactionId)
538+ if (if (wavesToNeutrino)
539+ then (pmt.assetId != unit)
540+ else false)
586541 then throw("Only Waves token is allowed for swapping.")
587- else commonSwap("waves", i)
542+ else if (if (neutrinoToWaves)
543+ then (pmt.assetId != neutrinoAssetId)
544+ else false)
545+ then throw("Only appropriate Neutrino tokens are allowed for swapping.")
546+ else if (if (!(wavesToNeutrino))
547+ then !(neutrinoToWaves)
548+ else false)
549+ then throw("Invalid swap type")
550+ else {
551+ let commonSwapInv = invoke(this, "commonSwap", [swapType, pmt.amount, account, swapTxId], nil)
552+ if ((commonSwapInv == commonSwapInv))
553+ then {
554+ let accelerateInv = if (accelerate)
555+ then invoke(this, "accelerate", [account, swapTxId], nil)
556+ else true
557+ if ((accelerateInv == accelerateInv))
558+ then nil
559+ else throw("Strict value is not equal to itself.")
560+ }
561+ else throw("Strict value is not equal to itself.")
562+ }
588563 }
589564
590565
591566
592567 @Callable(i)
593-func swapNeutrinoToWaves () = {
594- let pmt = value(i.payments[0])
595- if ((pmt.assetId != neutrinoAssetId))
596- then throw("Only appropriate Neutrino tokens are allowed for swapping.")
597- else commonSwap("neutrino", i)
568+func accelerate (account,swapTxId) = {
569+ let userAddress = addressFromStringValue(account)
570+ let checkCaller = if ((i.originCaller != userAddress))
571+ then throw("Permission denied")
572+ else true
573+ if ((checkCaller == checkCaller))
574+ then {
575+ let dataArray = swapDataFailOrREAD(account, swapTxId)
576+ let swapType = dataArray[sIdxSwapType]
577+ let inAmount = parseIntValue(dataArray[sIdxInAmount])
578+ let swapStatus = dataArray[sIdxStatus]
579+ let isQuick = (dataArray[sIdxIsQuick] == "true")
580+ let $t02550725715 = match invoke(this, "quickSwapLimitREADONLY", [toString(userAddress)], nil) {
581+ case r: (Int, Int) =>
582+ $Tuple2(r._1, r._2)
583+ case _ =>
584+ throw("Type casting error")
585+ }
586+ let quickSwapLimitTotal = $t02550725715._1
587+ let quickSwapUserSpent = $t02550725715._2
588+ let quickSwapLimit = (quickSwapLimitTotal - quickSwapUserSpent)
589+ let priceByIndex = getPriceHistory(getHeightPriceByIndex(priceIndex))
590+ let swapUsdnVolume = if ((swapType == "neutrino"))
591+ then inAmount
592+ else convertWavesToNeutrino(inAmount, priceByIndex)
593+ let checks = [if ((swapStatus != "PENDING"))
594+ then throw("Swap has been already processed")
595+ else true, if (isQuick)
596+ then throw("Swap has been already accelerated")
597+ else true, if ((swapUsdnVolume > quickSwapLimit))
598+ then throw(((("You have exceeded the quick swaps limit! Requested: " + toString(swapUsdnVolume)) + ", available: ") + toString(quickSwapLimit)))
599+ else true]
600+ if ((checks == checks))
601+ then [IntegerEntry(keyQuickSwapUserSpentInPeriod(userAddress), (swapUsdnVolume + quickSwapUserSpent)), IntegerEntry(keyUserLastQuickSwapHeight(userAddress), height), StringEntry(swapKEY(account, swapTxId), accelerateSwapDATA(dataArray))]
602+ else throw("Strict value is not equal to itself.")
603+ }
604+ else throw("Strict value is not equal to itself.")
598605 }
599606
600607
601608
602609 @Callable(i)
603610 func withdraw (account,index,swapTxId) = {
604- let result = invoke(this, "commonWithdraw", [account, index, swapTxId, base58'', false], nil)
605- if ((result == result))
606- then nil
607- else throw("Strict value is not equal to itself.")
608- }
609-
610-
611-
612-@Callable(i)
613-func withdrawV2 (account,index,swapTxId,isQuick) = {
614- let result = invoke(this, "commonWithdraw", [account, index, swapTxId, base58'', isQuick], nil)
611+ let result = invoke(this, "commonWithdraw", [account, index, swapTxId, base58''], nil)
615612 if ((result == result))
616613 then nil
617614 else throw("Strict value is not equal to itself.")
618615 }
619616
620617
621618
622619 @Callable(i)
623620 func withdrawRand (account,index,swapTxId,rsaSig) = {
624- let result = invoke(this, "commonWithdraw", [account, index, swapTxId, rsaSig, false], nil)
621+ let result = invoke(this, "commonWithdraw", [account, index, swapTxId, rsaSig], nil)
625622 if ((result == result))
626623 then nil
627624 else throw("Strict value is not equal to itself.")
628625 }
629626
630627
631628
632629 @Callable(i)
633630 func transferToAuction () = {
634631 let auctionNBAmount = (neutrinoSupply - assetBalance(addressFromStringValue(auctionContract), bondAssetId))
635632 let surplusWithLiquidation = (surplus - assetBalance(addressFromStringValue(liquidationContract), neutrinoAssetId))
636633 if (isBlocked)
637634 then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
638635 else if ((auctionNBAmount > (1 * PAULI)))
639636 then [ScriptTransfer(addressFromStringValue(auctionContract), auctionNBAmount, bondAssetId)]
640637 else if ((surplusWithLiquidation >= (1 * PAULI)))
641638 then [ScriptTransfer(addressFromStringValue(liquidationContract), surplusWithLiquidation, neutrinoAssetId)]
642639 else throw(((((((("bond were generated or do not need it. Deficit:" + toString(auctionNBAmount)) + "|") + toString(0)) + ". Surplus:") + toString(surplusWithLiquidation)) + "|") + toString(surplus)))
643640 }
644641
645642
646643
647644 @Callable(i)
648645 func acceptWaves () = if ((i.caller != addressFromStringValue(auctionContract)))
649646 then throw("Currently only auction contract is allowed to call")
650647 else $Tuple2(prepareUnleaseAndLease(0), "success")
651648
652649
653650
654651 @Callable(i)
655-func quickSwapLimitREADONLY (gNsbtAmount) = $Tuple2(nil, (gNsbtAmount * getNSBTPrice()))
652+func calcTotalQuickSwapLimitREADONLY (gNsbtAmount) = {
653+ let $t02876628823 = getDora2NSBTInfo()
654+ let nsbtPrice = $t02876628823._1
655+ let nsbtPriceLastHeight = $t02876628823._2
656+ let check = if (((height - nsbtPriceLastHeight) > getIntegerValue(this, keyDora2LastHeightLimit)))
657+ then throw("NSBT price is outdated")
658+ else true
659+ if ((check == check))
660+ then $Tuple2(nil, fraction(gNsbtAmount, nsbtPrice, WAVELET))
661+ else throw("Strict value is not equal to itself.")
662+ }
663+
664+
665+
666+@Callable(i)
667+func quickSwapLimitREADONLY (userAddressStr) = {
668+ let userAddress = addressFromStringValue(userAddressStr)
669+ let userGNsbtAmount = asInt(invoke(addressFromStringValue(getStringValue(this, keyNsbtLockContract)), "gNsbtAmountREADONLY", [toString(userAddress)], nil))
670+ if ((userGNsbtAmount == userGNsbtAmount))
671+ then {
672+ let quickSwapLimitTotal = asInt(invoke(this, "calcTotalQuickSwapLimitREADONLY", [userGNsbtAmount], nil))
673+ if ((quickSwapLimitTotal == quickSwapLimitTotal))
674+ then {
675+ let isNewQuickSwapPeriod = ((height - valueOrElse(getInteger(this, keyUserLastQuickSwapHeight(userAddress)), 0)) > getIntegerValue(this, keyQuickSwapLimitDuration))
676+ let quickSwapUserSpent = if (isNewQuickSwapPeriod)
677+ then 0
678+ else valueOrElse(getInteger(this, keyQuickSwapUserSpentInPeriod(userAddress)), 0)
679+ $Tuple2(nil, $Tuple2(quickSwapLimitTotal, quickSwapUserSpent))
680+ }
681+ else throw("Strict value is not equal to itself.")
682+ }
683+ else throw("Strict value is not equal to itself.")
684+ }
656685
657686

github/deemru/w8io/873ac7e 
107.99 ms