tx · HzF2TbmxcAp2BiCmGPJLLetNhYjCaoS9c5Pyo6kToPbN

3N4vUDe3oc1YPNwMyQi2h8f2tmGoA7wBZp2:  -0.03200000 Waves

2023.02.09 09:31 [2441743] smart account 3N4vUDe3oc1YPNwMyQi2h8f2tmGoA7wBZp2 > SELF 0.00000000 Waves

{ "type": 13, "id": "HzF2TbmxcAp2BiCmGPJLLetNhYjCaoS9c5Pyo6kToPbN", "fee": 3200000, "feeAssetId": null, "timestamp": 1675924331456, "version": 1, "sender": "3N4vUDe3oc1YPNwMyQi2h8f2tmGoA7wBZp2", "senderPublicKey": "6MuWw1pkme7UgQX2hZh8yTZyoWVkz8A4rmHZ1acrsrVm", "proofs": [ "4eF58PYrbMmWxjuXXqMBAvbK8qvm4jChZkm93v8g5DWnJvQff6NuBELWb9FaxSdS52sEWMsg5YBr5t3sQsDSNeBq" ], "script": "base64:BgKcKQgCEgQKAgEEEgYKBAEEAQgSAwoBCBIAEgQKAgEEEgMKAQESBAoCAQQSBAoCCAESBAoCCAESBAoCCAESBQoDAQgBEgASBAoCAQESAwoBARIFCgMBAQESBAoCCAgSABIDCgEIEgUKAwEBARIECgIBARIECgIIARIECgIICBILCgkIAQECAQIIBAQSBgoECAgBCBIAEgMKAQESAwoBARIECgIIASIKbFBkZWNpbWFscyIGc2NhbGU4IgxzY2FsZThCaWdJbnQiB3NjYWxlMTgiCnplcm9CaWdJbnQiBGJpZzAiBGJpZzEiBGJpZzIiC3dhdmVzU3RyaW5nIgNTRVAiClBvb2xBY3RpdmUiD1Bvb2xQdXREaXNhYmxlZCITUG9vbE1hdGNoZXJEaXNhYmxlZCIMUG9vbFNodXRkb3duIg5pZHhQb29sQWRkcmVzcyINaWR4UG9vbFN0YXR1cyIQaWR4UG9vbExQQXNzZXRJZCINaWR4QW10QXNzZXRJZCIPaWR4UHJpY2VBc3NldElkIg5pZHhBbXRBc3NldERjbSIQaWR4UHJpY2VBc3NldERjbSIOaWR4SUFtdEFzc2V0SWQiEGlkeElQcmljZUFzc2V0SWQiDWlkeExQQXNzZXREY20iEmlkeFBvb2xBbXRBc3NldEFtdCIUaWR4UG9vbFByaWNlQXNzZXRBbXQiEWlkeFBvb2xMUEFzc2V0QW10IhlpZHhGYWN0b3J5U3Rha2luZ0NvbnRyYWN0IhppZHhGYWN0b3J5U2xpcHBhZ2VDb250cmFjdCIFdG9YMTgiB29yaWdWYWwiDW9yaWdTY2FsZU11bHQiC3RvWDE4QmlnSW50Igdmcm9tWDE4IgN2YWwiD3Jlc3VsdFNjYWxlTXVsdCIMZnJvbVgxOFJvdW5kIgVyb3VuZCIHdG9TY2FsZSIDYW10IghyZXNTY2FsZSIIY3VyU2NhbGUiA2FicyIJYWJzQmlnSW50Igxzd2FwQ29udHJhY3QiAmZjIgNtcGsiBHBtcGsiAnBsIgJwaCIBaCIJdGltZXN0YW1wIgNwYXUiC3VzZXJBZGRyZXNzIgR0eElkIgNnYXUiAmFhIgJwYSIQa2V5RmFjdG9yeUNvbmZpZyINa2V5TWF0Y2hlclB1YiIpa2V5TWFwcGluZ1Bvb2xDb250cmFjdEFkZHJlc3NUb1Bvb2xBc3NldHMiE3Bvb2xDb250cmFjdEFkZHJlc3MiDWtleVBvb2xDb25maWciCWlBbXRBc3NldCILaVByaWNlQXNzZXQiH2tleU1hcHBpbmdzQmFzZUFzc2V0MmludGVybmFsSWQiDGJhc2VBc3NldFN0ciITa2V5QWxsUG9vbHNTaHV0ZG93biINa2V5UG9vbFdlaWdodCIPY29udHJhY3RBZGRyZXNzIhZrZXlBbGxvd2VkTHBTY3JpcHRIYXNoIhZrZXlGZWVDb2xsZWN0b3JBZGRyZXNzIg90aHJvd09yZGVyRXJyb3IiCm9yZGVyVmFsaWQiC3NlbmRlclZhbGlkIgxtYXRjaGVyVmFsaWQiD2dldFN0cmluZ09yRmFpbCIHYWRkcmVzcyIDa2V5IgxnZXRJbnRPckZhaWwiCHRocm93RXJyIgNtc2ciD2ZhY3RvcnlDb250cmFjdCITZmVlQ29sbGVjdG9yQWRkcmVzcyIFaW5GZWUiAUAiBm91dEZlZSIQaXNHbG9iYWxTaHV0ZG93biITZ2V0TWF0Y2hlclB1Yk9yRmFpbCINZ2V0UG9vbENvbmZpZyIIYW10QXNzZXQiCnByaWNlQXNzZXQiDHBhcnNlQXNzZXRJZCIFaW5wdXQiD2Fzc2V0SWRUb1N0cmluZyIPcGFyc2VQb29sQ29uZmlnIgpwb29sQ29uZmlnIhBwb29sQ29uZmlnUGFyc2VkIgskdDA3OTA2ODA3MiIOY2ZnUG9vbEFkZHJlc3MiDWNmZ1Bvb2xTdGF0dXMiDGNmZ0xwQXNzZXRJZCIQY2ZnQW1vdW50QXNzZXRJZCIPY2ZnUHJpY2VBc3NldElkIhZjZmdBbW91bnRBc3NldERlY2ltYWxzIhVjZmdQcmljZUFzc2V0RGVjaW1hbHMiEGdldEZhY3RvcnlDb25maWciD3N0YWtpbmdDb250cmFjdCIQc2xpcHBhZ2VDb250cmFjdCIRZGF0YVB1dEFjdGlvbkluZm8iDWluQW10QXNzZXRBbXQiD2luUHJpY2VBc3NldEFtdCIIb3V0THBBbXQiBXByaWNlIh1zbGlwcGFnZVRvbGVyYW5jZVBhc3NlZEJ5VXNlciIVc2xpcHBhZ2VUb2xlcmFuY2VSZWFsIgh0eEhlaWdodCILdHhUaW1lc3RhbXAiEnNsaXBhZ2VBbXRBc3NldEFtdCIUc2xpcGFnZVByaWNlQXNzZXRBbXQiEWRhdGFHZXRBY3Rpb25JbmZvIg5vdXRBbXRBc3NldEFtdCIQb3V0UHJpY2VBc3NldEFtdCIHaW5McEFtdCINZ2V0QWNjQmFsYW5jZSIHYXNzZXRJZCIPY2FsY1ByaWNlQmlnSW50IghwckFtdFgxOCIIYW1BbXRYMTgiEHByaXZhdGVDYWxjUHJpY2UiCmFtQXNzZXREY20iCnByQXNzZXREY20iBWFtQW10IgVwckFtdCIOYW10QXNzZXRBbXRYMTgiEHByaWNlQXNzZXRBbXRYMTgiCmNhbGNQcmljZXMiBWxwQW10IgNjZmciC2FtdEFzc2V0RGNtIg1wcmljZUFzc2V0RGNtIghwcmljZVgxOCIIbHBBbXRYMTgiE2xwUHJpY2VJbkFtQXNzZXRYMTgiE2xwUHJpY2VJblByQXNzZXRYMTgiD2NhbGN1bGF0ZVByaWNlcyIGcHJpY2VzIhRlc3RpbWF0ZUdldE9wZXJhdGlvbiIGdHhJZDU4IgpwbXRBc3NldElkIghwbXRMcEFtdCIJbHBBc3NldElkIglhbUFzc2V0SWQiCXByQXNzZXRJZCIKcG9vbFN0YXR1cyIKbHBFbWlzc2lvbiIJYW1CYWxhbmNlIgxhbUJhbGFuY2VYMTgiCXByQmFsYW5jZSIMcHJCYWxhbmNlWDE4IgtjdXJQcmljZVgxOCIIY3VyUHJpY2UiC3BtdExwQW10WDE4Ig1scEVtaXNzaW9uWDE4IgtvdXRBbUFtdFgxOCILb3V0UHJBbXRYMTgiCG91dEFtQW10IghvdXRQckFtdCIFc3RhdGUiFGVzdGltYXRlUHV0T3BlcmF0aW9uIhFzbGlwcGFnZVRvbGVyYW5jZSIMaW5BbUFzc2V0QW10IgtpbkFtQXNzZXRJZCIMaW5QckFzc2V0QW10IgtpblByQXNzZXRJZCIKaXNFdmFsdWF0ZSIGZW1pdExwIgxhbUFzc2V0SWRTdHIiDHByQXNzZXRJZFN0ciILaUFtdEFzc2V0SWQiDWlQcmljZUFzc2V0SWQiDmluQW1Bc3NldElkU3RyIg5pblByQXNzZXRJZFN0ciIPaW5BbUFzc2V0QW10WDE4Ig9pblByQXNzZXRBbXRYMTgiDHVzZXJQcmljZVgxOCIDcmVzIgtzbGlwcGFnZVgxOCIUc2xpcHBhZ2VUb2xlcmFuY2VYMTgiCnByVmlhQW1YMTgiCmFtVmlhUHJYMTgiDGV4cGVjdGVkQW10cyIRZXhwQW10QXNzZXRBbXRYMTgiE2V4cFByaWNlQXNzZXRBbXRYMTgiCWNhbGNMcEFtdCIOY2FsY0FtQXNzZXRQbXQiDmNhbGNQckFzc2V0UG10IgxzbGlwcGFnZUNhbGMiCWVtaXRMcEFtdCIGYW1EaWZmIgZwckRpZmYiC2NvbW1vblN0YXRlIht2YWxpZGF0ZU1hdGNoZXJPcmRlckFsbG93ZWQiBW9yZGVyIgphbXRBc3NldElkIgxwcmljZUFzc2V0SWQiEmFjY0FtdEFzc2V0QmFsYW5jZSIUYWNjUHJpY2VBc3NldEJhbGFuY2UiDW9yZGVyQW10QXNzZXQiEG9yZGVyQW10QXNzZXRTdHIiD29yZGVyUHJpY2VBc3NldCISb3JkZXJQcmljZUFzc2V0U3RyIgpvcmRlclByaWNlIghwcmljZURjbSIQY2FzdGVkT3JkZXJQcmljZSIRaXNPcmRlclByaWNlVmFsaWQiCWNvbW1vbkdldCIBaSIDcG10IgZwbXRBbXQiCWNvbW1vblB1dCIKYW1Bc3NldFBtdCIKcHJBc3NldFBtdCIGZXN0UHV0IgRlbWl0IgZhbW91bnQiB2VtaXRJbnYiDWVtaXRJbnZMZWdhY3kiByRtYXRjaDAiFWxlZ2FjeUZhY3RvcnlDb250cmFjdCIHdGFrZUZlZSIDZmVlIglmZWVBbW91bnQiD2NhbGNQdXRPbmVUb2tlbiIQcGF5bWVudEFtb3VudFJhdyIOcGF5bWVudEFzc2V0SWQiBmlzRXZhbCIQYW1vdW50QmFsYW5jZVJhdyIPcHJpY2VCYWxhbmNlUmF3IhRwYXltZW50SW5BbW91bnRBc3NldCINJHQwMjI5NjkyMzI2MiIQYW1vdW50QmFsYW5jZU9sZCIPcHJpY2VCYWxhbmNlT2xkIg0kdDAyMzI2NjIzNDE1IhRhbW91bnRBc3NldEFtb3VudFJhdyITcHJpY2VBc3NldEFtb3VudFJhdyIRYW1vdW50QXNzZXRBbW91bnQiEHByaWNlQXNzZXRBbW91bnQiDSR0MDIzNTQ3MjM2MTEiDXBheW1lbnRBbW91bnQiEGFtb3VudEJhbGFuY2VOZXciD3ByaWNlQmFsYW5jZU5ldyILcHJpY2VOZXdYMTgiCHByaWNlTmV3Ig5wYXltZW50QmFsYW5jZSIUcGF5bWVudEJhbGFuY2VCaWdJbnQiDHN1cHBseUJpZ0ludCILY2hlY2hTdXBwbHkiDWRlcG9zaXRCaWdJbnQiC2lzc3VlQW1vdW50IgtwcmljZU9sZFgxOCIIcHJpY2VPbGQiBGxvc3MiDSR0MDI1MDg4MjUyNTUiB2JhbGFuY2UiD2lzc3VlQW1vdW50Qm90aCIPY2FsY0dldE9uZVRva2VuIgpvdXRBc3NldElkIgZjaGVja3MiEG91dEluQW1vdW50QXNzZXQiDWJhbGFuY2VCaWdJbnQiDGFtQmFsYW5jZU9sZCIMcHJCYWxhbmNlT2xkIgpvdXRCYWxhbmNlIhBvdXRCYWxhbmNlQmlnSW50Ig5yZWRlZW1lZEJpZ0ludCIJYW1vdW50UmF3Ig0kdDAyNjgzNTI2ODkxIgt0b3RhbEFtb3VudCINJHQwMjY4OTUyNzEyMSILb3V0QW1BbW91bnQiC291dFByQW1vdW50IgxhbUJhbGFuY2VOZXciDHByQmFsYW5jZU5ldyIYYW1vdW50Qm90aEluUGF5bWVudEFzc2V0IhZtYW5hZ2VyUHVibGljS2V5T3JVbml0IgFzIh1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdCIJaXNNYW5hZ2VyIgJwayILbXVzdE1hbmFnZXIiAnBkIg1jbGVhbkFtb3VudEluIglpc1JldmVyc2UiDSR0MDI4Nzk4MjkxMDMiCGFzc2V0T3V0Igdhc3NldEluIhJwb29sQXNzZXRJbkJhbGFuY2UiE3Bvb2xBc3NldE91dEJhbGFuY2UiCWFtb3VudE91dCIMYW1vdW50T3V0TWluIglhZGRyZXNzVG8iBG9sZEsiBG5ld0siBmNoZWNrSyIIY2hlY2tNaW4iF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5IgtjaGVja0NhbGxlciIVY2hlY2tNYW5hZ2VyUHVibGljS2V5IgJwbSIFaGFzUE0iB2NoZWNrUE0iD3Nob3VsZEF1dG9TdGFrZSIEYW1JZCIEcHJJZCIMc2xpcHBhZ2VBSW52IgxzbGlwcGFnZVBJbnYiCmxwVHJhbnNmZXIiC3NscFN0YWtlSW52IgttYXhTbGlwcGFnZSIMbWluT3V0QW1vdW50IglhdXRvU3Rha2UiIGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkIg1pc1B1dERpc2FibGVkIgdwYXltZW50Ig0kdDAzNDIyODM0MzU4IgVib251cyITZW1pdEFtb3VudEVzdGltYXRlZCIKZW1pdEFtb3VudCIIc3Rha2VJbnYiB3NlbmRGZWUiDSR0MDM1MDg3MzUyMjIiDW91dEFzc2V0SWRTdHIiDWlzR2V0RGlzYWJsZWQiDSR0MDM2MDI3MzYxNjIiD2Ftb3VudEVzdGltYXRlZCIHYnVybkludiINYXNzZXRUcmFuc2ZlciINJHQwMzY3OTczNjkzNSINdW5zdGFrZUFtb3VudCIKdW5zdGFrZUludiINJHQwMzc3NjAzNzg5MyIJb3V0QW10QW10IhRidXJuTFBBc3NldE9uRmFjdG9yeSISbm9MZXNzVGhlbkFtdEFzc2V0IhRub0xlc3NUaGVuUHJpY2VBc3NldCINY2hlY2tQYXltZW50cyIPY2hlY2tQb29sU3RhdHVzIhVub0xlc3NUaGVuQW1vdW50QXNzZXQiDGNoZWNrQW1vdW50cyILYW10QXNzZXRTdHIiDXByaWNlQXNzZXRTdHIiDXBvb2xMUEJhbGFuY2UiCnByaWNlc0xpc3QiD2xwQW10QXNzZXRTaGFyZSIRbHBQcmljZUFzc2V0U2hhcmUiCnBvb2xXZWlnaHQiDGN1clByaWNlQ2FsYyIMYW1CYWxhbmNlUmF3IgxwckJhbGFuY2VSYXciD2FtQmFsYW5jZVJhd1gxOCIPcHJCYWxhbmNlUmF3WDE4IhBwYXltZW50THBBc3NldElkIgxwYXltZW50THBBbXQiAnR4IgZ2ZXJpZnkiD3RhcmdldFB1YmxpY0tleSIKbWF0Y2hlclB1YiIHbmV3SGFzaCILYWxsb3dlZEhhc2giC2N1cnJlbnRIYXNoZQABYQAIAAFiAIDC1y8AAWMJALYCAQCAwtcvAAFkCQC2AgEAgICQu7rWrfANAAFlCQC2AgEAAAABZgkAtgIBAAAAAWcJALYCAQABAAFoCQC2AgEAAgABaQIFV0FWRVMAAWoCAl9fAAFrAAEAAWwAAgABbQADAAFu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AmFLAAkA2QQBCQECYXkCBQJhRQkBAmFoAAECYUwABAJhTQkBAmF5AgUEdGhpcwkBAmFlAAQCYU4JAQJheQIFBHRoaXMJAQJhZgAEAmFtCQECYUICBQJhRQkBAmFuAQUCYU4EAmFsCQECYUICBQJhRQkBAmFuAQUCYU0JALUJAgkBAmF5AgUCYUUJAQJhawIJAKQDAQUCYWwJAKQDAQUCYW0FAWoBAmFPAQJhUAMJAAACBQJhUAUBaQUEdW5pdAkA2QQBBQJhUAECYVEBAmFQAwkAAAIFAmFQBQR1bml0BQFpCQDYBAEJAQV2YWx1ZQEFAmFQAQJhUgECYVMJAJkKBwkBEUBleHRyTmF0aXZlKDEwNjIpAQkAkQMCBQJhUwUBbwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmFTBQFwCQDZBAEJAJEDAgUCYVMFAXEJAQJhTwEJAJEDAgUCYVMFAXIJAQJhTwEJAJEDAgUCYVMFAXMJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJhUwUBdAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmFTBQF1AAJhVAkBAmFSAQkBAmFMAAACYVUFAmFUAAJhVggFAmFVAl8xAAJhVwgFAmFVAl8yAAJhWAgFAmFVAl8zAAJhWQgFAmFVAl80AAJhWggFAmFVAl81AAJiYQgFAmFVAl82AAJiYggFAmFVAl83AQJiYwAJALUJAgkBAmF5AgUCYUUJAQJhZwAFAWoAAmJkCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAKYIAQkAkQMCCQECYmMABQFCAhlpbmNvcnJlY3Qgc3Rha2luZyBhZGRyZXNzAAJiZQkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgkBAmJjAAUBQwIZaW5jb3JyZWN0IHN0YWtpbmcgYWRkcmVzcwECYmYKAmJnAmJoAmJpAmJqAmJrAmJsAmJtAmJuAmJvAmJwCQC5CQIJAMwIAgIUJWQlZCVkJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJiZwkAzAgCCQCkAwEFAmJoCQDMCAIJAKQDAQUCYmkJAMwIAgkApAMBBQJiagkAzAgCCQCkAwEFAmJrCQDMCAIJAKQDAQUCYmwJAMwIAgkApAMBBQJibQkAzAgCCQCkAwEFAmJuCQDMCAIJAKQDAQUCYm8JAMwIAgkApAMBBQJicAUDbmlsBQFqAQJicQYCYnICYnMCYnQCYmoCYm0CYm4JALkJAgkAzAgCAgwlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJicgkAzAgCCQCkAwEFAmJzCQDMCAIJAKQDAQUCYnQJAMwIAgkApAMBBQJiagkAzAgCCQCkAwEFAmJtCQDMCAIJAKQDAQUCYm4FA25pbAUBagECYnUBAmJ2AwkAAAIFAmJ2AgVXQVZFUwgJAO8HAQUEdGhpcwlhdmFpbGFibGUJAPAHAgUEdGhpcwkA2QQBBQJidgECYncCAmJ4AmJ5CQC8AgMFAmJ4BQFkBQJieQECYnoEAmJBAmJCAmJDAmJEBAJiRQkBAUQCBQJiQwUCYkEEAmJGCQEBRAIFAmJEBQJiQgkBAmJ3AgUCYkYFAmJFAQJiRwMCYkMCYkQCYkgEAmJJCQECYUwABAJiSgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF0BAJiSwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF1BAJiTAkBAmJ6BAUCYkoFAmJLBQJiQwUCYkQEAmJ5CQEBRAIFAmJDBQJiSgQCYngJAQFEAgUCYkQFAmJLBAJiTQkBAUQCBQJiSAUBYgQCYk4JAQJidwIFAmJ5BQJiTQQCYk8JAQJidwIFAmJ4BQJiTQkAzAgCBQJiTAkAzAgCBQJiTgkAzAgCBQJiTwUDbmlsAQJiUAMCYkMCYkQCYkgEAmJRCQECYkcDBQJiQwUCYkQFAmJICQDMCAIJAQFIAgkAkQMCBQJiUQAABQFiCQDMCAIJAQFIAgkAkQMCBQJiUQABBQFiCQDMCAIJAQFIAgkAkQMCBQJiUQACBQFiBQNuaWwBAmJSBAJiUwJiVAJiVQJhYgQCYkkJAQJhTAAEAmJWCQCRAwIFAmJJBQFxBAJiVwkAkQMCBQJiSQUBcgQCYlgJAJEDAgUCYkkFAXMEAmJBCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkkFAXQEAmJCCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkkFAXUEAmJZCQCRAwIFAmJJBQFwBAJiWggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFAmJWCQCsAgIJAKwCAgIGQXNzZXQgBQJiVgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkDCQECIT0CBQJiVgUCYlQJAAIBAhVJbnZhbGlkIGFzc2V0IHBhc3NlZC4EAmNhCQECYnUBBQJiVwQCY2IJAQFEAgUCY2EFAmJBBAJjYwkBAmJ1AQUCYlgEAmNkCQEBRAIFAmNjBQJiQgQCY2UJAQJidwIFAmNkBQJjYgQCY2YJAQFIAgUCY2UFAWIEAmNnCQEBRAIFAmJVBQFiBAJjaAkBAUQCBQJiWgUBYgQCY2kJALwCAwUCY2IFAmNnBQJjaAQCY2oJALwCAwUCY2QFAmNnBQJjaAQCY2sJAQFIAgUCY2kFAmJBBAJjbAkBAUgCBQJjagUCYkIEAmNtAwkAAAIFAmJTAgAFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhYgUCY2sDCQAAAgUCYlcCBVdBVkVTBQR1bml0CQDZBAEFAmJXCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFiBQJjbAMJAAACBQJiWAIFV0FWRVMFBHVuaXQJANkEAQUCYlgJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFkAgkApQgBBQJhYgUCYlMJAQJicQYFAmNrBQJjbAUCYlUFAmNmBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVwAFAmNmCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBWAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmNmBQNuaWwJAJwKCgUCY2sFAmNsBQJiVwUCYlgFAmNhBQJjYwUCYloFAmNlBQJiWQUCY20BAmNuCQJiUwJjbwJjcAJjcQJjcgJjcwJhYgJjdAJjdQQCYkkJAQJhTAAEAmJWCQDZBAEJAJEDAgUCYkkFAXEEAmN2CQCRAwIFAmJJBQFyBAJjdwkAkQMCBQJiSQUBcwQCY3gJAJEDAgUCYkkFAXYEAmN5CQCRAwIFAmJJBQF3BAJiSgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF0BAJiSwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF1BAJiWQkAkQMCBQJiSQUBcAQCYloICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYlYJAKwCAgkArAICAgZBc3NldCAJANgEAQUCYlYCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJjegkA2AQBCQELdmFsdWVPckVsc2UCBQJjcQkA2QQBAgVXQVZFUwQCY0EJANgEAQkBC3ZhbHVlT3JFbHNlAgUCY3MJANkEAQIFV0FWRVMDAwkBAiE9AgUCY3YFAmN6BgkBAiE9AgUCY3cFAmNBCQACAQIiSW52YWxpZCBhbXQgb3IgcHJpY2UgYXNzZXQgcGFzc2VkLgQCY2EDBQJjdAkBAmJ1AQUCY3YJAGUCCQECYnUBBQJjdgUCY3AEAmNjAwUCY3QJAQJidQEFAmN3CQBlAgkBAmJ1AQUCY3cFAmNyBAJjQgkBAUQCBQJjcAUCYkoEAmNDCQEBRAIFAmNyBQJiSwQCY0QJAQJidwIFAmNDBQJjQgQCY2IJAQFEAgUCY2EFAmJKBAJjZAkBAUQCBQJjYwUCYksEAmNFAwkAAAIFAmJaAAAEAmNlBQFlBAJjRgUBZQQCYk0JAHYGCQC5AgIFAmNCBQJjQwAACQC2AgEABQABAAAFBERPV04JAJcKBQkBAUgCBQJiTQUBYgkBAUgCBQJjQgUCYkoJAQFIAgUCY0MFAmJLCQECYncCCQC3AgIFAmNkBQJjQwkAtwICBQJjYgUCY0IFAmNGBAJjZQkBAmJ3AgUCY2QFAmNiBAJjRgkAvAIDCQEBUgEJALgCAgUCY2UFAmNEBQFkBQJjZQQCY0cJAQFEAgUCY28FAWIDAwkBAiE9AgUCY2UFAWUJAL8CAgUCY0YFAmNHBwkAAgEJAKwCAgkArAICCQCsAgICD1ByaWNlIHNsaXBwYWdlIAkApgMBBQJjRgIeIGV4Y2VlZGVkIHRoZSBwYXNzZWQgbGltaXQgb2YgCQCmAwEFAmNHBAJjaAkBAUQCBQJiWgUBYgQCY0gJALwCAwUCY0IFAmNlBQFkBAJjSQkAvAIDBQJjQwUBZAUCY2UEAmNKAwkAvwICBQJjSAUCY0MJAJQKAgUCY0kFAmNDCQCUCgIFAmNCBQJjSAQCY0sIBQJjSgJfMQQCY0wIBQJjSgJfMgQCYk0JALwCAwUCY2gFAmNMBQJjZAkAlwoFCQEBSAIFAmJNBQFiCQEBSAIFAmNLBQJiSgkBAUgCBQJjTAUCYksFAmNlBQJjRgQCY00IBQJjRQJfMQQCY04IBQJjRQJfMgQCY08IBQJjRQJfMwQCY2YJAQFIAggFAmNFAl80BQFiBAJjUAkBAUgCCAUCY0UCXzUFAWIDCQBnAgAABQJjTQkAAgECNkludmFsaWQgY2FsY3VsYXRpb25zLiBMUCBjYWxjdWxhdGVkIGlzIGxlc3MgdGhhbiB6ZXJvLgQCY1EDCQEBIQEFAmN1AAAFAmNNBAJjUgkAZQIFAmNwBQJjTgQCY1MJAGUCBQJjcgUCY08EAmNUCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVwAFAmNmCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBWAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmNmCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhYQIFAmFiBQJiUwkBAmJmCgUCY04FAmNPBQJjUQUCY2YFAmNvBQJjUAUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCY1IFAmNTBQNuaWwJAJ8KDQUCY00FAmNRBQJjZgUCY2EFAmNjBQJiWgUCYlYFAmJZBQJjVAUCY1IFAmNTBQJjcQUCY3MBAmNVAQJjVgQCYkkJAQJhTAAEAmNXCQCRAwIFAmJJBQFyBAJjWAkAkQMCBQJiSQUBcwQCYlkJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiSQUBcAQCYkoJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiSQUBdAQCYksJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiSQUBdQQCY1kJAQJidQEFAmNXBAJjWgkBAmJ1AQUCY1gEAmNlAwkAAAIIBQJjVglvcmRlclR5cGUFA0J1eQkBAmJ6BAUCYkoFAmJLCQBkAgUCY1kIBQJjVgZhbW91bnQFAmNaCQECYnoEBQJiSgUCYksJAGUCBQJjWQgFAmNWBmFtb3VudAUCY1oEAmNmCQEBSAIFAmNlBQFiAwMDCQECYUoABgkAAAIFAmJZBQFtBgkAAAIFAmJZBQFuCQACAQIcRXhjaGFuZ2Ugb3BlcmF0aW9ucyBkaXNhYmxlZAQCZGEICAUCY1YJYXNzZXRQYWlyC2Ftb3VudEFzc2V0BAJkYgMJAAACBQJkYQUEdW5pdAIFV0FWRVMJANgEAQkBBXZhbHVlAQUCZGEEAmRjCAgFAmNWCWFzc2V0UGFpcgpwcmljZUFzc2V0BAJkZAMJAAACBQJkYwUEdW5pdAIFV0FWRVMJANgEAQkBBXZhbHVlAQUCZGMDAwkBAiE9AgUCZGIFAmNXBgkBAiE9AgUCZGQFAmNYCQACAQITV3Jvbmcgb3JkZXIgYXNzZXRzLgQCZGUIBQJjVgVwcmljZQQCZGYJAGsDBQFiBQJiSwUCYkoEAmRnCQEBTQMFAmRlBQFiBQJkZgQCZGgDCQAAAggFAmNWCW9yZGVyVHlwZQUDQnV5CQBnAgUCY2YFAmRnCQBnAgUCZGcFAmNmBgECZGkBAmRqAwkBAiE9AgkAkAMBCAUCZGoIcGF5bWVudHMAAQkAAgECHWV4YWN0bHkgMSBwYXltZW50IGlzIGV4cGVjdGVkBAJkawkBBXZhbHVlAQkAkQMCCAUCZGoIcGF5bWVudHMAAAQCYlQJAQV2YWx1ZQEIBQJkawdhc3NldElkBAJkbAgFAmRrBmFtb3VudAQCY0UJAQJiUgQJANgEAQgFAmRqDXRyYW5zYWN0aW9uSWQJANgEAQUCYlQFAmRsCAUCZGoGY2FsbGVyBAJjawgFAmNFAl8xBAJjbAgFAmNFAl8yBAJiWQkBDXBhcnNlSW50VmFsdWUBCAUCY0UCXzkEAmNtCAUCY0UDXzEwAwMJAQJhSgAGCQAAAgUCYlkFAW4JAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmJZCQCXCgUFAmNrBQJjbAUCZGwFAmJUBQJjbQECZG0DAmRqAmNvAmN1AwkBAiE9AgkAkAMBCAUCZGoIcGF5bWVudHMAAgkAAgECH2V4YWN0bHkgMiBwYXltZW50cyBhcmUgZXhwZWN0ZWQEAmRuCQEFdmFsdWUBCQCRAwIIBQJkaghwYXltZW50cwAABAJkbwkBBXZhbHVlAQkAkQMCCAUCZGoIcGF5bWVudHMAAQQCZHAJAQJjbgkJANgEAQgFAmRqDXRyYW5zYWN0aW9uSWQFAmNvCAUCZG4GYW1vdW50CAUCZG4HYXNzZXRJZAgFAmRvBmFtb3VudAgFAmRvB2Fzc2V0SWQJAKUIAQgFAmRqBmNhbGxlcgcFAmN1BAJiWQkBDXBhcnNlSW50VmFsdWUBCAUCZHACXzgDAwMJAQJhSgAGCQAAAgUCYlkFAWwGCQAAAgUCYlkFAW4JAAIBCQCsAgICLFB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmJZBQJkcAECZHEBAmRyBAJkcwkA/AcEBQJhRQIEZW1pdAkAzAgCBQJkcgUDbmlsBQNuaWwDCQAAAgUCZHMFAmRzBAJkdAQCZHUFAmRzAwkAAQIFAmR1AgdBZGRyZXNzBAJkdgUCZHUJAPwHBAUCZHYCBGVtaXQJAMwIAgUCZHIFA25pbAUDbmlsBQR1bml0AwkAAAIFAmR0BQJkdAUCZHIJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmR3AgJkcgJkeAQCZHkDCQAAAgUCZHgAAAAACQBrAwUCZHIFAmR4BQFiCQCUCgIJAGUCBQJkcgUCZHkFAmR5AQJkegQCZEECZEICYWICYWMEAmRDCQAAAgUCYWMFBHVuaXQEAmRECQECYnUBCQECYVEBBQJhWQQCZEUJAQJidQEJAQJhUQEFAmFaBAJkRgMJAAACBQJkQgUCYVkGAwkAAAIFAmRCBQJhWgcJAQJhQwECDWludmFsaWQgYXNzZXQEAmRHAwUCZEMJAJQKAgUCZEQFAmRFAwUCZEYJAJQKAgkAZQIFAmREBQJkQQUCZEUJAJQKAgUCZEQJAGUCBQJkRQUCZEEEAmRICAUCZEcCXzEEAmRJCAUCZEcCXzIEAmRKAwUCZEYJAJQKAgUCZEEAAAkAlAoCAAAFAmRBBAJkSwgFAmRKAl8xBAJkTAgFAmRKAl8yBAJkTQgJAQJkdwIFAmRLBQJhRwJfMQQCZE4ICQECZHcCBQJkTAUCYUcCXzEEAmRPCQECZHcCBQJkQQUCYUcEAmRQCAUCZE8CXzEEAmR5CAUCZE8CXzIEAmRRCQBkAgUCZEgFAmRNBAJkUgkAZAIFAmRJBQJkTgQCZFMJAQJidwIJAQFEAgUCZFIFAmJiCQEBRAIFAmRRBQJiYQQCZFQJAQFIAgUCZFMFAWIEAmRVAwUCZEYFAmRIBQJkSQQCZFYJALYCAQUCZFUEAmRXCQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYVgJAKwCAgkArAICAgZhc3NldCAJANgEAQUCYVgCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJkWAMJAL8CAgUCZFcFAWYGCQECYUMBAiJpbml0aWFsIGRlcG9zaXQgcmVxdWlyZXMgYWxsIGNvaW5zAwkAAAIFAmRYBQJkWAQCZFkJALYCAQUCZFAEAmRaCQCWAwEJAMwIAgAACQDMCAIJAKADAQkAugICCQC5AgIFAmRXCQC4AgIJAQpzcXJ0QmlnSW50BAkAtwICBQFkCQC6AgIJALkCAgUCZFkFAWQFAmRWABIAEgUERE9XTgUBZAUBZAUDbmlsBAJjVAMFAmRDBQNuaWwJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZFQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZFQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFhAgkApQgBCQEFdmFsdWUBBQJhYgkA2AQBCQEFdmFsdWUBBQJhYwkBAmJmCgUCZEsFAmRMBQJkWgUCZFQAAAAABQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wAAAAAAUDbmlsBAJlYQkBAmJ3AgkBAUQCBQJkSQUCYmIJAQFEAgUCZEgFAmJhBAJlYgkBAUgCBQJlYQUBYgQCZWMEAmVkAwUCZEYJAJQKAgUCZEsFAmRICQCUCgIFAmRMBQJkSQQCZHIIBQJlZAJfMQQCZWUIBQJlZAJfMgQCZWYJAKADAQkAvAIDBQJkVwkAtgIBCQBpAgUCZHIAAgkAtgIBBQJlZQkAawMJAGUCBQJkWgUCZWYFAWIFAmVmCQCWCgQFAmRaBQJjVAUCZHkFAmVjCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJlZwUCZWgCZFACZEICYWICYWMEAmRDCQAAAgUCYWMFBHVuaXQEAmVpCQDMCAIDCQAAAgUCZEIFAmFYBgkBAmFDAQIQaW52YWxpZCBscCBhc3NldAUDbmlsAwkAAAIFAmVpBQJlaQQCZWoDCQAAAgUCZWgFAmFZBgMJAAACBQJlaAUCYVoHCQECYUMBAg1pbnZhbGlkIGFzc2V0BAJlawMFAmVqCQC2AgEJAQJidQEJAQJhUQEFAmFZCQC2AgEJAQJidQEJAQJhUQEFAmFaBAJlbAkBAmJ1AQkBAmFRAQUCYVkEAmVtCQECYnUBCQECYVEBBQJhWgQCZW4DBQJlagUCZWwFAmVtBAJlbwkAtgIBBQJlbgQCZFcJALYCAQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJhWAkArAICCQCsAgICBmFzc2V0IAkA2AQBBQJhWAIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmVwCQC2AgEFAmRQBAJlcQkAlgMBCQDMCAIAAAkAzAgCCQCgAwEJALoCAgkAuQICBQJlawkAuAICBQFkCQB2BgkAuAICBQFkCQC6AgIJALkCAgUCZXAFAWQFAmRXABIFAWgAAAASBQRET1dOBQFkBQNuaWwEAmVyCQECZHcCBQJlcQUCYUkEAmVzCAUCZXICXzEEAmR5CAUCZXICXzIEAmV0AwUCZWoJAJYKBAUCZXMAAAkAZQIFAmVsBQJlcQUCZW0JAJYKBAAABQJlcwUCZWwJAGUCBQJlbQUCZXEEAmV1CAUCZXQCXzEEAmV2CAUCZXQCXzIEAmV3CAUCZXQCXzMEAmV4CAUCZXQCXzQEAmRTCQECYncCCQEBRAIFAmV4BQJiYgkBAUQCBQJldwUCYmEEAmRUCQEBSAIFAmRTBQFiBAJjVAMFAmRDBQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAmFkAgkApQgBCQEFdmFsdWUBBQJhYgkA2AQBCQEFdmFsdWUBBQJhYwkBAmJxBgUCZXUFAmV2BQJkUAUCZFQFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFXAAUCZFQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFYAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZFQFA25pbAQCZWEJAQJidwIJAQFEAgUCZW0FAmJiCQEBRAIFAmVsBQJiYQQCZWIJAQFIAgUCZWEFAWIEAmVjBAJleQkAaAIJAKADAQkAvAIDBQJlawUCZXAFAmRXAAIJAGsDCQBlAgUCZXMFAmV5BQFiBQJleQkAlgoEBQJlcwUCY1QFAmR5BQJlYwkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZXoABAJkdQkAoggBCQEBVQADCQABAgUCZHUCBlN0cmluZwQCZUEFAmR1CQDZBAEFAmVBAwkAAQIFAmR1AgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IBAmVCAAQCZHUJAKIIAQkBAVYAAwkAAQIFAmR1AgZTdHJpbmcEAmVBBQJkdQkA2QQBBQJlQQMJAAECBQJkdQIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJlQwECZGoEAmR1CQECZXoAAwkAAQIFAmR1AgpCeXRlVmVjdG9yBAJlRAUCZHUJAAACCAUCZGoPY2FsbGVyUHVibGljS2V5BQJlRAMJAAECBQJkdQIEVW5pdAkAAAIIBQJkagZjYWxsZXIFBHRoaXMJAAIBAgtNYXRjaCBlcnJvcgECZUUBAmRqBAJlRgkAAgECEVBlcm1pc3Npb24gZGVuaWVkBAJkdQkBAmV6AAMJAAECBQJkdQIKQnl0ZVZlY3RvcgQCZUQFAmR1AwkAAAIIBQJkag9jYWxsZXJQdWJsaWNLZXkFAmVEBgUCZUYDCQABAgUCZHUCBFVuaXQDCQAAAggFAmRqBmNhbGxlcgUEdGhpcwYFAmVGCQACAQILTWF0Y2ggZXJyb3IcAmRqASFjYWxjdWxhdGVBbW91bnRPdXRGb3JTd2FwUkVBRE9OTFkCAmVHAmVIBAJlSQMJAAACBQJlSAcEAmVKCQECYXkCBQR0aGlzCQECYWYABAJlSwkBAmF5AgUEdGhpcwkBAmFlAAkAlAoCBQJlSgUCZUsEAmVKCQECYXkCBQR0aGlzCQECYWUABAJlSwkBAmF5AgUEdGhpcwkBAmFmAAkAlAoCBQJlSgUCZUsEAmVKCAUCZUkCXzEEAmVLCAUCZUkCXzIEAmVMCQECYnUBBQJlSwQCZU0JAQJidQEFAmVKBAJlTgkAaQIJAGgCBQJlTQUCZUcJAGQCBQJlTAUCZUcJAJQKAgUDbmlsBQJlTgJkagEmY2FsY3VsYXRlQW1vdW50T3V0Rm9yU3dhcEFuZFNlbmRUb2tlbnMEAmVHAmVIAmVPAmVQBAJlaQkAzAgCAwkAZwIICQEFdmFsdWUBCQCRAwIIBQJkaghwYXltZW50cwAABmFtb3VudAUCZUcGCQECYUMBAgxXcm9uZyBhbW91bnQJAMwIAgMJAAACCAUCZGoGY2FsbGVyCQERQGV4dHJOYXRpdmUoMTA2MikBCQECYXkCBQR0aGlzCQEBUwAGCQECYUMBAhFQZXJtaXNzaW9uIGRlbmllZAUDbmlsAwkAAAIFAmVpBQJlaQQCZGsJAQV2YWx1ZQEJAJEDAggFAmRqCHBheW1lbnRzAAAEAmVLAwkAAAIIBQJkawdhc3NldElkBQR1bml0CQDYBAEJAJsDAQIFV0FWRVMJANgEAQkBBXZhbHVlAQgFAmRrB2Fzc2V0SWQEAmVKAwkAAAIFAmVIBwkBAmF5AgUEdGhpcwkBAmFmAAkBAmF5AgUEdGhpcwkBAmFlAAQCZUwJAGUCCQECYnUBBQJlSwgJAQV2YWx1ZQEJAJEDAggFAmRqCHBheW1lbnRzAAAGYW1vdW50BAJlTQkBAmJ1AQUCZUoEAmVOCQBpAgkAaAIFAmVNBQJlRwkAZAIFAmVMBQJlRwQCZVEJAGgCBQJlTAUCZU0EAmVSCQBoAgkBAmJ1AQUCZUsJAGUCCQECYnUBBQJlSgUCZU4EAmVTAwkAZwIFAmVSBQJlUQYJAAIBAhRuZXcgSyBpcyBmZXdlciBlcnJvcgMJAAACBQJlUwUCZVMEAmVUAwkAZwIFAmVOBQJlTwYJAAIBAixFeGNoYW5nZSByZXN1bHQgaXMgZmV3ZXIgY29pbnMgdGhhbiBleHBlY3RlZAMJAAACBQJlVAUCZVQJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwkBEUBleHRyTmF0aXZlKDEwNjIpAQUCZVAFAmVOAwkAAAIFAmVLAgVXQVZFUwUEdW5pdAkA2QQBBQJlSgUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRqAQpzZXRNYW5hZ2VyAQJlVQQCZVYJAQJlRQEFAmRqAwkAAAIFAmVWBQJlVgQCZVcJANkEAQUCZVUDCQAAAgUCZVcFAmVXCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFWAAUCZVUFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkagEOY29uZmlybU1hbmFnZXIABAJlWAkBAmVCAAQCZVkDCQEJaXNEZWZpbmVkAQUCZVgGCQACAQISTm8gcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmVZBQJlWQQCZVoDCQAAAggFAmRqD2NhbGxlclB1YmxpY0tleQkBBXZhbHVlAQUCZVgGCQACAQIbWW91IGFyZSBub3QgcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmVaBQJlWgkAzAgCCQELU3RyaW5nRW50cnkCCQEBVQAJANgEAQkBBXZhbHVlAQUCZVgJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAVYABQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGoBA3B1dAICY28CZmEDCQBmAgAABQJjbwkAAgECIEludmFsaWQgc2xpcHBhZ2VUb2xlcmFuY2UgcGFzc2VkBAJkcAkBAmRtAwUCZGoFAmNvBgQCY1EIBQJkcAJfMgQCYlYIBQJkcAJfNwQCY20IBQJkcAJfOQQCY1IIBQJkcANfMTAEAmNTCAUCZHADXzExBAJmYggFAmRwA18xMgQCZmMIBQJkcANfMTMEAmRzCQD8BwQFAmFFAgRlbWl0CQDMCAIFAmNRBQNuaWwFA25pbAMJAAACBQJkcwUCZHMEAmR0BAJkdQUCZHMDCQABAgUCZHUCB0FkZHJlc3MEAmR2BQJkdQkA/AcEBQJkdgIEZW1pdAkAzAgCBQJjUQUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZHQFAmR0BAJmZAMJAGYCBQJjUgAACQD8BwQFAmJlAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZmIFAmNSBQNuaWwFA25pbAMJAAACBQJmZAUCZmQEAmZlAwkAZgIFAmNTAAAJAPwHBAUCYmUCA3B1dAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJmYwUCY1MFA25pbAUDbmlsAwkAAAIFAmZlBQJmZQQCZmYDBQJmYQQCZmcJAPwHBAUCYmQCBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJWBQJjUQUDbmlsAwkAAAIFAmZnBQJmZwUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJkagZjYWxsZXIFAmNRBQJiVgUDbmlsCQDOCAIFAmNtBQJmZgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkagEKcHV0Rm9yRnJlZQECZmgDCQBmAgAABQJmaAkAAgECFEludmFsaWQgdmFsdWUgcGFzc2VkBAJkcAkBAmRtAwUCZGoFAmZoBwgFAmRwAl85AmRqAQlwdXRPbmVUa24CAmZpAmZqBAJmawoAAmFICQD8BwQFAmFFAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCYUgCB0Jvb2xlYW4FAmFICQACAQkArAICCQADAQUCYUgCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmZsAwMDCQECYUoABgkAAAIFAmFXBQFsBgkAAAIFAmFXBQFuBgUCZmsEAmVpCQDMCAIDAwkBASEBBQJmbAYJAQJlQwEFAmRqBgkBAmFDAQIhcHV0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCZGoIcGF5bWVudHMAAQYJAQJhQwECHmV4YWN0bHkgMSBwYXltZW50IGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmVpBQJlaQQCZm0JAJEDAggFAmRqCHBheW1lbnRzAAAEAmRCCAUCZm0HYXNzZXRJZAQCZEEIBQJmbQZhbW91bnQEAmFiCAUCZGoGY2FsbGVyBAJhYwgFAmRqDXRyYW5zYWN0aW9uSWQEAmZuCQECZHoEBQJkQQUCZEIFAmFiBQJhYwMJAAACBQJmbgUCZm4EAmZvCAUCZm4CXzQEAmR5CAUCZm4CXzMEAmNUCAUCZm4CXzIEAmZwCAUCZm4CXzEEAmZxAwMJAGYCBQJmaQAACQBmAgUCZmkFAmZwBwkBAmFDAQkAuQkCCQDMCAICH2Ftb3VudCB0byByZWNlaXZlIGlzIGxlc3MgdGhhbiAJAMwIAgkApAMBBQJmaQUDbmlsAgAFAmZwBAJkcwkBAmRxAQUCZnEDCQAAAgUCZHMFAmRzBAJmZgMFAmZqBAJmcgkA/AcEBQJiZAIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYVgFAmZxBQNuaWwDCQAAAgUCZnIFAmZyBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmRqBmNhbGxlcgUCZnEFAmFYBQNuaWwEAmZzAwkAZgIFAmR5AAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYUYFAmR5BQJkQgUDbmlsBQNuaWwJAJQKAgkAzggCCQDOCAIFAmNUBQJmZgUCZnMFAmZxCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRqARFwdXRPbmVUa25SRUFET05MWQICZEICZEEEAmZ0CQECZHoEBQJkQQkBAmFPAQUCZEIFBHVuaXQFBHVuaXQEAmZwCAUCZnQCXzEEAmNUCAUCZnQCXzIEAmR5CAUCZnQCXzMEAmZvCAUCZnQCXzQJAJQKAgUDbmlsCQCVCgMFAmZwBQJkeQUCZm8CZGoBCWdldE9uZVRrbgICZnUCZmkEAmZrCgACYUgJAPwHBAUCYUUCKGlzUG9vbE9uZVRva2VuT3BlcmF0aW9uc0Rpc2FibGVkUkVBRE9OTFkJAMwIAgkApQgBBQR0aGlzBQNuaWwFA25pbAMJAAECBQJhSAIHQm9vbGVhbgUCYUgJAAIBCQCsAgIJAAMBBQJhSAIcIGNvdWxkbid0IGJlIGNhc3QgdG8gQm9vbGVhbgQCZnYDAwkBAmFKAAYJAAACBQJhVwUBbgYFAmZrBAJlaQkAzAgCAwMJAQEhAQUCZnYGCQECZUMBBQJkagYJAQJhQwECIWdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmRqCHBheW1lbnRzAAEGCQECYUMBAh5leGFjdGx5IDEgcGF5bWVudCBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJlaQUCZWkEAmVoCQECYU8BBQJmdQQCZm0JAJEDAggFAmRqCHBheW1lbnRzAAAEAmRCCAUCZm0HYXNzZXRJZAQCZFAIBQJmbQZhbW91bnQEAmFiCAUCZGoGY2FsbGVyBAJhYwgFAmRqDXRyYW5zYWN0aW9uSWQEAmZ3CQECZWcFBQJlaAUCZFAFAmRCBQJhYgUCYWMDCQAAAgUCZncFAmZ3BAJmbwgFAmZ3Al80BAJkeQgFAmZ3Al8zBAJjVAgFAmZ3Al8yBAJmeAgFAmZ3Al8xBAJkcgMDCQBmAgUCZmkAAAkAZgIFAmZpBQJmeAcJAQJhQwEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZmkFA25pbAIABQJmeAQCZnkJAPwHBAUCYUUCBGJ1cm4JAMwIAgUCZFAFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZEIFAmRQBQNuaWwDCQAAAgUCZnkFAmZ5BAJmegkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhYgUCZHIFAmVoBQNuaWwEAmZzAwkAZgIFAmR5AAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYUYFAmR5BQJlaAUDbmlsBQNuaWwJAJQKAgkAzggCCQDOCAIFAmNUBQJmegUCZnMFAmRyCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRqARFnZXRPbmVUa25SRUFET05MWQICZWgCZFAEAmZBCQECZWcFCQECYU8BBQJlaAUCZFAFAmFYBQR1bml0BQR1bml0BAJmeAgFAmZBAl8xBAJjVAgFAmZBAl8yBAJkeQgFAmZBAl8zBAJmbwgFAmZBAl80CQCUCgIFA25pbAkAlQoDBQJmeAUCZHkFAmZvAmRqARN1bnN0YWtlQW5kR2V0T25lVGtuAwJmQgJmdQJmaQQCZmsKAAJhSAkA/AcEBQJhRQIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmFIAgdCb29sZWFuBQJhSAkAAgEJAKwCAgkAAwEFAmFIAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJmdgMDCQECYUoABgkAAAIFAmFXBQFuBgUCZmsEAmVpCQDMCAIDAwkBASEBBQJmdgYJAQJlQwEFAmRqBgkBAmFDAQIhZ2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCZGoIcGF5bWVudHMAAAYJAQJhQwECGG5vIHBheW1lbnRzIGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmVpBQJlaQQCZWgJAQJhTwEFAmZ1BAJhYggFAmRqBmNhbGxlcgQCYWMIBQJkag10cmFuc2FjdGlvbklkBAJmQwkA/AcEBQJiZAIHdW5zdGFrZQkAzAgCCQDYBAEFAmFYCQDMCAIFAmZCBQNuaWwFA25pbAMJAAACBQJmQwUCZkMEAmZECQECZWcFBQJlaAUCZkIFAmFYBQJhYgUCYWMDCQAAAgUCZkQFAmZEBAJmbwgFAmZEAl80BAJkeQgFAmZEAl8zBAJjVAgFAmZEAl8yBAJmeAgFAmZEAl8xBAJkcgMDCQBmAgUCZmkAAAkAZgIFAmZpBQJmeAcJAQJhQwEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZmkFA25pbAIABQJmeAQCZnkJAPwHBAUCYUUCBGJ1cm4JAMwIAgUCZkIFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYVgFAmZCBQNuaWwDCQAAAgUCZnkFAmZ5BAJmegkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZGoGY2FsbGVyBQJkcgUCZWgFA25pbAQCZnMDCQBmAgUCZHkAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhRgUCZHkFAmVoBQNuaWwFA25pbAkAlAoCCQDOCAIJAM4IAgUCY1QFAmZ6BQJmcwUCZHIJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGoBA2dldAAEAmNFCQECZGkBBQJkagQCZkUIBQJjRQJfMQQCY2wIBQJjRQJfMgQCZGwIBQJjRQJfMwQCYlQIBQJjRQJfNAQCY20IBQJjRQJfNQQCZkYJAPwHBAUCYUUCBGJ1cm4JAMwIAgUCZGwFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYlQFAmRsBQNuaWwDCQAAAgUCZkYFAmZGBQJjbQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkagEJZ2V0Tm9MZXNzAgJmRwJmSAQCY0UJAQJkaQEFAmRqBAJjawgFAmNFAl8xBAJjbAgFAmNFAl8yBAJkbAgFAmNFAl8zBAJiVAgFAmNFAl80BAJjbQgFAmNFAl81AwkAZgIFAmZHBQJjawkAAgEJAKwCAgkArAICCQCsAgICHG5vTGVzc1RoZW5BbXRBc3NldCBmYWlsZWQ6ICAJAKQDAQUCY2sCAyA8IAkApAMBBQJmRwMJAGYCBQJmSAUCY2wJAAIBCQCsAgIJAKwCAgkArAICAh1ub0xlc3NUaGVuUHJpY2VBc3NldCBmYWlsZWQ6IAkApAMBBQJjbAIDIDwgCQCkAwEFAmZIBAJmRgkA/AcEBQJhRQIEYnVybgkAzAgCBQJkbAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiVAUCZGwFA25pbAMJAAACBQJmRgUCZkYFAmNtCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYu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YnUBBQJjWAQCZlADCQAAAgUCZk8AAAkAzAgCBQFlCQDMCAIFAWUJAMwIAgUBZQUDbmlsCQECYkcDBQJjWQUCY1oFAmZPBAJjZgAABAJmUQkBAUgCCQCRAwIFAmZQAAEFAWIEAmZSCQEBSAIJAJEDAgUCZlAAAgUBYgQCZlMJAQV2YWx1ZQEJAJoIAgUCYUUJAQJhcQEJAKUIAQUEdGhpcwkAlAoCBQNuaWwJALkJAgkAzAgCAg4lZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmNZCQDMCAIJAKQDAQUCY1oJAMwIAgkApAMBBQJmTwkAzAgCCQCkAwEFAmNmCQDMCAIJAKQDAQUCZlEJAMwIAgkApAMBBQJmUgkAzAgCCQCkAwEFAmZTBQNuaWwFAWoCZGoBIGV2YWx1YXRlUHV0QnlBbW91bnRBc3NldFJFQURPTkxZAQJjcAQCYkkJAQJhTAAEAmJWCQDZBAEJAJEDAgUCYkkFAXEEAmN2CQCRAwIFAmJJBQFyBAJiVwkA2QQBBQJjdgQCY3cJAJEDAgUCYkkFAXMEAmJYCQDZBAEFAmN3BAJiSgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF0BAJiSwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF1BAJiWQkAkQMCBQJiSQUBcAQCZk8ICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYlYJAKwCAgkArAICAgZBc3NldCAJANgEAQUCYlYCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJjWQkBAmJ1AQUCY3YEAmNaCQECYnUBBQJjdwQCYkUJAQFEAgUCY1kFAmJKBAJiRgkBAUQCBQJjWgUCYksEAmNlAwkAAAIFAmZPAAAFAWUJAQJidwIFAmJGBQJiRQQCY0IJAQFEAgUCY3AFAmJKBAJjQwkAvAIDBQJjQgUCY2UFAWQEAmNyCQEBSAIFAmNDBQJiSwQCZHAJAQJjbgkCAACgwh4FAmNwBQJiVwUCY3IFAmJYAgAGBwQCY00IBQJkcAJfMQQCZlQIBQJkcAJfMwQCY2EIBQJkcAJfNAQCY2MIBQJkcAJfNQQCYloIBQJkcAJfNgkAlAoCBQNuaWwJALkJAgkAzAgCAhAlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCY00JAMwIAgkApAMBCQEBSAIFAmNlBQFiCQDMCAIJAKQDAQUCY2EJAMwIAgkApAMBBQJjYwkAzAgCCQCkAwEFAmJaCQDMCAIFAmJZCQDMCAIJAKQDAQUCY3AJAMwIAgkApAMBBQJjcgUDbmlsBQFqAmRqAR9ldmFsdWF0ZVB1dEJ5UHJpY2VBc3NldFJFQURPTkxZAQJjcgQCYkkJAQJhTAAEAmJWCQDZBAEJAJEDAgUCYkkFAXEEAmN2CQCRAwIFAmJJBQFyBAJiVwkA2QQBBQJjdgQCY3cJAJEDAgUCYkkFAXMEAmJYCQDZBAEFAmN3BAJiSgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF0BAJiSwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJJBQF1BAJiWQkAkQMCBQJiSQUBcAQCZk8ICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYlYJAKwCAgkArAICAgZBc3NldCAJANgEAQUCYlYCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJmVQkBAmJ1AQUCY3YEAmZWCQECYnUBBQJjdwQCZlcJAQFEAgUCZlUFAmJKBAJmWAkBAUQCBQJmVgUCYksEAmNlAwkAAAIFAmZPAAAFAWUJAQJidwIFAmZYBQJmVwQCY0MJAQFEAgUCY3IFAmJLBAJjQgkAvAIDBQJjQwUBZAUCY2UEAmNwCQEBSAIFAmNCBQJiSgQCZHAJAQJjbgkCAACgwh4FAmNwBQJiVwUCY3IFAmJYAgAGBwQCY00IBQJkcAJfMQQCZlQIBQJkcAJfMwQCY2EIBQJkcAJfNAQCY2MIBQJkcAJfNQQCYloIBQJkcAJfNgkAlAoCBQNuaWwJALkJAgkAzAgCAhAlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCY00JAMwIAgkApAMBCQEBSAIFAmNlBQFiCQDMCAIJAKQDAQUCY2EJAMwIAgkApAMBBQJjYwkAzAgCCQCkAwEFAmJaCQDMCAIFAmJZCQDMCAIJAKQDAQUCY3AJAMwIAgkApAMBBQJjcgUDbmlsBQFqAmRqARNldmFsdWF0ZUdldFJFQURPTkxZAgJmWQJmWgQCY0UJAQJiUgQCAAUCZlkFAmZaBQR0aGlzBAJjawgFAmNFAl8xBAJjbAgFAmNFAl8yBAJjYQgFAmNFAl81BAJjYwgFAmNFAl82BAJiWggFAmNFAl83BAJjZggFAmNFAl84BAJiWQkBDXBhcnNlSW50VmFsdWUBCAUCY0UCXzkJAJQKAgUDbmlsCQC5CQIJAMwIAgIOJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJjawkAzAgCCQCkAwEFAmNsCQDMCAIJAKQDAQUCY2EJAMwIAgkApAMBBQJjYwkAzAgCCQCkAwEFAmJaCQDMCAIJAKYDAQUCY2YJAMwIAgkApAMBBQJiWQUDbmlsBQFqAQJnYQECZ2IABAJnYwQCZHUJAQJlegADCQABAgUCZHUCCkJ5dGVWZWN0b3IEAmVEBQJkdQUCZUQDCQABAgUCZHUCBFVuaXQIBQJnYQ9zZW5kZXJQdWJsaWNLZXkJAAIBAgtNYXRjaCBlcnJvcgQCZHUFAmdhAwkAAQIFAmR1AgVPcmRlcgQCY1YFAmR1BAJnZAkBAmFLAAQCYXYJAQJjVQEFAmNWBAJhdwkA9AMDCAUCY1YJYm9keUJ5dGVzCQCRAwIIBQJjVgZwcm9vZnMAAAgFAmNWD3NlbmRlclB1YmxpY0tleQQCYXgJAPQDAwgFAmNWCWJvZHlCeXRlcwkAkQMCCAUCY1YGcHJvb2ZzAAEFAmdkAwMDBQJhdgUCYXcHBQJheAcGCQECYXUDBQJhdgUCYXcFAmF4AwkAAQIFAmR1AhRTZXRTY3JpcHRUcmFuc2FjdGlvbgQCZUEFAmR1BAJnZQkA9gMBCQEFdmFsdWUBCAUCZUEGc2NyaXB0BAJnZgkA2wQBCQEFdmFsdWUBCQCdCAIFAmFFCQECYXMABAJnZwkA8QcBBQR0aGlzAwMJAAACBQJnZgUCZ2UJAQIhPQIFAmdnBQJnZQcGCQD0AwMIBQJnYQlib2R5Qnl0ZXMJAJEDAggFAmdhBnByb29mcwAABQJnYwkA9AMDCAUCZ2EJYm9keUJ5dGVzCQCRAwIIBQJnYQZwcm9vZnMAAAUCZ2PUbsUV", "chainId": 84, "height": 2441743, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: AoUQLUXDWbVcrXaoBsQpCLjcXzZezF6zdPGvW42fuDSW Next: 9x6RhetEx42z9WahwdXiARSRpDYSyQqdWu9RDXVptvLE Diff:
OldNewDifferences
662662 let poolAssetInBalance = getAccBalance(assetIn)
663663 let poolAssetOutBalance = getAccBalance(assetOut)
664664 let amountOut = ((poolAssetOutBalance * cleanAmountIn) / (poolAssetInBalance + cleanAmountIn))
665- let oldK = (poolAssetInBalance * poolAssetOutBalance)
666- let newK = ((getAccBalance(assetIn) + cleanAmountIn) * (getAccBalance(assetOut) - amountOut))
667- let checkK = if ((newK >= oldK))
668- then true
669- else throw("new K is fewer error")
670- if ((checkK == checkK))
671- then $Tuple2(nil, amountOut)
672- else throw("Strict value is not equal to itself.")
665+ $Tuple2(nil, amountOut)
673666 }
674667
675668
844837 let paymentAmountRaw = payment.amount
845838 let userAddress = i.caller
846839 let txId = i.transactionId
847- let $t03422234352 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
848- if (($t03422234352 == $t03422234352))
840+ let $t03422834358 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
841+ if (($t03422834358 == $t03422834358))
849842 then {
850- let bonus = $t03422234352._4
851- let feeAmount = $t03422234352._3
852- let commonState = $t03422234352._2
853- let emitAmountEstimated = $t03422234352._1
843+ let bonus = $t03422834358._4
844+ let feeAmount = $t03422834358._3
845+ let commonState = $t03422834358._2
846+ let emitAmountEstimated = $t03422834358._1
854847 let emitAmount = if (if ((minOutAmount > 0))
855848 then (minOutAmount > emitAmountEstimated)
856849 else false)
883876
884877 @Callable(i)
885878 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
886- let $t03508135216 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
887- let emitAmountEstimated = $t03508135216._1
888- let commonState = $t03508135216._2
889- let feeAmount = $t03508135216._3
890- let bonus = $t03508135216._4
879+ let $t03508735222 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
880+ let emitAmountEstimated = $t03508735222._1
881+ let commonState = $t03508735222._2
882+ let feeAmount = $t03508735222._3
883+ let bonus = $t03508735222._4
891884 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
892885 }
893886
921914 let paymentAmount = payment.amount
922915 let userAddress = i.caller
923916 let txId = i.transactionId
924- let $t03602136156 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
925- if (($t03602136156 == $t03602136156))
917+ let $t03602736162 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
918+ if (($t03602736162 == $t03602736162))
926919 then {
927- let bonus = $t03602136156._4
928- let feeAmount = $t03602136156._3
929- let commonState = $t03602136156._2
930- let amountEstimated = $t03602136156._1
920+ let bonus = $t03602736162._4
921+ let feeAmount = $t03602736162._3
922+ let commonState = $t03602736162._2
923+ let amountEstimated = $t03602736162._1
931924 let amount = if (if ((minOutAmount > 0))
932925 then (minOutAmount > amountEstimated)
933926 else false)
953946
954947 @Callable(i)
955948 func getOneTknREADONLY (outAssetId,paymentAmount) = {
956- let $t03679136929 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
957- let amountEstimated = $t03679136929._1
958- let commonState = $t03679136929._2
959- let feeAmount = $t03679136929._3
960- let bonus = $t03679136929._4
949+ let $t03679736935 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
950+ let amountEstimated = $t03679736935._1
951+ let commonState = $t03679736935._2
952+ let feeAmount = $t03679736935._3
953+ let bonus = $t03679736935._4
961954 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
962955 }
963956
991984 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
992985 if ((unstakeInv == unstakeInv))
993986 then {
994- let $t03775437887 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
995- if (($t03775437887 == $t03775437887))
987+ let $t03776037893 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
988+ if (($t03776037893 == $t03776037893))
996989 then {
997- let bonus = $t03775437887._4
998- let feeAmount = $t03775437887._3
999- let commonState = $t03775437887._2
1000- let amountEstimated = $t03775437887._1
990+ let bonus = $t03776037893._4
991+ let feeAmount = $t03776037893._3
992+ let commonState = $t03776037893._2
993+ let amountEstimated = $t03776037893._1
1001994 let amount = if (if ((minOutAmount > 0))
1002995 then (minOutAmount > amountEstimated)
1003996 else false)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let lPdecimals = 8
55
66 let scale8 = 100000000
77
88 let scale8BigInt = toBigInt(100000000)
99
1010 let scale18 = toBigInt(1000000000000000000)
1111
1212 let zeroBigInt = toBigInt(0)
1313
1414 let big0 = toBigInt(0)
1515
1616 let big1 = toBigInt(1)
1717
1818 let big2 = toBigInt(2)
1919
2020 let wavesString = "WAVES"
2121
2222 let SEP = "__"
2323
2424 let PoolActive = 1
2525
2626 let PoolPutDisabled = 2
2727
2828 let PoolMatcherDisabled = 3
2929
3030 let PoolShutdown = 4
3131
3232 let idxPoolAddress = 1
3333
3434 let idxPoolStatus = 2
3535
3636 let idxPoolLPAssetId = 3
3737
3838 let idxAmtAssetId = 4
3939
4040 let idxPriceAssetId = 5
4141
4242 let idxAmtAssetDcm = 6
4343
4444 let idxPriceAssetDcm = 7
4545
4646 let idxIAmtAssetId = 8
4747
4848 let idxIPriceAssetId = 9
4949
5050 let idxLPAssetDcm = 10
5151
5252 let idxPoolAmtAssetAmt = 1
5353
5454 let idxPoolPriceAssetAmt = 2
5555
5656 let idxPoolLPAssetAmt = 3
5757
5858 let idxFactoryStakingContract = 1
5959
6060 let idxFactorySlippageContract = 7
6161
6262 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
6363
6464
6565 func toX18BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult)
6666
6767
6868 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
6969
7070
7171 func fromX18Round (val,resultScaleMult,round) = toInt(fraction(val, toBigInt(resultScaleMult), scale18, round))
7272
7373
7474 func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
7575
7676
7777 func abs (val) = if ((0 > val))
7878 then -(val)
7979 else val
8080
8181
8282 func absBigInt (val) = if ((zeroBigInt > val))
8383 then -(val)
8484 else val
8585
8686
8787 func swapContract () = "%s__swapContract"
8888
8989
9090 func fc () = "%s__factoryContract"
9191
9292
9393 func mpk () = "%s__managerPublicKey"
9494
9595
9696 func pmpk () = "%s__pendingManagerPublicKey"
9797
9898
9999 func pl () = "%s%s__price__last"
100100
101101
102102 func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
103103
104104
105105 func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
106106
107107
108108 func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
109109
110110
111111 func aa () = "%s__amountAsset"
112112
113113
114114 func pa () = "%s__priceAsset"
115115
116116
117117 func keyFactoryConfig () = "%s__factoryConfig"
118118
119119
120120 func keyMatcherPub () = "%s%s__matcher__publicKey"
121121
122122
123123 func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
124124
125125
126126 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
127127
128128
129129 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
130130
131131
132132 func keyAllPoolsShutdown () = "%s__shutdown"
133133
134134
135135 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
136136
137137
138138 func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
139139
140140
141141 let keyFeeCollectorAddress = "%s__feeCollectorAddress"
142142
143143 func throwOrderError (orderValid,senderValid,matcherValid) = throw(((((("order validation failed: orderValid=" + toString(orderValid)) + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
144144
145145
146146 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
147147
148148
149149 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
150150
151151
152152 func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
153153
154154
155155 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
156156
157157 let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
158158
159159 let inFee = {
160160 let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil)
161161 if ($isInstanceOf(@, "Int"))
162162 then @
163163 else throw(($getType(@) + " couldn't be cast to Int"))
164164 }
165165
166166 let outFee = {
167167 let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil)
168168 if ($isInstanceOf(@, "Int"))
169169 then @
170170 else throw(($getType(@) + " couldn't be cast to Int"))
171171 }
172172
173173 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
174174
175175
176176 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
177177
178178
179179 func getPoolConfig () = {
180180 let amtAsset = getStringOrFail(this, aa())
181181 let priceAsset = getStringOrFail(this, pa())
182182 let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
183183 let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
184184 split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
185185 }
186186
187187
188188 func parseAssetId (input) = if ((input == wavesString))
189189 then unit
190190 else fromBase58String(input)
191191
192192
193193 func assetIdToString (input) = if ((input == unit))
194194 then wavesString
195195 else toBase58String(value(input))
196196
197197
198198 func parsePoolConfig (poolConfig) = $Tuple7(addressFromStringValue(poolConfig[idxPoolAddress]), parseIntValue(poolConfig[idxPoolStatus]), fromBase58String(poolConfig[idxPoolLPAssetId]), parseAssetId(poolConfig[idxAmtAssetId]), parseAssetId(poolConfig[idxPriceAssetId]), parseIntValue(poolConfig[idxAmtAssetDcm]), parseIntValue(poolConfig[idxPriceAssetDcm]))
199199
200200
201201 let poolConfigParsed = parsePoolConfig(getPoolConfig())
202202
203203 let $t079068072 = poolConfigParsed
204204
205205 let cfgPoolAddress = $t079068072._1
206206
207207 let cfgPoolStatus = $t079068072._2
208208
209209 let cfgLpAssetId = $t079068072._3
210210
211211 let cfgAmountAssetId = $t079068072._4
212212
213213 let cfgPriceAssetId = $t079068072._5
214214
215215 let cfgAmountAssetDecimals = $t079068072._6
216216
217217 let cfgPriceAssetDecimals = $t079068072._7
218218
219219 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
220220
221221
222222 let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
223223
224224 let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
225225
226226 func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slippageTolerancePassedByUser,slippageToleranceReal,txHeight,txTimestamp,slipageAmtAssetAmt,slipagePriceAssetAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slippageTolerancePassedByUser), toString(slippageToleranceReal), toString(txHeight), toString(txTimestamp), toString(slipageAmtAssetAmt), toString(slipagePriceAssetAmt)], SEP)
227227
228228
229229 func dataGetActionInfo (outAmtAssetAmt,outPriceAssetAmt,inLpAmt,price,txHeight,txTimestamp) = makeString(["%d%d%d%d%d%d", toString(outAmtAssetAmt), toString(outPriceAssetAmt), toString(inLpAmt), toString(price), toString(txHeight), toString(txTimestamp)], SEP)
230230
231231
232232 func getAccBalance (assetId) = if ((assetId == "WAVES"))
233233 then wavesBalance(this).available
234234 else assetBalance(this, fromBase58String(assetId))
235235
236236
237237 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
238238
239239
240240 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
241241 let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
242242 let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
243243 calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
244244 }
245245
246246
247247 func calcPrices (amAmt,prAmt,lpAmt) = {
248248 let cfg = getPoolConfig()
249249 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
250250 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
251251 let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
252252 let amAmtX18 = toX18(amAmt, amtAssetDcm)
253253 let prAmtX18 = toX18(prAmt, priceAssetDcm)
254254 let lpAmtX18 = toX18(lpAmt, scale8)
255255 let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
256256 let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
257257 [priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
258258 }
259259
260260
261261 func calculatePrices (amAmt,prAmt,lpAmt) = {
262262 let prices = calcPrices(amAmt, prAmt, lpAmt)
263263 [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
264264 }
265265
266266
267267 func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
268268 let cfg = getPoolConfig()
269269 let lpAssetId = cfg[idxPoolLPAssetId]
270270 let amAssetId = cfg[idxAmtAssetId]
271271 let prAssetId = cfg[idxPriceAssetId]
272272 let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
273273 let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
274274 let poolStatus = cfg[idxPoolStatus]
275275 let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
276276 if ((lpAssetId != pmtAssetId))
277277 then throw("Invalid asset passed.")
278278 else {
279279 let amBalance = getAccBalance(amAssetId)
280280 let amBalanceX18 = toX18(amBalance, amAssetDcm)
281281 let prBalance = getAccBalance(prAssetId)
282282 let prBalanceX18 = toX18(prBalance, prAssetDcm)
283283 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
284284 let curPrice = fromX18(curPriceX18, scale8)
285285 let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
286286 let lpEmissionX18 = toX18(lpEmission, scale8)
287287 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
288288 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
289289 let outAmAmt = fromX18(outAmAmtX18, amAssetDcm)
290290 let outPrAmt = fromX18(outPrAmtX18, prAssetDcm)
291291 let state = if ((txId58 == ""))
292292 then nil
293293 else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
294294 then unit
295295 else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
296296 then unit
297297 else fromBase58String(prAssetId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
298298 $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
299299 }
300300 }
301301
302302
303303 func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
304304 let cfg = getPoolConfig()
305305 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
306306 let amAssetIdStr = cfg[idxAmtAssetId]
307307 let prAssetIdStr = cfg[idxPriceAssetId]
308308 let iAmtAssetId = cfg[idxIAmtAssetId]
309309 let iPriceAssetId = cfg[idxIPriceAssetId]
310310 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
311311 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
312312 let poolStatus = cfg[idxPoolStatus]
313313 let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
314314 let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
315315 let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
316316 if (if ((amAssetIdStr != inAmAssetIdStr))
317317 then true
318318 else (prAssetIdStr != inPrAssetIdStr))
319319 then throw("Invalid amt or price asset passed.")
320320 else {
321321 let amBalance = if (isEvaluate)
322322 then getAccBalance(amAssetIdStr)
323323 else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
324324 let prBalance = if (isEvaluate)
325325 then getAccBalance(prAssetIdStr)
326326 else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
327327 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
328328 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
329329 let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
330330 let amBalanceX18 = toX18(amBalance, amtAssetDcm)
331331 let prBalanceX18 = toX18(prBalance, priceAssetDcm)
332332 let res = if ((lpEmission == 0))
333333 then {
334334 let curPriceX18 = zeroBigInt
335335 let slippageX18 = zeroBigInt
336336 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
337337 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
338338 }
339339 else {
340340 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
341341 let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
342342 let slippageToleranceX18 = toX18(slippageTolerance, scale8)
343343 if (if ((curPriceX18 != zeroBigInt))
344344 then (slippageX18 > slippageToleranceX18)
345345 else false)
346346 then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
347347 else {
348348 let lpEmissionX18 = toX18(lpEmission, scale8)
349349 let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
350350 let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
351351 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
352352 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
353353 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
354354 let expAmtAssetAmtX18 = expectedAmts._1
355355 let expPriceAssetAmtX18 = expectedAmts._2
356356 let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
357357 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(expAmtAssetAmtX18, amtAssetDcm), fromX18(expPriceAssetAmtX18, priceAssetDcm), curPriceX18, slippageX18)
358358 }
359359 }
360360 let calcLpAmt = res._1
361361 let calcAmAssetPmt = res._2
362362 let calcPrAssetPmt = res._3
363363 let curPrice = fromX18(res._4, scale8)
364364 let slippageCalc = fromX18(res._5, scale8)
365365 if ((0 >= calcLpAmt))
366366 then throw("Invalid calculations. LP calculated is less than zero.")
367367 else {
368368 let emitLpAmt = if (!(emitLp))
369369 then 0
370370 else calcLpAmt
371371 let amDiff = (inAmAssetAmt - calcAmAssetPmt)
372372 let prDiff = (inPrAssetAmt - calcPrAssetPmt)
373373 let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(calcAmAssetPmt, calcPrAssetPmt, emitLpAmt, curPrice, slippageTolerance, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))]
374374 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
375375 }
376376 }
377377 }
378378
379379
380380 func validateMatcherOrderAllowed (order) = {
381381 let cfg = getPoolConfig()
382382 let amtAssetId = cfg[idxAmtAssetId]
383383 let priceAssetId = cfg[idxPriceAssetId]
384384 let poolStatus = parseIntValue(cfg[idxPoolStatus])
385385 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
386386 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
387387 let accAmtAssetBalance = getAccBalance(amtAssetId)
388388 let accPriceAssetBalance = getAccBalance(priceAssetId)
389389 let curPriceX18 = if ((order.orderType == Buy))
390390 then privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
391391 else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance - order.amount), accPriceAssetBalance)
392392 let curPrice = fromX18(curPriceX18, scale8)
393393 if (if (if (isGlobalShutdown())
394394 then true
395395 else (poolStatus == PoolMatcherDisabled))
396396 then true
397397 else (poolStatus == PoolShutdown))
398398 then throw("Exchange operations disabled")
399399 else {
400400 let orderAmtAsset = order.assetPair.amountAsset
401401 let orderAmtAssetStr = if ((orderAmtAsset == unit))
402402 then "WAVES"
403403 else toBase58String(value(orderAmtAsset))
404404 let orderPriceAsset = order.assetPair.priceAsset
405405 let orderPriceAssetStr = if ((orderPriceAsset == unit))
406406 then "WAVES"
407407 else toBase58String(value(orderPriceAsset))
408408 if (if ((orderAmtAssetStr != amtAssetId))
409409 then true
410410 else (orderPriceAssetStr != priceAssetId))
411411 then throw("Wrong order assets.")
412412 else {
413413 let orderPrice = order.price
414414 let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
415415 let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
416416 let isOrderPriceValid = if ((order.orderType == Buy))
417417 then (curPrice >= castedOrderPrice)
418418 else (castedOrderPrice >= curPrice)
419419 true
420420 }
421421 }
422422 }
423423
424424
425425 func commonGet (i) = if ((size(i.payments) != 1))
426426 then throw("exactly 1 payment is expected")
427427 else {
428428 let pmt = value(i.payments[0])
429429 let pmtAssetId = value(pmt.assetId)
430430 let pmtAmt = pmt.amount
431431 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
432432 let outAmAmt = res._1
433433 let outPrAmt = res._2
434434 let poolStatus = parseIntValue(res._9)
435435 let state = res._10
436436 if (if (isGlobalShutdown())
437437 then true
438438 else (poolStatus == PoolShutdown))
439439 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
440440 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
441441 }
442442
443443
444444 func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
445445 then throw("exactly 2 payments are expected")
446446 else {
447447 let amAssetPmt = value(i.payments[0])
448448 let prAssetPmt = value(i.payments[1])
449449 let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
450450 let poolStatus = parseIntValue(estPut._8)
451451 if (if (if (isGlobalShutdown())
452452 then true
453453 else (poolStatus == PoolPutDisabled))
454454 then true
455455 else (poolStatus == PoolShutdown))
456456 then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
457457 else estPut
458458 }
459459
460460
461461 func emit (amount) = {
462462 let emitInv = invoke(factoryContract, "emit", [amount], nil)
463463 if ((emitInv == emitInv))
464464 then {
465465 let emitInvLegacy = match emitInv {
466466 case legacyFactoryContract: Address =>
467467 invoke(legacyFactoryContract, "emit", [amount], nil)
468468 case _ =>
469469 unit
470470 }
471471 if ((emitInvLegacy == emitInvLegacy))
472472 then amount
473473 else throw("Strict value is not equal to itself.")
474474 }
475475 else throw("Strict value is not equal to itself.")
476476 }
477477
478478
479479 func takeFee (amount,fee) = {
480480 let feeAmount = if ((fee == 0))
481481 then 0
482482 else fraction(amount, fee, scale8)
483483 $Tuple2((amount - feeAmount), feeAmount)
484484 }
485485
486486
487487 func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
488488 let isEval = (txId == unit)
489489 let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
490490 let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
491491 let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
492492 then true
493493 else if ((paymentAssetId == cfgPriceAssetId))
494494 then false
495495 else throwErr("invalid asset")
496496 let $t02296923262 = if (isEval)
497497 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
498498 else if (paymentInAmountAsset)
499499 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
500500 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
501501 let amountBalanceOld = $t02296923262._1
502502 let priceBalanceOld = $t02296923262._2
503503 let $t02326623415 = if (paymentInAmountAsset)
504504 then $Tuple2(paymentAmountRaw, 0)
505505 else $Tuple2(0, paymentAmountRaw)
506506 let amountAssetAmountRaw = $t02326623415._1
507507 let priceAssetAmountRaw = $t02326623415._2
508508 let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1
509509 let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1
510510 let $t02354723611 = takeFee(paymentAmountRaw, inFee)
511511 let paymentAmount = $t02354723611._1
512512 let feeAmount = $t02354723611._2
513513 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
514514 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
515515 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
516516 let priceNew = fromX18(priceNewX18, scale8)
517517 let paymentBalance = if (paymentInAmountAsset)
518518 then amountBalanceOld
519519 else priceBalanceOld
520520 let paymentBalanceBigInt = toBigInt(paymentBalance)
521521 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
522522 let chechSupply = if ((supplyBigInt > big0))
523523 then true
524524 else throwErr("initial deposit requires all coins")
525525 if ((chechSupply == chechSupply))
526526 then {
527527 let depositBigInt = toBigInt(paymentAmount)
528528 let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
529529 let commonState = if (isEval)
530530 then nil
531531 else [IntegerEntry(pl(), priceNew), IntegerEntry(ph(height, lastBlock.timestamp), priceNew), StringEntry(pau(toString(value(userAddress)), toBase58String(value(txId))), dataPutActionInfo(amountAssetAmountRaw, priceAssetAmountRaw, issueAmount, priceNew, 0, 0, height, lastBlock.timestamp, 0, 0))]
532532 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
533533 let priceOld = fromX18(priceOldX18, scale8)
534534 let loss = {
535535 let $t02508825255 = if (paymentInAmountAsset)
536536 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
537537 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
538538 let amount = $t02508825255._1
539539 let balance = $t02508825255._2
540540 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
541541 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
542542 }
543543 $Tuple4(issueAmount, commonState, feeAmount, loss)
544544 }
545545 else throw("Strict value is not equal to itself.")
546546 }
547547
548548
549549 func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
550550 let isEval = (txId == unit)
551551 let checks = [if ((paymentAssetId == cfgLpAssetId))
552552 then true
553553 else throwErr("invalid lp asset")]
554554 if ((checks == checks))
555555 then {
556556 let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
557557 then true
558558 else if ((outAssetId == cfgPriceAssetId))
559559 then false
560560 else throwErr("invalid asset")
561561 let balanceBigInt = if (outInAmountAsset)
562562 then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
563563 else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
564564 let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
565565 let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
566566 let outBalance = if (outInAmountAsset)
567567 then amBalanceOld
568568 else prBalanceOld
569569 let outBalanceBigInt = toBigInt(outBalance)
570570 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
571571 let redeemedBigInt = toBigInt(paymentAmount)
572572 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
573573 let $t02683526891 = takeFee(amountRaw, outFee)
574574 let totalAmount = $t02683526891._1
575575 let feeAmount = $t02683526891._2
576576 let $t02689527121 = if (outInAmountAsset)
577577 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
578578 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
579579 let outAmAmount = $t02689527121._1
580580 let outPrAmount = $t02689527121._2
581581 let amBalanceNew = $t02689527121._3
582582 let prBalanceNew = $t02689527121._4
583583 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
584584 let priceNew = fromX18(priceNewX18, scale8)
585585 let commonState = if (isEval)
586586 then nil
587587 else [StringEntry(gau(toString(value(userAddress)), toBase58String(value(txId))), dataGetActionInfo(outAmAmount, outPrAmount, paymentAmount, priceNew, height, lastBlock.timestamp)), IntegerEntry(pl(), priceNew), IntegerEntry(ph(height, lastBlock.timestamp), priceNew)]
588588 let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
589589 let priceOld = fromX18(priceOldX18, scale8)
590590 let loss = {
591591 let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
592592 fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
593593 }
594594 $Tuple4(totalAmount, commonState, feeAmount, loss)
595595 }
596596 else throw("Strict value is not equal to itself.")
597597 }
598598
599599
600600 func managerPublicKeyOrUnit () = match getString(mpk()) {
601601 case s: String =>
602602 fromBase58String(s)
603603 case _: Unit =>
604604 unit
605605 case _ =>
606606 throw("Match error")
607607 }
608608
609609
610610 func pendingManagerPublicKeyOrUnit () = match getString(pmpk()) {
611611 case s: String =>
612612 fromBase58String(s)
613613 case _: Unit =>
614614 unit
615615 case _ =>
616616 throw("Match error")
617617 }
618618
619619
620620 func isManager (i) = match managerPublicKeyOrUnit() {
621621 case pk: ByteVector =>
622622 (i.callerPublicKey == pk)
623623 case _: Unit =>
624624 (i.caller == this)
625625 case _ =>
626626 throw("Match error")
627627 }
628628
629629
630630 func mustManager (i) = {
631631 let pd = throw("Permission denied")
632632 match managerPublicKeyOrUnit() {
633633 case pk: ByteVector =>
634634 if ((i.callerPublicKey == pk))
635635 then true
636636 else pd
637637 case _: Unit =>
638638 if ((i.caller == this))
639639 then true
640640 else pd
641641 case _ =>
642642 throw("Match error")
643643 }
644644 }
645645
646646
647647 @Callable(i)
648648 func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse) = {
649649 let $t02879829103 = if ((isReverse == false))
650650 then {
651651 let assetOut = getStringOrFail(this, pa())
652652 let assetIn = getStringOrFail(this, aa())
653653 $Tuple2(assetOut, assetIn)
654654 }
655655 else {
656656 let assetOut = getStringOrFail(this, aa())
657657 let assetIn = getStringOrFail(this, pa())
658658 $Tuple2(assetOut, assetIn)
659659 }
660660 let assetOut = $t02879829103._1
661661 let assetIn = $t02879829103._2
662662 let poolAssetInBalance = getAccBalance(assetIn)
663663 let poolAssetOutBalance = getAccBalance(assetOut)
664664 let amountOut = ((poolAssetOutBalance * cleanAmountIn) / (poolAssetInBalance + cleanAmountIn))
665- let oldK = (poolAssetInBalance * poolAssetOutBalance)
666- let newK = ((getAccBalance(assetIn) + cleanAmountIn) * (getAccBalance(assetOut) - amountOut))
667- let checkK = if ((newK >= oldK))
668- then true
669- else throw("new K is fewer error")
670- if ((checkK == checkK))
671- then $Tuple2(nil, amountOut)
672- else throw("Strict value is not equal to itself.")
665+ $Tuple2(nil, amountOut)
673666 }
674667
675668
676669
677670 @Callable(i)
678671 func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo) = {
679672 let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn))
680673 then true
681674 else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(getStringOrFail(this, swapContract()))))
682675 then true
683676 else throwErr("Permission denied")]
684677 if ((checks == checks))
685678 then {
686679 let pmt = value(i.payments[0])
687680 let assetIn = if ((pmt.assetId == unit))
688681 then toBase58String(toBytes("WAVES"))
689682 else toBase58String(value(pmt.assetId))
690683 let assetOut = if ((isReverse == false))
691684 then getStringOrFail(this, pa())
692685 else getStringOrFail(this, aa())
693686 let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount)
694687 let poolAssetOutBalance = getAccBalance(assetOut)
695688 let amountOut = ((poolAssetOutBalance * cleanAmountIn) / (poolAssetInBalance + cleanAmountIn))
696689 let oldK = (poolAssetInBalance * poolAssetOutBalance)
697690 let newK = (getAccBalance(assetIn) * (getAccBalance(assetOut) - amountOut))
698691 let checkK = if ((newK >= oldK))
699692 then true
700693 else throw("new K is fewer error")
701694 if ((checkK == checkK))
702695 then {
703696 let checkMin = if ((amountOut >= amountOutMin))
704697 then true
705698 else throw("Exchange result is fewer coins than expected")
706699 if ((checkMin == checkMin))
707700 then [ScriptTransfer(addressFromStringValue(addressTo), amountOut, if ((assetIn == "WAVES"))
708701 then unit
709702 else fromBase58String(assetOut))]
710703 else throw("Strict value is not equal to itself.")
711704 }
712705 else throw("Strict value is not equal to itself.")
713706 }
714707 else throw("Strict value is not equal to itself.")
715708 }
716709
717710
718711
719712 @Callable(i)
720713 func setManager (pendingManagerPublicKey) = {
721714 let checkCaller = mustManager(i)
722715 if ((checkCaller == checkCaller))
723716 then {
724717 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
725718 if ((checkManagerPublicKey == checkManagerPublicKey))
726719 then [StringEntry(pmpk(), pendingManagerPublicKey)]
727720 else throw("Strict value is not equal to itself.")
728721 }
729722 else throw("Strict value is not equal to itself.")
730723 }
731724
732725
733726
734727 @Callable(i)
735728 func confirmManager () = {
736729 let pm = pendingManagerPublicKeyOrUnit()
737730 let hasPM = if (isDefined(pm))
738731 then true
739732 else throw("No pending manager")
740733 if ((hasPM == hasPM))
741734 then {
742735 let checkPM = if ((i.callerPublicKey == value(pm)))
743736 then true
744737 else throw("You are not pending manager")
745738 if ((checkPM == checkPM))
746739 then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())]
747740 else throw("Strict value is not equal to itself.")
748741 }
749742 else throw("Strict value is not equal to itself.")
750743 }
751744
752745
753746
754747 @Callable(i)
755748 func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
756749 then throw("Invalid slippageTolerance passed")
757750 else {
758751 let estPut = commonPut(i, slippageTolerance, true)
759752 let emitLpAmt = estPut._2
760753 let lpAssetId = estPut._7
761754 let state = estPut._9
762755 let amDiff = estPut._10
763756 let prDiff = estPut._11
764757 let amId = estPut._12
765758 let prId = estPut._13
766759 let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
767760 if ((emitInv == emitInv))
768761 then {
769762 let emitInvLegacy = match emitInv {
770763 case legacyFactoryContract: Address =>
771764 invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
772765 case _ =>
773766 unit
774767 }
775768 if ((emitInvLegacy == emitInvLegacy))
776769 then {
777770 let slippageAInv = if ((amDiff > 0))
778771 then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
779772 else nil
780773 if ((slippageAInv == slippageAInv))
781774 then {
782775 let slippagePInv = if ((prDiff > 0))
783776 then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
784777 else nil
785778 if ((slippagePInv == slippagePInv))
786779 then {
787780 let lpTransfer = if (shouldAutoStake)
788781 then {
789782 let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
790783 if ((slpStakeInv == slpStakeInv))
791784 then nil
792785 else throw("Strict value is not equal to itself.")
793786 }
794787 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
795788 (state ++ lpTransfer)
796789 }
797790 else throw("Strict value is not equal to itself.")
798791 }
799792 else throw("Strict value is not equal to itself.")
800793 }
801794 else throw("Strict value is not equal to itself.")
802795 }
803796 else throw("Strict value is not equal to itself.")
804797 }
805798
806799
807800
808801 @Callable(i)
809802 func putForFree (maxSlippage) = if ((0 > maxSlippage))
810803 then throw("Invalid value passed")
811804 else {
812805 let estPut = commonPut(i, maxSlippage, false)
813806 estPut._9
814807 }
815808
816809
817810
818811 @Callable(i)
819812 func putOneTkn (minOutAmount,autoStake) = {
820813 let isPoolOneTokenOperationsDisabled = {
821814 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
822815 if ($isInstanceOf(@, "Boolean"))
823816 then @
824817 else throw(($getType(@) + " couldn't be cast to Boolean"))
825818 }
826819 let isPutDisabled = if (if (if (isGlobalShutdown())
827820 then true
828821 else (cfgPoolStatus == PoolPutDisabled))
829822 then true
830823 else (cfgPoolStatus == PoolShutdown))
831824 then true
832825 else isPoolOneTokenOperationsDisabled
833826 let checks = [if (if (!(isPutDisabled))
834827 then true
835828 else isManager(i))
836829 then true
837830 else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
838831 then true
839832 else throwErr("exactly 1 payment are expected")]
840833 if ((checks == checks))
841834 then {
842835 let payment = i.payments[0]
843836 let paymentAssetId = payment.assetId
844837 let paymentAmountRaw = payment.amount
845838 let userAddress = i.caller
846839 let txId = i.transactionId
847- let $t03422234352 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
848- if (($t03422234352 == $t03422234352))
840+ let $t03422834358 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
841+ if (($t03422834358 == $t03422834358))
849842 then {
850- let bonus = $t03422234352._4
851- let feeAmount = $t03422234352._3
852- let commonState = $t03422234352._2
853- let emitAmountEstimated = $t03422234352._1
843+ let bonus = $t03422834358._4
844+ let feeAmount = $t03422834358._3
845+ let commonState = $t03422834358._2
846+ let emitAmountEstimated = $t03422834358._1
854847 let emitAmount = if (if ((minOutAmount > 0))
855848 then (minOutAmount > emitAmountEstimated)
856849 else false)
857850 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
858851 else emitAmountEstimated
859852 let emitInv = emit(emitAmount)
860853 if ((emitInv == emitInv))
861854 then {
862855 let lpTransfer = if (autoStake)
863856 then {
864857 let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
865858 if ((stakeInv == stakeInv))
866859 then nil
867860 else throw("Strict value is not equal to itself.")
868861 }
869862 else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
870863 let sendFee = if ((feeAmount > 0))
871864 then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
872865 else nil
873866 $Tuple2(((commonState ++ lpTransfer) ++ sendFee), emitAmount)
874867 }
875868 else throw("Strict value is not equal to itself.")
876869 }
877870 else throw("Strict value is not equal to itself.")
878871 }
879872 else throw("Strict value is not equal to itself.")
880873 }
881874
882875
883876
884877 @Callable(i)
885878 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
886- let $t03508135216 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
887- let emitAmountEstimated = $t03508135216._1
888- let commonState = $t03508135216._2
889- let feeAmount = $t03508135216._3
890- let bonus = $t03508135216._4
879+ let $t03508735222 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
880+ let emitAmountEstimated = $t03508735222._1
881+ let commonState = $t03508735222._2
882+ let feeAmount = $t03508735222._3
883+ let bonus = $t03508735222._4
891884 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
892885 }
893886
894887
895888
896889 @Callable(i)
897890 func getOneTkn (outAssetIdStr,minOutAmount) = {
898891 let isPoolOneTokenOperationsDisabled = {
899892 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
900893 if ($isInstanceOf(@, "Boolean"))
901894 then @
902895 else throw(($getType(@) + " couldn't be cast to Boolean"))
903896 }
904897 let isGetDisabled = if (if (isGlobalShutdown())
905898 then true
906899 else (cfgPoolStatus == PoolShutdown))
907900 then true
908901 else isPoolOneTokenOperationsDisabled
909902 let checks = [if (if (!(isGetDisabled))
910903 then true
911904 else isManager(i))
912905 then true
913906 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
914907 then true
915908 else throwErr("exactly 1 payment are expected")]
916909 if ((checks == checks))
917910 then {
918911 let outAssetId = parseAssetId(outAssetIdStr)
919912 let payment = i.payments[0]
920913 let paymentAssetId = payment.assetId
921914 let paymentAmount = payment.amount
922915 let userAddress = i.caller
923916 let txId = i.transactionId
924- let $t03602136156 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
925- if (($t03602136156 == $t03602136156))
917+ let $t03602736162 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
918+ if (($t03602736162 == $t03602736162))
926919 then {
927- let bonus = $t03602136156._4
928- let feeAmount = $t03602136156._3
929- let commonState = $t03602136156._2
930- let amountEstimated = $t03602136156._1
920+ let bonus = $t03602736162._4
921+ let feeAmount = $t03602736162._3
922+ let commonState = $t03602736162._2
923+ let amountEstimated = $t03602736162._1
931924 let amount = if (if ((minOutAmount > 0))
932925 then (minOutAmount > amountEstimated)
933926 else false)
934927 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
935928 else amountEstimated
936929 let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
937930 if ((burnInv == burnInv))
938931 then {
939932 let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
940933 let sendFee = if ((feeAmount > 0))
941934 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
942935 else nil
943936 $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
944937 }
945938 else throw("Strict value is not equal to itself.")
946939 }
947940 else throw("Strict value is not equal to itself.")
948941 }
949942 else throw("Strict value is not equal to itself.")
950943 }
951944
952945
953946
954947 @Callable(i)
955948 func getOneTknREADONLY (outAssetId,paymentAmount) = {
956- let $t03679136929 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
957- let amountEstimated = $t03679136929._1
958- let commonState = $t03679136929._2
959- let feeAmount = $t03679136929._3
960- let bonus = $t03679136929._4
949+ let $t03679736935 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
950+ let amountEstimated = $t03679736935._1
951+ let commonState = $t03679736935._2
952+ let feeAmount = $t03679736935._3
953+ let bonus = $t03679736935._4
961954 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
962955 }
963956
964957
965958
966959 @Callable(i)
967960 func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
968961 let isPoolOneTokenOperationsDisabled = {
969962 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
970963 if ($isInstanceOf(@, "Boolean"))
971964 then @
972965 else throw(($getType(@) + " couldn't be cast to Boolean"))
973966 }
974967 let isGetDisabled = if (if (isGlobalShutdown())
975968 then true
976969 else (cfgPoolStatus == PoolShutdown))
977970 then true
978971 else isPoolOneTokenOperationsDisabled
979972 let checks = [if (if (!(isGetDisabled))
980973 then true
981974 else isManager(i))
982975 then true
983976 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
984977 then true
985978 else throwErr("no payments are expected")]
986979 if ((checks == checks))
987980 then {
988981 let outAssetId = parseAssetId(outAssetIdStr)
989982 let userAddress = i.caller
990983 let txId = i.transactionId
991984 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
992985 if ((unstakeInv == unstakeInv))
993986 then {
994- let $t03775437887 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
995- if (($t03775437887 == $t03775437887))
987+ let $t03776037893 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
988+ if (($t03776037893 == $t03776037893))
996989 then {
997- let bonus = $t03775437887._4
998- let feeAmount = $t03775437887._3
999- let commonState = $t03775437887._2
1000- let amountEstimated = $t03775437887._1
990+ let bonus = $t03776037893._4
991+ let feeAmount = $t03776037893._3
992+ let commonState = $t03776037893._2
993+ let amountEstimated = $t03776037893._1
1001994 let amount = if (if ((minOutAmount > 0))
1002995 then (minOutAmount > amountEstimated)
1003996 else false)
1004997 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
1005998 else amountEstimated
1006999 let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
10071000 if ((burnInv == burnInv))
10081001 then {
10091002 let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
10101003 let sendFee = if ((feeAmount > 0))
10111004 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
10121005 else nil
10131006 $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
10141007 }
10151008 else throw("Strict value is not equal to itself.")
10161009 }
10171010 else throw("Strict value is not equal to itself.")
10181011 }
10191012 else throw("Strict value is not equal to itself.")
10201013 }
10211014 else throw("Strict value is not equal to itself.")
10221015 }
10231016
10241017
10251018
10261019 @Callable(i)
10271020 func get () = {
10281021 let res = commonGet(i)
10291022 let outAmtAmt = res._1
10301023 let outPrAmt = res._2
10311024 let pmtAmt = res._3
10321025 let pmtAssetId = res._4
10331026 let state = res._5
10341027 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
10351028 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
10361029 then state
10371030 else throw("Strict value is not equal to itself.")
10381031 }
10391032
10401033
10411034
10421035 @Callable(i)
10431036 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
10441037 let res = commonGet(i)
10451038 let outAmAmt = res._1
10461039 let outPrAmt = res._2
10471040 let pmtAmt = res._3
10481041 let pmtAssetId = res._4
10491042 let state = res._5
10501043 if ((noLessThenAmtAsset > outAmAmt))
10511044 then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
10521045 else if ((noLessThenPriceAsset > outPrAmt))
10531046 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
10541047 else {
10551048 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
10561049 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
10571050 then state
10581051 else throw("Strict value is not equal to itself.")
10591052 }
10601053 }
10611054
10621055
10631056
10641057 @Callable(i)
10651058 func unstakeAndGet (amount) = {
10661059 let checkPayments = if ((size(i.payments) != 0))
10671060 then throw("No payments are expected")
10681061 else true
10691062 if ((checkPayments == checkPayments))
10701063 then {
10711064 let cfg = getPoolConfig()
10721065 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
10731066 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
10741067 if ((unstakeInv == unstakeInv))
10751068 then {
10761069 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
10771070 let poolStatus = parseIntValue(res._9)
10781071 let state = res._10
10791072 let checkPoolStatus = if (if (isGlobalShutdown())
10801073 then true
10811074 else (poolStatus == PoolShutdown))
10821075 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
10831076 else true
10841077 if ((checkPoolStatus == checkPoolStatus))
10851078 then {
10861079 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
10871080 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
10881081 then state
10891082 else throw("Strict value is not equal to itself.")
10901083 }
10911084 else throw("Strict value is not equal to itself.")
10921085 }
10931086 else throw("Strict value is not equal to itself.")
10941087 }
10951088 else throw("Strict value is not equal to itself.")
10961089 }
10971090
10981091
10991092
11001093 @Callable(i)
11011094 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
11021095 let isGetDisabled = if (isGlobalShutdown())
11031096 then true
11041097 else (cfgPoolStatus == PoolShutdown)
11051098 let checks = [if (!(isGetDisabled))
11061099 then true
11071100 else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
11081101 then true
11091102 else throw("no payments are expected")]
11101103 if ((checks == checks))
11111104 then {
11121105 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
11131106 if ((unstakeInv == unstakeInv))
11141107 then {
11151108 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
11161109 let outAmAmt = res._1
11171110 let outPrAmt = res._2
11181111 let state = res._10
11191112 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
11201113 then true
11211114 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
11221115 then true
11231116 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
11241117 if ((checkAmounts == checkAmounts))
11251118 then {
11261119 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
11271120 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
11281121 then state
11291122 else throw("Strict value is not equal to itself.")
11301123 }
11311124 else throw("Strict value is not equal to itself.")
11321125 }
11331126 else throw("Strict value is not equal to itself.")
11341127 }
11351128 else throw("Strict value is not equal to itself.")
11361129 }
11371130
11381131
11391132
11401133 @Callable(i)
11411134 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
11421135 then throw("permissions denied")
11431136 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
11441137
11451138
11461139
11471140 @Callable(i)
11481141 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
11491142
11501143
11511144
11521145 @Callable(i)
11531146 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
11541147
11551148
11561149
11571150 @Callable(i)
11581151 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
11591152 let prices = calcPrices(amAmt, prAmt, lpAmt)
11601153 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
11611154 }
11621155
11631156
11641157
11651158 @Callable(i)
11661159 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
11671160
11681161
11691162
11701163 @Callable(i)
11711164 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
11721165
11731166
11741167
11751168 @Callable(i)
11761169 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
11771170
11781171
11791172
11801173 @Callable(i)
11811174 func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
11821175
11831176
11841177
11851178 @Callable(i)
11861179 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
11871180 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
11881181 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
11891182 }
11901183
11911184
11921185
11931186 @Callable(i)
11941187 func statsREADONLY () = {
11951188 let cfg = getPoolConfig()
11961189 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
11971190 let amtAssetId = cfg[idxAmtAssetId]
11981191 let priceAssetId = cfg[idxPriceAssetId]
11991192 let iAmtAssetId = cfg[idxIAmtAssetId]
12001193 let iPriceAssetId = cfg[idxIPriceAssetId]
12011194 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
12021195 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
12031196 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
12041197 let accAmtAssetBalance = getAccBalance(amtAssetId)
12051198 let accPriceAssetBalance = getAccBalance(priceAssetId)
12061199 let pricesList = if ((poolLPBalance == 0))
12071200 then [zeroBigInt, zeroBigInt, zeroBigInt]
12081201 else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
12091202 let curPrice = 0
12101203 let lpAmtAssetShare = fromX18(pricesList[1], scale8)
12111204 let lpPriceAssetShare = fromX18(pricesList[2], scale8)
12121205 let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
12131206 $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))
12141207 }
12151208
12161209
12171210
12181211 @Callable(i)
12191212 func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
12201213 let cfg = getPoolConfig()
12211214 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
12221215 let amAssetIdStr = cfg[idxAmtAssetId]
12231216 let amAssetId = fromBase58String(amAssetIdStr)
12241217 let prAssetIdStr = cfg[idxPriceAssetId]
12251218 let prAssetId = fromBase58String(prAssetIdStr)
12261219 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
12271220 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
12281221 let poolStatus = cfg[idxPoolStatus]
12291222 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
12301223 let accAmtAssetBalance = getAccBalance(amAssetIdStr)
12311224 let accPriceAssetBalance = getAccBalance(prAssetIdStr)
12321225 let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
12331226 let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
12341227 let curPriceX18 = if ((poolLPBalance == 0))
12351228 then zeroBigInt
12361229 else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
12371230 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
12381231 let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
12391232 let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
12401233 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
12411234 let calcLpAmt = estPut._1
12421235 let curPriceCalc = estPut._3
12431236 let amBalance = estPut._4
12441237 let prBalance = estPut._5
12451238 let lpEmission = estPut._6
12461239 $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))
12471240 }
12481241
12491242
12501243
12511244 @Callable(i)
12521245 func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
12531246 let cfg = getPoolConfig()
12541247 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
12551248 let amAssetIdStr = cfg[idxAmtAssetId]
12561249 let amAssetId = fromBase58String(amAssetIdStr)
12571250 let prAssetIdStr = cfg[idxPriceAssetId]
12581251 let prAssetId = fromBase58String(prAssetIdStr)
12591252 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
12601253 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
12611254 let poolStatus = cfg[idxPoolStatus]
12621255 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
12631256 let amBalanceRaw = getAccBalance(amAssetIdStr)
12641257 let prBalanceRaw = getAccBalance(prAssetIdStr)
12651258 let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
12661259 let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
12671260 let curPriceX18 = if ((poolLPBalance == 0))
12681261 then zeroBigInt
12691262 else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
12701263 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
12711264 let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
12721265 let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
12731266 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
12741267 let calcLpAmt = estPut._1
12751268 let curPriceCalc = estPut._3
12761269 let amBalance = estPut._4
12771270 let prBalance = estPut._5
12781271 let lpEmission = estPut._6
12791272 $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))
12801273 }
12811274
12821275
12831276
12841277 @Callable(i)
12851278 func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
12861279 let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
12871280 let outAmAmt = res._1
12881281 let outPrAmt = res._2
12891282 let amBalance = res._5
12901283 let prBalance = res._6
12911284 let lpEmission = res._7
12921285 let curPrice = res._8
12931286 let poolStatus = parseIntValue(res._9)
12941287 $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))
12951288 }
12961289
12971290
12981291 @Verifier(tx)
12991292 func verify () = {
13001293 let targetPublicKey = match managerPublicKeyOrUnit() {
13011294 case pk: ByteVector =>
13021295 pk
13031296 case _: Unit =>
13041297 tx.senderPublicKey
13051298 case _ =>
13061299 throw("Match error")
13071300 }
13081301 match tx {
13091302 case order: Order =>
13101303 let matcherPub = getMatcherPubOrFail()
13111304 let orderValid = validateMatcherOrderAllowed(order)
13121305 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
13131306 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
13141307 if (if (if (orderValid)
13151308 then senderValid
13161309 else false)
13171310 then matcherValid
13181311 else false)
13191312 then true
13201313 else throwOrderError(orderValid, senderValid, matcherValid)
13211314 case s: SetScriptTransaction =>
13221315 let newHash = blake2b256(value(s.script))
13231316 let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
13241317 let currentHash = scriptHash(this)
13251318 if (if ((allowedHash == newHash))
13261319 then (currentHash != newHash)
13271320 else false)
13281321 then true
13291322 else sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
13301323 case _ =>
13311324 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
13321325 }
13331326 }
13341327

github/deemru/w8io/3ef1775 
184.57 ms