tx · DwXLyBUqWarwgdGPFXsMRLLJvcUHvHCpnjtchnsRwnFF 3N6GEPCmNrarvmc77xK4TrstR1Bbcsxzt1X: -0.01000000 Waves 2022.01.19 14:51 [1885777] smart account 3N6GEPCmNrarvmc77xK4TrstR1Bbcsxzt1X > SELF 0.00000000 Waves
{ "type": 13, "id": "DwXLyBUqWarwgdGPFXsMRLLJvcUHvHCpnjtchnsRwnFF", "fee": 1000000, "feeAssetId": null, "timestamp": 1642593135577, "version": 2, "chainId": 84, "sender": "3N6GEPCmNrarvmc77xK4TrstR1Bbcsxzt1X", "senderPublicKey": "oJCUpcyP6uu1UA2wzroa6zrswNDU1SopgrXWXM56RsX", "proofs": [ "2ii1aHjZsGAge8cHrX9ZB1f2Z9uDyPNbTA5zhQHohMLEDxLK1xt6UsPEBtVEEqyfmYRX2L76uYokRRACPzYi8LjJ" ], "script": "base64:AAIFAAAAAAAAAGAIAhIDCgEBEhAKDggICAgICAgIAQEBAQEBEggKBggICAEBARIGCgQIAQgIEgYKBAgBCAISABIAEgQKAggEEgQKAggIEgUKAwgBCBIGCgQIAQgCEgASABIDCgEBEgMKAQgAAAB/AQAAAA5nZXROdW1iZXJCeUtleQAAAAEAAAADa2V5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAA2tleQAAAAAAAAAAAAEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABAAAAA2tleQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACBQAAAAR0aGlzBQAAAANrZXkCAAAAAAEAAAAMZ2V0Qm9vbEJ5S2V5AAAAAQAAAANrZXkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQbAAAAAgUAAAAEdGhpcwUAAAADa2V5BwEAAAAYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AAAAAgAAAAdhZGRyZXNzAAAAA2tleQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAAAdhZGRyZXNzBQAAAANrZXkAAAAAAAAAAAABAAAAGGdldFN0cmluZ0J5QWRkcmVzc0FuZEtleQAAAAIAAAAHYWRkcmVzcwAAAANrZXkJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAAHYWRkcmVzcwUAAAADa2V5AgAAAAABAAAAFmdldEJvb2xCeUFkZHJlc3NBbmRLZXkAAAACAAAAB2FkZHJlc3MAAAADa2V5CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGwAAAAIJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAAB2FkZHJlc3MFAAAAA2tleQcAAAAAEHB1YktleUFkbWluc0xpc3QJAARMAAAAAgIAAAAsR0pkTFNhTGl2NUs3eHVlamFjOG1jUmNIb3lvM2RQckVTcnZrdEczYTZNQVIJAARMAAAAAgIAAAAsRldWZmZZcjJBTG1ITWVqWm0zV3FlTHo2U2R5bTNnTEZHdEpuNEtUd3lVNXgJAARMAAAAAgIAAAAsM1doMkxhV2NiNWdnN0sycFBjVzNFcDZFQXVSQnpZa0FncmRwdDQzalRERmEJAARMAAAAAgIAAAAsNVdSWEZTandjVGJOZktjSnM4WnFYbVNTV1lzU1ZKVXRNdk1xWmo1aEg0TmMFAAAAA25pbAEAAAAFYXNJbnQAAAABAAAAA3ZhbAQAAAAHJG1hdGNoMAUAAAADdmFsAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAANJbnQEAAAABnZhbEludAUAAAAHJG1hdGNoMAUAAAAGdmFsSW50CQAAAgAAAAECAAAAF0ZhaWxlZCB0byBjYXN0IGludG8gSW50AAAAAANTRVACAAAAAl9fAAAAAAdXQVZFTEVUAAAAAAAF9eEAAAAAAAVQQVVMSQAAAAAAAA9CQAAAAAAIUFJJQ0VMRVQAAAAAAAAPQkAAAAAADkRFRkFVTFRTV0FQRkVFAAAAAAAAAE4gAAAAAAxJZHhOZXRBbW91bnQAAAAAAAAAAAAAAAAADElkeEZlZUFtb3VudAAAAAAAAAAAAQAAAAAOSWR4R3Jvc3NBbW91bnQAAAAAAAAAAAIAAAAAD2RvcmEyTnNidFN5bWJvbAIAAAAJTlNCVC1VU0RUAAAAAAdtaW5SYW5kAAAAAAAAAAA8AAAAAAdtYXhSYW5kAAAAAAAAAAWgAAAAABJOZXV0cmlub0Fzc2V0SWRLZXkCAAAAEW5ldXRyaW5vX2Fzc2V0X2lkAAAAAA5Cb25kQXNzZXRJZEtleQIAAAANYm9uZF9hc3NldF9pZAAAAAASQXVjdGlvbkNvbnRyYWN0S2V5AgAAABBhdWN0aW9uX2NvbnRyYWN0AAAAABZMaXF1aWRhdGlvbkNvbnRyYWN0S2V5AgAAABRsaXF1aWRhdGlvbl9jb250cmFjdAAAAAAOUlBEQ29udHJhY3RLZXkCAAAADHJwZF9jb250cmFjdAAAAAASQ29udHJvbENvbnRyYWN0S2V5AgAAABBjb250cm9sX2NvbnRyYWN0AAAAABtCYWxhbmNlV2F2ZXNMb2NrSW50ZXJ2YWxLZXkCAAAAG2JhbGFuY2Vfd2F2ZXNfbG9ja19pbnRlcnZhbAAAAAAeQmFsYW5jZU5ldXRyaW5vTG9ja0ludGVydmFsS2V5AgAAAB5iYWxhbmNlX25ldXRyaW5vX2xvY2tfaW50ZXJ2YWwAAAAAFU1pbldhdmVzU3dhcEFtb3VudEtleQIAAAAVbWluX3dhdmVzX3N3YXBfYW1vdW50AAAAABhNaW5OZXV0cmlub1N3YXBBbW91bnRLZXkCAAAAGG1pbl9uZXV0cmlub19zd2FwX2Ftb3VudAAAAAAbTm9kZU9yYWNsZVByb3ZpZGVyUHViS2V5S2V5AgAAABRub2RlX29yYWNsZV9wcm92aWRlcgAAAAAVTmV1dHJpbm9PdXRGZWVQYXJ0S2V5AgAAABhuZXV0cmlub091dF9zd2FwX2ZlZVBhcnQAAAAAEldhdmVzT3V0RmVlUGFydEtleQIAAAAVd2F2ZXNPdXRfc3dhcF9mZWVQYXJ0AAAAABJSc2FSYW5kUHVibGljNThLZXkCAAAAD3JhbmRfcnNhX3B1YmxpYwAAAAAQa2V5R05zYnRDb250cmFjdAIAAAARJXNfX2dOc2J0Q29udHJhY3QAAAAAE2tleU5zYnRMb2NrQ29udHJhY3QCAAAAFCVzX19uc2J0TG9ja0NvbnRyYWN0AAAAABBrZXlEb3JhMkNvbnRyYWN0AgAAABElc19fZG9yYTJDb250cmFjdAAAAAARa2V5UXVpY2tTd2FwRGVsYXkCAAAAEiVzX19xdWlja1N3YXBEZWxheQAAAAAZa2V5UXVpY2tTd2FwTGltaXREdXJhdGlvbgIAAAAaJXNfX3F1aWNrU3dhcExpbWl0RHVyYXRpb24AAAAAF2tleURvcmEyTGFzdEhlaWdodExpbWl0AgAAABglc19fZG9yYTJMYXN0SGVpZ2h0TGltaXQAAAAACFByaWNlS2V5AgAAAAVwcmljZQAAAAANUHJpY2VJbmRleEtleQIAAAALcHJpY2VfaW5kZXgAAAAADElzQmxvY2tlZEtleQIAAAAKaXNfYmxvY2tlZAEAAAASZ2V0UHJpY2VIaXN0b3J5S2V5AAAAAQAAAAVibG9jawkAASwAAAACCQABLAAAAAIFAAAACFByaWNlS2V5AgAAAAFfCQABpAAAAAEFAAAABWJsb2NrAQAAABhnZXRIZWlnaHRQcmljZUJ5SW5kZXhLZXkAAAABAAAABWluZGV4CQABLAAAAAIJAAEsAAAAAgUAAAANUHJpY2VJbmRleEtleQIAAAABXwkAAaQAAAABBQAAAAVpbmRleAEAAAAVZ2V0U3Rha2luZ05vZGVCeUluZGV4AAAAAQAAAANpZHgJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEJAAS5AAAAAgkABEwAAAACAgAAAAYlcyVkJXMJAARMAAAAAgIAAAAFbGVhc2UJAARMAAAAAgkAAaQAAAABBQAAAANpZHgJAARMAAAAAgIAAAALbm9kZUFkZHJlc3MFAAAAA25pbAUAAAADU0VQAQAAABxnZXRTdGFraW5nTm9kZUFkZHJlc3NCeUluZGV4AAAAAQAAAANpZHgJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAQAAABVnZXRTdGFraW5nTm9kZUJ5SW5kZXgAAAABBQAAAANpZHgBAAAAH2dldFJlc2VydmVkQW1vdW50Rm9yU3BvbnNvcnNoaXAAAAAACQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAAS5AAAAAgkABEwAAAACAgAAAAQlcyVzCQAETAAAAAICAAAABWxlYXNlCQAETAAAAAICAAAAF3Nwb25zb3JzaGlwV2F2ZXNSZXNlcnZlBQAAAANuaWwFAAAAA1NFUAkAAGgAAAACAAAAAAAAAAPoBQAAAAdXQVZFTEVUAQAAABhnZXRCYWxhbmNlVW5sb2NrQmxvY2tLZXkAAAABAAAABW93bmVyCQABLAAAAAICAAAAFWJhbGFuY2VfdW5sb2NrX2Jsb2NrXwUAAAAFb3duZXIBAAAADWdldExlYXNlSWRLZXkAAAABAAAACW5vZGVJbmRleAkABLkAAAACCQAETAAAAAICAAAABiVzJWQlcwkABEwAAAACAgAAAAVsZWFzZQkABEwAAAACCQABpAAAAAEFAAAACW5vZGVJbmRleAkABEwAAAACAgAAAAJpZAUAAAADbmlsBQAAAANTRVABAAAAEWdldExlYXNlQW1vdW50S2V5AAAAAQAAAAlub2RlSW5kZXgJAAS5AAAAAgkABEwAAAACAgAAAAYlcyVkJXMJAARMAAAAAgIAAAAFbGVhc2UJAARMAAAAAgkAAaQAAAABBQAAAAlub2RlSW5kZXgJAARMAAAAAgIAAAAGYW1vdW50BQAAAANuaWwFAAAAA1NFUAEAAAAQbWluU3dhcEFtb3VudEtFWQAAAAEAAAAIc3dhcFR5cGUJAAEsAAAAAgkAASwAAAACAgAAAARtaW5fBQAAAAhzd2FwVHlwZQIAAAAMX3N3YXBfYW1vdW50AQAAAA50b3RhbExvY2tlZEtFWQAAAAEAAAAIc3dhcFR5cGUJAAEsAAAAAgIAAAANYmFsYW5jZV9sb2NrXwUAAAAIc3dhcFR5cGUBAAAAFHRvdGFsTG9ja2VkQnlVc2VyS0VZAAAAAgAAAAhzd2FwVHlwZQAAAAVvd25lcgkABLkAAAACCQAETAAAAAICAAAADGJhbGFuY2VfbG9jawkABEwAAAACBQAAAAhzd2FwVHlwZQkABEwAAAACBQAAAAVvd25lcgUAAAADbmlsAgAAAAFfAQAAABZiYWxhbmNlTG9ja0ludGVydmFsS0VZAAAAAQAAAAhzd2FwVHlwZQkAASwAAAACCQABLAAAAAICAAAACGJhbGFuY2VfBQAAAAhzd2FwVHlwZQIAAAAOX2xvY2tfaW50ZXJ2YWwBAAAAGW1pbkJhbGFuY2VMb2NrSW50ZXJ2YWxLRVkAAAABAAAACHN3YXBUeXBlCQABLAAAAAIJAAEsAAAAAgIAAAAIYmFsYW5jZV8FAAAACHN3YXBUeXBlAgAAABZfbG9ja19pbnRlcnZhbF9taW5pbXVtAQAAABpub2RlQmFsYW5jZUxvY2tJbnRlcnZhbEtFWQAAAAACAAAAGmJhbGFuY2Vfbm9kZV9sb2NrX2ludGVydmFsAQAAAA1vdXRGZWVQYXJ0S0VZAAAAAQAAAAhzd2FwVHlwZQkAASwAAAACBQAAAAhzd2FwVHlwZQIAAAAQT3V0X3N3YXBfZmVlUGFydAEAAAAda2V5UXVpY2tTd2FwVXNlclNwZW50SW5QZXJpb2QAAAABAAAAC3VzZXJBZGRyZXNzCQAEuQAAAAIJAARMAAAAAgIAAAAEJXMlcwkABEwAAAACAgAAABpxdWlja1N3YXBVc2VyU3BlbnRJblBlcmlvZAkABEwAAAACCQAEJQAAAAEFAAAAC3VzZXJBZGRyZXNzBQAAAANuaWwFAAAAA1NFUAEAAAAaa2V5VXNlckxhc3RRdWlja1N3YXBIZWlnaHQAAAABAAAAC3VzZXJBZGRyZXNzCQAEuQAAAAIJAARMAAAAAgIAAAAEJXMlcwkABEwAAAACAgAAABd1c2VyTGFzdFF1aWNrU3dhcEhlaWdodAkABEwAAAACCQAEJQAAAAEFAAAAC3VzZXJBZGRyZXNzBQAAAANuaWwFAAAAA1NFUAEAAAANa2V5RG9yYTJQcmljZQAAAAEAAAAGc3ltYm9sCQAEuQAAAAIJAARMAAAAAgIAAAAEJXMlcwkABEwAAAACAgAAAAVwcmljZQkABEwAAAACBQAAAAZzeW1ib2wFAAAAA25pbAUAAAADU0VQAQAAABJrZXlEb3JhMkxhc3RIZWlnaHQAAAABAAAABnN5bWJvbAkABLkAAAACCQAETAAAAAICAAAABCVzJXMJAARMAAAAAgIAAAAKbGFzdEhlaWdodAkABEwAAAACBQAAAAZzeW1ib2wFAAAAA25pbAUAAAADU0VQAQAAABFtaW5Td2FwQW1vdW50UkVBRAAAAAEAAAAIc3dhcFR5cGUJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwkBAAAAEG1pblN3YXBBbW91bnRLRVkAAAABBQAAAAhzd2FwVHlwZQAAAAAAAAAAAAEAAAAPdG90YWxMb2NrZWRSRUFEAAAAAQAAAAhzd2FwVHlwZQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAOdG90YWxMb2NrZWRLRVkAAAABBQAAAAhzd2FwVHlwZQAAAAAAAAAAAAEAAAAVdG90YWxMb2NrZWRCeVVzZXJSRUFEAAAAAgAAAAhzd2FwVHlwZQAAAAVvd25lcgkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAUdG90YWxMb2NrZWRCeVVzZXJLRVkAAAACBQAAAAhzd2FwVHlwZQUAAAAFb3duZXIAAAAAAAAAAAABAAAAF2JhbGFuY2VMb2NrSW50ZXJ2YWxSRUFEAAAAAQAAAAhzd2FwVHlwZQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAWYmFsYW5jZUxvY2tJbnRlcnZhbEtFWQAAAAEFAAAACHN3YXBUeXBlBQAAAAdtYXhSYW5kAQAAABptaW5CYWxhbmNlTG9ja0ludGVydmFsUkVBRAAAAAEAAAAIc3dhcFR5cGUJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwkBAAAAGW1pbkJhbGFuY2VMb2NrSW50ZXJ2YWxLRVkAAAABBQAAAAhzd2FwVHlwZQUAAAAHbWluUmFuZAEAAAAbbm9kZUJhbGFuY2VMb2NrSW50ZXJ2YWxSRUFEAAAAAAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAabm9kZUJhbGFuY2VMb2NrSW50ZXJ2YWxLRVkAAAAAAAAAAAAAAAABAQAAABZjb252ZXJ0TmV1dHJpbm9Ub1dhdmVzAAAAAgAAAAZhbW91bnQAAAAFcHJpY2UJAABrAAAAAwkAAGsAAAADBQAAAAZhbW91bnQFAAAACFBSSUNFTEVUBQAAAAVwcmljZQUAAAAHV0FWRUxFVAUAAAAFUEFVTEkBAAAAFmNvbnZlcnRXYXZlc1RvTmV1dHJpbm8AAAACAAAABmFtb3VudAAAAAVwcmljZQkAAGsAAAADCQAAawAAAAMFAAAABmFtb3VudAUAAAAFcHJpY2UFAAAACFBSSUNFTEVUBQAAAAVQQVVMSQUAAAAHV0FWRUxFVAEAAAASY29udmVydFdhdmVzVG9Cb25kAAAAAgAAAAZhbW91bnQAAAAFcHJpY2UJAQAAABZjb252ZXJ0V2F2ZXNUb05ldXRyaW5vAAAAAgUAAAAGYW1vdW50BQAAAAVwcmljZQEAAAAWY29udmVydEpzb25BcnJheVRvTGlzdAAAAAEAAAAJanNvbkFycmF5CQAEtQAAAAIFAAAACWpzb25BcnJheQIAAAABLAEAAAARbWluU3dhcEFtb3VudEZBSUwAAAACAAAACHN3YXBUeXBlAAAADW1pblN3YXBBbW91bnQJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAYVGhlIHNwZWNpZmllZCBhbW91bnQgaW4gBQAAAAhzd2FwVHlwZQIAAAArIHN3YXAgaXMgbGVzcyB0aGFuIHRoZSByZXF1aXJlZCBtaW5pbXVtIG9mIAkAAaQAAAABBQAAAA1taW5Td2FwQW1vdW50AQAAABVlbWVyZ2VuY3lTaHV0ZG93bkZBSUwAAAAACQAAAgAAAAECAAAAWmNvbnRyYWN0IGlzIGJsb2NrZWQgYnkgRU1FUkdFTkNZIFNIVVRET1dOIGFjdGlvbnMgdW50aWxsIHJlYWN0aXZhdGlvbiBieSBlbWVyZ2VuY3kgb3JhY2xlcwEAAAAOcHJpY2VJbmRleEZBSUwAAAAFAAAABWluZGV4AAAACnByaWNlSW5kZXgAAAALaW5kZXhIZWlnaHQAAAAMdW5sb2NrSGVpZ2h0AAAAD3ByZXZJbmRleEhlaWdodAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAACNpbnZhbGlkIHByaWNlIGhpc3RvcnkgaW5kZXg6IGluZGV4PQkAAaQAAAABBQAAAAVpbmRleAIAAAAMIHByaWNlSW5kZXg9CQABpAAAAAEFAAAACnByaWNlSW5kZXgCAAAADSBpbmRleEhlaWdodD0JAAGkAAAAAQUAAAALaW5kZXhIZWlnaHQCAAAADiB1bmxvY2tIZWlnaHQ9CQABpAAAAAEFAAAADHVubG9ja0hlaWdodAIAAAARIHByZXZJbmRleEhlaWdodD0JAAGkAAAAAQUAAAAPcHJldkluZGV4SGVpZ2h0AAAAABNsaXF1aWRhdGlvbkNvbnRyYWN0CQEAAAAOZ2V0U3RyaW5nQnlLZXkAAAABBQAAABZMaXF1aWRhdGlvbkNvbnRyYWN0S2V5AAAAAA9uZXV0cmlub0Fzc2V0SWQJAAJZAAAAAQkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAASTmV1dHJpbm9Bc3NldElkS2V5AAAAAA9hdWN0aW9uQ29udHJhY3QJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAAEkF1Y3Rpb25Db250cmFjdEtleQAAAAALcnBkQ29udHJhY3QJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAADlJQRENvbnRyYWN0S2V5AAAAAA9jb250cm9sQ29udHJhY3QJAQAAAA5nZXRTdHJpbmdCeUtleQAAAAEFAAAAEkNvbnRyb2xDb250cmFjdEtleQAAAAAKcHJpY2VJbmRleAkBAAAAGGdldE51bWJlckJ5QWRkcmVzc0FuZEtleQAAAAIFAAAAD2NvbnRyb2xDb250cmFjdAUAAAANUHJpY2VJbmRleEtleQAAAAAJaXNCbG9ja2VkCQEAAAAWZ2V0Qm9vbEJ5QWRkcmVzc0FuZEtleQAAAAIFAAAAD2NvbnRyb2xDb250cmFjdAUAAAAMSXNCbG9ja2VkS2V5AAAAABhub2RlT3JhY2xlUHJvdmlkZXJQdWJLZXkJAAJZAAAAAQkBAAAADmdldFN0cmluZ0J5S2V5AAAAAQUAAAAbTm9kZU9yYWNsZVByb3ZpZGVyUHViS2V5S2V5AAAAAAtib25kQXNzZXRJZAkAAlkAAAABAgAAACw2blNwVnlOSDd5TTY5ZWc0NDZ3clFSOTRpcGJiY21aTVUxRU5Qd2FuQzk3ZwAAAAAVZGVwcmVjYXRlZEJvbmRBc3NldElkCQACWQAAAAECAAAALDk3NWFrWkJmbk1qNTEzVTdNWmFIS3pRcm1zRXg1YUUzd2RXS1RySEJoYmpGAAAAAAZyc2FQdWIJAAJbAAAAAQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAElJzYVJhbmRQdWJsaWM1OEtleQIAAAAlUlNBIHB1YmxpYyBrZXkgaGFzIG5vdCBiZWVuIHNwZWNpZmllZAAAAAAQbmV1dHJpbm9Db250cmFjdAUAAAAEdGhpcwAAAAAMY3VycmVudFByaWNlCQEAAAAYZ2V0TnVtYmVyQnlBZGRyZXNzQW5kS2V5AAAAAgUAAAAPY29udHJvbENvbnRyYWN0BQAAAAhQcmljZUtleQAAAAAVbmV1dHJpbm9Mb2NrZWRCYWxhbmNlCQEAAAAPdG90YWxMb2NrZWRSRUFEAAAAAQIAAAAIbmV1dHJpbm8AAAAAEndhdmVzTG9ja2VkQmFsYW5jZQkBAAAAD3RvdGFsTG9ja2VkUkVBRAAAAAECAAAABXdhdmVzAAAAAAdyZXNlcnZlCQAAZQAAAAIICQAD7wAAAAEFAAAAEG5ldXRyaW5vQ29udHJhY3QAAAAHcmVndWxhcgUAAAASd2F2ZXNMb2NrZWRCYWxhbmNlAAAAAA5uZXV0cmlub1N1cHBseQkAAGUAAAACCQAAZQAAAAIJAABkAAAAAgUAAAAVbmV1dHJpbm9Mb2NrZWRCYWxhbmNlCAkBAAAABXZhbHVlAAAAAQkAA+wAAAABBQAAAA9uZXV0cmlub0Fzc2V0SWQAAAAIcXVhbnRpdHkJAAPwAAAAAgUAAAAQbmV1dHJpbm9Db250cmFjdAUAAAAPbmV1dHJpbm9Bc3NldElkCQAD8AAAAAIJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAAE2xpcXVpZGF0aW9uQ29udHJhY3QFAAAAD25ldXRyaW5vQXNzZXRJZAAAAAAHc3VycGx1cwkAAGUAAAACCQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAIFAAAAB3Jlc2VydmUFAAAADGN1cnJlbnRQcmljZQUAAAAObmV1dHJpbm9TdXBwbHkAAAAAB2RlZmljaXQJAABlAAAAAgUAAAAObmV1dHJpbm9TdXBwbHkJAQAAABZjb252ZXJ0V2F2ZXNUb05ldXRyaW5vAAAAAgUAAAAHcmVzZXJ2ZQUAAAAMY3VycmVudFByaWNlAQAAABtjaGVja0lzVmFsaWRNaW5TcG9uc29yZWRGZWUAAAABAAAAAnR4BAAAAA5NSU5UUkFOU0ZFUkZFRQAAAAAAAAGGoAQAAAAWU3BvbnNvcmVkRmVlVXBwZXJCb3VuZAAAAAAAAAAD6AQAAAAPcmVhbE5ldXRyaW5vRmVlCQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAIFAAAADk1JTlRSQU5TRkVSRkVFBQAAAAxjdXJyZW50UHJpY2UEAAAADm1pbk5ldXRyaW5vRmVlCQAAaAAAAAIFAAAAD3JlYWxOZXV0cmlub0ZlZQAAAAAAAAAAAgQAAAAObWF4TmV1dHJpbm9GZWUJAABrAAAAAwUAAAAPcmVhbE5ldXRyaW5vRmVlBQAAABZTcG9uc29yZWRGZWVVcHBlckJvdW5kAAAAAAAAAABkBAAAAAhpbnB1dEZlZQkBAAAABXZhbHVlAAAAAQgFAAAAAnR4AAAAFG1pblNwb25zb3JlZEFzc2V0RmVlAwMJAABnAAAAAgUAAAAIaW5wdXRGZWUFAAAADm1pbk5ldXRyaW5vRmVlCQAAZwAAAAIFAAAADm1heE5ldXRyaW5vRmVlBQAAAAhpbnB1dEZlZQcJAAAAAAAAAggFAAAAAnR4AAAAB2Fzc2V0SWQFAAAAD25ldXRyaW5vQXNzZXRJZAcBAAAAD2dldFByaWNlSGlzdG9yeQAAAAEAAAAFYmxvY2sJAQAAABhnZXROdW1iZXJCeUFkZHJlc3NBbmRLZXkAAAACBQAAAA9jb250cm9sQ29udHJhY3QJAQAAABJnZXRQcmljZUhpc3RvcnlLZXkAAAABBQAAAAVibG9jawEAAAAVZ2V0SGVpZ2h0UHJpY2VCeUluZGV4AAAAAQAAAAVpbmRleAkBAAAAGGdldE51bWJlckJ5QWRkcmVzc0FuZEtleQAAAAIFAAAAD2NvbnRyb2xDb250cmFjdAkBAAAAGGdldEhlaWdodFByaWNlQnlJbmRleEtleQAAAAEFAAAABWluZGV4AAAAAAxzSWR4U3dhcFR5cGUAAAAAAAAAAAEAAAAACnNJZHhTdGF0dXMAAAAAAAAAAAIAAAAADHNJZHhJbkFtb3VudAAAAAAAAAAAAwAAAAAJc0lkeFByaWNlAAAAAAAAAAAEAAAAABBzSWR4T3V0TmV0QW1vdW50AAAAAAAAAAAFAAAAABBzSWR4T3V0RmVlQW1vdW50AAAAAAAAAAAGAAAAAA9zSWR4U3RhcnRIZWlnaHQAAAAAAAAAAAcAAAAAEnNJZHhTdGFydFRpbWVzdGFtcAAAAAAAAAAACAAAAAANc0lkeEVuZEhlaWdodAAAAAAAAAAACQAAAAAQc0lkeEVuZFRpbWVzdGFtcAAAAAAAAAAACgAAAAAUc0lkeFNlbGZVbmxvY2tIZWlnaHQAAAAAAAAAAAsAAAAAFHNJZHhSYW5kVW5sb2NrSGVpZ2h0AAAAAAAAAAAMAAAAAAlzSWR4SW5kZXgAAAAAAAAAAA0AAAAAEHNJZHhXaXRoZHJhd1R4SWQAAAAAAAAAAA4AAAAAC3NJZHhNaW5SYW5kAAAAAAAAAAAPAAAAAAtzSWR4TWF4UmFuZAAAAAAAAAAAEAAAAAALc0lkeElzUXVpY2sAAAAAAAAAABEBAAAAB3N3YXBLRVkAAAACAAAAC3VzZXJBZGRyZXNzAAAABHR4SWQJAAS5AAAAAgkABEwAAAACAgAAAAQlcyVzCQAETAAAAAIFAAAAC3VzZXJBZGRyZXNzCQAETAAAAAIFAAAABHR4SWQFAAAAA25pbAUAAAADU0VQAQAAAAtzdHJTd2FwREFUQQAAABEAAAAIc3dhcFR5cGUAAAAGc3RhdHVzAAAACGluQW1vdW50AAAABXByaWNlAAAADG91dE5ldEFtb3VudAAAAAxvdXRGZWVBbW91bnQAAAALc3RhcnRIZWlnaHQAAAAOc3RhcnRUaW1lc3RhbXAAAAAJZW5kSGVpZ2h0AAAADGVuZFRpbWVzdGFtcAAAABBzZWxmVW5sb2NrSGVpZ2h0AAAAEHJhbmRVbmxvY2tIZWlnaHQAAAAFaW5kZXgAAAAMd2l0aGRyYXdUeElkAAAAB3JhbmRNaW4AAAAHcmFuZE1heAAAAAdpc1F1aWNrCQAEuQAAAAIJAARMAAAAAgIAAAAcJXMlcyVkJWQlZCVkJWQlZCVkJWQlZCVkJWQlcwkABEwAAAACBQAAAAhzd2FwVHlwZQkABEwAAAACBQAAAAZzdGF0dXMJAARMAAAAAgUAAAAIaW5BbW91bnQJAARMAAAAAgUAAAAFcHJpY2UJAARMAAAAAgUAAAAMb3V0TmV0QW1vdW50CQAETAAAAAIFAAAADG91dEZlZUFtb3VudAkABEwAAAACBQAAAAtzdGFydEhlaWdodAkABEwAAAACBQAAAA5zdGFydFRpbWVzdGFtcAkABEwAAAACBQAAAAllbmRIZWlnaHQJAARMAAAAAgUAAAAMZW5kVGltZXN0YW1wCQAETAAAAAIFAAAAEHNlbGZVbmxvY2tIZWlnaHQJAARMAAAAAgUAAAAQcmFuZFVubG9ja0hlaWdodAkABEwAAAACBQAAAAVpbmRleAkABEwAAAACBQAAAAx3aXRoZHJhd1R4SWQJAARMAAAAAgUAAAAHcmFuZE1pbgkABEwAAAACBQAAAAdyYW5kTWF4CQAETAAAAAIFAAAAB2lzUXVpY2sFAAAAA25pbAUAAAADU0VQAQAAAA9wZW5kaW5nU3dhcERBVEEAAAADAAAACHN3YXBUeXBlAAAADWluQXNzZXRBbW91bnQAAAAQc2VsZlVubG9ja0hlaWdodAkBAAAAC3N0clN3YXBEQVRBAAAAEQUAAAAIc3dhcFR5cGUCAAAAB1BFTkRJTkcJAAGkAAAAAQUAAAANaW5Bc3NldEFtb3VudAIAAAABMAIAAAABMAIAAAABMAkAAaQAAAABBQAAAAZoZWlnaHQJAAGkAAAAAQgFAAAACWxhc3RCbG9jawAAAAl0aW1lc3RhbXACAAAAATACAAAAATAJAAGkAAAAAQUAAAAQc2VsZlVubG9ja0hlaWdodAIAAAABMAIAAAABMAIAAAAETlVMTAkAAaQAAAABCQEAAAAabWluQmFsYW5jZUxvY2tJbnRlcnZhbFJFQUQAAAABBQAAAAhzd2FwVHlwZQkAAaQAAAABCQEAAAAXYmFsYW5jZUxvY2tJbnRlcnZhbFJFQUQAAAABBQAAAAhzd2FwVHlwZQkAAaUAAAABBwEAAAASYWNjZWxlcmF0ZVN3YXBEQVRBAAAAAQAAAAlkYXRhQXJyYXkJAQAAAAtzdHJTd2FwREFUQQAAABEJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAAxzSWR4U3dhcFR5cGUJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAApzSWR4U3RhdHVzCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAMc0lkeEluQW1vdW50CQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAJc0lkeFByaWNlCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAQc0lkeE91dE5ldEFtb3VudAkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAEHNJZHhPdXRGZWVBbW91bnQJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAA9zSWR4U3RhcnRIZWlnaHQJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAABJzSWR4U3RhcnRUaW1lc3RhbXAJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAA1zSWR4RW5kSGVpZ2h0CQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAQc0lkeEVuZFRpbWVzdGFtcAkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAFHNJZHhTZWxmVW5sb2NrSGVpZ2h0CQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAUc0lkeFJhbmRVbmxvY2tIZWlnaHQJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAAlzSWR4SW5kZXgJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAABBzSWR4V2l0aGRyYXdUeElkCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAALc0lkeE1pblJhbmQJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAAtzSWR4TWF4UmFuZAkAAaUAAAABBgEAAAAOZmluaXNoU3dhcERBVEEAAAAHAAAACWRhdGFBcnJheQAAAAVwcmljZQAAAAxvdXROZXRBbW91bnQAAAAMb3V0RmVlQW1vdW50AAAAEHJhbmRVbmxvY2tIZWlnaHQAAAAFaW5kZXgAAAAMd2l0aGRyYXdUeElkCQEAAAALc3RyU3dhcERBVEEAAAARCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAMc0lkeFN3YXBUeXBlAgAAAAhGSU5JU0hFRAkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAADHNJZHhJbkFtb3VudAkAAaQAAAABBQAAAAVwcmljZQkAAaQAAAABBQAAAAxvdXROZXRBbW91bnQJAAGkAAAAAQUAAAAMb3V0RmVlQW1vdW50CQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAPc0lkeFN0YXJ0SGVpZ2h0CQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAASc0lkeFN0YXJ0VGltZXN0YW1wCQABpAAAAAEFAAAABmhlaWdodAkAAaQAAAABCAUAAAAJbGFzdEJsb2NrAAAACXRpbWVzdGFtcAkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAFHNJZHhTZWxmVW5sb2NrSGVpZ2h0CQABpAAAAAEFAAAAEHJhbmRVbmxvY2tIZWlnaHQJAAGkAAAAAQUAAAAFaW5kZXgFAAAADHdpdGhkcmF3VHhJZAkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAC3NJZHhNaW5SYW5kCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAALc0lkeE1heFJhbmQJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAAtzSWR4SXNRdWljawEAAAASc3dhcERhdGFGYWlsT3JSRUFEAAAAAgAAAAt1c2VyQWRkcmVzcwAAAAhzd2FwVHhJZAQAAAAHc3dhcEtleQkBAAAAB3N3YXBLRVkAAAACBQAAAAt1c2VyQWRkcmVzcwUAAAAIc3dhcFR4SWQJAAS1AAAAAgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAB3N3YXBLZXkJAAEsAAAAAgIAAAARbm8gc3dhcCBkYXRhIGZvciAFAAAAB3N3YXBLZXkFAAAAA1NFUAEAAAAJYXBwbHlGZWVzAAAAAgAAAAthbW91bnRHcm9zcwAAAAdmZWVQYXJ0BAAAAAlmZWVBbW91bnQJAABrAAAAAwUAAAALYW1vdW50R3Jvc3MFAAAAB2ZlZVBhcnQFAAAABVBBVUxJCQAETAAAAAIJAABlAAAAAgUAAAALYW1vdW50R3Jvc3MFAAAACWZlZUFtb3VudAkABEwAAAACBQAAAAlmZWVBbW91bnQJAARMAAAAAgUAAAALYW1vdW50R3Jvc3MFAAAAA25pbAEAAAAWcmFuZFVubG9ja0hlaWdodE9yRmFpbAAAAAUAAAAEdHhJZAAAAAZyc2FTaWcAAAAIc3dhcFR5cGUAAAALc3RhcnRIZWlnaHQAAAAQbWluTWF4UmFuZHNUdXBsZQQAAAAKaXNSc2FWYWxpZAkACigAAAAEBQAAAAZTSEEyNTYJAAGbAAAAAQUAAAAEdHhJZAUAAAAGcnNhU2lnBQAAAAZyc2FQdWIDCQEAAAABIQAAAAEFAAAACmlzUnNhVmFsaWQJAAACAAAAAQIAAAAVaW52YWxpZCBSU0Egc2lnbmF0dXJlBAAAABZtaW5CYWxhbmNlTG9ja0ludGVydmFsCAUAAAAQbWluTWF4UmFuZHNUdXBsZQAAAAJfMQQAAAAWbWF4QmFsYW5jZUxvY2tJbnRlcnZhbAgFAAAAEG1pbk1heFJhbmRzVHVwbGUAAAACXzIEAAAABHJhbmQJAABqAAAAAgkABLEAAAABCQALVAAAAAEFAAAABnJzYVNpZwkAAGUAAAACBQAAABZtYXhCYWxhbmNlTG9ja0ludGVydmFsBQAAABZtaW5CYWxhbmNlTG9ja0ludGVydmFsBAAAABByYW5kTG9ja0ludGVydmFsCQAAZAAAAAIFAAAAFm1pbkJhbGFuY2VMb2NrSW50ZXJ2YWwDCQAAZgAAAAIAAAAAAAAAAAAFAAAABHJhbmQJAQAAAAEtAAAAAQUAAAAEcmFuZAUAAAAEcmFuZAkAAGQAAAACBQAAAAtzdGFydEhlaWdodAUAAAAQcmFuZExvY2tJbnRlcnZhbAEAAAADYWJzAAAAAQAAAAF4AwkAAGYAAAACAAAAAAAAAAAABQAAAAF4CQEAAAABLQAAAAEFAAAAAXgFAAAAAXgBAAAACnNlbGVjdE5vZGUAAAABAAAADXVubGVhc2VBbW91bnQEAAAADWFtb3VudFRvTGVhc2UJAABlAAAAAgkAAGUAAAACCAkAA+8AAAABBQAAABBuZXV0cmlub0NvbnRyYWN0AAAACWF2YWlsYWJsZQUAAAANdW5sZWFzZUFtb3VudAkBAAAAH2dldFJlc2VydmVkQW1vdW50Rm9yU3BvbnNvcnNoaXAAAAAABAAAAApvbGRMZWFzZWQwCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAARZ2V0TGVhc2VBbW91bnRLZXkAAAABAAAAAAAAAAAABAAAAApvbGRMZWFzZWQxCQEAAAAOZ2V0TnVtYmVyQnlLZXkAAAABCQEAAAARZ2V0TGVhc2VBbW91bnRLZXkAAAABAAAAAAAAAAABBAAAAApuZXdMZWFzZWQwCQAAZAAAAAIFAAAADWFtb3VudFRvTGVhc2UFAAAACm9sZExlYXNlZDAEAAAACm5ld0xlYXNlZDEJAABkAAAAAgUAAAANYW1vdW50VG9MZWFzZQUAAAAKb2xkTGVhc2VkMQMDCQAAZgAAAAIFAAAACm5ld0xlYXNlZDAAAAAAAAAAAAAGCQAAZgAAAAIFAAAACm5ld0xlYXNlZDEAAAAAAAAAAAAEAAAABmRlbHRhMAkBAAAAA2FicwAAAAEJAABlAAAAAgUAAAAKbmV3TGVhc2VkMAUAAAAKb2xkTGVhc2VkMQQAAAAGZGVsdGExCQEAAAADYWJzAAAAAQkAAGUAAAACBQAAAApuZXdMZWFzZWQxBQAAAApvbGRMZWFzZWQwAwkAAGcAAAACBQAAAAZkZWx0YTEFAAAABmRlbHRhMAkABRQAAAACAAAAAAAAAAAABQAAAApuZXdMZWFzZWQwCQAFFAAAAAIAAAAAAAAAAAEFAAAACm5ld0xlYXNlZDEJAAUUAAAAAgD//////////wAAAAAAAAAAAAEAAAAWcHJlcGFyZVVubGVhc2VBbmRMZWFzZQAAAAEAAAANdW5sZWFzZUFtb3VudAQAAAANJHQwMTYyMTIxNjMwMAkBAAAACnNlbGVjdE5vZGUAAAABBQAAAA11bmxlYXNlQW1vdW50BAAAAAlub2RlSW5kZXgIBQAAAA0kdDAxNjIxMjE2MzAwAAAAAl8xBAAAAA5uZXdMZWFzZUFtb3VudAgFAAAADSR0MDE2MjEyMTYzMDAAAAACXzIDCQAAZgAAAAIFAAAADm5ld0xlYXNlQW1vdW50AAAAAAAAAAAABAAAAApsZWFzZUlkS2V5CQEAAAANZ2V0TGVhc2VJZEtleQAAAAEFAAAACW5vZGVJbmRleAQAAAAIb2xkTGVhc2UJAAQcAAAAAgUAAAAEdGhpcwUAAAAKbGVhc2VJZEtleQQAAAAOdW5sZWFzZU9yRW1wdHkDCQEAAAAJaXNEZWZpbmVkAAAAAQUAAAAIb2xkTGVhc2UJAARMAAAAAgkBAAAAC0xlYXNlQ2FuY2VsAAAAAQkBAAAABXZhbHVlAAAAAQUAAAAIb2xkTGVhc2UFAAAAA25pbAUAAAADbmlsBAAAAA5sZWFzZUFtb3VudEtleQkBAAAAEWdldExlYXNlQW1vdW50S2V5AAAAAQUAAAAJbm9kZUluZGV4BAAAAAVsZWFzZQkABEQAAAACCQEAAAAcZ2V0U3Rha2luZ05vZGVBZGRyZXNzQnlJbmRleAAAAAEFAAAACW5vZGVJbmRleAUAAAAObmV3TGVhc2VBbW91bnQJAAROAAAAAgUAAAAOdW5sZWFzZU9yRW1wdHkJAARMAAAAAgUAAAAFbGVhc2UJAARMAAAAAgkBAAAAC0JpbmFyeUVudHJ5AAAAAgUAAAAKbGVhc2VJZEtleQkABDkAAAABBQAAAAVsZWFzZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAEWdldExlYXNlQW1vdW50S2V5AAAAAQUAAAAJbm9kZUluZGV4BQAAAA5uZXdMZWFzZUFtb3VudAUAAAADbmlsBQAAAANuaWwBAAAAEGdldERvcmEyTlNCVEluZm8AAAAABAAAAA1kb3JhMkNvbnRyYWN0CQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQEAAAARQGV4dHJOYXRpdmUoMTA1MykAAAACBQAAAAR0aGlzBQAAABBrZXlEb3JhMkNvbnRyYWN0BAAAAAVwcmljZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAADWRvcmEyQ29udHJhY3QJAQAAAA1rZXlEb3JhMlByaWNlAAAAAQUAAAAPZG9yYTJOc2J0U3ltYm9sAgAAABdOU0JUIHByaWNlIGlzIHVuZGVmaW5lZAQAAAAKbGFzdEhlaWdodAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAA1kb3JhMkNvbnRyYWN0CQEAAAASa2V5RG9yYTJMYXN0SGVpZ2h0AAAAAQUAAAAPZG9yYTJOc2J0U3ltYm9sAAAAAAAAAAAACQAFFAAAAAIFAAAABXByaWNlBQAAAApsYXN0SGVpZ2h0AQAAAAxnZXROU0JUUHJpY2UAAAAABAAAAA0kdDAxNzI1ODE3MzAyCQEAAAAQZ2V0RG9yYTJOU0JUSW5mbwAAAAAEAAAABXByaWNlCAUAAAANJHQwMTcyNTgxNzMwMgAAAAJfMQQAAAAKbGFzdEhlaWdodAgFAAAADSR0MDE3MjU4MTczMDIAAAACXzIFAAAABXByaWNlAQAAAAh0aGlzT25seQAAAAEAAAABaQMJAQAAAAIhPQAAAAIIBQAAAAFpAAAABmNhbGxlcgUAAAAEdGhpcwkAAAIAAAABAgAAAC1QZXJtaXNzaW9uIGRlbmllZDogdGhpcyBjb250cmFjdCBvbmx5IGFsbG93ZWQGAAAADwAAAAFpAQAAAB1wcmVwYXJlVW5sZWFzZUFuZExlYXNlV3JhcHBlcgAAAAEAAAANdW5sZWFzZUFtb3VudAQAAAALY2hlY2tDYWxsZXIJAARMAAAAAgkBAAAACHRoaXNPbmx5AAAAAQUAAAABaQUAAAADbmlsAwkAAAAAAAACBQAAAAtjaGVja0NhbGxlcgUAAAALY2hlY2tDYWxsZXIJAQAAABZwcmVwYXJlVW5sZWFzZUFuZExlYXNlAAAAAQUAAAANdW5sZWFzZUFtb3VudAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAALY29uc3RydWN0b3IAAAAOAAAAEm5ldXRyaW5vQXNzZXRJZFBybQAAAA5ib25kQXNzZXRJZFBybQAAABJhdWN0aW9uQ29udHJhY3RQcm0AAAAWbGlxdWlkYXRpb25Db250cmFjdFBybQAAAA5ycGRDb250cmFjdFBybQAAABJjb250cm9sQ29udHJhY3RQcm0AAAAbbm9kZU9yYWNsZVByb3ZpZGVyUHViS2V5UHJtAAAAE3JzYVJhbmRQdWJsaWNLZXlQcm0AAAAbYmFsYW5jZVdhdmVzTG9ja0ludGVydmFsUHJtAAAAHmJhbGFuY2VOZXV0cmlub0xvY2tJbnRlcnZhbFBybQAAABVtaW5XYXZlc1N3YXBBbW91bnRQcm0AAAAYbWluTmV1dHJpbm9Td2FwQW1vdW50UHJtAAAAFW5ldXRyaW5vT3V0RmVlUGFydFBybQAAABJ3YXZlc091dEZlZVBhcnRQcm0EAAAAC2NoZWNrQ2FsbGVyCQEAAAAIdGhpc09ubHkAAAABBQAAAAFpAwkAAAAAAAACBQAAAAtjaGVja0NhbGxlcgUAAAALY2hlY2tDYWxsZXIJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAASTmV1dHJpbm9Bc3NldElkS2V5BQAAABJuZXV0cmlub0Fzc2V0SWRQcm0JAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAOQm9uZEFzc2V0SWRLZXkFAAAADmJvbmRBc3NldElkUHJtCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAEkF1Y3Rpb25Db250cmFjdEtleQUAAAASYXVjdGlvbkNvbnRyYWN0UHJtCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAFkxpcXVpZGF0aW9uQ29udHJhY3RLZXkFAAAAFmxpcXVpZGF0aW9uQ29udHJhY3RQcm0JAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAOUlBEQ29udHJhY3RLZXkFAAAADnJwZENvbnRyYWN0UHJtCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAEkNvbnRyb2xDb250cmFjdEtleQUAAAASY29udHJvbENvbnRyYWN0UHJtCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAG05vZGVPcmFjbGVQcm92aWRlclB1YktleUtleQUAAAAbbm9kZU9yYWNsZVByb3ZpZGVyUHViS2V5UHJtCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAElJzYVJhbmRQdWJsaWM1OEtleQUAAAATcnNhUmFuZFB1YmxpY0tleVBybQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAbQmFsYW5jZVdhdmVzTG9ja0ludGVydmFsS2V5BQAAABtiYWxhbmNlV2F2ZXNMb2NrSW50ZXJ2YWxQcm0JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAHkJhbGFuY2VOZXV0cmlub0xvY2tJbnRlcnZhbEtleQUAAAAeYmFsYW5jZU5ldXRyaW5vTG9ja0ludGVydmFsUHJtCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABVNaW5XYXZlc1N3YXBBbW91bnRLZXkFAAAAFW1pbldhdmVzU3dhcEFtb3VudFBybQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAYTWluTmV1dHJpbm9Td2FwQW1vdW50S2V5BQAAABhtaW5OZXV0cmlub1N3YXBBbW91bnRQcm0JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAFU5ldXRyaW5vT3V0RmVlUGFydEtleQUAAAAVbmV1dHJpbm9PdXRGZWVQYXJ0UHJtCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJXYXZlc091dEZlZVBhcnRLZXkFAAAAEndhdmVzT3V0RmVlUGFydFBybQUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAA1jb25zdHJ1Y3RvclYyAAAABgAAAA1nTnNidENvbnRyYWN0AAAAEG5zYnRMb2NrQ29udHJhY3QAAAANZG9yYTJDb250cmFjdAAAAA5xdWlja1N3YXBEZWxheQAAABZxdWlja1N3YXBMaW1pdER1cmF0aW9uAAAAFGRvcmEyTGFzdEhlaWdodExpbWl0BAAAAAtjaGVja0NhbGxlcgkBAAAACHRoaXNPbmx5AAAAAQUAAAABaQMJAAAAAAAAAgUAAAALY2hlY2tDYWxsZXIFAAAAC2NoZWNrQ2FsbGVyCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAEGtleUdOc2J0Q29udHJhY3QFAAAADWdOc2J0Q29udHJhY3QJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAATa2V5TnNidExvY2tDb250cmFjdAUAAAAQbnNidExvY2tDb250cmFjdAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAABBrZXlEb3JhMkNvbnRyYWN0BQAAAA1kb3JhMkNvbnRyYWN0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABFrZXlRdWlja1N3YXBEZWxheQUAAAAOcXVpY2tTd2FwRGVsYXkJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAGWtleVF1aWNrU3dhcExpbWl0RHVyYXRpb24FAAAAFnF1aWNrU3dhcExpbWl0RHVyYXRpb24JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAF2tleURvcmEyTGFzdEhlaWdodExpbWl0BQAAABRkb3JhMkxhc3RIZWlnaHRMaW1pdAUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAApjb21tb25Td2FwAAAABAAAAAhzd2FwVHlwZQAAAAZhbW91bnQAAAAHYWNjb3VudAAAAAR0eElkBAAAAAtjaGVja0NhbGxlcgkBAAAACHRoaXNPbmx5AAAAAQUAAAABaQMJAAAAAAAAAgUAAAALY2hlY2tDYWxsZXIFAAAAC2NoZWNrQ2FsbGVyBAAAAA1taW5Td2FwQW1vdW50CQEAAAARbWluU3dhcEFtb3VudFJFQUQAAAABBQAAAAhzd2FwVHlwZQQAAAALdG90YWxMb2NrZWQJAQAAAA90b3RhbExvY2tlZFJFQUQAAAABBQAAAAhzd2FwVHlwZQQAAAARdG90YWxMb2NrZWRCeVVzZXIJAQAAABV0b3RhbExvY2tlZEJ5VXNlclJFQUQAAAACBQAAAAhzd2FwVHlwZQUAAAAHYWNjb3VudAQAAAALbm9kZUFkZHJlc3MJAQAAABVnZXRTdGFraW5nTm9kZUJ5SW5kZXgAAAABAAAAAAAAAAAABAAAABZiYWxhbmNlTG9ja01heEludGVydmFsAwkAAAAAAAACBQAAAAtub2RlQWRkcmVzcwUAAAAHYWNjb3VudAkBAAAAG25vZGVCYWxhbmNlTG9ja0ludGVydmFsUkVBRAAAAAAJAQAAABdiYWxhbmNlTG9ja0ludGVydmFsUkVBRAAAAAEFAAAACHN3YXBUeXBlBAAAABBzZWxmVW5sb2NrSGVpZ2h0CQAAZAAAAAIFAAAABmhlaWdodAUAAAAWYmFsYW5jZUxvY2tNYXhJbnRlcnZhbAMJAABmAAAAAgUAAAANbWluU3dhcEFtb3VudAUAAAAGYW1vdW50CQEAAAARbWluU3dhcEFtb3VudEZBSUwAAAACBQAAAAhzd2FwVHlwZQUAAAANbWluU3dhcEFtb3VudAMFAAAACWlzQmxvY2tlZAkBAAAAFWVtZXJnZW5jeVNodXRkb3duRkFJTAAAAAAEAAAACWxlYXNlUGFydAMJAAAAAAAAAgUAAAAIc3dhcFR5cGUCAAAABXdhdmVzCQEAAAAWcHJlcGFyZVVubGVhc2VBbmRMZWFzZQAAAAEAAAAAAAAAAAAFAAAAA25pbAkABRQAAAACCQAETgAAAAIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABR0b3RhbExvY2tlZEJ5VXNlcktFWQAAAAIFAAAACHN3YXBUeXBlBQAAAAdhY2NvdW50CQAAZAAAAAIFAAAAEXRvdGFsTG9ja2VkQnlVc2VyBQAAAAZhbW91bnQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABhnZXRCYWxhbmNlVW5sb2NrQmxvY2tLZXkAAAABBQAAAAdhY2NvdW50BQAAABBzZWxmVW5sb2NrSGVpZ2h0CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAOdG90YWxMb2NrZWRLRVkAAAABBQAAAAhzd2FwVHlwZQkAAGQAAAACBQAAAAt0b3RhbExvY2tlZAUAAAAGYW1vdW50CQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAAdzd2FwS0VZAAAAAgUAAAAHYWNjb3VudAUAAAAEdHhJZAkBAAAAD3BlbmRpbmdTd2FwREFUQQAAAAMFAAAACHN3YXBUeXBlBQAAAAZhbW91bnQFAAAAEHNlbGZVbmxvY2tIZWlnaHQFAAAAA25pbAUAAAAJbGVhc2VQYXJ0BQAAAAR1bml0CQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAA5jb21tb25XaXRoZHJhdwAAAAQAAAAHYWNjb3VudAAAAAVpbmRleAAAAAhzd2FwVHhJZAAAAAZyc2FTaWcEAAAAC3VzZXJBZGRyZXNzCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAAAdhY2NvdW50BAAAAAtjaGVja0NhbGxlcgkBAAAACHRoaXNPbmx5AAAAAQUAAAABaQMJAAAAAAAAAgUAAAALY2hlY2tDYWxsZXIFAAAAC2NoZWNrQ2FsbGVyBAAAAAlkYXRhQXJyYXkJAQAAABJzd2FwRGF0YUZhaWxPclJFQUQAAAACBQAAAAdhY2NvdW50BQAAAAhzd2FwVHhJZAQAAAAQc2VsZlVubG9ja0hlaWdodAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAUc0lkeFNlbGZVbmxvY2tIZWlnaHQEAAAACHN3YXBUeXBlCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAMc0lkeFN3YXBUeXBlBAAAAAhpbkFtb3VudAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAMc0lkeEluQW1vdW50BAAAAApzd2FwU3RhdHVzCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAAKc0lkeFN0YXR1cwQAAAALc3RhcnRIZWlnaHQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAD3NJZHhTdGFydEhlaWdodAQAAAAHaXNRdWljawkAAAAAAAACCQABkQAAAAIFAAAACWRhdGFBcnJheQUAAAALc0lkeElzUXVpY2sCAAAABHRydWUEAAAADWNoZWNrU3dhcFR5cGUDAwkBAAAAAiE9AAAAAgUAAAAIc3dhcFR5cGUCAAAABXdhdmVzCQEAAAACIT0AAAACBQAAAAhzd2FwVHlwZQIAAAAIbmV1dHJpbm8HCQAAAgAAAAEJAAEsAAAAAgIAAAAWVW5zdXBwb3J0ZWQgc3dhcCB0eXBlIAUAAAAIc3dhcFR5cGUGAwkAAAAAAAACBQAAAA1jaGVja1N3YXBUeXBlBQAAAA1jaGVja1N3YXBUeXBlBAAAAApvdXRGZWVQYXJ0CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAAA1vdXRGZWVQYXJ0S0VZAAAAAQUAAAAIc3dhcFR5cGUFAAAADkRFRkFVTFRTV0FQRkVFBAAAAAt0b3RhbExvY2tlZAkBAAAAD3RvdGFsTG9ja2VkUkVBRAAAAAEFAAAACHN3YXBUeXBlBAAAABF0b3RhbExvY2tlZEJ5VXNlcgkBAAAAFXRvdGFsTG9ja2VkQnlVc2VyUkVBRAAAAAIFAAAACHN3YXBUeXBlBQAAAAdhY2NvdW50BAAAABBtaW5NYXhSYW5kc1R1cGxlCQAFFAAAAAIJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAlkYXRhQXJyYXkFAAAAC3NJZHhNaW5SYW5kCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAJZGF0YUFycmF5BQAAAAtzSWR4TWF4UmFuZAQAAAAMdW5sb2NrSGVpZ2h0AwUAAAAHaXNRdWljawkAAGQAAAACBQAAAAtzdGFydEhlaWdodAkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwUAAAARa2V5UXVpY2tTd2FwRGVsYXkDCQAAAAAAAAIFAAAABnJzYVNpZwEAAAAABQAAABBzZWxmVW5sb2NrSGVpZ2h0CQEAAAAWcmFuZFVubG9ja0hlaWdodE9yRmFpbAAAAAUFAAAACHN3YXBUeElkBQAAAAZyc2FTaWcFAAAACHN3YXBUeXBlBQAAAAtzdGFydEhlaWdodAUAAAAQbWluTWF4UmFuZHNUdXBsZQQAAAALaW5kZXhIZWlnaHQJAQAAABVnZXRIZWlnaHRQcmljZUJ5SW5kZXgAAAABBQAAAAVpbmRleAQAAAAPcHJldkluZGV4SGVpZ2h0CQEAAAAVZ2V0SGVpZ2h0UHJpY2VCeUluZGV4AAAAAQkAAGUAAAACBQAAAAVpbmRleAAAAAAAAAAAAQQAAAAMcHJpY2VCeUluZGV4CQEAAAAPZ2V0UHJpY2VIaXN0b3J5AAAAAQUAAAALaW5kZXhIZWlnaHQEAAAADSR0MDIyNDg1MjI2ODEDCQAAAAAAAAIFAAAACHN3YXBUeXBlAgAAAAV3YXZlcwkABRQAAAACCQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAIFAAAACGluQW1vdW50BQAAAAxwcmljZUJ5SW5kZXgFAAAAD25ldXRyaW5vQXNzZXRJZAkABRQAAAACCQEAAAAWY29udmVydE5ldXRyaW5vVG9XYXZlcwAAAAIFAAAACGluQW1vdW50BQAAAAxwcmljZUJ5SW5kZXgFAAAABHVuaXQEAAAADm91dEFtb3VudEdyb3NzCAUAAAANJHQwMjI0ODUyMjY4MQAAAAJfMQQAAAAIb3V0QXNzZXQIBQAAAA0kdDAyMjQ4NTIyNjgxAAAAAl8yBAAAAAxwYXlvdXRzQXJyYXkJAQAAAAlhcHBseUZlZXMAAAACBQAAAA5vdXRBbW91bnRHcm9zcwUAAAAKb3V0RmVlUGFydAQAAAAMb3V0TmV0QW1vdW50CQABkQAAAAIFAAAADHBheW91dHNBcnJheQUAAAAMSWR4TmV0QW1vdW50BAAAAAxvdXRGZWVBbW91bnQJAAGRAAAAAgUAAAAMcGF5b3V0c0FycmF5BQAAAAxJZHhGZWVBbW91bnQEAAAABmNoZWNrcwkABEwAAAACAwUAAAAJaXNCbG9ja2VkCQEAAAAVZW1lcmdlbmN5U2h1dGRvd25GQUlMAAAAAAYJAARMAAAAAgMJAQAAAAIhPQAAAAIFAAAACnN3YXBTdGF0dXMCAAAAB1BFTkRJTkcJAAACAAAAAQIAAAAfc3dhcCBoYXMgYmVlbiBhbHJlYWR5IHByb2Nlc3NlZAYJAARMAAAAAgMJAABmAAAAAgUAAAAMdW5sb2NrSGVpZ2h0BQAAAAZoZWlnaHQJAAACAAAAAQkAASwAAAACCQABLAAAAAICAAAAEXBsZWFzZSB3YWl0IGZvcjogCQABpAAAAAEFAAAADHVubG9ja0hlaWdodAIAAAAfIGJsb2NrIGhlaWdodCB0byB3aXRoZHJhdyBmdW5kcwYJAARMAAAAAgMDAwkAAGYAAAACBQAAAAVpbmRleAUAAAAKcHJpY2VJbmRleAYJAABmAAAAAgUAAAAMdW5sb2NrSGVpZ2h0BQAAAAtpbmRleEhlaWdodAYDCQEAAAACIT0AAAACBQAAAA9wcmV2SW5kZXhIZWlnaHQAAAAAAAAAAAAJAABnAAAAAgUAAAAPcHJldkluZGV4SGVpZ2h0BQAAAAx1bmxvY2tIZWlnaHQHCQEAAAAOcHJpY2VJbmRleEZBSUwAAAAFBQAAAAVpbmRleAUAAAAKcHJpY2VJbmRleAUAAAALaW5kZXhIZWlnaHQFAAAADHVubG9ja0hlaWdodAUAAAAPcHJldkluZGV4SGVpZ2h0BgkABEwAAAACAwkAAGcAAAACAAAAAAAAAAAACQABkQAAAAIFAAAA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AAAAAXIAAAACXzEIBQAAAAFyAAAAAl8yCQAAAgAAAAECAAAAElR5cGUgY2FzdGluZyBlcnJvcgQAAAATcXVpY2tTd2FwTGltaXRUb3RhbAgFAAAADSR0MDI2NzM0MjY5NDIAAAACXzEEAAAAEnF1aWNrU3dhcFVzZXJTcGVudAgFAAAADSR0MDI2NzM0MjY5NDIAAAACXzIEAAAADnF1aWNrU3dhcExpbWl0CQAAZQAAAAIFAAAAE3F1aWNrU3dhcExpbWl0VG90YWwFAAAAEnF1aWNrU3dhcFVzZXJTcGVudAQAAAAMcHJpY2VCeUluZGV4CQEAAAAPZ2V0UHJpY2VIaXN0b3J5AAAAAQkBAAAAFWdldEhlaWdodFByaWNlQnlJbmRleAAAAAEFAAAACnByaWNlSW5kZXgEAAAADnN3YXBVc2RuVm9sdW1lAwkAAAAAAAACBQAAAAhzd2FwVHlwZQIAAAAIbmV1dHJpbm8FAAAACGluQW1vdW50CQEAAAAWY29udmVydFdhdmVzVG9OZXV0cmlubwAAAAIFAAAACGluQW1vdW50BQAAAAxwcmljZUJ5SW5kZXgEAAAABmNoZWNrcwkABEwAAAACAwkBAAAAAiE9AAAAAgUAAAAKc3dhcFN0YXR1cwIAAAAHUEVORElORwkAAAIAAAABAgAAAB9Td2FwIGhhcyBiZWVuIGFscmVhZHkgcHJvY2Vzc2VkBgkABEwAAAACAwUAAAAHaXNRdWljawkAAAIAAAABAgAAACFTd2FwIGhhcyBiZWVuIGFscmVhZHkgYWNjZWxlcmF0ZWQGCQAETAAAAAIDCQAAZgAAAAIFAAAADnN3YXBVc2RuVm9sdW1lBQAAAA5xdWlja1N3YXBMaW1pdAkAAAIAAAABAgAAACdZb3UgaGF2ZSBleGNlZWRlZCB0aGUgcXVpY2sgc3dhcHMgbGltaXQGBQAAAANuaWwDCQAAAAAAAAIFAAAABmNoZWNrcwUAAAAGY2hlY2tzCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAda2V5UXVpY2tTd2FwVXNlclNwZW50SW5QZXJpb2QAAAABBQAAAAt1c2VyQWRkcmVzcwkAAGQAAAACBQAAAA5zd2FwVXNkblZvbHVtZQUAAAAScXVpY2tTd2FwVXNlclNwZW50CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAAaa2V5VXNlckxhc3RRdWlja1N3YXBIZWlnaHQAAAABBQAAAAt1c2VyQWRkcmVzcwUAAAAGaGVpZ2h0CQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAAdzd2FwS0VZAAAAAgUAAAAHYWNjb3VudAUAAAAIc3dhcFR4SWQJAQAAABJhY2NlbGVyYXRlU3dhcERBVEEAAAABBQAAAAlkYXRhQXJyYXkFAAAAA25pbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAACHdpdGhkcmF3AAAAAwAAAAdhY2NvdW50AAAABWluZGV4AAAACHN3YXBUeElkBAAAAAZyZXN1bHQJAAP8AAAABAUAAAAEdGhpcwIAAAAOY29tbW9uV2l0aGRyYXcJAARMAAAAAgUAAAAHYWNjb3VudAkABEwAAAACBQAAAAVpbmRleAkABEwAAAACBQAAAAhzd2FwVHhJZAkABEwAAAACAQAAAAAFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAAAZyZXN1bHQFAAAABnJlc3VsdAUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAAx3aXRoZHJhd1JhbmQAAAAEAAAAB2FjY291bnQAAAAFaW5kZXgAAAAIc3dhcFR4SWQAAAAGcnNhU2lnBAAAAAZyZXN1bHQJAAP8AAAABAUAAAAEdGhpcwIAAAAOY29tbW9uV2l0aGRyYXcJAARMAAAAAgUAAAAHYWNjb3VudAkABEwAAAACBQAAAAVpbmRleAkABEwAAAACBQAAAAhzd2FwVHhJZAkABEwAAAACBQAAAAZyc2FTaWcFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAAAZyZXN1bHQFAAAABnJlc3VsdAUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAABF0cmFuc2ZlclRvQXVjdGlvbgAAAAAEAAAAD2F1Y3Rpb25OQkFtb3VudAkAAGUAAAACBQAAAA5uZXV0cmlub1N1cHBseQkAA/AAAAACCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAAA9hdWN0aW9uQ29udHJhY3QFAAAAC2JvbmRBc3NldElkBAAAABZzdXJwbHVzV2l0aExpcXVpZGF0aW9uCQAAZQAAAAIFAAAAB3N1cnBsdXMJAAPwAAAAAgkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAATbGlxdWlkYXRpb25Db250cmFjdAUAAAAPbmV1dHJpbm9Bc3NldElkAwUAAAAJaXNCbG9ja2VkCQAAAgAAAAECAAAAWmNvbnRyYWN0IGlzIGJsb2NrZWQgYnkgRU1FUkdFTkNZIFNIVVRET1dOIGFjdGlvbnMgdW50aWxsIHJlYWN0aXZhdGlvbiBieSBlbWVyZ2VuY3kgb3JhY2xlcwMJAABmAAAAAgUAAAAPYXVjdGlvbk5CQW1vdW50CQAAaAAAAAIAAAAAAAAAAAEFAAAABVBBVUxJCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAAD2F1Y3Rpb25Db250cmFjdAUAAAAPYXVjdGlvbk5CQW1vdW50BQAAAAtib25kQXNzZXRJZAUAAAADbmlsAwkAAGcAAAACBQAAABZzdXJwbHVzV2l0aExpcXVpZGF0aW9uCQAAaAAAAAIAAAAAAAAAAAEFAAAABVBBVUxJCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAAE2xpcXVpZGF0aW9uQ29udHJhY3QFAAAAFnN1cnBsdXNXaXRoTGlxdWlkYXRpb24FAAAAD25ldXRyaW5vQXNzZXRJZAUAAAADbmlsCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAvYm9uZCB3ZXJlIGdlbmVyYXRlZCBvciBkbyBub3QgbmVlZCBpdC4gRGVmaWNpdDoJAAGkAAAAAQUAAAAPYXVjdGlvbk5CQW1vdW50AgAAAAF8CQABpAAAAAEAAAAAAAAAAAACAAAACi4gU3VycGx1czoJAAGkAAAAAQUAAAAWc3VycGx1c1dpdGhMaXF1aWRhdGlvbgIAAAABfAkAAaQAAAABBQAAAAdzdXJwbHVzAAAAAWkBAAAAC2FjY2VwdFdhdmVzAAAAAAMJAQAAAAIhPQAAAAIIBQAAAAFpAAAABmNhbGxlcgkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAAPYXVjdGlvbkNvbnRyYWN0CQAAAgAAAAECAAAAMkN1cnJlbnRseSBvbmx5IGF1Y3Rpb24gY29udHJhY3QgaXMgYWxsb3dlZCB0byBjYWxsCQAFFAAAAAIJAQAAABZwcmVwYXJlVW5sZWFzZUFuZExlYXNlAAAAAQAAAAAAAAAAAAIAAAAHc3VjY2VzcwAAAAFpAQAAAB9jYWxjVG90YWxRdWlja1N3YXBMaW1pdFJFQURPTkxZAAAAAQAAAAtnTnNidEFtb3VudAQAAAANJHQwMjk5MDkyOTk2NgkBAAAAEGdldERvcmEyTlNCVEluZm8AAAAABAAAAAluc2J0UHJpY2UIBQAAAA0kdDAyOTkwOTI5OTY2AAAAAl8xBAAAABNuc2J0UHJpY2VMYXN0SGVpZ2h0CAUAAAANJHQwMjk5MDkyOTk2NgAAAAJfMgQAAAAFY2hlY2sDCQAAZgAAAAIJAABlAAAAAgUAAAAGaGVpZ2h0BQAAABNuc2J0UHJpY2VMYXN0SGVpZ2h0CQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAAR0aGlzBQAAABdrZXlEb3JhMkxhc3RIZWlnaHRMaW1pdAkAAAIAAAABAgAAABZOU0JUIHByaWNlIGlzIG91dGRhdGVkBgMJAAAAAAAAAgUAAAAFY2hlY2sFAAAABWNoZWNrCQAFFAAAAAIFAAAAA25pbAkAAGsAAAADBQAAAAtnTnNidEFtb3VudAUAAAAJbnNidFByaWNlBQAAAAdXQVZFTEVUCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAABZxdWlja1N3YXBMaW1pdFJFQURPTkxZAAAAAQAAAA51c2VyQWRkcmVzc1N0cgQAAAALdXNlckFkZHJlc3MJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAADnVzZXJBZGRyZXNzU3RyBAAAAA91c2VyR05zYnRBbW91bnQJAQAAAAVhc0ludAAAAAEJAAP8AAAABAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkBAAAAEUBleHRyTmF0aXZlKDEwNTMpAAAAAgUAAAAEdGhpcwUAAAATa2V5TnNidExvY2tDb250cmFjdAIAAAATZ05zYnRBbW91bnRSRUFET05MWQkABEwAAAACCQAEJQAAAAEFAAAAC3VzZXJBZGRyZXNzBQAAAANuaWwFAAAAA25pbAMJAAAAAAAAAgUAAAAPdXNlckdOc2J0QW1vdW50BQAAAA91c2VyR05zYnRBbW91bnQEAAAAE3F1aWNrU3dhcExpbWl0VG90YWwJAQAAAAVhc0ludAAAAAEJAAP8AAAABAUAAAAEdGhpcwIAAAAfY2FsY1RvdGFsUXVpY2tTd2FwTGltaXRSRUFET05MWQkABEwAAAACBQAAAA91c2VyR05zYnRBbW91bnQFAAAAA25pbAUAAAADbmlsAwkAAAAAAAACBQAAABNxdWlja1N3YXBMaW1pdFRvdGFsBQAAABNxdWlja1N3YXBMaW1pdFRvdGFsBAAAABRpc05ld1F1aWNrU3dhcFBlcmlvZAkAAGYAAAACCQAAZQAAAAIFAAAABmhlaWdodAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAaa2V5VXNlckxhc3RRdWlja1N3YXBIZWlnaHQAAAABBQAAAAt1c2VyQWRkcmVzcwAAAAAAAAAAAAkBAAAAEUBleHRyTmF0aXZlKDEwNTApAAAAAgUAAAAEdGhpcwUAAAAZa2V5UXVpY2tTd2FwTGltaXREdXJhdGlvbgQAAAAScXVpY2tTd2FwVXNlclNwZW50AwUAAAAUaXNOZXdRdWlja1N3YXBQZXJpb2QAAAAAAAAAAAAJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwkBAAAAHWtleVF1aWNrU3dhcFVzZXJTcGVudEluUGVyaW9kAAAAAQUAAAALdXNlckFkZHJlc3MAAAAAAAAAAAAJAAUUAAAAAgUAAAADbmlsCQAFFAAAAAIFAAAAE3F1aWNrU3dhcExpbWl0VG90YWwFAAAAEnF1aWNrU3dhcFVzZXJTcGVudAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAQAAAAJ0eAEAAAAGdmVyaWZ5AAAAAAQAAAACaWQJAAJYAAAAAQgFAAAAAnR4AAAAAmlkBAAAABNtaW5TaWduYXR1cmVzTnVtYmVyAAAAAAAAAAADBAAAAAVjb3VudAkAAGQAAAACCQAAZAAAAAIJAABkAAAAAgMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAACQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAABCQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAQAAAAAAAAAAAQAAAAAAAAAAAAMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAACCQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAgAAAAAAAAAAAQAAAAAAAAAAAAMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAADCQACWQAAAAEJAAGRAAAAAgUAAAAQcHViS2V5QWRtaW5zTGlzdAAAAAAAAAAAAwAAAAAAAAAAAgAAAAAAAAAAAAQAAAARaXNTaWduYXR1cmVzVmFsaWQJAABnAAAAAgUAAAAFY291bnQFAAAAE21pblNpZ25hdHVyZXNOdW1iZXIEAAAAByRtYXRjaDAFAAAAAnR4AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAABVTcG9uc29yRmVlVHJhbnNhY3Rpb24EAAAACXNwb25zb3JUeAUAAAAHJG1hdGNoMAMFAAAAEWlzU2lnbmF0dXJlc1ZhbGlkCQEAAAAbY2hlY2tJc1ZhbGlkTWluU3BvbnNvcmVkRmVlAAAAAQUAAAAJc3BvbnNvclR4BwUAAAARaXNTaWduYXR1cmVzVmFsaWSp6g9p", "height": 1885777, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
Old | New | Differences | |
---|---|---|---|
1 | - | # no script | |
1 | + | {-# STDLIB_VERSION 5 #-} | |
2 | + | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | + | {-# CONTENT_TYPE DAPP #-} | |
4 | + | func getNumberByKey (key) = valueOrElse(getInteger(this, key), 0) | |
5 | + | ||
6 | + | ||
7 | + | func getStringByKey (key) = valueOrElse(getString(this, key), "") | |
8 | + | ||
9 | + | ||
10 | + | func getBoolByKey (key) = valueOrElse(getBoolean(this, key), false) | |
11 | + | ||
12 | + | ||
13 | + | func getNumberByAddressAndKey (address,key) = valueOrElse(getInteger(addressFromStringValue(address), key), 0) | |
14 | + | ||
15 | + | ||
16 | + | func getStringByAddressAndKey (address,key) = valueOrElse(getString(addressFromStringValue(address), key), "") | |
17 | + | ||
18 | + | ||
19 | + | func getBoolByAddressAndKey (address,key) = valueOrElse(getBoolean(addressFromStringValue(address), key), false) | |
20 | + | ||
21 | + | ||
22 | + | let pubKeyAdminsList = ["GJdLSaLiv5K7xuejac8mcRcHoyo3dPrESrvktG3a6MAR", "FWVffYr2ALmHMejZm3WqeLz6Sdym3gLFGtJn4KTwyU5x", "3Wh2LaWcb5gg7K2pPcW3Ep6EAuRBzYkAgrdpt43jTDFa", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"] | |
23 | + | ||
24 | + | func asInt (val) = match val { | |
25 | + | case valInt: Int => | |
26 | + | valInt | |
27 | + | case _ => | |
28 | + | throw("Failed to cast into Int") | |
29 | + | } | |
30 | + | ||
31 | + | ||
32 | + | let SEP = "__" | |
33 | + | ||
34 | + | let WAVELET = 100000000 | |
35 | + | ||
36 | + | let PAULI = 1000000 | |
37 | + | ||
38 | + | let PRICELET = 1000000 | |
39 | + | ||
40 | + | let DEFAULTSWAPFEE = 20000 | |
41 | + | ||
42 | + | let IdxNetAmount = 0 | |
43 | + | ||
44 | + | let IdxFeeAmount = 1 | |
45 | + | ||
46 | + | let IdxGrossAmount = 2 | |
47 | + | ||
48 | + | let dora2NsbtSymbol = "NSBT-USDT" | |
49 | + | ||
50 | + | let minRand = 60 | |
51 | + | ||
52 | + | let maxRand = 1440 | |
53 | + | ||
54 | + | let NeutrinoAssetIdKey = "neutrino_asset_id" | |
55 | + | ||
56 | + | let BondAssetIdKey = "bond_asset_id" | |
57 | + | ||
58 | + | let AuctionContractKey = "auction_contract" | |
59 | + | ||
60 | + | let LiquidationContractKey = "liquidation_contract" | |
61 | + | ||
62 | + | let RPDContractKey = "rpd_contract" | |
63 | + | ||
64 | + | let ControlContractKey = "control_contract" | |
65 | + | ||
66 | + | let BalanceWavesLockIntervalKey = "balance_waves_lock_interval" | |
67 | + | ||
68 | + | let BalanceNeutrinoLockIntervalKey = "balance_neutrino_lock_interval" | |
69 | + | ||
70 | + | let MinWavesSwapAmountKey = "min_waves_swap_amount" | |
71 | + | ||
72 | + | let MinNeutrinoSwapAmountKey = "min_neutrino_swap_amount" | |
73 | + | ||
74 | + | let NodeOracleProviderPubKeyKey = "node_oracle_provider" | |
75 | + | ||
76 | + | let NeutrinoOutFeePartKey = "neutrinoOut_swap_feePart" | |
77 | + | ||
78 | + | let WavesOutFeePartKey = "wavesOut_swap_feePart" | |
79 | + | ||
80 | + | let RsaRandPublic58Key = "rand_rsa_public" | |
81 | + | ||
82 | + | let keyGNsbtContract = "%s__gNsbtContract" | |
83 | + | ||
84 | + | let keyNsbtLockContract = "%s__nsbtLockContract" | |
85 | + | ||
86 | + | let keyDora2Contract = "%s__dora2Contract" | |
87 | + | ||
88 | + | let keyQuickSwapDelay = "%s__quickSwapDelay" | |
89 | + | ||
90 | + | let keyQuickSwapLimitDuration = "%s__quickSwapLimitDuration" | |
91 | + | ||
92 | + | let keyDora2LastHeightLimit = "%s__dora2LastHeightLimit" | |
93 | + | ||
94 | + | let PriceKey = "price" | |
95 | + | ||
96 | + | let PriceIndexKey = "price_index" | |
97 | + | ||
98 | + | let IsBlockedKey = "is_blocked" | |
99 | + | ||
100 | + | func getPriceHistoryKey (block) = ((PriceKey + "_") + toString(block)) | |
101 | + | ||
102 | + | ||
103 | + | func getHeightPriceByIndexKey (index) = ((PriceIndexKey + "_") + toString(index)) | |
104 | + | ||
105 | + | ||
106 | + | func getStakingNodeByIndex (idx) = getStringByKey(makeString(["%s%d%s", "lease", toString(idx), "nodeAddress"], SEP)) | |
107 | + | ||
108 | + | ||
109 | + | func getStakingNodeAddressByIndex (idx) = addressFromStringValue(getStakingNodeByIndex(idx)) | |
110 | + | ||
111 | + | ||
112 | + | func getReservedAmountForSponsorship () = valueOrElse(getInteger(this, makeString(["%s%s", "lease", "sponsorshipWavesReserve"], SEP)), (1000 * WAVELET)) | |
113 | + | ||
114 | + | ||
115 | + | func getBalanceUnlockBlockKey (owner) = ("balance_unlock_block_" + owner) | |
116 | + | ||
117 | + | ||
118 | + | func getLeaseIdKey (nodeIndex) = makeString(["%s%d%s", "lease", toString(nodeIndex), "id"], SEP) | |
119 | + | ||
120 | + | ||
121 | + | func getLeaseAmountKey (nodeIndex) = makeString(["%s%d%s", "lease", toString(nodeIndex), "amount"], SEP) | |
122 | + | ||
123 | + | ||
124 | + | func minSwapAmountKEY (swapType) = (("min_" + swapType) + "_swap_amount") | |
125 | + | ||
126 | + | ||
127 | + | func totalLockedKEY (swapType) = ("balance_lock_" + swapType) | |
128 | + | ||
129 | + | ||
130 | + | func totalLockedByUserKEY (swapType,owner) = makeString(["balance_lock", swapType, owner], "_") | |
131 | + | ||
132 | + | ||
133 | + | func balanceLockIntervalKEY (swapType) = (("balance_" + swapType) + "_lock_interval") | |
134 | + | ||
135 | + | ||
136 | + | func minBalanceLockIntervalKEY (swapType) = (("balance_" + swapType) + "_lock_interval_minimum") | |
137 | + | ||
138 | + | ||
139 | + | func nodeBalanceLockIntervalKEY () = "balance_node_lock_interval" | |
140 | + | ||
141 | + | ||
142 | + | func outFeePartKEY (swapType) = (swapType + "Out_swap_feePart") | |
143 | + | ||
144 | + | ||
145 | + | func keyQuickSwapUserSpentInPeriod (userAddress) = makeString(["%s%s", "quickSwapUserSpentInPeriod", toString(userAddress)], SEP) | |
146 | + | ||
147 | + | ||
148 | + | func keyUserLastQuickSwapHeight (userAddress) = makeString(["%s%s", "userLastQuickSwapHeight", toString(userAddress)], SEP) | |
149 | + | ||
150 | + | ||
151 | + | func keyDora2Price (symbol) = makeString(["%s%s", "price", symbol], SEP) | |
152 | + | ||
153 | + | ||
154 | + | func keyDora2LastHeight (symbol) = makeString(["%s%s", "lastHeight", symbol], SEP) | |
155 | + | ||
156 | + | ||
157 | + | func minSwapAmountREAD (swapType) = valueOrElse(getInteger(this, minSwapAmountKEY(swapType)), 0) | |
158 | + | ||
159 | + | ||
160 | + | func totalLockedREAD (swapType) = valueOrElse(getInteger(this, totalLockedKEY(swapType)), 0) | |
161 | + | ||
162 | + | ||
163 | + | func totalLockedByUserREAD (swapType,owner) = valueOrElse(getInteger(this, totalLockedByUserKEY(swapType, owner)), 0) | |
164 | + | ||
165 | + | ||
166 | + | func balanceLockIntervalREAD (swapType) = valueOrElse(getInteger(this, balanceLockIntervalKEY(swapType)), maxRand) | |
167 | + | ||
168 | + | ||
169 | + | func minBalanceLockIntervalREAD (swapType) = valueOrElse(getInteger(this, minBalanceLockIntervalKEY(swapType)), minRand) | |
170 | + | ||
171 | + | ||
172 | + | func nodeBalanceLockIntervalREAD () = valueOrElse(getInteger(this, nodeBalanceLockIntervalKEY()), 1) | |
173 | + | ||
174 | + | ||
175 | + | func convertNeutrinoToWaves (amount,price) = fraction(fraction(amount, PRICELET, price), WAVELET, PAULI) | |
176 | + | ||
177 | + | ||
178 | + | func convertWavesToNeutrino (amount,price) = fraction(fraction(amount, price, PRICELET), PAULI, WAVELET) | |
179 | + | ||
180 | + | ||
181 | + | func convertWavesToBond (amount,price) = convertWavesToNeutrino(amount, price) | |
182 | + | ||
183 | + | ||
184 | + | func convertJsonArrayToList (jsonArray) = split(jsonArray, ",") | |
185 | + | ||
186 | + | ||
187 | + | func minSwapAmountFAIL (swapType,minSwapAmount) = throw(((("The specified amount in " + swapType) + " swap is less than the required minimum of ") + toString(minSwapAmount))) | |
188 | + | ||
189 | + | ||
190 | + | func emergencyShutdownFAIL () = throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles") | |
191 | + | ||
192 | + | ||
193 | + | 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))) | |
194 | + | ||
195 | + | ||
196 | + | let liquidationContract = getStringByKey(LiquidationContractKey) | |
197 | + | ||
198 | + | let neutrinoAssetId = fromBase58String(getStringByKey(NeutrinoAssetIdKey)) | |
199 | + | ||
200 | + | let auctionContract = getStringByKey(AuctionContractKey) | |
201 | + | ||
202 | + | let rpdContract = getStringByKey(RPDContractKey) | |
203 | + | ||
204 | + | let controlContract = getStringByKey(ControlContractKey) | |
205 | + | ||
206 | + | let priceIndex = getNumberByAddressAndKey(controlContract, PriceIndexKey) | |
207 | + | ||
208 | + | let isBlocked = getBoolByAddressAndKey(controlContract, IsBlockedKey) | |
209 | + | ||
210 | + | let nodeOracleProviderPubKey = fromBase58String(getStringByKey(NodeOracleProviderPubKeyKey)) | |
211 | + | ||
212 | + | let bondAssetId = fromBase58String("6nSpVyNH7yM69eg446wrQR94ipbbcmZMU1ENPwanC97g") | |
213 | + | ||
214 | + | let deprecatedBondAssetId = fromBase58String("975akZBfnMj513U7MZaHKzQrmsEx5aE3wdWKTrHBhbjF") | |
215 | + | ||
216 | + | let rsaPub = fromBase64String(valueOrErrorMessage(getString(this, RsaRandPublic58Key), "RSA public key has not been specified")) | |
217 | + | ||
218 | + | let neutrinoContract = this | |
219 | + | ||
220 | + | let currentPrice = getNumberByAddressAndKey(controlContract, PriceKey) | |
221 | + | ||
222 | + | let neutrinoLockedBalance = totalLockedREAD("neutrino") | |
223 | + | ||
224 | + | let wavesLockedBalance = totalLockedREAD("waves") | |
225 | + | ||
226 | + | let reserve = (wavesBalance(neutrinoContract).regular - wavesLockedBalance) | |
227 | + | ||
228 | + | let neutrinoSupply = (((neutrinoLockedBalance + value(assetInfo(neutrinoAssetId)).quantity) - assetBalance(neutrinoContract, neutrinoAssetId)) - assetBalance(addressFromStringValue(liquidationContract), neutrinoAssetId)) | |
229 | + | ||
230 | + | let surplus = (convertWavesToNeutrino(reserve, currentPrice) - neutrinoSupply) | |
231 | + | ||
232 | + | let deficit = (neutrinoSupply - convertWavesToNeutrino(reserve, currentPrice)) | |
233 | + | ||
234 | + | func checkIsValidMinSponsoredFee (tx) = { | |
235 | + | let MINTRANSFERFEE = 100000 | |
236 | + | let SponsoredFeeUpperBound = 1000 | |
237 | + | let realNeutrinoFee = convertWavesToNeutrino(MINTRANSFERFEE, currentPrice) | |
238 | + | let minNeutrinoFee = (realNeutrinoFee * 2) | |
239 | + | let maxNeutrinoFee = fraction(realNeutrinoFee, SponsoredFeeUpperBound, 100) | |
240 | + | let inputFee = value(tx.minSponsoredAssetFee) | |
241 | + | if (if ((inputFee >= minNeutrinoFee)) | |
242 | + | then (maxNeutrinoFee >= inputFee) | |
243 | + | else false) | |
244 | + | then (tx.assetId == neutrinoAssetId) | |
245 | + | else false | |
246 | + | } | |
247 | + | ||
248 | + | ||
249 | + | func getPriceHistory (block) = getNumberByAddressAndKey(controlContract, getPriceHistoryKey(block)) | |
250 | + | ||
251 | + | ||
252 | + | func getHeightPriceByIndex (index) = getNumberByAddressAndKey(controlContract, getHeightPriceByIndexKey(index)) | |
253 | + | ||
254 | + | ||
255 | + | let sIdxSwapType = 1 | |
256 | + | ||
257 | + | let sIdxStatus = 2 | |
258 | + | ||
259 | + | let sIdxInAmount = 3 | |
260 | + | ||
261 | + | let sIdxPrice = 4 | |
262 | + | ||
263 | + | let sIdxOutNetAmount = 5 | |
264 | + | ||
265 | + | let sIdxOutFeeAmount = 6 | |
266 | + | ||
267 | + | let sIdxStartHeight = 7 | |
268 | + | ||
269 | + | let sIdxStartTimestamp = 8 | |
270 | + | ||
271 | + | let sIdxEndHeight = 9 | |
272 | + | ||
273 | + | let sIdxEndTimestamp = 10 | |
274 | + | ||
275 | + | let sIdxSelfUnlockHeight = 11 | |
276 | + | ||
277 | + | let sIdxRandUnlockHeight = 12 | |
278 | + | ||
279 | + | let sIdxIndex = 13 | |
280 | + | ||
281 | + | let sIdxWithdrawTxId = 14 | |
282 | + | ||
283 | + | let sIdxMinRand = 15 | |
284 | + | ||
285 | + | let sIdxMaxRand = 16 | |
286 | + | ||
287 | + | let sIdxIsQuick = 17 | |
288 | + | ||
289 | + | func swapKEY (userAddress,txId) = makeString(["%s%s", userAddress, txId], SEP) | |
290 | + | ||
291 | + | ||
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) | |
293 | + | ||
294 | + | ||
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)) | |
296 | + | ||
297 | + | ||
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]) | |
302 | + | ||
303 | + | ||
304 | + | func swapDataFailOrREAD (userAddress,swapTxId) = { | |
305 | + | let swapKey = swapKEY(userAddress, swapTxId) | |
306 | + | split(valueOrErrorMessage(getString(this, swapKey), ("no swap data for " + swapKey)), SEP) | |
307 | + | } | |
308 | + | ||
309 | + | ||
310 | + | func applyFees (amountGross,feePart) = { | |
311 | + | let feeAmount = fraction(amountGross, feePart, PAULI) | |
312 | + | [(amountGross - feeAmount), feeAmount, amountGross] | |
313 | + | } | |
314 | + | ||
315 | + | ||
316 | + | func randUnlockHeightOrFail (txId,rsaSig,swapType,startHeight,minMaxRandsTuple) = { | |
317 | + | let isRsaValid = rsaVerify_16Kb(SHA256, toBytes(txId), rsaSig, rsaPub) | |
318 | + | if (!(isRsaValid)) | |
319 | + | then throw("invalid RSA signature") | |
320 | + | else { | |
321 | + | let minBalanceLockInterval = minMaxRandsTuple._1 | |
322 | + | let maxBalanceLockInterval = minMaxRandsTuple._2 | |
323 | + | let rand = (toInt(sha256_16Kb(rsaSig)) % (maxBalanceLockInterval - minBalanceLockInterval)) | |
324 | + | let randLockInterval = (minBalanceLockInterval + (if ((0 > rand)) | |
325 | + | then -(rand) | |
326 | + | else rand)) | |
327 | + | (startHeight + randLockInterval) | |
328 | + | } | |
329 | + | } | |
330 | + | ||
331 | + | ||
332 | + | func abs (x) = if ((0 > x)) | |
333 | + | then -(x) | |
334 | + | else x | |
335 | + | ||
336 | + | ||
337 | + | func selectNode (unleaseAmount) = { | |
338 | + | let amountToLease = ((wavesBalance(neutrinoContract).available - unleaseAmount) - getReservedAmountForSponsorship()) | |
339 | + | let oldLeased0 = getNumberByKey(getLeaseAmountKey(0)) | |
340 | + | let oldLeased1 = getNumberByKey(getLeaseAmountKey(1)) | |
341 | + | let newLeased0 = (amountToLease + oldLeased0) | |
342 | + | let newLeased1 = (amountToLease + oldLeased1) | |
343 | + | if (if ((newLeased0 > 0)) | |
344 | + | then true | |
345 | + | else (newLeased1 > 0)) | |
346 | + | then { | |
347 | + | let delta0 = abs((newLeased0 - oldLeased1)) | |
348 | + | let delta1 = abs((newLeased1 - oldLeased0)) | |
349 | + | if ((delta1 >= delta0)) | |
350 | + | then $Tuple2(0, newLeased0) | |
351 | + | else $Tuple2(1, newLeased1) | |
352 | + | } | |
353 | + | else $Tuple2(-1, 0) | |
354 | + | } | |
355 | + | ||
356 | + | ||
357 | + | func prepareUnleaseAndLease (unleaseAmount) = { | |
358 | + | let $t01621216300 = selectNode(unleaseAmount) | |
359 | + | let nodeIndex = $t01621216300._1 | |
360 | + | let newLeaseAmount = $t01621216300._2 | |
361 | + | if ((newLeaseAmount > 0)) | |
362 | + | then { | |
363 | + | let leaseIdKey = getLeaseIdKey(nodeIndex) | |
364 | + | let oldLease = getBinary(this, leaseIdKey) | |
365 | + | let unleaseOrEmpty = if (isDefined(oldLease)) | |
366 | + | then [LeaseCancel(value(oldLease))] | |
367 | + | else nil | |
368 | + | let leaseAmountKey = getLeaseAmountKey(nodeIndex) | |
369 | + | let lease = Lease(getStakingNodeAddressByIndex(nodeIndex), newLeaseAmount) | |
370 | + | (unleaseOrEmpty ++ [lease, BinaryEntry(leaseIdKey, calculateLeaseId(lease)), IntegerEntry(getLeaseAmountKey(nodeIndex), newLeaseAmount)]) | |
371 | + | } | |
372 | + | else nil | |
373 | + | } | |
374 | + | ||
375 | + | ||
376 | + | func getDora2NSBTInfo () = { | |
377 | + | let dora2Contract = addressFromStringValue(getStringValue(this, keyDora2Contract)) | |
378 | + | let price = valueOrErrorMessage(getInteger(dora2Contract, keyDora2Price(dora2NsbtSymbol)), "NSBT price is undefined") | |
379 | + | let lastHeight = valueOrElse(getInteger(dora2Contract, keyDora2LastHeight(dora2NsbtSymbol)), 0) | |
380 | + | $Tuple2(price, lastHeight) | |
381 | + | } | |
382 | + | ||
383 | + | ||
384 | + | func getNSBTPrice () = { | |
385 | + | let $t01725817302 = getDora2NSBTInfo() | |
386 | + | let price = $t01725817302._1 | |
387 | + | let lastHeight = $t01725817302._2 | |
388 | + | price | |
389 | + | } | |
390 | + | ||
391 | + | ||
392 | + | func thisOnly (i) = if ((i.caller != this)) | |
393 | + | then throw("Permission denied: this contract only allowed") | |
394 | + | else true | |
395 | + | ||
396 | + | ||
397 | + | @Callable(i) | |
398 | + | func prepareUnleaseAndLeaseWrapper (unleaseAmount) = { | |
399 | + | let checkCaller = [thisOnly(i)] | |
400 | + | if ((checkCaller == checkCaller)) | |
401 | + | then prepareUnleaseAndLease(unleaseAmount) | |
402 | + | else throw("Strict value is not equal to itself.") | |
403 | + | } | |
404 | + | ||
405 | + | ||
406 | + | ||
407 | + | @Callable(i) | |
408 | + | func constructor (neutrinoAssetIdPrm,bondAssetIdPrm,auctionContractPrm,liquidationContractPrm,rpdContractPrm,controlContractPrm,nodeOracleProviderPubKeyPrm,rsaRandPublicKeyPrm,balanceWavesLockIntervalPrm,balanceNeutrinoLockIntervalPrm,minWavesSwapAmountPrm,minNeutrinoSwapAmountPrm,neutrinoOutFeePartPrm,wavesOutFeePartPrm) = { | |
409 | + | let checkCaller = thisOnly(i) | |
410 | + | if ((checkCaller == checkCaller)) | |
411 | + | 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)] | |
412 | + | else throw("Strict value is not equal to itself.") | |
413 | + | } | |
414 | + | ||
415 | + | ||
416 | + | ||
417 | + | @Callable(i) | |
418 | + | func constructorV2 (gNsbtContract,nsbtLockContract,dora2Contract,quickSwapDelay,quickSwapLimitDuration,dora2LastHeightLimit) = { | |
419 | + | let checkCaller = thisOnly(i) | |
420 | + | if ((checkCaller == checkCaller)) | |
421 | + | then [StringEntry(keyGNsbtContract, gNsbtContract), StringEntry(keyNsbtLockContract, nsbtLockContract), StringEntry(keyDora2Contract, dora2Contract), IntegerEntry(keyQuickSwapDelay, quickSwapDelay), IntegerEntry(keyQuickSwapLimitDuration, quickSwapLimitDuration), IntegerEntry(keyDora2LastHeightLimit, dora2LastHeightLimit)] | |
422 | + | else throw("Strict value is not equal to itself.") | |
423 | + | } | |
424 | + | ||
425 | + | ||
426 | + | ||
427 | + | @Callable(i) | |
428 | + | func commonSwap (swapType,amount,account,txId) = { | |
429 | + | let checkCaller = thisOnly(i) | |
430 | + | if ((checkCaller == checkCaller)) | |
431 | + | then { | |
432 | + | let minSwapAmount = minSwapAmountREAD(swapType) | |
433 | + | let totalLocked = totalLockedREAD(swapType) | |
434 | + | let totalLockedByUser = totalLockedByUserREAD(swapType, account) | |
435 | + | let nodeAddress = getStakingNodeByIndex(0) | |
436 | + | let balanceLockMaxInterval = if ((nodeAddress == account)) | |
437 | + | then nodeBalanceLockIntervalREAD() | |
438 | + | else balanceLockIntervalREAD(swapType) | |
439 | + | let selfUnlockHeight = (height + balanceLockMaxInterval) | |
440 | + | if ((minSwapAmount > amount)) | |
441 | + | then minSwapAmountFAIL(swapType, minSwapAmount) | |
442 | + | else if (isBlocked) | |
443 | + | then emergencyShutdownFAIL() | |
444 | + | else { | |
445 | + | let leasePart = if ((swapType == "waves")) | |
446 | + | then prepareUnleaseAndLease(0) | |
447 | + | else nil | |
448 | + | $Tuple2(([IntegerEntry(totalLockedByUserKEY(swapType, account), (totalLockedByUser + amount)), IntegerEntry(getBalanceUnlockBlockKey(account), selfUnlockHeight), IntegerEntry(totalLockedKEY(swapType), (totalLocked + amount)), StringEntry(swapKEY(account, txId), pendingSwapDATA(swapType, amount, selfUnlockHeight))] ++ leasePart), unit) | |
449 | + | } | |
450 | + | } | |
451 | + | else throw("Strict value is not equal to itself.") | |
452 | + | } | |
453 | + | ||
454 | + | ||
455 | + | ||
456 | + | @Callable(i) | |
457 | + | func commonWithdraw (account,index,swapTxId,rsaSig) = { | |
458 | + | let userAddress = addressFromStringValue(account) | |
459 | + | let checkCaller = thisOnly(i) | |
460 | + | if ((checkCaller == checkCaller)) | |
461 | + | then { | |
462 | + | let dataArray = swapDataFailOrREAD(account, swapTxId) | |
463 | + | let selfUnlockHeight = parseIntValue(dataArray[sIdxSelfUnlockHeight]) | |
464 | + | let swapType = dataArray[sIdxSwapType] | |
465 | + | let inAmount = parseIntValue(dataArray[sIdxInAmount]) | |
466 | + | let swapStatus = dataArray[sIdxStatus] | |
467 | + | let startHeight = parseIntValue(dataArray[sIdxStartHeight]) | |
468 | + | let isQuick = (dataArray[sIdxIsQuick] == "true") | |
469 | + | let checkSwapType = if (if ((swapType != "waves")) | |
470 | + | then (swapType != "neutrino") | |
471 | + | else false) | |
472 | + | then throw(("Unsupported swap type " + swapType)) | |
473 | + | else true | |
474 | + | if ((checkSwapType == checkSwapType)) | |
475 | + | then { | |
476 | + | let outFeePart = valueOrElse(getInteger(this, outFeePartKEY(swapType)), DEFAULTSWAPFEE) | |
477 | + | let totalLocked = totalLockedREAD(swapType) | |
478 | + | let totalLockedByUser = totalLockedByUserREAD(swapType, account) | |
479 | + | let minMaxRandsTuple = $Tuple2(parseIntValue(dataArray[sIdxMinRand]), parseIntValue(dataArray[sIdxMaxRand])) | |
480 | + | let unlockHeight = if (isQuick) | |
481 | + | then (startHeight + getIntegerValue(this, keyQuickSwapDelay)) | |
482 | + | else if ((rsaSig == base58'')) | |
483 | + | then selfUnlockHeight | |
484 | + | else randUnlockHeightOrFail(swapTxId, rsaSig, swapType, startHeight, minMaxRandsTuple) | |
485 | + | let indexHeight = getHeightPriceByIndex(index) | |
486 | + | let prevIndexHeight = getHeightPriceByIndex((index - 1)) | |
487 | + | let priceByIndex = getPriceHistory(indexHeight) | |
488 | + | let $t02248522681 = if ((swapType == "waves")) | |
489 | + | then $Tuple2(convertWavesToNeutrino(inAmount, priceByIndex), neutrinoAssetId) | |
490 | + | else $Tuple2(convertNeutrinoToWaves(inAmount, priceByIndex), unit) | |
491 | + | let outAmountGross = $t02248522681._1 | |
492 | + | let outAsset = $t02248522681._2 | |
493 | + | let payoutsArray = applyFees(outAmountGross, outFeePart) | |
494 | + | let outNetAmount = payoutsArray[IdxNetAmount] | |
495 | + | let outFeeAmount = payoutsArray[IdxFeeAmount] | |
496 | + | let checks = [if (isBlocked) | |
497 | + | then emergencyShutdownFAIL() | |
498 | + | else true, if ((swapStatus != "PENDING")) | |
499 | + | then throw("swap has been already processed") | |
500 | + | else true, if ((unlockHeight > height)) | |
501 | + | then throw((("please wait for: " + toString(unlockHeight)) + " block height to withdraw funds")) | |
502 | + | else true, if (if (if ((index > priceIndex)) | |
503 | + | then true | |
504 | + | else (unlockHeight > indexHeight)) | |
505 | + | then true | |
506 | + | else if ((prevIndexHeight != 0)) | |
507 | + | then (prevIndexHeight >= unlockHeight) | |
508 | + | else false) | |
509 | + | then priceIndexFAIL(index, priceIndex, indexHeight, unlockHeight, prevIndexHeight) | |
510 | + | else true, if ((0 >= payoutsArray[IdxGrossAmount])) | |
511 | + | then throw("balance equals zero") | |
512 | + | else true, if (if ((0 > outFeePart)) | |
513 | + | then true | |
514 | + | else (outFeePart >= PAULI)) | |
515 | + | then throw(((("invalid outFeePart config for " + swapType) + " swap: outFeePart=") + toString(outFeePart))) | |
516 | + | else true] | |
517 | + | if ((checks == checks)) | |
518 | + | then { | |
519 | + | let leasePart = if (if ((swapType == "neutrino")) | |
520 | + | then (outAmountGross > 0) | |
521 | + | else false) | |
522 | + | then invoke(this, "prepareUnleaseAndLeaseWrapper", [outAmountGross], nil) | |
523 | + | else unit | |
524 | + | if ((leasePart == leasePart)) | |
525 | + | then { | |
526 | + | let gNsbtContract = addressFromStringValue(getStringValue(this, keyGNsbtContract)) | |
527 | + | let sendFee = invoke(gNsbtContract, "deposit", nil, [AttachedPayment(outAsset, outFeeAmount)]) | |
528 | + | if ((sendFee == sendFee)) | |
529 | + | 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)))] | |
530 | + | else throw("Strict value is not equal to itself.") | |
531 | + | } | |
532 | + | else throw("Strict value is not equal to itself.") | |
533 | + | } | |
534 | + | else throw("Strict value is not equal to itself.") | |
535 | + | } | |
536 | + | else throw("Strict value is not equal to itself.") | |
537 | + | } | |
538 | + | else throw("Strict value is not equal to itself.") | |
539 | + | } | |
540 | + | ||
541 | + | ||
542 | + | ||
543 | + | @Callable(i) | |
544 | + | func swapWavesToNeutrino () = { | |
545 | + | let pmt = value(i.payments[0]) | |
546 | + | if (isDefined(pmt.assetId)) | |
547 | + | then throw("Only Waves token is allowed for swapping.") | |
548 | + | else { | |
549 | + | let commonSwapInv = invoke(this, "commonSwap", ["waves", pmt.amount, toString(i.caller), toBase58String(i.transactionId)], nil) | |
550 | + | if ((commonSwapInv == commonSwapInv)) | |
551 | + | then nil | |
552 | + | else throw("Strict value is not equal to itself.") | |
553 | + | } | |
554 | + | } | |
555 | + | ||
556 | + | ||
557 | + | ||
558 | + | @Callable(i) | |
559 | + | func swapNeutrinoToWaves () = { | |
560 | + | let pmt = value(i.payments[0]) | |
561 | + | if ((pmt.assetId != neutrinoAssetId)) | |
562 | + | then throw("Only appropriate Neutrino tokens are allowed for swapping.") | |
563 | + | else { | |
564 | + | let swapInv = invoke(this, "commonSwap", ["neutrino", pmt.amount, toString(i.caller), toBase58String(i.transactionId)], nil) | |
565 | + | if ((swapInv == swapInv)) | |
566 | + | then nil | |
567 | + | else throw("Strict value is not equal to itself.") | |
568 | + | } | |
569 | + | } | |
570 | + | ||
571 | + | ||
572 | + | ||
573 | + | @Callable(i) | |
574 | + | func swap (swapType,accelerate) = { | |
575 | + | let wavesToNeutrino = (swapType == "waves") | |
576 | + | let neutrinoToWaves = (swapType == "neutrino") | |
577 | + | let pmt = value(i.payments[0]) | |
578 | + | let account = toString(i.caller) | |
579 | + | let swapTxId = toBase58String(i.transactionId) | |
580 | + | let checks = [if (if (wavesToNeutrino) | |
581 | + | then true | |
582 | + | else neutrinoToWaves) | |
583 | + | then true | |
584 | + | else throw("Invalid swap type"), if (if (wavesToNeutrino) | |
585 | + | then (pmt.assetId == unit) | |
586 | + | else false) | |
587 | + | then true | |
588 | + | else throw("Only Waves token is allowed for swapping."), if (if (neutrinoToWaves) | |
589 | + | then (pmt.assetId == neutrinoAssetId) | |
590 | + | else false) | |
591 | + | then true | |
592 | + | else throw("Only appropriate Neutrino tokens are allowed for swapping.")] | |
593 | + | if ((checks == checks)) | |
594 | + | then { | |
595 | + | let commonSwapInv = invoke(this, "commonSwap", [swapType, pmt.amount, account, swapTxId], nil) | |
596 | + | if ((commonSwapInv == commonSwapInv)) | |
597 | + | then { | |
598 | + | let accelerateInv = if (accelerate) | |
599 | + | then invoke(this, "accelerate", [account, swapTxId], nil) | |
600 | + | else true | |
601 | + | if ((accelerateInv == accelerateInv)) | |
602 | + | then nil | |
603 | + | else throw("Strict value is not equal to itself.") | |
604 | + | } | |
605 | + | else throw("Strict value is not equal to itself.") | |
606 | + | } | |
607 | + | else throw("Strict value is not equal to itself.") | |
608 | + | } | |
609 | + | ||
610 | + | ||
611 | + | ||
612 | + | @Callable(i) | |
613 | + | func accelerate (account,swapTxId) = { | |
614 | + | let userAddress = addressFromStringValue(account) | |
615 | + | let checkCaller = if ((i.originCaller != userAddress)) | |
616 | + | then throw("Permission denied") | |
617 | + | else true | |
618 | + | if ((checkCaller == checkCaller)) | |
619 | + | then { | |
620 | + | let dataArray = swapDataFailOrREAD(account, swapTxId) | |
621 | + | let swapType = dataArray[sIdxSwapType] | |
622 | + | let inAmount = parseIntValue(dataArray[sIdxInAmount]) | |
623 | + | let swapStatus = dataArray[sIdxStatus] | |
624 | + | let isQuick = (dataArray[sIdxIsQuick] == "true") | |
625 | + | let $t02673426942 = match invoke(this, "quickSwapLimitREADONLY", [toString(userAddress)], nil) { | |
626 | + | case r: (Int, Int) => | |
627 | + | $Tuple2(r._1, r._2) | |
628 | + | case _ => | |
629 | + | throw("Type casting error") | |
630 | + | } | |
631 | + | let quickSwapLimitTotal = $t02673426942._1 | |
632 | + | let quickSwapUserSpent = $t02673426942._2 | |
633 | + | let quickSwapLimit = (quickSwapLimitTotal - quickSwapUserSpent) | |
634 | + | let priceByIndex = getPriceHistory(getHeightPriceByIndex(priceIndex)) | |
635 | + | let swapUsdnVolume = if ((swapType == "neutrino")) | |
636 | + | then inAmount | |
637 | + | else convertWavesToNeutrino(inAmount, priceByIndex) | |
638 | + | let checks = [if ((swapStatus != "PENDING")) | |
639 | + | then throw("Swap has been already processed") | |
640 | + | else true, if (isQuick) | |
641 | + | then throw("Swap has been already accelerated") | |
642 | + | else true, if ((swapUsdnVolume > quickSwapLimit)) | |
643 | + | then throw("You have exceeded the quick swaps limit") | |
644 | + | else true] | |
645 | + | if ((checks == checks)) | |
646 | + | then [IntegerEntry(keyQuickSwapUserSpentInPeriod(userAddress), (swapUsdnVolume + quickSwapUserSpent)), IntegerEntry(keyUserLastQuickSwapHeight(userAddress), height), StringEntry(swapKEY(account, swapTxId), accelerateSwapDATA(dataArray))] | |
647 | + | else throw("Strict value is not equal to itself.") | |
648 | + | } | |
649 | + | else throw("Strict value is not equal to itself.") | |
650 | + | } | |
651 | + | ||
652 | + | ||
653 | + | ||
654 | + | @Callable(i) | |
655 | + | func withdraw (account,index,swapTxId) = { | |
656 | + | let result = invoke(this, "commonWithdraw", [account, index, swapTxId, base58''], nil) | |
657 | + | if ((result == result)) | |
658 | + | then nil | |
659 | + | else throw("Strict value is not equal to itself.") | |
660 | + | } | |
661 | + | ||
662 | + | ||
663 | + | ||
664 | + | @Callable(i) | |
665 | + | func withdrawRand (account,index,swapTxId,rsaSig) = { | |
666 | + | let result = invoke(this, "commonWithdraw", [account, index, swapTxId, rsaSig], nil) | |
667 | + | if ((result == result)) | |
668 | + | then nil | |
669 | + | else throw("Strict value is not equal to itself.") | |
670 | + | } | |
671 | + | ||
672 | + | ||
673 | + | ||
674 | + | @Callable(i) | |
675 | + | func transferToAuction () = { | |
676 | + | let auctionNBAmount = (neutrinoSupply - assetBalance(addressFromStringValue(auctionContract), bondAssetId)) | |
677 | + | let surplusWithLiquidation = (surplus - assetBalance(addressFromStringValue(liquidationContract), neutrinoAssetId)) | |
678 | + | if (isBlocked) | |
679 | + | then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles") | |
680 | + | else if ((auctionNBAmount > (1 * PAULI))) | |
681 | + | then [ScriptTransfer(addressFromStringValue(auctionContract), auctionNBAmount, bondAssetId)] | |
682 | + | else if ((surplusWithLiquidation >= (1 * PAULI))) | |
683 | + | then [ScriptTransfer(addressFromStringValue(liquidationContract), surplusWithLiquidation, neutrinoAssetId)] | |
684 | + | else throw(((((((("bond were generated or do not need it. Deficit:" + toString(auctionNBAmount)) + "|") + toString(0)) + ". Surplus:") + toString(surplusWithLiquidation)) + "|") + toString(surplus))) | |
685 | + | } | |
686 | + | ||
687 | + | ||
688 | + | ||
689 | + | @Callable(i) | |
690 | + | func acceptWaves () = if ((i.caller != addressFromStringValue(auctionContract))) | |
691 | + | then throw("Currently only auction contract is allowed to call") | |
692 | + | else $Tuple2(prepareUnleaseAndLease(0), "success") | |
693 | + | ||
694 | + | ||
695 | + | ||
696 | + | @Callable(i) | |
697 | + | func calcTotalQuickSwapLimitREADONLY (gNsbtAmount) = { | |
698 | + | let $t02990929966 = getDora2NSBTInfo() | |
699 | + | let nsbtPrice = $t02990929966._1 | |
700 | + | let nsbtPriceLastHeight = $t02990929966._2 | |
701 | + | let check = if (((height - nsbtPriceLastHeight) > getIntegerValue(this, keyDora2LastHeightLimit))) | |
702 | + | then throw("NSBT price is outdated") | |
703 | + | else true | |
704 | + | if ((check == check)) | |
705 | + | then $Tuple2(nil, fraction(gNsbtAmount, nsbtPrice, WAVELET)) | |
706 | + | else throw("Strict value is not equal to itself.") | |
707 | + | } | |
708 | + | ||
709 | + | ||
710 | + | ||
711 | + | @Callable(i) | |
712 | + | func quickSwapLimitREADONLY (userAddressStr) = { | |
713 | + | let userAddress = addressFromStringValue(userAddressStr) | |
714 | + | let userGNsbtAmount = asInt(invoke(addressFromStringValue(getStringValue(this, keyNsbtLockContract)), "gNsbtAmountREADONLY", [toString(userAddress)], nil)) | |
715 | + | if ((userGNsbtAmount == userGNsbtAmount)) | |
716 | + | then { | |
717 | + | let quickSwapLimitTotal = asInt(invoke(this, "calcTotalQuickSwapLimitREADONLY", [userGNsbtAmount], nil)) | |
718 | + | if ((quickSwapLimitTotal == quickSwapLimitTotal)) | |
719 | + | then { | |
720 | + | let isNewQuickSwapPeriod = ((height - valueOrElse(getInteger(this, keyUserLastQuickSwapHeight(userAddress)), 0)) > getIntegerValue(this, keyQuickSwapLimitDuration)) | |
721 | + | let quickSwapUserSpent = if (isNewQuickSwapPeriod) | |
722 | + | then 0 | |
723 | + | else valueOrElse(getInteger(this, keyQuickSwapUserSpentInPeriod(userAddress)), 0) | |
724 | + | $Tuple2(nil, $Tuple2(quickSwapLimitTotal, quickSwapUserSpent)) | |
725 | + | } | |
726 | + | else throw("Strict value is not equal to itself.") | |
727 | + | } | |
728 | + | else throw("Strict value is not equal to itself.") | |
729 | + | } | |
730 | + | ||
731 | + | ||
732 | + | @Verifier(tx) | |
733 | + | func verify () = { | |
734 | + | let id = toBase58String(tx.id) | |
735 | + | let minSignaturesNumber = 3 | |
736 | + | let count = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0]))) | |
737 | + | then 1 | |
738 | + | else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1]))) | |
739 | + | then 1 | |
740 | + | else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2]))) | |
741 | + | then 1 | |
742 | + | else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[3], fromBase58String(pubKeyAdminsList[3]))) | |
743 | + | then 2 | |
744 | + | else 0)) | |
745 | + | let isSignaturesValid = (count >= minSignaturesNumber) | |
746 | + | match tx { | |
747 | + | case sponsorTx: SponsorFeeTransaction => | |
748 | + | if (isSignaturesValid) | |
749 | + | then checkIsValidMinSponsoredFee(sponsorTx) | |
750 | + | else false | |
751 | + | case _ => | |
752 | + | isSignaturesValid | |
753 | + | } | |
754 | + | } | |
755 | + |
github/deemru/w8io/873ac7e 41.65 ms ◑![]()