2020.10.04 12:23 [2269310] smart account 3P9ZegsKUtsEpdRPNVrMH7nHEEqY5MrmjDp > SELF 0.00000000 Waves

{ "type": 13, "id": "G42cQY3f5JPRXNq6pueQRSjVp2z2FAMFESEinZmDJJjN", "fee": 1400000, "feeAssetId": null, "timestamp": 1601801946992, "version": 1, "sender": "3P9ZegsKUtsEpdRPNVrMH7nHEEqY5MrmjDp", "senderPublicKey": "7ziFsWp9eo6kUB6ovqQzJfjgQarifNfpCGNW9DZi8YhN", "proofs": [ "39435aHe8FkdRYiEwACkmEoWAoCKqk5Jka6X5R2NJc83ZUo18GbUczdvRx3s2pPiw8EVwgtMxrmtLHpe2Gzy74Fe", "4wFwib69yP3A7n9hvxEX8EnwDomz9cifh27sSASPzWGuSnH8KWZWgyY2SC44z6HNubzMtn7aknq7tj2ZxaSMYKsn" ], "script": "base64:AAIEAAAAAAAAADoIAhIHCgUICAgICBIICgYBAQEBAQQSAwoBCBIFCgMICAgSAwoBARIAEgMKAQgSABIDCgEIEgASABIAAAAAUQAAAAAEdGVuNgAAAAAAAA9CQAAAAAAEdGVuOAAAAAAABfXhAAAAAAAHQlVMTEtleQIAAAAGQlVMTElkAAAAAAdCRUFSS2V5AgAAAAZCRUFSSWQAAAAADG1haW5Ub2tlbktleQIAAAALbWFpblRva2VuSWQAAAAAEWJ1bGxDb2xsYXRlcmFsS2V5AgAAAA5idWxsQ29sbGF0ZXJhbAAAAAARYmVhckNvbGxhdGVyYWxLZXkCAAAADmJlYXJDb2xsYXRlcmFsAAAAABJidWxsQ2lyY3VsYXRpb25LZXkCAAAAD2J1bGxDaXJjdWxhdGlvbgAAAAASYmVhckNpcmN1bGF0aW9uS2V5AgAAAA9iZWFyQ2lyY3VsYXRpb24AAAAAEmlzc3VlUGVyY2VudGlsZUtleQIAAAAPaXNzdWVQZXJjZW50aWxlAAAAABNyZWRlZW1QZXJjZW50aWxlS2V5AgAAABByZWRlZW1QZXJjZW50aWxlAAAAAAttaW5Jc3N1ZUtleQIAAAAIbWluSXNzdWUAAAAADG1pblJlZGVlbUtleQIAAAAJbWluUmVkZWVtAAAAAAptaW5Qb29sS2V5AgAAAAdtaW5Qb29sAAAAABJmZWVzQWNjdW11bGF0ZWRLZXkCAAAAD2ZlZXNBY2N1bXVsYXRlZAAAAAAQd2hpdGVsaXN0T25seUtleQIAAAANd2hpdGVsaXN0T25seQAAAAAMd2hpdGVsaXN0S2V5AgAAAA5pc3N1ZVdoaXRlTGlzdAAAAAALb3JhY2xlUEtLZXkCAAAABm9yYWNsZQAAAAARbGFzdFByaWNlSW5kZXhLZXkCAAAAC3ByaWNlX2luZGV4AAAAABBwcmljZUluZGV4UHJlZml4AgAAAAxwcmljZV9pbmRleF8AAAAAEXByaWNlSGVpZ2h0UHJlZml4AgAAAAZwcmljZV8AAAAAGm9yYWNsZUN1cnJlbnRQcmljZUluZGV4S2V5AgAAAAtwcmljZV9pbmRleAAAAAAabGFzdFJlYmFsYW5jZVByaWNlSW5kZXhLZXkCAAAAFWxhc3RTZXR0bGVtZW50UHJpY2VJZAAAAAAOaGVhZFBvaW50ZXJLZXkCAAAAC2hlYWRQb2ludGVyAAAAAA50YWlsUG9pbnRlcktleQIAAAALdGFpbFBvaW50ZXIAAAAADHF1ZXVlU2l6ZUtleQIAAAAJcXVldWVTaXplAAAAABVwb29sTWFpblRva2VuVmFsdWVLZXkCAAAAEnBvb2xNYWluVG9rZW5WYWx1ZQAAAAAJcG9vbFVwS2V5AgAAAAZwb29sVXAAAAAACnBvb2xEd25LZXkCAAAAB3Bvb2xEd24AAAAADnBvb2xFbmFibGVkS2V5AgAAAAtwb29sRW5hYmxlZAAAAAAXcG9vbFRva2VuQ2lyY3VsYXRpb25LZXkCAAAAFHBvb2xUb2tlbkNpcmN1bGF0aW9uAAAAAAxwb29sVG9rZW5LZXkCAAAACXBvb2xUb2tlbgAAAAAHYnVsbENvbAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAEWJ1bGxDb2xsYXRlcmFsS2V5AgAAABRubyBidWxsQ29sbGF0ZXJhbEtleQAAAAAHYmVhckNvbAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAEWJlYXJDb2xsYXRlcmFsS2V5AgAAABRubyBiZWFyQ29sbGF0ZXJhbEtleQAAAAAIYnVsbENpcmMJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAABJidWxsQ2lyY3VsYXRpb25LZXkCAAAAFW5vIGJ1bGxDaXJjdWxhdGlvbktleQAAAAAIYmVhckNpcmMJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAABJiZWFyQ2lyY3VsYXRpb25LZXkCAAAAFW5vIGJlYXJDaXJjdWxhdGlvbktleQAAAAAEQlVMTAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAB0JVTExLZXkCAAAACm5vIEJVTExLZXkAAAAABEJFQVIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAR0aGlzBQAAAAdCRUFSS2V5AgAAAApubyBCRUFSS2V5AAAAAAltYWluVG9rZW4JAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAR0aGlzBQAAAAxtYWluVG9rZW5LZXkCAAAAD25vIG1haW5Ub2tlbktleQAAAAAPaXNzdWVQZXJjZW50aWxlCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAASaXNzdWVQZXJjZW50aWxlS2V5AgAAABVubyBpc3N1ZVBlcmNlbnRpbGVLZXkAAAAAEHJlZGVlbVBlcmNlbnRpbGUJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAABNyZWRlZW1QZXJjZW50aWxlS2V5AgAAABZubyByZWRlZW1QZXJjZW50aWxlS2V5AAAAAAhtaW5Jc3N1ZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAC21pbklzc3VlS2V5AgAAAA5ubyBtaW5Jc3N1ZUtleQAAAAAJbWluUmVkZWVtCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAMbWluUmVkZWVtS2V5AgAAAA9ubyBtaW5SZWRlZW1LZXkAAAAAB21pblBvb2wJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAAAptaW5Qb29sS2V5AgAAAA1ubyBtaW5Qb29sS2V5AAAAAA13aGl0ZWxpc3RPbmx5CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQbAAAAAgUAAAAEdGhpcwUAAAAQd2hpdGVsaXN0T25seUtleQIAAAATbm8gd2hpdGVsaXN0T25seUtleQAAAAAJd2hpdGVsaXN0CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAAMd2hpdGVsaXN0S2V5AgAAABRubyBidWxsQ29sbGF0ZXJhbEtleQAAAAAPcG9vbEluaXRpYWxpemVkCQEAAAAJaXNEZWZpbmVkAAAAAQkABBsAAAACBQAAAAR0aGlzBQAAABVwb29sTWFpblRva2VuVmFsdWVLZXkAAAAAC3Bvb2xFbmFibGVkCQAAAAAAAAIJAAQbAAAAAgUAAAAEdGhpcwUAAAAOcG9vbEVuYWJsZWRLZXkGAAAAAAhwb29sTWFpbgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAFXBvb2xNYWluVG9rZW5WYWx1ZUtleQIAAAAYbm8gcG9vbE1haW5Ub2tlblZhbHVlS2V5AAAAAAZwb29sVXAJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAAAlwb29sVXBLZXkCAAAADG5vIHBvb2xVcEtleQAAAAAHcG9vbER3bgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAACnBvb2xEd25LZXkCAAAADW5vIHBvb2xEd25LZXkAAAAACXBvb2xUb2tlbgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAADHBvb2xUb2tlbktleQIAAAAPbm8gcG9vbFRva2VuS2V5AAAAABRwb29sVG9rZW5DaXJjdWxhdGlvbgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAF3Bvb2xUb2tlbkNpcmN1bGF0aW9uS2V5AgAAABpubyBwb29sVG9rZW5DaXJjdWxhdGlvbktleQAAAAAJcG9vbFZhbHVlCQAAZAAAAAIJAABkAAAAAgUAAAAIcG9vbE1haW4JAABrAAAAAwUAAAAHYnVsbENvbAUAAAAGcG9vbFVwBQAAAAhidWxsQ2lyYwkAAGsAAAADBQAAAAdiZWFyQ29sBQAAAAdwb29sRHduBQAAAAhiZWFyQ2lyYwAAAAAGb3JhY2xlCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAQAAABRhZGRyZXNzRnJvbVB1YmxpY0tleQAAAAEJAAJZAAAAAQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAC29yYWNsZVBLS2V5AgAAAA5ubyBvcmFjbGVQS0tleQIAAAASYmFkIG9yYWNsZSBhZGRyZXNzAAAAABRyZWJhbGFuY2VkUHJpY2VJbmRleAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAGmxhc3RSZWJhbGFuY2VQcmljZUluZGV4S2V5AgAAABdubyBsYXN0IHJlYmFsYW5jZSBwcmljZQAAAAAQb3JhY2xlUHJpY2VJbmRleAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABm9yYWNsZQUAAAARbGFzdFByaWNlSW5kZXhLZXkJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAE2JhZCBvcmFjbGUgZGF0YSBhdCAJAAQlAAAAAQUAAAAGb3JhY2xlAgAAABA6IG5vIGludGVnZXIgYXQgBQAAABFsYXN0UHJpY2VJbmRleEtleQAAAAAJcXVldWVTaXplCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAADHF1ZXVlU2l6ZUtleQAAAAAAAAAAAAAAAAALaGVhZFBvaW50ZXIJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAAOaGVhZFBvaW50ZXJLZXkCAAAAAAAAAAALdGFpbFBvaW50ZXIJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAAOdGFpbFBvaW50ZXJLZXkCAAAAAAAAAAAPZmVlc0FjY3VtdWxhdGVkCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAEmZlZXNBY2N1bXVsYXRlZEtleQAAAAAAAAAAAAAAAAAFSVNTVUUCAAAABUlTU1VFAAAAAAZSRURFRU0CAAAABlJFREVFTQAAAAAEUE9PTAIAAAAEUE9PTAAAAAAGVU5QT09MAgAAAAZVTlBPT0wAAAAACmZlZUFkZHJLZXkCAAAACmZlZUFkZHJlc3MAAAAADnN0YWtpbmdBZGRyS2V5AgAAAA5zdGFraW5nQWRkcmVzcwAAAAAPZGFlbW9uUHViS2V5S2V5AgAAAA9kYWVtb25QdWJsaWNLZXkAAAAACmZlZUFkZHJlc3MJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABCQEA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UG9vbFVwBQAAAAtjdXJCdWxsQ2lyYwQAAAAQbGlxdWlkYXRlZFRva2VucwMJAABmAAAAAgUAAAAEZGlmZgUAAAAIZXhwb3N1cmUFAAAACWN1clBvb2xVcAkAAGsAAAADBQAAAARkaWZmBQAAAAtjdXJCdWxsQ2lyYwUAAAAKY3VyQnVsbENvbAQAAAAPbGlxdWlkYXRlZFZhbHVlAwkAAGYAAAACBQAAAARkaWZmBQAAAAhleHBvc3VyZQUAAAAIZXhwb3N1cmUJAABrAAAAAwUAAAAQbGlxdWlkYXRlZFRva2VucwUAAAAKY3VyQnVsbENvbAUAAAALY3VyQnVsbENpcmMJAAUZAAAABwkAAGUAAAACBQAAAApjdXJCdWxsQ29sBQAAAA9saXF1aWRhdGVkVmFsdWUFAAAACmN1ckJlYXJDb2wJAABlAAAAAgUAAAALY3VyQnVsbENpcmMFAAAAEGxpcXVpZGF0ZWRUb2tlbnMFAAAAC2N1ckJlYXJDaXJjCQAAZAAAAAIFAAAAC2N1clBvb2xNYWluBQAAAA9saXF1aWRhdGVkVmFsdWUJAABlAAAAAgUAAAAJY3VyUG9vbFVwBQAAABBsaXF1aWRhdGVkVG9rZW5zBQAAAApjdXJQb29sRHduCgEAAAAIY2xvc2VEd24AAAAHAAAACmN1ckJ1bGxDb2wAAAAKY3VyQmVhckNvbAAAAAtjdXJCdWxsQ2lyYwAAAAtjdXJCZWFyQ2lyYwAAAAtjdXJQb29sTWFpbgAAAAljdXJQb29sVXAAAAAKY3VyUG9vbER3bgQAAAAEZGlmZgkAAGUAAAACBQAAAApjdXJCZWFyQ29sBQAAAApjdXJCdWxsQ29sBAAAAAhleHBvc3VyZQkAAGsAAAADBQAAAApjdXJCZWFyQ29sBQAAAApjdXJQb29sRHduBQAAAAtjdXJCZWFyQ2lyYwQAAAAQbGlxdWlkYXRlZFRva2VucwMJAABmAAAAAgUAAAAEZGlmZgUAAAAIZXhwb3N1cmUFAAAACmN1clBvb2xEd24JAABrAAAAAwUAAAAEZGlmZgUAAAALY3VyQmVhckNpcmMFAAAACmN1ckJlYXJDb2wEAAAAD2xpcXVpZGF0ZWRWYWx1ZQMJAABmAAAAAgUAAAAEZGlmZgUAAAAIZXhwb3N1cmUFAAAACGV4cG9zdXJlCQAAawAAAAMFAAAAEGxpcXVpZGF0ZWRUb2tlbnMFAAAACmN1ckJlYXJDb2wFAAAAC2N1ckJlYXJDaXJjCQAFGQAAAAcFAAAACmN1ckJ1bGxDb2wJAABlAAAAAgUAAAAKY3VyQmVhckNvbAUAAAAPbGlxdWlkYXRlZFZhbHVlBQAAAAtjdXJCdWxsQ2lyYwkAAGUAAAACBQAAAAtjdXJCZWFyQ2lyYwUAAAAQbGlxdWlkYXRlZFRva2VucwkAAGQAAAACBQAAAAtjdXJQb29sTWFpbgUAAAAPbGlxdWlkYXRlZFZhbHVlBQAAAAljdXJQb29sVXAJAABlAAAAAgUAAAAKY3VyUG9vbER3bgUAAAAQbGlxdWlkYXRlZFRva2VucwoBAAAAB29wZW5Ed24AAAAHAAAACmN1ckJ1bGxDb2wAAAAKY3VyQmVhckNvbAAAAAtjdXJCdWxsQ2lyYwAAAAtjdXJCZWFyQ2lyYwAAAAtjdXJQb29sTWFpbgAAAAljdXJQb29sVXAAAAAKY3VyUG9vbER3bgQAAAAEZGlmZgkAAGUAAAACBQAAAApjdXJCdWxsQ29sBQAAAApjdXJCZWFyQ29sBAAAAA5zcGVudFBvb2xWYWx1ZQMJAABmAAAAAgUAAAALY3VyUG9vbE1haW4FAAAABGRpZmYFAAAABGRpZmYFAAAAC2N1clBvb2xNYWluBAAAAA5hY3F1aXJlZFRva2VucwkAAGsAAAADBQAAAA5zcGVudFBvb2xWYWx1ZQUAAAALY3VyQmVhckNpcmMFAAAACmN1ckJlYXJDb2wJAAUZAAAABwUAAAAKY3VyQnVsbENvbAkAAGQAAAACBQAAAApjdXJCZWFyQ29sBQAAAA5zcGVudFBvb2xWYWx1ZQUAAAALY3VyQnVsbENpcmMJAABkAAAAAgUAAAALY3VyQmVhckNpcmMFAAAADmFjcXVpcmVkVG9rZW5zCQAAZQAAAAIFAAAAC2N1clBvb2xNYWluBQAAAA5zcGVudFBvb2xWYWx1ZQUAAAAJY3VyUG9vbFVwCQAAZAAAAAIFAAAACmN1clBvb2xEd24FAAAADmFjcXVpcmVkVG9rZW5zCgEAAAAGb3BlblVwAAAABwAAAApjdXJCdWxsQ29sAAAACmN1ckJlYXJDb2wAAAALY3VyQnVsbENpcmMAAAALY3VyQmVhckNpcmMAAAALY3VyUG9vbE1haW4AAAAJY3VyUG9vbFVwAAAACmN1clBvb2xEd24EAAAABGRpZmYJAABlAAAAAgUAAAAKY3VyQmVhckNvbAUAAAAKY3VyQnVsbENvbAQAAAAOc3BlbnRQb29sVmFsdWUDCQAAZgAAAAIFAAAAC2N1clBvb2xNYWluBQAAAARkaWZmBQAAAARkaWZmBQAAAAtjdXJQb29sTWFpbgQAAAAOYWNxdWlyZWRUb2tlbnMJAABrAAAAAwUAAAAOc3BlbnRQb29sVmFsdWUFAAAAC2N1ckJ1bGxDaXJjBQAAAApjdXJCdWxsQ29sCQAFGQAAAAcJAABkAAAAAgUAAAAKY3VyQnVsbENvbAUAAAAOc3BlbnRQb29sVmFsdWUFAAAACmN1ckJlYXJDb2wJAABkAAAAAgUAAAALY3VyQnVsbENpcmMFAAAADmFjcXVpcmVkVG9rZW5zBQAAAAtjdXJCZWFyQ2lyYwkAAGUAAAACBQAAAAtjdXJQb29sTWFpbgUAAAAOc3BlbnRQb29sVmFsdWUJAABkAAAAAgUAAAAJY3VyUG9vbFVwBQAAAA5hY3F1aXJlZFRva2VucwUAAAAKY3VyUG9vbER3bgMJAABmAAAAAgUAAAALY3VyQnVsbENvbDAFAAAAC2N1ckJlYXJDb2wwBAAAAAxhZnRlckNsb3NlVXAJAQAAAAdjbG9zZVVwAAAABwUAAAALY3VyQnVsbENvbDAFAAAAC2N1ckJlYXJDb2wwBQAAAAxjdXJCdWxsQ2lyYzAFAAAADGN1ckJlYXJDaXJjMAUAAAAMY3VyUG9vbE1haW4wBQAAAApjdXJQb29sVXAwBQAAAAtjdXJQb29sRHduMAQAAAAMJHQwOTk0NjEwMDgzBQAAAAxhZnRlckNsb3NlVXAEAAAAAWEIBQAAAAwkdDA5OTQ2MTAwODMAAAACXzEEAAAAAWIIBQAAAAwkdDA5OTQ2MTAwODMAAAACXzIEAAAAAWMIBQAAAAwkdDA5OTQ2MTAwODMAAAACXzMEAAAAAWQIBQAAAAwkdDA5OTQ2MTAwODMAAAACXzQEAAAAAWUIBQAAAAwkdDA5OTQ2MTAwODMAAAACXzUEAAAAAWYIBQAAAAwkdDA5OTQ2MTAwODMAAAACXzYEAAAAAWcIBQAAAAwkdDA5OTQ2MTAwODMAAAACXzcDCQAAZgAAAAIFAAAAAWYAAAAAAAAAAAAFAAAADGFmdGVyQ2xvc2VVcAMJAAAAAAAAAgUAAAABZgAAAAAAAAAAAAkBAAAAB29wZW5Ed24AAAAHBQAAAAFhBQAAAAFiBQAAAAFjBQAAAAFkBQAAAAFlBQAAAAFmBQAAAAFnCQAAAgAAAAECAAAACnBvb2xVcCA8IDAEAAAADWFmdGVyQ2xvc2VEd24JAQAAAAhjbG9zZUR3bgAAAAcFAAAAC2N1ckJ1bGxDb2wwBQAAAAtjdXJCZWFyQ29sMAUAAAAMY3VyQnVsbENpcmMwBQAAAAxjdXJCZWFyQ2lyYzAFAAAADGN1clBvb2xNYWluMAUAAAAKY3VyUG9vbFVwMAUAAAALY3VyUG9vbER3bjAEAAAADSR0MDEwNDM0MTA1NzQFAAAADWFmdGVyQ2xvc2VEd24EAAAAAWEIBQAAAA0kdDAxMDQzNDEwNTc0AAAAAl8xBAAAAAFiCAUAAAANJHQwMTA0MzQxMDU3NAAAAAJfMgQAAAABYwgFAAAADSR0MDEwNDM0MTA1NzQAAAACXzMEAAAAAWQIBQAAAA0kdDAxMDQzNDEwNTc0AAAAAl80BAAAAAFlCAUAAAANJHQwMTA0MzQxMDU3NAAAAAJfNQQAAAABZggFAAAADSR0MDEwNDM0MTA1NzQAAAACXzYEAAAAAWcIBQAAAA0kdDAxMDQzNDEwNTc0AAAAAl83AwkAAGYAAAACBQAAAAFnAAAAAAAAAAAABQAAAA1hZnRlckNsb3NlRHduAwkAAAAAAAACBQAAAAFnAAAAAAAAAAAACQEAAAAGb3BlblVwAAAABwUAAAABYQUAAAABYgUAAAABYwUAAAABZAUAAAABZQUAAAABZgUAAAABZwkAAAIAAAABAgAAAAtwb29sRHduIDwgMAEAAAAUYWN0aW9uc1dpdGhNYXliZVBvb2wAAAAEAAAAC2N1ckJ1bGxDb2wwAAAAC2N1ckJlYXJDb2wwAAAADGN1ckJ1bGxDaXJjMAAAAAxjdXJCZWFyQ2lyYzADBQAAAAtwb29sRW5hYmxlZAQAAAANJHQwMTA4OTgxMTA4MQkBAAAAC3Bvb2xTdXBwb3J0AAAABwUAAAALY3VyQnVsbENvbDAFAAAAC2N1ckJlYXJDb2wwBQAAAAxjdXJCdWxsQ2lyYzAFAAAADGN1ckJlYXJDaXJjMAUAAAAIcG9vbE1haW4FAAAABnBvb2xVcAUAAAAHcG9vbER3bgQAAAAIYnVsbENvbDEIBQAAAA0kdDAxMDg5ODExMDgxAAAAAl8xBAAAAAhiZWFyQ29sMQgFAAAADSR0MDEwODk4MTEwODEAAAACXzIEAAAACGJ1bGxDaWMxCAUAAAANJHQwMTA4OTgxMTA4MQAAAAJfMwQAAAAJYmVhckNpcmMxCAUAAAANJHQwMTA4OTgxMTA4MQAAAAJfNAQAAAAJcG9vbE1haW4xCAUAAAANJHQwMTA4OTgxMTA4MQAAAAJfNQQAAAAHcG9vbFVwMQgFAAAADSR0MDEwODk4MTEwODEAAAACXzYEAAAACHBvb2xEd24xCAUAAAANJHQwMTA4OTgxMTA4MQAAAAJfNwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARYnVsbENvbGxhdGVyYWxLZXkFAAAACGJ1bGxDb2wxCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJidWxsQ2lyY3VsYXRpb25LZXkFAAAACGJ1bGxDaWMxCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABFiZWFyQ29sbGF0ZXJhbEtleQUAAAAIYmVhckNvbDEJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEmJlYXJDaXJjdWxhdGlvbktleQUAAAAJYmVhckNpcmMxCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABVwb29sTWFpblRva2VuVmFsdWVLZXkFAAAACXBvb2xNYWluMQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAJcG9vbFVwS2V5BQAAAAdwb29sVXAxCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAApwb29sRHduS2V5BQAAAAhwb29sRHduMQUAAAADbmlsCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABFidWxsQ29sbGF0ZXJhbEtleQUAAAALY3VyQnVsbENvbDAJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEmJ1bGxDaXJjdWxhdGlvbktleQUAAAAM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DlNjcmlwdFRyYW5zZmVyAAAAAwUAAAAHaW52b2tlcgUAAAASYWRkZWRUb0NpcmN1bGF0aW9uCQACWQAAAAEFAAAABEJVTEwFAAAAA25pbAMJAAAAAAAAAgUAAAAFdG9rZW4FAAAABEJFQVIEAAAAEmFkZGVkVG9DaXJjdWxhdGlvbgkAAGsAAAADBQAAAAhiZWFyQ2lyYwUAAAAPYWRkZWRDb2xsYXRlcmFsBQAAAAdiZWFyQ29sCQAETgAAAAIJAQAAABRhY3Rpb25zV2l0aE1heWJlUG9vbAAAAAQFAAAAB2J1bGxDb2wJAABkAAAAAgUAAAAHYmVhckNvbAUAAAAPYWRkZWRDb2xsYXRlcmFsBQAAAAhidWxsQ2lyYwkAAGQAAAACBQAAAAhiZWFyQ2lyYwUAAAASYWRkZWRUb0NpcmN1bGF0aW9uCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAADmhlYWRQb2ludGVyS2V5BQAAAARuZXh0CQAETAAAAAIJAQAAAApjb2xsZWN0RmVlAAAAAQUAAAAHZmVlU2l6ZQkABEwAAAACBQAAABFkZWNyZWFzZVF1ZXVlU2l6ZQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAAdpbnZva2VyBQAAABJhZGRlZFRvQ2lyY3VsYXRpb24JAAJZAAAAAQUAAAAEQkVBUgUAAAADbmlsCQAAAgAAAAECAAAADGJhZCB0b2tlbiBpZAMJAAAAAAAAAgUAAAAGYWN0aW9uBQAAAAZSRURFRU0EAAAADXJlbW92ZWRUb2tlbnMFAAAAA2FtdAMJAAAAAAAAAgUAAAAFdG9rZW4FAAAABEJVTEwEAAAAEXJlbW92ZWRDb2xsYXRlcmFsCQAAawAAAAMFAAAAB2J1bGxDb2wFAAAADXJlbW92ZWRUb2tlbnMFAAAACGJ1bGxDaXJjBAAAAAdmZWVTaXplCQAAawAAAAMFAAAAEXJlbW92ZWRDb2xsYXRlcmFsBQAAABByZWRlZW1QZXJjZW50aWxlAAAAAAAAACcQBAAAAAZwYXlvdXQDCQAAZgAAAAIFAAAAEXJlbW92ZWRDb2xsYXRlcmFsBQAAAAdmZWVTaXplCQAAZQAAAAIFAAAAEXJlbW92ZWRDb2xsYXRlcmFsBQAAAAdmZWVTaXplAAAAAAAAAAAACQAETgAAAAIJAQAAABRhY3Rpb25zV2l0aE1heWJlUG9vbAAAAAQJAABlAAAAAgUAAAAHYnVsbENvbAUAAAARcmVtb3ZlZENvbGxhdGVyYWwFAAAAB2JlYXJDb2wJAABlAAAAAgUAAAAIYnVsbENpcmMFAAAADXJlbW92ZWRUb2tlbnMFAAAACGJlYXJDaXJjCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAADmhlYWRQb2ludGVyS2V5BQAAAARuZXh0CQAETAAAAAIJAQAAAApjb2xsZWN0RmVlAAAAAQUAAAAHZmVlU2l6ZQkABEwAAAACBQAAABFkZWNyZWFzZVF1ZXVlU2l6ZQkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAAdpbnZva2VyBQAAAAZwYXlvdXQJAAJZAAAAAQUAAAAJbWFpblRva2VuBQAAAANuaWwDCQAAAAAAAAIFAAAABXRva2VuBQAAAARCRUFSBAAAABFyZW1vdmVkQ29sbGF0ZXJhbAkAAGsAAAADBQAAAAdiZWFyQ29sBQAAAA1yZW1vdmVkVG9rZW5zBQAAAAhiZWFyQ2lyYwQAAAAHZmVlU2l6ZQkAAGsAAAADBQAAABFyZW1vdmVkQ29sbGF0ZXJhbAUAAAAQcmVkZWVtUGVyY2VudGlsZQAAAAAAAAAnEAQAAAAGcGF5b3V0AwkAAGYAAAACBQAAABFyZW1vdmVkQ29sbGF0ZXJhbAUAAAAHZmVlU2l6ZQkAAGUAAAACBQAAABFyZW1vdmVkQ29sbGF0ZXJhbAUAAAAHZmVlU2l6ZQAAAAAAAAAAAAkABE4AAAACCQEAAAAUYWN0aW9uc1dpdGhNYXliZVBvb2wAAAAEBQAAAAdidWxsQ29sCQAAZQAAAAIFAAAAB2JlYXJDb2wFAAAAEXJlbW92ZWRDb2xsYXRlcmFsBQAAAAhidWxsQ2lyYwkAAGUAAAACBQAAAAhiZWFyQ2lyYwUAAAANcmVtb3ZlZFRva2VucwkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAA5oZWFkUG9pbnRlcktleQUAAAAEbmV4dAkABEwAAAACCQEAAAAKY29sbGVjdEZlZQAAAAEFAAAAB2ZlZVNpemUJAARMAAAAAgUAAAARZGVjcmVhc2VRdWV1ZVNpemUJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAAHaW52b2tlcgUAAAAGcGF5b3V0CQACWQAAAAEFAAAACW1haW5Ub2tlbgUAAAADbmlsCQAAAgAAAAECAAAADGJhZCB0b2tlbiBpZAMJAAAAAAAAAgUAAAAGYWN0aW9uBQAAAARQT09MBAAAAAtpc3N1ZVRva2VucwkAAGsAAAADBQAAABRwb29sVG9rZW5DaXJjdWxhdGlvbgUAAAADYW10BQAAAAlwb29sVmFsdWUJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAFXBvb2xNYWluVG9rZW5WYWx1ZUtleQkAAGQAAAACBQAAAAhwb29sTWFpbgUAAAADYW10CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABdwb29sVG9rZW5DaXJjdWxhdGlvbktleQkAAGQAAAACBQAAABRwb29sVG9rZW5DaXJjdWxhdGlvbgUAAAALaXNzdWVUb2tlbnMJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAOaGVhZFBvaW50ZXJLZXkFAAAABG5leHQJAARMAAAAAgUAAAARZGVjcmVhc2VRdWV1ZVNpemUJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAAHaW52b2tlcgUAAAALaXNzdWVUb2tlbnMJAAJZAAAAAQUAAAAJcG9vbFRva2VuBQAAAANuaWwDCQAAAAAAAAIFAAAABmFjdGlvbgUAAAAGVU5QT09MCgEAAAAFc2hhcmUAAAABAAAAAWEJAABrAAAAAwUAAAABYQUAAAADYW10BQAAABRwb29sVG9rZW5DaXJjdWxhdGlvbgQAAAAMdW5wb29sZWRNYWluCQEAAAAFc2hhcmUAAAABBQAAAAhwb29sTWFpbgQAAAAKdW5wb29sZWRVcAkBAAAABXNoYXJlAAAAAQUAAAAGcG9vbFVwBAAAAAt1bnBvb2xlZER3bgkBAAAABXNoYXJlAAAAAQUAAAAHcG9vbER3bgQAAAAPdW5wb29sZWRVcFZhbHVlCQAAawAAAAMFAAAACnVucG9vbGVkVXAFAAAAB2J1bGxDb2wFAAAACGJ1bGxDaXJjBAAAABB1bnBvb2xlZER3blZhbHVlCQAAawAAAAMFAAAAC3VucG9vbGVkRHduBQAAAAdiZWFyQ29sBQAAAAhiZWFyQ2lyYwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAVcG9vbE1haW5Ub2tlblZhbHVlS2V5CQAAZQAAAAIFAAAACHBvb2xNYWluBQAAAAx1bnBvb2xlZE1haW4JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAF3Bvb2xUb2tlbkNpcmN1bGF0aW9uS2V5CQAAZQAAAAIFAAAAFHBvb2xUb2tlbkNpcmN1bGF0aW9uBQAAAANhbXQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAACXBvb2xVcEtleQkAAGUAAAACBQAAAAZwb29sVXAFAAAACnVucG9vbGVkVXAJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAACnBvb2xEd25LZXkJAABlAAAAAgUAAAAHcG9vbER3bgUAAAALdW5wb29sZWREd24JAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEmJ1bGxDaXJjdWxhdGlvbktleQkAAGUAAAACBQAAAAhidWxsQ2lyYwUAAAAKdW5wb29sZWRVcAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAASYmVhckNpcmN1bGF0aW9uS2V5CQAAZQAAAAIFAAAACGJlYXJDaXJjBQAAAAt1bnBvb2xlZER3bgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARYnVsbENvbGxhdGVyYWxLZXkJAABlAAAAAgUAAAAHYnVsbENvbAUAAAAPdW5wb29sZWRVcFZhbHVlCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABFiZWFyQ29sbGF0ZXJhbEtleQkAAGUAAAACBQAAAAdiZWFyQ29sBQAAABB1bnBvb2xlZER3blZhbHVlCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAADmhlYWRQb2ludGVyS2V5BQAAAARuZXh0CQAETAAAAAIFAAAAEWRlY3JlYXNlUXVldWVTaXplCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMFAAAAB2ludm9rZXIJAABkAAAAAgkAAGQAAAACBQAAAAx1bnBvb2xlZE1haW4FAAAAD3VucG9vbGVkVXBWYWx1ZQUAAAAQdW5wb29sZWREd25WYWx1ZQkAAlkAAAABBQAAAAltYWluVG9rZW4FAAAAA25pbAkAAAIAAAABCQABLAAAAAICAAAADGJhZCBhY3Rpb246IAUAAAAGYWN0aW9uAwUAAAANaXNMYXN0RWxlbWVudAkABEwAAAACBQAAAA1vdmVyd3JpdGVUYWlsBQAAAAVpdGVtcwUAAAAFaXRlbXMBAAAACXJlYmFsYW5jZQAAAAAKAQAAAAJMVgAAAAMAAAABdgAAAAJwMAAAAAJwMQQAAAAFZGVub20AAAAAAAAAAGQEAAAABHBtYXgJAABpAAAAAgMJAABmAAAAAgUAAAACcDEFAAAAAnAwBQAAAAJwMQUAAAACcDAFAAAABWRlbm9tBAAAAARwbWluCQAAaQAAAAIDCQAAZgAAAAIFAAAAAnAwBQAAAAJwMQUAAAACcDEFAAAAAnAwBQAAAAVkZW5vbQQAAAABYQkAAGgAAAACBQAAAARwbWluBQAAAARwbWluBAAAAAFiCQAAZQAAAAIJAABoAAAAAgkAAGgAAAACAAAAAAAAAAAJBQAAAARwbWF4BQAAAARwbWF4CQAAaAAAAAIJAABoAAAAAgAAAAAAAAAADwUAAAAEcG1heAUAAAAEcG1pbgkAAGsAAAADBQAAAAF2CQAAZAAAAAIJAABoAAAAAgAAAAAAAAAABgUAAAABYQUAAAABYgkAAGQAAAACCQAAaAAAAAIAAAAAAAAAAAcFAAAAAWEFAAAAAWIEAAAAEXNldHRsZWRQcmljZUluZGV4CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAabGFzdFJlYmFsYW5jZVByaWNlSW5kZXhLZXkCAAAAEWluY29uc2lzdGVudCBkYXRhBAAAABN1bnNldHRsZWRQcmljZUluZGV4CQAAZAAAAAIFAAAAEXNldHRsZWRQcmljZUluZGV4AAAAAAAAAAABBAAAABJzZXR0bGVkUHJpY2VIZWlnaHQJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAZvcmFjbGUJAAEsAAAAAgIAAAAMcHJpY2VfaW5kZXhfCQABpAAAAAEFAAAAEXNldHRsZWRQcmljZUluZGV4AgAAAChiYWQgb3JhY2xlIGRhdGEgZm9yIHNldHRsZWQgcHJpY2UgaGVpZ2h0BAAAAAxzZXR0bGVkUHJpY2UJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAZvcmFjbGUJAAEsAAAAAgIAAAAGcHJpY2VfCQABpAAAAAEFAAAAEnNldHRsZWRQcmljZUhlaWdodAIAAAAZYmFkIG9yYWNsZSBkYXRhIGZvciBwcmljZQQAAAAPbmV4dFByaWNlSGVpZ2h0CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAGb3JhY2xlCQABLAAAAAICAAAADHByaWNlX2luZGV4XwkAAaQAAAABBQAAABN1bnNldHRsZWRQcmljZUluZGV4AgAAABRubyBuZXh0IHByaWNlIGhlaWdodAQAAAAJbmV4dFByaWNlCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAGb3JhY2xlCQABLAAAAAICAAAABnByaWNlXwkAAaQAAAABBQAAAA9uZXh0UHJpY2VIZWlnaHQCAAAADW5vIG5leHQgcHJpY2UEAAAABm1pblZvbAMJAABmAAAAAgUAAAAHYmVhckNvbAUAAAAHYnVsbENvbAUAAAAHYnVsbENvbAUAAAAHYmVhckNvbAQAAAAGcmVkaXN0CQEAAAACTFYAAAADBQAAAAZtaW5Wb2wFAAAADHNldHRsZWRQcmljZQUAAAAJbmV4dFByaWNlBAAAAApuZXdCdWxsQ29sAwkAAGYAAAACBQAAAAluZXh0UHJpY2UFAAAADHNldHRsZWRQcmljZQkAAGQAAAACBQAAAAdidWxsQ29sBQAAAAZyZWRpc3QJAABlAAAAAgUAAAAHYnVsbENvbAUAAAAGcmVkaXN0BAAAAApuZXdCZWFyQ29sAwkAAGYAAAACBQAAAAluZXh0UHJpY2UFAAAADHNldHRsZWRQcmljZQkAAGUAAAACBQAAAAdiZWFyQ29sBQAAAAZyZWRpc3QJAABkAAAAAgUAAAAHYmVhckNvbAUAAAAGcmVkaXN0AwUAAAALcG9vbEVuYWJsZWQEAAAADSR0MDE5MjIwMTk0MDcJAQAAAAtwb29sU3VwcG9ydAAAAAcFAAAACm5ld0J1bGxDb2wFAAAACm5ld0JlYXJDb2wFAAAACGJ1bGxDaXJjBQAAAAhiZWFyQ2lyYwUAAAAIcG9vbE1haW4FAAAABnBvb2xVcAUAAAAHcG9vbER3bgQAAAAKdXBkQnVsbENvbAgFAAAADSR0MDE5MjIwMTk0MDcAAAACXzEEAAAACnVwZEJlYXJDb2wIBQAAAA0kdDAxOTIyMDE5NDA3AAAAAl8yBAAAAAt1cGRCdWxsQ2lyYwgFAAAADSR0MDE5MjIwMTk0MDcAAAACXzMEAAAAC3VwZEJlYXJDaXJjCAUAAAANJHQwMTkyMjAxOTQwNwAAAAJfNAQAAAALdXBkUG9vbE1haW4IBQAAAA0kdDAxOTIyMDE5NDA3AAAAAl81BAAAAAl1cGRQb29sVXAIBQAAAA0kdDAxOTIyMDE5NDA3AAAAAl82BAAAAAp1cGRQb29sRHduCAUAAAANJHQwMTkyMjAxOTQwNwAAAAJfNwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARYnVsbENvbGxhdGVyYWxLZXkFAAAACnVwZEJ1bGxDb2wJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEWJlYXJDb2xsYXRlcmFsS2V5BQAAAAp1cGRCZWFyQ29sCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJidWxsQ2lyY3VsYXRpb25LZXkFAAAAC3VwZEJ1bGxDaXJjCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJiZWFyQ2lyY3VsYXRpb25LZXkFAAAAC3VwZEJlYXJDaXJjCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABVwb29sTWFpblRva2VuVmFsdWVLZXkFAAAAC3VwZFBvb2xNYWluCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAlwb29sVXBLZXkFAAAACXVwZFBvb2xVcAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAKcG9vbER3bktleQUAAAAKdXBkUG9vbER3bgkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAabGFzdFJlYmFsYW5jZVByaWNlSW5kZXhLZXkFAAAAE3Vuc2V0dGxlZFByaWNlSW5kZXgFAAAAA25pbAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARYnVsbENvbGxhdGVyYWxLZXkFAAAACm5ld0J1bGxDb2wJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEWJlYXJDb2xsYXRlcmFsS2V5BQAAAApuZXdCZWFyQ29sCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABpsYXN0UmViYWxhbmNlUHJpY2VJbmRleEtleQUAAAATdW5zZXR0bGVkUHJpY2VJbmRleAUAAAADbmlsAAAADAAAAANpbnYBAAAABGluaXQAAAAFAAAABmJ1bGxJZAAAAAZiZWFySWQAAAALbWFpblRva2VuSWQAAAAIb3JhY2xlUEsAAAALd2hpdGVsaXN0ZWQDCQEAAAAJaXNEZWZpbmVkAAAAAQkABB0AAAACBQAAAAR0aGlzBQAAAAdCVUxMS2V5CQAAAgAAAAECAAAAE2FscmVhZHkgaW5pdGlhbGl6ZWQDCQEAAAACIT0AAAACCQACWAAAAAEJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAggJAAGRAAAAAggFAAAAA2ludgAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAdhc3NldElkAgAAABluZXV0cmlubyBwYXltZW50IHJlcXVpcmVkBQAAAAttYWluVG9rZW5JZAkAAAIAAAABAgAAABdwYXltZW50IG5vdCBpbiBuZXV0cmlubwQAAAATdG90YWxPd25lZE1haW5Ub2tlbggJAAGRAAAAAggFAAAAA2ludgAAAAhwYXltZW50cwAAAAAAAAAAAAAAAAZhbW91bnQEAAAABWJ1bGxzCQAAaQAAAAIFAAAAE3RvdGFsT3duZWRNYWluVG9rZW4AAAAAAAAAAAIEAAAABWJlYXJzCQAAZQAAAAIFAAAAE3RvdGFsT3duZWRNYWluVG9rZW4FAAAABWJ1bGxzAwMJAAAAAAAAAgUAAAAFYmVhcnMAAAAAAAAAAAAGCQAAAAAAAAIFAAAABWJ1bGxzAAAAAAAAAAAACQAAAgAAAAECAAAAE2Nhbid0IGluaXQgYmFsYW5jZXMEAAAAF29yYWNsZUN1cnJlbnRQcmljZUluZGV4CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQEAAAAUYWRkcmVzc0Zyb21QdWJsaWNLZXkAAAABCQACWQAAAAEFAAAACG9yYWNsZVBLAgAAABJiYWQgb3JhY2xlIGFkZHJlc3MFAAAAEWxhc3RQcmljZUluZGV4S2V5AgAAACJjYW4ndCBmaW5kIGxhc3Qgb3JhY2xlIHByaWNlIGluZGV4CQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAB0JVTExLZXkFAAAABmJ1bGxJZAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAAdCRUFSS2V5BQAAAAZiZWFySWQJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAMbWFpblRva2VuS2V5BQAAAAttYWluVG9rZW5JZAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACBQAAAAtvcmFjbGVQS0tleQUAAAAIb3JhY2xlUEsJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAEWJ1bGxDb2xsYXRlcmFsS2V5BQAAAAVidWxscwkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAARYmVhckNvbGxhdGVyYWxLZXkFAAAABWJlYXJzCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJidWxsQ2lyY3VsYXRpb25LZXkFAAAABWJ1bGxzCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABJiZWFyQ2lyY3VsYXRpb25LZXkFAAAABWJlYXJzCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABpsYXN0UmViYWxhbmNlUHJpY2VJbmRleEtleQUAAAAXb3JhY2xlQ3VycmVudFByaWNlSW5kZXgJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgUAAAAMd2hpdGVsaXN0S2V5BQAAAAt3aGl0ZWxpc3RlZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAASaXNzdWVQZXJj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", "chainId": 87, "height": 2269310, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: EQCpMC2MmbSLSGwsHFtDXai27wxfvpRCMgv36evxEzjA Next: H5XQMYij4pYQCbR2oGmk5yYmxhkNhSjH5Yz2XMT6xTHD Diff:
OldNewDifferences
1-{-# STDLIB_VERSION 3 #-}
1+{-# STDLIB_VERSION 4 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let ten6 = 1000000
5+
6+let ten8 = 100000000
7+
48 let BULLKey = "BULLId"
59
610 let BEARKey = "BEARId"
711
812 let mainTokenKey = "mainTokenId"
13+
14+let bullCollateralKey = "bullCollateral"
15+
16+let bearCollateralKey = "bearCollateral"
17+
18+let bullCirculationKey = "bullCirculation"
19+
20+let bearCirculationKey = "bearCirculation"
921
1022 let issuePercentileKey = "issuePercentile"
1123
1527
1628 let minRedeemKey = "minRedeem"
1729
30+let minPoolKey = "minPool"
31+
32+let feesAccumulatedKey = "feesAccumulated"
33+
1834 let whitelistOnlyKey = "whitelistOnly"
35+
36+let whitelistKey = "issueWhiteList"
1937
2038 let oraclePKKey = "oracle"
2139
2947
3048 let lastRebalancePriceIndexKey = "lastSettlementPriceId"
3149
32-let bullCollateralKey = "bullCollateral"
50+let headPointerKey = "headPointer"
3351
34-let bearCollateralKey = "bearCollateral"
52+let tailPointerKey = "tailPointer"
3553
36-let bullCirculationKey = "bullCirculation"
54+let queueSizeKey = "queueSize"
3755
38-let bearCirculationKey = "bearCirculation"
56+let poolMainTokenValueKey = "poolMainTokenValue"
3957
40-let whitelistKey = "issueWhiteList"
58+let poolUpKey = "poolUp"
4159
42-let whitelist = valueOrErrorMessage(getString(this, whitelistKey), "no bullCollateralKey")
60+let poolDwnKey = "poolDwn"
61+
62+let poolEnabledKey = "poolEnabled"
63+
64+let poolTokenCirculationKey = "poolTokenCirculation"
65+
66+let poolTokenKey = "poolToken"
4367
4468 let bullCol = valueOrErrorMessage(getInteger(this, bullCollateralKey), "no bullCollateralKey")
4569
6387
6488 let minRedeem = valueOrErrorMessage(getInteger(this, minRedeemKey), "no minRedeemKey")
6589
90+let minPool = valueOrErrorMessage(getInteger(this, minPoolKey), "no minPoolKey")
91+
6692 let whitelistOnly = valueOrErrorMessage(getBoolean(this, whitelistOnlyKey), "no whitelistOnlyKey")
93+
94+let whitelist = valueOrErrorMessage(getString(this, whitelistKey), "no bullCollateralKey")
95+
96+let poolInitialized = isDefined(getBoolean(this, poolMainTokenValueKey))
97+
98+let poolEnabled = (getBoolean(this, poolEnabledKey) == true)
99+
100+let poolMain = valueOrErrorMessage(getInteger(this, poolMainTokenValueKey), "no poolMainTokenValueKey")
101+
102+let poolUp = valueOrErrorMessage(getInteger(this, poolUpKey), "no poolUpKey")
103+
104+let poolDwn = valueOrErrorMessage(getInteger(this, poolDwnKey), "no poolDwnKey")
105+
106+let poolToken = valueOrErrorMessage(getString(this, poolTokenKey), "no poolTokenKey")
107+
108+let poolTokenCirculation = valueOrErrorMessage(getInteger(this, poolTokenCirculationKey), "no poolTokenCirculationKey")
109+
110+let poolValue = ((poolMain + fraction(bullCol, poolUp, bullCirc)) + fraction(bearCol, poolDwn, bearCirc))
67111
68112 let oracle = valueOrErrorMessage(addressFromPublicKey(fromBase58String(valueOrErrorMessage(getString(this, oraclePKKey), "no oraclePKKey"))), "bad oracle address")
69113
71115
72116 let oraclePriceIndex = valueOrErrorMessage(getInteger(oracle, lastPriceIndexKey), ((("bad oracle data at " + toString(oracle)) + ": no integer at ") + lastPriceIndexKey))
73117
74-let headPointerKey = "headPointer"
118+let queueSize = valueOrElse(getInteger(this, queueSizeKey), 0)
75119
76-let tailPointerKey = "tailPointer"
120+let headPointer = valueOrElse(getString(this, headPointerKey), "")
77121
78-let queueSizeKey = "queueSize"
122+let tailPointer = valueOrElse(getString(this, tailPointerKey), "")
79123
80-let queueSize = match getInteger(this, queueSizeKey) {
81- case i: Int =>
82- i
83- case _ =>
84- 0
85-}
86-
87-let headPointer = match getString(this, headPointerKey) {
88- case s: String =>
89- s
90- case _ =>
91- ""
92-}
93-
94-let tailPointer = match getString(this, tailPointerKey) {
95- case s: String =>
96- s
97- case _ =>
98- ""
99-}
100-
101-let feesAccumulatedKey = "feesAccumulated"
102-
103-let feesAccumulated = match getInteger(this, feesAccumulatedKey) {
104- case i: Int =>
105- i
106- case _ =>
107- 0
108-}
124+let feesAccumulated = valueOrElse(getInteger(this, feesAccumulatedKey), 0)
109125
110126 let ISSUE = "ISSUE"
111127
112128 let REDEEM = "REDEEM"
129+
130+let POOL = "POOL"
131+
132+let UNPOOL = "UNPOOL"
113133
114134 let feeAddrKey = "feeAddress"
115135
127147
128148 let pubKeyAdminsList = ["2HHqV8W9DJayV5R6tBD2Sb8srphpoboDi7r1t1aPiumC", "5ZXe82RRASU7qshXM2J9JNYhqJ9GWYjjVq2gwUV5Naz9", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
129149
150+func safeFraction (a,b,c) = if (if ((a == 0))
151+ then true
152+ else (b == 0))
153+ then 0
154+ else fraction(a, b, c)
155+
156+
130157 func buildNewItem (action,amt,token,priceIndex,invoker) = (((((((((action + "|") + toString(amt)) + "|") + token) + "|") + toString(priceIndex)) + "|") + invoker) + "|")
131158
132159
133-func validateEnqueue (inv) = if ((inv.caller == this))
160+func validateRequestRedeem (inv) = if ((inv.caller == this))
134161 then throw("can't do")
135162 else {
136163 func errorMessage (got) = throw(((((("only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") tokens are accepted, received: ") + got))
137164
138- if (!(isDefined(inv.payment)))
139- then errorMessage("no attached payment")
165+ let assetId = toBase58String(valueOrErrorMessage(value(inv.payments[0]).assetId, "waves are not accepted here"))
166+ if (if ((assetId != BEAR))
167+ then (assetId != BULL)
168+ else false)
169+ then errorMessage(assetId)
140170 else {
141- let assetId = toBase58String(valueOrErrorMessage(value(inv.payment).assetId, "waves are not accepted here"))
142- if (if ((assetId != BEAR))
143- then (assetId != BULL)
144- else false)
145- then errorMessage(assetId)
146- else {
147- let attachedAmount = value(inv.payment).amount
148- let col = if ((assetId == BEAR))
149- then bearCol
150- else bullCol
151- let circ = if ((assetId == BEAR))
152- then bearCirc
153- else bullCirc
154- let estimated = fraction(col, attachedAmount, circ)
155- if ((minRedeem > estimated))
156- 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)))
157- else unit
158- }
171+ let attachedAmount = inv.payments[0].amount
172+ let col = if ((assetId == BEAR))
173+ then bearCol
174+ else bullCol
175+ let circ = if ((assetId == BEAR))
176+ then bearCirc
177+ else bullCirc
178+ let estimated = fraction(col, attachedAmount, circ)
179+ if ((minRedeem > estimated))
180+ 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)))
181+ else unit
159182 }
160183 }
161184
162185
163186 func enqueue (id,action,amt,token,priceIndex,invoker) = {
164- let increaseQueueSize = DataEntry(queueSizeKey, (queueSize + 1))
187+ let increaseQueueSize = IntegerEntry(queueSizeKey, (queueSize + 1))
165188 let itm = buildNewItem(action, amt, token, priceIndex, invoker)
166189 if ((queueSize == 0))
167- then WriteSet([DataEntry(headPointerKey, id), DataEntry(tailPointerKey, id), DataEntry(id, itm), increaseQueueSize])
190+ then [StringEntry(headPointerKey, id), StringEntry(tailPointerKey, id), StringEntry(id, itm), increaseQueueSize]
168191 else {
169192 let prevId = valueOrErrorMessage(getString(this, tailPointerKey), "can't get tail pointer")
170193 let prevItm = split(valueOrErrorMessage(getString(this, prevId), "can't resolve pointer"), "|")
171194 let updatedPrevItm = ((((((((((prevItm[0] + "|") + prevItm[1]) + "|") + prevItm[2]) + "|") + prevItm[3]) + "|") + prevItm[4]) + "|") + id)
172- WriteSet([DataEntry(prevId, updatedPrevItm), DataEntry(id, itm), DataEntry(tailPointerKey, id), increaseQueueSize])
195+[StringEntry(prevId, updatedPrevItm), StringEntry(id, itm), StringEntry(tailPointerKey, id), increaseQueueSize]
173196 }
174197 }
198+
199+
200+func poolSupport (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0,curPoolMain0,curPoolUp0,curPoolDwn0) = {
201+ func closeUp (curBullCol,curBearCol,curBullCirc,curBearCirc,curPoolMain,curPoolUp,curPoolDwn) = {
202+ let diff = (curBullCol - curBearCol)
203+ let exposure = fraction(curBullCol, curPoolUp, curBullCirc)
204+ let liquidatedTokens = if ((diff > exposure))
205+ then curPoolUp
206+ else fraction(diff, curBullCirc, curBullCol)
207+ let liquidatedValue = if ((diff > exposure))
208+ then exposure
209+ else fraction(liquidatedTokens, curBullCol, curBullCirc)
210+ $Tuple7((curBullCol - liquidatedValue), curBearCol, (curBullCirc - liquidatedTokens), curBearCirc, (curPoolMain + liquidatedValue), (curPoolUp - liquidatedTokens), curPoolDwn)
211+ }
212+
213+ func closeDwn (curBullCol,curBearCol,curBullCirc,curBearCirc,curPoolMain,curPoolUp,curPoolDwn) = {
214+ let diff = (curBearCol - curBullCol)
215+ let exposure = fraction(curBearCol, curPoolDwn, curBearCirc)
216+ let liquidatedTokens = if ((diff > exposure))
217+ then curPoolDwn
218+ else fraction(diff, curBearCirc, curBearCol)
219+ let liquidatedValue = if ((diff > exposure))
220+ then exposure
221+ else fraction(liquidatedTokens, curBearCol, curBearCirc)
222+ $Tuple7(curBullCol, (curBearCol - liquidatedValue), curBullCirc, (curBearCirc - liquidatedTokens), (curPoolMain + liquidatedValue), curPoolUp, (curPoolDwn - liquidatedTokens))
223+ }
224+
225+ func openDwn (curBullCol,curBearCol,curBullCirc,curBearCirc,curPoolMain,curPoolUp,curPoolDwn) = {
226+ let diff = (curBullCol - curBearCol)
227+ let spentPoolValue = if ((curPoolMain > diff))
228+ then diff
229+ else curPoolMain
230+ let acquiredTokens = fraction(spentPoolValue, curBearCirc, curBearCol)
231+ $Tuple7(curBullCol, (curBearCol + spentPoolValue), curBullCirc, (curBearCirc + acquiredTokens), (curPoolMain - spentPoolValue), curPoolUp, (curPoolDwn + acquiredTokens))
232+ }
233+
234+ func openUp (curBullCol,curBearCol,curBullCirc,curBearCirc,curPoolMain,curPoolUp,curPoolDwn) = {
235+ let diff = (curBearCol - curBullCol)
236+ let spentPoolValue = if ((curPoolMain > diff))
237+ then diff
238+ else curPoolMain
239+ let acquiredTokens = fraction(spentPoolValue, curBullCirc, curBullCol)
240+ $Tuple7((curBullCol + spentPoolValue), curBearCol, (curBullCirc + acquiredTokens), curBearCirc, (curPoolMain - spentPoolValue), (curPoolUp + acquiredTokens), curPoolDwn)
241+ }
242+
243+ if ((curBullCol0 > curBearCol0))
244+ then {
245+ 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
254+ if ((f > 0))
255+ then afterCloseUp
256+ else if ((f == 0))
257+ then openDwn(a, b, c, d, e, f, g)
258+ else throw("poolUp < 0")
259+ }
260+ else {
261+ 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
270+ if ((g > 0))
271+ then afterCloseDwn
272+ else if ((g == 0))
273+ then openUp(a, b, c, d, e, f, g)
274+ else throw("poolDwn < 0")
275+ }
276+ }
277+
278+
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
289+[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)]
175292
176293
177294 func dequeue () = if ((queueSize == 0))
178295 then throw("nothing to settle")
179296 else {
180- func collectFee (fees) = DataEntry(feesAccumulatedKey, (feesAccumulated + fees))
297+ func collectFee (fees) = IntegerEntry(feesAccumulatedKey, (feesAccumulated + fees))
181298
182- let decreaseQueueSize = DataEntry(queueSizeKey, (queueSize - 1))
299+ let decreaseQueueSize = IntegerEntry(queueSizeKey, (queueSize - 1))
183300 let isLastElement = (headPointer == tailPointer)
184- let overwriteTail = DataEntry(tailPointerKey, "")
301+ let overwriteTail = StringEntry(tailPointerKey, "")
185302 let data = split(valueOrErrorMessage(getString(this, headPointer), "bad head pointer"), "|")
186303 let action = data[0]
187304 let amt = parseIntValue(data[1])
189306 let priceIndex = parseIntValue(data[3])
190307 let invoker = addressFromStringValue(data[4])
191308 let next = data[5]
192- if ((rebalancedPriceIndex > priceIndex))
309+ let items = if ((rebalancedPriceIndex > priceIndex))
193310 then throw(((("corrupt state, rebalancedPriceIndex=" + toString(rebalancedPriceIndex)) + ", request price id=") + toString(priceIndex)))
194311 else if ((priceIndex > rebalancedPriceIndex))
195312 then throw("can't dequeue, too early, rebalance first")
200317 if ((token == BULL))
201318 then {
202319 let addedToCirculation = fraction(bullCirc, addedCollateral, bullCol)
203- let items = [DataEntry(bullCollateralKey, (bullCol + addedCollateral)), DataEntry(bullCirculationKey, (bullCirc + addedToCirculation)), DataEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize]
204- ScriptResult(WriteSet(if (isLastElement)
205- then overwriteTail :: items
206- else items), TransferSet([ScriptTransfer(invoker, addedToCirculation, fromBase58String(BULL))]))
320+ (actionsWithMaybePool((bullCol + addedCollateral), bearCol, (bullCirc + addedToCirculation), bearCirc) ++ [StringEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize, ScriptTransfer(invoker, addedToCirculation, fromBase58String(BULL))])
207321 }
208322 else if ((token == BEAR))
209323 then {
210324 let addedToCirculation = fraction(bearCirc, addedCollateral, bearCol)
211- let items = [DataEntry(bearCollateralKey, (bearCol + addedCollateral)), DataEntry(bearCirculationKey, (bearCirc + addedToCirculation)), DataEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize]
212- ScriptResult(WriteSet(if (isLastElement)
213- then overwriteTail :: items
214- else items), TransferSet([ScriptTransfer(invoker, addedToCirculation, fromBase58String(BEAR))]))
325+ (actionsWithMaybePool(bullCol, (bearCol + addedCollateral), bullCirc, (bearCirc + addedToCirculation)) ++ [StringEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize, ScriptTransfer(invoker, addedToCirculation, fromBase58String(BEAR))])
215326 }
216327 else throw("bad token id")
217328 }
225336 let payout = if ((removedCollateral > feeSize))
226337 then (removedCollateral - feeSize)
227338 else 0
228- let items = [DataEntry(bullCollateralKey, (bullCol - removedCollateral)), DataEntry(bullCirculationKey, (bullCirc - removedTokens)), DataEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize]
229- ScriptResult(WriteSet(if (isLastElement)
230- then overwriteTail :: items
231- else items), TransferSet([ScriptTransfer(invoker, payout, fromBase58String(mainToken))]))
339+ (actionsWithMaybePool((bullCol - removedCollateral), bearCol, (bullCirc - removedTokens), bearCirc) ++ [StringEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize, ScriptTransfer(invoker, payout, fromBase58String(mainToken))])
232340 }
233341 else if ((token == BEAR))
234342 then {
237345 let payout = if ((removedCollateral > feeSize))
238346 then (removedCollateral - feeSize)
239347 else 0
240- let items = [DataEntry(bearCollateralKey, (bearCol - removedCollateral)), DataEntry(bearCirculationKey, (bearCirc - removedTokens)), DataEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize]
241- ScriptResult(WriteSet(if (isLastElement)
242- then overwriteTail :: items
243- else items), TransferSet([ScriptTransfer(invoker, payout, fromBase58String(mainToken))]))
348+ (actionsWithMaybePool(bullCol, (bearCol - removedCollateral), bullCirc, (bearCirc - removedTokens)) ++ [StringEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize, ScriptTransfer(invoker, payout, fromBase58String(mainToken))])
244349 }
245350 else throw("bad token id")
246351 }
247- else throw(("bad action: " + action))
352+ else if ((action == POOL))
353+ then {
354+ let issueTokens = fraction(poolTokenCirculation, amt, poolValue)
355+[IntegerEntry(poolMainTokenValueKey, (poolMain + amt)), IntegerEntry(poolTokenCirculationKey, (poolTokenCirculation + issueTokens)), StringEntry(headPointerKey, next), decreaseQueueSize, ScriptTransfer(invoker, issueTokens, fromBase58String(poolToken))]
356+ }
357+ else if ((action == UNPOOL))
358+ then {
359+ func share (a) = fraction(a, amt, poolTokenCirculation)
360+
361+ let unpooledMain = share(poolMain)
362+ let unpooledUp = share(poolUp)
363+ let unpooledDwn = share(poolDwn)
364+ let unpooledUpValue = fraction(unpooledUp, bullCol, bullCirc)
365+ let unpooledDwnValue = fraction(unpooledDwn, bearCol, bearCirc)
366+[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))]
367+ }
368+ else throw(("bad action: " + action))
369+ if (isLastElement)
370+ then overwriteTail :: items
371+ else items
248372 }
249373
250374
272396 then bullCol
273397 else bearCol
274398 let redist = LV(minVol, settledPrice, nextPrice)
275- if ((nextPrice > settledPrice))
276- then WriteSet([DataEntry(bullCollateralKey, (bullCol + redist)), DataEntry(bearCollateralKey, (bearCol - redist)), DataEntry(lastRebalancePriceIndexKey, unsettledPriceIndex)])
277- else if ((settledPrice > nextPrice))
278- then WriteSet([DataEntry(bullCollateralKey, (bullCol - redist)), DataEntry(bearCollateralKey, (bearCol + redist)), DataEntry(lastRebalancePriceIndexKey, unsettledPriceIndex)])
279- else WriteSet([DataEntry(lastRebalancePriceIndexKey, unsettledPriceIndex)])
399+ let newBullCol = if ((nextPrice > settledPrice))
400+ then (bullCol + redist)
401+ else (bullCol - redist)
402+ let newBearCol = if ((nextPrice > settledPrice))
403+ then (bearCol - redist)
404+ 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
415+[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)]
280418 }
281419
282420
283421 @Callable(inv)
284422 func init (bullId,bearId,mainTokenId,oraclePK,whitelisted) = if (isDefined(getString(this, BULLKey)))
285423 then throw("already initialized")
286- else if (!(isDefined(inv.payment)))
287- then throw("neutrino payment required")
288- else if ((toBase58String(valueOrErrorMessage(value(inv.payment).assetId, "neutrino payment required")) != mainTokenId))
289- then throw("payment not in neutrino")
290- else {
291- let totalOwnedMainToken = value(inv.payment).amount
292- let bulls = (totalOwnedMainToken / 2)
293- let bears = (totalOwnedMainToken - bulls)
294- if (if ((bears == 0))
295- then true
296- else (bulls == 0))
297- then throw("can't init balances")
298- else {
299- let oracleCurrentPriceIndex = valueOrErrorMessage(getInteger(valueOrErrorMessage(addressFromPublicKey(fromBase58String(oraclePK)), "bad oracle address"), lastPriceIndexKey), "can't find last oracle price index")
300- ScriptResult(WriteSet([DataEntry(BULLKey, bullId), DataEntry(BEARKey, bearId), DataEntry(mainTokenKey, mainTokenId), DataEntry(oraclePKKey, oraclePK), DataEntry(bullCollateralKey, bulls), DataEntry(bearCollateralKey, bears), DataEntry(bullCirculationKey, bulls), DataEntry(bearCirculationKey, bears), DataEntry(lastRebalancePriceIndexKey, oracleCurrentPriceIndex), DataEntry(whitelistKey, whitelisted), DataEntry(issuePercentileKey, 0), DataEntry(redeemPercentileKey, 0), DataEntry(minIssueKey, 0), DataEntry(minRedeemKey, 0), DataEntry(whitelistOnlyKey, true)]), TransferSet([ScriptTransfer(inv.caller, bulls, fromBase58String(bullId)), ScriptTransfer(inv.caller, bears, fromBase58String(bearId))]))
301- }
302- }
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+ }
303439
304440
305441
306442 @Callable(i)
307-func setParams (iP,rP,mI,mR,wl) = if ((i.caller != this))
443+func setParams (iP,rP,mI,mR,mP,wl) = if ((i.caller != this))
308444 then throw("only self can change whitelist")
309- else WriteSet([DataEntry(issuePercentileKey, iP), DataEntry(redeemPercentileKey, rP), DataEntry(minIssueKey, mI), DataEntry(minRedeemKey, mR), DataEntry(whitelistOnlyKey, wl)])
445+ else [IntegerEntry(issuePercentileKey, iP), IntegerEntry(redeemPercentileKey, rP), IntegerEntry(minIssueKey, mI), IntegerEntry(minRedeemKey, mR), IntegerEntry(minPoolKey, mP), BooleanEntry(whitelistOnlyKey, wl)]
310446
311447
312448
313449 @Callable(i)
314450 func setWhitelist (l) = if ((i.caller != this))
315451 then throw("only self can change whitelist")
316- else WriteSet([DataEntry(whitelistKey, l)])
452+ else [StringEntry(whitelistKey, l)]
317453
318454
319455
320456 @Callable(i)
321457 func setAddresses (feeAddr,stakingAddr,daemonPK) = if ((i.caller != this))
322458 then throw("only self can change feeAcc addresses")
323- else WriteSet([DataEntry(feeAddrKey, feeAddr), DataEntry(stakingAddrKey, stakingAddr), DataEntry(daemonPubKeyKey, daemonPK)])
459+ else [StringEntry(feeAddrKey, feeAddr), StringEntry(stakingAddrKey, stakingAddr), StringEntry(daemonPubKeyKey, daemonPK)]
324460
325461
326462
327463 @Callable(i)
328464 func withdrawFee (amount) = if ((amount > feesAccumulated))
329465 then throw(("too much. available: " + toString(feesAccumulated)))
330- else ScriptResult(WriteSet([DataEntry(feesAccumulatedKey, (feesAccumulated - amount))]), TransferSet([ScriptTransfer(feeAddress, amount, fromBase58String(mainToken))]))
466+ else [IntegerEntry(feesAccumulatedKey, (feesAccumulated - amount)), ScriptTransfer(feeAddress, amount, fromBase58String(mainToken))]
331467
332468
333469
334470 @Callable(inv)
335-func requestRedeem () = if ((validateEnqueue(inv) == unit))
471+func requestRedeem () = if ((validateRequestRedeem(inv) == unit))
336472 then {
337- let assetId = toBase58String(valueOrErrorMessage(value(inv.payment).assetId, "waves are not accepted here"))
338- enqueue(toBase58String(inv.transactionId), REDEEM, value(inv.payment).amount, assetId, (oraclePriceIndex + 1), toString(inv.caller))
473+ let assetId = toBase58String(valueOrErrorMessage(inv.payments[0].assetId, "waves are not accepted here"))
474+ enqueue(toBase58String(inv.transactionId), REDEEM, inv.payments[0].amount, assetId, (oraclePriceIndex + 1), toString(inv.caller))
339475 }
340476 else throw("doesn't happen")
341477
354490 then (tokenId != BEAR)
355491 else false)
356492 then errorMessage
357- else if (!(isDefined(inv.payment)))
493+ else if ((inv.payments[0].assetId != fromBase58String(mainToken)))
358494 then errorMessage
359- else if ((value(inv.payment).assetId != fromBase58String(mainToken)))
360- then errorMessage
361- else if ((minIssue > value(inv.payment).amount))
362- then throw((("Attached payment too small. Min required: " + toString((minIssue / 1000000))) + " USDN"))
363- else enqueue(toBase58String(inv.transactionId), ISSUE, value(inv.payment).amount, tokenId, (oraclePriceIndex + 1), toString(inv.caller))
495+ else if ((minIssue > inv.payments[0].amount))
496+ 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))
364498 }
365499
366500
387521 }
388522
389523
524+
525+@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")
537+ else {
538+ let errMessage = (("please attach 10.000000 main tokens(" + mainToken) + ")")
539+ let pmt = inv.payments[0]
540+ if ((pmt.amount != (10 * ten6)))
541+ 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))]
545+ }
546+
547+
548+
549+@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")
556+ 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))
564+ }
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+ }
583+
584+
390585 @Verifier(tx)
391586 func verify () = {
392587 let adminAction = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
407602 let lock = if (if ((tx.function == "lockNeutrinoSP"))
408603 then (tx.args[0] == stakingAddress)
409604 else false)
410- then (wavesBalance(this) >= ((100 * 1000) * 1000))
605+ then (wavesBalance(this).available >= ten8)
411606 else false
412607 let funcCorrect = if (lock)
413608 then true
Full:
OldNewDifferences
1-{-# STDLIB_VERSION 3 #-}
1+{-# STDLIB_VERSION 4 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4+let ten6 = 1000000
5+
6+let ten8 = 100000000
7+
48 let BULLKey = "BULLId"
59
610 let BEARKey = "BEARId"
711
812 let mainTokenKey = "mainTokenId"
13+
14+let bullCollateralKey = "bullCollateral"
15+
16+let bearCollateralKey = "bearCollateral"
17+
18+let bullCirculationKey = "bullCirculation"
19+
20+let bearCirculationKey = "bearCirculation"
921
1022 let issuePercentileKey = "issuePercentile"
1123
1224 let redeemPercentileKey = "redeemPercentile"
1325
1426 let minIssueKey = "minIssue"
1527
1628 let minRedeemKey = "minRedeem"
1729
30+let minPoolKey = "minPool"
31+
32+let feesAccumulatedKey = "feesAccumulated"
33+
1834 let whitelistOnlyKey = "whitelistOnly"
35+
36+let whitelistKey = "issueWhiteList"
1937
2038 let oraclePKKey = "oracle"
2139
2240 let lastPriceIndexKey = "price_index"
2341
2442 let priceIndexPrefix = "price_index_"
2543
2644 let priceHeightPrefix = "price_"
2745
2846 let oracleCurrentPriceIndexKey = "price_index"
2947
3048 let lastRebalancePriceIndexKey = "lastSettlementPriceId"
3149
32-let bullCollateralKey = "bullCollateral"
50+let headPointerKey = "headPointer"
3351
34-let bearCollateralKey = "bearCollateral"
52+let tailPointerKey = "tailPointer"
3553
36-let bullCirculationKey = "bullCirculation"
54+let queueSizeKey = "queueSize"
3755
38-let bearCirculationKey = "bearCirculation"
56+let poolMainTokenValueKey = "poolMainTokenValue"
3957
40-let whitelistKey = "issueWhiteList"
58+let poolUpKey = "poolUp"
4159
42-let whitelist = valueOrErrorMessage(getString(this, whitelistKey), "no bullCollateralKey")
60+let poolDwnKey = "poolDwn"
61+
62+let poolEnabledKey = "poolEnabled"
63+
64+let poolTokenCirculationKey = "poolTokenCirculation"
65+
66+let poolTokenKey = "poolToken"
4367
4468 let bullCol = valueOrErrorMessage(getInteger(this, bullCollateralKey), "no bullCollateralKey")
4569
4670 let bearCol = valueOrErrorMessage(getInteger(this, bearCollateralKey), "no bearCollateralKey")
4771
4872 let bullCirc = valueOrErrorMessage(getInteger(this, bullCirculationKey), "no bullCirculationKey")
4973
5074 let bearCirc = valueOrErrorMessage(getInteger(this, bearCirculationKey), "no bearCirculationKey")
5175
5276 let BULL = valueOrErrorMessage(getString(this, BULLKey), "no BULLKey")
5377
5478 let BEAR = valueOrErrorMessage(getString(this, BEARKey), "no BEARKey")
5579
5680 let mainToken = valueOrErrorMessage(getString(this, mainTokenKey), "no mainTokenKey")
5781
5882 let issuePercentile = valueOrErrorMessage(getInteger(this, issuePercentileKey), "no issuePercentileKey")
5983
6084 let redeemPercentile = valueOrErrorMessage(getInteger(this, redeemPercentileKey), "no redeemPercentileKey")
6185
6286 let minIssue = valueOrErrorMessage(getInteger(this, minIssueKey), "no minIssueKey")
6387
6488 let minRedeem = valueOrErrorMessage(getInteger(this, minRedeemKey), "no minRedeemKey")
6589
90+let minPool = valueOrErrorMessage(getInteger(this, minPoolKey), "no minPoolKey")
91+
6692 let whitelistOnly = valueOrErrorMessage(getBoolean(this, whitelistOnlyKey), "no whitelistOnlyKey")
93+
94+let whitelist = valueOrErrorMessage(getString(this, whitelistKey), "no bullCollateralKey")
95+
96+let poolInitialized = isDefined(getBoolean(this, poolMainTokenValueKey))
97+
98+let poolEnabled = (getBoolean(this, poolEnabledKey) == true)
99+
100+let poolMain = valueOrErrorMessage(getInteger(this, poolMainTokenValueKey), "no poolMainTokenValueKey")
101+
102+let poolUp = valueOrErrorMessage(getInteger(this, poolUpKey), "no poolUpKey")
103+
104+let poolDwn = valueOrErrorMessage(getInteger(this, poolDwnKey), "no poolDwnKey")
105+
106+let poolToken = valueOrErrorMessage(getString(this, poolTokenKey), "no poolTokenKey")
107+
108+let poolTokenCirculation = valueOrErrorMessage(getInteger(this, poolTokenCirculationKey), "no poolTokenCirculationKey")
109+
110+let poolValue = ((poolMain + fraction(bullCol, poolUp, bullCirc)) + fraction(bearCol, poolDwn, bearCirc))
67111
68112 let oracle = valueOrErrorMessage(addressFromPublicKey(fromBase58String(valueOrErrorMessage(getString(this, oraclePKKey), "no oraclePKKey"))), "bad oracle address")
69113
70114 let rebalancedPriceIndex = valueOrErrorMessage(getInteger(this, lastRebalancePriceIndexKey), "no last rebalance price")
71115
72116 let oraclePriceIndex = valueOrErrorMessage(getInteger(oracle, lastPriceIndexKey), ((("bad oracle data at " + toString(oracle)) + ": no integer at ") + lastPriceIndexKey))
73117
74-let headPointerKey = "headPointer"
118+let queueSize = valueOrElse(getInteger(this, queueSizeKey), 0)
75119
76-let tailPointerKey = "tailPointer"
120+let headPointer = valueOrElse(getString(this, headPointerKey), "")
77121
78-let queueSizeKey = "queueSize"
122+let tailPointer = valueOrElse(getString(this, tailPointerKey), "")
79123
80-let queueSize = match getInteger(this, queueSizeKey) {
81- case i: Int =>
82- i
83- case _ =>
84- 0
85-}
86-
87-let headPointer = match getString(this, headPointerKey) {
88- case s: String =>
89- s
90- case _ =>
91- ""
92-}
93-
94-let tailPointer = match getString(this, tailPointerKey) {
95- case s: String =>
96- s
97- case _ =>
98- ""
99-}
100-
101-let feesAccumulatedKey = "feesAccumulated"
102-
103-let feesAccumulated = match getInteger(this, feesAccumulatedKey) {
104- case i: Int =>
105- i
106- case _ =>
107- 0
108-}
124+let feesAccumulated = valueOrElse(getInteger(this, feesAccumulatedKey), 0)
109125
110126 let ISSUE = "ISSUE"
111127
112128 let REDEEM = "REDEEM"
129+
130+let POOL = "POOL"
131+
132+let UNPOOL = "UNPOOL"
113133
114134 let feeAddrKey = "feeAddress"
115135
116136 let stakingAddrKey = "stakingAddress"
117137
118138 let daemonPubKeyKey = "daemonPublicKey"
119139
120140 let feeAddress = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(this, feeAddrKey), "no feeAddress")), "bad feeAddress")
121141
122142 let stakingAddress = valueOrErrorMessage(getString(this, stakingAddrKey), "no stakingAddress")
123143
124144 let daemonPublicKey = fromBase58String(valueOrErrorMessage(getString(this, daemonPubKeyKey), "no daemonPublicKey"))
125145
126146 let rpdAddress = addressFromString("3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ")
127147
128148 let pubKeyAdminsList = ["2HHqV8W9DJayV5R6tBD2Sb8srphpoboDi7r1t1aPiumC", "5ZXe82RRASU7qshXM2J9JNYhqJ9GWYjjVq2gwUV5Naz9", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"]
129149
150+func safeFraction (a,b,c) = if (if ((a == 0))
151+ then true
152+ else (b == 0))
153+ then 0
154+ else fraction(a, b, c)
155+
156+
130157 func buildNewItem (action,amt,token,priceIndex,invoker) = (((((((((action + "|") + toString(amt)) + "|") + token) + "|") + toString(priceIndex)) + "|") + invoker) + "|")
131158
132159
133-func validateEnqueue (inv) = if ((inv.caller == this))
160+func validateRequestRedeem (inv) = if ((inv.caller == this))
134161 then throw("can't do")
135162 else {
136163 func errorMessage (got) = throw(((((("only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") tokens are accepted, received: ") + got))
137164
138- if (!(isDefined(inv.payment)))
139- then errorMessage("no attached payment")
165+ let assetId = toBase58String(valueOrErrorMessage(value(inv.payments[0]).assetId, "waves are not accepted here"))
166+ if (if ((assetId != BEAR))
167+ then (assetId != BULL)
168+ else false)
169+ then errorMessage(assetId)
140170 else {
141- let assetId = toBase58String(valueOrErrorMessage(value(inv.payment).assetId, "waves are not accepted here"))
142- if (if ((assetId != BEAR))
143- then (assetId != BULL)
144- else false)
145- then errorMessage(assetId)
146- else {
147- let attachedAmount = value(inv.payment).amount
148- let col = if ((assetId == BEAR))
149- then bearCol
150- else bullCol
151- let circ = if ((assetId == BEAR))
152- then bearCirc
153- else bullCirc
154- let estimated = fraction(col, attachedAmount, circ)
155- if ((minRedeem > estimated))
156- 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)))
157- else unit
158- }
171+ let attachedAmount = inv.payments[0].amount
172+ let col = if ((assetId == BEAR))
173+ then bearCol
174+ else bullCol
175+ let circ = if ((assetId == BEAR))
176+ then bearCirc
177+ else bullCirc
178+ let estimated = fraction(col, attachedAmount, circ)
179+ if ((minRedeem > estimated))
180+ 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)))
181+ else unit
159182 }
160183 }
161184
162185
163186 func enqueue (id,action,amt,token,priceIndex,invoker) = {
164- let increaseQueueSize = DataEntry(queueSizeKey, (queueSize + 1))
187+ let increaseQueueSize = IntegerEntry(queueSizeKey, (queueSize + 1))
165188 let itm = buildNewItem(action, amt, token, priceIndex, invoker)
166189 if ((queueSize == 0))
167- then WriteSet([DataEntry(headPointerKey, id), DataEntry(tailPointerKey, id), DataEntry(id, itm), increaseQueueSize])
190+ then [StringEntry(headPointerKey, id), StringEntry(tailPointerKey, id), StringEntry(id, itm), increaseQueueSize]
168191 else {
169192 let prevId = valueOrErrorMessage(getString(this, tailPointerKey), "can't get tail pointer")
170193 let prevItm = split(valueOrErrorMessage(getString(this, prevId), "can't resolve pointer"), "|")
171194 let updatedPrevItm = ((((((((((prevItm[0] + "|") + prevItm[1]) + "|") + prevItm[2]) + "|") + prevItm[3]) + "|") + prevItm[4]) + "|") + id)
172- WriteSet([DataEntry(prevId, updatedPrevItm), DataEntry(id, itm), DataEntry(tailPointerKey, id), increaseQueueSize])
195+[StringEntry(prevId, updatedPrevItm), StringEntry(id, itm), StringEntry(tailPointerKey, id), increaseQueueSize]
173196 }
174197 }
198+
199+
200+func poolSupport (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0,curPoolMain0,curPoolUp0,curPoolDwn0) = {
201+ func closeUp (curBullCol,curBearCol,curBullCirc,curBearCirc,curPoolMain,curPoolUp,curPoolDwn) = {
202+ let diff = (curBullCol - curBearCol)
203+ let exposure = fraction(curBullCol, curPoolUp, curBullCirc)
204+ let liquidatedTokens = if ((diff > exposure))
205+ then curPoolUp
206+ else fraction(diff, curBullCirc, curBullCol)
207+ let liquidatedValue = if ((diff > exposure))
208+ then exposure
209+ else fraction(liquidatedTokens, curBullCol, curBullCirc)
210+ $Tuple7((curBullCol - liquidatedValue), curBearCol, (curBullCirc - liquidatedTokens), curBearCirc, (curPoolMain + liquidatedValue), (curPoolUp - liquidatedTokens), curPoolDwn)
211+ }
212+
213+ func closeDwn (curBullCol,curBearCol,curBullCirc,curBearCirc,curPoolMain,curPoolUp,curPoolDwn) = {
214+ let diff = (curBearCol - curBullCol)
215+ let exposure = fraction(curBearCol, curPoolDwn, curBearCirc)
216+ let liquidatedTokens = if ((diff > exposure))
217+ then curPoolDwn
218+ else fraction(diff, curBearCirc, curBearCol)
219+ let liquidatedValue = if ((diff > exposure))
220+ then exposure
221+ else fraction(liquidatedTokens, curBearCol, curBearCirc)
222+ $Tuple7(curBullCol, (curBearCol - liquidatedValue), curBullCirc, (curBearCirc - liquidatedTokens), (curPoolMain + liquidatedValue), curPoolUp, (curPoolDwn - liquidatedTokens))
223+ }
224+
225+ func openDwn (curBullCol,curBearCol,curBullCirc,curBearCirc,curPoolMain,curPoolUp,curPoolDwn) = {
226+ let diff = (curBullCol - curBearCol)
227+ let spentPoolValue = if ((curPoolMain > diff))
228+ then diff
229+ else curPoolMain
230+ let acquiredTokens = fraction(spentPoolValue, curBearCirc, curBearCol)
231+ $Tuple7(curBullCol, (curBearCol + spentPoolValue), curBullCirc, (curBearCirc + acquiredTokens), (curPoolMain - spentPoolValue), curPoolUp, (curPoolDwn + acquiredTokens))
232+ }
233+
234+ func openUp (curBullCol,curBearCol,curBullCirc,curBearCirc,curPoolMain,curPoolUp,curPoolDwn) = {
235+ let diff = (curBearCol - curBullCol)
236+ let spentPoolValue = if ((curPoolMain > diff))
237+ then diff
238+ else curPoolMain
239+ let acquiredTokens = fraction(spentPoolValue, curBullCirc, curBullCol)
240+ $Tuple7((curBullCol + spentPoolValue), curBearCol, (curBullCirc + acquiredTokens), curBearCirc, (curPoolMain - spentPoolValue), (curPoolUp + acquiredTokens), curPoolDwn)
241+ }
242+
243+ if ((curBullCol0 > curBearCol0))
244+ then {
245+ 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
254+ if ((f > 0))
255+ then afterCloseUp
256+ else if ((f == 0))
257+ then openDwn(a, b, c, d, e, f, g)
258+ else throw("poolUp < 0")
259+ }
260+ else {
261+ 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
270+ if ((g > 0))
271+ then afterCloseDwn
272+ else if ((g == 0))
273+ then openUp(a, b, c, d, e, f, g)
274+ else throw("poolDwn < 0")
275+ }
276+ }
277+
278+
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
289+[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)]
175292
176293
177294 func dequeue () = if ((queueSize == 0))
178295 then throw("nothing to settle")
179296 else {
180- func collectFee (fees) = DataEntry(feesAccumulatedKey, (feesAccumulated + fees))
297+ func collectFee (fees) = IntegerEntry(feesAccumulatedKey, (feesAccumulated + fees))
181298
182- let decreaseQueueSize = DataEntry(queueSizeKey, (queueSize - 1))
299+ let decreaseQueueSize = IntegerEntry(queueSizeKey, (queueSize - 1))
183300 let isLastElement = (headPointer == tailPointer)
184- let overwriteTail = DataEntry(tailPointerKey, "")
301+ let overwriteTail = StringEntry(tailPointerKey, "")
185302 let data = split(valueOrErrorMessage(getString(this, headPointer), "bad head pointer"), "|")
186303 let action = data[0]
187304 let amt = parseIntValue(data[1])
188305 let token = data[2]
189306 let priceIndex = parseIntValue(data[3])
190307 let invoker = addressFromStringValue(data[4])
191308 let next = data[5]
192- if ((rebalancedPriceIndex > priceIndex))
309+ let items = if ((rebalancedPriceIndex > priceIndex))
193310 then throw(((("corrupt state, rebalancedPriceIndex=" + toString(rebalancedPriceIndex)) + ", request price id=") + toString(priceIndex)))
194311 else if ((priceIndex > rebalancedPriceIndex))
195312 then throw("can't dequeue, too early, rebalance first")
196313 else if ((action == ISSUE))
197314 then {
198315 let feeSize = fraction(amt, issuePercentile, 10000)
199316 let addedCollateral = (amt - feeSize)
200317 if ((token == BULL))
201318 then {
202319 let addedToCirculation = fraction(bullCirc, addedCollateral, bullCol)
203- let items = [DataEntry(bullCollateralKey, (bullCol + addedCollateral)), DataEntry(bullCirculationKey, (bullCirc + addedToCirculation)), DataEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize]
204- ScriptResult(WriteSet(if (isLastElement)
205- then overwriteTail :: items
206- else items), TransferSet([ScriptTransfer(invoker, addedToCirculation, fromBase58String(BULL))]))
320+ (actionsWithMaybePool((bullCol + addedCollateral), bearCol, (bullCirc + addedToCirculation), bearCirc) ++ [StringEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize, ScriptTransfer(invoker, addedToCirculation, fromBase58String(BULL))])
207321 }
208322 else if ((token == BEAR))
209323 then {
210324 let addedToCirculation = fraction(bearCirc, addedCollateral, bearCol)
211- let items = [DataEntry(bearCollateralKey, (bearCol + addedCollateral)), DataEntry(bearCirculationKey, (bearCirc + addedToCirculation)), DataEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize]
212- ScriptResult(WriteSet(if (isLastElement)
213- then overwriteTail :: items
214- else items), TransferSet([ScriptTransfer(invoker, addedToCirculation, fromBase58String(BEAR))]))
325+ (actionsWithMaybePool(bullCol, (bearCol + addedCollateral), bullCirc, (bearCirc + addedToCirculation)) ++ [StringEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize, ScriptTransfer(invoker, addedToCirculation, fromBase58String(BEAR))])
215326 }
216327 else throw("bad token id")
217328 }
218329 else if ((action == REDEEM))
219330 then {
220331 let removedTokens = amt
221332 if ((token == BULL))
222333 then {
223334 let removedCollateral = fraction(bullCol, removedTokens, bullCirc)
224335 let feeSize = fraction(removedCollateral, redeemPercentile, 10000)
225336 let payout = if ((removedCollateral > feeSize))
226337 then (removedCollateral - feeSize)
227338 else 0
228- let items = [DataEntry(bullCollateralKey, (bullCol - removedCollateral)), DataEntry(bullCirculationKey, (bullCirc - removedTokens)), DataEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize]
229- ScriptResult(WriteSet(if (isLastElement)
230- then overwriteTail :: items
231- else items), TransferSet([ScriptTransfer(invoker, payout, fromBase58String(mainToken))]))
339+ (actionsWithMaybePool((bullCol - removedCollateral), bearCol, (bullCirc - removedTokens), bearCirc) ++ [StringEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize, ScriptTransfer(invoker, payout, fromBase58String(mainToken))])
232340 }
233341 else if ((token == BEAR))
234342 then {
235343 let removedCollateral = fraction(bearCol, removedTokens, bearCirc)
236344 let feeSize = fraction(removedCollateral, redeemPercentile, 10000)
237345 let payout = if ((removedCollateral > feeSize))
238346 then (removedCollateral - feeSize)
239347 else 0
240- let items = [DataEntry(bearCollateralKey, (bearCol - removedCollateral)), DataEntry(bearCirculationKey, (bearCirc - removedTokens)), DataEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize]
241- ScriptResult(WriteSet(if (isLastElement)
242- then overwriteTail :: items
243- else items), TransferSet([ScriptTransfer(invoker, payout, fromBase58String(mainToken))]))
348+ (actionsWithMaybePool(bullCol, (bearCol - removedCollateral), bullCirc, (bearCirc - removedTokens)) ++ [StringEntry(headPointerKey, next), collectFee(feeSize), decreaseQueueSize, ScriptTransfer(invoker, payout, fromBase58String(mainToken))])
244349 }
245350 else throw("bad token id")
246351 }
247- else throw(("bad action: " + action))
352+ else if ((action == POOL))
353+ then {
354+ let issueTokens = fraction(poolTokenCirculation, amt, poolValue)
355+[IntegerEntry(poolMainTokenValueKey, (poolMain + amt)), IntegerEntry(poolTokenCirculationKey, (poolTokenCirculation + issueTokens)), StringEntry(headPointerKey, next), decreaseQueueSize, ScriptTransfer(invoker, issueTokens, fromBase58String(poolToken))]
356+ }
357+ else if ((action == UNPOOL))
358+ then {
359+ func share (a) = fraction(a, amt, poolTokenCirculation)
360+
361+ let unpooledMain = share(poolMain)
362+ let unpooledUp = share(poolUp)
363+ let unpooledDwn = share(poolDwn)
364+ let unpooledUpValue = fraction(unpooledUp, bullCol, bullCirc)
365+ let unpooledDwnValue = fraction(unpooledDwn, bearCol, bearCirc)
366+[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))]
367+ }
368+ else throw(("bad action: " + action))
369+ if (isLastElement)
370+ then overwriteTail :: items
371+ else items
248372 }
249373
250374
251375 func rebalance () = {
252376 func LV (v,p0,p1) = {
253377 let denom = 100
254378 let pmax = ((if ((p1 > p0))
255379 then p1
256380 else p0) / denom)
257381 let pmin = ((if ((p0 > p1))
258382 then p1
259383 else p0) / denom)
260384 let a = (pmin * pmin)
261385 let b = (((9 * pmax) * pmax) - ((15 * pmax) * pmin))
262386 fraction(v, ((6 * a) + b), ((7 * a) + b))
263387 }
264388
265389 let settledPriceIndex = valueOrErrorMessage(getInteger(this, lastRebalancePriceIndexKey), "inconsistent data")
266390 let unsettledPriceIndex = (settledPriceIndex + 1)
267391 let settledPriceHeight = valueOrErrorMessage(getInteger(oracle, ("price_index_" + toString(settledPriceIndex))), "bad oracle data for settled price height")
268392 let settledPrice = valueOrErrorMessage(getInteger(oracle, ("price_" + toString(settledPriceHeight))), "bad oracle data for price")
269393 let nextPriceHeight = valueOrErrorMessage(getInteger(oracle, ("price_index_" + toString(unsettledPriceIndex))), "no next price height")
270394 let nextPrice = valueOrErrorMessage(getInteger(oracle, ("price_" + toString(nextPriceHeight))), "no next price")
271395 let minVol = if ((bearCol > bullCol))
272396 then bullCol
273397 else bearCol
274398 let redist = LV(minVol, settledPrice, nextPrice)
275- if ((nextPrice > settledPrice))
276- then WriteSet([DataEntry(bullCollateralKey, (bullCol + redist)), DataEntry(bearCollateralKey, (bearCol - redist)), DataEntry(lastRebalancePriceIndexKey, unsettledPriceIndex)])
277- else if ((settledPrice > nextPrice))
278- then WriteSet([DataEntry(bullCollateralKey, (bullCol - redist)), DataEntry(bearCollateralKey, (bearCol + redist)), DataEntry(lastRebalancePriceIndexKey, unsettledPriceIndex)])
279- else WriteSet([DataEntry(lastRebalancePriceIndexKey, unsettledPriceIndex)])
399+ let newBullCol = if ((nextPrice > settledPrice))
400+ then (bullCol + redist)
401+ else (bullCol - redist)
402+ let newBearCol = if ((nextPrice > settledPrice))
403+ then (bearCol - redist)
404+ 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
415+[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)]
280418 }
281419
282420
283421 @Callable(inv)
284422 func init (bullId,bearId,mainTokenId,oraclePK,whitelisted) = if (isDefined(getString(this, BULLKey)))
285423 then throw("already initialized")
286- else if (!(isDefined(inv.payment)))
287- then throw("neutrino payment required")
288- else if ((toBase58String(valueOrErrorMessage(value(inv.payment).assetId, "neutrino payment required")) != mainTokenId))
289- then throw("payment not in neutrino")
290- else {
291- let totalOwnedMainToken = value(inv.payment).amount
292- let bulls = (totalOwnedMainToken / 2)
293- let bears = (totalOwnedMainToken - bulls)
294- if (if ((bears == 0))
295- then true
296- else (bulls == 0))
297- then throw("can't init balances")
298- else {
299- let oracleCurrentPriceIndex = valueOrErrorMessage(getInteger(valueOrErrorMessage(addressFromPublicKey(fromBase58String(oraclePK)), "bad oracle address"), lastPriceIndexKey), "can't find last oracle price index")
300- ScriptResult(WriteSet([DataEntry(BULLKey, bullId), DataEntry(BEARKey, bearId), DataEntry(mainTokenKey, mainTokenId), DataEntry(oraclePKKey, oraclePK), DataEntry(bullCollateralKey, bulls), DataEntry(bearCollateralKey, bears), DataEntry(bullCirculationKey, bulls), DataEntry(bearCirculationKey, bears), DataEntry(lastRebalancePriceIndexKey, oracleCurrentPriceIndex), DataEntry(whitelistKey, whitelisted), DataEntry(issuePercentileKey, 0), DataEntry(redeemPercentileKey, 0), DataEntry(minIssueKey, 0), DataEntry(minRedeemKey, 0), DataEntry(whitelistOnlyKey, true)]), TransferSet([ScriptTransfer(inv.caller, bulls, fromBase58String(bullId)), ScriptTransfer(inv.caller, bears, fromBase58String(bearId))]))
301- }
302- }
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+ }
303439
304440
305441
306442 @Callable(i)
307-func setParams (iP,rP,mI,mR,wl) = if ((i.caller != this))
443+func setParams (iP,rP,mI,mR,mP,wl) = if ((i.caller != this))
308444 then throw("only self can change whitelist")
309- else WriteSet([DataEntry(issuePercentileKey, iP), DataEntry(redeemPercentileKey, rP), DataEntry(minIssueKey, mI), DataEntry(minRedeemKey, mR), DataEntry(whitelistOnlyKey, wl)])
445+ else [IntegerEntry(issuePercentileKey, iP), IntegerEntry(redeemPercentileKey, rP), IntegerEntry(minIssueKey, mI), IntegerEntry(minRedeemKey, mR), IntegerEntry(minPoolKey, mP), BooleanEntry(whitelistOnlyKey, wl)]
310446
311447
312448
313449 @Callable(i)
314450 func setWhitelist (l) = if ((i.caller != this))
315451 then throw("only self can change whitelist")
316- else WriteSet([DataEntry(whitelistKey, l)])
452+ else [StringEntry(whitelistKey, l)]
317453
318454
319455
320456 @Callable(i)
321457 func setAddresses (feeAddr,stakingAddr,daemonPK) = if ((i.caller != this))
322458 then throw("only self can change feeAcc addresses")
323- else WriteSet([DataEntry(feeAddrKey, feeAddr), DataEntry(stakingAddrKey, stakingAddr), DataEntry(daemonPubKeyKey, daemonPK)])
459+ else [StringEntry(feeAddrKey, feeAddr), StringEntry(stakingAddrKey, stakingAddr), StringEntry(daemonPubKeyKey, daemonPK)]
324460
325461
326462
327463 @Callable(i)
328464 func withdrawFee (amount) = if ((amount > feesAccumulated))
329465 then throw(("too much. available: " + toString(feesAccumulated)))
330- else ScriptResult(WriteSet([DataEntry(feesAccumulatedKey, (feesAccumulated - amount))]), TransferSet([ScriptTransfer(feeAddress, amount, fromBase58String(mainToken))]))
466+ else [IntegerEntry(feesAccumulatedKey, (feesAccumulated - amount)), ScriptTransfer(feeAddress, amount, fromBase58String(mainToken))]
331467
332468
333469
334470 @Callable(inv)
335-func requestRedeem () = if ((validateEnqueue(inv) == unit))
471+func requestRedeem () = if ((validateRequestRedeem(inv) == unit))
336472 then {
337- let assetId = toBase58String(valueOrErrorMessage(value(inv.payment).assetId, "waves are not accepted here"))
338- enqueue(toBase58String(inv.transactionId), REDEEM, value(inv.payment).amount, assetId, (oraclePriceIndex + 1), toString(inv.caller))
473+ let assetId = toBase58String(valueOrErrorMessage(inv.payments[0].assetId, "waves are not accepted here"))
474+ enqueue(toBase58String(inv.transactionId), REDEEM, inv.payments[0].amount, assetId, (oraclePriceIndex + 1), toString(inv.caller))
339475 }
340476 else throw("doesn't happen")
341477
342478
343479
344480 @Callable(inv)
345481 func requestIssue (tokenId) = if ((inv.caller == this))
346482 then throw("can't do")
347483 else if (if (whitelistOnly)
348484 then !(isDefined(indexOf(whitelist, toString(inv.caller))))
349485 else false)
350486 then throw("only whitelisted can do")
351487 else {
352488 let errorMessage = throw((((((("only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") tokens are available in exchange for USDN(") + mainToken) + ")"))
353489 if (if ((tokenId != BULL))
354490 then (tokenId != BEAR)
355491 else false)
356492 then errorMessage
357- else if (!(isDefined(inv.payment)))
493+ else if ((inv.payments[0].assetId != fromBase58String(mainToken)))
358494 then errorMessage
359- else if ((value(inv.payment).assetId != fromBase58String(mainToken)))
360- then errorMessage
361- else if ((minIssue > value(inv.payment).amount))
362- then throw((("Attached payment too small. Min required: " + toString((minIssue / 1000000))) + " USDN"))
363- else enqueue(toBase58String(inv.transactionId), ISSUE, value(inv.payment).amount, tokenId, (oraclePriceIndex + 1), toString(inv.caller))
495+ else if ((minIssue > inv.payments[0].amount))
496+ 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))
364498 }
365499
366500
367501
368502 @Callable(inv)
369503 func settle () = {
370504 let queueEmpty = (headPointer == "")
371505 let canRebalance = (oraclePriceIndex > rebalancedPriceIndex)
372506 if (queueEmpty)
373507 then if (canRebalance)
374508 then rebalance()
375509 else throw("[OK] all done, carry on")
376510 else {
377511 let data = split(valueOrErrorMessage(getString(this, headPointer), "bad head pointer"), "|")
378512 let priceIndex = parseIntValue(data[3])
379513 if ((priceIndex > rebalancedPriceIndex))
380514 then if (canRebalance)
381515 then rebalance()
382516 else throw("[OK] need to wait")
383517 else if ((priceIndex == rebalancedPriceIndex))
384518 then dequeue()
385519 else throw("corrupt data, future price id already rebalanced")
386520 }
387521 }
388522
389523
524+
525+@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")
537+ else {
538+ let errMessage = (("please attach 10.000000 main tokens(" + mainToken) + ")")
539+ let pmt = inv.payments[0]
540+ if ((pmt.amount != (10 * ten6)))
541+ 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))]
545+ }
546+
547+
548+
549+@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")
556+ 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))
564+ }
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+ }
583+
584+
390585 @Verifier(tx)
391586 func verify () = {
392587 let adminAction = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(pubKeyAdminsList[0])))
393588 then 1
394589 else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(pubKeyAdminsList[1])))
395590 then 1
396591 else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(pubKeyAdminsList[2])))
397592 then 1
398593 else 0)) > 1)
399594 let stakingAction = match tx {
400595 case tx: InvokeScriptTransaction =>
401596 let signedCorrectly = sigVerify(tx.bodyBytes, tx.proofs[0], daemonPublicKey)
402597 let feesCorrect = if ((tx.feeAssetId == unit))
403598 then ((1000 * 1000) >= tx.fee)
404599 else false
405600 let dappCorrect = (tx.dApp == rpdAddress)
406601 let unlock = (tx.function == "unlockNeutrino")
407602 let lock = if (if ((tx.function == "lockNeutrinoSP"))
408603 then (tx.args[0] == stakingAddress)
409604 else false)
410- then (wavesBalance(this) >= ((100 * 1000) * 1000))
605+ then (wavesBalance(this).available >= ten8)
411606 else false
412607 let funcCorrect = if (lock)
413608 then true
414609 else unlock
415610 if (if (if (signedCorrectly)
416611 then feesCorrect
417612 else false)
418613 then dappCorrect
419614 else false)
420615 then funcCorrect
421616 else false
422617 case _ =>
423618 false
424619 }
425620 if (adminAction)
426621 then true
427622 else stakingAction
428623 }
429624

github/deemru/w8io/786bc32 
110.96 ms