tx · 93a9EBkd3SmCa8cF1ZfSFe8UPdKSgs7tFysQnGqMwmAz

3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr:  -0.02200000 Waves

2023.05.10 14:13 [2571712] smart account 3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr > SELF 0.00000000 Waves

{ "type": 13, "id": "93a9EBkd3SmCa8cF1ZfSFe8UPdKSgs7tFysQnGqMwmAz", "fee": 2200000, "feeAssetId": null, "timestamp": 1683717178703, "version": 2, "chainId": 84, "sender": "3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr", "senderPublicKey": "GFbasS3jufhZkK4xR7tdTjjnP8K33KvJFEDHRtxXDkaJ", "proofs": [ "3u8RYHYnmTLYZ9teYYYn7ooXMEoBfnbG6R1mUFm1SBhSocUzvV9C2dybqgtV2wo4cWkjutyGC6rVfen7p4DPGpc4" ], "script": "base64:BgL9FAgCEgQKAggBEgcKBQgICAgBEgQKAggIEgUKAwgIARIECgIICBIDCgEBEgMKAQESBAoCCAgSBAoCCAQSABIDCgEBEgASBAoCCAgSBAoCCAgSBAoCCAgiCXNlcGFyYXRvciIOcG9vbFdlaWdodE11bHQiD21heERlcHRoRGVmYXVsdCIWZmluYWxpemF0aW9uU3RhZ2VUb3RhbCIXZmluYWxpemF0aW9uU3RhZ2VTaGFyZXMiDmtleUVwb2NoTGVuZ3RoIhFrZXlFcG9jaExlbmd0aE5ldyIVa2V5RXBvY2hMZW5ndGhCeUVwb2NoIgVlcG9jaCIPa2V5Q3VycmVudEVwb2NoIgtrZXlNYXhEZXB0aCIia2V5Vm90aW5nRW1pc3Npb25DYW5kaWRhdGVDb250cmFjdCISa2V5RmFjdG9yeUNvbnRyYWN0IhNrZXlCb29zdGluZ0NvbnRyYWN0IhJrZXlTdGFraW5nQ29udHJhY3QiFGtleUZpbmFsaXphdGlvblN0YWdlIgtrZXlOZXh0UG9vbCILa2V5TmV4dFVzZXIiDmtleVN0YXJ0SGVpZ2h0IhFrZXlDdXJyZW50RXBvY2hVaSIQa2V5U3RhcnRIZWlnaHRVaSIda2V5RmluYWxpemF0aW9uU2hvdWxkQmVGb3JjZWQiFWtleVN0YXJ0SGVpZ2h0QnlFcG9jaCIMa2V5RmluYWxpemVkIglrZXlJbkxpc3QiBHBvb2wiCyR0MDE2OTMxNzMzIg1hbW91bnRBc3NldElkIgxwcmljZUFzc2V0SWQiB2tleVVzZWQiB2FkZHJlc3MiB2tleVZvdGUiCyR0MDIwMDcyMDQ3Ig9rZXlWb3RpbmdSZXN1bHQiCyR0MDIyMjkyMjY5IhVrZXlWb3RpbmdSZXN1bHRTdGFrZWQiDGxwQXNzZXRJZFN0ciIMa2V5UG9vbFNoYXJlIgskdDAyNTkwMjYzMCINa2V5VG90YWxWb3RlcyIPa2V5U3Rha2VkQnlVc2VyIg51c2VyQWRkcmVzc1N0ciIHd3JhcEVyciIDbXNnIgh0aHJvd0VyciIOZ2V0VmFsdWVPckZhaWwiA2tleSIEdHlwZSIFZXJyb3IiByRtYXRjaDAiA3N0ciIDaW50IgxnZXRTdHJPckZhaWwiAUAiDGdldEludE9yRmFpbCIMcG9vbFRvU3RyaW5nIgxzdHJpbmdUb1Bvb2wiBXBhcnRzIhZnZXRMcEFzc2V0QnlQb29sQXNzZXRzIh9rZXlNYXBwaW5nc0Jhc2VBc3NldDJpbnRlcm5hbElkIgxiYXNlQXNzZXRTdHIiKWtleU1hcHBpbmdQb29sQXNzZXRzVG9Qb29sQ29udHJhY3RBZGRyZXNzIhhpbnRlcm5hbEFtb3VudEFzc2V0SWRTdHIiF2ludGVybmFsUHJpY2VBc3NldElkU3RyIh9rZXlNYXBwaW5nUG9vbENvbnRyYWN0VG9MUEFzc2V0IhNwb29sQ29udHJhY3RBZGRyZXNzIg9mYWN0b3J5Q29udHJhY3QiFWFtb3VudEFzc2V0SW50ZXJuYWxJZCIUcHJpY2VBc3NldEludGVybmFsSWQiCWxwQXNzZXRJZCIYY2hlY2tXeEVtaXNzaW9uUG9vbExhYmVsIgskdDA1MTY4NTIwOCINcG9vbHNMaXN0TmFtZSIQZ2V0Vm90ZXNMaXN0TmFtZSILJHQwNTUwOTU1NDkiC2tleUxpc3RIZWFkIghsaXN0TmFtZSIEbWV0YSILa2V5TGlzdFNpemUiC2tleUxpc3RQcmV2IgJpZCILa2V5TGlzdE5leHQiDGNvbnRhaW5zTm9kZSIKaGVhZE9yVW5pdCIKcHJldk9yVW5pdCIKbmV4dE9yVW5pdCIRaW5zZXJ0Tm9kZUFjdGlvbnMiCGxpc3RTaXplIgljaGVja05vZGUiEWRlbGV0ZU5vZGVBY3Rpb25zIhZrZXlNYW5hZ2VyVmF1bHRBZGRyZXNzIhNrZXlNYW5hZ2VyUHVibGljS2V5IhxnZXRNYW5hZ2VyVmF1bHRBZGRyZXNzT3JUaGlzIgFzIhZtYW5hZ2VyUHVibGljS2V5T3JVbml0IhNtYW5hZ2VyVmF1bHRBZGRyZXNzIglpc01hbmFnZXIiAWkiAnBrIgttdXN0TWFuYWdlciIIbXVzdFRoaXMiC3VzZXJBZGRyZXNzIgx0YXJnZXRIZWlnaHQiF2Jvb3N0aW5nQ29udHJhY3RBZGRyZXNzIh92b3RpbmdFbWlzc2lvbkNhbmRpZGF0ZUNvbnRyYWN0IhBib29zdGluZ0NvbnRyYWN0Ig9zdGFraW5nQ29udHJhY3QiC2Vwb2NoTGVuZ3RoIgZjaGVja3MiDWluTGlzdEFjdGlvbnMiGGN1cnJlbnRFcG9jaElzTm90RGVmaW5lZCISc3RhcnRIZWlnaHRBY3Rpb25zIgZhbW91bnQiC3N0YXJ0SGVpZ2h0IgllbmRIZWlnaHQiF2ZpbmFsaXphdGlvblN0YWdlT3JVbml0IgR1c2VkIgR2b3RlIgpwb29sUmVzdWx0Igp0b3RhbFZvdGVzIhNnd3hBbW91bnRBdEVuZFRvdGFsIglhdmFpbGFibGUiB25ld1ZvdGUiCnd4RW1pc3Npb24iDXZvdGVzTGlzdE5hbWUiEHZvdGVzTGlzdEFjdGlvbnMiDm5ld0Vwb2NoTGVuZ3RoIgtuZXdNYXhEZXB0aCIHcG9vbFN0ciILY2hlY2tDYWxsZXIiDWVwb2NoUHJldmlvdXMiE3N0YXJ0SGVpZ2h0UHJldmlvdXMiE2Vwb2NoTGVuZ3RoUHJldmlvdXMiEWVuZEhlaWdodFByZXZpb3VzIhBjaGVja1RhcmdldEVwb2NoIg0kdDAxNzU1MjE3NTkyIhtnd3hBbW91bnRBdEVuZFRvdGFsUHJldmlvdXMiDHZvdGluZ1Jlc3VsdCIMdm90ZVByZXZpb3VzIhp2b3RpbmdSZXN1bHRTdGFrZWRQcmV2aW91cyIMc3Rha2VkQnlVc2VyIhl2b3RpbmdSZXN1bHRTdGFrZWRBY3Rpb25zIgdhY3Rpb25zIgVmb3JjZSILdGFyZ2V0RXBvY2giDGN1cnJlbnRFcG9jaCINJHQwMTk5NDkxOTk4OSIBciIFc2hhcmUiD21vZGlmeVdlaWdodEludiIQcG9vbHNMaXN0QWN0aW9ucyINcHJldmlvdXNFcG9jaCIIbmV3RXBvY2giFG5ld0Vwb2NoTGVuZ3RoT3B0aW9uIhVuZXdFcG9jaExlbmd0aEFjdGlvbnMiCnBvb2xPclVuaXQiCnVzZXJPclVuaXQiByRtYXRjaDEiDHBvb2xzSGVhZFN0ciIObmV4dFVzZXJPclVuaXQiBHVzZXIiBG5leHQiDnByb2Nlc3NWb3RlSW52Ig5uZXh0UG9vbE9yVW5pdCIHJG1hdGNoMiIIbmV4dFVzZXIiC25leHRQb29sU3RyIgdjb3VudGVyIgZyZXN1bHQiCG1heERlcHRoIgNpbnYiAnR4IgZ2ZXJpZnkiD3RhcmdldFB1YmxpY0tleTgAAWECAl9fAAFiAIDC1y8AAWMACgABZAAAAAFlAAEAAWYJALkJAgkAzAgCAgIlcwkAzAgCAgtlcG9jaExlbmd0aAUDbmlsBQFhAAFnCQC5CQIJAMwIAgIEJXMlcwkAzAgCAhBlcG9jaExlbmd0aF9fbmV3BQNuaWwFAWEBAWgBAWkJALkJAgkAzAgCAgQlcyVkCQDMCAICC2Vwb2NoTGVuZ3RoCQDMCAIJAKQDAQUBaQUDbmlsBQFhAAFqCQC5CQIJAMwIAgICJXMJAMwIAgIMY3VycmVudEVwb2NoBQNuaWwFAWEAAWsJALkJAgkAzAgCAgIlcwkAzAgCAghtYXhEZXB0aAUDbmlsBQFhAAFsCQC5CQIJAMwIAgICJXMJAMwIAgIfdm90aW5nRW1pc3Npb25DYW5kaWRhdGVDb250cmFjdAUDbmlsBQFhAAFtCQC5CQIJAMwIAgICJXMJAMwIAgIPZmFjdG9yeUNvbnRyYWN0BQNuaWwFAWEAAW4JALkJAgkAzAgCAgIlcwkAzAgCAhBib29zdGluZ0NvbnRyYWN0BQNuaWwFAWEAAW8JALkJAgkAzAgCAgIlcwkAzAgCAg9zdGFraW5nQ29udHJhY3QFA25pbAUBYQABcAkAuQkCCQDMCAICAiVzCQDMCAICEWZpbmFsaXphdGlvblN0YWdlBQNuaWwFAWEAAXEJALkJAgkAzAgCAgIlcwkAzAgCAghuZXh0UG9vbAUDbmlsBQFhAAFyCQC5CQIJAMwIAgICJXMJAMwIAgIIbmV4dFVzZXIFA25pbAUBYQABcwkAuQkCCQDMCAICAiVzCQDMCAICC3N0YXJ0SGVpZ2h0BQNuaWwFAWEAAXQJALkJAgkAzAgCAgIlcwkAzAgCAg5jdXJyZW50RXBvY2hVaQUDbmlsBQFhAAF1CQC5CQIJAMwIAgICJXMJAMwIAgINc3RhcnRIZWlnaHRVaQUDbmlsBQFhAAF2CQC5CQIJAMwIAgICJXMJAMwIAgIFZm9yY2UFA25pbAUBYQEBdwEBaQkAuQkCCQDMCAICBCVzJWQJAMwIAgILc3RhcnRIZWlnaHQJAMwIAgkApAMBBQFpBQNuaWwFAWEBAXgBAWkJALkJAgkAzAgCAgQlcyVkCQDMCAICCWZpbmFsaXplZAkAzAgCCQCkAwEFAWkFA25pbAUBYQEBeQEBegQBQQUBegQBQggFAUECXzEEAUMIBQFBAl8yCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICBmluTGlzdAkAzAgCBQFCCQDMCAIFAUMFA25pbAUBYQEBRAIBRQFpCQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICBHVzZWQJAMwIAgkApQgBBQFFCQDMCAIJAKQDAQUBaQUDbmlsBQFhAQFGAwF6AUUBaQQBRwUBegQBQggFAUcCXzEEAUMIBQFHAl8yCQC5CQIJAMwIAgIKJXMlcyVzJXMlZAkAzAgCAgR2b3RlCQDMCAIFAUIJAMwIAgUBQwkAzAgCCQClCAEFAUUJAMwIAgkApAMBBQFpBQNuaWwFAWEBAUgCAXoBaQQBSQUBegQBQggFAUkCXzEEAUMIBQFJAl8yCQC5CQIJAMwIAgIIJXMlcyVzJWQJAMwIAgIMdm90aW5nUmVzdWx0CQDMCAIFAUIJAMwIAgUBQwkAzAgCCQCkAwEFAWkFA25pbAUBYQEBSgIBSwFpCQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICEnZvdGluZ1Jlc3VsdFN0YWtlZAkAzAgCBQFLCQDMCAIJAKQDAQUBaQUDbmlsBQFhAQFMAgF6AWkEAU0FAXoEAUIIBQFNAl8xBAFDCAUBTQJfMgkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICCXBvb2xTaGFyZQkAzAgCBQFCCQDMCAIFAUMJAMwIAgkApAMBBQFpBQNuaWwFAWEBAU4BAWkJALkJAgkAzAgCAgQlcyVkCQDMCAICCnRvdGFsVm90ZXMJAMwIAgkApAMBBQFpBQNuaWwFAWEBAU8CAUsBUAkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgZzdGFrZWQJAMwIAgUBUAkAzAgCBQFLBQNuaWwFAWEBAVEBAVIJALkJAgkAzAgCAhV2b3RpbmdfZW1pc3Npb24ucmlkZToJAMwIAgUBUgUDbmlsAgEgAQFTAQFSCQACAQkBAVEBBQFSAQFUAwFFAVUBVgQBVwkBAVEBCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAUUJAMwIAgIBLgkAzAgCBQFVCQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgQBWAUBVgMJAAECBQFYAgZTdHJpbmcEAVkFAVgJAJ0IAgUBRQUBVQMJAAECBQFYAgNJbnQEAVoFAVgJAJoIAgUBRQUBVQkBAVMBAhJpbnZhbGlkIGVudHJ5IHR5cGUFAVcBAmFhAgFFAVUKAAJhYgkBAVQDBQFFBQFVAgADCQABAgUCYWICBlN0cmluZwUCYWIJAAIBCQCsAgIJAAMBBQJhYgIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nAQJhYwIBRQFVCgACYWIJAQFUAwUBRQUBVQAAAwkAAQIFAmFiAgNJbnQFAmFiCQACAQkArAICCQADAQUCYWICGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAECYWQBAXoJAKwCAgkArAICCAUBegJfMQUBYQgFAXoCXzIBAmFlAQFZBAJhZgkAtQkCBQFZBQFhAwkAAAIJAJADAQUCYWYAAgkAlAoCCQCRAwIFAmFmAAAJAJEDAgUCYWYAAQkBAVMBAhNpbnZhbGlkIHBvb2wgc3RyaW5nAQJhZwIBQgFDCgECYWgBAmFpCQCsAgICKCVzJXMlc19fbWFwcGluZ3NfX2Jhc2VBc3NldDJpbnRlcm5hbElkX18FAmFpCgECYWoCAmFrAmFsCQCsAgIJAKwCAgkArAICCQCsAgICCiVkJWQlcyVzX18JAKQDAQUCYWsCAl9fCQCkAwEFAmFsAiNfX21hcHBpbmdzX19wb29sQXNzZXRzMlBvb2xDb250cmFjdAoBAmFtAQJhbgkArAICCQCsAgICCCVzJXMlc19fBQJhbgIgX19tYXBwaW5nc19fcG9vbENvbnRyYWN0MkxwQXNzZXQEAmFvCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYWECBQR0aGlzBQFtBAJhcAkBAmFjAgUCYW8JAQJhaAEFAUIEAmFxCQECYWMCBQJhbwkBAmFoAQUBQwQCYW4JAQJhYQIFAmFvCQECYWoCBQJhcAUCYXEEAmFyCQECYWECBQJhbwkBAmFtAQUCYW4FAmFyAQJhcwEBegQCYXQFAXoEAUIIBQJhdAJfMQQBQwgFAmF0Al8yBAJhbwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFhAgUEdGhpcwUBbQoAAmFiCQD8BwQFAmFvAhhjaGVja1d4RW1pc3Npb25Qb29sTGFiZWwJAMwIAgUBQgkAzAgCBQFDBQNuaWwFA25pbAMJAAECBQJhYgIHQm9vbGVhbgUCYWIJAAIBCQCsAgIJAAMBBQJhYgIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgACYXUCBXBvb2xzAQJhdgEBegQCYXcFAXoEAUIIBQJhdwJfMQQBQwgFAmF3Al8yCQC5CQIJAMwIAgIFdm90ZXMJAMwIAgUBQgkAzAgCBQFDBQNuaWwFAWEBAmF4AQJheQQCYXoDCQAAAgUCYXkFAmF1AgQlcyVzAgglcyVzJXMlcwkAuQkCCQDMCAIFAmF6CQDMCAIFAmF5CQDMCAICBGhlYWQFA25pbAUBYQECYUEBAmF5BAJhegMJAAACBQJheQUCYXUCBCVzJXMCCCVzJXMlcyVzCQC5CQIJAMwIAgUCYXoJAMwIAgUCYXkJAMwIAgIEc2l6ZQUDbmlsBQFhAQJhQgICYXkCYUMEAmF6AwkAAAIFAmF5BQJhdQIIJXMlcyVzJXMCCiVzJXMlcyVzJXMJALkJAgkAzAgCBQJhegkAzAgCBQJheQkAzAgCBQJhQwkAzAgCAgRwcmV2BQNuaWwFAWEBAmFEAgJheQJhQwQCYXoDCQAAAgUCYXkFAmF1AgglcyVzJXMlcwIKJXMlcyVzJXMlcwkAuQkCCQDMCAIFAmF6CQDMCAIFAmF5CQDMCAIFAmFDCQDMCAICBG5leHQFA25pbAUBYQECYUUCAmF5AmFDBAJhRgkAnQgCBQR0aGlzCQECYXgBBQJheQQCYUcJAJ0IAgUEdGhpcwkBAmFCAgUCYXkFAmFDBAJhSAkAnQgCBQR0aGlzCQECYUQCBQJheQUCYUMDAwkAAAIFAmFDCQELdmFsdWVPckVsc2UCBQJhRgIABgkBAiE9AgUCYUcFBHVuaXQGCQECIT0CBQJhSAUEdW5pdAECYUkCAmF5AmFDBAJhRgkAnQgCBQR0aGlzCQECYXgBBQJheQQCYUoJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmFBAQUCYXkAAAQCYUsDCQEBIQEJAQJhRQIFAmF5BQJhQwYJAQFTAQILTm9kZSBleGlzdHMDCQAAAgUCYUsFAmFLCQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFBAQUCYXkJAGQCBQJhSgABBQNuaWwDCQECIT0CBQJhRgUEdW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQECYUQCBQJheQUCYUMJAQV2YWx1ZQEFAmFGCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhQgIFAmF5CQEFdmFsdWUBBQJhRgUCYUMFA25pbAUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJheAEFAmF5BQJhQwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJhTAICYXkCYUMEAmFGCQCdCAIFBHRoaXMJAQJheAEFAmF5BAJhSgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYUEBBQJheQAABAJhRwkAnQgCBQR0aGlzCQECYUICBQJheQUCYUMEAmFICQCdCAIFBHRoaXMJAQJhRAIFAmF5BQJhQwkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYUEBBQJheQkAZQIFAmFKAAEFA25pbAMDCQECIT0CBQJhRwUEdW5pdAkBAiE9AgUCYUgFBHVuaXQHCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhRAIFAmF5CQEFdmFsdWUBBQJhRwkBBXZhbHVlAQUCYUgJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFCAgUCYXkJAQV2YWx1ZQEFAmFICQEFdmFsdWUBBQJhRwkAzAgCCQELRGVsZXRlRW50cnkBCQECYUICBQJheQUCYUMJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFEAgUCYXkFAmFDBQNuaWwDCQECIT0CBQJhSAUEdW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQECYXgBBQJheQkBBXZhbHVlAQUCYUgJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFEAgUCYXkFAmFDCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhQgIFAmF5CQEFdmFsdWUBBQJhSAUDbmlsAwkBAiE9AgUCYUcFBHVuaXQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFCAgUCYXkFAmFDCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhRAIFAmF5CQEFdmFsdWUBBQJhRwUDbmlsAwkAAAIFAmFDCQELdmFsdWVPckVsc2UCBQJhRgIACQDMCAIJAQtEZWxldGVFbnRyeQEJAQJheAEFAmF5BQNuaWwJAQFTAQkArAICCQCsAgIJAKwCAgIOaW52YWxpZCBub2RlOiAFAmF5AgEuBQJhQwECYU0AAhclc19fbWFuYWdlclZhdWx0QWRkcmVzcwECYU4AAhQlc19fbWFuYWdlclB1YmxpY0tleQECYU8ABAFYCQCiCAEJAQJhTQADCQABAgUBWAIGU3RyaW5nBAJhUAUBWAkBEUBleHRyTmF0aXZlKDEwNjIpAQUCYVAFBHRoaXMBAmFRAAQCYVIJAQJhTwAEAVgJAJ0IAgUCYVIJAQJhTgADCQABAgUBWAIGU3RyaW5nBAJhUAUBWAkA2QQBBQJhUAMJAAECBQFYAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmFTAQJhVAQBWAkBAmFRAAMJAAECBQFYAgpCeXRlVmVjdG9yBAJhVQUBWAkAAAIIBQJhVA9jYWxsZXJQdWJsaWNLZXkFAmFVAwkAAQIFAVgCBFVuaXQJAAACCAUCYVQGY2FsbGVyBQR0aGlzCQACAQILTWF0Y2ggZXJyb3IBAmFWAQJhVAMJAQJhUwEFAmFUBgkAAgECEXBlcm1pc3Npb24gZGVuaWVkAQJhVwECYVQDCQAAAggFAmFUBmNhbGxlcgUEdGhpcwYJAAIBAhFwZXJtaXNzaW9uIGRlbmllZA8CYVQBGGdldFVzZXJHd3hBbW91bnRBdEhlaWdodAICYVgCYVkEAmFaCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBAmFhAgUEdGhpcwUBbgkBAVEBAiFpbnZhbGlkIGJvb3N0aW5nIGNvbnRyYWN0IGFkZHJlc3MJAJQKAgUDbmlsCgACYWIJAPwHBAUCYVoCIGdldFVzZXJHd3hBbW91bnRBdEhlaWdodFJFQURPTkxZCQDMCAIFAmFYCQDMCAIFAmFZBQNuaWwFA25pbAMJAAECBQJhYgIDSW50BQJhYgkAAgEJAKwCAgkAAwEFAmFiAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQCYVQBC2NvbnN0cnVjdG9yBQJhbwJiYQJiYgJiYwJiZAQCYmUJAMwIAgkBAmFWAQUCYVQJAMwIAgMJAQIhPQIJAKYIAQUCYW8FBHVuaXQGAiBpbnZhbGlkIGZhY3RvcnkgY29udHJhY3QgYWRkcmVzcwkAzAgCAwkBAiE9AgkApggBBQJiYQUEdW5pdAYCMmludmFsaWQgdm90aW5nIGVtaXNzaW9uIGNhbmRpZGF0ZSBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQECIT0CCQCmCAEFAmJiBQR1bml0BgIhaW52YWxpZCBib29zdGluZyBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQECIT0CCQCmCAEFAmJjBQR1bml0BgIgaW52YWxpZCBzdGFraW5nIGNvbnRyYWN0IGFkZHJlc3MJAMwIAgMJAGYCBQJiZAAABgkBAVMBAhRpbnZhbGlkIGVwb2NoIGxlbmd0aAUDbmlsAwkAAAIFAmJlBQJiZQkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAW0FAmFvCQDMCAIJAQtTdHJpbmdFbnRyeQIFAWwFAmJhCQDMCAIJAQtTdHJpbmdFbnRyeQIFAW4FAmJiCQDMCAIJAQtTdHJpbmdFbnRyeQIFAW8FAmJjCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFmBQJiZAUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFUAQZjcmVhdGUCAUIBQwQCYmUJAMwIAgMJAAACCQDYBAEICAUCYVQGY2FsbGVyBWJ5dGVzCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAWwCAAYJAQJhVgEFAmFUBQNuaWwDCQAAAgUCYmUFAmJlBAF6CQCUCgIFAUIFAUMEAmJmCQDOCAIJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAQF5AQUBegYFA25pbAkBAmFJAgUCYXUJAQJhZAEFAXoEAmJnCQAAAgkAmggCBQR0aGlzBQFqBQR1bml0BAJiaAMFAmJnBAFpAAAJAMwIAgkBDEludGVnZXJFbnRyeQIFAWoFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIJAQF3AQUBaQUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFzBQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFAXQFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIFAXUFBmhlaWdodAUDbmlsBQNuaWwJAJQKAgkAzggCBQJiZgUCYmgFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYVQBBHZvdGUDAUIBQwJiaQQBegkAlAoCBQFCBQFDBAFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWoAAAQCYmoJAQJhYwIFBHRoaXMJAQF3AQUBaQQCYmQJAQJhYwIFBHRoaXMFAWYEAmJrCQBkAgUCYmoFAmJkBAJibAkAmggCBQR0aGlzBQFwBAJibQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBRAIIBQJhVAZjYWxsZXIFAWkAAAQCYm4JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUYDBQF6CAUCYVQGY2FsbGVyBQFpAAAEAmJvCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFIAgUBegUBaQAABAJicAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBTgEFAWkAAAQCYnEKAAJhYgkA/AcEBQR0aGlzAhhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQJAMwIAgkA2AQBCAgFAmFUBmNhbGxlcgVieXRlcwkAzAgCBQJiawUDbmlsBQNuaWwDCQABAgUCYWICA0ludAUCYWIJAAIBCQCsAgIJAAMBBQJhYgIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50BAJicgkAZQIFAmJxBQJibQQCYnMJAGQCBQJibgUCYmkEAmJ0CQECYXMBBQF6BAJiZQkAzAgCAwkBAiE9AgkAoAgBCQEBeQEFAXoFBHVuaXQGCQEBUwECDmludmFsaWQgYXNzZXRzCQDMCAIDCQBmAgUCYmsFBmhlaWdodAYJAQFTAQIOaW52YWxpZCBoZWlnaHQJAMwIAgMJAAACBQJibAUEdW5pdAYJAQFTAQIYZmluYWxpemF0aW9uIGluIHByb2dyZXNzCQDMCAIDCQBmAgUCYnEAAAYJAQFTAQITeW91IGRvIG5vdCBoYXZlIGdXWAkAzAgCAwMJAGYCBQJiaQAACQBnAgUCYnIFAmJpBwYJAQFTAQIOaW52YWxpZCBhbW91bnQJAMwIAgMFAmJ0BgkBAVMBAh1wb29sIGhhc24ndCBXWF9FTUlTU0lPTiBsYWJlbAUDbmlsAwkAAAIFAmJlBQJiZQQCYnUJAQJhdgEFAXoEAVAJAKUIAQgFAmFUBmNhbGxlcgQCYnYDCQECYUUCBQJidQUBUAUDbmlsCQECYUkCBQJidQUBUAkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFEAggFAmFUBmNhbGxlcgUBaQkAZAIFAmJtBQJiaQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUYDBQF6CAUCYVQGY2FsbGVyBQFpBQJicwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUgCBQF6BQFpCQBkAgUCYm8FAmJpCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBTgEFAWkJAGQCBQJicAUCYmkFA25pbAUCYnYFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYVQBCmNhbmNlbFZvdGUCAUIBQwQBegkAlAoCBQFCBQFDBAFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWoAAAQCYmoJAQJhYwIFBHRoaXMJAQF3AQUBaQQCYmQJAQJhYwIFBHRoaXMFAWYEAmJrCQBkAgUCYmoFAmJkBAJibAkAmggCBQR0aGlzBQFwBAJibQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBRAIIBQJhVAZjYWxsZXIFAWkAAAQCYm4JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUYDBQF6CAUCYVQGY2FsbGVyBQFpAAAEAmJvCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFIAgUBegUBaQAABAJicAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBTgEFAWkAAAQCYmUJAMwIAgMJAQIhPQIJAKAIAQkBAXkBBQF6BQR1bml0BgkBAVMBAg5pbnZhbGlkIGFzc2V0cwkAzAgCAwkAZgIFAmJrBQZoZWlnaHQGCQEBUwECDmludmFsaWQgaGVpZ2h0CQDMCAIDCQAAAgUCYmwFBHVuaXQGCQEBUwECGGZpbmFsaXphdGlvbiBpbiBwcm9ncmVzcwkAzAgCAwkAZgIFAmJuAAAGCQEBUwECB25vIHZvdGUFA25pbAMJAAACBQJiZQUCYmUEAmJ1CQECYXYBBQF6BAFQCQClCAEIBQJhVAZjYWxsZXIJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBRAIIBQJhVAZjYWxsZXIFAWkJAJYDAQkAzAgCCQBlAgUCYm0FAmJuCQDMCAIAAAUDbmlsCQDMCAIJAQtEZWxldGVFbnRyeQEJAQFGAwUBeggFAmFUBmNhbGxlcgUBaQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUgCBQF6BQFpCQBlAgUCYm8FAmJuCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBTgEFAWkJAGUCBQJicAUCYm4FA25pbAkBAmFMAgUCYnUFAVAFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYVQBDnNldEVwb2NoTGVuZ3RoAQJidwQCYmUJAMwIAgkBAmFWAQUCYVQJAMwIAgMJAGYCBQJidwAABgkBAVMBAhRpbnZhbGlkIGVwb2NoIGxlbmd0aAUDbmlsAwkAAAIFAmJlBQJiZQkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFnBQJidwUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFUAQtzZXRNYXhEZXB0aAECYngEAmJlCQDMCAIJAQJhVgEFAmFUCQDMCAIDCQBmAgUCYngAAAYJAQFTAQIRaW52YWxpZCBtYXggZGVwdGgFA25pbAMJAAACBQJiZQUCYmUJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBawUCYngFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhVAETcHJvY2Vzc1ZvdGVJTlRFUk5BTAICYnkBUAQCYnoJAQJhVwEFAmFUAwkAAAIFAmJ6BQJiegQCYVgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQFQCQEBUQEJAKwCAgIqcHJvY2Vzc1ZvdGVJTlRFUk5BTDogaW52YWxpZCB1c2VyIGFkZHJlc3MgBQFQBAFpCQECYWMCBQR0aGlzBQFqBAJiQQkAZQIFAWkAAQQCYmQJAQJhYwIFBHRoaXMFAWYEAmJqCQECYWMCBQR0aGlzCQEBdwEFAWkEAmJrCQBkAgUCYmoFAmJkBAJiQgkBAmFjAgUEdGhpcwkBAXcBBQJiQQQCYkMJAQJhYwIFBHRoaXMJAQFoAQUCYkEEAmJECQBkAgUCYkIFAmJDBAJiRQMJAGcCBQJiQQAABgkBAVMBAitwcm9jZXNzVm90ZUlOVEVSTkFMOiBpbnZhbGlkIHByZXZpb3VzIGVwb2NoAwkAAAIFAmJFBQJiRQQBegkBAmFlAQUCYnkEAmJGBQF6BAFCCAUCYkYCXzEEAUMIBQJiRgJfMgQCYnQJAQJhcwEFAXoEAmJxCgACYWIJAPwHBAUEdGhpcwIYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0CQDMCAIFAVAJAMwIAgUCYmsFA25pbAUDbmlsAwkAAQIFAmFiAgNJbnQFAmFiCQACAQkArAICCQADAQUCYWICGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAQCYkcKAAJhYgkA/AcEBQR0aGlzAhhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQJAMwIAgUBUAkAzAgCBQJiRAUDbmlsBQNuaWwDCQABAgUCYWICA0ludAUCYWIJAAIBCQCsAgIJAAMBBQJhYgIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50BAJicAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEBTgEFAWkAAAQCYkgJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAUgCBQF6BQFpAAAEAmJJCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQkBAUYDBQF6BQJhWAUCYkEJAQFRAQkArAICCQCsAgIJAKwCAgkArAICAhRwcm9jZXNzVm90ZUlOVEVSTkFMIAUCYnkCASAFAVACEjogbm8gcHJldmlvdXMgdm90ZQQCYm0JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUQCBQJhWAUBaQAABAFLCQECYWcCBQFCBQFDBAJiSgkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEBSgIFAUsFAmJBAAAEAmJjCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYWECBQR0aGlzBQFvBAJiSwkBC3ZhbHVlT3JFbHNlAgkAmggCBQJiYwkBAU8CBQFLBQFQAAAEAmJMAwkAAAIFAmJLAAAFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUoCBQFLBQJiQQkAZAIFAmJKBQJiSQUDbmlsBAJicwMJAGYCBQJiRwAACQBrAwUCYkkFAmJxBQJiRwAABAJiTQMDCQBmAgUCYnMAAAUCYnQHCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBRgMFAXoFAmFYBQFpBQJicwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAU4BBQFpCQBkAgUCYnAFAmJzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBSAIFAXoFAWkJAGQCBQJiSAUCYnMJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFEAgUCYVgFAWkJAGQCBQJibQUCYnMFA25pbAkBAmFMAgkBAmF2AQUBegUBUAkAlAoCCQDOCAIFAmJNBQJiTAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhVAETcHJvY2Vzc1Bvb2xJTlRFUk5BTAICYnkCYk4EAmJ6CQECYVcBBQJhVAMJAAACBQJiegUCYnoEAmJPBAJiUAkBAmFjAgUEdGhpcwUBagMFAmJOBQJiUAkAZQIFAmJQAAEEAmJFAwkAZwIFAmJPAAAGCQEBUwECKXByb2Nlc3NQb29sSU5URVJOQUw6IGludmFsaWQgdGFyZ2V0IGVwb2NoAwkAAAIFAmJFBQJiRQQBegkBAmFlAQUCYnkEAmJRBQF6BAFCCAUCYlECXzEEAUMIBQJiUQJfMgQCYmMJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQJhYQIFBHRoaXMFAW8EAmFvCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYWECBQR0aGlzBQFtBAJhcgkBAmFnAgUBQgUBQwQCYlIKAAJhYgkA/AcEBQJiYwISdXNlcnNMaXN0VHJhdmVyc2FsCQDMCAIFAmFyBQNuaWwFA25pbAMJAAECBQJhYgIHQm9vbGVhbgUCYWIJAAIBCQCsAgIJAAMBBQJhYgIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgMJAAACBQJiUgUCYlIDBQJiUgkAlAoCBQNuaWwGBAJidAkBAmFzAQUBegQCYnAJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAU4BBQJiTwAABAJiSAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBSAIFAXoFAmJPAAAEAmJTAwMJAAACBQJicAAABgkBASEBBQJidAAACQBrAwUCYkgFAWIFAmJwBAJiVAkA/AcEBQJhbwIMbW9kaWZ5V2VpZ2h0CQDMCAIFAmFyCQDMCAIFAmJTBQNuaWwFA25pbAMJAAACBQJiVAUCYlQEAmJVAwMFAmJ0BgUCYk4FA25pbAkAzggCCQDMCAIJAQtEZWxldGVFbnRyeQEJAQF5AQUBegUDbmlsCQECYUwCBQJhdQUCYnkJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBTAIFAXoFAmJPBQJiUwUDbmlsBQJiVQcJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYVQBDmZpbmFsaXplSGVscGVyAAQCYk4JAQt2YWx1ZU9yRWxzZQIJAKAIAQUBdgcEAWkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBagAABAJiVgkAZQIFAWkAAQQCYmoJAQJhYwIFBHRoaXMJAQF3AQUBaQQCYmQJAQJhYwIFBHRoaXMFAWYEAmJrCQBkAgUCYmoFAmJkBAJibAkAmggCBQR0aGlzBQFwAwMDCQBnAgUGaGVpZ2h0BQJiawkAAAIFAmJsBQR1bml0BwkBASEBBQJiTgcEAmJXCQBkAgUBaQABBAJiWAkAmggCBQR0aGlzBQFnBAJiWQQBWAUCYlgDCQABAgUBWAIDSW50BAJidwUBWAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBZgUCYncJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBZwUDbmlsAwkAAQIFAVgCBFVuaXQFA25pbAkAAgECC01hdGNoIGVycm9yCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAXcBBQJiVwUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFzBQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFAWoFAmJXCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFwBQFkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBaAEFAWkFAmJkBQNuaWwFAmJZBgMDBQJiTgkAAAIFAmJsBQR1bml0BwkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFwBQFlBQNuaWwGAwkAAAIFAmJsBQR1bml0CQCUCgIFA25pbAcDCQAAAgUCYmwFAWQEAmJaCQCiCAEFAXEEAmNhCQCiCAEFAXIEAVgFAmJaAwkAAQIFAVgCBFVuaXQEAmNiCQCiCAEJAQJheAEFAmF1AwkAAQIFAmNiAgRVbml0CQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAXAFAWUJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcQkAzAgCCQELRGVsZXRlRW50cnkBBQFyBQNuaWwGAwkAAQIFAmNiAgZTdHJpbmcEAmNjBQJjYgkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXEFAmNjBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IDCQABAgUBWAIGU3RyaW5nBAJieQUBWAQBegkBAmFlAQUCYnkEAmNkBAJjYgUCY2EDCQABAgUCY2ICBFVuaXQJAKIIAQkBAmF4AQkBAmF2AQUBegMJAAECBQJjYgIGU3RyaW5nBAJjZQUCY2IEAmNmCQCiCAEJAQJhRAIJAQJhdgEFAXoFAmNlAwkAAAIFAmNmBQJjZgQCY2cJAPwHBAUEdGhpcwITcHJvY2Vzc1ZvdGVJTlRFUk5BTAkAzAgCBQJieQkAzAgCBQJjZQUDbmlsBQNuaWwDCQAAAgUCY2cFAmNnBQJjZgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECC01hdGNoIGVycm9yBAJjYgUCY2QDCQABAgUCY2ICBFVuaXQEAmNoCQCiCAEJAQJhRAIFAmF1BQJieQQCY2kFAmNoAwkAAQIFAmNpAgRVbml0CQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAXAFAWUJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcQkAzAgCCQELRGVsZXRlRW50cnkBBQFyBQNuaWwGAwkAAQIFAmNpAgZTdHJpbmcEAmFQBQJjaQkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXEFAmFQCQDMCAIJAQtEZWxldGVFbnRyeQEFAXIFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgMJAAECBQJjYgIGU3RyaW5nBAJjagUCY2IJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQFyBQJjagUDbmlsBgkAAgECC01hdGNoIGVycm9yCQACAQILTWF0Y2ggZXJyb3IDCQAAAgUCYmwFAWUEAmJaCQCiCAEFAXEEAVgFAmJaAwkAAQIFAVgCBFVuaXQEAmNiCQCiCAEJAQJheAEFAmF1AwkAAQIFAmNiAgRVbml0BAJiTQMFAmJOCQDMCAIJAQtEZWxldGVFbnRyeQEFAXAJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBdgUDbmlsCQDMCAIJAQtEZWxldGVFbnRyeQEFAXAJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAQF4AQUCYlYGCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF0BQFpCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF1BQJiagUDbmlsCQCUCgIFAmJNBgMJAAECBQJjYgIGU3RyaW5nBAJjawUCY2IJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQFxBQJjawUDbmlsBgkAAgECC01hdGNoIGVycm9yAwkAAQIFAVgCBlN0cmluZwQCYnkFAVgEAmNoCQCiCAEJAQJhRAIFAmF1BQJieQMJAAACBQJjaAUCY2gEAmJSCgACYWIJAPwHBAUEdGhpcwITcHJvY2Vzc1Bvb2xJTlRFUk5BTAkAzAgCBQJieQkAzAgCBQJiTgUDbmlsBQNuaWwDCQABAgUCYWICB0Jvb2xlYW4FAmFiCQACAQkArAICCQADAQUCYWICHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4DCQAAAgUCYlIFAmJSAwUCYlIJAJQKAgUDbmlsBgQCY2IFAmNoAwkAAQIFAmNiAgRVbml0BAJiTQMFAmJOCQDMCAIJAQtEZWxldGVFbnRyeQEFAXAJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBdgkAzAgCCQELRGVsZXRlRW50cnkBBQFxBQNuaWwJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcAkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBAXgBBQJiVgYJAMwIAgkBDEludGVnZXJFbnRyeQIFAXQFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIFAXUFAmJqCQDMCAIJAQtEZWxldGVFbnRyeQEFAXEFA25pbAkAlAoCBQJiTQYDCQABAgUCY2ICBlN0cmluZwQCY2sFAmNiCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBcQUCY2sFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECC01hdGNoIGVycm9yCQEBUwECFmZpbmFsaXphdGlvbiBpcyBicm9rZW4CYVQBD2ZpbmFsaXplV3JhcHBlcgECY2wEAmNtCgACYWIJAPwHBAUEdGhpcwIOZmluYWxpemVIZWxwZXIFA25pbAUDbmlsAwkAAQIFAmFiAgdCb29sZWFuBQJhYgkAAgEJAKwCAgkAAwEFAmFiAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuAwkAAAIFAmNtBQJjbQMJAQEhAQUCY20DCQAAAgUCY2wAAAkBAVMBAh5DdXJyZW50IHZvdGluZyBpcyBub3Qgb3ZlciB5ZXQJAJQKAgUDbmlsBQR1bml0BAJjbgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFrBQFjAwkAZgIFAmNuBQJjbAQCY28JAPwHBAUEdGhpcwIPZmluYWxpemVXcmFwcGVyCQDMCAIJAGQCBQJjbAABBQNuaWwFA25pbAMJAAACBQJjbwUCY28JAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhVAEIZmluYWxpemUABAJjbwkA/AcEBQR0aGlzAg9maW5hbGl6ZVdyYXBwZXIJAMwIAgAABQNuaWwFA25pbAMJAAACBQJjbwUCY28JAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFUARRjb250YWluc05vZGVSRUFET05MWQICYXkCYUMJAJQKAgUDbmlsCQECYUUCBQJheQUCYUMCYVQBCmluc2VydE5vZGUCAmF5AmFDBAJiegkBAmFWAQUCYVQDCQAAAgUCYnoFAmJ6CQCUCgIJAQJhSQIFAmF5BQJhQwUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhVAEKZGVsZXRlTm9kZQICYXkCYUMEAmJ6CQECYVYBBQJhVAMJAAACBQJiegUCYnoJAJQKAgkBAmFMAgUCYXkFAmFDBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJjcAECY3EABAJjcgQBWAkBAmFRAAMJAAECBQFYAgpCeXRlVmVjdG9yBAJhVQUBWAUCYVUDCQABAgUBWAIEVW5pdAgFAmNwD3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yCQD0AwMIBQJjcAlib2R5Qnl0ZXMJAJEDAggFAmNwBnByb29mcwAABQJjcqdopXI=", "height": 2571712, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 9M4xqTeAmwYzfc5FZbbjL8HiqyYjc6ppWA3BEg1Ymjrq Next: HjGqyxJs9QCdAWgkxTxzhgJ6CdBn6LedTwjXjm6Neh4t Diff:
OldNewDifferences
261261 func keyManagerPublicKey () = "%s__managerPublicKey"
262262
263263
264-func getManagerAddressOrFail () = addressFromStringValue(getStringValue(keyManagerVaultAddress()))
264+func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
265+ case s: String =>
266+ addressFromStringValue(s)
267+ case _ =>
268+ this
269+}
265270
266271
267272 func managerPublicKeyOrUnit () = {
268- let managerVaultAddress = getManagerAddressOrFail()
273+ let managerVaultAddress = getManagerVaultAddressOrThis()
269274 match getString(managerVaultAddress, keyManagerPublicKey()) {
270275 case s: String =>
271276 fromBase58String(s)
479484 if ((checkTargetEpoch == checkTargetEpoch))
480485 then {
481486 let pool = stringToPool(poolStr)
482- let $t01748817528 = pool
483- let amountAssetId = $t01748817528._1
484- let priceAssetId = $t01748817528._2
487+ let $t01755217592 = pool
488+ let amountAssetId = $t01755217592._1
489+ let priceAssetId = $t01755217592._2
485490 let wxEmission = checkWxEmissionPoolLabel(pool)
486491 let gwxAmountAtEndTotal = {
487492 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)
540545 if ((checkTargetEpoch == checkTargetEpoch))
541546 then {
542547 let pool = stringToPool(poolStr)
543- let $t01988519925 = pool
544- let amountAssetId = $t01988519925._1
545- let priceAssetId = $t01988519925._2
548+ let $t01994919989 = pool
549+ let amountAssetId = $t01994919989._1
550+ let priceAssetId = $t01994919989._2
546551 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
547552 let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
548553 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
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 func getLpAssetByPoolAssets (amountAssetId,priceAssetId) = {
144144 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
145145
146146 func keyMappingPoolAssetsToPoolContractAddress (internalAmountAssetIdStr,internalPriceAssetIdStr) = (((("%d%d%s%s__" + toString(internalAmountAssetIdStr)) + "__") + toString(internalPriceAssetIdStr)) + "__mappings__poolAssets2PoolContract")
147147
148148 func keyMappingPoolContractToLPAsset (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
149149
150150 let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
151151 let amountAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amountAssetId))
152152 let priceAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAssetId))
153153 let poolContractAddress = getStrOrFail(factoryContract, keyMappingPoolAssetsToPoolContractAddress(amountAssetInternalId, priceAssetInternalId))
154154 let lpAssetId = getStrOrFail(factoryContract, keyMappingPoolContractToLPAsset(poolContractAddress))
155155 lpAssetId
156156 }
157157
158158
159159 func checkWxEmissionPoolLabel (pool) = {
160160 let $t051685208 = pool
161161 let amountAssetId = $t051685208._1
162162 let priceAssetId = $t051685208._2
163163 let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
164164 let @ = invoke(factoryContract, "checkWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil)
165165 if ($isInstanceOf(@, "Boolean"))
166166 then @
167167 else throw(($getType(@) + " couldn't be cast to Boolean"))
168168 }
169169
170170
171171 let poolsListName = "pools"
172172
173173 func getVotesListName (pool) = {
174174 let $t055095549 = pool
175175 let amountAssetId = $t055095549._1
176176 let priceAssetId = $t055095549._2
177177 makeString(["votes", amountAssetId, priceAssetId], separator)
178178 }
179179
180180
181181 func keyListHead (listName) = {
182182 let meta = if ((listName == poolsListName))
183183 then "%s%s"
184184 else "%s%s%s%s"
185185 makeString([meta, listName, "head"], separator)
186186 }
187187
188188
189189 func keyListSize (listName) = {
190190 let meta = if ((listName == poolsListName))
191191 then "%s%s"
192192 else "%s%s%s%s"
193193 makeString([meta, listName, "size"], separator)
194194 }
195195
196196
197197 func keyListPrev (listName,id) = {
198198 let meta = if ((listName == poolsListName))
199199 then "%s%s%s%s"
200200 else "%s%s%s%s%s"
201201 makeString([meta, listName, id, "prev"], separator)
202202 }
203203
204204
205205 func keyListNext (listName,id) = {
206206 let meta = if ((listName == poolsListName))
207207 then "%s%s%s%s"
208208 else "%s%s%s%s%s"
209209 makeString([meta, listName, id, "next"], separator)
210210 }
211211
212212
213213 func containsNode (listName,id) = {
214214 let headOrUnit = getString(this, keyListHead(listName))
215215 let prevOrUnit = getString(this, keyListPrev(listName, id))
216216 let nextOrUnit = getString(this, keyListNext(listName, id))
217217 if (if ((id == valueOrElse(headOrUnit, "")))
218218 then true
219219 else (prevOrUnit != unit))
220220 then true
221221 else (nextOrUnit != unit)
222222 }
223223
224224
225225 func insertNodeActions (listName,id) = {
226226 let headOrUnit = getString(this, keyListHead(listName))
227227 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
228228 let checkNode = if (!(containsNode(listName, id)))
229229 then true
230230 else throwErr("Node exists")
231231 if ((checkNode == checkNode))
232232 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
233233 then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
234234 else nil)) ++ [StringEntry(keyListHead(listName), id)])
235235 else throw("Strict value is not equal to itself.")
236236 }
237237
238238
239239 func deleteNodeActions (listName,id) = {
240240 let headOrUnit = getString(this, keyListHead(listName))
241241 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
242242 let prevOrUnit = getString(this, keyListPrev(listName, id))
243243 let nextOrUnit = getString(this, keyListNext(listName, id))
244244 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
245245 then (nextOrUnit != unit)
246246 else false)
247247 then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
248248 else if ((nextOrUnit != unit))
249249 then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
250250 else if ((prevOrUnit != unit))
251251 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
252252 else if ((id == valueOrElse(headOrUnit, "")))
253253 then [DeleteEntry(keyListHead(listName))]
254254 else throwErr(((("invalid node: " + listName) + ".") + id))))
255255 }
256256
257257
258258 func keyManagerVaultAddress () = "%s__managerVaultAddress"
259259
260260
261261 func keyManagerPublicKey () = "%s__managerPublicKey"
262262
263263
264-func getManagerAddressOrFail () = addressFromStringValue(getStringValue(keyManagerVaultAddress()))
264+func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
265+ case s: String =>
266+ addressFromStringValue(s)
267+ case _ =>
268+ this
269+}
265270
266271
267272 func managerPublicKeyOrUnit () = {
268- let managerVaultAddress = getManagerAddressOrFail()
273+ let managerVaultAddress = getManagerVaultAddressOrThis()
269274 match getString(managerVaultAddress, keyManagerPublicKey()) {
270275 case s: String =>
271276 fromBase58String(s)
272277 case _: Unit =>
273278 unit
274279 case _ =>
275280 throw("Match error")
276281 }
277282 }
278283
279284
280285 func isManager (i) = match managerPublicKeyOrUnit() {
281286 case pk: ByteVector =>
282287 (i.callerPublicKey == pk)
283288 case _: Unit =>
284289 (i.caller == this)
285290 case _ =>
286291 throw("Match error")
287292 }
288293
289294
290295 func mustManager (i) = if (isManager(i))
291296 then true
292297 else throw("permission denied")
293298
294299
295300 func mustThis (i) = if ((i.caller == this))
296301 then true
297302 else throw("permission denied")
298303
299304
300305 @Callable(i)
301306 func getUserGwxAmountAtHeight (userAddress,targetHeight) = {
302307 let boostingContractAddress = valueOrErrorMessage(addressFromString(getStrOrFail(this, keyBoostingContract)), wrapErr("invalid boosting contract address"))
303308 $Tuple2(nil, {
304309 let @ = invoke(boostingContractAddress, "getUserGwxAmountAtHeightREADONLY", [userAddress, targetHeight], nil)
305310 if ($isInstanceOf(@, "Int"))
306311 then @
307312 else throw(($getType(@) + " couldn't be cast to Int"))
308313 })
309314 }
310315
311316
312317
313318 @Callable(i)
314319 func constructor (factoryContract,votingEmissionCandidateContract,boostingContract,stakingContract,epochLength) = {
315320 let checks = [mustManager(i), if ((addressFromString(factoryContract) != unit))
316321 then true
317322 else "invalid factory contract address", if ((addressFromString(votingEmissionCandidateContract) != unit))
318323 then true
319324 else "invalid voting emission candidate contract address", if ((addressFromString(boostingContract) != unit))
320325 then true
321326 else "invalid boosting contract address", if ((addressFromString(stakingContract) != unit))
322327 then true
323328 else "invalid staking contract address", if ((epochLength > 0))
324329 then true
325330 else throwErr("invalid epoch length")]
326331 if ((checks == checks))
327332 then $Tuple2([StringEntry(keyFactoryContract, factoryContract), StringEntry(keyVotingEmissionCandidateContract, votingEmissionCandidateContract), StringEntry(keyBoostingContract, boostingContract), StringEntry(keyStakingContract, stakingContract), IntegerEntry(keyEpochLength, epochLength)], unit)
328333 else throw("Strict value is not equal to itself.")
329334 }
330335
331336
332337
333338 @Callable(i)
334339 func create (amountAssetId,priceAssetId) = {
335340 let checks = [if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionCandidateContract), "")))
336341 then true
337342 else mustManager(i)]
338343 if ((checks == checks))
339344 then {
340345 let pool = $Tuple2(amountAssetId, priceAssetId)
341346 let inListActions = ([BooleanEntry(keyInList(pool), true)] ++ insertNodeActions(poolsListName, poolToString(pool)))
342347 let currentEpochIsNotDefined = (getInteger(this, keyCurrentEpoch) == unit)
343348 let startHeightActions = if (currentEpochIsNotDefined)
344349 then {
345350 let epoch = 0
346351 [IntegerEntry(keyCurrentEpoch, epoch), IntegerEntry(keyStartHeightByEpoch(epoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, height)]
347352 }
348353 else nil
349354 $Tuple2((inListActions ++ startHeightActions), unit)
350355 }
351356 else throw("Strict value is not equal to itself.")
352357 }
353358
354359
355360
356361 @Callable(i)
357362 func vote (amountAssetId,priceAssetId,amount) = {
358363 let pool = $Tuple2(amountAssetId, priceAssetId)
359364 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
360365 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
361366 let epochLength = getIntOrFail(this, keyEpochLength)
362367 let endHeight = (startHeight + epochLength)
363368 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
364369 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
365370 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
366371 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
367372 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
368373 let gwxAmountAtEndTotal = {
369374 let @ = invoke(this, "getUserGwxAmountAtHeight", [toBase58String(i.caller.bytes), endHeight], nil)
370375 if ($isInstanceOf(@, "Int"))
371376 then @
372377 else throw(($getType(@) + " couldn't be cast to Int"))
373378 }
374379 let available = (gwxAmountAtEndTotal - used)
375380 let newVote = (vote + amount)
376381 let wxEmission = checkWxEmissionPoolLabel(pool)
377382 let checks = [if ((getBoolean(keyInList(pool)) != unit))
378383 then true
379384 else throwErr("invalid assets"), if ((endHeight > height))
380385 then true
381386 else throwErr("invalid height"), if ((finalizationStageOrUnit == unit))
382387 then true
383388 else throwErr("finalization in progress"), if ((gwxAmountAtEndTotal > 0))
384389 then true
385390 else throwErr("you do not have gWX"), if (if ((amount > 0))
386391 then (available >= amount)
387392 else false)
388393 then true
389394 else throwErr("invalid amount"), if (wxEmission)
390395 then true
391396 else throwErr("pool hasn't WX_EMISSION label")]
392397 if ((checks == checks))
393398 then {
394399 let votesListName = getVotesListName(pool)
395400 let userAddressStr = toString(i.caller)
396401 let votesListActions = if (containsNode(votesListName, userAddressStr))
397402 then nil
398403 else insertNodeActions(votesListName, userAddressStr)
399404 $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)
400405 }
401406 else throw("Strict value is not equal to itself.")
402407 }
403408
404409
405410
406411 @Callable(i)
407412 func cancelVote (amountAssetId,priceAssetId) = {
408413 let pool = $Tuple2(amountAssetId, priceAssetId)
409414 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
410415 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
411416 let epochLength = getIntOrFail(this, keyEpochLength)
412417 let endHeight = (startHeight + epochLength)
413418 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
414419 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
415420 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
416421 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
417422 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
418423 let checks = [if ((getBoolean(keyInList(pool)) != unit))
419424 then true
420425 else throwErr("invalid assets"), if ((endHeight > height))
421426 then true
422427 else throwErr("invalid height"), if ((finalizationStageOrUnit == unit))
423428 then true
424429 else throwErr("finalization in progress"), if ((vote > 0))
425430 then true
426431 else throwErr("no vote")]
427432 if ((checks == checks))
428433 then {
429434 let votesListName = getVotesListName(pool)
430435 let userAddressStr = toString(i.caller)
431436 $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)
432437 }
433438 else throw("Strict value is not equal to itself.")
434439 }
435440
436441
437442
438443 @Callable(i)
439444 func setEpochLength (newEpochLength) = {
440445 let checks = [mustManager(i), if ((newEpochLength > 0))
441446 then true
442447 else throwErr("invalid epoch length")]
443448 if ((checks == checks))
444449 then $Tuple2([IntegerEntry(keyEpochLengthNew, newEpochLength)], unit)
445450 else throw("Strict value is not equal to itself.")
446451 }
447452
448453
449454
450455 @Callable(i)
451456 func setMaxDepth (newMaxDepth) = {
452457 let checks = [mustManager(i), if ((newMaxDepth > 0))
453458 then true
454459 else throwErr("invalid max depth")]
455460 if ((checks == checks))
456461 then $Tuple2([IntegerEntry(keyMaxDepth, newMaxDepth)], unit)
457462 else throw("Strict value is not equal to itself.")
458463 }
459464
460465
461466
462467 @Callable(i)
463468 func processVoteINTERNAL (poolStr,userAddressStr) = {
464469 let checkCaller = mustThis(i)
465470 if ((checkCaller == checkCaller))
466471 then {
467472 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr(("processVoteINTERNAL: invalid user address " + userAddressStr)))
468473 let epoch = getIntOrFail(this, keyCurrentEpoch)
469474 let epochPrevious = (epoch - 1)
470475 let epochLength = getIntOrFail(this, keyEpochLength)
471476 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
472477 let endHeight = (startHeight + epochLength)
473478 let startHeightPrevious = getIntOrFail(this, keyStartHeightByEpoch(epochPrevious))
474479 let epochLengthPrevious = getIntOrFail(this, keyEpochLengthByEpoch(epochPrevious))
475480 let endHeightPrevious = (startHeightPrevious + epochLengthPrevious)
476481 let checkTargetEpoch = if ((epochPrevious >= 0))
477482 then true
478483 else throwErr("processVoteINTERNAL: invalid previous epoch")
479484 if ((checkTargetEpoch == checkTargetEpoch))
480485 then {
481486 let pool = stringToPool(poolStr)
482- let $t01748817528 = pool
483- let amountAssetId = $t01748817528._1
484- let priceAssetId = $t01748817528._2
487+ let $t01755217592 = pool
488+ let amountAssetId = $t01755217592._1
489+ let priceAssetId = $t01755217592._2
485490 let wxEmission = checkWxEmissionPoolLabel(pool)
486491 let gwxAmountAtEndTotal = {
487492 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)
488493 if ($isInstanceOf(@, "Int"))
489494 then @
490495 else throw(($getType(@) + " couldn't be cast to Int"))
491496 }
492497 let gwxAmountAtEndTotalPrevious = {
493498 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeightPrevious], nil)
494499 if ($isInstanceOf(@, "Int"))
495500 then @
496501 else throw(($getType(@) + " couldn't be cast to Int"))
497502 }
498503 let totalVotes = valueOrElse(getInteger(keyTotalVotes(epoch)), 0)
499504 let votingResult = valueOrElse(getInteger(keyVotingResult(pool, epoch)), 0)
500505 let votePrevious = valueOrErrorMessage(getInteger(keyVote(pool, userAddress, epochPrevious)), wrapErr((((("processVoteINTERNAL " + poolStr) + " ") + userAddressStr) + ": no previous vote")))
501506 let used = valueOrElse(getInteger(this, keyUsed(userAddress, epoch)), 0)
502507 let lpAssetIdStr = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
503508 let votingResultStakedPrevious = valueOrElse(getInteger(keyVotingResultStaked(lpAssetIdStr, epochPrevious)), 0)
504509 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
505510 let stakedByUser = valueOrElse(getInteger(stakingContract, keyStakedByUser(lpAssetIdStr, userAddressStr)), 0)
506511 let votingResultStakedActions = if ((stakedByUser == 0))
507512 then nil
508513 else [IntegerEntry(keyVotingResultStaked(lpAssetIdStr, epochPrevious), (votingResultStakedPrevious + votePrevious))]
509514 let newVote = if ((gwxAmountAtEndTotalPrevious > 0))
510515 then fraction(votePrevious, gwxAmountAtEndTotal, gwxAmountAtEndTotalPrevious)
511516 else 0
512517 let actions = if (if ((newVote > 0))
513518 then wxEmission
514519 else false)
515520 then [IntegerEntry(keyVote(pool, userAddress, epoch), newVote), IntegerEntry(keyTotalVotes(epoch), (totalVotes + newVote)), IntegerEntry(keyVotingResult(pool, epoch), (votingResult + newVote)), IntegerEntry(keyUsed(userAddress, epoch), (used + newVote))]
516521 else deleteNodeActions(getVotesListName(pool), userAddressStr)
517522 $Tuple2((actions ++ votingResultStakedActions), unit)
518523 }
519524 else throw("Strict value is not equal to itself.")
520525 }
521526 else throw("Strict value is not equal to itself.")
522527 }
523528
524529
525530
526531 @Callable(i)
527532 func processPoolINTERNAL (poolStr,force) = {
528533 let checkCaller = mustThis(i)
529534 if ((checkCaller == checkCaller))
530535 then {
531536 let targetEpoch = {
532537 let currentEpoch = getIntOrFail(this, keyCurrentEpoch)
533538 if (force)
534539 then currentEpoch
535540 else (currentEpoch - 1)
536541 }
537542 let checkTargetEpoch = if ((targetEpoch >= 0))
538543 then true
539544 else throwErr("processPoolINTERNAL: invalid target epoch")
540545 if ((checkTargetEpoch == checkTargetEpoch))
541546 then {
542547 let pool = stringToPool(poolStr)
543- let $t01988519925 = pool
544- let amountAssetId = $t01988519925._1
545- let priceAssetId = $t01988519925._2
548+ let $t01994919989 = pool
549+ let amountAssetId = $t01994919989._1
550+ let priceAssetId = $t01994919989._2
546551 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
547552 let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
548553 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
549554 let r = {
550555 let @ = invoke(stakingContract, "usersListTraversal", [lpAssetId], nil)
551556 if ($isInstanceOf(@, "Boolean"))
552557 then @
553558 else throw(($getType(@) + " couldn't be cast to Boolean"))
554559 }
555560 if ((r == r))
556561 then if (r)
557562 then $Tuple2(nil, true)
558563 else {
559564 let wxEmission = checkWxEmissionPoolLabel(pool)
560565 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
561566 let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
562567 let share = if (if ((totalVotes == 0))
563568 then true
564569 else !(wxEmission))
565570 then 0
566571 else fraction(votingResult, poolWeightMult, totalVotes)
567572 let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
568573 if ((modifyWeightInv == modifyWeightInv))
569574 then {
570575 let poolsListActions = if (if (wxEmission)
571576 then true
572577 else force)
573578 then nil
574579 else ([DeleteEntry(keyInList(pool))] ++ deleteNodeActions(poolsListName, poolStr))
575580 $Tuple2(([IntegerEntry(keyPoolShare(pool, targetEpoch), share)] ++ poolsListActions), false)
576581 }
577582 else throw("Strict value is not equal to itself.")
578583 }
579584 else throw("Strict value is not equal to itself.")
580585 }
581586 else throw("Strict value is not equal to itself.")
582587 }
583588 else throw("Strict value is not equal to itself.")
584589 }
585590
586591
587592
588593 @Callable(i)
589594 func finalizeHelper () = {
590595 let force = valueOrElse(getBoolean(keyFinalizationShouldBeForced), false)
591596 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
592597 let previousEpoch = (epoch - 1)
593598 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
594599 let epochLength = getIntOrFail(this, keyEpochLength)
595600 let endHeight = (startHeight + epochLength)
596601 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
597602 if (if (if ((height >= endHeight))
598603 then (finalizationStageOrUnit == unit)
599604 else false)
600605 then !(force)
601606 else false)
602607 then {
603608 let newEpoch = (epoch + 1)
604609 let newEpochLengthOption = getInteger(this, keyEpochLengthNew)
605610 let newEpochLengthActions = match newEpochLengthOption {
606611 case newEpochLength: Int =>
607612 [IntegerEntry(keyEpochLength, newEpochLength), DeleteEntry(keyEpochLengthNew)]
608613 case _: Unit =>
609614 nil
610615 case _ =>
611616 throw("Match error")
612617 }
613618 $Tuple2(([IntegerEntry(keyStartHeightByEpoch(newEpoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpoch, newEpoch), IntegerEntry(keyFinalizationStage, finalizationStageTotal), IntegerEntry(keyEpochLengthByEpoch(epoch), epochLength)] ++ newEpochLengthActions), true)
614619 }
615620 else if (if (force)
616621 then (finalizationStageOrUnit == unit)
617622 else false)
618623 then $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares)], true)
619624 else if ((finalizationStageOrUnit == unit))
620625 then $Tuple2(nil, false)
621626 else if ((finalizationStageOrUnit == finalizationStageTotal))
622627 then {
623628 let poolOrUnit = getString(keyNextPool)
624629 let userOrUnit = getString(keyNextUser)
625630 match poolOrUnit {
626631 case _: Unit =>
627632 match getString(keyListHead(poolsListName)) {
628633 case _: Unit =>
629634 $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
630635 case poolsHeadStr: String =>
631636 $Tuple2([StringEntry(keyNextPool, poolsHeadStr)], true)
632637 case _ =>
633638 throw("Match error")
634639 }
635640 case poolStr: String =>
636641 let pool = stringToPool(poolStr)
637642 let nextUserOrUnit = match userOrUnit {
638643 case _: Unit =>
639644 getString(keyListHead(getVotesListName(pool)))
640645 case user: String =>
641646 let next = getString(keyListNext(getVotesListName(pool), user))
642647 if ((next == next))
643648 then {
644649 let processVoteInv = invoke(this, "processVoteINTERNAL", [poolStr, user], nil)
645650 if ((processVoteInv == processVoteInv))
646651 then next
647652 else throw("Strict value is not equal to itself.")
648653 }
649654 else throw("Strict value is not equal to itself.")
650655 case _ =>
651656 throw("Match error")
652657 }
653658 match nextUserOrUnit {
654659 case _: Unit =>
655660 let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
656661 match nextPoolOrUnit {
657662 case _: Unit =>
658663 $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
659664 case s: String =>
660665 $Tuple2([StringEntry(keyNextPool, s), DeleteEntry(keyNextUser)], true)
661666 case _ =>
662667 throw("Match error")
663668 }
664669 case nextUser: String =>
665670 $Tuple2([StringEntry(keyNextUser, nextUser)], true)
666671 case _ =>
667672 throw("Match error")
668673 }
669674 case _ =>
670675 throw("Match error")
671676 }
672677 }
673678 else if ((finalizationStageOrUnit == finalizationStageShares))
674679 then {
675680 let poolOrUnit = getString(keyNextPool)
676681 match poolOrUnit {
677682 case _: Unit =>
678683 match getString(keyListHead(poolsListName)) {
679684 case _: Unit =>
680685 let actions = if (force)
681686 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced)]
682687 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight)]
683688 $Tuple2(actions, true)
684689 case nextPoolStr: String =>
685690 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
686691 case _ =>
687692 throw("Match error")
688693 }
689694 case poolStr: String =>
690695 let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
691696 if ((nextPoolOrUnit == nextPoolOrUnit))
692697 then {
693698 let r = {
694699 let @ = invoke(this, "processPoolINTERNAL", [poolStr, force], nil)
695700 if ($isInstanceOf(@, "Boolean"))
696701 then @
697702 else throw(($getType(@) + " couldn't be cast to Boolean"))
698703 }
699704 if ((r == r))
700705 then if (r)
701706 then $Tuple2(nil, true)
702707 else match nextPoolOrUnit {
703708 case _: Unit =>
704709 let actions = if (force)
705710 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced), DeleteEntry(keyNextPool)]
706711 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight), DeleteEntry(keyNextPool)]
707712 $Tuple2(actions, true)
708713 case nextPoolStr: String =>
709714 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
710715 case _ =>
711716 throw("Match error")
712717 }
713718 else throw("Strict value is not equal to itself.")
714719 }
715720 else throw("Strict value is not equal to itself.")
716721 case _ =>
717722 throw("Match error")
718723 }
719724 }
720725 else throwErr("finalization is broken")
721726 }
722727
723728
724729
725730 @Callable(i)
726731 func finalizeWrapper (counter) = {
727732 let result = {
728733 let @ = invoke(this, "finalizeHelper", nil, nil)
729734 if ($isInstanceOf(@, "Boolean"))
730735 then @
731736 else throw(($getType(@) + " couldn't be cast to Boolean"))
732737 }
733738 if ((result == result))
734739 then if (!(result))
735740 then if ((counter == 0))
736741 then throwErr("Current voting is not over yet")
737742 else $Tuple2(nil, unit)
738743 else {
739744 let maxDepth = valueOrElse(getInteger(this, keyMaxDepth), maxDepthDefault)
740745 if ((maxDepth > counter))
741746 then {
742747 let inv = invoke(this, "finalizeWrapper", [(counter + 1)], nil)
743748 if ((inv == inv))
744749 then $Tuple2(nil, unit)
745750 else throw("Strict value is not equal to itself.")
746751 }
747752 else $Tuple2(nil, unit)
748753 }
749754 else throw("Strict value is not equal to itself.")
750755 }
751756
752757
753758
754759 @Callable(i)
755760 func finalize () = {
756761 let inv = invoke(this, "finalizeWrapper", [0], nil)
757762 if ((inv == inv))
758763 then $Tuple2(nil, unit)
759764 else throw("Strict value is not equal to itself.")
760765 }
761766
762767
763768
764769 @Callable(i)
765770 func containsNodeREADONLY (listName,id) = $Tuple2(nil, containsNode(listName, id))
766771
767772
768773
769774 @Callable(i)
770775 func insertNode (listName,id) = {
771776 let checkCaller = mustManager(i)
772777 if ((checkCaller == checkCaller))
773778 then $Tuple2(insertNodeActions(listName, id), unit)
774779 else throw("Strict value is not equal to itself.")
775780 }
776781
777782
778783
779784 @Callable(i)
780785 func deleteNode (listName,id) = {
781786 let checkCaller = mustManager(i)
782787 if ((checkCaller == checkCaller))
783788 then $Tuple2(deleteNodeActions(listName, id), unit)
784789 else throw("Strict value is not equal to itself.")
785790 }
786791
787792
788793 @Verifier(tx)
789794 func verify () = {
790795 let targetPublicKey = match managerPublicKeyOrUnit() {
791796 case pk: ByteVector =>
792797 pk
793798 case _: Unit =>
794799 tx.senderPublicKey
795800 case _ =>
796801 throw("Match error")
797802 }
798803 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
799804 }
800805

github/deemru/w8io/3ef1775 
123.23 ms