tx · 2ShjP7N3qiCGDMFtPggVSUxL5ifvtAgbToQKCZsr4KSL

3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr:  -0.02300000 Waves

2023.08.17 16:17 [2714643] smart account 3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr > SELF 0.00000000 Waves

{ "type": 13, "id": "2ShjP7N3qiCGDMFtPggVSUxL5ifvtAgbToQKCZsr4KSL", "fee": 2300000, "feeAssetId": null, "timestamp": 1692278286197, "version": 2, "chainId": 84, "sender": "3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr", "senderPublicKey": "GFbasS3jufhZkK4xR7tdTjjnP8K33KvJFEDHRtxXDkaJ", "proofs": [ "3SS1vWAcpPiEQs2uHvCJbKsrvKW9adLJLqLNGvbmxGvoqp6PT95q1qgsfa3Gs1W2uiwaUZ3Zp3zs5ztPv6VjAnZn" ], "script": "base64:BgKEFwgCEgQKAggBEgcKBQgICAgBEgQKAggIEgUKAwgIARIECgIICBIDCgEBEgMKAQESBAoCCAgSBAoCCAQSABIDCgEBEgASBAoCCAgSBAoCCAgSBAoCCAgSABIECgIICCIJc2VwYXJhdG9yIg5wb29sV2VpZ2h0TXVsdCIPbWF4RGVwdGhEZWZhdWx0IhZmaW5hbGl6YXRpb25TdGFnZVRvdGFsIhdmaW5hbGl6YXRpb25TdGFnZVNoYXJlcyIOa2V5RXBvY2hMZW5ndGgiEWtleUVwb2NoTGVuZ3RoTmV3IhVrZXlFcG9jaExlbmd0aEJ5RXBvY2giBWVwb2NoIg9rZXlDdXJyZW50RXBvY2giC2tleU1heERlcHRoIiJrZXlWb3RpbmdFbWlzc2lvbkNhbmRpZGF0ZUNvbnRyYWN0Ih1rZXlWb3RpbmdFbWlzc2lvblJhdGVDb250cmFjdCISa2V5RmFjdG9yeUNvbnRyYWN0IhNrZXlCb29zdGluZ0NvbnRyYWN0IhJrZXlTdGFraW5nQ29udHJhY3QiFGtleUZpbmFsaXphdGlvblN0YWdlIgtrZXlOZXh0UG9vbCILa2V5TmV4dFVzZXIiDmtleVN0YXJ0SGVpZ2h0IhFrZXlDdXJyZW50RXBvY2hVaSIQa2V5U3RhcnRIZWlnaHRVaSIda2V5RmluYWxpemF0aW9uU2hvdWxkQmVGb3JjZWQiFWtleVN0YXJ0SGVpZ2h0QnlFcG9jaCIMa2V5RmluYWxpemVkIglrZXlJbkxpc3QiBHBvb2wiCyR0MDE3ODgxODI4Ig1hbW91bnRBc3NldElkIgxwcmljZUFzc2V0SWQiB2tleVVzZWQiB2FkZHJlc3MiB2tleVZvdGUiCyR0MDIxMDIyMTQyIg9rZXlWb3RpbmdSZXN1bHQiCyR0MDIzMjQyMzY0IhVrZXlWb3RpbmdSZXN1bHRTdGFrZWQiDGxwQXNzZXRJZFN0ciIMa2V5UG9vbFNoYXJlIgskdDAyNjg1MjcyNSINa2V5VG90YWxWb3RlcyIPa2V5U3Rha2VkQnlVc2VyIg51c2VyQWRkcmVzc1N0ciIHd3JhcEVyciIDbXNnIgh0aHJvd0VyciIOZ2V0VmFsdWVPckZhaWwiA2tleSIEdHlwZSIFZXJyb3IiByRtYXRjaDAiA3N0ciIDaW50IgxnZXRTdHJPckZhaWwiAUAiDGdldEludE9yRmFpbCIMcG9vbFRvU3RyaW5nIgxzdHJpbmdUb1Bvb2wiBXBhcnRzIg9mYWN0b3J5Q29udHJhY3QiGklkeEZhY3RvcnlDZmdHd3hSZXdhcmREYXBwIg1rZXlGYWN0b3J5Q2ZnIhRyZWFkRmFjdG9yeUNmZ09yRmFpbCIHZmFjdG9yeSIZZ2V0R3d4UmV3YXJkQWRkcmVzc09yRmFpbCIKZmFjdG9yeUNmZyIWZ2V0THBBc3NldEJ5UG9vbEFzc2V0cyIfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZCIMYmFzZUFzc2V0U3RyIilrZXlNYXBwaW5nUG9vbEFzc2V0c1RvUG9vbENvbnRyYWN0QWRkcmVzcyIYaW50ZXJuYWxBbW91bnRBc3NldElkU3RyIhdpbnRlcm5hbFByaWNlQXNzZXRJZFN0ciIfa2V5TWFwcGluZ1Bvb2xDb250cmFjdFRvTFBBc3NldCITcG9vbENvbnRyYWN0QWRkcmVzcyIVYW1vdW50QXNzZXRJbnRlcm5hbElkIhRwcmljZUFzc2V0SW50ZXJuYWxJZCIJbHBBc3NldElkIhhjaGVja1d4RW1pc3Npb25Qb29sTGFiZWwiCyR0MDU1NjU1NjA1IhBnd3hSZXdhcmREZXBvc2l0IhJnd3hSZXdhcmRzQ29udHJhY3QiDXBvb2xzTGlzdE5hbWUiEGdldFZvdGVzTGlzdE5hbWUiCyR0MDYwMjI2MDYyIgtrZXlMaXN0SGVhZCIIbGlzdE5hbWUiBG1ldGEiC2tleUxpc3RTaXplIgtrZXlMaXN0UHJldiICaWQiC2tleUxpc3ROZXh0Igxjb250YWluc05vZGUiCmhlYWRPclVuaXQiCnByZXZPclVuaXQiCm5leHRPclVuaXQiEWluc2VydE5vZGVBY3Rpb25zIghsaXN0U2l6ZSIJY2hlY2tOb2RlIhFkZWxldGVOb2RlQWN0aW9ucyIWa2V5TWFuYWdlclZhdWx0QWRkcmVzcyITa2V5TWFuYWdlclB1YmxpY0tleSIcZ2V0TWFuYWdlclZhdWx0QWRkcmVzc09yVGhpcyIBcyIWbWFuYWdlclB1YmxpY0tleU9yVW5pdCITbWFuYWdlclZhdWx0QWRkcmVzcyIJaXNNYW5hZ2VyIgFpIgJwayILbXVzdE1hbmFnZXIiCG11c3RUaGlzIgt1c2VyQWRkcmVzcyIMdGFyZ2V0SGVpZ2h0Ihdib29zdGluZ0NvbnRyYWN0QWRkcmVzcyIfdm90aW5nRW1pc3Npb25DYW5kaWRhdGVDb250cmFjdCIQYm9vc3RpbmdDb250cmFjdCIPc3Rha2luZ0NvbnRyYWN0IgtlcG9jaExlbmd0aCIGY2hlY2tzIg1pbkxpc3RBY3Rpb25zIhhjdXJyZW50RXBvY2hJc05vdERlZmluZWQiEnN0YXJ0SGVpZ2h0QWN0aW9ucyIGYW1vdW50IgtzdGFydEhlaWdodCIJZW5kSGVpZ2h0IhdmaW5hbGl6YXRpb25TdGFnZU9yVW5pdCIEdXNlZCIEdm90ZSIKcG9vbFJlc3VsdCIKdG90YWxWb3RlcyITZ3d4QW1vdW50QXRFbmRUb3RhbCIJYXZhaWxhYmxlIgduZXdWb3RlIgp3eEVtaXNzaW9uIg12b3Rlc0xpc3ROYW1lIhB2b3Rlc0xpc3RBY3Rpb25zIg5uZXdFcG9jaExlbmd0aCILbmV3TWF4RGVwdGgiB3Bvb2xTdHIiC2NoZWNrQ2FsbGVyIg1lcG9jaFByZXZpb3VzIhNzdGFydEhlaWdodFByZXZpb3VzIhNlcG9jaExlbmd0aFByZXZpb3VzIhFlbmRIZWlnaHRQcmV2aW91cyIQY2hlY2tUYXJnZXRFcG9jaCINJHQwMTgwNjUxODEwNSIbZ3d4QW1vdW50QXRFbmRUb3RhbFByZXZpb3VzIgx2b3RpbmdSZXN1bHQiDHZvdGVQcmV2aW91cyIadm90aW5nUmVzdWx0U3Rha2VkUHJldmlvdXMiDHN0YWtlZEJ5VXNlciIZdm90aW5nUmVzdWx0U3Rha2VkQWN0aW9ucyIHYWN0aW9ucyIFZm9yY2UiC3RhcmdldEVwb2NoIgxjdXJyZW50RXBvY2giDSR0MDIwNDYyMjA1MDIiAXIiBXNoYXJlIg9tb2RpZnlXZWlnaHRJbnYiEHBvb2xzTGlzdEFjdGlvbnMiDXByZXZpb3VzRXBvY2giCG5ld0Vwb2NoIhRuZXdFcG9jaExlbmd0aE9wdGlvbiIVbmV3RXBvY2hMZW5ndGhBY3Rpb25zIgpwb29sT3JVbml0Igp1c2VyT3JVbml0IgckbWF0Y2gxIgxwb29sc0hlYWRTdHIiDm5leHRVc2VyT3JVbml0IgR1c2VyIgRuZXh0Ig5wcm9jZXNzVm90ZUludiIObmV4dFBvb2xPclVuaXQiByRtYXRjaDIiCG5leHRVc2VyIhNnd3hSZXdhcmREZXBvc2l0SW52IgtuZXh0UG9vbFN0ciIHY291bnRlciIadm90aW5nRW1pc3Npb25SYXRlQ29udHJhY3QiBnJlc3VsdCIDaW52IghtYXhEZXB0aCIWZmluYWxpemF0aW9uSW5Qcm9ncmVzcyICdHgiBnZlcmlmeSIPdGFyZ2V0UHVibGljS2V5PwABYQICX18AAWIAgMLXLwABYwAKAAFkAAAAAWUAAQABZgkAuQkCCQDMCAICAiVzCQDMCAICC2Vwb2NoTGVuZ3RoBQNuaWwFAWEAAWcJALkJAgkAzAgCAgQlcyVzCQDMCAICEGVwb2NoTGVuZ3RoX19uZXcFA25pbAUBYQEBaAEBaQkAuQkCCQDMCAICBCVzJWQJAMwIAgILZXBvY2hMZW5ndGgJAMwIAgkApAMBBQFpBQNuaWwFAWEAAWoJALkJAgkAzAgCAgIlcwkAzAgCAgxjdXJyZW50RXBvY2gFA25pbAUBYQABawkAuQkCCQDMCAICAiVzCQDMCAICCG1heERlcHRoBQNuaWwFAWEAAWwJALkJAgkAzAgCAgIlcwkAzAgCAh92b3RpbmdFbWlzc2lvbkNhbmRpZGF0ZUNvbnRyYWN0BQNuaWwFAWEAAW0JALkJAgkAzAgCAgIlcwkAzAgCAhp2b3RpbmdFbWlzc2lvblJhdGVDb250cmFjdAUDbmlsBQFhAAFuCQC5CQIJAMwIAgICJXMJAMwIAgIPZmFjdG9yeUNvbnRyYWN0BQNuaWwFAWEAAW8JALkJAgkAzAgCAgIlcwkAzAgCAhBib29zdGluZ0NvbnRyYWN0BQNuaWwFAWEAAXAJALkJAgkAzAgCAgIlcwkAzAgCAg9zdGFraW5nQ29udHJhY3QFA25pbAUBYQABcQkAuQkCCQDMCAICAiVzCQDMCAICEWZpbmFsaXphdGlvblN0YWdlBQNuaWwFAWEAAXIJALkJAgkAzAgCAgIlcwkAzAgCAghuZXh0UG9vbAUDbmlsBQFhAAFzCQC5CQIJAMwIAgICJXMJAMwIAgIIbmV4dFVzZXIFA25pbAUBYQABdAkAuQkCCQDMCAICAiVzCQDMCAICC3N0YXJ0SGVpZ2h0BQNuaWwFAWEAAXUJALkJAgkAzAgCAgIlcwkAzAgCAg5jdXJyZW50RXBvY2hVaQUDbmlsBQFhAAF2CQC5CQIJAMwIAgICJXMJAMwIAgINc3RhcnRIZWlnaHRVaQUDbmlsBQFhAAF3CQC5CQIJAMwIAgICJXMJAMwIAgIFZm9yY2UFA25pbAUBYQEBeAEBaQkAuQkCCQDMCAICBCVzJWQJAMwIAgILc3RhcnRIZWlnaHQJAMwIAgkApAMBBQFpBQNuaWwFAWEBAXkBAWkJALkJAgkAzAgCAgQlcyVkCQDMCAICCWZpbmFsaXplZAkAzAgCCQCkAwEFAWkFA25pbAUBYQEBegEBQQQBQgUBQQQBQwgFAUICXzEEAUQIBQFCAl8yCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICBmluTGlzdAkAzAgCBQFDCQDMCAIFAUQFA25pbAUBYQEBRQIBRgFpCQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICBHVzZWQJAMwIAgkApQgBBQFGCQDMCAIJAKQDAQUBaQUDbmlsBQFhAQFHAwFBAUYBaQQBSAUBQQQBQwgFAUgCXzEEAUQIBQFIAl8yCQC5CQIJAMwIAgIKJXMlcyVzJXMlZAkAzAgCAgR2b3RlCQDMCAIFAUMJAMwIAgUBRAkAzAgCCQClCAEFAUYJAMwIAgkApAMBBQFpBQNuaWwFAWEBAUkCAUEBaQQBSgUBQQQBQwgFAUoCXzEEAUQIBQFKAl8yCQC5CQIJAMwIAgIIJXMlcyVzJWQJAMwIAgIMdm90aW5nUmVzdWx0CQDMCAIFAUMJAMwIAgUBRAkAzAgCCQCkAwEFAWkFA25pbAUBYQEBSwIBTAFpCQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICEnZvdGluZ1Jlc3VsdFN0YWtlZAkAzAgCBQFMCQDMCAIJAKQDAQUBaQUDbmlsBQFhAQFNAgFBAWkEAU4FAUEEAUMIBQFOAl8xBAFECAUBTgJfMgkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICCXBvb2xTaGFyZQkAzAgCBQFDCQDMCAIFAUQJAMwIAgkApAMBBQFpBQNuaWwFAWEBAU8BAWkJALkJAgkAzAgCAgQlcyVkCQDMCAICCnRvdGFsVm90ZXMJAMwIAgkApAMBBQFpBQNuaWwFAWEBAVACAUwBUQkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgZzdGFrZWQJAMwIAgUBUQkAzAgCBQFMBQNuaWwFAWEBAVIBAVMJALkJAgkAzAgCAhV2b3RpbmdfZW1pc3Npb24ucmlkZToJAMwIAgUBUwUDbmlsAgEgAQFUAQFTCQACAQkBAVIBBQFTAQFVAwFGAVYBVwQBWAkBAVIBCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAUYJAMwIAgIBLgkAzAgCBQFWCQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgQBWQUBVwMJAAECBQFZAgZTdHJpbmcEAVoFAVkJAJ0IAgUBRgUBVgMJAAECBQFZAgNJbnQEAmFhBQFZCQCaCAIFAUYFAVYJAQFUAQISaW52YWxpZCBlbnRyeSB0eXBlBQFYAQJhYgIBRgFWCgACYWMJAQFVAwUBRgUBVgIAAwkAAQIFAmFjAgZTdHJpbmcFAmFjCQACAQkArAICCQADAQUCYWMCGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwECYWQCAUYBVgoAAmFjCQEBVQMFAUYFAVYAAAMJAAECBQJhYwIDSW50BQJhYwkAAgEJAKwCAgkAAwEFAmFjAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQBAmFlAQFBCQCsAgIJAKwCAggFAUECXzEFAWEIBQFBAl8yAQJhZgEBWgQCYWcJALUJAgUBWgUBYQMJAAACCQCQAwEFAmFnAAIJAJQKAgkAkQMCBQJhZwAACQCRAwIFAmFnAAEJAQFUAQITaW52YWxpZCBwb29sIHN0cmluZwACYWgJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQJhYgIFBHRoaXMFAW4AAmFpAAoBAmFqAAIRJXNfX2ZhY3RvcnlDb25maWcBAmFrAQJhbAkAtQkCCQECYWICBQJhbAkBAmFqAAUBYQECYW0BAmFuCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFAmFuBQJhaQECYW8CAUMBRAoBAmFwAQJhcQkArAICAiglcyVzJXNfX21hcHBpbmdzX19iYXNlQXNzZXQyaW50ZXJuYWxJZF9fBQJhcQoBAmFyAgJhcwJhdAkArAICCQCsAgIJAKwCAgkArAICAgolZCVkJXMlc19fCQCkAwEFAmFzAgJfXwkApAMBBQJhdAIjX19tYXBwaW5nc19fcG9vbEFzc2V0czJQb29sQ29udHJhY3QKAQJhdQECYXYJAKwCAgkArAICAgglcyVzJXNfXwUCYXYCIF9fbWFwcGluZ3NfX3Bvb2xDb250cmFjdDJMcEFzc2V0BAJhdwkBAmFkAgUCYWgJAQJhcAEFAUMEAmF4CQECYWQCBQJhaAkBAmFwAQUBRAQCYXYJAQJhYgIFAmFoCQECYXICBQJhdwUCYXgEAmF5CQECYWICBQJhaAkBAmF1AQUCYXYFAmF5AQJhegEBQQQCYUEFAUEEAUMIBQJhQQJfMQQBRAgFAmFBAl8yCgACYWMJAPwHBAUCYWgCGGNoZWNrV3hFbWlzc2lvblBvb2xMYWJlbAkAzAgCBQFDCQDMCAIFAUQFA25pbAUDbmlsAwkAAQIFAmFjAgdCb29sZWFuBQJhYwkAAgEJAKwCAgkAAwEFAmFjAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuAQJhQgAEAmFuCQECYWsBBQJhaAQCYUMJAQJhbQEFAmFuCQD8BwQFAmFDAgdkZXBvc2l0BQNuaWwFA25pbAACYUQCBXBvb2xzAQJhRQEBQQQCYUYFAUEEAUMIBQJhRgJfMQQBRAgFAmFGAl8yCQC5CQIJAMwIAgIFdm90ZXMJAMwIAgUBQwkAzAgCBQFEBQNuaWwFAWEBAmFHAQJhSAQCYUkDCQAAAgUCYUgFAmFEAgQlcyVzAgglcyVzJXMlcwkAuQkCCQDMCAIFAmFJCQDMCAIFAmFICQDMCAICBGhlYWQFA25pbAUBYQECYUoBAmFIBAJhSQMJAAACBQJhSAUCYUQCBCVzJXMCCCVzJXMlcyVzCQC5CQIJAMwIAgUCYUkJAMwIAgUCYUgJAMwIAgIEc2l6ZQUDbmlsBQFhAQJhSwICYUgCYUwEAmFJAwkAAAIFAmFIBQJhRAIIJXMlcyVzJXMCCiVzJXMlcyVzJXMJALkJAgkAzAgCBQJhSQkAzAgCBQJhSAkAzAgCBQJhTAkAzAgCAgRwcmV2BQNuaWwFAWEBAmFNAgJhSAJhTAQCYUkDCQAAAgUCYUgFAmFEAgglcyVzJXMlcwIKJXMlcyVzJXMlcwkAuQkCCQDMCAIFAmFJCQDMCAIFAmFICQDMCAIFAmFMCQDMCAICBG5leHQFA25pbAUBYQECYU4CAmFIAmFMBAJhTwkAnQgCBQR0aGlzCQECYUcBBQJhSAQCYVAJAJ0IAgUEdGhpcwkBAmFLAgUCYUgFAmFMBAJhUQkAnQgCBQR0aGlzCQECYU0CBQJhSAUCYUwDAwkAAAIFAmFMCQELdmFsdWVPckVsc2UCBQJhTwIABgkBAiE9AgUCYVAFBHVuaXQGCQECIT0CBQJhUQUEdW5pdAECYVICAmFIAmFMBAJhTwkAnQgCBQR0aGlzCQECYUcBBQJhSAQCYVMJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmFKAQUCYUgAAAQCYVQDCQEBIQEJAQJhTgIFAmFIBQJhTAYJAQFUAQILTm9kZSBleGlzdHMDCQAAAgUCYVQFAmFUCQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFKAQUCYUgJAGQCBQJhUwABBQNuaWwDCQECIT0CBQJhTwUEdW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQECYU0CBQJhSAUCYUwJAQV2YWx1ZQEFAmFPCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhSwIFAmFICQEFdmFsdWUBBQJhTwUCYUwFA25pbAUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhRwEFAmFIBQJhTAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJhVQICYUgCYUwEAmFPCQCdCAIFBHRoaXMJAQJhRwEFAmFIBAJhUwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYUoBBQJhSAAABAJhUAkAnQgCBQR0aGlzCQECYUsCBQJhSAUCYUwEAmFRCQCdCAIFBHRoaXMJAQJhTQIFAmFIBQJhTAkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYUoBBQJhSAkAZQIFAmFTAAEFA25pbAMDCQECIT0CBQJhUAUEdW5pdAkBAiE9AgUCYVEFBHVuaXQHCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhTQIFAmFICQEFdmFsdWUBBQJhUAkBBXZhbHVlAQUCYVEJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFLAgUCYUgJAQV2YWx1ZQEFAmFRCQEFdmFsdWUBBQJhUAkAzAgCCQELRGVsZXRlRW50cnkBCQECYUsCBQJhSAUCYUwJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFNAgUCYUgFAmFMBQNuaWwDCQECIT0CBQJhUQUEdW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQECYUcBBQJhSAkBBXZhbHVlAQUCYVEJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFNAgUCYUgFAmFMCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhSwIFAmFICQEFdmFsdWUBBQJhUQUDbmlsAwkBAiE9AgUCYVAFBHVuaXQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFLAgUCYUgFAmFMCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhTQIFAmFICQEFdmFsdWUBBQJhUAUDbmlsAwkAAAIFAmFMCQELdmFsdWVPckVsc2UCBQJhTwIACQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhRwEFAmFIBQNuaWwJAQFUAQkArAICCQCsAgIJAKwCAgIOaW52YWxpZCBub2RlOiAFAmFIAgEuBQJhTAECYVYAAhclc19fbWFuYWdlclZhdWx0QWRkcmVzcwECYVcAAhQlc19fbWFuYWdlclB1YmxpY0tleQECYVgABAFZCQCiCAEJAQJhVgADCQABAgUBWQIGU3RyaW5nBAJhWQUBWQkBEUBleHRyTmF0aXZlKDEwNjIpAQUCYVkFBHRoaXMBAmFaAAQCYmEJAQJhWAAEAVkJAJ0IAgUCYmEJAQJhVwADCQABAgUBWQIGU3RyaW5nBAJhWQUBWQkA2QQBBQJhWQMJAAECBQFZAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmJiAQJiYwQBWQkBAmFaAAMJAAECBQFZAgpCeXRlVmVjdG9yBAJiZAUBWQkAAAIIBQJiYw9jYWxsZXJQdWJsaWNLZXkFAmJkAwkAAQIFAVkCBFVuaXQJAAACCAUCYmMGY2FsbGVyBQR0aGlzCQACAQILTWF0Y2ggZXJyb3IBAmJlAQJiYwMJAQJiYgEFAmJjBgkAAgECEXBlcm1pc3Npb24gZGVuaWVkAQJiZgECYmMDCQAAAggFAmJjBmNhbGxlcgUEdGhpcwYJAAIBAhFwZXJtaXNzaW9uIGRlbmllZBECYmMBGGdldFVzZXJHd3hBbW91bnRBdEhlaWdodAICYmcCYmgEAmJpCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBAmFiAgUEdGhpcwUBbwkBAVIBAiFpbnZhbGlkIGJvb3N0aW5nIGNvbnRyYWN0IGFkZHJlc3MJAJQKAgUDbmlsCgACYWMJAPwHBAUCYmkCIGdldFVzZXJHd3hBbW91bnRBdEhlaWdodFJFQURPTkxZCQDMCAIFAmJnCQDMCAIFAmJoBQNuaWwFA25pbAMJAAECBQJhYwIDSW50BQJhYwkAAgEJAKwCAgkAAwEFAmFjAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQCYmMBC2NvbnN0cnVjdG9yBQJhaAJiagJiawJibAJibQQCYm4JAMwIAgkBAmJlAQUCYmMJAMwIAgMJAQIhPQIJAKYIAQUCYWgFBHVuaXQGAiBpbnZhbGlkIGZhY3RvcnkgY29udHJhY3QgYWRkcmVzcwkAzAgCAwkBAiE9AgkApggBBQJiagUEdW5pdAYCMmludmFsaWQgdm90aW5nIGVtaXNzaW9uIGNhbmRpZGF0ZSBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQECIT0CCQCmCAEFAmJrBQR1bml0BgIhaW52YWxpZCBib29zdGluZyBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQECIT0CCQCmCAEFAmJsBQR1bml0BgIgaW52YWxpZCBzdGFraW5nIGNvbnRyYWN0IGFkZHJlc3MJAMwIAgMJAGYCBQJibQAABgkBAVQBAhRpbnZhbGlkIGVwb2NoIGxlbmd0aAUDbmlsAwkAAAIFAmJuBQJibgkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAW4FAmFoCQDMCAIJAQtTdHJpbmdFbnRyeQIFAWwFAmJqCQDMCAIJAQtTdHJpbmdFbnRyeQIFAW8FAmJrCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXAFAmJsCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFmBQJibQUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJjAQZjcmVhdGUCAUMBRAQCYm4JAMwIAgMJAAACCQDYBAEICAUCYmMGY2FsbGVyBWJ5dGVzCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAWwCAAYJAQJiZQEFAmJjBQNuaWwDCQAAAgUCYm4FAmJuBAFBCQCUCgIFAUMFAUQEAmJvCQDOCAIJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAQF6AQUBQQYFA25pbAkBAmFSAgUCYUQJAQJhZQEFAUEEAmJwCQAAAgkAmggCBQR0aGlzBQFqBQR1bml0BAJicQMFAmJwBAFpAAAJAMwIAgkBDEludGVnZXJFbnRyeQIFAWoFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIJAQF4AQUBaQUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF0BQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFAXUFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIFAXYFBmhlaWdodAUDbmlsBQNuaWwJAJQKAgkAzggCBQJibwUCYnEFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmMBBHZvdGUDAUMBRAJicgQBQQkAlAoCBQFDBQFEBAFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWoAAAQCYnMJAQJhZAIFBHRoaXMJAQF4AQUBaQQCYm0JAQJhZAIFBHRoaXMFAWYEAmJ0CQBkAgUCYnMFAmJtBAJidQkAmggCBQR0aGlzBQFxBAJidgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBRQIIBQJiYwZjYWxsZXIFAWkAAAQCYncJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUcDBQFBCAUCYmMGY2FsbGVyBQFpAAAEAmJ4CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFJAgUBQQUBaQAABAJieQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBTwEFAWkAAAQCYnoKAAJhYwkA/AcEBQR0aGlzAhhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQJAMwIAgkA2AQBCAgFAmJjBmNhbGxlcgVieXRlcwkAzAgCBQJidAUDbmlsBQNuaWwDCQABAgUCYWMCA0ludAUCYWMJAAIBCQCsAgIJAAMBBQJhYwIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50BAJiQQkAZQIFAmJ6BQJidgQCYkIJAGQCBQJidwUCYnIEAmJDCQECYXoBBQFBBAJibgkAzAgCAwkBAiE9AgkAoAgBCQEBegEFAUEFBHVuaXQGCQEBVAECDmludmFsaWQgYXNzZXRzCQDMCAIDCQBmAgUCYnQFBmhlaWdodAYJAQFUAQIOaW52YWxpZCBoZWlnaHQJAMwIAgMJAAACBQJidQUEdW5pdAYJAQFUAQIYZmluYWxpemF0aW9uIGluIHByb2dyZXNzCQDMCAIDCQBmAgUCYnoAAAYJAQFUAQITeW91IGRvIG5vdCBoYXZlIGdXWAkAzAgCAwMJAGYCBQJicgAACQBnAgUCYkEFAmJyBwYJAQFUAQIOaW52YWxpZCBhbW91bnQJAMwIAgMFAmJDBgkBAVQBAh1wb29sIGhhc24ndCBXWF9FTUlTU0lPTiBsYWJlbAUDbmlsAwkAAAIFAmJuBQJibgQCYkQJAQJhRQEFAUEEAVEJAKUIAQgFAmJjBmNhbGxlcgQCYkUDCQECYU4CBQJiRAUBUQUDbmlsCQECYVICBQJiRAUBUQkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFFAggFAmJjBmNhbGxlcgUBaQkAZAIFAmJ2BQJicgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUcDBQFBCAUCYmMGY2FsbGVyBQFpBQJiQgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUkCBQFBBQFpCQBkAgUCYngFAmJyCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBTwEFAWkJAGQCBQJieQUCYnIFA25pbAUCYkUFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmMBCmNhbmNlbFZvdGUCAUMBRAQBQQkAlAoCBQFDBQFEBAFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWoAAAQCYnMJAQJhZAIFBHRoaXMJAQF4AQUBaQQCYm0JAQJhZAIFBHRoaXMFAWYEAmJ0CQBkAgUCYnMFAmJtBAJidQkAmggCBQR0aGlzBQFxBAJidgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBRQIIBQJiYwZjYWxsZXIFAWkAAAQCYncJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUcDBQFBCAUCYmMGY2FsbGVyBQFpAAAEAmJ4CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFJAgUBQQUBaQAABAJieQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBTwEFAWkAAAQCYm4JAMwIAgMJAQIhPQIJAKAIAQkBAXoBBQFBBQR1bml0BgkBAVQBAg5pbnZhbGlkIGFzc2V0cwkAzAgCAwkAZgIFAmJ0BQZoZWlnaHQGCQEBVAECDmludmFsaWQgaGVpZ2h0CQDMCAIDCQAAAgUCYnUFBHVuaXQGCQEBVAECGGZpbmFsaXphdGlvbiBpbiBwcm9ncmVzcwkAzAgCAwkAZgIFAmJ3AAAGCQEBVAECB25vIHZvdGUFA25pbAMJAAACBQJibgUCYm4EAmJECQECYUUBBQFBBAFRCQClCAEIBQJiYwZjYWxsZXIJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBRQIIBQJiYwZjYWxsZXIFAWkJAJYDAQkAzAgCCQBlAgUCYnYFAmJ3CQDMCAIAAAUDbmlsCQDMCAIJAQtEZWxldGVFbnRyeQEJAQFHAwUBQQgFAmJjBmNhbGxlcgUBaQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUkCBQFBBQFpCQBlAgUCYngFAmJ3CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBTwEFAWkJAGUCBQJieQUCYncFA25pbAkBAmFVAgUCYkQFAVEFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmMBDnNldEVwb2NoTGVuZ3RoAQJiRgQCYm4JAMwIAgkBAmJlAQUCYmMJAMwIAgMJAGYCBQJiRgAABgkBAVQBAhRpbnZhbGlkIGVwb2NoIGxlbmd0aAUDbmlsAwkAAAIFAmJuBQJibgkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFnBQJiRgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJjAQtzZXRNYXhEZXB0aAECYkcEAmJuCQDMCAIJAQJiZQEFAmJjCQDMCAIDCQBmAgUCYkcAAAYJAQFUAQIRaW52YWxpZCBtYXggZGVwdGgFA25pbAMJAAACBQJibgUCYm4JAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBawUCYkcFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiYwETcHJvY2Vzc1ZvdGVJTlRFUk5BTAICYkgBUQQCYkkJAQJiZgEFAmJjAwkAAAIFAmJJBQJiSQQCYmcJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQFRCQEBUgEJAKwCAgIqcHJvY2Vzc1ZvdGVJTlRFUk5BTDogaW52YWxpZCB1c2VyIGFkZHJlc3MgBQFRBAFpCQECYWQCBQR0aGlzBQFqBAJiSgkAZQIFAWkAAQQCYm0JAQJhZAIFBHRoaXMFAWYEAmJzCQECYWQCBQR0aGlzCQEBeAEFAWkEAmJ0CQBkAgUCYnMFAmJtBAJiSwkBAmFkAgUEdGhpcwkBAXgBBQJiSgQCYkwJAQJhZAIFBHRoaXMJAQFoAQUCYkoEAmJNCQBkAgUCYksFAmJMBAJiTgMJAGcCBQJiSgAABgkBAVQBAitwcm9jZXNzVm90ZUlOVEVSTkFMOiBpbnZhbGlkIHByZXZpb3VzIGVwb2NoAwkAAAIFAmJOBQJiTgQBQQkBAmFmAQUCYkgEAmJPBQFBBAFDCAUCYk8CXzEEAUQIBQJiTwJfMgQCYkMJAQJhegEFAUEEAmJ6CgACYWMJAPwHBAUEdGhpcwIYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0CQDMCAIFAVEJAMwIAgUCYnQFA25pbAUDbmlsAwkAAQIFAmFjAgNJbnQFAmFjCQACAQkArAICCQADAQUCYWMCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAQCYlAKAAJhYwkA/AcEBQR0aGlzAhhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQJAMwIAgUBUQkAzAgCBQJiTQUDbmlsBQNuaWwDCQABAgUCYWMCA0ludAUCYWMJAAIBCQCsAgIJAAMBBQJhYwIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50BAJieQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEBTwEFAWkAAAQCYlEJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAUkCBQFBBQFpAAAEAmJSCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQkBAUcDBQFBBQJiZwUCYkoJAQFSAQkArAICCQCsAgIJAKwCAgkArAICAhRwcm9jZXNzVm90ZUlOVEVSTkFMIAUCYkgCASAFAVECEjogbm8gcHJldmlvdXMgdm90ZQQCYnYJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUUCBQJiZwUBaQAABAFMCQECYW8CBQFDBQFEBAJiUwkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEBSwIFAUwFAmJKAAAEAmJsCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYWICBQR0aGlzBQFwBAJiVAkBC3ZhbHVlT3JFbHNlAgkAmggCBQJibAkBAVACBQFMBQFRAAAEAmJVAwkAAAIFAmJUAAAFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUsCBQFMBQJiSgkAZAIFAmJTBQJiUgUDbmlsBAJiQgMJAGYCBQJiUAAACQBrAwUCYlIFAmJ6BQJiUAAABAJiVgMDCQBmAgUCYkIAAAUCYkMHCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBRwMFAUEFAmJnBQFpBQJiQgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAU8BBQFpCQBkAgUCYnkFAmJCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBSQIFAUEFAWkJAGQCBQJiUQUCYkIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFFAgUCYmcFAWkJAGQCBQJidgUCYkIFA25pbAkBAmFVAgkBAmFFAQUBQQUBUQkAlAoCCQDOCAIFAmJWBQJiVQUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiYwETcHJvY2Vzc1Bvb2xJTlRFUk5BTAICYkgCYlcEAmJJCQECYmYBBQJiYwMJAAACBQJiSQUCYkkEAmJYBAJiWQkBAmFkAgUEdGhpcwUBagMFAmJXBQJiWQkAZQIFAmJZAAEEAmJOAwkAZwIFAmJYAAAGCQEBVAECKXByb2Nlc3NQb29sSU5URVJOQUw6IGludmFsaWQgdGFyZ2V0IGVwb2NoAwkAAAIFAmJOBQJiTgQBQQkBAmFmAQUCYkgEAmJaBQFBBAFDCAUCYloCXzEEAUQIBQJiWgJfMgQCYmwJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQJhYgIFBHRoaXMFAXAEAmF5CQECYW8CBQFDBQFEBAJjYQoAAmFjCQD8BwQFAmJsAhJ1c2Vyc0xpc3RUcmF2ZXJzYWwJAMwIAgUCYXkFA25pbAUDbmlsAwkAAQIFAmFjAgdCb29sZWFuBQJhYwkAAgEJAKwCAgkAAwEFAmFjAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuAwkAAAIFAmNhBQJjYQMFAmNhCQCUCgIFA25pbAYEAmJDCQECYXoBBQFBBAJieQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBTwEFAmJYAAAEAmJRCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFJAgUBQQUCYlgAAAQCY2IDAwkAAAIFAmJ5AAAGCQEBIQEFAmJDAAAJAGsDBQJiUQUBYgUCYnkEAmNjCQD8BwQFAmFoAgxtb2RpZnlXZWlnaHQJAMwIAgUCYXkJAMwIAgUCY2IFA25pbAUDbmlsAwkAAAIFAmNjBQJjYwQCY2QDAwUCYkMGBQJiVwUDbmlsCQDOCAIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAXoBBQFBBQNuaWwJAQJhVQIFAmFEBQJiSAkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFNAgUBQQUCYlgFAmNiBQNuaWwFAmNkBwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiYwEOZmluYWxpemVIZWxwZXIABAJiVwkBC3ZhbHVlT3JFbHNlAgkAoAgBBQF3BwQBaQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFqAAAEAmNlCQBlAgUBaQABBAJicwkBAmFkAgUEdGhpcwkBAXgBBQFpBAJibQkBAmFkAgUEdGhpcwUBZgQCYnQJAGQCBQJicwUCYm0EAmJ1CQCaCAIFBHRoaXMFAXEDAwMJAGcCBQZoZWlnaHQFAmJ0CQAAAgUCYnUFBHVuaXQHCQEBIQEFAmJXBwQCY2YJAGQCBQFpAAEEAmNnCQCaCAIFBHRoaXMFAWcEAmNoBAFZBQJjZwMJAAECBQFZAgNJbnQEAmJGBQFZCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFmBQJiRgkAzAgCCQELRGVsZXRlRW50cnkBBQFnBQNuaWwDCQABAgUBWQIEVW5pdAUDbmlsCQACAQILTWF0Y2ggZXJyb3IJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBeAEFAmNmBQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFAXQFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBagUCY2YJAMwIAgkBDEludGVnZXJFbnRyeQIFAXEFAWQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFoAQUBaQUCYm0FA25pbAUCY2gGAwMFAmJXCQAAAgUCYnUFBHVuaXQHCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAXEFAWUFA25pbAYDCQAAAgUCYnUFBHVuaXQJAJQKAgUDbmlsBwMJAAACBQJidQUBZAQCY2kJAKIIAQUBcgQCY2oJAKIIAQUBcwQBWQUCY2kDCQABAgUBWQIEVW5pdAQCY2sJAKIIAQkBAmFHAQUCYUQDCQABAgUCY2sCBFVuaXQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBcQUBZQkAzAgCCQELRGVsZXRlRW50cnkBBQFyCQDMCAIJAQtEZWxldGVFbnRyeQEFAXMFA25pbAYDCQABAgUCY2sCBlN0cmluZwQCY2wFAmNrCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBcgUCY2wFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgMJAAECBQFZAgZTdHJpbmcEAmJIBQFZBAFBCQECYWYBBQJiSAQCY20EAmNrBQJjagMJAAECBQJjawIEVW5pdAkAoggBCQECYUcBCQECYUUBBQFBAwkAAQIFAmNrAgZTdHJpbmcEAmNuBQJjawQCY28JAKIIAQkBAmFNAgkBAmFFAQUBQQUCY24DCQAAAgUCY28FAmNvBAJjcAkA/AcEBQR0aGlzAhNwcm9jZXNzVm90ZUlOVEVSTkFMCQDMCAIFAmJICQDMCAIFAmNuBQNuaWwFA25pbAMJAAACBQJjcAUCY3AFAmNvCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQILTWF0Y2ggZXJyb3IEAmNrBQJjbQMJAAECBQJjawIEVW5pdAQCY3EJAKIIAQkBAmFNAgUCYUQFAmJIBAJjcgUCY3EDCQABAgUCY3ICBFVuaXQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBcQUBZQkAzAgCCQELRGVsZXRlRW50cnkBBQFyCQDMCAIJAQtEZWxldGVFbnRyeQEFAXMFA25pbAYDCQABAgUCY3ICBlN0cmluZwQCYVkFAmNyCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBcgUCYVkJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcwUDbmlsBgkAAgECC01hdGNoIGVycm9yAwkAAQIFAmNrAgZTdHJpbmcEAmNzBQJjawkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXMFAmNzBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IJAAIBAgtNYXRjaCBlcnJvcgMJAAACBQJidQUBZQQCY2kJAKIIAQUBcgQBWQUCY2kDCQABAgUBWQIEVW5pdAQCY2sJAKIIAQkBAmFHAQUCYUQDCQABAgUCY2sCBFVuaXQEAmJWAwUCYlcJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcQkAzAgCCQELRGVsZXRlRW50cnkBBQF3BQNuaWwJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcQkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBAXkBBQJjZQYJAMwIAgkBDEludGVnZXJFbnRyeQIFAXUFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIFAXYFAmJzBQNuaWwEAmN0CQECYUIAAwkAAAIFAmN0BQJjdAkAlAoCBQJiVgYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DCQABAgUCY2sCBlN0cmluZwQCY3UFAmNrCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBcgUCY3UFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgMJAAECBQFZAgZTdHJpbmcEAmJIBQFZBAJjcQkAoggBCQECYU0CBQJhRAUCYkgDCQAAAgUCY3EFAmNxBAJjYQoAAmFjCQD8BwQFBHRoaXMCE3Byb2Nlc3NQb29sSU5URVJOQUwJAMwIAgUCYkgJAMwIAgUCYlcFA25pbAUDbmlsAwkAAQIFAmFjAgdCb29sZWFuBQJhYwkAAgEJAKwCAgkAAwEFAmFjAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuAwkAAAIFAmNhBQJjYQMFAmNhCQCUCgIFA25pbAYEAmNrBQJjcQMJAAECBQJjawIEVW5pdAQCYlYDBQJiVwkAzAgCCQELRGVsZXRlRW50cnkBBQFxCQDMCAIJAQtEZWxldGVFbnRyeQEFAXcJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcgUDbmlsCQDMCAIJAQtEZWxldGVFbnRyeQEFAXEJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAQF5AQUCY2UGCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF1BQFpCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF2BQJicwkAzAgCCQELRGVsZXRlRW50cnkBBQFyBQNuaWwEAmN0CQECYUIAAwkAAAIFAmN0BQJjdAkAlAoCBQJiVgYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4DCQABAgUCY2sCBlN0cmluZwQCY3UFAmNrCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBcgUCY3UFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECC01hdGNoIGVycm9yCQEBVAECFmZpbmFsaXphdGlvbiBpcyBicm9rZW4CYmMBD2ZpbmFsaXplV3JhcHBlcgECY3YEAmN3CQERQGV4dHJOYXRpdmUoMTA2MikBCQERQGV4dHJOYXRpdmUoMTA1MykCBQR0aGlzBQFtBAJjeAoAAmFjCQD8BwQFBHRoaXMCDmZpbmFsaXplSGVscGVyBQNuaWwFA25pbAMJAAECBQJhYwIHQm9vbGVhbgUCYWMJAAIBCQCsAgIJAAMBBQJhYwIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgMJAAACBQJjeAUCY3gDCQEBIQEFAmN4AwkAAAIFAmN2AAAJAQFUAQIeQ3VycmVudCB2b3RpbmcgaXMgbm90IG92ZXIgeWV0BAJjeQkA/AcEBQJjdwIIZmluYWxpemUFA25pbAUDbmlsAwkAAAIFAmN5BQJjeQkAlAoCBQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4EAmN6CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWsFAWMDCQBmAgUCY3oFAmN2BAJjeQkA/AcEBQR0aGlzAg9maW5hbGl6ZVdyYXBwZXIJAMwIAgkAZAIFAmN2AAEFA25pbAUDbmlsAwkAAAIFAmN5BQJjeQkAlAoCBQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJjAQhmaW5hbGl6ZQAEAmN5CQD8BwQFBHRoaXMCD2ZpbmFsaXplV3JhcHBlcgkAzAgCAAAFA25pbAUDbmlsAwkAAAIFAmN5BQJjeQkAlAoCBQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmMBFGNvbnRhaW5zTm9kZVJFQURPTkxZAgJhSAJhTAkAlAoCBQNuaWwJAQJhTgIFAmFIBQJhTAJiYwEKaW5zZXJ0Tm9kZQICYUgCYUwEAmJJCQECYmUBBQJiYwMJAAACBQJiSQUCYkkJAJQKAgkBAmFSAgUCYUgFAmFMBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJjAQpkZWxldGVOb2RlAgJhSAJhTAQCYkkJAQJiZQEFAmJjAwkAAAIFAmJJBQJiSQkAlAoCCQECYVUCBQJhSAUCYUwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmMBGGlzRmluYWxpemF0aW9uSW5Qcm9ncmVzcwAEAmJ1CQCaCAIFBHRoaXMFAXEEAmNBCQECIT0CBQJidQUEdW5pdAkAlAoCBQNuaWwFAmNBAmJjAQpkZWxldGVQb29sAgFDAUQEAmJJAwMJAAACCAUCYmMGY2FsbGVyBQJhaAYJAQJiZQEFAmJjBgkBAVQBAhFQZXJtaXNzaW9uIGRlbmllZAMJAAACBQJiSQUCYkkEAmFIAgVwb29scwQBQQkAlAoCBQFDBQFEBAJhTAkAuQkCCQDMCAIFAUMJAMwIAgUBRAUDbmlsBQFhBAJiVgMJAQJhTgIFAmFIBQJhTAkBAmFVAgUCYUgFAmFMBQNuaWwJAM4IAgkAzAgCCQELRGVsZXRlRW50cnkBCQEBegEFAUEFA25pbAUCYlYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmNCAQJjQwAEAmNEBAFZCQECYVoAAwkAAQIFAVkCCkJ5dGVWZWN0b3IEAmJkBQFZBQJiZAMJAAECBQFZAgRVbml0CAUCY0IPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IJAPQDAwgFAmNCCWJvZHlCeXRlcwkAkQMCCAUCY0IGcHJvb2ZzAAAFAmNEebn+Cw==", "height": 2714643, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 8WrPY7kArxAmyT1mLxCG77qiiDKVNdYBJEknqDegH8wz Next: DTuYfjDy1KPGyDeNqgrLo3sfyUBECphu2Dyu3hMwZQ5A 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+
184191 let poolsListName = "pools"
185192
186193 func getVotesListName (pool) = {
187- let $t058195859 = pool
188- let amountAssetId = $t058195859._1
189- let priceAssetId = $t058195859._2
194+ let $t060226062 = pool
195+ let amountAssetId = $t060226062._1
196+ let priceAssetId = $t060226062._2
190197 makeString(["votes", amountAssetId, priceAssetId], separator)
191198 }
192199
497504 if ((checkTargetEpoch == checkTargetEpoch))
498505 then {
499506 let pool = stringToPool(poolStr)
500- let $t01786217902 = pool
501- let amountAssetId = $t01786217902._1
502- let priceAssetId = $t01786217902._2
507+ let $t01806518105 = pool
508+ let amountAssetId = $t01806518105._1
509+ let priceAssetId = $t01806518105._2
503510 let wxEmission = checkWxEmissionPoolLabel(pool)
504511 let gwxAmountAtEndTotal = {
505512 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)
558565 if ((checkTargetEpoch == checkTargetEpoch))
559566 then {
560567 let pool = stringToPool(poolStr)
561- let $t02025920299 = pool
562- let amountAssetId = $t02025920299._1
563- let priceAssetId = $t02025920299._2
568+ let $t02046220502 = pool
569+ let amountAssetId = $t02046220502._1
570+ let priceAssetId = $t02046220502._2
564571 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
565572 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
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- }
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+ }
584603 else throw("Strict value is not equal to itself.")
585604 }
586605 else throw("Strict value is not equal to itself.")
685704 let actions = if (force)
686705 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced)]
687706 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight)]
688- $Tuple2(actions, true)
707+ let gwxRewardDepositInv = gwxRewardDeposit()
708+ if ((gwxRewardDepositInv == gwxRewardDepositInv))
709+ then $Tuple2(actions, true)
710+ else throw("Strict value is not equal to itself.")
689711 case nextPoolStr: String =>
690712 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
691713 case _ =>
709731 let actions = if (force)
710732 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced), DeleteEntry(keyNextPool)]
711733 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight), DeleteEntry(keyNextPool)]
712- $Tuple2(actions, true)
734+ let gwxRewardDepositInv = gwxRewardDeposit()
735+ if ((gwxRewardDepositInv == gwxRewardDepositInv))
736+ then $Tuple2(actions, true)
737+ else throw("Strict value is not equal to itself.")
713738 case nextPoolStr: String =>
714739 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
715740 case _ =>
827852 }
828853
829854
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-
847855 @Verifier(tx)
848856 func verify () = {
849857 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+
184191 let poolsListName = "pools"
185192
186193 func getVotesListName (pool) = {
187- let $t058195859 = pool
188- let amountAssetId = $t058195859._1
189- let priceAssetId = $t058195859._2
194+ let $t060226062 = pool
195+ let amountAssetId = $t060226062._1
196+ let priceAssetId = $t060226062._2
190197 makeString(["votes", amountAssetId, priceAssetId], separator)
191198 }
192199
193200
194201 func keyListHead (listName) = {
195202 let meta = if ((listName == poolsListName))
196203 then "%s%s"
197204 else "%s%s%s%s"
198205 makeString([meta, listName, "head"], separator)
199206 }
200207
201208
202209 func keyListSize (listName) = {
203210 let meta = if ((listName == poolsListName))
204211 then "%s%s"
205212 else "%s%s%s%s"
206213 makeString([meta, listName, "size"], separator)
207214 }
208215
209216
210217 func keyListPrev (listName,id) = {
211218 let meta = if ((listName == poolsListName))
212219 then "%s%s%s%s"
213220 else "%s%s%s%s%s"
214221 makeString([meta, listName, id, "prev"], separator)
215222 }
216223
217224
218225 func keyListNext (listName,id) = {
219226 let meta = if ((listName == poolsListName))
220227 then "%s%s%s%s"
221228 else "%s%s%s%s%s"
222229 makeString([meta, listName, id, "next"], separator)
223230 }
224231
225232
226233 func containsNode (listName,id) = {
227234 let headOrUnit = getString(this, keyListHead(listName))
228235 let prevOrUnit = getString(this, keyListPrev(listName, id))
229236 let nextOrUnit = getString(this, keyListNext(listName, id))
230237 if (if ((id == valueOrElse(headOrUnit, "")))
231238 then true
232239 else (prevOrUnit != unit))
233240 then true
234241 else (nextOrUnit != unit)
235242 }
236243
237244
238245 func insertNodeActions (listName,id) = {
239246 let headOrUnit = getString(this, keyListHead(listName))
240247 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
241248 let checkNode = if (!(containsNode(listName, id)))
242249 then true
243250 else throwErr("Node exists")
244251 if ((checkNode == checkNode))
245252 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
246253 then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
247254 else nil)) ++ [StringEntry(keyListHead(listName), id)])
248255 else throw("Strict value is not equal to itself.")
249256 }
250257
251258
252259 func deleteNodeActions (listName,id) = {
253260 let headOrUnit = getString(this, keyListHead(listName))
254261 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
255262 let prevOrUnit = getString(this, keyListPrev(listName, id))
256263 let nextOrUnit = getString(this, keyListNext(listName, id))
257264 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
258265 then (nextOrUnit != unit)
259266 else false)
260267 then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
261268 else if ((nextOrUnit != unit))
262269 then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
263270 else if ((prevOrUnit != unit))
264271 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
265272 else if ((id == valueOrElse(headOrUnit, "")))
266273 then [DeleteEntry(keyListHead(listName))]
267274 else throwErr(((("invalid node: " + listName) + ".") + id))))
268275 }
269276
270277
271278 func keyManagerVaultAddress () = "%s__managerVaultAddress"
272279
273280
274281 func keyManagerPublicKey () = "%s__managerPublicKey"
275282
276283
277284 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
278285 case s: String =>
279286 addressFromStringValue(s)
280287 case _ =>
281288 this
282289 }
283290
284291
285292 func managerPublicKeyOrUnit () = {
286293 let managerVaultAddress = getManagerVaultAddressOrThis()
287294 match getString(managerVaultAddress, keyManagerPublicKey()) {
288295 case s: String =>
289296 fromBase58String(s)
290297 case _: Unit =>
291298 unit
292299 case _ =>
293300 throw("Match error")
294301 }
295302 }
296303
297304
298305 func isManager (i) = match managerPublicKeyOrUnit() {
299306 case pk: ByteVector =>
300307 (i.callerPublicKey == pk)
301308 case _: Unit =>
302309 (i.caller == this)
303310 case _ =>
304311 throw("Match error")
305312 }
306313
307314
308315 func mustManager (i) = if (isManager(i))
309316 then true
310317 else throw("permission denied")
311318
312319
313320 func mustThis (i) = if ((i.caller == this))
314321 then true
315322 else throw("permission denied")
316323
317324
318325 @Callable(i)
319326 func getUserGwxAmountAtHeight (userAddress,targetHeight) = {
320327 let boostingContractAddress = valueOrErrorMessage(addressFromString(getStrOrFail(this, keyBoostingContract)), wrapErr("invalid boosting contract address"))
321328 $Tuple2(nil, {
322329 let @ = invoke(boostingContractAddress, "getUserGwxAmountAtHeightREADONLY", [userAddress, targetHeight], nil)
323330 if ($isInstanceOf(@, "Int"))
324331 then @
325332 else throw(($getType(@) + " couldn't be cast to Int"))
326333 })
327334 }
328335
329336
330337
331338 @Callable(i)
332339 func constructor (factoryContract,votingEmissionCandidateContract,boostingContract,stakingContract,epochLength) = {
333340 let checks = [mustManager(i), if ((addressFromString(factoryContract) != unit))
334341 then true
335342 else "invalid factory contract address", if ((addressFromString(votingEmissionCandidateContract) != unit))
336343 then true
337344 else "invalid voting emission candidate contract address", if ((addressFromString(boostingContract) != unit))
338345 then true
339346 else "invalid boosting contract address", if ((addressFromString(stakingContract) != unit))
340347 then true
341348 else "invalid staking contract address", if ((epochLength > 0))
342349 then true
343350 else throwErr("invalid epoch length")]
344351 if ((checks == checks))
345352 then $Tuple2([StringEntry(keyFactoryContract, factoryContract), StringEntry(keyVotingEmissionCandidateContract, votingEmissionCandidateContract), StringEntry(keyBoostingContract, boostingContract), StringEntry(keyStakingContract, stakingContract), IntegerEntry(keyEpochLength, epochLength)], unit)
346353 else throw("Strict value is not equal to itself.")
347354 }
348355
349356
350357
351358 @Callable(i)
352359 func create (amountAssetId,priceAssetId) = {
353360 let checks = [if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionCandidateContract), "")))
354361 then true
355362 else mustManager(i)]
356363 if ((checks == checks))
357364 then {
358365 let pool = $Tuple2(amountAssetId, priceAssetId)
359366 let inListActions = ([BooleanEntry(keyInList(pool), true)] ++ insertNodeActions(poolsListName, poolToString(pool)))
360367 let currentEpochIsNotDefined = (getInteger(this, keyCurrentEpoch) == unit)
361368 let startHeightActions = if (currentEpochIsNotDefined)
362369 then {
363370 let epoch = 0
364371 [IntegerEntry(keyCurrentEpoch, epoch), IntegerEntry(keyStartHeightByEpoch(epoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, height)]
365372 }
366373 else nil
367374 $Tuple2((inListActions ++ startHeightActions), unit)
368375 }
369376 else throw("Strict value is not equal to itself.")
370377 }
371378
372379
373380
374381 @Callable(i)
375382 func vote (amountAssetId,priceAssetId,amount) = {
376383 let pool = $Tuple2(amountAssetId, priceAssetId)
377384 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
378385 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
379386 let epochLength = getIntOrFail(this, keyEpochLength)
380387 let endHeight = (startHeight + epochLength)
381388 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
382389 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
383390 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
384391 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
385392 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
386393 let gwxAmountAtEndTotal = {
387394 let @ = invoke(this, "getUserGwxAmountAtHeight", [toBase58String(i.caller.bytes), endHeight], nil)
388395 if ($isInstanceOf(@, "Int"))
389396 then @
390397 else throw(($getType(@) + " couldn't be cast to Int"))
391398 }
392399 let available = (gwxAmountAtEndTotal - used)
393400 let newVote = (vote + amount)
394401 let wxEmission = checkWxEmissionPoolLabel(pool)
395402 let checks = [if ((getBoolean(keyInList(pool)) != unit))
396403 then true
397404 else throwErr("invalid assets"), if ((endHeight > height))
398405 then true
399406 else throwErr("invalid height"), if ((finalizationStageOrUnit == unit))
400407 then true
401408 else throwErr("finalization in progress"), if ((gwxAmountAtEndTotal > 0))
402409 then true
403410 else throwErr("you do not have gWX"), if (if ((amount > 0))
404411 then (available >= amount)
405412 else false)
406413 then true
407414 else throwErr("invalid amount"), if (wxEmission)
408415 then true
409416 else throwErr("pool hasn't WX_EMISSION label")]
410417 if ((checks == checks))
411418 then {
412419 let votesListName = getVotesListName(pool)
413420 let userAddressStr = toString(i.caller)
414421 let votesListActions = if (containsNode(votesListName, userAddressStr))
415422 then nil
416423 else insertNodeActions(votesListName, userAddressStr)
417424 $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)
418425 }
419426 else throw("Strict value is not equal to itself.")
420427 }
421428
422429
423430
424431 @Callable(i)
425432 func cancelVote (amountAssetId,priceAssetId) = {
426433 let pool = $Tuple2(amountAssetId, priceAssetId)
427434 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
428435 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
429436 let epochLength = getIntOrFail(this, keyEpochLength)
430437 let endHeight = (startHeight + epochLength)
431438 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
432439 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
433440 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
434441 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
435442 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
436443 let checks = [if ((getBoolean(keyInList(pool)) != unit))
437444 then true
438445 else throwErr("invalid assets"), if ((endHeight > height))
439446 then true
440447 else throwErr("invalid height"), if ((finalizationStageOrUnit == unit))
441448 then true
442449 else throwErr("finalization in progress"), if ((vote > 0))
443450 then true
444451 else throwErr("no vote")]
445452 if ((checks == checks))
446453 then {
447454 let votesListName = getVotesListName(pool)
448455 let userAddressStr = toString(i.caller)
449456 $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)
450457 }
451458 else throw("Strict value is not equal to itself.")
452459 }
453460
454461
455462
456463 @Callable(i)
457464 func setEpochLength (newEpochLength) = {
458465 let checks = [mustManager(i), if ((newEpochLength > 0))
459466 then true
460467 else throwErr("invalid epoch length")]
461468 if ((checks == checks))
462469 then $Tuple2([IntegerEntry(keyEpochLengthNew, newEpochLength)], unit)
463470 else throw("Strict value is not equal to itself.")
464471 }
465472
466473
467474
468475 @Callable(i)
469476 func setMaxDepth (newMaxDepth) = {
470477 let checks = [mustManager(i), if ((newMaxDepth > 0))
471478 then true
472479 else throwErr("invalid max depth")]
473480 if ((checks == checks))
474481 then $Tuple2([IntegerEntry(keyMaxDepth, newMaxDepth)], unit)
475482 else throw("Strict value is not equal to itself.")
476483 }
477484
478485
479486
480487 @Callable(i)
481488 func processVoteINTERNAL (poolStr,userAddressStr) = {
482489 let checkCaller = mustThis(i)
483490 if ((checkCaller == checkCaller))
484491 then {
485492 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr(("processVoteINTERNAL: invalid user address " + userAddressStr)))
486493 let epoch = getIntOrFail(this, keyCurrentEpoch)
487494 let epochPrevious = (epoch - 1)
488495 let epochLength = getIntOrFail(this, keyEpochLength)
489496 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
490497 let endHeight = (startHeight + epochLength)
491498 let startHeightPrevious = getIntOrFail(this, keyStartHeightByEpoch(epochPrevious))
492499 let epochLengthPrevious = getIntOrFail(this, keyEpochLengthByEpoch(epochPrevious))
493500 let endHeightPrevious = (startHeightPrevious + epochLengthPrevious)
494501 let checkTargetEpoch = if ((epochPrevious >= 0))
495502 then true
496503 else throwErr("processVoteINTERNAL: invalid previous epoch")
497504 if ((checkTargetEpoch == checkTargetEpoch))
498505 then {
499506 let pool = stringToPool(poolStr)
500- let $t01786217902 = pool
501- let amountAssetId = $t01786217902._1
502- let priceAssetId = $t01786217902._2
507+ let $t01806518105 = pool
508+ let amountAssetId = $t01806518105._1
509+ let priceAssetId = $t01806518105._2
503510 let wxEmission = checkWxEmissionPoolLabel(pool)
504511 let gwxAmountAtEndTotal = {
505512 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)
506513 if ($isInstanceOf(@, "Int"))
507514 then @
508515 else throw(($getType(@) + " couldn't be cast to Int"))
509516 }
510517 let gwxAmountAtEndTotalPrevious = {
511518 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeightPrevious], nil)
512519 if ($isInstanceOf(@, "Int"))
513520 then @
514521 else throw(($getType(@) + " couldn't be cast to Int"))
515522 }
516523 let totalVotes = valueOrElse(getInteger(keyTotalVotes(epoch)), 0)
517524 let votingResult = valueOrElse(getInteger(keyVotingResult(pool, epoch)), 0)
518525 let votePrevious = valueOrErrorMessage(getInteger(keyVote(pool, userAddress, epochPrevious)), wrapErr((((("processVoteINTERNAL " + poolStr) + " ") + userAddressStr) + ": no previous vote")))
519526 let used = valueOrElse(getInteger(this, keyUsed(userAddress, epoch)), 0)
520527 let lpAssetIdStr = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
521528 let votingResultStakedPrevious = valueOrElse(getInteger(keyVotingResultStaked(lpAssetIdStr, epochPrevious)), 0)
522529 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
523530 let stakedByUser = valueOrElse(getInteger(stakingContract, keyStakedByUser(lpAssetIdStr, userAddressStr)), 0)
524531 let votingResultStakedActions = if ((stakedByUser == 0))
525532 then nil
526533 else [IntegerEntry(keyVotingResultStaked(lpAssetIdStr, epochPrevious), (votingResultStakedPrevious + votePrevious))]
527534 let newVote = if ((gwxAmountAtEndTotalPrevious > 0))
528535 then fraction(votePrevious, gwxAmountAtEndTotal, gwxAmountAtEndTotalPrevious)
529536 else 0
530537 let actions = if (if ((newVote > 0))
531538 then wxEmission
532539 else false)
533540 then [IntegerEntry(keyVote(pool, userAddress, epoch), newVote), IntegerEntry(keyTotalVotes(epoch), (totalVotes + newVote)), IntegerEntry(keyVotingResult(pool, epoch), (votingResult + newVote)), IntegerEntry(keyUsed(userAddress, epoch), (used + newVote))]
534541 else deleteNodeActions(getVotesListName(pool), userAddressStr)
535542 $Tuple2((actions ++ votingResultStakedActions), unit)
536543 }
537544 else throw("Strict value is not equal to itself.")
538545 }
539546 else throw("Strict value is not equal to itself.")
540547 }
541548
542549
543550
544551 @Callable(i)
545552 func processPoolINTERNAL (poolStr,force) = {
546553 let checkCaller = mustThis(i)
547554 if ((checkCaller == checkCaller))
548555 then {
549556 let targetEpoch = {
550557 let currentEpoch = getIntOrFail(this, keyCurrentEpoch)
551558 if (force)
552559 then currentEpoch
553560 else (currentEpoch - 1)
554561 }
555562 let checkTargetEpoch = if ((targetEpoch >= 0))
556563 then true
557564 else throwErr("processPoolINTERNAL: invalid target epoch")
558565 if ((checkTargetEpoch == checkTargetEpoch))
559566 then {
560567 let pool = stringToPool(poolStr)
561- let $t02025920299 = pool
562- let amountAssetId = $t02025920299._1
563- let priceAssetId = $t02025920299._2
568+ let $t02046220502 = pool
569+ let amountAssetId = $t02046220502._1
570+ let priceAssetId = $t02046220502._2
564571 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
565572 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
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- }
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+ }
584603 else throw("Strict value is not equal to itself.")
585604 }
586605 else throw("Strict value is not equal to itself.")
587606 }
588607 else throw("Strict value is not equal to itself.")
589608 }
590609
591610
592611
593612 @Callable(i)
594613 func finalizeHelper () = {
595614 let force = valueOrElse(getBoolean(keyFinalizationShouldBeForced), false)
596615 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
597616 let previousEpoch = (epoch - 1)
598617 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
599618 let epochLength = getIntOrFail(this, keyEpochLength)
600619 let endHeight = (startHeight + epochLength)
601620 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
602621 if (if (if ((height >= endHeight))
603622 then (finalizationStageOrUnit == unit)
604623 else false)
605624 then !(force)
606625 else false)
607626 then {
608627 let newEpoch = (epoch + 1)
609628 let newEpochLengthOption = getInteger(this, keyEpochLengthNew)
610629 let newEpochLengthActions = match newEpochLengthOption {
611630 case newEpochLength: Int =>
612631 [IntegerEntry(keyEpochLength, newEpochLength), DeleteEntry(keyEpochLengthNew)]
613632 case _: Unit =>
614633 nil
615634 case _ =>
616635 throw("Match error")
617636 }
618637 $Tuple2(([IntegerEntry(keyStartHeightByEpoch(newEpoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpoch, newEpoch), IntegerEntry(keyFinalizationStage, finalizationStageTotal), IntegerEntry(keyEpochLengthByEpoch(epoch), epochLength)] ++ newEpochLengthActions), true)
619638 }
620639 else if (if (force)
621640 then (finalizationStageOrUnit == unit)
622641 else false)
623642 then $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares)], true)
624643 else if ((finalizationStageOrUnit == unit))
625644 then $Tuple2(nil, false)
626645 else if ((finalizationStageOrUnit == finalizationStageTotal))
627646 then {
628647 let poolOrUnit = getString(keyNextPool)
629648 let userOrUnit = getString(keyNextUser)
630649 match poolOrUnit {
631650 case _: Unit =>
632651 match getString(keyListHead(poolsListName)) {
633652 case _: Unit =>
634653 $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
635654 case poolsHeadStr: String =>
636655 $Tuple2([StringEntry(keyNextPool, poolsHeadStr)], true)
637656 case _ =>
638657 throw("Match error")
639658 }
640659 case poolStr: String =>
641660 let pool = stringToPool(poolStr)
642661 let nextUserOrUnit = match userOrUnit {
643662 case _: Unit =>
644663 getString(keyListHead(getVotesListName(pool)))
645664 case user: String =>
646665 let next = getString(keyListNext(getVotesListName(pool), user))
647666 if ((next == next))
648667 then {
649668 let processVoteInv = invoke(this, "processVoteINTERNAL", [poolStr, user], nil)
650669 if ((processVoteInv == processVoteInv))
651670 then next
652671 else throw("Strict value is not equal to itself.")
653672 }
654673 else throw("Strict value is not equal to itself.")
655674 case _ =>
656675 throw("Match error")
657676 }
658677 match nextUserOrUnit {
659678 case _: Unit =>
660679 let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
661680 match nextPoolOrUnit {
662681 case _: Unit =>
663682 $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
664683 case s: String =>
665684 $Tuple2([StringEntry(keyNextPool, s), DeleteEntry(keyNextUser)], true)
666685 case _ =>
667686 throw("Match error")
668687 }
669688 case nextUser: String =>
670689 $Tuple2([StringEntry(keyNextUser, nextUser)], true)
671690 case _ =>
672691 throw("Match error")
673692 }
674693 case _ =>
675694 throw("Match error")
676695 }
677696 }
678697 else if ((finalizationStageOrUnit == finalizationStageShares))
679698 then {
680699 let poolOrUnit = getString(keyNextPool)
681700 match poolOrUnit {
682701 case _: Unit =>
683702 match getString(keyListHead(poolsListName)) {
684703 case _: Unit =>
685704 let actions = if (force)
686705 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced)]
687706 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight)]
688- $Tuple2(actions, true)
707+ let gwxRewardDepositInv = gwxRewardDeposit()
708+ if ((gwxRewardDepositInv == gwxRewardDepositInv))
709+ then $Tuple2(actions, true)
710+ else throw("Strict value is not equal to itself.")
689711 case nextPoolStr: String =>
690712 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
691713 case _ =>
692714 throw("Match error")
693715 }
694716 case poolStr: String =>
695717 let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
696718 if ((nextPoolOrUnit == nextPoolOrUnit))
697719 then {
698720 let r = {
699721 let @ = invoke(this, "processPoolINTERNAL", [poolStr, force], nil)
700722 if ($isInstanceOf(@, "Boolean"))
701723 then @
702724 else throw(($getType(@) + " couldn't be cast to Boolean"))
703725 }
704726 if ((r == r))
705727 then if (r)
706728 then $Tuple2(nil, true)
707729 else match nextPoolOrUnit {
708730 case _: Unit =>
709731 let actions = if (force)
710732 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced), DeleteEntry(keyNextPool)]
711733 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight), DeleteEntry(keyNextPool)]
712- $Tuple2(actions, true)
734+ let gwxRewardDepositInv = gwxRewardDeposit()
735+ if ((gwxRewardDepositInv == gwxRewardDepositInv))
736+ then $Tuple2(actions, true)
737+ else throw("Strict value is not equal to itself.")
713738 case nextPoolStr: String =>
714739 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
715740 case _ =>
716741 throw("Match error")
717742 }
718743 else throw("Strict value is not equal to itself.")
719744 }
720745 else throw("Strict value is not equal to itself.")
721746 case _ =>
722747 throw("Match error")
723748 }
724749 }
725750 else throwErr("finalization is broken")
726751 }
727752
728753
729754
730755 @Callable(i)
731756 func finalizeWrapper (counter) = {
732757 let votingEmissionRateContract = addressFromStringValue(getStringValue(this, keyVotingEmissionRateContract))
733758 let result = {
734759 let @ = invoke(this, "finalizeHelper", nil, nil)
735760 if ($isInstanceOf(@, "Boolean"))
736761 then @
737762 else throw(($getType(@) + " couldn't be cast to Boolean"))
738763 }
739764 if ((result == result))
740765 then if (!(result))
741766 then if ((counter == 0))
742767 then throwErr("Current voting is not over yet")
743768 else {
744769 let inv = invoke(votingEmissionRateContract, "finalize", nil, nil)
745770 if ((inv == inv))
746771 then $Tuple2(nil, unit)
747772 else throw("Strict value is not equal to itself.")
748773 }
749774 else {
750775 let maxDepth = valueOrElse(getInteger(this, keyMaxDepth), maxDepthDefault)
751776 if ((maxDepth > counter))
752777 then {
753778 let inv = invoke(this, "finalizeWrapper", [(counter + 1)], nil)
754779 if ((inv == inv))
755780 then $Tuple2(nil, unit)
756781 else throw("Strict value is not equal to itself.")
757782 }
758783 else $Tuple2(nil, unit)
759784 }
760785 else throw("Strict value is not equal to itself.")
761786 }
762787
763788
764789
765790 @Callable(i)
766791 func finalize () = {
767792 let inv = invoke(this, "finalizeWrapper", [0], nil)
768793 if ((inv == inv))
769794 then $Tuple2(nil, unit)
770795 else throw("Strict value is not equal to itself.")
771796 }
772797
773798
774799
775800 @Callable(i)
776801 func containsNodeREADONLY (listName,id) = $Tuple2(nil, containsNode(listName, id))
777802
778803
779804
780805 @Callable(i)
781806 func insertNode (listName,id) = {
782807 let checkCaller = mustManager(i)
783808 if ((checkCaller == checkCaller))
784809 then $Tuple2(insertNodeActions(listName, id), unit)
785810 else throw("Strict value is not equal to itself.")
786811 }
787812
788813
789814
790815 @Callable(i)
791816 func deleteNode (listName,id) = {
792817 let checkCaller = mustManager(i)
793818 if ((checkCaller == checkCaller))
794819 then $Tuple2(deleteNodeActions(listName, id), unit)
795820 else throw("Strict value is not equal to itself.")
796821 }
797822
798823
799824
800825 @Callable(i)
801826 func isFinalizationInProgress () = {
802827 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
803828 let finalizationInProgress = (finalizationStageOrUnit != unit)
804829 $Tuple2(nil, finalizationInProgress)
805830 }
806831
807832
808833
809834 @Callable(i)
810835 func deletePool (amountAssetId,priceAssetId) = {
811836 let checkCaller = if (if ((i.caller == factoryContract))
812837 then true
813838 else mustManager(i))
814839 then true
815840 else throwErr("Permission denied")
816841 if ((checkCaller == checkCaller))
817842 then {
818843 let listName = "pools"
819844 let pool = $Tuple2(amountAssetId, priceAssetId)
820845 let id = makeString([amountAssetId, priceAssetId], separator)
821846 let actions = if (containsNode(listName, id))
822847 then deleteNodeActions(listName, id)
823848 else nil
824849 ([DeleteEntry(keyInList(pool))] ++ actions)
825850 }
826851 else throw("Strict value is not equal to itself.")
827852 }
828853
829854
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-
847855 @Verifier(tx)
848856 func verify () = {
849857 let targetPublicKey = match managerPublicKeyOrUnit() {
850858 case pk: ByteVector =>
851859 pk
852860 case _: Unit =>
853861 tx.senderPublicKey
854862 case _ =>
855863 throw("Match error")
856864 }
857865 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
858866 }
859867

github/deemru/w8io/026f985 
322.67 ms