tx · 5K2phYuNKrK2CFi6yfCaFsE87qrabh8xt7r4WfxRSsVV

3N4vUDe3oc1YPNwMyQi2h8f2tmGoA7wBZp2:  -0.03200000 Waves

2023.02.09 10:53 [2441822] smart account 3N4vUDe3oc1YPNwMyQi2h8f2tmGoA7wBZp2 > SELF 0.00000000 Waves

{ "type": 13, "id": "5K2phYuNKrK2CFi6yfCaFsE87qrabh8xt7r4WfxRSsVV", "fee": 3200000, "feeAssetId": null, "timestamp": 1675929164340, "version": 1, "sender": "3N4vUDe3oc1YPNwMyQi2h8f2tmGoA7wBZp2", "senderPublicKey": "6MuWw1pkme7UgQX2hZh8yTZyoWVkz8A4rmHZ1acrsrVm", "proofs": [ "4rgofjRSyfAtnXBKoJw3jKRm69JcedVzpWqV5wWo8PrZQDXjQXVnTwtFTep6PyrzSgx2ZxFQ4hkosnT5iaQACvvd" ], "script": "base64:BgKcKQgCEgQKAgEEEgYKBAEEAQgSAwoBCBIAEgQKAgEEEgMKAQESBAoCAQQSBAoCCAESBAoCCAESBAoCCAESBQoDAQgBEgASBAoCAQESAwoBARIFCgMBAQESBAoCCAgSABIDCgEIEgUKAwEBARIECgIBARIECgIIARIECgIICBILCgkIAQECAQIIBAQSBgoECAgBCBIAEgMKAQESAwoBARIECgIIASIKbFBkZWNpbWFscyIGc2NhbGU4IgxzY2FsZThCaWdJbnQiB3NjYWxlMTgiCnplcm9CaWdJbnQiBGJpZzAiBGJpZzEiBGJpZzIiC3dhdmVzU3RyaW5nIgNTRVAiClBvb2xBY3RpdmUiD1Bvb2xQdXREaXNhYmxlZCITUG9vbE1hdGNoZXJEaXNhYmxlZCIMUG9vbFNodXRkb3duIg5pZHhQb29sQWRkcmVzcyINaWR4UG9vbFN0YXR1cyIQaWR4UG9vbExQQXNzZXRJZCINaWR4QW10QXNzZXRJZCIPaWR4UHJpY2VBc3NldElkIg5pZHhBbXRBc3NldERjbSIQaWR4UHJpY2VBc3NldERjbSIOaWR4SUFtdEFzc2V0SWQiEGlkeElQcmljZUFzc2V0SWQiDWlkeExQQXNzZXREY20iEmlkeFBvb2xBbXRBc3NldEFtdCIUaWR4UG9vbFByaWNlQXNzZXRBbXQiEWlkeFBvb2xMUEFzc2V0QW10IhlpZHhGYWN0b3J5U3Rha2luZ0NvbnRyYWN0IhppZHhGYWN0b3J5U2xpcHBhZ2VDb250cmFjdCIFdG9YMTgiB29yaWdWYWwiDW9yaWdTY2FsZU11bHQiC3RvWDE4QmlnSW50Igdmcm9tWDE4IgN2YWwiD3Jlc3VsdFNjYWxlTXVsdCIMZnJvbVgxOFJvdW5kIgVyb3VuZCIHdG9TY2FsZSIDYW10IghyZXNTY2FsZSIIY3VyU2NhbGUiA2FicyIJYWJzQmlnSW50Igxzd2FwQ29udHJhY3QiAmZjIgNtcGsiBHBtcGsiAnBsIgJwaCIBaCIJdGltZXN0YW1wIgNwYXUiC3VzZXJBZGRyZXNzIgR0eElkIgNnYXUiAmFhIgJwYSIQa2V5RmFjdG9yeUNvbmZpZyINa2V5TWF0Y2hlclB1YiIpa2V5TWFwcGluZ1Bvb2xDb250cmFjdEFkZHJlc3NUb1Bvb2xBc3NldHMiE3Bvb2xDb250cmFjdEFkZHJlc3MiDWtleVBvb2xDb25maWciCWlBbXRBc3NldCILaVByaWNlQXNzZXQiH2tleU1hcHBpbmdzQmFzZUFzc2V0MmludGVybmFsSWQiDGJhc2VBc3NldFN0ciITa2V5QWxsUG9vbHNTaHV0ZG93biINa2V5UG9vbFdlaWdodCIPY29udHJhY3RBZGRyZXNzIhZrZXlBbGxvd2VkTHBTY3JpcHRIYXNoIhZrZXlGZWVDb2xsZWN0b3JBZGRyZXNzIg90aHJvd09yZGVyRXJyb3IiCm9yZGVyVmFsaWQiC3NlbmRlclZhbGlkIgxtYXRjaGVyVmFsaWQiD2dldFN0cmluZ09yRmFpbCIHYWRkcmVzcyIDa2V5IgxnZXRJbnRPckZhaWwiCHRocm93RXJyIgNtc2ciD2ZhY3RvcnlDb250cmFjdCITZmVlQ29sbGVjdG9yQWRkcmVzcyIFaW5GZWUiAUAiBm91dEZlZSIQaXNHbG9iYWxTaHV0ZG93biITZ2V0TWF0Y2hlclB1Yk9yRmFpbCINZ2V0UG9vbENvbmZpZyIIYW10QXNzZXQiCnByaWNlQXNzZXQiDHBhcnNlQXNzZXRJZCIFaW5wdXQiD2Fzc2V0SWRUb1N0cmluZyIPcGFyc2VQb29sQ29uZmlnIgpwb29sQ29uZmlnIhBwb29sQ29uZmlnUGFyc2VkIgskdDA3OTA2ODA3MiIOY2ZnUG9vbEFkZHJlc3MiDWNmZ1Bvb2xTdGF0dXMiDGNmZ0xwQXNzZXRJZCIQY2ZnQW1vdW50QXNzZXRJZCIPY2ZnUHJpY2VBc3NldElkIhZjZmdBbW91bnRBc3NldERlY2ltYWxzIhVjZmdQcmljZUFzc2V0RGVjaW1hbHMiEGdldEZhY3RvcnlDb25maWciD3N0YWtpbmdDb250cmFjdCIQc2xpcHBhZ2VDb250cmFjdCIRZGF0YVB1dEFjdGlvbkluZm8iDWluQW10QXNzZXRBbXQiD2luUHJpY2VBc3NldEFtdCIIb3V0THBBbXQiBXByaWNlIh1zbGlwcGFnZVRvbGVyYW5jZVBhc3NlZEJ5VXNlciIVc2xpcHBhZ2VUb2xlcmFuY2VSZWFsIgh0eEhlaWdodCILdHhUaW1lc3RhbXAiEnNsaXBhZ2VBbXRBc3NldEFtdCIUc2xpcGFnZVByaWNlQXNzZXRBbXQiEWRhdGFHZXRBY3Rpb25JbmZvIg5vdXRBbXRBc3NldEFtdCIQb3V0UHJpY2VBc3NldEFtdCIHaW5McEFtdCINZ2V0QWNjQmFsYW5jZSIHYXNzZXRJZCIPY2FsY1ByaWNlQmlnSW50IghwckFtdFgxOCIIYW1BbXRYMTgiEHByaXZhdGVDYWxjUHJpY2UiCmFtQXNzZXREY20iCnByQXNzZXREY20iBWFtQW10IgVwckFtdCIOYW10QXNzZXRBbXRYMTgiEHByaWNlQXNzZXRBbXRYMTgiCmNhbGNQcmljZXMiBWxwQW10IgNjZmciC2FtdEFzc2V0RGNtIg1wcmljZUFzc2V0RGNtIghwcmljZVgxOCIIbHBBbXRYMTgiE2xwUHJpY2VJbkFtQXNzZXRYMTgiE2xwUHJpY2VJblByQXNzZXRYMTgiD2NhbGN1bGF0ZVByaWNlcyIGcHJpY2VzIhRlc3RpbWF0ZUdldE9wZXJhdGlvbiIGdHhJZDU4IgpwbXRBc3NldElkIghwbXRMcEFtdCIJbHBBc3NldElkIglhbUFzc2V0SWQiCXByQXNzZXRJZCIKcG9vbFN0YXR1cyIKbHBFbWlzc2lvbiIJYW1CYWxhbmNlIgxhbUJhbGFuY2VYMTgiCXByQmFsYW5jZSIMcHJCYWxhbmNlWDE4IgtjdXJQcmljZVgxOCIIY3VyUHJpY2UiC3BtdExwQW10WDE4Ig1scEVtaXNzaW9uWDE4IgtvdXRBbUFtdFgxOCILb3V0UHJBbXRYMTgiCG91dEFtQW10IghvdXRQckFtdCIFc3RhdGUiFGVzdGltYXRlUHV0T3BlcmF0aW9uIhFzbGlwcGFnZVRvbGVyYW5jZSIMaW5BbUFzc2V0QW10IgtpbkFtQXNzZXRJZCIMaW5QckFzc2V0QW10IgtpblByQXNzZXRJZCIKaXNFdmFsdWF0ZSIGZW1pdExwIgxhbUFzc2V0SWRTdHIiDHByQXNzZXRJZFN0ciILaUFtdEFzc2V0SWQiDWlQcmljZUFzc2V0SWQiDmluQW1Bc3NldElkU3RyIg5pblByQXNzZXRJZFN0ciIPaW5BbUFzc2V0QW10WDE4Ig9pblByQXNzZXRBbXRYMTgiDHVzZXJQcmljZVgxOCIDcmVzIgtzbGlwcGFnZVgxOCIUc2xpcHBhZ2VUb2xlcmFuY2VYMTgiCnByVmlhQW1YMTgiCmFtVmlhUHJYMTgiDGV4cGVjdGVkQW10cyIRZXhwQW10QXNzZXRBbXRYMTgiE2V4cFByaWNlQXNzZXRBbXRYMTgiCWNhbGNMcEFtdCIOY2FsY0FtQXNzZXRQbXQiDmNhbGNQckFzc2V0UG10IgxzbGlwcGFnZUNhbGMiCWVtaXRMcEFtdCIGYW1EaWZmIgZwckRpZmYiC2NvbW1vblN0YXRlIht2YWxpZGF0ZU1hdGNoZXJPcmRlckFsbG93ZWQiBW9yZGVyIgphbXRBc3NldElkIgxwcmljZUFzc2V0SWQiEmFjY0FtdEFzc2V0QmFsYW5jZSIUYWNjUHJpY2VBc3NldEJhbGFuY2UiDW9yZGVyQW10QXNzZXQiEG9yZGVyQW10QXNzZXRTdHIiD29yZGVyUHJpY2VBc3NldCISb3JkZXJQcmljZUFzc2V0U3RyIgpvcmRlclByaWNlIghwcmljZURjbSIQY2FzdGVkT3JkZXJQcmljZSIRaXNPcmRlclByaWNlVmFsaWQiCWNvbW1vbkdldCIBaSIDcG10IgZwbXRBbXQiCWNvbW1vblB1dCIKYW1Bc3NldFBtdCIKcHJBc3NldFBtdCIGZXN0UHV0IgRlbWl0IgZhbW91bnQiB2VtaXRJbnYiDWVtaXRJbnZMZWdhY3kiByRtYXRjaDAiFWxlZ2FjeUZhY3RvcnlDb250cmFjdCIHdGFrZUZlZSIDZmVlIglmZWVBbW91bnQiD2NhbGNQdXRPbmVUb2tlbiIQcGF5bWVudEFtb3VudFJhdyIOcGF5bWVudEFzc2V0SWQiBmlzRXZhbCIQYW1vdW50QmFsYW5jZVJhdyIPcHJpY2VCYWxhbmNlUmF3IhRwYXltZW50SW5BbW91bnRBc3NldCINJHQwMjI5NjkyMzI2MiIQYW1vdW50QmFsYW5jZU9sZCIPcHJpY2VCYWxhbmNlT2xkIg0kdDAyMzI2NjIzNDE1IhRhbW91bnRBc3NldEFtb3VudFJhdyITcHJpY2VBc3NldEFtb3VudFJhdyIRYW1vdW50QXNzZXRBbW91bnQiEHByaWNlQXNzZXRBbW91bnQiDSR0MDIzNTQ3MjM2MTEiDXBheW1lbnRBbW91bnQiEGFtb3VudEJhbGFuY2VOZXciD3ByaWNlQmFsYW5jZU5ldyILcHJpY2VOZXdYMTgiCHByaWNlTmV3Ig5wYXltZW50QmFsYW5jZSIUcGF5bWVudEJhbGFuY2VCaWdJbnQiDHN1cHBseUJpZ0ludCILY2hlY2hTdXBwbHkiDWRlcG9zaXRCaWdJbnQiC2lzc3VlQW1vdW50IgtwcmljZU9sZFgxOCIIcHJpY2VPbGQiBGxvc3MiDSR0MDI1MDg4MjUyNTUiB2JhbGFuY2UiD2lzc3VlQW1vdW50Qm90aCIPY2FsY0dldE9uZVRva2VuIgpvdXRBc3NldElkIgZjaGVja3MiEG91dEluQW1vdW50QXNzZXQiDWJhbGFuY2VCaWdJbnQiDGFtQmFsYW5jZU9sZCIMcHJCYWxhbmNlT2xkIgpvdXRCYWxhbmNlIhBvdXRCYWxhbmNlQmlnSW50Ig5yZWRlZW1lZEJpZ0ludCIJYW1vdW50UmF3Ig0kdDAyNjgzNTI2ODkxIgt0b3RhbEFtb3VudCINJHQwMjY4OTUyNzEyMSILb3V0QW1BbW91bnQiC291dFByQW1vdW50IgxhbUJhbGFuY2VOZXciDHByQmFsYW5jZU5ldyIYYW1vdW50Qm90aEluUGF5bWVudEFzc2V0IhZtYW5hZ2VyUHVibGljS2V5T3JVbml0IgFzIh1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdCIJaXNNYW5hZ2VyIgJwayILbXVzdE1hbmFnZXIiAnBkIg1jbGVhbkFtb3VudEluIglpc1JldmVyc2UiDSR0MDI4Nzk4MjkxMDMiCGFzc2V0T3V0Igdhc3NldEluIhJwb29sQXNzZXRJbkJhbGFuY2UiE3Bvb2xBc3NldE91dEJhbGFuY2UiCWFtb3VudE91dCIEb2xkSyIEbmV3SyIGY2hlY2tLIgxhbW91bnRPdXRNaW4iCWFkZHJlc3NUbyIIY2hlY2tNaW4iF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5IgtjaGVja0NhbGxlciIVY2hlY2tNYW5hZ2VyUHVibGljS2V5IgJwbSIFaGFzUE0iB2NoZWNrUE0iD3Nob3VsZEF1dG9TdGFrZSIEYW1JZCIEcHJJZCIMc2xpcHBhZ2VBSW52IgxzbGlwcGFnZVBJbnYiCmxwVHJhbnNmZXIiC3NscFN0YWtlSW52IgttYXhTbGlwcGFnZSIMbWluT3V0QW1vdW50IglhdXRvU3Rha2UiIGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkIg1pc1B1dERpc2FibGVkIgdwYXltZW50Ig0kdDAzNDI5NDM0NDI0IgVib251cyITZW1pdEFtb3VudEVzdGltYXRlZCIKZW1pdEFtb3VudCIIc3Rha2VJbnYiB3NlbmRGZWUiDSR0MDM1MTUzMzUyODgiDW91dEFzc2V0SWRTdHIiDWlzR2V0RGlzYWJsZWQiDSR0MDM2MDkzMzYyMjgiD2Ftb3VudEVzdGltYXRlZCIHYnVybkludiINYXNzZXRUcmFuc2ZlciINJHQwMzY4NjMzNzAwMSINdW5zdGFrZUFtb3VudCIKdW5zdGFrZUludiINJHQwMzc4MjYzNzk1OSIJb3V0QW10QW10IhRidXJuTFBBc3NldE9uRmFjdG9yeSISbm9MZXNzVGhlbkFtdEFzc2V0IhRub0xlc3NUaGVuUHJpY2VBc3NldCINY2hlY2tQYXltZW50cyIPY2hlY2tQb29sU3RhdHVzIhVub0xlc3NUaGVuQW1vdW50QXNzZXQiDGNoZWNrQW1vdW50cyILYW10QXNzZXRTdHIiDXByaWNlQXNzZXRTdHIiDXBvb2xMUEJhbGFuY2UiCnByaWNlc0xpc3QiD2xwQW10QXNzZXRTaGFyZSIRbHBQcmljZUFzc2V0U2hhcmUiCnBvb2xXZWlnaHQiDGN1clByaWNlQ2FsYyIMYW1CYWxhbmNlUmF3IgxwckJhbGFuY2VSYXciD2FtQmFsYW5jZVJhd1gxOCIPcHJCYWxhbmNlUmF3WDE4IhBwYXltZW50THBBc3NldElkIgxwYXltZW50THBBbXQiAnR4IgZ2ZXJpZnkiD3RhcmdldFB1YmxpY0tleSIKbWF0Y2hlclB1YiIHbmV3SGFzaCILYWxsb3dlZEhhc2giC2N1cnJlbnRIYXNoZQABYQAIAAFiAIDC1y8AAWMJALYCAQCAwtcvAAFkCQC2AgEAgICQu7rWrfANAAFlCQC2AgEAAAABZgkAtgIBAAAAAWcJALYCAQABAAFoCQC2AgEAAgABaQIFV0FWRVMAAWoCAl9fAAFrAAEAAWwAAgABbQADAAFuAAQAAW8AAQABcAACAAFxAAMAAXIABAABcwAFAAF0AAYAAXUABwABdgAIAAF3AAkAAXgACgABeQABAAF6AAIAAUEAAwABQgABAAFDAAcBAUQCAUUBRgkAvAIDCQC2AgEFAUUFAWQJALYCAQUBRgEBRwIBRQFGCQC8AgMFAUUFAWQFAUYBAUgCAUkBSgkAoAMBCQC8AgMFAUkJALYCAQUBSgUBZAEBSwMBSQFKAUwJAKADAQkAvQIEBQFJCQC2AgEFAUoFAWQFAUwBAU0DAU4BTwFQCQBrAwUBTgUBTwUBUAEBUQEBSQMJAGYCAAAFAUkJAQEtAQUBSQUBSQEBUgEBSQMJAL8CAgUBZQUBSQkAvgIBBQFJBQFJAQFTAAIQJXNfX3N3YXBDb250cmFjdAEBVAACEyVzX19mYWN0b3J5Q29udHJhY3QBAVUAAhQlc19fbWFuYWdlclB1YmxpY0tleQEBVgACGyVzX19wZW5kaW5nTWFuYWdlclB1YmxpY0tleQEBVwACESVzJXNfX3ByaWNlX19sYXN0AQFYAgFZAVoJALkJAgkAzAgCAhglcyVzJWQlZF9fcHJpY2VfX2hpc3RvcnkJAMwIAgkApAMBBQFZCQDMCAIJAKQDAQUBWgUDbmlsBQFqAQJhYQICYWICYWMJAKwCAgkArAICCQCsAgICCyVzJXMlc19fUF9fBQJhYgICX18FAmFjAQJhZAICYWICYWMJAKwCAgkArAICCQCsAgICCyVzJXMlc19fR19fBQJhYgICX18FAmFjAQJhZQACDyVzX19hbW91bnRBc3NldAECYWYAAg4lc19fcHJpY2VBc3NldAECYWcAAhElc19fZmFjdG9yeUNvbmZpZwECYWgAAhglcyVzX19tYXRjaGVyX19wdWJsaWNLZXkBAmFpAQJhagkArAICCQCsAgICCCVzJXMlc19fBQJhagIgX19tYXBwaW5nc19fcG9vbENvbnRyYWN0MkxwQXNzZXQBAmFrAgJhbAJhbQkArAICCQCsAgIJAKwCAgkArAICAgglZCVkJXNfXwUCYWwCAl9fBQJhbQIIX19jb25maWcBAmFuAQJhbwkArAICAiglcyVzJXNfX21hcHBpbmdzX19iYXNlQXNzZXQyaW50ZXJuYWxJZF9fBQJhbwECYXAAAgwlc19fc2h1dGRvd24BAmFxAQJhcgkArAICAhIlcyVzX19wb29sV2VpZ2h0X18FAmFyAQJhcwACFyVzX19hbGxvd2VkTHBTY3JpcHRIYXNoAAJhdAIXJXNfX2ZlZUNvbGxlY3RvckFkZHJlc3MBAmF1AwJhdgJhdwJheAkAAgEJAKwCAgkArAICCQCsAgIJAKwCAgkArAICAiRvcmRlciB2YWxpZGF0aW9uIGZhaWxlZDogb3JkZXJWYWxpZD0JAKUDAQUCYXYCDSBzZW5kZXJWYWxpZD0JAKUDAQUCYXcCDiBtYXRjaGVyVmFsaWQ9CQClAwEFAmF4AQJheQICYXoCYUEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAnQgCBQJhegUCYUEJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUCYXoJAMwIAgIBLgkAzAgCBQJhQQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAAQJhQgICYXoCYUEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkAmggCBQJhegUCYUEJALkJAgkAzAgCAgptYW5kYXRvcnkgCQDMCAIJAKUIAQUCYXoJAMwIAgIBLgkAzAgCBQJhQQkAzAgCAg8gaXMgbm90IGRlZmluZWQFA25pbAIAAQJhQwECYUQJAAIBCQC5CQIJAMwIAgIIbHAucmlkZToJAMwIAgUCYUQFA25pbAIBIAACYUUJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQJheQIFBHRoaXMJAQFUAAACYUYJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQJheQIFAmFFBQJhdAACYUcKAAJhSAkA/AcEBQJhRQIQZ2V0SW5GZWVSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFIAgNJbnQFAmFICQACAQkArAICCQADAQUCYUgCGCBjb3VsZG4ndCBiZSBjYXN0IHRvIEludAACYUkKAAJhSAkA/AcEBQJhRQIRZ2V0T3V0RmVlUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJhSAIDSW50BQJhSAkAAgEJAKwCAgkAAwEFAmFIAhggY291bGRuJ3QgYmUgY2FzdCB0byBJbnQBAmFKAAkBC3ZhbHVlT3JFbHNlAgkAmwgCBQJhRQkBAmFwAAcBAmFLAAkA2QQBCQECYXkCBQJhRQkBAmFoAAECYUwABAJhTQkBAmF5AgUEdGhpcwkBAmFlAAQCYU4JAQJheQIFBHRoaXMJAQJhZgAEAmFtCQECYUICBQJhRQkBAmFuAQUCYU4EAmFsCQECYUICBQJhRQkBAmFuAQUCYU0JALUJAgkBAmF5AgUCYUUJAQJhawIJAKQDAQUCYWwJAKQDAQUCYW0FAWoBAmFPAQJhUAMJAAACBQJhUAUBaQUEdW5pdAkA2QQBBQJhUAECYVEBAmFQAwkAAAIFAmFQBQR1bml0BQFpCQDYBAEJAQV2YWx1ZQEFAmFQAQJhUgECYVMJAJkKBwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQJhUwUBbwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmFTBQFwCQDZBAEJAJEDAgUCYVMFAXEJAQJhTwEJAJEDAgUCYVMFAXIJAQJhTwEJAJEDAgUCYVMFAXMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJhUwUBdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmFTBQF1AAJhVAkBAmFSAQkBAmFMAAACYVUFAmFUAAJhVggFAmFVAl8xAAJhVwgFAmFVAl8yAAJhWAgFAmFVAl8zAAJhWQgFAmFVAl80AAJhWggFAmFVAl81AAJiYQgFAmFVAl82AAJiYggFAmFVAl83AQJiYwAJALUJAgkBAmF5AgUCYUUJAQJhZwAFAWoAAmJkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCCQECYmMABQFCAhlpbmNvcnJlY3Qgc3Rha2luZyBhZGRyZXNzAAJiZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgkBAmJjAAUBQwIZaW5jb3JyZWN0IHN0YWtpbmcgYWRkcmVzcwECYmYKAmJnAmJoAmJpAmJqAmJrAmJsAmJtAmJuAmJvAmJwCQC5CQIJAMwIAgIUJWQlZCVkJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJiZwkAzAgCCQCkAwEFAmJoCQDMCAIJAKQDAQUCYmkJAMwIAgkApAMBBQJiagkAzAgCCQCkAwEFAmJrCQDMCAIJAKQDAQUCYmwJAMwIAgkApAMBBQJibQkAzAgCCQCkAwEFAmJuCQDMCAIJAKQDAQUCYm8JAMwIAgkApAMBBQJicAUDbmlsBQFqAQJicQYCYnICYnMCYnQCYmoCYm0CYm4JALkJAgkAzAgCAgwlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJicgkAzAgCCQCkAwEFAmJzCQDMCAIJAKQDAQUCYnQJAMwIAgkApAMBBQJiagkAzAgCCQCkAwEFAmJtCQDMCAIJAKQDAQUCYm4FA25pbAUBagECYnUBAmJ2AwkAAAIFAmJ2AgVXQVZFUwgJAO8HAQUEdGhpcwlhdmFpbGFibGUJAPAHAgUEdGhpcwkA2QQBBQJidgECYncCAmJ4AmJ5CQC8AgMFAmJ4BQFkBQJieQECYnoEAmJBAmJCAmJDAmJEBAJiRQkBAUQCBQJiQwUCYkEEAmJGCQEBRAIFAmJEBQJiQgkBAmJ3AgUCYkYFAmJFAQJiRwMCYkMCYkQCYkgEAmJJCQECYUwABAJiSgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF0BAJiSwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF1BAJiTAkBAmJ6BAUCYkoFAmJLBQJiQwUCYkQEAmJ5CQEBRAIFAmJDBQJiSgQCYngJAQFEAgUCYkQFAmJLBAJiTQkBAUQCBQJiSAUBYgQCYk4JAQJidwIFAmJ5BQJiTQQCYk8JAQJidwIFAmJ4BQJiTQkAzAgCBQJiTAkAzAgCBQJiTgkAzAgCBQJiTwUDbmlsAQJiUAMCYkMCYkQCYkgEAmJRCQECYkcDBQJiQwUCYkQFAmJICQDMCAIJAQFIAgkAkQMCBQJiUQAABQFiCQDMCAIJAQFIAgkAkQMCBQJiUQABBQFiCQDMCAIJAQFIAgkAkQMCBQJiUQACBQFiBQNuaWwBAmJSBAJiUwJiVAJiVQJhYgQCYkkJAQJhTAAEAmJWCQCRAwIFAmJJBQFxBAJiVwkAkQMCBQJiSQUBcgQCYlgJAJEDAgUCYkkFAXMEAmJBCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkkFAXQEAmJCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkkFAXUEAmJZCQCRAwIFAmJJBQFwBAJiWggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFAmJWCQCsAgIJAKwCAgIGQXNzZXQgBQJiVgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkDCQECIT0CBQJiVgUCYlQJAAIBAhVJbnZhbGlkIGFzc2V0IHBhc3NlZC4EAmNhCQECYnUBBQJiVwQCY2IJAQFEAgUCY2EFAmJBBAJjYwkBAmJ1AQUCYlgEAmNkCQEBRAIFAmNjBQJiQgQCY2UJAQJidwIFAmNkBQJjYgQCY2YJAQFIAgUCY2UFAWIEAmNnCQEBRAIFAmJVBQFiBAJjaAkBAUQCBQJiWgUBYgQCY2kJALwCAwUCY2IFAmNnBQJjaAQCY2oJALwCAwUCY2QFAmNnBQJjaAQCY2sJAQFIAgUCY2kFAmJBBAJjbAkBAUgCBQJjagUCYkIEAmNtAwkAAAIFAmJTAgAFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhYgUCY2sDCQAAAgUCYlcCBVdBVkVTBQR1bml0CQDZBAEFAmJXCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFiBQJjbAMJAAACBQJiWAIFV0FWRVMFBHVuaXQJANkEAQUCYlgJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFkAgkApQgBBQJhYgUCYlMJAQJicQYFAmNrBQJjbAUCYlUFAmNmBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVwAFAmNmCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBWAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmNmBQNuaWwJAJwKCgUCY2sFAmNsBQJiVwUCYlgFAmNhBQJjYwUCYloFAmNlBQJiWQUCY20BAmNuCQJiUwJjbwJjcAJjcQJjcgJjcwJhYgJjdAJjdQQCYkkJAQJhTAAEAmJWCQDZBAEJAJEDAgUCYkkFAXEEAmN2CQCRAwIFAmJJBQFyBAJjdwkAkQMCBQJiSQUBcwQCY3gJAJEDAgUCYkkFAXYEAmN5CQCRAwIFAmJJBQF3BAJiSgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF0BAJiSwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF1BAJiWQkAkQMCBQJiSQUBcAQCYloICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYlYJAKwCAgkArAICAgZBc3NldCAJANgEAQUCYlYCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJjegkA2AQBCQELdmFsdWVPckVsc2UCBQJjcQkA2QQBAgVXQVZFUwQCY0EJANgEAQkBC3ZhbHVlT3JFbHNlAgUCY3MJANkEAQIFV0FWRVMDAwkBAiE9AgUCY3YFAmN6BgkBAiE9AgUCY3cFAmNBCQACAQIiSW52YWxpZCBhbXQgb3IgcHJpY2UgYXNzZXQgcGFzc2VkLgQCY2EDBQJjdAkBAmJ1AQUCY3YJAGUCCQECYnUBBQJjdgUCY3AEAmNjAwUCY3QJAQJidQEFAmN3CQBlAgkBAmJ1AQUCY3cFAmNyBAJjQgkBAUQCBQJjcAUCYkoEAmNDCQEBRAIFAmNyBQJiSwQCY0QJAQJidwIFAmNDBQJjQgQCY2IJAQFEAgUCY2EFAmJKBAJjZAkBAUQCBQJjYwUCYksEAmNFAwkAAAIFAmJaAAAEAmNlBQFlBAJjRgUBZQQCYk0JAHYGCQC5AgIFAmNCBQJjQwAACQC2AgEABQABAAAFBERPV04JAJcKBQkBAUgCBQJiTQUBYgkBAUgCBQJjQgUCYkoJAQFIAgUCY0MFAmJLCQECYncCCQC3AgIFAmNkBQJjQwkAtwICBQJjYgUCY0IFAmNGBAJjZQkBAmJ3AgUCY2QFAmNiBAJjRgkAvAIDCQEBUgEJALgCAgUCY2UFAmNEBQFkBQJjZQQCY0cJAQFEAgUCY28FAWIDAwkBAiE9AgUCY2UFAWUJAL8CAgUCY0YFAmNHBwkAAgEJAKwCAgkArAICCQCsAgICD1ByaWNlIHNsaXBwYWdlIAkApgMBBQJjRgIeIGV4Y2VlZGVkIHRoZSBwYXNzZWQgbGltaXQgb2YgCQCmAwEFAmNHBAJjaAkBAUQCBQJiWgUBYgQCY0gJALwCAwUCY0IFAmNlBQFkBAJjSQkAvAIDBQJjQwUBZAUCY2UEAmNKAwkAvwICBQJjSAUCY0MJAJQKAgUCY0kFAmNDCQCUCgIFAmNCBQJjSAQCY0sIBQJjSgJfMQQCY0wIBQJjSgJfMgQCYk0JALwCAwUCY2gFAmNMBQJjZAkAlwoFCQEBSAIFAmJNBQFiCQEBSAIFAmNLBQJiSgkBAUgCBQJjTAUCYksFAmNlBQJjRgQCY00IBQJjRQJfMQQCY04IBQJjRQJfMgQCY08IBQJjRQJfMwQCY2YJAQFIAggFAmNFAl80BQFiBAJjUAkBAUgCCAUCY0UCXzUFAWIDCQBnAgAABQJjTQkAAgECNkludmFsaWQgY2FsY3VsYXRpb25zLiBMUCBjYWxjdWxhdGVkIGlzIGxlc3MgdGhhbiB6ZXJvLgQCY1EDCQEBIQEFAmN1AAAFAmNNBAJjUgkAZQIFAmNwBQJjTgQCY1MJAGUCBQJjcgUCY08EAmNUCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVwAFAmNmCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBWAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmNmCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhYQIFAmFiBQJiUwkBAmJmCgUCY04FAmNPBQJjUQUCY2YFAmNvBQJjUAUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCY1IFAmNTBQNuaWwJAJ8KDQUCY00FAmNRBQJjZgUCY2EFAmNjBQJiWgUCYlYFAmJZBQJjVAUCY1IFAmNTBQJjcQUCY3MBAmNVAQJjVgQCYkkJAQJhTAAEAmNXCQCRAwIFAmJJBQFyBAJjWAkAkQMCBQJiSQUBcwQCYlkJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiSQUBcAQCYkoJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiSQUBdAQCYksJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiSQUBdQQCY1kJAQJidQEFAmNXBAJjWgkBAmJ1AQUCY1gEAmNlAwkAAAIIBQJjVglvcmRlclR5cGUFA0J1eQkBAmJ6BAUCYkoFAmJLCQBkAgUCY1kIBQJjVgZhbW91bnQFAmNaCQECYnoEBQJiSgUCYksJAGUCBQJjWQgFAmNWBmFtb3VudAUCY1oEAmNmCQEBSAIFAmNlBQFiAwMDCQECYUoABgkAAAIFAmJZBQFtBgkAAAIFAmJZBQFuCQACAQIcRXhjaGFuZ2Ugb3BlcmF0aW9ucyBkaXNhYmxlZAQCZGEICAUCY1YJYXNzZXRQYWlyC2Ftb3VudEFzc2V0BAJkYgMJAAACBQJkYQUEdW5pdAIFV0FWRVMJANgEAQkBBXZhbHVlAQUCZGEEAmRjCAgFAmNWCWFzc2V0UGFpcgpwcmljZUFzc2V0BAJkZAMJAAACBQJkYwUEdW5pdAIFV0FWRVMJANgEAQkBBXZhbHVlAQUCZGMDAwkBAiE9AgUCZGIFAmNXBgkBAiE9AgUCZGQFAmNYCQACAQITV3Jvbmcgb3JkZXIgYXNzZXRzLgQCZGUIBQJjVgVwcmljZQQCZGYJAGsDBQFiBQJiSwUCYkoEAmRnCQEBTQMFAmRlBQFiBQJkZgQCZGgDCQAAAggFAmNWCW9yZGVyVHlwZQUDQnV5CQBnAgUCY2YFAmRnCQBnAgUCZGcFAmNmBgECZGkBAmRqAwkBAiE9AgkAkAMBCAUCZGoIcGF5bWVudHMAAQkAAgECHWV4YWN0bHkgMSBwYXltZW50IGlzIGV4cGVjdGVkBAJkawkBBXZhbHVlAQkAkQMCCAUCZGoIcGF5bWVudHMAAAQCYlQJAQV2YWx1ZQEIBQJkawdhc3NldElkBAJkbAgFAmRrBmFtb3VudAQCY0UJAQJiUgQJANgEAQgFAmRqDXRyYW5zYWN0aW9uSWQJANgEAQUCYlQFAmRsCAUCZGoGY2FsbGVyBAJjawgFAmNFAl8xBAJjbAgFAmNFAl8yBAJiWQkBDXBhcnNlSW50VmFsdWUBCAUCY0UCXzkEAmNtCAUCY0UDXzEwAwMJAQJhSgAGCQAAAgUCYlkFAW4JAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmJZCQCXCgUFAmNrBQJjbAUCZGwFAmJUBQJjbQECZG0DAmRqAmNvAmN1AwkBAiE9AgkAkAMBCAUCZGoIcGF5bWVudHMAAgkAAgECH2V4YWN0bHkgMiBwYXltZW50cyBhcmUgZXhwZWN0ZWQEAmRuCQEFdmFsdWUBCQCRAwIIBQJkaghwYXltZW50cwAABAJkbwkBBXZhbHVlAQkAkQMCCAUCZGoIcGF5bWVudHMAAQQCZHAJAQJjbgkJANgEAQgFAmRqDXRyYW5zYWN0aW9uSWQFAmNvCAUCZG4GYW1vdW50CAUCZG4HYXNzZXRJZAgFAmRvBmFtb3VudAgFAmRvB2Fzc2V0SWQJAKUIAQgFAmRqBmNhbGxlcgcFAmN1BAJiWQkBDXBhcnNlSW50VmFsdWUBCAUCZHACXzgDAwMJAQJhSgAGCQAAAgUCYlkFAWwGCQAAAgUCYlkFAW4JAAIBCQCsAgICLFB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmJZBQJkcAECZHEBAmRyBAJkcwkA/AcEBQJhRQIEZW1pdAkAzAgCBQJkcgUDbmlsBQNuaWwDCQAAAgUCZHMFAmRzBAJkdAQCZHUFAmRzAwkAAQIFAmR1AgdBZGRyZXNzBAJkdgUCZHUJAPwHBAUCZHYCBGVtaXQJAMwIAgUCZHIFA25pbAUDbmlsBQR1bml0AwkAAAIFAmR0BQJkdAUCZHIJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmR3AgJkcgJkeAQCZHkDCQAAAgUCZHgAAAAACQBrAwUCZHIFAmR4BQFiCQCUCgIJAGUCBQJkcgUCZHkFAmR5AQJkegQCZEECZEICYWICYWMEAmRDCQAAAgUCYWMFBHVuaXQEAmRECQECYnUBCQECYVEBBQJhWQQCZEUJAQJidQEJAQJhUQEFAmFaBAJkRgMJAAACBQJkQgUCYVkGAwkAAAIFAmRCBQJhWgcJAQJhQwECDWludmFsaWQgYXNzZXQEAmRHAwUCZEMJAJQKAgUCZEQFAmRFAwUCZEYJAJQKAgkAZQIFAmREBQJkQQUCZEUJAJQKAgUCZEQJAGUCBQJkRQUCZEEEAmRICAUCZEcCXzEEAmRJCAUCZEcCXzIEAmRKAwUCZEYJAJQKAgUCZEEAAAkAlAoCAAAFAmRBBAJkSwgFAmRKAl8xBAJkTAgFAmRKAl8yBAJkTQgJAQJkdwIFAmRLBQJhRwJfMQQCZE4ICQECZHcCBQJkTAUCYUcCXzEEAmRPCQECZHcCBQJkQQUCYUcEAmRQCAUCZE8CXzEEAmR5CAUCZE8CXzIEAmRRCQBkAgUCZEgFAmRNBAJkUgkAZAIFAmRJBQJkTgQCZFMJAQJidwIJAQFEAgUCZFIFAmJiCQEBRAIFAmRRBQJiYQQCZFQJAQFIAgUCZFMFAWIEAmRVAwUCZEYFAmRIBQJkSQQCZFYJALYCAQUCZFUEAmRXCQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYVgJAKwCAgkArAICAgZhc3NldCAJANgEAQUCYVgCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJkWAMJAL8CAgUCZFcFAWYGCQECYUMBAiJpbml0aWFsIGRlcG9zaXQgcmVxdWlyZXMgYWxsIGNvaW5zAwkAAAIFAmRYBQJkWAQCZFkJALYCAQUCZFAEAmRaCQCWAwEJAMwIAgAACQDMCAIJAKADAQkAugICCQC5AgIFAmRXCQC4AgIJAQpzcXJ0QmlnSW50BAkAtwICBQFkCQC6AgIJALkCAgUCZFkFAWQFAmRWABIAEgUERE9XTgUBZAUBZAUDbmlsBAJjVAMFAmRDBQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZFQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZFQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFhAgkApQgBCQEFdmFsdWUBBQJhYgkA2AQBCQEFdmFsdWUBBQJhYwkBAmJmCgUCZEsFAmRMBQJkWgUCZFQAAAAABQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wAAAAAAUDbmlsBAJlYQkBAmJ3AgkBAUQCBQJkSQUCYmIJAQFEAgUCZEgFAmJhBAJlYgkBAUgCBQJlYQUBYgQCZWMEAmVkAwUCZEYJAJQKAgUCZEsFAmRICQCUCgIFAmRMBQJkSQQCZHIIBQJlZAJfMQQCZWUIBQJlZAJfMgQCZWYJAKADAQkAvAIDBQJkVwkAtgIBCQBpAgUCZHIAAgkAtgIBBQJlZQkAawMJAGUCBQJkWgUCZWYFAWIFAmVmCQCWCgQFAmRaBQJjVAUCZHkFAmVjCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJlZwUCZWgCZFACZEICYWICYWMEAmRDCQAAAgUCYWMFBHVuaXQEAmVpCQDMCAIDCQAAAgUCZEIFAmFYBgkBAmFDAQIQaW52YWxpZCBscCBhc3NldAUDbmlsAwkAAAIFAmVpBQJlaQQCZWoDCQAAAgUCZWgFAmFZBgMJAAACBQJlaAUCYVoHCQECYUMBAg1pbnZhbGlkIGFzc2V0BAJlawMFAmVqCQC2AgEJAQJidQEJAQJhUQEFAmFZCQC2AgEJAQJidQEJAQJhUQEFAmFaBAJlbAkBAmJ1AQkBAmFRAQUCYVkEAmVtCQECYnUBCQECYVEBBQJhWgQCZW4DBQJlagUCZWwFAmVtBAJlbwkAtgIBBQJlbgQCZFcJALYCAQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJhWAkArAICCQCsAgICBmFzc2V0IAkA2AQBBQJhWAIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmVwCQC2AgEFAmRQBAJlcQkAlgMBCQDMCAIAAAkAzAgCCQCgAwEJALoCAgkAuQICBQJlawkAuAICBQFkCQB2BgkAuAICBQFkCQC6AgIJALkCAgUCZXAFAWQFAmRXABIFAWgAAAASBQRET1dOBQFkBQNuaWwEAmVyCQECZHcCBQJlcQUCYUkEAmVzCAUCZXICXzEEAmR5CAUCZXICXzIEAmV0AwUCZWoJAJYKBAUCZXMAAAkAZQIFAmVsBQJlcQUCZW0JAJYKBAAABQJlcwUCZWwJAGUCBQJlbQUCZXEEAmV1CAUCZXQCXzEEAmV2CAUCZXQCXzIEAmV3CAUCZXQCXzMEAmV4CAUCZXQCXzQEAmRTCQECYncCCQEBRAIFAmV4BQJiYgkBAUQCBQJldwUCYmEEAmRUCQEBSAIFAmRTBQFiBAJjVAMFAmRDBQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFkAgkApQgBCQEFdmFsdWUBBQJhYgkA2AQBCQEFdmFsdWUBBQJhYwkBAmJxBgUCZXUFAmV2BQJkUAUCZFQFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZFQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZFQFA25pbAQCZWEJAQJidwIJAQFEAgUCZW0FAmJiCQEBRAIFAmVsBQJiYQQCZWIJAQFIAgUCZWEFAWIEAmVjBAJleQkAaAIJAKADAQkAvAIDBQJlawUCZXAFAmRXAAIJAGsDCQBlAgUCZXMFAmV5BQFiBQJleQkAlgoEBQJlcwUCY1QFAmR5BQJlYwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZXoABAJkdQkAoggBCQEBVQADCQABAgUCZHUCBlN0cmluZwQCZUEFAmR1CQDZBAEFAmVBAwkAAQIFAmR1AgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmVCAAQCZHUJAKIIAQkBAVYAAwkAAQIFAmR1AgZTdHJpbmcEAmVBBQJkdQkA2QQBBQJlQQMJAAECBQJkdQIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJlQwECZGoEAmR1CQECZXoAAwkAAQIFAmR1AgpCeXRlVmVjdG9yBAJlRAUCZHUJAAACCAUCZGoPY2FsbGVyUHVibGljS2V5BQJlRAMJAAECBQJkdQIEVW5pdAkAAAIIBQJkagZjYWxsZXIFBHRoaXMJAAIBAgtNYXRjaCBlcnJvcgECZUUBAmRqBAJlRgkAAgECEVBlcm1pc3Npb24gZGVuaWVkBAJkdQkBAmV6AAMJAAECBQJkdQIKQnl0ZVZlY3RvcgQCZUQFAmR1AwkAAAIIBQJkag9jYWxsZXJQdWJsaWNLZXkFAmVEBgUCZUYDCQABAgUCZHUCBFVuaXQDCQAAAggFAmRqBmNhbGxlcgUEdGhpcwYFAmVGCQACAQILTWF0Y2ggZXJyb3IcAmRqASFjYWxjdWxhdGVBbW91bnRPdXRGb3JTd2FwUkVBRE9OTFkCAmVHAmVIBAJlSQMJAAACBQJlSAcEAmVKCQECYXkCBQR0aGlzCQECYWYABAJlSwkBAmF5AgUEdGhpcwkBAmFlAAkAlAoCBQJlSgUCZUsEAmVKCQECYXkCBQR0aGlzCQECYWUABAJlSwkBAmF5AgUEdGhpcwkBAmFmAAkAlAoCBQJlSgUCZUsEAmVKCAUCZUkCXzEEAmVLCAUCZUkCXzIEAmVMCQECYnUBBQJlSwQCZU0JAQJidQEFAmVKBAJlTgkAawMFAmVNBQJlRwkAZAIFAmVMBQJlRwQCZU8JALkCAgkAtgIBBQJlTAkAtgIBBQJlTQQCZVAJALkCAgkAtwICCQC2AgEJAQJidQEFAmVLCQC2AgEFAmVHCQC4AgIJALYCAQkBAmJ1AQUCZUoJALYCAQUCZU4EAmVRAwkAwAICBQJlUAUCZU8GCQACAQIUbmV3IEsgaXMgZmV3ZXIgZXJyb3IDCQAAAgUCZVEFAmVRCQCUCgIFA25pbAUCZU4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGoBJmNhbGN1bGF0ZUFtb3VudE91dEZvclN3YXBBbmRTZW5kVG9rZW5zBAJlRwJlSAJlUgJlUwQCZWkJAMwIAgMJAGcCCAkBBXZhbHVlAQkAkQMCCAUCZGoIcGF5bWVudHMAAAZhbW91bnQFAmVHBgkBAmFDAQIMV3JvbmcgYW1vdW50CQDMCAIDCQAAAggFAmRqBmNhbGxlcgkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmF5AgUEdGhpcwkBAVMABgkBAmFDAQIRUGVybWlzc2lvbiBkZW5pZWQFA25pbAMJAAACBQJlaQUCZWkEAmRrCQEFdmFsdWUBCQCRAwIIBQJkaghwYXltZW50cwAABAJlSwMJAAACCAUCZGsHYXNzZXRJZAUEdW5pdAkA2AQBCQCbAwECBVdBVkVTCQDYBAEJAQV2YWx1ZQEIBQJkawdhc3NldElkBAJlSgMJAAACBQJlSAcJAQJheQIFBHRoaXMJAQJhZgAJAQJheQIFBHRoaXMJAQJhZQAEAmVMCQBlAgkBAmJ1AQUCZUsICQEFdmFsdWUBCQCRAwIIBQJkaghwYXltZW50cwAABmFtb3VudAQCZU0JAQJidQEFAmVKBAJlTgkAaQIJAGgCBQJlTQUCZUcJAGQCBQJlTAUCZUcEAmVPCQBoAgUCZUwFAmVNBAJlUAkAaAIJAQJidQEFAmVLCQBlAgkBAmJ1AQUCZUoFAmVOBAJlUQMJAGcCBQJlUAUCZU8GCQACAQIUbmV3IEsgaXMgZmV3ZXIgZXJyb3IDCQAAAgUCZVEFAmVRBAJlVAMJAGcCBQJlTgUCZVIGCQACAQIsRXhjaGFuZ2UgcmVzdWx0IGlzIGZld2VyIGNvaW5zIHRoYW4gZXhwZWN0ZWQDCQAAAgUCZVQFAmVUCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmVTBQJlTgMJAAACBQJlSwIFV0FWRVMFBHVuaXQJANkEAQUCZUoFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkagEKc2V0TWFuYWdlcgECZVUEAmVWCQECZUUBBQJkagMJAAACBQJlVgUCZVYEAmVXCQDZBAEFAmVVAwkAAAIFAmVXBQJlVwkAzAgCCQELU3RyaW5nRW50cnkCCQEBVgAFAmVVBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGoBDmNvbmZpcm1NYW5hZ2VyAAQCZVgJAQJlQgAEAmVZAwkBCWlzRGVmaW5lZAEFAmVYBgkAAgECEk5vIHBlbmRpbmcgbWFuYWdlcgMJAAACBQJlWQUCZVkEAmVaAwkAAAIIBQJkag9jYWxsZXJQdWJsaWNLZXkJAQV2YWx1ZQEFAmVYBgkAAgECG1lvdSBhcmUgbm90IHBlbmRpbmcgbWFuYWdlcgMJAAACBQJlWgUCZVoJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAVUACQDYBAEJAQV2YWx1ZQEFAmVYCQDMCAIJAQtEZWxldGVFbnRyeQEJAQFWAAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRqAQNwdXQCAmNvAmZhAwkAZgIAAAUCY28JAAIBAiBJbnZhbGlkIHNsaXBwYWdlVG9sZXJhbmNlIHBhc3NlZAQCZHAJAQJkbQMFAmRqBQJjbwYEAmNRCAUCZHACXzIEAmJWCAUCZHACXzcEAmNtCAUCZHACXzkEAmNSCAUCZHADXzEwBAJjUwgFAmRwA18xMQQCZmIIBQJkcANfMTIEAmZjCAUCZHADXzEzBAJkcwkA/AcEBQJhRQIEZW1pdAkAzAgCBQJjUQUDbmlsBQNuaWwDCQAAAgUCZHMFAmRzBAJkdAQCZHUFAmRzAwkAAQIFAmR1AgdBZGRyZXNzBAJkdgUCZHUJAPwHBAUCZHYCBGVtaXQJAMwIAgUCY1EFA25pbAUDbmlsBQR1bml0AwkAAAIFAmR0BQJkdAQCZmQDCQBmAgUCY1IAAAkA/AcEBQJiZQIDcHV0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmZiBQJjUgUDbmlsBQNuaWwDCQAAAgUCZmQFAmZkBAJmZQMJAGYCBQJjUwAACQD8BwQFAmJlAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZmMFAmNTBQNuaWwFA25pbAMJAAACBQJmZQUCZmUEAmZmAwUCZmEEAmZnCQD8BwQFAmJkAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiVgUCY1EFA25pbAMJAAACBQJmZwUCZmcFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZGoGY2FsbGVyBQJjUQUCYlYFA25pbAkAzggCBQJjbQUCZmYJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGoBCnB1dEZvckZyZWUBAmZoAwkAZgIAAAUCZmgJAAIBAhRJbnZhbGlkIHZhbHVlIHBhc3NlZAQCZHAJAQJkbQMFAmRqBQJmaAcIBQJkcAJfOQJkagEJcHV0T25lVGtuAgJmaQJmagQCZmsKAAJhSAkA/AcEBQJhRQIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFIAgdCb29sZWFuBQJhSAkAAgEJAKwCAgkAAwEFAmFIAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJmbAMDAwkBAmFKAAYJAAACBQJhVwUBbAYJAAACBQJhVwUBbgYFAmZrBAJlaQkAzAgCAwMJAQEhAQUCZmwGCQECZUMBBQJkagYJAQJhQwECIXB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmRqCHBheW1lbnRzAAEGCQECYUMBAh5leGFjdGx5IDEgcGF5bWVudCBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJlaQUCZWkEAmZtCQCRAwIIBQJkaghwYXltZW50cwAABAJkQggFAmZtB2Fzc2V0SWQEAmRBCAUCZm0GYW1vdW50BAJhYggFAmRqBmNhbGxlcgQCYWMIBQJkag10cmFuc2FjdGlvbklkBAJmbgkBAmR6BAUCZEEFAmRCBQJhYgUCYWMDCQAAAgUCZm4FAmZuBAJmbwgFAmZuAl80BAJkeQgFAmZuAl8zBAJjVAgFAmZuAl8yBAJmcAgFAmZuAl8xBAJmcQMDCQBmAgUCZmkAAAkAZgIFAmZpBQJmcAcJAQJhQwEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZmkFA25pbAIABQJmcAQCZHMJAQJkcQEFAmZxAwkAAAIFAmRzBQJkcwQCZmYDBQJmagQCZnIJAPwHBAUCYmQCBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmFYBQJmcQUDbmlsAwkAAAIFAmZyBQJmcgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJkagZjYWxsZXIFAmZxBQJhWAUDbmlsBAJmcwMJAGYCBQJkeQAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFGBQJkeQUCZEIFA25pbAUDbmlsCQCUCgIJAM4IAgkAzggCBQJjVAUCZmYFAmZzBQJmcQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkagERcHV0T25lVGtuUkVBRE9OTFkCAmRCAmRBBAJmdAkBAmR6BAUCZEEJAQJhTwEFAmRCBQR1bml0BQR1bml0BAJmcAgFAmZ0Al8xBAJjVAgFAmZ0Al8yBAJkeQgFAmZ0Al8zBAJmbwgFAmZ0Al80CQCUCgIFA25pbAkAlQoDBQJmcAUCZHkFAmZvAmRqAQlnZXRPbmVUa24CAmZ1AmZpBAJmawoAAmFICQD8BwQFAmFFAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYUgCB0Jvb2xlYW4FAmFICQACAQkArAICCQADAQUCYUgCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmZ2AwMJAQJhSgAGCQAAAgUCYVcFAW4GBQJmawQCZWkJAMwIAgMDCQEBIQEFAmZ2BgkBAmVDAQUCZGoGCQECYUMBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJkaghwYXltZW50cwABBgkBAmFDAQIeZXhhY3RseSAxIHBheW1lbnQgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZWkFAmVpBAJlaAkBAmFPAQUCZnUEAmZtCQCRAwIIBQJkaghwYXltZW50cwAABAJkQggFAmZtB2Fzc2V0SWQEAmRQCAUCZm0GYW1vdW50BAJhYggFAmRqBmNhbGxlcgQCYWMIBQJkag10cmFuc2FjdGlvbklkBAJmdwkBAmVnBQUCZWgFAmRQBQJkQgUCYWIFAmFjAwkAAAIFAmZ3BQJmdwQCZm8IBQJmdwJfNAQCZHkIBQJmdwJfMwQCY1QIBQJmdwJfMgQCZngIBQJmdwJfMQQCZHIDAwkAZgIFAmZpAAAJAGYCBQJmaQUCZngHCQECYUMBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZpBQNuaWwCAAUCZngEAmZ5CQD8BwQFAmFFAgRidXJuCQDMCAIFAmRQBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmRCBQJkUAUDbmlsAwkAAAIFAmZ5BQJmeQQCZnoJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYWIFAmRyBQJlaAUDbmlsBAJmcwMJAGYCBQJkeQAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFGBQJkeQUCZWgFA25pbAUDbmlsCQCUCgIJAM4IAgkAzggCBQJjVAUCZnoFAmZzBQJkcgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkagERZ2V0T25lVGtuUkVBRE9OTFkCAmVoAmRQBAJmQQkBAmVnBQkBAmFPAQUCZWgFAmRQBQJhWAUEdW5pdAUEdW5pdAQCZngIBQJmQQJfMQQCY1QIBQJmQQJfMgQCZHkIBQJmQQJfMwQCZm8IBQJmQQJfNAkAlAoCBQNuaWwJAJUKAwUCZngFAmR5BQJmbwJkagETdW5zdGFrZUFuZEdldE9uZVRrbgMCZkICZnUCZmkEAmZrCgACYUgJAPwHBAUCYUUCKGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJhSAIHQm9vbGVhbgUCYUgJAAIBCQCsAgIJAAMBBQJhSAIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCZnYDAwkBAmFKAAYJAAACBQJhVwUBbgYFAmZrBAJlaQkAzAgCAwMJAQEhAQUCZnYGCQECZUMBBQJkagYJAQJhQwECIWdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmRqCHBheW1lbnRzAAAGCQECYUMBAhhubyBwYXltZW50cyBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJlaQUCZWkEAmVoCQECYU8BBQJmdQQCYWIIBQJkagZjYWxsZXIEAmFjCAUCZGoNdHJhbnNhY3Rpb25JZAQCZkMJAPwHBAUCYmQCB3Vuc3Rha2UJAMwIAgkA2AQBBQJhWAkAzAgCBQJmQgUDbmlsBQNuaWwDCQAAAgUCZkMFAmZDBAJmRAkBAmVnBQUCZWgFAmZCBQJhWAUCYWIFAmFjAwkAAAIFAmZEBQJmRAQCZm8IBQJmRAJfNAQCZHkIBQJmRAJfMwQCY1QIBQJmRAJfMgQCZngIBQJmRAJfMQQCZHIDAwkAZgIFAmZpAAAJAGYCBQJmaQUCZngHCQECYUMBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZpBQNuaWwCAAUCZngEAmZ5CQD8BwQFAmFFAgRidXJuCQDMCAIFAmZCBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmFYBQJmQgUDbmlsAwkAAAIFAmZ5BQJmeQQCZnoJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmRqBmNhbGxlcgUCZHIFAmVoBQNuaWwEAmZzAwkAZgIFAmR5AAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYUYFAmR5BQJlaAUDbmlsBQNuaWwJAJQKAgkAzggCCQDOCAIFAmNUBQJmegUCZnMFAmRyCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRqAQNnZXQABAJjRQkBAmRpAQUCZGoEAmZFCAUCY0UCXzEEAmNsCAUCY0UCXzIEAmRsCAUCY0UCXzMEAmJUCAUCY0UCXzQEAmNtCAUCY0UCXzUEAmZGCQD8BwQFAmFFAgRidXJuCQDMCAIFAmRsBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJUBQJkbAUDbmlsAwkAAAIFAmZGBQJmRgUCY20JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGoBCWdldE5vTGVzcwICZkcCZkgEAmNFCQECZGkBBQJkagQCY2sIBQJjRQJfMQQCY2wIBQJjRQJfMgQCZGwIBQJjRQJfMwQCYlQIBQJjRQJfNAQCY20IBQJjRQJfNQMJAGYCBQJmRwUCY2sJAAIBCQCsAgIJAKwCAgkArAICAhxub0xlc3NUaGVuQW10QXNzZXQgZmFpbGVkOiAgCQCkAwEFAmNrAgMgPCAJAKQDAQUCZkcDCQBmAgUCZkgFAmNsCQACAQkArAICCQCsAgIJAKwCAgIdbm9MZXNzVGhlblByaWNlQXNzZXQgZmFpbGVkOiAJAKQDAQUCY2wCAyA8IAkApAMBBQJmSAQCZkYJAPwHBAUCYUUCBGJ1cm4JAMwIAgUCZGwFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYlQFAmRsBQNuaWwDCQAAAgUCZkYFAmZGBQJjbQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkagENdW5zdGFrZUFuZEdldAECZHIEAmZJAwkBAiE9AgkAkAMBCAUCZGoIcGF5bWVudHMAAAkAAgECGE5vIHBheW1lbnRzIGFyZSBleHBlY3RlZAYDCQAAAgUCZkkFAmZJBAJiSQkBAmFMAAQCYlYJANkEAQkAkQMCBQJiSQUBcQQCZkMJAPwHBAUCYmQCB3Vuc3Rha2UJAMwIAgkA2AQBBQJiVgkAzAgCBQJkcgUDbmlsBQNuaWwDCQAAAgUCZkMFAmZDBAJjRQkBAmJSBAkA2AQBCAUCZGoNdHJhbnNhY3Rpb25JZAkA2AQBBQJiVgUCZHIIBQJkagZjYWxsZXIEAmJZCQENcGFyc2VJbnRWYWx1ZQEIBQJjRQJfOQQCY20IBQJjRQNfMTAEAmZKAwMJAQJhSgAGCQAAAgUCYlkFAW4JAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmJZBgMJAAACBQJmSgUCZkoEAmZGCQD8BwQFAmFFAgRidXJuCQDMCAIFAmRyBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJWBQJkcgUDbmlsAwkAAAIFAmZGBQJmRgUCY20JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGoBE3Vuc3Rha2VBbmRHZXROb0xlc3MDAmZCAmZLAmZIBAJmdgMJAQJhSgAGCQAAAgUCYVcFAW4EAmVpCQDMCAIDCQEBIQEFAmZ2BgkAAgECIWdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmRqCHBheW1lbnRzAAAGCQACAQIYbm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZWkFAmVpBAJmQwkA/AcEBQJiZAIHdW5zdGFrZQkAzAgCCQDYBAEFAmFYCQDMCAIFAmZCBQNuaWwFA25pbAMJAAACBQJmQwUCZkMEAmNFCQECYlIECQDYBAEIBQJkag10cmFuc2FjdGlvbklkCQDYBAEFAmFYBQJmQggFAmRqBmNhbGxlcgQCY2sIBQJjRQJfMQQCY2wIBQJjRQJfMgQCY20IBQJjRQNfMTAEAmZMCQDMCAIDCQBnAgUCY2sFAmZLBgkAAgEJALkJAgkAzAgCAixhbW91bnQgYXNzZXQgYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZLBQNuaWwCAAkAzAgCAwkAZwIFAmNsBQJmSAYJAAIBCQC5CQIJAMwIAgIrcHJpY2UgYXNzZXQgYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZIBQNuaWwCAAUDbmlsAwkAAAIFAmZMBQJmTAQCZkYJAPwHBAUCYUUCBGJ1cm4JAMwIAgUCZkIFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYVgFAmZCBQNuaWwDCQAAAgUCZkYFAmZGBQJjbQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkagEIYWN0aXZhdGUCAmZNAmZOAwkBAiE9AgkApQgBCAUCZGoGY2FsbGVyCQClCAEFAmFFCQACAQIScGVybWlzc2lvbnMgZGVuaWVkCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFlAAUCZk0JAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFmAAUCZk4FA25pbAIHc3VjY2VzcwJkagEcZ2V0UG9vbENvbmZpZ1dyYXBwZXJSRUFET05MWQAJAJQKAgUDbmlsCQECYUwAAmRqARxnZXRBY2NCYWxhbmNlV3JhcHBlclJFQURPTkxZAQJidgkAlAoCBQNuaWwJAQJidQEFAmJ2AmRqARljYWxjUHJpY2VzV3JhcHBlclJFQURPTkxZAwJiQwJiRAJiSAQCYlEJAQJiRwMFAmJDBQJiRAUCYkgJAJQKAgUDbmlsCQDMCAIJAKYDAQkAkQMCBQJiUQAACQDMCAIJAKYDAQkAkQMCBQJiUQABCQDMCAIJAKYDAQkAkQMCBQJiUQACBQNuaWwCZGoBFHRvWDE4V3JhcHBlclJFQURPTkxZAgFFAUYJAJQKAgUDbmlsCQCmAwEJAQFEAgUBRQUBRgJkagEWZnJvbVgxOFdyYXBwZXJSRUFET05MWQIBSQFKCQCUCgIFA25pbAkBAUgCCQCnAwEFAUkFAUoCZGoBHmNhbGNQcmljZUJpZ0ludFdyYXBwZXJSRUFET05MWQICYngCYnkJAJQKAgUDbmlsCQCmAwEJAQJidwIJAKcDAQUCYngJAKcDAQUCYnkCZGoBI2VzdGltYXRlUHV0T3BlcmF0aW9uV3JhcHBlclJFQURPTkxZCQJiUwJjbwJjcAJjcQJjcgJjcwJhYgJjdAJjdQkAlAoCBQNuaWwJAQJjbgkFAmJTBQJjbwUCY3AFAmNxBQJjcgUCY3MFAmFiBQJjdAUCY3UCZGoBI2VzdGltYXRlR2V0T3BlcmF0aW9uV3JhcHBlclJFQURPTkxZBAJiUwJiVAJiVQJhYgQCY0UJAQJiUgQFAmJTBQJiVAUCYlUJARFAZXh0ck5hdGl2ZSgxMDYyKQEFAmFiCQCUCgIFA25pbAkAnAoKCAUCY0UCXzEIBQJjRQJfMggFAmNFAl8zCAUCY0UCXzQIBQJjRQJfNQgFAmNFAl82CAUCY0UCXzcJAKYDAQgFAmNFAl84CAUCY0UCXzkIBQJjRQNfMTACZGoBDXN0YXRzUkVBRE9OTFkABAJiSQkBAmFMAAQCYlYJANkEAQkAkQMCBQJiSQUBcQQCY1cJAJEDAgUCYkkFAXIEAmNYCQCRAwIFAmJJBQFzBAJjeAkAkQMCBQJiSQUBdgQCY3kJAJEDAgUCYkkFAXcEAmJKCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkkFAXQEAmJLCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkkFAXUEAmZPCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmJWCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmJWAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCY1kJAQJidQEFAmNXBAJjWgkBAmJ1AQUCY1gEAmZQAwkAAAIFAmZPAAAJAMwIAgUBZQkAzAgCBQFlCQDMCAIFAWUFA25pbAkBAmJHAwUCY1kFAmNaBQJmTwQCY2YAAAQCZlEJAQFIAgkAkQMCBQJmUAABBQFiBAJmUgkBAUgCCQCRAwIFAmZQAAIFAWIEAmZTCQEFdmFsdWUBCQCaCAIFAmFFCQECYXEBCQClCAEFBHRoaXMJAJQKAgUDbmlsCQC5CQIJAMwIAgIOJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJjWQkAzAgCCQCkAwEFAmNaCQDMCAIJAKQDAQUCZk8JAMwIAgkApAMBBQJjZgkAzAgCCQCkAwEFAmZRCQDMCAIJAKQDAQUCZlIJAMwIAgkApAMBBQJmUwUDbmlsBQFqAmRqASBldmFsdWF0ZVB1dEJ5QW1vdW50QXNzZXRSRUFET05MWQECY3AEAmJJCQECYUwABAJiVgkA2QQBCQCRAwIFAmJJBQFxBAJjdgkAkQMCBQJiSQUBcgQCYlcJANkEAQUCY3YEAmN3CQCRAwIFAmJJBQFzBAJiWAkA2QQBBQJjdwQCYkoJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiSQUBdAQCYksJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiSQUBdQQCYlkJAJEDAgUCYkkFAXAEAmZPCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmJWCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmJWAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCY1kJAQJidQEFAmN2BAJjWgkBAmJ1AQUCY3cEAmJFCQEBRAIFAmNZBQJiSgQCYkYJAQFEAgUCY1oFAmJLBAJjZQMJAAACBQJmTwAABQFlCQECYncCBQJiRgUCYkUEAmNCCQEBRAIFAmNwBQJiSgQCY0MJALwCAwUCY0IFAmNlBQFkBAJjcgkBAUgCBQJjQwUCYksEAmRwCQECY24JAgAAoMIeBQJjcAUCYlcFAmNyBQJiWAIABgcEAmNNCAUCZHACXzEEAmZUCAUCZHACXzMEAmNhCAUCZHACXzQEAmNjCAUCZHACXzUEAmJaCAUCZHACXzYJAJQKAgUDbmlsCQC5CQIJAMwIAgIQJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmNNCQDMCAIJAKQDAQkBAUgCBQJjZQUBYgkAzAgCCQCkAwEFAmNhCQDMCAIJAKQDAQUCY2MJAMwIAgkApAMBBQJiWgkAzAgCBQJiWQkAzAgCCQCkAwEFAmNwCQDMCAIJAKQDAQUCY3IFA25pbAUBagJkagEfZXZhbHVhdGVQdXRCeVByaWNlQXNzZXRSRUFET05MWQECY3IEAmJJCQECYUwABAJiVgkA2QQBCQCRAwIFAmJJBQFxBAJjdgkAkQMCBQJiSQUBcgQCYlcJANkEAQUCY3YEAmN3CQCRAwIFAmJJBQFzBAJiWAkA2QQBBQJjdwQCYkoJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiSQUBdAQCYksJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiSQUBdQQCYlkJAJEDAgUCYkkFAXAEAmZPCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmJWCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmJWAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCZlUJAQJidQEFAmN2BAJmVgkBAmJ1AQUCY3cEAmZXCQEBRAIFAmZVBQJiSgQCZlgJAQFEAgUCZlYFAmJLBAJjZQMJAAACBQJmTwAABQFlCQECYncCBQJmWAUCZlcEAmNDCQEBRAIFAmNyBQJiSwQCY0IJALwCAwUCY0MFAWQFAmNlBAJjcAkBAUgCBQJjQgUCYkoEAmRwCQECY24JAgAAoMIeBQJjcAUCYlcFAmNyBQJiWAIABgcEAmNNCAUCZHACXzEEAmZUCAUCZHACXzMEAmNhCAUCZHACXzQEAmNjCAUCZHACXzUEAmJaCAUCZHACXzYJAJQKAgUDbmlsCQC5CQIJAMwIAgIQJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmNNCQDMCAIJAKQDAQkBAUgCBQJjZQUBYgkAzAgCCQCkAwEFAmNhCQDMCAIJAKQDAQUCY2MJAMwIAgkApAMBBQJiWgkAzAgCBQJiWQkAzAgCCQCkAwEFAmNwCQDMCAIJAKQDAQUCY3IFA25pbAUBagJkagETZXZhbHVhdGVHZXRSRUFET05MWQICZlkCZloEAmNFCQECYlIEAgAFAmZZBQJmWgUEdGhpcwQCY2sIBQJjRQJfMQQCY2wIBQJjRQJfMgQCY2EIBQJjRQJfNQQCY2MIBQJjRQJfNgQCYloIBQJjRQJfNwQCY2YIBQJjRQJfOAQCYlkJAQ1wYXJzZUludFZhbHVlAQgFAmNFAl85CQCUCgIFA25pbAkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCY2sJAMwIAgkApAMBBQJjbAkAzAgCCQCkAwEFAmNhCQDMCAIJAKQDAQUCY2MJAMwIAgkApAMBBQJiWgkAzAgCCQCmAwEFAmNmCQDMCAIJAKQDAQUCYlkFA25pbAUBagECZ2EBAmdiAAQCZ2MEAmR1CQECZXoAAwkAAQIFAmR1AgpCeXRlVmVjdG9yBAJlRAUCZHUFAmVEAwkAAQIFAmR1AgRVbml0CAUCZ2EPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IEAmR1BQJnYQMJAAECBQJkdQIFT3JkZXIEAmNWBQJkdQQCZ2QJAQJhSwAEAmF2CQECY1UBBQJjVgQCYXcJAPQDAwgFAmNWCWJvZHlCeXRlcwkAkQMCCAUCY1YGcHJvb2ZzAAAIBQJjVg9zZW5kZXJQdWJsaWNLZXkEAmF4CQD0AwMIBQJjVglib2R5Qnl0ZXMJAJEDAggFAmNWBnByb29mcwABBQJnZAMDAwUCYXYFAmF3BwUCYXgHBgkBAmF1AwUCYXYFAmF3BQJheAMJAAECBQJkdQIUU2V0U2NyaXB0VHJhbnNhY3Rpb24EAmVBBQJkdQQCZ2UJAPYDAQkBBXZhbHVlAQgFAmVBBnNjcmlwdAQCZ2YJANsEAQkBBXZhbHVlAQkAnQgCBQJhRQkBAmFzAAQCZ2cJAPEHAQUEdGhpcwMDCQAAAgUCZ2YFAmdlCQECIT0CBQJnZwUCZ2UHBgkA9AMDCAUCZ2EJYm9keUJ5dGVzCQCRAwIIBQJnYQZwcm9vZnMAAAUCZ2MJAPQDAwgFAmdhCWJvZHlCeXRlcwkAkQMCCAUCZ2EGcHJvb2ZzAAAFAmdj+bnUOA==", "chainId": 84, "height": 2441822, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 9x6RhetEx42z9WahwdXiARSRpDYSyQqdWu9RDXVptvLE Next: UBgWvRfcUmxWtN5rsStZJbQsoWp5EBBsEKjxZEY5Zxq Diff:
OldNewDifferences
661661 let assetIn = $t02879829103._2
662662 let poolAssetInBalance = getAccBalance(assetIn)
663663 let poolAssetOutBalance = getAccBalance(assetOut)
664- let amountOut = ((poolAssetOutBalance * cleanAmountIn) / (poolAssetInBalance + cleanAmountIn))
664+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
665665 let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
666666 let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
667667 let checkK = if ((newK >= oldK))
844844 let paymentAmountRaw = payment.amount
845845 let userAddress = i.caller
846846 let txId = i.transactionId
847- let $t03428834418 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
848- if (($t03428834418 == $t03428834418))
847+ let $t03429434424 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
848+ if (($t03429434424 == $t03429434424))
849849 then {
850- let bonus = $t03428834418._4
851- let feeAmount = $t03428834418._3
852- let commonState = $t03428834418._2
853- let emitAmountEstimated = $t03428834418._1
850+ let bonus = $t03429434424._4
851+ let feeAmount = $t03429434424._3
852+ let commonState = $t03429434424._2
853+ let emitAmountEstimated = $t03429434424._1
854854 let emitAmount = if (if ((minOutAmount > 0))
855855 then (minOutAmount > emitAmountEstimated)
856856 else false)
883883
884884 @Callable(i)
885885 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
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
886+ let $t03515335288 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
887+ let emitAmountEstimated = $t03515335288._1
888+ let commonState = $t03515335288._2
889+ let feeAmount = $t03515335288._3
890+ let bonus = $t03515335288._4
891891 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
892892 }
893893
921921 let paymentAmount = payment.amount
922922 let userAddress = i.caller
923923 let txId = i.transactionId
924- let $t03608736222 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
925- if (($t03608736222 == $t03608736222))
924+ let $t03609336228 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
925+ if (($t03609336228 == $t03609336228))
926926 then {
927- let bonus = $t03608736222._4
928- let feeAmount = $t03608736222._3
929- let commonState = $t03608736222._2
930- let amountEstimated = $t03608736222._1
927+ let bonus = $t03609336228._4
928+ let feeAmount = $t03609336228._3
929+ let commonState = $t03609336228._2
930+ let amountEstimated = $t03609336228._1
931931 let amount = if (if ((minOutAmount > 0))
932932 then (minOutAmount > amountEstimated)
933933 else false)
953953
954954 @Callable(i)
955955 func getOneTknREADONLY (outAssetId,paymentAmount) = {
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
956+ let $t03686337001 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
957+ let amountEstimated = $t03686337001._1
958+ let commonState = $t03686337001._2
959+ let feeAmount = $t03686337001._3
960+ let bonus = $t03686337001._4
961961 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
962962 }
963963
991991 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
992992 if ((unstakeInv == unstakeInv))
993993 then {
994- let $t03782037953 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
995- if (($t03782037953 == $t03782037953))
994+ let $t03782637959 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
995+ if (($t03782637959 == $t03782637959))
996996 then {
997- let bonus = $t03782037953._4
998- let feeAmount = $t03782037953._3
999- let commonState = $t03782037953._2
1000- let amountEstimated = $t03782037953._1
997+ let bonus = $t03782637959._4
998+ let feeAmount = $t03782637959._3
999+ let commonState = $t03782637959._2
1000+ let amountEstimated = $t03782637959._1
10011001 let amount = if (if ((minOutAmount > 0))
10021002 then (minOutAmount > amountEstimated)
10031003 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)
664- let amountOut = ((poolAssetOutBalance * cleanAmountIn) / (poolAssetInBalance + cleanAmountIn))
664+ let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn))
665665 let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance))
666666 let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut)))
667667 let checkK = if ((newK >= oldK))
668668 then true
669669 else throw("new K is fewer error")
670670 if ((checkK == checkK))
671671 then $Tuple2(nil, amountOut)
672672 else throw("Strict value is not equal to itself.")
673673 }
674674
675675
676676
677677 @Callable(i)
678678 func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo) = {
679679 let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
680680 then true
681681 else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(getStringOrFail(this, swapContract()))))
682682 then true
683683 else throwErr("Permission denied")]
684684 if ((checks == checks))
685685 then {
686686 let pmt = value(i.payments[0])
687687 let assetIn = if ((pmt.assetId == unit))
688688 then toBase58String(toBytes("WAVES"))
689689 else toBase58String(value(pmt.assetId))
690690 let assetOut = if ((isReverse == false))
691691 then getStringOrFail(this, pa())
692692 else getStringOrFail(this, aa())
693693 let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
694694 let poolAssetOutBalance = getAccBalance(assetOut)
695695 let amountOut = ((poolAssetOutBalance * cleanAmountIn) / (poolAssetInBalance + cleanAmountIn))
696696 let oldK = (poolAssetInBalance * poolAssetOutBalance)
697697 let newK = (getAccBalance(assetIn) * (getAccBalance(assetOut) - amountOut))
698698 let checkK = if ((newK >= oldK))
699699 then true
700700 else throw("new K is fewer error")
701701 if ((checkK == checkK))
702702 then {
703703 let checkMin = if ((amountOut >= amountOutMin))
704704 then true
705705 else throw("Exchange result is fewer coins than expected")
706706 if ((checkMin == checkMin))
707707 then [ScriptTransfer(addressFromStringValue(addressTo), amountOut, if ((assetIn == "WAVES"))
708708 then unit
709709 else fromBase58String(assetOut))]
710710 else throw("Strict value is not equal to itself.")
711711 }
712712 else throw("Strict value is not equal to itself.")
713713 }
714714 else throw("Strict value is not equal to itself.")
715715 }
716716
717717
718718
719719 @Callable(i)
720720 func setManager (pendingManagerPublicKey) = {
721721 let checkCaller = mustManager(i)
722722 if ((checkCaller == checkCaller))
723723 then {
724724 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
725725 if ((checkManagerPublicKey == checkManagerPublicKey))
726726 then [StringEntry(pmpk(), pendingManagerPublicKey)]
727727 else throw("Strict value is not equal to itself.")
728728 }
729729 else throw("Strict value is not equal to itself.")
730730 }
731731
732732
733733
734734 @Callable(i)
735735 func confirmManager () = {
736736 let pm = pendingManagerPublicKeyOrUnit()
737737 let hasPM = if (isDefined(pm))
738738 then true
739739 else throw("No pending manager")
740740 if ((hasPM == hasPM))
741741 then {
742742 let checkPM = if ((i.callerPublicKey == value(pm)))
743743 then true
744744 else throw("You are not pending manager")
745745 if ((checkPM == checkPM))
746746 then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())]
747747 else throw("Strict value is not equal to itself.")
748748 }
749749 else throw("Strict value is not equal to itself.")
750750 }
751751
752752
753753
754754 @Callable(i)
755755 func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
756756 then throw("Invalid slippageTolerance passed")
757757 else {
758758 let estPut = commonPut(i, slippageTolerance, true)
759759 let emitLpAmt = estPut._2
760760 let lpAssetId = estPut._7
761761 let state = estPut._9
762762 let amDiff = estPut._10
763763 let prDiff = estPut._11
764764 let amId = estPut._12
765765 let prId = estPut._13
766766 let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
767767 if ((emitInv == emitInv))
768768 then {
769769 let emitInvLegacy = match emitInv {
770770 case legacyFactoryContract: Address =>
771771 invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
772772 case _ =>
773773 unit
774774 }
775775 if ((emitInvLegacy == emitInvLegacy))
776776 then {
777777 let slippageAInv = if ((amDiff > 0))
778778 then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
779779 else nil
780780 if ((slippageAInv == slippageAInv))
781781 then {
782782 let slippagePInv = if ((prDiff > 0))
783783 then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
784784 else nil
785785 if ((slippagePInv == slippagePInv))
786786 then {
787787 let lpTransfer = if (shouldAutoStake)
788788 then {
789789 let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
790790 if ((slpStakeInv == slpStakeInv))
791791 then nil
792792 else throw("Strict value is not equal to itself.")
793793 }
794794 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
795795 (state ++ lpTransfer)
796796 }
797797 else throw("Strict value is not equal to itself.")
798798 }
799799 else throw("Strict value is not equal to itself.")
800800 }
801801 else throw("Strict value is not equal to itself.")
802802 }
803803 else throw("Strict value is not equal to itself.")
804804 }
805805
806806
807807
808808 @Callable(i)
809809 func putForFree (maxSlippage) = if ((0 > maxSlippage))
810810 then throw("Invalid value passed")
811811 else {
812812 let estPut = commonPut(i, maxSlippage, false)
813813 estPut._9
814814 }
815815
816816
817817
818818 @Callable(i)
819819 func putOneTkn (minOutAmount,autoStake) = {
820820 let isPoolOneTokenOperationsDisabled = {
821821 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
822822 if ($isInstanceOf(@, "Boolean"))
823823 then @
824824 else throw(($getType(@) + " couldn't be cast to Boolean"))
825825 }
826826 let isPutDisabled = if (if (if (isGlobalShutdown())
827827 then true
828828 else (cfgPoolStatus == PoolPutDisabled))
829829 then true
830830 else (cfgPoolStatus == PoolShutdown))
831831 then true
832832 else isPoolOneTokenOperationsDisabled
833833 let checks = [if (if (!(isPutDisabled))
834834 then true
835835 else isManager(i))
836836 then true
837837 else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
838838 then true
839839 else throwErr("exactly 1 payment are expected")]
840840 if ((checks == checks))
841841 then {
842842 let payment = i.payments[0]
843843 let paymentAssetId = payment.assetId
844844 let paymentAmountRaw = payment.amount
845845 let userAddress = i.caller
846846 let txId = i.transactionId
847- let $t03428834418 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
848- if (($t03428834418 == $t03428834418))
847+ let $t03429434424 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
848+ if (($t03429434424 == $t03429434424))
849849 then {
850- let bonus = $t03428834418._4
851- let feeAmount = $t03428834418._3
852- let commonState = $t03428834418._2
853- let emitAmountEstimated = $t03428834418._1
850+ let bonus = $t03429434424._4
851+ let feeAmount = $t03429434424._3
852+ let commonState = $t03429434424._2
853+ let emitAmountEstimated = $t03429434424._1
854854 let emitAmount = if (if ((minOutAmount > 0))
855855 then (minOutAmount > emitAmountEstimated)
856856 else false)
857857 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
858858 else emitAmountEstimated
859859 let emitInv = emit(emitAmount)
860860 if ((emitInv == emitInv))
861861 then {
862862 let lpTransfer = if (autoStake)
863863 then {
864864 let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
865865 if ((stakeInv == stakeInv))
866866 then nil
867867 else throw("Strict value is not equal to itself.")
868868 }
869869 else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
870870 let sendFee = if ((feeAmount > 0))
871871 then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
872872 else nil
873873 $Tuple2(((commonState ++ lpTransfer) ++ sendFee), emitAmount)
874874 }
875875 else throw("Strict value is not equal to itself.")
876876 }
877877 else throw("Strict value is not equal to itself.")
878878 }
879879 else throw("Strict value is not equal to itself.")
880880 }
881881
882882
883883
884884 @Callable(i)
885885 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
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
886+ let $t03515335288 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
887+ let emitAmountEstimated = $t03515335288._1
888+ let commonState = $t03515335288._2
889+ let feeAmount = $t03515335288._3
890+ let bonus = $t03515335288._4
891891 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
892892 }
893893
894894
895895
896896 @Callable(i)
897897 func getOneTkn (outAssetIdStr,minOutAmount) = {
898898 let isPoolOneTokenOperationsDisabled = {
899899 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
900900 if ($isInstanceOf(@, "Boolean"))
901901 then @
902902 else throw(($getType(@) + " couldn't be cast to Boolean"))
903903 }
904904 let isGetDisabled = if (if (isGlobalShutdown())
905905 then true
906906 else (cfgPoolStatus == PoolShutdown))
907907 then true
908908 else isPoolOneTokenOperationsDisabled
909909 let checks = [if (if (!(isGetDisabled))
910910 then true
911911 else isManager(i))
912912 then true
913913 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
914914 then true
915915 else throwErr("exactly 1 payment are expected")]
916916 if ((checks == checks))
917917 then {
918918 let outAssetId = parseAssetId(outAssetIdStr)
919919 let payment = i.payments[0]
920920 let paymentAssetId = payment.assetId
921921 let paymentAmount = payment.amount
922922 let userAddress = i.caller
923923 let txId = i.transactionId
924- let $t03608736222 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
925- if (($t03608736222 == $t03608736222))
924+ let $t03609336228 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
925+ if (($t03609336228 == $t03609336228))
926926 then {
927- let bonus = $t03608736222._4
928- let feeAmount = $t03608736222._3
929- let commonState = $t03608736222._2
930- let amountEstimated = $t03608736222._1
927+ let bonus = $t03609336228._4
928+ let feeAmount = $t03609336228._3
929+ let commonState = $t03609336228._2
930+ let amountEstimated = $t03609336228._1
931931 let amount = if (if ((minOutAmount > 0))
932932 then (minOutAmount > amountEstimated)
933933 else false)
934934 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
935935 else amountEstimated
936936 let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
937937 if ((burnInv == burnInv))
938938 then {
939939 let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
940940 let sendFee = if ((feeAmount > 0))
941941 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
942942 else nil
943943 $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
944944 }
945945 else throw("Strict value is not equal to itself.")
946946 }
947947 else throw("Strict value is not equal to itself.")
948948 }
949949 else throw("Strict value is not equal to itself.")
950950 }
951951
952952
953953
954954 @Callable(i)
955955 func getOneTknREADONLY (outAssetId,paymentAmount) = {
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
956+ let $t03686337001 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
957+ let amountEstimated = $t03686337001._1
958+ let commonState = $t03686337001._2
959+ let feeAmount = $t03686337001._3
960+ let bonus = $t03686337001._4
961961 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
962962 }
963963
964964
965965
966966 @Callable(i)
967967 func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
968968 let isPoolOneTokenOperationsDisabled = {
969969 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
970970 if ($isInstanceOf(@, "Boolean"))
971971 then @
972972 else throw(($getType(@) + " couldn't be cast to Boolean"))
973973 }
974974 let isGetDisabled = if (if (isGlobalShutdown())
975975 then true
976976 else (cfgPoolStatus == PoolShutdown))
977977 then true
978978 else isPoolOneTokenOperationsDisabled
979979 let checks = [if (if (!(isGetDisabled))
980980 then true
981981 else isManager(i))
982982 then true
983983 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
984984 then true
985985 else throwErr("no payments are expected")]
986986 if ((checks == checks))
987987 then {
988988 let outAssetId = parseAssetId(outAssetIdStr)
989989 let userAddress = i.caller
990990 let txId = i.transactionId
991991 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
992992 if ((unstakeInv == unstakeInv))
993993 then {
994- let $t03782037953 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
995- if (($t03782037953 == $t03782037953))
994+ let $t03782637959 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
995+ if (($t03782637959 == $t03782637959))
996996 then {
997- let bonus = $t03782037953._4
998- let feeAmount = $t03782037953._3
999- let commonState = $t03782037953._2
1000- let amountEstimated = $t03782037953._1
997+ let bonus = $t03782637959._4
998+ let feeAmount = $t03782637959._3
999+ let commonState = $t03782637959._2
1000+ let amountEstimated = $t03782637959._1
10011001 let amount = if (if ((minOutAmount > 0))
10021002 then (minOutAmount > amountEstimated)
10031003 else false)
10041004 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
10051005 else amountEstimated
10061006 let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
10071007 if ((burnInv == burnInv))
10081008 then {
10091009 let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
10101010 let sendFee = if ((feeAmount > 0))
10111011 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
10121012 else nil
10131013 $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
10141014 }
10151015 else throw("Strict value is not equal to itself.")
10161016 }
10171017 else throw("Strict value is not equal to itself.")
10181018 }
10191019 else throw("Strict value is not equal to itself.")
10201020 }
10211021 else throw("Strict value is not equal to itself.")
10221022 }
10231023
10241024
10251025
10261026 @Callable(i)
10271027 func get () = {
10281028 let res = commonGet(i)
10291029 let outAmtAmt = res._1
10301030 let outPrAmt = res._2
10311031 let pmtAmt = res._3
10321032 let pmtAssetId = res._4
10331033 let state = res._5
10341034 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
10351035 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
10361036 then state
10371037 else throw("Strict value is not equal to itself.")
10381038 }
10391039
10401040
10411041
10421042 @Callable(i)
10431043 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
10441044 let res = commonGet(i)
10451045 let outAmAmt = res._1
10461046 let outPrAmt = res._2
10471047 let pmtAmt = res._3
10481048 let pmtAssetId = res._4
10491049 let state = res._5
10501050 if ((noLessThenAmtAsset > outAmAmt))
10511051 then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
10521052 else if ((noLessThenPriceAsset > outPrAmt))
10531053 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
10541054 else {
10551055 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
10561056 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
10571057 then state
10581058 else throw("Strict value is not equal to itself.")
10591059 }
10601060 }
10611061
10621062
10631063
10641064 @Callable(i)
10651065 func unstakeAndGet (amount) = {
10661066 let checkPayments = if ((size(i.payments) != 0))
10671067 then throw("No payments are expected")
10681068 else true
10691069 if ((checkPayments == checkPayments))
10701070 then {
10711071 let cfg = getPoolConfig()
10721072 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
10731073 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
10741074 if ((unstakeInv == unstakeInv))
10751075 then {
10761076 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
10771077 let poolStatus = parseIntValue(res._9)
10781078 let state = res._10
10791079 let checkPoolStatus = if (if (isGlobalShutdown())
10801080 then true
10811081 else (poolStatus == PoolShutdown))
10821082 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
10831083 else true
10841084 if ((checkPoolStatus == checkPoolStatus))
10851085 then {
10861086 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
10871087 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
10881088 then state
10891089 else throw("Strict value is not equal to itself.")
10901090 }
10911091 else throw("Strict value is not equal to itself.")
10921092 }
10931093 else throw("Strict value is not equal to itself.")
10941094 }
10951095 else throw("Strict value is not equal to itself.")
10961096 }
10971097
10981098
10991099
11001100 @Callable(i)
11011101 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
11021102 let isGetDisabled = if (isGlobalShutdown())
11031103 then true
11041104 else (cfgPoolStatus == PoolShutdown)
11051105 let checks = [if (!(isGetDisabled))
11061106 then true
11071107 else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
11081108 then true
11091109 else throw("no payments are expected")]
11101110 if ((checks == checks))
11111111 then {
11121112 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
11131113 if ((unstakeInv == unstakeInv))
11141114 then {
11151115 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
11161116 let outAmAmt = res._1
11171117 let outPrAmt = res._2
11181118 let state = res._10
11191119 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
11201120 then true
11211121 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
11221122 then true
11231123 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
11241124 if ((checkAmounts == checkAmounts))
11251125 then {
11261126 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
11271127 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11281128 then state
11291129 else throw("Strict value is not equal to itself.")
11301130 }
11311131 else throw("Strict value is not equal to itself.")
11321132 }
11331133 else throw("Strict value is not equal to itself.")
11341134 }
11351135 else throw("Strict value is not equal to itself.")
11361136 }
11371137
11381138
11391139
11401140 @Callable(i)
11411141 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
11421142 then throw("permissions denied")
11431143 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
11441144
11451145
11461146
11471147 @Callable(i)
11481148 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
11491149
11501150
11511151
11521152 @Callable(i)
11531153 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
11541154
11551155
11561156
11571157 @Callable(i)
11581158 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
11591159 let prices = calcPrices(amAmt, prAmt, lpAmt)
11601160 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
11611161 }
11621162
11631163
11641164
11651165 @Callable(i)
11661166 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
11671167
11681168
11691169
11701170 @Callable(i)
11711171 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
11721172
11731173
11741174
11751175 @Callable(i)
11761176 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
11771177
11781178
11791179
11801180 @Callable(i)
11811181 func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
11821182
11831183
11841184
11851185 @Callable(i)
11861186 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
11871187 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
11881188 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
11891189 }
11901190
11911191
11921192
11931193 @Callable(i)
11941194 func statsREADONLY () = {
11951195 let cfg = getPoolConfig()
11961196 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
11971197 let amtAssetId = cfg[idxAmtAssetId]
11981198 let priceAssetId = cfg[idxPriceAssetId]
11991199 let iAmtAssetId = cfg[idxIAmtAssetId]
12001200 let iPriceAssetId = cfg[idxIPriceAssetId]
12011201 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
12021202 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
12031203 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
12041204 let accAmtAssetBalance = getAccBalance(amtAssetId)
12051205 let accPriceAssetBalance = getAccBalance(priceAssetId)
12061206 let pricesList = if ((poolLPBalance == 0))
12071207 then [zeroBigInt, zeroBigInt, zeroBigInt]
12081208 else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
12091209 let curPrice = 0
12101210 let lpAmtAssetShare = fromX18(pricesList[1], scale8)
12111211 let lpPriceAssetShare = fromX18(pricesList[2], scale8)
12121212 let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
12131213 $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))
12141214 }
12151215
12161216
12171217
12181218 @Callable(i)
12191219 func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
12201220 let cfg = getPoolConfig()
12211221 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
12221222 let amAssetIdStr = cfg[idxAmtAssetId]
12231223 let amAssetId = fromBase58String(amAssetIdStr)
12241224 let prAssetIdStr = cfg[idxPriceAssetId]
12251225 let prAssetId = fromBase58String(prAssetIdStr)
12261226 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
12271227 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
12281228 let poolStatus = cfg[idxPoolStatus]
12291229 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
12301230 let accAmtAssetBalance = getAccBalance(amAssetIdStr)
12311231 let accPriceAssetBalance = getAccBalance(prAssetIdStr)
12321232 let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
12331233 let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
12341234 let curPriceX18 = if ((poolLPBalance == 0))
12351235 then zeroBigInt
12361236 else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
12371237 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
12381238 let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
12391239 let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
12401240 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
12411241 let calcLpAmt = estPut._1
12421242 let curPriceCalc = estPut._3
12431243 let amBalance = estPut._4
12441244 let prBalance = estPut._5
12451245 let lpEmission = estPut._6
12461246 $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))
12471247 }
12481248
12491249
12501250
12511251 @Callable(i)
12521252 func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
12531253 let cfg = getPoolConfig()
12541254 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
12551255 let amAssetIdStr = cfg[idxAmtAssetId]
12561256 let amAssetId = fromBase58String(amAssetIdStr)
12571257 let prAssetIdStr = cfg[idxPriceAssetId]
12581258 let prAssetId = fromBase58String(prAssetIdStr)
12591259 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
12601260 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
12611261 let poolStatus = cfg[idxPoolStatus]
12621262 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
12631263 let amBalanceRaw = getAccBalance(amAssetIdStr)
12641264 let prBalanceRaw = getAccBalance(prAssetIdStr)
12651265 let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
12661266 let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
12671267 let curPriceX18 = if ((poolLPBalance == 0))
12681268 then zeroBigInt
12691269 else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
12701270 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
12711271 let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
12721272 let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
12731273 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
12741274 let calcLpAmt = estPut._1
12751275 let curPriceCalc = estPut._3
12761276 let amBalance = estPut._4
12771277 let prBalance = estPut._5
12781278 let lpEmission = estPut._6
12791279 $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))
12801280 }
12811281
12821282
12831283
12841284 @Callable(i)
12851285 func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
12861286 let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
12871287 let outAmAmt = res._1
12881288 let outPrAmt = res._2
12891289 let amBalance = res._5
12901290 let prBalance = res._6
12911291 let lpEmission = res._7
12921292 let curPrice = res._8
12931293 let poolStatus = parseIntValue(res._9)
12941294 $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))
12951295 }
12961296
12971297
12981298 @Verifier(tx)
12991299 func verify () = {
13001300 let targetPublicKey = match managerPublicKeyOrUnit() {
13011301 case pk: ByteVector =>
13021302 pk
13031303 case _: Unit =>
13041304 tx.senderPublicKey
13051305 case _ =>
13061306 throw("Match error")
13071307 }
13081308 match tx {
13091309 case order: Order =>
13101310 let matcherPub = getMatcherPubOrFail()
13111311 let orderValid = validateMatcherOrderAllowed(order)
13121312 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
13131313 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
13141314 if (if (if (orderValid)
13151315 then senderValid
13161316 else false)
13171317 then matcherValid
13181318 else false)
13191319 then true
13201320 else throwOrderError(orderValid, senderValid, matcherValid)
13211321 case s: SetScriptTransaction =>
13221322 let newHash = blake2b256(value(s.script))
13231323 let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
13241324 let currentHash = scriptHash(this)
13251325 if (if ((allowedHash == newHash))
13261326 then (currentHash != newHash)
13271327 else false)
13281328 then true
13291329 else sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
13301330 case _ =>
13311331 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
13321332 }
13331333 }
13341334

github/deemru/w8io/3ef1775 
209.76 ms