tx · 7KYQJz6bNGU2KQkhS5iu73VCFofNkvPeBrLrqr3JrhF4

3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr:  -0.02300000 Waves

2023.05.22 10:07 [2588858] smart account 3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr > SELF 0.00000000 Waves

{ "type": 13, "id": "7KYQJz6bNGU2KQkhS5iu73VCFofNkvPeBrLrqr3JrhF4", "fee": 2300000, "feeAssetId": null, "timestamp": 1684739306144, "version": 2, "chainId": 84, "sender": "3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr", "senderPublicKey": "GFbasS3jufhZkK4xR7tdTjjnP8K33KvJFEDHRtxXDkaJ", "proofs": [ "x7qwCisDewAQxQw4YLfQmrdy2hVpgL7RRQnnoJaFrBC9oovqST9HVcZ77WMYTFHf9o3Sf1vMH1G9gDnhGTFpMmC" ], "script": "base64:BgLDFggCEgQKAggBEgcKBQgICAgBEgQKAggIEgUKAwgIARIECgIICBIDCgEBEgMKAQESBAoCCAgSBAoCCAQSABIDCgEBEgASBAoCCAgSBAoCCAgSBAoCCAgSACIJc2VwYXJhdG9yIg5wb29sV2VpZ2h0TXVsdCIPbWF4RGVwdGhEZWZhdWx0IhZmaW5hbGl6YXRpb25TdGFnZVRvdGFsIhdmaW5hbGl6YXRpb25TdGFnZVNoYXJlcyIOa2V5RXBvY2hMZW5ndGgiEWtleUVwb2NoTGVuZ3RoTmV3IhVrZXlFcG9jaExlbmd0aEJ5RXBvY2giBWVwb2NoIg9rZXlDdXJyZW50RXBvY2giC2tleU1heERlcHRoIiJrZXlWb3RpbmdFbWlzc2lvbkNhbmRpZGF0ZUNvbnRyYWN0IhJrZXlGYWN0b3J5Q29udHJhY3QiE2tleUJvb3N0aW5nQ29udHJhY3QiEmtleVN0YWtpbmdDb250cmFjdCIUa2V5RmluYWxpemF0aW9uU3RhZ2UiC2tleU5leHRQb29sIgtrZXlOZXh0VXNlciIOa2V5U3RhcnRIZWlnaHQiEWtleUN1cnJlbnRFcG9jaFVpIhBrZXlTdGFydEhlaWdodFVpIh1rZXlGaW5hbGl6YXRpb25TaG91bGRCZUZvcmNlZCIVa2V5U3RhcnRIZWlnaHRCeUVwb2NoIgxrZXlGaW5hbGl6ZWQiCWtleUluTGlzdCIEcG9vbCILJHQwMTY5MzE3MzMiDWFtb3VudEFzc2V0SWQiDHByaWNlQXNzZXRJZCIHa2V5VXNlZCIHYWRkcmVzcyIHa2V5Vm90ZSILJHQwMjAwNzIwNDciD2tleVZvdGluZ1Jlc3VsdCILJHQwMjIyOTIyNjkiFWtleVZvdGluZ1Jlc3VsdFN0YWtlZCIMbHBBc3NldElkU3RyIgxrZXlQb29sU2hhcmUiCyR0MDI1OTAyNjMwIg1rZXlUb3RhbFZvdGVzIg9rZXlTdGFrZWRCeVVzZXIiDnVzZXJBZGRyZXNzU3RyIgd3cmFwRXJyIgNtc2ciCHRocm93RXJyIg5nZXRWYWx1ZU9yRmFpbCIDa2V5IgR0eXBlIgVlcnJvciIHJG1hdGNoMCIDc3RyIgNpbnQiDGdldFN0ck9yRmFpbCIBQCIMZ2V0SW50T3JGYWlsIgxwb29sVG9TdHJpbmciDHN0cmluZ1RvUG9vbCIFcGFydHMiD2ZhY3RvcnlDb250cmFjdCIaSWR4RmFjdG9yeUNmZ0d3eFJld2FyZERhcHAiDWtleUZhY3RvcnlDZmciFHJlYWRGYWN0b3J5Q2ZnT3JGYWlsIgdmYWN0b3J5IhlnZXRHd3hSZXdhcmRBZGRyZXNzT3JGYWlsIgpmYWN0b3J5Q2ZnIhZnZXRMcEFzc2V0QnlQb29sQXNzZXRzIh9rZXlNYXBwaW5nc0Jhc2VBc3NldDJpbnRlcm5hbElkIgxiYXNlQXNzZXRTdHIiKWtleU1hcHBpbmdQb29sQXNzZXRzVG9Qb29sQ29udHJhY3RBZGRyZXNzIhhpbnRlcm5hbEFtb3VudEFzc2V0SWRTdHIiF2ludGVybmFsUHJpY2VBc3NldElkU3RyIh9rZXlNYXBwaW5nUG9vbENvbnRyYWN0VG9MUEFzc2V0IhNwb29sQ29udHJhY3RBZGRyZXNzIhVhbW91bnRBc3NldEludGVybmFsSWQiFHByaWNlQXNzZXRJbnRlcm5hbElkIglscEFzc2V0SWQiGGNoZWNrV3hFbWlzc2lvblBvb2xMYWJlbCILJHQwNTQ3MDU1MTAiEGd3eFJld2FyZERlcG9zaXQiEmd3eFJld2FyZHNDb250cmFjdCINcG9vbHNMaXN0TmFtZSIQZ2V0Vm90ZXNMaXN0TmFtZSILJHQwNTkyNzU5NjciC2tleUxpc3RIZWFkIghsaXN0TmFtZSIEbWV0YSILa2V5TGlzdFNpemUiC2tleUxpc3RQcmV2IgJpZCILa2V5TGlzdE5leHQiDGNvbnRhaW5zTm9kZSIKaGVhZE9yVW5pdCIKcHJldk9yVW5pdCIKbmV4dE9yVW5pdCIRaW5zZXJ0Tm9kZUFjdGlvbnMiCGxpc3RTaXplIgljaGVja05vZGUiEWRlbGV0ZU5vZGVBY3Rpb25zIhZrZXlNYW5hZ2VyVmF1bHRBZGRyZXNzIhNrZXlNYW5hZ2VyUHVibGljS2V5IhxnZXRNYW5hZ2VyVmF1bHRBZGRyZXNzT3JUaGlzIgFzIhZtYW5hZ2VyUHVibGljS2V5T3JVbml0IhNtYW5hZ2VyVmF1bHRBZGRyZXNzIglpc01hbmFnZXIiAWkiAnBrIgttdXN0TWFuYWdlciIIbXVzdFRoaXMiC3VzZXJBZGRyZXNzIgx0YXJnZXRIZWlnaHQiF2Jvb3N0aW5nQ29udHJhY3RBZGRyZXNzIh92b3RpbmdFbWlzc2lvbkNhbmRpZGF0ZUNvbnRyYWN0IhBib29zdGluZ0NvbnRyYWN0Ig9zdGFraW5nQ29udHJhY3QiC2Vwb2NoTGVuZ3RoIgZjaGVja3MiDWluTGlzdEFjdGlvbnMiGGN1cnJlbnRFcG9jaElzTm90RGVmaW5lZCISc3RhcnRIZWlnaHRBY3Rpb25zIgZhbW91bnQiC3N0YXJ0SGVpZ2h0IgllbmRIZWlnaHQiF2ZpbmFsaXphdGlvblN0YWdlT3JVbml0IgR1c2VkIgR2b3RlIgpwb29sUmVzdWx0Igp0b3RhbFZvdGVzIhNnd3hBbW91bnRBdEVuZFRvdGFsIglhdmFpbGFibGUiB25ld1ZvdGUiCnd4RW1pc3Npb24iDXZvdGVzTGlzdE5hbWUiEHZvdGVzTGlzdEFjdGlvbnMiDm5ld0Vwb2NoTGVuZ3RoIgtuZXdNYXhEZXB0aCIHcG9vbFN0ciILY2hlY2tDYWxsZXIiDWVwb2NoUHJldmlvdXMiE3N0YXJ0SGVpZ2h0UHJldmlvdXMiE2Vwb2NoTGVuZ3RoUHJldmlvdXMiEWVuZEhlaWdodFByZXZpb3VzIhBjaGVja1RhcmdldEVwb2NoIg0kdDAxNzk3MDE4MDEwIhtnd3hBbW91bnRBdEVuZFRvdGFsUHJldmlvdXMiDHZvdGluZ1Jlc3VsdCIMdm90ZVByZXZpb3VzIhp2b3RpbmdSZXN1bHRTdGFrZWRQcmV2aW91cyIMc3Rha2VkQnlVc2VyIhl2b3RpbmdSZXN1bHRTdGFrZWRBY3Rpb25zIgdhY3Rpb25zIgVmb3JjZSILdGFyZ2V0RXBvY2giDGN1cnJlbnRFcG9jaCINJHQwMjAzNjcyMDQwNyIBciIFc2hhcmUiD21vZGlmeVdlaWdodEludiIQcG9vbHNMaXN0QWN0aW9ucyINcHJldmlvdXNFcG9jaCIIbmV3RXBvY2giFG5ld0Vwb2NoTGVuZ3RoT3B0aW9uIhVuZXdFcG9jaExlbmd0aEFjdGlvbnMiCnBvb2xPclVuaXQiCnVzZXJPclVuaXQiByRtYXRjaDEiDHBvb2xzSGVhZFN0ciIObmV4dFVzZXJPclVuaXQiBHVzZXIiBG5leHQiDnByb2Nlc3NWb3RlSW52Ig5uZXh0UG9vbE9yVW5pdCIHJG1hdGNoMiIIbmV4dFVzZXIiE2d3eFJld2FyZERlcG9zaXRJbnYiC25leHRQb29sU3RyIgdjb3VudGVyIgZyZXN1bHQiCG1heERlcHRoIgNpbnYiFmZpbmFsaXphdGlvbkluUHJvZ3Jlc3MiAnR4IgZ2ZXJpZnkiD3RhcmdldFB1YmxpY0tleT4AAWECAl9fAAFiAIDC1y8AAWMACgABZAAAAAFlAAEAAWYJALkJAgkAzAgCAgIlcwkAzAgCAgtlcG9jaExlbmd0aAUDbmlsBQFhAAFnCQC5CQIJAMwIAgIEJXMlcwkAzAgCAhBlcG9jaExlbmd0aF9fbmV3BQNuaWwFAWEBAWgBAWkJALkJAgkAzAgCAgQlcyVkCQDMCAICC2Vwb2NoTGVuZ3RoCQDMCAIJAKQDAQUBaQUDbmlsBQFhAAFqCQC5CQIJAMwIAgICJXMJAMwIAgIMY3VycmVudEVwb2NoBQNuaWwFAWEAAWsJALkJAgkAzAgCAgIlcwkAzAgCAghtYXhEZXB0aAUDbmlsBQFhAAFsCQC5CQIJAMwIAgICJXMJAMwIAgIfdm90aW5nRW1pc3Npb25DYW5kaWRhdGVDb250cmFjdAUDbmlsBQFhAAFtCQC5CQIJAMwIAgICJXMJAMwIAgIPZmFjdG9yeUNvbnRyYWN0BQNuaWwFAWEAAW4JALkJAgkAzAgCAgIlcwkAzAgCAhBib29zdGluZ0NvbnRyYWN0BQNuaWwFAWEAAW8JALkJAgkAzAgCAgIlcwkAzAgCAg9zdGFraW5nQ29udHJhY3QFA25pbAUBYQABcAkAuQkCCQDMCAICAiVzCQDMCAICEWZpbmFsaXphdGlvblN0YWdlBQNuaWwFAWEAAXEJALkJAgkAzAgCAgIlcwkAzAgCAghuZXh0UG9vbAUDbmlsBQFhAAFyCQC5CQIJAMwIAgICJXMJAMwIAgIIbmV4dFVzZXIFA25pbAUBYQABcwkAuQkCCQDMCAICAiVzCQDMCAICC3N0YXJ0SGVpZ2h0BQNuaWwFAWEAAXQJALkJAgkAzAgCAgIlcwkAzAgCAg5jdXJyZW50RXBvY2hVaQUDbmlsBQFhAAF1CQC5CQIJAMwIAgICJXMJAMwIAgINc3RhcnRIZWlnaHRVaQUDbmlsBQFhAAF2CQC5CQIJAMwIAgICJXMJAMwIAgIFZm9yY2UFA25pbAUBYQEBdwEBaQkAuQkCCQDMCAICBCVzJWQJAMwIAgILc3RhcnRIZWlnaHQJAMwIAgkApAMBBQFpBQNuaWwFAWEBAXgBAWkJALkJAgkAzAgCAgQlcyVkCQDMCAICCWZpbmFsaXplZAkAzAgCCQCkAwEFAWkFA25pbAUBYQEBeQEBegQBQQUBegQBQggFAUECXzEEAUMIBQFBAl8yCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICBmluTGlzdAkAzAgCBQFCCQDMCAIFAUMFA25pbAUBYQEBRAIBRQFpCQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICBHVzZWQJAMwIAgkApQgBBQFFCQDMCAIJAKQDAQUBaQUDbmlsBQFhAQFGAwF6AUUBaQQBRwUBegQBQggFAUcCXzEEAUMIBQFHAl8yCQC5CQIJAMwIAgIKJXMlcyVzJXMlZAkAzAgCAgR2b3RlCQDMCAIFAUIJAMwIAgUBQwkAzAgCCQClCAEFAUUJAMwIAgkApAMBBQFpBQNuaWwFAWEBAUgCAXoBaQQBSQUBegQBQggFAUkCXzEEAUMIBQFJAl8yCQC5CQIJAMwIAgIIJXMlcyVzJWQJAMwIAgIMdm90aW5nUmVzdWx0CQDMCAIFAUIJAMwIAgUBQwkAzAgCCQCkAwEFAWkFA25pbAUBYQEBSgIBSwFpCQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICEnZvdGluZ1Jlc3VsdFN0YWtlZAkAzAgCBQFLCQDMCAIJAKQDAQUBaQUDbmlsBQFhAQFMAgF6AWkEAU0FAXoEAUIIBQFNAl8xBAFDCAUBTQJfMgkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICCXBvb2xTaGFyZQkAzAgCBQFCCQDMCAIFAUMJAMwIAgkApAMBBQFpBQNuaWwFAWEBAU4BAWkJALkJAgkAzAgCAgQlcyVkCQDMCAICCnRvdGFsVm90ZXMJAMwIAgkApAMBBQFpBQNuaWwFAWEBAU8CAUsBUAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgZzdGFrZWQJAMwIAgUBUAkAzAgCBQFLBQNuaWwFAWEBAVEBAVIJALkJAgkAzAgCAhV2b3RpbmdfZW1pc3Npb24ucmlkZToJAMwIAgUBUgUDbmlsAgEgAQFTAQFSCQACAQkBAVEBBQFSAQFUAwFFAVUBVgQBVwkBAVEBCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAUUJAMwIAgIBLgkAzAgCBQFVCQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgQBWAUBVgMJAAECBQFYAgZTdHJpbmcEAVkFAVgJAJ0IAgUBRQUBVQMJAAECBQFYAgNJbnQEAVoFAVgJAJoIAgUBRQUBVQkBAVMBAhJpbnZhbGlkIGVudHJ5IHR5cGUFAVcBAmFhAgFFAVUKAAJhYgkBAVQDBQFFBQFVAgADCQABAgUCYWICBlN0cmluZwUCYWIJAAIBCQCsAgIJAAMBBQJhYgIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nAQJhYwIBRQFVCgACYWIJAQFUAwUBRQUBVQAAAwkAAQIFAmFiAgNJbnQFAmFiCQACAQkArAICCQADAQUCYWICGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAECYWQBAXoJAKwCAgkArAICCAUBegJfMQUBYQgFAXoCXzIBAmFlAQFZBAJhZgkAtQkCBQFZBQFhAwkAAAIJAJADAQUCYWYAAgkAlAoCCQCRAwIFAmFmAAAJAJEDAgUCYWYAAQkBAVMBAhNpbnZhbGlkIHBvb2wgc3RyaW5nAAJhZwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFhAgUEdGhpcwUBbQACYWgACgECYWkAAhElc19fZmFjdG9yeUNvbmZpZwECYWoBAmFrCQC1CQIJAQJhYQIFAmFrCQECYWkABQFhAQJhbAECYW0JARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYW0FAmFoAQJhbgIBQgFDCgECYW8BAmFwCQCsAgICKCVzJXMlc19fbWFwcGluZ3NfX2Jhc2VBc3NldDJpbnRlcm5hbElkX18FAmFwCgECYXECAmFyAmFzCQCsAgIJAKwCAgkArAICCQCsAgICCiVkJWQlcyVzX18JAKQDAQUCYXICAl9fCQCkAwEFAmFzAiNfX21hcHBpbmdzX19wb29sQXNzZXRzMlBvb2xDb250cmFjdAoBAmF0AQJhdQkArAICCQCsAgICCCVzJXMlc19fBQJhdQIgX19tYXBwaW5nc19fcG9vbENvbnRyYWN0MkxwQXNzZXQEAmF2CQECYWMCBQJhZwkBAmFvAQUBQgQCYXcJAQJhYwIFAmFnCQECYW8BBQFDBAJhdQkBAmFhAgUCYWcJAQJhcQIFAmF2BQJhdwQCYXgJAQJhYQIFAmFnCQECYXQBBQJhdQUCYXgBAmF5AQF6BAJhegUBegQBQggFAmF6Al8xBAFDCAUCYXoCXzIKAAJhYgkA/AcEBQJhZwIYY2hlY2tXeEVtaXNzaW9uUG9vbExhYmVsCQDMCAIFAUIJAMwIAgUBQwUDbmlsBQNuaWwDCQABAgUCYWICB0Jvb2xlYW4FAmFiCQACAQkArAICCQADAQUCYWICHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4BAmFBAAQCYW0JAQJhagEFAmFnBAJhQgkBAmFsAQUCYW0JAPwHBAUCYUICB2RlcG9zaXQFA25pbAUDbmlsAAJhQwIFcG9vbHMBAmFEAQF6BAJhRQUBegQBQggFAmFFAl8xBAFDCAUCYUUCXzIJALkJAgkAzAgCAgV2b3RlcwkAzAgCBQFCCQDMCAIFAUMFA25pbAUBYQECYUYBAmFHBAJhSAMJAAACBQJhRwUCYUMCBCVzJXMCCCVzJXMlcyVzCQC5CQIJAMwIAgUCYUgJAMwIAgUCYUcJAMwIAgIEaGVhZAUDbmlsBQFhAQJhSQECYUcEAmFIAwkAAAIFAmFHBQJhQwIEJXMlcwIIJXMlcyVzJXMJALkJAgkAzAgCBQJhSAkAzAgCBQJhRwkAzAgCAgRzaXplBQNuaWwFAWEBAmFKAgJhRwJhSwQCYUgDCQAAAgUCYUcFAmFDAgglcyVzJXMlcwIKJXMlcyVzJXMlcwkAuQkCCQDMCAIFAmFICQDMCAIFAmFHCQDMCAIFAmFLCQDMCAICBHByZXYFA25pbAUBYQECYUwCAmFHAmFLBAJhSAMJAAACBQJhRwUCYUMCCCVzJXMlcyVzAgolcyVzJXMlcyVzCQC5CQIJAMwIAgUCYUgJAMwIAgUCYUcJAMwIAgUCYUsJAMwIAgIEbmV4dAUDbmlsBQFhAQJhTQICYUcCYUsEAmFOCQCdCAIFBHRoaXMJAQJhRgEFAmFHBAJhTwkAnQgCBQR0aGlzCQECYUoCBQJhRwUCYUsEAmFQCQCdCAIFBHRoaXMJAQJhTAIFAmFHBQJhSwMDCQAAAgUCYUsJAQt2YWx1ZU9yRWxzZQIFAmFOAgAGCQECIT0CBQJhTwUEdW5pdAYJAQIhPQIFAmFQBQR1bml0AQJhUQICYUcCYUsEAmFOCQCdCAIFBHRoaXMJAQJhRgEFAmFHBAJhUgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYUkBBQJhRwAABAJhUwMJAQEhAQkBAmFNAgUCYUcFAmFLBgkBAVMBAgtOb2RlIGV4aXN0cwMJAAACBQJhUwUCYVMJAM4IAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYUkBBQJhRwkAZAIFAmFSAAEFA25pbAMJAQIhPQIFAmFOBQR1bml0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhTAIFAmFHBQJhSwkBBXZhbHVlAQUCYU4JAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFKAgUCYUcJAQV2YWx1ZQEFAmFOBQJhSwUDbmlsBQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFGAQUCYUcFAmFLBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmFUAgJhRwJhSwQCYU4JAJ0IAgUEdGhpcwkBAmFGAQUCYUcEAmFSCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQJhSQEFAmFHAAAEAmFPCQCdCAIFBHRoaXMJAQJhSgIFAmFHBQJhSwQCYVAJAJ0IAgUEdGhpcwkBAmFMAgUCYUcFAmFLCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhSQEFAmFHCQBlAgUCYVIAAQUDbmlsAwMJAQIhPQIFAmFPBQR1bml0CQECIT0CBQJhUAUEdW5pdAcJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFMAgUCYUcJAQV2YWx1ZQEFAmFPCQEFdmFsdWUBBQJhUAkAzAgCCQELU3RyaW5nRW50cnkCCQECYUoCBQJhRwkBBXZhbHVlAQUCYVAJAQV2YWx1ZQEFAmFPCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhSgIFAmFHBQJhSwkAzAgCCQELRGVsZXRlRW50cnkBCQECYUwCBQJhRwUCYUsFA25pbAMJAQIhPQIFAmFQBQR1bml0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhRgEFAmFHCQEFdmFsdWUBBQJhUAkAzAgCCQELRGVsZXRlRW50cnkBCQECYUwCBQJhRwUCYUsJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFKAgUCYUcJAQV2YWx1ZQEFAmFQBQNuaWwDCQECIT0CBQJhTwUEdW5pdAkAzAgCCQELRGVsZXRlRW50cnkBCQECYUoCBQJhRwUCYUsJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFMAgUCYUcJAQV2YWx1ZQEFAmFPBQNuaWwDCQAAAgUCYUsJAQt2YWx1ZU9yRWxzZQIFAmFOAgAJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFGAQUCYUcFA25pbAkBAVMBCQCsAgIJAKwCAgkArAICAg5pbnZhbGlkIG5vZGU6IAUCYUcCAS4FAmFLAQJhVQACFyVzX19tYW5hZ2VyVmF1bHRBZGRyZXNzAQJhVgACFCVzX19tYW5hZ2VyUHVibGljS2V5AQJhVwAEAVgJAKIIAQkBAmFVAAMJAAECBQFYAgZTdHJpbmcEAmFYBQFYCQERQGV4dHJOYXRpdmUoMTA2MikBBQJhWAUEdGhpcwECYVkABAJhWgkBAmFXAAQBWAkAnQgCBQJhWgkBAmFWAAMJAAECBQFYAgZTdHJpbmcEAmFYBQFYCQDZBAEFAmFYAwkAAQIFAVgCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgECYmEBAmJiBAFYCQECYVkAAwkAAQIFAVgCCkJ5dGVWZWN0b3IEAmJjBQFYCQAAAggFAmJiD2NhbGxlclB1YmxpY0tleQUCYmMDCQABAgUBWAIEVW5pdAkAAAIIBQJiYgZjYWxsZXIFBHRoaXMJAAIBAgtNYXRjaCBlcnJvcgECYmQBAmJiAwkBAmJhAQUCYmIGCQACAQIRcGVybWlzc2lvbiBkZW5pZWQBAmJlAQJiYgMJAAACCAUCYmIGY2FsbGVyBQR0aGlzBgkAAgECEXBlcm1pc3Npb24gZGVuaWVkEAJiYgEYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0AgJiZgJiZwQCYmgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQECYWECBQR0aGlzBQFuCQEBUQECIWludmFsaWQgYm9vc3RpbmcgY29udHJhY3QgYWRkcmVzcwkAlAoCBQNuaWwKAAJhYgkA/AcEBQJiaAIgZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0UkVBRE9OTFkJAMwIAgUCYmYJAMwIAgUCYmcFA25pbAUDbmlsAwkAAQIFAmFiAgNJbnQFAmFiCQACAQkArAICCQADAQUCYWICGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAJiYgELY29uc3RydWN0b3IFAmFnAmJpAmJqAmJrAmJsBAJibQkAzAgCCQECYmQBBQJiYgkAzAgCAwkBAiE9AgkApggBBQJhZwUEdW5pdAYCIGludmFsaWQgZmFjdG9yeSBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQECIT0CCQCmCAEFAmJpBQR1bml0BgIyaW52YWxpZCB2b3RpbmcgZW1pc3Npb24gY2FuZGlkYXRlIGNvbnRyYWN0IGFkZHJlc3MJAMwIAgMJAQIhPQIJAKYIAQUCYmoFBHVuaXQGAiFpbnZhbGlkIGJvb3N0aW5nIGNvbnRyYWN0IGFkZHJlc3MJAMwIAgMJAQIhPQIJAKYIAQUCYmsFBHVuaXQGAiBpbnZhbGlkIHN0YWtpbmcgY29udHJhY3QgYWRkcmVzcwkAzAgCAwkAZgIFAmJsAAAGCQEBUwECFGludmFsaWQgZXBvY2ggbGVuZ3RoBQNuaWwDCQAAAgUCYm0FAmJtCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBbQUCYWcJAMwIAgkBC1N0cmluZ0VudHJ5AgUBbAUCYmkJAMwIAgkBC1N0cmluZ0VudHJ5AgUBbgUCYmoJAMwIAgkBC1N0cmluZ0VudHJ5AgUBbwUCYmsJAMwIAgkBDEludGVnZXJFbnRyeQIFAWYFAmJsBQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmIBBmNyZWF0ZQIBQgFDBAJibQkAzAgCAwkAAAIJANgEAQgIBQJiYgZjYWxsZXIFYnl0ZXMJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUBbAIABgkBAmJkAQUCYmIFA25pbAMJAAACBQJibQUCYm0EAXoJAJQKAgUBQgUBQwQCYm4JAM4IAgkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBAXkBBQF6BgUDbmlsCQECYVECBQJhQwkBAmFkAQUBegQCYm8JAAACCQCaCAIFBHRoaXMFAWoFBHVuaXQEAmJwAwUCYm8EAWkAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBagUBaQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAXcBBQFpBQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFAXMFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdAUBaQkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdQUGaGVpZ2h0BQNuaWwFA25pbAkAlAoCCQDOCAIFAmJuBQJicAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiYgEEdm90ZQMBQgFDAmJxBAF6CQCUCgIFAUIFAUMEAWkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBagAABAJicgkBAmFjAgUEdGhpcwkBAXcBBQFpBAJibAkBAmFjAgUEdGhpcwUBZgQCYnMJAGQCBQJicgUCYmwEAmJ0CQCaCAIFBHRoaXMFAXAEAmJ1CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFEAggFAmJiBmNhbGxlcgUBaQAABAJidgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBRgMFAXoIBQJiYgZjYWxsZXIFAWkAAAQCYncJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUgCBQF6BQFpAAAEAmJ4CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFOAQUBaQAABAJieQoAAmFiCQD8BwQFBHRoaXMCGGdldFVzZXJHd3hBbW91bnRBdEhlaWdodAkAzAgCCQDYBAEICAUCYmIGY2FsbGVyBWJ5dGVzCQDMCAIFAmJzBQNuaWwFA25pbAMJAAECBQJhYgIDSW50BQJhYgkAAgEJAKwCAgkAAwEFAmFiAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQEAmJ6CQBlAgUCYnkFAmJ1BAJiQQkAZAIFAmJ2BQJicQQCYkIJAQJheQEFAXoEAmJtCQDMCAIDCQECIT0CCQCgCAEJAQF5AQUBegUEdW5pdAYJAQFTAQIOaW52YWxpZCBhc3NldHMJAMwIAgMJAGYCBQJicwUGaGVpZ2h0BgkBAVMBAg5pbnZhbGlkIGhlaWdodAkAzAgCAwkAAAIFAmJ0BQR1bml0BgkBAVMBAhhmaW5hbGl6YXRpb24gaW4gcHJvZ3Jlc3MJAMwIAgMJAGYCBQJieQAABgkBAVMBAhN5b3UgZG8gbm90IGhhdmUgZ1dYCQDMCAIDAwkAZgIFAmJxAAAJAGcCBQJiegUCYnEHBgkBAVMBAg5pbnZhbGlkIGFtb3VudAkAzAgCAwUCYkIGCQEBUwECHXBvb2wgaGFzbid0IFdYX0VNSVNTSU9OIGxhYmVsBQNuaWwDCQAAAgUCYm0FAmJtBAJiQwkBAmFEAQUBegQBUAkApQgBCAUCYmIGY2FsbGVyBAJiRAMJAQJhTQIFAmJDBQFQBQNuaWwJAQJhUQIFAmJDBQFQCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUQCCAUCYmIGY2FsbGVyBQFpCQBkAgUCYnUFAmJxCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBRgMFAXoIBQJiYgZjYWxsZXIFAWkFAmJBCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBSAIFAXoFAWkJAGQCBQJidwUCYnEJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFOAQUBaQkAZAIFAmJ4BQJicQUDbmlsBQJiRAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiYgEKY2FuY2VsVm90ZQIBQgFDBAF6CQCUCgIFAUIFAUMEAWkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBagAABAJicgkBAmFjAgUEdGhpcwkBAXcBBQFpBAJibAkBAmFjAgUEdGhpcwUBZgQCYnMJAGQCBQJicgUCYmwEAmJ0CQCaCAIFBHRoaXMFAXAEAmJ1CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFEAggFAmJiBmNhbGxlcgUBaQAABAJidgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBRgMFAXoIBQJiYgZjYWxsZXIFAWkAAAQCYncJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUgCBQF6BQFpAAAEAmJ4CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFOAQUBaQAABAJibQkAzAgCAwkBAiE9AgkAoAgBCQEBeQEFAXoFBHVuaXQGCQEBUwECDmludmFsaWQgYXNzZXRzCQDMCAIDCQBmAgUCYnMFBmhlaWdodAYJAQFTAQIOaW52YWxpZCBoZWlnaHQJAMwIAgMJAAACBQJidAUEdW5pdAYJAQFTAQIYZmluYWxpemF0aW9uIGluIHByb2dyZXNzCQDMCAIDCQBmAgUCYnYAAAYJAQFTAQIHbm8gdm90ZQUDbmlsAwkAAAIFAmJtBQJibQQCYkMJAQJhRAEFAXoEAVAJAKUIAQgFAmJiBmNhbGxlcgkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFEAggFAmJiBmNhbGxlcgUBaQkAlgMBCQDMCAIJAGUCBQJidQUCYnYJAMwIAgAABQNuaWwJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAUYDBQF6CAUCYmIGY2FsbGVyBQFpCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBSAIFAXoFAWkJAGUCBQJidwUCYnYJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFOAQUBaQkAZQIFAmJ4BQJidgUDbmlsCQECYVQCBQJiQwUBUAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiYgEOc2V0RXBvY2hMZW5ndGgBAmJFBAJibQkAzAgCCQECYmQBBQJiYgkAzAgCAwkAZgIFAmJFAAAGCQEBUwECFGludmFsaWQgZXBvY2ggbGVuZ3RoBQNuaWwDCQAAAgUCYm0FAmJtCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAWcFAmJFBQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmIBC3NldE1heERlcHRoAQJiRgQCYm0JAMwIAgkBAmJkAQUCYmIJAMwIAgMJAGYCBQJiRgAABgkBAVMBAhFpbnZhbGlkIG1heCBkZXB0aAUDbmlsAwkAAAIFAmJtBQJibQkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFrBQJiRgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJiARNwcm9jZXNzVm90ZUlOVEVSTkFMAgJiRwFQBAJiSAkBAmJlAQUCYmIDCQAAAgUCYkgFAmJIBAJiZgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEFAVAJAQFRAQkArAICAipwcm9jZXNzVm90ZUlOVEVSTkFMOiBpbnZhbGlkIHVzZXIgYWRkcmVzcyAFAVAEAWkJAQJhYwIFBHRoaXMFAWoEAmJJCQBlAgUBaQABBAJibAkBAmFjAgUEdGhpcwUBZgQCYnIJAQJhYwIFBHRoaXMJAQF3AQUBaQQCYnMJAGQCBQJicgUCYmwEAmJKCQECYWMCBQR0aGlzCQEBdwEFAmJJBAJiSwkBAmFjAgUEdGhpcwkBAWgBBQJiSQQCYkwJAGQCBQJiSgUCYksEAmJNAwkAZwIFAmJJAAAGCQEBUwECK3Byb2Nlc3NWb3RlSU5URVJOQUw6IGludmFsaWQgcHJldmlvdXMgZXBvY2gDCQAAAgUCYk0FAmJNBAF6CQECYWUBBQJiRwQCYk4FAXoEAUIIBQJiTgJfMQQBQwgFAmJOAl8yBAJiQgkBAmF5AQUBegQCYnkKAAJhYgkA/AcEBQR0aGlzAhhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQJAMwIAgUBUAkAzAgCBQJicwUDbmlsBQNuaWwDCQABAgUCYWICA0ludAUCYWIJAAIBCQCsAgIJAAMBBQJhYgIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50BAJiTwoAAmFiCQD8BwQFBHRoaXMCGGdldFVzZXJHd3hBbW91bnRBdEhlaWdodAkAzAgCBQFQCQDMCAIFAmJMBQNuaWwFA25pbAMJAAECBQJhYgIDSW50BQJhYgkAAgEJAKwCAgkAAwEFAmFiAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQEAmJ4CQELdmFsdWVPckVsc2UCCQCfCAEJAQFOAQUBaQAABAJiUAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEBSAIFAXoFAWkAAAQCYlEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnwgBCQEBRgMFAXoFAmJmBQJiSQkBAVEBCQCsAgIJAKwCAgkArAICCQCsAgICFHByb2Nlc3NWb3RlSU5URVJOQUwgBQJiRwIBIAUBUAISOiBubyBwcmV2aW91cyB2b3RlBAJidQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBRAIFAmJmBQFpAAAEAUsJAQJhbgIFAUIFAUMEAmJSCQELdmFsdWVPckVsc2UCCQCfCAEJAQFKAgUBSwUCYkkAAAQCYmsJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQJhYQIFBHRoaXMFAW8EAmJTCQELdmFsdWVPckVsc2UCCQCaCAIFAmJrCQEBTwIFAUsFAVAAAAQCYlQDCQAAAgUCYlMAAAUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBSgIFAUsFAmJJCQBkAgUCYlIFAmJRBQNuaWwEAmJBAwkAZgIFAmJPAAAJAGsDBQJiUQUCYnkFAmJPAAAEAmJVAwMJAGYCBQJiQQAABQJiQgcJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFGAwUBegUCYmYFAWkFAmJBCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBTgEFAWkJAGQCBQJieAUCYkEJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFIAgUBegUBaQkAZAIFAmJQBQJiQQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUQCBQJiZgUBaQkAZAIFAmJ1BQJiQQUDbmlsCQECYVQCCQECYUQBBQF6BQFQCQCUCgIJAM4IAgUCYlUFAmJUBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJiARNwcm9jZXNzUG9vbElOVEVSTkFMAgJiRwJiVgQCYkgJAQJiZQEFAmJiAwkAAAIFAmJIBQJiSAQCYlcEAmJYCQECYWMCBQR0aGlzBQFqAwUCYlYFAmJYCQBlAgUCYlgAAQQCYk0DCQBnAgUCYlcAAAYJAQFTAQIpcHJvY2Vzc1Bvb2xJTlRFUk5BTDogaW52YWxpZCB0YXJnZXQgZXBvY2gDCQAAAgUCYk0FAmJNBAF6CQECYWUBBQJiRwQCYlkFAXoEAUIIBQJiWQJfMQQBQwgFAmJZAl8yBAJiawkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFhAgUEdGhpcwUBbwQCYXgJAQJhbgIFAUIFAUMEAmJaCgACYWIJAPwHBAUCYmsCEnVzZXJzTGlzdFRyYXZlcnNhbAkAzAgCBQJheAUDbmlsBQNuaWwDCQABAgUCYWICB0Jvb2xlYW4FAmFiCQACAQkArAICCQADAQUCYWICHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4DCQAAAgUCYloFAmJaAwUCYloJAJQKAgUDbmlsBgQCYkIJAQJheQEFAXoEAmJ4CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFOAQUCYlcAAAQCYlAJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUgCBQF6BQJiVwAABAJjYQMDCQAAAgUCYngAAAYJAQEhAQUCYkIAAAkAawMFAmJQBQFiBQJieAQCY2IJAPwHBAUCYWcCDG1vZGlmeVdlaWdodAkAzAgCBQJheAkAzAgCBQJjYQUDbmlsBQNuaWwDCQAAAgUCY2IFAmNiBAJjYwMDBQJiQgYFAmJWBQNuaWwJAM4IAgkAzAgCCQELRGVsZXRlRW50cnkBCQEBeQEFAXoFA25pbAkBAmFUAgUCYUMFAmJHCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUwCBQF6BQJiVwUCY2EFA25pbAUCY2MHCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJiAQ5maW5hbGl6ZUhlbHBlcgAEAmJWCQELdmFsdWVPckVsc2UCCQCgCAEFAXYHBAFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWoAAAQCY2QJAGUCBQFpAAEEAmJyCQECYWMCBQR0aGlzCQEBdwEFAWkEAmJsCQECYWMCBQR0aGlzBQFmBAJicwkAZAIFAmJyBQJibAQCYnQJAJoIAgUEdGhpcwUBcAMDAwkAZwIFBmhlaWdodAUCYnMJAAACBQJidAUEdW5pdAcJAQEhAQUCYlYHBAJjZQkAZAIFAWkAAQQCY2YJAJoIAgUEdGhpcwUBZwQCY2cEAVgFAmNmAwkAAQIFAVgCA0ludAQCYkUFAVgJAMwIAgkBDEludGVnZXJFbnRyeQIFAWYFAmJFCQDMCAIJAQtEZWxldGVFbnRyeQEFAWcFA25pbAMJAAECBQFYAgRVbml0BQNuaWwJAAIBAgtNYXRjaCBlcnJvcgkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQF3AQUCY2UFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBcwUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFqBQJjZQkAzAgCCQEMSW50ZWdlckVudHJ5AgUBcAUBZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAWgBBQFpBQJibAUDbmlsBQJjZwYDAwUCYlYJAAACBQJidAUEdW5pdAcJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBcAUBZQUDbmlsBgMJAAACBQJidAUEdW5pdAkAlAoCBQNuaWwHAwkAAAIFAmJ0BQFkBAJjaAkAoggBBQFxBAJjaQkAoggBBQFyBAFYBQJjaAMJAAECBQFYAgRVbml0BAJjagkAoggBCQECYUYBBQJhQwMJAAECBQJjagIEVW5pdAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFwBQFlCQDMCAIJAQtEZWxldGVFbnRyeQEFAXEJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcgUDbmlsBgMJAAECBQJjagIGU3RyaW5nBAJjawUCY2oJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQFxBQJjawUDbmlsBgkAAgECC01hdGNoIGVycm9yAwkAAQIFAVgCBlN0cmluZwQCYkcFAVgEAXoJAQJhZQEFAmJHBAJjbAQCY2oFAmNpAwkAAQIFAmNqAgRVbml0CQCiCAEJAQJhRgEJAQJhRAEFAXoDCQABAgUCY2oCBlN0cmluZwQCY20FAmNqBAJjbgkAoggBCQECYUwCCQECYUQBBQF6BQJjbQMJAAACBQJjbgUCY24EAmNvCQD8BwQFBHRoaXMCE3Byb2Nlc3NWb3RlSU5URVJOQUwJAMwIAgUCYkcJAMwIAgUCY20FA25pbAUDbmlsAwkAAAIFAmNvBQJjbwUCY24JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAgtNYXRjaCBlcnJvcgQCY2oFAmNsAwkAAQIFAmNqAgRVbml0BAJjcAkAoggBCQECYUwCBQJhQwUCYkcEAmNxBQJjcAMJAAECBQJjcQIEVW5pdAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFwBQFlCQDMCAIJAQtEZWxldGVFbnRyeQEFAXEJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcgUDbmlsBgMJAAECBQJjcQIGU3RyaW5nBAJhWAUCY3EJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQFxBQJhWAkAzAgCCQELRGVsZXRlRW50cnkBBQFyBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IDCQABAgUCY2oCBlN0cmluZwQCY3IFAmNqCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBcgUCY3IFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgkAAgECC01hdGNoIGVycm9yAwkAAAIFAmJ0BQFlBAJjaAkAoggBBQFxBAFYBQJjaAMJAAECBQFYAgRVbml0BAJjagkAoggBCQECYUYBBQJhQwMJAAECBQJjagIEVW5pdAQCYlUDBQJiVgkAzAgCCQELRGVsZXRlRW50cnkBBQFwCQDMCAIJAQtEZWxldGVFbnRyeQEFAXYFA25pbAkAzAgCCQELRGVsZXRlRW50cnkBBQFwCQDMCAIJAQxCb29sZWFuRW50cnkCCQEBeAEFAmNkBgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdAUBaQkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdQUCYnIFA25pbAQCY3MJAQJhQQADCQAAAgUCY3MFAmNzCQCUCgIFAmJVBgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgMJAAECBQJjagIGU3RyaW5nBAJjdAUCY2oJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQFxBQJjdAUDbmlsBgkAAgECC01hdGNoIGVycm9yAwkAAQIFAVgCBlN0cmluZwQCYkcFAVgEAmNwCQCiCAEJAQJhTAIFAmFDBQJiRwMJAAACBQJjcAUCY3AEAmJaCgACYWIJAPwHBAUEdGhpcwITcHJvY2Vzc1Bvb2xJTlRFUk5BTAkAzAgCBQJiRwkAzAgCBQJiVgUDbmlsBQNuaWwDCQABAgUCYWICB0Jvb2xlYW4FAmFiCQACAQkArAICCQADAQUCYWICHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4DCQAAAgUCYloFAmJaAwUCYloJAJQKAgUDbmlsBgQCY2oFAmNwAwkAAQIFAmNqAgRVbml0BAJiVQMFAmJWCQDMCAIJAQtEZWxldGVFbnRyeQEFAXAJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBdgkAzAgCCQELRGVsZXRlRW50cnkBBQFxBQNuaWwJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcAkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBAXgBBQJjZAYJAMwIAgkBDEludGVnZXJFbnRyeQIFAXQFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIFAXUFAmJyCQDMCAIJAQtEZWxldGVFbnRyeQEFAXEFA25pbAQCY3MJAQJhQQADCQAAAgUCY3MFAmNzCQCUCgIFAmJVBgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgMJAAECBQJjagIGU3RyaW5nBAJjdAUCY2oJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQFxBQJjdAUDbmlsBgkAAgECC01hdGNoIGVycm9yCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQILTWF0Y2ggZXJyb3IJAQFTAQIWZmluYWxpemF0aW9uIGlzIGJyb2tlbgJiYgEPZmluYWxpemVXcmFwcGVyAQJjdQQCY3YKAAJhYgkA/AcEBQR0aGlzAg5maW5hbGl6ZUhlbHBlcgUDbmlsBQNuaWwDCQABAgUCYWICB0Jvb2xlYW4FAmFiCQACAQkArAICCQADAQUCYWICHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4DCQAAAgUCY3YFAmN2AwkBASEBBQJjdgMJAAACBQJjdQAACQEBUwECHkN1cnJlbnQgdm90aW5nIGlzIG5vdCBvdmVyIHlldAkAlAoCBQNuaWwFBHVuaXQEAmN3CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWsFAWMDCQBmAgUCY3cFAmN1BAJjeAkA/AcEBQR0aGlzAg9maW5hbGl6ZVdyYXBwZXIJAMwIAgkAZAIFAmN1AAEFA25pbAUDbmlsAwkAAAIFAmN4BQJjeAkAlAoCBQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJiAQhmaW5hbGl6ZQAEAmN4CQD8BwQFBHRoaXMCD2ZpbmFsaXplV3JhcHBlcgkAzAgCAAAFA25pbAUDbmlsAwkAAAIFAmN4BQJjeAkAlAoCBQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmIBFGNvbnRhaW5zTm9kZVJFQURPTkxZAgJhRwJhSwkAlAoCBQNuaWwJAQJhTQIFAmFHBQJhSwJiYgEKaW5zZXJ0Tm9kZQICYUcCYUsEAmJICQECYmQBBQJiYgMJAAACBQJiSAUCYkgJAJQKAgkBAmFRAgUCYUcFAmFLBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJiAQpkZWxldGVOb2RlAgJhRwJhSwQCYkgJAQJiZAEFAmJiAwkAAAIFAmJIBQJiSAkAlAoCCQECYVQCBQJhRwUCYUsFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmIBGGlzRmluYWxpemF0aW9uSW5Qcm9ncmVzcwAEAmJ0CQCaCAIFBHRoaXMFAXAEAmN5CQECIT0CBQJidAUEdW5pdAkAlAoCBQNuaWwFAmN5AQJjegECY0EABAJjQgQBWAkBAmFZAAMJAAECBQFYAgpCeXRlVmVjdG9yBAJiYwUBWAUCYmMDCQABAgUBWAIEVW5pdAgFAmN6D3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yCQD0AwMIBQJjeglib2R5Qnl0ZXMJAJEDAggFAmN6BnByb29mcwAABQJjQhfF/kY=", "height": 2588858, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 5mdwckWoBuwHGxXrUXHeYhvZFyg7PfnXgoE6CtGxbTWw Next: Fs8EQGC68ygA1Mc2a5Bcn3tJcoUq2SmE9cDxeMQBfKui Diff:
OldNewDifferences
813813 }
814814
815815
816+
817+@Callable(i)
818+func isFinalizationInProgress () = {
819+ let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
820+ let finalizationInProgress = (finalizationStageOrUnit != unit)
821+ $Tuple2(nil, finalizationInProgress)
822+ }
823+
824+
816825 @Verifier(tx)
817826 func verify () = {
818827 let targetPublicKey = match managerPublicKeyOrUnit() {
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "__"
55
66 let poolWeightMult = 100000000
77
88 let maxDepthDefault = 10
99
1010 let finalizationStageTotal = 0
1111
1212 let finalizationStageShares = 1
1313
1414 let keyEpochLength = makeString(["%s", "epochLength"], separator)
1515
1616 let keyEpochLengthNew = makeString(["%s%s", "epochLength__new"], separator)
1717
1818 func keyEpochLengthByEpoch (epoch) = makeString(["%s%d", "epochLength", toString(epoch)], separator)
1919
2020
2121 let keyCurrentEpoch = makeString(["%s", "currentEpoch"], separator)
2222
2323 let keyMaxDepth = makeString(["%s", "maxDepth"], separator)
2424
2525 let keyVotingEmissionCandidateContract = makeString(["%s", "votingEmissionCandidateContract"], separator)
2626
2727 let keyFactoryContract = makeString(["%s", "factoryContract"], separator)
2828
2929 let keyBoostingContract = makeString(["%s", "boostingContract"], separator)
3030
3131 let keyStakingContract = makeString(["%s", "stakingContract"], separator)
3232
3333 let keyFinalizationStage = makeString(["%s", "finalizationStage"], separator)
3434
3535 let keyNextPool = makeString(["%s", "nextPool"], separator)
3636
3737 let keyNextUser = makeString(["%s", "nextUser"], separator)
3838
3939 let keyStartHeight = makeString(["%s", "startHeight"], separator)
4040
4141 let keyCurrentEpochUi = makeString(["%s", "currentEpochUi"], separator)
4242
4343 let keyStartHeightUi = makeString(["%s", "startHeightUi"], separator)
4444
4545 let keyFinalizationShouldBeForced = makeString(["%s", "force"], separator)
4646
4747 func keyStartHeightByEpoch (epoch) = makeString(["%s%d", "startHeight", toString(epoch)], separator)
4848
4949
5050 func keyFinalized (epoch) = makeString(["%s%d", "finalized", toString(epoch)], separator)
5151
5252
5353 func keyInList (pool) = {
5454 let $t016931733 = pool
5555 let amountAssetId = $t016931733._1
5656 let priceAssetId = $t016931733._2
5757 makeString(["%s%s%s", "inList", amountAssetId, priceAssetId], separator)
5858 }
5959
6060
6161 func keyUsed (address,epoch) = makeString(["%s%s%d", "used", toString(address), toString(epoch)], separator)
6262
6363
6464 func keyVote (pool,address,epoch) = {
6565 let $t020072047 = pool
6666 let amountAssetId = $t020072047._1
6767 let priceAssetId = $t020072047._2
6868 makeString(["%s%s%s%s%d", "vote", amountAssetId, priceAssetId, toString(address), toString(epoch)], separator)
6969 }
7070
7171
7272 func keyVotingResult (pool,epoch) = {
7373 let $t022292269 = pool
7474 let amountAssetId = $t022292269._1
7575 let priceAssetId = $t022292269._2
7676 makeString(["%s%s%s%d", "votingResult", amountAssetId, priceAssetId, toString(epoch)], separator)
7777 }
7878
7979
8080 func keyVotingResultStaked (lpAssetIdStr,epoch) = makeString(["%s%s%d", "votingResultStaked", lpAssetIdStr, toString(epoch)], separator)
8181
8282
8383 func keyPoolShare (pool,epoch) = {
8484 let $t025902630 = pool
8585 let amountAssetId = $t025902630._1
8686 let priceAssetId = $t025902630._2
8787 makeString(["%s%s%s%d", "poolShare", amountAssetId, priceAssetId, toString(epoch)], separator)
8888 }
8989
9090
9191 func keyTotalVotes (epoch) = makeString(["%s%d", "totalVotes", toString(epoch)], separator)
9292
9393
9494 func keyStakedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s", "staked", userAddressStr, lpAssetIdStr], separator)
9595
9696
9797 func wrapErr (msg) = makeString(["voting_emission.ride:", msg], " ")
9898
9999
100100 func throwErr (msg) = throw(wrapErr(msg))
101101
102102
103103 func getValueOrFail (address,key,type) = {
104104 let error = wrapErr(makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
105105 valueOrErrorMessage( match type {
106106 case str: String =>
107107 getString(address, key)
108108 case int: Int =>
109109 getInteger(address, key)
110110 case _ =>
111111 throwErr("invalid entry type")
112112 }, error)
113113 }
114114
115115
116116 func getStrOrFail (address,key) = {
117117 let @ = getValueOrFail(address, key, "")
118118 if ($isInstanceOf(@, "String"))
119119 then @
120120 else throw(($getType(@) + " couldn't be cast to String"))
121121 }
122122
123123
124124 func getIntOrFail (address,key) = {
125125 let @ = getValueOrFail(address, key, 0)
126126 if ($isInstanceOf(@, "Int"))
127127 then @
128128 else throw(($getType(@) + " couldn't be cast to Int"))
129129 }
130130
131131
132132 func poolToString (pool) = ((pool._1 + separator) + pool._2)
133133
134134
135135 func stringToPool (str) = {
136136 let parts = split(str, separator)
137137 if ((size(parts) == 2))
138138 then $Tuple2(parts[0], parts[1])
139139 else throwErr("invalid pool string")
140140 }
141141
142142
143143 let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
144144
145145 let IdxFactoryCfgGwxRewardDapp = 10
146146
147147 func keyFactoryCfg () = "%s__factoryConfig"
148148
149149
150150 func readFactoryCfgOrFail (factory) = split(getStrOrFail(factory, keyFactoryCfg()), separator)
151151
152152
153153 func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp])
154154
155155
156156 func getLpAssetByPoolAssets (amountAssetId,priceAssetId) = {
157157 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
158158
159159 func keyMappingPoolAssetsToPoolContractAddress (internalAmountAssetIdStr,internalPriceAssetIdStr) = (((("%d%d%s%s__" + toString(internalAmountAssetIdStr)) + "__") + toString(internalPriceAssetIdStr)) + "__mappings__poolAssets2PoolContract")
160160
161161 func keyMappingPoolContractToLPAsset (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
162162
163163 let amountAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amountAssetId))
164164 let priceAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAssetId))
165165 let poolContractAddress = getStrOrFail(factoryContract, keyMappingPoolAssetsToPoolContractAddress(amountAssetInternalId, priceAssetInternalId))
166166 let lpAssetId = getStrOrFail(factoryContract, keyMappingPoolContractToLPAsset(poolContractAddress))
167167 lpAssetId
168168 }
169169
170170
171171 func checkWxEmissionPoolLabel (pool) = {
172172 let $t054705510 = pool
173173 let amountAssetId = $t054705510._1
174174 let priceAssetId = $t054705510._2
175175 let @ = invoke(factoryContract, "checkWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil)
176176 if ($isInstanceOf(@, "Boolean"))
177177 then @
178178 else throw(($getType(@) + " couldn't be cast to Boolean"))
179179 }
180180
181181
182182 func gwxRewardDeposit () = {
183183 let factoryCfg = readFactoryCfgOrFail(factoryContract)
184184 let gwxRewardsContract = getGwxRewardAddressOrFail(factoryCfg)
185185 invoke(gwxRewardsContract, "deposit", nil, nil)
186186 }
187187
188188
189189 let poolsListName = "pools"
190190
191191 func getVotesListName (pool) = {
192192 let $t059275967 = pool
193193 let amountAssetId = $t059275967._1
194194 let priceAssetId = $t059275967._2
195195 makeString(["votes", amountAssetId, priceAssetId], separator)
196196 }
197197
198198
199199 func keyListHead (listName) = {
200200 let meta = if ((listName == poolsListName))
201201 then "%s%s"
202202 else "%s%s%s%s"
203203 makeString([meta, listName, "head"], separator)
204204 }
205205
206206
207207 func keyListSize (listName) = {
208208 let meta = if ((listName == poolsListName))
209209 then "%s%s"
210210 else "%s%s%s%s"
211211 makeString([meta, listName, "size"], separator)
212212 }
213213
214214
215215 func keyListPrev (listName,id) = {
216216 let meta = if ((listName == poolsListName))
217217 then "%s%s%s%s"
218218 else "%s%s%s%s%s"
219219 makeString([meta, listName, id, "prev"], separator)
220220 }
221221
222222
223223 func keyListNext (listName,id) = {
224224 let meta = if ((listName == poolsListName))
225225 then "%s%s%s%s"
226226 else "%s%s%s%s%s"
227227 makeString([meta, listName, id, "next"], separator)
228228 }
229229
230230
231231 func containsNode (listName,id) = {
232232 let headOrUnit = getString(this, keyListHead(listName))
233233 let prevOrUnit = getString(this, keyListPrev(listName, id))
234234 let nextOrUnit = getString(this, keyListNext(listName, id))
235235 if (if ((id == valueOrElse(headOrUnit, "")))
236236 then true
237237 else (prevOrUnit != unit))
238238 then true
239239 else (nextOrUnit != unit)
240240 }
241241
242242
243243 func insertNodeActions (listName,id) = {
244244 let headOrUnit = getString(this, keyListHead(listName))
245245 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
246246 let checkNode = if (!(containsNode(listName, id)))
247247 then true
248248 else throwErr("Node exists")
249249 if ((checkNode == checkNode))
250250 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
251251 then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
252252 else nil)) ++ [StringEntry(keyListHead(listName), id)])
253253 else throw("Strict value is not equal to itself.")
254254 }
255255
256256
257257 func deleteNodeActions (listName,id) = {
258258 let headOrUnit = getString(this, keyListHead(listName))
259259 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
260260 let prevOrUnit = getString(this, keyListPrev(listName, id))
261261 let nextOrUnit = getString(this, keyListNext(listName, id))
262262 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
263263 then (nextOrUnit != unit)
264264 else false)
265265 then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
266266 else if ((nextOrUnit != unit))
267267 then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
268268 else if ((prevOrUnit != unit))
269269 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
270270 else if ((id == valueOrElse(headOrUnit, "")))
271271 then [DeleteEntry(keyListHead(listName))]
272272 else throwErr(((("invalid node: " + listName) + ".") + id))))
273273 }
274274
275275
276276 func keyManagerVaultAddress () = "%s__managerVaultAddress"
277277
278278
279279 func keyManagerPublicKey () = "%s__managerPublicKey"
280280
281281
282282 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
283283 case s: String =>
284284 addressFromStringValue(s)
285285 case _ =>
286286 this
287287 }
288288
289289
290290 func managerPublicKeyOrUnit () = {
291291 let managerVaultAddress = getManagerVaultAddressOrThis()
292292 match getString(managerVaultAddress, keyManagerPublicKey()) {
293293 case s: String =>
294294 fromBase58String(s)
295295 case _: Unit =>
296296 unit
297297 case _ =>
298298 throw("Match error")
299299 }
300300 }
301301
302302
303303 func isManager (i) = match managerPublicKeyOrUnit() {
304304 case pk: ByteVector =>
305305 (i.callerPublicKey == pk)
306306 case _: Unit =>
307307 (i.caller == this)
308308 case _ =>
309309 throw("Match error")
310310 }
311311
312312
313313 func mustManager (i) = if (isManager(i))
314314 then true
315315 else throw("permission denied")
316316
317317
318318 func mustThis (i) = if ((i.caller == this))
319319 then true
320320 else throw("permission denied")
321321
322322
323323 @Callable(i)
324324 func getUserGwxAmountAtHeight (userAddress,targetHeight) = {
325325 let boostingContractAddress = valueOrErrorMessage(addressFromString(getStrOrFail(this, keyBoostingContract)), wrapErr("invalid boosting contract address"))
326326 $Tuple2(nil, {
327327 let @ = invoke(boostingContractAddress, "getUserGwxAmountAtHeightREADONLY", [userAddress, targetHeight], nil)
328328 if ($isInstanceOf(@, "Int"))
329329 then @
330330 else throw(($getType(@) + " couldn't be cast to Int"))
331331 })
332332 }
333333
334334
335335
336336 @Callable(i)
337337 func constructor (factoryContract,votingEmissionCandidateContract,boostingContract,stakingContract,epochLength) = {
338338 let checks = [mustManager(i), if ((addressFromString(factoryContract) != unit))
339339 then true
340340 else "invalid factory contract address", if ((addressFromString(votingEmissionCandidateContract) != unit))
341341 then true
342342 else "invalid voting emission candidate contract address", if ((addressFromString(boostingContract) != unit))
343343 then true
344344 else "invalid boosting contract address", if ((addressFromString(stakingContract) != unit))
345345 then true
346346 else "invalid staking contract address", if ((epochLength > 0))
347347 then true
348348 else throwErr("invalid epoch length")]
349349 if ((checks == checks))
350350 then $Tuple2([StringEntry(keyFactoryContract, factoryContract), StringEntry(keyVotingEmissionCandidateContract, votingEmissionCandidateContract), StringEntry(keyBoostingContract, boostingContract), StringEntry(keyStakingContract, stakingContract), IntegerEntry(keyEpochLength, epochLength)], unit)
351351 else throw("Strict value is not equal to itself.")
352352 }
353353
354354
355355
356356 @Callable(i)
357357 func create (amountAssetId,priceAssetId) = {
358358 let checks = [if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionCandidateContract), "")))
359359 then true
360360 else mustManager(i)]
361361 if ((checks == checks))
362362 then {
363363 let pool = $Tuple2(amountAssetId, priceAssetId)
364364 let inListActions = ([BooleanEntry(keyInList(pool), true)] ++ insertNodeActions(poolsListName, poolToString(pool)))
365365 let currentEpochIsNotDefined = (getInteger(this, keyCurrentEpoch) == unit)
366366 let startHeightActions = if (currentEpochIsNotDefined)
367367 then {
368368 let epoch = 0
369369 [IntegerEntry(keyCurrentEpoch, epoch), IntegerEntry(keyStartHeightByEpoch(epoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, height)]
370370 }
371371 else nil
372372 $Tuple2((inListActions ++ startHeightActions), unit)
373373 }
374374 else throw("Strict value is not equal to itself.")
375375 }
376376
377377
378378
379379 @Callable(i)
380380 func vote (amountAssetId,priceAssetId,amount) = {
381381 let pool = $Tuple2(amountAssetId, priceAssetId)
382382 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
383383 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
384384 let epochLength = getIntOrFail(this, keyEpochLength)
385385 let endHeight = (startHeight + epochLength)
386386 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
387387 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
388388 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
389389 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
390390 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
391391 let gwxAmountAtEndTotal = {
392392 let @ = invoke(this, "getUserGwxAmountAtHeight", [toBase58String(i.caller.bytes), endHeight], nil)
393393 if ($isInstanceOf(@, "Int"))
394394 then @
395395 else throw(($getType(@) + " couldn't be cast to Int"))
396396 }
397397 let available = (gwxAmountAtEndTotal - used)
398398 let newVote = (vote + amount)
399399 let wxEmission = checkWxEmissionPoolLabel(pool)
400400 let checks = [if ((getBoolean(keyInList(pool)) != unit))
401401 then true
402402 else throwErr("invalid assets"), if ((endHeight > height))
403403 then true
404404 else throwErr("invalid height"), if ((finalizationStageOrUnit == unit))
405405 then true
406406 else throwErr("finalization in progress"), if ((gwxAmountAtEndTotal > 0))
407407 then true
408408 else throwErr("you do not have gWX"), if (if ((amount > 0))
409409 then (available >= amount)
410410 else false)
411411 then true
412412 else throwErr("invalid amount"), if (wxEmission)
413413 then true
414414 else throwErr("pool hasn't WX_EMISSION label")]
415415 if ((checks == checks))
416416 then {
417417 let votesListName = getVotesListName(pool)
418418 let userAddressStr = toString(i.caller)
419419 let votesListActions = if (containsNode(votesListName, userAddressStr))
420420 then nil
421421 else insertNodeActions(votesListName, userAddressStr)
422422 $Tuple2(([IntegerEntry(keyUsed(i.caller, epoch), (used + amount)), IntegerEntry(keyVote(pool, i.caller, epoch), newVote), IntegerEntry(keyVotingResult(pool, epoch), (poolResult + amount)), IntegerEntry(keyTotalVotes(epoch), (totalVotes + amount))] ++ votesListActions), unit)
423423 }
424424 else throw("Strict value is not equal to itself.")
425425 }
426426
427427
428428
429429 @Callable(i)
430430 func cancelVote (amountAssetId,priceAssetId) = {
431431 let pool = $Tuple2(amountAssetId, priceAssetId)
432432 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
433433 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
434434 let epochLength = getIntOrFail(this, keyEpochLength)
435435 let endHeight = (startHeight + epochLength)
436436 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
437437 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
438438 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
439439 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
440440 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
441441 let checks = [if ((getBoolean(keyInList(pool)) != unit))
442442 then true
443443 else throwErr("invalid assets"), if ((endHeight > height))
444444 then true
445445 else throwErr("invalid height"), if ((finalizationStageOrUnit == unit))
446446 then true
447447 else throwErr("finalization in progress"), if ((vote > 0))
448448 then true
449449 else throwErr("no vote")]
450450 if ((checks == checks))
451451 then {
452452 let votesListName = getVotesListName(pool)
453453 let userAddressStr = toString(i.caller)
454454 $Tuple2(([IntegerEntry(keyUsed(i.caller, epoch), max([(used - vote), 0])), DeleteEntry(keyVote(pool, i.caller, epoch)), IntegerEntry(keyVotingResult(pool, epoch), (poolResult - vote)), IntegerEntry(keyTotalVotes(epoch), (totalVotes - vote))] ++ deleteNodeActions(votesListName, userAddressStr)), unit)
455455 }
456456 else throw("Strict value is not equal to itself.")
457457 }
458458
459459
460460
461461 @Callable(i)
462462 func setEpochLength (newEpochLength) = {
463463 let checks = [mustManager(i), if ((newEpochLength > 0))
464464 then true
465465 else throwErr("invalid epoch length")]
466466 if ((checks == checks))
467467 then $Tuple2([IntegerEntry(keyEpochLengthNew, newEpochLength)], unit)
468468 else throw("Strict value is not equal to itself.")
469469 }
470470
471471
472472
473473 @Callable(i)
474474 func setMaxDepth (newMaxDepth) = {
475475 let checks = [mustManager(i), if ((newMaxDepth > 0))
476476 then true
477477 else throwErr("invalid max depth")]
478478 if ((checks == checks))
479479 then $Tuple2([IntegerEntry(keyMaxDepth, newMaxDepth)], unit)
480480 else throw("Strict value is not equal to itself.")
481481 }
482482
483483
484484
485485 @Callable(i)
486486 func processVoteINTERNAL (poolStr,userAddressStr) = {
487487 let checkCaller = mustThis(i)
488488 if ((checkCaller == checkCaller))
489489 then {
490490 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr(("processVoteINTERNAL: invalid user address " + userAddressStr)))
491491 let epoch = getIntOrFail(this, keyCurrentEpoch)
492492 let epochPrevious = (epoch - 1)
493493 let epochLength = getIntOrFail(this, keyEpochLength)
494494 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
495495 let endHeight = (startHeight + epochLength)
496496 let startHeightPrevious = getIntOrFail(this, keyStartHeightByEpoch(epochPrevious))
497497 let epochLengthPrevious = getIntOrFail(this, keyEpochLengthByEpoch(epochPrevious))
498498 let endHeightPrevious = (startHeightPrevious + epochLengthPrevious)
499499 let checkTargetEpoch = if ((epochPrevious >= 0))
500500 then true
501501 else throwErr("processVoteINTERNAL: invalid previous epoch")
502502 if ((checkTargetEpoch == checkTargetEpoch))
503503 then {
504504 let pool = stringToPool(poolStr)
505505 let $t01797018010 = pool
506506 let amountAssetId = $t01797018010._1
507507 let priceAssetId = $t01797018010._2
508508 let wxEmission = checkWxEmissionPoolLabel(pool)
509509 let gwxAmountAtEndTotal = {
510510 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)
511511 if ($isInstanceOf(@, "Int"))
512512 then @
513513 else throw(($getType(@) + " couldn't be cast to Int"))
514514 }
515515 let gwxAmountAtEndTotalPrevious = {
516516 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeightPrevious], nil)
517517 if ($isInstanceOf(@, "Int"))
518518 then @
519519 else throw(($getType(@) + " couldn't be cast to Int"))
520520 }
521521 let totalVotes = valueOrElse(getInteger(keyTotalVotes(epoch)), 0)
522522 let votingResult = valueOrElse(getInteger(keyVotingResult(pool, epoch)), 0)
523523 let votePrevious = valueOrErrorMessage(getInteger(keyVote(pool, userAddress, epochPrevious)), wrapErr((((("processVoteINTERNAL " + poolStr) + " ") + userAddressStr) + ": no previous vote")))
524524 let used = valueOrElse(getInteger(this, keyUsed(userAddress, epoch)), 0)
525525 let lpAssetIdStr = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
526526 let votingResultStakedPrevious = valueOrElse(getInteger(keyVotingResultStaked(lpAssetIdStr, epochPrevious)), 0)
527527 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
528528 let stakedByUser = valueOrElse(getInteger(stakingContract, keyStakedByUser(lpAssetIdStr, userAddressStr)), 0)
529529 let votingResultStakedActions = if ((stakedByUser == 0))
530530 then nil
531531 else [IntegerEntry(keyVotingResultStaked(lpAssetIdStr, epochPrevious), (votingResultStakedPrevious + votePrevious))]
532532 let newVote = if ((gwxAmountAtEndTotalPrevious > 0))
533533 then fraction(votePrevious, gwxAmountAtEndTotal, gwxAmountAtEndTotalPrevious)
534534 else 0
535535 let actions = if (if ((newVote > 0))
536536 then wxEmission
537537 else false)
538538 then [IntegerEntry(keyVote(pool, userAddress, epoch), newVote), IntegerEntry(keyTotalVotes(epoch), (totalVotes + newVote)), IntegerEntry(keyVotingResult(pool, epoch), (votingResult + newVote)), IntegerEntry(keyUsed(userAddress, epoch), (used + newVote))]
539539 else deleteNodeActions(getVotesListName(pool), userAddressStr)
540540 $Tuple2((actions ++ votingResultStakedActions), unit)
541541 }
542542 else throw("Strict value is not equal to itself.")
543543 }
544544 else throw("Strict value is not equal to itself.")
545545 }
546546
547547
548548
549549 @Callable(i)
550550 func processPoolINTERNAL (poolStr,force) = {
551551 let checkCaller = mustThis(i)
552552 if ((checkCaller == checkCaller))
553553 then {
554554 let targetEpoch = {
555555 let currentEpoch = getIntOrFail(this, keyCurrentEpoch)
556556 if (force)
557557 then currentEpoch
558558 else (currentEpoch - 1)
559559 }
560560 let checkTargetEpoch = if ((targetEpoch >= 0))
561561 then true
562562 else throwErr("processPoolINTERNAL: invalid target epoch")
563563 if ((checkTargetEpoch == checkTargetEpoch))
564564 then {
565565 let pool = stringToPool(poolStr)
566566 let $t02036720407 = pool
567567 let amountAssetId = $t02036720407._1
568568 let priceAssetId = $t02036720407._2
569569 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
570570 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
571571 let r = {
572572 let @ = invoke(stakingContract, "usersListTraversal", [lpAssetId], nil)
573573 if ($isInstanceOf(@, "Boolean"))
574574 then @
575575 else throw(($getType(@) + " couldn't be cast to Boolean"))
576576 }
577577 if ((r == r))
578578 then if (r)
579579 then $Tuple2(nil, true)
580580 else {
581581 let wxEmission = checkWxEmissionPoolLabel(pool)
582582 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
583583 let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
584584 let share = if (if ((totalVotes == 0))
585585 then true
586586 else !(wxEmission))
587587 then 0
588588 else fraction(votingResult, poolWeightMult, totalVotes)
589589 let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
590590 if ((modifyWeightInv == modifyWeightInv))
591591 then {
592592 let poolsListActions = if (if (wxEmission)
593593 then true
594594 else force)
595595 then nil
596596 else ([DeleteEntry(keyInList(pool))] ++ deleteNodeActions(poolsListName, poolStr))
597597 $Tuple2(([IntegerEntry(keyPoolShare(pool, targetEpoch), share)] ++ poolsListActions), false)
598598 }
599599 else throw("Strict value is not equal to itself.")
600600 }
601601 else throw("Strict value is not equal to itself.")
602602 }
603603 else throw("Strict value is not equal to itself.")
604604 }
605605 else throw("Strict value is not equal to itself.")
606606 }
607607
608608
609609
610610 @Callable(i)
611611 func finalizeHelper () = {
612612 let force = valueOrElse(getBoolean(keyFinalizationShouldBeForced), false)
613613 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
614614 let previousEpoch = (epoch - 1)
615615 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
616616 let epochLength = getIntOrFail(this, keyEpochLength)
617617 let endHeight = (startHeight + epochLength)
618618 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
619619 if (if (if ((height >= endHeight))
620620 then (finalizationStageOrUnit == unit)
621621 else false)
622622 then !(force)
623623 else false)
624624 then {
625625 let newEpoch = (epoch + 1)
626626 let newEpochLengthOption = getInteger(this, keyEpochLengthNew)
627627 let newEpochLengthActions = match newEpochLengthOption {
628628 case newEpochLength: Int =>
629629 [IntegerEntry(keyEpochLength, newEpochLength), DeleteEntry(keyEpochLengthNew)]
630630 case _: Unit =>
631631 nil
632632 case _ =>
633633 throw("Match error")
634634 }
635635 $Tuple2(([IntegerEntry(keyStartHeightByEpoch(newEpoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpoch, newEpoch), IntegerEntry(keyFinalizationStage, finalizationStageTotal), IntegerEntry(keyEpochLengthByEpoch(epoch), epochLength)] ++ newEpochLengthActions), true)
636636 }
637637 else if (if (force)
638638 then (finalizationStageOrUnit == unit)
639639 else false)
640640 then $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares)], true)
641641 else if ((finalizationStageOrUnit == unit))
642642 then $Tuple2(nil, false)
643643 else if ((finalizationStageOrUnit == finalizationStageTotal))
644644 then {
645645 let poolOrUnit = getString(keyNextPool)
646646 let userOrUnit = getString(keyNextUser)
647647 match poolOrUnit {
648648 case _: Unit =>
649649 match getString(keyListHead(poolsListName)) {
650650 case _: Unit =>
651651 $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
652652 case poolsHeadStr: String =>
653653 $Tuple2([StringEntry(keyNextPool, poolsHeadStr)], true)
654654 case _ =>
655655 throw("Match error")
656656 }
657657 case poolStr: String =>
658658 let pool = stringToPool(poolStr)
659659 let nextUserOrUnit = match userOrUnit {
660660 case _: Unit =>
661661 getString(keyListHead(getVotesListName(pool)))
662662 case user: String =>
663663 let next = getString(keyListNext(getVotesListName(pool), user))
664664 if ((next == next))
665665 then {
666666 let processVoteInv = invoke(this, "processVoteINTERNAL", [poolStr, user], nil)
667667 if ((processVoteInv == processVoteInv))
668668 then next
669669 else throw("Strict value is not equal to itself.")
670670 }
671671 else throw("Strict value is not equal to itself.")
672672 case _ =>
673673 throw("Match error")
674674 }
675675 match nextUserOrUnit {
676676 case _: Unit =>
677677 let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
678678 match nextPoolOrUnit {
679679 case _: Unit =>
680680 $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
681681 case s: String =>
682682 $Tuple2([StringEntry(keyNextPool, s), DeleteEntry(keyNextUser)], true)
683683 case _ =>
684684 throw("Match error")
685685 }
686686 case nextUser: String =>
687687 $Tuple2([StringEntry(keyNextUser, nextUser)], true)
688688 case _ =>
689689 throw("Match error")
690690 }
691691 case _ =>
692692 throw("Match error")
693693 }
694694 }
695695 else if ((finalizationStageOrUnit == finalizationStageShares))
696696 then {
697697 let poolOrUnit = getString(keyNextPool)
698698 match poolOrUnit {
699699 case _: Unit =>
700700 match getString(keyListHead(poolsListName)) {
701701 case _: Unit =>
702702 let actions = if (force)
703703 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced)]
704704 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight)]
705705 let gwxRewardDepositInv = gwxRewardDeposit()
706706 if ((gwxRewardDepositInv == gwxRewardDepositInv))
707707 then $Tuple2(actions, true)
708708 else throw("Strict value is not equal to itself.")
709709 case nextPoolStr: String =>
710710 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
711711 case _ =>
712712 throw("Match error")
713713 }
714714 case poolStr: String =>
715715 let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
716716 if ((nextPoolOrUnit == nextPoolOrUnit))
717717 then {
718718 let r = {
719719 let @ = invoke(this, "processPoolINTERNAL", [poolStr, force], nil)
720720 if ($isInstanceOf(@, "Boolean"))
721721 then @
722722 else throw(($getType(@) + " couldn't be cast to Boolean"))
723723 }
724724 if ((r == r))
725725 then if (r)
726726 then $Tuple2(nil, true)
727727 else match nextPoolOrUnit {
728728 case _: Unit =>
729729 let actions = if (force)
730730 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced), DeleteEntry(keyNextPool)]
731731 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight), DeleteEntry(keyNextPool)]
732732 let gwxRewardDepositInv = gwxRewardDeposit()
733733 if ((gwxRewardDepositInv == gwxRewardDepositInv))
734734 then $Tuple2(actions, true)
735735 else throw("Strict value is not equal to itself.")
736736 case nextPoolStr: String =>
737737 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
738738 case _ =>
739739 throw("Match error")
740740 }
741741 else throw("Strict value is not equal to itself.")
742742 }
743743 else throw("Strict value is not equal to itself.")
744744 case _ =>
745745 throw("Match error")
746746 }
747747 }
748748 else throwErr("finalization is broken")
749749 }
750750
751751
752752
753753 @Callable(i)
754754 func finalizeWrapper (counter) = {
755755 let result = {
756756 let @ = invoke(this, "finalizeHelper", nil, nil)
757757 if ($isInstanceOf(@, "Boolean"))
758758 then @
759759 else throw(($getType(@) + " couldn't be cast to Boolean"))
760760 }
761761 if ((result == result))
762762 then if (!(result))
763763 then if ((counter == 0))
764764 then throwErr("Current voting is not over yet")
765765 else $Tuple2(nil, unit)
766766 else {
767767 let maxDepth = valueOrElse(getInteger(this, keyMaxDepth), maxDepthDefault)
768768 if ((maxDepth > counter))
769769 then {
770770 let inv = invoke(this, "finalizeWrapper", [(counter + 1)], nil)
771771 if ((inv == inv))
772772 then $Tuple2(nil, unit)
773773 else throw("Strict value is not equal to itself.")
774774 }
775775 else $Tuple2(nil, unit)
776776 }
777777 else throw("Strict value is not equal to itself.")
778778 }
779779
780780
781781
782782 @Callable(i)
783783 func finalize () = {
784784 let inv = invoke(this, "finalizeWrapper", [0], nil)
785785 if ((inv == inv))
786786 then $Tuple2(nil, unit)
787787 else throw("Strict value is not equal to itself.")
788788 }
789789
790790
791791
792792 @Callable(i)
793793 func containsNodeREADONLY (listName,id) = $Tuple2(nil, containsNode(listName, id))
794794
795795
796796
797797 @Callable(i)
798798 func insertNode (listName,id) = {
799799 let checkCaller = mustManager(i)
800800 if ((checkCaller == checkCaller))
801801 then $Tuple2(insertNodeActions(listName, id), unit)
802802 else throw("Strict value is not equal to itself.")
803803 }
804804
805805
806806
807807 @Callable(i)
808808 func deleteNode (listName,id) = {
809809 let checkCaller = mustManager(i)
810810 if ((checkCaller == checkCaller))
811811 then $Tuple2(deleteNodeActions(listName, id), unit)
812812 else throw("Strict value is not equal to itself.")
813813 }
814814
815815
816+
817+@Callable(i)
818+func isFinalizationInProgress () = {
819+ let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
820+ let finalizationInProgress = (finalizationStageOrUnit != unit)
821+ $Tuple2(nil, finalizationInProgress)
822+ }
823+
824+
816825 @Verifier(tx)
817826 func verify () = {
818827 let targetPublicKey = match managerPublicKeyOrUnit() {
819828 case pk: ByteVector =>
820829 pk
821830 case _: Unit =>
822831 tx.senderPublicKey
823832 case _ =>
824833 throw("Match error")
825834 }
826835 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
827836 }
828837

github/deemru/w8io/fabc49c 
69.02 ms