2024.04.17 09:39 [3066422] smart account 3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr > SELF 0.00000000 Waves

{ "type": 13, "id": "GGrxUtyWStFqoWpfsizaH2df2wUuz1wdjQGdkBjksJVx", "fee": 2700000, "feeAssetId": null, "timestamp": 1713335985603, "version": 2, "chainId": 84, "sender": "3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr", "senderPublicKey": "GFbasS3jufhZkK4xR7tdTjjnP8K33KvJFEDHRtxXDkaJ", "proofs": [ "3g4rQKcH5hmFVTW3F7q6PXUFaBiBiCgKMaSQMA1JR9qW6ZJjHKdAJYNxThsrxgQrKVmBB4GcDjpGnoxtRJivPW6o" ], "script": "base64:BgKtGggCEgQKAggBEgcKBQgICAgBEgQKAggIEgUKAwgIARIECgIICBIDCgEBEgMKAQESAwoBCBIECgIICBIECgIIBBIAEgMKAQESABIECgIICBIECgIICBIECgIICBIAEgQKAggIEgQKAggIIglzZXBhcmF0b3IiDnBvb2xXZWlnaHRNdWx0Ig9tYXhEZXB0aERlZmF1bHQiGWZpbmFsaXphdGlvblN0YWdlQmFsYW5jZXMiFmZpbmFsaXphdGlvblN0YWdlVG90YWwiF2ZpbmFsaXphdGlvblN0YWdlU2hhcmVzIhRyZXN1bXB0aW9uRmVlRGVmYXVsdCIOa2V5RXBvY2hMZW5ndGgiEWtleUVwb2NoTGVuZ3RoTmV3IhVrZXlFcG9jaExlbmd0aEJ5RXBvY2giBWVwb2NoIg9rZXlDdXJyZW50RXBvY2giC2tleU1heERlcHRoIhBrZXlSZXN1bXB0aW9uRmVlIiJrZXlWb3RpbmdFbWlzc2lvbkNhbmRpZGF0ZUNvbnRyYWN0Ih1rZXlWb3RpbmdFbWlzc2lvblJhdGVDb250cmFjdCISa2V5RmFjdG9yeUNvbnRyYWN0IhNrZXlCb29zdGluZ0NvbnRyYWN0IhJrZXlTdGFraW5nQ29udHJhY3QiFmtleUFzc2V0c1N0b3JlQ29udHJhY3QiFGtleUZpbmFsaXphdGlvblN0YWdlIgtrZXlOZXh0UG9vbCILa2V5TmV4dFVzZXIiDmtleVN0YXJ0SGVpZ2h0IhFrZXlDdXJyZW50RXBvY2hVaSIQa2V5U3RhcnRIZWlnaHRVaSIda2V5RmluYWxpemF0aW9uU2hvdWxkQmVGb3JjZWQiFWtleVN0YXJ0SGVpZ2h0QnlFcG9jaCIMa2V5RmluYWxpemVkIglrZXlJbkxpc3QiBHBvb2wiCyR0MDIwMTMyMDUzIg1hbW91bnRBc3NldElkIgxwcmljZUFzc2V0SWQiF2tleUluc3VmZmljaWVudEJhbGFuY2VzIgskdDAyMjAyMjI0MiIHa2V5VXNlZCIHYWRkcmVzcyIHa2V5Vm90ZSILJHQwMjU1MDI1OTAiD2tleVZvdGluZ1Jlc3VsdCILJHQwMjc3MjI4MTIiFWtleVZvdGluZ1Jlc3VsdFN0YWtlZCIMbHBBc3NldElkU3RyIgxrZXlQb29sU2hhcmUiCyR0MDMxMzMzMTczIg1rZXlUb3RhbFZvdGVzIg9rZXlTdGFrZWRCeVVzZXIiDnVzZXJBZGRyZXNzU3RyIgd3cmFwRXJyIgNtc2ciCHRocm93RXJyIg5nZXRWYWx1ZU9yRmFpbCIDa2V5IgR0eXBlIgVlcnJvciIHJG1hdGNoMCIDc3RyIgNpbnQiDGdldFN0ck9yRmFpbCIBQCIMZ2V0SW50T3JGYWlsIgxwb29sVG9TdHJpbmciDHN0cmluZ1RvUG9vbCIFcGFydHMiD2ZhY3RvcnlDb250cmFjdCIaSWR4RmFjdG9yeUNmZ0d3eFJld2FyZERhcHAiDWtleUZhY3RvcnlDZmciFHJlYWRGYWN0b3J5Q2ZnT3JGYWlsIgdmYWN0b3J5IhlnZXRHd3hSZXdhcmRBZGRyZXNzT3JGYWlsIgpmYWN0b3J5Q2ZnIgtnZXRQb29sSW5mbyIOcG9vbEluZm9PcHRpb24iFmdldExwQXNzZXRCeVBvb2xBc3NldHMiH2tleU1hcHBpbmdzQmFzZUFzc2V0MmludGVybmFsSWQiDGJhc2VBc3NldFN0ciIpa2V5TWFwcGluZ1Bvb2xBc3NldHNUb1Bvb2xDb250cmFjdEFkZHJlc3MiGGludGVybmFsQW1vdW50QXNzZXRJZFN0ciIXaW50ZXJuYWxQcmljZUFzc2V0SWRTdHIiH2tleU1hcHBpbmdQb29sQ29udHJhY3RUb0xQQXNzZXQiE3Bvb2xDb250cmFjdEFkZHJlc3MiFWFtb3VudEFzc2V0SW50ZXJuYWxJZCIUcHJpY2VBc3NldEludGVybmFsSWQiCWxwQXNzZXRJZCIYY2hlY2tXeEVtaXNzaW9uUG9vbExhYmVsIgskdDA2Mjk5NjMzOSIQZ3d4UmV3YXJkRGVwb3NpdCISZ3d4UmV3YXJkc0NvbnRyYWN0Ig1wb29sc0xpc3ROYW1lIhBnZXRWb3Rlc0xpc3ROYW1lIgskdDA2NzU2Njc5NiILa2V5TGlzdEhlYWQiCGxpc3ROYW1lIgRtZXRhIgtrZXlMaXN0U2l6ZSILa2V5TGlzdFByZXYiAmlkIgtrZXlMaXN0TmV4dCIMY29udGFpbnNOb2RlIgpoZWFkT3JVbml0IgpwcmV2T3JVbml0IgpuZXh0T3JVbml0IhFpbnNlcnROb2RlQWN0aW9ucyIIbGlzdFNpemUiCWNoZWNrTm9kZSIRZGVsZXRlTm9kZUFjdGlvbnMiFmtleU1hbmFnZXJWYXVsdEFkZHJlc3MiE2tleU1hbmFnZXJQdWJsaWNLZXkiHGdldE1hbmFnZXJWYXVsdEFkZHJlc3NPclRoaXMiAXMiFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQiE21hbmFnZXJWYXVsdEFkZHJlc3MiCWlzTWFuYWdlciIBaSICcGsiC211c3RNYW5hZ2VyIghtdXN0VGhpcyILdXNlckFkZHJlc3MiDHRhcmdldEhlaWdodCIXYm9vc3RpbmdDb250cmFjdEFkZHJlc3MiH3ZvdGluZ0VtaXNzaW9uQ2FuZGlkYXRlQ29udHJhY3QiEGJvb3N0aW5nQ29udHJhY3QiD3N0YWtpbmdDb250cmFjdCILZXBvY2hMZW5ndGgiBmNoZWNrcyINaW5MaXN0QWN0aW9ucyIYY3VycmVudEVwb2NoSXNOb3REZWZpbmVkIhJzdGFydEhlaWdodEFjdGlvbnMiBmFtb3VudCILc3RhcnRIZWlnaHQiCWVuZEhlaWdodCIXZmluYWxpemF0aW9uU3RhZ2VPclVuaXQiBHVzZWQiBHZvdGUiCnBvb2xSZXN1bHQiCnRvdGFsVm90ZXMiE2d3eEFtb3VudEF0RW5kVG90YWwiCWF2YWlsYWJsZSIHbmV3Vm90ZSIKd3hFbWlzc2lvbiINdm90ZXNMaXN0TmFtZSIQdm90ZXNMaXN0QWN0aW9ucyIObmV3RXBvY2hMZW5ndGgiC25ld01heERlcHRoIgdwb29sU3RyIgtjaGVja0NhbGxlciINZXBvY2hQcmV2aW91cyINJHQwMTcwMjAxNzA2MCISYmFsYW5jZUlzT2tDdXJyZW50IhNiYWxhbmNlSXNPa1ByZXZpb3VzIgdhY3Rpb25zIhNkZWxldGVXeEVtaXNzaW9uSW52Ig9tb2RpZnlXZWlnaHRJbnYiC3Bvb2xBZGRyZXNzIgluZXdTdGF0dXMiEHNldFBvb2xTdGF0dXNJbnYiC2xpc3RBY3Rpb25zIhNzdGFydEhlaWdodFByZXZpb3VzIhNlcG9jaExlbmd0aFByZXZpb3VzIhFlbmRIZWlnaHRQcmV2aW91cyIQY2hlY2tUYXJnZXRFcG9jaCINJHQwMTk0MTMxOTQ1MyIbZ3d4QW1vdW50QXRFbmRUb3RhbFByZXZpb3VzIgx2b3RpbmdSZXN1bHQiDHZvdGVQcmV2aW91cyIadm90aW5nUmVzdWx0U3Rha2VkUHJldmlvdXMiDHN0YWtlZEJ5VXNlciIZdm90aW5nUmVzdWx0U3Rha2VkQWN0aW9ucyIFZm9yY2UiC3RhcmdldEVwb2NoIgxjdXJyZW50RXBvY2giDSR0MDIxODE2MjE4NTYiAXIiE2Fzc2V0c1N0b3JlQ29udHJhY3QiBXNoYXJlIg1wcmV2aW91c0Vwb2NoIghuZXdFcG9jaCIUbmV3RXBvY2hMZW5ndGhPcHRpb24iFW5ld0Vwb2NoTGVuZ3RoQWN0aW9ucyIKcG9vbE9yVW5pdCIHJG1hdGNoMSILbmV4dFBvb2xTdHIiDm5leHRQb29sT3JVbml0Igp1c2VyT3JVbml0Igxwb29sc0hlYWRTdHIiDm5leHRVc2VyT3JVbml0IgR1c2VyIgRuZXh0Ig5wcm9jZXNzVm90ZUludiIHJG1hdGNoMiIIbmV4dFVzZXIiE2d3eFJld2FyZERlcG9zaXRJbnYiB2NvdW50ZXIiGnZvdGluZ0VtaXNzaW9uUmF0ZUNvbnRyYWN0IgZyZXN1bHQiA2ludiIIbWF4RGVwdGgiFmZpbmFsaXphdGlvbkluUHJvZ3Jlc3MiC2JhbGFuY2VJc09rIgdwYXltZW50Ig9rQm9vc3RpbmdDb25maWciDWlkeENmZ0Fzc2V0SWQiCXd4QXNzZXRJZCITYW1vdW50QXNzZXRWZXJpZmllZCIScHJpY2VBc3NldFZlcmlmaWVkIg1yZXN1bXB0aW9uRmVlIgJ0eCIGdmVyaWZ5Ig90YXJnZXRQdWJsaWNLZXlFAAFhAgJfXwABYgCAwtcvAAFjAAoAAWQAAAABZQABAAFmAAIAAWcAgJDK0sYOAAFoCQC5CQIJAMwIAgICJXMJAMwIAgILZXBvY2hMZW5ndGgFA25pbAUBYQABaQkAuQkCCQDMCAICBCVzJXMJAMwIAgIQZXBvY2hMZW5ndGhfX25ldwUDbmlsBQFhAQFqAQFrCQC5CQIJAMwIAgIEJXMlZAkAzAgCAgtlcG9jaExlbmd0aAkAzAgCCQCkAwEFAWsFA25pbAUBYQABbAkAuQkCCQDMCAICAiVzCQDMCAICDGN1cnJlbnRFcG9jaAUDbmlsBQFhAAFtCQC5CQIJAMwIAgICJXMJAMwIAgIIbWF4RGVwdGgFA25pbAUBYQABbgkAuQkCCQDMCAICAiVzCQDMCAICDXJlc3VtcHRpb25GZWUFA25pbAUBYQABbwkAuQkCCQDMCAICAiVzCQDMCAICH3ZvdGluZ0VtaXNzaW9uQ2FuZGlkYXRlQ29udHJhY3QFA25pbAUBYQABcAkAuQkCCQDMCAICAiVzCQDMCAICGnZvdGluZ0VtaXNzaW9uUmF0ZUNvbnRyYWN0BQNuaWwFAWEAAXEJALkJAgkAzAgCAgIlcwkAzAgCAg9mYWN0b3J5Q29udHJhY3QFA25pbAUBYQABcgkAuQkCCQDMCAICAiVzCQDMCAICEGJvb3N0aW5nQ29udHJhY3QFA25pbAUBYQABcwkAuQkCCQDMCAICAiVzCQDMCAICD3N0YWtpbmdDb250cmFjdAUDbmlsBQFhAAF0CQC5CQIJAMwIAgICJXMJAMwIAgITYXNzZXRzU3RvcmVDb250cmFjdAUDbmlsBQFhAAF1CQC5CQIJAMwIAgICJXMJAMwIAgIRZmluYWxpemF0aW9uU3RhZ2UFA25pbAUBYQABdgkAuQkCCQDMCAICAiVzCQDMCAICCG5leHRQb29sBQNuaWwFAWEAAXcJALkJAgkAzAgCAgIlcwkAzAgCAghuZXh0VXNlcgUDbmlsBQFhAAF4CQC5CQIJAMwIAgICJXMJAMwIAgILc3RhcnRIZWlnaHQFA25pbAUBYQABeQkAuQkCCQDMCAICAiVzCQDMCAICDmN1cnJlbnRFcG9jaFVpBQNuaWwFAWEAAXoJALkJAgkAzAgCAgIlcwkAzAgCAg1zdGFydEhlaWdodFVpBQNuaWwFAWEAAUEJALkJAgkAzAgCAgIlcwkAzAgCAgVmb3JjZQUDbmlsBQFhAQFCAQFrCQC5CQIJAMwIAgIEJXMlZAkAzAgCAgtzdGFydEhlaWdodAkAzAgCCQCkAwEFAWsFA25pbAUBYQEBQwEBawkAuQkCCQDMCAICBCVzJWQJAMwIAgIJZmluYWxpemVkCQDMCAIJAKQDAQUBawUDbmlsBQFhAQFEAQFFBAFGBQFFBAFHCAUBRgJfMQQBSAgFAUYCXzIJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIGaW5MaXN0CQDMCAIFAUcJAMwIAgUBSAUDbmlsBQFhAQFJAgFFAWsEAUoFAUUEAUcIBQFKAl8xBAFICAUBSgJfMgkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICFGluc3VmZmljaWVudEJhbGFuY2VzCQDMCAIFAUcJAMwIAgUBSAkAzAgCCQCkAwEFAWsFA25pbAUBYQEBSwIBTAFrCQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICBHVzZWQJAMwIAgkApQgBBQFMCQDMCAIJAKQDAQUBawUDbmlsBQFhAQFNAwFFAUwBawQBTgUBRQQBRwgFAU4CXzEEAUgIBQFOAl8yCQC5CQIJAMwIAgIKJXMlcyVzJXMlZAkAzAgCAgR2b3RlCQDMCAIFAUcJAMwIAgUBSAkAzAgCCQClCAEFAUwJAMwIAgkApAMBBQFrBQNuaWwFAWEBAU8CAUUBawQBUAUBRQQBRwgFAVACXzEEAUgIBQFQAl8yCQC5CQIJAMwIAgIIJXMlcyVzJWQJAMwIAgIMdm90aW5nUmVzdWx0CQDMCAIFAUcJAMwIAgUBSAkAzAgCCQCkAwEFAWsFA25pbAUBYQEBUQIBUgFrCQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICEnZvdGluZ1Jlc3VsdFN0YWtlZAkAzAgCBQFSCQDMCAIJAKQDAQUBawUDbmlsBQFhAQFTAgFFAWsEAVQFAUUEAUcIBQFUAl8xBAFICAUBVAJfMgkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICCXBvb2xTaGFyZQkAzAgCBQFHCQDMCAIFAUgJAMwIAgkApAMBBQFrBQNuaWwFAWEBAVUBAWsJALkJAgkAzAgCAgQlcyVkCQDMCAICCnRvdGFsVm90ZXMJAMwIAgkApAMBBQFrBQNuaWwFAWEBAVYCAVIBVwkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgZzdGFrZWQJAMwIAgUBVwkAzAgCBQFSBQNuaWwFAWEBAVgBAVkJALkJAgkAzAgCAhV2b3RpbmdfZW1pc3Npb24ucmlkZToJAMwIAgUBWQUDbmlsAgEgAQFaAQFZCQACAQkBAVgBBQFZAQJhYQMBTAJhYgJhYwQCYWQJAQFYAQkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQFMCQDMCAICAS4JAMwIAgUCYWIJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBAJhZQUCYWMDCQABAgUCYWUCBlN0cmluZwQCYWYFAmFlCQCdCAIFAUwFAmFiAwkAAQIFAmFlAgNJbnQEAmFnBQJhZQkAmggCBQFMBQJhYgkBAVoBAhJpbnZhbGlkIGVudHJ5IHR5cGUFAmFkAQJhaAIBTAJhYgoAAmFpCQECYWEDBQFMBQJhYgIAAwkAAQIFAmFpAgZTdHJpbmcFAmFpCQACAQkArAICCQADAQUCYWkCGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwECYWoCAUwCYWIKAAJhaQkBAmFhAwUBTAUCYWIAAAMJAAECBQJhaQIDSW50BQJhaQkAAgEJAKwCAgkAAwEFAmFpAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQBAmFrAQFFCQCsAgIJAKwCAggFAUUCXzEFAWEIBQFFAl8yAQJhbAECYWYEAmFtCQC1CQIFAmFmBQFhAwkAAAIJAJADAQUCYW0AAgkAlAoCCQCRAwIFAmFtAAAJAJEDAgUCYW0AAQkBAVoBAhNpbnZhbGlkIHBvb2wgc3RyaW5nAAJhbgkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFoAgUEdGhpcwUBcQACYW8ACgECYXAAAhElc19fZmFjdG9yeUNvbmZpZwECYXEBAmFyCQC1CQIJAQJhaAIFAmFyCQECYXAABQFhAQJhcwECYXQJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYXQFAmFvAQJhdQIBRwFIBAJhdgoAAmFpCQD8BwQFAmFuAhBwb29sSW5mb1JFQURPTkxZCQDMCAIFAUcJAMwIAgUBSAUDbmlsBQNuaWwDCQABAgUCYWkCFShBZGRyZXNzLCBCeXRlVmVjdG9yKQUCYWkFBHVuaXQFAmF2AQJhdwIBRwFICgECYXgBAmF5CQCsAgICKCVzJXMlc19fbWFwcGluZ3NfX2Jhc2VBc3NldDJpbnRlcm5hbElkX18FAmF5CgECYXoCAmFBAmFCCQCsAgIJAKwCAgkArAICCQCsAgICCiVkJWQlcyVzX18JAKQDAQUCYUECAl9fCQCkAwEFAmFCAiNfX21hcHBpbmdzX19wb29sQXNzZXRzMlBvb2xDb250cmFjdAoBAmFDAQJhRAkArAICCQCsAgICCCVzJXMlc19fBQJhRAIgX19tYXBwaW5nc19fcG9vbENvbnRyYWN0MkxwQXNzZXQEAmFFCQECYWoCBQJhbgkBAmF4AQUBRwQCYUYJAQJhagIFAmFuCQECYXgBBQFIBAJhRAkBAmFoAgUCYW4JAQJhegIFAmFFBQJhRgQCYUcJAQJhaAIFAmFuCQECYUMBBQJhRAUCYUcBAmFIAQFFBAJhSQUBRQQBRwgFAmFJAl8xBAFICAUCYUkCXzIKAAJhaQkA/AcEBQJhbgIYY2hlY2tXeEVtaXNzaW9uUG9vbExhYmVsCQDMCAIFAUcJAMwIAgUBSAUDbmlsBQNuaWwDCQABAgUCYWkCB0Jvb2xlYW4FAmFpCQACAQkArAICCQADAQUCYWkCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4BAmFKAAQCYXQJAQJhcQEFAmFuBAJhSwkBAmFzAQUCYXQJAPwHBAUCYUsCB2RlcG9zaXQFA25pbAUDbmlsAAJhTAIFcG9vbHMBAmFNAQFFBAJhTgUBRQQBRwgFAmFOAl8xBAFICAUCYU4CXzIJALkJAgkAzAgCAgV2b3RlcwkAzAgCBQFHCQDMCAIFAUgFA25pbAUBYQECYU8BAmFQBAJhUQMJAAACBQJhUAUCYUwCBCVzJXMCCCVzJXMlcyVzCQC5CQIJAMwIAgUCYVEJAMwIAgUCYVAJAMwIAgIEaGVhZAUDbmlsBQFhAQJhUgECYVAEAmFRAwkAAAIFAmFQBQJhTAIEJXMlcwIIJXMlcyVzJXMJALkJAgkAzAgCBQJhUQkAzAgCBQJhUAkAzAgCAgRzaXplBQNuaWwFAWEBAmFTAgJhUAJhVAQCYVEDCQAAAgUCYVAFAmFMAgglcyVzJXMlcwIKJXMlcyVzJXMlcwkAuQkCCQDMCAIFAmFRCQDMCAIFAmFQCQDMCAIFAmFUCQDMCAICBHByZXYFA25pbAUBYQECYVUCAmFQAmFUBAJhUQMJAAACBQJhUAUCYUwCCCVzJXMlcyVzAgolcyVzJXMlcyVzCQC5CQIJAMwIAgUCYVEJAMwIAgUCYVAJAMwIAgUCYVQJAMwIAgIEbmV4dAUDbmlsBQFhAQJhVgICYVACYVQEAmFXCQCdCAIFBHRoaXMJAQJhTwEFAmFQBAJhWAkAnQgCBQR0aGlzCQECYVMCBQJhUAUCYVQEAmFZCQCdCAIFBHRoaXMJAQJhVQIFAmFQBQJhVAMDCQAAAgUCYVQJAQt2YWx1ZU9yRWxzZQIFAmFXAgAGCQECIT0CBQJhWAUEdW5pdAYJAQIhPQIFAmFZBQR1bml0AQJhWgICYVACYVQEAmFXCQCdCAIFBHRoaXMJAQJhTwEFAmFQBAJiYQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYVIBBQJhUAAABAJiYgMJAQEhAQkBAmFWAgUCYVAFAmFUBgkBAVoBAgtOb2RlIGV4aXN0cwMJAAACBQJiYgUCYmIJAM4IAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYVIBBQJhUAkAZAIFAmJhAAEFA25pbAMJAQIhPQIFAmFXBQR1bml0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhVQIFAmFQBQJhVAkBBXZhbHVlAQUCYVcJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFTAgUCYVAJAQV2YWx1ZQEFAmFXBQJhVAUDbmlsBQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFPAQUCYVAFAmFUBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmJjAgJhUAJhVAQCYVcJAJ0IAgUEdGhpcwkBAmFPAQUCYVAEAmJhCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQJhUgEFAmFQAAAEAmFYCQCdCAIFBHRoaXMJAQJhUwIFAmFQBQJhVAQCYVkJAJ0IAgUEdGhpcwkBAmFVAgUCYVAFAmFUCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhUgEFAmFQCQBlAgUCYmEAAQUDbmlsAwMJAQIhPQIFAmFYBQR1bml0CQECIT0CBQJhWQUEdW5pdAcJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFVAgUCYVAJAQV2YWx1ZQEFAmFYCQEFdmFsdWUBBQJhWQkAzAgCCQELU3RyaW5nRW50cnkCCQECYVMCBQJhUAkBBXZhbHVlAQUCYVkJAQV2YWx1ZQEFAmFYCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhUwIFAmFQBQJhVAkAzAgCCQELRGVsZXRlRW50cnkBCQECYVUCBQJhUAUCYVQFA25pbAMJAQIhPQIFAmFZBQR1bml0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhTwEFAmFQCQEFdmFsdWUBBQJhWQkAzAgCCQELRGVsZXRlRW50cnkBCQECYVUCBQJhUAUCYVQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFTAgUCYVAJAQV2YWx1ZQEFAmFZBQNuaWwDCQECIT0CBQJhWAUEdW5pdAkAzAgCCQELRGVsZXRlRW50cnkBCQECYVMCBQJhUAUCYVQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFVAgUCYVAJAQV2YWx1ZQEFAmFYBQNuaWwDCQAAAgUCYVQJAQt2YWx1ZU9yRWxzZQIFAmFXAgAJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFPAQUCYVAFA25pbAkBAVoBCQCsAgIJAKwCAgkArAICAg5pbnZhbGlkIG5vZGU6IAUCYVACAS4FAmFUAQJiZAACFyVzX19tYW5hZ2VyVmF1bHRBZGRyZXNzAQJiZQACFCVzX19tYW5hZ2VyUHVibGljS2V5AQJiZgAEAmFlCQCiCAEJAQJiZAADCQABAgUCYWUCBlN0cmluZwQCYmcFAmFlCQERQGV4dHJOYXRpdmUoMTA2MikBBQJiZwUEdGhpcwECYmgABAJiaQkBAmJmAAQCYWUJAJ0IAgUCYmkJAQJiZQADCQABAgUCYWUCBlN0cmluZwQCYmcFAmFlCQDZBAEFAmJnAwkAAQIFAmFlAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmJqAQJiawQCYWUJAQJiaAADCQABAgUCYWUCCkJ5dGVWZWN0b3IEAmJsBQJhZQkAAAIIBQJiaw9jYWxsZXJQdWJsaWNLZXkFAmJsAwkAAQIFAmFlAgRVbml0CQAAAggFAmJrBmNhbGxlcgUEdGhpcwkAAgECC01hdGNoIGVycm9yAQJibQECYmsDCQECYmoBBQJiawYJAAIBAhFwZXJtaXNzaW9uIGRlbmllZAECYm4BAmJrAwkAAAIIBQJiawZjYWxsZXIFBHRoaXMGCQACAQIRcGVybWlzc2lvbiBkZW5pZWQTAmJrARhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQCAmJvAmJwBAJicQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAQJhaAIFBHRoaXMFAXIJAQFYAQIhaW52YWxpZCBib29zdGluZyBjb250cmFjdCBhZGRyZXNzCQCUCgIFA25pbAoAAmFpCQD8BwQFAmJxAiBnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHRSRUFET05MWQkAzAgCBQJibwkAzAgCBQJicAUDbmlsBQNuaWwDCQABAgUCYWkCA0ludAUCYWkJAAIBCQCsAgIJAAMBBQJhaQIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AmJrAQtjb25zdHJ1Y3RvcgUCYW4CYnICYnMCYnQCYnUEAmJ2CQDMCAIJAQJibQEFAmJrCQDMCAIDCQECIT0CCQCmCAEFAmFuBQR1bml0BgIgaW52YWxpZCBmYWN0b3J5IGNvbnRyYWN0IGFkZHJlc3MJAMwIAgMJAQIhPQIJAKYIAQUCYnIFBHVuaXQGAjJpbnZhbGlkIHZvdGluZyBlbWlzc2lvbiBjYW5kaWRhdGUgY29udHJhY3QgYWRkcmVzcwkAzAgCAwkBAiE9AgkApggBBQJicwUEdW5pdAYCIWludmFsaWQgYm9vc3RpbmcgY29udHJhY3QgYWRkcmVzcwkAzAgCAwkBAiE9AgkApggBBQJidAUEdW5pdAYCIGludmFsaWQgc3Rha2luZyBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQBmAgUCYnUAAAYJAQFaAQIUaW52YWxpZCBlcG9jaCBsZW5ndGgFA25pbAMJAAACBQJidgUCYnYJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQFxBQJhbgkAzAgCCQELU3RyaW5nRW50cnkCBQFvBQJicgkAzAgCCQELU3RyaW5nRW50cnkCBQFyBQJicwkAzAgCCQELU3RyaW5nRW50cnkCBQFzBQJidAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBaAUCYnUFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiawEGY3JlYXRlAgFHAUgEAmJ2CQDMCAIDCQAAAgkA2AQBCAgFAmJrBmNhbGxlcgVieXRlcwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQFvAgAGCQECYm0BBQJiawUDbmlsAwkAAAIFAmJ2BQJidgQBRQkAlAoCBQFHBQFIBAJidwkAzggCCQDMCAIJAQxCb29sZWFuRW50cnkCCQEBRAEFAUUGBQNuaWwJAQJhWgIFAmFMCQECYWsBBQFFBAJieAkAAAIJAJoIAgUEdGhpcwUBbAUEdW5pdAQCYnkDBQJieAQBawAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFsBQFrCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBQgEFAWsFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBeAUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF5BQFrCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF6BQZoZWlnaHQFA25pbAUDbmlsCQCUCgIJAM4IAgUCYncFAmJ5BQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJrAQR2b3RlAwFHAUgCYnoEAUUJAJQKAgUBRwUBSAQBawkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFsAAAEAmJBCQECYWoCBQR0aGlzCQEBQgEFAWsEAmJ1CQECYWoCBQR0aGlzBQFoBAJiQgkAZAIFAmJBBQJidQQCYkMJAJoIAgUEdGhpcwUBdQQCYkQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUsCCAUCYmsGY2FsbGVyBQFrAAAEAmJFCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFNAwUBRQgFAmJrBmNhbGxlcgUBawAABAJiRgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBTwIFAUUFAWsAAAQCYkcJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAVUBBQFrAAAEAmJICgACYWkJAPwHBAUEdGhpcwIYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0CQDMCAIJANgEAQgIBQJiawZjYWxsZXIFYnl0ZXMJAMwIAgUCYkIFA25pbAUDbmlsAwkAAQIFAmFpAgNJbnQFAmFpCQACAQkArAICCQADAQUCYWkCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAQCYkkJAGUCBQJiSAUCYkQEAmJKCQBkAgUCYkUFAmJ6BAJiSwkBAmFIAQUBRQQCYnYJAMwIAgMJAQIhPQIJAKAIAQkBAUQBBQFFBQR1bml0BgkBAVoBAg5pbnZhbGlkIGFzc2V0cwkAzAgCAwkAZgIFAmJCBQZoZWlnaHQGCQEBWgECDmludmFsaWQgaGVpZ2h0CQDMCAIDCQAAAgUCYkMFBHVuaXQGCQEBWgECGGZpbmFsaXphdGlvbiBpbiBwcm9ncmVzcwkAzAgCAwkAZgIFAmJIAAAGCQEBWgECE3lvdSBkbyBub3QgaGF2ZSBnV1gJAMwIAgMDCQBmAgUCYnoAAAkAZwIFAmJJBQJiegcGCQEBWgECDmludmFsaWQgYW1vdW50CQDMCAIDBQJiSwYJAQFaAQIdcG9vbCBoYXNuJ3QgV1hfRU1JU1NJT04gbGFiZWwFA25pbAMJAAACBQJidgUCYnYEAmJMCQECYU0BBQFFBAFXCQClCAEIBQJiawZjYWxsZXIEAmJNAwkBAmFWAgUCYkwFAVcFA25pbAkBAmFaAgUCYkwFAVcJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBSwIIBQJiawZjYWxsZXIFAWsJAGQCBQJiRAUCYnoJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFNAwUBRQgFAmJrBmNhbGxlcgUBawUCYkoJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFPAgUBRQUBawkAZAIFAmJGBQJiegkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVUBBQFrCQBkAgUCYkcFAmJ6BQNuaWwFAmJNBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJrAQpjYW5jZWxWb3RlAgFHAUgEAUUJAJQKAgUBRwUBSAQBawkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFsAAAEAmJBCQECYWoCBQR0aGlzCQEBQgEFAWsEAmJ1CQECYWoCBQR0aGlzBQFoBAJiQgkAZAIFAmJBBQJidQQCYkMJAJoIAgUEdGhpcwUBdQQCYkQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUsCCAUCYmsGY2FsbGVyBQFrAAAEAmJFCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFNAwUBRQgFAmJrBmNhbGxlcgUBawAABAJiRgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBTwIFAUUFAWsAAAQCYkcJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAVUBBQFrAAAEAmJ2CQDMCAIDCQECIT0CCQCgCAEJAQFEAQUBRQUEdW5pdAYJAQFaAQIOaW52YWxpZCBhc3NldHMJAMwIAgMJAGYCBQJiQgUGaGVpZ2h0BgkBAVoBAg5pbnZhbGlkIGhlaWdodAkAzAgCAwkAAAIFAmJDBQR1bml0BgkBAVoBAhhmaW5hbGl6YXRpb24gaW4gcHJvZ3Jlc3MJAMwIAgMJAGYCBQJiRQAABgkBAVoBAgdubyB2b3RlBQNuaWwDCQAAAgUCYnYFAmJ2BAJiTAkBAmFNAQUBRQQBVwkApQgBCAUCYmsGY2FsbGVyCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUsCCAUCYmsGY2FsbGVyBQFrCQCWAwEJAMwIAgkAZQIFAmJEBQJiRQkAzAgCAAAFA25pbAkAzAgCCQELRGVsZXRlRW50cnkBCQEBTQMFAUUIBQJiawZjYWxsZXIFAWsJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFPAgUBRQUBawkAZQIFAmJGBQJiRQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVUBBQFrCQBlAgUCYkcFAmJFBQNuaWwJAQJiYwIFAmJMBQFXBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJrAQ5zZXRFcG9jaExlbmd0aAECYk4EAmJ2CQDMCAIJAQJibQEFAmJrCQDMCAIDCQBmAgUCYk4AAAYJAQFaAQIUaW52YWxpZCBlcG9jaCBsZW5ndGgFA25pbAMJAAACBQJidgUCYnYJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBaQUCYk4FA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiawELc2V0TWF4RGVwdGgBAmJPBAJidgkAzAgCCQECYm0BBQJiawkAzAgCAwkAZgIFAmJPAAAGCQEBWgECEWludmFsaWQgbWF4IGRlcHRoBQNuaWwDCQAAAgUCYnYFAmJ2CQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAW0FAmJPBQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmsBGnByb2Nlc3NQb29sQmFsYW5jZUlOVEVSTkFMAQJiUAQCYlEJAQJibgEFAmJrAwkAAAIFAmJRBQJiUQQBawkBAmFqAgUEdGhpcwUBbAQCYlIJAGUCBQFrAAEEAUUJAQJhbAEFAmJQBAJiUwUBRQQBRwgFAmJTAl8xBAFICAUCYlMCXzIEAmFHCQECYXcCBQFHBQFIBAJiVAoAAmFpCQD8BwQFAmFuAgxjaGVja0JhbGFuY2UJAMwIAgUCYUcFA25pbAUDbmlsAwkAAQIFAmFpAgdCb29sZWFuBQJhaQkAAgEJAKwCAgkAAwEFAmFpAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJiVQkBASEBCQELdmFsdWVPckVsc2UCCQCbCAIFBHRoaXMJAQFJAgUBRQkAZQIFAmJSAAEHBAJiVgMJAQEhAQUCYlQDCQEBIQEFAmJVBAJiVwkA/AcEBQJhbgIZZGVsZXRlV3hFbWlzc2lvblBvb2xMYWJlbAkAzAgCBQFHCQDMCAIFAUgFA25pbAUDbmlsAwkAAAIFAmJXBQJiVwQCYlgJAPwHBAUCYW4CDG1vZGlmeVdlaWdodAkAzAgCBQJhRwkAzAgCAAAFA25pbAUDbmlsAwkAAAIFAmJYBQJiWAQCYlkICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAQJhdQIFAUcFAUgJAQFYAQIOaW52YWxpZCBhc3NldHMCXzEEAmJaAAMEAmNhCQD8BwQFAmFuAgptYW5hZ2VQb29sCQDMCAIJAKUIAQUCYlkJAMwIAgUCYloFA25pbAUDbmlsAwkAAAIFAmNhBQJjYQQCY2IJAM4IAgkAzAgCCQELRGVsZXRlRW50cnkBCQEBRAEFAUUFA25pbAkBAmJjAgUCYUwJAQJhawEFAUUJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVMCBQFFBQJiUgAABQNuaWwFAmNiCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQxCb29sZWFuRW50cnkCCQEBSQIFAUUFAmJSBgUDbmlsBQNuaWwJAJQKAgUCYlYFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmsBE3Byb2Nlc3NWb3RlSU5URVJOQUwCAmJQAVcEAmJRCQECYm4BBQJiawMJAAACBQJiUQUCYlEEAmJvCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQUBVwkBAVgBCQCsAgICKnByb2Nlc3NWb3RlSU5URVJOQUw6IGludmFsaWQgdXNlciBhZGRyZXNzIAUBVwQBawkBAmFqAgUEdGhpcwUBbAQCYlIJAGUCBQFrAAEEAmJ1CQECYWoCBQR0aGlzBQFoBAJiQQkBAmFqAgUEdGhpcwkBAUIBBQFrBAJiQgkAZAIFAmJBBQJidQQCY2MJAQJhagIFBHRoaXMJAQFCAQUCYlIEAmNkCQECYWoCBQR0aGlzCQEBagEFAmJSBAJjZQkAZAIFAmNjBQJjZAQCY2YDCQBnAgUCYlIAAAYJAQFaAQIrcHJvY2Vzc1ZvdGVJTlRFUk5BTDogaW52YWxpZCBwcmV2aW91cyBlcG9jaAMJAAACBQJjZgUCY2YEAUUJAQJhbAEFAmJQBAJjZwUBRQQBRwgFAmNnAl8xBAFICAUCY2cCXzIEAmJICgACYWkJAPwHBAUEdGhpcwIYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0CQDMCAIFAVcJAMwIAgUCYkIFA25pbAUDbmlsAwkAAQIFAmFpAgNJbnQFAmFpCQACAQkArAICCQADAQUCYWkCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAQCY2gKAAJhaQkA/AcEBQR0aGlzAhhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQJAMwIAgUBVwkAzAgCBQJjZQUDbmlsBQNuaWwDCQABAgUCYWkCA0ludAUCYWkJAAIBCQCsAgIJAAMBBQJhaQIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50BAJiRwkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEBVQEFAWsAAAQCY2kJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAU8CBQFFBQFrAAAEAmNqCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQkBAU0DBQFFBQJibwUCYlIJAQFYAQkArAICCQCsAgIJAKwCAgkArAICAhRwcm9jZXNzVm90ZUlOVEVSTkFMIAUCYlACASAFAVcCEjogbm8gcHJldmlvdXMgdm90ZQQCYkQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUsCBQJibwUBawAABAFSCQECYXcCBQFHBQFIBAJjawkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEBUQIFAVIFAmJSAAAEAmJ0CQERQGV4dHJOYXRpdmUoMTA2MikBCQECYWgCBQR0aGlzBQFzBAJjbAkBC3ZhbHVlT3JFbHNlAgkAmggCBQJidAkBAVYCBQFSBQFXAAAEAmNtAwkAAAIFAmNsAAAFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVECBQFSBQJiUgkAZAIFAmNrBQJjagUDbmlsBAJhRwkBAmF3AgUBRwUBSAQCYkoDCQBmAgUCY2gAAAkAawMFAmNqBQJiSAUCY2gAAAQCYlYDCQBmAgUCYkoAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAU0DBQFFBQJibwUBawUCYkoJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFVAQUBawkAZAIFAmJHBQJiSgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAU8CBQFFBQFrCQBkAgUCY2kFAmJKCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBSwIFAmJvBQFrCQBkAgUCYkQFAmJKBQNuaWwJAQJiYwIJAQJhTQEFAUUFAVcJAJQKAgkAzggCBQJiVgUCY20FBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmsBE3Byb2Nlc3NQb29sSU5URVJOQUwCAmJQAmNuBAJiUQkBAmJuAQUCYmsDCQAAAgUCYlEFAmJRBAJjbwQCY3AJAQJhagIFBHRoaXMFAWwDBQJjbgUCY3AJAGUCBQJjcAABBAJjZgMJAGcCBQJjbwAABgkBAVoBAilwcm9jZXNzUG9vbElOVEVSTkFMOiBpbnZhbGlkIHRhcmdldCBlcG9jaAMJAAACBQJjZgUCY2YEAUUJAQJhbAEFAmJQBAJjcQUBRQQBRwgFAmNxAl8xBAFICAUCY3ECXzIEAmJ0CQERQGV4dHJOYXRpdmUoMTA2MikBCQECYWgCBQR0aGlzBQFzBAJhRwkBAmF3AgUBRwUBSAQCY3IKAAJhaQkA/AcEBQJidAISdXNlcnNMaXN0VHJhdmVyc2FsCQDMCAIFAmFHBQNuaWwFA25pbAMJAAECBQJhaQIHQm9vbGVhbgUCYWkJAAIBCQCsAgIJAAMBBQJhaQIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgMJAAACBQJjcgUCY3IDBQJjcgkAlAoCBQNuaWwGBAJjcwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFAmFuBQF0Ah1pbnZhbGlkIGFzc2V0cyBzdG9yZSBjb250cmFjdAQCYkcJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAVUBBQJjbwAABAJjaQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBTwIFAUUFAmNvAAAEAmN0AwkAAAIFAmJHAAAAAAkAawMFAmNpBQFiBQJiRwQCYlgJAPwHBAUCYW4CDG1vZGlmeVdlaWdodAkAzAgCBQJhRwkAzAgCBQJjdAUDbmlsBQNuaWwDCQAAAgUCYlgFAmJYCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFTAgUBRQUCY28FAmN0BQNuaWwHCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJrAQ5maW5hbGl6ZUhlbHBlcgAEAmNuCQELdmFsdWVPckVsc2UCCQCgCAEFAUEHBAFrCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWwAAAQCY3UJAGUCBQFrAAEEAmJBCQECYWoCBQR0aGlzCQEBQgEFAWsEAmJ1CQECYWoCBQR0aGlzBQFoBAJiQgkAZAIFAmJBBQJidQQCYkMJAJoIAgUEdGhpcwUBdQMDAwkAZwIFBmhlaWdodAUCYkIJAAACBQJiQwUEdW5pdAcJAQEhAQUCY24HBAJjdgkAZAIFAWsAAQQCY3cJAJoIAgUEdGhpcwUBaQQCY3gEAmFlBQJjdwMJAAECBQJhZQIDSW50BAJiTgUCYWUJAMwIAgkBDEludGVnZXJFbnRyeQIFAWgFAmJOCQDMCAIJAQtEZWxldGVFbnRyeQEFAWkFA25pbAMJAAECBQJhZQIEVW5pdAUDbmlsCQACAQILTWF0Y2ggZXJyb3IJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBQgEFAmN2BQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFAXgFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBbAUCY3YJAMwIAgkBDEludGVnZXJFbnRyeQIFAXUFAWQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFqAQUBawUCYnUFA25pbAUCY3gGAwMFAmNuCQAAAgUCYkMFBHVuaXQHCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAXUFAWYFA25pbAYDCQAAAgUCYkMFBHVuaXQJAJQKAgUDbmlsBwMJAAACBQJiQwUBZAQCY3kJAKIIAQUBdgQCYWUFAmN5AwkAAQIFAmFlAgRVbml0BAJjegkAoggBCQECYU8BBQJhTAMJAAECBQJjegIEVW5pdAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF1BQFlCQDMCAIJAQtEZWxldGVFbnRyeQEFAXYFA25pbAYDCQABAgUCY3oCBlN0cmluZwQCY0EFAmN6CQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBdgUCY0EFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgMJAAECBQJhZQIGU3RyaW5nBAJiUAUCYWUEAmNCCQCiCAEJAQJhVQIFAmFMBQJiUAMJAAACBQJjQgUCY0IEAmNyCQD8BwQFBHRoaXMCGnByb2Nlc3NQb29sQmFsYW5jZUlOVEVSTkFMCQDMCAIFAmJQBQNuaWwFA25pbAMJAAACBQJjcgUCY3IEAmN6BQJjQgMJAAECBQJjegIEVW5pdAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF1BQFlCQDMCAIJAQtEZWxldGVFbnRyeQEFAXYFA25pbAYDCQABAgUCY3oCBlN0cmluZwQCY0EFAmN6CQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBdgUCY0EFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECC01hdGNoIGVycm9yAwkAAAIFAmJDBQFlBAJjeQkAoggBBQF2BAJjQwkAoggBBQF3BAJhZQUCY3kDCQABAgUCYWUCBFVuaXQEAmN6CQCiCAEJAQJhTwEFAmFMAwkAAQIFAmN6AgRVbml0CQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAXUFAWYJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBdgkAzAgCCQELRGVsZXRlRW50cnkBBQF3BQNuaWwGAwkAAQIFAmN6AgZTdHJpbmcEAmNEBQJjegkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXYFAmNEBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IDCQABAgUCYWUCBlN0cmluZwQCYlAFAmFlBAFFCQECYWwBBQJiUAQCY0UEAmN6BQJjQwMJAAECBQJjegIEVW5pdAkAoggBCQECYU8BCQECYU0BBQFFAwkAAQIFAmN6AgZTdHJpbmcEAmNGBQJjegQCY0cJAKIIAQkBAmFVAgkBAmFNAQUBRQUCY0YDCQAAAgUCY0cFAmNHBAJjSAkA/AcEBQR0aGlzAhNwcm9jZXNzVm90ZUlOVEVSTkFMCQDMCAIFAmJQCQDMCAIFAmNGBQNuaWwFA25pbAMJAAACBQJjSAUCY0gFAmNHCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQILTWF0Y2ggZXJyb3IEAmN6BQJjRQMJAAECBQJjegIEVW5pdAQCY0IJAKIIAQkBAmFVAgUCYUwFAmJQBAJjSQUCY0IDCQABAgUCY0kCBFVuaXQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdQUBZgkAzAgCCQELRGVsZXRlRW50cnkBBQF2CQDMCAIJAQtEZWxldGVFbnRyeQEFAXcFA25pbAYDCQABAgUCY0kCBlN0cmluZwQCYmcFAmNJCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBdgUCYmcJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBdwUDbmlsBgkAAgECC01hdGNoIGVycm9yAwkAAQIFAmN6AgZTdHJpbmcEAmNKBQJjegkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXcFAmNKBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IJAAIBAgtNYXRjaCBlcnJvcgMJAAACBQJiQwUBZgQCY3kJAKIIAQUBdgQCYWUFAmN5AwkAAQIFAmFlAgRVbml0BAJjegkAoggBCQECYU8BBQJhTAMJAAECBQJjegIEVW5pdAQCYlYDBQJjbgkAzAgCCQELRGVsZXRlRW50cnkBBQF1CQDMCAIJAQtEZWxldGVFbnRyeQEFAUEFA25pbAkAzAgCCQELRGVsZXRlRW50cnkBBQF1CQDMCAIJAQxCb29sZWFuRW50cnkCCQEBQwEFAmN1BgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBeQUBawkAzAgCCQEMSW50ZWdlckVudHJ5AgUBegUCYkEFA25pbAQCY0sJAQJhSgADCQAAAgUCY0sFAmNLCQCUCgIFAmJWBgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgMJAAECBQJjegIGU3RyaW5nBAJjQQUCY3oJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQF2BQJjQQUDbmlsBgkAAgECC01hdGNoIGVycm9yAwkAAQIFAmFlAgZTdHJpbmcEAmJQBQJhZQQCY0IJAKIIAQkBAmFVAgUCYUwFAmJQAwkAAAIFAmNCBQJjQgQCY3IKAAJhaQkA/AcEBQR0aGlzAhNwcm9jZXNzUG9vbElOVEVSTkFMCQDMCAIFAmJQCQDMCAIFAmNuBQNuaWwFA25pbAMJAAECBQJhaQIHQm9vbGVhbgUCYWkJAAIBCQCsAgIJAAMBBQJhaQIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgMJAAACBQJjcgUCY3IDBQJjcgkAlAoCBQNuaWwGBAJjegUCY0IDCQABAgUCY3oCBFVuaXQEAmJWAwUCY24JAMwIAgkBC0RlbGV0ZUVudHJ5AQUBdQkAzAgCCQELRGVsZXRlRW50cnkBBQFBCQDMCAIJAQtEZWxldGVFbnRyeQEFAXYFA25pbAkAzAgCCQELRGVsZXRlRW50cnkBBQF1CQDMCAIJAQxCb29sZWFuRW50cnkCCQEBQwEFAmN1BgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBeQUBawkAzAgCCQEMSW50ZWdlckVudHJ5AgUBegUCYkEJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBdgUDbmlsBAJjSwkBAmFKAAMJAAACBQJjSwUCY0sJAJQKAgUCYlYGCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAwkAAQIFAmN6AgZTdHJpbmcEAmNBBQJjegkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXYFAmNBBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAgtNYXRjaCBlcnJvcgkBAVoBAhZmaW5hbGl6YXRpb24gaXMgYnJva2VuAmJrAQ9maW5hbGl6ZVdyYXBwZXIBAmNMBAJjTQkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwUBcAQCY04KAAJhaQkA/AcEBQR0aGlzAg5maW5hbGl6ZUhlbHBlcgUDbmlsBQNuaWwDCQABAgUCYWkCB0Jvb2xlYW4FAmFpCQACAQkArAICCQADAQUCYWkCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4DCQAAAgUCY04FAmNOAwkBASEBBQJjTgMJAAACBQJjTAAACQEBWgECHkN1cnJlbnQgdm90aW5nIGlzIG5vdCBvdmVyIHlldAQCY08JAPwHBAUCY00CCGZpbmFsaXplBQNuaWwFA25pbAMJAAACBQJjTwUCY08JAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAJjUAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFtBQFjAwkAZgIFAmNQBQJjTAQCY08JAPwHBAUEdGhpcwIPZmluYWxpemVXcmFwcGVyCQDMCAIJAGQCBQJjTAABBQNuaWwFA25pbAMJAAACBQJjTwUCY08JAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiawEIZmluYWxpemUABAJjTwkA/AcEBQR0aGlzAg9maW5hbGl6ZVdyYXBwZXIJAMwIAgAABQNuaWwFA25pbAMJAAACBQJjTwUCY08JAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJrARRjb250YWluc05vZGVSRUFET05MWQICYVACYVQJAJQKAgUDbmlsCQECYVYCBQJhUAUCYVQCYmsBCmluc2VydE5vZGUCAmFQAmFUBAJiUQkBAmJtAQUCYmsDCQAAAgUCYlEFAmJRCQCUCgIJAQJhWgIFAmFQBQJhVAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiawEKZGVsZXRlTm9kZQICYVACYVQEAmJRCQECYm0BBQJiawMJAAACBQJiUQUCYlEJAJQKAgkBAmJjAgUCYVAFAmFUBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJrARhpc0ZpbmFsaXphdGlvbkluUHJvZ3Jlc3MABAJiQwkAmggCBQR0aGlzBQF1BAJjUQkBAiE9AgUCYkMFBHVuaXQJAJQKAgUDbmlsBQJjUQJiawEKZGVsZXRlUG9vbAIBRwFIBAJiUQMDCQAAAggFAmJrBmNhbGxlcgUCYW4GCQECYm0BBQJiawYJAQFaAQIRUGVybWlzc2lvbiBkZW5pZWQDCQAAAgUCYlEFAmJRBAJhUAIFcG9vbHMEAUUJAJQKAgUBRwUBSAQCYVQJALkJAgkAzAgCBQFHCQDMCAIFAUgFA25pbAUBYQQCYlYDCQECYVYCBQJhUAUCYVQJAQJiYwIFAmFQBQJhVAUDbmlsCQDOCAIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAUQBBQFFBQNuaWwFAmJWCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJrAQZyZXN1bWUCAUcBSAQCYUcJAQJhdwIFAUcFAUgEAmNSCgACYWkJAPwHBAUCYW4CDGNoZWNrQmFsYW5jZQkAzAgCBQJhRwUDbmlsBQNuaWwDCQABAgUCYWkCB0Jvb2xlYW4FAmFpCQACAQkArAICCQADAQUCYWkCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmNTCQCRAwIIBQJiawhwYXltZW50cwAABAJjcwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwUBdAQCY1QCCiVzX19jb25maWcEAmNVAAEEAmJzCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYWgCBQR0aGlzBQFyBAJjVgkA2QQBCQCRAwIJALUJAgkBEUBleHRyTmF0aXZlKDEwNTMpAgUCYnMFAmNUBQFhBQJjVQQCY1cKAAJhaQkA/AcEBQJjcwISaXNWZXJpZmllZFJFQURPTkxZCQDMCAIFAUcFA25pbAUDbmlsAwkAAQIFAmFpAgdCb29sZWFuBQJhaQkAAgEJAKwCAgkAAwEFAmFpAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJjWAoAAmFpCQD8BwQFAmNzAhJpc1ZlcmlmaWVkUkVBRE9OTFkJAMwIAgUBSAUDbmlsBQNuaWwDCQABAgUCYWkCB0Jvb2xlYW4FAmFpCQACAQkArAICCQADAQUCYWkCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmNZCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAW4FAWcEAmJ2CQDMCAIDBQJjUgYJAQFaAQIVaW5zdWZmaWNpZW50IGJhbGFuY2VzCQDMCAIDCQAAAgkAkAMBCAUCYmsIcGF5bWVudHMAAQYJAQFaAQIVMSBwYXltZW50IGlzIHJlcXVpcmVkCQDMCAIDCQAAAggFAmNTB2Fzc2V0SWQFAmNWBgkBAVoBAhhpbnZhbGlkIHBheW1lbnQgYXNzZXQgaWQJAMwIAgMJAAACCAUCY1MGYW1vdW50BQJjWQYJAQFaAQIWaW52YWxpZCBwYXltZW50IGFtb3VudAkAzAgCAwMFAmNXBQJjWAcGCQEBWgECHmJvdGggYXNzZXRzIHNob3VsZCBiZSB2ZXJpZmllZAUDbmlsAwkAAAIFAmJ2BQJidgQBRQkAlAoCBQFHBQFIBAJidwkAzggCCQDMCAIJAQxCb29sZWFuRW50cnkCCQEBRAEFAUUGBQNuaWwJAQJhWgIFAmFMCQECYWsBBQFFCQCUCgIFAmJ3BQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJjWgECZGEABAJkYgQCYWUJAQJiaAADCQABAgUCYWUCCkJ5dGVWZWN0b3IEAmJsBQJhZQUCYmwDCQABAgUCYWUCBFVuaXQIBQJjWg9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgkA9AMDCAUCY1oJYm9keUJ5dGVzCQCRAwIIBQJjWgZwcm9vZnMAAAUCZGIAx6uQ", "height": 3066422, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: Gf6pwhR3UYk3PnoMQGNGJTH1ioev6wyS3FTEY5qj9AC3 Next: GSPTD42ZfJuujPW4kMVGFUbmJF82gZzGM2p1WJ26e4mc Diff:
OldNewDifferences
77
88 let maxDepthDefault = 10
99
10-let finalizationStageTotal = 0
10+let finalizationStageBalances = 0
1111
12-let finalizationStageShares = 1
12+let finalizationStageTotal = 1
13+
14+let finalizationStageShares = 2
15+
16+let resumptionFeeDefault = 500000000000
1317
1418 let keyEpochLength = makeString(["%s", "epochLength"], separator)
1519
2125 let keyCurrentEpoch = makeString(["%s", "currentEpoch"], separator)
2226
2327 let keyMaxDepth = makeString(["%s", "maxDepth"], separator)
28+
29+let keyResumptionFee = makeString(["%s", "resumptionFee"], separator)
2430
2531 let keyVotingEmissionCandidateContract = makeString(["%s", "votingEmissionCandidateContract"], separator)
2632
5561
5662
5763 func keyInList (pool) = {
58- let $t018691909 = pool
59- let amountAssetId = $t018691909._1
60- let priceAssetId = $t018691909._2
64+ let $t020132053 = pool
65+ let amountAssetId = $t020132053._1
66+ let priceAssetId = $t020132053._2
6167 makeString(["%s%s%s", "inList", amountAssetId, priceAssetId], separator)
68+ }
69+
70+
71+func keyInsufficientBalances (pool,epoch) = {
72+ let $t022022242 = pool
73+ let amountAssetId = $t022022242._1
74+ let priceAssetId = $t022022242._2
75+ makeString(["%s%s%s%d", "insufficientBalances", amountAssetId, priceAssetId, toString(epoch)], separator)
6276 }
6377
6478
6680
6781
6882 func keyVote (pool,address,epoch) = {
69- let $t021832223 = pool
70- let amountAssetId = $t021832223._1
71- let priceAssetId = $t021832223._2
83+ let $t025502590 = pool
84+ let amountAssetId = $t025502590._1
85+ let priceAssetId = $t025502590._2
7286 makeString(["%s%s%s%s%d", "vote", amountAssetId, priceAssetId, toString(address), toString(epoch)], separator)
7387 }
7488
7589
7690 func keyVotingResult (pool,epoch) = {
77- let $t024052445 = pool
78- let amountAssetId = $t024052445._1
79- let priceAssetId = $t024052445._2
91+ let $t027722812 = pool
92+ let amountAssetId = $t027722812._1
93+ let priceAssetId = $t027722812._2
8094 makeString(["%s%s%s%d", "votingResult", amountAssetId, priceAssetId, toString(epoch)], separator)
8195 }
8296
8599
86100
87101 func keyPoolShare (pool,epoch) = {
88- let $t027662806 = pool
89- let amountAssetId = $t027662806._1
90- let priceAssetId = $t027662806._2
102+ let $t031333173 = pool
103+ let amountAssetId = $t031333173._1
104+ let priceAssetId = $t031333173._2
91105 makeString(["%s%s%s%d", "poolShare", amountAssetId, priceAssetId, toString(epoch)], separator)
92106 }
93107
157171 func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp])
158172
159173
174+func getPoolInfo (amountAssetId,priceAssetId) = {
175+ let poolInfoOption = {
176+ let @ = invoke(factoryContract, "poolInfoREADONLY", [amountAssetId, priceAssetId], nil)
177+ if ($isInstanceOf(@, "(Address, ByteVector)"))
178+ then @
179+ else unit
180+ }
181+ poolInfoOption
182+ }
183+
184+
160185 func getLpAssetByPoolAssets (amountAssetId,priceAssetId) = {
161186 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
162187
173198
174199
175200 func checkWxEmissionPoolLabel (pool) = {
176- let $t056465686 = pool
177- let amountAssetId = $t056465686._1
178- let priceAssetId = $t056465686._2
201+ let $t062996339 = pool
202+ let amountAssetId = $t062996339._1
203+ let priceAssetId = $t062996339._2
179204 let @ = invoke(factoryContract, "checkWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil)
180205 if ($isInstanceOf(@, "Boolean"))
181206 then @
193218 let poolsListName = "pools"
194219
195220 func getVotesListName (pool) = {
196- let $t061036143 = pool
197- let amountAssetId = $t061036143._1
198- let priceAssetId = $t061036143._2
221+ let $t067566796 = pool
222+ let amountAssetId = $t067566796._1
223+ let priceAssetId = $t067566796._2
199224 makeString(["votes", amountAssetId, priceAssetId], separator)
200225 }
201226
487512
488513
489514 @Callable(i)
515+func processPoolBalanceINTERNAL (poolStr) = {
516+ let checkCaller = mustThis(i)
517+ if ((checkCaller == checkCaller))
518+ then {
519+ let epoch = getIntOrFail(this, keyCurrentEpoch)
520+ let epochPrevious = (epoch - 1)
521+ let pool = stringToPool(poolStr)
522+ let $t01702017060 = pool
523+ let amountAssetId = $t01702017060._1
524+ let priceAssetId = $t01702017060._2
525+ let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
526+ let balanceIsOkCurrent = {
527+ let @ = invoke(factoryContract, "checkBalance", [lpAssetId], nil)
528+ if ($isInstanceOf(@, "Boolean"))
529+ then @
530+ else throw(($getType(@) + " couldn't be cast to Boolean"))
531+ }
532+ let balanceIsOkPrevious = !(valueOrElse(getBoolean(this, keyInsufficientBalances(pool, (epochPrevious - 1))), false))
533+ let actions = if (!(balanceIsOkCurrent))
534+ then if (!(balanceIsOkPrevious))
535+ then {
536+ let deleteWxEmissionInv = invoke(factoryContract, "deleteWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil)
537+ if ((deleteWxEmissionInv == deleteWxEmissionInv))
538+ then {
539+ let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, 0], nil)
540+ if ((modifyWeightInv == modifyWeightInv))
541+ then {
542+ let poolAddress = valueOrErrorMessage(getPoolInfo(amountAssetId, priceAssetId), wrapErr("invalid assets"))._1
543+ let newStatus = 3
544+ let setPoolStatusInv = invoke(factoryContract, "managePool", [toString(poolAddress), newStatus], nil)
545+ if ((setPoolStatusInv == setPoolStatusInv))
546+ then {
547+ let listActions = ([DeleteEntry(keyInList(pool))] ++ deleteNodeActions(poolsListName, poolToString(pool)))
548+ ([IntegerEntry(keyPoolShare(pool, epochPrevious), 0)] ++ listActions)
549+ }
550+ else throw("Strict value is not equal to itself.")
551+ }
552+ else throw("Strict value is not equal to itself.")
553+ }
554+ else throw("Strict value is not equal to itself.")
555+ }
556+ else [BooleanEntry(keyInsufficientBalances(pool, epochPrevious), true)]
557+ else nil
558+ $Tuple2(actions, unit)
559+ }
560+ else throw("Strict value is not equal to itself.")
561+ }
562+
563+
564+
565+@Callable(i)
490566 func processVoteINTERNAL (poolStr,userAddressStr) = {
491567 let checkCaller = mustThis(i)
492568 if ((checkCaller == checkCaller))
506582 if ((checkTargetEpoch == checkTargetEpoch))
507583 then {
508584 let pool = stringToPool(poolStr)
509- let $t01814618186 = pool
510- let amountAssetId = $t01814618186._1
511- let priceAssetId = $t01814618186._2
512- let wxEmission = checkWxEmissionPoolLabel(pool)
585+ let $t01941319453 = pool
586+ let amountAssetId = $t01941319453._1
587+ let priceAssetId = $t01941319453._2
513588 let gwxAmountAtEndTotal = {
514589 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)
515590 if ($isInstanceOf(@, "Int"))
534609 then nil
535610 else [IntegerEntry(keyVotingResultStaked(lpAssetIdStr, epochPrevious), (votingResultStakedPrevious + votePrevious))]
536611 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
537- let balanceIsOk = {
538- let @ = invoke(factoryContract, "checkBalance", [lpAssetId], nil)
539- if ($isInstanceOf(@, "Boolean"))
540- then @
541- else throw(($getType(@) + " couldn't be cast to Boolean"))
542- }
543612 let newVote = if ((gwxAmountAtEndTotalPrevious > 0))
544613 then fraction(votePrevious, gwxAmountAtEndTotal, gwxAmountAtEndTotalPrevious)
545614 else 0
546- let actions = if (if (if ((newVote > 0))
547- then wxEmission
548- else false)
549- then balanceIsOk
550- else false)
615+ let actions = if ((newVote > 0))
551616 then [IntegerEntry(keyVote(pool, userAddress, epoch), newVote), IntegerEntry(keyTotalVotes(epoch), (totalVotes + newVote)), IntegerEntry(keyVotingResult(pool, epoch), (votingResult + newVote)), IntegerEntry(keyUsed(userAddress, epoch), (used + newVote))]
552617 else deleteNodeActions(getVotesListName(pool), userAddressStr)
553618 $Tuple2((actions ++ votingResultStakedActions), unit)
576641 if ((checkTargetEpoch == checkTargetEpoch))
577642 then {
578643 let pool = stringToPool(poolStr)
579- let $t02072220762 = pool
580- let amountAssetId = $t02072220762._1
581- let priceAssetId = $t02072220762._2
644+ let $t02181621856 = pool
645+ let amountAssetId = $t02181621856._1
646+ let priceAssetId = $t02181621856._2
582647 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
583648 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
584649 let r = {
591656 then if (r)
592657 then $Tuple2(nil, true)
593658 else {
594- let assetsStoreContract = addressFromStringValue(valueOrElse(getString(this, keyAssetsStoreContract), "invalid assets store contract"))
595- let wxEmission = checkWxEmissionPoolLabel(pool)
596- let balanceIsOk = {
597- let @ = invoke(factoryContract, "checkBalance", [lpAssetId], nil)
598- if ($isInstanceOf(@, "Boolean"))
599- then @
600- else throw(($getType(@) + " couldn't be cast to Boolean"))
601- }
602- let amountAssetVerified = {
603- let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [amountAssetId], nil)
604- if ($isInstanceOf(@, "Boolean"))
605- then @
606- else throw(($getType(@) + " couldn't be cast to Boolean"))
607- }
608- let priceAssetVerified = {
609- let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [priceAssetId], nil)
610- if ($isInstanceOf(@, "Boolean"))
611- then @
612- else throw(($getType(@) + " couldn't be cast to Boolean"))
613- }
614- let setWxEmissionInv = if (if (if (if (!(wxEmission))
615- then balanceIsOk
616- else false)
617- then amountAssetVerified
618- else false)
619- then priceAssetVerified
620- else false)
621- then invoke(factoryContract, "setWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil)
622- else unit
623- if ((setWxEmissionInv == setWxEmissionInv))
624- then {
625- let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
626- let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
627- let share = if (if (if ((totalVotes == 0))
628- then true
629- else !(wxEmission))
630- then true
631- else !(balanceIsOk))
632- then 0
633- else fraction(votingResult, poolWeightMult, totalVotes)
634- let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
635- if ((modifyWeightInv == modifyWeightInv))
636- then $Tuple2([IntegerEntry(keyPoolShare(pool, targetEpoch), share)], false)
637- else throw("Strict value is not equal to itself.")
638- }
659+ let assetsStoreContract = addressFromStringValue(valueOrErrorMessage(getString(factoryContract, keyAssetsStoreContract), "invalid assets store contract"))
660+ let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
661+ let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
662+ let share = if ((totalVotes == 0))
663+ then 0
664+ else fraction(votingResult, poolWeightMult, totalVotes)
665+ let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
666+ if ((modifyWeightInv == modifyWeightInv))
667+ then $Tuple2([IntegerEntry(keyPoolShare(pool, targetEpoch), share)], false)
639668 else throw("Strict value is not equal to itself.")
640669 }
641670 else throw("Strict value is not equal to itself.")
672701 case _ =>
673702 throw("Match error")
674703 }
675- $Tuple2(([IntegerEntry(keyStartHeightByEpoch(newEpoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpoch, newEpoch), IntegerEntry(keyFinalizationStage, finalizationStageTotal), IntegerEntry(keyEpochLengthByEpoch(epoch), epochLength)] ++ newEpochLengthActions), true)
704+ $Tuple2(([IntegerEntry(keyStartHeightByEpoch(newEpoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpoch, newEpoch), IntegerEntry(keyFinalizationStage, finalizationStageBalances), IntegerEntry(keyEpochLengthByEpoch(epoch), epochLength)] ++ newEpochLengthActions), true)
676705 }
677706 else if (if (force)
678707 then (finalizationStageOrUnit == unit)
680709 then $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares)], true)
681710 else if ((finalizationStageOrUnit == unit))
682711 then $Tuple2(nil, false)
683- else if ((finalizationStageOrUnit == finalizationStageTotal))
712+ else if ((finalizationStageOrUnit == finalizationStageBalances))
684713 then {
685714 let poolOrUnit = getString(keyNextPool)
686- let userOrUnit = getString(keyNextUser)
687715 match poolOrUnit {
688716 case _: Unit =>
689717 match getString(keyListHead(poolsListName)) {
690718 case _: Unit =>
691- $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
692- case poolsHeadStr: String =>
693- $Tuple2([StringEntry(keyNextPool, poolsHeadStr)], true)
719+ $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageTotal), DeleteEntry(keyNextPool)], true)
720+ case nextPoolStr: String =>
721+ $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
694722 case _ =>
695723 throw("Match error")
696724 }
697725 case poolStr: String =>
698- let pool = stringToPool(poolStr)
699- let nextUserOrUnit = match userOrUnit {
726+ let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
727+ if ((nextPoolOrUnit == nextPoolOrUnit))
728+ then {
729+ let r = invoke(this, "processPoolBalanceINTERNAL", [poolStr], nil)
730+ if ((r == r))
731+ then match nextPoolOrUnit {
732+ case _: Unit =>
733+ $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageTotal), DeleteEntry(keyNextPool)], true)
734+ case nextPoolStr: String =>
735+ $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
736+ case _ =>
737+ throw("Match error")
738+ }
739+ else throw("Strict value is not equal to itself.")
740+ }
741+ else throw("Strict value is not equal to itself.")
742+ case _ =>
743+ throw("Match error")
744+ }
745+ }
746+ else if ((finalizationStageOrUnit == finalizationStageTotal))
747+ then {
748+ let poolOrUnit = getString(keyNextPool)
749+ let userOrUnit = getString(keyNextUser)
750+ match poolOrUnit {
751+ case _: Unit =>
752+ match getString(keyListHead(poolsListName)) {
753+ case _: Unit =>
754+ $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
755+ case poolsHeadStr: String =>
756+ $Tuple2([StringEntry(keyNextPool, poolsHeadStr)], true)
757+ case _ =>
758+ throw("Match error")
759+ }
760+ case poolStr: String =>
761+ let pool = stringToPool(poolStr)
762+ let nextUserOrUnit = match userOrUnit {
763+ case _: Unit =>
764+ getString(keyListHead(getVotesListName(pool)))
765+ case user: String =>
766+ let next = getString(keyListNext(getVotesListName(pool), user))
767+ if ((next == next))
768+ then {
769+ let processVoteInv = invoke(this, "processVoteINTERNAL", [poolStr, user], nil)
770+ if ((processVoteInv == processVoteInv))
771+ then next
772+ else throw("Strict value is not equal to itself.")
773+ }
774+ else throw("Strict value is not equal to itself.")
775+ case _ =>
776+ throw("Match error")
777+ }
778+ match nextUserOrUnit {
779+ case _: Unit =>
780+ let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
781+ match nextPoolOrUnit {
782+ case _: Unit =>
783+ $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
784+ case s: String =>
785+ $Tuple2([StringEntry(keyNextPool, s), DeleteEntry(keyNextUser)], true)
786+ case _ =>
787+ throw("Match error")
788+ }
789+ case nextUser: String =>
790+ $Tuple2([StringEntry(keyNextUser, nextUser)], true)
791+ case _ =>
792+ throw("Match error")
793+ }
794+ case _ =>
795+ throw("Match error")
796+ }
797+ }
798+ else if ((finalizationStageOrUnit == finalizationStageShares))
799+ then {
800+ let poolOrUnit = getString(keyNextPool)
801+ match poolOrUnit {
700802 case _: Unit =>
701- getString(keyListHead(getVotesListName(pool)))
702- case user: String =>
703- let next = getString(keyListNext(getVotesListName(pool), user))
704- if ((next == next))
803+ match getString(keyListHead(poolsListName)) {
804+ case _: Unit =>
805+ let actions = if (force)
806+ then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced)]
807+ else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight)]
808+ let gwxRewardDepositInv = gwxRewardDeposit()
809+ if ((gwxRewardDepositInv == gwxRewardDepositInv))
810+ then $Tuple2(actions, true)
811+ else throw("Strict value is not equal to itself.")
812+ case nextPoolStr: String =>
813+ $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
814+ case _ =>
815+ throw("Match error")
816+ }
817+ case poolStr: String =>
818+ let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
819+ if ((nextPoolOrUnit == nextPoolOrUnit))
705820 then {
706- let processVoteInv = invoke(this, "processVoteINTERNAL", [poolStr, user], nil)
707- if ((processVoteInv == processVoteInv))
708- then next
821+ let r = {
822+ let @ = invoke(this, "processPoolINTERNAL", [poolStr, force], nil)
823+ if ($isInstanceOf(@, "Boolean"))
824+ then @
825+ else throw(($getType(@) + " couldn't be cast to Boolean"))
826+ }
827+ if ((r == r))
828+ then if (r)
829+ then $Tuple2(nil, true)
830+ else match nextPoolOrUnit {
831+ case _: Unit =>
832+ let actions = if (force)
833+ then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced), DeleteEntry(keyNextPool)]
834+ else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight), DeleteEntry(keyNextPool)]
835+ let gwxRewardDepositInv = gwxRewardDeposit()
836+ if ((gwxRewardDepositInv == gwxRewardDepositInv))
837+ then $Tuple2(actions, true)
838+ else throw("Strict value is not equal to itself.")
839+ case nextPoolStr: String =>
840+ $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
841+ case _ =>
842+ throw("Match error")
843+ }
709844 else throw("Strict value is not equal to itself.")
710845 }
711846 else throw("Strict value is not equal to itself.")
712847 case _ =>
713848 throw("Match error")
714849 }
715- match nextUserOrUnit {
716- case _: Unit =>
717- let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
718- match nextPoolOrUnit {
719- case _: Unit =>
720- $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
721- case s: String =>
722- $Tuple2([StringEntry(keyNextPool, s), DeleteEntry(keyNextUser)], true)
723- case _ =>
724- throw("Match error")
725- }
726- case nextUser: String =>
727- $Tuple2([StringEntry(keyNextUser, nextUser)], true)
728- case _ =>
729- throw("Match error")
730850 }
731- case _ =>
732- throw("Match error")
733- }
734- }
735- else if ((finalizationStageOrUnit == finalizationStageShares))
736- then {
737- let poolOrUnit = getString(keyNextPool)
738- match poolOrUnit {
739- case _: Unit =>
740- match getString(keyListHead(poolsListName)) {
741- case _: Unit =>
742- let actions = if (force)
743- then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced)]
744- else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight)]
745- let gwxRewardDepositInv = gwxRewardDeposit()
746- if ((gwxRewardDepositInv == gwxRewardDepositInv))
747- then $Tuple2(actions, true)
748- else throw("Strict value is not equal to itself.")
749- case nextPoolStr: String =>
750- $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
751- case _ =>
752- throw("Match error")
753- }
754- case poolStr: String =>
755- let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
756- if ((nextPoolOrUnit == nextPoolOrUnit))
757- then {
758- let r = {
759- let @ = invoke(this, "processPoolINTERNAL", [poolStr, force], nil)
760- if ($isInstanceOf(@, "Boolean"))
761- then @
762- else throw(($getType(@) + " couldn't be cast to Boolean"))
763- }
764- if ((r == r))
765- then if (r)
766- then $Tuple2(nil, true)
767- else match nextPoolOrUnit {
768- case _: Unit =>
769- let actions = if (force)
770- then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced), DeleteEntry(keyNextPool)]
771- else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight), DeleteEntry(keyNextPool)]
772- let gwxRewardDepositInv = gwxRewardDeposit()
773- if ((gwxRewardDepositInv == gwxRewardDepositInv))
774- then $Tuple2(actions, true)
775- else throw("Strict value is not equal to itself.")
776- case nextPoolStr: String =>
777- $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
778- case _ =>
779- throw("Match error")
780- }
781- else throw("Strict value is not equal to itself.")
782- }
783- else throw("Strict value is not equal to itself.")
784- case _ =>
785- throw("Match error")
786- }
787- }
788- else throwErr("finalization is broken")
851+ else throwErr("finalization is broken")
789852 }
790853
791854
890953 }
891954
892955
956+
957+@Callable(i)
958+func resume (amountAssetId,priceAssetId) = {
959+ let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
960+ let balanceIsOk = {
961+ let @ = invoke(factoryContract, "checkBalance", [lpAssetId], nil)
962+ if ($isInstanceOf(@, "Boolean"))
963+ then @
964+ else throw(($getType(@) + " couldn't be cast to Boolean"))
965+ }
966+ let payment = i.payments[0]
967+ let assetsStoreContract = addressFromStringValue(getStringValue(this, keyAssetsStoreContract))
968+ let kBoostingConfig = "%s__config"
969+ let idxCfgAssetId = 1
970+ let boostingContract = addressFromStringValue(getStrOrFail(this, keyBoostingContract))
971+ let wxAssetId = fromBase58String(split(getStringValue(boostingContract, kBoostingConfig), separator)[idxCfgAssetId])
972+ let amountAssetVerified = {
973+ let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [amountAssetId], nil)
974+ if ($isInstanceOf(@, "Boolean"))
975+ then @
976+ else throw(($getType(@) + " couldn't be cast to Boolean"))
977+ }
978+ let priceAssetVerified = {
979+ let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [priceAssetId], nil)
980+ if ($isInstanceOf(@, "Boolean"))
981+ then @
982+ else throw(($getType(@) + " couldn't be cast to Boolean"))
983+ }
984+ let resumptionFee = valueOrElse(getInteger(this, keyResumptionFee), resumptionFeeDefault)
985+ let checks = [if (balanceIsOk)
986+ then true
987+ else throwErr("insufficient balances"), if ((size(i.payments) == 1))
988+ then true
989+ else throwErr("1 payment is required"), if ((payment.assetId == wxAssetId))
990+ then true
991+ else throwErr("invalid payment asset id"), if ((payment.amount == resumptionFee))
992+ then true
993+ else throwErr("invalid payment amount"), if (if (amountAssetVerified)
994+ then priceAssetVerified
995+ else false)
996+ then true
997+ else throwErr("both assets should be verified")]
998+ if ((checks == checks))
999+ then {
1000+ let pool = $Tuple2(amountAssetId, priceAssetId)
1001+ let inListActions = ([BooleanEntry(keyInList(pool), true)] ++ insertNodeActions(poolsListName, poolToString(pool)))
1002+ $Tuple2(inListActions, unit)
1003+ }
1004+ else throw("Strict value is not equal to itself.")
1005+ }
1006+
1007+
8931008 @Verifier(tx)
8941009 func verify () = {
8951010 let targetPublicKey = match managerPublicKeyOrUnit() {
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "__"
55
66 let poolWeightMult = 100000000
77
88 let maxDepthDefault = 10
99
10-let finalizationStageTotal = 0
10+let finalizationStageBalances = 0
1111
12-let finalizationStageShares = 1
12+let finalizationStageTotal = 1
13+
14+let finalizationStageShares = 2
15+
16+let resumptionFeeDefault = 500000000000
1317
1418 let keyEpochLength = makeString(["%s", "epochLength"], separator)
1519
1620 let keyEpochLengthNew = makeString(["%s%s", "epochLength__new"], separator)
1721
1822 func keyEpochLengthByEpoch (epoch) = makeString(["%s%d", "epochLength", toString(epoch)], separator)
1923
2024
2125 let keyCurrentEpoch = makeString(["%s", "currentEpoch"], separator)
2226
2327 let keyMaxDepth = makeString(["%s", "maxDepth"], separator)
28+
29+let keyResumptionFee = makeString(["%s", "resumptionFee"], separator)
2430
2531 let keyVotingEmissionCandidateContract = makeString(["%s", "votingEmissionCandidateContract"], separator)
2632
2733 let keyVotingEmissionRateContract = makeString(["%s", "votingEmissionRateContract"], separator)
2834
2935 let keyFactoryContract = makeString(["%s", "factoryContract"], separator)
3036
3137 let keyBoostingContract = makeString(["%s", "boostingContract"], separator)
3238
3339 let keyStakingContract = makeString(["%s", "stakingContract"], separator)
3440
3541 let keyAssetsStoreContract = makeString(["%s", "assetsStoreContract"], separator)
3642
3743 let keyFinalizationStage = makeString(["%s", "finalizationStage"], separator)
3844
3945 let keyNextPool = makeString(["%s", "nextPool"], separator)
4046
4147 let keyNextUser = makeString(["%s", "nextUser"], separator)
4248
4349 let keyStartHeight = makeString(["%s", "startHeight"], separator)
4450
4551 let keyCurrentEpochUi = makeString(["%s", "currentEpochUi"], separator)
4652
4753 let keyStartHeightUi = makeString(["%s", "startHeightUi"], separator)
4854
4955 let keyFinalizationShouldBeForced = makeString(["%s", "force"], separator)
5056
5157 func keyStartHeightByEpoch (epoch) = makeString(["%s%d", "startHeight", toString(epoch)], separator)
5258
5359
5460 func keyFinalized (epoch) = makeString(["%s%d", "finalized", toString(epoch)], separator)
5561
5662
5763 func keyInList (pool) = {
58- let $t018691909 = pool
59- let amountAssetId = $t018691909._1
60- let priceAssetId = $t018691909._2
64+ let $t020132053 = pool
65+ let amountAssetId = $t020132053._1
66+ let priceAssetId = $t020132053._2
6167 makeString(["%s%s%s", "inList", amountAssetId, priceAssetId], separator)
68+ }
69+
70+
71+func keyInsufficientBalances (pool,epoch) = {
72+ let $t022022242 = pool
73+ let amountAssetId = $t022022242._1
74+ let priceAssetId = $t022022242._2
75+ makeString(["%s%s%s%d", "insufficientBalances", amountAssetId, priceAssetId, toString(epoch)], separator)
6276 }
6377
6478
6579 func keyUsed (address,epoch) = makeString(["%s%s%d", "used", toString(address), toString(epoch)], separator)
6680
6781
6882 func keyVote (pool,address,epoch) = {
69- let $t021832223 = pool
70- let amountAssetId = $t021832223._1
71- let priceAssetId = $t021832223._2
83+ let $t025502590 = pool
84+ let amountAssetId = $t025502590._1
85+ let priceAssetId = $t025502590._2
7286 makeString(["%s%s%s%s%d", "vote", amountAssetId, priceAssetId, toString(address), toString(epoch)], separator)
7387 }
7488
7589
7690 func keyVotingResult (pool,epoch) = {
77- let $t024052445 = pool
78- let amountAssetId = $t024052445._1
79- let priceAssetId = $t024052445._2
91+ let $t027722812 = pool
92+ let amountAssetId = $t027722812._1
93+ let priceAssetId = $t027722812._2
8094 makeString(["%s%s%s%d", "votingResult", amountAssetId, priceAssetId, toString(epoch)], separator)
8195 }
8296
8397
8498 func keyVotingResultStaked (lpAssetIdStr,epoch) = makeString(["%s%s%d", "votingResultStaked", lpAssetIdStr, toString(epoch)], separator)
8599
86100
87101 func keyPoolShare (pool,epoch) = {
88- let $t027662806 = pool
89- let amountAssetId = $t027662806._1
90- let priceAssetId = $t027662806._2
102+ let $t031333173 = pool
103+ let amountAssetId = $t031333173._1
104+ let priceAssetId = $t031333173._2
91105 makeString(["%s%s%s%d", "poolShare", amountAssetId, priceAssetId, toString(epoch)], separator)
92106 }
93107
94108
95109 func keyTotalVotes (epoch) = makeString(["%s%d", "totalVotes", toString(epoch)], separator)
96110
97111
98112 func keyStakedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s", "staked", userAddressStr, lpAssetIdStr], separator)
99113
100114
101115 func wrapErr (msg) = makeString(["voting_emission.ride:", msg], " ")
102116
103117
104118 func throwErr (msg) = throw(wrapErr(msg))
105119
106120
107121 func getValueOrFail (address,key,type) = {
108122 let error = wrapErr(makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
109123 valueOrErrorMessage( match type {
110124 case str: String =>
111125 getString(address, key)
112126 case int: Int =>
113127 getInteger(address, key)
114128 case _ =>
115129 throwErr("invalid entry type")
116130 }, error)
117131 }
118132
119133
120134 func getStrOrFail (address,key) = {
121135 let @ = getValueOrFail(address, key, "")
122136 if ($isInstanceOf(@, "String"))
123137 then @
124138 else throw(($getType(@) + " couldn't be cast to String"))
125139 }
126140
127141
128142 func getIntOrFail (address,key) = {
129143 let @ = getValueOrFail(address, key, 0)
130144 if ($isInstanceOf(@, "Int"))
131145 then @
132146 else throw(($getType(@) + " couldn't be cast to Int"))
133147 }
134148
135149
136150 func poolToString (pool) = ((pool._1 + separator) + pool._2)
137151
138152
139153 func stringToPool (str) = {
140154 let parts = split(str, separator)
141155 if ((size(parts) == 2))
142156 then $Tuple2(parts[0], parts[1])
143157 else throwErr("invalid pool string")
144158 }
145159
146160
147161 let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
148162
149163 let IdxFactoryCfgGwxRewardDapp = 10
150164
151165 func keyFactoryCfg () = "%s__factoryConfig"
152166
153167
154168 func readFactoryCfgOrFail (factory) = split(getStrOrFail(factory, keyFactoryCfg()), separator)
155169
156170
157171 func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp])
158172
159173
174+func getPoolInfo (amountAssetId,priceAssetId) = {
175+ let poolInfoOption = {
176+ let @ = invoke(factoryContract, "poolInfoREADONLY", [amountAssetId, priceAssetId], nil)
177+ if ($isInstanceOf(@, "(Address, ByteVector)"))
178+ then @
179+ else unit
180+ }
181+ poolInfoOption
182+ }
183+
184+
160185 func getLpAssetByPoolAssets (amountAssetId,priceAssetId) = {
161186 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
162187
163188 func keyMappingPoolAssetsToPoolContractAddress (internalAmountAssetIdStr,internalPriceAssetIdStr) = (((("%d%d%s%s__" + toString(internalAmountAssetIdStr)) + "__") + toString(internalPriceAssetIdStr)) + "__mappings__poolAssets2PoolContract")
164189
165190 func keyMappingPoolContractToLPAsset (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
166191
167192 let amountAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amountAssetId))
168193 let priceAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAssetId))
169194 let poolContractAddress = getStrOrFail(factoryContract, keyMappingPoolAssetsToPoolContractAddress(amountAssetInternalId, priceAssetInternalId))
170195 let lpAssetId = getStrOrFail(factoryContract, keyMappingPoolContractToLPAsset(poolContractAddress))
171196 lpAssetId
172197 }
173198
174199
175200 func checkWxEmissionPoolLabel (pool) = {
176- let $t056465686 = pool
177- let amountAssetId = $t056465686._1
178- let priceAssetId = $t056465686._2
201+ let $t062996339 = pool
202+ let amountAssetId = $t062996339._1
203+ let priceAssetId = $t062996339._2
179204 let @ = invoke(factoryContract, "checkWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil)
180205 if ($isInstanceOf(@, "Boolean"))
181206 then @
182207 else throw(($getType(@) + " couldn't be cast to Boolean"))
183208 }
184209
185210
186211 func gwxRewardDeposit () = {
187212 let factoryCfg = readFactoryCfgOrFail(factoryContract)
188213 let gwxRewardsContract = getGwxRewardAddressOrFail(factoryCfg)
189214 invoke(gwxRewardsContract, "deposit", nil, nil)
190215 }
191216
192217
193218 let poolsListName = "pools"
194219
195220 func getVotesListName (pool) = {
196- let $t061036143 = pool
197- let amountAssetId = $t061036143._1
198- let priceAssetId = $t061036143._2
221+ let $t067566796 = pool
222+ let amountAssetId = $t067566796._1
223+ let priceAssetId = $t067566796._2
199224 makeString(["votes", amountAssetId, priceAssetId], separator)
200225 }
201226
202227
203228 func keyListHead (listName) = {
204229 let meta = if ((listName == poolsListName))
205230 then "%s%s"
206231 else "%s%s%s%s"
207232 makeString([meta, listName, "head"], separator)
208233 }
209234
210235
211236 func keyListSize (listName) = {
212237 let meta = if ((listName == poolsListName))
213238 then "%s%s"
214239 else "%s%s%s%s"
215240 makeString([meta, listName, "size"], separator)
216241 }
217242
218243
219244 func keyListPrev (listName,id) = {
220245 let meta = if ((listName == poolsListName))
221246 then "%s%s%s%s"
222247 else "%s%s%s%s%s"
223248 makeString([meta, listName, id, "prev"], separator)
224249 }
225250
226251
227252 func keyListNext (listName,id) = {
228253 let meta = if ((listName == poolsListName))
229254 then "%s%s%s%s"
230255 else "%s%s%s%s%s"
231256 makeString([meta, listName, id, "next"], separator)
232257 }
233258
234259
235260 func containsNode (listName,id) = {
236261 let headOrUnit = getString(this, keyListHead(listName))
237262 let prevOrUnit = getString(this, keyListPrev(listName, id))
238263 let nextOrUnit = getString(this, keyListNext(listName, id))
239264 if (if ((id == valueOrElse(headOrUnit, "")))
240265 then true
241266 else (prevOrUnit != unit))
242267 then true
243268 else (nextOrUnit != unit)
244269 }
245270
246271
247272 func insertNodeActions (listName,id) = {
248273 let headOrUnit = getString(this, keyListHead(listName))
249274 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
250275 let checkNode = if (!(containsNode(listName, id)))
251276 then true
252277 else throwErr("Node exists")
253278 if ((checkNode == checkNode))
254279 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
255280 then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
256281 else nil)) ++ [StringEntry(keyListHead(listName), id)])
257282 else throw("Strict value is not equal to itself.")
258283 }
259284
260285
261286 func deleteNodeActions (listName,id) = {
262287 let headOrUnit = getString(this, keyListHead(listName))
263288 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
264289 let prevOrUnit = getString(this, keyListPrev(listName, id))
265290 let nextOrUnit = getString(this, keyListNext(listName, id))
266291 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
267292 then (nextOrUnit != unit)
268293 else false)
269294 then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
270295 else if ((nextOrUnit != unit))
271296 then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
272297 else if ((prevOrUnit != unit))
273298 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
274299 else if ((id == valueOrElse(headOrUnit, "")))
275300 then [DeleteEntry(keyListHead(listName))]
276301 else throwErr(((("invalid node: " + listName) + ".") + id))))
277302 }
278303
279304
280305 func keyManagerVaultAddress () = "%s__managerVaultAddress"
281306
282307
283308 func keyManagerPublicKey () = "%s__managerPublicKey"
284309
285310
286311 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
287312 case s: String =>
288313 addressFromStringValue(s)
289314 case _ =>
290315 this
291316 }
292317
293318
294319 func managerPublicKeyOrUnit () = {
295320 let managerVaultAddress = getManagerVaultAddressOrThis()
296321 match getString(managerVaultAddress, keyManagerPublicKey()) {
297322 case s: String =>
298323 fromBase58String(s)
299324 case _: Unit =>
300325 unit
301326 case _ =>
302327 throw("Match error")
303328 }
304329 }
305330
306331
307332 func isManager (i) = match managerPublicKeyOrUnit() {
308333 case pk: ByteVector =>
309334 (i.callerPublicKey == pk)
310335 case _: Unit =>
311336 (i.caller == this)
312337 case _ =>
313338 throw("Match error")
314339 }
315340
316341
317342 func mustManager (i) = if (isManager(i))
318343 then true
319344 else throw("permission denied")
320345
321346
322347 func mustThis (i) = if ((i.caller == this))
323348 then true
324349 else throw("permission denied")
325350
326351
327352 @Callable(i)
328353 func getUserGwxAmountAtHeight (userAddress,targetHeight) = {
329354 let boostingContractAddress = valueOrErrorMessage(addressFromString(getStrOrFail(this, keyBoostingContract)), wrapErr("invalid boosting contract address"))
330355 $Tuple2(nil, {
331356 let @ = invoke(boostingContractAddress, "getUserGwxAmountAtHeightREADONLY", [userAddress, targetHeight], nil)
332357 if ($isInstanceOf(@, "Int"))
333358 then @
334359 else throw(($getType(@) + " couldn't be cast to Int"))
335360 })
336361 }
337362
338363
339364
340365 @Callable(i)
341366 func constructor (factoryContract,votingEmissionCandidateContract,boostingContract,stakingContract,epochLength) = {
342367 let checks = [mustManager(i), if ((addressFromString(factoryContract) != unit))
343368 then true
344369 else "invalid factory contract address", if ((addressFromString(votingEmissionCandidateContract) != unit))
345370 then true
346371 else "invalid voting emission candidate contract address", if ((addressFromString(boostingContract) != unit))
347372 then true
348373 else "invalid boosting contract address", if ((addressFromString(stakingContract) != unit))
349374 then true
350375 else "invalid staking contract address", if ((epochLength > 0))
351376 then true
352377 else throwErr("invalid epoch length")]
353378 if ((checks == checks))
354379 then $Tuple2([StringEntry(keyFactoryContract, factoryContract), StringEntry(keyVotingEmissionCandidateContract, votingEmissionCandidateContract), StringEntry(keyBoostingContract, boostingContract), StringEntry(keyStakingContract, stakingContract), IntegerEntry(keyEpochLength, epochLength)], unit)
355380 else throw("Strict value is not equal to itself.")
356381 }
357382
358383
359384
360385 @Callable(i)
361386 func create (amountAssetId,priceAssetId) = {
362387 let checks = [if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionCandidateContract), "")))
363388 then true
364389 else mustManager(i)]
365390 if ((checks == checks))
366391 then {
367392 let pool = $Tuple2(amountAssetId, priceAssetId)
368393 let inListActions = ([BooleanEntry(keyInList(pool), true)] ++ insertNodeActions(poolsListName, poolToString(pool)))
369394 let currentEpochIsNotDefined = (getInteger(this, keyCurrentEpoch) == unit)
370395 let startHeightActions = if (currentEpochIsNotDefined)
371396 then {
372397 let epoch = 0
373398 [IntegerEntry(keyCurrentEpoch, epoch), IntegerEntry(keyStartHeightByEpoch(epoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, height)]
374399 }
375400 else nil
376401 $Tuple2((inListActions ++ startHeightActions), unit)
377402 }
378403 else throw("Strict value is not equal to itself.")
379404 }
380405
381406
382407
383408 @Callable(i)
384409 func vote (amountAssetId,priceAssetId,amount) = {
385410 let pool = $Tuple2(amountAssetId, priceAssetId)
386411 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
387412 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
388413 let epochLength = getIntOrFail(this, keyEpochLength)
389414 let endHeight = (startHeight + epochLength)
390415 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
391416 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
392417 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
393418 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
394419 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
395420 let gwxAmountAtEndTotal = {
396421 let @ = invoke(this, "getUserGwxAmountAtHeight", [toBase58String(i.caller.bytes), endHeight], nil)
397422 if ($isInstanceOf(@, "Int"))
398423 then @
399424 else throw(($getType(@) + " couldn't be cast to Int"))
400425 }
401426 let available = (gwxAmountAtEndTotal - used)
402427 let newVote = (vote + amount)
403428 let wxEmission = checkWxEmissionPoolLabel(pool)
404429 let checks = [if ((getBoolean(keyInList(pool)) != unit))
405430 then true
406431 else throwErr("invalid assets"), if ((endHeight > height))
407432 then true
408433 else throwErr("invalid height"), if ((finalizationStageOrUnit == unit))
409434 then true
410435 else throwErr("finalization in progress"), if ((gwxAmountAtEndTotal > 0))
411436 then true
412437 else throwErr("you do not have gWX"), if (if ((amount > 0))
413438 then (available >= amount)
414439 else false)
415440 then true
416441 else throwErr("invalid amount"), if (wxEmission)
417442 then true
418443 else throwErr("pool hasn't WX_EMISSION label")]
419444 if ((checks == checks))
420445 then {
421446 let votesListName = getVotesListName(pool)
422447 let userAddressStr = toString(i.caller)
423448 let votesListActions = if (containsNode(votesListName, userAddressStr))
424449 then nil
425450 else insertNodeActions(votesListName, userAddressStr)
426451 $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)
427452 }
428453 else throw("Strict value is not equal to itself.")
429454 }
430455
431456
432457
433458 @Callable(i)
434459 func cancelVote (amountAssetId,priceAssetId) = {
435460 let pool = $Tuple2(amountAssetId, priceAssetId)
436461 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
437462 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
438463 let epochLength = getIntOrFail(this, keyEpochLength)
439464 let endHeight = (startHeight + epochLength)
440465 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
441466 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
442467 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
443468 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
444469 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
445470 let checks = [if ((getBoolean(keyInList(pool)) != unit))
446471 then true
447472 else throwErr("invalid assets"), if ((endHeight > height))
448473 then true
449474 else throwErr("invalid height"), if ((finalizationStageOrUnit == unit))
450475 then true
451476 else throwErr("finalization in progress"), if ((vote > 0))
452477 then true
453478 else throwErr("no vote")]
454479 if ((checks == checks))
455480 then {
456481 let votesListName = getVotesListName(pool)
457482 let userAddressStr = toString(i.caller)
458483 $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)
459484 }
460485 else throw("Strict value is not equal to itself.")
461486 }
462487
463488
464489
465490 @Callable(i)
466491 func setEpochLength (newEpochLength) = {
467492 let checks = [mustManager(i), if ((newEpochLength > 0))
468493 then true
469494 else throwErr("invalid epoch length")]
470495 if ((checks == checks))
471496 then $Tuple2([IntegerEntry(keyEpochLengthNew, newEpochLength)], unit)
472497 else throw("Strict value is not equal to itself.")
473498 }
474499
475500
476501
477502 @Callable(i)
478503 func setMaxDepth (newMaxDepth) = {
479504 let checks = [mustManager(i), if ((newMaxDepth > 0))
480505 then true
481506 else throwErr("invalid max depth")]
482507 if ((checks == checks))
483508 then $Tuple2([IntegerEntry(keyMaxDepth, newMaxDepth)], unit)
484509 else throw("Strict value is not equal to itself.")
485510 }
486511
487512
488513
489514 @Callable(i)
515+func processPoolBalanceINTERNAL (poolStr) = {
516+ let checkCaller = mustThis(i)
517+ if ((checkCaller == checkCaller))
518+ then {
519+ let epoch = getIntOrFail(this, keyCurrentEpoch)
520+ let epochPrevious = (epoch - 1)
521+ let pool = stringToPool(poolStr)
522+ let $t01702017060 = pool
523+ let amountAssetId = $t01702017060._1
524+ let priceAssetId = $t01702017060._2
525+ let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
526+ let balanceIsOkCurrent = {
527+ let @ = invoke(factoryContract, "checkBalance", [lpAssetId], nil)
528+ if ($isInstanceOf(@, "Boolean"))
529+ then @
530+ else throw(($getType(@) + " couldn't be cast to Boolean"))
531+ }
532+ let balanceIsOkPrevious = !(valueOrElse(getBoolean(this, keyInsufficientBalances(pool, (epochPrevious - 1))), false))
533+ let actions = if (!(balanceIsOkCurrent))
534+ then if (!(balanceIsOkPrevious))
535+ then {
536+ let deleteWxEmissionInv = invoke(factoryContract, "deleteWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil)
537+ if ((deleteWxEmissionInv == deleteWxEmissionInv))
538+ then {
539+ let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, 0], nil)
540+ if ((modifyWeightInv == modifyWeightInv))
541+ then {
542+ let poolAddress = valueOrErrorMessage(getPoolInfo(amountAssetId, priceAssetId), wrapErr("invalid assets"))._1
543+ let newStatus = 3
544+ let setPoolStatusInv = invoke(factoryContract, "managePool", [toString(poolAddress), newStatus], nil)
545+ if ((setPoolStatusInv == setPoolStatusInv))
546+ then {
547+ let listActions = ([DeleteEntry(keyInList(pool))] ++ deleteNodeActions(poolsListName, poolToString(pool)))
548+ ([IntegerEntry(keyPoolShare(pool, epochPrevious), 0)] ++ listActions)
549+ }
550+ else throw("Strict value is not equal to itself.")
551+ }
552+ else throw("Strict value is not equal to itself.")
553+ }
554+ else throw("Strict value is not equal to itself.")
555+ }
556+ else [BooleanEntry(keyInsufficientBalances(pool, epochPrevious), true)]
557+ else nil
558+ $Tuple2(actions, unit)
559+ }
560+ else throw("Strict value is not equal to itself.")
561+ }
562+
563+
564+
565+@Callable(i)
490566 func processVoteINTERNAL (poolStr,userAddressStr) = {
491567 let checkCaller = mustThis(i)
492568 if ((checkCaller == checkCaller))
493569 then {
494570 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr(("processVoteINTERNAL: invalid user address " + userAddressStr)))
495571 let epoch = getIntOrFail(this, keyCurrentEpoch)
496572 let epochPrevious = (epoch - 1)
497573 let epochLength = getIntOrFail(this, keyEpochLength)
498574 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
499575 let endHeight = (startHeight + epochLength)
500576 let startHeightPrevious = getIntOrFail(this, keyStartHeightByEpoch(epochPrevious))
501577 let epochLengthPrevious = getIntOrFail(this, keyEpochLengthByEpoch(epochPrevious))
502578 let endHeightPrevious = (startHeightPrevious + epochLengthPrevious)
503579 let checkTargetEpoch = if ((epochPrevious >= 0))
504580 then true
505581 else throwErr("processVoteINTERNAL: invalid previous epoch")
506582 if ((checkTargetEpoch == checkTargetEpoch))
507583 then {
508584 let pool = stringToPool(poolStr)
509- let $t01814618186 = pool
510- let amountAssetId = $t01814618186._1
511- let priceAssetId = $t01814618186._2
512- let wxEmission = checkWxEmissionPoolLabel(pool)
585+ let $t01941319453 = pool
586+ let amountAssetId = $t01941319453._1
587+ let priceAssetId = $t01941319453._2
513588 let gwxAmountAtEndTotal = {
514589 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)
515590 if ($isInstanceOf(@, "Int"))
516591 then @
517592 else throw(($getType(@) + " couldn't be cast to Int"))
518593 }
519594 let gwxAmountAtEndTotalPrevious = {
520595 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeightPrevious], nil)
521596 if ($isInstanceOf(@, "Int"))
522597 then @
523598 else throw(($getType(@) + " couldn't be cast to Int"))
524599 }
525600 let totalVotes = valueOrElse(getInteger(keyTotalVotes(epoch)), 0)
526601 let votingResult = valueOrElse(getInteger(keyVotingResult(pool, epoch)), 0)
527602 let votePrevious = valueOrErrorMessage(getInteger(keyVote(pool, userAddress, epochPrevious)), wrapErr((((("processVoteINTERNAL " + poolStr) + " ") + userAddressStr) + ": no previous vote")))
528603 let used = valueOrElse(getInteger(this, keyUsed(userAddress, epoch)), 0)
529604 let lpAssetIdStr = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
530605 let votingResultStakedPrevious = valueOrElse(getInteger(keyVotingResultStaked(lpAssetIdStr, epochPrevious)), 0)
531606 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
532607 let stakedByUser = valueOrElse(getInteger(stakingContract, keyStakedByUser(lpAssetIdStr, userAddressStr)), 0)
533608 let votingResultStakedActions = if ((stakedByUser == 0))
534609 then nil
535610 else [IntegerEntry(keyVotingResultStaked(lpAssetIdStr, epochPrevious), (votingResultStakedPrevious + votePrevious))]
536611 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
537- let balanceIsOk = {
538- let @ = invoke(factoryContract, "checkBalance", [lpAssetId], nil)
539- if ($isInstanceOf(@, "Boolean"))
540- then @
541- else throw(($getType(@) + " couldn't be cast to Boolean"))
542- }
543612 let newVote = if ((gwxAmountAtEndTotalPrevious > 0))
544613 then fraction(votePrevious, gwxAmountAtEndTotal, gwxAmountAtEndTotalPrevious)
545614 else 0
546- let actions = if (if (if ((newVote > 0))
547- then wxEmission
548- else false)
549- then balanceIsOk
550- else false)
615+ let actions = if ((newVote > 0))
551616 then [IntegerEntry(keyVote(pool, userAddress, epoch), newVote), IntegerEntry(keyTotalVotes(epoch), (totalVotes + newVote)), IntegerEntry(keyVotingResult(pool, epoch), (votingResult + newVote)), IntegerEntry(keyUsed(userAddress, epoch), (used + newVote))]
552617 else deleteNodeActions(getVotesListName(pool), userAddressStr)
553618 $Tuple2((actions ++ votingResultStakedActions), unit)
554619 }
555620 else throw("Strict value is not equal to itself.")
556621 }
557622 else throw("Strict value is not equal to itself.")
558623 }
559624
560625
561626
562627 @Callable(i)
563628 func processPoolINTERNAL (poolStr,force) = {
564629 let checkCaller = mustThis(i)
565630 if ((checkCaller == checkCaller))
566631 then {
567632 let targetEpoch = {
568633 let currentEpoch = getIntOrFail(this, keyCurrentEpoch)
569634 if (force)
570635 then currentEpoch
571636 else (currentEpoch - 1)
572637 }
573638 let checkTargetEpoch = if ((targetEpoch >= 0))
574639 then true
575640 else throwErr("processPoolINTERNAL: invalid target epoch")
576641 if ((checkTargetEpoch == checkTargetEpoch))
577642 then {
578643 let pool = stringToPool(poolStr)
579- let $t02072220762 = pool
580- let amountAssetId = $t02072220762._1
581- let priceAssetId = $t02072220762._2
644+ let $t02181621856 = pool
645+ let amountAssetId = $t02181621856._1
646+ let priceAssetId = $t02181621856._2
582647 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
583648 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
584649 let r = {
585650 let @ = invoke(stakingContract, "usersListTraversal", [lpAssetId], nil)
586651 if ($isInstanceOf(@, "Boolean"))
587652 then @
588653 else throw(($getType(@) + " couldn't be cast to Boolean"))
589654 }
590655 if ((r == r))
591656 then if (r)
592657 then $Tuple2(nil, true)
593658 else {
594- let assetsStoreContract = addressFromStringValue(valueOrElse(getString(this, keyAssetsStoreContract), "invalid assets store contract"))
595- let wxEmission = checkWxEmissionPoolLabel(pool)
596- let balanceIsOk = {
597- let @ = invoke(factoryContract, "checkBalance", [lpAssetId], nil)
598- if ($isInstanceOf(@, "Boolean"))
599- then @
600- else throw(($getType(@) + " couldn't be cast to Boolean"))
601- }
602- let amountAssetVerified = {
603- let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [amountAssetId], nil)
604- if ($isInstanceOf(@, "Boolean"))
605- then @
606- else throw(($getType(@) + " couldn't be cast to Boolean"))
607- }
608- let priceAssetVerified = {
609- let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [priceAssetId], nil)
610- if ($isInstanceOf(@, "Boolean"))
611- then @
612- else throw(($getType(@) + " couldn't be cast to Boolean"))
613- }
614- let setWxEmissionInv = if (if (if (if (!(wxEmission))
615- then balanceIsOk
616- else false)
617- then amountAssetVerified
618- else false)
619- then priceAssetVerified
620- else false)
621- then invoke(factoryContract, "setWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil)
622- else unit
623- if ((setWxEmissionInv == setWxEmissionInv))
624- then {
625- let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
626- let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
627- let share = if (if (if ((totalVotes == 0))
628- then true
629- else !(wxEmission))
630- then true
631- else !(balanceIsOk))
632- then 0
633- else fraction(votingResult, poolWeightMult, totalVotes)
634- let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
635- if ((modifyWeightInv == modifyWeightInv))
636- then $Tuple2([IntegerEntry(keyPoolShare(pool, targetEpoch), share)], false)
637- else throw("Strict value is not equal to itself.")
638- }
659+ let assetsStoreContract = addressFromStringValue(valueOrErrorMessage(getString(factoryContract, keyAssetsStoreContract), "invalid assets store contract"))
660+ let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
661+ let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
662+ let share = if ((totalVotes == 0))
663+ then 0
664+ else fraction(votingResult, poolWeightMult, totalVotes)
665+ let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
666+ if ((modifyWeightInv == modifyWeightInv))
667+ then $Tuple2([IntegerEntry(keyPoolShare(pool, targetEpoch), share)], false)
639668 else throw("Strict value is not equal to itself.")
640669 }
641670 else throw("Strict value is not equal to itself.")
642671 }
643672 else throw("Strict value is not equal to itself.")
644673 }
645674 else throw("Strict value is not equal to itself.")
646675 }
647676
648677
649678
650679 @Callable(i)
651680 func finalizeHelper () = {
652681 let force = valueOrElse(getBoolean(keyFinalizationShouldBeForced), false)
653682 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
654683 let previousEpoch = (epoch - 1)
655684 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
656685 let epochLength = getIntOrFail(this, keyEpochLength)
657686 let endHeight = (startHeight + epochLength)
658687 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
659688 if (if (if ((height >= endHeight))
660689 then (finalizationStageOrUnit == unit)
661690 else false)
662691 then !(force)
663692 else false)
664693 then {
665694 let newEpoch = (epoch + 1)
666695 let newEpochLengthOption = getInteger(this, keyEpochLengthNew)
667696 let newEpochLengthActions = match newEpochLengthOption {
668697 case newEpochLength: Int =>
669698 [IntegerEntry(keyEpochLength, newEpochLength), DeleteEntry(keyEpochLengthNew)]
670699 case _: Unit =>
671700 nil
672701 case _ =>
673702 throw("Match error")
674703 }
675- $Tuple2(([IntegerEntry(keyStartHeightByEpoch(newEpoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpoch, newEpoch), IntegerEntry(keyFinalizationStage, finalizationStageTotal), IntegerEntry(keyEpochLengthByEpoch(epoch), epochLength)] ++ newEpochLengthActions), true)
704+ $Tuple2(([IntegerEntry(keyStartHeightByEpoch(newEpoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpoch, newEpoch), IntegerEntry(keyFinalizationStage, finalizationStageBalances), IntegerEntry(keyEpochLengthByEpoch(epoch), epochLength)] ++ newEpochLengthActions), true)
676705 }
677706 else if (if (force)
678707 then (finalizationStageOrUnit == unit)
679708 else false)
680709 then $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares)], true)
681710 else if ((finalizationStageOrUnit == unit))
682711 then $Tuple2(nil, false)
683- else if ((finalizationStageOrUnit == finalizationStageTotal))
712+ else if ((finalizationStageOrUnit == finalizationStageBalances))
684713 then {
685714 let poolOrUnit = getString(keyNextPool)
686- let userOrUnit = getString(keyNextUser)
687715 match poolOrUnit {
688716 case _: Unit =>
689717 match getString(keyListHead(poolsListName)) {
690718 case _: Unit =>
691- $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
692- case poolsHeadStr: String =>
693- $Tuple2([StringEntry(keyNextPool, poolsHeadStr)], true)
719+ $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageTotal), DeleteEntry(keyNextPool)], true)
720+ case nextPoolStr: String =>
721+ $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
694722 case _ =>
695723 throw("Match error")
696724 }
697725 case poolStr: String =>
698- let pool = stringToPool(poolStr)
699- let nextUserOrUnit = match userOrUnit {
726+ let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
727+ if ((nextPoolOrUnit == nextPoolOrUnit))
728+ then {
729+ let r = invoke(this, "processPoolBalanceINTERNAL", [poolStr], nil)
730+ if ((r == r))
731+ then match nextPoolOrUnit {
732+ case _: Unit =>
733+ $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageTotal), DeleteEntry(keyNextPool)], true)
734+ case nextPoolStr: String =>
735+ $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
736+ case _ =>
737+ throw("Match error")
738+ }
739+ else throw("Strict value is not equal to itself.")
740+ }
741+ else throw("Strict value is not equal to itself.")
742+ case _ =>
743+ throw("Match error")
744+ }
745+ }
746+ else if ((finalizationStageOrUnit == finalizationStageTotal))
747+ then {
748+ let poolOrUnit = getString(keyNextPool)
749+ let userOrUnit = getString(keyNextUser)
750+ match poolOrUnit {
751+ case _: Unit =>
752+ match getString(keyListHead(poolsListName)) {
753+ case _: Unit =>
754+ $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
755+ case poolsHeadStr: String =>
756+ $Tuple2([StringEntry(keyNextPool, poolsHeadStr)], true)
757+ case _ =>
758+ throw("Match error")
759+ }
760+ case poolStr: String =>
761+ let pool = stringToPool(poolStr)
762+ let nextUserOrUnit = match userOrUnit {
763+ case _: Unit =>
764+ getString(keyListHead(getVotesListName(pool)))
765+ case user: String =>
766+ let next = getString(keyListNext(getVotesListName(pool), user))
767+ if ((next == next))
768+ then {
769+ let processVoteInv = invoke(this, "processVoteINTERNAL", [poolStr, user], nil)
770+ if ((processVoteInv == processVoteInv))
771+ then next
772+ else throw("Strict value is not equal to itself.")
773+ }
774+ else throw("Strict value is not equal to itself.")
775+ case _ =>
776+ throw("Match error")
777+ }
778+ match nextUserOrUnit {
779+ case _: Unit =>
780+ let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
781+ match nextPoolOrUnit {
782+ case _: Unit =>
783+ $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
784+ case s: String =>
785+ $Tuple2([StringEntry(keyNextPool, s), DeleteEntry(keyNextUser)], true)
786+ case _ =>
787+ throw("Match error")
788+ }
789+ case nextUser: String =>
790+ $Tuple2([StringEntry(keyNextUser, nextUser)], true)
791+ case _ =>
792+ throw("Match error")
793+ }
794+ case _ =>
795+ throw("Match error")
796+ }
797+ }
798+ else if ((finalizationStageOrUnit == finalizationStageShares))
799+ then {
800+ let poolOrUnit = getString(keyNextPool)
801+ match poolOrUnit {
700802 case _: Unit =>
701- getString(keyListHead(getVotesListName(pool)))
702- case user: String =>
703- let next = getString(keyListNext(getVotesListName(pool), user))
704- if ((next == next))
803+ match getString(keyListHead(poolsListName)) {
804+ case _: Unit =>
805+ let actions = if (force)
806+ then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced)]
807+ else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight)]
808+ let gwxRewardDepositInv = gwxRewardDeposit()
809+ if ((gwxRewardDepositInv == gwxRewardDepositInv))
810+ then $Tuple2(actions, true)
811+ else throw("Strict value is not equal to itself.")
812+ case nextPoolStr: String =>
813+ $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
814+ case _ =>
815+ throw("Match error")
816+ }
817+ case poolStr: String =>
818+ let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
819+ if ((nextPoolOrUnit == nextPoolOrUnit))
705820 then {
706- let processVoteInv = invoke(this, "processVoteINTERNAL", [poolStr, user], nil)
707- if ((processVoteInv == processVoteInv))
708- then next
821+ let r = {
822+ let @ = invoke(this, "processPoolINTERNAL", [poolStr, force], nil)
823+ if ($isInstanceOf(@, "Boolean"))
824+ then @
825+ else throw(($getType(@) + " couldn't be cast to Boolean"))
826+ }
827+ if ((r == r))
828+ then if (r)
829+ then $Tuple2(nil, true)
830+ else match nextPoolOrUnit {
831+ case _: Unit =>
832+ let actions = if (force)
833+ then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced), DeleteEntry(keyNextPool)]
834+ else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight), DeleteEntry(keyNextPool)]
835+ let gwxRewardDepositInv = gwxRewardDeposit()
836+ if ((gwxRewardDepositInv == gwxRewardDepositInv))
837+ then $Tuple2(actions, true)
838+ else throw("Strict value is not equal to itself.")
839+ case nextPoolStr: String =>
840+ $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
841+ case _ =>
842+ throw("Match error")
843+ }
709844 else throw("Strict value is not equal to itself.")
710845 }
711846 else throw("Strict value is not equal to itself.")
712847 case _ =>
713848 throw("Match error")
714849 }
715- match nextUserOrUnit {
716- case _: Unit =>
717- let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
718- match nextPoolOrUnit {
719- case _: Unit =>
720- $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
721- case s: String =>
722- $Tuple2([StringEntry(keyNextPool, s), DeleteEntry(keyNextUser)], true)
723- case _ =>
724- throw("Match error")
725- }
726- case nextUser: String =>
727- $Tuple2([StringEntry(keyNextUser, nextUser)], true)
728- case _ =>
729- throw("Match error")
730850 }
731- case _ =>
732- throw("Match error")
733- }
734- }
735- else if ((finalizationStageOrUnit == finalizationStageShares))
736- then {
737- let poolOrUnit = getString(keyNextPool)
738- match poolOrUnit {
739- case _: Unit =>
740- match getString(keyListHead(poolsListName)) {
741- case _: Unit =>
742- let actions = if (force)
743- then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced)]
744- else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight)]
745- let gwxRewardDepositInv = gwxRewardDeposit()
746- if ((gwxRewardDepositInv == gwxRewardDepositInv))
747- then $Tuple2(actions, true)
748- else throw("Strict value is not equal to itself.")
749- case nextPoolStr: String =>
750- $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
751- case _ =>
752- throw("Match error")
753- }
754- case poolStr: String =>
755- let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
756- if ((nextPoolOrUnit == nextPoolOrUnit))
757- then {
758- let r = {
759- let @ = invoke(this, "processPoolINTERNAL", [poolStr, force], nil)
760- if ($isInstanceOf(@, "Boolean"))
761- then @
762- else throw(($getType(@) + " couldn't be cast to Boolean"))
763- }
764- if ((r == r))
765- then if (r)
766- then $Tuple2(nil, true)
767- else match nextPoolOrUnit {
768- case _: Unit =>
769- let actions = if (force)
770- then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced), DeleteEntry(keyNextPool)]
771- else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight), DeleteEntry(keyNextPool)]
772- let gwxRewardDepositInv = gwxRewardDeposit()
773- if ((gwxRewardDepositInv == gwxRewardDepositInv))
774- then $Tuple2(actions, true)
775- else throw("Strict value is not equal to itself.")
776- case nextPoolStr: String =>
777- $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
778- case _ =>
779- throw("Match error")
780- }
781- else throw("Strict value is not equal to itself.")
782- }
783- else throw("Strict value is not equal to itself.")
784- case _ =>
785- throw("Match error")
786- }
787- }
788- else throwErr("finalization is broken")
851+ else throwErr("finalization is broken")
789852 }
790853
791854
792855
793856 @Callable(i)
794857 func finalizeWrapper (counter) = {
795858 let votingEmissionRateContract = addressFromStringValue(getStringValue(this, keyVotingEmissionRateContract))
796859 let result = {
797860 let @ = invoke(this, "finalizeHelper", nil, nil)
798861 if ($isInstanceOf(@, "Boolean"))
799862 then @
800863 else throw(($getType(@) + " couldn't be cast to Boolean"))
801864 }
802865 if ((result == result))
803866 then if (!(result))
804867 then if ((counter == 0))
805868 then throwErr("Current voting is not over yet")
806869 else {
807870 let inv = invoke(votingEmissionRateContract, "finalize", nil, nil)
808871 if ((inv == inv))
809872 then $Tuple2(nil, unit)
810873 else throw("Strict value is not equal to itself.")
811874 }
812875 else {
813876 let maxDepth = valueOrElse(getInteger(this, keyMaxDepth), maxDepthDefault)
814877 if ((maxDepth > counter))
815878 then {
816879 let inv = invoke(this, "finalizeWrapper", [(counter + 1)], nil)
817880 if ((inv == inv))
818881 then $Tuple2(nil, unit)
819882 else throw("Strict value is not equal to itself.")
820883 }
821884 else $Tuple2(nil, unit)
822885 }
823886 else throw("Strict value is not equal to itself.")
824887 }
825888
826889
827890
828891 @Callable(i)
829892 func finalize () = {
830893 let inv = invoke(this, "finalizeWrapper", [0], nil)
831894 if ((inv == inv))
832895 then $Tuple2(nil, unit)
833896 else throw("Strict value is not equal to itself.")
834897 }
835898
836899
837900
838901 @Callable(i)
839902 func containsNodeREADONLY (listName,id) = $Tuple2(nil, containsNode(listName, id))
840903
841904
842905
843906 @Callable(i)
844907 func insertNode (listName,id) = {
845908 let checkCaller = mustManager(i)
846909 if ((checkCaller == checkCaller))
847910 then $Tuple2(insertNodeActions(listName, id), unit)
848911 else throw("Strict value is not equal to itself.")
849912 }
850913
851914
852915
853916 @Callable(i)
854917 func deleteNode (listName,id) = {
855918 let checkCaller = mustManager(i)
856919 if ((checkCaller == checkCaller))
857920 then $Tuple2(deleteNodeActions(listName, id), unit)
858921 else throw("Strict value is not equal to itself.")
859922 }
860923
861924
862925
863926 @Callable(i)
864927 func isFinalizationInProgress () = {
865928 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
866929 let finalizationInProgress = (finalizationStageOrUnit != unit)
867930 $Tuple2(nil, finalizationInProgress)
868931 }
869932
870933
871934
872935 @Callable(i)
873936 func deletePool (amountAssetId,priceAssetId) = {
874937 let checkCaller = if (if ((i.caller == factoryContract))
875938 then true
876939 else mustManager(i))
877940 then true
878941 else throwErr("Permission denied")
879942 if ((checkCaller == checkCaller))
880943 then {
881944 let listName = "pools"
882945 let pool = $Tuple2(amountAssetId, priceAssetId)
883946 let id = makeString([amountAssetId, priceAssetId], separator)
884947 let actions = if (containsNode(listName, id))
885948 then deleteNodeActions(listName, id)
886949 else nil
887950 ([DeleteEntry(keyInList(pool))] ++ actions)
888951 }
889952 else throw("Strict value is not equal to itself.")
890953 }
891954
892955
956+
957+@Callable(i)
958+func resume (amountAssetId,priceAssetId) = {
959+ let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
960+ let balanceIsOk = {
961+ let @ = invoke(factoryContract, "checkBalance", [lpAssetId], nil)
962+ if ($isInstanceOf(@, "Boolean"))
963+ then @
964+ else throw(($getType(@) + " couldn't be cast to Boolean"))
965+ }
966+ let payment = i.payments[0]
967+ let assetsStoreContract = addressFromStringValue(getStringValue(this, keyAssetsStoreContract))
968+ let kBoostingConfig = "%s__config"
969+ let idxCfgAssetId = 1
970+ let boostingContract = addressFromStringValue(getStrOrFail(this, keyBoostingContract))
971+ let wxAssetId = fromBase58String(split(getStringValue(boostingContract, kBoostingConfig), separator)[idxCfgAssetId])
972+ let amountAssetVerified = {
973+ let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [amountAssetId], nil)
974+ if ($isInstanceOf(@, "Boolean"))
975+ then @
976+ else throw(($getType(@) + " couldn't be cast to Boolean"))
977+ }
978+ let priceAssetVerified = {
979+ let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [priceAssetId], nil)
980+ if ($isInstanceOf(@, "Boolean"))
981+ then @
982+ else throw(($getType(@) + " couldn't be cast to Boolean"))
983+ }
984+ let resumptionFee = valueOrElse(getInteger(this, keyResumptionFee), resumptionFeeDefault)
985+ let checks = [if (balanceIsOk)
986+ then true
987+ else throwErr("insufficient balances"), if ((size(i.payments) == 1))
988+ then true
989+ else throwErr("1 payment is required"), if ((payment.assetId == wxAssetId))
990+ then true
991+ else throwErr("invalid payment asset id"), if ((payment.amount == resumptionFee))
992+ then true
993+ else throwErr("invalid payment amount"), if (if (amountAssetVerified)
994+ then priceAssetVerified
995+ else false)
996+ then true
997+ else throwErr("both assets should be verified")]
998+ if ((checks == checks))
999+ then {
1000+ let pool = $Tuple2(amountAssetId, priceAssetId)
1001+ let inListActions = ([BooleanEntry(keyInList(pool), true)] ++ insertNodeActions(poolsListName, poolToString(pool)))
1002+ $Tuple2(inListActions, unit)
1003+ }
1004+ else throw("Strict value is not equal to itself.")
1005+ }
1006+
1007+
8931008 @Verifier(tx)
8941009 func verify () = {
8951010 let targetPublicKey = match managerPublicKeyOrUnit() {
8961011 case pk: ByteVector =>
8971012 pk
8981013 case _: Unit =>
8991014 tx.senderPublicKey
9001015 case _ =>
9011016 throw("Match error")
9021017 }
9031018 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
9041019 }
9051020

github/deemru/w8io/786bc32 
132.93 ms