tx · 6qBFadnFQ5qUzzraGbXFMkseSEujpAasVYF8jLtqTto1

3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr:  -0.02300000 Waves

2023.09.07 12:04 [2744758] smart account 3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr > SELF 0.00000000 Waves

{ "type": 13, "id": "6qBFadnFQ5qUzzraGbXFMkseSEujpAasVYF8jLtqTto1", "fee": 2300000, "feeAssetId": null, "timestamp": 1694077505805, "version": 2, "chainId": 84, "sender": "3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr", "senderPublicKey": "GFbasS3jufhZkK4xR7tdTjjnP8K33KvJFEDHRtxXDkaJ", "proofs": [ "34h1cm6tQUkudHQK5bphhVrRFSUPnP3GFt49zcU75fHuwaaQXNZbGBwqBFEzKGsvKaETgqEjyqPPWka4ztKGHEKs" ], "script": "base64:BgLcFggCEgQKAggBEgcKBQgICAgBEgQKAggIEgUKAwgIARIECgIICBIDCgEBEgMKAQESBAoCCAgSBAoCCAQSABIDCgEBEgASBAoCCAgSBAoCCAgSBAoCCAgSABIECgIICBIDCgEIIglzZXBhcmF0b3IiDnBvb2xXZWlnaHRNdWx0Ig9tYXhEZXB0aERlZmF1bHQiFmZpbmFsaXphdGlvblN0YWdlVG90YWwiF2ZpbmFsaXphdGlvblN0YWdlU2hhcmVzIg5rZXlFcG9jaExlbmd0aCIRa2V5RXBvY2hMZW5ndGhOZXciFWtleUVwb2NoTGVuZ3RoQnlFcG9jaCIFZXBvY2giD2tleUN1cnJlbnRFcG9jaCILa2V5TWF4RGVwdGgiImtleVZvdGluZ0VtaXNzaW9uQ2FuZGlkYXRlQ29udHJhY3QiHWtleVZvdGluZ0VtaXNzaW9uUmF0ZUNvbnRyYWN0IhJrZXlGYWN0b3J5Q29udHJhY3QiE2tleUJvb3N0aW5nQ29udHJhY3QiEmtleVN0YWtpbmdDb250cmFjdCIUa2V5RmluYWxpemF0aW9uU3RhZ2UiC2tleU5leHRQb29sIgtrZXlOZXh0VXNlciIOa2V5U3RhcnRIZWlnaHQiEWtleUN1cnJlbnRFcG9jaFVpIhBrZXlTdGFydEhlaWdodFVpIh1rZXlGaW5hbGl6YXRpb25TaG91bGRCZUZvcmNlZCIVa2V5U3RhcnRIZWlnaHRCeUVwb2NoIgxrZXlGaW5hbGl6ZWQiCWtleUluTGlzdCIEcG9vbCILJHQwMTc4ODE4MjgiDWFtb3VudEFzc2V0SWQiDHByaWNlQXNzZXRJZCIHa2V5VXNlZCIHYWRkcmVzcyIHa2V5Vm90ZSILJHQwMjEwMjIxNDIiD2tleVZvdGluZ1Jlc3VsdCILJHQwMjMyNDIzNjQiFWtleVZvdGluZ1Jlc3VsdFN0YWtlZCIMbHBBc3NldElkU3RyIgxrZXlQb29sU2hhcmUiCyR0MDI2ODUyNzI1Ig1rZXlUb3RhbFZvdGVzIg9rZXlTdGFrZWRCeVVzZXIiDnVzZXJBZGRyZXNzU3RyIgd3cmFwRXJyIgNtc2ciCHRocm93RXJyIg5nZXRWYWx1ZU9yRmFpbCIDa2V5IgR0eXBlIgVlcnJvciIHJG1hdGNoMCIDc3RyIgNpbnQiDGdldFN0ck9yRmFpbCIBQCIMZ2V0SW50T3JGYWlsIgxwb29sVG9TdHJpbmciDHN0cmluZ1RvUG9vbCIFcGFydHMiD2ZhY3RvcnlDb250cmFjdCIaSWR4RmFjdG9yeUNmZ0d3eFJld2FyZERhcHAiDWtleUZhY3RvcnlDZmciFHJlYWRGYWN0b3J5Q2ZnT3JGYWlsIgdmYWN0b3J5IhlnZXRHd3hSZXdhcmRBZGRyZXNzT3JGYWlsIgpmYWN0b3J5Q2ZnIhZnZXRMcEFzc2V0QnlQb29sQXNzZXRzIh9rZXlNYXBwaW5nc0Jhc2VBc3NldDJpbnRlcm5hbElkIgxiYXNlQXNzZXRTdHIiKWtleU1hcHBpbmdQb29sQXNzZXRzVG9Qb29sQ29udHJhY3RBZGRyZXNzIhhpbnRlcm5hbEFtb3VudEFzc2V0SWRTdHIiF2ludGVybmFsUHJpY2VBc3NldElkU3RyIh9rZXlNYXBwaW5nUG9vbENvbnRyYWN0VG9MUEFzc2V0IhNwb29sQ29udHJhY3RBZGRyZXNzIhVhbW91bnRBc3NldEludGVybmFsSWQiFHByaWNlQXNzZXRJbnRlcm5hbElkIglscEFzc2V0SWQiGGNoZWNrV3hFbWlzc2lvblBvb2xMYWJlbCILJHQwNTU2NTU2MDUiDXBvb2xzTGlzdE5hbWUiEGdldFZvdGVzTGlzdE5hbWUiCyR0MDU4MTk1ODU5IgtrZXlMaXN0SGVhZCIIbGlzdE5hbWUiBG1ldGEiC2tleUxpc3RTaXplIgtrZXlMaXN0UHJldiICaWQiC2tleUxpc3ROZXh0Igxjb250YWluc05vZGUiCmhlYWRPclVuaXQiCnByZXZPclVuaXQiCm5leHRPclVuaXQiEWluc2VydE5vZGVBY3Rpb25zIghsaXN0U2l6ZSIJY2hlY2tOb2RlIhFkZWxldGVOb2RlQWN0aW9ucyIWa2V5TWFuYWdlclZhdWx0QWRkcmVzcyITa2V5TWFuYWdlclB1YmxpY0tleSIcZ2V0TWFuYWdlclZhdWx0QWRkcmVzc09yVGhpcyIBcyIWbWFuYWdlclB1YmxpY0tleU9yVW5pdCITbWFuYWdlclZhdWx0QWRkcmVzcyIJaXNNYW5hZ2VyIgFpIgJwayILbXVzdE1hbmFnZXIiCG11c3RUaGlzIgt1c2VyQWRkcmVzcyIMdGFyZ2V0SGVpZ2h0Ihdib29zdGluZ0NvbnRyYWN0QWRkcmVzcyIfdm90aW5nRW1pc3Npb25DYW5kaWRhdGVDb250cmFjdCIQYm9vc3RpbmdDb250cmFjdCIPc3Rha2luZ0NvbnRyYWN0IgtlcG9jaExlbmd0aCIGY2hlY2tzIg1pbkxpc3RBY3Rpb25zIhhjdXJyZW50RXBvY2hJc05vdERlZmluZWQiEnN0YXJ0SGVpZ2h0QWN0aW9ucyIGYW1vdW50IgtzdGFydEhlaWdodCIJZW5kSGVpZ2h0IhdmaW5hbGl6YXRpb25TdGFnZU9yVW5pdCIEdXNlZCIEdm90ZSIKcG9vbFJlc3VsdCIKdG90YWxWb3RlcyITZ3d4QW1vdW50QXRFbmRUb3RhbCIJYXZhaWxhYmxlIgduZXdWb3RlIgp3eEVtaXNzaW9uIg12b3Rlc0xpc3ROYW1lIhB2b3Rlc0xpc3RBY3Rpb25zIg5uZXdFcG9jaExlbmd0aCILbmV3TWF4RGVwdGgiB3Bvb2xTdHIiC2NoZWNrQ2FsbGVyIg1lcG9jaFByZXZpb3VzIhNzdGFydEhlaWdodFByZXZpb3VzIhNlcG9jaExlbmd0aFByZXZpb3VzIhFlbmRIZWlnaHRQcmV2aW91cyIQY2hlY2tUYXJnZXRFcG9jaCINJHQwMTc4NjIxNzkwMiIbZ3d4QW1vdW50QXRFbmRUb3RhbFByZXZpb3VzIgx2b3RpbmdSZXN1bHQiDHZvdGVQcmV2aW91cyIadm90aW5nUmVzdWx0U3Rha2VkUHJldmlvdXMiDHN0YWtlZEJ5VXNlciIZdm90aW5nUmVzdWx0U3Rha2VkQWN0aW9ucyIHYWN0aW9ucyIFZm9yY2UiC3RhcmdldEVwb2NoIgxjdXJyZW50RXBvY2giDSR0MDIwMjU5MjAyOTkiBXNoYXJlIg9tb2RpZnlXZWlnaHRJbnYiEHBvb2xzTGlzdEFjdGlvbnMiDXByZXZpb3VzRXBvY2giCG5ld0Vwb2NoIhRuZXdFcG9jaExlbmd0aE9wdGlvbiIVbmV3RXBvY2hMZW5ndGhBY3Rpb25zIgpwb29sT3JVbml0Igp1c2VyT3JVbml0IgckbWF0Y2gxIgxwb29sc0hlYWRTdHIiDm5leHRVc2VyT3JVbml0IgR1c2VyIgRuZXh0Ig5wcm9jZXNzVm90ZUludiIObmV4dFBvb2xPclVuaXQiByRtYXRjaDIiCG5leHRVc2VyIgtuZXh0UG9vbFN0ciIBciIHY291bnRlciIadm90aW5nRW1pc3Npb25SYXRlQ29udHJhY3QiBnJlc3VsdCIDaW52IghtYXhEZXB0aCIWZmluYWxpemF0aW9uSW5Qcm9ncmVzcyIJZ3d4QW1vdW50IgFuIgJ0eCIGdmVyaWZ5Ig90YXJnZXRQdWJsaWNLZXk+AAFhAgJfXwABYgCAwtcvAAFjAAoAAWQAAAABZQABAAFmCQC5CQIJAMwIAgICJXMJAMwIAgILZXBvY2hMZW5ndGgFA25pbAUBYQABZwkAuQkCCQDMCAICBCVzJXMJAMwIAgIQZXBvY2hMZW5ndGhfX25ldwUDbmlsBQFhAQFoAQFpCQC5CQIJAMwIAgIEJXMlZAkAzAgCAgtlcG9jaExlbmd0aAkAzAgCCQCkAwEFAWkFA25pbAUBYQABagkAuQkCCQDMCAICAiVzCQDMCAICDGN1cnJlbnRFcG9jaAUDbmlsBQFhAAFrCQC5CQIJAMwIAgICJXMJAMwIAgIIbWF4RGVwdGgFA25pbAUBYQABbAkAuQkCCQDMCAICAiVzCQDMCAICH3ZvdGluZ0VtaXNzaW9uQ2FuZGlkYXRlQ29udHJhY3QFA25pbAUBYQABbQkAuQkCCQDMCAICAiVzCQDMCAICGnZvdGluZ0VtaXNzaW9uUmF0ZUNvbnRyYWN0BQNuaWwFAWEAAW4JALkJAgkAzAgCAgIlcwkAzAgCAg9mYWN0b3J5Q29udHJhY3QFA25pbAUBYQABbwkAuQkCCQDMCAICAiVzCQDMCAICEGJvb3N0aW5nQ29udHJhY3QFA25pbAUBYQABcAkAuQkCCQDMCAICAiVzCQDMCAICD3N0YWtpbmdDb250cmFjdAUDbmlsBQFhAAFxCQC5CQIJAMwIAgICJXMJAMwIAgIRZmluYWxpemF0aW9uU3RhZ2UFA25pbAUBYQABcgkAuQkCCQDMCAICAiVzCQDMCAICCG5leHRQb29sBQNuaWwFAWEAAXMJALkJAgkAzAgCAgIlcwkAzAgCAghuZXh0VXNlcgUDbmlsBQFhAAF0CQC5CQIJAMwIAgICJXMJAMwIAgILc3RhcnRIZWlnaHQFA25pbAUBYQABdQkAuQkCCQDMCAICAiVzCQDMCAICDmN1cnJlbnRFcG9jaFVpBQNuaWwFAWEAAXYJALkJAgkAzAgCAgIlcwkAzAgCAg1zdGFydEhlaWdodFVpBQNuaWwFAWEAAXcJALkJAgkAzAgCAgIlcwkAzAgCAgVmb3JjZQUDbmlsBQFhAQF4AQFpCQC5CQIJAMwIAgIEJXMlZAkAzAgCAgtzdGFydEhlaWdodAkAzAgCCQCkAwEFAWkFA25pbAUBYQEBeQEBaQkAuQkCCQDMCAICBCVzJWQJAMwIAgIJZmluYWxpemVkCQDMCAIJAKQDAQUBaQUDbmlsBQFhAQF6AQFBBAFCBQFBBAFDCAUBQgJfMQQBRAgFAUICXzIJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIGaW5MaXN0CQDMCAIFAUMJAMwIAgUBRAUDbmlsBQFhAQFFAgFGAWkJALkJAgkAzAgCAgYlcyVzJWQJAMwIAgIEdXNlZAkAzAgCCQClCAEFAUYJAMwIAgkApAMBBQFpBQNuaWwFAWEBAUcDAUEBRgFpBAFIBQFBBAFDCAUBSAJfMQQBRAgFAUgCXzIJALkJAgkAzAgCAgolcyVzJXMlcyVkCQDMCAICBHZvdGUJAMwIAgUBQwkAzAgCBQFECQDMCAIJAKUIAQUBRgkAzAgCCQCkAwEFAWkFA25pbAUBYQEBSQIBQQFpBAFKBQFBBAFDCAUBSgJfMQQBRAgFAUoCXzIJALkJAgkAzAgCAgglcyVzJXMlZAkAzAgCAgx2b3RpbmdSZXN1bHQJAMwIAgUBQwkAzAgCBQFECQDMCAIJAKQDAQUBaQUDbmlsBQFhAQFLAgFMAWkJALkJAgkAzAgCAgYlcyVzJWQJAMwIAgISdm90aW5nUmVzdWx0U3Rha2VkCQDMCAIFAUwJAMwIAgkApAMBBQFpBQNuaWwFAWEBAU0CAUEBaQQBTgUBQQQBQwgFAU4CXzEEAUQIBQFOAl8yCQC5CQIJAMwIAgIIJXMlcyVzJWQJAMwIAgIJcG9vbFNoYXJlCQDMCAIFAUMJAMwIAgUBRAkAzAgCCQCkAwEFAWkFA25pbAUBYQEBTwEBaQkAuQkCCQDMCAICBCVzJWQJAMwIAgIKdG90YWxWb3RlcwkAzAgCCQCkAwEFAWkFA25pbAUBYQEBUAIBTAFRCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICBnN0YWtlZAkAzAgCBQFRCQDMCAIFAUwFA25pbAUBYQEBUgEBUwkAuQkCCQDMCAICFXZvdGluZ19lbWlzc2lvbi5yaWRlOgkAzAgCBQFTBQNuaWwCASABAVQBAVMJAAIBCQEBUgEFAVMBAVUDAUYBVgFXBAFYCQEBUgEJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUBRgkAzAgCAgEuCQDMCAIFAVYJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCBAFZBQFXAwkAAQIFAVkCBlN0cmluZwQBWgUBWQkAnQgCBQFGBQFWAwkAAQIFAVkCA0ludAQCYWEFAVkJAJoIAgUBRgUBVgkBAVQBAhJpbnZhbGlkIGVudHJ5IHR5cGUFAVgBAmFiAgFGAVYKAAJhYwkBAVUDBQFGBQFWAgADCQABAgUCYWMCBlN0cmluZwUCYWMJAAIBCQCsAgIJAAMBBQJhYwIbIGNvdWxkbid0IGJlIGNhc3QgdG8gU3RyaW5nAQJhZAIBRgFWCgACYWMJAQFVAwUBRgUBVgAAAwkAAQIFAmFjAgNJbnQFAmFjCQACAQkArAICCQADAQUCYWMCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAECYWUBAUEJAKwCAgkArAICCAUBQQJfMQUBYQgFAUECXzIBAmFmAQFaBAJhZwkAtQkCBQFaBQFhAwkAAAIJAJADAQUCYWcAAgkAlAoCCQCRAwIFAmFnAAAJAJEDAgUCYWcAAQkBAVQBAhNpbnZhbGlkIHBvb2wgc3RyaW5nAAJhaAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFiAgUEdGhpcwUBbgACYWkACgECYWoAAhElc19fZmFjdG9yeUNvbmZpZwECYWsBAmFsCQC1CQIJAQJhYgIFAmFsCQECYWoABQFhAQJhbQECYW4JARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYW4FAmFpAQJhbwIBQwFECgECYXABAmFxCQCsAgICKCVzJXMlc19fbWFwcGluZ3NfX2Jhc2VBc3NldDJpbnRlcm5hbElkX18FAmFxCgECYXICAmFzAmF0CQCsAgIJAKwCAgkArAIC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ZWxldGVFbnRyeQEJAQJhSwIFAmFGBQJhSgUDbmlsAwkBAiE9AgUCYU8FBHVuaXQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFFAQUCYUYJAQV2YWx1ZQEFAmFPCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhSwIFAmFGBQJhSgkAzAgCCQELRGVsZXRlRW50cnkBCQECYUkCBQJhRgkBBXZhbHVlAQUCYU8FA25pbAMJAQIhPQIFAmFOBQR1bml0CQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhSQIFAmFGBQJhSgkAzAgCCQELRGVsZXRlRW50cnkBCQECYUsCBQJhRgkBBXZhbHVlAQUCYU4FA25pbAMJAAACBQJhSgkBC3ZhbHVlT3JFbHNlAgUCYU0CAAkAzAgCCQELRGVsZXRlRW50cnkBCQECYUUBBQJhRgUDbmlsCQEBVAEJAKwCAgkArAICCQCsAgICDmludmFsaWQgbm9kZTogBQJhRgIBLgUCYUoBAmFUAAIXJXNfX21hbmFnZXJWYXVsdEFkZHJlc3MBAmFVAAIUJXNfX21hbmFnZXJQdWJsaWNLZXkBAmFWAAQBWQkAoggBCQECYVQAAwkAAQIFAVkCBlN0cmluZwQCYVcFAVkJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmFXBQR0aGlzAQJhWAAEAmFZCQECYVYABAFZCQCdCAIFAmFZCQECYVUAAwkAAQIFAVkCBlN0cmluZwQCYVcFAVkJANkEAQUCYVcDCQABAgUBWQIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJhWgECYmEEAVkJAQJhWAADCQABAgUBWQIKQnl0ZVZlY3RvcgQCYmIFAVkJAAACCAUCYmEPY2FsbGVyUHVibGljS2V5BQJiYgMJAAECBQFZAgRVbml0CQAAAggFAmJhBmNhbGxlcgUEdGhpcwkAAgECC01hdGNoIGVycm9yAQJiYwECYmEDCQECYVoBBQJiYQYJAAIBAhFwZXJtaXNzaW9uIGRlbmllZAECYmQBAmJhAwkAAAIIBQJiYQZjYWxsZXIFBHRoaXMGCQACAQIRcGVybWlzc2lvbiBkZW5pZWQSAmJhARhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQCAmJlAmJmBAJiZwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAQJhYgIFBHRoaXMFAW8JAQFSAQIhaW52YWxpZCBib29zdGluZyBjb250cmFjdCBhZGRyZXNzCQCUCgIFA25pbAoAAmFjCQD8BwQFAmJnAiBnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHRSRUFET05MWQkAzAgCBQJiZQkAzAgCBQJiZgUDbmlsBQNuaWwDCQABAgUCYWMCA0ludAUCYWMJAAIBCQCsAgIJAAMBBQJhYwIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AmJhAQtjb25zdHJ1Y3RvcgUCYWgCYmgCYmkCYmoCYmsEAmJsCQDMCAIJAQJiYwEFAmJhCQDMCAIDCQECIT0CCQCmCAEFAmFoBQR1bml0BgIgaW52YWxpZCBmYWN0b3J5IGNvbnRyYWN0IGFkZHJlc3MJAMwIAgMJAQIhPQIJAKYIAQUCYmgFBHVuaXQGAjJpbnZhbGlkIHZvdGluZyBlbWlzc2lvbiBjYW5kaWRhdGUgY29udHJhY3QgYWRkcmVzcwkAzAgCAwkBAiE9AgkApggBBQJiaQUEdW5pdAYCIWludmFsaWQgYm9vc3RpbmcgY29udHJhY3QgYWRkcmVzcwkAzAgCAwkBAiE9AgkApggBBQJiagUEdW5pdAYCIGludmFsaWQgc3Rha2luZyBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQBmAgUCYmsAAAYJAQFUAQIUaW52YWxpZCBlcG9jaCBsZW5ndGgFA25pbAMJAAACBQJibAUCYmwJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQFuBQJhaAkAzAgCCQELU3RyaW5nRW50cnkCBQFsBQJiaAkAzAgCCQELU3RyaW5nRW50cnkCBQFvBQJiaQkAzAgCCQELU3RyaW5nRW50cnkCBQFwBQJiagkAzAgCCQEMSW50ZWdlckVudHJ5AgUBZgUCYmsFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiYQEGY3JlYXRlAgFDAUQEAmJsCQDMCAIDCQAAAgkA2AQBCAgFAmJhBmNhbGxlcgVieXRlcwkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQFsAgAGCQECYmMBBQJiYQUDbmlsAwkAAAIFAmJsBQJibAQBQQkAlAoCBQFDBQFEBAJibQkAzggCCQDMCAIJAQxCb29sZWFuRW50cnkCCQEBegEFAUEGBQNuaWwJAQJhUAIFAmFCCQECYWUBBQFBBAJibgkAAAIJAJoIAgUEdGhpcwUBagUEdW5pdAQCYm8DBQJibgQBaQAACQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFqBQFpCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBeAEFAWkFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdAUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF1BQFpCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF2BQZoZWlnaHQFA25pbAUDbmlsCQCUCgIJAM4IAgUCYm0FAmJvBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJhAQR2b3RlAwFDAUQCYnAEAUEJAJQKAgUBQwUBRAQBaQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFqAAAEAmJxCQECYWQCBQR0aGlzCQEBeAEFAWkEAmJrCQECYWQCBQR0aGlzBQFmBAJicgkAZAIFAmJxBQJiawQCYnMJAJoIAgUEdGhpcwUBcQQCYnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUUCCAUCYmEGY2FsbGVyBQFpAAAEAmJ1CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFHAwUBQQgFAmJhBmNhbGxlcgUBaQAABAJidgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBSQIFAUEFAWkAAAQCYncJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAU8BBQFpAAAEAmJ4CgACYWMJAPwHBAUEdGhpcwIYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0CQDMCAIJANgEAQgIBQJiYQZjYWxsZXIFYnl0ZXMJAMwIAgUCYnIFA25pbAUDbmlsAwkAAQIFAmFjAgNJbnQFAmFjCQACAQkArAICCQADAQUCYWMCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAQCYnkJAGUCBQJieAUCYnQEAmJ6CQBkAgUCYnUFAmJwBAJiQQkBAmF6AQUBQQQCYmwJAMwIAgMJAQIhPQIJAKAIAQkBAXoBBQFBBQR1bml0BgkBAVQBAg5pbnZhbGlkIGFzc2V0cwkAzAgCAwkAZgIFAmJyBQZoZWlnaHQGCQEBVAECDmludmFsaWQgaGVpZ2h0CQDMCAIDCQAAAgUCYnMFBHVuaXQGCQEBVAECGGZpbmFsaXphdGlvbiBpbiBwcm9ncmVzcwkAzAgCAwkAZgIFAmJ4AAAGCQEBVAECE3lvdSBkbyBub3QgaGF2ZSBnV1gJAMwIAgMDCQBmAgUCYnAAAAkAZwIFAmJ5BQJicAcGCQEBVAECDmludmFsaWQgYW1vdW50CQDMCAIDBQJiQQYJAQFUAQIdcG9vbCBoYXNuJ3QgV1hfRU1JU1NJT04gbGFiZWwFA25pbAMJAAACBQJibAUCYmwEAmJCCQECYUMBBQFBBAFRCQClCAEIBQJiYQZjYWxsZXIEAmJDAwkBAmFMAgUCYkIFAVEFA25pbAkBAmFQAgUCYkIFAVEJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBRQIIBQJiYQZjYWxsZXIFAWkJAGQCBQJidAUCYnAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFHAwUBQQgFAmJhBmNhbGxlcgUBaQUCYnoJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFJAgUBQQUBaQkAZAIFAmJ2BQJicAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAU8BBQFpCQBkAgUCYncFAmJwBQNuaWwFAmJDBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJhAQpjYW5jZWxWb3RlAgFDAUQEAUEJAJQKAgUBQwUBRAQBaQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFqAAAEAmJxCQECYWQCBQR0aGlzCQEBeAEFAWkEAmJrCQECYWQCBQR0aGlzBQFmBAJicgkAZAIFAmJxBQJiawQCYnMJAJoIAgUEdGhpcwUBcQQCYnQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUUCCAUCYmEGY2FsbGVyBQFpAAAEAmJ1CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFHAwUBQQgFAmJhBmNhbGxlcgUBaQAABAJidgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBSQIFAUEFAWkAAAQCYncJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAU8BBQFpAAAEAmJsCQDMCAIDCQECIT0CCQCgCAEJAQF6AQUBQQUEdW5pdAYJAQFUAQIOaW52YWxpZCBhc3NldHMJAMwIAgMJAGYCBQJicgUGaGVpZ2h0BgkBAVQBAg5pbnZhbGlkIGhlaWdodAkAzAgCAwkAAAIFAmJzBQR1bml0BgkBAVQBAhhmaW5hbGl6YXRpb24gaW4gcHJvZ3Jlc3MJAMwIAgMJAGYCBQJidQAABgkBAVQBAgdubyB2b3RlBQNuaWwDCQAAAgUCYmwFAmJsBAJiQgkBAmFDAQUBQQQBUQkApQgBCAUCYmEGY2FsbGVyCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUUCCAUCYmEGY2FsbGVyBQFpCQCWAwEJAMwIAgkAZQIFAmJ0BQJidQkAzAgCAAAFA25pbAkAzAgCCQELRGVsZXRlRW50cnkBCQEBRwMFAUEIBQJiYQZjYWxsZXIFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFJAgUBQQUBaQkAZQIFAmJ2BQJidQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAU8BBQFpCQBlAgUCYncFAmJ1BQNuaWwJAQJhUwIFAmJCBQFRBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJhAQ5zZXRFcG9jaExlbmd0aAECYkQEAmJsCQDMCAIJAQJiYwEFAmJhCQDMCAIDCQBmAgUCYkQAAAYJAQFUAQIUaW52YWxpZCBlcG9jaCBsZW5ndGgFA25pbAMJAAACBQJibAUCYmwJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBZwUCYkQFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiYQELc2V0TWF4RGVwdGgBAmJFBAJibAkAzAgCCQECYmMBBQJiYQkAzAgCAwkAZgIFAmJFAAAGCQEBVAECEWludmFsaWQgbWF4IGRlcHRoBQNuaWwDCQAAAgUCYmwFAmJsCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAWsFAmJFBQNuaWwFBHVuaXQJAAIB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BQFwBAJheQkBAmFvAgUBQwUBRAQCYkEJAQJhegEFAUEEAmJ3CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFPAQUCYlYAAAQCYk8JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUkCBQFBBQJiVgAABAJiWQMDCQAAAgUCYncAAAYJAQEhAQUCYkEAAAkAawMFAmJPBQFiBQJidwQCYloJAPwHBAUCYWgCDG1vZGlmeVdlaWdodAkAzAgCBQJheQkAzAgCBQJiWQUDbmlsBQNuaWwDCQAAAgUCYloFAmJaBAJjYQMDBQJiQQYFAmJVBQNuaWwJAM4IAgkAzAgCCQELRGVsZXRlRW50cnkBCQEBegEFAUEFA25pbAkBAmFTAgUCYUIFAmJGCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAU0CBQFBBQJiVgUCYlkFA25pbAUCY2EHCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJhAQ5maW5hbGl6ZUhlbHBlcgAEAmJVCQELdmFsdWVPckVsc2UCCQCgCAEFAXcHBAFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWoAAAQCY2IJAGUCBQFpAAEEAmJxCQECYWQCBQR0aGlzCQEBeAEFAWkEAmJrCQECYWQCBQR0aGlzBQFmBAJicgkAZAIFAmJxBQJiawQCYnMJAJoIAgUEdGhpcwUBcQMDAwkAZwIFBmhlaWdodAUCYnIJAAACBQJicwUEdW5pdAcJAQEhAQUCYlUHBAJjYwkAZAIFAWkAAQQCY2QJAJoIAgUEdGhpcwUBZwQCY2UEAVkFAmNkAwkAAQIFAVkCA0ludAQCYkQFAVkJAMwIAgkBDEludGVnZXJFbnRyeQIFAWYFAmJECQDMCAIJAQtEZWxldGVFbnRyeQEFAWcFA25pbAMJAAECBQFZAgRVbml0BQNuaWwJAAIBAgtNYXRjaCBlcnJvcgkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQF4AQUCY2MFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdAUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFqBQJjYwkAzAgCCQEMSW50ZWdlckVudHJ5AgUBcQUBZAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAWgBBQFpBQJiawUDbmlsBQJjZQYDAwUCYlUJAAACBQJicwUEdW5pdAcJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBcQUBZQUDbmlsBgMJAAACBQJicwUEdW5pdAkAlAoCBQNuaWwHAwkAAAIFAmJzBQFkBAJjZgkAoggBBQFyBAJjZwkAoggBBQFzBAFZBQJjZgMJAAECBQFZAgRVbml0BAJjaAkAoggBCQECYUUBBQJhQgMJAAECBQJjaAIEVW5pdAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFxBQFlCQDMCAIJAQtEZWxldGVFbnRyeQEFAXIJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcwUDbmlsBgMJAAECBQJjaAIGU3RyaW5nBAJjaQUCY2gJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQFyBQJjaQUDbmlsBgkAAgECC01hdGNoIGVycm9yAwkAAQIFAVkCBlN0cmluZwQCYkYFAVkEAUEJAQJhZgEFAmJGBAJjagQCY2gFAmNnAwkAAQIFAmNoAgRVbml0CQCiCAEJAQJhRQEJAQJhQwEFAUEDCQABAgUCY2gCBlN0cmluZwQCY2sFAmNoBAJjbAkAoggBCQECYUsCCQECYUMBBQFBBQJjawMJAAACBQJjbAUCY2wEAmNtCQD8BwQFBHRoaXMCE3Byb2Nlc3NWb3RlSU5URVJOQUwJAMwIAgUCYkYJAMwIAgUCY2sFA25pbAUDbmlsAwkAAAIFAmNtBQJjbQUCY2wJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAgtNYXRjaCBlcnJvcgQCY2gFAmNqAwkAAQIFAmNoAgRVbml0BAJjbgkAoggBCQECYUsCBQJhQgUCYkYEAmNvBQJjbgMJAAECBQJjbwIEVW5pdAkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFxBQFlCQDMCAIJAQtEZWxldGVFbnRyeQEFAXIJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcwUDbmlsBgMJAAECBQJjbwIGU3RyaW5nBAJhVwUCY28JAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQFyBQJhVwkAzAgCCQELRGVsZXRlRW50cnkBBQFzBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IDCQABAgUCY2gCBlN0cmluZwQCY3AFAmNoCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBcwUCY3AFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgkAAgECC01hdGNoIGVycm9yAwkAAAIFAmJzBQFlBAJjZgkAoggBBQFyBAFZBQJjZgMJAAECBQFZAgRVbml0BAJjaAkAoggBCQECYUUBBQJhQgMJAAECBQJjaAIEVW5pdAQCYlQDBQJiVQkAzAgCCQELRGVsZXRlRW50cnkBBQFxCQDMCAIJAQtEZWxldGVFbnRyeQEFAXcFA25pbAkAzAgCCQELRGVsZXRlRW50cnkBBQFxCQDMCAIJAQxCb29sZWFuRW50cnkCCQEBeQEFAmNiBgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdQUBaQkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdgUCYnEFA25pbAkAlAoCBQJiVAYDCQABAgUCY2gCBlN0cmluZwQCY3EFAmNoCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBcgUCY3EFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgMJAAECBQFZAgZTdHJpbmcEAmJGBQFZBAJjbgkAoggBCQECYUsCBQJhQgUCYkYDCQAAAgUCY24FAmNuBAJjcgoAAmFjCQD8BwQFBHRoaXMCE3Byb2Nlc3NQb29sSU5URVJOQUwJAMwIAgUCYkYJAMwIAgUCYlUFA25pbAUDbmlsAwkAAQIFAmFjAgdCb29sZWFuBQJhYwkAAgEJAKwCAgkAAwEFAmFjAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuAwkAAAIFAmNyBQJjcgMFAmNyCQCUCgIFA25pbAYEAmNoBQJjbgMJAAECBQJjaAIEVW5pdAQCYlQDBQJiVQkAzAgCCQELRGVsZXRlRW50cnkBBQFxCQDMCAIJAQtEZWxldGVFbnRyeQEFAXcJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcgUDbmlsCQDMCAIJAQtEZWxldGVFbnRyeQEFAXEJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAQF5AQUCY2IGCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF1BQFpCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF2BQJicQkAzAgCCQELRGVsZXRlRW50cnkBBQFyBQNuaWwJAJQKAgUCYlQGAwkAAQIFAmNoAgZTdHJpbmcEAmNxBQJjaAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXIFAmNxBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAgtNYXRjaCBlcnJvcgkBAVQBAhZmaW5hbGl6YXRpb24gaXMgYnJva2VuAmJhAQ9maW5hbGl6ZVdyYXBwZXIBAmNzBAJjdAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwUBbQQCY3UKAAJhYwkA/AcEBQR0aGlzAg5maW5hbGl6ZUhlbHBlcgUDbmlsBQNuaWwDCQABAgUCYWMCB0Jvb2xlYW4FAmFjCQACAQkArAICCQADAQUCYWMCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4DCQAAAgUCY3UFAmN1AwkBASEBBQJjdQMJAAACBQJjcwAACQEBVAECHkN1cnJlbnQgdm90aW5nIGlzIG5vdCBvdmVyIHlldAQCY3YJAPwHBAUCY3QCCGZpbmFsaXplBQNuaWwFA25pbAMJAAACBQJjdgUCY3YJAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAJjdwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFrBQFjAwkAZgIFAmN3BQJjcwQCY3YJAPwHBAUEdGhpcwIPZmluYWxpemVXcmFwcGVyCQDMCAIJAGQCBQJjcwABBQNuaWwFA25pbAMJAAACBQJjdgUCY3YJAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiYQEIZmluYWxpemUABAJjdgkA/AcEBQR0aGlzAg9maW5hbGl6ZVdyYXBwZXIJAMwIAgAABQNuaWwFA25pbAMJAAACBQJjdgUCY3YJAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJhARRjb250YWluc05vZGVSRUFET05MWQICYUYCYUoJAJQKAgUDbmlsCQECYUwCBQJhRgUCYUoCYmEBCmluc2VydE5vZGUCAmFGAmFKBAJiRwkBAmJjAQUCYmEDCQAAAgUCYkcFAmJHCQCUCgIJAQJhUAIFAmFGBQJhSgUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiYQEKZGVsZXRlTm9kZQICYUYCYUoEAmJHCQECYmMBBQJiYQMJAAACBQJiRwUCYkcJAJQKAgkBAmFTAgUCYUYFAmFKBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJhARhpc0ZpbmFsaXphdGlvbkluUHJvZ3Jlc3MABAJicwkAmggCBQR0aGlzBQFxBAJjeAkBAiE9AgUCYnMFBHVuaXQJAJQKAgUDbmlsBQJjeAJiYQEKZGVsZXRlUG9vbAIBQwFEBAJiRwMDCQAAAggFAmJhBmNhbGxlcgUCYWgGCQECYmMBBQJiYQYJAQFUAQIRUGVybWlzc2lvbiBkZW5pZWQDCQAAAgUCYkcFAmJHBAJhRgIFcG9vbHMEAUEJAJQKAgUBQwUBRAQCYUoJALkJAgkAzAgCBQFDCQDMCAIFAUQFA25pbAUBYQQCYlQDCQECYUwCBQJhRgUCYUoJAQJhUwIFAmFGBQJhSgUDbmlsCQDOCAIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAXoBBQFBBQNuaWwFAmJUCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJhARJnZXRMb2NrZWRHd3hBbW91bnQBAVEEAmJlCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQUBUQkBAVIBAhRpbnZhbGlkIHVzZXIgYWRkcmVzcwQBaQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFqAAAEAmN5BAFZCQCaCAIFBHRoaXMJAQFFAgUCYmUFAWkDCQABAgUBWQIEVW5pdAAAAwkAAQIFAVkCA0ludAQCY3oFAVkFAmN6CQACAQILTWF0Y2ggZXJyb3IJAJQKAgUDbmlsBQJjeQECY0EBAmNCAAQCY0MEAVkJAQJhWAADCQABAgUBWQIKQnl0ZVZlY3RvcgQCYmIFAVkFAmJiAwkAAQIFAVkCBFVuaXQIBQJjQQ9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgkA9AMDCAUCY0EJYm9keUJ5dGVzCQCRAwIIBQJjQQZwcm9vZnMAAAUCY0Ntk8qj", "height": 2744758, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: E1UXDS5fsEjMasUfBUjQ6KVFsnLR3ei2P2FNT2JjFuqh Next: FRCajPuTxvXbBg91L5VZtWSXicaY1zvBVYTGPAV18Nsz Diff:
OldNewDifferences
181181 }
182182
183183
184-func gwxRewardDeposit () = {
185- let factoryCfg = readFactoryCfgOrFail(factoryContract)
186- let gwxRewardsContract = getGwxRewardAddressOrFail(factoryCfg)
187- invoke(gwxRewardsContract, "deposit", nil, nil)
188- }
189-
190-
191184 let poolsListName = "pools"
192185
193186 func getVotesListName (pool) = {
194- let $t060226062 = pool
195- let amountAssetId = $t060226062._1
196- let priceAssetId = $t060226062._2
187+ let $t058195859 = pool
188+ let amountAssetId = $t058195859._1
189+ let priceAssetId = $t058195859._2
197190 makeString(["votes", amountAssetId, priceAssetId], separator)
198191 }
199192
504497 if ((checkTargetEpoch == checkTargetEpoch))
505498 then {
506499 let pool = stringToPool(poolStr)
507- let $t01806518105 = pool
508- let amountAssetId = $t01806518105._1
509- let priceAssetId = $t01806518105._2
500+ let $t01786217902 = pool
501+ let amountAssetId = $t01786217902._1
502+ let priceAssetId = $t01786217902._2
510503 let wxEmission = checkWxEmissionPoolLabel(pool)
511504 let gwxAmountAtEndTotal = {
512505 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)
565558 if ((checkTargetEpoch == checkTargetEpoch))
566559 then {
567560 let pool = stringToPool(poolStr)
568- let $t02046220502 = pool
569- let amountAssetId = $t02046220502._1
570- let priceAssetId = $t02046220502._2
561+ let $t02025920299 = pool
562+ let amountAssetId = $t02025920299._1
563+ let priceAssetId = $t02025920299._2
571564 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
572565 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
573- let r = {
574- let @ = invoke(stakingContract, "usersListTraversal", [lpAssetId], nil)
575- if ($isInstanceOf(@, "Boolean"))
576- then @
577- else throw(($getType(@) + " couldn't be cast to Boolean"))
578- }
579- if ((r == r))
580- then if (r)
581- then $Tuple2(nil, true)
582- else {
583- let wxEmission = checkWxEmissionPoolLabel(pool)
584- let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
585- let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
586- let share = if (if ((totalVotes == 0))
587- then true
588- else !(wxEmission))
589- then 0
590- else fraction(votingResult, poolWeightMult, totalVotes)
591- let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
592- if ((modifyWeightInv == modifyWeightInv))
593- then {
594- let poolsListActions = if (if (wxEmission)
595- then true
596- else force)
597- then nil
598- else ([DeleteEntry(keyInList(pool))] ++ deleteNodeActions(poolsListName, poolStr))
599- $Tuple2(([IntegerEntry(keyPoolShare(pool, targetEpoch), share)] ++ poolsListActions), false)
600- }
601- else throw("Strict value is not equal to itself.")
602- }
566+ let wxEmission = checkWxEmissionPoolLabel(pool)
567+ let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
568+ let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
569+ let share = if (if ((totalVotes == 0))
570+ then true
571+ else !(wxEmission))
572+ then 0
573+ else fraction(votingResult, poolWeightMult, totalVotes)
574+ let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
575+ if ((modifyWeightInv == modifyWeightInv))
576+ then {
577+ let poolsListActions = if (if (wxEmission)
578+ then true
579+ else force)
580+ then nil
581+ else ([DeleteEntry(keyInList(pool))] ++ deleteNodeActions(poolsListName, poolStr))
582+ $Tuple2(([IntegerEntry(keyPoolShare(pool, targetEpoch), share)] ++ poolsListActions), false)
583+ }
603584 else throw("Strict value is not equal to itself.")
604585 }
605586 else throw("Strict value is not equal to itself.")
704685 let actions = if (force)
705686 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced)]
706687 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight)]
707- let gwxRewardDepositInv = gwxRewardDeposit()
708- if ((gwxRewardDepositInv == gwxRewardDepositInv))
709- then $Tuple2(actions, true)
710- else throw("Strict value is not equal to itself.")
688+ $Tuple2(actions, true)
711689 case nextPoolStr: String =>
712690 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
713691 case _ =>
731709 let actions = if (force)
732710 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced), DeleteEntry(keyNextPool)]
733711 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight), DeleteEntry(keyNextPool)]
734- let gwxRewardDepositInv = gwxRewardDeposit()
735- if ((gwxRewardDepositInv == gwxRewardDepositInv))
736- then $Tuple2(actions, true)
737- else throw("Strict value is not equal to itself.")
712+ $Tuple2(actions, true)
738713 case nextPoolStr: String =>
739714 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
740715 case _ =>
852827 }
853828
854829
830+
831+@Callable(i)
832+func getLockedGwxAmount (userAddressStr) = {
833+ let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
834+ let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
835+ let gwxAmount = match getInteger(this, keyUsed(userAddress, epoch)) {
836+ case _: Unit =>
837+ 0
838+ case n: Int =>
839+ n
840+ case _ =>
841+ throw("Match error")
842+ }
843+ $Tuple2(nil, gwxAmount)
844+ }
845+
846+
855847 @Verifier(tx)
856848 func verify () = {
857849 let targetPublicKey = match managerPublicKeyOrUnit() {
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let separator = "__"
55
66 let poolWeightMult = 100000000
77
88 let maxDepthDefault = 10
99
1010 let finalizationStageTotal = 0
1111
1212 let finalizationStageShares = 1
1313
1414 let keyEpochLength = makeString(["%s", "epochLength"], separator)
1515
1616 let keyEpochLengthNew = makeString(["%s%s", "epochLength__new"], separator)
1717
1818 func keyEpochLengthByEpoch (epoch) = makeString(["%s%d", "epochLength", toString(epoch)], separator)
1919
2020
2121 let keyCurrentEpoch = makeString(["%s", "currentEpoch"], separator)
2222
2323 let keyMaxDepth = makeString(["%s", "maxDepth"], separator)
2424
2525 let keyVotingEmissionCandidateContract = makeString(["%s", "votingEmissionCandidateContract"], separator)
2626
2727 let keyVotingEmissionRateContract = makeString(["%s", "votingEmissionRateContract"], separator)
2828
2929 let keyFactoryContract = makeString(["%s", "factoryContract"], separator)
3030
3131 let keyBoostingContract = makeString(["%s", "boostingContract"], separator)
3232
3333 let keyStakingContract = makeString(["%s", "stakingContract"], separator)
3434
3535 let keyFinalizationStage = makeString(["%s", "finalizationStage"], separator)
3636
3737 let keyNextPool = makeString(["%s", "nextPool"], separator)
3838
3939 let keyNextUser = makeString(["%s", "nextUser"], separator)
4040
4141 let keyStartHeight = makeString(["%s", "startHeight"], separator)
4242
4343 let keyCurrentEpochUi = makeString(["%s", "currentEpochUi"], separator)
4444
4545 let keyStartHeightUi = makeString(["%s", "startHeightUi"], separator)
4646
4747 let keyFinalizationShouldBeForced = makeString(["%s", "force"], separator)
4848
4949 func keyStartHeightByEpoch (epoch) = makeString(["%s%d", "startHeight", toString(epoch)], separator)
5050
5151
5252 func keyFinalized (epoch) = makeString(["%s%d", "finalized", toString(epoch)], separator)
5353
5454
5555 func keyInList (pool) = {
5656 let $t017881828 = pool
5757 let amountAssetId = $t017881828._1
5858 let priceAssetId = $t017881828._2
5959 makeString(["%s%s%s", "inList", amountAssetId, priceAssetId], separator)
6060 }
6161
6262
6363 func keyUsed (address,epoch) = makeString(["%s%s%d", "used", toString(address), toString(epoch)], separator)
6464
6565
6666 func keyVote (pool,address,epoch) = {
6767 let $t021022142 = pool
6868 let amountAssetId = $t021022142._1
6969 let priceAssetId = $t021022142._2
7070 makeString(["%s%s%s%s%d", "vote", amountAssetId, priceAssetId, toString(address), toString(epoch)], separator)
7171 }
7272
7373
7474 func keyVotingResult (pool,epoch) = {
7575 let $t023242364 = pool
7676 let amountAssetId = $t023242364._1
7777 let priceAssetId = $t023242364._2
7878 makeString(["%s%s%s%d", "votingResult", amountAssetId, priceAssetId, toString(epoch)], separator)
7979 }
8080
8181
8282 func keyVotingResultStaked (lpAssetIdStr,epoch) = makeString(["%s%s%d", "votingResultStaked", lpAssetIdStr, toString(epoch)], separator)
8383
8484
8585 func keyPoolShare (pool,epoch) = {
8686 let $t026852725 = pool
8787 let amountAssetId = $t026852725._1
8888 let priceAssetId = $t026852725._2
8989 makeString(["%s%s%s%d", "poolShare", amountAssetId, priceAssetId, toString(epoch)], separator)
9090 }
9191
9292
9393 func keyTotalVotes (epoch) = makeString(["%s%d", "totalVotes", toString(epoch)], separator)
9494
9595
9696 func keyStakedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s", "staked", userAddressStr, lpAssetIdStr], separator)
9797
9898
9999 func wrapErr (msg) = makeString(["voting_emission.ride:", msg], " ")
100100
101101
102102 func throwErr (msg) = throw(wrapErr(msg))
103103
104104
105105 func getValueOrFail (address,key,type) = {
106106 let error = wrapErr(makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
107107 valueOrErrorMessage( match type {
108108 case str: String =>
109109 getString(address, key)
110110 case int: Int =>
111111 getInteger(address, key)
112112 case _ =>
113113 throwErr("invalid entry type")
114114 }, error)
115115 }
116116
117117
118118 func getStrOrFail (address,key) = {
119119 let @ = getValueOrFail(address, key, "")
120120 if ($isInstanceOf(@, "String"))
121121 then @
122122 else throw(($getType(@) + " couldn't be cast to String"))
123123 }
124124
125125
126126 func getIntOrFail (address,key) = {
127127 let @ = getValueOrFail(address, key, 0)
128128 if ($isInstanceOf(@, "Int"))
129129 then @
130130 else throw(($getType(@) + " couldn't be cast to Int"))
131131 }
132132
133133
134134 func poolToString (pool) = ((pool._1 + separator) + pool._2)
135135
136136
137137 func stringToPool (str) = {
138138 let parts = split(str, separator)
139139 if ((size(parts) == 2))
140140 then $Tuple2(parts[0], parts[1])
141141 else throwErr("invalid pool string")
142142 }
143143
144144
145145 let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
146146
147147 let IdxFactoryCfgGwxRewardDapp = 10
148148
149149 func keyFactoryCfg () = "%s__factoryConfig"
150150
151151
152152 func readFactoryCfgOrFail (factory) = split(getStrOrFail(factory, keyFactoryCfg()), separator)
153153
154154
155155 func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp])
156156
157157
158158 func getLpAssetByPoolAssets (amountAssetId,priceAssetId) = {
159159 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
160160
161161 func keyMappingPoolAssetsToPoolContractAddress (internalAmountAssetIdStr,internalPriceAssetIdStr) = (((("%d%d%s%s__" + toString(internalAmountAssetIdStr)) + "__") + toString(internalPriceAssetIdStr)) + "__mappings__poolAssets2PoolContract")
162162
163163 func keyMappingPoolContractToLPAsset (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
164164
165165 let amountAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amountAssetId))
166166 let priceAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAssetId))
167167 let poolContractAddress = getStrOrFail(factoryContract, keyMappingPoolAssetsToPoolContractAddress(amountAssetInternalId, priceAssetInternalId))
168168 let lpAssetId = getStrOrFail(factoryContract, keyMappingPoolContractToLPAsset(poolContractAddress))
169169 lpAssetId
170170 }
171171
172172
173173 func checkWxEmissionPoolLabel (pool) = {
174174 let $t055655605 = pool
175175 let amountAssetId = $t055655605._1
176176 let priceAssetId = $t055655605._2
177177 let @ = invoke(factoryContract, "checkWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil)
178178 if ($isInstanceOf(@, "Boolean"))
179179 then @
180180 else throw(($getType(@) + " couldn't be cast to Boolean"))
181181 }
182182
183183
184-func gwxRewardDeposit () = {
185- let factoryCfg = readFactoryCfgOrFail(factoryContract)
186- let gwxRewardsContract = getGwxRewardAddressOrFail(factoryCfg)
187- invoke(gwxRewardsContract, "deposit", nil, nil)
188- }
189-
190-
191184 let poolsListName = "pools"
192185
193186 func getVotesListName (pool) = {
194- let $t060226062 = pool
195- let amountAssetId = $t060226062._1
196- let priceAssetId = $t060226062._2
187+ let $t058195859 = pool
188+ let amountAssetId = $t058195859._1
189+ let priceAssetId = $t058195859._2
197190 makeString(["votes", amountAssetId, priceAssetId], separator)
198191 }
199192
200193
201194 func keyListHead (listName) = {
202195 let meta = if ((listName == poolsListName))
203196 then "%s%s"
204197 else "%s%s%s%s"
205198 makeString([meta, listName, "head"], separator)
206199 }
207200
208201
209202 func keyListSize (listName) = {
210203 let meta = if ((listName == poolsListName))
211204 then "%s%s"
212205 else "%s%s%s%s"
213206 makeString([meta, listName, "size"], separator)
214207 }
215208
216209
217210 func keyListPrev (listName,id) = {
218211 let meta = if ((listName == poolsListName))
219212 then "%s%s%s%s"
220213 else "%s%s%s%s%s"
221214 makeString([meta, listName, id, "prev"], separator)
222215 }
223216
224217
225218 func keyListNext (listName,id) = {
226219 let meta = if ((listName == poolsListName))
227220 then "%s%s%s%s"
228221 else "%s%s%s%s%s"
229222 makeString([meta, listName, id, "next"], separator)
230223 }
231224
232225
233226 func containsNode (listName,id) = {
234227 let headOrUnit = getString(this, keyListHead(listName))
235228 let prevOrUnit = getString(this, keyListPrev(listName, id))
236229 let nextOrUnit = getString(this, keyListNext(listName, id))
237230 if (if ((id == valueOrElse(headOrUnit, "")))
238231 then true
239232 else (prevOrUnit != unit))
240233 then true
241234 else (nextOrUnit != unit)
242235 }
243236
244237
245238 func insertNodeActions (listName,id) = {
246239 let headOrUnit = getString(this, keyListHead(listName))
247240 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
248241 let checkNode = if (!(containsNode(listName, id)))
249242 then true
250243 else throwErr("Node exists")
251244 if ((checkNode == checkNode))
252245 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
253246 then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
254247 else nil)) ++ [StringEntry(keyListHead(listName), id)])
255248 else throw("Strict value is not equal to itself.")
256249 }
257250
258251
259252 func deleteNodeActions (listName,id) = {
260253 let headOrUnit = getString(this, keyListHead(listName))
261254 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
262255 let prevOrUnit = getString(this, keyListPrev(listName, id))
263256 let nextOrUnit = getString(this, keyListNext(listName, id))
264257 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
265258 then (nextOrUnit != unit)
266259 else false)
267260 then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
268261 else if ((nextOrUnit != unit))
269262 then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
270263 else if ((prevOrUnit != unit))
271264 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
272265 else if ((id == valueOrElse(headOrUnit, "")))
273266 then [DeleteEntry(keyListHead(listName))]
274267 else throwErr(((("invalid node: " + listName) + ".") + id))))
275268 }
276269
277270
278271 func keyManagerVaultAddress () = "%s__managerVaultAddress"
279272
280273
281274 func keyManagerPublicKey () = "%s__managerPublicKey"
282275
283276
284277 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
285278 case s: String =>
286279 addressFromStringValue(s)
287280 case _ =>
288281 this
289282 }
290283
291284
292285 func managerPublicKeyOrUnit () = {
293286 let managerVaultAddress = getManagerVaultAddressOrThis()
294287 match getString(managerVaultAddress, keyManagerPublicKey()) {
295288 case s: String =>
296289 fromBase58String(s)
297290 case _: Unit =>
298291 unit
299292 case _ =>
300293 throw("Match error")
301294 }
302295 }
303296
304297
305298 func isManager (i) = match managerPublicKeyOrUnit() {
306299 case pk: ByteVector =>
307300 (i.callerPublicKey == pk)
308301 case _: Unit =>
309302 (i.caller == this)
310303 case _ =>
311304 throw("Match error")
312305 }
313306
314307
315308 func mustManager (i) = if (isManager(i))
316309 then true
317310 else throw("permission denied")
318311
319312
320313 func mustThis (i) = if ((i.caller == this))
321314 then true
322315 else throw("permission denied")
323316
324317
325318 @Callable(i)
326319 func getUserGwxAmountAtHeight (userAddress,targetHeight) = {
327320 let boostingContractAddress = valueOrErrorMessage(addressFromString(getStrOrFail(this, keyBoostingContract)), wrapErr("invalid boosting contract address"))
328321 $Tuple2(nil, {
329322 let @ = invoke(boostingContractAddress, "getUserGwxAmountAtHeightREADONLY", [userAddress, targetHeight], nil)
330323 if ($isInstanceOf(@, "Int"))
331324 then @
332325 else throw(($getType(@) + " couldn't be cast to Int"))
333326 })
334327 }
335328
336329
337330
338331 @Callable(i)
339332 func constructor (factoryContract,votingEmissionCandidateContract,boostingContract,stakingContract,epochLength) = {
340333 let checks = [mustManager(i), if ((addressFromString(factoryContract) != unit))
341334 then true
342335 else "invalid factory contract address", if ((addressFromString(votingEmissionCandidateContract) != unit))
343336 then true
344337 else "invalid voting emission candidate contract address", if ((addressFromString(boostingContract) != unit))
345338 then true
346339 else "invalid boosting contract address", if ((addressFromString(stakingContract) != unit))
347340 then true
348341 else "invalid staking contract address", if ((epochLength > 0))
349342 then true
350343 else throwErr("invalid epoch length")]
351344 if ((checks == checks))
352345 then $Tuple2([StringEntry(keyFactoryContract, factoryContract), StringEntry(keyVotingEmissionCandidateContract, votingEmissionCandidateContract), StringEntry(keyBoostingContract, boostingContract), StringEntry(keyStakingContract, stakingContract), IntegerEntry(keyEpochLength, epochLength)], unit)
353346 else throw("Strict value is not equal to itself.")
354347 }
355348
356349
357350
358351 @Callable(i)
359352 func create (amountAssetId,priceAssetId) = {
360353 let checks = [if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionCandidateContract), "")))
361354 then true
362355 else mustManager(i)]
363356 if ((checks == checks))
364357 then {
365358 let pool = $Tuple2(amountAssetId, priceAssetId)
366359 let inListActions = ([BooleanEntry(keyInList(pool), true)] ++ insertNodeActions(poolsListName, poolToString(pool)))
367360 let currentEpochIsNotDefined = (getInteger(this, keyCurrentEpoch) == unit)
368361 let startHeightActions = if (currentEpochIsNotDefined)
369362 then {
370363 let epoch = 0
371364 [IntegerEntry(keyCurrentEpoch, epoch), IntegerEntry(keyStartHeightByEpoch(epoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, height)]
372365 }
373366 else nil
374367 $Tuple2((inListActions ++ startHeightActions), unit)
375368 }
376369 else throw("Strict value is not equal to itself.")
377370 }
378371
379372
380373
381374 @Callable(i)
382375 func vote (amountAssetId,priceAssetId,amount) = {
383376 let pool = $Tuple2(amountAssetId, priceAssetId)
384377 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
385378 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
386379 let epochLength = getIntOrFail(this, keyEpochLength)
387380 let endHeight = (startHeight + epochLength)
388381 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
389382 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
390383 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
391384 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
392385 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
393386 let gwxAmountAtEndTotal = {
394387 let @ = invoke(this, "getUserGwxAmountAtHeight", [toBase58String(i.caller.bytes), endHeight], nil)
395388 if ($isInstanceOf(@, "Int"))
396389 then @
397390 else throw(($getType(@) + " couldn't be cast to Int"))
398391 }
399392 let available = (gwxAmountAtEndTotal - used)
400393 let newVote = (vote + amount)
401394 let wxEmission = checkWxEmissionPoolLabel(pool)
402395 let checks = [if ((getBoolean(keyInList(pool)) != unit))
403396 then true
404397 else throwErr("invalid assets"), if ((endHeight > height))
405398 then true
406399 else throwErr("invalid height"), if ((finalizationStageOrUnit == unit))
407400 then true
408401 else throwErr("finalization in progress"), if ((gwxAmountAtEndTotal > 0))
409402 then true
410403 else throwErr("you do not have gWX"), if (if ((amount > 0))
411404 then (available >= amount)
412405 else false)
413406 then true
414407 else throwErr("invalid amount"), if (wxEmission)
415408 then true
416409 else throwErr("pool hasn't WX_EMISSION label")]
417410 if ((checks == checks))
418411 then {
419412 let votesListName = getVotesListName(pool)
420413 let userAddressStr = toString(i.caller)
421414 let votesListActions = if (containsNode(votesListName, userAddressStr))
422415 then nil
423416 else insertNodeActions(votesListName, userAddressStr)
424417 $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)
425418 }
426419 else throw("Strict value is not equal to itself.")
427420 }
428421
429422
430423
431424 @Callable(i)
432425 func cancelVote (amountAssetId,priceAssetId) = {
433426 let pool = $Tuple2(amountAssetId, priceAssetId)
434427 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
435428 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
436429 let epochLength = getIntOrFail(this, keyEpochLength)
437430 let endHeight = (startHeight + epochLength)
438431 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
439432 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
440433 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
441434 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
442435 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
443436 let checks = [if ((getBoolean(keyInList(pool)) != unit))
444437 then true
445438 else throwErr("invalid assets"), if ((endHeight > height))
446439 then true
447440 else throwErr("invalid height"), if ((finalizationStageOrUnit == unit))
448441 then true
449442 else throwErr("finalization in progress"), if ((vote > 0))
450443 then true
451444 else throwErr("no vote")]
452445 if ((checks == checks))
453446 then {
454447 let votesListName = getVotesListName(pool)
455448 let userAddressStr = toString(i.caller)
456449 $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)
457450 }
458451 else throw("Strict value is not equal to itself.")
459452 }
460453
461454
462455
463456 @Callable(i)
464457 func setEpochLength (newEpochLength) = {
465458 let checks = [mustManager(i), if ((newEpochLength > 0))
466459 then true
467460 else throwErr("invalid epoch length")]
468461 if ((checks == checks))
469462 then $Tuple2([IntegerEntry(keyEpochLengthNew, newEpochLength)], unit)
470463 else throw("Strict value is not equal to itself.")
471464 }
472465
473466
474467
475468 @Callable(i)
476469 func setMaxDepth (newMaxDepth) = {
477470 let checks = [mustManager(i), if ((newMaxDepth > 0))
478471 then true
479472 else throwErr("invalid max depth")]
480473 if ((checks == checks))
481474 then $Tuple2([IntegerEntry(keyMaxDepth, newMaxDepth)], unit)
482475 else throw("Strict value is not equal to itself.")
483476 }
484477
485478
486479
487480 @Callable(i)
488481 func processVoteINTERNAL (poolStr,userAddressStr) = {
489482 let checkCaller = mustThis(i)
490483 if ((checkCaller == checkCaller))
491484 then {
492485 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr(("processVoteINTERNAL: invalid user address " + userAddressStr)))
493486 let epoch = getIntOrFail(this, keyCurrentEpoch)
494487 let epochPrevious = (epoch - 1)
495488 let epochLength = getIntOrFail(this, keyEpochLength)
496489 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
497490 let endHeight = (startHeight + epochLength)
498491 let startHeightPrevious = getIntOrFail(this, keyStartHeightByEpoch(epochPrevious))
499492 let epochLengthPrevious = getIntOrFail(this, keyEpochLengthByEpoch(epochPrevious))
500493 let endHeightPrevious = (startHeightPrevious + epochLengthPrevious)
501494 let checkTargetEpoch = if ((epochPrevious >= 0))
502495 then true
503496 else throwErr("processVoteINTERNAL: invalid previous epoch")
504497 if ((checkTargetEpoch == checkTargetEpoch))
505498 then {
506499 let pool = stringToPool(poolStr)
507- let $t01806518105 = pool
508- let amountAssetId = $t01806518105._1
509- let priceAssetId = $t01806518105._2
500+ let $t01786217902 = pool
501+ let amountAssetId = $t01786217902._1
502+ let priceAssetId = $t01786217902._2
510503 let wxEmission = checkWxEmissionPoolLabel(pool)
511504 let gwxAmountAtEndTotal = {
512505 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)
513506 if ($isInstanceOf(@, "Int"))
514507 then @
515508 else throw(($getType(@) + " couldn't be cast to Int"))
516509 }
517510 let gwxAmountAtEndTotalPrevious = {
518511 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeightPrevious], nil)
519512 if ($isInstanceOf(@, "Int"))
520513 then @
521514 else throw(($getType(@) + " couldn't be cast to Int"))
522515 }
523516 let totalVotes = valueOrElse(getInteger(keyTotalVotes(epoch)), 0)
524517 let votingResult = valueOrElse(getInteger(keyVotingResult(pool, epoch)), 0)
525518 let votePrevious = valueOrErrorMessage(getInteger(keyVote(pool, userAddress, epochPrevious)), wrapErr((((("processVoteINTERNAL " + poolStr) + " ") + userAddressStr) + ": no previous vote")))
526519 let used = valueOrElse(getInteger(this, keyUsed(userAddress, epoch)), 0)
527520 let lpAssetIdStr = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
528521 let votingResultStakedPrevious = valueOrElse(getInteger(keyVotingResultStaked(lpAssetIdStr, epochPrevious)), 0)
529522 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
530523 let stakedByUser = valueOrElse(getInteger(stakingContract, keyStakedByUser(lpAssetIdStr, userAddressStr)), 0)
531524 let votingResultStakedActions = if ((stakedByUser == 0))
532525 then nil
533526 else [IntegerEntry(keyVotingResultStaked(lpAssetIdStr, epochPrevious), (votingResultStakedPrevious + votePrevious))]
534527 let newVote = if ((gwxAmountAtEndTotalPrevious > 0))
535528 then fraction(votePrevious, gwxAmountAtEndTotal, gwxAmountAtEndTotalPrevious)
536529 else 0
537530 let actions = if (if ((newVote > 0))
538531 then wxEmission
539532 else false)
540533 then [IntegerEntry(keyVote(pool, userAddress, epoch), newVote), IntegerEntry(keyTotalVotes(epoch), (totalVotes + newVote)), IntegerEntry(keyVotingResult(pool, epoch), (votingResult + newVote)), IntegerEntry(keyUsed(userAddress, epoch), (used + newVote))]
541534 else deleteNodeActions(getVotesListName(pool), userAddressStr)
542535 $Tuple2((actions ++ votingResultStakedActions), unit)
543536 }
544537 else throw("Strict value is not equal to itself.")
545538 }
546539 else throw("Strict value is not equal to itself.")
547540 }
548541
549542
550543
551544 @Callable(i)
552545 func processPoolINTERNAL (poolStr,force) = {
553546 let checkCaller = mustThis(i)
554547 if ((checkCaller == checkCaller))
555548 then {
556549 let targetEpoch = {
557550 let currentEpoch = getIntOrFail(this, keyCurrentEpoch)
558551 if (force)
559552 then currentEpoch
560553 else (currentEpoch - 1)
561554 }
562555 let checkTargetEpoch = if ((targetEpoch >= 0))
563556 then true
564557 else throwErr("processPoolINTERNAL: invalid target epoch")
565558 if ((checkTargetEpoch == checkTargetEpoch))
566559 then {
567560 let pool = stringToPool(poolStr)
568- let $t02046220502 = pool
569- let amountAssetId = $t02046220502._1
570- let priceAssetId = $t02046220502._2
561+ let $t02025920299 = pool
562+ let amountAssetId = $t02025920299._1
563+ let priceAssetId = $t02025920299._2
571564 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
572565 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
573- let r = {
574- let @ = invoke(stakingContract, "usersListTraversal", [lpAssetId], nil)
575- if ($isInstanceOf(@, "Boolean"))
576- then @
577- else throw(($getType(@) + " couldn't be cast to Boolean"))
578- }
579- if ((r == r))
580- then if (r)
581- then $Tuple2(nil, true)
582- else {
583- let wxEmission = checkWxEmissionPoolLabel(pool)
584- let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
585- let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
586- let share = if (if ((totalVotes == 0))
587- then true
588- else !(wxEmission))
589- then 0
590- else fraction(votingResult, poolWeightMult, totalVotes)
591- let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
592- if ((modifyWeightInv == modifyWeightInv))
593- then {
594- let poolsListActions = if (if (wxEmission)
595- then true
596- else force)
597- then nil
598- else ([DeleteEntry(keyInList(pool))] ++ deleteNodeActions(poolsListName, poolStr))
599- $Tuple2(([IntegerEntry(keyPoolShare(pool, targetEpoch), share)] ++ poolsListActions), false)
600- }
601- else throw("Strict value is not equal to itself.")
602- }
566+ let wxEmission = checkWxEmissionPoolLabel(pool)
567+ let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
568+ let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
569+ let share = if (if ((totalVotes == 0))
570+ then true
571+ else !(wxEmission))
572+ then 0
573+ else fraction(votingResult, poolWeightMult, totalVotes)
574+ let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
575+ if ((modifyWeightInv == modifyWeightInv))
576+ then {
577+ let poolsListActions = if (if (wxEmission)
578+ then true
579+ else force)
580+ then nil
581+ else ([DeleteEntry(keyInList(pool))] ++ deleteNodeActions(poolsListName, poolStr))
582+ $Tuple2(([IntegerEntry(keyPoolShare(pool, targetEpoch), share)] ++ poolsListActions), false)
583+ }
603584 else throw("Strict value is not equal to itself.")
604585 }
605586 else throw("Strict value is not equal to itself.")
606587 }
607588 else throw("Strict value is not equal to itself.")
608589 }
609590
610591
611592
612593 @Callable(i)
613594 func finalizeHelper () = {
614595 let force = valueOrElse(getBoolean(keyFinalizationShouldBeForced), false)
615596 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
616597 let previousEpoch = (epoch - 1)
617598 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
618599 let epochLength = getIntOrFail(this, keyEpochLength)
619600 let endHeight = (startHeight + epochLength)
620601 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
621602 if (if (if ((height >= endHeight))
622603 then (finalizationStageOrUnit == unit)
623604 else false)
624605 then !(force)
625606 else false)
626607 then {
627608 let newEpoch = (epoch + 1)
628609 let newEpochLengthOption = getInteger(this, keyEpochLengthNew)
629610 let newEpochLengthActions = match newEpochLengthOption {
630611 case newEpochLength: Int =>
631612 [IntegerEntry(keyEpochLength, newEpochLength), DeleteEntry(keyEpochLengthNew)]
632613 case _: Unit =>
633614 nil
634615 case _ =>
635616 throw("Match error")
636617 }
637618 $Tuple2(([IntegerEntry(keyStartHeightByEpoch(newEpoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpoch, newEpoch), IntegerEntry(keyFinalizationStage, finalizationStageTotal), IntegerEntry(keyEpochLengthByEpoch(epoch), epochLength)] ++ newEpochLengthActions), true)
638619 }
639620 else if (if (force)
640621 then (finalizationStageOrUnit == unit)
641622 else false)
642623 then $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares)], true)
643624 else if ((finalizationStageOrUnit == unit))
644625 then $Tuple2(nil, false)
645626 else if ((finalizationStageOrUnit == finalizationStageTotal))
646627 then {
647628 let poolOrUnit = getString(keyNextPool)
648629 let userOrUnit = getString(keyNextUser)
649630 match poolOrUnit {
650631 case _: Unit =>
651632 match getString(keyListHead(poolsListName)) {
652633 case _: Unit =>
653634 $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
654635 case poolsHeadStr: String =>
655636 $Tuple2([StringEntry(keyNextPool, poolsHeadStr)], true)
656637 case _ =>
657638 throw("Match error")
658639 }
659640 case poolStr: String =>
660641 let pool = stringToPool(poolStr)
661642 let nextUserOrUnit = match userOrUnit {
662643 case _: Unit =>
663644 getString(keyListHead(getVotesListName(pool)))
664645 case user: String =>
665646 let next = getString(keyListNext(getVotesListName(pool), user))
666647 if ((next == next))
667648 then {
668649 let processVoteInv = invoke(this, "processVoteINTERNAL", [poolStr, user], nil)
669650 if ((processVoteInv == processVoteInv))
670651 then next
671652 else throw("Strict value is not equal to itself.")
672653 }
673654 else throw("Strict value is not equal to itself.")
674655 case _ =>
675656 throw("Match error")
676657 }
677658 match nextUserOrUnit {
678659 case _: Unit =>
679660 let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
680661 match nextPoolOrUnit {
681662 case _: Unit =>
682663 $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
683664 case s: String =>
684665 $Tuple2([StringEntry(keyNextPool, s), DeleteEntry(keyNextUser)], true)
685666 case _ =>
686667 throw("Match error")
687668 }
688669 case nextUser: String =>
689670 $Tuple2([StringEntry(keyNextUser, nextUser)], true)
690671 case _ =>
691672 throw("Match error")
692673 }
693674 case _ =>
694675 throw("Match error")
695676 }
696677 }
697678 else if ((finalizationStageOrUnit == finalizationStageShares))
698679 then {
699680 let poolOrUnit = getString(keyNextPool)
700681 match poolOrUnit {
701682 case _: Unit =>
702683 match getString(keyListHead(poolsListName)) {
703684 case _: Unit =>
704685 let actions = if (force)
705686 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced)]
706687 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight)]
707- let gwxRewardDepositInv = gwxRewardDeposit()
708- if ((gwxRewardDepositInv == gwxRewardDepositInv))
709- then $Tuple2(actions, true)
710- else throw("Strict value is not equal to itself.")
688+ $Tuple2(actions, true)
711689 case nextPoolStr: String =>
712690 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
713691 case _ =>
714692 throw("Match error")
715693 }
716694 case poolStr: String =>
717695 let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
718696 if ((nextPoolOrUnit == nextPoolOrUnit))
719697 then {
720698 let r = {
721699 let @ = invoke(this, "processPoolINTERNAL", [poolStr, force], nil)
722700 if ($isInstanceOf(@, "Boolean"))
723701 then @
724702 else throw(($getType(@) + " couldn't be cast to Boolean"))
725703 }
726704 if ((r == r))
727705 then if (r)
728706 then $Tuple2(nil, true)
729707 else match nextPoolOrUnit {
730708 case _: Unit =>
731709 let actions = if (force)
732710 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced), DeleteEntry(keyNextPool)]
733711 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight), DeleteEntry(keyNextPool)]
734- let gwxRewardDepositInv = gwxRewardDeposit()
735- if ((gwxRewardDepositInv == gwxRewardDepositInv))
736- then $Tuple2(actions, true)
737- else throw("Strict value is not equal to itself.")
712+ $Tuple2(actions, true)
738713 case nextPoolStr: String =>
739714 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
740715 case _ =>
741716 throw("Match error")
742717 }
743718 else throw("Strict value is not equal to itself.")
744719 }
745720 else throw("Strict value is not equal to itself.")
746721 case _ =>
747722 throw("Match error")
748723 }
749724 }
750725 else throwErr("finalization is broken")
751726 }
752727
753728
754729
755730 @Callable(i)
756731 func finalizeWrapper (counter) = {
757732 let votingEmissionRateContract = addressFromStringValue(getStringValue(this, keyVotingEmissionRateContract))
758733 let result = {
759734 let @ = invoke(this, "finalizeHelper", nil, nil)
760735 if ($isInstanceOf(@, "Boolean"))
761736 then @
762737 else throw(($getType(@) + " couldn't be cast to Boolean"))
763738 }
764739 if ((result == result))
765740 then if (!(result))
766741 then if ((counter == 0))
767742 then throwErr("Current voting is not over yet")
768743 else {
769744 let inv = invoke(votingEmissionRateContract, "finalize", nil, nil)
770745 if ((inv == inv))
771746 then $Tuple2(nil, unit)
772747 else throw("Strict value is not equal to itself.")
773748 }
774749 else {
775750 let maxDepth = valueOrElse(getInteger(this, keyMaxDepth), maxDepthDefault)
776751 if ((maxDepth > counter))
777752 then {
778753 let inv = invoke(this, "finalizeWrapper", [(counter + 1)], nil)
779754 if ((inv == inv))
780755 then $Tuple2(nil, unit)
781756 else throw("Strict value is not equal to itself.")
782757 }
783758 else $Tuple2(nil, unit)
784759 }
785760 else throw("Strict value is not equal to itself.")
786761 }
787762
788763
789764
790765 @Callable(i)
791766 func finalize () = {
792767 let inv = invoke(this, "finalizeWrapper", [0], nil)
793768 if ((inv == inv))
794769 then $Tuple2(nil, unit)
795770 else throw("Strict value is not equal to itself.")
796771 }
797772
798773
799774
800775 @Callable(i)
801776 func containsNodeREADONLY (listName,id) = $Tuple2(nil, containsNode(listName, id))
802777
803778
804779
805780 @Callable(i)
806781 func insertNode (listName,id) = {
807782 let checkCaller = mustManager(i)
808783 if ((checkCaller == checkCaller))
809784 then $Tuple2(insertNodeActions(listName, id), unit)
810785 else throw("Strict value is not equal to itself.")
811786 }
812787
813788
814789
815790 @Callable(i)
816791 func deleteNode (listName,id) = {
817792 let checkCaller = mustManager(i)
818793 if ((checkCaller == checkCaller))
819794 then $Tuple2(deleteNodeActions(listName, id), unit)
820795 else throw("Strict value is not equal to itself.")
821796 }
822797
823798
824799
825800 @Callable(i)
826801 func isFinalizationInProgress () = {
827802 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
828803 let finalizationInProgress = (finalizationStageOrUnit != unit)
829804 $Tuple2(nil, finalizationInProgress)
830805 }
831806
832807
833808
834809 @Callable(i)
835810 func deletePool (amountAssetId,priceAssetId) = {
836811 let checkCaller = if (if ((i.caller == factoryContract))
837812 then true
838813 else mustManager(i))
839814 then true
840815 else throwErr("Permission denied")
841816 if ((checkCaller == checkCaller))
842817 then {
843818 let listName = "pools"
844819 let pool = $Tuple2(amountAssetId, priceAssetId)
845820 let id = makeString([amountAssetId, priceAssetId], separator)
846821 let actions = if (containsNode(listName, id))
847822 then deleteNodeActions(listName, id)
848823 else nil
849824 ([DeleteEntry(keyInList(pool))] ++ actions)
850825 }
851826 else throw("Strict value is not equal to itself.")
852827 }
853828
854829
830+
831+@Callable(i)
832+func getLockedGwxAmount (userAddressStr) = {
833+ let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr("invalid user address"))
834+ let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
835+ let gwxAmount = match getInteger(this, keyUsed(userAddress, epoch)) {
836+ case _: Unit =>
837+ 0
838+ case n: Int =>
839+ n
840+ case _ =>
841+ throw("Match error")
842+ }
843+ $Tuple2(nil, gwxAmount)
844+ }
845+
846+
855847 @Verifier(tx)
856848 func verify () = {
857849 let targetPublicKey = match managerPublicKeyOrUnit() {
858850 case pk: ByteVector =>
859851 pk
860852 case _: Unit =>
861853 tx.senderPublicKey
862854 case _ =>
863855 throw("Match error")
864856 }
865857 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
866858 }
867859

github/deemru/w8io/3ef1775 
122.79 ms