tx · 9wNALryRHbvVdvYgPVX7w4vGaoXZQLuQt8cmdKQu1BjK

3Mp3nG9T5fKGziHW8mcCqx3jMFx3towh3WA:  -0.02200000 Waves

2023.02.15 16:01 [2450756] smart account 3Mp3nG9T5fKGziHW8mcCqx3jMFx3towh3WA > SELF 0.00000000 Waves

{ "type": 13, "id": "9wNALryRHbvVdvYgPVX7w4vGaoXZQLuQt8cmdKQu1BjK", "fee": 2200000, "feeAssetId": null, "timestamp": 1676466088205, "version": 2, "chainId": 84, "sender": "3Mp3nG9T5fKGziHW8mcCqx3jMFx3towh3WA", "senderPublicKey": "D46gQxzmdzdCTYRg6dMcwFoUrc6ZmxF6GKd5ZoTkvzp1", "proofs": [ "3Hq9aYeybzweYASwR3ACuwstiiiYyLeSBhMExRR2t1Jw6yf9Do4zPKUuNkrc79ayYKvr3hUZx8KGge32p6q3kj7s" ], "script": "base64:BgLJFAgCEgMKAQgSABIECgIIARIHCgUICAgIARIECgIICBIFCgMICAESBAoCCAgSAwoBARIDCgEBEgQKAggIEgQKAggEEgASAwoBARIAEgQKAggIEgQKAggIEgQKAggIIglzZXBhcmF0b3IiDnBvb2xXZWlnaHRNdWx0Ig9tYXhEZXB0aERlZmF1bHQiFmZpbmFsaXphdGlvblN0YWdlVG90YWwiF2ZpbmFsaXphdGlvblN0YWdlU2hhcmVzIg5rZXlFcG9jaExlbmd0aCIRa2V5RXBvY2hMZW5ndGhOZXciFWtleUVwb2NoTGVuZ3RoQnlFcG9jaCIFZXBvY2giD2tleUN1cnJlbnRFcG9jaCILa2V5TWF4RGVwdGgiImtleVZvdGluZ0VtaXNzaW9uQ2FuZGlkYXRlQ29udHJhY3QiEmtleUZhY3RvcnlDb250cmFjdCITa2V5Qm9vc3RpbmdDb250cmFjdCISa2V5U3Rha2luZ0NvbnRyYWN0IhRrZXlGaW5hbGl6YXRpb25TdGFnZSILa2V5TmV4dFBvb2wiC2tleU5leHRVc2VyIg5rZXlTdGFydEhlaWdodCIRa2V5Q3VycmVudEVwb2NoVWkiEGtleVN0YXJ0SGVpZ2h0VWkiHWtleUZpbmFsaXphdGlvblNob3VsZEJlRm9yY2VkIhVrZXlTdGFydEhlaWdodEJ5RXBvY2giDGtleUZpbmFsaXplZCIJa2V5SW5MaXN0IgRwb29sIgskdDAxNjkzMTczMyINYW1vdW50QXNzZXRJZCIMcHJpY2VBc3NldElkIgdrZXlVc2VkIgdhZGRyZXNzIgdrZXlWb3RlIgskdDAyMDA3MjA0NyIPa2V5Vm90aW5nUmVzdWx0IgskdDAyMjI5MjI2OSIMa2V5UG9vbFNoYXJlIgskdDAyNDM0MjQ3NCINa2V5VG90YWxWb3RlcyIHd3JhcEVyciIDbXNnIgh0aHJvd0VyciIOZ2V0VmFsdWVPckZhaWwiA2tleSIEdHlwZSIFZXJyb3IiByRtYXRjaDAiA3N0ciIDaW50IgxnZXRTdHJPckZhaWwiAUAiDGdldEludE9yRmFpbCIMcG9vbFRvU3RyaW5nIgxzdHJpbmdUb1Bvb2wiBXBhcnRzIhZnZXRMcEFzc2V0QnlQb29sQXNzZXRzIh9rZXlNYXBwaW5nc0Jhc2VBc3NldDJpbnRlcm5hbElkIgxiYXNlQXNzZXRTdHIiKWtleU1hcHBpbmdQb29sQXNzZXRzVG9Qb29sQ29udHJhY3RBZGRyZXNzIhhpbnRlcm5hbEFtb3VudEFzc2V0SWRTdHIiF2ludGVybmFsUHJpY2VBc3NldElkU3RyIh9rZXlNYXBwaW5nUG9vbENvbnRyYWN0VG9MUEFzc2V0IhNwb29sQ29udHJhY3RBZGRyZXNzIg9mYWN0b3J5Q29udHJhY3QiFWFtb3VudEFzc2V0SW50ZXJuYWxJZCIUcHJpY2VBc3NldEludGVybmFsSWQiCWxwQXNzZXRJZCIYY2hlY2tXeEVtaXNzaW9uUG9vbExhYmVsIgskdDA0ODQzNDg4MyINcG9vbHNMaXN0TmFtZSIQZ2V0Vm90ZXNMaXN0TmFtZSILJHQwNTE4NDUyMjQiC2tleUxpc3RIZWFkIghsaXN0TmFtZSIEbWV0YSILa2V5TGlzdFNpemUiC2tleUxpc3RQcmV2IgJpZCILa2V5TGlzdE5leHQiDGNvbnRhaW5zTm9kZSIKaGVhZE9yVW5pdCIKcHJldk9yVW5pdCIKbmV4dE9yVW5pdCIRaW5zZXJ0Tm9kZUFjdGlvbnMiCGxpc3RTaXplIgljaGVja05vZGUiEWRlbGV0ZU5vZGVBY3Rpb25zIhNrZXlNYW5hZ2VyUHVibGljS2V5IhprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleSIWbWFuYWdlclB1YmxpY0tleU9yVW5pdCIBcyIdcGVuZGluZ01hbmFnZXJQdWJsaWNLZXlPclVuaXQiFXBlcm1pc3Npb25EZW5pZWRFcnJvciIIbXVzdFRoaXMiAWkiC211c3RNYW5hZ2VyIgJwayIXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkiC2NoZWNrQ2FsbGVyIhVjaGVja01hbmFnZXJQdWJsaWNLZXkiAnBtIgVoYXNQTSIHY2hlY2tQTSILdXNlckFkZHJlc3MiDHRhcmdldEhlaWdodCIXYm9vc3RpbmdDb250cmFjdEFkZHJlc3MiH3ZvdGluZ0VtaXNzaW9uQ2FuZGlkYXRlQ29udHJhY3QiEGJvb3N0aW5nQ29udHJhY3QiD3N0YWtpbmdDb250cmFjdCILZXBvY2hMZW5ndGgiBmNoZWNrcyINaW5MaXN0QWN0aW9ucyIYY3VycmVudEVwb2NoSXNOb3REZWZpbmVkIhJzdGFydEhlaWdodEFjdGlvbnMiBmFtb3VudCILc3RhcnRIZWlnaHQiCWVuZEhlaWdodCIXZmluYWxpemF0aW9uU3RhZ2VPclVuaXQiBHVzZWQiBHZvdGUiCnBvb2xSZXN1bHQiCnRvdGFsVm90ZXMiE2d3eEFtb3VudEF0RW5kVG90YWwiCWF2YWlsYWJsZSIHbmV3Vm90ZSIKd3hFbWlzc2lvbiINdm90ZXNMaXN0TmFtZSIOdXNlckFkZHJlc3NTdHIiEHZvdGVzTGlzdEFjdGlvbnMiDm5ld0Vwb2NoTGVuZ3RoIgtuZXdNYXhEZXB0aCIHcG9vbFN0ciINZXBvY2hQcmV2aW91cyITc3RhcnRIZWlnaHRQcmV2aW91cyITZXBvY2hMZW5ndGhQcmV2aW91cyIRZW5kSGVpZ2h0UHJldmlvdXMiEGNoZWNrVGFyZ2V0RXBvY2giDSR0MDE3Njc1MTc3MTUiG2d3eEFtb3VudEF0RW5kVG90YWxQcmV2aW91cyIMdm90aW5nUmVzdWx0Igx2b3RlUHJldmlvdXMiB2FjdGlvbnMiBWZvcmNlIgt0YXJnZXRFcG9jaCIMY3VycmVudEVwb2NoIg0kdDAxOTQ0MTE5NDgxIgFyIgVzaGFyZSIPbW9kaWZ5V2VpZ2h0SW52IhBwb29sc0xpc3RBY3Rpb25zIg1wcmV2aW91c0Vwb2NoIghuZXdFcG9jaCIUbmV3RXBvY2hMZW5ndGhPcHRpb24iFW5ld0Vwb2NoTGVuZ3RoQWN0aW9ucyIKcG9vbE9yVW5pdCIKdXNlck9yVW5pdCIHJG1hdGNoMSIMcG9vbHNIZWFkU3RyIg5uZXh0VXNlck9yVW5pdCIEdXNlciIEbmV4dCIOcHJvY2Vzc1ZvdGVJbnYiDm5leHRQb29sT3JVbml0IgckbWF0Y2gyIghuZXh0VXNlciILbmV4dFBvb2xTdHIiB2NvdW50ZXIiBnJlc3VsdCIIbWF4RGVwdGgiA2ludiICdHgiBnZlcmlmeSIPdGFyZ2V0UHVibGljS2V5NgABYQICX18AAWIAgMLXLwABYwAKAAFkAAAAAWUAAQABZgkAuQkCCQDMCAICAiVzCQDMCAICC2Vwb2NoTGVuZ3RoBQNuaWwFAWEAAWcJALkJAgkAzAgCAgQlcyVzCQDMCAICEGVwb2NoTGVuZ3RoX19uZXcFA25pbAUBYQEBaAEBaQkAuQkCCQDMCAICBCVzJWQJAMwIAgILZXBvY2hMZW5ndGgJAMwIAgkApAMBBQFpBQNuaWwFAWEAAWoJALkJAgkAzAgCAgIlcwkAzAgCAgxjdXJyZW50RXBvY2gFA25pbAUBYQABawkAuQkCCQDMCAICAiVzCQDMCAICCG1heERlcHRoBQNuaWwFAWEAAWwJALkJAgkAzAgCAgIlcwkAzAgCAh92b3RpbmdFbWlzc2lvbkNhbmRpZGF0ZUNvbnRyYWN0BQNuaWwFAWEAAW0JALkJAgkAzAgCAgIlcwkAzAgCAg9mYWN0b3J5Q29udHJhY3QFA25pbAUBYQABbgkAuQkCCQDMCAICAiVzCQDMCAICEGJvb3N0aW5nQ29udHJhY3QFA25pbAUBYQABbwkAuQkCCQDMCAICAiVzCQDMCAICD3N0YWtpbmdDb250cmFjdAUDbmlsBQFhAAFwCQC5CQIJAMwIAgICJXMJAMwIAgIRZmluYWxpemF0aW9uU3RhZ2UFA25pbAUBYQABcQkAuQkCCQDMCAICAiVzCQDMCAICCG5leHRQb29sBQNuaWwFAWEAAXIJALkJAgkAzAgCAgIlcwkAzAgCAghuZXh0VXNlcgUDbmlsBQFhAAFzCQC5CQIJAMwIAgICJXMJAMwIAgILc3RhcnRIZWlnaHQFA25pbAUBYQABdAkAuQkCCQDMCAICAiVzCQDMCAICDmN1cnJlbnRFcG9jaFVpBQNuaWwFAWEAAXUJALkJAgkAzAgCAgIlcwkAzAgCAg1zdGFydEhlaWdodFVpBQNuaWwFAWEAAXYJALkJAgkAzAgCAgIlcwkAzAgCAgVmb3JjZQUDbmlsBQFhAQF3AQFpCQC5CQIJAMwIAgIEJXMlZAkAzAgCAgtzdGFydEhlaWdodAkAzAgCCQCkAwEFAWkFA25pbAUBYQEBeAEBaQkAuQkCCQDMCAICBCVzJWQJAMwIAgIJZmluYWxpemVkCQDMCAIJAKQDAQUBaQUDbmlsBQFhAQF5AQF6BAFBBQF6BAFCCAUBQQJfMQQBQwgFAUECXzIJALkJAgkAzAgCAgYlcyVzJXMJAMwIAgIGaW5MaXN0CQDMCAIFAUIJAMwIAgUBQwUDbmlsBQFhAQFEAgFFAWkJALkJAgkAzAgCAgYlcyVzJWQJAMwIAgIEdXNlZAkAzAgCCQClCAEFAUUJAMwIAgkApAMBBQFpBQNuaWwFAWEBAUYDAXoBRQFpBAFHBQF6BAFCCAUBRwJfMQQBQwgFAUcCXzIJALkJAgkAzAgCAgolcyVzJXMlcyVkCQDMCAICBHZvdGUJAMwIAgUBQgkAzAgCBQFDCQDMCAIJAKUIAQUBRQkAzAgCCQCkAwEFAWkFA25pbAUBYQEBSAIBegFpBAFJBQF6BAFCCAUBSQJfMQQBQwgFAUkCXzIJALkJAgkAzAgCAgglcyVzJXMlZAkAzAgCAgx2b3RpbmdSZXN1bHQJAMwIAgUBQgkAzAgCBQFDCQDMCAIJAKQDAQUBaQUDbmlsBQFhAQFKAgF6AWkEAUsFAXoEAUIIBQFLAl8xBAFDCAUBSwJfMgkAuQkCCQDMCAICCCVzJXMlcyVkCQDMCAICCXBvb2xTaGFyZQkAzAgCBQFCCQDMCAIFAUMJAMwIAgkApAMBBQFpBQNuaWwFAWEBAUwBAWkJALkJAgkAzAgCAgQlcyVkCQDMCAICCnRvdGFsVm90ZXMJAMwIAgkApAMBBQFpBQNuaWwFAWEBAU0BAU4JALkJAgkAzAgCAhV2b3RpbmdfZW1pc3Npb24ucmlkZToJAMwIAgUBTgUDbmlsAgEgAQFPAQFOCQACAQkBAU0BBQFOAQFQAwFFAVEBUgQBUwkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQFFCQDMCAICAS4JAMwIAgUBUQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIACQETdmFsdWVPckVycm9yTWVzc2FnZQIEAVQFAVIDCQABAgUBVAIGU3RyaW5nBAFVBQFUCQCdCAIFAUUFAVEDCQABAgUBVAIDSW50BAFWBQFUCQCaCAIFAUUFAVEJAAIBAhJpbnZhbGlkIGVudHJ5IHR5cGUFAVMBAVcCAUUBUQoAAVgJAQFQAwUBRQUBUQIAAwkAAQIFAVgCBlN0cmluZwUBWAkAAgEJAKwCAgkAAwEFAVgCGyBjb3VsZG4ndCBiZSBjYXN0IHRvIFN0cmluZwEBWQIBRQFRCgABWAkBAVADBQFFBQFRAAADCQABAgUBWAIDSW50BQFYCQACAQkArAICCQADAQUBWAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AQFaAQF6CQCsAgIJAKwCAggFAXoCXzEFAWEIBQF6Al8yAQJhYQEBVQQCYWIJALUJAgUBVQUBYQMJAAACCQCQAwEFAmFiAAIJAJQKAgkAkQMCBQJhYgAACQCRAwIFAmFiAAEJAAIBAhNpbnZhbGlkIHBvb2wgc3RyaW5nAQJhYwIBQgFDCgECYWQBAmFlCQCsAgICKCVzJXMlc19fbWFwcGluZ3NfX2Jhc2VBc3NldDJpbnRlcm5hbElkX18FAmFlCgECYWYCAmFnAmFoCQCsAgIJAKwCAgkArAICCQCsAgICCiVkJWQlcyVzX18JAKQDAQUCYWcCAl9fCQCkAwEFAmFoAiNfX21hcHBpbmdzX19wb29sQXNzZXRzMlBvb2xDb250cmFjdAoBAmFpAQJhagkArAICCQCsAgICCCVzJXMlc19fBQJhagIgX19tYXBwaW5nc19fcG9vbENvbnRyYWN0MkxwQXNzZXQEAmFrCQERQGV4dHJOYXRpdmUoMTA2MikBCQEBVwIFBHRoaXMFAW0EAmFsCQEBWQIFAmFrCQECYWQBBQFCBAJhbQkBAVkCBQJhawkBAmFkAQUBQwQCYWoJAQFXAgUCYWsJAQJhZgIFAmFsBQJhbQQCYW4JAQFXAgUCYWsJAQJhaQEFAmFqBQJhbgECYW8BAXoEAmFwBQF6BAFCCAUCYXACXzEEAUMIBQJhcAJfMgQCYWsJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQFXAgUEdGhpcwUBbQoAAVgJAPwHBAUCYWsCGGNoZWNrV3hFbWlzc2lvblBvb2xMYWJlbAkAzAgCBQFCCQDMCAIFAUMFA25pbAUDbmlsAwkAAQIFAVgCB0Jvb2xlYW4FAVgJAAIBCQCsAgIJAAMBBQFYAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuAAJhcQIFcG9vbHMBAmFyAQF6BAJhcwUBegQBQggFAmFzAl8xBAFDCAUCYXMCXzIJALkJAgkAzAgCAgV2b3RlcwkAzAgCBQFCCQDMCAIFAUMFA25pbAUBYQECYXQBAmF1BAJhdgMJAAACBQJhdQUCYXECBCVzJXMCCCVzJXMlcyVzCQC5CQIJAMwIAgUCYXYJAMwIAgUCYXUJAMwIAgIEaGVhZAUDbmlsBQFhAQJhdwECYXUEAmF2AwkAAAIFAmF1BQJhcQIEJXMlcwIIJXMlcyVzJXMJALkJAgkAzAgCBQJhdgkAzAgCBQJhdQkAzAgCAgRzaXplBQNuaWwFAWEBAmF4AgJhdQJheQQCYXYDCQAAAgUCYXUFAmFxAgglcyVzJXMlcwIKJXMlcyVzJXMlcwkAuQkCCQDMCAIFAmF2CQDMCAIFAmF1CQDMCAIFAmF5CQDMCAICBHByZXYFA25pbAUBYQECYXoCAmF1AmF5BAJhdgMJAAACBQJhdQUCYXECCCVzJXMlcyVzAgolcyVzJXMlcyVzCQC5CQIJAMwIAgUCYXYJAMwIAgUCYXUJAMwIAgUCYXkJAMwIAgIEbmV4dAUDbmlsBQFhAQJhQQICYXUCYXkEAmFCCQCdCAIFBHRoaXMJAQJhdAEFAmF1BAJhQwkAnQgCBQR0aGlzCQECYXgCBQJhdQUCYXkEAmFECQCdCAIFBHRoaXMJAQJhegIFAmF1BQJheQMDCQAAAgUCYXkJAQt2YWx1ZU9yRWxzZQIFAmFCAgAGCQECIT0CBQJhQwUEdW5pdAYJAQIhPQIFAmFEBQR1bml0AQJhRQICYXUCYXkEAmFCCQCdCAIFBHRoaXMJAQJhdAEFAmF1BAJhRgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQECYXcBBQJhdQAABAJhRwMJAQEhAQkBAmFBAgUCYXUFAmF5BgkAAgECC05vZGUgZXhpc3RzAwkAAAIFAmFHBQJhRwkAzggCCQDOCAIJAMwIAgkBDEludGVnZXJFbnRyeQIJAQJhdwEFAmF1CQBkAgUCYUYAAQUDbmlsAwkBAiE9AgUCYUIFBHVuaXQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmF6AgUCYXUFAmF5CQEFdmFsdWUBBQJhQgkAzAgCCQELU3RyaW5nRW50cnkCCQECYXgCBQJhdQkBBXZhbHVlAQUCYUIFAmF5BQNuaWwFA25pbAkAzAgCCQELU3RyaW5nRW50cnkCCQECYXQBBQJhdQUCYXkFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECYUgCAmF1AmF5BAJhQgkAnQgCBQR0aGlzCQECYXQBBQJhdQQCYUYJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAmF3AQUCYXUAAAQCYUMJAJ0IAgUEdGhpcwkBAmF4AgUCYXUFAmF5BAJhRAkAnQgCBQR0aGlzCQECYXoCBQJhdQUCYXkJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAmF3AQUCYXUJAGUCBQJhRgABBQNuaWwDAwkBAiE9AgUCYUMFBHVuaXQJAQIhPQIFAmFEBQR1bml0BwkAzAgCCQELU3RyaW5nRW50cnkCCQECYXoCBQJhdQkBBXZhbHVlAQUCYUMJAQV2YWx1ZQEFAmFECQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJheAIFAmF1CQEFdmFsdWUBBQJhRAkBBXZhbHVlAQUCYUMJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAmF4AgUCYXUFAmF5CQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhegIFAmF1BQJheQUDbmlsAwkBAiE9AgUCYUQFBHVuaXQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmF0AQUCYXUJAQV2YWx1ZQEFAmFECQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhegIFAmF1BQJheQkAzAgCCQELRGVsZXRlRW50cnkBCQECYXgCBQJhdQkBBXZhbHVlAQUCYUQFA25pbAMJAQIhPQIFAmFDBQR1bml0CQDMCAIJAQtEZWxldGVFbnRyeQEJAQJheAIFAmF1BQJheQkAzAgCCQELRGVsZXRlRW50cnkBCQECYXoCBQJhdQkBBXZhbHVlAQUCYUMFA25pbAMJAAACBQJheQkBC3ZhbHVlT3JFbHNlAgUCYUICAAkAzAgCCQELRGVsZXRlRW50cnkBCQECYXQBBQJhdQUDbmlsCQACAQkArAICCQCsAgIJAKwCAgIOaW52YWxpZCBub2RlOiAFAmF1AgEuBQJheQECYUkAAhQlc19fbWFuYWdlclB1YmxpY0tleQECYUoAAhslc19fcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkBAmFLAAQBVAkAoggBCQECYUkAAwkAAQIFAVQCBlN0cmluZwQCYUwFAVQJANkEAQUCYUwDCQABAgUBVAIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJhTQAEAVQJAKIIAQkBAmFKAAMJAAECBQFUAgZTdHJpbmcEAmFMBQFUCQDZBAEFAmFMAwkAAQIFAVQCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgACYU4JAAIBAhFQZXJtaXNzaW9uIGRlbmllZAECYU8BAmFQAwkAAAIIBQJhUAZjYWxsZXIFBHRoaXMGBQJhTgECYVEBAmFQBAFUCQECYUsAAwkAAQIFAVQCCkJ5dGVWZWN0b3IEAmFSBQFUAwkAAAIIBQJhUA9jYWxsZXJQdWJsaWNLZXkFAmFSBgUCYU4DCQABAgUBVAIEVW5pdAkBAmFPAQUCYVAJAAIBAgtNYXRjaCBlcnJvchECYVABCnNldE1hbmFnZXIBAmFTBAJhVAkBAmFRAQUCYVADCQAAAgUCYVQFAmFUBAJhVQkA2QQBBQJhUwMJAAACBQJhVQUCYVUJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFKAAUCYVMFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhUAEOY29uZmlybU1hbmFnZXIABAJhVgkBAmFNAAQCYVcDCQEJaXNEZWZpbmVkAQUCYVYGCQACAQISTm8gcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmFXBQJhVwQCYVgDCQAAAggFAmFQD2NhbGxlclB1YmxpY0tleQkBBXZhbHVlAQUCYVYGCQACAQIbWW91IGFyZSBub3QgcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmFYBQJhWAkAzAgCCQELU3RyaW5nRW50cnkCCQECYUkACQDYBAEJAQV2YWx1ZQEFAmFWCQDMCAIJAQtEZWxldGVFbnRyeQEJAQJhSgAFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhUAEYZ2V0VXNlckd3eEFtb3VudEF0SGVpZ2h0AgJhWQJhWgQCYmEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQEBVwIFBHRoaXMFAW4CIWludmFsaWQgYm9vc3RpbmcgY29udHJhY3QgYWRkcmVzcwkAlAoCBQNuaWwKAAFYCQD8BwQFAmJhAiBnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHRSRUFET05MWQkAzAgCBQJhWQkAzAgCBQJhWgUDbmlsBQNuaWwDCQABAgUBWAIDSW50BQFYCQACAQkArAICCQADAQUBWAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50AmFQAQtjb25zdHJ1Y3RvcgUCYWsCYmICYmMCYmQCYmUEAmJmCQDMCAIJAQJhUQEFAmFQCQDMCAIDCQECIT0CCQCmCAEFAmFrBQR1bml0BgIgaW52YWxpZCBmYWN0b3J5IGNvbnRyYWN0IGFkZHJlc3MJAMwIAgMJAQIhPQIJAKYIAQUCYmIFBHVuaXQGAjJpbnZhbGlkIHZvdGluZyBlbWlzc2lvbiBjYW5kaWRhdGUgY29udHJhY3QgYWRkcmVzcwkAzAgCAwkBAiE9AgkApggBBQJiYwUEdW5pdAYCIWludmFsaWQgYm9vc3RpbmcgY29udHJhY3QgYWRkcmVzcwkAzAgCAwkBAiE9AgkApggBBQJiZAUEdW5pdAYCIGludmFsaWQgc3Rha2luZyBjb250cmFjdCBhZGRyZXNzCQDMCAIDCQBmAgUCYmUAAAYJAAIBAhRpbnZhbGlkIGVwb2NoIGxlbmd0aAUDbmlsAwkAAAIFAmJmBQJiZgkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAW0FAmFrCQDMCAIJAQtTdHJpbmdFbnRyeQIFAWwFAmJiCQDMCAIJAQtTdHJpbmdFbnRyeQIFAW4FAmJjCQDMCAIJAQtTdHJpbmdFbnRyeQIFAW8FAmJkCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFmBQJiZQUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFQAQZjcmVhdGUCAUIBQwQCYmYJAMwIAgMJAAACCQDYBAEICAUCYVAGY2FsbGVyBWJ5dGVzCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMFAWwCAAYJAQJhUQEFAmFQBQNuaWwDCQAAAgUCYmYFAmJmBAF6CQCUCgIFAUIFAUMEAmJnCQDOCAIJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAQF5AQUBegYFA25pbAkBAmFFAgUCYXEJAQFaAQUBegQCYmgJAAACCQCaCAIFBHRoaXMFAWoFBHVuaXQEAmJpAwUCYmgEAWkAAAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBagUBaQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAXcBBQFpBQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFAXMFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdAUBaQkAzAgCCQEMSW50ZWdlckVudHJ5AgUBdQUGaGVpZ2h0BQNuaWwFA25pbAkAlAoCCQDOCAIFAmJnBQJiaQUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhUAEEdm90ZQMBQgFDAmJqBAF6CQCUCgIFAUIFAUMEAWkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBagAABAJiawkBAVkCBQR0aGlzCQEBdwEFAWkEAmJlCQEBWQIFBHRoaXMFAWYEAmJsCQBkAgUCYmsFAmJlBAJibQkAmggCBQR0aGlzBQFwBAJibgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBRAIIBQJhUAZjYWxsZXIFAWkAAAQCYm8JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUYDBQF6CAUCYVAGY2FsbGVyBQFpAAAEAmJwCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFIAgUBegUBaQAABAJicQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBTAEFAWkAAAQCYnIKAAFYCQD8BwQFBHRoaXMCGGdldFVzZXJHd3hBbW91bnRBdEhlaWdodAkAzAgCCQDYBAEICAUCYVAGY2FsbGVyBWJ5dGVzCQDMCAIFAmJsBQNuaWwFA25pbAMJAAECBQFYAgNJbnQFAVgJAAIBCQCsAgIJAAMBBQFYAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQEAmJzCQBlAgUCYnIFAmJuBAJidAkAZAIFAmJvBQJiagQCYnUJAQJhbwEFAXoEAmJmCQDMCAIDCQECIT0CCQCgCAEJAQF5AQUBegUEdW5pdAYJAAIBAg5pbnZhbGlkIGFzc2V0cwkAzAgCAwkAZgIFAmJsBQZoZWlnaHQGCQACAQIOaW52YWxpZCBoZWlnaHQJAMwIAgMJAAACBQJibQUEdW5pdAYJAAIBAhhmaW5hbGl6YXRpb24gaW4gcHJvZ3Jlc3MJAMwIAgMJAGYCBQJicgAABgkAAgECE3lvdSBkbyBub3QgaGF2ZSBnV1gJAMwIAgMDCQBmAgUCYmoAAAkAZwIFAmJzBQJiagcGCQACAQIOaW52YWxpZCBhbW91bnQJAMwIAgMFAmJ1BgkAAgECHXBvb2wgaGFzbid0IFdYX0VNSVNTSU9OIGxhYmVsBQNuaWwDCQAAAgUCYmYFAmJmBAJidgkBAmFyAQUBegQCYncJAKUIAQgFAmFQBmNhbGxlcgQCYngDCQECYUECBQJidgUCYncFA25pbAkBAmFFAgUCYnYFAmJ3CQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUQCCAUCYVAGY2FsbGVyBQFpCQBkAgUCYm4FAmJqCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBRgMFAXoIBQJhUAZjYWxsZXIFAWkFAmJ0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBSAIFAXoFAWkJAGQCBQJicAUCYmoJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFMAQUBaQkAZAIFAmJxBQJiagUDbmlsBQJieAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhUAEKY2FuY2VsVm90ZQIBQgFDBAF6CQCUCgIFAUIFAUMEAWkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBagAABAJiawkBAVkCBQR0aGlzCQEBdwEFAWkEAmJlCQEBWQIFBHRoaXMFAWYEAmJsCQBkAgUCYmsFAmJlBAJibQkAmggCBQR0aGlzBQFwBAJibgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBRAIIBQJhUAZjYWxsZXIFAWkAAAQCYm8JAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUYDBQF6CAUCYVAGY2FsbGVyBQFpAAAEAmJwCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFIAgUBegUBaQAABAJicQkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBTAEFAWkAAAQCYmYJAMwIAgMJAQIhPQIJAKAIAQkBAXkBBQF6BQR1bml0BgkAAgECDmludmFsaWQgYXNzZXRzCQDMCAIDCQBmAgUCYmwFBmhlaWdodAYJAAIBAg5pbnZhbGlkIGhlaWdodAkAzAgCAwkAAAIFAmJtBQR1bml0BgkAAgECGGZpbmFsaXphdGlvbiBpbiBwcm9ncmVzcwkAzAgCAwkAZgIFAmJvAAAGCQACAQIHbm8gdm90ZQUDbmlsAwkAAAIFAmJmBQJiZgQCYnYJAQJhcgEFAXoEAmJ3CQClCAEIBQJhUAZjYWxsZXIJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBRAIIBQJhUAZjYWxsZXIFAWkJAJYDAQkAzAgCCQBlAgUCYm4FAmJvCQDMCAIAAAUDbmlsCQDMCAIJAQtEZWxldGVFbnRyeQEJAQFGAwUBeggFAmFQBmNhbGxlcgUBaQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUgCBQF6BQFpCQBlAgUCYnAFAmJvCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBTAEFAWkJAGUCBQJicQUCYm8FA25pbAkBAmFIAgUCYnYFAmJ3BQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFQAQ5zZXRFcG9jaExlbmd0aAECYnkEAmJmCQDMCAIJAQJhUQEFAmFQCQDMCAIDCQBmAgUCYnkAAAYJAAIBAhRpbnZhbGlkIGVwb2NoIGxlbmd0aAUDbmlsAwkAAAIFAmJmBQJiZgkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFnBQJieQUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFQAQtzZXRNYXhEZXB0aAECYnoEAmJmCQDMCAIJAQJhUQEFAmFQCQDMCAIDCQBmAgUCYnoAAAYJAAIBAhFpbnZhbGlkIG1heCBkZXB0aAUDbmlsAwkAAAIFAmJmBQJiZgkAlAoCCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFrBQJiegUDbmlsBQR1bml0CQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFQARNwcm9jZXNzVm90ZUlOVEVSTkFMAgJiQQJidwQCYVQJAQJhTwEFAmFQAwkAAAIFAmFUBQJhVAQCYVkJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBBQJidwkArAICAipwcm9jZXNzVm90ZUlOVEVSTkFMOiBpbnZhbGlkIHVzZXIgYWRkcmVzcyAFAmJ3BAFpCQEBWQIFBHRoaXMFAWoEAmJCCQBlAgUBaQABBAJiZQkBAVkCBQR0aGlzBQFmBAJiawkBAVkCBQR0aGlzCQEBdwEFAWkEAmJsCQBkAgUCYmsFAmJlBAJiQwkBAVkCBQR0aGlzCQEBdwEFAmJCBAJiRAkBAVkCBQR0aGlzCQEBaAEFAmJCBAJiRQkAZAIFAmJDBQJiRAQCYkYDCQBnAgUCYkIAAAYJAAIBAitwcm9jZXNzVm90ZUlOVEVSTkFMOiBpbnZhbGlkIHByZXZpb3VzIGVwb2NoAwkAAAIFAmJGBQJiRgQBegkBAmFhAQUCYkEEAmJHBQF6BAFCCAUCYkcCXzEEAUMIBQJiRwJfMgQCYnUJAQJhbwEFAXoEAmJyCgABWAkA/AcEBQR0aGlzAhhnZXRVc2VyR3d4QW1vdW50QXRIZWlnaHQJAMwIAgUCYncJAMwIAgUCYmwFA25pbAUDbmlsAwkAAQIFAVgCA0ludAUBWAkAAgEJAKwCAgkAAwEFAVgCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAQCYkgKAAFYCQD8BwQFBHRoaXMCGGdldFVzZXJHd3hBbW91bnRBdEhlaWdodAkAzAgCBQJidwkAzAgCBQJiRQUDbmlsBQNuaWwDCQABAgUBWAIDSW50BQFYCQACAQkArAICCQADAQUBWAIYIGNvdWxkbid0IGJlIGNhc3QgdG8gSW50BAJicQkBC3ZhbHVlT3JFbHNlAgkAnwgBCQEBTAEFAWkAAAQCYkkJAQt2YWx1ZU9yRWxzZQIJAJ8IAQkBAUgCBQF6BQFpAAAEAmJKCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ8IAQkBAUYDBQF6BQJhWQUCYkIJAKwCAgkArAICCQCsAgIJAKwCAgIUcHJvY2Vzc1ZvdGVJTlRFUk5BTCAFAmJBAgEgBQJidwISOiBubyBwcmV2aW91cyB2b3RlBAJibgkBC3ZhbHVlT3JFbHNlAgkAmggCBQR0aGlzCQEBRAIFAmFZBQFpAAAEAmJ0AwkAZgIFAmJIAAAJAGsDBQJiSgUCYnIFAmJIAAAEAmJLAwMJAGYCBQJidAAABQJidQcJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFGAwUBegUCYVkFAWkFAmJ0CQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBTAEFAWkJAGQCBQJicQUCYnQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFIAgUBegUBaQkAZAIFAmJJBQJidAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUQCBQJhWQUBaQkAZAIFAmJuBQJidAUDbmlsCQECYUgCCQECYXIBBQF6BQJidwkAlAoCBQJiSwUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhUAETcHJvY2Vzc1Bvb2xJTlRFUk5BTAICYkECYkwEAmFUCQECYU8BBQJhUAMJAAACBQJhVAUCYVQEAmJNBAJiTgkBAVkCBQR0aGlzBQFqAwUCYkwFAmJOCQBlAgUCYk4AAQQCYkYDCQBnAgUCYk0AAAYJAAIBAilwcm9jZXNzUG9vbElOVEVSTkFMOiBpbnZhbGlkIHRhcmdldCBlcG9jaAMJAAACBQJiRgUCYkYEAXoJAQJhYQEFAmJBBAJiTwUBegQBQggFAmJPAl8xBAFDCAUCYk8CXzIEAmJkCQERQGV4dHJOYXRpdmUoMTA2MikBCQEBVwIFBHRoaXMFAW8EAmFrCQERQGV4dHJOYXRpdmUoMTA2MikBCQEBVwIFBHRoaXMFAW0EAmFuCQECYWMCBQFCBQFDBAJiUAoAAVgJAPwHBAUCYmQCEnVzZXJzTGlzdFRyYXZlcnNhbAkAzAgCBQJhbgUDbmlsBQNuaWwDCQABAgUBWAIHQm9vbGVhbgUBWAkAAgEJAKwCAgkAAwEFAVgCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4DCQAAAgUCYlAFAmJQAwUCYlAJAJQKAgUDbmlsBgQCYnUJAQJhbwEFAXoEAmJxCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMJAQFMAQUCYk0AAAQCYkkJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwkBAUgCBQF6BQJiTQAABAJiUQMDCQAAAgUCYnEAAAYJAQEhAQUCYnUAAAkAawMFAmJJBQFiBQJicQQCYlIJAPwHBAUCYWsCDG1vZGlmeVdlaWdodAkAzAgCBQJhbgkAzAgCBQJiUQUDbmlsBQNuaWwDCQAAAgUCYlIFAmJSBAJiUwMDBQJidQYFAmJMBQNuaWwJAM4IAgkAzAgCCQELRGVsZXRlRW50cnkBCQEBeQEFAXoFA25pbAkBAmFIAgUCYXEFAmJBCQCUCgIJAM4IAgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAUoCBQF6BQJiTQUCYlEFA25pbAUCYlMHCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmFQAQ5maW5hbGl6ZUhlbHBlcgAEAmJMCQELdmFsdWVPckVsc2UCCQCgCAEFAXYHBAFpCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAWoAAAQCYlQJAGUCBQFpAAEEAmJrCQEBWQIFBHRoaXMJAQF3AQUBaQQCYmUJAQFZAgUEdGhpcwUBZgQCYmwJAGQCBQJiawUCYmUEAmJtCQCaCAIFBHRoaXMFAXADAwMJAGcCBQZoZWlnaHQFAmJsCQAAAgUCYm0FBHVuaXQHCQEBIQEFAmJMBwQCYlUJAGQCBQFpAAEEAmJWCQCaCAIFBHRoaXMFAWcEAmJXBAFUBQJiVgMJAAECBQFUAgNJbnQEAmJ5BQFUCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQFmBQJieQkAzAgCCQELRGVsZXRlRW50cnkBBQFnBQNuaWwDCQABAgUBVAIEVW5pdAUDbmlsCQACAQILTWF0Y2ggZXJyb3IJAJQKAgkAzggCCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBdwEFAmJVBQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFAXMFBmhlaWdodAkAzAgCCQEMSW50ZWdlckVudHJ5AgUBagUCYlUJAMwIAgkBDEludGVnZXJFbnRyeQIFAXAFAWQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFoAQUBaQUCYmUFA25pbAUCYlcGAwMFAmJMCQAAAgUCYm0FBHVuaXQHCQCUCgIJAMwIAgkBDEludGVnZXJFbnRyeQIFAXAFAWUFA25pbAYDCQAAAgUCYm0FBHVuaXQJAJQKAgUDbmlsBwMJAAACBQJibQUBZAQCYlgJAKIIAQUBcQQCYlkJAKIIAQUBcgQBVAUCYlgDCQABAgUBVAIEVW5pdAQCYloJAKIIAQkBAmF0AQUCYXEDCQABAgUCYloCBFVuaXQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBcAUBZQkAzAgCCQELRGVsZXRlRW50cnkBBQFxCQDMCAIJAQtEZWxldGVFbnRyeQEFAXIFA25pbAYDCQABAgUCYloCBlN0cmluZwQCY2EFAmJaCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBcQUCY2EFA25pbAYJAAIBAgtNYXRjaCBlcnJvcgMJAAECBQFUAgZTdHJpbmcEAmJBBQFUBAF6CQECYWEBBQJiQQQCY2IEAmJaBQJiWQMJAAECBQJiWgIEVW5pdAkAoggBCQECYXQBCQECYXIBBQF6AwkAAQIFAmJaAgZTdHJpbmcEAmNjBQJiWgQCY2QJAKIIAQkBAmF6AgkBAmFyAQUBegUCY2MDCQAAAgUCY2QFAmNkBAJjZQkA/AcEBQR0aGlzAhNwcm9jZXNzVm90ZUlOVEVSTkFMCQDMCAIFAmJBCQDMCAIFAmNjBQNuaWwFA25pbAMJAAACBQJjZQUCY2UFAmNkCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQILTWF0Y2ggZXJyb3IEAmJaBQJjYgMJAAECBQJiWgIEVW5pdAQCY2YJAKIIAQkBAmF6AgUCYXEFAmJBBAJjZwUCY2YDCQABAgUCY2cCBFVuaXQJAJQKAgkAzAgCCQEMSW50ZWdlckVudHJ5AgUBcAUBZQkAzAgCCQELRGVsZXRlRW50cnkBBQFxCQDMCAIJAQtEZWxldGVFbnRyeQEFAXIFA25pbAYDCQABAgUCY2cCBlN0cmluZwQCYUwFAmNnCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgUBcQUCYUwJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcgUDbmlsBgkAAgECC01hdGNoIGVycm9yAwkAAQIFAmJaAgZTdHJpbmcEAmNoBQJiWgkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXIFAmNoBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IJAAIBAgtNYXRjaCBlcnJvcgMJAAACBQJibQUBZQQCYlgJAKIIAQUBcQQBVAUCYlgDCQABAgUBVAIEVW5pdAQCYloJAKIIAQkBAmF0AQUCYXEDCQABAgUCYloCBFVuaXQEAmJLAwUCYkwJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcAkAzAgCCQELRGVsZXRlRW50cnkBBQF2BQNuaWwJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcAkAzAgCCQEMQm9vbGVhbkVudHJ5AgkBAXgBBQJiVAYJAMwIAgkBDEludGVnZXJFbnRyeQIFAXQFAWkJAMwIAgkBDEludGVnZXJFbnRyeQIFAXUFAmJrBQNuaWwJAJQKAgUCYksGAwkAAQIFAmJaAgZTdHJpbmcEAmNpBQJiWgkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXEFAmNpBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IDCQABAgUBVAIGU3RyaW5nBAJiQQUBVAQCY2YJAKIIAQkBAmF6AgUCYXEFAmJBAwkAAAIFAmNmBQJjZgQCYlAKAAFYCQD8BwQFBHRoaXMCE3Byb2Nlc3NQb29sSU5URVJOQUwJAMwIAgUCYkEJAMwIAgUCYkwFA25pbAUDbmlsAwkAAQIFAVgCB0Jvb2xlYW4FAVgJAAIBCQCsAgIJAAMBBQFYAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuAwkAAAIFAmJQBQJiUAMFAmJQCQCUCgIFA25pbAYEAmJaBQJjZgMJAAECBQJiWgIEVW5pdAQCYksDBQJiTAkAzAgCCQELRGVsZXRlRW50cnkBBQFwCQDMCAIJAQtEZWxldGVFbnRyeQEFAXYJAMwIAgkBC0RlbGV0ZUVudHJ5AQUBcQUDbmlsCQDMCAIJAQtEZWxldGVFbnRyeQEFAXAJAMwIAgkBDEJvb2xlYW5FbnRyeQIJAQF4AQUCYlQGCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF0BQFpCQDMCAIJAQxJbnRlZ2VyRW50cnkCBQF1BQJiawkAzAgCCQELRGVsZXRlRW50cnkBBQFxBQNuaWwJAJQKAgUCYksGAwkAAQIFAmJaAgZTdHJpbmcEAmNpBQJiWgkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIFAXEFAmNpBQNuaWwGCQACAQILTWF0Y2ggZXJyb3IJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAgtNYXRjaCBlcnJvcgkAAgECFmZpbmFsaXphdGlvbiBpcyBicm9rZW4CYVABD2ZpbmFsaXplV3JhcHBlcgECY2oEAmNrCgABWAkA/AcEBQR0aGlzAg5maW5hbGl6ZUhlbHBlcgUDbmlsBQNuaWwDCQABAgUBWAIHQm9vbGVhbgUBWAkAAgEJAKwCAgkAAwEFAVgCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4DCQAAAgUCY2sFAmNrAwkBASEBBQJjawMJAAACBQJjagAACQACAQIeQ3VycmVudCB2b3RpbmcgaXMgbm90IG92ZXIgeWV0CQCUCgIFA25pbAUEdW5pdAQCY2wJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUBawUBYwMJAGYCBQJjbAUCY2oEAmNtCQD8BwQFBHRoaXMCD2ZpbmFsaXplV3JhcHBlcgkAzAgCCQBkAgUCY2oAAQUDbmlsBQNuaWwDCQAAAgUCY20FAmNtCQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAlAoCBQNuaWwFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYVABCGZpbmFsaXplAAQCY20JAPwHBAUEdGhpcwIPZmluYWxpemVXcmFwcGVyCQDMCAIAAAUDbmlsBQNuaWwDCQAAAgUCY20FAmNtCQCUCgIFA25pbAUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJhUAEUY29udGFpbnNOb2RlUkVBRE9OTFkCAmF1AmF5CQCUCgIFA25pbAkBAmFBAgUCYXUFAmF5AmFQAQppbnNlcnROb2RlAgJhdQJheQQCYVQJAQJhUQEFAmFQAwkAAAIFAmFUBQJhVAkAlAoCCQECYUUCBQJhdQUCYXkFBHVuaXQJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CYVABCmRlbGV0ZU5vZGUCAmF1AmF5BAJhVAkBAmFRAQUCYVADCQAAAgUCYVQFAmFUCQCUCgIJAQJhSAIFAmF1BQJheQUEdW5pdAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY24BAmNvAAQCY3AEAVQJAQJhSwADCQABAgUBVAIKQnl0ZVZlY3RvcgQCYVIFAVQFAmFSAwkAAQIFAVQCBFVuaXQIBQJjbg9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgkA9AMDCAUCY24JYm9keUJ5dGVzCQCRAwIIBQJjbgZwcm9vZnMAAAUCY3B/mryz", "height": 2450756, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 9WWceSDgNsALAgLzTKevALZyJJ7rXd3XQJFnFqMLtzmA Next: J5xk3tv5ZG3ejqi8Nb7LUtAzqNrUxLQh2U7ek9ud6Pa3 Diff:
OldNewDifferences
810810 }
811811
812812
813-
814-@Callable(i)
815-func getVoteInfoREADONLY (lpAssetIdStr,userAddressStr) = {
816- let userAddress = addressFromStringValue(userAddressStr)
817- let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
818- let idxAmountAssetId = 4
819- let idxPriceAssetId = 5
820- let poolCfg = {
821- let @ = invoke(factoryContract, "getPoolConfigByLpAssetId", [lpAssetIdStr], nil)
822- if ($isInstanceOf(@, "List[Any]"))
823- then @
824- else throw(($getType(@) + " couldn't be cast to List[Any]"))
825- }
826- let amountAssetId = {
827- let @ = poolCfg[idxAmountAssetId]
828- if ($isInstanceOf(@, "String"))
829- then @
830- else throw(($getType(@) + " couldn't be cast to String"))
831- }
832- let priceAssetId = {
833- let @ = poolCfg[idxPriceAssetId]
834- if ($isInstanceOf(@, "String"))
835- then @
836- else throw(($getType(@) + " couldn't be cast to String"))
837- }
838- let lastFinalizedEpoch = {
839- let epoch = (value(getInteger(this, keyCurrentEpoch)) - 1)
840- if ((0 > epoch))
841- then throwErr("invalid epoch")
842- else epoch
843- }
844- let pool = $Tuple2(amountAssetId, priceAssetId)
845- let userVote = valueOrElse(getInteger(this, keyVote(pool, userAddress, lastFinalizedEpoch)), 0)
846- let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, lastFinalizedEpoch)), 0)
847- $Tuple2(nil, $Tuple2(userVote, poolResult))
848- }
849-
850-
851813 @Verifier(tx)
852814 func verify () = {
853815 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 keyFactoryContract = makeString(["%s", "factoryContract"], separator)
2828
2929 let keyBoostingContract = makeString(["%s", "boostingContract"], separator)
3030
3131 let keyStakingContract = makeString(["%s", "stakingContract"], separator)
3232
3333 let keyFinalizationStage = makeString(["%s", "finalizationStage"], separator)
3434
3535 let keyNextPool = makeString(["%s", "nextPool"], separator)
3636
3737 let keyNextUser = makeString(["%s", "nextUser"], separator)
3838
3939 let keyStartHeight = makeString(["%s", "startHeight"], separator)
4040
4141 let keyCurrentEpochUi = makeString(["%s", "currentEpochUi"], separator)
4242
4343 let keyStartHeightUi = makeString(["%s", "startHeightUi"], separator)
4444
4545 let keyFinalizationShouldBeForced = makeString(["%s", "force"], separator)
4646
4747 func keyStartHeightByEpoch (epoch) = makeString(["%s%d", "startHeight", toString(epoch)], separator)
4848
4949
5050 func keyFinalized (epoch) = makeString(["%s%d", "finalized", toString(epoch)], separator)
5151
5252
5353 func keyInList (pool) = {
5454 let $t016931733 = pool
5555 let amountAssetId = $t016931733._1
5656 let priceAssetId = $t016931733._2
5757 makeString(["%s%s%s", "inList", amountAssetId, priceAssetId], separator)
5858 }
5959
6060
6161 func keyUsed (address,epoch) = makeString(["%s%s%d", "used", toString(address), toString(epoch)], separator)
6262
6363
6464 func keyVote (pool,address,epoch) = {
6565 let $t020072047 = pool
6666 let amountAssetId = $t020072047._1
6767 let priceAssetId = $t020072047._2
6868 makeString(["%s%s%s%s%d", "vote", amountAssetId, priceAssetId, toString(address), toString(epoch)], separator)
6969 }
7070
7171
7272 func keyVotingResult (pool,epoch) = {
7373 let $t022292269 = pool
7474 let amountAssetId = $t022292269._1
7575 let priceAssetId = $t022292269._2
7676 makeString(["%s%s%s%d", "votingResult", amountAssetId, priceAssetId, toString(epoch)], separator)
7777 }
7878
7979
8080 func keyPoolShare (pool,epoch) = {
8181 let $t024342474 = pool
8282 let amountAssetId = $t024342474._1
8383 let priceAssetId = $t024342474._2
8484 makeString(["%s%s%s%d", "poolShare", amountAssetId, priceAssetId, toString(epoch)], separator)
8585 }
8686
8787
8888 func keyTotalVotes (epoch) = makeString(["%s%d", "totalVotes", toString(epoch)], separator)
8989
9090
9191 func wrapErr (msg) = makeString(["voting_emission.ride:", msg], " ")
9292
9393
9494 func throwErr (msg) = throw(wrapErr(msg))
9595
9696
9797 func getValueOrFail (address,key,type) = {
9898 let error = makeString(["mandatory ", toString(address), ".", key, " is not defined"], "")
9999 valueOrErrorMessage( match type {
100100 case str: String =>
101101 getString(address, key)
102102 case int: Int =>
103103 getInteger(address, key)
104104 case _ =>
105105 throw("invalid entry type")
106106 }, error)
107107 }
108108
109109
110110 func getStrOrFail (address,key) = {
111111 let @ = getValueOrFail(address, key, "")
112112 if ($isInstanceOf(@, "String"))
113113 then @
114114 else throw(($getType(@) + " couldn't be cast to String"))
115115 }
116116
117117
118118 func getIntOrFail (address,key) = {
119119 let @ = getValueOrFail(address, key, 0)
120120 if ($isInstanceOf(@, "Int"))
121121 then @
122122 else throw(($getType(@) + " couldn't be cast to Int"))
123123 }
124124
125125
126126 func poolToString (pool) = ((pool._1 + separator) + pool._2)
127127
128128
129129 func stringToPool (str) = {
130130 let parts = split(str, separator)
131131 if ((size(parts) == 2))
132132 then $Tuple2(parts[0], parts[1])
133133 else throw("invalid pool string")
134134 }
135135
136136
137137 func getLpAssetByPoolAssets (amountAssetId,priceAssetId) = {
138138 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
139139
140140 func keyMappingPoolAssetsToPoolContractAddress (internalAmountAssetIdStr,internalPriceAssetIdStr) = (((("%d%d%s%s__" + toString(internalAmountAssetIdStr)) + "__") + toString(internalPriceAssetIdStr)) + "__mappings__poolAssets2PoolContract")
141141
142142 func keyMappingPoolContractToLPAsset (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
143143
144144 let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
145145 let amountAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amountAssetId))
146146 let priceAssetInternalId = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAssetId))
147147 let poolContractAddress = getStrOrFail(factoryContract, keyMappingPoolAssetsToPoolContractAddress(amountAssetInternalId, priceAssetInternalId))
148148 let lpAssetId = getStrOrFail(factoryContract, keyMappingPoolContractToLPAsset(poolContractAddress))
149149 lpAssetId
150150 }
151151
152152
153153 func checkWxEmissionPoolLabel (pool) = {
154154 let $t048434883 = pool
155155 let amountAssetId = $t048434883._1
156156 let priceAssetId = $t048434883._2
157157 let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
158158 let @ = invoke(factoryContract, "checkWxEmissionPoolLabel", [amountAssetId, priceAssetId], nil)
159159 if ($isInstanceOf(@, "Boolean"))
160160 then @
161161 else throw(($getType(@) + " couldn't be cast to Boolean"))
162162 }
163163
164164
165165 let poolsListName = "pools"
166166
167167 func getVotesListName (pool) = {
168168 let $t051845224 = pool
169169 let amountAssetId = $t051845224._1
170170 let priceAssetId = $t051845224._2
171171 makeString(["votes", amountAssetId, priceAssetId], separator)
172172 }
173173
174174
175175 func keyListHead (listName) = {
176176 let meta = if ((listName == poolsListName))
177177 then "%s%s"
178178 else "%s%s%s%s"
179179 makeString([meta, listName, "head"], separator)
180180 }
181181
182182
183183 func keyListSize (listName) = {
184184 let meta = if ((listName == poolsListName))
185185 then "%s%s"
186186 else "%s%s%s%s"
187187 makeString([meta, listName, "size"], separator)
188188 }
189189
190190
191191 func keyListPrev (listName,id) = {
192192 let meta = if ((listName == poolsListName))
193193 then "%s%s%s%s"
194194 else "%s%s%s%s%s"
195195 makeString([meta, listName, id, "prev"], separator)
196196 }
197197
198198
199199 func keyListNext (listName,id) = {
200200 let meta = if ((listName == poolsListName))
201201 then "%s%s%s%s"
202202 else "%s%s%s%s%s"
203203 makeString([meta, listName, id, "next"], separator)
204204 }
205205
206206
207207 func containsNode (listName,id) = {
208208 let headOrUnit = getString(this, keyListHead(listName))
209209 let prevOrUnit = getString(this, keyListPrev(listName, id))
210210 let nextOrUnit = getString(this, keyListNext(listName, id))
211211 if (if ((id == valueOrElse(headOrUnit, "")))
212212 then true
213213 else (prevOrUnit != unit))
214214 then true
215215 else (nextOrUnit != unit)
216216 }
217217
218218
219219 func insertNodeActions (listName,id) = {
220220 let headOrUnit = getString(this, keyListHead(listName))
221221 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
222222 let checkNode = if (!(containsNode(listName, id)))
223223 then true
224224 else throw("Node exists")
225225 if ((checkNode == checkNode))
226226 then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit))
227227 then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)]
228228 else nil)) ++ [StringEntry(keyListHead(listName), id)])
229229 else throw("Strict value is not equal to itself.")
230230 }
231231
232232
233233 func deleteNodeActions (listName,id) = {
234234 let headOrUnit = getString(this, keyListHead(listName))
235235 let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0)
236236 let prevOrUnit = getString(this, keyListPrev(listName, id))
237237 let nextOrUnit = getString(this, keyListNext(listName, id))
238238 ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit))
239239 then (nextOrUnit != unit)
240240 else false)
241241 then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))]
242242 else if ((nextOrUnit != unit))
243243 then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))]
244244 else if ((prevOrUnit != unit))
245245 then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))]
246246 else if ((id == valueOrElse(headOrUnit, "")))
247247 then [DeleteEntry(keyListHead(listName))]
248248 else throw(((("invalid node: " + listName) + ".") + id))))
249249 }
250250
251251
252252 func keyManagerPublicKey () = "%s__managerPublicKey"
253253
254254
255255 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
256256
257257
258258 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
259259 case s: String =>
260260 fromBase58String(s)
261261 case _: Unit =>
262262 unit
263263 case _ =>
264264 throw("Match error")
265265 }
266266
267267
268268 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
269269 case s: String =>
270270 fromBase58String(s)
271271 case _: Unit =>
272272 unit
273273 case _ =>
274274 throw("Match error")
275275 }
276276
277277
278278 let permissionDeniedError = throw("Permission denied")
279279
280280 func mustThis (i) = if ((i.caller == this))
281281 then true
282282 else permissionDeniedError
283283
284284
285285 func mustManager (i) = match managerPublicKeyOrUnit() {
286286 case pk: ByteVector =>
287287 if ((i.callerPublicKey == pk))
288288 then true
289289 else permissionDeniedError
290290 case _: Unit =>
291291 mustThis(i)
292292 case _ =>
293293 throw("Match error")
294294 }
295295
296296
297297 @Callable(i)
298298 func setManager (pendingManagerPublicKey) = {
299299 let checkCaller = mustManager(i)
300300 if ((checkCaller == checkCaller))
301301 then {
302302 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
303303 if ((checkManagerPublicKey == checkManagerPublicKey))
304304 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
305305 else throw("Strict value is not equal to itself.")
306306 }
307307 else throw("Strict value is not equal to itself.")
308308 }
309309
310310
311311
312312 @Callable(i)
313313 func confirmManager () = {
314314 let pm = pendingManagerPublicKeyOrUnit()
315315 let hasPM = if (isDefined(pm))
316316 then true
317317 else throw("No pending manager")
318318 if ((hasPM == hasPM))
319319 then {
320320 let checkPM = if ((i.callerPublicKey == value(pm)))
321321 then true
322322 else throw("You are not pending manager")
323323 if ((checkPM == checkPM))
324324 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
325325 else throw("Strict value is not equal to itself.")
326326 }
327327 else throw("Strict value is not equal to itself.")
328328 }
329329
330330
331331
332332 @Callable(i)
333333 func getUserGwxAmountAtHeight (userAddress,targetHeight) = {
334334 let boostingContractAddress = valueOrErrorMessage(addressFromString(getStrOrFail(this, keyBoostingContract)), "invalid boosting contract address")
335335 $Tuple2(nil, {
336336 let @ = invoke(boostingContractAddress, "getUserGwxAmountAtHeightREADONLY", [userAddress, targetHeight], nil)
337337 if ($isInstanceOf(@, "Int"))
338338 then @
339339 else throw(($getType(@) + " couldn't be cast to Int"))
340340 })
341341 }
342342
343343
344344
345345 @Callable(i)
346346 func constructor (factoryContract,votingEmissionCandidateContract,boostingContract,stakingContract,epochLength) = {
347347 let checks = [mustManager(i), if ((addressFromString(factoryContract) != unit))
348348 then true
349349 else "invalid factory contract address", if ((addressFromString(votingEmissionCandidateContract) != unit))
350350 then true
351351 else "invalid voting emission candidate contract address", if ((addressFromString(boostingContract) != unit))
352352 then true
353353 else "invalid boosting contract address", if ((addressFromString(stakingContract) != unit))
354354 then true
355355 else "invalid staking contract address", if ((epochLength > 0))
356356 then true
357357 else throw("invalid epoch length")]
358358 if ((checks == checks))
359359 then $Tuple2([StringEntry(keyFactoryContract, factoryContract), StringEntry(keyVotingEmissionCandidateContract, votingEmissionCandidateContract), StringEntry(keyBoostingContract, boostingContract), StringEntry(keyStakingContract, stakingContract), IntegerEntry(keyEpochLength, epochLength)], unit)
360360 else throw("Strict value is not equal to itself.")
361361 }
362362
363363
364364
365365 @Callable(i)
366366 func create (amountAssetId,priceAssetId) = {
367367 let checks = [if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionCandidateContract), "")))
368368 then true
369369 else mustManager(i)]
370370 if ((checks == checks))
371371 then {
372372 let pool = $Tuple2(amountAssetId, priceAssetId)
373373 let inListActions = ([BooleanEntry(keyInList(pool), true)] ++ insertNodeActions(poolsListName, poolToString(pool)))
374374 let currentEpochIsNotDefined = (getInteger(this, keyCurrentEpoch) == unit)
375375 let startHeightActions = if (currentEpochIsNotDefined)
376376 then {
377377 let epoch = 0
378378 [IntegerEntry(keyCurrentEpoch, epoch), IntegerEntry(keyStartHeightByEpoch(epoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, height)]
379379 }
380380 else nil
381381 $Tuple2((inListActions ++ startHeightActions), unit)
382382 }
383383 else throw("Strict value is not equal to itself.")
384384 }
385385
386386
387387
388388 @Callable(i)
389389 func vote (amountAssetId,priceAssetId,amount) = {
390390 let pool = $Tuple2(amountAssetId, priceAssetId)
391391 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
392392 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
393393 let epochLength = getIntOrFail(this, keyEpochLength)
394394 let endHeight = (startHeight + epochLength)
395395 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
396396 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
397397 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
398398 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
399399 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
400400 let gwxAmountAtEndTotal = {
401401 let @ = invoke(this, "getUserGwxAmountAtHeight", [toBase58String(i.caller.bytes), endHeight], nil)
402402 if ($isInstanceOf(@, "Int"))
403403 then @
404404 else throw(($getType(@) + " couldn't be cast to Int"))
405405 }
406406 let available = (gwxAmountAtEndTotal - used)
407407 let newVote = (vote + amount)
408408 let wxEmission = checkWxEmissionPoolLabel(pool)
409409 let checks = [if ((getBoolean(keyInList(pool)) != unit))
410410 then true
411411 else throw("invalid assets"), if ((endHeight > height))
412412 then true
413413 else throw("invalid height"), if ((finalizationStageOrUnit == unit))
414414 then true
415415 else throw("finalization in progress"), if ((gwxAmountAtEndTotal > 0))
416416 then true
417417 else throw("you do not have gWX"), if (if ((amount > 0))
418418 then (available >= amount)
419419 else false)
420420 then true
421421 else throw("invalid amount"), if (wxEmission)
422422 then true
423423 else throw("pool hasn't WX_EMISSION label")]
424424 if ((checks == checks))
425425 then {
426426 let votesListName = getVotesListName(pool)
427427 let userAddressStr = toString(i.caller)
428428 let votesListActions = if (containsNode(votesListName, userAddressStr))
429429 then nil
430430 else insertNodeActions(votesListName, userAddressStr)
431431 $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)
432432 }
433433 else throw("Strict value is not equal to itself.")
434434 }
435435
436436
437437
438438 @Callable(i)
439439 func cancelVote (amountAssetId,priceAssetId) = {
440440 let pool = $Tuple2(amountAssetId, priceAssetId)
441441 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
442442 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
443443 let epochLength = getIntOrFail(this, keyEpochLength)
444444 let endHeight = (startHeight + epochLength)
445445 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
446446 let used = valueOrElse(getInteger(this, keyUsed(i.caller, epoch)), 0)
447447 let vote = valueOrElse(getInteger(this, keyVote(pool, i.caller, epoch)), 0)
448448 let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, epoch)), 0)
449449 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(epoch)), 0)
450450 let checks = [if ((getBoolean(keyInList(pool)) != unit))
451451 then true
452452 else throw("invalid assets"), if ((endHeight > height))
453453 then true
454454 else throw("invalid height"), if ((finalizationStageOrUnit == unit))
455455 then true
456456 else throw("finalization in progress"), if ((vote > 0))
457457 then true
458458 else throw("no vote")]
459459 if ((checks == checks))
460460 then {
461461 let votesListName = getVotesListName(pool)
462462 let userAddressStr = toString(i.caller)
463463 $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)
464464 }
465465 else throw("Strict value is not equal to itself.")
466466 }
467467
468468
469469
470470 @Callable(i)
471471 func setEpochLength (newEpochLength) = {
472472 let checks = [mustManager(i), if ((newEpochLength > 0))
473473 then true
474474 else throw("invalid epoch length")]
475475 if ((checks == checks))
476476 then $Tuple2([IntegerEntry(keyEpochLengthNew, newEpochLength)], unit)
477477 else throw("Strict value is not equal to itself.")
478478 }
479479
480480
481481
482482 @Callable(i)
483483 func setMaxDepth (newMaxDepth) = {
484484 let checks = [mustManager(i), if ((newMaxDepth > 0))
485485 then true
486486 else throw("invalid max depth")]
487487 if ((checks == checks))
488488 then $Tuple2([IntegerEntry(keyMaxDepth, newMaxDepth)], unit)
489489 else throw("Strict value is not equal to itself.")
490490 }
491491
492492
493493
494494 @Callable(i)
495495 func processVoteINTERNAL (poolStr,userAddressStr) = {
496496 let checkCaller = mustThis(i)
497497 if ((checkCaller == checkCaller))
498498 then {
499499 let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), ("processVoteINTERNAL: invalid user address " + userAddressStr))
500500 let epoch = getIntOrFail(this, keyCurrentEpoch)
501501 let epochPrevious = (epoch - 1)
502502 let epochLength = getIntOrFail(this, keyEpochLength)
503503 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
504504 let endHeight = (startHeight + epochLength)
505505 let startHeightPrevious = getIntOrFail(this, keyStartHeightByEpoch(epochPrevious))
506506 let epochLengthPrevious = getIntOrFail(this, keyEpochLengthByEpoch(epochPrevious))
507507 let endHeightPrevious = (startHeightPrevious + epochLengthPrevious)
508508 let checkTargetEpoch = if ((epochPrevious >= 0))
509509 then true
510510 else throw("processVoteINTERNAL: invalid previous epoch")
511511 if ((checkTargetEpoch == checkTargetEpoch))
512512 then {
513513 let pool = stringToPool(poolStr)
514514 let $t01767517715 = pool
515515 let amountAssetId = $t01767517715._1
516516 let priceAssetId = $t01767517715._2
517517 let wxEmission = checkWxEmissionPoolLabel(pool)
518518 let gwxAmountAtEndTotal = {
519519 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeight], nil)
520520 if ($isInstanceOf(@, "Int"))
521521 then @
522522 else throw(($getType(@) + " couldn't be cast to Int"))
523523 }
524524 let gwxAmountAtEndTotalPrevious = {
525525 let @ = invoke(this, "getUserGwxAmountAtHeight", [userAddressStr, endHeightPrevious], nil)
526526 if ($isInstanceOf(@, "Int"))
527527 then @
528528 else throw(($getType(@) + " couldn't be cast to Int"))
529529 }
530530 let totalVotes = valueOrElse(getInteger(keyTotalVotes(epoch)), 0)
531531 let votingResult = valueOrElse(getInteger(keyVotingResult(pool, epoch)), 0)
532532 let votePrevious = valueOrErrorMessage(getInteger(keyVote(pool, userAddress, epochPrevious)), (((("processVoteINTERNAL " + poolStr) + " ") + userAddressStr) + ": no previous vote"))
533533 let used = valueOrElse(getInteger(this, keyUsed(userAddress, epoch)), 0)
534534 let newVote = if ((gwxAmountAtEndTotalPrevious > 0))
535535 then fraction(votePrevious, gwxAmountAtEndTotal, gwxAmountAtEndTotalPrevious)
536536 else 0
537537 let actions = if (if ((newVote > 0))
538538 then wxEmission
539539 else false)
540540 then [IntegerEntry(keyVote(pool, userAddress, epoch), newVote), IntegerEntry(keyTotalVotes(epoch), (totalVotes + newVote)), IntegerEntry(keyVotingResult(pool, epoch), (votingResult + newVote)), IntegerEntry(keyUsed(userAddress, epoch), (used + newVote))]
541541 else deleteNodeActions(getVotesListName(pool), userAddressStr)
542542 $Tuple2(actions, unit)
543543 }
544544 else throw("Strict value is not equal to itself.")
545545 }
546546 else throw("Strict value is not equal to itself.")
547547 }
548548
549549
550550
551551 @Callable(i)
552552 func processPoolINTERNAL (poolStr,force) = {
553553 let checkCaller = mustThis(i)
554554 if ((checkCaller == checkCaller))
555555 then {
556556 let targetEpoch = {
557557 let currentEpoch = getIntOrFail(this, keyCurrentEpoch)
558558 if (force)
559559 then currentEpoch
560560 else (currentEpoch - 1)
561561 }
562562 let checkTargetEpoch = if ((targetEpoch >= 0))
563563 then true
564564 else throw("processPoolINTERNAL: invalid target epoch")
565565 if ((checkTargetEpoch == checkTargetEpoch))
566566 then {
567567 let pool = stringToPool(poolStr)
568568 let $t01944119481 = pool
569569 let amountAssetId = $t01944119481._1
570570 let priceAssetId = $t01944119481._2
571571 let stakingContract = addressFromStringValue(getStrOrFail(this, keyStakingContract))
572572 let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
573573 let lpAssetId = getLpAssetByPoolAssets(amountAssetId, priceAssetId)
574574 let r = {
575575 let @ = invoke(stakingContract, "usersListTraversal", [lpAssetId], nil)
576576 if ($isInstanceOf(@, "Boolean"))
577577 then @
578578 else throw(($getType(@) + " couldn't be cast to Boolean"))
579579 }
580580 if ((r == r))
581581 then if (r)
582582 then $Tuple2(nil, true)
583583 else {
584584 let wxEmission = checkWxEmissionPoolLabel(pool)
585585 let totalVotes = valueOrElse(getInteger(this, keyTotalVotes(targetEpoch)), 0)
586586 let votingResult = valueOrElse(getInteger(this, keyVotingResult(pool, targetEpoch)), 0)
587587 let share = if (if ((totalVotes == 0))
588588 then true
589589 else !(wxEmission))
590590 then 0
591591 else fraction(votingResult, poolWeightMult, totalVotes)
592592 let modifyWeightInv = invoke(factoryContract, "modifyWeight", [lpAssetId, share], nil)
593593 if ((modifyWeightInv == modifyWeightInv))
594594 then {
595595 let poolsListActions = if (if (wxEmission)
596596 then true
597597 else force)
598598 then nil
599599 else ([DeleteEntry(keyInList(pool))] ++ deleteNodeActions(poolsListName, poolStr))
600600 $Tuple2(([IntegerEntry(keyPoolShare(pool, targetEpoch), share)] ++ poolsListActions), false)
601601 }
602602 else throw("Strict value is not equal to itself.")
603603 }
604604 else throw("Strict value is not equal to itself.")
605605 }
606606 else throw("Strict value is not equal to itself.")
607607 }
608608 else throw("Strict value is not equal to itself.")
609609 }
610610
611611
612612
613613 @Callable(i)
614614 func finalizeHelper () = {
615615 let force = valueOrElse(getBoolean(keyFinalizationShouldBeForced), false)
616616 let epoch = valueOrElse(getInteger(this, keyCurrentEpoch), 0)
617617 let previousEpoch = (epoch - 1)
618618 let startHeight = getIntOrFail(this, keyStartHeightByEpoch(epoch))
619619 let epochLength = getIntOrFail(this, keyEpochLength)
620620 let endHeight = (startHeight + epochLength)
621621 let finalizationStageOrUnit = getInteger(this, keyFinalizationStage)
622622 if (if (if ((height >= endHeight))
623623 then (finalizationStageOrUnit == unit)
624624 else false)
625625 then !(force)
626626 else false)
627627 then {
628628 let newEpoch = (epoch + 1)
629629 let newEpochLengthOption = getInteger(this, keyEpochLengthNew)
630630 let newEpochLengthActions = match newEpochLengthOption {
631631 case newEpochLength: Int =>
632632 [IntegerEntry(keyEpochLength, newEpochLength), DeleteEntry(keyEpochLengthNew)]
633633 case _: Unit =>
634634 nil
635635 case _ =>
636636 throw("Match error")
637637 }
638638 $Tuple2(([IntegerEntry(keyStartHeightByEpoch(newEpoch), height), IntegerEntry(keyStartHeight, height), IntegerEntry(keyCurrentEpoch, newEpoch), IntegerEntry(keyFinalizationStage, finalizationStageTotal), IntegerEntry(keyEpochLengthByEpoch(epoch), epochLength)] ++ newEpochLengthActions), true)
639639 }
640640 else if (if (force)
641641 then (finalizationStageOrUnit == unit)
642642 else false)
643643 then $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares)], true)
644644 else if ((finalizationStageOrUnit == unit))
645645 then $Tuple2(nil, false)
646646 else if ((finalizationStageOrUnit == finalizationStageTotal))
647647 then {
648648 let poolOrUnit = getString(keyNextPool)
649649 let userOrUnit = getString(keyNextUser)
650650 match poolOrUnit {
651651 case _: Unit =>
652652 match getString(keyListHead(poolsListName)) {
653653 case _: Unit =>
654654 $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
655655 case poolsHeadStr: String =>
656656 $Tuple2([StringEntry(keyNextPool, poolsHeadStr)], true)
657657 case _ =>
658658 throw("Match error")
659659 }
660660 case poolStr: String =>
661661 let pool = stringToPool(poolStr)
662662 let nextUserOrUnit = match userOrUnit {
663663 case _: Unit =>
664664 getString(keyListHead(getVotesListName(pool)))
665665 case user: String =>
666666 let next = getString(keyListNext(getVotesListName(pool), user))
667667 if ((next == next))
668668 then {
669669 let processVoteInv = invoke(this, "processVoteINTERNAL", [poolStr, user], nil)
670670 if ((processVoteInv == processVoteInv))
671671 then next
672672 else throw("Strict value is not equal to itself.")
673673 }
674674 else throw("Strict value is not equal to itself.")
675675 case _ =>
676676 throw("Match error")
677677 }
678678 match nextUserOrUnit {
679679 case _: Unit =>
680680 let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
681681 match nextPoolOrUnit {
682682 case _: Unit =>
683683 $Tuple2([IntegerEntry(keyFinalizationStage, finalizationStageShares), DeleteEntry(keyNextPool), DeleteEntry(keyNextUser)], true)
684684 case s: String =>
685685 $Tuple2([StringEntry(keyNextPool, s), DeleteEntry(keyNextUser)], true)
686686 case _ =>
687687 throw("Match error")
688688 }
689689 case nextUser: String =>
690690 $Tuple2([StringEntry(keyNextUser, nextUser)], true)
691691 case _ =>
692692 throw("Match error")
693693 }
694694 case _ =>
695695 throw("Match error")
696696 }
697697 }
698698 else if ((finalizationStageOrUnit == finalizationStageShares))
699699 then {
700700 let poolOrUnit = getString(keyNextPool)
701701 match poolOrUnit {
702702 case _: Unit =>
703703 match getString(keyListHead(poolsListName)) {
704704 case _: Unit =>
705705 let actions = if (force)
706706 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced)]
707707 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight)]
708708 $Tuple2(actions, true)
709709 case nextPoolStr: String =>
710710 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
711711 case _ =>
712712 throw("Match error")
713713 }
714714 case poolStr: String =>
715715 let nextPoolOrUnit = getString(keyListNext(poolsListName, poolStr))
716716 if ((nextPoolOrUnit == nextPoolOrUnit))
717717 then {
718718 let r = {
719719 let @ = invoke(this, "processPoolINTERNAL", [poolStr, force], nil)
720720 if ($isInstanceOf(@, "Boolean"))
721721 then @
722722 else throw(($getType(@) + " couldn't be cast to Boolean"))
723723 }
724724 if ((r == r))
725725 then if (r)
726726 then $Tuple2(nil, true)
727727 else match nextPoolOrUnit {
728728 case _: Unit =>
729729 let actions = if (force)
730730 then [DeleteEntry(keyFinalizationStage), DeleteEntry(keyFinalizationShouldBeForced), DeleteEntry(keyNextPool)]
731731 else [DeleteEntry(keyFinalizationStage), BooleanEntry(keyFinalized(previousEpoch), true), IntegerEntry(keyCurrentEpochUi, epoch), IntegerEntry(keyStartHeightUi, startHeight), DeleteEntry(keyNextPool)]
732732 $Tuple2(actions, true)
733733 case nextPoolStr: String =>
734734 $Tuple2([StringEntry(keyNextPool, nextPoolStr)], true)
735735 case _ =>
736736 throw("Match error")
737737 }
738738 else throw("Strict value is not equal to itself.")
739739 }
740740 else throw("Strict value is not equal to itself.")
741741 case _ =>
742742 throw("Match error")
743743 }
744744 }
745745 else throw("finalization is broken")
746746 }
747747
748748
749749
750750 @Callable(i)
751751 func finalizeWrapper (counter) = {
752752 let result = {
753753 let @ = invoke(this, "finalizeHelper", nil, nil)
754754 if ($isInstanceOf(@, "Boolean"))
755755 then @
756756 else throw(($getType(@) + " couldn't be cast to Boolean"))
757757 }
758758 if ((result == result))
759759 then if (!(result))
760760 then if ((counter == 0))
761761 then throw("Current voting is not over yet")
762762 else $Tuple2(nil, unit)
763763 else {
764764 let maxDepth = valueOrElse(getInteger(this, keyMaxDepth), maxDepthDefault)
765765 if ((maxDepth > counter))
766766 then {
767767 let inv = invoke(this, "finalizeWrapper", [(counter + 1)], nil)
768768 if ((inv == inv))
769769 then $Tuple2(nil, unit)
770770 else throw("Strict value is not equal to itself.")
771771 }
772772 else $Tuple2(nil, unit)
773773 }
774774 else throw("Strict value is not equal to itself.")
775775 }
776776
777777
778778
779779 @Callable(i)
780780 func finalize () = {
781781 let inv = invoke(this, "finalizeWrapper", [0], nil)
782782 if ((inv == inv))
783783 then $Tuple2(nil, unit)
784784 else throw("Strict value is not equal to itself.")
785785 }
786786
787787
788788
789789 @Callable(i)
790790 func containsNodeREADONLY (listName,id) = $Tuple2(nil, containsNode(listName, id))
791791
792792
793793
794794 @Callable(i)
795795 func insertNode (listName,id) = {
796796 let checkCaller = mustManager(i)
797797 if ((checkCaller == checkCaller))
798798 then $Tuple2(insertNodeActions(listName, id), unit)
799799 else throw("Strict value is not equal to itself.")
800800 }
801801
802802
803803
804804 @Callable(i)
805805 func deleteNode (listName,id) = {
806806 let checkCaller = mustManager(i)
807807 if ((checkCaller == checkCaller))
808808 then $Tuple2(deleteNodeActions(listName, id), unit)
809809 else throw("Strict value is not equal to itself.")
810810 }
811811
812812
813-
814-@Callable(i)
815-func getVoteInfoREADONLY (lpAssetIdStr,userAddressStr) = {
816- let userAddress = addressFromStringValue(userAddressStr)
817- let factoryContract = addressFromStringValue(getStrOrFail(this, keyFactoryContract))
818- let idxAmountAssetId = 4
819- let idxPriceAssetId = 5
820- let poolCfg = {
821- let @ = invoke(factoryContract, "getPoolConfigByLpAssetId", [lpAssetIdStr], nil)
822- if ($isInstanceOf(@, "List[Any]"))
823- then @
824- else throw(($getType(@) + " couldn't be cast to List[Any]"))
825- }
826- let amountAssetId = {
827- let @ = poolCfg[idxAmountAssetId]
828- if ($isInstanceOf(@, "String"))
829- then @
830- else throw(($getType(@) + " couldn't be cast to String"))
831- }
832- let priceAssetId = {
833- let @ = poolCfg[idxPriceAssetId]
834- if ($isInstanceOf(@, "String"))
835- then @
836- else throw(($getType(@) + " couldn't be cast to String"))
837- }
838- let lastFinalizedEpoch = {
839- let epoch = (value(getInteger(this, keyCurrentEpoch)) - 1)
840- if ((0 > epoch))
841- then throwErr("invalid epoch")
842- else epoch
843- }
844- let pool = $Tuple2(amountAssetId, priceAssetId)
845- let userVote = valueOrElse(getInteger(this, keyVote(pool, userAddress, lastFinalizedEpoch)), 0)
846- let poolResult = valueOrElse(getInteger(this, keyVotingResult(pool, lastFinalizedEpoch)), 0)
847- $Tuple2(nil, $Tuple2(userVote, poolResult))
848- }
849-
850-
851813 @Verifier(tx)
852814 func verify () = {
853815 let targetPublicKey = match managerPublicKeyOrUnit() {
854816 case pk: ByteVector =>
855817 pk
856818 case _: Unit =>
857819 tx.senderPublicKey
858820 case _ =>
859821 throw("Match error")
860822 }
861823 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
862824 }
863825

github/deemru/w8io/fabc49c 
74.11 ms