tx · Gf6pwhR3UYk3PnoMQGNGJTH1ioev6wyS3FTEY5qj9AC3

3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr:  -0.02400000 Waves

2024.01.15 09:06 [2932251] smart account 3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr > SELF 0.00000000 Waves

{ "type": 13, "id": "Gf6pwhR3UYk3PnoMQGNGJTH1ioev6wyS3FTEY5qj9AC3", "fee": 2400000, "feeAssetId": null, "timestamp": 1705298796966, "version": 2, "chainId": 84, "sender": "3N9Zi6AcWcGbM23jQJ4fnzFsoHoTsxYDznr", "senderPublicKey": "GFbasS3jufhZkK4xR7tdTjjnP8K33KvJFEDHRtxXDkaJ", "proofs": [ "S2nx2cF7w8v33n76tMqjnrSXUeUFDfWyQ3B8ULRq8Uy4VLU1KHyUcaJ6rBanLmuX5SM4q9yQkRvgsmQKKWW7PaJ" ], "script": "base64:BgLnFwgCEgQKAggBEgcKBQgICAgBEgQKAggIEgUKAwgIARIECgIICBIDCgEBEgMKAQESBAoCCAgSBAoCCAQSABIDCgEBEgASBAoCCAgSBAoCCAgSBAoCCAgSABIECgIICCIJc2VwYXJhdG9yIg5wb29sV2VpZ2h0TXVsdCIPbWF4RGVwdGhEZWZhdWx0IhZmaW5hbGl6YXRpb25TdGFnZVRvdGFsIhdmaW5hbGl6YXRpb25TdGFnZVNoYXJlcyIOa2V5RXBvY2hMZW5ndGgiEWtleUVwb2NoTGVuZ3RoTmV3IhVrZXlFcG9jaExlbmd0aEJ5RXBvY2giBWVwb2NoIg9rZXlDdXJyZW50RXBvY2giC2tleU1heERlcHRoIiJrZXlWb3RpbmdFbWlzc2lvbkNhbmRpZGF0ZUNvbnRyYWN0Ih1rZXlWb3RpbmdFbWlzc2lvblJhdGVDb250cmFjdCISa2V5RmFjdG9yeUNvbnRyYWN0IhNrZXlCb29zdGluZ0NvbnRyYWN0IhJrZXlTdGFraW5nQ29udHJhY3QiFmtleUFzc2V0c1N0b3JlQ29udHJhY3QiFGtleUZpbmFsaXphdGlvblN0YWdlIgtrZXlOZXh0UG9vbCILa2V5TmV4dFVzZXIiDmtleVN0YXJ0SGVpZ2h0IhFrZXlDdXJyZW50RXBvY2hVaSIQa2V5U3RhcnRIZWlnaHRVaSIda2V5RmluYWxpemF0aW9uU2hvdWxkQmVGb3JjZWQiFWtleVN0YXJ0SGVpZ2h0QnlFcG9jaCIMa2V5RmluYWxpemVkIglrZXlJbkxpc3QiBHBvb2wiCyR0MDE4NjkxOTA5Ig1hbW91bnRBc3NldElkIgxwcmljZUFzc2V0SWQiB2tleVVzZWQiB2FkZHJlc3MiB2tleVZvdGUiCyR0MDIxODMyMjIzIg9rZXlWb3RpbmdSZXN1bHQiCyR0MDI0MDUyNDQ1IhVrZXlWb3RpbmdSZXN1bHRTdGFrZWQiDGxwQXNzZXRJZFN0ciIMa2V5UG9vbFNoYXJlIgskdDAyNzY2MjgwNiINa2V5VG90YWxWb3RlcyIPa2V5U3Rha2VkQnlVc2VyIg51c2VyQWRkcmVzc1N0ciIHd3JhcEVyciIDbXNnIgh0aHJvd0VyciIOZ2V0VmFsdWVPckZhaWwiA2tleSIEdHlwZSIFZXJyb3IiByRtYXRjaDAiA3N0ciIDaW50IgxnZXRTdHJPckZhaWwiAUAiDGdldEludE9yRmFpbCIMcG9vbFRvU3RyaW5nIgxzdHJpbmdUb1Bvb2wiBXBhcnRzIg9mYWN0b3J5Q29udHJhY3QiGklkeEZhY3RvcnlDZmdHd3hSZXdhcmREYXBwIg1rZXlGYWN0b3J5Q2ZnIhRyZWFkRmFjdG9yeUNmZ09yRmFpbCIHZmFjdG9yeSIZZ2V0R3d4UmV3YXJkQWRkcmVzc09yRmFpbCIKZmFjdG9yeUNmZyIWZ2V0THBBc3NldEJ5UG9vbEFzc2V0cyIfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZCIMYmFzZUFzc2V0U3RyIilrZXlNYXBwaW5nUG9vbEFzc2V0c1RvUG9vbENvbnRyYWN0QWRkcmVzcyIYaW50ZXJuYWxBbW91bnRBc3NldElkU3RyIhdpbnRlcm5hbFByaWNlQXNzZXRJZFN0ciIfa2V5TWFwcGluZ1Bvb2xDb250cmFjdFRvTFBBc3NldCITcG9vbENvbnRyYWN0QWRkcmVzcyIVYW1vdW50QXNzZXRJbnRlcm5hbElkIhRwcmljZUFzc2V0SW50ZXJuYWxJZCIJbHBBc3NldElkIhhjaGVja1d4RW1pc3Npb25Qb29sTGFiZWwiCyR0MDU2NDY1Njg2IhBnd3hSZXdhcmREZXBvc2l0IhJnd3hSZXdhcmRzQ29udHJhY3QiDXBvb2xzTGlzdE5hbWUiEGdldFZvdGVzTGlzdE5hbWUiCyR0MDYxMDM2MTQzIgtrZXlMaXN0SGVhZCIIbGlzdE5hbWUiBG1ldGEiC2tleUxpc3RTaXplIgtrZXlMaXN0UHJldiICaWQiC2tleUxpc3ROZXh0Igxjb250YWluc05vZGUiCmhlYWRPclVuaXQiCnByZXZPclVuaXQiCm5leHRPclVuaXQiEWluc2VydE5vZGVBY3Rpb25zIghsaXN0U2l6ZSIJY2hlY2tOb2RlIhFkZWxldGVOb2RlQWN0aW9ucyIWa2V5TWFuYWdlclZhdWx0QWRkcmVzcyITa2V5TWFuYWdlclB1YmxpY0tleSIcZ2V0TWFuYWdlclZhdWx0QWRkcmVzc09yVGhpcyIBcyIWbWFuYWdlclB1YmxpY0tleU9yVW5pdCITbWFuYWdlclZhdWx0QWRkcmVzcyIJaXNNYW5hZ2VyIgFpIgJwayILbXVzdE1hbmFnZXIiCG11c3RUaGlzIgt1c2VyQWRkcmVzcyIMdGFyZ2V0SGVpZ2h0Ihdib29zdGluZ0NvbnRyYWN0QWRkcmVzcyIfdm90aW5nRW1pc3Npb25DYW5kaWRhdGVDb250cmFjdCIQYm9vc3RpbmdDb250cmFjdCIPc3Rha2luZ0NvbnRyYWN0IgtlcG9jaExlbmd0aCIGY2hlY2tzIg1pbkxpc3RBY3Rpb25zIhhjdXJyZW50RXBvY2hJc05vdERlZmluZWQiEnN0YXJ0SGVpZ2h0QWN0aW9ucyIGYW1vdW50IgtzdGFydEhlaWdodCIJZW5kSGVpZ2h0IhdmaW5hbGl6YXRpb25TdGFnZU9yVW5pdCIEdXNlZCIEdm90ZSIKcG9vbFJlc3VsdCIKdG90YWxWb3RlcyITZ3d4QW1vdW50QXRFbmRUb3RhbCIJYXZhaWxhYmxlIgduZXdWb3RlIgp3eEVtaXNzaW9uIg12b3Rlc0xpc3ROYW1lIhB2b3Rlc0xpc3RBY3Rpb25zIg5uZXdFcG9jaExlbmd0aCILbmV3TWF4RGVwdGgiB3Bvb2xTdHIiC2NoZWNrQ2FsbGVyIg1lcG9jaFByZXZpb3VzIhNzdGFydEhlaWdodFByZXZpb3VzIhNlcG9jaExlbmd0aFByZXZpb3VzIhFlbmRIZWlnaHRQcmV2aW91cyIQY2hlY2tUYXJnZXRFcG9jaCINJHQwMTgxNDYxODE4NiIbZ3d4QW1vdW50QXRFbmRUb3RhbFByZXZpb3VzIgx2b3RpbmdSZXN1bHQiDHZvdGVQcmV2aW91cyIadm90aW5nUmVzdWx0U3Rha2VkUHJldmlvdXMiDHN0YWtlZEJ5VXNlciIZdm90aW5nUmVzdWx0U3Rha2VkQWN0aW9ucyILYmFsYW5jZUlzT2siB2FjdGlvbnMiBWZvcmNlIgt0YXJnZXRFcG9jaCIMY3VycmVudEVwb2NoIg0kdDAyMDcyMjIwNzYyIgFyIhNhc3NldHNTdG9yZUNvbnRyYWN0IhNhbW91bnRBc3NldFZlcmlmaWVkIhJwcmljZUFzc2V0VmVyaWZpZWQiEHNldFd4RW1pc3Npb25JbnYiBXNoYXJlIg9tb2RpZnlXZWlnaHRJbnYiDXByZXZpb3VzRXBvY2giCG5ld0Vwb2NoIhRuZXdFcG9jaExlbmd0aE9wdGlvbiIVbmV3RXBvY2hMZW5ndGhBY3Rpb25zIgpwb29sT3JVbml0Igp1c2VyT3JVbml0IgckbWF0Y2gxIgxwb29sc0hlYWRTdHIiDm5leHRVc2VyT3JVbml0IgR1c2VyIgRuZXh0Ig5wcm9jZXNzVm90ZUludiIObmV4dFBvb2xPclVuaXQiByRtYXRjaDIiCG5leHRVc2VyIhNnd3hSZXdhcmREZXBvc2l0SW52IgtuZXh0UG9vbFN0ciIHY291bnRlciIadm90aW5nRW1pc3Npb25SYXRlQ29udHJhY3QiBnJlc3VsdCIDaW52IghtYXhEZXB0aCIWZmluYWxpemF0aW9uSW5Qcm9ncmVzcyICdHgiBnZlcmlmeSIPdGFyZ2V0UHVibGljS2V5QAABYQICX18AAWIAgMLXLwABYwAKAAFkAAAAAWUAAQABZgkAuQkCCQDMCAICAiVzCQDMCAICC2Vwb2NoTGVuZ3RoBQNuaWwFAWEAAWcJALkJAgkAzAgCAgQlcyVzCQDMCAICEGVwb2NoTGVuZ3RoX19uZXcFA25pbAUBYQEBaAEBaQkAuQkCCQDMCAICBCVzJWQJAMwIAgILZXBvY2hMZW5ndGgJAMwIAgkApAMBBQFpBQNuaWwFAWEAAWoJALkJAgkAzAgCAgIlcwkAzAgCAgxjdXJyZW50RXBvY2gFA25pbAUBYQABawkAuQkCCQDMCAICAiVzCQDMCAICCG1heERlcHRoBQNuaWwFAWEAAWwJALkJAgkAzAgCAgIlcwkAzAgCAh92b3RpbmdFbWlzc2lvbkNhbmRpZGF0ZUNvbnRyYWN0BQNuaWwFAWEAAW0JALkJAgkAzAgCAgIlcwkAzAgCAhp2b3RpbmdFbWlzc2lvblJhdGVDb250cmFjdAUDbmlsBQFhAAFuCQC5CQIJAMwIAgICJXMJAMwIAgIPZmFjdG9yeUNvbnRyYWN0BQNuaWwFAWEAAW8JALkJAgkAzAgCAgIlcwkAzAgCAhBib29zdGluZ0NvbnRyYWN0BQNuaWwFAWEAAXAJALkJAgkAzAgCAgIlcwkAzAgCAg9zdGFraW5nQ29udHJhY3QFA25pbAUBYQABcQkAuQkCCQDMCAICAiVzCQDMCAICE2Fzc2V0c1N0b3JlQ29udHJhY3QFA25pbAUBYQABcgkAuQkCCQDMCAICAiVzCQDMCAICEWZpbmFsaXphdGlvblN0YWdlBQNuaWwFAWEAAXMJALkJAgkAzAgCAgIlcwkAzAgCAghuZXh0UG9vbAUDbmlsBQFhAAF0CQC5CQIJAMwIAgICJXMJAMwIAgIIbmV4dFVzZXIFA25pbAUBYQABdQkAuQkCCQDMCAICAiVzCQDMCAICC3N0YXJ0SGVpZ2h0BQNuaWwFAWEAAXYJALkJAgkAzAgCAgIlcwkAzAgCAg5jdXJyZW50RXBvY2hVaQUDbmlsBQFhAAF3CQC5CQIJAMwIAgICJXMJAMwIAgINc3RhcnRIZWlnaHRVaQUDbmlsBQFhAAF4CQC5CQIJAMwIAgICJXMJAMwIAgIFZm9yY2UFA25pbAUBYQEBeQEBaQkAuQkCCQDMCAICBCVzJWQJAMwIAgILc3RhcnRIZWlnaHQJAMwIAgkApAMBBQFpBQNuaWwFAWEBAXoBAWkJALkJAgkAzAgCAgQlcyVkCQDMCAICCWZpbmFsaXplZAkAzAgCCQCkAwEFAWkFA25pbAUBYQEBQQEBQgQBQwUBQgQBRAgFAUMCXzEEAUUIBQFDAl8yCQC5CQIJAMwIAgIGJXMlcyVzCQDMCAICBmluTGlzdAkAzAgCBQFECQDMCAIFAUUFA25pbAUBYQEBRgIBRwFpCQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICBHVzZWQJAMwIAgkApQgBBQFHCQDMCAIJAKQDAQUBaQUDbmlsBQFhAQFIAwFCAUcBaQQBSQUBQgQBRAgFAUkCXzEEAUUIBQFJAl8yCQC5CQIJAMwIAgIKJXMlcyVzJXMlZAkAzAgCAgR2b3RlCQDMCAIFAUQJAMwIAgUBRQkAzAgCCQClCAEFAUcJAMwIAgkApAMBBQFpBQNuaWwFAWEBAUoCAUIBaQQBSwUBQgQBRAgFAUsCXzEEAUUIBQFLAl8yCQC5CQIJAMwIAgIIJXMlcyVzJWQJAMwIAgIMdm90aW5nUmVzdWx0CQDMCAIFAUQJAMwIAgUBRQkAzAgCCQCkAwEFAWkFA25pbAUBYQEBTAIBTQFpCQC5CQIJAMwIAgIGJXMlcyVkCQDMCAICEnZvdGluZ1Jlc3VsdFN0YWtlZAkAzAgCBQFNCQDMCAIJAKQDAQUBaQUDbmlsBQFhAQFOAgFCAWkEAU8FAUIEAUQIBQFPAl8xBAFFCAUBTwJfMgkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICCXBvb2xTaGFyZQkAzAgCBQFECQDMCAIFAUUJAMwIAgkApAMBBQFpBQNuaWwFAWEBAVABAWkJALkJAgkAzAgCAgQlcyVkCQDMCAICCnRvdGFsVm90ZXMJAMwIAgkApAMBBQFpBQNuaWwFAWEBAVECAU0BUgkAuQkCCQDMCAICBiVzJXMlcwkAzAgCAgZzdGFrZWQJAMwIAgUBUgkAzAgCBQFNBQNuaWwFAWEBAVMBAVQJALkJAgkAzAgCAhV2b3RpbmdfZW1pc3Npb24ucmlkZToJAMwIAgUBVAUDbmlsAgEgAQFVAQFUCQACAQkBAVMBBQFUAQFWAwFHAVcBWAQBWQkBAVMBCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAUcJAMwIAgIBLgkAzAgCBQFXCQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgAJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgQBWgUBWAMJAAECBQFaAgZTdHJpbmcEAmFhBQFaCQCdCAIFAUcFAVcDCQABAgUBWgIDSW50BAJhYgUBWgkAmggCBQFHBQFXCQEBVQECEmludmFsaWQgZW50cnkgdHlwZQUBWQECYWMCAUcBVwoAAmFkCQEBVgMFAUcFAVcCAAMJAAECBQJhZAIGU3RyaW5nBQJhZAkAAgEJAKwCAgkAAwEFAmFkAhsgY291bGRuJ3QgYmUgY2FzdCB0byBTdHJpbmcBAmFlAgFHAVcKAAJhZAkBAVYDBQFHBQFXAAADCQABAgUCYWQCA0ludAUCYWQJAAIBCQCsAgIJAAMBBQJhZAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AQJhZgEBQgkArAICCQCsAgIIBQFCAl8xBQFhCAUBQgJfMgECYWcBAmFhBAJhaAkAtQkCBQJhYQUBYQMJAAACCQCQAwEFAmFoAAIJAJQKAgkAkQMCBQJhaAAACQCRAwIFAmFoAAEJAQFVAQITaW52YWxpZCBwb29sIHN0cmluZwACYWkJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQJhYwIFBHRoaXMFAW4AAmFqAAoBAmFrAAIRJXNfX2ZhY3RvcnlDb25maWcBAmFsAQJhbQkAtQkCCQECYWMCBQJhbQkBAmFrAAUBYQECYW4BAmFvCQERQGV4dHJOYXRpdmUoMTA2MikBCQCRAwIFAmFvBQJhagECYXACAUQBRQoBAmFxAQJhcgkArAICAiglcyVzJXNfX21hcHBpbmdzX19iYXNlQXNzZXQyaW50ZXJuYWxJZF9fBQJhcgoBAmFzAgJhdAJhdQkArAICCQCsAgIJAKwCAgkArAICAgolZCVkJXMlc19fCQCkAwEFAmF0AgJfXwkApAMBBQJhdQIjX19tYXBwaW5nc19fcG9vbEFzc2V0czJQb29sQ29udHJhY3QKAQJhdgECYXcJAKwCAgkArAICAgglcyVzJXNfXwUCYXcCIF9fbWFwcGluZ3NfX3Bvb2xDb250cmFjdDJMcEFzc2V0BAJheAkBAmFlAgUCYWkJAQJhcQEFAUQEAmF5CQECYWUCBQJhaQkBAmFxAQUBRQQCYXcJAQJhYwIFAmFpCQECYXMCBQJheAUCYXkEAmF6CQECYWMCBQJhaQkBAmF2AQUCYXcFAmF6AQJhQQEBQgQCYUIFAUIEAUQIBQJhQgJfMQQBRQgFAmFCAl8yCgACYWQJAPwHBAUCYWkCGGNoZWNrV3hFbWlzc2lvblBvb2xMYWJlbAkAzAgCBQFECQDMCAIFAUUFA25pbAUDbmlsAwkAAQIFAmFkAgdCb29sZWFuBQJhZAkAAgEJAKwCAgkAAwEFAmFkAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuAQJhQwAEAmFvCQECYWwBBQJhaQQCYUQJAQJhbgEFAmFvCQD8BwQFAmFEAgdkZXBvc2l0BQNuaWwFA25pbAACYUUCBXBvb2xzAQJhRgEBQgQCYUcFAUIEAUQIBQJhRwJfMQQBRQgFAmFHAl8yCQC5CQIJAMwIAgIFdm90ZXMJAMwIAgUBRAkAzAgCBQFFBQNuaWwFAWEBAmFIAQJhSQQCYUoDCQAAAgUCYUkFAmFFAgQlcyVzAgglcyVzJXMlcwkAuQkCCQDMCAIFAmFKCQDMCAIFAmFJCQDMCAICBGhlYWQFA25pbAUBYQECYUsBAmFJBAJhSgMJAAACBQJhSQUCYUUCBCVzJXMCCCVzJXMlcyVzCQC5CQIJAMwIAgUCYUoJAMwIAgUCYUkJAMwIAgIEc2l6ZQUDbmlsBQFhAQJhTAICYUkCYU0EAmFKAwkAAAIFAmFJBQJhRQIIJXMlcyVzJXMCCiVzJXMlcyVzJXMJALkJAgkAzAgCBQJhSgkAzAgCBQJhSQkAzAgCBQJhTQkAzAgCAgRwcmV2BQNuaWwFAWEBAmFOAgJhSQJhTQQCYUoDCQAAAgUCYUkFAmFFAgglcyVzJXMlcwIKJXMlcyVzJXMlcwkAuQkCCQDMCAIFAmFKCQDMCAIFAmFJCQDMCAIFAmFNCQDMCAICBG5leHQFA25pbAUBYQECYU8CAmFJAmFNBAJhUAkAnQgCBQR0aGlzCQECYUgBBQJhSQQCYVEJAJ0IAgUEdGhpcwkBAmFMAgUCYUkFAmFNBAJhUgkAnQgCBQR0aGlzCQECYU4CBQJhSQUCYU0DAwkAAAIFAmFNCQELdmFsdWVPckVsc2UCBQJhUAIABgkBAiE9AgUCYVEFBHVuaXQGCQECIT0CBQJhUgUEdW5pdAECYVMCAmFJAmFNBAJhUAkAnQgCBQR0aGlzCQECYUgBBQJhSQQCYVQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmFLAQUCYUkAAAQCYVUDCQEBIQEJAQJhTwIFAmFJBQJhTQYJAQFVAQILTm9kZSBleGlzdHMDCQAAAgUCYVUFAmFVCQDOCAIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmFLAQUCYUkJAGQCBQJhVAABBQNuaWwDCQECIT0CBQJhUAUEdW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQECYU4CBQJhSQUCYU0JAQV2YWx1ZQEFAmFQCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhTAIFAmFJCQEFdmFsdWUBBQJhUAUCYU0FA25pbAUDbmlsCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhSAEFAmFJBQJhTQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJhVgICYUkCYU0EAmFQCQCdCAIFBHRoaXMJAQJhSAEFAmFJBAJhVAkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYUsBBQJhSQAABAJhUQkAnQgCBQR0aGlzCQECYUwCBQJhSQUCYU0EAmFSCQCdCAIFBHRoaXMJAQJhTgIFAmFJBQJhTQkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQECYUsBBQJhSQkAZQIFAmFUAAEFA25pbAMDCQECIT0CBQJhUQUEdW5pdAkBAiE9AgUCYVIFBHVuaXQHCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhTgIFAmFJCQEFdmFsdWUBBQJhUQkBBXZhbHVlAQUCYVIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFMAgUCYUkJAQV2YWx1ZQEFAmFSCQEFdmFsdWUBBQJhUQkAzAgCCQELRGVsZXRlRW50cnkBCQECYUwCBQJhSQUCYU0JAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFOAgUCYUkFAmFNBQNuaWwDCQECIT0CBQJhUgUEdW5pdAkAzAgCCQELU3RyaW5nRW50cnkCCQECYUgBBQJhSQkBBXZhbHVlAQUCYVIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFOAgUCYUkFAmFNCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhTAIFAmFJCQEFdmFsdWUBBQJhUgUDbmlsAwkBAiE9AgUCYVEFBHVuaXQJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmFMAgUCYUkFAmFNCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhTgIFAmFJCQEFdmFsdWUBBQJhUQUDbmlsAwkAAAIFAmFNCQELdmFsdWVPckVsc2UCBQJhUAIACQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhSAEFAmFJBQNuaWwJAQFVAQkArAICCQCsAgIJAKwCAgIOaW52YWxpZCBub2RlOiAFAmFJAgEuBQJhTQECYVcAAhclc19fbWFuYWdlclZhdWx0QWRkcmVzcwECYVgAAhQlc19fbWFuYWdlclB1YmxpY0tleQECYVkABAFaCQCiCAEJAQJhVwADCQABAgUBWgIGU3RyaW5nBAJhWgUBWgkBEUBleHRyTmF0aXZlKDEwNjIpAQUCYVoFBHRoaXMBAmJhAAQCYmIJAQJhWQAEAVoJAJ0IAgUCYmIJAQJhWAADCQABAgUBWgIGU3RyaW5nBAJhWgUBWgkA2QQBBQJhWgMJAAECBQFaAgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmJjAQJiZAQBWgkBAmJhAAMJAAECBQFaAgpCeXRlVmVjdG9yBAJiZQUBWgkAAAIIBQJiZA9jYWxsZXJQdWJsaWNLZXkFAmJlAwkAAQIFAVoCBFVuaXQJAAACCAUCYmQGY2FsbGVyBQR0aGlzCQACAQILTWF0Y2ggZXJyb3IBAmJmAQJiZAMJAQJiYwEFAmJkBgkAAgECEXBlcm1pc3Npb24gZGVuaWVkAQJiZwECYmQDCQAAAggFAmJkBmNhbGxlcgUEdGhpcwYJAAIBAhFwZXJtaXNzaW9uIGRlbmllZBECYmQBGGdldFVzZXJHd3hBbW91bnRBdEhlaWdodAICYmgCYmkEAmJqCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkBAmFjAgUEdGhpcwUBbwkBAVMBAiFpbnZhbGlkIGJvb3N0aW5nIGNvbnRyYWN0IGFkZHJlc3MJAJQKAgUDbmlsCgACYWQJAPwHBAUCYmoCIGdldFVzZXJHd3hBbW91bnRBdEhlaWdodFJFQURPTkxZCQDMCAIFAmJoCQDMCAIFAmJpBQNuaWwFA25pbAMJAAECBQJhZAIDSW50BQJhZAkAAgEJAKwCAgkAAwEFAmFkAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQCYmQBC2NvbnN0cnVjdG9yBQJhaQJiawJibAJibQJibgQCYm8JAMwIAgkBAmJmAQUCYmQJAMwIAgMJAQIhPQIJAKYIAQUCYWkFBHVuaXQGAiBpbnZhbGlkIGZhY3RvcnkgY29udHJhY3QgYWRkcmVzcwkAzAgCAwkBAiE9AgkApggBBQJiawUEdW5pdAYCMmludmFsaWQgdm90aW5nIGVtaXNzaW9uIGNhbmRpZGF0ZSBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQECIT0CCQCmCAEFAmJsBQR1bml0BgIhaW52YWxpZCBib29zdGluZyBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQECIT0CCQCmCAEFAmJtBQR1bml0BgIgaW52YWxpZCBzdGFraW5nIGNvbnRyYWN0IGFkZHJlc3MJAMwIAgMJAGYCBQJibgAABgkBAVUBAhRpbnZhbGlkIGVwb2NoIGxlbmd0aAUDbmlsAwkAAAIFAmJvBQJibwkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAW4FAmFpCQDMCAIJAQtTdHJpbmdFbnRyeQIFAWwFAmJrCQDMCAIJAQtTdHJpbmdFbnRyeQIFAW8FAmJsCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXAFAmJtCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFmBQJibgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJkAQZjcmVhdGUCAUQBRQQCYm8JAMwIAgMJAAACCQDYBAEICAUCYmQGY2FsbGVyBWJ5dGVzCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAWwCAAYJAQJiZgEFAmJkBQNuaWwDCQAAAgUCYm8FAmJvBAFCCQCUCgIFAUQFAUUEAmJwCQDOCAIJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAQFBAQUBQgYFA25pbAkBAmFTAgUCYUUJAQJhZgEFAUIEAmJxCQAAAgkAmggCBQR0aGlzBQFqBQR1bml0BAJicgMFAmJxBAFpAAAJAMwIAgkBDEludGVnZXJFbnRyeQIFAWoFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIJAQF5AQUBaQUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF1BQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFAXYFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIFAXcFBmhlaWdodAUDbmlsBQNuaWwJAJQKAgkAzggCBQJicAUCYnIFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmQBBHZvdGUDAUQBRQJicwQBQgkAlAoCBQFEBQFFBAFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWoAAAQCYnQJAQJhZQIFBHRoaXMJAQF5AQUBaQQCYm4JAQJhZQIFBHRoaXMFAWYEAmJ1CQBkAgUCYnQFAmJuBAJidgkAmggCBQR0aGlzBQFyBAJidwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBRgIIBQJiZAZjYWxsZXIFAWkAAAQCYngJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUgDBQFCCAUCYmQGY2FsbGVyBQFpAAAEAmJ5CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFKAgUBQgUBaQAABAJiegkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBUAEFAWkAAAQCYkEKAAJhZAkA/AcEBQR0aGlzAhhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQJAMwIAgkA2AQBCAgFAmJkBmNhbGxlcgVieXRlcwkAzAgCBQJidQUDbmlsBQNuaWwDCQABAgUCYWQCA0ludAUCYWQJAAIBCQCsAgIJAAMBBQJhZAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50BAJiQgkAZQIFAmJBBQJidwQCYkMJAGQCBQJieAUCYnMEAmJECQECYUEBBQFCBAJibwkAzAgCAwkBAiE9AgkAoAgBCQEBQQEFAUIFBHVuaXQGCQEBVQECDmludmFsaWQgYXNzZXRzCQDMCAIDCQBmAgUCYnUFBmhlaWdodAYJAQFVAQIOaW52YWxpZCBoZWlnaHQJAMwIAgMJAAACBQJidgUEdW5pdAYJAQFVAQIYZmluYWxpemF0aW9uIGluIHByb2dyZXNzCQDMCAIDCQBmAgUCYkEAAAYJAQFVAQITeW91IGRvIG5vdCBoYXZlIGdXWAkAzAgCAwMJAGYCBQJicwAACQBnAgUCYkIFAmJzBwYJAQFVAQIOaW52YWxpZCBhbW91bnQJAMwIAgMFAmJEBgkBAVUBAh1wb29sIGhhc24ndCBXWF9FTUlTU0lPTiBsYWJlbAUDbmlsAwkAAAIFAmJvBQJibwQCYkUJAQJhRgEFAUIEAVIJAKUIAQgFAmJkBmNhbGxlcgQCYkYDCQECYU8CBQJiRQUBUgUDbmlsCQECYVMCBQJiRQUBUgkAlAoCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFGAggFAmJkBmNhbGxlcgUBaQkAZAIFAmJ3BQJicwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUgDBQFCCAUCYmQGY2FsbGVyBQFpBQJiQwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUoCBQFCBQFpCQBkAgUCYnkFAmJzCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBUAEFAWkJAGQCBQJiegUCYnMFA25pbAUCYkYFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmQBCmNhbmNlbFZvdGUCAUQBRQQBQgkAlAoCBQFEBQFFBAFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWoAAAQCYnQJAQJhZQIFBHRoaXMJAQF5AQUBaQQCYm4JAQJhZQIFBHRoaXMFAWYEAmJ1CQBkAgUCYnQFAmJuBAJidgkAmggCBQR0aGlzBQFyBAJidwkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBRgIIBQJiZAZjYWxsZXIFAWkAAAQCYngJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUgDBQFCCAUCYmQGY2FsbGVyBQFpAAAEAmJ5CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFKAgUBQgUBaQAABAJiegkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBUAEFAWkAAAQCYm8JAMwIAgMJAQIhPQIJAKAIAQkBAUEBBQFCBQR1bml0BgkBAVUBAg5pbnZhbGlkIGFzc2V0cwkAzAgCAwkAZgIFAmJ1BQZoZWlnaHQGCQEBVQECDmludmFsaWQgaGVpZ2h0CQDMCAIDCQAAAgUCYnYFBHVuaXQGCQEBVQECGGZpbmFsaXphdGlvbiBpbiBwcm9ncmVzcwkAzAgCAwkAZgIFAmJ4AAAGCQEBVQECB25vIHZvdGUFA25pbAMJAAACBQJibwUCYm8EAmJFCQECYUYBBQFCBAFSCQClCAEIBQJiZAZjYWxsZXIJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBRgIIBQJiZAZjYWxsZXIFAWkJAJYDAQkAzAgCCQBlAgUCYncFAmJ4CQDMCAIAAAUDbmlsCQDMCAIJAQtEZWxldGVFbnRyeQEJAQFIAwUBQggFAmJkBmNhbGxlcgUBaQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUoCBQFCBQFpCQBlAgUCYnkFAmJ4CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBUAEFAWkJAGUCBQJiegUCYngFA25pbAkBAmFWAgUCYkUFAVIFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmQBDnNldEVwb2NoTGVuZ3RoAQJiRwQCYm8JAMwIAgkBAmJmAQUCYmQJAMwIAgMJAGYCBQJiRwAABgkBAVUBAhRpbnZhbGlkIGVwb2NoIGxlbmd0aAUDbmlsAwkAAAIFAmJvBQJibwkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFnBQJiRwUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJkAQtzZXRNYXhEZXB0aAECYkgEAmJvCQDMCAIJAQJiZgEFAmJkCQDMCAIDCQBmAgUCYkgAAAYJAQFVAQIRaW52YWxpZCBtYXggZGVwdGgFA25pbAMJAAACBQJibwUCYm8JAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBawUCYkgFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiZAETcHJvY2Vzc1ZvdGVJTlRFUk5BTAICYkkBUgQCYkoJAQJiZwEFAmJkAwkAAAIFAmJKBQJiSgQCYmgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQFSCQEBUwEJAKwCAgIqcHJvY2Vzc1ZvdGVJTlRFUk5BTDogaW52YWxpZCB1c2VyIGFkZHJlc3MgBQFSBAFpCQECYWUCBQR0aGlzBQFqBAJiSwkAZQIFAWkAAQQCYm4JAQJhZQIFBHRoaXMFAWYEAmJ0CQECYWUCBQR0aGlzCQEBeQEFAWkEAmJ1CQBkAgUCYnQFAmJuBAJiTAkBAmFlAgUEdGhpcwkBAXkBBQJiSwQCYk0JAQJhZQIFBHRoaXMJAQFoAQUCYksEAmJOCQBkAgUCYkwFAmJNBAJiTwMJAGcCBQJiSwAABgkBAVUBAitwcm9jZXNzVm90ZUlOVEVSTkFMOiBpbnZhbGlkIHByZXZpb3VzIGVwb2NoAwkAAAIFAmJPBQJiTwQBQgkBAmFnAQUCYkkEAmJQBQFCBAFECAUCYlACXzEEAUUIBQJiUAJfMgQCYkQJAQJhQQEFAUIEAmJBCgACYWQJAPwHBAUEdGhpcwIYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0CQDMCAIFAVIJAMwIAgUCYnUFA25pbAUDbmlsAwkAAQIFAmFkAgNJbnQFAmFkCQACAQkArAICCQADAQUCYWQCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAQCYlEKAAJhZAkA/AcEBQR0aGlzAhhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQJAMwIAgUBUgkAzAgCBQJiTgUDbmlsBQNuaWwDCQABAgUCYWQCA0ludAUCYWQJAAIBCQCsAgIJAAMBBQJhZAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50BAJiegkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEBUAEFAWkAAAQCYlIJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAUoCBQFCBQFpAAAEAmJTCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQkBAUgDBQFCBQJiaAUCYksJAQFTAQkArAICCQCsAgIJAKwCAgkArAICAhRwcm9jZXNzVm90ZUlOVEVSTkFMIAUCYkkCASAFAVICEjogbm8gcHJldmlvdXMgdm90ZQQCYncJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUYCBQJiaAUBaQAABAFNCQECYXACBQFEBQFFBAJiVAkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEBTAIFAU0FAmJLAAAEAmJtCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYWMCBQR0aGlzBQFwBAJiVQkBC3ZhbHVlT3JFbHNlAgkAmggCBQJibQkBAVECBQFNBQFSAAAEAmJWAwkAAAIFAmJVAAAFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUwCBQFNBQJiSwkAZAIFAmJUBQJiUwUDbmlsBAJhegkBAmFwAgUBRAUBRQQCYlcKAAJhZAkA/AcEBQJhaQIMY2hlY2tCYWxhbmNlCQDMCAIFAmF6BQNuaWwFA25pbAMJAAECBQJhZAIHQm9vbGVhbgUCYWQJAAIBCQCsAgIJAAMBBQJhZAIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCYkMDCQBmAgUCYlEAAAkAawMFAmJTBQJiQQUCYlEAAAQCYlgDAwMJAGYCBQJiQwAABQJiRAcFAmJXBwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUgDBQFCBQJiaAUBaQUCYkMJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFQAQUBaQkAZAIFAmJ6BQJiQwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUoCBQFCBQFpCQBkAgUCYlIFAmJDCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBRgIFAmJoBQFpCQBkAgUCYncFAmJDBQNuaWwJAQJhVgIJAQJhRgEFAUIFAVIJAJQKAgkAzggCBQJiWAUCYlYFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmQBE3Byb2Nlc3NQb29sSU5URVJOQUwCAmJJAmJZBAJiSgkBAmJnAQUCYmQDCQAAAgUCYkoFAmJKBAJiWgQCY2EJAQJhZQIFBHRoaXMFAWoDBQJiWQUCY2EJAGUCBQJjYQABBAJiTwMJAGcCBQJiWgAABgkBAVUBAilwcm9jZXNzUG9vbElOVEVSTkFMOiBpbnZhbGlkIHRhcmdldCBlcG9jaAMJAAACBQJiTwUCYk8EAUIJAQJhZwEFAmJJBAJjYgUBQgQBRAgFAmNiAl8xBAFFCAUCY2ICXzIEAmJtCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYWMCBQR0aGlzBQFwBAJhegkBAmFwAgUBRAUBRQQCY2MKAAJhZAkA/AcEBQJibQISdXNlcnNMaXN0VHJhdmVyc2FsCQDMCAIFAmF6BQNuaWwFA25pbAMJAAECBQJhZAIHQm9vbGVhbgUCYWQJAAIBCQCsAgIJAAMBBQJhZAIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgMJAAACBQJjYwUCY2MDBQJjYwkAlAoCBQNuaWwGBAJjZAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBC3ZhbHVlT3JFbHNlAgkAnQgCBQR0aGlzBQFxAh1pbnZhbGlkIGFzc2V0cyBzdG9yZSBjb250cmFjdAQCYkQJAQJhQQEFAUIEAmJXCgACYWQJAPwHBAUCYWkCDGNoZWNrQmFsYW5jZQkAzAgCBQJhegUDbmlsBQNuaWwDCQABAgUCYWQCB0Jvb2xlYW4FAmFkCQACAQkArAICCQADAQUCYWQCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmNlCgACYWQJAPwHBAUCY2QCEmlzVmVyaWZpZWRSRUFET05MWQkAzAgCBQFEBQNuaWwFA25pbAMJAAECBQJhZAIHQm9vbGVhbgUCYWQJAAIBCQCsAgIJAAMBBQJhZAIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCY2YKAAJhZAkA/AcEBQJjZAISaXNWZXJpZmllZFJFQURPTkxZCQDMCAIFAUUFA25pbAUDbmlsAwkAAQIFAmFkAgdCb29sZWFuBQJhZAkAAgEJAKwCAgkAAwEFAmFkAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJjZwMDAwMJAQEhAQUCYkQFAmJXBwUCY2UHBQJjZgcJAPwHBAUCYWkCFnNldFd4RW1pc3Npb25Qb29sTGFiZWwJAMwIAgUBRAkAzAgCBQFFBQNuaWwFA25pbAUEdW5pdAMJAAACBQJjZwUCY2cEAmJ6CQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFQAQUCYloAAAQCYlIJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUoCBQFCBQJiWgAABAJjaAMDAwkAAAIFAmJ6AAAGCQEBIQEFAmJEBgkBASEBBQJiVwAACQBrAwUCYlIFAWIFAmJ6BAJjaQkA/AcEBQJhaQIMbW9kaWZ5V2VpZ2h0CQDMCAIFAmF6CQDMCAIFAmNoBQNuaWwFA25pbAMJAAACBQJjaQUCY2kJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAU4CBQFCBQJiWgUCY2gFA25pbAcJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYmQBDmZpbmFsaXplSGVscGVyAAQCYlkJAQt2YWx1ZU9yRWxzZQIJAKAIAQUBeAcEAWkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBagAABAJjagkAZQIFAWkAAQQCYnQJAQJhZQIFBHRoaXMJAQF5AQUBaQQCYm4JAQJhZQIFBHRoaXMFAWYEAmJ1CQBkAgUCYnQFAmJuBAJidgkAmggCBQR0aGlzBQFyAwMDCQBnAgUGaGVpZ2h0BQJidQkAAAIFAmJ2BQR1bml0BwkBASEBBQJiWQcEAmNrCQBkAgUBaQABBAJjbAkAmggCBQR0aGlzBQFnBAJjbQQBWgUCY2wDCQABAgUBWgIDSW50BAJiRwUBWgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBZgUCYkcJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBZwUDbmlsAwkAAQIFAVoCBFVuaXQFA25pbAkAAgECC01hdGNoIGVycm9yCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAXkBBQJjawUGaGVpZ2h0CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF1BQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFAWoFAmNrCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFyBQFkCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBaAEFAWkFAmJuBQNuaWwFAmNtBgMDBQJiWQkAAAIFAmJ2BQR1bml0BwkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFyBQFlBQNuaWwGAwkAAAIFAmJ2BQR1bml0CQCUCgIFA25pbAcDCQAAAgUCYnYFAWQEAmNuCQCiCAEFAXMEAmNvCQCiCAEFAXQEAVoFAmNuAwkAAQIFAVoCBFVuaXQEAmNwCQCiCAEJAQJhSAEFAmFFAwkAAQIFAmNwAgRVbml0CQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAXIFAWUJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcwkAzAgCCQELRGVsZXRlRW50cnkBBQF0BQNuaWwGAwkAAQIFAmNwAgZTdHJpbmcEAmNxBQJjcAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXMFAmNxBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IDCQABAgUBWgIGU3RyaW5nBAJiSQUBWgQBQgkBAmFnAQUCYkkEAmNyBAJjcAUCY28DCQABAgUCY3ACBFVuaXQJAKIIAQkBAmFIAQkBAmFGAQUBQgMJAAECBQJjcAIGU3RyaW5nBAJjcwUCY3AEAmN0CQCiCAEJAQJhTgIJAQJhRgEFAUIFAmNzAwkAAAIFAmN0BQJjdAQCY3UJAPwHBAUEdGhpcwITcHJvY2Vzc1ZvdGVJTlRFUk5BTAkAzAgCBQJiSQkAzAgCBQJjcwUDbmlsBQNuaWwDCQAAAgUCY3UFAmN1BQJjdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECC01hdGNoIGVycm9yBAJjcAUCY3IDCQABAgUCY3ACBFVuaXQEAmN2CQCiCAEJAQJhTgIFAmFFBQJiSQQCY3cFAmN2AwkAAQIFAmN3AgRVbml0CQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAXIFAWUJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcwkAzAgCCQELRGVsZXRlRW50cnkBBQF0BQNuaWwGAwkAAQIFAmN3AgZTdHJpbmcEAmFaBQJjdwkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXMFAmFaCQDMCAIJAQtEZWxldGVFbnRyeQEFAXQFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgMJAAECBQJjcAIGU3RyaW5nBAJjeAUCY3AJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCBQF0BQJjeAUDbmlsBgkAAgECC01hdGNoIGVycm9yCQACAQILTWF0Y2ggZXJyb3IDCQAAAgUCYnYFAWUEAmNuCQCiCAEFAXMEAVoFAmNuAwkAAQIFAVoCBFVuaXQEAmNwCQCiCAEJAQJhSAEFAmFFAwkAAQIFAmNwAgRVbml0BAJiWAMFAmJZCQDMCAIJAQtEZWxldGVFbnRyeQEFAXIJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBeAUDbmlsCQDMCAIJAQtEZWxldGVFbnRyeQEFAXIJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAQF6AQUCY2oGCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF2BQFpCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF3BQJidAUDbmlsBAJjeQkBAmFDAAMJAAACBQJjeQUCY3kJAJQKAgUCYlgGCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAwkAAQIFAmNwAgZTdHJpbmcEAmN6BQJjcAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXMFAmN6BQNuaWwGCQACAQILTWF0Y2ggZXJyb3IDCQABAgUBWgIGU3RyaW5nBAJiSQUBWgQCY3YJAKIIAQkBAmFOAgUCYUUFAmJJAwkAAAIFAmN2BQJjdgQCY2MKAAJhZAkA/AcEBQR0aGlzAhNwcm9jZXNzUG9vbElOVEVSTkFMCQDMCAIFAmJJCQDMCAIFAmJZBQNuaWwFA25pbAMJAAECBQJhZAIHQm9vbGVhbgUCYWQJAAIBCQCsAgIJAAMBBQJhZAIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgMJAAACBQJjYwUCY2MDBQJjYwkAlAoCBQNuaWwGBAJjcAUCY3YDCQABAgUCY3ACBFVuaXQEAmJYAwUCYlkJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcgkAzAgCCQELRGVsZXRlRW50cnkBBQF4CQDMCAIJAQtEZWxldGVFbnRyeQEFAXMFA25pbAkAzAgCCQELRGVsZXRlRW50cnkBBQFyCQDMCAIJAQxCb29sZWFuRW50cnkCCQEBegEFAmNqBgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdgUBaQkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdwUCYnQJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcwUDbmlsBAJjeQkBAmFDAAMJAAACBQJjeQUCY3kJAJQKAgUCYlgGCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAwkAAQIFAmNwAgZTdHJpbmcEAmN6BQJjcAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXMFAmN6BQNuaWwGCQACAQILTWF0Y2ggZXJyb3IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAgtNYXRjaCBlcnJvcgkBAVUBAhZmaW5hbGl6YXRpb24gaXMgYnJva2VuAmJkAQ9maW5hbGl6ZVdyYXBwZXIBAmNBBAJjQgkBEUBleHRyTmF0aXZlKDEwNjIpAQkBEUBleHRyTmF0aXZlKDEwNTMpAgUEdGhpcwUBbQQCY0MKAAJhZAkA/AcEBQR0aGlzAg5maW5hbGl6ZUhlbHBlcgUDbmlsBQNuaWwDCQABAgUCYWQCB0Jvb2xlYW4FAmFkCQACAQkArAICCQADAQUCYWQCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4DCQAAAgUCY0MFAmNDAwkBASEBBQJjQwMJAAACBQJjQQAACQEBVQECHkN1cnJlbnQgdm90aW5nIGlzIG5vdCBvdmVyIHlldAQCY0QJAPwHBAUCY0ICCGZpbmFsaXplBQNuaWwFA25pbAMJAAACBQJjRAUCY0QJAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuBAJjRQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzBQFrBQFjAwkAZgIFAmNFBQJjQQQCY0QJAPwHBAUEdGhpcwIPZmluYWxpemVXcmFwcGVyCQDMCAIJAGQCBQJjQQABBQNuaWwFA25pbAMJAAACBQJjRAUCY0QJAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiZAEIZmluYWxpemUABAJjRAkA/AcEBQR0aGlzAg9maW5hbGl6ZVdyYXBwZXIJAMwIAgAABQNuaWwFA25pbAMJAAACBQJjRAUCY0QJAJQKAgUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJkARRjb250YWluc05vZGVSRUFET05MWQICYUkCYU0JAJQKAgUDbmlsCQECYU8CBQJhSQUCYU0CYmQBCmluc2VydE5vZGUCAmFJAmFNBAJiSgkBAmJmAQUCYmQDCQAAAgUCYkoFAmJKCQCUCgIJAQJhUwIFAmFJBQJhTQUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJiZAEKZGVsZXRlTm9kZQICYUkCYU0EAmJKCQECYmYBBQJiZAMJAAACBQJiSgUCYkoJAJQKAgkBAmFWAgUCYUkFAmFNBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmJkARhpc0ZpbmFsaXphdGlvbkluUHJvZ3Jlc3MABAJidgkAmggCBQR0aGlzBQFyBAJjRgkBAiE9AgUCYnYFBHVuaXQJAJQKAgUDbmlsBQJjRgJiZAEKZGVsZXRlUG9vbAIBRAFFBAJiSgMDCQAAAggFAmJkBmNhbGxlcgUCYWkGCQECYmYBBQJiZAYJAQFVAQIRUGVybWlzc2lvbiBkZW5pZWQDCQAAAgUCYkoFAmJKBAJhSQIFcG9vbHMEAUIJAJQKAgUBRAUBRQQCYU0JALkJAgkAzAgCBQFECQDMCAIFAUUFA25pbAUBYQQCYlgDCQECYU8CBQJhSQUCYU0JAQJhVgIFAmFJBQJhTQUDbmlsCQDOCAIJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAUEBBQFCBQNuaWwFAmJYCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJjRwECY0gABAJjSQQBWgkBAmJhAAMJAAECBQFaAgpCeXRlVmVjdG9yBAJiZQUBWgUCYmUDCQABAgUBWgIEVW5pdAgFAmNHD3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yCQD0AwMIBQJjRwlib2R5Qnl0ZXMJAJEDAggFAmNHBnByb29mcwAABQJjSeYK41I=", "height": 2932251, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 6FY627hQpwQbpuxPkTSiSRNDTg45vxDnJ46axyrwscfb Next: GGrxUtyWStFqoWpfsizaH2df2wUuz1wdjQGdkBjksJVx Diff:
OldNewDifferences
3232
3333 let keyStakingContract = makeString(["%s", "stakingContract"], separator)
3434
35+let keyAssetsStoreContract = makeString(["%s", "assetsStoreContract"], separator)
36+
3537 let keyFinalizationStage = makeString(["%s", "finalizationStage"], separator)
3638
3739 let keyNextPool = makeString(["%s", "nextPool"], separator)
5355
5456
5557 func keyInList (pool) = {
56- let $t017881828 = pool
57- let amountAssetId = $t017881828._1
58- let priceAssetId = $t017881828._2
58+ let $t018691909 = pool
59+ let amountAssetId = $t018691909._1
60+ let priceAssetId = $t018691909._2
5961 makeString(["%s%s%s", "inList", amountAssetId, priceAssetId], separator)
6062 }
6163
6466
6567
6668 func keyVote (pool,address,epoch) = {
67- let $t021022142 = pool
68- let amountAssetId = $t021022142._1
69- let priceAssetId = $t021022142._2
69+ let $t021832223 = pool
70+ let amountAssetId = $t021832223._1
71+ let priceAssetId = $t021832223._2
7072 makeString(["%s%s%s%s%d", "vote", amountAssetId, priceAssetId, toString(address), toString(epoch)], separator)
7173 }
7274
7375
7476 func keyVotingResult (pool,epoch) = {
75- let $t023242364 = pool
76- let amountAssetId = $t023242364._1
77- let priceAssetId = $t023242364._2
77+ let $t024052445 = pool
78+ let amountAssetId = $t024052445._1
79+ let priceAssetId = $t024052445._2
7880 makeString(["%s%s%s%d", "votingResult", amountAssetId, priceAssetId, toString(epoch)], separator)
7981 }
8082
8385
8486
8587 func keyPoolShare (pool,epoch) = {
86- let $t026852725 = pool
87- let amountAssetId = $t026852725._1
88- let priceAssetId = $t026852725._2
88+ let $t027662806 = pool
89+ let amountAssetId = $t027662806._1
90+ let priceAssetId = $t027662806._2
8991 makeString(["%s%s%s%d", "poolShare", amountAssetId, priceAssetId, toString(epoch)], separator)
9092 }
9193
171173
172174
173175 func checkWxEmissionPoolLabel (pool) = {
174- let $t055655605 = pool
175- let amountAssetId = $t055655605._1
176- let priceAssetId = $t055655605._2
176+ let $t056465686 = pool
177+ let amountAssetId = $t056465686._1
178+ let priceAssetId = $t056465686._2
177179 let @ = invoke(factoryContract, "checkWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil)
178180 if ($isInstanceOf(@, "Boolean"))
179181 then @
191193 let poolsListName = "pools"
192194
193195 func getVotesListName (pool) = {
194- let $t060226062 = pool
195- let amountAssetId = $t060226062._1
196- let priceAssetId = $t060226062._2
196+ let $t061036143 = pool
197+ let amountAssetId = $t061036143._1
198+ let priceAssetId = $t061036143._2
197199 makeString(["votes", amountAssetId, priceAssetId], separator)
198200 }
199201
504506 if ((checkTargetEpoch == checkTargetEpoch))
505507 then {
506508 let pool = stringToPool(poolStr)
507- let $t01806518105 = pool
508- let amountAssetId = $t01806518105._1
509- let priceAssetId = $t01806518105._2
509+ let $t01814618186 = pool
510+ let amountAssetId = $t01814618186._1
511+ let priceAssetId = $t01814618186._2
510512 let wxEmission = checkWxEmissionPoolLabel(pool)
511513 let gwxAmountAtEndTotal = {
512514 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)
574576 if ((checkTargetEpoch == checkTargetEpoch))
575577 then {
576578 let pool = stringToPool(poolStr)
577- let $t02064120681 = pool
578- let amountAssetId = $t02064120681._1
579- let priceAssetId = $t02064120681._2
579+ let $t02072220762 = pool
580+ let amountAssetId = $t02072220762._1
581+ let priceAssetId = $t02072220762._2
580582 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
581583 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
582584 let r = {
589591 then if (r)
590592 then $Tuple2(nil, true)
591593 else {
594+ let assetsStoreContract = addressFromStringValue(valueOrElse(getString(this, keyAssetsStoreContract), "invalid assets store contract"))
592595 let wxEmission = checkWxEmissionPoolLabel(pool)
593596 let balanceIsOk = {
594597 let @ = invoke(factoryContract, "checkBalance", [lpAssetId], nil)
596599 then @
597600 else throw(($getType(@) + " couldn't be cast to Boolean"))
598601 }
599- let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
600- let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
601- let share = if (if (if ((totalVotes == 0))
602- then true
603- else !(wxEmission))
604- then true
605- else !(balanceIsOk))
606- then 0
607- else fraction(votingResult, poolWeightMult, totalVotes)
608- let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
609- if ((modifyWeightInv == modifyWeightInv))
602+ let amountAssetVerified = {
603+ let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [amountAssetId], nil)
604+ if ($isInstanceOf(@, "Boolean"))
605+ then @
606+ else throw(($getType(@) + " couldn't be cast to Boolean"))
607+ }
608+ let priceAssetVerified = {
609+ let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [priceAssetId], nil)
610+ if ($isInstanceOf(@, "Boolean"))
611+ then @
612+ else throw(($getType(@) + " couldn't be cast to Boolean"))
613+ }
614+ let setWxEmissionInv = if (if (if (if (!(wxEmission))
615+ then balanceIsOk
616+ else false)
617+ then amountAssetVerified
618+ else false)
619+ then priceAssetVerified
620+ else false)
621+ then invoke(factoryContract, "setWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil)
622+ else unit
623+ if ((setWxEmissionInv == setWxEmissionInv))
610624 then {
611- let poolsListActions = if (if (wxEmission)
625+ let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
626+ let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
627+ let share = if (if (if ((totalVotes == 0))
612628 then true
613- else force)
614- then nil
615- else ([DeleteEntry(keyInList(pool))] ++ deleteNodeActions(poolsListName, poolStr))
616- $Tuple2(([IntegerEntry(keyPoolShare(pool, targetEpoch), share)] ++ poolsListActions), false)
629+ else !(wxEmission))
630+ then true
631+ else !(balanceIsOk))
632+ then 0
633+ else fraction(votingResult, poolWeightMult, totalVotes)
634+ let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
635+ if ((modifyWeightInv == modifyWeightInv))
636+ then $Tuple2([IntegerEntry(keyPoolShare(pool, targetEpoch), share)], false)
637+ else throw("Strict value is not equal to itself.")
617638 }
618639 else throw("Strict value is not equal to itself.")
619640 }
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
35+let keyAssetsStoreContract = makeString(["%s", "assetsStoreContract"], separator)
36+
3537 let keyFinalizationStage = makeString(["%s", "finalizationStage"], separator)
3638
3739 let keyNextPool = makeString(["%s", "nextPool"], separator)
3840
3941 let keyNextUser = makeString(["%s", "nextUser"], separator)
4042
4143 let keyStartHeight = makeString(["%s", "startHeight"], separator)
4244
4345 let keyCurrentEpochUi = makeString(["%s", "currentEpochUi"], separator)
4446
4547 let keyStartHeightUi = makeString(["%s", "startHeightUi"], separator)
4648
4749 let keyFinalizationShouldBeForced = makeString(["%s", "force"], separator)
4850
4951 func keyStartHeightByEpoch (epoch) = makeString(["%s%d", "startHeight", toString(epoch)], separator)
5052
5153
5254 func keyFinalized (epoch) = makeString(["%s%d", "finalized", toString(epoch)], separator)
5355
5456
5557 func keyInList (pool) = {
56- let $t017881828 = pool
57- let amountAssetId = $t017881828._1
58- let priceAssetId = $t017881828._2
58+ let $t018691909 = pool
59+ let amountAssetId = $t018691909._1
60+ let priceAssetId = $t018691909._2
5961 makeString(["%s%s%s", "inList", amountAssetId, priceAssetId], separator)
6062 }
6163
6264
6365 func keyUsed (address,epoch) = makeString(["%s%s%d", "used", toString(address), toString(epoch)], separator)
6466
6567
6668 func keyVote (pool,address,epoch) = {
67- let $t021022142 = pool
68- let amountAssetId = $t021022142._1
69- let priceAssetId = $t021022142._2
69+ let $t021832223 = pool
70+ let amountAssetId = $t021832223._1
71+ let priceAssetId = $t021832223._2
7072 makeString(["%s%s%s%s%d", "vote", amountAssetId, priceAssetId, toString(address), toString(epoch)], separator)
7173 }
7274
7375
7476 func keyVotingResult (pool,epoch) = {
75- let $t023242364 = pool
76- let amountAssetId = $t023242364._1
77- let priceAssetId = $t023242364._2
77+ let $t024052445 = pool
78+ let amountAssetId = $t024052445._1
79+ let priceAssetId = $t024052445._2
7880 makeString(["%s%s%s%d", "votingResult", amountAssetId, priceAssetId, toString(epoch)], separator)
7981 }
8082
8183
8284 func keyVotingResultStaked (lpAssetIdStr,epoch) = makeString(["%s%s%d", "votingResultStaked", lpAssetIdStr, toString(epoch)], separator)
8385
8486
8587 func keyPoolShare (pool,epoch) = {
86- let $t026852725 = pool
87- let amountAssetId = $t026852725._1
88- let priceAssetId = $t026852725._2
88+ let $t027662806 = pool
89+ let amountAssetId = $t027662806._1
90+ let priceAssetId = $t027662806._2
8991 makeString(["%s%s%s%d", "poolShare", amountAssetId, priceAssetId, toString(epoch)], separator)
9092 }
9193
9294
9395 func keyTotalVotes (epoch) = makeString(["%s%d", "totalVotes", toString(epoch)], separator)
9496
9597
9698 func keyStakedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s", "staked", userAddressStr, lpAssetIdStr], separator)
9799
98100
99101 func wrapErr (msg) = makeString(["voting_emission.ride:", msg], " ")
100102
101103
102104 func throwErr (msg) = throw(wrapErr(msg))
103105
104106
105107 func getValueOrFail (address,key,type) = {
106108 let error = wrapErr(makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
107109 valueOrErrorMessage( match type {
108110 case str: String =>
109111 getString(address, key)
110112 case int: Int =>
111113 getInteger(address, key)
112114 case _ =>
113115 throwErr("invalid entry type")
114116 }, error)
115117 }
116118
117119
118120 func getStrOrFail (address,key) = {
119121 let @ = getValueOrFail(address, key, "")
120122 if ($isInstanceOf(@, "String"))
121123 then @
122124 else throw(($getType(@) + " couldn't be cast to String"))
123125 }
124126
125127
126128 func getIntOrFail (address,key) = {
127129 let @ = getValueOrFail(address, key, 0)
128130 if ($isInstanceOf(@, "Int"))
129131 then @
130132 else throw(($getType(@) + " couldn't be cast to Int"))
131133 }
132134
133135
134136 func poolToString (pool) = ((pool._1 + separator) + pool._2)
135137
136138
137139 func stringToPool (str) = {
138140 let parts = split(str, separator)
139141 if ((size(parts) == 2))
140142 then $Tuple2(parts[0], parts[1])
141143 else throwErr("invalid pool string")
142144 }
143145
144146
145147 let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
146148
147149 let IdxFactoryCfgGwxRewardDapp = 10
148150
149151 func keyFactoryCfg () = "%s__factoryConfig"
150152
151153
152154 func readFactoryCfgOrFail (factory) = split(getStrOrFail(factory, keyFactoryCfg()), separator)
153155
154156
155157 func getGwxRewardAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgGwxRewardDapp])
156158
157159
158160 func getLpAssetByPoolAssets (amountAssetId,priceAssetId) = {
159161 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
160162
161163 func keyMappingPoolAssetsToPoolContractAddress (internalAmountAssetIdStr,internalPriceAssetIdStr) = (((("%d%d%s%s__" + toString(internalAmountAssetIdStr)) + "__") + toString(internalPriceAssetIdStr)) + "__mappings__poolAssets2PoolContract")
162164
163165 func keyMappingPoolContractToLPAsset (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
164166
165167 let amountAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amountAssetId))
166168 let priceAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAssetId))
167169 let poolContractAddress = getStrOrFail(factoryContract, keyMappingPoolAssetsToPoolContractAddress(amountAssetInternalId, priceAssetInternalId))
168170 let lpAssetId = getStrOrFail(factoryContract, keyMappingPoolContractToLPAsset(poolContractAddress))
169171 lpAssetId
170172 }
171173
172174
173175 func checkWxEmissionPoolLabel (pool) = {
174- let $t055655605 = pool
175- let amountAssetId = $t055655605._1
176- let priceAssetId = $t055655605._2
176+ let $t056465686 = pool
177+ let amountAssetId = $t056465686._1
178+ let priceAssetId = $t056465686._2
177179 let @ = invoke(factoryContract, "checkWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil)
178180 if ($isInstanceOf(@, "Boolean"))
179181 then @
180182 else throw(($getType(@) + " couldn't be cast to Boolean"))
181183 }
182184
183185
184186 func gwxRewardDeposit () = {
185187 let factoryCfg = readFactoryCfgOrFail(factoryContract)
186188 let gwxRewardsContract = getGwxRewardAddressOrFail(factoryCfg)
187189 invoke(gwxRewardsContract, "deposit", nil, nil)
188190 }
189191
190192
191193 let poolsListName = "pools"
192194
193195 func getVotesListName (pool) = {
194- let $t060226062 = pool
195- let amountAssetId = $t060226062._1
196- let priceAssetId = $t060226062._2
196+ let $t061036143 = pool
197+ let amountAssetId = $t061036143._1
198+ let priceAssetId = $t061036143._2
197199 makeString(["votes", amountAssetId, priceAssetId], separator)
198200 }
199201
200202
201203 func keyListHead (listName) = {
202204 let meta = if ((listName == poolsListName))
203205 then "%s%s"
204206 else "%s%s%s%s"
205207 makeString([meta, listName, "head"], separator)
206208 }
207209
208210
209211 func keyListSize (listName) = {
210212 let meta = if ((listName == poolsListName))
211213 then "%s%s"
212214 else "%s%s%s%s"
213215 makeString([meta, listName, "size"], separator)
214216 }
215217
216218
217219 func keyListPrev (listName,id) = {
218220 let meta = if ((listName == poolsListName))
219221 then "%s%s%s%s"
220222 else "%s%s%s%s%s"
221223 makeString([meta, listName, id, "prev"], separator)
222224 }
223225
224226
225227 func keyListNext (listName,id) = {
226228 let meta = if ((listName == poolsListName))
227229 then "%s%s%s%s"
228230 else "%s%s%s%s%s"
229231 makeString([meta, listName, id, "next"], separator)
230232 }
231233
232234
233235 func containsNode (listName,id) = {
234236 let headOrUnit = getString(this, keyListHead(listName))
235237 let prevOrUnit = getString(this, keyListPrev(listName, id))
236238 let nextOrUnit = getString(this, keyListNext(listName, id))
237239 if (if ((id == valueOrElse(headOrUnit, "")))
238240 then true
239241 else (prevOrUnit != unit))
240242 then true
241243 else (nextOrUnit != unit)
242244 }
243245
244246
245247 func insertNodeActions (listName,id) = {
246248 let headOrUnit = getString(this, keyListHead(listName))
247249 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
248250 let checkNode = if (!(containsNode(listName, id)))
249251 then true
250252 else throwErr("Node exists")
251253 if ((checkNode == checkNode))
252254 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
253255 then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
254256 else nil)) ++ [StringEntry(keyListHead(listName), id)])
255257 else throw("Strict value is not equal to itself.")
256258 }
257259
258260
259261 func deleteNodeActions (listName,id) = {
260262 let headOrUnit = getString(this, keyListHead(listName))
261263 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
262264 let prevOrUnit = getString(this, keyListPrev(listName, id))
263265 let nextOrUnit = getString(this, keyListNext(listName, id))
264266 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
265267 then (nextOrUnit != unit)
266268 else false)
267269 then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
268270 else if ((nextOrUnit != unit))
269271 then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
270272 else if ((prevOrUnit != unit))
271273 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
272274 else if ((id == valueOrElse(headOrUnit, "")))
273275 then [DeleteEntry(keyListHead(listName))]
274276 else throwErr(((("invalid node: " + listName) + ".") + id))))
275277 }
276278
277279
278280 func keyManagerVaultAddress () = "%s__managerVaultAddress"
279281
280282
281283 func keyManagerPublicKey () = "%s__managerPublicKey"
282284
283285
284286 func getManagerVaultAddressOrThis () = match getString(keyManagerVaultAddress()) {
285287 case s: String =>
286288 addressFromStringValue(s)
287289 case _ =>
288290 this
289291 }
290292
291293
292294 func managerPublicKeyOrUnit () = {
293295 let managerVaultAddress = getManagerVaultAddressOrThis()
294296 match getString(managerVaultAddress, keyManagerPublicKey()) {
295297 case s: String =>
296298 fromBase58String(s)
297299 case _: Unit =>
298300 unit
299301 case _ =>
300302 throw("Match error")
301303 }
302304 }
303305
304306
305307 func isManager (i) = match managerPublicKeyOrUnit() {
306308 case pk: ByteVector =>
307309 (i.callerPublicKey == pk)
308310 case _: Unit =>
309311 (i.caller == this)
310312 case _ =>
311313 throw("Match error")
312314 }
313315
314316
315317 func mustManager (i) = if (isManager(i))
316318 then true
317319 else throw("permission denied")
318320
319321
320322 func mustThis (i) = if ((i.caller == this))
321323 then true
322324 else throw("permission denied")
323325
324326
325327 @Callable(i)
326328 func getUserGwxAmountAtHeight (userAddress,targetHeight) = {
327329 let boostingContractAddress = valueOrErrorMessage(addressFromString(getStrOrFail(this, keyBoostingContract)), wrapErr("invalid boosting contract address"))
328330 $Tuple2(nil, {
329331 let @ = invoke(boostingContractAddress, "getUserGwxAmountAtHeightREADONLY", [userAddress, targetHeight], nil)
330332 if ($isInstanceOf(@, "Int"))
331333 then @
332334 else throw(($getType(@) + " couldn't be cast to Int"))
333335 })
334336 }
335337
336338
337339
338340 @Callable(i)
339341 func constructor (factoryContract,votingEmissionCandidateContract,boostingContract,stakingContract,epochLength) = {
340342 let checks = [mustManager(i), if ((addressFromString(factoryContract) != unit))
341343 then true
342344 else "invalid factory contract address", if ((addressFromString(votingEmissionCandidateContract) != unit))
343345 then true
344346 else "invalid voting emission candidate contract address", if ((addressFromString(boostingContract) != unit))
345347 then true
346348 else "invalid boosting contract address", if ((addressFromString(stakingContract) != unit))
347349 then true
348350 else "invalid staking contract address", if ((epochLength > 0))
349351 then true
350352 else throwErr("invalid epoch length")]
351353 if ((checks == checks))
352354 then $Tuple2([StringEntry(keyFactoryContract, factoryContract), StringEntry(keyVotingEmissionCandidateContract, votingEmissionCandidateContract), StringEntry(keyBoostingContract, boostingContract), StringEntry(keyStakingContract, stakingContract), IntegerEntry(keyEpochLength, epochLength)], unit)
353355 else throw("Strict value is not equal to itself.")
354356 }
355357
356358
357359
358360 @Callable(i)
359361 func create (amountAssetId,priceAssetId) = {
360362 let checks = [if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionCandidateContract), "")))
361363 then true
362364 else mustManager(i)]
363365 if ((checks == checks))
364366 then {
365367 let pool = $Tuple2(amountAssetId, priceAssetId)
366368 let inListActions = ([BooleanEntry(keyInList(pool), true)] ++ insertNodeActions(poolsListName, poolToString(pool)))
367369 let currentEpochIsNotDefined = (getInteger(this, keyCurrentEpoch) == unit)
368370 let startHeightActions = if (currentEpochIsNotDefined)
369371 then {
370372 let epoch = 0
371373 [IntegerEntry(keyCurrentEpoch, epoch), IntegerEntry(keyStartHeightByEpoch(epoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, height)]
372374 }
373375 else nil
374376 $Tuple2((inListActions ++ startHeightActions), unit)
375377 }
376378 else throw("Strict value is not equal to itself.")
377379 }
378380
379381
380382
381383 @Callable(i)
382384 func vote (amountAssetId,priceAssetId,amount) = {
383385 let pool = $Tuple2(amountAssetId, priceAssetId)
384386 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
385387 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
386388 let epochLength = getIntOrFail(this, keyEpochLength)
387389 let endHeight = (startHeight + epochLength)
388390 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
389391 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
390392 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
391393 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
392394 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
393395 let gwxAmountAtEndTotal = {
394396 let @ = invoke(this, "getUserGwxAmountAtHeight", [toBase58String(i.caller.bytes), endHeight], nil)
395397 if ($isInstanceOf(@, "Int"))
396398 then @
397399 else throw(($getType(@) + " couldn't be cast to Int"))
398400 }
399401 let available = (gwxAmountAtEndTotal - used)
400402 let newVote = (vote + amount)
401403 let wxEmission = checkWxEmissionPoolLabel(pool)
402404 let checks = [if ((getBoolean(keyInList(pool)) != unit))
403405 then true
404406 else throwErr("invalid assets"), if ((endHeight > height))
405407 then true
406408 else throwErr("invalid height"), if ((finalizationStageOrUnit == unit))
407409 then true
408410 else throwErr("finalization in progress"), if ((gwxAmountAtEndTotal > 0))
409411 then true
410412 else throwErr("you do not have gWX"), if (if ((amount > 0))
411413 then (available >= amount)
412414 else false)
413415 then true
414416 else throwErr("invalid amount"), if (wxEmission)
415417 then true
416418 else throwErr("pool hasn't WX_EMISSION label")]
417419 if ((checks == checks))
418420 then {
419421 let votesListName = getVotesListName(pool)
420422 let userAddressStr = toString(i.caller)
421423 let votesListActions = if (containsNode(votesListName, userAddressStr))
422424 then nil
423425 else insertNodeActions(votesListName, userAddressStr)
424426 $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)
425427 }
426428 else throw("Strict value is not equal to itself.")
427429 }
428430
429431
430432
431433 @Callable(i)
432434 func cancelVote (amountAssetId,priceAssetId) = {
433435 let pool = $Tuple2(amountAssetId, priceAssetId)
434436 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
435437 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
436438 let epochLength = getIntOrFail(this, keyEpochLength)
437439 let endHeight = (startHeight + epochLength)
438440 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
439441 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
440442 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
441443 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
442444 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
443445 let checks = [if ((getBoolean(keyInList(pool)) != unit))
444446 then true
445447 else throwErr("invalid assets"), if ((endHeight > height))
446448 then true
447449 else throwErr("invalid height"), if ((finalizationStageOrUnit == unit))
448450 then true
449451 else throwErr("finalization in progress"), if ((vote > 0))
450452 then true
451453 else throwErr("no vote")]
452454 if ((checks == checks))
453455 then {
454456 let votesListName = getVotesListName(pool)
455457 let userAddressStr = toString(i.caller)
456458 $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)
457459 }
458460 else throw("Strict value is not equal to itself.")
459461 }
460462
461463
462464
463465 @Callable(i)
464466 func setEpochLength (newEpochLength) = {
465467 let checks = [mustManager(i), if ((newEpochLength > 0))
466468 then true
467469 else throwErr("invalid epoch length")]
468470 if ((checks == checks))
469471 then $Tuple2([IntegerEntry(keyEpochLengthNew, newEpochLength)], unit)
470472 else throw("Strict value is not equal to itself.")
471473 }
472474
473475
474476
475477 @Callable(i)
476478 func setMaxDepth (newMaxDepth) = {
477479 let checks = [mustManager(i), if ((newMaxDepth > 0))
478480 then true
479481 else throwErr("invalid max depth")]
480482 if ((checks == checks))
481483 then $Tuple2([IntegerEntry(keyMaxDepth, newMaxDepth)], unit)
482484 else throw("Strict value is not equal to itself.")
483485 }
484486
485487
486488
487489 @Callable(i)
488490 func processVoteINTERNAL (poolStr,userAddressStr) = {
489491 let checkCaller = mustThis(i)
490492 if ((checkCaller == checkCaller))
491493 then {
492494 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), wrapErr(("processVoteINTERNAL: invalid user address " + userAddressStr)))
493495 let epoch = getIntOrFail(this, keyCurrentEpoch)
494496 let epochPrevious = (epoch - 1)
495497 let epochLength = getIntOrFail(this, keyEpochLength)
496498 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
497499 let endHeight = (startHeight + epochLength)
498500 let startHeightPrevious = getIntOrFail(this, keyStartHeightByEpoch(epochPrevious))
499501 let epochLengthPrevious = getIntOrFail(this, keyEpochLengthByEpoch(epochPrevious))
500502 let endHeightPrevious = (startHeightPrevious + epochLengthPrevious)
501503 let checkTargetEpoch = if ((epochPrevious >= 0))
502504 then true
503505 else throwErr("processVoteINTERNAL: invalid previous epoch")
504506 if ((checkTargetEpoch == checkTargetEpoch))
505507 then {
506508 let pool = stringToPool(poolStr)
507- let $t01806518105 = pool
508- let amountAssetId = $t01806518105._1
509- let priceAssetId = $t01806518105._2
509+ let $t01814618186 = pool
510+ let amountAssetId = $t01814618186._1
511+ let priceAssetId = $t01814618186._2
510512 let wxEmission = checkWxEmissionPoolLabel(pool)
511513 let gwxAmountAtEndTotal = {
512514 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)
513515 if ($isInstanceOf(@, "Int"))
514516 then @
515517 else throw(($getType(@) + " couldn't be cast to Int"))
516518 }
517519 let gwxAmountAtEndTotalPrevious = {
518520 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeightPrevious], nil)
519521 if ($isInstanceOf(@, "Int"))
520522 then @
521523 else throw(($getType(@) + " couldn't be cast to Int"))
522524 }
523525 let totalVotes = valueOrElse(getInteger(keyTotalVotes(epoch)), 0)
524526 let votingResult = valueOrElse(getInteger(keyVotingResult(pool, epoch)), 0)
525527 let votePrevious = valueOrErrorMessage(getInteger(keyVote(pool, userAddress, epochPrevious)), wrapErr((((("processVoteINTERNAL " + poolStr) + " ") + userAddressStr) + ": no previous vote")))
526528 let used = valueOrElse(getInteger(this, keyUsed(userAddress, epoch)), 0)
527529 let lpAssetIdStr = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
528530 let votingResultStakedPrevious = valueOrElse(getInteger(keyVotingResultStaked(lpAssetIdStr, epochPrevious)), 0)
529531 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
530532 let stakedByUser = valueOrElse(getInteger(stakingContract, keyStakedByUser(lpAssetIdStr, userAddressStr)), 0)
531533 let votingResultStakedActions = if ((stakedByUser == 0))
532534 then nil
533535 else [IntegerEntry(keyVotingResultStaked(lpAssetIdStr, epochPrevious), (votingResultStakedPrevious + votePrevious))]
534536 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
535537 let balanceIsOk = {
536538 let @ = invoke(factoryContract, "checkBalance", [lpAssetId], nil)
537539 if ($isInstanceOf(@, "Boolean"))
538540 then @
539541 else throw(($getType(@) + " couldn't be cast to Boolean"))
540542 }
541543 let newVote = if ((gwxAmountAtEndTotalPrevious > 0))
542544 then fraction(votePrevious, gwxAmountAtEndTotal, gwxAmountAtEndTotalPrevious)
543545 else 0
544546 let actions = if (if (if ((newVote > 0))
545547 then wxEmission
546548 else false)
547549 then balanceIsOk
548550 else false)
549551 then [IntegerEntry(keyVote(pool, userAddress, epoch), newVote), IntegerEntry(keyTotalVotes(epoch), (totalVotes + newVote)), IntegerEntry(keyVotingResult(pool, epoch), (votingResult + newVote)), IntegerEntry(keyUsed(userAddress, epoch), (used + newVote))]
550552 else deleteNodeActions(getVotesListName(pool), userAddressStr)
551553 $Tuple2((actions ++ votingResultStakedActions), unit)
552554 }
553555 else throw("Strict value is not equal to itself.")
554556 }
555557 else throw("Strict value is not equal to itself.")
556558 }
557559
558560
559561
560562 @Callable(i)
561563 func processPoolINTERNAL (poolStr,force) = {
562564 let checkCaller = mustThis(i)
563565 if ((checkCaller == checkCaller))
564566 then {
565567 let targetEpoch = {
566568 let currentEpoch = getIntOrFail(this, keyCurrentEpoch)
567569 if (force)
568570 then currentEpoch
569571 else (currentEpoch - 1)
570572 }
571573 let checkTargetEpoch = if ((targetEpoch >= 0))
572574 then true
573575 else throwErr("processPoolINTERNAL: invalid target epoch")
574576 if ((checkTargetEpoch == checkTargetEpoch))
575577 then {
576578 let pool = stringToPool(poolStr)
577- let $t02064120681 = pool
578- let amountAssetId = $t02064120681._1
579- let priceAssetId = $t02064120681._2
579+ let $t02072220762 = pool
580+ let amountAssetId = $t02072220762._1
581+ let priceAssetId = $t02072220762._2
580582 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
581583 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
582584 let r = {
583585 let @ = invoke(stakingContract, "usersListTraversal", [lpAssetId], nil)
584586 if ($isInstanceOf(@, "Boolean"))
585587 then @
586588 else throw(($getType(@) + " couldn't be cast to Boolean"))
587589 }
588590 if ((r == r))
589591 then if (r)
590592 then $Tuple2(nil, true)
591593 else {
594+ let assetsStoreContract = addressFromStringValue(valueOrElse(getString(this, keyAssetsStoreContract), "invalid assets store contract"))
592595 let wxEmission = checkWxEmissionPoolLabel(pool)
593596 let balanceIsOk = {
594597 let @ = invoke(factoryContract, "checkBalance", [lpAssetId], nil)
595598 if ($isInstanceOf(@, "Boolean"))
596599 then @
597600 else throw(($getType(@) + " couldn't be cast to Boolean"))
598601 }
599- let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
600- let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
601- let share = if (if (if ((totalVotes == 0))
602- then true
603- else !(wxEmission))
604- then true
605- else !(balanceIsOk))
606- then 0
607- else fraction(votingResult, poolWeightMult, totalVotes)
608- let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
609- if ((modifyWeightInv == modifyWeightInv))
602+ let amountAssetVerified = {
603+ let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [amountAssetId], nil)
604+ if ($isInstanceOf(@, "Boolean"))
605+ then @
606+ else throw(($getType(@) + " couldn't be cast to Boolean"))
607+ }
608+ let priceAssetVerified = {
609+ let @ = invoke(assetsStoreContract, "isVerifiedREADONLY", [priceAssetId], nil)
610+ if ($isInstanceOf(@, "Boolean"))
611+ then @
612+ else throw(($getType(@) + " couldn't be cast to Boolean"))
613+ }
614+ let setWxEmissionInv = if (if (if (if (!(wxEmission))
615+ then balanceIsOk
616+ else false)
617+ then amountAssetVerified
618+ else false)
619+ then priceAssetVerified
620+ else false)
621+ then invoke(factoryContract, "setWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil)
622+ else unit
623+ if ((setWxEmissionInv == setWxEmissionInv))
610624 then {
611- let poolsListActions = if (if (wxEmission)
625+ let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
626+ let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
627+ let share = if (if (if ((totalVotes == 0))
612628 then true
613- else force)
614- then nil
615- else ([DeleteEntry(keyInList(pool))] ++ deleteNodeActions(poolsListName, poolStr))
616- $Tuple2(([IntegerEntry(keyPoolShare(pool, targetEpoch), share)] ++ poolsListActions), false)
629+ else !(wxEmission))
630+ then true
631+ else !(balanceIsOk))
632+ then 0
633+ else fraction(votingResult, poolWeightMult, totalVotes)
634+ let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
635+ if ((modifyWeightInv == modifyWeightInv))
636+ then $Tuple2([IntegerEntry(keyPoolShare(pool, targetEpoch), share)], false)
637+ else throw("Strict value is not equal to itself.")
617638 }
618639 else throw("Strict value is not equal to itself.")
619640 }
620641 else throw("Strict value is not equal to itself.")
621642 }
622643 else throw("Strict value is not equal to itself.")
623644 }
624645 else throw("Strict value is not equal to itself.")
625646 }
626647
627648
628649
629650 @Callable(i)
630651 func finalizeHelper () = {
631652 let force = valueOrElse(getBoolean(keyFinalizationShouldBeForced), false)
632653 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
633654 let previousEpoch = (epoch - 1)
634655 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
635656 let epochLength = getIntOrFail(this, keyEpochLength)
636657 let endHeight = (startHeight + epochLength)
637658 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
638659 if (if (if ((height >= endHeight))
639660 then (finalizationStageOrUnit == unit)
640661 else false)
641662 then !(force)
642663 else false)
643664 then {
644665 let newEpoch = (epoch + 1)
645666 let newEpochLengthOption = getInteger(this, keyEpochLengthNew)
646667 let newEpochLengthActions = match newEpochLengthOption {
647668 case newEpochLength: Int =>
648669 [IntegerEntry(keyEpochLength, newEpochLength), DeleteEntry(keyEpochLengthNew)]
649670 case _: Unit =>
650671 nil
651672 case _ =>
652673 throw("Match error")
653674 }
654675 $Tuple2(([IntegerEntry(keyStartHeightByEpoch(newEpoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpoch, newEpoch), IntegerEntry(keyFinalizationStage, finalizationStageTotal), IntegerEntry(keyEpochLengthByEpoch(epoch), epochLength)] ++ newEpochLengthActions), true)
655676 }
656677 else if (if (force)
657678 then (finalizationStageOrUnit == unit)
658679 else false)
659680 then $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares)], true)
660681 else if ((finalizationStageOrUnit == unit))
661682 then $Tuple2(nil, false)
662683 else if ((finalizationStageOrUnit == finalizationStageTotal))
663684 then {
664685 let poolOrUnit = getString(keyNextPool)
665686 let userOrUnit = getString(keyNextUser)
666687 match poolOrUnit {
667688 case _: Unit =>
668689 match getString(keyListHead(poolsListName)) {
669690 case _: Unit =>
670691 $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
671692 case poolsHeadStr: String =>
672693 $Tuple2([StringEntry(keyNextPool, poolsHeadStr)], true)
673694 case _ =>
674695 throw("Match error")
675696 }
676697 case poolStr: String =>
677698 let pool = stringToPool(poolStr)
678699 let nextUserOrUnit = match userOrUnit {
679700 case _: Unit =>
680701 getString(keyListHead(getVotesListName(pool)))
681702 case user: String =>
682703 let next = getString(keyListNext(getVotesListName(pool), user))
683704 if ((next == next))
684705 then {
685706 let processVoteInv = invoke(this, "processVoteINTERNAL", [poolStr, user], nil)
686707 if ((processVoteInv == processVoteInv))
687708 then next
688709 else throw("Strict value is not equal to itself.")
689710 }
690711 else throw("Strict value is not equal to itself.")
691712 case _ =>
692713 throw("Match error")
693714 }
694715 match nextUserOrUnit {
695716 case _: Unit =>
696717 let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
697718 match nextPoolOrUnit {
698719 case _: Unit =>
699720 $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
700721 case s: String =>
701722 $Tuple2([StringEntry(keyNextPool, s), DeleteEntry(keyNextUser)], true)
702723 case _ =>
703724 throw("Match error")
704725 }
705726 case nextUser: String =>
706727 $Tuple2([StringEntry(keyNextUser, nextUser)], true)
707728 case _ =>
708729 throw("Match error")
709730 }
710731 case _ =>
711732 throw("Match error")
712733 }
713734 }
714735 else if ((finalizationStageOrUnit == finalizationStageShares))
715736 then {
716737 let poolOrUnit = getString(keyNextPool)
717738 match poolOrUnit {
718739 case _: Unit =>
719740 match getString(keyListHead(poolsListName)) {
720741 case _: Unit =>
721742 let actions = if (force)
722743 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced)]
723744 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight)]
724745 let gwxRewardDepositInv = gwxRewardDeposit()
725746 if ((gwxRewardDepositInv == gwxRewardDepositInv))
726747 then $Tuple2(actions, true)
727748 else throw("Strict value is not equal to itself.")
728749 case nextPoolStr: String =>
729750 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
730751 case _ =>
731752 throw("Match error")
732753 }
733754 case poolStr: String =>
734755 let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
735756 if ((nextPoolOrUnit == nextPoolOrUnit))
736757 then {
737758 let r = {
738759 let @ = invoke(this, "processPoolINTERNAL", [poolStr, force], nil)
739760 if ($isInstanceOf(@, "Boolean"))
740761 then @
741762 else throw(($getType(@) + " couldn't be cast to Boolean"))
742763 }
743764 if ((r == r))
744765 then if (r)
745766 then $Tuple2(nil, true)
746767 else match nextPoolOrUnit {
747768 case _: Unit =>
748769 let actions = if (force)
749770 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced), DeleteEntry(keyNextPool)]
750771 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight), DeleteEntry(keyNextPool)]
751772 let gwxRewardDepositInv = gwxRewardDeposit()
752773 if ((gwxRewardDepositInv == gwxRewardDepositInv))
753774 then $Tuple2(actions, true)
754775 else throw("Strict value is not equal to itself.")
755776 case nextPoolStr: String =>
756777 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
757778 case _ =>
758779 throw("Match error")
759780 }
760781 else throw("Strict value is not equal to itself.")
761782 }
762783 else throw("Strict value is not equal to itself.")
763784 case _ =>
764785 throw("Match error")
765786 }
766787 }
767788 else throwErr("finalization is broken")
768789 }
769790
770791
771792
772793 @Callable(i)
773794 func finalizeWrapper (counter) = {
774795 let votingEmissionRateContract = addressFromStringValue(getStringValue(this, keyVotingEmissionRateContract))
775796 let result = {
776797 let @ = invoke(this, "finalizeHelper", nil, nil)
777798 if ($isInstanceOf(@, "Boolean"))
778799 then @
779800 else throw(($getType(@) + " couldn't be cast to Boolean"))
780801 }
781802 if ((result == result))
782803 then if (!(result))
783804 then if ((counter == 0))
784805 then throwErr("Current voting is not over yet")
785806 else {
786807 let inv = invoke(votingEmissionRateContract, "finalize", nil, nil)
787808 if ((inv == inv))
788809 then $Tuple2(nil, unit)
789810 else throw("Strict value is not equal to itself.")
790811 }
791812 else {
792813 let maxDepth = valueOrElse(getInteger(this, keyMaxDepth), maxDepthDefault)
793814 if ((maxDepth > counter))
794815 then {
795816 let inv = invoke(this, "finalizeWrapper", [(counter + 1)], nil)
796817 if ((inv == inv))
797818 then $Tuple2(nil, unit)
798819 else throw("Strict value is not equal to itself.")
799820 }
800821 else $Tuple2(nil, unit)
801822 }
802823 else throw("Strict value is not equal to itself.")
803824 }
804825
805826
806827
807828 @Callable(i)
808829 func finalize () = {
809830 let inv = invoke(this, "finalizeWrapper", [0], nil)
810831 if ((inv == inv))
811832 then $Tuple2(nil, unit)
812833 else throw("Strict value is not equal to itself.")
813834 }
814835
815836
816837
817838 @Callable(i)
818839 func containsNodeREADONLY (listName,id) = $Tuple2(nil, containsNode(listName, id))
819840
820841
821842
822843 @Callable(i)
823844 func insertNode (listName,id) = {
824845 let checkCaller = mustManager(i)
825846 if ((checkCaller == checkCaller))
826847 then $Tuple2(insertNodeActions(listName, id), unit)
827848 else throw("Strict value is not equal to itself.")
828849 }
829850
830851
831852
832853 @Callable(i)
833854 func deleteNode (listName,id) = {
834855 let checkCaller = mustManager(i)
835856 if ((checkCaller == checkCaller))
836857 then $Tuple2(deleteNodeActions(listName, id), unit)
837858 else throw("Strict value is not equal to itself.")
838859 }
839860
840861
841862
842863 @Callable(i)
843864 func isFinalizationInProgress () = {
844865 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
845866 let finalizationInProgress = (finalizationStageOrUnit != unit)
846867 $Tuple2(nil, finalizationInProgress)
847868 }
848869
849870
850871
851872 @Callable(i)
852873 func deletePool (amountAssetId,priceAssetId) = {
853874 let checkCaller = if (if ((i.caller == factoryContract))
854875 then true
855876 else mustManager(i))
856877 then true
857878 else throwErr("Permission denied")
858879 if ((checkCaller == checkCaller))
859880 then {
860881 let listName = "pools"
861882 let pool = $Tuple2(amountAssetId, priceAssetId)
862883 let id = makeString([amountAssetId, priceAssetId], separator)
863884 let actions = if (containsNode(listName, id))
864885 then deleteNodeActions(listName, id)
865886 else nil
866887 ([DeleteEntry(keyInList(pool))] ++ actions)
867888 }
868889 else throw("Strict value is not equal to itself.")
869890 }
870891
871892
872893 @Verifier(tx)
873894 func verify () = {
874895 let targetPublicKey = match managerPublicKeyOrUnit() {
875896 case pk: ByteVector =>
876897 pk
877898 case _: Unit =>
878899 tx.senderPublicKey
879900 case _ =>
880901 throw("Match error")
881902 }
882903 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
883904 }
884905

github/deemru/w8io/169f3d6 
103.51 ms