2020.10.09 11:08 [2276465] smart account 3P9ZegsKUtsEpdRPNVrMH7nHEEqY5MrmjDp > SELF 0.00000000 Waves

{ "type": 13, "id": "H5XQMYij4pYQCbR2oGmk5yYmxhkNhSjH5Yz2XMT6xTHD", "fee": 1400000, "feeAssetId": null, "timestamp": 1602230693439, "version": 2, "chainId": 87, "sender": "3P9ZegsKUtsEpdRPNVrMH7nHEEqY5MrmjDp", "senderPublicKey": "7ziFsWp9eo6kUB6ovqQzJfjgQarifNfpCGNW9DZi8YhN", "proofs": [ "2dumNErwQd498BCk1J1b4K6Bc6kv7VnAzJAtzDJmZqw1hmo487Rbq34eF3txrnaS52sVhtciRcwjndStKGN6pv1J", "GT2ikgomspDh8UmC387N2CWbDNKE9yQoTDvRXguEXdTKfFw7NbwytLT5YxZjvWYwYE3hoPgXzdaypNMkGiqJc5o" ], "script": "base64:AAIEAAAAAAAAACEIAhILCgkICAgICAgICAESAwoBARIAEgMKAQgSABIAEgAAAABQAAAAAAR0ZW42AAAAAAAAD0JAAAAAAAR0ZW44AAAAAAAF9eEAAAAAABFjb25maWdQcm92aWRlcktleQIAAAAOY29uZmlnUHJvdmlkZXIAAAAADmNvbmZpZ1Byb3ZpZGVyBAAAAAckbWF0Y2gwCQAEHQAAAAIFAAAABHRoaXMFAAAAEWNvbmZpZ1Byb3ZpZGVyS2V5AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAAZTdHJpbmcEAAAAAXMFAAAAByRtYXRjaDAJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEFAAAAAXMFAAAABHRoaXMAAAAAB0JVTExLZXkCAAAABkJVTExJZAAAAAAHQkVBUktleQIAAAAGQkVBUklkAAAAAAxtYWluVG9rZW5LZXkCAAAAC21haW5Ub2tlbklkAAAAABFidWxsQ29sbGF0ZXJhbEtleQIAAAAOYnVsbENvbGxhdGVyYWwAAAAAEWJlYXJDb2xsYXRlcmFsS2V5AgAAAA5iZWFyQ29sbGF0ZXJhbAAAAAASYnVsbENpcmN1bGF0aW9uS2V5AgAAAA9idWxsQ2lyY3VsYXRpb24AAAAAEmJlYXJDaXJjdWxhdGlvbktleQIAAAAPYmVhckNpcmN1bGF0aW9uAAAAABJpc3N1ZVBlcmNlbnRpbGVLZXkCAAAAD2lzc3VlUGVyY2VudGlsZQAAAAATcmVkZWVtUGVyY2VudGlsZUtleQIAAAAQcmVkZWVtUGVyY2VudGlsZQAAAAALbWluSXNzdWVLZXkCAAAACG1pbklzc3VlAAAAAAxtaW5SZWRlZW1LZXkCAAAACW1pblJlZGVlbQAAAAAKbWluUG9vbEtleQIAAAAHbWluUG9vbAAAAAASZmVlc0FjY3VtdWxhdGVkS2V5AgAAAA9mZWVzQWNjdW11bGF0ZWQAAAAADHdoaXRlbGlzdEtleQIAAAAOaXNzdWVXaGl0ZUxpc3QAAAAAC29yYWNsZVBLS2V5AgAAAAZvcmFjbGUAAAAAEWxhc3RQcmljZUluZGV4S2V5AgAAAAtwcmljZV9pbmRleAAAAAAQcHJpY2VJbmRleFByZWZpeAIAAAAMcHJpY2VfaW5kZXhfAAAAABFwcmljZUhlaWdodFByZWZpeAIAAAAGcHJpY2VfAAAAABpvcmFjbGVDdXJyZW50UHJpY2VJbmRleEtleQIAAAALcHJpY2VfaW5kZXgAAAAAGmxhc3RSZWJhbGFuY2VQcmljZUluZGV4S2V5AgAAABVsYXN0U2V0dGxlbWVudFByaWNlSWQAAAAADmhlYWRQb2ludGVyS2V5AgAAAAtoZWFkUG9pbnRlcgAAAAAOdGFpbFBvaW50ZXJLZXkCAAAAC3RhaWxQb2ludGVyAAAAAAxxdWV1ZVNpemVLZXkCAAAACXF1ZXVlU2l6ZQAAAAAVcG9vbE1haW5Ub2tlblZhbHVlS2V5AgAAABJwb29sTWFpblRva2VuVmFsdWUAAAAACXBvb2xVcEtleQIAAAAGcG9vbFVwAAAAAApwb29sRHduS2V5AgAAAAdwb29sRHduAAAAABdwb29sVG9rZW5DaXJjdWxhdGlvbktleQIAAAAUcG9vbFRva2VuQ2lyY3VsYXRpb24AAAAADHBvb2xUb2tlbktleQIAAAAJcG9vbFRva2VuAAAAAAdidWxsQ29sCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAARYnVsbENvbGxhdGVyYWxLZXkCAAAAFG5vIGJ1bGxDb2xsYXRlcmFsS2V5AAAAAAdiZWFyQ29sCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAARYmVhckNvbGxhdGVyYWxLZXkCAAAAFG5vIGJlYXJDb2xsYXRlcmFsS2V5AAAAAAhidWxsQ2lyYwkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAEmJ1bGxDaXJjdWxhdGlvbktleQIAAAAVbm8gYnVsbENpcmN1bGF0aW9uS2V5AAAAAAhiZWFyQ2lyYwkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAEmJlYXJDaXJjdWxhdGlvbktleQIAAAAVbm8gYmVhckNpcmN1bGF0aW9uS2V5AAAAAARCVUxMCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAAHQlVMTEtleQIAAAAKbm8gQlVMTEtleQAAAAAEQkVBUgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAB0JFQVJLZXkCAAAACm5vIEJFQVJLZXkAAAAACW1haW5Ub2tlbgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAADG1haW5Ub2tlbktleQIAAAAPbm8gbWFpblRva2VuS2V5AAAAAA9pc3N1ZVBlcmNlbnRpbGUJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAA5jb25maWdQcm92aWRlcgUAAAASaXNzdWVQZXJjZW50aWxlS2V5AgAAABVubyBpc3N1ZVBlcmNlbnRpbGVLZXkAAAAAEHJlZGVlbVBlcmNlbnRpbGUJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAA5jb25maWdQcm92aWRlcgUAAAATcmVkZWVtUGVyY2VudGlsZUtleQIAAAAWbm8gcmVkZWVtUGVyY2VudGlsZUtleQAAAAAIbWluSXNzdWUJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAA5jb25maWdQcm92aWRlcgUAAAALbWluSXNzdWVLZXkCAAAADm5vIG1pbklzc3VlS2V5AAAAAAltaW5SZWRlZW0JAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAA5jb25maWdQcm92aWRlcgUAAAAMbWluUmVkZWVtS2V5AgAAAA9ubyBtaW5SZWRlZW1LZXkAAAAAB21pblBvb2wJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAA5jb25maWdQcm92aWRlcgUAAAAKbWluUG9vbEtleQIAAAANbm8gbWluUG9vbEtleQAAAAAJd2hpdGVsaXN0CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAOY29uZmlnUHJvdmlkZXIFAAAADHdoaXRlbGlzdEtleQIAAAAPbm8gd2hpdGVsaXN0S2V5AQAAAAdhbGxvd2VkAAAAAQAAAAFhAwkAAAAAAAACBQAAAAl3aGl0ZWxpc3QCAAAAAAYJAQAAAAlpc0RlZmluZWQAAAABCQAEswAAAAIFAAAACXdoaXRlbGlzdAkABCUAAAABBQAAAAFhAAAAAAhwb29sTWFpbgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAFXBvb2xNYWluVG9rZW5WYWx1ZUtleQIAAAAYbm8gcG9vbE1haW5Ub2tlblZhbHVlS2V5AAAAAAZwb29sVXAJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAAAlwb29sVXBLZXkCAAAADG5vIHBvb2xVcEtleQAAAAAHcG9vbER3bgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAACnBvb2xEd25LZXkCAAAADW5vIHBvb2xEd25LZXkAAAAACXBvb2xUb2tlbgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAADHBvb2xUb2tlbktleQIAAAAPbm8gcG9vbFRva2VuS2V5AAAAABRwb29sVG9rZW5DaXJjdWxhdGlvbgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAF3Bvb2xUb2tlbkNpcmN1bGF0aW9uS2V5AgAAABpubyBwb29sVG9rZW5DaXJjdWxhdGlvbktleQAAAAAJcG9vbFZhbHVlCQAAZAAAAAIJAABkAAAAAgUAAAAIcG9vbE1haW4JAABrAAAAAwUAAAAHYnVsbENvbAUAAAAGcG9vbFVwBQAAAAhidWxsQ2lyYwkAAGsAAAADBQAAAAdiZWFyQ29sBQAAAAdwb29sRHduBQAAAAhiZWFyQ2lyYwAAAAAGb3JhY2xlCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAQAAABRhZGRyZXNzRnJvbVB1YmxpY0tleQAAAAEJAAJZAAAAAQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAC29yYWNsZVBLS2V5AgAAAA5ubyBvcmFjbGVQS0tleQIAAAASYmFkIG9yYWNsZSBhZGRyZXNzAAAAABRyZWJhbGFuY2VkUHJpY2VJbmRleAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAGmxhc3RSZWJhbGFuY2VQcmljZUluZGV4S2V5AgAAABdubyBsYXN0IHJlYmFsYW5jZSBwcmljZQAAAAAQb3JhY2xlUHJpY2VJbmRleAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABm9yYWNsZQUAAAARbGFzdFByaWNlSW5kZXhLZXkJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAE2JhZCBvcmFjbGUgZGF0YSBhdCAJAAQlAAAAAQUAAAAGb3JhY2xlAgAAABA6IG5vIGludGVnZXIgYXQgBQAAABFsYXN0UHJpY2VJbmRleEtleQAAAAAJcXVldWVTaXplCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAADHF1ZXVlU2l6ZUtleQAAAAAAAAAAAAAAAAALaGVhZFBvaW50ZXIJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAAOaGVhZFBvaW50ZXJLZXkCAAAAAAAAAAALdGFpbFBvaW50ZXIJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAAOdGFpbFBvaW50ZXJLZXkCAAAAAAAAAAAPZmVlc0FjY3VtdWxhdGVkCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAEmZlZXNBY2N1bXVsYXRlZEtleQAAAAAAAAAAAAAAAAAFSVNTVUUCAAAABUlTU1VFAAAAAAZSRURFRU0CAAAABlJFREVFTQAAAAAEUE9PTAIAAAAEUE9PTAAAAAAGVU5QT09MAgAAAAZVTlBPT0wAAAAACmZlZUFkZHJLZXkCAAAACmZlZUFkZHJlc3MAAAAADnN0YWtpbmdBZGRyS2V5AgAAAA5zdGFraW5nQWRkcmVzcwAAAAAPZGFlbW9uUHViS2V5S2V5AgAAAA9kYWVtb25QdWJsaWNLZXkAAAAACmZlZUFkZHJlc3MJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAOY29uZmlnUHJvdmlkZXIFAAAACmZlZUFkZHJLZXkCAAAADW5vIGZlZUFkZHJlc3MCAAAADmJhZCBmZWVBZGRyZXNzAAAAAA5zdGFraW5nQWRkcmVzcwkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAADmNvbmZpZ1Byb3ZpZGVyBQAAAA5zdGFraW5nQWRkcktleQIAAAARbm8gc3Rha2luZ0FkZHJlc3MAAAAAD2RhZW1vblB1YmxpY0tleQkAAlkAAAABCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAOY29uZmlnUHJvdmlkZXIFAAAAD2RhZW1vblB1YktleUtleQIAAAASbm8gZGFlbW9uUHVibGljS2V5AAAAAApycGRBZGRyZXNzCQAEJgAAAAECAAAAIzNQTmlrTTZ5cDROcWNTVThndXhRdG1SNW9ucjJENGU4eVRKAAAAABBwdWJLZXlBZG1pbnNMaXN0CQAETAAAAAICAAAALDJISHFWOFc5REpheVY1UjZ0QkQyU2I4c3JwaHBvYm9EaTdyMXQxYVBpdW1DCQAETAAAAAICAAAALDVaWGU4MlJSQVNVN3FzaFhNMko5Sk5ZaHFKOUdXWWpqVnEyZ3dVVjVOYXo5CQAETAAAAAICAAAALDVXUlhGU2p3Y1RiTmZLY0pzOFpxWG1TU1dZc1NWSlV0TXZNcVpqNWhINE5jBQAAAANuaWwBAAAADHNhZmVGcmFjdGlvbgAAAAMAAAABYQAAAAFiAAAAAWMDAwkAAAAAAAACBQAAAAFhAAAAAAAAAAAABgkAAAAAAAACBQAAAAFiAAAAAAAAAAAAAAAAAAAAAAAACQAAawAAAAMFAAAAAWEFAAAAAWIFAAAAAWMBAAAADGJ1aWxkTmV3SXRlbQAAAAUAAAAGYWN0aW9uAAAAA2FtdAAAAAV0b2tlbgAAAApwcmljZUluZGV4AAAAB2ludm9rZXIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIFAAAABmFjdGlvbgIA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YWluMAAAAApjdXJQb29sVXAwAAAAC2N1clBvb2xEd24wCgEAAAAHY2xvc2VVcAAAAAcAAAAKY3VyQnVsbENvbAAAAApjdXJCZWFyQ29sAAAAC2N1ckJ1bGxDaXJjAAAAC2N1ckJlYXJDaXJjAAAAC2N1clBvb2xNYWluAAAACWN1clBvb2xVcAAAAApjdXJQb29sRHduBAAAAARkaWZmCQAAZQAAAAIFAAAACmN1ckJ1bGxDb2wFAAAACmN1ckJlYXJDb2wEAAAACGV4cG9zdXJlCQAAawAAAAMFAAAACmN1ckJ1bGxDb2wFAAAACWN1clBvb2xVcAUAAAALY3VyQnVsbENpcmMEAAAAEGxpcXVpZGF0ZWRUb2tlbnMDCQAAZgAAAAIFAAAABGRpZmYFAAAACGV4cG9zdXJlBQAAAAljdXJQb29sVXAJAABrAAAAAwUAAAAEZGlmZgUAAAALY3VyQnVsbENpcmMFAAAACmN1ckJ1bGxDb2wEAAAAD2xpcXVpZGF0ZWRWYWx1ZQMJAABmAAAAAgUAAAAEZGlmZgUAAAAIZXhwb3N1cmUFAAAACGV4cG9zdXJlCQAAawAAAAMFAAAAEGxpcXVpZGF0ZWRUb2tlbnMFAAAACmN1ckJ1bGxDb2wFAAAAC2N1ckJ1bGxDaXJjCQAFGQAAAAcJAABlAAAAAgUAAAAKY3VyQnVsbENvbAUAAAAPbGlxdWlkYXRlZFZhbHVlBQAAAApjdXJCZWFyQ29sCQAAZQAAAAIFAAAAC2N1ckJ1bGxDaXJjBQAAABBsaXF1aWRhdGVkVG9rZW5zBQAAAAtjdXJCZWFyQ2lyYwkAAGQAAAACBQAAAAtjdXJQb29sTWFpbgUAAAAPbGlxdWlkYXRlZFZhbHVlCQAAZQAAAAIFAAAACWN1clBvb2xVcAUAAAAQbGlxdWlkYXRlZFRva2VucwUAAAAKY3VyUG9vbER3bgoBAAAACGNsb3NlRHduAAAABwAAAApjdXJCdWxsQ29sAAAACmN1ckJlYXJDb2wAAAALY3VyQnVsbENpcmMAAAALY3VyQmVhckNpcmMAAAALY3VyUG9vbE1haW4AAAAJY3VyUG9vbFVwAAAACmN1clBvb2xEd24EAAAABGRpZmYJAABlAAAAAgUAAAAKY3VyQmVhckNvbAUAAAAKY3VyQnVsbENvbAQAAAAIZXhwb3N1cmUJAABrAAAAAwUAAAAKY3VyQmVhckNvbAUAAAAKY3VyUG9vbER3bgUAAAALY3VyQmVhckNpcmMEAAAAEGxpcXVpZGF0ZWRUb2tlbnMDCQAAZgAAAAIFAAAABGRpZmYFAAAACGV4cG9zdXJlBQAAAApjdXJQb29sRHduCQAAawAAAAMFAAAABGRpZmYFAAAAC2N1ckJlYXJDaXJjBQAAAApjdXJCZWFyQ29sBAAAAA9saXF1aWRhdGVkVmFsdWUDCQAAZgAAAAIFAAAABGRpZmYFAAAACGV4cG9zdXJlBQAAAAhleHBvc3VyZQkAAGsAAAADBQAAABBsaXF1aWRhdGVkVG9rZW5zBQAAAApjdXJCZWFyQ29sBQAAAAtjdXJCZWFyQ2lyYwkABRkAAAAHBQAAAApjdXJCdWxsQ29sCQAAZQAAAAIFAAAACmN1ckJlYXJDb2wFAAAAD2xpcXVpZGF0ZWRWYWx1ZQUAAAALY3VyQnVsbENpcmMJAABlAAAAAgUAAAALY3VyQmVhckNpcmMFAAAAEGxpcXVpZGF0ZWRUb2tlbnMJAABkAAAAAgUAAAALY3VyUG9vbE1haW4FAAAAD2xpcXVpZGF0ZWRWYWx1ZQUAAAAJY3VyUG9vbFVwCQAAZQAAAAIFAAAACmN1clBvb2xEd24FAAAAEGxpcXVpZGF0ZWRUb2tlbnMKAQAAAAdvcGVuRHduAAAABwAAAApjdXJCdWxsQ29sAAAACmN1ckJlYXJDb2wAAAALY3VyQnVsbENpcmMAAAALY3VyQmVhckNpcmMAAAALY3VyUG9vbE1haW4AAAAJY3VyUG9vbFVwAAAACmN1clBvb2xEd24EAAAABGRpZmYJAABlAAAAAgUAAAAKY3VyQnVsbENvbAUAAAAKY3VyQmVhckNvbAQAAAAOc3BlbnRQb29sVmFsdWUDCQAAZgAAAAIFAAAAC2N1clBvb2xNYWluBQAAAARkaWZmBQAAAARkaWZmBQAAAAtjdXJQb29sTWFpbgQAAAAOYWNxdWlyZWRUb2tlbnMJAABrAAAAAwUAAAAOc3BlbnRQb29sVmFsdWUFAAAAC2N1ckJlYXJDaXJjBQAAAApjdXJCZWFyQ29sCQAFGQAAAAcFAAAACmN1ckJ1bGxDb2wJAABkAAAAAgUAAAAKY3VyQmVhckNvbAUAAAAOc3BlbnRQb29sVmFsdWUFAAAAC2N1ckJ1bGxDaXJjCQAAZAAAAAIFAAAAC2N1ckJlYXJDaXJjBQAAAA5hY3F1aXJlZFRva2VucwkAAGUAAAACBQAAAAtjdXJQb29sTWFpbgUAAAAOc3BlbnRQb29sVmFsdWUFAAAACWN1clBvb2xVcAkAAGQAAAACBQAAAApjdXJQb29sRHduBQAAAA5hY3F1aXJlZFRva2VucwoBAAAABm9wZW5VcAAAAAcAAAAKY3VyQnVsbENvbAAAAApjdXJCZWFyQ29sAAAAC2N1ckJ1bGxDaXJjAAAAC2N1ckJlYXJDaXJjAAAAC2N1clBvb2xNYWluAAAACWN1clBvb2xVcAAAAApjdXJQb29sRHduBAAAAARkaWZmCQAAZQAAAAIFAAAACmN1ckJlYXJDb2wFAAAACmN1ckJ1bGxDb2wEAAAADnNwZW50UG9vbFZhbHVlAwkAAGYAAAACBQAAAAtjdXJQb29sTWFpbgUAAAAEZGlmZgUAAAAEZGlmZgUAAAALY3VyUG9vbE1haW4EAAAADmFjcXVpcmVkVG9rZW5zCQAAawAAAAMFAAAADnNwZW50UG9vbFZhbHVlBQAAAAtjdXJCdWxsQ2lyYwUAAAAKY3VyQnVsbENvbAkABRkAAAAHCQAAZAAAAAIFAAAACmN1ckJ1bGxDb2wFAAAADnNwZW50UG9vbFZhbHVlBQAAAApjdXJCZWFyQ29sCQAAZAAAAAIFAAAAC2N1ckJ1bGxDaXJjBQAAAA5hY3F1aXJlZFRva2VucwUAAAALY3VyQmVhckNpcmMJAABlAAAAAgUAAAALY3VyUG9vbE1haW4FAAAADnNwZW50UG9vbFZhbHVlCQAAZAAAAAIFAAAACWN1clBvb2xVcAUAAAAOYWNxdWlyZWRUb2tlbnMFAAAACmN1clBvb2xEd24DCQAAZgAAAAIFAAAAC2N1ckJ1bGxDb2wwBQAAAAtjdXJCZWFyQ29sMAQAAAAMYWZ0ZXJDbG9zZVVwCQEAAAAHY2xvc2VVcAAAAAcFAAAAC2N1ckJ1bGxDb2wwBQAAAAtjdXJCZWFyQ29sMAUAAAAMY3VyQnVsbENpcmMwBQAAAAxjdXJCZWFyQ2lyYzAFAAAADGN1clBvb2xNYWluMAUAAAAKY3VyUG9vbFVwMAUAAAALY3VyUG9vbER3bjAEAAAADSR0MDEwMjg2MTA0MjMFAAAADGFmdGVyQ2xvc2VVcAQAAAABYQgFAAAADSR0MDEwMjg2MTA0MjMAAAACXzEEAAAAAWIIBQAAAA0kdDAxMDI4NjEwNDIzAAAAAl8yBAAAAAFjCAUAAAANJHQwMTAyODYxMDQyMwAAAAJfMwQAAAABZAgFAAAADSR0MDEwMjg2MTA0MjMAAAACXzQEAAAAAWUIBQAAAA0kdDAxMDI4NjEwNDIzAAAAAl81BAAAAAFmCAUAAAANJHQwMTAyODYxMDQyMwAAAAJfNgQAAAABZwgFAAAADSR0MDEwMjg2MTA0MjMAAAACXzcDCQAAZgAAAAIFAAAAAWYAAAAAAAAAAAAFAAAADGFmdGVyQ2xvc2VVcAMJAAAAAAAAAgUAAAABZgAAAAAAAAAAAAkBAAAAB29wZW5Ed24AAAAHBQAAAAFhBQAAAAFiBQAAAAFjBQAAAAFkBQAAAAFlBQAAAAFmBQAAAAFnCQAAAgAAAAECAAAACnBvb2xVcCA8IDAEAAAADWFmdGVyQ2xvc2VEd24JAQAAAAhjbG9zZUR3bgAAAAcFAAAAC2N1ckJ1bGxDb2wwBQAAAAtjdXJCZWFyQ29sMAUAAAAMY3VyQnVsbENpcmMwBQAAAAxjdXJCZWFyQ2lyYzAFAAAADGN1clBvb2xNYWluMAUAAAAKY3VyUG9vbFVwMAUAAAALY3VyUG9vbER3bjAEAAAADSR0MDEwNzc0MTA5MTQFAAAADWFmdGVyQ2xvc2VEd24EAAAAAWEIBQAAAA0kdDAxMDc3NDEwOTE0AAAAAl8xBAAAAAFiCAUAAAANJHQwMTA3NzQxMDkxNAAAAAJfMgQAAAABYwgFAAAADSR0MDEwNzc0MTA5MTQAAAACXzMEAAAAAWQIBQAAAA0kdDAxMDc3NDEwOTE0AAAAAl80BAAAAAFlCAUAAAANJHQwMTA3NzQxMDkxNAAAAAJfNQQAAAABZggFAAAADSR0MDEwNzc0MTA5MTQAAAACXzYEAAAAAWcIBQAAAA0kdDAxMDc3NDEwOTE0AAAAAl83AwkAAGYAAAACBQAAAAFnAAAAAAAAAAAABQAAAA1hZnRlckNsb3NlRHduAwkAAAAAAAACBQAAAAFnAAAAAAAAAAAACQEAAAAGb3BlblVwAAAABwUAAAABYQUAAAABYgUAAAABYwUAAAABZAUAAAABZQUAAAABZgUAAAABZwkAAAIAAAABAgAAAAtwb29sRHduIDwgMAEAAAAUYWN0aW9uc1dpdGhNYXliZVBvb2wAAAAEAAAAC2N1ckJ1bGxDb2wwAAAAC2N1ckJlYXJDb2wwAAAADGN1ckJ1bGxDaXJjMAAAAAxjdXJCZWFyQ2lyYzAEAAAADSR0MDExMjExMTEzOTQJAQAAAAtwb29sU3VwcG9ydAAAAAcFAAAAC2N1ckJ1bGxDb2wwBQAAAAtjdXJCZWFyQ29sMAUAAAAMY3VyQnVsbENpcmMwBQAAAAxjdXJCZWFyQ2lyYzAFAAAACHBvb2xNYWluBQAAAAZwb29sVXAFAAAAB3Bvb2xEd24EAAAACGJ1bGxDb2wxCAUAAAANJHQwMTEyMTExMTM5NAAAAAJfMQQAAAAIYmVhckNvbDEIBQAAAA0kdDAxMTIxMTExMzk0AAAAAl8yBAAAAAhidWxsQ2ljMQgFAAAADSR0MDExMjExMTEzOTQAAAACXzMEAAAACWJlYXJDaXJjMQgFAAAADSR0MDExMjExMTEzOTQAAAACXzQEAAAACXBvb2xNYWluMQgFAAAADSR0MDExMjExMTEzOTQAAAACXzUEAAAAB3Bvb2xVcDEIBQAAAA0kdDAxMTIxMTExMzk0AAAAAl82BAAAAAhwb29sRHduMQgFAAAADSR0MDExMjExMTEzOTQAAAACXzcJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEWJ1bGxDb2xsYXRlcmFsS2V5BQAAAAhidWxsQ29sMQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAASYnVsbENpcmN1bGF0aW9uS2V5BQAAAAhidWxsQ2ljMQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARYmVhckNvbGxhdGVyYWxLZXkFAAAACGJlYXJDb2wxCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJiZWFyQ2lyY3VsYXRpb25LZXkFAAAACWJlYXJDaXJjMQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAVcG9vbE1haW5Ub2tlblZhbHVlS2V5BQAAAAlwb29sTWFpbjEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAACXBvb2xVcEtleQUAAAAHcG9vbFVwMQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAKcG9vbER3bktleQUAAAAIcG9vbER3bjEFAAAAA25pbAEAAAAHZGVxdWV1ZQAAAAADCQAAAAAAAAIFAAAACXF1ZXVlU2l6ZQAAAAAAAAAAAAkAAAIAAAABAgAAABFub3RoaW5nIHRvIHNldHRsZQoBAAAACmNvbGxlY3RGZWUAAAABAAAABGZlZXMJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJmZWVzQWNjdW11bGF0ZWRLZXkJAABkAAAAAgUAAAAPZmVlc0FjY3VtdWxhdGVkBQAAAARmZWVzBAAAABFkZWNyZWFzZVF1ZXVlU2l6ZQkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAADHF1ZXVlU2l6ZUtleQkAAGUAAAACBQAAAAlxdWV1ZVNpemUAAAAAAAAAAAEEAAAADWlzTGFzdEVsZW1lbnQJAAAAAAAAAgUAAAALaGVhZFBvaW50ZXIFAAAAC3RhaWxQb2ludGVyBAAAAA1vdmVyd3JpdGVUYWlsCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAA50YWlsUG9pbnRlcktleQIAAAAABAAAAARkYXRhCQAEtQAAAAIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAR0aGlzBQAAAAtoZWFkUG9pbnRlcgIAAAAQYmFkIGhlYWQgcG9pbnRlcgIAAAABfAQAAAAGYWN0aW9uCQABkQAAAAIFAAAABGRhdGEAAAAAAAAAAAAEAAAAA2FtdAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAABGRhdGEAAAAAAAAAAAEEAAAABXRva2VuCQABkQAAAAIFAAAABGRhdGEAAAAAAAAAAAIEAAAACnByaWNlSW5kZXgJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAARkYXRhAAAAAAAAAAADBAAAAAdpbnZva2VyCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQABkQAAAAIFAAAABGRhdGEAAAAAAAAAAAQEAAAABG5leHQJAAGRAAAAAgUAAAAEZGF0YQAAAAAAAAAABQQAAAAFaXRlbXMDCQAAZgAAAAIFAAAAFHJlYmFsYW5jZWRQcmljZUluZGV4BQAAAApwcmljZUluZGV4CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAJGNvcnJ1cHQgc3RhdGUsIHJlYmFsYW5jZWRQcmljZUluZGV4PQkAAaQAAAABBQAAABRyZWJhbGFuY2VkUHJpY2VJbmRleAIAAAATLCByZXF1ZXN0IHByaWNlIGlkPQkAAaQAAAABBQAAAApwcmljZUluZGV4AwkAAGYAAAACBQAAAApwcmljZUluZGV4BQAAABRyZWJhbGFuY2VkUHJpY2VJbmRleAkAAAIAAAABAgAAACljYW4ndCBkZXF1ZXVlLCB0b28gZWFybHksIHJlYmFsYW5jZSBmaXJzdAMJAAAAAAAAAgUAAAAGYWN0aW9uBQAAAAVJU1NVRQQAAAAHZmVlU2l6ZQkAAGsAAAADBQAAAANhbXQFAAAAD2lzc3VlUGVyY2VudGlsZQAAAAAAAAAnEAQAAAAPYWRkZWRDb2xsYXRlcmFsCQAAZQAAAAIFAAAAA2FtdAUAAAAHZmVlU2l6ZQMJAAAAAAAAAgUAAAAFdG9rZW4FAAAABEJVTEwEAAAAEmFkZGVkVG9DaXJjdWxhdGlvbgkAAGsAAAADBQAAAAhidWxsQ2lyYwUAAAAPYWRkZWRDb2xsYXRlcmFsBQAAAAdidWxsQ29sCQAETgAAAAIJAQAAABRhY3Rpb25zV2l0aE1heWJlUG9vbAAAAAQJAABkAAAAAgUAAAAHYnVsbENvbAUAAAAPYWRkZWRDb2xsYXRlcmFsBQAAAAdiZWFyQ29sCQAAZAAAAAIFAAAACGJ1bGxDaXJjBQAAABJhZGRlZFRvQ2lyY3VsYXRpb24FAAAACGJlYXJDaXJjCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAADmhlYWRQb2ludGVyS2V5BQAAAARuZXh0CQAETAAAAAIJAQAAAApjb2xsZWN0RmVlAAAAAQUAAAAHZmVlU2l6ZQkABEwAAAACBQAAABFkZWNyZWFzZVF1ZXVlU2l6ZQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAAdpbnZva2VyBQAAABJhZGRlZFRvQ2lyY3VsYXRpb24JAAJZAAAAAQUAAAAEQlVMTAUAAAADbmlsAwkAAAAAAAACBQAAAAV0b2tlbgUAAAAEQkVBUgQAAAASYWRkZWRUb0NpcmN1bGF0aW9uCQAAawAAAAMFAAAACGJlYXJDaXJjBQAAAA9hZGRlZENvbGxhdGVyYWwFAAAAB2JlYXJDb2wJAAROAAAAAgkBAAAAFGFjdGlvbnNXaXRoTWF5YmVQb29sAAAABAUAAAAHYnVsbENvbAkAAGQAAAACBQAAAAdiZWFyQ29sBQAAAA9hZGRlZENvbGxhdGVyYWwFAAAACGJ1bGxDaXJjCQAAZAAAAAIFAAAACGJlYXJDaXJjBQAAABJhZGRlZFRvQ2lyY3VsYXRpb24JAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAOaGVhZFBvaW50ZXJLZXkFAAAABG5leHQJAARMAAAAAgkBAAAACmNvbGxlY3RGZWUAAAABBQAAAAdmZWVTaXplCQAETAAAAAIFAAAAEWRlY3JlYXNlUXVldWVTaXplCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMFAAAAB2ludm9rZXIFAAAAEmFkZGVkVG9DaXJjdWxhdGlvbgkAAlkAAAABBQAAAARCRUFSBQAAAANuaWwJAAACAAAAAQIAAAAMYmFkIHRva2VuIGlkAwkAAAAAAAACBQAAAAZhY3Rpb24FAAAABlJFREVFTQQAAAANcmVtb3ZlZFRva2VucwUAAAADYW10AwkAAAAAAAACBQAAAAV0b2tlbgUAAAAEQlVMTAQAAAARcmVtb3ZlZENvbGxhdGVyYWwJAABrAAAAAwUAAAAHYnVsbENvbAUAAAANcmVtb3ZlZFRva2VucwUAAAAIYnVsbENpcmMEAAAAB2ZlZVNpemUJAABrAAAAAwUAAAARcmVtb3ZlZENvbGxhdGVyYWwFAAAAEHJlZGVlbVBlcmNlbnRpbGUAAAAAAAAAJxAEAAAABnBheW91dAMJAABmAAAAAgUAAAARcmVtb3ZlZENvbGxhdGVyYWwFAAAAB2ZlZVNpemUJAABlAAAAAgUAAAARcmVtb3ZlZENvbGxhdGVyYWwFAAAAB2ZlZVNpemUAAAAAAAAAAAAJAAROAAAAAgkBAAAAFGFjdGlvbnNXaXRoTWF5YmVQb29sAAAABAkAAGUAAAACBQAAAAdidWxsQ29sBQAAABFyZW1vdmVkQ29sbGF0ZXJhbAUAAAAHYmVhckNvbAkAAGUAAAACBQAAAAhidWxsQ2lyYwUAAAANcmVtb3ZlZFRva2VucwUAAAAIYmVhckNpcmMJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAOaGVhZFBvaW50ZXJLZXkFAAAABG5leHQJAARMAAAAAgkBAAAACmNvbGxlY3RGZWUAAAABBQAAAAdmZWVTaXplCQAETAAAAAIFAAAAEWRlY3JlYXNlUXVldWVTaXplCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMFAAAAB2ludm9rZXIFAAAABnBheW91dAkAAlkAAAABBQAAAAltYWluVG9rZW4FAAAAA25pbAMJAAAAAAAAAgUAAAAFdG9rZW4FAAAABEJFQVIEAAAAEXJlbW92ZWRDb2xsYXRlcmFsCQAAawAAAAMFAAAAB2JlYXJDb2wFAAAADXJlbW92ZWRUb2tlbnMFAAAACGJlYXJDaXJjBAAAAAdmZWVTaXplCQAAawAAAAMFAAAAEXJlbW92ZWRDb2xsYXRlcmFsBQAAABByZWRlZW1QZXJjZW50aWxlAAAAAAAAACcQBAAAAAZwYXlvdXQDCQAAZgAAAAIFAAAAEXJlbW92ZWRDb2xsYXRlcmFsBQAAAAdmZWVTaXplCQAAZQAAAAIFAAAAEXJlbW92ZWRDb2xsYXRlcmFsBQAAAAdmZWVTaXplAAAAAAAAAAAACQAETgAAAAIJAQAAABRhY3Rpb25zV2l0aE1heWJlUG9vbAAAAAQFAAAAB2J1bGxDb2wJAABlAAAAAgUAAAAHYmVhckNvbAUAAAARcmVtb3ZlZENvbGxhdGVyYWwFAAAACGJ1bGxDaXJjCQAAZQAAAAIFAAAACGJlYXJDaXJjBQAAAA1yZW1vdmVkVG9rZW5zCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAADmhlYWRQb2ludGVyS2V5BQAAAARuZXh0CQAETAAAAAIJAQAAAApjb2xsZWN0RmVlAAAAAQUAAAAHZmVlU2l6ZQkABEwAAAACBQAAABFkZWNyZWFzZVF1ZXVlU2l6ZQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAAdpbnZva2VyBQAAAAZwYXlvdXQJAAJZAAAAAQUAAAAJbWFpblRva2VuBQAAAANuaWwJAAACAAAAAQIAAAAMYmFkIHRva2VuIGlkAwkAAAAAAAACBQAAAAZhY3Rpb24FAAAABFBPT0wEAAAAC2lzc3VlVG9rZW5zCQAAawAAAAMFAAAAFHBvb2xUb2tlbkNpcmN1bGF0aW9uBQAAAANhbXQFAAAACXBvb2xWYWx1ZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAVcG9vbE1haW5Ub2tlblZhbHVlS2V5CQAAZAAAAAIFAAAACHBvb2xNYWluBQAAAANhbXQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAF3Bvb2xUb2tlbkNpcmN1bGF0aW9uS2V5CQAAZAAAAAIFAAAAFHBvb2xUb2tlbkNpcmN1bGF0aW9uBQAAAAtpc3N1ZVRva2VucwkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAA5oZWFkUG9pbnRlcktleQUAAAAEbmV4dAkABEwAAAACBQAAABFkZWNyZWFzZVF1ZXVlU2l6ZQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAAdpbnZva2VyBQAAAAtpc3N1ZVRva2VucwkAAlkAAAABBQAAAAlwb29sVG9rZW4FAAAAA25pbAMJAAAAAAAAAgUAAAAGYWN0aW9uBQAAAAZVTlBPT0wKAQAAAAVzaGFyZQAAAAEAAAABYQkAAGsAAAADBQAAAAFhBQAAAANhbXQFAAAAFHBvb2xUb2tlbkNpcmN1bGF0aW9uBAAAAAx1bnBvb2xlZE1haW4JAQAAAAVzaGFyZQAAAAEFAAAACHBvb2xNYWluBAAAAAp1bnBvb2xlZFVwCQEAAAAFc2hhcmUAAAABBQAAAAZwb29sVXAEAAAAC3VucG9vbGVkRHduCQEAAAAFc2hhcmUAAAABBQAAAAdwb29sRHduBAAAAA91bnBvb2xlZFVwVmFsdWUJAABrAAAAAwUAAAAKdW5wb29sZWRVcAUAAAAHYnVsbENvbAUAAAAIYnVsbENpcmMEAAAAEHVucG9vbGVkRHduVmFsdWUJAABrAAAAAwUAAAALdW5wb29sZWREd24FAAAAB2JlYXJDb2wFAAAACGJlYXJDaXJjCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABVwb29sTWFpblRva2VuVmFsdWVLZXkJAABlAAAAAgUAAAAIcG9vbE1haW4FAAAADHVucG9vbGVkTWFpbgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAXcG9vbFRva2VuQ2lyY3VsYXRpb25LZXkJAABlAAAAAgUAAAAUcG9vbFRva2VuQ2lyY3VsYXRpb24FAAAAA2FtdAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAJcG9vbFVwS2V5CQAAZQAAAAIFAAAABnBvb2xVcAUAAAAKdW5wb29sZWRVcAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAKcG9vbER3bktleQkAAGUAAAACBQAAAAdwb29sRHduBQAAAAt1bnBvb2xlZER3bgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAASYnVsbENpcmN1bGF0aW9uS2V5CQAAZQAAAAIFAAAACGJ1bGxDaXJjBQAAAAp1bnBvb2xlZFVwCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJiZWFyQ2lyY3VsYXRpb25LZXkJAABlAAAAAgUAAAAIYmVhckNpcmMFAAAAC3VucG9vbGVkRHduCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABFidWxsQ29sbGF0ZXJhbEtleQkAAGUAAAACBQAAAAdidWxsQ29sBQAAAA91bnBvb2xlZFVwVmFsdWUJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEWJlYXJDb2xsYXRlcmFsS2V5CQAAZQAAAAIFAAAAB2JlYXJDb2wFAAAAEHVucG9vbGVkRHduVmFsdWUJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAOaGVhZFBvaW50ZXJLZXkFAAAABG5leHQJAARMAAAAAgUAAAARZGVjcmVhc2VRdWV1ZVNpemUJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAAHaW52b2tlcgkAAGQAAAACCQAAZAAAAAIFAAAADHVucG9vbGVkTWFpbgUAAAAPdW5wb29sZWRVcFZhbHVlBQAAABB1bnBvb2xlZER3blZhbHVlCQACWQAAAAEFAAAACW1haW5Ub2tlbgUAAAADbmlsCQAAAgAAAAEJAAEsAAAAAgIAAAAMYmFkIGFjdGlvbjogBQAAAAZhY3Rpb24DBQAAAA1pc0xhc3RFbGVtZW50CQAETAAAAAIFAAAADW92ZXJ3cml0ZVRhaWwFAAAABWl0ZW1zBQAAAAVpdGVtcwEAAAAJcmViYWxhbmNlAAAAAAoBAAAAAkxWAAAAAwAAAAF2AAAAAnAwAAAAAnAxBAAAAAVkZW5vbQAAAAAAAAAAZAQAAAAEcG1heAkAAGkAAAACAwkAAGYAAAACBQAAAAJwMQUAAAACcDAFAAAAAnAxBQAAAAJwMAUAAAAFZGVub20EAAAABHBtaW4JAABpAAAAAgMJAABmAAAAAgUAAAACcDAFAAAAAnAxBQAAAAJwMQUAAAACcDAFAAAABWRlbm9tBAAAAAFhCQAAaAAAAAIFAAAABHBtaW4FAAAABHBtaW4EAAAAAWIJAABlAAAAAgkAAGgAAAACCQAAaAAAAAIAAAAAAAAAAAkFAAAABHBtYXgFAAAABHBtYXgJAABoAAAAAgkAAGgAAAACAAAAAAAAAAAPBQAAAARwbWF4BQAAAARwbWluCQAAawAAAAMFAAAAAXYJAABkAAAAAgkAAGgAAAACAAAAAAAAAAAGBQAAAAFhBQAAAAFiCQAAZAAAAAIJAABoAAAAAgAAAAAAAAAABwUAAAABYQUAAAABYgQAAAARc2V0dGxlZFByaWNlSW5kZXgJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAABpsYXN0UmViYWxhbmNlUHJpY2VJbmRleEtleQIAAAARaW5jb25zaXN0ZW50IGRhdGEEAAAAE3Vuc2V0dGxlZFByaWNlSW5kZXgJAABkAAAAAgUAAAARc2V0dGxlZFByaWNlSW5kZXgAAAAAAAAAAAEEAAAAEnNldHRsZWRQcmljZUhlaWdodAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABm9yYWNsZQkAASwAAAACAgAAAAxwcmljZV9pbmRleF8JAAGkAAAAAQUAAAARc2V0dGxlZFByaWNlSW5kZXgCAAAAKGJhZCBvcmFjbGUgZGF0YSBmb3Igc2V0dGxlZCBwcmljZSBoZWlnaHQEAAAADHNldHRsZWRQcmljZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABm9yYWNsZQkAASwAAAACAgAAAAZwcmljZV8JAAGkAAAAAQUAAAASc2V0dGxlZFByaWNlSGVpZ2h0AgAAABliYWQgb3JhY2xlIGRhdGEgZm9yIHByaWNlBAAAAA9uZXh0UHJpY2VIZWlnaHQJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAZvcmFjbGUJAAEsAAAAAgIAAAAMcHJpY2VfaW5kZXhfCQABpAAAAAEFAAAAE3Vuc2V0dGxlZFByaWNlSW5kZXgCAAAAFG5vIG5leHQgcHJpY2UgaGVpZ2h0BAAAAAluZXh0UHJpY2UJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAZvcmFjbGUJAAEsAAAAAgIAAAAGcHJpY2VfCQABpAAAAAEFAAAAD25leHRQcmljZUhlaWdodAIAAAANbm8gbmV4dCBwcmljZQQAAAAGbWluVm9sAwkAAGYAAAACBQAAAAdiZWFyQ29sBQAAAAdidWxsQ29sBQAAAAdidWxsQ29sBQAAAAdiZWFyQ29sBAAAAAZyZWRpc3QJAQAAAAJMVgAAAAMFAAAABm1pblZvbAUAAAAMc2V0dGxlZFByaWNlBQAAAAluZXh0UHJpY2UEAAAACm5ld0J1bGxDb2wDCQAAZgAAAAIFAAAACW5leHRQcmljZQUAAAAMc2V0dGxlZFByaWNlCQAAZAAAAAIFAAAAB2J1bGxDb2wFAAAABnJlZGlzdAkAAGUAAAACBQAAAAdidWxsQ29sBQAAAAZyZWRpc3QEAAAACm5ld0JlYXJDb2wDCQAAZgAAAAIFAAAACW5leHRQcmljZQUAAAAMc2V0dGxlZFByaWNlCQAAZQAAAAIFAAAAB2JlYXJDb2wFAAAABnJlZGlzdAkAAGQAAAACBQAAAAdiZWFyQ29sBQAAAAZyZWRpc3QEAAAADSR0MDE5MjYwMTk0NDcJAQAAAAtwb29sU3VwcG9ydAAAAAcFAAAACm5ld0J1bGxDb2wFAAAACm5ld0JlYXJDb2wFAAAACGJ1bGxDaXJjBQAAAAhiZWFyQ2lyYwUAAAAIcG9vbE1haW4FAAAABnBvb2xVcAUAAAAHcG9vbER3bgQAAAAKdXBkQnVsbENvbAgFAAAADSR0MDE5MjYwMTk0NDcAAAACXzEEAAAACnVwZEJlYXJDb2wIBQAAAA0kdDAxOTI2MDE5NDQ3AAAAAl8yBAAAAAt1cGRCdWxsQ2lyYwgFAAAADSR0MDE5MjYwMTk0NDcAAAACXzMEAAAAC3VwZEJlYXJDaXJjCAUAAAANJHQwMTkyNjAxOTQ0NwAAAAJfNAQAAAALdXBkUG9vbE1haW4IBQAAAA0kdDAxOTI2MDE5NDQ3AAAAAl81BAAAAAl1cGRQb29sVXAIBQAAAA0kdDAxOTI2MDE5NDQ3AAAAAl82BAAAAAp1cGRQb29sRHduCAUAAAANJHQwMTkyNjAxOTQ0NwAAAAJfNwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARYnVsbENvbGxhdGVyYWxLZXkFAAAACnVwZEJ1bGxDb2wJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEWJlYXJDb2xsYXRlcmFsS2V5BQAAAAp1cGRCZWFyQ29sCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJidWxsQ2lyY3VsYXRpb25LZXkFAAAAC3VwZEJ1bGxDaXJjCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJiZWFyQ2lyY3VsYXRpb25LZXkFAAAAC3VwZEJlYXJDaXJjCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABVwb29sTWFpblRva2VuVmFsdWVLZXkFAAAAC3VwZFBvb2xNYWluCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAlwb29sVXBLZXkFAAAACXVwZFBvb2xVcAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAKcG9vbER3bktleQUAAAAKdXBkUG9vbER3bgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAabGFzdFJlYmFsYW5jZVByaWNlSW5kZXhLZXkFAAAAE3Vuc2V0dGxlZFByaWNlSW5kZXgFAAAAA25pbAAAAAcAAAADaW52AQAAAARpbml0AAAACQAAAAZjb25maWcAAAAIb3JhY2xlUEsAAAAGbmFtZXVwAAAAB25hbWVkd24AAAAGZGVzY1VwAAAAB2Rlc2NEd24AAAAIcG9vbE5hbWUAAAAIcG9vbERlc2MAAAAFZGVub20DCQEAAAAJaXNEZWZpbmVkAAAAAQkABB0AAAACBQAAAAR0aGlzBQAAAAdCVUxMS2V5CQAAAgAAAAECAAAAE2FscmVhZHkgaW5pdGlhbGl6ZWQEAAAAE3RvdGFsT3duZWRNYWluVG9rZW4ICQABkQAAAAIIBQAAAANpbnYAAAAIcGF5bWVudHMAAAAAAAAAAAAAAAAGYW1vdW50BAAAAAVidWxscwkAAGkAAAACBQAAABN0b3RhbE93bmVkTWFpblRva2VuAAAAAAAAAAADBAAAAAViZWFycwUAAAAFYnVsbHMEAAAABXBvb2xzCQAAZQAAAAIJAABlAAAAAgUAAAATdG90YWxPd25lZE1haW5Ub2tlbgUAAAAFYnVsbHMFAAAABWJlYXJzAwMDCQAAAAAAAAIFAAAABWJlYXJzAAAAAAAAAAAABgkAAAAAAAACBQAAAAVidWxscwAAAAAAAAAAAAYJAAAAAAAAAgUAAAAFcG9vbHMAAAAAAAAAAAAJAAACAAAAAQIAAAATY2FuJ3QgaW5pdCBiYWxhbmNlcwQAAAAXb3JhY2xlQ3VycmVudFByaWNlSW5kZXgJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAQAAABRhZGRyZXNzRnJvbVB1YmxpY0tleQAAAAEJAAJZAAAAAQUAAAAIb3JhY2xlUEsCAAAAEmJhZCBvcmFjbGUgYWRkcmVzcwUAAAARbGFzdFByaWNlSW5kZXhLZXkCAAAAImNhbid0IGZpbmQgbGFzdCBvcmFjbGUgcHJpY2UgaW5kZXgEAAAABGJ1bGwJAARCAAAABQUAAAAGbmFtZXVwBQAAAAZkZXNjVXAJAABoAAAAAgkAAGgAAAACAAAAAAAAAABkBQAAAAR0ZW42BQAAAAR0ZW42AAAAAAAAAAAGBgQAAAAEYmVhcgkABEIAAAAFBQAAAAduYW1lZHduBQAAAAdkZXNjRHduCQAAaAAAAAIJAABoAAAAAgAAAAAAAAAAZAUAAAAEdGVuNgUAAAAEdGVuNgAAAAAAAAAABgYEAAAABHBvb2wJAARCAAAABQUAAAAIcG9vbE5hbWUFAAAACHBvb2xEZXNjCQAAaAAAAAIJAABoAAAAAgAAAAAAAAAAZAUAAAAEdGVuNgUAAAAEdGVuNgAAAAAAAAAABgYEAAAABGJ1aWQJAAQ4AAAAAQUAAAAEYnVsbAQAAAAEYmVpZAkABDgAAAABBQAAAARiZWFyBAAAAARwb2lkCQAEOAAAAAEFAAAABHBvb2wJAARMAAAAAgUAAAAEYnVsbAkABEwAAAACBQAAAARiZWFyCQAETAAAAAIFAAAABHBvb2wJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAHQlVMTEtleQkAAlgAAAABBQAAAARidWlkCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAB0JFQVJLZXkJAAJYAAAAAQUAAAAEYmVpZAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAAxtYWluVG9rZW5LZXkJAAJYAAAAAQkBAAAABXZhbHVlAAAAAQgJAAGRAAAAAggFAAAAA2ludgAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAdhc3NldElkCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAADHBvb2xUb2tlbktleQkAAlgAAAABBQAAAARwb2lkCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAC29yYWNsZVBLS2V5BQAAAAhvcmFjbGVQSwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAabGFzdFJlYmFsYW5jZVByaWNlSW5kZXhLZXkFAAAAF29yYWNsZUN1cnJlbnRQcmljZUluZGV4CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABFidWxsQ29sbGF0ZXJhbEtleQUAAAAFYnVsbHMJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEWJlYXJDb2xsYXRlcmFsS2V5BQAAAAViZWFycwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAASYnVsbENpcmN1bGF0aW9uS2V5CQAAaQAAAAIFAAAABWJ1bGxzBQAAAAVkZW5vbQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAASYmVhckNpcmN1bGF0aW9uS2V5CQAAaQAAAAIFAAAABWJlYXJzBQAAAAVkZW5vbQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAXcG9vbFRva2VuQ2lyY3VsYXRpb25LZXkJAABpAAAAAgUAAAAFcG9vbHMFAAAABWRlbm9tCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAApwb29sRHduS2V5AAAAAAAAAAAACQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAlwb29sVXBLZXkAAAAAAAAAAAAJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAFXBvb2xNYWluVG9rZW5WYWx1ZUtleQUAAAAFcG9vbHMJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAARY29uZmlnUHJvdmlkZXJLZXkFAAAABmNvbmZpZwkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAADaW52AAAABmNhbGxlcgkAAGkAAAACBQAAAAVidWxscwUAAAAFZGVub20FAAAABGJ1aWQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAA2ludgAAAAZjYWxsZXIJAABpAAAAAgUAAAAFYmVhcnMFAAAABWRlbm9tBQAAAARiZWlkCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAANpbnYAAAAGY2FsbGVyCQAAaQAAAAIFAAAABXBvb2xzBQAAAAVkZW5vbQUAAAAEcG9pZAUAAAADbmlsAAAAAWkBAAAAC3dpdGhkcmF3RmVlAAAAAQAAAAZhbW91bnQDCQAAZgAAAAIFAAAABmFtb3VudAUAAAAPZmVlc0FjY3VtdWxhdGVkCQAAAgAAAAEJAAEsAAAAAgIAAAAVdG9vIG11Y2guIGF2YWlsYWJsZTogCQABpAAAAAEFAAAAD2ZlZXNBY2N1bXVsYXRlZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAASZmVlc0FjY3VtdWxhdGVkS2V5CQAAZQAAAAIFAAAAD2ZlZXNBY2N1bXVsYXRlZAUAAAAGYW1vdW50CQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMFAAAACmZlZUFkZHJlc3MFAAAABmFtb3VudAkAAlkAAAABBQAAAAltYWluVG9rZW4FAAAAA25pbAAAAANpbnYBAAAADXJlcXVlc3RSZWRlZW0AAAAAAwkAAAAAAAACCQEAAAAVdmFsaWRhdGVSZXF1ZXN0UmVkZWVtAAAAAQUAAAADaW52BQAAAAR1bml0BAAAAAdhc3NldElkCQACWAAAAAEJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAggJAAGRAAAAAggFAAAAA2ludgAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAdhc3NldElkAgAAABt3YXZlcyBhcmUgbm90IGFjY2VwdGVkIGhlcmUJAQAAAAdlbnF1ZXVlAAAABgkAAlgAAAABCAUAAAADaW52AAAADXRyYW5zYWN0aW9uSWQFAAAABlJFREVFTQgJAAGRAAAAAggFAAAAA2ludgAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAZhbW91bnQFAAAAB2Fzc2V0SWQJAABkAAAAAgUAAAAQb3JhY2xlUHJpY2VJbmRleAAAAAAAAAAAAQkABCUAAAABCAUAAAADaW52AAAABmNhbGxlcgkAAAIAAAABAgAAAA5kb2Vzbid0IGhhcHBlbgAAAANpbnYBAAAADHJlcXVlc3RJc3N1ZQAAAAEAAAAHdG9rZW5JZAMJAAAAAAAAAggFAAAAA2ludgAAAAZjYWxsZXIFAAAABHRoaXMJAAACAAAAAQIAAAAIY2FuJ3QgZG8DCQEAAAABIQAAAAEJAQAAAAdhbGxvd2VkAAAAAQgFAAAAA2ludgAAAAZjYWxsZXIJAAACAAAAAQIAAAAXb25seSB3aGl0ZWxpc3RlZCBjYW4gZG8EAAAADGVycm9yTWVzc2FnZQkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAApvbmx5IEJVTEwoBQAAAARCVUxMAgAAAAopIG9yIEJFQVIoBQAAAARCRUFSAgAAACwpIHRva2VucyBhcmUgYXZhaWxhYmxlIGluIGV4Y2hhbmdlIGZvciBVU0ROKAUAAAAJbWFpblRva2VuAgAAAAEpAwMJAQAAAAIhPQAAAAIFAAAAB3Rva2VuSWQFAAAABEJVTEwJAQAAAAIhPQAAAAIFAAAAB3Rva2VuSWQFAAAABEJFQVIHBQAAAAxlcnJvck1lc3NhZ2UDCQEAAAACIT0AAAACCAkAAZEAAAACCAUAAAADaW52AAAACHBheW1lbnRzAAAAAAAAAAAAAAAAB2Fzc2V0SWQJAAJZAAAAAQUAAAAJbWFpblRva2VuBQAAAAxlcnJvck1lc3NhZ2UDCQAAZgAAAAIFAAAACG1pbklzc3VlCAkAAZEAAAACCAUAAAADaW52AAAACHBheW1lbnRzAAAAAAAAAAAAAAAABmFtb3VudAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgIAAAAqQXR0YWNoZWQgcGF5bWVudCB0b28gc21hbGwuIE1pbiByZXF1aXJlZDogCQABpAAAAAEJAABpAAAAAgUAAAAIbWluSXNzdWUAAAAAAAAPQkACAAAABSBVU0ROBAAAAAptYXhBbGxvd2VkCQEAAAAIbWF4SXNzdWUAAAABBQAAAAd0b2tlbklkAwMJAAAAAAAAAgUAAAAJd2hpdGVsaXN0AgAAAAAJAABmAAAAAggJAAGRAAAAAggFAAAAA2ludgAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAZhbW91bnQFAAAACm1heEFsbG93ZWQHCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAAER0cnlpbmcgdG8gaXNzdWUgbW9yZSB0aGFuIHBvb2wgY2FuIGhhbmRsZS4gTWF4IGF0dGFjaG1lbnQgYWxsb3dlZCA9IAkAAaQAAAABCQAAaQAAAAIFAAAACm1heEFsbG93ZWQAAAAAAAAPQkACAAAABSBVU0ROCQEAAAAHZW5xdWV1ZQAAAAYJAAJYAAAAAQgFAAAAA2ludgAAAA10cmFuc2FjdGlvbklkBQAAAAVJU1NVRQgJAAGRAAAAAggFAAAAA2ludgAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAZhbW91bnQFAAAAB3Rva2VuSWQJAABkAAAAAgUAAAAQb3JhY2xlUHJpY2VJbmRleAAAAAAAAAAAAQkABCUAAAABCAUAAAADaW52AAAABmNhbGxlcgAAAANpbnYBAAAABnNldHRsZQAAAAAEAAAACnF1ZXVlRW1wdHkJAAAAAAAAAgUAAAALaGVhZFBvaW50ZXICAAAAAAQAAAAMY2FuUmViYWxhbmNlCQAAZgAAAAIFAAAAEG9yYWNsZVByaWNlSW5kZXgFAAAAFHJlYmFsYW5jZWRQcmljZUluZGV4AwUAAAAKcXVldWVFbXB0eQMFAAAADGNhblJlYmFsYW5jZQkBAAAACXJlYmFsYW5jZQAAAAAJAAACAAAAAQIAAAAXW09LXSBhbGwgZG9uZSwgY2Fycnkgb24EAAAABGRhdGEJAAS1AAAAAgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAC2hlYWRQb2ludGVyAgAAABBiYWQgaGVhZCBwb2ludGVyAgAAAAF8BAAAAApwcmljZUluZGV4CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAEZGF0YQAAAAAAAAAAAwMJAABmAAAAAgUAAAAKcHJpY2VJbmRleAUAAAAUcmViYWxhbmNlZFByaWNlSW5kZXgDBQAAAAxjYW5SZWJhbGFuY2UJAQAAAAlyZWJhbGFuY2UAAAAACQAAAgAAAAECAAAAEVtPS10gbmVlZCB0byB3YWl0AwkAAAAAAAACBQAAAApwcmljZUluZGV4BQAAABRyZWJhbGFuY2VkUHJpY2VJbmRleAkBAAAAB2RlcXVldWUAAAAACQAAAgAAAAECAAAAMGNvcnJ1cHQgZGF0YSwgZnV0dXJlIHByaWNlIGlkIGFscmVhZHkgcmViYWxhbmNlZAAAAANpbnYBAAAAC3JlcXVlc3RQb29sAAAAAAMJAQAAAAEhAAAAAQkBAAAAB2FsbG93ZWQAAAABCAUAAAADaW52AAAABmNhbGxlcgkAAAIAAAABAgAAABdvbmx5IHdoaXRlbGlzdGVkIGNhbiBkbwQAAAAKZXJyTWVzc2FnZQkAASwAAAACCQABLAAAAAICAAAAHG1haW4gdG9rZW4gbXVzdCBiZSBhdHRhY2hlZCgFAAAACW1haW5Ub2tlbgIAAAABKQQAAAADcG10CQABkQAAAAIIBQAAAANpbnYAAAAIcGF5bWVudHMAAAAAAAAAAAADCQEAAAACIT0AAAACCAUAAAADcG10AAAAB2Fzc2V0SWQJAAJZAAAAAQUAAAAJbWFpblRva2VuCQAAAgAAAAEFAAAACmVyck1lc3NhZ2UDCQAAZgAAAAIFAAAAB21pblBvb2wIBQAAAANwbXQAAAAGYW1vdW50CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAADnBvb2wgYXQgbGVhc3QgCQABpAAAAAEFAAAAB21pblBvb2wCAAAAASAFAAAACW1haW5Ub2tlbgkBAAAAB2VucXVldWUAAAAGCQACWAAAAAEIBQAAAANpbnYAAAANdHJhbnNhY3Rpb25JZAUAAAAEUE9PTAgJAAGRAAAAAggFAAAAA2ludgAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAZhbW91bnQCAAAAAAkAAGQAAAACBQAAABBvcmFjbGVQcmljZUluZGV4AAAAAAAAAAABCQAEJQAAAAEIBQAAAANpbnYAAAAGY2FsbGVyAAAAA2ludgEAAAANcmVxdWVzdFVucG9vbAAAAAAEAAAACmVyck1lc3NhZ2UJAAEsAAAAAgkAASwAAAACAgAAABhvbmx5IHBvb2wgdG9rZW4gYWxsb3dlZCgFAAAACXBvb2xUb2tlbgIAAAABKQQAAAADcG10CQABkQAAAAIIBQAAAANpbnYAAAAIcGF5bWVudHMAAAAAAAAAAAADCQEAAAACIT0AAAACCAUAAAADcG10AAAAB2Fzc2V0SWQJAAJZAAAAAQUAAAAJcG9vbFRva2VuCQAAAgAAAAEFAAAACmVyck1lc3NhZ2UEAAAACGVzdGltYXRlCQAAawAAAAMFAAAACXBvb2xWYWx1ZQgFAAAAA3BtdAAAAAZhbW91bnQFAAAAFHBvb2xUb2tlbkNpcmN1bGF0aW9uAwkAAGYAAAACBQAAAAdtaW5Qb29sBQAAAAhlc3RpbWF0ZQkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABN1bnBvb2wgYXQgbGVhc3QgZm9yCQABpAAAAAEFAAAAB21pblBvb2wCAAAAASAFAAAACW1haW5Ub2tlbgkBAAAAB2VucXVldWUAAAAGCQACWAAAAAEIBQAAAANpbnYAAAANdHJhbnNhY3Rpb25JZAUAAAAGVU5QT09MCAkAAZEAAAACCAUAAAADaW52AAAACHBheW1lbnRzAAAAAAAAAAAAAAAABmFtb3VudAIAAAAACQAAZAAAAAIFAAAAEG9yYWNsZVByaWNlSW5kZXgAAAAAAAAAAAEJAAQlAAAAAQgFAAAAA2ludgAAAAZjYWxsZXIAAAABAAAAAnR4AQAAAAZ2ZXJpZnkAAAAABAAAAAdpbml0aWFsAwkBAAAAASEAAAABCQEAAAAJaXNEZWZpbmVkAAAAAQkABB0AAAACBQAAAAR0aGlzBQAAAAdCVUxMS2V5CQAB9AAAAAMIBQAAAAJ0eAAAAAlib2R5Qnl0ZXMJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAAgFAAAAAnR4AAAAD3NlbmRlclB1YmxpY0tleQcEAAAAC2FkbWluQWN0aW9uCQAAZgAAAAIJAABkAAAAAgkAAGQAAAACAwkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAJAAJZAAAAAQkAAZEAAAACBQAAABBwdWJLZXlBZG1pbnNMaXN0AAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAwkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAEJAAJZAAAAAQkAAZEAAAACBQAAABBwdWJLZXlBZG1pbnNMaXN0AAAAAAAAAAABAAAAAAAAAAABAAAAAAAAAAAAAwkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAIJAAJZAAAAAQkAAZEAAAACBQAAABBwdWJLZXlBZG1pbnNMaXN0AAAAAAAAAAACAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAABBAAAAA1zdGFraW5nQWN0aW9uBAAAAAckbWF0Y2gwBQAAAAJ0eAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAXSW52b2tlU2NyaXB0VHJhbnNhY3Rpb24EAAAAAnR4BQAAAAckbWF0Y2gwBAAAAA9zaWduZWRDb3JyZWN0bHkJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAABQAAAA9kYWVtb25QdWJsaWNLZXkEAAAAC2ZlZXNDb3JyZWN0AwkAAAAAAAACCAUAAAACdHgAAAAKZmVlQXNzZXRJZAUAAAAEdW5pdAkAAGcAAAACCQAAaAAAAAIAAAAAAAAAA+gAAAAAAAAAA+gIBQAAAAJ0eAAAAANmZWUHBAAAAAtkYXBwQ29ycmVjdAkAAAAAAAACCAUAAAACdHgAAAAEZEFwcAUAAAAKcnBkQWRkcmVzcwQAAAAGdW5sb2NrCQAAAAAAAAIIBQAAAAJ0eAAAAAhmdW5jdGlvbgIAAAAOdW5sb2NrTmV1dHJpbm8EAAAABGxvY2sDAwkAAAAAAAACCAUAAAACdHgAAAAIZnVuY3Rpb24CAAAADmxvY2tOZXV0cmlub1NQCQAAAAAAAAIJAAGRAAAAAggFAAAAAnR4AAAABGFyZ3MAAAAAAAAAAAAFAAAADnN0YWtpbmdBZGRyZXNzBwkAAGcAAAACCAkAA+8AAAABBQAAAAR0aGlzAAAACWF2YWlsYWJsZQUAAAAEdGVuOAcEAAAAC2Z1bmNDb3JyZWN0AwUAAAAEbG9jawYFAAAABnVubG9jawMDAwUAAAAPc2lnbmVkQ29ycmVjdGx5BQAAAAtmZWVzQ29ycmVjdAcFAAAAC2RhcHBDb3JyZWN0BwUAAAALZnVuY0NvcnJlY3QHBwMDBQAAAAdpbml0aWFsBgUAAAALYWRtaW5BY3Rpb24GBQAAAA1zdGFraW5nQWN0aW9u9ONx/A==", "height": 2276465, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: G42cQY3f5JPRXNq6pueQRSjVp2z2FAMFESEinZmDJJjN Next: 5i1hDiMHv7QhuYsVhcggdNTP3dd8P66tbbnySD1yyLsj Diff:
OldNewDifferences
44 let ten6 = 1000000
55
66 let ten8 = 100000000
7+
8+let configProviderKey = "configProvider"
9+
10+let configProvider = match getString(this, configProviderKey) {
11+ case s: String =>
12+ addressFromStringValue(s)
13+ case _ =>
14+ this
15+}
716
817 let BULLKey = "BULLId"
918
3140
3241 let feesAccumulatedKey = "feesAccumulated"
3342
34-let whitelistOnlyKey = "whitelistOnly"
35-
3643 let whitelistKey = "issueWhiteList"
3744
3845 let oraclePKKey = "oracle"
5966
6067 let poolDwnKey = "poolDwn"
6168
62-let poolEnabledKey = "poolEnabled"
63-
6469 let poolTokenCirculationKey = "poolTokenCirculation"
6570
6671 let poolTokenKey = "poolToken"
7984
8085 let mainToken = valueOrErrorMessage(getString(this, mainTokenKey), "no mainTokenKey")
8186
82-let issuePercentile = valueOrErrorMessage(getInteger(this, issuePercentileKey), "no issuePercentileKey")
87+let issuePercentile = valueOrErrorMessage(getInteger(configProvider, issuePercentileKey), "no issuePercentileKey")
8388
84-let redeemPercentile = valueOrErrorMessage(getInteger(this, redeemPercentileKey), "no redeemPercentileKey")
89+let redeemPercentile = valueOrErrorMessage(getInteger(configProvider, redeemPercentileKey), "no redeemPercentileKey")
8590
86-let minIssue = valueOrErrorMessage(getInteger(this, minIssueKey), "no minIssueKey")
91+let minIssue = valueOrErrorMessage(getInteger(configProvider, minIssueKey), "no minIssueKey")
8792
88-let minRedeem = valueOrErrorMessage(getInteger(this, minRedeemKey), "no minRedeemKey")
93+let minRedeem = valueOrErrorMessage(getInteger(configProvider, minRedeemKey), "no minRedeemKey")
8994
90-let minPool = valueOrErrorMessage(getInteger(this, minPoolKey), "no minPoolKey")
95+let minPool = valueOrErrorMessage(getInteger(configProvider, minPoolKey), "no minPoolKey")
9196
92-let whitelistOnly = valueOrErrorMessage(getBoolean(this, whitelistOnlyKey), "no whitelistOnlyKey")
97+let whitelist = valueOrErrorMessage(getString(configProvider, whitelistKey), "no whitelistKey")
9398
94-let whitelist = valueOrErrorMessage(getString(this, whitelistKey), "no bullCollateralKey")
99+func allowed (a) = if ((whitelist == ""))
100+ then true
101+ else isDefined(indexOf(whitelist, toString(a)))
95102
96-let poolInitialized = isDefined(getBoolean(this, poolMainTokenValueKey))
97-
98-let poolEnabled = (getBoolean(this, poolEnabledKey) == true)
99103
100104 let poolMain = valueOrErrorMessage(getInteger(this, poolMainTokenValueKey), "no poolMainTokenValueKey")
101105
137141
138142 let daemonPubKeyKey = "daemonPublicKey"
139143
140-let feeAddress = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, feeAddrKey), "no feeAddress")), "bad feeAddress")
144+let feeAddress = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(configProvider, feeAddrKey), "no feeAddress")), "bad feeAddress")
141145
142-let stakingAddress = valueOrErrorMessage(getString(this, stakingAddrKey), "no stakingAddress")
146+let stakingAddress = valueOrErrorMessage(getString(configProvider, stakingAddrKey), "no stakingAddress")
143147
144-let daemonPublicKey = fromBase58String(valueOrErrorMessage(getString(this, daemonPubKeyKey), "no daemonPublicKey"))
148+let daemonPublicKey = fromBase58String(valueOrErrorMessage(getString(configProvider, daemonPubKeyKey), "no daemonPublicKey"))
145149
146150 let rpdAddress = addressFromString("3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ")
147151
155159
156160
157161 func buildNewItem (action,amt,token,priceIndex,invoker) = (((((((((action + "|") + toString(amt)) + "|") + token) + "|") + toString(priceIndex)) + "|") + invoker) + "|")
162+
163+
164+func maxIssue (tokenId) = {
165+ let poolInvestment = if ((poolUp > 0))
166+ then BULL
167+ else BEAR
168+ if ((poolInvestment == tokenId))
169+ then poolMain
170+ else ((2 * poolValue) - poolMain)
171+ }
158172
159173
160174 func validateRequestRedeem (inv) = if ((inv.caller == this))
243257 if ((curBullCol0 > curBearCol0))
244258 then {
245259 let afterCloseUp = closeUp(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0)
246- let $t0994610083 = afterCloseUp
247- let a = $t0994610083._1
248- let b = $t0994610083._2
249- let c = $t0994610083._3
250- let d = $t0994610083._4
251- let e = $t0994610083._5
252- let f = $t0994610083._6
253- let g = $t0994610083._7
260+ let $t01028610423 = afterCloseUp
261+ let a = $t01028610423._1
262+ let b = $t01028610423._2
263+ let c = $t01028610423._3
264+ let d = $t01028610423._4
265+ let e = $t01028610423._5
266+ let f = $t01028610423._6
267+ let g = $t01028610423._7
254268 if ((f > 0))
255269 then afterCloseUp
256270 else if ((f == 0))
259273 }
260274 else {
261275 let afterCloseDwn = closeDwn(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0)
262- let $t01043410574 = afterCloseDwn
263- let a = $t01043410574._1
264- let b = $t01043410574._2
265- let c = $t01043410574._3
266- let d = $t01043410574._4
267- let e = $t01043410574._5
268- let f = $t01043410574._6
269- let g = $t01043410574._7
276+ let $t01077410914 = afterCloseDwn
277+ let a = $t01077410914._1
278+ let b = $t01077410914._2
279+ let c = $t01077410914._3
280+ let d = $t01077410914._4
281+ let e = $t01077410914._5
282+ let f = $t01077410914._6
283+ let g = $t01077410914._7
270284 if ((g > 0))
271285 then afterCloseDwn
272286 else if ((g == 0))
276290 }
277291
278292
279-func actionsWithMaybePool (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0) = if (poolEnabled)
280- then {
281- let $t01089811081 = poolSupport(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, poolMain, poolUp, poolDwn)
282- let bullCol1 = $t01089811081._1
283- let bearCol1 = $t01089811081._2
284- let bullCic1 = $t01089811081._3
285- let bearCirc1 = $t01089811081._4
286- let poolMain1 = $t01089811081._5
287- let poolUp1 = $t01089811081._6
288- let poolDwn1 = $t01089811081._7
293+func actionsWithMaybePool (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0) = {
294+ let $t01121111394 = poolSupport(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, poolMain, poolUp, poolDwn)
295+ let bullCol1 = $t01121111394._1
296+ let bearCol1 = $t01121111394._2
297+ let bullCic1 = $t01121111394._3
298+ let bearCirc1 = $t01121111394._4
299+ let poolMain1 = $t01121111394._5
300+ let poolUp1 = $t01121111394._6
301+ let poolDwn1 = $t01121111394._7
289302 [IntegerEntry(bullCollateralKey, bullCol1), IntegerEntry(bullCirculationKey, bullCic1), IntegerEntry(bearCollateralKey, bearCol1), IntegerEntry(bearCirculationKey, bearCirc1), IntegerEntry(poolMainTokenValueKey, poolMain1), IntegerEntry(poolUpKey, poolUp1), IntegerEntry(poolDwnKey, poolDwn1)]
290- }
291- else [IntegerEntry(bullCollateralKey, curBullCol0), IntegerEntry(bullCirculationKey, curBullCirc0), IntegerEntry(bearCollateralKey, curBearCol0), IntegerEntry(bearCirculationKey, curBearCirc0)]
303+ }
292304
293305
294306 func dequeue () = if ((queueSize == 0))
402414 let newBearCol = if ((nextPrice > settledPrice))
403415 then (bearCol - redist)
404416 else (bearCol + redist)
405- if (poolEnabled)
406- then {
407- let $t01922019407 = poolSupport(newBullCol, newBearCol, bullCirc, bearCirc, poolMain, poolUp, poolDwn)
408- let updBullCol = $t01922019407._1
409- let updBearCol = $t01922019407._2
410- let updBullCirc = $t01922019407._3
411- let updBearCirc = $t01922019407._4
412- let updPoolMain = $t01922019407._5
413- let updPoolUp = $t01922019407._6
414- let updPoolDwn = $t01922019407._7
417+ let $t01926019447 = poolSupport(newBullCol, newBearCol, bullCirc, bearCirc, poolMain, poolUp, poolDwn)
418+ let updBullCol = $t01926019447._1
419+ let updBearCol = $t01926019447._2
420+ let updBullCirc = $t01926019447._3
421+ let updBearCirc = $t01926019447._4
422+ let updPoolMain = $t01926019447._5
423+ let updPoolUp = $t01926019447._6
424+ let updPoolDwn = $t01926019447._7
415425 [IntegerEntry(bullCollateralKey, updBullCol), IntegerEntry(bearCollateralKey, updBearCol), IntegerEntry(bullCirculationKey, updBullCirc), IntegerEntry(bearCirculationKey, updBearCirc), IntegerEntry(poolMainTokenValueKey, updPoolMain), IntegerEntry(poolUpKey, updPoolUp), IntegerEntry(poolDwnKey, updPoolDwn), IntegerEntry(lastRebalancePriceIndexKey, unsettledPriceIndex)]
416- }
417- else [IntegerEntry(bullCollateralKey, newBullCol), IntegerEntry(bearCollateralKey, newBearCol), IntegerEntry(lastRebalancePriceIndexKey, unsettledPriceIndex)]
418426 }
419427
420428
421429 @Callable(inv)
422-func init (bullId,bearId,mainTokenId,oraclePK,whitelisted) = if (isDefined(getString(this, BULLKey)))
430+func init (config,oraclePK,nameup,namedwn,descUp,descDwn,poolName,poolDesc,denom) = if (isDefined(getString(this, BULLKey)))
423431 then throw("already initialized")
424- else if ((toBase58String(valueOrErrorMessage(inv.payments[0].assetId, "neutrino payment required")) != mainTokenId))
425- then throw("payment not in neutrino")
426- else {
427- let totalOwnedMainToken = inv.payments[0].amount
428- let bulls = (totalOwnedMainToken / 2)
429- let bears = (totalOwnedMainToken - bulls)
430- if (if ((bears == 0))
431- then true
432- else (bulls == 0))
433- then throw("can't init balances")
434- else {
435- let oracleCurrentPriceIndex = valueOrErrorMessage(getInteger(valueOrErrorMessage(addressFromPublicKey(fromBase58String(oraclePK)), "bad oracle address"), lastPriceIndexKey), "can't find last oracle price index")
436-[StringEntry(BULLKey, bullId), StringEntry(BEARKey, bearId), StringEntry(mainTokenKey, mainTokenId), StringEntry(oraclePKKey, oraclePK), IntegerEntry(bullCollateralKey, bulls), IntegerEntry(bearCollateralKey, bears), IntegerEntry(bullCirculationKey, bulls), IntegerEntry(bearCirculationKey, bears), IntegerEntry(lastRebalancePriceIndexKey, oracleCurrentPriceIndex), StringEntry(whitelistKey, whitelisted), IntegerEntry(issuePercentileKey, 0), IntegerEntry(redeemPercentileKey, 0), IntegerEntry(minIssueKey, 0), IntegerEntry(minRedeemKey, 0), BooleanEntry(whitelistOnlyKey, true), ScriptTransfer(inv.caller, bulls, fromBase58String(bullId)), ScriptTransfer(inv.caller, bears, fromBase58String(bearId))]
437- }
438- }
439-
440-
441-
442-@Callable(i)
443-func setParams (iP,rP,mI,mR,mP,wl) = if ((i.caller != this))
444- then throw("only self can change whitelist")
445- else [IntegerEntry(issuePercentileKey, iP), IntegerEntry(redeemPercentileKey, rP), IntegerEntry(minIssueKey, mI), IntegerEntry(minRedeemKey, mR), IntegerEntry(minPoolKey, mP), BooleanEntry(whitelistOnlyKey, wl)]
446-
447-
448-
449-@Callable(i)
450-func setWhitelist (l) = if ((i.caller != this))
451- then throw("only self can change whitelist")
452- else [StringEntry(whitelistKey, l)]
453-
454-
455-
456-@Callable(i)
457-func setAddresses (feeAddr,stakingAddr,daemonPK) = if ((i.caller != this))
458- then throw("only self can change feeAcc addresses")
459- else [StringEntry(feeAddrKey, feeAddr), StringEntry(stakingAddrKey, stakingAddr), StringEntry(daemonPubKeyKey, daemonPK)]
432+ else {
433+ let totalOwnedMainToken = inv.payments[0].amount
434+ let bulls = (totalOwnedMainToken / 3)
435+ let bears = bulls
436+ let pools = ((totalOwnedMainToken - bulls) - bears)
437+ if (if (if ((bears == 0))
438+ then true
439+ else (bulls == 0))
440+ then true
441+ else (pools == 0))
442+ then throw("can't init balances")
443+ else {
444+ let oracleCurrentPriceIndex = valueOrErrorMessage(getInteger(valueOrErrorMessage(addressFromPublicKey(fromBase58String(oraclePK)), "bad oracle address"), lastPriceIndexKey), "can't find last oracle price index")
445+ let bull = Issue(nameup, descUp, ((100 * ten6) * ten6), 6, true)
446+ let bear = Issue(namedwn, descDwn, ((100 * ten6) * ten6), 6, true)
447+ let pool = Issue(poolName, poolDesc, ((100 * ten6) * ten6), 6, true)
448+ let buid = calculateAssetId(bull)
449+ let beid = calculateAssetId(bear)
450+ let poid = calculateAssetId(pool)
451+[bull, bear, pool, StringEntry(BULLKey, toBase58String(buid)), StringEntry(BEARKey, toBase58String(beid)), StringEntry(mainTokenKey, toBase58String(value(inv.payments[0].assetId))), StringEntry(poolTokenKey, toBase58String(poid)), StringEntry(oraclePKKey, oraclePK), IntegerEntry(lastRebalancePriceIndexKey, oracleCurrentPriceIndex), IntegerEntry(bullCollateralKey, bulls), IntegerEntry(bearCollateralKey, bears), IntegerEntry(bullCirculationKey, (bulls / denom)), IntegerEntry(bearCirculationKey, (bears / denom)), IntegerEntry(poolTokenCirculationKey, (pools / denom)), IntegerEntry(poolDwnKey, 0), IntegerEntry(poolUpKey, 0), IntegerEntry(poolMainTokenValueKey, pools), StringEntry(configProviderKey, config), ScriptTransfer(inv.caller, (bulls / denom), buid), ScriptTransfer(inv.caller, (bears / denom), beid), ScriptTransfer(inv.caller, (pools / denom), poid)]
452+ }
453+ }
460454
461455
462456
480474 @Callable(inv)
481475 func requestIssue (tokenId) = if ((inv.caller == this))
482476 then throw("can't do")
483- else if (if (whitelistOnly)
484- then !(isDefined(indexOf(whitelist, toString(inv.caller))))
485- else false)
477+ else if (!(allowed(inv.caller)))
486478 then throw("only whitelisted can do")
487479 else {
488480 let errorMessage = throw((((((("only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") tokens are available in exchange for USDN(") + mainToken) + ")"))
494486 then errorMessage
495487 else if ((minIssue > inv.payments[0].amount))
496488 then throw((("Attached payment too small. Min required: " + toString((minIssue / 1000000))) + " USDN"))
497- else enqueue(toBase58String(inv.transactionId), ISSUE, inv.payments[0].amount, tokenId, (oraclePriceIndex + 1), toString(inv.caller))
489+ else {
490+ let maxAllowed = maxIssue(tokenId)
491+ if (if ((whitelist == ""))
492+ then (inv.payments[0].amount > maxAllowed)
493+ else false)
494+ then throw((("trying to issue more than pool can handle. Max attachment allowed = " + toString((maxAllowed / 1000000))) + " USDN"))
495+ else enqueue(toBase58String(inv.transactionId), ISSUE, inv.payments[0].amount, tokenId, (oraclePriceIndex + 1), toString(inv.caller))
496+ }
498497 }
499498
500499
523522
524523
525524 @Callable(inv)
526-func setupPool (poolTokenId) = if ((inv.caller != this))
527- then throw("only self can init")
528- else if (poolInitialized)
529- then throw("pool already initialized")
530- else [IntegerEntry(poolDwnKey, 0), IntegerEntry(poolUpKey, 0), IntegerEntry(poolMainTokenValueKey, 0), StringEntry(poolTokenKey, poolTokenId), IntegerEntry(poolTokenCirculationKey, 0), BooleanEntry(poolEnabledKey, false), IntegerEntry(minPoolKey, ((10 * 1000) * 1000))]
531-
532-
533-
534-@Callable(inv)
535-func startPool () = if ((poolValue != 0))
536- then throw("pool already started")
525+func requestPool () = if (!(allowed(inv.caller)))
526+ then throw("only whitelisted can do")
537527 else {
538- let errMessage = (("please attach 10.000000 main tokens(" + mainToken) + ")")
528+ let errMessage = (("main token must be attached(" + mainToken) + ")")
539529 let pmt = inv.payments[0]
540- if ((pmt.amount != (10 * ten6)))
530+ if ((pmt.assetId != fromBase58String(mainToken)))
541531 then throw(errMessage)
542- else if ((pmt.assetId != fromBase58String(mainToken)))
543- then throw(errMessage)
544- else [IntegerEntry(poolDwnKey, 0), IntegerEntry(poolUpKey, 0), IntegerEntry(poolMainTokenValueKey, (10 * ten6)), BooleanEntry(poolEnabledKey, true), IntegerEntry(poolTokenCirculationKey, ten6), ScriptTransfer(inv.caller, ten6, fromBase58String(poolToken))]
532+ else if ((minPool > pmt.amount))
533+ then throw(((("pool at least " + toString(minPool)) + " ") + mainToken))
534+ else enqueue(toBase58String(inv.transactionId), POOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller))
545535 }
546536
547537
548538
549539 @Callable(inv)
550-func requestPool () = if (!(poolEnabled))
551- then throw("pooling not enabled at the moment")
552- else if (if (whitelistOnly)
553- then !(isDefined(indexOf(whitelist, toString(inv.caller))))
554- else false)
555- then throw("only whitelisted can do")
540+func requestUnpool () = {
541+ let errMessage = (("only pool token allowed(" + poolToken) + ")")
542+ let pmt = inv.payments[0]
543+ if ((pmt.assetId != fromBase58String(poolToken)))
544+ then throw(errMessage)
556545 else {
557- let errMessage = (("main token must be attached(" + mainToken) + ")")
558- let pmt = inv.payments[0]
559- if ((pmt.assetId != fromBase58String(mainToken)))
560- then throw(errMessage)
561- else if ((minPool > pmt.amount))
562- then throw(((("pool at least " + toString(minPool)) + " ") + mainToken))
563- else enqueue(toBase58String(inv.transactionId), POOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller))
546+ let estimate = fraction(poolValue, pmt.amount, poolTokenCirculation)
547+ if ((minPool > estimate))
548+ then throw(((("unpool at least for" + toString(minPool)) + " ") + mainToken))
549+ else enqueue(toBase58String(inv.transactionId), UNPOOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller))
564550 }
565-
566-
567-
568-@Callable(inv)
569-func requestUnpool () = if (!(poolEnabled))
570- then throw("pool not enabled at the moment")
571- else {
572- let errMessage = (("only pool token allowed(" + poolToken) + ")")
573- let pmt = inv.payments[0]
574- if ((pmt.assetId != fromBase58String(poolToken)))
575- then throw(errMessage)
576- else {
577- let estimate = fraction(poolValue, pmt.amount, poolTokenCirculation)
578- if ((minPool > estimate))
579- then throw(((("unpool at least for" + toString(minPool)) + " ") + mainToken))
580- else enqueue(toBase58String(inv.transactionId), UNPOOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller))
581- }
582- }
551+ }
583552
584553
585554 @Verifier(tx)
586555 func verify () = {
556+ let initial = if (!(isDefined(getString(this, BULLKey))))
557+ then sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
558+ else false
587559 let adminAction = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
588560 then 1
589561 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
617589 case _ =>
618590 false
619591 }
620- if (adminAction)
592+ if (if (initial)
593+ then true
594+ else adminAction)
621595 then true
622596 else stakingAction
623597 }
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 4 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let ten6 = 1000000
55
66 let ten8 = 100000000
7+
8+let configProviderKey = "configProvider"
9+
10+let configProvider = match getString(this, configProviderKey) {
11+ case s: String =>
12+ addressFromStringValue(s)
13+ case _ =>
14+ this
15+}
716
817 let BULLKey = "BULLId"
918
1019 let BEARKey = "BEARId"
1120
1221 let mainTokenKey = "mainTokenId"
1322
1423 let bullCollateralKey = "bullCollateral"
1524
1625 let bearCollateralKey = "bearCollateral"
1726
1827 let bullCirculationKey = "bullCirculation"
1928
2029 let bearCirculationKey = "bearCirculation"
2130
2231 let issuePercentileKey = "issuePercentile"
2332
2433 let redeemPercentileKey = "redeemPercentile"
2534
2635 let minIssueKey = "minIssue"
2736
2837 let minRedeemKey = "minRedeem"
2938
3039 let minPoolKey = "minPool"
3140
3241 let feesAccumulatedKey = "feesAccumulated"
3342
34-let whitelistOnlyKey = "whitelistOnly"
35-
3643 let whitelistKey = "issueWhiteList"
3744
3845 let oraclePKKey = "oracle"
3946
4047 let lastPriceIndexKey = "price_index"
4148
4249 let priceIndexPrefix = "price_index_"
4350
4451 let priceHeightPrefix = "price_"
4552
4653 let oracleCurrentPriceIndexKey = "price_index"
4754
4855 let lastRebalancePriceIndexKey = "lastSettlementPriceId"
4956
5057 let headPointerKey = "headPointer"
5158
5259 let tailPointerKey = "tailPointer"
5360
5461 let queueSizeKey = "queueSize"
5562
5663 let poolMainTokenValueKey = "poolMainTokenValue"
5764
5865 let poolUpKey = "poolUp"
5966
6067 let poolDwnKey = "poolDwn"
6168
62-let poolEnabledKey = "poolEnabled"
63-
6469 let poolTokenCirculationKey = "poolTokenCirculation"
6570
6671 let poolTokenKey = "poolToken"
6772
6873 let bullCol = valueOrErrorMessage(getInteger(this, bullCollateralKey), "no bullCollateralKey")
6974
7075 let bearCol = valueOrErrorMessage(getInteger(this, bearCollateralKey), "no bearCollateralKey")
7176
7277 let bullCirc = valueOrErrorMessage(getInteger(this, bullCirculationKey), "no bullCirculationKey")
7378
7479 let bearCirc = valueOrErrorMessage(getInteger(this, bearCirculationKey), "no bearCirculationKey")
7580
7681 let BULL = valueOrErrorMessage(getString(this, BULLKey), "no BULLKey")
7782
7883 let BEAR = valueOrErrorMessage(getString(this, BEARKey), "no BEARKey")
7984
8085 let mainToken = valueOrErrorMessage(getString(this, mainTokenKey), "no mainTokenKey")
8186
82-let issuePercentile = valueOrErrorMessage(getInteger(this, issuePercentileKey), "no issuePercentileKey")
87+let issuePercentile = valueOrErrorMessage(getInteger(configProvider, issuePercentileKey), "no issuePercentileKey")
8388
84-let redeemPercentile = valueOrErrorMessage(getInteger(this, redeemPercentileKey), "no redeemPercentileKey")
89+let redeemPercentile = valueOrErrorMessage(getInteger(configProvider, redeemPercentileKey), "no redeemPercentileKey")
8590
86-let minIssue = valueOrErrorMessage(getInteger(this, minIssueKey), "no minIssueKey")
91+let minIssue = valueOrErrorMessage(getInteger(configProvider, minIssueKey), "no minIssueKey")
8792
88-let minRedeem = valueOrErrorMessage(getInteger(this, minRedeemKey), "no minRedeemKey")
93+let minRedeem = valueOrErrorMessage(getInteger(configProvider, minRedeemKey), "no minRedeemKey")
8994
90-let minPool = valueOrErrorMessage(getInteger(this, minPoolKey), "no minPoolKey")
95+let minPool = valueOrErrorMessage(getInteger(configProvider, minPoolKey), "no minPoolKey")
9196
92-let whitelistOnly = valueOrErrorMessage(getBoolean(this, whitelistOnlyKey), "no whitelistOnlyKey")
97+let whitelist = valueOrErrorMessage(getString(configProvider, whitelistKey), "no whitelistKey")
9398
94-let whitelist = valueOrErrorMessage(getString(this, whitelistKey), "no bullCollateralKey")
99+func allowed (a) = if ((whitelist == ""))
100+ then true
101+ else isDefined(indexOf(whitelist, toString(a)))
95102
96-let poolInitialized = isDefined(getBoolean(this, poolMainTokenValueKey))
97-
98-let poolEnabled = (getBoolean(this, poolEnabledKey) == true)
99103
100104 let poolMain = valueOrErrorMessage(getInteger(this, poolMainTokenValueKey), "no poolMainTokenValueKey")
101105
102106 let poolUp = valueOrErrorMessage(getInteger(this, poolUpKey), "no poolUpKey")
103107
104108 let poolDwn = valueOrErrorMessage(getInteger(this, poolDwnKey), "no poolDwnKey")
105109
106110 let poolToken = valueOrErrorMessage(getString(this, poolTokenKey), "no poolTokenKey")
107111
108112 let poolTokenCirculation = valueOrErrorMessage(getInteger(this, poolTokenCirculationKey), "no poolTokenCirculationKey")
109113
110114 let poolValue = ((poolMain + fraction(bullCol, poolUp, bullCirc)) + fraction(bearCol, poolDwn, bearCirc))
111115
112116 let oracle = valueOrErrorMessage(addressFromPublicKey(fromBase58String(valueOrErrorMessage(getString(this, oraclePKKey), "no oraclePKKey"))), "bad oracle address")
113117
114118 let rebalancedPriceIndex = valueOrErrorMessage(getInteger(this, lastRebalancePriceIndexKey), "no last rebalance price")
115119
116120 let oraclePriceIndex = valueOrErrorMessage(getInteger(oracle, lastPriceIndexKey), ((("bad oracle data at " + toString(oracle)) + ": no integer at ") + lastPriceIndexKey))
117121
118122 let queueSize = valueOrElse(getInteger(this, queueSizeKey), 0)
119123
120124 let headPointer = valueOrElse(getString(this, headPointerKey), "")
121125
122126 let tailPointer = valueOrElse(getString(this, tailPointerKey), "")
123127
124128 let feesAccumulated = valueOrElse(getInteger(this, feesAccumulatedKey), 0)
125129
126130 let ISSUE = "ISSUE"
127131
128132 let REDEEM = "REDEEM"
129133
130134 let POOL = "POOL"
131135
132136 let UNPOOL = "UNPOOL"
133137
134138 let feeAddrKey = "feeAddress"
135139
136140 let stakingAddrKey = "stakingAddress"
137141
138142 let daemonPubKeyKey = "daemonPublicKey"
139143
140-let feeAddress = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, feeAddrKey), "no feeAddress")), "bad feeAddress")
144+let feeAddress = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(configProvider, feeAddrKey), "no feeAddress")), "bad feeAddress")
141145
142-let stakingAddress = valueOrErrorMessage(getString(this, stakingAddrKey), "no stakingAddress")
146+let stakingAddress = valueOrErrorMessage(getString(configProvider, stakingAddrKey), "no stakingAddress")
143147
144-let daemonPublicKey = fromBase58String(valueOrErrorMessage(getString(this, daemonPubKeyKey), "no daemonPublicKey"))
148+let daemonPublicKey = fromBase58String(valueOrErrorMessage(getString(configProvider, daemonPubKeyKey), "no daemonPublicKey"))
145149
146150 let rpdAddress = addressFromString("3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ")
147151
148152 let pubKeyAdminsList = ["2HHqV8W9DJayV5R6tBD2Sb8srphpoboDi7r1t1aPiumC", "5ZXe82RRASU7qshXM2J9JNYhqJ9GWYjjVq2gwUV5Naz9", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
149153
150154 func safeFraction (a,b,c) = if (if ((a == 0))
151155 then true
152156 else (b == 0))
153157 then 0
154158 else fraction(a, b, c)
155159
156160
157161 func buildNewItem (action,amt,token,priceIndex,invoker) = (((((((((action + "|") + toString(amt)) + "|") + token) + "|") + toString(priceIndex)) + "|") + invoker) + "|")
162+
163+
164+func maxIssue (tokenId) = {
165+ let poolInvestment = if ((poolUp > 0))
166+ then BULL
167+ else BEAR
168+ if ((poolInvestment == tokenId))
169+ then poolMain
170+ else ((2 * poolValue) - poolMain)
171+ }
158172
159173
160174 func validateRequestRedeem (inv) = if ((inv.caller == this))
161175 then throw("can't do")
162176 else {
163177 func errorMessage (got) = throw(((((("only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") tokens are accepted, received: ") + got))
164178
165179 let assetId = toBase58String(valueOrErrorMessage(value(inv.payments[0]).assetId, "waves are not accepted here"))
166180 if (if ((assetId != BEAR))
167181 then (assetId != BULL)
168182 else false)
169183 then errorMessage(assetId)
170184 else {
171185 let attachedAmount = inv.payments[0].amount
172186 let col = if ((assetId == BEAR))
173187 then bearCol
174188 else bullCol
175189 let circ = if ((assetId == BEAR))
176190 then bearCirc
177191 else bullCirc
178192 let estimated = fraction(col, attachedAmount, circ)
179193 if ((minRedeem > estimated))
180194 then throw((((((((((("Attached payment too small. Min redeem amount is " + toString((minRedeem / 1000000))) + " USDN, ") + "attached amount: ") + toString(attachedAmount)) + ", col: ") + toString(col)) + ", circ: ") + toString(circ)) + ", estimated: ") + toString(estimated)))
181195 else unit
182196 }
183197 }
184198
185199
186200 func enqueue (id,action,amt,token,priceIndex,invoker) = {
187201 let increaseQueueSize = IntegerEntry(queueSizeKey, (queueSize + 1))
188202 let itm = buildNewItem(action, amt, token, priceIndex, invoker)
189203 if ((queueSize == 0))
190204 then [StringEntry(headPointerKey, id), StringEntry(tailPointerKey, id), StringEntry(id, itm), increaseQueueSize]
191205 else {
192206 let prevId = valueOrErrorMessage(getString(this, tailPointerKey), "can't get tail pointer")
193207 let prevItm = split(valueOrErrorMessage(getString(this, prevId), "can't resolve pointer"), "|")
194208 let updatedPrevItm = ((((((((((prevItm[0] + "|") + prevItm[1]) + "|") + prevItm[2]) + "|") + prevItm[3]) + "|") + prevItm[4]) + "|") + id)
195209 [StringEntry(prevId, updatedPrevItm), StringEntry(id, itm), StringEntry(tailPointerKey, id), increaseQueueSize]
196210 }
197211 }
198212
199213
200214 func poolSupport (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0,curPoolMain0,curPoolUp0,curPoolDwn0) = {
201215 func closeUp (curBullCol,curBearCol,curBullCirc,curBearCirc,curPoolMain,curPoolUp,curPoolDwn) = {
202216 let diff = (curBullCol - curBearCol)
203217 let exposure = fraction(curBullCol, curPoolUp, curBullCirc)
204218 let liquidatedTokens = if ((diff > exposure))
205219 then curPoolUp
206220 else fraction(diff, curBullCirc, curBullCol)
207221 let liquidatedValue = if ((diff > exposure))
208222 then exposure
209223 else fraction(liquidatedTokens, curBullCol, curBullCirc)
210224 $Tuple7((curBullCol - liquidatedValue), curBearCol, (curBullCirc - liquidatedTokens), curBearCirc, (curPoolMain + liquidatedValue), (curPoolUp - liquidatedTokens), curPoolDwn)
211225 }
212226
213227 func closeDwn (curBullCol,curBearCol,curBullCirc,curBearCirc,curPoolMain,curPoolUp,curPoolDwn) = {
214228 let diff = (curBearCol - curBullCol)
215229 let exposure = fraction(curBearCol, curPoolDwn, curBearCirc)
216230 let liquidatedTokens = if ((diff > exposure))
217231 then curPoolDwn
218232 else fraction(diff, curBearCirc, curBearCol)
219233 let liquidatedValue = if ((diff > exposure))
220234 then exposure
221235 else fraction(liquidatedTokens, curBearCol, curBearCirc)
222236 $Tuple7(curBullCol, (curBearCol - liquidatedValue), curBullCirc, (curBearCirc - liquidatedTokens), (curPoolMain + liquidatedValue), curPoolUp, (curPoolDwn - liquidatedTokens))
223237 }
224238
225239 func openDwn (curBullCol,curBearCol,curBullCirc,curBearCirc,curPoolMain,curPoolUp,curPoolDwn) = {
226240 let diff = (curBullCol - curBearCol)
227241 let spentPoolValue = if ((curPoolMain > diff))
228242 then diff
229243 else curPoolMain
230244 let acquiredTokens = fraction(spentPoolValue, curBearCirc, curBearCol)
231245 $Tuple7(curBullCol, (curBearCol + spentPoolValue), curBullCirc, (curBearCirc + acquiredTokens), (curPoolMain - spentPoolValue), curPoolUp, (curPoolDwn + acquiredTokens))
232246 }
233247
234248 func openUp (curBullCol,curBearCol,curBullCirc,curBearCirc,curPoolMain,curPoolUp,curPoolDwn) = {
235249 let diff = (curBearCol - curBullCol)
236250 let spentPoolValue = if ((curPoolMain > diff))
237251 then diff
238252 else curPoolMain
239253 let acquiredTokens = fraction(spentPoolValue, curBullCirc, curBullCol)
240254 $Tuple7((curBullCol + spentPoolValue), curBearCol, (curBullCirc + acquiredTokens), curBearCirc, (curPoolMain - spentPoolValue), (curPoolUp + acquiredTokens), curPoolDwn)
241255 }
242256
243257 if ((curBullCol0 > curBearCol0))
244258 then {
245259 let afterCloseUp = closeUp(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0)
246- let $t0994610083 = afterCloseUp
247- let a = $t0994610083._1
248- let b = $t0994610083._2
249- let c = $t0994610083._3
250- let d = $t0994610083._4
251- let e = $t0994610083._5
252- let f = $t0994610083._6
253- let g = $t0994610083._7
260+ let $t01028610423 = afterCloseUp
261+ let a = $t01028610423._1
262+ let b = $t01028610423._2
263+ let c = $t01028610423._3
264+ let d = $t01028610423._4
265+ let e = $t01028610423._5
266+ let f = $t01028610423._6
267+ let g = $t01028610423._7
254268 if ((f > 0))
255269 then afterCloseUp
256270 else if ((f == 0))
257271 then openDwn(a, b, c, d, e, f, g)
258272 else throw("poolUp < 0")
259273 }
260274 else {
261275 let afterCloseDwn = closeDwn(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0)
262- let $t01043410574 = afterCloseDwn
263- let a = $t01043410574._1
264- let b = $t01043410574._2
265- let c = $t01043410574._3
266- let d = $t01043410574._4
267- let e = $t01043410574._5
268- let f = $t01043410574._6
269- let g = $t01043410574._7
276+ let $t01077410914 = afterCloseDwn
277+ let a = $t01077410914._1
278+ let b = $t01077410914._2
279+ let c = $t01077410914._3
280+ let d = $t01077410914._4
281+ let e = $t01077410914._5
282+ let f = $t01077410914._6
283+ let g = $t01077410914._7
270284 if ((g > 0))
271285 then afterCloseDwn
272286 else if ((g == 0))
273287 then openUp(a, b, c, d, e, f, g)
274288 else throw("poolDwn < 0")
275289 }
276290 }
277291
278292
279-func actionsWithMaybePool (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0) = if (poolEnabled)
280- then {
281- let $t01089811081 = poolSupport(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, poolMain, poolUp, poolDwn)
282- let bullCol1 = $t01089811081._1
283- let bearCol1 = $t01089811081._2
284- let bullCic1 = $t01089811081._3
285- let bearCirc1 = $t01089811081._4
286- let poolMain1 = $t01089811081._5
287- let poolUp1 = $t01089811081._6
288- let poolDwn1 = $t01089811081._7
293+func actionsWithMaybePool (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0) = {
294+ let $t01121111394 = poolSupport(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, poolMain, poolUp, poolDwn)
295+ let bullCol1 = $t01121111394._1
296+ let bearCol1 = $t01121111394._2
297+ let bullCic1 = $t01121111394._3
298+ let bearCirc1 = $t01121111394._4
299+ let poolMain1 = $t01121111394._5
300+ let poolUp1 = $t01121111394._6
301+ let poolDwn1 = $t01121111394._7
289302 [IntegerEntry(bullCollateralKey, bullCol1), IntegerEntry(bullCirculationKey, bullCic1), IntegerEntry(bearCollateralKey, bearCol1), IntegerEntry(bearCirculationKey, bearCirc1), IntegerEntry(poolMainTokenValueKey, poolMain1), IntegerEntry(poolUpKey, poolUp1), IntegerEntry(poolDwnKey, poolDwn1)]
290- }
291- else [IntegerEntry(bullCollateralKey, curBullCol0), IntegerEntry(bullCirculationKey, curBullCirc0), IntegerEntry(bearCollateralKey, curBearCol0), IntegerEntry(bearCirculationKey, curBearCirc0)]
303+ }
292304
293305
294306 func dequeue () = if ((queueSize == 0))
295307 then throw("nothing to settle")
296308 else {
297309 func collectFee (fees) = IntegerEntry(feesAccumulatedKey, (feesAccumulated + fees))
298310
299311 let decreaseQueueSize = IntegerEntry(queueSizeKey, (queueSize - 1))
300312 let isLastElement = (headPointer == tailPointer)
301313 let overwriteTail = StringEntry(tailPointerKey, "")
302314 let data = split(valueOrErrorMessage(getString(this, headPointer), "bad head pointer"), "|")
303315 let action = data[0]
304316 let amt = parseIntValue(data[1])
305317 let token = data[2]
306318 let priceIndex = parseIntValue(data[3])
307319 let invoker = addressFromStringValue(data[4])
308320 let next = data[5]
309321 let items = if ((rebalancedPriceIndex > priceIndex))
310322 then throw(((("corrupt state, rebalancedPriceIndex=" + toString(rebalancedPriceIndex)) + ", request price id=") + toString(priceIndex)))
311323 else if ((priceIndex > rebalancedPriceIndex))
312324 then throw("can't dequeue, too early, rebalance first")
313325 else if ((action == ISSUE))
314326 then {
315327 let feeSize = fraction(amt, issuePercentile, 10000)
316328 let addedCollateral = (amt - feeSize)
317329 if ((token == BULL))
318330 then {
319331 let addedToCirculation = fraction(bullCirc, addedCollateral, bullCol)
320332 (actionsWithMaybePool((bullCol + addedCollateral), bearCol, (bullCirc + addedToCirculation), bearCirc) ++ [StringEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize, ScriptTransfer(invoker, addedToCirculation, fromBase58String(BULL))])
321333 }
322334 else if ((token == BEAR))
323335 then {
324336 let addedToCirculation = fraction(bearCirc, addedCollateral, bearCol)
325337 (actionsWithMaybePool(bullCol, (bearCol + addedCollateral), bullCirc, (bearCirc + addedToCirculation)) ++ [StringEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize, ScriptTransfer(invoker, addedToCirculation, fromBase58String(BEAR))])
326338 }
327339 else throw("bad token id")
328340 }
329341 else if ((action == REDEEM))
330342 then {
331343 let removedTokens = amt
332344 if ((token == BULL))
333345 then {
334346 let removedCollateral = fraction(bullCol, removedTokens, bullCirc)
335347 let feeSize = fraction(removedCollateral, redeemPercentile, 10000)
336348 let payout = if ((removedCollateral > feeSize))
337349 then (removedCollateral - feeSize)
338350 else 0
339351 (actionsWithMaybePool((bullCol - removedCollateral), bearCol, (bullCirc - removedTokens), bearCirc) ++ [StringEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize, ScriptTransfer(invoker, payout, fromBase58String(mainToken))])
340352 }
341353 else if ((token == BEAR))
342354 then {
343355 let removedCollateral = fraction(bearCol, removedTokens, bearCirc)
344356 let feeSize = fraction(removedCollateral, redeemPercentile, 10000)
345357 let payout = if ((removedCollateral > feeSize))
346358 then (removedCollateral - feeSize)
347359 else 0
348360 (actionsWithMaybePool(bullCol, (bearCol - removedCollateral), bullCirc, (bearCirc - removedTokens)) ++ [StringEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize, ScriptTransfer(invoker, payout, fromBase58String(mainToken))])
349361 }
350362 else throw("bad token id")
351363 }
352364 else if ((action == POOL))
353365 then {
354366 let issueTokens = fraction(poolTokenCirculation, amt, poolValue)
355367 [IntegerEntry(poolMainTokenValueKey, (poolMain + amt)), IntegerEntry(poolTokenCirculationKey, (poolTokenCirculation + issueTokens)), StringEntry(headPointerKey, next), decreaseQueueSize, ScriptTransfer(invoker, issueTokens, fromBase58String(poolToken))]
356368 }
357369 else if ((action == UNPOOL))
358370 then {
359371 func share (a) = fraction(a, amt, poolTokenCirculation)
360372
361373 let unpooledMain = share(poolMain)
362374 let unpooledUp = share(poolUp)
363375 let unpooledDwn = share(poolDwn)
364376 let unpooledUpValue = fraction(unpooledUp, bullCol, bullCirc)
365377 let unpooledDwnValue = fraction(unpooledDwn, bearCol, bearCirc)
366378 [IntegerEntry(poolMainTokenValueKey, (poolMain - unpooledMain)), IntegerEntry(poolTokenCirculationKey, (poolTokenCirculation - amt)), IntegerEntry(poolUpKey, (poolUp - unpooledUp)), IntegerEntry(poolDwnKey, (poolDwn - unpooledDwn)), IntegerEntry(bullCirculationKey, (bullCirc - unpooledUp)), IntegerEntry(bearCirculationKey, (bearCirc - unpooledDwn)), IntegerEntry(bullCollateralKey, (bullCol - unpooledUpValue)), IntegerEntry(bearCollateralKey, (bearCol - unpooledDwnValue)), StringEntry(headPointerKey, next), decreaseQueueSize, ScriptTransfer(invoker, ((unpooledMain + unpooledUpValue) + unpooledDwnValue), fromBase58String(mainToken))]
367379 }
368380 else throw(("bad action: " + action))
369381 if (isLastElement)
370382 then overwriteTail :: items
371383 else items
372384 }
373385
374386
375387 func rebalance () = {
376388 func LV (v,p0,p1) = {
377389 let denom = 100
378390 let pmax = ((if ((p1 > p0))
379391 then p1
380392 else p0) / denom)
381393 let pmin = ((if ((p0 > p1))
382394 then p1
383395 else p0) / denom)
384396 let a = (pmin * pmin)
385397 let b = (((9 * pmax) * pmax) - ((15 * pmax) * pmin))
386398 fraction(v, ((6 * a) + b), ((7 * a) + b))
387399 }
388400
389401 let settledPriceIndex = valueOrErrorMessage(getInteger(this, lastRebalancePriceIndexKey), "inconsistent data")
390402 let unsettledPriceIndex = (settledPriceIndex + 1)
391403 let settledPriceHeight = valueOrErrorMessage(getInteger(oracle, ("price_index_" + toString(settledPriceIndex))), "bad oracle data for settled price height")
392404 let settledPrice = valueOrErrorMessage(getInteger(oracle, ("price_" + toString(settledPriceHeight))), "bad oracle data for price")
393405 let nextPriceHeight = valueOrErrorMessage(getInteger(oracle, ("price_index_" + toString(unsettledPriceIndex))), "no next price height")
394406 let nextPrice = valueOrErrorMessage(getInteger(oracle, ("price_" + toString(nextPriceHeight))), "no next price")
395407 let minVol = if ((bearCol > bullCol))
396408 then bullCol
397409 else bearCol
398410 let redist = LV(minVol, settledPrice, nextPrice)
399411 let newBullCol = if ((nextPrice > settledPrice))
400412 then (bullCol + redist)
401413 else (bullCol - redist)
402414 let newBearCol = if ((nextPrice > settledPrice))
403415 then (bearCol - redist)
404416 else (bearCol + redist)
405- if (poolEnabled)
406- then {
407- let $t01922019407 = poolSupport(newBullCol, newBearCol, bullCirc, bearCirc, poolMain, poolUp, poolDwn)
408- let updBullCol = $t01922019407._1
409- let updBearCol = $t01922019407._2
410- let updBullCirc = $t01922019407._3
411- let updBearCirc = $t01922019407._4
412- let updPoolMain = $t01922019407._5
413- let updPoolUp = $t01922019407._6
414- let updPoolDwn = $t01922019407._7
417+ let $t01926019447 = poolSupport(newBullCol, newBearCol, bullCirc, bearCirc, poolMain, poolUp, poolDwn)
418+ let updBullCol = $t01926019447._1
419+ let updBearCol = $t01926019447._2
420+ let updBullCirc = $t01926019447._3
421+ let updBearCirc = $t01926019447._4
422+ let updPoolMain = $t01926019447._5
423+ let updPoolUp = $t01926019447._6
424+ let updPoolDwn = $t01926019447._7
415425 [IntegerEntry(bullCollateralKey, updBullCol), IntegerEntry(bearCollateralKey, updBearCol), IntegerEntry(bullCirculationKey, updBullCirc), IntegerEntry(bearCirculationKey, updBearCirc), IntegerEntry(poolMainTokenValueKey, updPoolMain), IntegerEntry(poolUpKey, updPoolUp), IntegerEntry(poolDwnKey, updPoolDwn), IntegerEntry(lastRebalancePriceIndexKey, unsettledPriceIndex)]
416- }
417- else [IntegerEntry(bullCollateralKey, newBullCol), IntegerEntry(bearCollateralKey, newBearCol), IntegerEntry(lastRebalancePriceIndexKey, unsettledPriceIndex)]
418426 }
419427
420428
421429 @Callable(inv)
422-func init (bullId,bearId,mainTokenId,oraclePK,whitelisted) = if (isDefined(getString(this, BULLKey)))
430+func init (config,oraclePK,nameup,namedwn,descUp,descDwn,poolName,poolDesc,denom) = if (isDefined(getString(this, BULLKey)))
423431 then throw("already initialized")
424- else if ((toBase58String(valueOrErrorMessage(inv.payments[0].assetId, "neutrino payment required")) != mainTokenId))
425- then throw("payment not in neutrino")
426- else {
427- let totalOwnedMainToken = inv.payments[0].amount
428- let bulls = (totalOwnedMainToken / 2)
429- let bears = (totalOwnedMainToken - bulls)
430- if (if ((bears == 0))
431- then true
432- else (bulls == 0))
433- then throw("can't init balances")
434- else {
435- let oracleCurrentPriceIndex = valueOrErrorMessage(getInteger(valueOrErrorMessage(addressFromPublicKey(fromBase58String(oraclePK)), "bad oracle address"), lastPriceIndexKey), "can't find last oracle price index")
436-[StringEntry(BULLKey, bullId), StringEntry(BEARKey, bearId), StringEntry(mainTokenKey, mainTokenId), StringEntry(oraclePKKey, oraclePK), IntegerEntry(bullCollateralKey, bulls), IntegerEntry(bearCollateralKey, bears), IntegerEntry(bullCirculationKey, bulls), IntegerEntry(bearCirculationKey, bears), IntegerEntry(lastRebalancePriceIndexKey, oracleCurrentPriceIndex), StringEntry(whitelistKey, whitelisted), IntegerEntry(issuePercentileKey, 0), IntegerEntry(redeemPercentileKey, 0), IntegerEntry(minIssueKey, 0), IntegerEntry(minRedeemKey, 0), BooleanEntry(whitelistOnlyKey, true), ScriptTransfer(inv.caller, bulls, fromBase58String(bullId)), ScriptTransfer(inv.caller, bears, fromBase58String(bearId))]
437- }
438- }
439-
440-
441-
442-@Callable(i)
443-func setParams (iP,rP,mI,mR,mP,wl) = if ((i.caller != this))
444- then throw("only self can change whitelist")
445- else [IntegerEntry(issuePercentileKey, iP), IntegerEntry(redeemPercentileKey, rP), IntegerEntry(minIssueKey, mI), IntegerEntry(minRedeemKey, mR), IntegerEntry(minPoolKey, mP), BooleanEntry(whitelistOnlyKey, wl)]
446-
447-
448-
449-@Callable(i)
450-func setWhitelist (l) = if ((i.caller != this))
451- then throw("only self can change whitelist")
452- else [StringEntry(whitelistKey, l)]
453-
454-
455-
456-@Callable(i)
457-func setAddresses (feeAddr,stakingAddr,daemonPK) = if ((i.caller != this))
458- then throw("only self can change feeAcc addresses")
459- else [StringEntry(feeAddrKey, feeAddr), StringEntry(stakingAddrKey, stakingAddr), StringEntry(daemonPubKeyKey, daemonPK)]
432+ else {
433+ let totalOwnedMainToken = inv.payments[0].amount
434+ let bulls = (totalOwnedMainToken / 3)
435+ let bears = bulls
436+ let pools = ((totalOwnedMainToken - bulls) - bears)
437+ if (if (if ((bears == 0))
438+ then true
439+ else (bulls == 0))
440+ then true
441+ else (pools == 0))
442+ then throw("can't init balances")
443+ else {
444+ let oracleCurrentPriceIndex = valueOrErrorMessage(getInteger(valueOrErrorMessage(addressFromPublicKey(fromBase58String(oraclePK)), "bad oracle address"), lastPriceIndexKey), "can't find last oracle price index")
445+ let bull = Issue(nameup, descUp, ((100 * ten6) * ten6), 6, true)
446+ let bear = Issue(namedwn, descDwn, ((100 * ten6) * ten6), 6, true)
447+ let pool = Issue(poolName, poolDesc, ((100 * ten6) * ten6), 6, true)
448+ let buid = calculateAssetId(bull)
449+ let beid = calculateAssetId(bear)
450+ let poid = calculateAssetId(pool)
451+[bull, bear, pool, StringEntry(BULLKey, toBase58String(buid)), StringEntry(BEARKey, toBase58String(beid)), StringEntry(mainTokenKey, toBase58String(value(inv.payments[0].assetId))), StringEntry(poolTokenKey, toBase58String(poid)), StringEntry(oraclePKKey, oraclePK), IntegerEntry(lastRebalancePriceIndexKey, oracleCurrentPriceIndex), IntegerEntry(bullCollateralKey, bulls), IntegerEntry(bearCollateralKey, bears), IntegerEntry(bullCirculationKey, (bulls / denom)), IntegerEntry(bearCirculationKey, (bears / denom)), IntegerEntry(poolTokenCirculationKey, (pools / denom)), IntegerEntry(poolDwnKey, 0), IntegerEntry(poolUpKey, 0), IntegerEntry(poolMainTokenValueKey, pools), StringEntry(configProviderKey, config), ScriptTransfer(inv.caller, (bulls / denom), buid), ScriptTransfer(inv.caller, (bears / denom), beid), ScriptTransfer(inv.caller, (pools / denom), poid)]
452+ }
453+ }
460454
461455
462456
463457 @Callable(i)
464458 func withdrawFee (amount) = if ((amount > feesAccumulated))
465459 then throw(("too much. available: " + toString(feesAccumulated)))
466460 else [IntegerEntry(feesAccumulatedKey, (feesAccumulated - amount)), ScriptTransfer(feeAddress, amount, fromBase58String(mainToken))]
467461
468462
469463
470464 @Callable(inv)
471465 func requestRedeem () = if ((validateRequestRedeem(inv) == unit))
472466 then {
473467 let assetId = toBase58String(valueOrErrorMessage(inv.payments[0].assetId, "waves are not accepted here"))
474468 enqueue(toBase58String(inv.transactionId), REDEEM, inv.payments[0].amount, assetId, (oraclePriceIndex + 1), toString(inv.caller))
475469 }
476470 else throw("doesn't happen")
477471
478472
479473
480474 @Callable(inv)
481475 func requestIssue (tokenId) = if ((inv.caller == this))
482476 then throw("can't do")
483- else if (if (whitelistOnly)
484- then !(isDefined(indexOf(whitelist, toString(inv.caller))))
485- else false)
477+ else if (!(allowed(inv.caller)))
486478 then throw("only whitelisted can do")
487479 else {
488480 let errorMessage = throw((((((("only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") tokens are available in exchange for USDN(") + mainToken) + ")"))
489481 if (if ((tokenId != BULL))
490482 then (tokenId != BEAR)
491483 else false)
492484 then errorMessage
493485 else if ((inv.payments[0].assetId != fromBase58String(mainToken)))
494486 then errorMessage
495487 else if ((minIssue > inv.payments[0].amount))
496488 then throw((("Attached payment too small. Min required: " + toString((minIssue / 1000000))) + " USDN"))
497- else enqueue(toBase58String(inv.transactionId), ISSUE, inv.payments[0].amount, tokenId, (oraclePriceIndex + 1), toString(inv.caller))
489+ else {
490+ let maxAllowed = maxIssue(tokenId)
491+ if (if ((whitelist == ""))
492+ then (inv.payments[0].amount > maxAllowed)
493+ else false)
494+ then throw((("trying to issue more than pool can handle. Max attachment allowed = " + toString((maxAllowed / 1000000))) + " USDN"))
495+ else enqueue(toBase58String(inv.transactionId), ISSUE, inv.payments[0].amount, tokenId, (oraclePriceIndex + 1), toString(inv.caller))
496+ }
498497 }
499498
500499
501500
502501 @Callable(inv)
503502 func settle () = {
504503 let queueEmpty = (headPointer == "")
505504 let canRebalance = (oraclePriceIndex > rebalancedPriceIndex)
506505 if (queueEmpty)
507506 then if (canRebalance)
508507 then rebalance()
509508 else throw("[OK] all done, carry on")
510509 else {
511510 let data = split(valueOrErrorMessage(getString(this, headPointer), "bad head pointer"), "|")
512511 let priceIndex = parseIntValue(data[3])
513512 if ((priceIndex > rebalancedPriceIndex))
514513 then if (canRebalance)
515514 then rebalance()
516515 else throw("[OK] need to wait")
517516 else if ((priceIndex == rebalancedPriceIndex))
518517 then dequeue()
519518 else throw("corrupt data, future price id already rebalanced")
520519 }
521520 }
522521
523522
524523
525524 @Callable(inv)
526-func setupPool (poolTokenId) = if ((inv.caller != this))
527- then throw("only self can init")
528- else if (poolInitialized)
529- then throw("pool already initialized")
530- else [IntegerEntry(poolDwnKey, 0), IntegerEntry(poolUpKey, 0), IntegerEntry(poolMainTokenValueKey, 0), StringEntry(poolTokenKey, poolTokenId), IntegerEntry(poolTokenCirculationKey, 0), BooleanEntry(poolEnabledKey, false), IntegerEntry(minPoolKey, ((10 * 1000) * 1000))]
531-
532-
533-
534-@Callable(inv)
535-func startPool () = if ((poolValue != 0))
536- then throw("pool already started")
525+func requestPool () = if (!(allowed(inv.caller)))
526+ then throw("only whitelisted can do")
537527 else {
538- let errMessage = (("please attach 10.000000 main tokens(" + mainToken) + ")")
528+ let errMessage = (("main token must be attached(" + mainToken) + ")")
539529 let pmt = inv.payments[0]
540- if ((pmt.amount != (10 * ten6)))
530+ if ((pmt.assetId != fromBase58String(mainToken)))
541531 then throw(errMessage)
542- else if ((pmt.assetId != fromBase58String(mainToken)))
543- then throw(errMessage)
544- else [IntegerEntry(poolDwnKey, 0), IntegerEntry(poolUpKey, 0), IntegerEntry(poolMainTokenValueKey, (10 * ten6)), BooleanEntry(poolEnabledKey, true), IntegerEntry(poolTokenCirculationKey, ten6), ScriptTransfer(inv.caller, ten6, fromBase58String(poolToken))]
532+ else if ((minPool > pmt.amount))
533+ then throw(((("pool at least " + toString(minPool)) + " ") + mainToken))
534+ else enqueue(toBase58String(inv.transactionId), POOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller))
545535 }
546536
547537
548538
549539 @Callable(inv)
550-func requestPool () = if (!(poolEnabled))
551- then throw("pooling not enabled at the moment")
552- else if (if (whitelistOnly)
553- then !(isDefined(indexOf(whitelist, toString(inv.caller))))
554- else false)
555- then throw("only whitelisted can do")
540+func requestUnpool () = {
541+ let errMessage = (("only pool token allowed(" + poolToken) + ")")
542+ let pmt = inv.payments[0]
543+ if ((pmt.assetId != fromBase58String(poolToken)))
544+ then throw(errMessage)
556545 else {
557- let errMessage = (("main token must be attached(" + mainToken) + ")")
558- let pmt = inv.payments[0]
559- if ((pmt.assetId != fromBase58String(mainToken)))
560- then throw(errMessage)
561- else if ((minPool > pmt.amount))
562- then throw(((("pool at least " + toString(minPool)) + " ") + mainToken))
563- else enqueue(toBase58String(inv.transactionId), POOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller))
546+ let estimate = fraction(poolValue, pmt.amount, poolTokenCirculation)
547+ if ((minPool > estimate))
548+ then throw(((("unpool at least for" + toString(minPool)) + " ") + mainToken))
549+ else enqueue(toBase58String(inv.transactionId), UNPOOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller))
564550 }
565-
566-
567-
568-@Callable(inv)
569-func requestUnpool () = if (!(poolEnabled))
570- then throw("pool not enabled at the moment")
571- else {
572- let errMessage = (("only pool token allowed(" + poolToken) + ")")
573- let pmt = inv.payments[0]
574- if ((pmt.assetId != fromBase58String(poolToken)))
575- then throw(errMessage)
576- else {
577- let estimate = fraction(poolValue, pmt.amount, poolTokenCirculation)
578- if ((minPool > estimate))
579- then throw(((("unpool at least for" + toString(minPool)) + " ") + mainToken))
580- else enqueue(toBase58String(inv.transactionId), UNPOOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller))
581- }
582- }
551+ }
583552
584553
585554 @Verifier(tx)
586555 func verify () = {
556+ let initial = if (!(isDefined(getString(this, BULLKey))))
557+ then sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
558+ else false
587559 let adminAction = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
588560 then 1
589561 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
590562 then 1
591563 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2])))
592564 then 1
593565 else 0)) > 1)
594566 let stakingAction = match tx {
595567 case tx: InvokeScriptTransaction =>
596568 let signedCorrectly = sigVerify(tx.bodyBytes, tx.proofs[0], daemonPublicKey)
597569 let feesCorrect = if ((tx.feeAssetId == unit))
598570 then ((1000 * 1000) >= tx.fee)
599571 else false
600572 let dappCorrect = (tx.dApp == rpdAddress)
601573 let unlock = (tx.function == "unlockNeutrino")
602574 let lock = if (if ((tx.function == "lockNeutrinoSP"))
603575 then (tx.args[0] == stakingAddress)
604576 else false)
605577 then (wavesBalance(this).available >= ten8)
606578 else false
607579 let funcCorrect = if (lock)
608580 then true
609581 else unlock
610582 if (if (if (signedCorrectly)
611583 then feesCorrect
612584 else false)
613585 then dappCorrect
614586 else false)
615587 then funcCorrect
616588 else false
617589 case _ =>
618590 false
619591 }
620- if (adminAction)
592+ if (if (initial)
593+ then true
594+ else adminAction)
621595 then true
622596 else stakingAction
623597 }
624598

github/deemru/w8io/786bc32 
102.53 ms