tx · 9x6RhetEx42z9WahwdXiARSRpDYSyQqdWu9RDXVptvLE

3N4vUDe3oc1YPNwMyQi2h8f2tmGoA7wBZp2:  -0.03200000 Waves

2023.02.09 09:38 [2441750] smart account 3N4vUDe3oc1YPNwMyQi2h8f2tmGoA7wBZp2 > SELF 0.00000000 Waves

{ "type": 13, "id": "9x6RhetEx42z9WahwdXiARSRpDYSyQqdWu9RDXVptvLE", "fee": 3200000, "feeAssetId": null, "timestamp": 1675924730551, "version": 1, "sender": "3N4vUDe3oc1YPNwMyQi2h8f2tmGoA7wBZp2", "senderPublicKey": "6MuWw1pkme7UgQX2hZh8yTZyoWVkz8A4rmHZ1acrsrVm", "proofs": [ "3oVbX7N75kmRZDkDEDUDo9gtVDLnRuRKnk6UPg2N5DWMoke8BAk62ftCLfHP5YBasPmmaeX3b8YimLTMXtSWk3Hr" ], "script": "base64:BgKcKQgCEgQKAgEEEgYKBAEEAQgSAwoBCBIAEgQKAgEEEgMKAQESBAoCAQQSBAoCCAESBAoCCAESBAoCCAESBQoDAQgBEgASBAoCAQESAwoBARIFCgMBAQESBAoCCAgSABIDCgEIEgUKAwEBARIECgIBARIECgIIARIECgIICBILCgkIAQECAQIIBAQSBgoECAgBCBIAEgMKAQESAwoBARIECgIIASIKbFBkZWNpbWFscyIGc2NhbGU4IgxzY2FsZThCaWdJbnQiB3NjYWxlMTgiCnplcm9CaWdJbnQiBGJpZzAiBGJpZzEiBGJpZzIiC3dhdmVzU3RyaW5nIgNTRVAiClBvb2xBY3RpdmUiD1Bvb2xQdXREaXNhYmxlZCITUG9vbE1hdGNoZXJEaXNhYmxlZCIMUG9vbFNodXRkb3duIg5pZHhQb29sQWRkcmVzcyINaWR4UG9vbFN0YXR1cyIQaWR4UG9vbExQQXNzZXRJZCINaWR4QW10QXNzZXRJZCIPaWR4UHJpY2VBc3NldElkIg5pZHhBbXRBc3NldERjbSIQaWR4UHJpY2VBc3NldERjbSIOaWR4SUFtdEFzc2V0SWQiEGlkeElQcmljZUFzc2V0SWQiDWlkeExQQXNzZXREY20iEmlkeFBvb2xBbXRBc3NldEFtdCIUaWR4UG9vbFByaWNlQXNzZXRBbXQiEWlkeFBvb2xMUEFzc2V0QW10IhlpZHhGYWN0b3J5U3Rha2luZ0NvbnRyYWN0IhppZHhGYWN0b3J5U2xpcHBhZ2VDb250cmFjdCIFdG9YMTgiB29yaWdWYWwiDW9yaWdTY2FsZU11bHQiC3RvWDE4QmlnSW50Igdmcm9tWDE4IgN2YWwiD3Jlc3VsdFNjYWxlTXVsdCIMZnJvbVgxOFJvdW5kIgVyb3VuZCIHdG9TY2FsZSIDYW10IghyZXNTY2FsZSIIY3VyU2NhbGUiA2FicyIJYWJzQmlnSW50Igxzd2FwQ29udHJhY3QiAmZjIgNtcGsiBHBtcGsiAnBsIgJwaCIBaCIJdGltZXN0YW1wIgNwYXUiC3VzZXJBZGRyZXNzIgR0eElkIgNnYXUiAmFhIgJwYSIQa2V5RmFjdG9yeUNvbmZpZyINa2V5TWF0Y2hlclB1YiIpa2V5TWFwcGluZ1Bvb2xDb250cmFjdEFkZHJlc3NUb1Bvb2xBc3NldHMiE3Bvb2xDb250cmFjdEFkZHJlc3MiDWtleVBvb2xDb25maWciCWlBbXRBc3NldCILaVByaWNlQXNzZXQiH2tleU1hcHBpbmdzQmFzZUFzc2V0MmludGVybmFsSWQiDGJhc2VBc3NldFN0ciITa2V5QWxsUG9vbHNTaHV0ZG93biINa2V5UG9vbFdlaWdodCIPY29udHJhY3RBZGRyZXNzIhZrZXlBbGxvd2VkTHBTY3JpcHRIYXNoIhZrZXlGZWVDb2xsZWN0b3JBZGRyZXNzIg90aHJvd09yZGVyRXJyb3IiCm9yZGVyVmFsaWQiC3NlbmRlclZhbGlkIgxtYXRjaGVyVmFsaWQiD2dldFN0cmluZ09yRmFpbCIHYWRkcmVzcyIDa2V5IgxnZXRJbnRPckZhaWwiCHRocm93RXJyIgNtc2ciD2ZhY3RvcnlDb250cmFjdCITZmVlQ29sbGVjdG9yQWRkcmVzcyIFaW5GZWUiAUAiBm91dEZlZSIQaXNHbG9iYWxTaHV0ZG93biITZ2V0TWF0Y2hlclB1Yk9yRmFpbCINZ2V0UG9vbENvbmZpZyIIYW10QXNzZXQiCnByaWNlQXNzZXQiDHBhcnNlQXNzZXRJZCIFaW5wdXQiD2Fzc2V0SWRUb1N0cmluZyIPcGFyc2VQb29sQ29uZmlnIgpwb29sQ29uZmlnIhBwb29sQ29uZmlnUGFyc2VkIgskdDA3OTA2ODA3MiIOY2ZnUG9vbEFkZHJlc3MiDWNmZ1Bvb2xTdGF0dXMiDGNmZ0xwQXNzZXRJZCIQY2ZnQW1vdW50QXNzZXRJZCIPY2ZnUHJpY2VBc3NldElkIhZjZmdBbW91bnRBc3NldERlY2ltYWxzIhVjZmdQcmljZUFzc2V0RGVjaW1hbHMiEGdldEZhY3RvcnlDb25maWciD3N0YWtpbmdDb250cmFjdCIQc2xpcHBhZ2VDb250cmFjdCIRZGF0YVB1dEFjdGlvbkluZm8iDWluQW10QXNzZXRBbXQiD2luUHJpY2VBc3NldEFtdCIIb3V0THBBbXQiBXByaWNlIh1zbGlwcGFnZVRvbGVyYW5jZVBhc3NlZEJ5VXNlciIVc2xpcHBhZ2VUb2xlcmFuY2VSZWFsIgh0eEhlaWdodCILdHhUaW1lc3RhbXAiEnNsaXBhZ2VBbXRBc3NldEFtdCIUc2xpcGFnZVByaWNlQXNzZXRBbXQiEWRhdGFHZXRBY3Rpb25JbmZvIg5vdXRBbXRBc3NldEFtdCIQb3V0UHJpY2VBc3NldEFtdCIHaW5McEFtdCINZ2V0QWNjQmFsYW5jZSIHYXNzZXRJZCIPY2FsY1ByaWNlQmlnSW50IghwckFtdFgxOCIIYW1BbXRYMTgiEHByaXZhdGVDYWxjUHJpY2UiCmFtQXNzZXREY20iCnByQXNzZXREY20iBWFtQW10IgVwckFtdCIOYW10QXNzZXRBbXRYMTgiEHByaWNlQXNzZXRBbXRYMTgiCmNhbGNQcmljZXMiBWxwQW10IgNjZmciC2FtdEFzc2V0RGNtIg1wcmljZUFzc2V0RGNtIghwcmljZVgxOCIIbHBBbXRYMTgiE2xwUHJpY2VJbkFtQXNzZXRYMTgiE2xwUHJpY2VJblByQXNzZXRYMTgiD2NhbGN1bGF0ZVByaWNlcyIGcHJpY2VzIhRlc3RpbWF0ZUdldE9wZXJhdGlvbiIGdHhJZDU4IgpwbXRBc3NldElkIghwbXRMcEFtdCIJbHBBc3NldElkIglhbUFzc2V0SWQiCXByQXNzZXRJZCIKcG9vbFN0YXR1cyIKbHBFbWlzc2lvbiIJYW1CYWxhbmNlIgxhbUJhbGFuY2VYMTgiCXByQmFsYW5jZSIMcHJCYWxhbmNlWDE4IgtjdXJQcmljZVgxOCIIY3VyUHJpY2UiC3BtdExwQW10WDE4Ig1scEVtaXNzaW9uWDE4IgtvdXRBbUFtdFgxOCILb3V0UHJBbXRYMTgiCG91dEFtQW10IghvdXRQckFtdCIFc3RhdGUiFGVzdGltYXRlUHV0T3BlcmF0aW9uIhFzbGlwcGFnZVRvbGVyYW5jZSIMaW5BbUFzc2V0QW10IgtpbkFtQXNzZXRJZCIMaW5QckFzc2V0QW10IgtpblByQXNzZXRJZCIKaXNFdmFsdWF0ZSIGZW1pdExwIgxhbUFzc2V0SWRTdHIiDHByQXNzZXRJZFN0ciILaUFtdEFzc2V0SWQiDWlQcmljZUFzc2V0SWQiDmluQW1Bc3NldElkU3RyIg5pblByQXNzZXRJZFN0ciIPaW5BbUFzc2V0QW10WDE4Ig9pblByQXNzZXRBbXRYMTgiDHVzZXJQcmljZVgxOCIDcmVzIgtzbGlwcGFnZVgxOCIUc2xpcHBhZ2VUb2xlcmFuY2VYMTgiCnByVmlhQW1YMTgiCmFtVmlhUHJYMTgiDGV4cGVjdGVkQW10cyIRZXhwQW10QXNzZXRBbXRYMTgiE2V4cFByaWNlQXNzZXRBbXRYMTgiCWNhbGNMcEFtdCIOY2FsY0FtQXNzZXRQbXQiDmNhbGNQckFzc2V0UG10IgxzbGlwcGFnZUNhbGMiCWVtaXRMcEFtdCIGYW1EaWZmIgZwckRpZmYiC2NvbW1vblN0YXRlIht2YWxpZGF0ZU1hdGNoZXJPcmRlckFsbG93ZWQiBW9yZGVyIgphbXRBc3NldElkIgxwcmljZUFzc2V0SWQiEmFjY0FtdEFzc2V0QmFsYW5jZSIUYWNjUHJpY2VBc3NldEJhbGFuY2UiDW9yZGVyQW10QXNzZXQiEG9yZGVyQW10QXNzZXRTdHIiD29yZGVyUHJpY2VBc3NldCISb3JkZXJQcmljZUFzc2V0U3RyIgpvcmRlclByaWNlIghwcmljZURjbSIQY2FzdGVkT3JkZXJQcmljZSIRaXNPcmRlclByaWNlVmFsaWQiCWNvbW1vbkdldCIBaSIDcG10IgZwbXRBbXQiCWNvbW1vblB1dCIKYW1Bc3NldFBtdCIKcHJBc3NldFBtdCIGZXN0UHV0IgRlbWl0IgZhbW91bnQiB2VtaXRJbnYiDWVtaXRJbnZMZWdhY3kiByRtYXRjaDAiFWxlZ2FjeUZhY3RvcnlDb250cmFjdCIHdGFrZUZlZSIDZmVlIglmZWVBbW91bnQiD2NhbGNQdXRPbmVUb2tlbiIQcGF5bWVudEFtb3VudFJhdyIOcGF5bWVudEFzc2V0SWQiBmlzRXZhbCIQYW1vdW50QmFsYW5jZVJhdyIPcHJpY2VCYWxhbmNlUmF3IhRwYXltZW50SW5BbW91bnRBc3NldCINJHQwMjI5NjkyMzI2MiIQYW1vdW50QmFsYW5jZU9sZCIPcHJpY2VCYWxhbmNlT2xkIg0kdDAyMzI2NjIzNDE1IhRhbW91bnRBc3NldEFtb3VudFJhdyITcHJpY2VBc3NldEFtb3VudFJhdyIRYW1vdW50QXNzZXRBbW91bnQiEHByaWNlQXNzZXRBbW91bnQiDSR0MDIzNTQ3MjM2MTEiDXBheW1lbnRBbW91bnQiEGFtb3VudEJhbGFuY2VOZXciD3ByaWNlQmFsYW5jZU5ldyILcHJpY2VOZXdYMTgiCHByaWNlTmV3Ig5wYXltZW50QmFsYW5jZSIUcGF5bWVudEJhbGFuY2VCaWdJbnQiDHN1cHBseUJpZ0ludCILY2hlY2hTdXBwbHkiDWRlcG9zaXRCaWdJbnQiC2lzc3VlQW1vdW50IgtwcmljZU9sZFgxOCIIcHJpY2VPbGQiBGxvc3MiDSR0MDI1MDg4MjUyNTUiB2JhbGFuY2UiD2lzc3VlQW1vdW50Qm90aCIPY2FsY0dldE9uZVRva2VuIgpvdXRBc3NldElkIgZjaGVja3MiEG91dEluQW1vdW50QXNzZXQiDWJhbGFuY2VCaWdJbnQiDGFtQmFsYW5jZU9sZCIMcHJCYWxhbmNlT2xkIgpvdXRCYWxhbmNlIhBvdXRCYWxhbmNlQmlnSW50Ig5yZWRlZW1lZEJpZ0ludCIJYW1vdW50UmF3Ig0kdDAyNjgzNTI2ODkxIgt0b3RhbEFtb3VudCINJHQwMjY4OTUyNzEyMSILb3V0QW1BbW91bnQiC291dFByQW1vdW50IgxhbUJhbGFuY2VOZXciDHByQmFsYW5jZU5ldyIYYW1vdW50Qm90aEluUGF5bWVudEFzc2V0IhZtYW5hZ2VyUHVibGljS2V5T3JVbml0IgFzIh1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdCIJaXNNYW5hZ2VyIgJwayILbXVzdE1hbmFnZXIiAnBkIg1jbGVhbkFtb3VudEluIglpc1JldmVyc2UiDSR0MDI4Nzk4MjkxMDMiCGFzc2V0T3V0Igdhc3NldEluIhJwb29sQXNzZXRJbkJhbGFuY2UiE3Bvb2xBc3NldE91dEJhbGFuY2UiCWFtb3VudE91dCIEb2xkSyIEbmV3SyIGY2hlY2tLIgxhbW91bnRPdXRNaW4iCWFkZHJlc3NUbyIIY2hlY2tNaW4iF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5IgtjaGVja0NhbGxlciIVY2hlY2tNYW5hZ2VyUHVibGljS2V5IgJwbSIFaGFzUE0iB2NoZWNrUE0iD3Nob3VsZEF1dG9TdGFrZSIEYW1JZCIEcHJJZCIMc2xpcHBhZ2VBSW52IgxzbGlwcGFnZVBJbnYiCmxwVHJhbnNmZXIiC3NscFN0YWtlSW52IgttYXhTbGlwcGFnZSIMbWluT3V0QW1vdW50IglhdXRvU3Rha2UiIGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkIg1pc1B1dERpc2FibGVkIgdwYXltZW50Ig0kdDAzNDI4ODM0NDE4IgVib251cyITZW1pdEFtb3VudEVzdGltYXRlZCIKZW1pdEFtb3VudCIIc3Rha2VJbnYiB3NlbmRGZWUiDSR0MDM1MTQ3MzUyODIiDW91dEFzc2V0SWRTdHIiDWlzR2V0RGlzYWJsZWQiDSR0MDM2MDg3MzYyMjIiD2Ftb3VudEVzdGltYXRlZCIHYnVybkludiINYXNzZXRUcmFuc2ZlciINJHQwMzY4NTczNjk5NSINdW5zdGFrZUFtb3VudCIKdW5zdGFrZUludiINJHQwMzc4MjAzNzk1MyIJb3V0QW10QW10IhRidXJuTFBBc3NldE9uRmFjdG9yeSISbm9MZXNzVGhlbkFtdEFzc2V0IhRub0xlc3NUaGVuUHJpY2VBc3NldCINY2hlY2tQYXltZW50cyIPY2hlY2tQb29sU3RhdHVzIhVub0xlc3NUaGVuQW1vdW50QXNzZXQiDGNoZWNrQW1vdW50cyILYW10QXNzZXRTdHIiDXByaWNlQXNzZXRTdHIiDXBvb2xMUEJhbGFuY2UiCnByaWNlc0xpc3QiD2xwQW10QXNzZXRTaGFyZSIRbHBQcmljZUFzc2V0U2hhcmUiCnBvb2xXZWlnaHQiDGN1clByaWNlQ2FsYyIMYW1CYWxhbmNlUmF3IgxwckJhbGFuY2VSYXciD2FtQmFsYW5jZVJhd1gxOCIPcHJCYWxhbmNlUmF3WDE4IhBwYXltZW50THBBc3NldElkIgxwYXltZW50THBBbXQiAnR4IgZ2ZXJpZnkiD3RhcmdldFB1YmxpY0tleSIKbWF0Y2hlclB1YiIHbmV3SGFzaCILYWxsb3dlZEhhc2giC2N1cnJlbnRIYXNoZQABYQAIAAFiAIDC1y8AAWMJALYCAQCAwtcvAAFkCQC2AgEAgICQu7rWrfANAAFlCQC2AgEAAAABZgkAtgIBAAAAAWcJALYCAQABAAFoCQC2AgEAAgABaQIFV0FWRVMAAWoCAl9fAAFrAAEAAWwAAgABbQADAAFuAAQAAW8AAQABcAACAAFxAAMAAXIABAABcwAFAAF0AAYAAXUABwABdgAIAAF3AAkAAXgACgABeQABAAF6AAIAAUEAAwABQgABAAFDAAcBAUQCAUUBRgkAvAIDCQC2AgEFAUUFAWQJALYCAQUBRgEBRwIBRQFGCQC8AgMFAUUFAWQFAUYBAUgCAUkBSgkAoAMBCQC8AgMFAUkJALYCAQUBSgUBZAEBSwMBSQFKAUwJAKADAQkAvQIEBQFJCQC2AgEFAUoFAWQFAUwBAU0DAU4BTwFQCQBrAwUBTgUBTwUBUAEBUQEBSQMJAGYCAAAFAUkJAQEtAQUBSQUBSQEBUgEBSQMJAL8CAgUBZQUBSQkAvgIBBQFJBQFJAQFTAAIQJXNfX3N3YXBDb250cmFjdAEBVAACEyVzX19mYWN0b3J5Q29udHJhY3QBAVUAAhQlc19fbWFuYWdlclB1YmxpY0tleQEBVgACGyVzX19wZW5kaW5nTWFuYWdlclB1YmxpY0tleQEBVwACESVzJXNfX3ByaWNlX19sYXN0AQFYAgFZAVoJALkJAgkAzAgCAhglcyVzJWQlZF9fcHJpY2VfX2hpc3RvcnkJAMwIAgkApAMBBQFZCQDMCAIJAKQDAQUBWgUDbmlsBQFqAQJhYQICYWICYWMJAKwCAgkArAICCQCsAgICCyVzJXMlc19fUF9fBQJhYgICX18FAmFjAQJhZAICYWICYWMJAKwCAgkArAICCQCsAgICCyVzJXMlc19fR19fBQJhYgICX18FAmFjAQJhZQACDyVzX19hbW91bnRBc3NldAECYWYAAg4lc19fcHJpY2VBc3NldAECYWcAAhElc19fZmFjdG9yeUNvbmZpZwECYWgAAhglcyVzX19tYXRjaGVyX19wdWJsaWNLZXkBAmFpAQJhagkArAICCQCsAgICCCVzJXMlc19fBQJhagIgX19tYXBwaW5nc19fcG9vbENvbnRyYWN0MkxwQXNzZXQBAmFrAgJhbAJhbQkArAICCQCsAgIJAKwCAgkArAICAgglZCVkJXNfXwUCYWwCAl9fBQJhbQIIX19jb25maWcBAmFuAQJhbwkArAICAiglcyVzJXNfX21hcHBpbmdzX19iYXNlQXNzZXQyaW50ZXJuYWxJZF9fBQJhbwECYXAAAgwlc19fc2h1dGRvd24BAmFxAQJhcgkArAICAhIlcyVzX19wb29sV2VpZ2h0X18FAmFyAQJhcwACFyVzX19hbGxvd2VkTHBTY3JpcHRIYXNoAAJhdAIXJXNfX2ZlZUNvbGxlY3RvckFkZHJlc3MBAmF1AwJhdgJhdwJheAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAiRvcmRlciB2YWxpZGF0aW9uIGZhaWxlZDogb3JkZXJWYWxpZD0JAKUDAQUCYXYCDSBzZW5kZXJWYWxpZD0JAKUDAQUCYXcCDiBtYXRjaGVyVmFsaWQ9CQClAwEFAmF4AQJheQICYXoCYUEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQJhegUCYUEJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUCYXoJAMwIAgIBLgkAzAgCBQJhQQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAAQJhQgICYXoCYUEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQJhegUCYUEJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUCYXoJAMwIAgIBLgkAzAgCBQJhQQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAAQJhQwECYUQJAAIBCQC5CQIJAMwIAgIIbHAucmlkZToJAMwIAgUCYUQFA25pbAIBIAACYUUJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQJheQIFBHRoaXMJAQFUAAACYUYJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQJheQIFAmFFBQJhdAACYUcKAAJhSAkA/AcEBQJhRQIQZ2V0SW5GZWVSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFIAgNJbnQFAmFICQACAQkArAICCQADAQUCYUgCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAACYUkKAAJhSAkA/AcEBQJhRQIRZ2V0T3V0RmVlUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJhSAIDSW50BQJhSAkAAgEJAKwCAgkAAwEFAmFIAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQBAmFKAAkBC3ZhbHVlT3JFbHNlAgkAmwgCBQJhRQkBAmFwAAcBAmFLAAkA2QQBCQECYXkCBQJhRQkBAmFoAAECYUwABAJhTQkBAmF5AgUEdGhpcwkBAmFlAAQCYU4JAQJheQIFBHRoaXMJAQJhZgAEAmFtCQECYUICBQJhRQkBAmFuAQUCYU4EAmFsCQECYUICBQJhRQkBAmFuAQUCYU0JALUJAgkBAmF5AgUCYUUJAQJhawIJAKQDAQUCYWwJAKQDAQUCYW0FAWoBAmFPAQJhUAMJAAACBQJhUAUBaQUEdW5pdAkA2QQBBQJhUAECYVEBAmFQAwkAAAIFAmFQBQR1bml0BQFpCQDYBAEJAQV2YWx1ZQEFAmFQAQJhUgECYVMJAJkKBwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQJhUwUBbwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmFTBQFwCQDZBAEJAJEDAgUCYVMFAXEJAQJhTwEJAJEDAgUCYVMFAXIJAQJhTwEJAJEDAgUCYVMFAXMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJhUwUBdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmFTBQF1AAJhVAkBAmFSAQkBAmFMAAACYVUFAmFUAAJhVggFAmFVAl8xAAJhVwgFAmFVAl8yAAJhWAgFAmFVAl8zAAJhWQgFAmFVAl80AAJhWggFAmFVAl81AAJiYQgFAmFVAl82AAJiYggFAmFVAl83AQJiYwAJALUJAgkBAmF5AgUCYUUJAQJhZwAFAWoAAmJkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCCQECYmMABQFCAhlpbmNvcnJlY3Qgc3Rha2luZyBhZGRyZXNzAAJiZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgkBAmJjAAUBQwIZaW5jb3JyZWN0IHN0YWtpbmcgYWRkcmVzcwECYmYKAmJnAmJoAmJpAmJqAmJrAmJsAmJtAmJuAmJvAmJwCQC5CQIJAMwIAgIUJWQlZCVkJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJiZwkAzAgCCQCkAwEFAmJoCQDMCAIJAKQDAQUCYmkJAMwIAgkApAMBBQJiagkAzAgCCQCkAwEFAmJrCQDMCAIJAKQDAQUCYmwJAMwIAgkApAMBBQJibQkAzAgCCQCkAwEFAmJuCQDMCAIJAKQDAQUCYm8JAMwIAgkApAMBBQJicAUDbmlsBQFqAQJicQYCYnICYnMCYnQCYmoCYm0CYm4JALkJAgkAzAgCAgwlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJicgkAzAgCCQCkAwEFAmJzCQDMCAIJAKQDAQUCYnQJAMwIAgkApAMBBQJiagkAzAgCCQCkAwEFAmJtCQDMCAIJAKQDAQUCYm4FA25pbAUBagECYnUBAmJ2AwkAAAIFAmJ2AgVXQVZFUwgJAO8HAQUEdGhpcwlhdmFpbGFibGUJAPAHAgUEdGhpcwkA2QQBBQJidgECYncCAmJ4AmJ5CQC8AgMFAmJ4BQFkBQJieQECYnoEAmJBAmJCAmJDAmJEBAJiRQkBAUQCBQJiQwUCYkEEAmJGCQEBRAIFAmJEBQJiQgkBAmJ3AgUCYkYFAmJFAQJiRwMCYkMCYkQCYkgEAmJJCQECYUwABAJiSgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF0BAJiSwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF1BAJiTAkBAmJ6BAUCYkoFAmJLBQJiQwUCYkQEAmJ5CQEBRAIFAmJDBQJiSgQCYngJAQFEAgUCYkQFAmJLBAJiTQkBAUQCBQJiSAUBYgQCYk4JAQJidwIFAmJ5BQJiTQQCYk8JAQJidwIFAmJ4BQJiTQkAzAgCBQJiTAkAzAgCBQJiTgkAzAgCBQJiTwUDbmlsAQJiUAMCYkMCYkQCYkgEAmJRCQECYkcDBQJiQwUCYkQFAmJICQDMCAIJAQFIAgkAkQMCBQJiUQAABQFiCQDMCAIJAQFIAgkAkQMCBQJiUQABBQFiCQDMCAIJAQFIAgkAkQMCBQJiUQACBQFiBQNuaWwBAmJSBAJiUwJiVAJiVQJhYgQCYkkJAQJhTAAEAmJWCQCRAwIFAmJJBQFxBAJiVwkAkQMCBQJiSQUBcgQCYlgJAJEDAgUCYkkFAXMEAmJBCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkkFAXQEAmJCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkkFAXUEAmJZCQCRAwIFAmJJBQFwBAJiWggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFAmJWCQCsAgIJAKwCAgIGQXNzZXQgBQJiVgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkDCQECIT0CBQJiVgUCYlQJAAIBAhVJbnZhbGlkIGFzc2V0IHBhc3NlZC4EAmNhCQECYnUBBQJiVwQCY2IJAQFEAgUCY2EFAmJBBAJjYwkBAmJ1AQUCYlgEAmNkCQEBRAIFAmNjBQJiQgQCY2UJAQJidwIFAmNkBQJjYgQCY2YJAQFIAgUCY2UFAWIEAmNnCQEBRAIFAmJVBQFiBAJjaAkBAUQCBQJiWgUBYgQCY2kJALwCAwUCY2IFAmNnBQJjaAQCY2oJALwCAwUCY2QFAmNnBQJjaAQCY2sJAQFIAgUCY2kFAmJBBAJjbAkBAUgCBQJjagUCYkIEAmNtAwkAAAIFAmJTAgAFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhYgUCY2sDCQAAAgUCYlcCBVdBVkVTBQR1bml0CQDZBAEFAmJXCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFiBQJjbAMJAAACBQJiWAIFV0FWRVMFBHVuaXQJANkEAQUCYlgJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFkAgkApQgBBQJhYgUCYlMJAQJicQYFAmNrBQJjbAUCYlUFAmNmBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVwAFAmNmCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBWAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmNmBQNuaWwJAJwKCgUCY2sFAmNsBQJiVwUCYlgFAmNhBQJjYwUCYloFAmNlBQJiWQUCY20BAmNuCQJiUwJjbwJjcAJjcQJjcgJjcwJhYgJjdAJjdQQCYkkJAQJhTAAEAmJWCQDZBAEJAJEDAgUCYkkFAXEEAmN2CQCRAwIFAmJJBQFyBAJjdwkAkQMCBQJiSQUBcwQCY3gJAJEDAgUCYkkFAXYEAmN5CQCRAwIFAmJJBQF3BAJiSgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF0BAJiSwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF1BAJiWQkAkQMCBQJiSQUBcAQCYloICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYlYJAKwCAgkArAICAgZBc3NldCAJANgEAQUCYlYCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJjegkA2AQBCQELdmFsdWVPckVsc2UCBQJjcQkA2QQBAgVXQVZFUwQCY0EJANgEAQkBC3ZhbHVlT3JFbHNlAgUCY3MJANkEAQIFV0FWRVMDAwkBAiE9AgUCY3YFAmN6BgkBAiE9AgUCY3cFAmNBCQACAQIiSW52YWxpZCBhbXQgb3IgcHJpY2UgYXNzZXQgcGFzc2VkLgQCY2EDBQJjdAkBAmJ1AQUCY3YJAGUCCQECYnUBBQJjdgUCY3AEAmNjAwUCY3QJAQJidQEFAmN3CQBlAgkBAmJ1AQUCY3cFAmNyBAJjQgkBAUQCBQJjcAUCYkoEAmNDCQEBRAIFAmNyBQJiSwQCY0QJAQJidwIFAmNDBQJjQgQCY2IJAQFEAgUCY2EFAmJKBAJjZAkBAUQCBQJjYwUCYksEAmNFAwkAAAIFAmJaAAAEAmNlBQFlBAJjRgUBZQQCYk0JAHYGCQC5AgIFAmNCBQJjQwAACQC2AgEABQABAAAFBERPV04JAJcKBQkBAUgCBQJiTQUBYgkBAUgCBQJjQgUCYkoJAQFIAgUCY0MFAmJLCQECYncCCQC3AgIFAmNkBQJjQwkAtwICBQJjYgUCY0IFAmNGBAJjZQkBAmJ3AgUCY2QFAmNiBAJjRgkAvAIDCQEBUgEJALgCAgUCY2UFAmNEBQFkBQJjZQQCY0cJAQFEAgUCY28FAWIDAwkBAiE9AgUCY2UFAWUJAL8CAgUCY0YFAmNHBwkAAgEJAKwCAgkArAICCQCsAgICD1ByaWNlIHNsaXBwYWdlIAkApgMBBQJjRgIeIGV4Y2VlZGVkIHRoZSBwYXNzZWQgbGltaXQgb2YgCQCmAwEFAmNHBAJjaAkBAUQCBQJiWgUBYgQCY0gJALwCAwUCY0IFAmNlBQFkBAJjSQkAvAIDBQJjQwUBZAUCY2UEAmNKAwkAvwICBQJjSAUCY0MJAJQKAgUCY0kFAmNDCQCUCgIFAmNCBQJjSAQCY0sIBQJjSgJfMQQCY0wIBQJjSgJfMgQCYk0JALwCAwUCY2gFAmNMBQJjZAkAlwoFCQEBSAIFAmJNBQFiCQEBSAIFAmNLBQJiSgkBAUgCBQJjTAUCYksFAmNlBQJjRgQCY00IBQJjRQJfMQQCY04IBQJjRQJfMgQCY08IBQJjRQJfMwQCY2YJAQFIAggFAmNFAl80BQFiBAJjUAkBAUgCCAUCY0UCXzUFAWIDCQBnAgAABQJjTQkAAgECNkludmFsaWQgY2FsY3VsYXRpb25zLiBMUCBjYWxjdWxhdGVkIGlzIGxlc3MgdGhhbiB6ZXJvLgQCY1EDCQEBIQEFAmN1AAAFAmNNBAJjUgkAZQIFAmNwBQJjTgQCY1MJAGUCBQJjcgUCY08EAmNUCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVwAFAmNmCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBWAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmNmCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhYQIFAmFiBQJiUwkBAmJmCgUCY04FAmNPBQJjUQUCY2YFAmNvBQJjUAUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCY1IFAmNTBQNuaWwJAJ8KDQUCY00FAmNRBQJjZgUCY2EFAmNjBQJiWgUCYlYFAmJZBQJjVAUCY1IFAmNTBQJjcQUCY3MBAmNVAQJjVgQCYkkJAQJhTAAEAmNXCQCRAwIFAmJJBQFyBAJjWAkAkQMCBQJiSQUBcwQCYlkJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiSQUBcAQCYkoJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiSQUBdAQCYksJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiSQUBdQQCY1kJAQJidQEFAmNXBAJjWgkBAmJ1AQUCY1gEAmNlAwkAAAIIBQJjVglvcmRlclR5cGUFA0J1eQkBAmJ6BAUCYkoFAmJLCQBkAgUCY1kIBQJjVgZhbW91bnQFAmNaCQECYnoEBQJiSgUCYksJAGUCBQJjWQgFAmNWBmFtb3VudAUCY1oEAmNmCQEBSAIFAmNlBQFiAwMDCQECYUoABgkAAAIFAmJZBQFtBgkAAAIFAmJZBQFuCQACAQIcRXhjaGFuZ2Ugb3BlcmF0aW9ucyBkaXNhYmxlZAQCZGEICAUCY1YJYXNzZXRQYWlyC2Ftb3VudEFzc2V0BAJkYgMJAAACBQJkYQUEdW5pdAIFV0FWRVMJANgEAQkBBXZhbHVlAQUCZGEEAmRjCAgFAmNWCWFzc2V0UGFpcgpwcmljZUFzc2V0BAJkZAMJAAACBQJkYwUEdW5pdAIFV0FWRVMJANgEAQkBBXZhbHVlAQUCZGMDAwkBAiE9AgUCZGIFAmNXBgkBAiE9AgUCZGQFAmNYCQACAQITV3Jvbmcgb3JkZXIgYXNzZXRzLgQCZGUIBQJjVgVwcmljZQQCZGYJAGsDBQFiBQJiSwUCYkoEAmRnCQEBTQMFAmRlBQFiBQJkZgQCZGgDCQAAAggFAmNWCW9yZGVyVHlwZQUDQnV5CQBnAgUCY2YFAmRnCQBnAgUCZGcFAmNmBgECZGkBAmRqAwkBAiE9AgkAkAMBCAUCZGoIcGF5bWVudHMAAQkAAgECHWV4YWN0bHkgMSBwYXltZW50IGlzIGV4cGVjdGVkBAJkawkBBXZhbHVlAQkAkQMCCAUCZGoIcGF5bWVudHMAAAQCYlQJAQV2YWx1ZQEIBQJkawdhc3NldElkBAJkbAgFAmRrBmFtb3VudAQCY0UJAQJiUgQJANgEAQgFAmRqDXRyYW5zYWN0aW9uSWQJANgEAQUCYlQFAmRsCAUCZGoGY2FsbGVyBAJjawgFAmNFAl8xBAJjbAgFAmNFAl8yBAJiWQkBDXBhcnNlSW50VmFsdWUBCAUCY0UCXzkEAmNtCAUCY0UDXzEwAwMJAQJhSgAGCQAAAgUCYlkFAW4JAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmJZCQCXCgUFAmNrBQJjbAUCZGwFAmJUBQJjbQECZG0DAmRqAmNvAmN1AwkBAiE9AgkAkAMBCAUCZGoIcGF5bWVudHMAAgkAAgECH2V4YWN0bHkgMiBwYXltZW50cyBhcmUgZXhwZWN0ZWQEAmRuCQEFdmFsdWUBCQCRAwIIBQJkaghwYXltZW50cwAABAJkbwkBBXZhbHVlAQkAkQMCCAUCZGoIcGF5bWVudHMAAQQCZHAJAQJjbgkJANgEAQgFAmRqDXRyYW5zYWN0aW9uSWQFAmNvCAUCZG4GYW1vdW50CAUCZG4HYXNzZXRJZAgFAmRvBmFtb3VudAgFAmRvB2Fzc2V0SWQJAKUIAQgFAmRqBmNhbGxlcgcFAmN1BAJiWQkBDXBhcnNlSW50VmFsdWUBCAUCZHACXzgDAwMJAQJhSgAGCQAAAgUCYlkFAWwGCQAAAgUCYlkFAW4JAAIBCQCsAgICLFB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmJZBQJkcAECZHEBAmRyBAJkcwkA/AcEBQJhRQIEZW1pdAkAzAgCBQJkcgUDbmlsBQNuaWwDCQAAAgUCZHMFAmRzBAJkdAQCZHUFAmRzAwkAAQIFAmR1AgdBZGRyZXNzBAJkdgUCZHUJAPwHBAUCZHYCBGVtaXQJAMwIAgUCZHIFA25pbAUDbmlsBQR1bml0AwkAAAIFAmR0BQJkdAUCZHIJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmR3AgJkcgJkeAQCZHkDCQAAAgUCZHgAAAAACQBrAwUCZHIFAmR4BQFiCQCUCgIJAGUCBQJkcgUCZHkFAmR5AQJkegQCZEECZEICYWICYWMEAmRDCQAAAgUCYWMFBHVuaXQEAmRECQECYnUBCQECYVEBBQJhWQQCZEUJAQJidQEJAQJhUQEFAmFaBAJkRgMJAAACBQJkQgUCYVkGAwkAAAIFAmRCBQJhWgcJAQJhQwECDWludmFsaWQgYXNzZXQEAmRHAwUCZEMJAJQKAgUCZEQFAmRFAwUCZEYJAJQKAgkAZQIFAmREBQJkQQUCZEUJAJQKAgUCZEQJAGUCBQJkRQUCZEEEAmRICAUCZEcCXzEEAmRJCAUCZEcCXzIEAmRKAwUCZEYJAJQKAgUCZEEAAAkAlAoCAAAFAmRBBAJkSwgFAmRKAl8xBAJkTAgFAmRKAl8yBAJkTQgJAQJkdwIFAmRLBQJhRwJfMQQCZE4ICQECZHcCBQJkTAUCYUcCXzEEAmRPCQECZHcCBQJkQQUCYUcEAmRQCAUCZE8CXzEEAmR5CAUCZE8CXzIEAmRRCQBkAgUCZEgFAmRNBAJkUgkAZAIFAmRJBQJkTgQCZFMJAQJidwIJAQFEAgUCZFIFAmJiCQEBRAIFAmRRBQJiYQQCZFQJAQFIAgUCZFMFAWIEAmRVAwUCZEYFAmRIBQJkSQQCZFYJALYCAQUCZFUEAmRXCQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYVgJAKwCAgkArAICAgZhc3NldCAJANgEAQUCYVgCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJkWAMJAL8CAgUCZFcFAWYGCQECYUMBAiJpbml0aWFsIGRlcG9zaXQgcmVxdWlyZXMgYWxsIGNvaW5zAwkAAAIFAmRYBQJkWAQCZFkJALYCAQUCZFAEAmRaCQCWAwEJAMwIAgAACQDMCAIJAKADAQkAugICCQC5AgIFAmRXCQC4AgIJAQpzcXJ0QmlnSW50BAkAtwICBQFkCQC6AgIJALkCAgUCZFkFAWQFAmRWABIAEgUERE9XTgUBZAUBZAUDbmlsBAJjVAMFAmRDBQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZFQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZFQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFhAgkApQgBCQEFdmFsdWUBBQJhYgkA2AQBCQEFdmFsdWUBBQJhYwkBAmJmCgUCZEsFAmRMBQJkWgUCZFQAAAAABQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wAAAAAAUDbmlsBAJlYQkBAmJ3AgkBAUQCBQJkSQUCYmIJAQFEAgUCZEgFAmJhBAJlYgkBAUgCBQJlYQUBYgQCZWMEAmVkAwUCZEYJAJQKAgUCZEsFAmRICQCUCgIFAmRMBQJkSQQCZHIIBQJlZAJfMQQCZWUIBQJlZAJfMgQCZWYJAKADAQkAvAIDBQJkVwkAtgIBCQBpAgUCZHIAAgkAtgIBBQJlZQkAawMJAGUCBQJkWgUCZWYFAWIFAmVmCQCWCgQFAmRaBQJjVAUCZHkFAmVjCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJlZwUCZWgCZFACZEICYWICYWMEAmRDCQAAAgUCYWMFBHVuaXQEAmVpCQDMCAIDCQAAAgUCZEIFAmFYBgkBAmFDAQIQaW52YWxpZCBscCBhc3NldAUDbmlsAwkAAAIFAmVpBQJlaQQCZWoDCQAAAgUCZWgFAmFZBgMJAAACBQJlaAUCYVoHCQECYUMBAg1pbnZhbGlkIGFzc2V0BAJlawMFAmVqCQC2AgEJAQJidQEJAQJhUQEFAmFZCQC2AgEJAQJidQEJAQJhUQEFAmFaBAJlbAkBAmJ1AQkBAmFRAQUCYVkEAmVtCQECYnUBCQECYVEBBQJhWgQCZW4DBQJlagUCZWwFAmVtBAJlbwkAtgIBBQJlbgQCZFcJALYCAQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJhWAkArAICCQCsAgICBmFzc2V0IAkA2AQBBQJhWAIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmVwCQC2AgEFAmRQBAJlcQkAlgMBCQDMCAIAAAkAzAgCCQCgAwEJALoCAgkAuQICBQJlawkAuAICBQFkCQB2BgkAuAICBQFkCQC6AgIJALkCAgUCZXAFAWQFAmRXABIFAWgAAAASBQRET1dOBQFkBQNuaWwEAmVyCQECZHcCBQJlcQUCYUkEAmVzCAUCZXICXzEEAmR5CAUCZXICXzIEAmV0AwUCZWoJAJYKBAUCZXMAAAkAZQIFAmVsBQJlcQUCZW0JAJYKBAAABQJlcwUCZWwJAGUCBQJlbQUCZXEEAmV1CAUCZXQCXzEEAmV2CAUCZXQCXzIEAmV3CAUCZXQCXzMEAmV4CAUCZXQCXzQEAmRTCQECYncCCQEBRAIFAmV4BQJiYgkBAUQCBQJldwUCYmEEAmRUCQEBSAIFAmRTBQFiBAJjVAMFAmRDBQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFkAgkApQgBCQEFdmFsdWUBBQJhYgkA2AQBCQEFdmFsdWUBBQJhYwkBAmJxBgUCZXUFAmV2BQJkUAUCZFQFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZFQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZFQFA25pbAQCZWEJAQJidwIJAQFEAgUCZW0FAmJiCQEBRAIFAmVsBQJiYQQCZWIJAQFIAgUCZWEFAWIEAmVjBAJleQkAaAIJAKADAQkAvAIDBQJlawUCZXAFAmRXAAIJAGsDCQBlAgUCZXMFAmV5BQFiBQJleQkAlgoEBQJlcwUCY1QFAmR5BQJlYwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZXoABAJkdQkAoggBCQEBVQADCQABAgUCZHUCBlN0cmluZwQCZUEFAmR1CQDZBAEFAmVBAwkAAQIFAmR1AgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmVCAAQCZHUJAKIIAQkBAVYAAwkAAQIFAmR1AgZTdHJpbmcEAmVBBQJkdQkA2QQBBQJlQQMJAAECBQJkdQIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJlQwECZGoEAmR1CQECZXoAAwkAAQIFAmR1AgpCeXRlVmVjdG9yBAJlRAUCZHUJAAACCAUCZGoPY2FsbGVyUHVibGljS2V5BQJlRAMJAAECBQJkdQIEVW5pdAkAAAIIBQJkagZjYWxsZXIFBHRoaXMJAAIBAgtNYXRjaCBlcnJvcgECZUUBAmRqBAJlRgkAAgECEVBlcm1pc3Npb24gZGVuaWVkBAJkdQkBAmV6AAMJAAECBQJkdQIKQnl0ZVZlY3RvcgQCZUQFAmR1AwkAAAIIBQJkag9jYWxsZXJQdWJsaWNLZXkFAmVEBgUCZUYDCQABAgUCZHUCBFVuaXQDCQAAAggFAmRqBmNhbGxlcgUEdGhpcwYFAmVGCQACAQILTWF0Y2ggZXJyb3IcAmRqASFjYWxjdWxhdGVBbW91bnRPdXRGb3JTd2FwUkVBRE9OTFkCAmVHAmVIBAJlSQMJAAACBQJlSAcEAmVKCQECYXkCBQR0aGlzCQECYWYABAJlSwkBAmF5AgUEdGhpcwkBAmFlAAkAlAoCBQJlSgUCZUsEAmVKCQECYXkCBQR0aGlzCQECYWUABAJlSwkBAmF5AgUEdGhpcwkBAmFmAAkAlAoCBQJlSgUCZUsEAmVKCAUCZUkCXzEEAmVLCAUCZUkCXzIEAmVMCQECYnUBBQJlSwQCZU0JAQJidQEFAmVKBAJlTgkAaQIJAGgCBQJlTQUCZUcJAGQCBQJlTAUCZUcEAmVPCQC5AgIJALYCAQUCZUwJALYCAQUCZU0EAmVQCQC5AgIJALcCAgkAtgIBCQECYnUBBQJlSwkAtgIBBQJlRwkAuAICCQC2AgEJAQJidQEFAmVKCQC2AgEFAmVOBAJlUQMJAMACAgUCZVAFAmVPBgkAAgECFG5ldyBLIGlzIGZld2VyIGVycm9yAwkAAAIFAmVRBQJlUQkAlAoCBQNuaWwFAmVOCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRqASZjYWxjdWxhdGVBbW91bnRPdXRGb3JTd2FwQW5kU2VuZFRva2VucwQCZUcCZUgCZVICZVMEAmVpCQDMCAIDCQBnAggJAQV2YWx1ZQEJAJEDAggFAmRqCHBheW1lbnRzAAAGYW1vdW50BQJlRwYJAQJhQwECDFdyb25nIGFtb3VudAkAzAgCAwkAAAIIBQJkagZjYWxsZXIJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQJheQIFBHRoaXMJAQFTAAYJAQJhQwECEVBlcm1pc3Npb24gZGVuaWVkBQNuaWwDCQAAAgUCZWkFAmVpBAJkawkBBXZhbHVlAQkAkQMCCAUCZGoIcGF5bWVudHMAAAQCZUsDCQAAAggFAmRrB2Fzc2V0SWQFBHVuaXQJANgEAQkAmwMBAgVXQVZFUwkA2AQBCQEFdmFsdWUBCAUCZGsHYXNzZXRJZAQCZUoDCQAAAgUCZUgHCQECYXkCBQR0aGlzCQECYWYACQECYXkCBQR0aGlzCQECYWUABAJlTAkAZQIJAQJidQEFAmVLCAkBBXZhbHVlAQkAkQMCCAUCZGoIcGF5bWVudHMAAAZhbW91bnQEAmVNCQECYnUBBQJlSgQCZU4JAGkCCQBoAgUCZU0FAmVHCQBkAgUCZUwFAmVHBAJlTwkAaAIFAmVMBQJlTQQCZVAJAGgCCQECYnUBBQJlSwkAZQIJAQJidQEFAmVKBQJlTgQCZVEDCQBnAgUCZVAFAmVPBgkAAgECFG5ldyBLIGlzIGZld2VyIGVycm9yAwkAAAIFAmVRBQJlUQQCZVQDCQBnAgUCZU4FAmVSBgkAAgECLEV4Y2hhbmdlIHJlc3VsdCBpcyBmZXdlciBjb2lucyB0aGFuIGV4cGVjdGVkAwkAAAIFAmVUBQJlVAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCQERQGV4dHJOYXRpdmUoMTA2MikBBQJlUwUCZU4DCQAAAgUCZUsCBVdBVkVTBQR1bml0CQDZBAEFAmVKBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGoBCnNldE1hbmFnZXIBAmVVBAJlVgkBAmVFAQUCZGoDCQAAAgUCZVYFAmVWBAJlVwkA2QQBBQJlVQMJAAACBQJlVwUCZVcJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAVYABQJlVQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRqAQ5jb25maXJtTWFuYWdlcgAEAmVYCQECZUIABAJlWQMJAQlpc0RlZmluZWQBBQJlWAYJAAIBAhJObyBwZW5kaW5nIG1hbmFnZXIDCQAAAgUCZVkFAmVZBAJlWgMJAAACCAUCZGoPY2FsbGVyUHVibGljS2V5CQEFdmFsdWUBBQJlWAYJAAIBAhtZb3UgYXJlIG5vdCBwZW5kaW5nIG1hbmFnZXIDCQAAAgUCZVoFAmVaCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFVAAkA2AQBCQEFdmFsdWUBBQJlWAkAzAgCCQELRGVsZXRlRW50cnkBCQEBVgAFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkagEDcHV0AgJjbwJmYQMJAGYCAAAFAmNvCQACAQIgSW52YWxpZCBzbGlwcGFnZVRvbGVyYW5jZSBwYXNzZWQEAmRwCQECZG0DBQJkagUCY28GBAJjUQgFAmRwAl8yBAJiVggFAmRwAl83BAJjbQgFAmRwAl85BAJjUggFAmRwA18xMAQCY1MIBQJkcANfMTEEAmZiCAUCZHADXzEyBAJmYwgFAmRwA18xMwQCZHMJAPwHBAUCYUUCBGVtaXQJAMwIAgUCY1EFA25pbAUDbmlsAwkAAAIFAmRzBQJkcwQCZHQEAmR1BQJkcwMJAAECBQJkdQIHQWRkcmVzcwQCZHYFAmR1CQD8BwQFAmR2AgRlbWl0CQDMCAIFAmNRBQNuaWwFA25pbAUEdW5pdAMJAAACBQJkdAUCZHQEAmZkAwkAZgIFAmNSAAAJAPwHBAUCYmUCA3B1dAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJmYgUCY1IFA25pbAUDbmlsAwkAAAIFAmZkBQJmZAQCZmUDCQBmAgUCY1MAAAkA/AcEBQJiZQIDcHV0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmZjBQJjUwUDbmlsBQNuaWwDCQAAAgUCZmUFAmZlBAJmZgMFAmZhBAJmZwkA/AcEBQJiZAIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYlYFAmNRBQNuaWwDCQAAAgUCZmcFAmZnBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmRqBmNhbGxlcgUCY1EFAmJWBQNuaWwJAM4IAgUCY20FAmZmCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRqAQpwdXRGb3JGcmVlAQJmaAMJAGYCAAAFAmZoCQACAQIUSW52YWxpZCB2YWx1ZSBwYXNzZWQEAmRwCQECZG0DBQJkagUCZmgHCAUCZHACXzkCZGoBCXB1dE9uZVRrbgICZmkCZmoEAmZrCgACYUgJAPwHBAUCYUUCKGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJhSAIHQm9vbGVhbgUCYUgJAAIBCQCsAgIJAAMBBQJhSAIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCZmwDAwMJAQJhSgAGCQAAAgUCYVcFAWwGCQAAAgUCYVcFAW4GBQJmawQCZWkJAMwIAgMDCQEBIQEFAmZsBgkBAmVDAQUCZGoGCQECYUMBAiFwdXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJkaghwYXltZW50cwABBgkBAmFDAQIeZXhhY3RseSAxIHBheW1lbnQgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZWkFAmVpBAJmbQkAkQMCCAUCZGoIcGF5bWVudHMAAAQCZEIIBQJmbQdhc3NldElkBAJkQQgFAmZtBmFtb3VudAQCYWIIBQJkagZjYWxsZXIEAmFjCAUCZGoNdHJhbnNhY3Rpb25JZAQCZm4JAQJkegQFAmRBBQJkQgUCYWIFAmFjAwkAAAIFAmZuBQJmbgQCZm8IBQJmbgJfNAQCZHkIBQJmbgJfMwQCY1QIBQJmbgJfMgQCZnAIBQJmbgJfMQQCZnEDAwkAZgIFAmZpAAAJAGYCBQJmaQUCZnAHCQECYUMBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZpBQNuaWwCAAUCZnAEAmRzCQECZHEBBQJmcQMJAAACBQJkcwUCZHMEAmZmAwUCZmoEAmZyCQD8BwQFAmJkAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJhWAUCZnEFA25pbAMJAAACBQJmcgUCZnIFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZGoGY2FsbGVyBQJmcQUCYVgFA25pbAQCZnMDCQBmAgUCZHkAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhRgUCZHkFAmRCBQNuaWwFA25pbAkAlAoCCQDOCAIJAM4IAgUCY1QFAmZmBQJmcwUCZnEJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGoBEXB1dE9uZVRrblJFQURPTkxZAgJkQgJkQQQCZnQJAQJkegQFAmRBCQECYU8BBQJkQgUEdW5pdAUEdW5pdAQCZnAIBQJmdAJfMQQCY1QIBQJmdAJfMgQCZHkIBQJmdAJfMwQCZm8IBQJmdAJfNAkAlAoCBQNuaWwJAJUKAwUCZnAFAmR5BQJmbwJkagEJZ2V0T25lVGtuAgJmdQJmaQQCZmsKAAJhSAkA/AcEBQJhRQIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFIAgdCb29sZWFuBQJhSAkAAgEJAKwCAgkAAwEFAmFIAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJmdgMDCQECYUoABgkAAAIFAmFXBQFuBgUCZmsEAmVpCQDMCAIDAwkBASEBBQJmdgYJAQJlQwEFAmRqBgkBAmFDAQIhZ2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCZGoIcGF5bWVudHMAAQYJAQJhQwECHmV4YWN0bHkgMSBwYXltZW50IGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmVpBQJlaQQCZWgJAQJhTwEFAmZ1BAJmbQkAkQMCCAUCZGoIcGF5bWVudHMAAAQCZEIIBQJmbQdhc3NldElkBAJkUAgFAmZtBmFtb3VudAQCYWIIBQJkagZjYWxsZXIEAmFjCAUCZGoNdHJhbnNhY3Rpb25JZAQCZncJAQJlZwUFAmVoBQJkUAUCZEIFAmFiBQJhYwMJAAACBQJmdwUCZncEAmZvCAUCZncCXzQEAmR5CAUCZncCXzMEAmNUCAUCZncCXzIEAmZ4CAUCZncCXzEEAmRyAwMJAGYCBQJmaQAACQBmAgUCZmkFAmZ4BwkBAmFDAQkAuQkCCQDMCAICH2Ftb3VudCB0byByZWNlaXZlIGlzIGxlc3MgdGhhbiAJAMwIAgkApAMBBQJmaQUDbmlsAgAFAmZ4BAJmeQkA/AcEBQJhRQIEYnVybgkAzAgCBQJkUAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJkQgUCZFAFA25pbAMJAAACBQJmeQUCZnkEAmZ6CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFiBQJkcgUCZWgFA25pbAQCZnMDCQBmAgUCZHkAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhRgUCZHkFAmVoBQNuaWwFA25pbAkAlAoCCQDOCAIJAM4IAgUCY1QFAmZ6BQJmcwUCZHIJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGoBEWdldE9uZVRrblJFQURPTkxZAgJlaAJkUAQCZkEJAQJlZwUJAQJhTwEFAmVoBQJkUAUCYVgFBHVuaXQFBHVuaXQEAmZ4CAUCZkECXzEEAmNUCAUCZkECXzIEAmR5CAUCZkECXzMEAmZvCAUCZkECXzQJAJQKAgUDbmlsCQCVCgMFAmZ4BQJkeQUCZm8CZGoBE3Vuc3Rha2VBbmRHZXRPbmVUa24DAmZCAmZ1AmZpBAJmawoAAmFICQD8BwQFAmFFAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYUgCB0Jvb2xlYW4FAmFICQACAQkArAICCQADAQUCYUgCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmZ2AwMJAQJhSgAGCQAAAgUCYVcFAW4GBQJmawQCZWkJAMwIAgMDCQEBIQEFAmZ2BgkBAmVDAQUCZGoGCQECYUMBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJkaghwYXltZW50cwAABgkBAmFDAQIYbm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZWkFAmVpBAJlaAkBAmFPAQUCZnUEAmFiCAUCZGoGY2FsbGVyBAJhYwgFAmRqDXRyYW5zYWN0aW9uSWQEAmZDCQD8BwQFAmJkAgd1bnN0YWtlCQDMCAIJANgEAQUCYVgJAMwIAgUCZkIFA25pbAUDbmlsAwkAAAIFAmZDBQJmQwQCZkQJAQJlZwUFAmVoBQJmQgUCYVgFAmFiBQJhYwMJAAACBQJmRAUCZkQEAmZvCAUCZkQCXzQEAmR5CAUCZkQCXzMEAmNUCAUCZkQCXzIEAmZ4CAUCZkQCXzEEAmRyAwMJAGYCBQJmaQAACQBmAgUCZmkFAmZ4BwkBAmFDAQkAuQkCCQDMCAICH2Ftb3VudCB0byByZWNlaXZlIGlzIGxlc3MgdGhhbiAJAMwIAgkApAMBBQJmaQUDbmlsAgAFAmZ4BAJmeQkA/AcEBQJhRQIEYnVybgkAzAgCBQJmQgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJhWAUCZkIFA25pbAMJAAACBQJmeQUCZnkEAmZ6CQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJkagZjYWxsZXIFAmRyBQJlaAUDbmlsBAJmcwMJAGYCBQJkeQAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFGBQJkeQUCZWgFA25pbAUDbmlsCQCUCgIJAM4IAgkAzggCBQJjVAUCZnoFAmZzBQJkcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkagEDZ2V0AAQCY0UJAQJkaQEFAmRqBAJmRQgFAmNFAl8xBAJjbAgFAmNFAl8yBAJkbAgFAmNFAl8zBAJiVAgFAmNFAl80BAJjbQgFAmNFAl81BAJmRgkA/AcEBQJhRQIEYnVybgkAzAgCBQJkbAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiVAUCZGwFA25pbAMJAAACBQJmRgUCZkYFAmNtCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRqAQlnZXROb0xlc3MCAmZHAmZIBAJjRQkBAmRpAQUCZGoEAmNrCAUCY0UCXzEEAmNsCAUCY0UCXzIEAmRsCAUCY0UCXzMEAmJUCAUCY0UCXzQEAmNtCAUCY0UCXzUDCQBmAgUCZkcFAmNrCQACAQkArAICCQCsAgIJAKwCAgIcbm9MZXNzVGhlbkFtdEFzc2V0IGZhaWxlZDogIAkApAMBBQJjawIDIDwgCQCkAwEFAmZHAwkAZgIFAmZIBQJjbAkAAgEJAKwCAgkArAICCQCsAgICHW5vTGVzc1RoZW5QcmljZUFzc2V0IGZhaWxlZDogCQCkAwEFAmNsAgMgPCAJAKQDAQUCZkgEAmZGCQD8BwQFAmFFAgRidXJuCQDMCAIFAmRsBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJUBQJkbAUDbmlsAwkAAAIFAmZGBQJmRgUCY20JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGoBDXVuc3Rha2VBbmRHZXQBAmRyBAJmSQMJAQIhPQIJAJADAQgFAmRqCHBheW1lbnRzAAAJAAIBAhhObyBwYXltZW50cyBhcmUgZXhwZWN0ZWQGAwkAAAIFAmZJBQJmSQQCYkkJAQJhTAAEAmJWCQDZBAEJAJEDAgUCYkkFAXEEAmZDCQD8BwQFAmJkAgd1bnN0YWtlCQDMCAIJANgEAQUCYlYJAMwIAgUCZHIFA25pbAUDbmlsAwkAAAIFAmZDBQJmQwQCY0UJAQJiUgQJANgEAQgFAmRqDXRyYW5zYWN0aW9uSWQJANgEAQUCYlYFAmRyCAUCZGoGY2FsbGVyBAJiWQkBDXBhcnNlSW50VmFsdWUBCAUCY0UCXzkEAmNtCAUCY0UDXzEwBAJmSgMDCQECYUoABgkAAAIFAmJZBQFuCQACAQkArAICAixHZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4uIFN0YXR1cyA9IAkApAMBBQJiWQYDCQAAAgUCZkoFAmZKBAJmRgkA/AcEBQJhRQIEYnVybgkAzAgCBQJkcgUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiVgUCZHIFA25pbAMJAAACBQJmRgUCZkYFAmNtCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRqARN1bnN0YWtlQW5kR2V0Tm9MZXNzAwJmQgJmSwJmSAQCZnYDCQECYUoABgkAAAIFAmFXBQFuBAJlaQkAzAgCAwkBASEBBQJmdgYJAAIBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJkaghwYXltZW50cwAABgkAAgECGG5vIHBheW1lbnRzIGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmVpBQJlaQQCZkMJAPwHBAUCYmQCB3Vuc3Rha2UJAMwIAgkA2AQBBQJhWAkAzAgCBQJmQgUDbmlsBQNuaWwDCQAAAgUCZkMFAmZDBAJjRQkBAmJSBAkA2AQBCAUCZGoNdHJhbnNhY3Rpb25JZAkA2AQBBQJhWAUCZkIIBQJkagZjYWxsZXIEAmNrCAUCY0UCXzEEAmNsCAUCY0UCXzIEAmNtCAUCY0UDXzEwBAJmTAkAzAgCAwkAZwIFAmNrBQJmSwYJAAIBCQC5CQIJAMwIAgIsYW1vdW50IGFzc2V0IGFtb3VudCB0byByZWNlaXZlIGlzIGxlc3MgdGhhbiAJAMwIAgkApAMBBQJmSwUDbmlsAgAJAMwIAgMJAGcCBQJjbAUCZkgGCQACAQkAuQkCCQDMCAICK3ByaWNlIGFzc2V0IGFtb3VudCB0byByZWNlaXZlIGlzIGxlc3MgdGhhbiAJAMwIAgkApAMBBQJmSAUDbmlsAgAFA25pbAMJAAACBQJmTAUCZkwEAmZGCQD8BwQFAmFFAgRidXJuCQDMCAIFAmZCBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmFYBQJmQgUDbmlsAwkAAAIFAmZGBQJmRgUCY20JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGoBCGFjdGl2YXRlAgJmTQJmTgMJAQIhPQIJAKUIAQgFAmRqBmNhbGxlcgkApQgBBQJhRQkAAgECEnBlcm1pc3Npb25zIGRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZQAFAmZNCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhZgAFAmZOBQNuaWwCB3N1Y2Nlc3MCZGoBHGdldFBvb2xDb25maWdXcmFwcGVyUkVBRE9OTFkACQCUCgIFA25pbAkBAmFMAAJkagEcZ2V0QWNjQmFsYW5jZVdyYXBwZXJSRUFET05MWQECYnYJAJQKAgUDbmlsCQECYnUBBQJidgJkagEZY2FsY1ByaWNlc1dyYXBwZXJSRUFET05MWQMCYkMCYkQCYkgEAmJRCQECYkcDBQJiQwUCYkQFAmJICQCUCgIFA25pbAkAzAgCCQCmAwEJAJEDAgUCYlEAAAkAzAgCCQCmAwEJAJEDAgUCYlEAAQkAzAgCCQCmAwEJAJEDAgUCYlEAAgUDbmlsAmRqARR0b1gxOFdyYXBwZXJSRUFET05MWQIBRQFGCQCUCgIFA25pbAkApgMBCQEBRAIFAUUFAUYCZGoBFmZyb21YMThXcmFwcGVyUkVBRE9OTFkCAUkBSgkAlAoCBQNuaWwJAQFIAgkApwMBBQFJBQFKAmRqAR5jYWxjUHJpY2VCaWdJbnRXcmFwcGVyUkVBRE9OTFkCAmJ4AmJ5CQCUCgIFA25pbAkApgMBCQECYncCCQCnAwEFAmJ4CQCnAwEFAmJ5AmRqASNlc3RpbWF0ZVB1dE9wZXJhdGlvbldyYXBwZXJSRUFET05MWQkCYlMCY28CY3ACY3ECY3ICY3MCYWICY3QCY3UJAJQKAgUDbmlsCQECY24JBQJiUwUCY28FAmNwBQJjcQUCY3IFAmNzBQJhYgUCY3QFAmN1AmRqASNlc3RpbWF0ZUdldE9wZXJhdGlvbldyYXBwZXJSRUFET05MWQQCYlMCYlQCYlUCYWIEAmNFCQECYlIEBQJiUwUCYlQFAmJVCQERQGV4dHJOYXRpdmUoMTA2MikBBQJhYgkAlAoCBQNuaWwJAJwKCggFAmNFAl8xCAUCY0UCXzIIBQJjRQJfMwgFAmNFAl80CAUCY0UCXzUIBQJjRQJfNggFAmNFAl83CQCmAwEIBQJjRQJfOAgFAmNFAl85CAUCY0UDXzEwAmRqAQ1zdGF0c1JFQURPTkxZAAQCYkkJAQJhTAAEAmJWCQDZBAEJAJEDAgUCYkkFAXEEAmNXCQCRAwIFAmJJBQFyBAJjWAkAkQMCBQJiSQUBcwQCY3gJAJEDAgUCYkkFAXYEAmN5CQCRAwIFAmJJBQF3BAJiSgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF0BAJiSwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF1BAJmTwgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJiVgkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJiVgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmNZCQECYnUBBQJjVwQCY1oJAQJidQEFAmNYBAJmUAMJAAACBQJmTwAACQDMCAIFAWUJAMwIAgUBZQkAzAgCBQFlBQNuaWwJAQJiRwMFAmNZBQJjWgUCZk8EAmNmAAAEAmZRCQEBSAIJAJEDAgUCZlAAAQUBYgQCZlIJAQFIAgkAkQMCBQJmUAACBQFiBAJmUwkBBXZhbHVlAQkAmggCBQJhRQkBAmFxAQkApQgBBQR0aGlzCQCUCgIFA25pbAkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCY1kJAMwIAgkApAMBBQJjWgkAzAgCCQCkAwEFAmZPCQDMCAIJAKQDAQUCY2YJAMwIAgkApAMBBQJmUQkAzAgCCQCkAwEFAmZSCQDMCAIJAKQDAQUCZlMFA25pbAUBagJkagEgZXZhbHVhdGVQdXRCeUFtb3VudEFzc2V0UkVBRE9OTFkBAmNwBAJiSQkBAmFMAAQCYlYJANkEAQkAkQMCBQJiSQUBcQQCY3YJAJEDAgUCYkkFAXIEAmJXCQDZBAEFAmN2BAJjdwkAkQMCBQJiSQUBcwQCYlgJANkEAQUCY3cEAmJKCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkkFAXQEAmJLCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkkFAXUEAmJZCQCRAwIFAmJJBQFwBAJmTwgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJiVgkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJiVgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmNZCQECYnUBBQJjdgQCY1oJAQJidQEFAmN3BAJiRQkBAUQCBQJjWQUCYkoEAmJGCQEBRAIFAmNaBQJiSwQCY2UDCQAAAgUCZk8AAAUBZQkBAmJ3AgUCYkYFAmJFBAJjQgkBAUQCBQJjcAUCYkoEAmNDCQC8AgMFAmNCBQJjZQUBZAQCY3IJAQFIAgUCY0MFAmJLBAJkcAkBAmNuCQIAAKDCHgUCY3AFAmJXBQJjcgUCYlgCAAYHBAJjTQgFAmRwAl8xBAJmVAgFAmRwAl8zBAJjYQgFAmRwAl80BAJjYwgFAmRwAl81BAJiWggFAmRwAl82CQCUCgIFA25pbAkAuQkCCQDMCAICECVkJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJjTQkAzAgCCQCkAwEJAQFIAgUCY2UFAWIJAMwIAgkApAMBBQJjYQkAzAgCCQCkAwEFAmNjCQDMCAIJAKQDAQUCYloJAMwIAgUCYlkJAMwIAgkApAMBBQJjcAkAzAgCCQCkAwEFAmNyBQNuaWwFAWoCZGoBH2V2YWx1YXRlUHV0QnlQcmljZUFzc2V0UkVBRE9OTFkBAmNyBAJiSQkBAmFMAAQCYlYJANkEAQkAkQMCBQJiSQUBcQQCY3YJAJEDAgUCYkkFAXIEAmJXCQDZBAEFAmN2BAJjdwkAkQMCBQJiSQUBcwQCYlgJANkEAQUCY3cEAmJKCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkkFAXQEAmJLCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkkFAXUEAmJZCQCRAwIFAmJJBQFwBAJmTwgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJiVgkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJiVgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmZVCQECYnUBBQJjdgQCZlYJAQJidQEFAmN3BAJmVwkBAUQCBQJmVQUCYkoEAmZYCQEBRAIFAmZWBQJiSwQCY2UDCQAAAgUCZk8AAAUBZQkBAmJ3AgUCZlgFAmZXBAJjQwkBAUQCBQJjcgUCYksEAmNCCQC8AgMFAmNDBQFkBQJjZQQCY3AJAQFIAgUCY0IFAmJKBAJkcAkBAmNuCQIAAKDCHgUCY3AFAmJXBQJjcgUCYlgCAAYHBAJjTQgFAmRwAl8xBAJmVAgFAmRwAl8zBAJjYQgFAmRwAl80BAJjYwgFAmRwAl81BAJiWggFAmRwAl82CQCUCgIFA25pbAkAuQkCCQDMCAICECVkJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJjTQkAzAgCCQCkAwEJAQFIAgUCY2UFAWIJAMwIAgkApAMBBQJjYQkAzAgCCQCkAwEFAmNjCQDMCAIJAKQDAQUCYloJAMwIAgUCYlkJAMwIAgkApAMBBQJjcAkAzAgCCQCkAwEFAmNyBQNuaWwFAWoCZGoBE2V2YWx1YXRlR2V0UkVBRE9OTFkCAmZZAmZaBAJjRQkBAmJSBAIABQJmWQUCZloFBHRoaXMEAmNrCAUCY0UCXzEEAmNsCAUCY0UCXzIEAmNhCAUCY0UCXzUEAmNjCAUCY0UCXzYEAmJaCAUCY0UCXzcEAmNmCAUCY0UCXzgEAmJZCQENcGFyc2VJbnRWYWx1ZQEIBQJjRQJfOQkAlAoCBQNuaWwJALkJAgkAzAgCAg4lZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmNrCQDMCAIJAKQDAQUCY2wJAMwIAgkApAMBBQJjYQkAzAgCCQCkAwEFAmNjCQDMCAIJAKQDAQUCYloJAMwIAgkApgMBBQJjZgkAzAgCCQCkAwEFAmJZBQNuaWwFAWoBAmdhAQJnYgAEAmdjBAJkdQkBAmV6AAMJAAECBQJkdQIKQnl0ZVZlY3RvcgQCZUQFAmR1BQJlRAMJAAECBQJkdQIEVW5pdAgFAmdhD3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yBAJkdQUCZ2EDCQABAgUCZHUCBU9yZGVyBAJjVgUCZHUEAmdkCQECYUsABAJhdgkBAmNVAQUCY1YEAmF3CQD0AwMIBQJjVglib2R5Qnl0ZXMJAJEDAggFAmNWBnByb29mcwAACAUCY1YPc2VuZGVyUHVibGljS2V5BAJheAkA9AMDCAUCY1YJYm9keUJ5dGVzCQCRAwIIBQJjVgZwcm9vZnMAAQUCZ2QDAwMFAmF2BQJhdwcFAmF4BwYJAQJhdQMFAmF2BQJhdwUCYXgDCQABAgUCZHUCFFNldFNjcmlwdFRyYW5zYWN0aW9uBAJlQQUCZHUEAmdlCQD2AwEJAQV2YWx1ZQEIBQJlQQZzY3JpcHQEAmdmCQDbBAEJAQV2YWx1ZQEJAJ0IAgUCYUUJAQJhcwAEAmdnCQDxBwEFBHRoaXMDAwkAAAIFAmdmBQJnZQkBAiE9AgUCZ2cFAmdlBwYJAPQDAwgFAmdhCWJvZHlCeXRlcwkAkQMCCAUCZ2EGcHJvb2ZzAAAFAmdjCQD0AwMIBQJnYQlib2R5Qnl0ZXMJAJEDAggFAmdhBnByb29mcwAABQJnY3VB6WA=", "chainId": 84, "height": 2441750, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: HzF2TbmxcAp2BiCmGPJLLetNhYjCaoS9c5Pyo6kToPbN Next: 5K2phYuNKrK2CFi6yfCaFsE87qrabh8xt7r4WfxRSsVV Diff:
OldNewDifferences
662662 let poolAssetInBalance = getAccBalance(assetIn)
663663 let poolAssetOutBalance = getAccBalance(assetOut)
664664 let amountOut = ((poolAssetOutBalance * cleanAmountIn) / (poolAssetInBalance + cleanAmountIn))
665- $Tuple2(nil, amountOut)
665+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
666+ let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
667+ let checkK = if ((newK >= oldK))
668+ then true
669+ else throw("new K is fewer error")
670+ if ((checkK == checkK))
671+ then $Tuple2(nil, amountOut)
672+ else throw("Strict value is not equal to itself.")
666673 }
667674
668675
837844 let paymentAmountRaw = payment.amount
838845 let userAddress = i.caller
839846 let txId = i.transactionId
840- let $t03422834358 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
841- if (($t03422834358 == $t03422834358))
847+ let $t03428834418 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
848+ if (($t03428834418 == $t03428834418))
842849 then {
843- let bonus = $t03422834358._4
844- let feeAmount = $t03422834358._3
845- let commonState = $t03422834358._2
846- let emitAmountEstimated = $t03422834358._1
850+ let bonus = $t03428834418._4
851+ let feeAmount = $t03428834418._3
852+ let commonState = $t03428834418._2
853+ let emitAmountEstimated = $t03428834418._1
847854 let emitAmount = if (if ((minOutAmount > 0))
848855 then (minOutAmount > emitAmountEstimated)
849856 else false)
876883
877884 @Callable(i)
878885 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
879- let $t03508735222 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
880- let emitAmountEstimated = $t03508735222._1
881- let commonState = $t03508735222._2
882- let feeAmount = $t03508735222._3
883- let bonus = $t03508735222._4
886+ let $t03514735282 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
887+ let emitAmountEstimated = $t03514735282._1
888+ let commonState = $t03514735282._2
889+ let feeAmount = $t03514735282._3
890+ let bonus = $t03514735282._4
884891 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
885892 }
886893
914921 let paymentAmount = payment.amount
915922 let userAddress = i.caller
916923 let txId = i.transactionId
917- let $t03602736162 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
918- if (($t03602736162 == $t03602736162))
924+ let $t03608736222 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
925+ if (($t03608736222 == $t03608736222))
919926 then {
920- let bonus = $t03602736162._4
921- let feeAmount = $t03602736162._3
922- let commonState = $t03602736162._2
923- let amountEstimated = $t03602736162._1
927+ let bonus = $t03608736222._4
928+ let feeAmount = $t03608736222._3
929+ let commonState = $t03608736222._2
930+ let amountEstimated = $t03608736222._1
924931 let amount = if (if ((minOutAmount > 0))
925932 then (minOutAmount > amountEstimated)
926933 else false)
946953
947954 @Callable(i)
948955 func getOneTknREADONLY (outAssetId,paymentAmount) = {
949- let $t03679736935 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
950- let amountEstimated = $t03679736935._1
951- let commonState = $t03679736935._2
952- let feeAmount = $t03679736935._3
953- let bonus = $t03679736935._4
956+ let $t03685736995 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
957+ let amountEstimated = $t03685736995._1
958+ let commonState = $t03685736995._2
959+ let feeAmount = $t03685736995._3
960+ let bonus = $t03685736995._4
954961 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
955962 }
956963
984991 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
985992 if ((unstakeInv == unstakeInv))
986993 then {
987- let $t03776037893 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
988- if (($t03776037893 == $t03776037893))
994+ let $t03782037953 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
995+ if (($t03782037953 == $t03782037953))
989996 then {
990- let bonus = $t03776037893._4
991- let feeAmount = $t03776037893._3
992- let commonState = $t03776037893._2
993- let amountEstimated = $t03776037893._1
997+ let bonus = $t03782037953._4
998+ let feeAmount = $t03782037953._3
999+ let commonState = $t03782037953._2
1000+ let amountEstimated = $t03782037953._1
9941001 let amount = if (if ((minOutAmount > 0))
9951002 then (minOutAmount > amountEstimated)
9961003 else false)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let lPdecimals = 8
55
66 let scale8 = 100000000
77
88 let scale8BigInt = toBigInt(100000000)
99
1010 let scale18 = toBigInt(1000000000000000000)
1111
1212 let zeroBigInt = toBigInt(0)
1313
1414 let big0 = toBigInt(0)
1515
1616 let big1 = toBigInt(1)
1717
1818 let big2 = toBigInt(2)
1919
2020 let wavesString = "WAVES"
2121
2222 let SEP = "__"
2323
2424 let PoolActive = 1
2525
2626 let PoolPutDisabled = 2
2727
2828 let PoolMatcherDisabled = 3
2929
3030 let PoolShutdown = 4
3131
3232 let idxPoolAddress = 1
3333
3434 let idxPoolStatus = 2
3535
3636 let idxPoolLPAssetId = 3
3737
3838 let idxAmtAssetId = 4
3939
4040 let idxPriceAssetId = 5
4141
4242 let idxAmtAssetDcm = 6
4343
4444 let idxPriceAssetDcm = 7
4545
4646 let idxIAmtAssetId = 8
4747
4848 let idxIPriceAssetId = 9
4949
5050 let idxLPAssetDcm = 10
5151
5252 let idxPoolAmtAssetAmt = 1
5353
5454 let idxPoolPriceAssetAmt = 2
5555
5656 let idxPoolLPAssetAmt = 3
5757
5858 let idxFactoryStakingContract = 1
5959
6060 let idxFactorySlippageContract = 7
6161
6262 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
6363
6464
6565 func toX18BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
6666
6767
6868 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
6969
7070
7171 func fromX18Round (val,resultScaleMult,round) = toInt(fraction(val, toBigInt(resultScaleMult), scale18, round))
7272
7373
7474 func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
7575
7676
7777 func abs (val) = if ((0 > val))
7878 then -(val)
7979 else val
8080
8181
8282 func absBigInt (val) = if ((zeroBigInt > val))
8383 then -(val)
8484 else val
8585
8686
8787 func swapContract () = "%s__swapContract"
8888
8989
9090 func fc () = "%s__factoryContract"
9191
9292
9393 func mpk () = "%s__managerPublicKey"
9494
9595
9696 func pmpk () = "%s__pendingManagerPublicKey"
9797
9898
9999 func pl () = "%s%s__price__last"
100100
101101
102102 func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
103103
104104
105105 func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
106106
107107
108108 func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
109109
110110
111111 func aa () = "%s__amountAsset"
112112
113113
114114 func pa () = "%s__priceAsset"
115115
116116
117117 func keyFactoryConfig () = "%s__factoryConfig"
118118
119119
120120 func keyMatcherPub () = "%s%s__matcher__publicKey"
121121
122122
123123 func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
124124
125125
126126 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
127127
128128
129129 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
130130
131131
132132 func keyAllPoolsShutdown () = "%s__shutdown"
133133
134134
135135 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
136136
137137
138138 func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
139139
140140
141141 let keyFeeCollectorAddress = "%s__feeCollectorAddress"
142142
143143 func throwOrderError (orderValid,senderValid,matcherValid) = throw(((((("order validation failed: orderValid=" + toString(orderValid)) + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
144144
145145
146146 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
147147
148148
149149 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
150150
151151
152152 func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
153153
154154
155155 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
156156
157157 let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
158158
159159 let inFee = {
160160 let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
161161 if ($isInstanceOf(@, "Int"))
162162 then @
163163 else throw(($getType(@) + " couldn't be cast to Int"))
164164 }
165165
166166 let outFee = {
167167 let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
168168 if ($isInstanceOf(@, "Int"))
169169 then @
170170 else throw(($getType(@) + " couldn't be cast to Int"))
171171 }
172172
173173 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
174174
175175
176176 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
177177
178178
179179 func getPoolConfig () = {
180180 let amtAsset = getStringOrFail(this, aa())
181181 let priceAsset = getStringOrFail(this, pa())
182182 let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
183183 let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
184184 split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
185185 }
186186
187187
188188 func parseAssetId (input) = if ((input == wavesString))
189189 then unit
190190 else fromBase58String(input)
191191
192192
193193 func assetIdToString (input) = if ((input == unit))
194194 then wavesString
195195 else toBase58String(value(input))
196196
197197
198198 func parsePoolConfig (poolConfig) = $Tuple7(addressFromStringValue(poolConfig[idxPoolAddress]), parseIntValue(poolConfig[idxPoolStatus]), fromBase58String(poolConfig[idxPoolLPAssetId]), parseAssetId(poolConfig[idxAmtAssetId]), parseAssetId(poolConfig[idxPriceAssetId]), parseIntValue(poolConfig[idxAmtAssetDcm]), parseIntValue(poolConfig[idxPriceAssetDcm]))
199199
200200
201201 let poolConfigParsed = parsePoolConfig(getPoolConfig())
202202
203203 let $t079068072 = poolConfigParsed
204204
205205 let cfgPoolAddress = $t079068072._1
206206
207207 let cfgPoolStatus = $t079068072._2
208208
209209 let cfgLpAssetId = $t079068072._3
210210
211211 let cfgAmountAssetId = $t079068072._4
212212
213213 let cfgPriceAssetId = $t079068072._5
214214
215215 let cfgAmountAssetDecimals = $t079068072._6
216216
217217 let cfgPriceAssetDecimals = $t079068072._7
218218
219219 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
220220
221221
222222 let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
223223
224224 let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
225225
226226 func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slippageTolerancePassedByUser,slippageToleranceReal,txHeight,txTimestamp,slipageAmtAssetAmt,slipagePriceAssetAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slippageTolerancePassedByUser), toString(slippageToleranceReal), toString(txHeight), toString(txTimestamp), toString(slipageAmtAssetAmt), toString(slipagePriceAssetAmt)], SEP)
227227
228228
229229 func dataGetActionInfo (outAmtAssetAmt,outPriceAssetAmt,inLpAmt,price,txHeight,txTimestamp) = makeString(["%d%d%d%d%d%d", toString(outAmtAssetAmt), toString(outPriceAssetAmt), toString(inLpAmt), toString(price), toString(txHeight), toString(txTimestamp)], SEP)
230230
231231
232232 func getAccBalance (assetId) = if ((assetId == "WAVES"))
233233 then wavesBalance(this).available
234234 else assetBalance(this, fromBase58String(assetId))
235235
236236
237237 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
238238
239239
240240 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
241241 let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
242242 let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
243243 calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
244244 }
245245
246246
247247 func calcPrices (amAmt,prAmt,lpAmt) = {
248248 let cfg = getPoolConfig()
249249 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
250250 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
251251 let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
252252 let amAmtX18 = toX18(amAmt, amtAssetDcm)
253253 let prAmtX18 = toX18(prAmt, priceAssetDcm)
254254 let lpAmtX18 = toX18(lpAmt, scale8)
255255 let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
256256 let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
257257 [priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
258258 }
259259
260260
261261 func calculatePrices (amAmt,prAmt,lpAmt) = {
262262 let prices = calcPrices(amAmt, prAmt, lpAmt)
263263 [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
264264 }
265265
266266
267267 func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
268268 let cfg = getPoolConfig()
269269 let lpAssetId = cfg[idxPoolLPAssetId]
270270 let amAssetId = cfg[idxAmtAssetId]
271271 let prAssetId = cfg[idxPriceAssetId]
272272 let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
273273 let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
274274 let poolStatus = cfg[idxPoolStatus]
275275 let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
276276 if ((lpAssetId != pmtAssetId))
277277 then throw("Invalid asset passed.")
278278 else {
279279 let amBalance = getAccBalance(amAssetId)
280280 let amBalanceX18 = toX18(amBalance, amAssetDcm)
281281 let prBalance = getAccBalance(prAssetId)
282282 let prBalanceX18 = toX18(prBalance, prAssetDcm)
283283 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
284284 let curPrice = fromX18(curPriceX18, scale8)
285285 let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
286286 let lpEmissionX18 = toX18(lpEmission, scale8)
287287 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
288288 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
289289 let outAmAmt = fromX18(outAmAmtX18, amAssetDcm)
290290 let outPrAmt = fromX18(outPrAmtX18, prAssetDcm)
291291 let state = if ((txId58 == ""))
292292 then nil
293293 else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
294294 then unit
295295 else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
296296 then unit
297297 else fromBase58String(prAssetId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
298298 $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
299299 }
300300 }
301301
302302
303303 func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
304304 let cfg = getPoolConfig()
305305 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
306306 let amAssetIdStr = cfg[idxAmtAssetId]
307307 let prAssetIdStr = cfg[idxPriceAssetId]
308308 let iAmtAssetId = cfg[idxIAmtAssetId]
309309 let iPriceAssetId = cfg[idxIPriceAssetId]
310310 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
311311 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
312312 let poolStatus = cfg[idxPoolStatus]
313313 let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
314314 let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
315315 let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
316316 if (if ((amAssetIdStr != inAmAssetIdStr))
317317 then true
318318 else (prAssetIdStr != inPrAssetIdStr))
319319 then throw("Invalid amt or price asset passed.")
320320 else {
321321 let amBalance = if (isEvaluate)
322322 then getAccBalance(amAssetIdStr)
323323 else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
324324 let prBalance = if (isEvaluate)
325325 then getAccBalance(prAssetIdStr)
326326 else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
327327 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
328328 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
329329 let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
330330 let amBalanceX18 = toX18(amBalance, amtAssetDcm)
331331 let prBalanceX18 = toX18(prBalance, priceAssetDcm)
332332 let res = if ((lpEmission == 0))
333333 then {
334334 let curPriceX18 = zeroBigInt
335335 let slippageX18 = zeroBigInt
336336 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
337337 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
338338 }
339339 else {
340340 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
341341 let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
342342 let slippageToleranceX18 = toX18(slippageTolerance, scale8)
343343 if (if ((curPriceX18 != zeroBigInt))
344344 then (slippageX18 > slippageToleranceX18)
345345 else false)
346346 then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
347347 else {
348348 let lpEmissionX18 = toX18(lpEmission, scale8)
349349 let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
350350 let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
351351 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
352352 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
353353 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
354354 let expAmtAssetAmtX18 = expectedAmts._1
355355 let expPriceAssetAmtX18 = expectedAmts._2
356356 let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
357357 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(expAmtAssetAmtX18, amtAssetDcm), fromX18(expPriceAssetAmtX18, priceAssetDcm), curPriceX18, slippageX18)
358358 }
359359 }
360360 let calcLpAmt = res._1
361361 let calcAmAssetPmt = res._2
362362 let calcPrAssetPmt = res._3
363363 let curPrice = fromX18(res._4, scale8)
364364 let slippageCalc = fromX18(res._5, scale8)
365365 if ((0 >= calcLpAmt))
366366 then throw("Invalid calculations. LP calculated is less than zero.")
367367 else {
368368 let emitLpAmt = if (!(emitLp))
369369 then 0
370370 else calcLpAmt
371371 let amDiff = (inAmAssetAmt - calcAmAssetPmt)
372372 let prDiff = (inPrAssetAmt - calcPrAssetPmt)
373373 let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(calcAmAssetPmt, calcPrAssetPmt, emitLpAmt, curPrice, slippageTolerance, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
374374 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
375375 }
376376 }
377377 }
378378
379379
380380 func validateMatcherOrderAllowed (order) = {
381381 let cfg = getPoolConfig()
382382 let amtAssetId = cfg[idxAmtAssetId]
383383 let priceAssetId = cfg[idxPriceAssetId]
384384 let poolStatus = parseIntValue(cfg[idxPoolStatus])
385385 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
386386 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
387387 let accAmtAssetBalance = getAccBalance(amtAssetId)
388388 let accPriceAssetBalance = getAccBalance(priceAssetId)
389389 let curPriceX18 = if ((order.orderType == Buy))
390390 then privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
391391 else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance - order.amount), accPriceAssetBalance)
392392 let curPrice = fromX18(curPriceX18, scale8)
393393 if (if (if (isGlobalShutdown())
394394 then true
395395 else (poolStatus == PoolMatcherDisabled))
396396 then true
397397 else (poolStatus == PoolShutdown))
398398 then throw("Exchange operations disabled")
399399 else {
400400 let orderAmtAsset = order.assetPair.amountAsset
401401 let orderAmtAssetStr = if ((orderAmtAsset == unit))
402402 then "WAVES"
403403 else toBase58String(value(orderAmtAsset))
404404 let orderPriceAsset = order.assetPair.priceAsset
405405 let orderPriceAssetStr = if ((orderPriceAsset == unit))
406406 then "WAVES"
407407 else toBase58String(value(orderPriceAsset))
408408 if (if ((orderAmtAssetStr != amtAssetId))
409409 then true
410410 else (orderPriceAssetStr != priceAssetId))
411411 then throw("Wrong order assets.")
412412 else {
413413 let orderPrice = order.price
414414 let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
415415 let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
416416 let isOrderPriceValid = if ((order.orderType == Buy))
417417 then (curPrice >= castedOrderPrice)
418418 else (castedOrderPrice >= curPrice)
419419 true
420420 }
421421 }
422422 }
423423
424424
425425 func commonGet (i) = if ((size(i.payments) != 1))
426426 then throw("exactly 1 payment is expected")
427427 else {
428428 let pmt = value(i.payments[0])
429429 let pmtAssetId = value(pmt.assetId)
430430 let pmtAmt = pmt.amount
431431 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
432432 let outAmAmt = res._1
433433 let outPrAmt = res._2
434434 let poolStatus = parseIntValue(res._9)
435435 let state = res._10
436436 if (if (isGlobalShutdown())
437437 then true
438438 else (poolStatus == PoolShutdown))
439439 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
440440 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
441441 }
442442
443443
444444 func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
445445 then throw("exactly 2 payments are expected")
446446 else {
447447 let amAssetPmt = value(i.payments[0])
448448 let prAssetPmt = value(i.payments[1])
449449 let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
450450 let poolStatus = parseIntValue(estPut._8)
451451 if (if (if (isGlobalShutdown())
452452 then true
453453 else (poolStatus == PoolPutDisabled))
454454 then true
455455 else (poolStatus == PoolShutdown))
456456 then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
457457 else estPut
458458 }
459459
460460
461461 func emit (amount) = {
462462 let emitInv = invoke(factoryContract, "emit", [amount], nil)
463463 if ((emitInv == emitInv))
464464 then {
465465 let emitInvLegacy = match emitInv {
466466 case legacyFactoryContract: Address =>
467467 invoke(legacyFactoryContract, "emit", [amount], nil)
468468 case _ =>
469469 unit
470470 }
471471 if ((emitInvLegacy == emitInvLegacy))
472472 then amount
473473 else throw("Strict value is not equal to itself.")
474474 }
475475 else throw("Strict value is not equal to itself.")
476476 }
477477
478478
479479 func takeFee (amount,fee) = {
480480 let feeAmount = if ((fee == 0))
481481 then 0
482482 else fraction(amount, fee, scale8)
483483 $Tuple2((amount - feeAmount), feeAmount)
484484 }
485485
486486
487487 func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
488488 let isEval = (txId == unit)
489489 let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
490490 let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
491491 let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
492492 then true
493493 else if ((paymentAssetId == cfgPriceAssetId))
494494 then false
495495 else throwErr("invalid asset")
496496 let $t02296923262 = if (isEval)
497497 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
498498 else if (paymentInAmountAsset)
499499 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
500500 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
501501 let amountBalanceOld = $t02296923262._1
502502 let priceBalanceOld = $t02296923262._2
503503 let $t02326623415 = if (paymentInAmountAsset)
504504 then $Tuple2(paymentAmountRaw, 0)
505505 else $Tuple2(0, paymentAmountRaw)
506506 let amountAssetAmountRaw = $t02326623415._1
507507 let priceAssetAmountRaw = $t02326623415._2
508508 let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
509509 let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
510510 let $t02354723611 = takeFee(paymentAmountRaw, inFee)
511511 let paymentAmount = $t02354723611._1
512512 let feeAmount = $t02354723611._2
513513 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
514514 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
515515 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
516516 let priceNew = fromX18(priceNewX18, scale8)
517517 let paymentBalance = if (paymentInAmountAsset)
518518 then amountBalanceOld
519519 else priceBalanceOld
520520 let paymentBalanceBigInt = toBigInt(paymentBalance)
521521 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
522522 let chechSupply = if ((supplyBigInt > big0))
523523 then true
524524 else throwErr("initial deposit requires all coins")
525525 if ((chechSupply == chechSupply))
526526 then {
527527 let depositBigInt = toBigInt(paymentAmount)
528528 let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
529529 let commonState = if (isEval)
530530 then nil
531531 else [IntegerEntry(pl(), priceNew), IntegerEntry(ph(height, lastBlock.timestamp), priceNew), StringEntry(pau(toString(value(userAddress)), toBase58String(value(txId))), dataPutActionInfo(amountAssetAmountRaw, priceAssetAmountRaw, issueAmount, priceNew, 0, 0, height, lastBlock.timestamp, 0, 0))]
532532 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
533533 let priceOld = fromX18(priceOldX18, scale8)
534534 let loss = {
535535 let $t02508825255 = if (paymentInAmountAsset)
536536 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
537537 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
538538 let amount = $t02508825255._1
539539 let balance = $t02508825255._2
540540 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
541541 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
542542 }
543543 $Tuple4(issueAmount, commonState, feeAmount, loss)
544544 }
545545 else throw("Strict value is not equal to itself.")
546546 }
547547
548548
549549 func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
550550 let isEval = (txId == unit)
551551 let checks = [if ((paymentAssetId == cfgLpAssetId))
552552 then true
553553 else throwErr("invalid lp asset")]
554554 if ((checks == checks))
555555 then {
556556 let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
557557 then true
558558 else if ((outAssetId == cfgPriceAssetId))
559559 then false
560560 else throwErr("invalid asset")
561561 let balanceBigInt = if (outInAmountAsset)
562562 then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
563563 else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
564564 let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
565565 let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
566566 let outBalance = if (outInAmountAsset)
567567 then amBalanceOld
568568 else prBalanceOld
569569 let outBalanceBigInt = toBigInt(outBalance)
570570 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
571571 let redeemedBigInt = toBigInt(paymentAmount)
572572 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
573573 let $t02683526891 = takeFee(amountRaw, outFee)
574574 let totalAmount = $t02683526891._1
575575 let feeAmount = $t02683526891._2
576576 let $t02689527121 = if (outInAmountAsset)
577577 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
578578 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
579579 let outAmAmount = $t02689527121._1
580580 let outPrAmount = $t02689527121._2
581581 let amBalanceNew = $t02689527121._3
582582 let prBalanceNew = $t02689527121._4
583583 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
584584 let priceNew = fromX18(priceNewX18, scale8)
585585 let commonState = if (isEval)
586586 then nil
587587 else [StringEntry(gau(toString(value(userAddress)), toBase58String(value(txId))), dataGetActionInfo(outAmAmount, outPrAmount, paymentAmount, priceNew, height, lastBlock.timestamp)), IntegerEntry(pl(), priceNew), IntegerEntry(ph(height, lastBlock.timestamp), priceNew)]
588588 let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
589589 let priceOld = fromX18(priceOldX18, scale8)
590590 let loss = {
591591 let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
592592 fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
593593 }
594594 $Tuple4(totalAmount, commonState, feeAmount, loss)
595595 }
596596 else throw("Strict value is not equal to itself.")
597597 }
598598
599599
600600 func managerPublicKeyOrUnit () = match getString(mpk()) {
601601 case s: String =>
602602 fromBase58String(s)
603603 case _: Unit =>
604604 unit
605605 case _ =>
606606 throw("Match error")
607607 }
608608
609609
610610 func pendingManagerPublicKeyOrUnit () = match getString(pmpk()) {
611611 case s: String =>
612612 fromBase58String(s)
613613 case _: Unit =>
614614 unit
615615 case _ =>
616616 throw("Match error")
617617 }
618618
619619
620620 func isManager (i) = match managerPublicKeyOrUnit() {
621621 case pk: ByteVector =>
622622 (i.callerPublicKey == pk)
623623 case _: Unit =>
624624 (i.caller == this)
625625 case _ =>
626626 throw("Match error")
627627 }
628628
629629
630630 func mustManager (i) = {
631631 let pd = throw("Permission denied")
632632 match managerPublicKeyOrUnit() {
633633 case pk: ByteVector =>
634634 if ((i.callerPublicKey == pk))
635635 then true
636636 else pd
637637 case _: Unit =>
638638 if ((i.caller == this))
639639 then true
640640 else pd
641641 case _ =>
642642 throw("Match error")
643643 }
644644 }
645645
646646
647647 @Callable(i)
648648 func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse) = {
649649 let $t02879829103 = if ((isReverse == false))
650650 then {
651651 let assetOut = getStringOrFail(this, pa())
652652 let assetIn = getStringOrFail(this, aa())
653653 $Tuple2(assetOut, assetIn)
654654 }
655655 else {
656656 let assetOut = getStringOrFail(this, aa())
657657 let assetIn = getStringOrFail(this, pa())
658658 $Tuple2(assetOut, assetIn)
659659 }
660660 let assetOut = $t02879829103._1
661661 let assetIn = $t02879829103._2
662662 let poolAssetInBalance = getAccBalance(assetIn)
663663 let poolAssetOutBalance = getAccBalance(assetOut)
664664 let amountOut = ((poolAssetOutBalance * cleanAmountIn) / (poolAssetInBalance + cleanAmountIn))
665- $Tuple2(nil, amountOut)
665+ let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
666+ let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
667+ let checkK = if ((newK >= oldK))
668+ then true
669+ else throw("new K is fewer error")
670+ if ((checkK == checkK))
671+ then $Tuple2(nil, amountOut)
672+ else throw("Strict value is not equal to itself.")
666673 }
667674
668675
669676
670677 @Callable(i)
671678 func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo) = {
672679 let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
673680 then true
674681 else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(getStringOrFail(this, swapContract()))))
675682 then true
676683 else throwErr("Permission denied")]
677684 if ((checks == checks))
678685 then {
679686 let pmt = value(i.payments[0])
680687 let assetIn = if ((pmt.assetId == unit))
681688 then toBase58String(toBytes("WAVES"))
682689 else toBase58String(value(pmt.assetId))
683690 let assetOut = if ((isReverse == false))
684691 then getStringOrFail(this, pa())
685692 else getStringOrFail(this, aa())
686693 let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
687694 let poolAssetOutBalance = getAccBalance(assetOut)
688695 let amountOut = ((poolAssetOutBalance * cleanAmountIn) / (poolAssetInBalance + cleanAmountIn))
689696 let oldK = (poolAssetInBalance * poolAssetOutBalance)
690697 let newK = (getAccBalance(assetIn) * (getAccBalance(assetOut) - amountOut))
691698 let checkK = if ((newK >= oldK))
692699 then true
693700 else throw("new K is fewer error")
694701 if ((checkK == checkK))
695702 then {
696703 let checkMin = if ((amountOut >= amountOutMin))
697704 then true
698705 else throw("Exchange result is fewer coins than expected")
699706 if ((checkMin == checkMin))
700707 then [ScriptTransfer(addressFromStringValue(addressTo), amountOut, if ((assetIn == "WAVES"))
701708 then unit
702709 else fromBase58String(assetOut))]
703710 else throw("Strict value is not equal to itself.")
704711 }
705712 else throw("Strict value is not equal to itself.")
706713 }
707714 else throw("Strict value is not equal to itself.")
708715 }
709716
710717
711718
712719 @Callable(i)
713720 func setManager (pendingManagerPublicKey) = {
714721 let checkCaller = mustManager(i)
715722 if ((checkCaller == checkCaller))
716723 then {
717724 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
718725 if ((checkManagerPublicKey == checkManagerPublicKey))
719726 then [StringEntry(pmpk(), pendingManagerPublicKey)]
720727 else throw("Strict value is not equal to itself.")
721728 }
722729 else throw("Strict value is not equal to itself.")
723730 }
724731
725732
726733
727734 @Callable(i)
728735 func confirmManager () = {
729736 let pm = pendingManagerPublicKeyOrUnit()
730737 let hasPM = if (isDefined(pm))
731738 then true
732739 else throw("No pending manager")
733740 if ((hasPM == hasPM))
734741 then {
735742 let checkPM = if ((i.callerPublicKey == value(pm)))
736743 then true
737744 else throw("You are not pending manager")
738745 if ((checkPM == checkPM))
739746 then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())]
740747 else throw("Strict value is not equal to itself.")
741748 }
742749 else throw("Strict value is not equal to itself.")
743750 }
744751
745752
746753
747754 @Callable(i)
748755 func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
749756 then throw("Invalid slippageTolerance passed")
750757 else {
751758 let estPut = commonPut(i, slippageTolerance, true)
752759 let emitLpAmt = estPut._2
753760 let lpAssetId = estPut._7
754761 let state = estPut._9
755762 let amDiff = estPut._10
756763 let prDiff = estPut._11
757764 let amId = estPut._12
758765 let prId = estPut._13
759766 let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
760767 if ((emitInv == emitInv))
761768 then {
762769 let emitInvLegacy = match emitInv {
763770 case legacyFactoryContract: Address =>
764771 invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
765772 case _ =>
766773 unit
767774 }
768775 if ((emitInvLegacy == emitInvLegacy))
769776 then {
770777 let slippageAInv = if ((amDiff > 0))
771778 then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
772779 else nil
773780 if ((slippageAInv == slippageAInv))
774781 then {
775782 let slippagePInv = if ((prDiff > 0))
776783 then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
777784 else nil
778785 if ((slippagePInv == slippagePInv))
779786 then {
780787 let lpTransfer = if (shouldAutoStake)
781788 then {
782789 let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
783790 if ((slpStakeInv == slpStakeInv))
784791 then nil
785792 else throw("Strict value is not equal to itself.")
786793 }
787794 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
788795 (state ++ lpTransfer)
789796 }
790797 else throw("Strict value is not equal to itself.")
791798 }
792799 else throw("Strict value is not equal to itself.")
793800 }
794801 else throw("Strict value is not equal to itself.")
795802 }
796803 else throw("Strict value is not equal to itself.")
797804 }
798805
799806
800807
801808 @Callable(i)
802809 func putForFree (maxSlippage) = if ((0 > maxSlippage))
803810 then throw("Invalid value passed")
804811 else {
805812 let estPut = commonPut(i, maxSlippage, false)
806813 estPut._9
807814 }
808815
809816
810817
811818 @Callable(i)
812819 func putOneTkn (minOutAmount,autoStake) = {
813820 let isPoolOneTokenOperationsDisabled = {
814821 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
815822 if ($isInstanceOf(@, "Boolean"))
816823 then @
817824 else throw(($getType(@) + " couldn't be cast to Boolean"))
818825 }
819826 let isPutDisabled = if (if (if (isGlobalShutdown())
820827 then true
821828 else (cfgPoolStatus == PoolPutDisabled))
822829 then true
823830 else (cfgPoolStatus == PoolShutdown))
824831 then true
825832 else isPoolOneTokenOperationsDisabled
826833 let checks = [if (if (!(isPutDisabled))
827834 then true
828835 else isManager(i))
829836 then true
830837 else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
831838 then true
832839 else throwErr("exactly 1 payment are expected")]
833840 if ((checks == checks))
834841 then {
835842 let payment = i.payments[0]
836843 let paymentAssetId = payment.assetId
837844 let paymentAmountRaw = payment.amount
838845 let userAddress = i.caller
839846 let txId = i.transactionId
840- let $t03422834358 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
841- if (($t03422834358 == $t03422834358))
847+ let $t03428834418 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
848+ if (($t03428834418 == $t03428834418))
842849 then {
843- let bonus = $t03422834358._4
844- let feeAmount = $t03422834358._3
845- let commonState = $t03422834358._2
846- let emitAmountEstimated = $t03422834358._1
850+ let bonus = $t03428834418._4
851+ let feeAmount = $t03428834418._3
852+ let commonState = $t03428834418._2
853+ let emitAmountEstimated = $t03428834418._1
847854 let emitAmount = if (if ((minOutAmount > 0))
848855 then (minOutAmount > emitAmountEstimated)
849856 else false)
850857 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
851858 else emitAmountEstimated
852859 let emitInv = emit(emitAmount)
853860 if ((emitInv == emitInv))
854861 then {
855862 let lpTransfer = if (autoStake)
856863 then {
857864 let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
858865 if ((stakeInv == stakeInv))
859866 then nil
860867 else throw("Strict value is not equal to itself.")
861868 }
862869 else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
863870 let sendFee = if ((feeAmount > 0))
864871 then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
865872 else nil
866873 $Tuple2(((commonState ++ lpTransfer) ++ sendFee), emitAmount)
867874 }
868875 else throw("Strict value is not equal to itself.")
869876 }
870877 else throw("Strict value is not equal to itself.")
871878 }
872879 else throw("Strict value is not equal to itself.")
873880 }
874881
875882
876883
877884 @Callable(i)
878885 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
879- let $t03508735222 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
880- let emitAmountEstimated = $t03508735222._1
881- let commonState = $t03508735222._2
882- let feeAmount = $t03508735222._3
883- let bonus = $t03508735222._4
886+ let $t03514735282 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
887+ let emitAmountEstimated = $t03514735282._1
888+ let commonState = $t03514735282._2
889+ let feeAmount = $t03514735282._3
890+ let bonus = $t03514735282._4
884891 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
885892 }
886893
887894
888895
889896 @Callable(i)
890897 func getOneTkn (outAssetIdStr,minOutAmount) = {
891898 let isPoolOneTokenOperationsDisabled = {
892899 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
893900 if ($isInstanceOf(@, "Boolean"))
894901 then @
895902 else throw(($getType(@) + " couldn't be cast to Boolean"))
896903 }
897904 let isGetDisabled = if (if (isGlobalShutdown())
898905 then true
899906 else (cfgPoolStatus == PoolShutdown))
900907 then true
901908 else isPoolOneTokenOperationsDisabled
902909 let checks = [if (if (!(isGetDisabled))
903910 then true
904911 else isManager(i))
905912 then true
906913 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
907914 then true
908915 else throwErr("exactly 1 payment are expected")]
909916 if ((checks == checks))
910917 then {
911918 let outAssetId = parseAssetId(outAssetIdStr)
912919 let payment = i.payments[0]
913920 let paymentAssetId = payment.assetId
914921 let paymentAmount = payment.amount
915922 let userAddress = i.caller
916923 let txId = i.transactionId
917- let $t03602736162 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
918- if (($t03602736162 == $t03602736162))
924+ let $t03608736222 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
925+ if (($t03608736222 == $t03608736222))
919926 then {
920- let bonus = $t03602736162._4
921- let feeAmount = $t03602736162._3
922- let commonState = $t03602736162._2
923- let amountEstimated = $t03602736162._1
927+ let bonus = $t03608736222._4
928+ let feeAmount = $t03608736222._3
929+ let commonState = $t03608736222._2
930+ let amountEstimated = $t03608736222._1
924931 let amount = if (if ((minOutAmount > 0))
925932 then (minOutAmount > amountEstimated)
926933 else false)
927934 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
928935 else amountEstimated
929936 let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
930937 if ((burnInv == burnInv))
931938 then {
932939 let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
933940 let sendFee = if ((feeAmount > 0))
934941 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
935942 else nil
936943 $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
937944 }
938945 else throw("Strict value is not equal to itself.")
939946 }
940947 else throw("Strict value is not equal to itself.")
941948 }
942949 else throw("Strict value is not equal to itself.")
943950 }
944951
945952
946953
947954 @Callable(i)
948955 func getOneTknREADONLY (outAssetId,paymentAmount) = {
949- let $t03679736935 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
950- let amountEstimated = $t03679736935._1
951- let commonState = $t03679736935._2
952- let feeAmount = $t03679736935._3
953- let bonus = $t03679736935._4
956+ let $t03685736995 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
957+ let amountEstimated = $t03685736995._1
958+ let commonState = $t03685736995._2
959+ let feeAmount = $t03685736995._3
960+ let bonus = $t03685736995._4
954961 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
955962 }
956963
957964
958965
959966 @Callable(i)
960967 func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
961968 let isPoolOneTokenOperationsDisabled = {
962969 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
963970 if ($isInstanceOf(@, "Boolean"))
964971 then @
965972 else throw(($getType(@) + " couldn't be cast to Boolean"))
966973 }
967974 let isGetDisabled = if (if (isGlobalShutdown())
968975 then true
969976 else (cfgPoolStatus == PoolShutdown))
970977 then true
971978 else isPoolOneTokenOperationsDisabled
972979 let checks = [if (if (!(isGetDisabled))
973980 then true
974981 else isManager(i))
975982 then true
976983 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
977984 then true
978985 else throwErr("no payments are expected")]
979986 if ((checks == checks))
980987 then {
981988 let outAssetId = parseAssetId(outAssetIdStr)
982989 let userAddress = i.caller
983990 let txId = i.transactionId
984991 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
985992 if ((unstakeInv == unstakeInv))
986993 then {
987- let $t03776037893 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
988- if (($t03776037893 == $t03776037893))
994+ let $t03782037953 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
995+ if (($t03782037953 == $t03782037953))
989996 then {
990- let bonus = $t03776037893._4
991- let feeAmount = $t03776037893._3
992- let commonState = $t03776037893._2
993- let amountEstimated = $t03776037893._1
997+ let bonus = $t03782037953._4
998+ let feeAmount = $t03782037953._3
999+ let commonState = $t03782037953._2
1000+ let amountEstimated = $t03782037953._1
9941001 let amount = if (if ((minOutAmount > 0))
9951002 then (minOutAmount > amountEstimated)
9961003 else false)
9971004 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
9981005 else amountEstimated
9991006 let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
10001007 if ((burnInv == burnInv))
10011008 then {
10021009 let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
10031010 let sendFee = if ((feeAmount > 0))
10041011 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
10051012 else nil
10061013 $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
10071014 }
10081015 else throw("Strict value is not equal to itself.")
10091016 }
10101017 else throw("Strict value is not equal to itself.")
10111018 }
10121019 else throw("Strict value is not equal to itself.")
10131020 }
10141021 else throw("Strict value is not equal to itself.")
10151022 }
10161023
10171024
10181025
10191026 @Callable(i)
10201027 func get () = {
10211028 let res = commonGet(i)
10221029 let outAmtAmt = res._1
10231030 let outPrAmt = res._2
10241031 let pmtAmt = res._3
10251032 let pmtAssetId = res._4
10261033 let state = res._5
10271034 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
10281035 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
10291036 then state
10301037 else throw("Strict value is not equal to itself.")
10311038 }
10321039
10331040
10341041
10351042 @Callable(i)
10361043 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
10371044 let res = commonGet(i)
10381045 let outAmAmt = res._1
10391046 let outPrAmt = res._2
10401047 let pmtAmt = res._3
10411048 let pmtAssetId = res._4
10421049 let state = res._5
10431050 if ((noLessThenAmtAsset > outAmAmt))
10441051 then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
10451052 else if ((noLessThenPriceAsset > outPrAmt))
10461053 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
10471054 else {
10481055 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
10491056 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
10501057 then state
10511058 else throw("Strict value is not equal to itself.")
10521059 }
10531060 }
10541061
10551062
10561063
10571064 @Callable(i)
10581065 func unstakeAndGet (amount) = {
10591066 let checkPayments = if ((size(i.payments) != 0))
10601067 then throw("No payments are expected")
10611068 else true
10621069 if ((checkPayments == checkPayments))
10631070 then {
10641071 let cfg = getPoolConfig()
10651072 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
10661073 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
10671074 if ((unstakeInv == unstakeInv))
10681075 then {
10691076 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
10701077 let poolStatus = parseIntValue(res._9)
10711078 let state = res._10
10721079 let checkPoolStatus = if (if (isGlobalShutdown())
10731080 then true
10741081 else (poolStatus == PoolShutdown))
10751082 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
10761083 else true
10771084 if ((checkPoolStatus == checkPoolStatus))
10781085 then {
10791086 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
10801087 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
10811088 then state
10821089 else throw("Strict value is not equal to itself.")
10831090 }
10841091 else throw("Strict value is not equal to itself.")
10851092 }
10861093 else throw("Strict value is not equal to itself.")
10871094 }
10881095 else throw("Strict value is not equal to itself.")
10891096 }
10901097
10911098
10921099
10931100 @Callable(i)
10941101 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
10951102 let isGetDisabled = if (isGlobalShutdown())
10961103 then true
10971104 else (cfgPoolStatus == PoolShutdown)
10981105 let checks = [if (!(isGetDisabled))
10991106 then true
11001107 else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
11011108 then true
11021109 else throw("no payments are expected")]
11031110 if ((checks == checks))
11041111 then {
11051112 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
11061113 if ((unstakeInv == unstakeInv))
11071114 then {
11081115 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
11091116 let outAmAmt = res._1
11101117 let outPrAmt = res._2
11111118 let state = res._10
11121119 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
11131120 then true
11141121 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
11151122 then true
11161123 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
11171124 if ((checkAmounts == checkAmounts))
11181125 then {
11191126 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
11201127 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11211128 then state
11221129 else throw("Strict value is not equal to itself.")
11231130 }
11241131 else throw("Strict value is not equal to itself.")
11251132 }
11261133 else throw("Strict value is not equal to itself.")
11271134 }
11281135 else throw("Strict value is not equal to itself.")
11291136 }
11301137
11311138
11321139
11331140 @Callable(i)
11341141 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
11351142 then throw("permissions denied")
11361143 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
11371144
11381145
11391146
11401147 @Callable(i)
11411148 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
11421149
11431150
11441151
11451152 @Callable(i)
11461153 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
11471154
11481155
11491156
11501157 @Callable(i)
11511158 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
11521159 let prices = calcPrices(amAmt, prAmt, lpAmt)
11531160 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
11541161 }
11551162
11561163
11571164
11581165 @Callable(i)
11591166 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
11601167
11611168
11621169
11631170 @Callable(i)
11641171 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
11651172
11661173
11671174
11681175 @Callable(i)
11691176 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
11701177
11711178
11721179
11731180 @Callable(i)
11741181 func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
11751182
11761183
11771184
11781185 @Callable(i)
11791186 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
11801187 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
11811188 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
11821189 }
11831190
11841191
11851192
11861193 @Callable(i)
11871194 func statsREADONLY () = {
11881195 let cfg = getPoolConfig()
11891196 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
11901197 let amtAssetId = cfg[idxAmtAssetId]
11911198 let priceAssetId = cfg[idxPriceAssetId]
11921199 let iAmtAssetId = cfg[idxIAmtAssetId]
11931200 let iPriceAssetId = cfg[idxIPriceAssetId]
11941201 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
11951202 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
11961203 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
11971204 let accAmtAssetBalance = getAccBalance(amtAssetId)
11981205 let accPriceAssetBalance = getAccBalance(priceAssetId)
11991206 let pricesList = if ((poolLPBalance == 0))
12001207 then [zeroBigInt, zeroBigInt, zeroBigInt]
12011208 else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
12021209 let curPrice = 0
12031210 let lpAmtAssetShare = fromX18(pricesList[1], scale8)
12041211 let lpPriceAssetShare = fromX18(pricesList[2], scale8)
12051212 let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
12061213 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(accAmtAssetBalance), toString(accPriceAssetBalance), toString(poolLPBalance), toString(curPrice), toString(lpAmtAssetShare), toString(lpPriceAssetShare), toString(poolWeight)], SEP))
12071214 }
12081215
12091216
12101217
12111218 @Callable(i)
12121219 func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
12131220 let cfg = getPoolConfig()
12141221 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
12151222 let amAssetIdStr = cfg[idxAmtAssetId]
12161223 let amAssetId = fromBase58String(amAssetIdStr)
12171224 let prAssetIdStr = cfg[idxPriceAssetId]
12181225 let prAssetId = fromBase58String(prAssetIdStr)
12191226 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
12201227 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
12211228 let poolStatus = cfg[idxPoolStatus]
12221229 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
12231230 let accAmtAssetBalance = getAccBalance(amAssetIdStr)
12241231 let accPriceAssetBalance = getAccBalance(prAssetIdStr)
12251232 let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
12261233 let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
12271234 let curPriceX18 = if ((poolLPBalance == 0))
12281235 then zeroBigInt
12291236 else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
12301237 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
12311238 let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
12321239 let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
12331240 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
12341241 let calcLpAmt = estPut._1
12351242 let curPriceCalc = estPut._3
12361243 let amBalance = estPut._4
12371244 let prBalance = estPut._5
12381245 let lpEmission = estPut._6
12391246 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(calcLpAmt), toString(fromX18(curPriceX18, scale8)), toString(amBalance), toString(prBalance), toString(lpEmission), poolStatus, toString(inAmAssetAmt), toString(inPrAssetAmt)], SEP))
12401247 }
12411248
12421249
12431250
12441251 @Callable(i)
12451252 func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
12461253 let cfg = getPoolConfig()
12471254 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
12481255 let amAssetIdStr = cfg[idxAmtAssetId]
12491256 let amAssetId = fromBase58String(amAssetIdStr)
12501257 let prAssetIdStr = cfg[idxPriceAssetId]
12511258 let prAssetId = fromBase58String(prAssetIdStr)
12521259 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
12531260 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
12541261 let poolStatus = cfg[idxPoolStatus]
12551262 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
12561263 let amBalanceRaw = getAccBalance(amAssetIdStr)
12571264 let prBalanceRaw = getAccBalance(prAssetIdStr)
12581265 let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
12591266 let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
12601267 let curPriceX18 = if ((poolLPBalance == 0))
12611268 then zeroBigInt
12621269 else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
12631270 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
12641271 let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
12651272 let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
12661273 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
12671274 let calcLpAmt = estPut._1
12681275 let curPriceCalc = estPut._3
12691276 let amBalance = estPut._4
12701277 let prBalance = estPut._5
12711278 let lpEmission = estPut._6
12721279 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(calcLpAmt), toString(fromX18(curPriceX18, scale8)), toString(amBalance), toString(prBalance), toString(lpEmission), poolStatus, toString(inAmAssetAmt), toString(inPrAssetAmt)], SEP))
12731280 }
12741281
12751282
12761283
12771284 @Callable(i)
12781285 func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
12791286 let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
12801287 let outAmAmt = res._1
12811288 let outPrAmt = res._2
12821289 let amBalance = res._5
12831290 let prBalance = res._6
12841291 let lpEmission = res._7
12851292 let curPrice = res._8
12861293 let poolStatus = parseIntValue(res._9)
12871294 $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(outAmAmt), toString(outPrAmt), toString(amBalance), toString(prBalance), toString(lpEmission), toString(curPrice), toString(poolStatus)], SEP))
12881295 }
12891296
12901297
12911298 @Verifier(tx)
12921299 func verify () = {
12931300 let targetPublicKey = match managerPublicKeyOrUnit() {
12941301 case pk: ByteVector =>
12951302 pk
12961303 case _: Unit =>
12971304 tx.senderPublicKey
12981305 case _ =>
12991306 throw("Match error")
13001307 }
13011308 match tx {
13021309 case order: Order =>
13031310 let matcherPub = getMatcherPubOrFail()
13041311 let orderValid = validateMatcherOrderAllowed(order)
13051312 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
13061313 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
13071314 if (if (if (orderValid)
13081315 then senderValid
13091316 else false)
13101317 then matcherValid
13111318 else false)
13121319 then true
13131320 else throwOrderError(orderValid, senderValid, matcherValid)
13141321 case s: SetScriptTransaction =>
13151322 let newHash = blake2b256(value(s.script))
13161323 let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
13171324 let currentHash = scriptHash(this)
13181325 if (if ((allowedHash == newHash))
13191326 then (currentHash != newHash)
13201327 else false)
13211328 then true
13221329 else sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
13231330 case _ =>
13241331 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
13251332 }
13261333 }
13271334

github/deemru/w8io/3ef1775 
176.48 ms