tx · HMhuth8E4erWybLPu7ULFa7bpB7QgAw6YLn3amCMAga4 3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr: -0.02700000 Waves 2024.04.17 11:31 [3066519] smart account 3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr > SELF 0.00000000 Waves
{ "type": 13, "id": "HMhuth8E4erWybLPu7ULFa7bpB7QgAw6YLn3amCMAga4", "fee": 2700000, "feeAssetId": null, "timestamp": 1713342701286, "version": 2, "chainId": 84, "sender": "3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr", "senderPublicKey": "GFbasS3jufhZkK4xR7tdTjjnP8K33KvJFEDHRtxXDkaJ", "proofs": [ "5Lfqso3XowxmzVNVoER4pesJLCR72BFmFLDaqcGVLPpeFnbEaHxN9XtqfybZf14R6cbzs7wBGE5641FUx29zp9wA" ], "script": "base64:BgKpGggCEgQKAggBEgcKBQgICAgBEgQKAggIEgUKAwgIARIECgIICBIDCgEBEgMKAQESAwoBCBIECgIICBIECgIIBBIAEgMKAQESABIECgIICBIECgIICBIECgIICBIAEgQKAggIEgQKAggIIglzZXBhcmF0b3IiDnBvb2xXZWlnaHRNdWx0Ig9tYXhEZXB0aERlZmF1bHQiGWZpbmFsaXphdGlvblN0YWdlQmFsYW5jZXMiFmZpbmFsaXphdGlvblN0YWdlVG90YWwiF2ZpbmFsaXphdGlvblN0YWdlU2hhcmVzIg5rZXlFcG9jaExlbmd0aCIRa2V5RXBvY2hMZW5ndGhOZXciFWtleUVwb2NoTGVuZ3RoQnlFcG9jaCIFZXBvY2giD2tleUN1cnJlbnRFcG9jaCILa2V5TWF4RGVwdGgiEGtleVJlc3VtcHRpb25GZWUiImtleVZvdGluZ0VtaXNzaW9uQ2FuZGlkYXRlQ29udHJhY3QiHWtleVZvdGluZ0VtaXNzaW9uUmF0ZUNvbnRyYWN0IhJrZXlGYWN0b3J5Q29udHJhY3QiE2tleUJvb3N0aW5nQ29udHJhY3QiEmtleVN0YWtpbmdDb250cmFjdCIWa2V5QXNzZXRzU3RvcmVDb250cmFjdCIUa2V5RmluYWxpemF0aW9uU3RhZ2UiC2tleU5leHRQb29sIgtrZXlOZXh0VXNlciIOa2V5U3RhcnRIZWlnaHQiEWtleUN1cnJlbnRFcG9jaFVpIhBrZXlTdGFydEhlaWdodFVpIh1rZXlGaW5hbGl6YXRpb25TaG91bGRCZUZvcmNlZCIVa2V5U3RhcnRIZWlnaHRCeUVwb2NoIgxrZXlGaW5hbGl6ZWQiCWtleUluTGlzdCIEcG9vbCILJHQwMTk3MjIwMTIiDWFtb3VudEFzc2V0SWQiDHByaWNlQXNzZXRJZCIXa2V5SW5zdWZmaWNpZW50QmFsYW5jZXMiCyR0MDIxNjEyMjAxIgdrZXlVc2VkIgdhZGRyZXNzIgdrZXlWb3RlIgskdDAyNTA5MjU0OSIPa2V5Vm90aW5nUmVzdWx0IgskdDAyNzMxMjc3MSIVa2V5Vm90aW5nUmVzdWx0U3Rha2VkIgxscEFzc2V0SWRTdHIiDGtleVBvb2xTaGFyZSILJHQwMzA5MjMxMzIiDWtleVRvdGFsVm90ZXMiD2tleVN0YWtlZEJ5VXNlciIOdXNlckFkZHJlc3NTdHIiB3dyYXBFcnIiA21zZyIIdGhyb3dFcnIiDmdldFZhbHVlT3JGYWlsIgNrZXkiBHR5cGUiBWVycm9yIgckbWF0Y2gwIgNzdHIiA2ludCIMZ2V0U3RyT3JGYWlsIgFAIgxnZXRJbnRPckZhaWwiDHBvb2xUb1N0cmluZyIMc3RyaW5nVG9Qb29sIgVwYXJ0cyIPZmFjdG9yeUNvbnRyYWN0IhpJZHhGYWN0b3J5Q2ZnR3d4UmV3YXJkRGFwcCINa2V5RmFjdG9yeUNmZyIUcmVhZEZhY3RvcnlDZmdPckZhaWwiB2ZhY3RvcnkiGWdldEd3eFJld2FyZEFkZHJlc3NPckZhaWwiCmZhY3RvcnlDZmciC2dldFBvb2xJbmZvIg5wb29sSW5mb09wdGlvbiIWZ2V0THBBc3NldEJ5UG9vbEFzc2V0cyIfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZCIMYmFzZUFzc2V0U3RyIilrZXlNYXBwaW5nUG9vbEFzc2V0c1RvUG9vbENvbnRyYWN0QWRkcmVzcyIYaW50ZXJuYWxBbW91bnRBc3NldElkU3RyIhdpbnRlcm5hbFByaWNlQXNzZXRJZFN0ciIfa2V5TWFwcGluZ1Bvb2xDb250cmFjdFRvTFBBc3NldCITcG9vbENvbnRyYWN0QWRkcmVzcyIVYW1vdW50QXNzZXRJbnRlcm5hbElkIhRwcmljZUFzc2V0SW50ZXJuYWxJZCIJbHBBc3NldElkIhhjaGVja1d4RW1pc3Npb25Qb29sTGFiZWwiCyR0MDYyNTg2Mjk4IhBnd3hSZXdhcmREZXBvc2l0IhJnd3hSZXdhcmRzQ29udHJhY3QiDXBvb2xzTGlzdE5hbWUiEGdldFZvdGVzTGlzdE5hbWUiCyR0MDY3MTU2NzU1IgtrZXlMaXN0SGVhZCIIbGlzdE5hbWUiBG1ldGEiC2tleUxpc3RTaXplIgtrZXlMaXN0UHJldiICaWQiC2tleUxpc3ROZXh0Igxjb250YWluc05vZGUiCmhlYWRPclVuaXQiCnByZXZPclVuaXQiCm5leHRPclVuaXQiEWluc2VydE5vZGVBY3Rpb25zIghsaXN0U2l6ZSIJY2hlY2tOb2RlIhFkZWxldGVOb2RlQWN0aW9ucyIWa2V5TWFuYWdlclZhdWx0QWRkcmVzcyITa2V5TWFuYWdlclB1YmxpY0tleSIcZ2V0TWFuYWdlclZhdWx0QWRkcmVzc09yVGhpcyIBcyIWbWFuYWdlclB1YmxpY0tleU9yVW5pdCITbWFuYWdlclZhdWx0QWRkcmVzcyIJaXNNYW5hZ2VyIgFpIgJwayILbXVzdE1hbmFnZXIiCG11c3RUaGlzIgt1c2VyQWRkcmVzcyIMdGFyZ2V0SGVpZ2h0Ihdib29zdGluZ0NvbnRyYWN0QWRkcmVzcyIfdm90aW5nRW1pc3Npb25DYW5kaWRhdGVDb250cmFjdCIQYm9vc3RpbmdDb250cmFjdCIPc3Rha2luZ0NvbnRyYWN0IgtlcG9jaExlbmd0aCIGY2hlY2tzIg1pbkxpc3RBY3Rpb25zIhhjdXJyZW50RXBvY2hJc05vdERlZmluZWQiEnN0YXJ0SGVpZ2h0QWN0aW9ucyIGYW1vdW50IgtzdGFydEhlaWdodCIJZW5kSGVpZ2h0IhdmaW5hbGl6YXRpb25TdGFnZU9yVW5pdCIEdXNlZCIEdm90ZSIKcG9vbFJlc3VsdCIKdG90YWxWb3RlcyITZ3d4QW1vdW50QXRFbmRUb3RhbCIJYXZhaWxhYmxlIgduZXdWb3RlIgp3eEVtaXNzaW9uIg12b3Rlc0xpc3ROYW1lIhB2b3Rlc0xpc3RBY3Rpb25zIg5uZXdFcG9jaExlbmd0aCILbmV3TWF4RGVwdGgiB3Bvb2xTdHIiC2NoZWNrQ2FsbGVyIg1lcG9jaFByZXZpb3VzIg0kdDAxNjk3OTE3MDE5IhJiYWxhbmNlSXNPa0N1cnJlbnQiE2JhbGFuY2VJc09rUHJldmlvdXMiB2FjdGlvbnMiE2RlbGV0ZVd4RW1pc3Npb25JbnYiD21vZGlmeVdlaWdodEludiILcG9vbEFkZHJlc3MiCW5ld1N0YXR1cyIQc2V0UG9vbFN0YXR1c0ludiILbGlzdEFjdGlvbnMiE3N0YXJ0SGVpZ2h0UHJldmlvdXMiE2Vwb2NoTGVuZ3RoUHJldmlvdXMiEWVuZEhlaWdodFByZXZpb3VzIhBjaGVja1RhcmdldEVwb2NoIg0kdDAxOTM3MjE5NDEyIhtnd3hBbW91bnRBdEVuZFRvdGFsUHJldmlvdXMiDHZvdGluZ1Jlc3VsdCIMdm90ZVByZXZpb3VzIhp2b3RpbmdSZXN1bHRTdGFrZWRQcmV2aW91cyIMc3Rha2VkQnlVc2VyIhl2b3RpbmdSZXN1bHRTdGFrZWRBY3Rpb25zIgVmb3JjZSILdGFyZ2V0RXBvY2giDGN1cnJlbnRFcG9jaCINJHQwMjE3NzUyMTgxNSIBciITYXNzZXRzU3RvcmVDb250cmFjdCIFc2hhcmUiDXByZXZpb3VzRXBvY2giCG5ld0Vwb2NoIhRuZXdFcG9jaExlbmd0aE9wdGlvbiIVbmV3RXBvY2hMZW5ndGhBY3Rpb25zIgpwb29sT3JVbml0IgckbWF0Y2gxIgtuZXh0UG9vbFN0ciIObmV4dFBvb2xPclVuaXQiCnVzZXJPclVuaXQiDHBvb2xzSGVhZFN0ciIObmV4dFVzZXJPclVuaXQiBHVzZXIiBG5leHQiDnByb2Nlc3NWb3RlSW52IgckbWF0Y2gyIghuZXh0VXNlciITZ3d4UmV3YXJkRGVwb3NpdEludiIHY291bnRlciIadm90aW5nRW1pc3Npb25SYXRlQ29udHJhY3QiBnJlc3VsdCIDaW52IghtYXhEZXB0aCIWZmluYWxpemF0aW9uSW5Qcm9ncmVzcyILYmFsYW5jZUlzT2siB3BheW1lbnQiD2tCb29zdGluZ0NvbmZpZyINaWR4Q2ZnQXNzZXRJZCIJd3hBc3NldElkIhNhbW91bnRBc3NldFZlcmlmaWVkIhJwcmljZUFzc2V0VmVyaWZpZWQiDXJlc3VtcHRpb25GZWUiEHNldFd4RW1pc3Npb25JbnYiAnR4IgZ2ZXJpZnkiD3RhcmdldFB1YmxpY0tleUQAAWECAl9fAAFiAIDC1y8AAWMACgABZAAAAAFlAAEAAWYAAgABZwkAuQkCCQDMCAICAiVzCQDMCAICC2Vwb2NoTGVuZ3RoBQNuaWwFAWEAAWgJALkJAgkAzAgCAgQlcyVzCQDMCAICEGVwb2NoTGVuZ3RoX19uZXcFA25pbAUBYQEBaQEBagkAuQkCCQDMCAICBCVzJWQJAMwIAgILZXBvY2hMZW5ndGgJAMwIAgkApAMBBQFqBQNuaWwFAWEAAWsJALkJAgkAzAgCAgIlcwkAzAgCAgxjdXJyZW50RXBvY2gFA25pbAUBYQABbAkAuQkCCQDMCAICAiVzCQDMCAICCG1heERlcHRoBQNuaWwFAWEAAW0JALkJAgkAzAgCAgIlcwkAzAgCAg1yZXN1bXB0aW9uRmVlBQNuaWwFAWEAAW4JALkJAgkAzAgCAgIlcwkAzAgCAh92b3RpbmdFbWlzc2lvbkNhbmRpZGF0ZUNvbnRyYWN0BQNuaWwFAWEAAW8JALkJAgkAzAgCAgIlcwkAzAgCAhp2b3RpbmdFbWlzc2lvblJhdGVDb250cmFjdAUDbmlsBQFhAAFwCQC5CQIJAMwIAgICJXMJAMwIAgIPZmFjdG9yeUNvbnRyYWN0BQNuaWwFAWEAAXEJALkJAgkAzAgCAgIlcwkAzAgCAhBib29zdGluZ0NvbnRyYWN0BQNuaWwFAWEAAXIJALkJAgkAzAgCAgIlcwkAzAgCAg9zdGFraW5nQ29udHJhY3QFA25pbAUBYQABcwkAuQkCCQDMCAICAiVzCQDMCAICE2Fzc2V0c1N0b3JlQ29udHJhY3QFA25pbAUBYQABdAkAuQkCCQDMCAICAiVzCQDMCAICEWZpbmFsaXphdGlvblN0YWdlBQNuaWwFAWEAAXUJALkJAgkAzAgCAgIlcwkAzAgCAghuZXh0UG9vbAUDbmlsBQFhAAF2CQC5CQIJAMwIAgICJXMJAMwIAgIIbmV4dFVzZXIFA25pbAUBYQABdwkAuQkCCQDMCAICAiVzCQDMCAICC3N0YXJ0SGVpZ2h0BQNuaWwFAWEAAXgJALkJAgkAzAgCAgIlcwkAzAgCAg5jdXJyZW50RXBvY2hVaQUDbmlsBQFhAAF5CQC5CQIJAMwIAgICJXMJAMwIAgINc3RhcnRIZWlnaHRVaQUDbmlsBQFhAAF6CQC5CQIJAMwIAgICJXMJAMwIAgIFZm9yY2UFA25pbAUBYQEBQQEBagkAuQkCCQDMCAICBCVzJWQJAMwIAgILc3RhcnRIZWlnaHQJAMwIAgkApAMBBQFqBQNuaWwFAWEBAUIBAWoJALkJAgkAzAgCAgQlcyVkCQDMCAICCWZpbmFsaXplZAkAzAgCCQCkAwEFAWoFA25pbAUBYQEBQwEBRAQBRQUBRAQBRggFAUUCXzEEAUcIBQFFAl8yCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICBmluTGlzdAkAzAgCBQFGCQDMCAIFAUcFA25pbAUBYQEBSAIBRAFqBAFJBQFEBAFGCAUBSQJfMQQBRwgFAUkCXzIJALkJAgkAzAgCAgglcyVzJXMlZAkAzAgCAhRpbnN1ZmZpY2llbnRCYWxhbmNlcwkAzAgCBQFGCQDMCAIFAUcJAMwIAgkApAMBBQFqBQNuaWwFAWEBAUoCAUsBagkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAgR1c2VkCQDMCAIJAKUIAQUBSwkAzAgCCQCkAwEFAWoFA25pbAUBYQEBTAMBRAFLAWoEAU0FAUQEAUYIBQFNAl8xBAFHCAUBTQJfMgkAuQkCCQDMCAICCiVzJXMlcyVzJWQJAMwIAgIEdm90ZQkAzAgCBQFGCQDMCAIFAUcJAMwIAgkApQgBBQFLCQDMCAIJAKQDAQUBagUDbmlsBQFhAQFOAgFEAWoEAU8FAUQEAUYIBQFPAl8xBAFHCAUBTwJfMgkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICDHZvdGluZ1Jlc3VsdAkAzAgCBQFGCQDMCAIFAUcJAMwIAgkApAMBBQFqBQNuaWwFAWEBAVACAVEBagkAuQkCCQDMCAICBiVzJXMlZAkAzAgCAhJ2b3RpbmdSZXN1bHRTdGFrZWQJAMwIAgUBUQkAzAgCCQCkAwEFAWoFA25pbAUBYQEBUgIBRAFqBAFTBQFEBAFGCAUBUwJfMQQBRwgFAVMCXzIJALkJAgkAzAgCAgglcyVzJXMlZAkAzAgCAglwb29sU2hhcmUJAMwIAgUBRgkAzAgCBQFHCQDMCAIJAKQDAQUBagUDbmlsBQFhAQFUAQFqCQC5CQIJAMwIAgIEJXMlZAkAzAgCAgp0b3RhbFZvdGVzCQDMCAIJAKQDAQUBagUDbmlsBQFhAQFVAgFRAVYJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIGc3Rha2VkCQDMCAIFAVYJAMwIAgUBUQUDbmlsBQFhAQFXAQFYCQC5CQIJAMwIAgIVdm90aW5nX2VtaXNzaW9uLnJpZGU6CQDMCAIFAVgFA25pbAIBIAEBWQEBWAkAAgEJAQFXAQUBWAEBWgMBSwJhYQJhYgQCYWMJAQFXAQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQFLCQDMCAICAS4JAMwIAgUCYWEJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBAJhZAUCYWIDCQABAgUCYWQCBlN0cmluZwQCYWUFAmFkCQCdCAIFAUsFAmFhAwkAAQIFAmFkAgNJbnQEAmFmBQJhZAkAmggCBQFLBQJhYQkBAVkBAhJpbnZhbGlkIGVudHJ5IHR5cGUFAmFjAQJhZwIBSwJhYQoAAmFoCQEBWgMFAUsFAmFhAgADCQABAgUCYWgCBlN0cmluZwUCYWgJAAIBCQCsAgIJAAMBBQJhaAIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nAQJhaQIBSwJhYQoAAmFoCQEBWgMFAUsFAmFhAAADCQABAgUCYWgCA0ludAUCYWgJAAIBCQCsAgIJAAMBBQJhaAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AQJhagEBRAkArAICCQCsAgIIBQFEAl8xBQFhCAUBRAJfMgECYWsBAmFlBAJhbAkAtQkCBQJhZQUBYQMJAAACCQCQAwEFAmFsAAIJAJQKAgkAkQMCBQJhbAAACQCRAwIFAmFsAAEJAQFZAQITaW52YWxpZCBwb29sIHN0cmluZwACYW0JARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQJhZwIFBHRoaXMFAXAAAmFuAAoBAmFvAAIRJXNfX2ZhY3RvcnlDb25maWcBAmFwAQJhcQkAtQkCCQECYWcCBQJhcQkBAmFvAAUBYQECYXIBAmFzCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFAmFzBQJhbgECYXQCAUYBRwQCYXUKAAJhaAkA/AcEBQJhbQIQcG9vbEluZm9SRUFET05MWQkAzAgCBQFGCQDMCAIFAUcFA25pbAUDbmlsAwkAAQIFAmFoAhUoQWRkcmVzcywgQnl0ZVZlY3RvcikFAmFoBQR1bml0BQJhdQECYXYCAUYBRwoBAmF3AQJheAkArAICAiglcyVzJXNfX21hcHBpbmdzX19iYXNlQXNzZXQyaW50ZXJuYWxJZF9fBQJheAoBAmF5AgJhegJhQQkArAICCQCsAgIJAKwCAgkArAICAgolZCVkJXMlc19fCQCkAwEFAmF6AgJfXwkApAMBBQJhQQIjX19tYXBwaW5nc19fcG9vbEFzc2V0czJQb29sQ29udHJhY3QKAQJhQgECYUMJAKwCAgkArAICAgglcyVzJXNfXwUCYUMCIF9fbWFwcGluZ3NfX3Bvb2xDb250cmFjdDJMcEFzc2V0BAJhRAkBAmFpAgUCYW0JAQJhdwEFAUYEAmFFCQECYWkCBQJhbQkBAmF3AQUBRwQCYUMJAQJhZwIFAmFtCQECYXkCBQJhRAUCYUUEAmFGCQECYWcCBQJhbQkBAmFCAQUCYUMFAmFGAQJhRwEBRAQCYUgFAUQEAUYIBQJhSAJfMQQBRwgFAmFIAl8yCgACYWgJAPwHBAUCYW0CGGNoZWNrV3hFbWlzc2lvblBvb2xMYWJlbAkAzAgCBQFGCQDMCAIFAUcFA25pbAUDbmlsAwkAAQIFAmFoAgdCb29sZWFuBQJhaAkAAgEJAKwCAgkAAwEFAmFoAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuAQJhSQAEAmFzCQECYXABBQJhbQQCYUoJAQJhcgEFAmFzCQD8BwQFAmFKAgdkZXBvc2l0BQNuaWwFA25pbAACYUsCBXBvb2xzAQJhTAEBRAQCYU0FAUQEAUYIBQJhTQJfMQQBRwgFAmFNAl8yCQC5CQIJAMwIAgIFdm90ZXMJAMwIAgUBRgkAzAgCBQFHBQNuaWwFAWEBAmFOAQJhTwQCYVADCQAAAgUCYU8FAmFLAgQlcyVzAgglcyVzJXMlcwkAuQkCCQDMCAIFAmFQCQDMCAIFAmFPCQDMCAICBGhlYWQFA25pbAUBYQECYVEBAmFPBAJhUAMJAAACBQJhTwUCYUsCBCVzJXMCCCVzJXMlcyVzCQC5CQIJAMwIAgUCYVAJAMwIAgUCYU8JAMwIAgIEc2l6ZQUDbmlsBQFhAQJhUgICYU8CYVMEAmFQAwkAAAIFAmFPBQJhSwIIJXMlcyVzJXMCCiVzJXMlcyVzJXMJALkJAgkAzAgCBQJhUAkAzAgCBQJhTwkAzAgCBQJhUwkAzAgCAgRwcmV2BQNuaWwFAWEBAmFUAgJhTwJhUwQCYVADCQAAAgUCYU8FAmFLAgglcyVzJXMlcwIKJXMlcyVzJXMlcwkAuQkCCQDMCAIFAmFQCQDMCAIFAmFPCQDMCAIFAmFTCQDMCAICBG5leHQFA25pbAUBYQECYVUCAmFPAmFTBAJhVgkAnQgCBQR0aGlzCQECYU4BBQJhTwQCYVcJAJ0IAgUEdGhpcwkBAmFSAgUCYU8FAmFTBAJhWAkAnQgCBQR0aGlzCQECYVQCBQJhTwUCYVMDAwkAAAIFAmFTCQELdmFsdWVPckVsc2UCBQJhVgIABgkBAiE9AgUCYVcFBHVuaXQGCQECIT0CBQJhWAUEdW5pdAECYVkCAmFPAmFTBAJhVgkAnQgCBQR0aGlzCQECYU4BBQJhTwQCYVoJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmFRAQUCYU8AAAQCYmEDCQEBIQEJAQJhVQIFAmFPBQJhUwYJAQFZAQILTm9kZSBleGlzdHMDCQAAAgUCYmEFAmJhCQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFRAQUCYU8JAGQCBQJhWgABBQNuaWwDCQECIT0CBQJhVgUEdW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQECYVQCBQJhTwUCYVMJAQV2YWx1ZQEFAmFWCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhUgIFAmFPCQEFdmFsdWUBBQJhVgUCYVMFA25pbAUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhTgEFAmFPBQJhUwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJiYgICYU8CYVMEAmFWCQCdCAIFBHRoaXMJAQJhTgEFAmFPBAJhWgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYVEBBQJhTwAABAJhVwkAnQgCBQR0aGlzCQECYVICBQJhTwUCYVMEAmFYCQCdCAIFBHRoaXMJAQJhVAIFAmFPBQJhUwkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYVEBBQJhTwkAZQIFAmFaAAEFA25pbAMDCQECIT0CBQJhVwUEdW5pdAkBAiE9AgUCYVgFBHVuaXQHCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhVAIFAmFPCQEFdmFsdWUBBQJhVwkBBXZhbHVlAQUCYVgJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFSAgUCYU8JAQV2YWx1ZQEFAmFYCQEFdmFsdWUBBQJhVwkAzAgCCQELRGVsZXRlRW50cnkBCQECYVICBQJhTwUCYVMJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFUAgUCYU8FAmFTBQNuaWwDCQECIT0CBQJhWAUEdW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQECYU4BBQJhTwkBBXZhbHVlAQUCYVgJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFUAgUCYU8FAmFTCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhUgIFAmFPCQEFdmFsdWUBBQJhWAUDbmlsAwkBAiE9AgUCYVcFBHVuaXQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFSAgUCYU8FAmFTCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhVAIFAmFPCQEFdmFsdWUBBQJhVwUDbmlsAwkAAAIFAmFTCQELdmFsdWVPckVsc2UCBQJhVgIACQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhTgEFAmFPBQNuaWwJAQFZAQkArAICCQCsAgIJAKwCAgIOaW52YWxpZCBub2RlOiAFAmFPAgEuBQJhUwECYmMAAhclc19fbWFuYWdlclZhdWx0QWRkcmVzcwECYmQAAhQlc19fbWFuYWdlclB1YmxpY0tleQECYmUABAJhZAkAoggBCQECYmMAAwkAAQIFAmFkAgZTdHJpbmcEAmJmBQJhZAkBEUBleHRyTmF0aXZlKDEwNjIpAQUCYmYFBHRoaXMBAmJnAAQCYmgJAQJiZQAEAmFkCQCdCAIFAmJoCQECYmQAAwkAAQIFAmFkAgZTdHJpbmcEAmJmBQJhZAkA2QQBBQJiZgMJAAECBQJhZAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJiaQECYmoEAmFkCQECYmcAAwkAAQIFAmFkAgpCeXRlVmVjdG9yBAJiawUCYWQJAAACCAUCYmoPY2FsbGVyUHVibGljS2V5BQJiawMJAAECBQJhZAIEVW5pdAkAAAIIBQJiagZjYWxsZXIFBHRoaXMJAAIBAgtNYXRjaCBlcnJvcgECYmwBAmJqAwkBAmJpAQUCYmoGCQACAQIRcGVybWlzc2lvbiBkZW5pZWQBAmJtAQJiagMJAAACCAUCYmoGY2FsbGVyBQR0aGlzBgkAAgECEXBlcm1pc3Npb24gZGVuaWVkEwJiagEYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0AgJibgJibwQCYnAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQECYWcCBQR0aGlzBQFxCQEBVwECIWludmFsaWQgYm9vc3RpbmcgY29udHJhY3QgYWRkcmVzcwkAlAoCBQNuaWwKAAJhaAkA/AcEBQJicAIgZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0UkVBRE9OTFkJAMwIAgUCYm4JAMwIAgUCYm8FA25pbAUDbmlsAwkAAQIFAmFoAgNJbnQFAmFoCQACAQkArAICCQADAQUCYWgCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAJiagELY29uc3RydWN0b3IFAmFtAmJxAmJyAmJzAmJ0BAJidQkAzAgCCQECYmwBBQJiagkAzAgCAwkBAiE9AgkApggBBQJhbQUEdW5pdAYCIGludmFsaWQgZmFjdG9yeSBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQECIT0CCQCmCAEFAmJxBQR1bml0BgIyaW52YWxpZCB2b3RpbmcgZW1pc3Npb24gY2FuZGlkYXRlIGNvbnRyYWN0IGFkZHJlc3MJAMwIAgMJAQIhPQIJAKYIAQUCYnIFBHVuaXQGAiFpbnZhbGlkIGJvb3N0aW5nIGNvbnRyYWN0IGFkZHJlc3MJAMwIAgMJAQIhPQIJAKYIAQUCYnMFBHVuaXQGAiBpbnZhbGlkIHN0YWtpbmcgY29udHJhY3QgYWRkcmVzcwkAzAgCAwkAZgIFAmJ0AAAGCQEBWQECFGludmFsaWQgZXBvY2ggbGVuZ3RoBQNuaWwDCQAAAgUCYnUFAmJ1CQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBcAUCYW0JAMwIAgkBC1N0cmluZ0VudHJ5AgUBbgUCYnEJAMwIAgkBC1N0cmluZ0VudHJ5AgUBcQUCYnIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBcgUCYnMJAMwIAgkBDEludGVnZXJFbnRyeQIFAWcFAmJ0BQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmoBBmNyZWF0ZQIBRgFHBAJidQkAzAgCAwkAAAIJANgEAQgIBQJiagZjYWxsZXIFYnl0ZXMJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwUBbgIABgkBAmJsAQUCYmoFA25pbAMJAAACBQJidQUCYnUEAUQJAJQKAgUBRgUBRwQCYnYJAM4IAgkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBAUMBBQFEBgUDbmlsCQECYVkCBQJhSwkBAmFqAQUBRAQCYncJAAACCQCaCAIFBHRoaXMFAWsFBHVuaXQEAmJ4AwUCYncEAWoAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBawUBagkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUEBBQFqBQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFAXcFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBeAUBagkAzAgCCQEMSW50ZWdlckVudHJ5AgUBeQUGaGVpZ2h0BQNuaWwFA25pbAkAlAoCCQDOCAIFAmJ2BQJieAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiagEEdm90ZQMBRgFHAmJ5BAFECQCUCgIFAUYFAUcEAWoJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBawAABAJiegkBAmFpAgUEdGhpcwkBAUEBBQFqBAJidAkBAmFpAgUEdGhpcwUBZwQCYkEJAGQCBQJiegUCYnQEAmJCCQCaCAIFBHRoaXMFAXQEAmJDCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFKAggFAmJqBmNhbGxlcgUBagAABAJiRAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBTAMFAUQIBQJiagZjYWxsZXIFAWoAAAQCYkUJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAU4CBQFEBQFqAAAEAmJGCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFUAQUBagAABAJiRwoAAmFoCQD8BwQFBHRoaXMCGGdldFVzZXJHd3hBbW91bnRBdEhlaWdodAkAzAgCCQDYBAEICAUCYmoGY2FsbGVyBWJ5dGVzCQDMCAIFAmJBBQNuaWwFA25pbAMJAAECBQJhaAIDSW50BQJhaAkAAgEJAKwCAgkAAwEFAmFoAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQEAmJICQBlAgUCYkcFAmJDBAJiSQkAZAIFAmJEBQJieQQCYkoJAQJhRwEFAUQEAmJ1CQDMCAIDCQECIT0CCQCgCAEJAQFDAQUBRAUEdW5pdAYJAQFZAQIOaW52YWxpZCBhc3NldHMJAMwIAgMJAGYCBQJiQQUGaGVpZ2h0BgkBAVkBAg5pbnZhbGlkIGhlaWdodAkAzAgCAwkAAAIFAmJCBQR1bml0BgkBAVkBAhhmaW5hbGl6YXRpb24gaW4gcHJvZ3Jlc3MJAMwIAgMJAGYCBQJiRwAABgkBAVkBAhN5b3UgZG8gbm90IGhhdmUgZ1dYCQDMCAIDAwkAZgIFAmJ5AAAJAGcCBQJiSAUCYnkHBgkBAVkBAg5pbnZhbGlkIGFtb3VudAkAzAgCAwUCYkoGCQEBWQECHXBvb2wgaGFzbid0IFdYX0VNSVNTSU9OIGxhYmVsBQNuaWwDCQAAAgUCYnUFAmJ1BAJiSwkBAmFMAQUBRAQBVgkApQgBCAUCYmoGY2FsbGVyBAJiTAMJAQJhVQIFAmJLBQFWBQNuaWwJAQJhWQIFAmJLBQFWCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUoCCAUCYmoGY2FsbGVyBQFqCQBkAgUCYkMFAmJ5CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBTAMFAUQIBQJiagZjYWxsZXIFAWoFAmJJCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBTgIFAUQFAWoJAGQCBQJiRQUCYnkJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFUAQUBagkAZAIFAmJGBQJieQUDbmlsBQJiTAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiagEKY2FuY2VsVm90ZQIBRgFHBAFECQCUCgIFAUYFAUcEAWoJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBawAABAJiegkBAmFpAgUEdGhpcwkBAUEBBQFqBAJidAkBAmFpAgUEdGhpcwUBZwQCYkEJAGQCBQJiegUCYnQEAmJCCQCaCAIFBHRoaXMFAXQEAmJDCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFKAggFAmJqBmNhbGxlcgUBagAABAJiRAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBTAMFAUQIBQJiagZjYWxsZXIFAWoAAAQCYkUJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAU4CBQFEBQFqAAAEAmJGCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFUAQUBagAABAJidQkAzAgCAwkBAiE9AgkAoAgBCQEBQwEFAUQFBHVuaXQGCQEBWQECDmludmFsaWQgYXNzZXRzCQDMCAIDCQBmAgUCYkEFBmhlaWdodAYJAQFZAQIOaW52YWxpZCBoZWlnaHQJAMwIAgMJAAACBQJiQgUEdW5pdAYJAQFZAQIYZmluYWxpemF0aW9uIGluIHByb2dyZXNzCQDMCAIDCQBmAgUCYkQAAAYJAQFZAQIHbm8gdm90ZQUDbmlsAwkAAAIFAmJ1BQJidQQCYksJAQJhTAEFAUQEAVYJAKUIAQgFAmJqBmNhbGxlcgkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFKAggFAmJqBmNhbGxlcgUBagkAlgMBCQDMCAIJAGUCBQJiQwUCYkQJAMwIAgAABQNuaWwJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAUwDBQFECAUCYmoGY2FsbGVyBQFqCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBTgIFAUQFAWoJAGUCBQJiRQUCYkQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFUAQUBagkAZQIFAmJGBQJiRAUDbmlsCQECYmICBQJiSwUBVgUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiagEOc2V0RXBvY2hMZW5ndGgBAmJNBAJidQkAzAgCCQECYmwBBQJiagkAzAgCAwkAZgIFAmJNAAAGCQEBWQECFGludmFsaWQgZXBvY2ggbGVuZ3RoBQNuaWwDCQAAAgUCYnUFAmJ1CQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAWgFAmJNBQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmoBC3NldE1heERlcHRoAQJiTgQCYnUJAMwIAgkBAmJsAQUCYmoJAMwIAgMJAGYCBQJiTgAABgkBAVkBAhFpbnZhbGlkIG1heCBkZXB0aAUDbmlsAwkAAAIFAmJ1BQJidQkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFsBQJiTgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJqARpwcm9jZXNzUG9vbEJhbGFuY2VJTlRFUk5BTAECYk8EAmJQCQECYm0BBQJiagMJAAACBQJiUAUCYlAEAWoJAQJhaQIFBHRoaXMFAWsEAmJRCQBlAgUBagABBAFECQECYWsBBQJiTwQCYlIFAUQEAUYIBQJiUgJfMQQBRwgFAmJSAl8yBAJhRgkBAmF2AgUBRgUBRwQCYlMKAAJhaAkA/AcEBQJhbQIMY2hlY2tCYWxhbmNlCQDMCAIFAmFGBQNuaWwFA25pbAMJAAECBQJhaAIHQm9vbGVhbgUCYWgJAAIBCQCsAgIJAAMBBQJhaAIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCYlQJAQEhAQkBC3ZhbHVlT3JFbHNlAgkAmwgCBQR0aGlzCQEBSAIFAUQJAGUCBQJiUQABBwQCYlUDCQEBIQEFAmJTAwkBASEBBQJiVAQCYlYJAPwHBAUCYW0CGWRlbGV0ZVd4RW1pc3Npb25Qb29sTGFiZWwJAMwIAgUBRgkAzAgCBQFHBQNuaWwFA25pbAMJAAACBQJiVgUCYlYEAmJXCQD8BwQFAmFtAgxtb2RpZnlXZWlnaHQJAMwIAgUCYUYJAMwIAgAABQNuaWwFA25pbAMJAAACBQJiVwUCYlcEAmJYCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQECYXQCBQFGBQFHCQEBVwECDmludmFsaWQgYXNzZXRzAl8xBAJiWQADBAJiWgkA/AcEBQJhbQIKbWFuYWdlUG9vbAkAzAgCCQClCAEFAmJYCQDMCAIFAmJZBQNuaWwFA25pbAMJAAACBQJiWgUCYloEAmNhCQDOCAIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAUMBBQFEBQNuaWwJAQJiYgIFAmFLCQECYWoBBQFECQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFSAgUBRAUCYlEAAAUDbmlsBQJjYQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBAUgCBQFEBQJiUQYFA25pbAUDbmlsCQCUCgIFAmJVBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJqARNwcm9jZXNzVm90ZUlOVEVSTkFMAgJiTwFWBAJiUAkBAmJtAQUCYmoDCQAAAgUCYlAFAmJQBAJibgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEFAVYJAQFXAQkArAICAipwcm9jZXNzVm90ZUlOVEVSTkFMOiBpbnZhbGlkIHVzZXIgYWRkcmVzcyAFAVYEAWoJAQJhaQIFBHRoaXMFAWsEAmJRCQBlAgUBagABBAJidAkBAmFpAgUEdGhpcwUBZwQCYnoJAQJhaQIFBHRoaXMJAQFBAQUBagQCYkEJAGQCBQJiegUCYnQEAmNiCQECYWkCBQR0aGlzCQEBQQEFAmJRBAJjYwkBAmFpAgUEdGhpcwkBAWkBBQJiUQQCY2QJAGQCBQJjYgUCY2MEAmNlAwkAZwIFAmJRAAAGCQEBWQECK3Byb2Nlc3NWb3RlSU5URVJOQUw6IGludmFsaWQgcHJldmlvdXMgZXBvY2gDCQAAAgUCY2UFAmNlBAFECQECYWsBBQJiTwQCY2YFAUQEAUYIBQJjZgJfMQQBRwgFAmNmAl8yBAJiRwoAAmFoCQD8BwQFBHRoaXMCGGdldFVzZXJHd3hBbW91bnRBdEhlaWdodAkAzAgCBQFWCQDMCAIFAmJBBQNuaWwFA25pbAMJAAECBQJhaAIDSW50BQJhaAkAAgEJAKwCAgkAAwEFAmFoAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQEAmNnCgACYWgJAPwHBAUEdGhpcwIYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0CQDMCAIFAVYJAMwIAgUCY2QFA25pbAUDbmlsAwkAAQIFAmFoAgNJbnQFAmFoCQACAQkArAICCQADAQUCYWgCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAQCYkYJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAVQBBQFqAAAEAmNoCQELdmFsdWVPckVsc2UCCQCfCAEJAQFOAgUBRAUBagAABAJjaQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCfCAEJAQFMAwUBRAUCYm4FAmJRCQEBVwEJAKwCAgkArAICCQCsAgIJAKwCAgIUcHJvY2Vzc1ZvdGVJTlRFUk5BTCAFAmJPAgEgBQFWAhI6IG5vIHByZXZpb3VzIHZvdGUEAmJDCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFKAgUCYm4FAWoAAAQBUQkBAmF2AgUBRgUBRwQCY2oJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAVACBQFRBQJiUQAABAJicwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFnAgUEdGhpcwUBcgQCY2sJAQt2YWx1ZU9yRWxzZQIJAJoIAgUCYnMJAQFVAgUBUQUBVgAABAJjbAMJAAACBQJjawAABQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFQAgUBUQUCYlEJAGQCBQJjagUCY2kFA25pbAQCYUYJAQJhdgIFAUYFAUcEAmJJAwkAZgIFAmNnAAAJAGsDBQJjaQUCYkcFAmNnAAAEAmJVAwkAZgIFAmJJAAAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFMAwUBRAUCYm4FAWoFAmJJCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVAEFAWoJAGQCBQJiRgUCYkkJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFOAgUBRAUBagkAZAIFAmNoBQJiSQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUoCBQJibgUBagkAZAIFAmJDBQJiSQUDbmlsCQECYmICCQECYUwBBQFEBQFWCQCUCgIJAM4IAgUCYlUFAmNsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJqARNwcm9jZXNzUG9vbElOVEVSTkFMAgJiTwJjbQQCYlAJAQJibQEFAmJqAwkAAAIFAmJQBQJiUAQCY24EAmNvCQECYWkCBQR0aGlzBQFrAwUCY20FAmNvCQBlAgUCY28AAQQCY2UDCQBnAgUCY24AAAYJAQFZAQIpcHJvY2Vzc1Bvb2xJTlRFUk5BTDogaW52YWxpZCB0YXJnZXQgZXBvY2gDCQAAAgUCY2UFAmNlBAFECQECYWsBBQJiTwQCY3AFAUQEAUYIBQJjcAJfMQQBRwgFAmNwAl8yBAJicwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFnAgUEdGhpcwUBcgQCYUYJAQJhdgIFAUYFAUcEAmNxCgACYWgJAPwHBAUCYnMCEnVzZXJzTGlzdFRyYXZlcnNhbAkAzAgCBQJhRgUDbmlsBQNuaWwDCQABAgUCYWgCB0Jvb2xlYW4FAmFoCQACAQkArAICCQADAQUCYWgCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4DCQAAAgUCY3EFAmNxAwUCY3EJAJQKAgUDbmlsBgQCY3IJARFAZXh0ck5hdGl2ZSgxMDYyKQEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQJhbQUBcwIdaW52YWxpZCBhc3NldHMgc3RvcmUgY29udHJhY3QEAmJGCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFUAQUCY24AAAQCY2gJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAU4CBQFEBQJjbgAABAJjcwMJAAACBQJiRgAAAAAJAGsDBQJjaAUBYgUCYkYEAmJXCQD8BwQFAmFtAgxtb2RpZnlXZWlnaHQJAMwIAgUCYUYJAMwIAgUCY3MFA25pbAUDbmlsAwkAAAIFAmJXBQJiVwkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBUgIFAUQFAmNuBQJjcwUDbmlsBwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiagEOZmluYWxpemVIZWxwZXIABAJjbQkBC3ZhbHVlT3JFbHNlAgkAoAgBBQF6BwQBagkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFrAAAEAmN0CQBlAgUBagABBAJiegkBAmFpAgUEdGhpcwkBAUEBBQFqBAJidAkBAmFpAgUEdGhpcwUBZwQCYkEJAGQCBQJiegUCYnQEAmJCCQCaCAIFBHRoaXMFAXQDAwMJAGcCBQZoZWlnaHQFAmJBCQAAAgUCYkIFBHVuaXQHCQEBIQEFAmNtBwQCY3UJAGQCBQFqAAEEAmN2CQCaCAIFBHRoaXMFAWgEAmN3BAJhZAUCY3YDCQABAgUCYWQCA0ludAQCYk0FAmFkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFnBQJiTQkAzAgCCQELRGVsZXRlRW50cnkBBQFoBQNuaWwDCQABAgUCYWQCBFVuaXQFA25pbAkAAgECC01hdGNoIGVycm9yCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUEBBQJjdQUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF3BQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFAWsFAmN1CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF0BQFkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBaQEFAWoFAmJ0BQNuaWwFAmN3BgMDBQJjbQkAAAIFAmJCBQR1bml0BwkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF0BQFmBQNuaWwGAwkAAAIFAmJCBQR1bml0CQCUCgIFA25pbAcDCQAAAgUCYkIFAWQEAmN4CQCiCAEFAXUEAmFkBQJjeAMJAAECBQJhZAIEVW5pdAQCY3kJAKIIAQkBAmFOAQUCYUsDCQABAgUCY3kCBFVuaXQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdAUBZQkAzAgCCQELRGVsZXRlRW50cnkBBQF1BQNuaWwGAwkAAQIFAmN5AgZTdHJpbmcEAmN6BQJjeQkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXUFAmN6BQNuaWwGCQACAQILTWF0Y2ggZXJyb3IDCQABAgUCYWQCBlN0cmluZwQCYk8FAmFkBAJjQQkAoggBCQECYVQCBQJhSwUCYk8DCQAAAgUCY0EFAmNBBAJjcQkA/AcEBQR0aGlzAhpwcm9jZXNzUG9vbEJhbGFuY2VJTlRFUk5BTAkAzAgCBQJiTwUDbmlsBQNuaWwDCQAAAgUCY3EFAmNxBAJjeQUCY0EDCQABAgUCY3kCBFVuaXQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdAUBZQkAzAgCCQELRGVsZXRlRW50cnkBBQF1BQNuaWwGAwkAAQIFAmN5AgZTdHJpbmcEAmN6BQJjeQkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXUFAmN6BQNuaWwGCQACAQILTWF0Y2ggZXJyb3IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAgtNYXRjaCBlcnJvcgMJAAACBQJiQgUBZQQCY3gJAKIIAQUBdQQCY0IJAKIIAQUBdgQCYWQFAmN4AwkAAQIFAmFkAgRVbml0BAJjeQkAoggBCQECYU4BBQJhSwMJAAECBQJjeQIEVW5pdAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF0BQFmCQDMCAIJAQtEZWxldGVFbnRyeQEFAXUJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBdgUDbmlsBgMJAAECBQJjeQIGU3RyaW5nBAJjQwUCY3kJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQF1BQJjQwUDbmlsBgkAAgECC01hdGNoIGVycm9yAwkAAQIFAmFkAgZTdHJpbmcEAmJPBQJhZAQBRAkBAmFrAQUCYk8EAmNEBAJjeQUCY0IDCQABAgUCY3kCBFVuaXQJAKIIAQkBAmFOAQkBAmFMAQUBRAMJAAECBQJjeQIGU3RyaW5nBAJjRQUCY3kEAmNGCQCiCAEJAQJhVAIJAQJhTAEFAUQFAmNFAwkAAAIFAmNGBQJjRgQCY0cJAPwHBAUEdGhpcwITcHJvY2Vzc1ZvdGVJTlRFUk5BTAkAzAgCBQJiTwkAzAgCBQJjRQUDbmlsBQNuaWwDCQAAAgUCY0cFAmNHBQJjRgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECC01hdGNoIGVycm9yBAJjeQUCY0QDCQABAgUCY3kCBFVuaXQEAmNBCQCiCAEJAQJhVAIFAmFLBQJiTwQCY0gFAmNBAwkAAQIFAmNIAgRVbml0CQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAXQFAWYJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBdQkAzAgCCQELRGVsZXRlRW50cnkBBQF2BQNuaWwGAwkAAQIFAmNIAgZTdHJpbmcEAmJmBQJjSAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXUFAmJmCQDMCAIJAQtEZWxldGVFbnRyeQEFAXYFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgMJAAECBQJjeQIGU3RyaW5nBAJjSQUCY3kJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQF2BQJjSQUDbmlsBgkAAgECC01hdGNoIGVycm9yCQACAQILTWF0Y2ggZXJyb3IDCQAAAgUCYkIFAWYEAmN4CQCiCAEFAXUEAmFkBQJjeAMJAAECBQJhZAIEVW5pdAQCY3kJAKIIAQkBAmFOAQUCYUsDCQABAgUCY3kCBFVuaXQEAmJVAwUCY20JAMwIAgkBC0RlbGV0ZUVudHJ5AQUBdAkAzAgCCQELRGVsZXRlRW50cnkBBQF6BQNuaWwJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBdAkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBAUIBBQJjdAYJAMwIAgkBDEludGVnZXJFbnRyeQIFAXgFAWoJAMwIAgkBDEludGVnZXJFbnRyeQIFAXkFAmJ6BQNuaWwEAmNKCQECYUkAAwkAAAIFAmNKBQJjSgkAlAoCBQJiVQYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DCQABAgUCY3kCBlN0cmluZwQCY3oFAmN5CQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBdQUCY3oFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgMJAAECBQJhZAIGU3RyaW5nBAJiTwUCYWQEAmNBCQCiCAEJAQJhVAIFAmFLBQJiTwMJAAACBQJjQQUCY0EEAmNxCgACYWgJAPwHBAUEdGhpcwITcHJvY2Vzc1Bvb2xJTlRFUk5BTAkAzAgCBQJiTwkAzAgCBQJjbQUDbmlsBQNuaWwDCQABAgUCYWgCB0Jvb2xlYW4FAmFoCQACAQkArAICCQADAQUCYWgCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4DCQAAAgUCY3EFAmNxAwUCY3EJAJQKAgUDbmlsBgQCY3kFAmNBAwkAAQIFAmN5AgRVbml0BAJiVQMFAmNtCQDMCAIJAQtEZWxldGVFbnRyeQEFAXQJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBegkAzAgCCQELRGVsZXRlRW50cnkBBQF1BQNuaWwJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBdAkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBAUIBBQJjdAYJAMwIAgkBDEludGVnZXJFbnRyeQIFAXgFAWoJAMwIAgkBDEludGVnZXJFbnRyeQIFAXkFAmJ6CQDMCAIJAQtEZWxldGVFbnRyeQEFAXUFA25pbAQCY0oJAQJhSQADCQAAAgUCY0oFAmNKCQCUCgIFAmJVBgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgMJAAECBQJjeQIGU3RyaW5nBAJjegUCY3kJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQF1BQJjegUDbmlsBgkAAgECC01hdGNoIGVycm9yCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQILTWF0Y2ggZXJyb3IJAQFZAQIWZmluYWxpemF0aW9uIGlzIGJyb2tlbgJiagEPZmluYWxpemVXcmFwcGVyAQJjSwQCY0wJARFAZXh0ck5hdGl2ZSgxMDYyKQEJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBHRoaXMFAW8EAmNNCgACYWgJAPwHBAUEdGhpcwIOZmluYWxpemVIZWxwZXIFA25pbAUDbmlsAwkAAQIFAmFoAgdCb29sZWFuBQJhaAkAAgEJAKwCAgkAAwEFAmFoAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuAwkAAAIFAmNNBQJjTQMJAQEhAQUCY00DCQAAAgUCY0sAAAkBAVkBAh5DdXJyZW50IHZvdGluZyBpcyBub3Qgb3ZlciB5ZXQEAmNOCQD8BwQFAmNMAghmaW5hbGl6ZQUDbmlsBQNuaWwDCQAAAgUCY04FAmNOCQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgQCY08JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBbAUBYwMJAGYCBQJjTwUCY0sEAmNOCQD8BwQFBHRoaXMCD2ZpbmFsaXplV3JhcHBlcgkAzAgCCQBkAgUCY0sAAQUDbmlsBQNuaWwDCQAAAgUCY04FAmNOCQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAlAoCBQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmoBCGZpbmFsaXplAAQCY04JAPwHBAUEdGhpcwIPZmluYWxpemVXcmFwcGVyCQDMCAIAAAUDbmlsBQNuaWwDCQAAAgUCY04FAmNOCQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiagEUY29udGFpbnNOb2RlUkVBRE9OTFkCAmFPAmFTCQCUCgIFA25pbAkBAmFVAgUCYU8FAmFTAmJqAQppbnNlcnROb2RlAgJhTwJhUwQCYlAJAQJibAEFAmJqAwkAAAIFAmJQBQJiUAkAlAoCCQECYVkCBQJhTwUCYVMFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmoBCmRlbGV0ZU5vZGUCAmFPAmFTBAJiUAkBAmJsAQUCYmoDCQAAAgUCYlAFAmJQCQCUCgIJAQJiYgIFAmFPBQJhUwUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiagEYaXNGaW5hbGl6YXRpb25JblByb2dyZXNzAAQCYkIJAJoIAgUEdGhpcwUBdAQCY1AJAQIhPQIFAmJCBQR1bml0CQCUCgIFA25pbAUCY1ACYmoBCmRlbGV0ZVBvb2wCAUYBRwQCYlADAwkAAAIIBQJiagZjYWxsZXIFAmFtBgkBAmJsAQUCYmoGCQEBWQECEVBlcm1pc3Npb24gZGVuaWVkAwkAAAIFAmJQBQJiUAQCYU8CBXBvb2xzBAFECQCUCgIFAUYFAUcEAmFTCQC5CQIJAMwIAgUBRgkAzAgCBQFHBQNuaWwFAWEEAmJVAwkBAmFVAgUCYU8FAmFTCQECYmICBQJhTwUCYVMFA25pbAkAzggCCQDMCAIJAQtEZWxldGVFbnRyeQEJAQFDAQUBRAUDbmlsBQJiVQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiagEGcmVzdW1lAgFGAUcEAmFGCQECYXYCBQFGBQFHBAJjUQoAAmFoCQD8BwQFAmFtAgxjaGVja0JhbGFuY2UJAMwIAgUCYUYFA25pbAUDbmlsAwkAAQIFAmFoAgdCb29sZWFuBQJhaAkAAgEJAKwCAgkAAwEFAmFoAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJjUgkAkQMCCAUCYmoIcGF5bWVudHMAAAQCY3IJARFAZXh0ck5hdGl2ZSgxMDYyKQEJARFAZXh0ck5hdGl2ZSgxMDUzKQIFBHRoaXMFAXMEAmNTAgolc19fY29uZmlnBAJjVAABBAJicgkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFnAgUEdGhpcwUBcQQCY1UJANkEAQkAkQMCCQC1CQIJARFAZXh0ck5hdGl2ZSgxMDUzKQIFAmJyBQJjUwUBYQUCY1QEAmNWCgACYWgJAPwHBAUCY3ICEmlzVmVyaWZpZWRSRUFET05MWQkAzAgCBQFGBQNuaWwFA25pbAMJAAECBQJhaAIHQm9vbGVhbgUCYWgJAAIBCQCsAgIJAAMBBQJhaAIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCY1cKAAJhaAkA/AcEBQJjcgISaXNWZXJpZmllZFJFQURPTkxZCQDMCAIFAUcFA25pbAUDbmlsAwkAAQIFAmFoAgdCb29sZWFuBQJhaAkAAgEJAKwCAgkAAwEFAmFoAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJjWAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFBHRoaXMFAW0CFmludmFsaWQgcmVzdW1wdGlvbiBmZWUEAmJ1CQDMCAIDBQJjUQYJAQFZAQIVaW5zdWZmaWNpZW50IGJhbGFuY2VzCQDMCAIDCQAAAgkAkAMBCAUCYmoIcGF5bWVudHMAAQYJAQFZAQIVMSBwYXltZW50IGlzIHJlcXVpcmVkCQDMCAIDCQAAAggFAmNSB2Fzc2V0SWQFAmNVBgkBAVkBAhhpbnZhbGlkIHBheW1lbnQgYXNzZXQgaWQJAMwIAgMJAAACCAUCY1IGYW1vdW50BQJjWAYJAQFZAQIWaW52YWxpZCBwYXltZW50IGFtb3VudAkAzAgCAwMFAmNWBQJjVwcGCQEBWQECHmJvdGggYXNzZXRzIHNob3VsZCBiZSB2ZXJpZmllZAUDbmlsAwkAAAIFAmJ1BQJidQQCY1kJAPwHBAUCYW0CFnNldFd4RW1pc3Npb25Qb29sTGFiZWwJAMwIAgUBRgkAzAgCBQFHBQNuaWwFA25pbAMJAAACBQJjWQUCY1kEAUQJAJQKAgUBRgUBRwQCYnYJAM4IAgkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBAUMBBQFEBgUDbmlsCQECYVkCBQJhSwkBAmFqAQUBRAkAlAoCBQJidgUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY1oBAmRhAAQCZGIEAmFkCQECYmcAAwkAAQIFAmFkAgpCeXRlVmVjdG9yBAJiawUCYWQFAmJrAwkAAQIFAmFkAgRVbml0CAUCY1oPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IJAPQDAwgFAmNaCWJvZHlCeXRlcwkAkQMCCAUCY1oGcHJvb2ZzAAAFAmRiPUiPew==", "height": 3066519, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: GSPTD42ZfJuujPW4kMVGFUbmJF82gZzGM2p1WJ26e4mc Next: KTryZkBiizn7FmoWa3HxgrzWHARH3brtXuWu8ijAznF Diff:
Old | New | Differences | |
---|---|---|---|
12 | 12 | let finalizationStageTotal = 1 | |
13 | 13 | ||
14 | 14 | let finalizationStageShares = 2 | |
15 | - | ||
16 | - | let resumptionFeeDefault = 500000000000 | |
17 | 15 | ||
18 | 16 | let keyEpochLength = makeString(["%s", "epochLength"], separator) | |
19 | 17 | ||
61 | 59 | ||
62 | 60 | ||
63 | 61 | func keyInList (pool) = { | |
64 | - | let $ | |
65 | - | let amountAssetId = $ | |
66 | - | let priceAssetId = $ | |
62 | + | let $t019722012 = pool | |
63 | + | let amountAssetId = $t019722012._1 | |
64 | + | let priceAssetId = $t019722012._2 | |
67 | 65 | makeString(["%s%s%s", "inList", amountAssetId, priceAssetId], separator) | |
68 | 66 | } | |
69 | 67 | ||
70 | 68 | ||
71 | 69 | func keyInsufficientBalances (pool,epoch) = { | |
72 | - | let $ | |
73 | - | let amountAssetId = $ | |
74 | - | let priceAssetId = $ | |
70 | + | let $t021612201 = pool | |
71 | + | let amountAssetId = $t021612201._1 | |
72 | + | let priceAssetId = $t021612201._2 | |
75 | 73 | makeString(["%s%s%s%d", "insufficientBalances", amountAssetId, priceAssetId, toString(epoch)], separator) | |
76 | 74 | } | |
77 | 75 | ||
80 | 78 | ||
81 | 79 | ||
82 | 80 | func keyVote (pool,address,epoch) = { | |
83 | - | let $ | |
84 | - | let amountAssetId = $ | |
85 | - | let priceAssetId = $ | |
81 | + | let $t025092549 = pool | |
82 | + | let amountAssetId = $t025092549._1 | |
83 | + | let priceAssetId = $t025092549._2 | |
86 | 84 | makeString(["%s%s%s%s%d", "vote", amountAssetId, priceAssetId, toString(address), toString(epoch)], separator) | |
87 | 85 | } | |
88 | 86 | ||
89 | 87 | ||
90 | 88 | func keyVotingResult (pool,epoch) = { | |
91 | - | let $ | |
92 | - | let amountAssetId = $ | |
93 | - | let priceAssetId = $ | |
89 | + | let $t027312771 = pool | |
90 | + | let amountAssetId = $t027312771._1 | |
91 | + | let priceAssetId = $t027312771._2 | |
94 | 92 | makeString(["%s%s%s%d", "votingResult", amountAssetId, priceAssetId, toString(epoch)], separator) | |
95 | 93 | } | |
96 | 94 | ||
99 | 97 | ||
100 | 98 | ||
101 | 99 | func keyPoolShare (pool,epoch) = { | |
102 | - | let $ | |
103 | - | let amountAssetId = $ | |
104 | - | let priceAssetId = $ | |
100 | + | let $t030923132 = pool | |
101 | + | let amountAssetId = $t030923132._1 | |
102 | + | let priceAssetId = $t030923132._2 | |
105 | 103 | makeString(["%s%s%s%d", "poolShare", amountAssetId, priceAssetId, toString(epoch)], separator) | |
106 | 104 | } | |
107 | 105 | ||
198 | 196 | ||
199 | 197 | ||
200 | 198 | func checkWxEmissionPoolLabel (pool) = { | |
201 | - | let $ | |
202 | - | let amountAssetId = $ | |
203 | - | let priceAssetId = $ | |
199 | + | let $t062586298 = pool | |
200 | + | let amountAssetId = $t062586298._1 | |
201 | + | let priceAssetId = $t062586298._2 | |
204 | 202 | let @ = invoke(factoryContract, "checkWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil) | |
205 | 203 | if ($isInstanceOf(@, "Boolean")) | |
206 | 204 | then @ | |
218 | 216 | let poolsListName = "pools" | |
219 | 217 | ||
220 | 218 | func getVotesListName (pool) = { | |
221 | - | let $ | |
222 | - | let amountAssetId = $ | |
223 | - | let priceAssetId = $ | |
219 | + | let $t067156755 = pool | |
220 | + | let amountAssetId = $t067156755._1 | |
221 | + | let priceAssetId = $t067156755._2 | |
224 | 222 | makeString(["votes", amountAssetId, priceAssetId], separator) | |
225 | 223 | } | |
226 | 224 | ||
519 | 517 | let epoch = getIntOrFail(this, keyCurrentEpoch) | |
520 | 518 | let epochPrevious = (epoch - 1) | |
521 | 519 | let pool = stringToPool(poolStr) | |
522 | - | let $ | |
523 | - | let amountAssetId = $ | |
524 | - | let priceAssetId = $ | |
520 | + | let $t01697917019 = pool | |
521 | + | let amountAssetId = $t01697917019._1 | |
522 | + | let priceAssetId = $t01697917019._2 | |
525 | 523 | let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId) | |
526 | 524 | let balanceIsOkCurrent = { | |
527 | 525 | let @ = invoke(factoryContract, "checkBalance", [lpAssetId], nil) | |
582 | 580 | if ((checkTargetEpoch == checkTargetEpoch)) | |
583 | 581 | then { | |
584 | 582 | let pool = stringToPool(poolStr) | |
585 | - | let $ | |
586 | - | let amountAssetId = $ | |
587 | - | let priceAssetId = $ | |
583 | + | let $t01937219412 = pool | |
584 | + | let amountAssetId = $t01937219412._1 | |
585 | + | let priceAssetId = $t01937219412._2 | |
588 | 586 | let gwxAmountAtEndTotal = { | |
589 | 587 | let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil) | |
590 | 588 | if ($isInstanceOf(@, "Int")) | |
641 | 639 | if ((checkTargetEpoch == checkTargetEpoch)) | |
642 | 640 | then { | |
643 | 641 | let pool = stringToPool(poolStr) | |
644 | - | let $ | |
645 | - | let amountAssetId = $ | |
646 | - | let priceAssetId = $ | |
642 | + | let $t02177521815 = pool | |
643 | + | let amountAssetId = $t02177521815._1 | |
644 | + | let priceAssetId = $t02177521815._2 | |
647 | 645 | let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract)) | |
648 | 646 | let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId) | |
649 | 647 | let r = { | |
981 | 979 | then @ | |
982 | 980 | else throw(($getType(@) + " couldn't be cast to Boolean")) | |
983 | 981 | } | |
984 | - | let resumptionFee = | |
982 | + | let resumptionFee = valueOrErrorMessage(getInteger(this, keyResumptionFee), "invalid resumption fee") | |
985 | 983 | let checks = [if (balanceIsOk) | |
986 | 984 | then true | |
987 | 985 | else throwErr("insufficient balances"), if ((size(i.payments) == 1)) |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 6 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | let separator = "__" | |
5 | 5 | ||
6 | 6 | let poolWeightMult = 100000000 | |
7 | 7 | ||
8 | 8 | let maxDepthDefault = 10 | |
9 | 9 | ||
10 | 10 | let finalizationStageBalances = 0 | |
11 | 11 | ||
12 | 12 | let finalizationStageTotal = 1 | |
13 | 13 | ||
14 | 14 | let finalizationStageShares = 2 | |
15 | - | ||
16 | - | let resumptionFeeDefault = 500000000000 | |
17 | 15 | ||
18 | 16 | let keyEpochLength = makeString(["%s", "epochLength"], separator) | |
19 | 17 | ||
20 | 18 | let keyEpochLengthNew = makeString(["%s%s", "epochLength__new"], separator) | |
21 | 19 | ||
22 | 20 | func keyEpochLengthByEpoch (epoch) = makeString(["%s%d", "epochLength", toString(epoch)], separator) | |
23 | 21 | ||
24 | 22 | ||
25 | 23 | let keyCurrentEpoch = makeString(["%s", "currentEpoch"], separator) | |
26 | 24 | ||
27 | 25 | let keyMaxDepth = makeString(["%s", "maxDepth"], separator) | |
28 | 26 | ||
29 | 27 | let keyResumptionFee = makeString(["%s", "resumptionFee"], separator) | |
30 | 28 | ||
31 | 29 | let keyVotingEmissionCandidateContract = makeString(["%s", "votingEmissionCandidateContract"], separator) | |
32 | 30 | ||
33 | 31 | let keyVotingEmissionRateContract = makeString(["%s", "votingEmissionRateContract"], separator) | |
34 | 32 | ||
35 | 33 | let keyFactoryContract = makeString(["%s", "factoryContract"], separator) | |
36 | 34 | ||
37 | 35 | let keyBoostingContract = makeString(["%s", "boostingContract"], separator) | |
38 | 36 | ||
39 | 37 | let keyStakingContract = makeString(["%s", "stakingContract"], separator) | |
40 | 38 | ||
41 | 39 | let keyAssetsStoreContract = makeString(["%s", "assetsStoreContract"], separator) | |
42 | 40 | ||
43 | 41 | let keyFinalizationStage = makeString(["%s", "finalizationStage"], separator) | |
44 | 42 | ||
45 | 43 | let keyNextPool = makeString(["%s", "nextPool"], separator) | |
46 | 44 | ||
47 | 45 | let keyNextUser = makeString(["%s", "nextUser"], separator) | |
48 | 46 | ||
49 | 47 | let keyStartHeight = makeString(["%s", "startHeight"], separator) | |
50 | 48 | ||
51 | 49 | let keyCurrentEpochUi = makeString(["%s", "currentEpochUi"], separator) | |
52 | 50 | ||
53 | 51 | let keyStartHeightUi = makeString(["%s", "startHeightUi"], separator) | |
54 | 52 | ||
55 | 53 | let keyFinalizationShouldBeForced = makeString(["%s", "force"], separator) | |
56 | 54 | ||
57 | 55 | func keyStartHeightByEpoch (epoch) = makeString(["%s%d", "startHeight", toString(epoch)], separator) | |
58 | 56 | ||
59 | 57 | ||
60 | 58 | func keyFinalized (epoch) = makeString(["%s%d", "finalized", toString(epoch)], separator) | |
61 | 59 | ||
62 | 60 | ||
63 | 61 | func keyInList (pool) = { | |
64 | - | let $ | |
65 | - | let amountAssetId = $ | |
66 | - | let priceAssetId = $ | |
62 | + | let $t019722012 = pool | |
63 | + | let amountAssetId = $t019722012._1 | |
64 | + | let priceAssetId = $t019722012._2 | |
67 | 65 | makeString(["%s%s%s", "inList", amountAssetId, priceAssetId], separator) | |
68 | 66 | } | |
69 | 67 | ||
70 | 68 | ||
71 | 69 | func keyInsufficientBalances (pool,epoch) = { | |
72 | - | let $ | |
73 | - | let amountAssetId = $ | |
74 | - | let priceAssetId = $ | |
70 | + | let $t021612201 = pool | |
71 | + | let amountAssetId = $t021612201._1 | |
72 | + | let priceAssetId = $t021612201._2 | |
75 | 73 | makeString(["%s%s%s%d", "insufficientBalances", amountAssetId, priceAssetId, toString(epoch)], separator) | |
76 | 74 | } | |
77 | 75 | ||
78 | 76 | ||
79 | 77 | func keyUsed (address,epoch) = makeString(["%s%s%d", "used", toString(address), toString(epoch)], separator) | |
80 | 78 | ||
81 | 79 | ||
82 | 80 | func keyVote (pool,address,epoch) = { | |
83 | - | let $ | |
84 | - | let amountAssetId = $ | |
85 | - | let priceAssetId = $ | |
81 | + | let $t025092549 = pool | |
82 | + | let amountAssetId = $t025092549._1 | |
83 | + | let priceAssetId = $t025092549._2 | |
86 | 84 | makeString(["%s%s%s%s%d", "vote", amountAssetId, priceAssetId, toString(address), toString(epoch)], separator) | |
87 | 85 | } | |
88 | 86 | ||
89 | 87 | ||
90 | 88 | func keyVotingResult (pool,epoch) = { | |
91 | - | let $ | |
92 | - | let amountAssetId = $ | |
93 | - | let priceAssetId = $ | |
89 | + | let $t027312771 = pool | |
90 | + | let amountAssetId = $t027312771._1 | |
91 | + | let priceAssetId = $t027312771._2 | |
94 | 92 | makeString(["%s%s%s%d", "votingResult", amountAssetId, priceAssetId, toString(epoch)], separator) | |
95 | 93 | } | |
96 | 94 | ||
97 | 95 | ||
98 | 96 | func keyVotingResultStaked (lpAssetIdStr,epoch) = makeString(["%s%s%d", "votingResultStaked", lpAssetIdStr, toString(epoch)], separator) | |
99 | 97 | ||
100 | 98 | ||
101 | 99 | func keyPoolShare (pool,epoch) = { | |
102 | - | let $ | |
103 | - | let amountAssetId = $ | |
104 | - | let priceAssetId = $ | |
100 | + | let $t030923132 = pool | |
101 | + | let amountAssetId = $t030923132._1 | |
102 | + | let priceAssetId = $t030923132._2 | |
105 | 103 | makeString(["%s%s%s%d", "poolShare", amountAssetId, priceAssetId, toString(epoch)], separator) | |
106 | 104 | } | |
107 | 105 | ||
108 | 106 | ||
109 | 107 | func keyTotalVotes (epoch) = makeString(["%s%d", "totalVotes", toString(epoch)], separator) | |
110 | 108 | ||
111 | 109 | ||
112 | 110 | func keyStakedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s", "staked", userAddressStr, lpAssetIdStr], separator) | |
113 | 111 | ||
114 | 112 | ||
115 | 113 | func wrapErr (msg) = makeString(["voting_emission.ride:", msg], " ") | |
116 | 114 | ||
117 | 115 | ||
118 | 116 | func throwErr (msg) = throw(wrapErr(msg)) | |
119 | 117 | ||
120 | 118 | ||
121 | 119 | func getValueOrFail (address,key,type) = { | |
122 | 120 | let error = wrapErr(makeString(["mandatory ", toString(address), ".", key, " is not defined"], "")) | |
123 | 121 | valueOrErrorMessage( match type { | |
124 | 122 | case str: String => | |
125 | 123 | getString(address, key) | |
126 | 124 | case int: Int => | |
127 | 125 | getInteger(address, key) | |
128 | 126 | case _ => | |
129 | 127 | throwErr("invalid entry type") | |
130 | 128 | }, error) | |
131 | 129 | } | |
132 | 130 | ||
133 | 131 | ||
134 | 132 | func getStrOrFail (address,key) = { | |
135 | 133 | let @ = getValueOrFail(address, key, "") | |
136 | 134 | if ($isInstanceOf(@, "String")) | |
137 | 135 | then @ | |
138 | 136 | else throw(($getType(@) + " couldn't be cast to String")) | |
139 | 137 | } | |
140 | 138 | ||
141 | 139 | ||
142 | 140 | func getIntOrFail (address,key) = { | |
143 | 141 | let @ = getValueOrFail(address, key, 0) | |
144 | 142 | if ($isInstanceOf(@, "Int")) | |
145 | 143 | then @ | |
146 | 144 | else throw(($getType(@) + " couldn't be cast to Int")) | |
147 | 145 | } | |
148 | 146 | ||
149 | 147 | ||
150 | 148 | func poolToString (pool) = ((pool._1 + separator) + pool._2) | |
151 | 149 | ||
152 | 150 | ||
153 | 151 | func stringToPool (str) = { | |
154 | 152 | let parts = split(str, separator) | |
155 | 153 | if ((size(parts) == 2)) | |
156 | 154 | then $Tuple2(parts[0], parts[1]) | |
157 | 155 | else throwErr("invalid pool string") | |
158 | 156 | } | |
159 | 157 | ||
160 | 158 | ||
161 | 159 | let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract)) | |
162 | 160 | ||
163 | 161 | let IdxFactoryCfgGwxRewardDapp = 10 | |
164 | 162 | ||
165 | 163 | func keyFactoryCfg () = "%s__factoryConfig" | |
166 | 164 | ||
167 | 165 | ||
168 | 166 | func readFactoryCfgOrFail (factory) = split(getStrOrFail(factory, keyFactoryCfg()), separator) | |
169 | 167 | ||
170 | 168 | ||
171 | 169 | func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp]) | |
172 | 170 | ||
173 | 171 | ||
174 | 172 | func getPoolInfo (amountAssetId,priceAssetId) = { | |
175 | 173 | let poolInfoOption = { | |
176 | 174 | let @ = invoke(factoryContract, "poolInfoREADONLY", [amountAssetId, priceAssetId], nil) | |
177 | 175 | if ($isInstanceOf(@, "(Address, ByteVector)")) | |
178 | 176 | then @ | |
179 | 177 | else unit | |
180 | 178 | } | |
181 | 179 | poolInfoOption | |
182 | 180 | } | |
183 | 181 | ||
184 | 182 | ||
185 | 183 | func getLpAssetByPoolAssets (amountAssetId,priceAssetId) = { | |
186 | 184 | func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr) | |
187 | 185 | ||
188 | 186 | func keyMappingPoolAssetsToPoolContractAddress (internalAmountAssetIdStr,internalPriceAssetIdStr) = (((("%d%d%s%s__" + toString(internalAmountAssetIdStr)) + "__") + toString(internalPriceAssetIdStr)) + "__mappings__poolAssets2PoolContract") | |
189 | 187 | ||
190 | 188 | func keyMappingPoolContractToLPAsset (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset") | |
191 | 189 | ||
192 | 190 | let amountAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amountAssetId)) | |
193 | 191 | let priceAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAssetId)) | |
194 | 192 | let poolContractAddress = getStrOrFail(factoryContract, keyMappingPoolAssetsToPoolContractAddress(amountAssetInternalId, priceAssetInternalId)) | |
195 | 193 | let lpAssetId = getStrOrFail(factoryContract, keyMappingPoolContractToLPAsset(poolContractAddress)) | |
196 | 194 | lpAssetId | |
197 | 195 | } | |
198 | 196 | ||
199 | 197 | ||
200 | 198 | func checkWxEmissionPoolLabel (pool) = { | |
201 | - | let $ | |
202 | - | let amountAssetId = $ | |
203 | - | let priceAssetId = $ | |
199 | + | let $t062586298 = pool | |
200 | + | let amountAssetId = $t062586298._1 | |
201 | + | let priceAssetId = $t062586298._2 | |
204 | 202 | let @ = invoke(factoryContract, "checkWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil) | |
205 | 203 | if ($isInstanceOf(@, "Boolean")) | |
206 | 204 | then @ | |
207 | 205 | else throw(($getType(@) + " couldn't be cast to Boolean")) | |
208 | 206 | } | |
209 | 207 | ||
210 | 208 | ||
211 | 209 | func gwxRewardDeposit () = { | |
212 | 210 | let factoryCfg = readFactoryCfgOrFail(factoryContract) | |
213 | 211 | let gwxRewardsContract = getGwxRewardAddressOrFail(factoryCfg) | |
214 | 212 | invoke(gwxRewardsContract, "deposit", nil, nil) | |
215 | 213 | } | |
216 | 214 | ||
217 | 215 | ||
218 | 216 | let poolsListName = "pools" | |
219 | 217 | ||
220 | 218 | func getVotesListName (pool) = { | |
221 | - | let $ | |
222 | - | let amountAssetId = $ | |
223 | - | let priceAssetId = $ | |
219 | + | let $t067156755 = pool | |
220 | + | let amountAssetId = $t067156755._1 | |
221 | + | let priceAssetId = $t067156755._2 | |
224 | 222 | makeString(["votes", amountAssetId, priceAssetId], separator) | |
225 | 223 | } | |
226 | 224 | ||
227 | 225 | ||
228 | 226 | func keyListHead (listName) = { | |
229 | 227 | let meta = if ((listName == poolsListName)) | |
230 | 228 | then "%s%s" | |
231 | 229 | else "%s%s%s%s" | |
232 | 230 | makeString([meta, listName, "head"], separator) | |
233 | 231 | } | |
234 | 232 | ||
235 | 233 | ||
236 | 234 | func keyListSize (listName) = { | |
237 | 235 | let meta = if ((listName == poolsListName)) | |
238 | 236 | then "%s%s" | |
239 | 237 | else "%s%s%s%s" | |
240 | 238 | makeString([meta, listName, "size"], separator) | |
241 | 239 | } | |
242 | 240 | ||
243 | 241 | ||
244 | 242 | func keyListPrev (listName,id) = { | |
245 | 243 | let meta = if ((listName == poolsListName)) | |
246 | 244 | then "%s%s%s%s" | |
247 | 245 | else "%s%s%s%s%s" | |
248 | 246 | makeString([meta, listName, id, "prev"], separator) | |
249 | 247 | } | |
250 | 248 | ||
251 | 249 | ||
252 | 250 | func keyListNext (listName,id) = { | |
253 | 251 | let meta = if ((listName == poolsListName)) | |
254 | 252 | then "%s%s%s%s" | |
255 | 253 | else "%s%s%s%s%s" | |
256 | 254 | makeString([meta, listName, id, "next"], separator) | |
257 | 255 | } | |
258 | 256 | ||
259 | 257 | ||
260 | 258 | func containsNode (listName,id) = { | |
261 | 259 | let headOrUnit = getString(this, keyListHead(listName)) | |
262 | 260 | let prevOrUnit = getString(this, keyListPrev(listName, id)) | |
263 | 261 | let nextOrUnit = getString(this, keyListNext(listName, id)) | |
264 | 262 | if (if ((id == valueOrElse(headOrUnit, ""))) | |
265 | 263 | then true | |
266 | 264 | else (prevOrUnit != unit)) | |
267 | 265 | then true | |
268 | 266 | else (nextOrUnit != unit) | |
269 | 267 | } | |
270 | 268 | ||
271 | 269 | ||
272 | 270 | func insertNodeActions (listName,id) = { | |
273 | 271 | let headOrUnit = getString(this, keyListHead(listName)) | |
274 | 272 | let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0) | |
275 | 273 | let checkNode = if (!(containsNode(listName, id))) | |
276 | 274 | then true | |
277 | 275 | else throwErr("Node exists") | |
278 | 276 | if ((checkNode == checkNode)) | |
279 | 277 | then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit)) | |
280 | 278 | then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)] | |
281 | 279 | else nil)) ++ [StringEntry(keyListHead(listName), id)]) | |
282 | 280 | else throw("Strict value is not equal to itself.") | |
283 | 281 | } | |
284 | 282 | ||
285 | 283 | ||
286 | 284 | func deleteNodeActions (listName,id) = { | |
287 | 285 | let headOrUnit = getString(this, keyListHead(listName)) | |
288 | 286 | let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0) | |
289 | 287 | let prevOrUnit = getString(this, keyListPrev(listName, id)) | |
290 | 288 | let nextOrUnit = getString(this, keyListNext(listName, id)) | |
291 | 289 | ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit)) | |
292 | 290 | then (nextOrUnit != unit) | |
293 | 291 | else false) | |
294 | 292 | then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))] | |
295 | 293 | else if ((nextOrUnit != unit)) | |
296 | 294 | then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))] | |
297 | 295 | else if ((prevOrUnit != unit)) | |
298 | 296 | then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))] | |
299 | 297 | else if ((id == valueOrElse(headOrUnit, ""))) | |
300 | 298 | then [DeleteEntry(keyListHead(listName))] | |
301 | 299 | else throwErr(((("invalid node: " + listName) + ".") + id)))) | |
302 | 300 | } | |
303 | 301 | ||
304 | 302 | ||
305 | 303 | func keyManagerVaultAddress () = "%s__managerVaultAddress" | |
306 | 304 | ||
307 | 305 | ||
308 | 306 | func keyManagerPublicKey () = "%s__managerPublicKey" | |
309 | 307 | ||
310 | 308 | ||
311 | 309 | func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) { | |
312 | 310 | case s: String => | |
313 | 311 | addressFromStringValue(s) | |
314 | 312 | case _ => | |
315 | 313 | this | |
316 | 314 | } | |
317 | 315 | ||
318 | 316 | ||
319 | 317 | func managerPublicKeyOrUnit () = { | |
320 | 318 | let managerVaultAddress = getManagerVaultAddressOrThis() | |
321 | 319 | match getString(managerVaultAddress, keyManagerPublicKey()) { | |
322 | 320 | case s: String => | |
323 | 321 | fromBase58String(s) | |
324 | 322 | case _: Unit => | |
325 | 323 | unit | |
326 | 324 | case _ => | |
327 | 325 | throw("Match error") | |
328 | 326 | } | |
329 | 327 | } | |
330 | 328 | ||
331 | 329 | ||
332 | 330 | func isManager (i) = match managerPublicKeyOrUnit() { | |
333 | 331 | case pk: ByteVector => | |
334 | 332 | (i.callerPublicKey == pk) | |
335 | 333 | case _: Unit => | |
336 | 334 | (i.caller == this) | |
337 | 335 | case _ => | |
338 | 336 | throw("Match error") | |
339 | 337 | } | |
340 | 338 | ||
341 | 339 | ||
342 | 340 | func mustManager (i) = if (isManager(i)) | |
343 | 341 | then true | |
344 | 342 | else throw("permission denied") | |
345 | 343 | ||
346 | 344 | ||
347 | 345 | func mustThis (i) = if ((i.caller == this)) | |
348 | 346 | then true | |
349 | 347 | else throw("permission denied") | |
350 | 348 | ||
351 | 349 | ||
352 | 350 | @Callable(i) | |
353 | 351 | func getUserGwxAmountAtHeight (userAddress,targetHeight) = { | |
354 | 352 | let boostingContractAddress = valueOrErrorMessage(addressFromString(getStrOrFail(this, keyBoostingContract)), wrapErr("invalid boosting contract address")) | |
355 | 353 | $Tuple2(nil, { | |
356 | 354 | let @ = invoke(boostingContractAddress, "getUserGwxAmountAtHeightREADONLY", [userAddress, targetHeight], nil) | |
357 | 355 | if ($isInstanceOf(@, "Int")) | |
358 | 356 | then @ | |
359 | 357 | else throw(($getType(@) + " couldn't be cast to Int")) | |
360 | 358 | }) | |
361 | 359 | } | |
362 | 360 | ||
363 | 361 | ||
364 | 362 | ||
365 | 363 | @Callable(i) | |
366 | 364 | func constructor (factoryContract,votingEmissionCandidateContract,boostingContract,stakingContract,epochLength) = { | |
367 | 365 | let checks = [mustManager(i), if ((addressFromString(factoryContract) != unit)) | |
368 | 366 | then true | |
369 | 367 | else "invalid factory contract address", if ((addressFromString(votingEmissionCandidateContract) != unit)) | |
370 | 368 | then true | |
371 | 369 | else "invalid voting emission candidate contract address", if ((addressFromString(boostingContract) != unit)) | |
372 | 370 | then true | |
373 | 371 | else "invalid boosting contract address", if ((addressFromString(stakingContract) != unit)) | |
374 | 372 | then true | |
375 | 373 | else "invalid staking contract address", if ((epochLength > 0)) | |
376 | 374 | then true | |
377 | 375 | else throwErr("invalid epoch length")] | |
378 | 376 | if ((checks == checks)) | |
379 | 377 | then $Tuple2([StringEntry(keyFactoryContract, factoryContract), StringEntry(keyVotingEmissionCandidateContract, votingEmissionCandidateContract), StringEntry(keyBoostingContract, boostingContract), StringEntry(keyStakingContract, stakingContract), IntegerEntry(keyEpochLength, epochLength)], unit) | |
380 | 378 | else throw("Strict value is not equal to itself.") | |
381 | 379 | } | |
382 | 380 | ||
383 | 381 | ||
384 | 382 | ||
385 | 383 | @Callable(i) | |
386 | 384 | func create (amountAssetId,priceAssetId) = { | |
387 | 385 | let checks = [if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionCandidateContract), ""))) | |
388 | 386 | then true | |
389 | 387 | else mustManager(i)] | |
390 | 388 | if ((checks == checks)) | |
391 | 389 | then { | |
392 | 390 | let pool = $Tuple2(amountAssetId, priceAssetId) | |
393 | 391 | let inListActions = ([BooleanEntry(keyInList(pool), true)] ++ insertNodeActions(poolsListName, poolToString(pool))) | |
394 | 392 | let currentEpochIsNotDefined = (getInteger(this, keyCurrentEpoch) == unit) | |
395 | 393 | let startHeightActions = if (currentEpochIsNotDefined) | |
396 | 394 | then { | |
397 | 395 | let epoch = 0 | |
398 | 396 | [IntegerEntry(keyCurrentEpoch, epoch), IntegerEntry(keyStartHeightByEpoch(epoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, height)] | |
399 | 397 | } | |
400 | 398 | else nil | |
401 | 399 | $Tuple2((inListActions ++ startHeightActions), unit) | |
402 | 400 | } | |
403 | 401 | else throw("Strict value is not equal to itself.") | |
404 | 402 | } | |
405 | 403 | ||
406 | 404 | ||
407 | 405 | ||
408 | 406 | @Callable(i) | |
409 | 407 | func vote (amountAssetId,priceAssetId,amount) = { | |
410 | 408 | let pool = $Tuple2(amountAssetId, priceAssetId) | |
411 | 409 | let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0) | |
412 | 410 | let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch)) | |
413 | 411 | let epochLength = getIntOrFail(this, keyEpochLength) | |
414 | 412 | let endHeight = (startHeight + epochLength) | |
415 | 413 | let finalizationStageOrUnit = getInteger(this, keyFinalizationStage) | |
416 | 414 | let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0) | |
417 | 415 | let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0) | |
418 | 416 | let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0) | |
419 | 417 | let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0) | |
420 | 418 | let gwxAmountAtEndTotal = { | |
421 | 419 | let @ = invoke(this, "getUserGwxAmountAtHeight", [toBase58String(i.caller.bytes), endHeight], nil) | |
422 | 420 | if ($isInstanceOf(@, "Int")) | |
423 | 421 | then @ | |
424 | 422 | else throw(($getType(@) + " couldn't be cast to Int")) | |
425 | 423 | } | |
426 | 424 | let available = (gwxAmountAtEndTotal - used) | |
427 | 425 | let newVote = (vote + amount) | |
428 | 426 | let wxEmission = checkWxEmissionPoolLabel(pool) | |
429 | 427 | let checks = [if ((getBoolean(keyInList(pool)) != unit)) | |
430 | 428 | then true | |
431 | 429 | else throwErr("invalid assets"), if ((endHeight > height)) | |
432 | 430 | then true | |
433 | 431 | else throwErr("invalid height"), if ((finalizationStageOrUnit == unit)) | |
434 | 432 | then true | |
435 | 433 | else throwErr("finalization in progress"), if ((gwxAmountAtEndTotal > 0)) | |
436 | 434 | then true | |
437 | 435 | else throwErr("you do not have gWX"), if (if ((amount > 0)) | |
438 | 436 | then (available >= amount) | |
439 | 437 | else false) | |
440 | 438 | then true | |
441 | 439 | else throwErr("invalid amount"), if (wxEmission) | |
442 | 440 | then true | |
443 | 441 | else throwErr("pool hasn't WX_EMISSION label")] | |
444 | 442 | if ((checks == checks)) | |
445 | 443 | then { | |
446 | 444 | let votesListName = getVotesListName(pool) | |
447 | 445 | let userAddressStr = toString(i.caller) | |
448 | 446 | let votesListActions = if (containsNode(votesListName, userAddressStr)) | |
449 | 447 | then nil | |
450 | 448 | else insertNodeActions(votesListName, userAddressStr) | |
451 | 449 | $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) | |
452 | 450 | } | |
453 | 451 | else throw("Strict value is not equal to itself.") | |
454 | 452 | } | |
455 | 453 | ||
456 | 454 | ||
457 | 455 | ||
458 | 456 | @Callable(i) | |
459 | 457 | func cancelVote (amountAssetId,priceAssetId) = { | |
460 | 458 | let pool = $Tuple2(amountAssetId, priceAssetId) | |
461 | 459 | let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0) | |
462 | 460 | let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch)) | |
463 | 461 | let epochLength = getIntOrFail(this, keyEpochLength) | |
464 | 462 | let endHeight = (startHeight + epochLength) | |
465 | 463 | let finalizationStageOrUnit = getInteger(this, keyFinalizationStage) | |
466 | 464 | let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0) | |
467 | 465 | let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0) | |
468 | 466 | let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0) | |
469 | 467 | let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0) | |
470 | 468 | let checks = [if ((getBoolean(keyInList(pool)) != unit)) | |
471 | 469 | then true | |
472 | 470 | else throwErr("invalid assets"), if ((endHeight > height)) | |
473 | 471 | then true | |
474 | 472 | else throwErr("invalid height"), if ((finalizationStageOrUnit == unit)) | |
475 | 473 | then true | |
476 | 474 | else throwErr("finalization in progress"), if ((vote > 0)) | |
477 | 475 | then true | |
478 | 476 | else throwErr("no vote")] | |
479 | 477 | if ((checks == checks)) | |
480 | 478 | then { | |
481 | 479 | let votesListName = getVotesListName(pool) | |
482 | 480 | let userAddressStr = toString(i.caller) | |
483 | 481 | $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) | |
484 | 482 | } | |
485 | 483 | else throw("Strict value is not equal to itself.") | |
486 | 484 | } | |
487 | 485 | ||
488 | 486 | ||
489 | 487 | ||
490 | 488 | @Callable(i) | |
491 | 489 | func setEpochLength (newEpochLength) = { | |
492 | 490 | let checks = [mustManager(i), if ((newEpochLength > 0)) | |
493 | 491 | then true | |
494 | 492 | else throwErr("invalid epoch length")] | |
495 | 493 | if ((checks == checks)) | |
496 | 494 | then $Tuple2([IntegerEntry(keyEpochLengthNew, newEpochLength)], unit) | |
497 | 495 | else throw("Strict value is not equal to itself.") | |
498 | 496 | } | |
499 | 497 | ||
500 | 498 | ||
501 | 499 | ||
502 | 500 | @Callable(i) | |
503 | 501 | func setMaxDepth (newMaxDepth) = { | |
504 | 502 | let checks = [mustManager(i), if ((newMaxDepth > 0)) | |
505 | 503 | then true | |
506 | 504 | else throwErr("invalid max depth")] | |
507 | 505 | if ((checks == checks)) | |
508 | 506 | then $Tuple2([IntegerEntry(keyMaxDepth, newMaxDepth)], unit) | |
509 | 507 | else throw("Strict value is not equal to itself.") | |
510 | 508 | } | |
511 | 509 | ||
512 | 510 | ||
513 | 511 | ||
514 | 512 | @Callable(i) | |
515 | 513 | func processPoolBalanceINTERNAL (poolStr) = { | |
516 | 514 | let checkCaller = mustThis(i) | |
517 | 515 | if ((checkCaller == checkCaller)) | |
518 | 516 | then { | |
519 | 517 | let epoch = getIntOrFail(this, keyCurrentEpoch) | |
520 | 518 | let epochPrevious = (epoch - 1) | |
521 | 519 | let pool = stringToPool(poolStr) | |
522 | - | let $ | |
523 | - | let amountAssetId = $ | |
524 | - | let priceAssetId = $ | |
520 | + | let $t01697917019 = pool | |
521 | + | let amountAssetId = $t01697917019._1 | |
522 | + | let priceAssetId = $t01697917019._2 | |
525 | 523 | let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId) | |
526 | 524 | let balanceIsOkCurrent = { | |
527 | 525 | let @ = invoke(factoryContract, "checkBalance", [lpAssetId], nil) | |
528 | 526 | if ($isInstanceOf(@, "Boolean")) | |
529 | 527 | then @ | |
530 | 528 | else throw(($getType(@) + " couldn't be cast to Boolean")) | |
531 | 529 | } | |
532 | 530 | let balanceIsOkPrevious = !(valueOrElse(getBoolean(this, keyInsufficientBalances(pool, (epochPrevious - 1))), false)) | |
533 | 531 | let actions = if (!(balanceIsOkCurrent)) | |
534 | 532 | then if (!(balanceIsOkPrevious)) | |
535 | 533 | then { | |
536 | 534 | let deleteWxEmissionInv = invoke(factoryContract, "deleteWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil) | |
537 | 535 | if ((deleteWxEmissionInv == deleteWxEmissionInv)) | |
538 | 536 | then { | |
539 | 537 | let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, 0], nil) | |
540 | 538 | if ((modifyWeightInv == modifyWeightInv)) | |
541 | 539 | then { | |
542 | 540 | let poolAddress = valueOrErrorMessage(getPoolInfo(amountAssetId, priceAssetId), wrapErr("invalid assets"))._1 | |
543 | 541 | let newStatus = 3 | |
544 | 542 | let setPoolStatusInv = invoke(factoryContract, "managePool", [toString(poolAddress), newStatus], nil) | |
545 | 543 | if ((setPoolStatusInv == setPoolStatusInv)) | |
546 | 544 | then { | |
547 | 545 | let listActions = ([DeleteEntry(keyInList(pool))] ++ deleteNodeActions(poolsListName, poolToString(pool))) | |
548 | 546 | ([IntegerEntry(keyPoolShare(pool, epochPrevious), 0)] ++ listActions) | |
549 | 547 | } | |
550 | 548 | else throw("Strict value is not equal to itself.") | |
551 | 549 | } | |
552 | 550 | else throw("Strict value is not equal to itself.") | |
553 | 551 | } | |
554 | 552 | else throw("Strict value is not equal to itself.") | |
555 | 553 | } | |
556 | 554 | else [BooleanEntry(keyInsufficientBalances(pool, epochPrevious), true)] | |
557 | 555 | else nil | |
558 | 556 | $Tuple2(actions, unit) | |
559 | 557 | } | |
560 | 558 | else throw("Strict value is not equal to itself.") | |
561 | 559 | } | |
562 | 560 | ||
563 | 561 | ||
564 | 562 | ||
565 | 563 | @Callable(i) | |
566 | 564 | func processVoteINTERNAL (poolStr,userAddressStr) = { | |
567 | 565 | let checkCaller = mustThis(i) | |
568 | 566 | if ((checkCaller == checkCaller)) | |
569 | 567 | then { | |
570 | 568 | let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr(("processVoteINTERNAL: invalid user address " + userAddressStr))) | |
571 | 569 | let epoch = getIntOrFail(this, keyCurrentEpoch) | |
572 | 570 | let epochPrevious = (epoch - 1) | |
573 | 571 | let epochLength = getIntOrFail(this, keyEpochLength) | |
574 | 572 | let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch)) | |
575 | 573 | let endHeight = (startHeight + epochLength) | |
576 | 574 | let startHeightPrevious = getIntOrFail(this, keyStartHeightByEpoch(epochPrevious)) | |
577 | 575 | let epochLengthPrevious = getIntOrFail(this, keyEpochLengthByEpoch(epochPrevious)) | |
578 | 576 | let endHeightPrevious = (startHeightPrevious + epochLengthPrevious) | |
579 | 577 | let checkTargetEpoch = if ((epochPrevious >= 0)) | |
580 | 578 | then true | |
581 | 579 | else throwErr("processVoteINTERNAL: invalid previous epoch") | |
582 | 580 | if ((checkTargetEpoch == checkTargetEpoch)) | |
583 | 581 | then { | |
584 | 582 | let pool = stringToPool(poolStr) | |
585 | - | let $ | |
586 | - | let amountAssetId = $ | |
587 | - | let priceAssetId = $ | |
583 | + | let $t01937219412 = pool | |
584 | + | let amountAssetId = $t01937219412._1 | |
585 | + | let priceAssetId = $t01937219412._2 | |
588 | 586 | let gwxAmountAtEndTotal = { | |
589 | 587 | let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil) | |
590 | 588 | if ($isInstanceOf(@, "Int")) | |
591 | 589 | then @ | |
592 | 590 | else throw(($getType(@) + " couldn't be cast to Int")) | |
593 | 591 | } | |
594 | 592 | let gwxAmountAtEndTotalPrevious = { | |
595 | 593 | let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeightPrevious], nil) | |
596 | 594 | if ($isInstanceOf(@, "Int")) | |
597 | 595 | then @ | |
598 | 596 | else throw(($getType(@) + " couldn't be cast to Int")) | |
599 | 597 | } | |
600 | 598 | let totalVotes = valueOrElse(getInteger(keyTotalVotes(epoch)), 0) | |
601 | 599 | let votingResult = valueOrElse(getInteger(keyVotingResult(pool, epoch)), 0) | |
602 | 600 | let votePrevious = valueOrErrorMessage(getInteger(keyVote(pool, userAddress, epochPrevious)), wrapErr((((("processVoteINTERNAL " + poolStr) + " ") + userAddressStr) + ": no previous vote"))) | |
603 | 601 | let used = valueOrElse(getInteger(this, keyUsed(userAddress, epoch)), 0) | |
604 | 602 | let lpAssetIdStr = getLpAssetByPoolAssets(amountAssetId, priceAssetId) | |
605 | 603 | let votingResultStakedPrevious = valueOrElse(getInteger(keyVotingResultStaked(lpAssetIdStr, epochPrevious)), 0) | |
606 | 604 | let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract)) | |
607 | 605 | let stakedByUser = valueOrElse(getInteger(stakingContract, keyStakedByUser(lpAssetIdStr, userAddressStr)), 0) | |
608 | 606 | let votingResultStakedActions = if ((stakedByUser == 0)) | |
609 | 607 | then nil | |
610 | 608 | else [IntegerEntry(keyVotingResultStaked(lpAssetIdStr, epochPrevious), (votingResultStakedPrevious + votePrevious))] | |
611 | 609 | let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId) | |
612 | 610 | let newVote = if ((gwxAmountAtEndTotalPrevious > 0)) | |
613 | 611 | then fraction(votePrevious, gwxAmountAtEndTotal, gwxAmountAtEndTotalPrevious) | |
614 | 612 | else 0 | |
615 | 613 | let actions = if ((newVote > 0)) | |
616 | 614 | then [IntegerEntry(keyVote(pool, userAddress, epoch), newVote), IntegerEntry(keyTotalVotes(epoch), (totalVotes + newVote)), IntegerEntry(keyVotingResult(pool, epoch), (votingResult + newVote)), IntegerEntry(keyUsed(userAddress, epoch), (used + newVote))] | |
617 | 615 | else deleteNodeActions(getVotesListName(pool), userAddressStr) | |
618 | 616 | $Tuple2((actions ++ votingResultStakedActions), unit) | |
619 | 617 | } | |
620 | 618 | else throw("Strict value is not equal to itself.") | |
621 | 619 | } | |
622 | 620 | else throw("Strict value is not equal to itself.") | |
623 | 621 | } | |
624 | 622 | ||
625 | 623 | ||
626 | 624 | ||
627 | 625 | @Callable(i) | |
628 | 626 | func processPoolINTERNAL (poolStr,force) = { | |
629 | 627 | let checkCaller = mustThis(i) | |
630 | 628 | if ((checkCaller == checkCaller)) | |
631 | 629 | then { | |
632 | 630 | let targetEpoch = { | |
633 | 631 | let currentEpoch = getIntOrFail(this, keyCurrentEpoch) | |
634 | 632 | if (force) | |
635 | 633 | then currentEpoch | |
636 | 634 | else (currentEpoch - 1) | |
637 | 635 | } | |
638 | 636 | let checkTargetEpoch = if ((targetEpoch >= 0)) | |
639 | 637 | then true | |
640 | 638 | else throwErr("processPoolINTERNAL: invalid target epoch") | |
641 | 639 | if ((checkTargetEpoch == checkTargetEpoch)) | |
642 | 640 | then { | |
643 | 641 | let pool = stringToPool(poolStr) | |
644 | - | let $ | |
645 | - | let amountAssetId = $ | |
646 | - | let priceAssetId = $ | |
642 | + | let $t02177521815 = pool | |
643 | + | let amountAssetId = $t02177521815._1 | |
644 | + | let priceAssetId = $t02177521815._2 | |
647 | 645 | let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract)) | |
648 | 646 | let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId) | |
649 | 647 | let r = { | |
650 | 648 | let @ = invoke(stakingContract, "usersListTraversal", [lpAssetId], nil) | |
651 | 649 | if ($isInstanceOf(@, "Boolean")) | |
652 | 650 | then @ | |
653 | 651 | else throw(($getType(@) + " couldn't be cast to Boolean")) | |
654 | 652 | } | |
655 | 653 | if ((r == r)) | |
656 | 654 | then if (r) | |
657 | 655 | then $Tuple2(nil, true) | |
658 | 656 | else { | |
659 | 657 | let assetsStoreContract = addressFromStringValue(valueOrErrorMessage(getString(factoryContract, keyAssetsStoreContract), "invalid assets store contract")) | |
660 | 658 | let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0) | |
661 | 659 | let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0) | |
662 | 660 | let share = if ((totalVotes == 0)) | |
663 | 661 | then 0 | |
664 | 662 | else fraction(votingResult, poolWeightMult, totalVotes) | |
665 | 663 | let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil) | |
666 | 664 | if ((modifyWeightInv == modifyWeightInv)) | |
667 | 665 | then $Tuple2([IntegerEntry(keyPoolShare(pool, targetEpoch), share)], false) | |
668 | 666 | else throw("Strict value is not equal to itself.") | |
669 | 667 | } | |
670 | 668 | else throw("Strict value is not equal to itself.") | |
671 | 669 | } | |
672 | 670 | else throw("Strict value is not equal to itself.") | |
673 | 671 | } | |
674 | 672 | else throw("Strict value is not equal to itself.") | |
675 | 673 | } | |
676 | 674 | ||
677 | 675 | ||
678 | 676 | ||
679 | 677 | @Callable(i) | |
680 | 678 | func finalizeHelper () = { | |
681 | 679 | let force = valueOrElse(getBoolean(keyFinalizationShouldBeForced), false) | |
682 | 680 | let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0) | |
683 | 681 | let previousEpoch = (epoch - 1) | |
684 | 682 | let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch)) | |
685 | 683 | let epochLength = getIntOrFail(this, keyEpochLength) | |
686 | 684 | let endHeight = (startHeight + epochLength) | |
687 | 685 | let finalizationStageOrUnit = getInteger(this, keyFinalizationStage) | |
688 | 686 | if (if (if ((height >= endHeight)) | |
689 | 687 | then (finalizationStageOrUnit == unit) | |
690 | 688 | else false) | |
691 | 689 | then !(force) | |
692 | 690 | else false) | |
693 | 691 | then { | |
694 | 692 | let newEpoch = (epoch + 1) | |
695 | 693 | let newEpochLengthOption = getInteger(this, keyEpochLengthNew) | |
696 | 694 | let newEpochLengthActions = match newEpochLengthOption { | |
697 | 695 | case newEpochLength: Int => | |
698 | 696 | [IntegerEntry(keyEpochLength, newEpochLength), DeleteEntry(keyEpochLengthNew)] | |
699 | 697 | case _: Unit => | |
700 | 698 | nil | |
701 | 699 | case _ => | |
702 | 700 | throw("Match error") | |
703 | 701 | } | |
704 | 702 | $Tuple2(([IntegerEntry(keyStartHeightByEpoch(newEpoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpoch, newEpoch), IntegerEntry(keyFinalizationStage, finalizationStageBalances), IntegerEntry(keyEpochLengthByEpoch(epoch), epochLength)] ++ newEpochLengthActions), true) | |
705 | 703 | } | |
706 | 704 | else if (if (force) | |
707 | 705 | then (finalizationStageOrUnit == unit) | |
708 | 706 | else false) | |
709 | 707 | then $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares)], true) | |
710 | 708 | else if ((finalizationStageOrUnit == unit)) | |
711 | 709 | then $Tuple2(nil, false) | |
712 | 710 | else if ((finalizationStageOrUnit == finalizationStageBalances)) | |
713 | 711 | then { | |
714 | 712 | let poolOrUnit = getString(keyNextPool) | |
715 | 713 | match poolOrUnit { | |
716 | 714 | case _: Unit => | |
717 | 715 | match getString(keyListHead(poolsListName)) { | |
718 | 716 | case _: Unit => | |
719 | 717 | $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageTotal), DeleteEntry(keyNextPool)], true) | |
720 | 718 | case nextPoolStr: String => | |
721 | 719 | $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true) | |
722 | 720 | case _ => | |
723 | 721 | throw("Match error") | |
724 | 722 | } | |
725 | 723 | case poolStr: String => | |
726 | 724 | let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr)) | |
727 | 725 | if ((nextPoolOrUnit == nextPoolOrUnit)) | |
728 | 726 | then { | |
729 | 727 | let r = invoke(this, "processPoolBalanceINTERNAL", [poolStr], nil) | |
730 | 728 | if ((r == r)) | |
731 | 729 | then match nextPoolOrUnit { | |
732 | 730 | case _: Unit => | |
733 | 731 | $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageTotal), DeleteEntry(keyNextPool)], true) | |
734 | 732 | case nextPoolStr: String => | |
735 | 733 | $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true) | |
736 | 734 | case _ => | |
737 | 735 | throw("Match error") | |
738 | 736 | } | |
739 | 737 | else throw("Strict value is not equal to itself.") | |
740 | 738 | } | |
741 | 739 | else throw("Strict value is not equal to itself.") | |
742 | 740 | case _ => | |
743 | 741 | throw("Match error") | |
744 | 742 | } | |
745 | 743 | } | |
746 | 744 | else if ((finalizationStageOrUnit == finalizationStageTotal)) | |
747 | 745 | then { | |
748 | 746 | let poolOrUnit = getString(keyNextPool) | |
749 | 747 | let userOrUnit = getString(keyNextUser) | |
750 | 748 | match poolOrUnit { | |
751 | 749 | case _: Unit => | |
752 | 750 | match getString(keyListHead(poolsListName)) { | |
753 | 751 | case _: Unit => | |
754 | 752 | $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true) | |
755 | 753 | case poolsHeadStr: String => | |
756 | 754 | $Tuple2([StringEntry(keyNextPool, poolsHeadStr)], true) | |
757 | 755 | case _ => | |
758 | 756 | throw("Match error") | |
759 | 757 | } | |
760 | 758 | case poolStr: String => | |
761 | 759 | let pool = stringToPool(poolStr) | |
762 | 760 | let nextUserOrUnit = match userOrUnit { | |
763 | 761 | case _: Unit => | |
764 | 762 | getString(keyListHead(getVotesListName(pool))) | |
765 | 763 | case user: String => | |
766 | 764 | let next = getString(keyListNext(getVotesListName(pool), user)) | |
767 | 765 | if ((next == next)) | |
768 | 766 | then { | |
769 | 767 | let processVoteInv = invoke(this, "processVoteINTERNAL", [poolStr, user], nil) | |
770 | 768 | if ((processVoteInv == processVoteInv)) | |
771 | 769 | then next | |
772 | 770 | else throw("Strict value is not equal to itself.") | |
773 | 771 | } | |
774 | 772 | else throw("Strict value is not equal to itself.") | |
775 | 773 | case _ => | |
776 | 774 | throw("Match error") | |
777 | 775 | } | |
778 | 776 | match nextUserOrUnit { | |
779 | 777 | case _: Unit => | |
780 | 778 | let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr)) | |
781 | 779 | match nextPoolOrUnit { | |
782 | 780 | case _: Unit => | |
783 | 781 | $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true) | |
784 | 782 | case s: String => | |
785 | 783 | $Tuple2([StringEntry(keyNextPool, s), DeleteEntry(keyNextUser)], true) | |
786 | 784 | case _ => | |
787 | 785 | throw("Match error") | |
788 | 786 | } | |
789 | 787 | case nextUser: String => | |
790 | 788 | $Tuple2([StringEntry(keyNextUser, nextUser)], true) | |
791 | 789 | case _ => | |
792 | 790 | throw("Match error") | |
793 | 791 | } | |
794 | 792 | case _ => | |
795 | 793 | throw("Match error") | |
796 | 794 | } | |
797 | 795 | } | |
798 | 796 | else if ((finalizationStageOrUnit == finalizationStageShares)) | |
799 | 797 | then { | |
800 | 798 | let poolOrUnit = getString(keyNextPool) | |
801 | 799 | match poolOrUnit { | |
802 | 800 | case _: Unit => | |
803 | 801 | match getString(keyListHead(poolsListName)) { | |
804 | 802 | case _: Unit => | |
805 | 803 | let actions = if (force) | |
806 | 804 | then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced)] | |
807 | 805 | else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight)] | |
808 | 806 | let gwxRewardDepositInv = gwxRewardDeposit() | |
809 | 807 | if ((gwxRewardDepositInv == gwxRewardDepositInv)) | |
810 | 808 | then $Tuple2(actions, true) | |
811 | 809 | else throw("Strict value is not equal to itself.") | |
812 | 810 | case nextPoolStr: String => | |
813 | 811 | $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true) | |
814 | 812 | case _ => | |
815 | 813 | throw("Match error") | |
816 | 814 | } | |
817 | 815 | case poolStr: String => | |
818 | 816 | let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr)) | |
819 | 817 | if ((nextPoolOrUnit == nextPoolOrUnit)) | |
820 | 818 | then { | |
821 | 819 | let r = { | |
822 | 820 | let @ = invoke(this, "processPoolINTERNAL", [poolStr, force], nil) | |
823 | 821 | if ($isInstanceOf(@, "Boolean")) | |
824 | 822 | then @ | |
825 | 823 | else throw(($getType(@) + " couldn't be cast to Boolean")) | |
826 | 824 | } | |
827 | 825 | if ((r == r)) | |
828 | 826 | then if (r) | |
829 | 827 | then $Tuple2(nil, true) | |
830 | 828 | else match nextPoolOrUnit { | |
831 | 829 | case _: Unit => | |
832 | 830 | let actions = if (force) | |
833 | 831 | then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced), DeleteEntry(keyNextPool)] | |
834 | 832 | else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight), DeleteEntry(keyNextPool)] | |
835 | 833 | let gwxRewardDepositInv = gwxRewardDeposit() | |
836 | 834 | if ((gwxRewardDepositInv == gwxRewardDepositInv)) | |
837 | 835 | then $Tuple2(actions, true) | |
838 | 836 | else throw("Strict value is not equal to itself.") | |
839 | 837 | case nextPoolStr: String => | |
840 | 838 | $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true) | |
841 | 839 | case _ => | |
842 | 840 | throw("Match error") | |
843 | 841 | } | |
844 | 842 | else throw("Strict value is not equal to itself.") | |
845 | 843 | } | |
846 | 844 | else throw("Strict value is not equal to itself.") | |
847 | 845 | case _ => | |
848 | 846 | throw("Match error") | |
849 | 847 | } | |
850 | 848 | } | |
851 | 849 | else throwErr("finalization is broken") | |
852 | 850 | } | |
853 | 851 | ||
854 | 852 | ||
855 | 853 | ||
856 | 854 | @Callable(i) | |
857 | 855 | func finalizeWrapper (counter) = { | |
858 | 856 | let votingEmissionRateContract = addressFromStringValue(getStringValue(this, keyVotingEmissionRateContract)) | |
859 | 857 | let result = { | |
860 | 858 | let @ = invoke(this, "finalizeHelper", nil, nil) | |
861 | 859 | if ($isInstanceOf(@, "Boolean")) | |
862 | 860 | then @ | |
863 | 861 | else throw(($getType(@) + " couldn't be cast to Boolean")) | |
864 | 862 | } | |
865 | 863 | if ((result == result)) | |
866 | 864 | then if (!(result)) | |
867 | 865 | then if ((counter == 0)) | |
868 | 866 | then throwErr("Current voting is not over yet") | |
869 | 867 | else { | |
870 | 868 | let inv = invoke(votingEmissionRateContract, "finalize", nil, nil) | |
871 | 869 | if ((inv == inv)) | |
872 | 870 | then $Tuple2(nil, unit) | |
873 | 871 | else throw("Strict value is not equal to itself.") | |
874 | 872 | } | |
875 | 873 | else { | |
876 | 874 | let maxDepth = valueOrElse(getInteger(this, keyMaxDepth), maxDepthDefault) | |
877 | 875 | if ((maxDepth > counter)) | |
878 | 876 | then { | |
879 | 877 | let inv = invoke(this, "finalizeWrapper", [(counter + 1)], nil) | |
880 | 878 | if ((inv == inv)) | |
881 | 879 | then $Tuple2(nil, unit) | |
882 | 880 | else throw("Strict value is not equal to itself.") | |
883 | 881 | } | |
884 | 882 | else $Tuple2(nil, unit) | |
885 | 883 | } | |
886 | 884 | else throw("Strict value is not equal to itself.") | |
887 | 885 | } | |
888 | 886 | ||
889 | 887 | ||
890 | 888 | ||
891 | 889 | @Callable(i) | |
892 | 890 | func finalize () = { | |
893 | 891 | let inv = invoke(this, "finalizeWrapper", [0], nil) | |
894 | 892 | if ((inv == inv)) | |
895 | 893 | then $Tuple2(nil, unit) | |
896 | 894 | else throw("Strict value is not equal to itself.") | |
897 | 895 | } | |
898 | 896 | ||
899 | 897 | ||
900 | 898 | ||
901 | 899 | @Callable(i) | |
902 | 900 | func containsNodeREADONLY (listName,id) = $Tuple2(nil, containsNode(listName, id)) | |
903 | 901 | ||
904 | 902 | ||
905 | 903 | ||
906 | 904 | @Callable(i) | |
907 | 905 | func insertNode (listName,id) = { | |
908 | 906 | let checkCaller = mustManager(i) | |
909 | 907 | if ((checkCaller == checkCaller)) | |
910 | 908 | then $Tuple2(insertNodeActions(listName, id), unit) | |
911 | 909 | else throw("Strict value is not equal to itself.") | |
912 | 910 | } | |
913 | 911 | ||
914 | 912 | ||
915 | 913 | ||
916 | 914 | @Callable(i) | |
917 | 915 | func deleteNode (listName,id) = { | |
918 | 916 | let checkCaller = mustManager(i) | |
919 | 917 | if ((checkCaller == checkCaller)) | |
920 | 918 | then $Tuple2(deleteNodeActions(listName, id), unit) | |
921 | 919 | else throw("Strict value is not equal to itself.") | |
922 | 920 | } | |
923 | 921 | ||
924 | 922 | ||
925 | 923 | ||
926 | 924 | @Callable(i) | |
927 | 925 | func isFinalizationInProgress () = { | |
928 | 926 | let finalizationStageOrUnit = getInteger(this, keyFinalizationStage) | |
929 | 927 | let finalizationInProgress = (finalizationStageOrUnit != unit) | |
930 | 928 | $Tuple2(nil, finalizationInProgress) | |
931 | 929 | } | |
932 | 930 | ||
933 | 931 | ||
934 | 932 | ||
935 | 933 | @Callable(i) | |
936 | 934 | func deletePool (amountAssetId,priceAssetId) = { | |
937 | 935 | let checkCaller = if (if ((i.caller == factoryContract)) | |
938 | 936 | then true | |
939 | 937 | else mustManager(i)) | |
940 | 938 | then true | |
941 | 939 | else throwErr("Permission denied") | |
942 | 940 | if ((checkCaller == checkCaller)) | |
943 | 941 | then { | |
944 | 942 | let listName = "pools" | |
945 | 943 | let pool = $Tuple2(amountAssetId, priceAssetId) | |
946 | 944 | let id = makeString([amountAssetId, priceAssetId], separator) | |
947 | 945 | let actions = if (containsNode(listName, id)) | |
948 | 946 | then deleteNodeActions(listName, id) | |
949 | 947 | else nil | |
950 | 948 | ([DeleteEntry(keyInList(pool))] ++ actions) | |
951 | 949 | } | |
952 | 950 | else throw("Strict value is not equal to itself.") | |
953 | 951 | } | |
954 | 952 | ||
955 | 953 | ||
956 | 954 | ||
957 | 955 | @Callable(i) | |
958 | 956 | func resume (amountAssetId,priceAssetId) = { | |
959 | 957 | let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId) | |
960 | 958 | let balanceIsOk = { | |
961 | 959 | let @ = invoke(factoryContract, "checkBalance", [lpAssetId], nil) | |
962 | 960 | if ($isInstanceOf(@, "Boolean")) | |
963 | 961 | then @ | |
964 | 962 | else throw(($getType(@) + " couldn't be cast to Boolean")) | |
965 | 963 | } | |
966 | 964 | let payment = i.payments[0] | |
967 | 965 | let assetsStoreContract = addressFromStringValue(getStringValue(this, keyAssetsStoreContract)) | |
968 | 966 | let kBoostingConfig = "%s__config" | |
969 | 967 | let idxCfgAssetId = 1 | |
970 | 968 | let boostingContract = addressFromStringValue(getStrOrFail(this, keyBoostingContract)) | |
971 | 969 | let wxAssetId = fromBase58String(split(getStringValue(boostingContract, kBoostingConfig), separator)[idxCfgAssetId]) | |
972 | 970 | let amountAssetVerified = { | |
973 | 971 | let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [amountAssetId], nil) | |
974 | 972 | if ($isInstanceOf(@, "Boolean")) | |
975 | 973 | then @ | |
976 | 974 | else throw(($getType(@) + " couldn't be cast to Boolean")) | |
977 | 975 | } | |
978 | 976 | let priceAssetVerified = { | |
979 | 977 | let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [priceAssetId], nil) | |
980 | 978 | if ($isInstanceOf(@, "Boolean")) | |
981 | 979 | then @ | |
982 | 980 | else throw(($getType(@) + " couldn't be cast to Boolean")) | |
983 | 981 | } | |
984 | - | let resumptionFee = | |
982 | + | let resumptionFee = valueOrErrorMessage(getInteger(this, keyResumptionFee), "invalid resumption fee") | |
985 | 983 | let checks = [if (balanceIsOk) | |
986 | 984 | then true | |
987 | 985 | else throwErr("insufficient balances"), if ((size(i.payments) == 1)) | |
988 | 986 | then true | |
989 | 987 | else throwErr("1 payment is required"), if ((payment.assetId == wxAssetId)) | |
990 | 988 | then true | |
991 | 989 | else throwErr("invalid payment asset id"), if ((payment.amount == resumptionFee)) | |
992 | 990 | then true | |
993 | 991 | else throwErr("invalid payment amount"), if (if (amountAssetVerified) | |
994 | 992 | then priceAssetVerified | |
995 | 993 | else false) | |
996 | 994 | then true | |
997 | 995 | else throwErr("both assets should be verified")] | |
998 | 996 | if ((checks == checks)) | |
999 | 997 | then { | |
1000 | 998 | let setWxEmissionInv = invoke(factoryContract, "setWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil) | |
1001 | 999 | if ((setWxEmissionInv == setWxEmissionInv)) | |
1002 | 1000 | then { | |
1003 | 1001 | let pool = $Tuple2(amountAssetId, priceAssetId) | |
1004 | 1002 | let inListActions = ([BooleanEntry(keyInList(pool), true)] ++ insertNodeActions(poolsListName, poolToString(pool))) | |
1005 | 1003 | $Tuple2(inListActions, unit) | |
1006 | 1004 | } | |
1007 | 1005 | else throw("Strict value is not equal to itself.") | |
1008 | 1006 | } | |
1009 | 1007 | else throw("Strict value is not equal to itself.") | |
1010 | 1008 | } | |
1011 | 1009 | ||
1012 | 1010 | ||
1013 | 1011 | @Verifier(tx) | |
1014 | 1012 | func verify () = { | |
1015 | 1013 | let targetPublicKey = match managerPublicKeyOrUnit() { | |
1016 | 1014 | case pk: ByteVector => | |
1017 | 1015 | pk | |
1018 | 1016 | case _: Unit => | |
1019 | 1017 | tx.senderPublicKey | |
1020 | 1018 | case _ => | |
1021 | 1019 | throw("Match error") | |
1022 | 1020 | } | |
1023 | 1021 | sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey) | |
1024 | 1022 | } | |
1025 | 1023 |
github/deemru/w8io/fabc49c 106.98 ms ◑