tx · 7kgLpjyXegDCmDuWXnPDFboirXWvnwiMqHX2pS7dR5fE

3Mp3nG9T5fKGziHW8mcCqx3jMFx3towh3WA:  -0.02100000 Waves

2022.10.20 11:14 [2280469] smart account 3Mp3nG9T5fKGziHW8mcCqx3jMFx3towh3WA > SELF 0.00000000 Waves

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

github/deemru/w8io/fabc49c 
62.29 ms