tx · EPg2XDwmnRirsUjDDTukWvuHXPca6tfd5hXVvw6XKNpD

3N1dMZiRHyPfV3HE1UP73tMqZyrajT8s7Gd:  -0.03100000 Waves

2022.11.24 17:25 [2331293] smart account 3N1dMZiRHyPfV3HE1UP73tMqZyrajT8s7Gd > SELF 0.00000000 Waves

{ "type": 13, "id": "EPg2XDwmnRirsUjDDTukWvuHXPca6tfd5hXVvw6XKNpD", "fee": 3100000, "feeAssetId": null, "timestamp": 1669299331287, "version": 1, "sender": "3N1dMZiRHyPfV3HE1UP73tMqZyrajT8s7Gd", "senderPublicKey": "5nXNn4nUrku3ormf7LVLKqY9doTY1LZWZ3uDiDHre72C", "proofs": [ "4xVkMZxC5pMcL5HqUeEbPZtKQra9m9VUc3p3cMvUn5o81JwoRUvQ3gha5nKdEKZBKSURpLK6411c25GUtDMmuqdz" ], "script": "base64:BgLYKQgCEgMKAQgSABIECgIBBBIDCgEBEgQKAgEEEgQKAggBEgQKAggBEgQKAggBEgUKAwEIARIAEgQKAgEBEgMKAQESBQoDAQEBEgQKAggIEgASABIDCgEIEgUKAwEBARIECgIBARIECgIIARIECgIICBILCgkIAQECAQIIBAQSBgoECAgBCBIAEgMKAQESAwoBARIECgIIASIKbFBkZWNpbWFscyIGc2NhbGU4IgxzY2FsZThCaWdJbnQiB3NjYWxlMTgiCnplcm9CaWdJbnQiBGJpZzAiBGJpZzEiBGJpZzIiC3dhdmVzU3RyaW5nIgNTRVAiClBvb2xBY3RpdmUiD1Bvb2xQdXREaXNhYmxlZCITUG9vbE1hdGNoZXJEaXNhYmxlZCIMUG9vbFNodXRkb3duIg5pZHhQb29sQWRkcmVzcyINaWR4UG9vbFN0YXR1cyIQaWR4UG9vbExQQXNzZXRJZCINaWR4QW10QXNzZXRJZCIPaWR4UHJpY2VBc3NldElkIg5pZHhBbXRBc3NldERjbSIQaWR4UHJpY2VBc3NldERjbSIOaWR4SUFtdEFzc2V0SWQiEGlkeElQcmljZUFzc2V0SWQiDWlkeExQQXNzZXREY20iEmlkeFBvb2xBbXRBc3NldEFtdCIUaWR4UG9vbFByaWNlQXNzZXRBbXQiEWlkeFBvb2xMUEFzc2V0QW10IhlpZHhGYWN0b3J5U3Rha2luZ0NvbnRyYWN0IhppZHhGYWN0b3J5U2xpcHBhZ2VDb250cmFjdCIFdG9YMTgiB29yaWdWYWwiDW9yaWdTY2FsZU11bHQiB2Zyb21YMTgiA3ZhbCIPcmVzdWx0U2NhbGVNdWx0Igd0b1NjYWxlIgNhbXQiCHJlc1NjYWxlIghjdXJTY2FsZSIDYWJzIglhYnNCaWdJbnQiAmZjIgNtcGsiBHBtcGsiAnBsIgJwaCIBaCIJdGltZXN0YW1wIgNwYXUiC3VzZXJBZGRyZXNzIgR0eElkIgNnYXUiAmFhIgJwYSIGa2V5RmVlIgpmZWVEZWZhdWx0IgNmZWUiBmtleUtMcCITa2V5TGFzdEtMcFJlZnJlc2hlZCISa2V5UmVmcmVzaEtMcERlbGF5IhBrZXlGYWN0b3J5Q29uZmlnIg1rZXlNYXRjaGVyUHViIilrZXlNYXBwaW5nUG9vbENvbnRyYWN0QWRkcmVzc1RvUG9vbEFzc2V0cyITcG9vbENvbnRyYWN0QWRkcmVzcyINa2V5UG9vbENvbmZpZyIJaUFtdEFzc2V0IgtpUHJpY2VBc3NldCIfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZCIMYmFzZUFzc2V0U3RyIhNrZXlBbGxQb29sc1NodXRkb3duIg1rZXlQb29sV2VpZ2h0Ig9jb250cmFjdEFkZHJlc3MiFmtleUFsbG93ZWRMcFNjcmlwdEhhc2giFmtleUZlZUNvbGxlY3RvckFkZHJlc3MiD3Rocm93T3JkZXJFcnJvciIKb3JkZXJWYWxpZCILc2VuZGVyVmFsaWQiDG1hdGNoZXJWYWxpZCIPZ2V0U3RyaW5nT3JGYWlsIgdhZGRyZXNzIgNrZXkiDGdldEludE9yRmFpbCIIdGhyb3dFcnIiA21zZyIGZm10RXJyIgVhc0ludCIHJG1hdGNoMCIGdmFsSW50Ig9mYWN0b3J5Q29udHJhY3QiE2ZlZUNvbGxlY3RvckFkZHJlc3MiEGlzR2xvYmFsU2h1dGRvd24iE2dldE1hdGNoZXJQdWJPckZhaWwiDWdldFBvb2xDb25maWciCGFtdEFzc2V0IgpwcmljZUFzc2V0IgxwYXJzZUFzc2V0SWQiBWlucHV0Ig9hc3NldElkVG9TdHJpbmciD3BhcnNlUG9vbENvbmZpZyIKcG9vbENvbmZpZyIQcG9vbENvbmZpZ1BhcnNlZCILJHQwNzkxNjgwODIiDmNmZ1Bvb2xBZGRyZXNzIg1jZmdQb29sU3RhdHVzIgxjZmdMcEFzc2V0SWQiEGNmZ0Ftb3VudEFzc2V0SWQiD2NmZ1ByaWNlQXNzZXRJZCIWY2ZnQW1vdW50QXNzZXREZWNpbWFscyIVY2ZnUHJpY2VBc3NldERlY2ltYWxzIhBnZXRGYWN0b3J5Q29uZmlnIg9zdGFraW5nQ29udHJhY3QiEHNsaXBwYWdlQ29udHJhY3QiEWRhdGFQdXRBY3Rpb25JbmZvIg1pbkFtdEFzc2V0QW10Ig9pblByaWNlQXNzZXRBbXQiCG91dExwQW10IgVwcmljZSIdc2xpcHBhZ2VUb2xlcmFuY2VQYXNzZWRCeVVzZXIiFXNsaXBwYWdlVG9sZXJhbmNlUmVhbCIIdHhIZWlnaHQiC3R4VGltZXN0YW1wIhJzbGlwYWdlQW10QXNzZXRBbXQiFHNsaXBhZ2VQcmljZUFzc2V0QW10IhFkYXRhR2V0QWN0aW9uSW5mbyIOb3V0QW10QXNzZXRBbXQiEG91dFByaWNlQXNzZXRBbXQiB2luTHBBbXQiDWdldEFjY0JhbGFuY2UiB2Fzc2V0SWQiD2NhbGNQcmljZUJpZ0ludCIIcHJBbXRYMTgiCGFtQW10WDE4IhBwcml2YXRlQ2FsY1ByaWNlIgphbUFzc2V0RGNtIgpwckFzc2V0RGNtIgVhbUFtdCIFcHJBbXQiDmFtdEFzc2V0QW10WDE4IhBwcmljZUFzc2V0QW10WDE4IgpjYWxjUHJpY2VzIgVscEFtdCIDY2ZnIgthbXRBc3NldERjbSINcHJpY2VBc3NldERjbSIIcHJpY2VYMTgiCGxwQW10WDE4IhNscFByaWNlSW5BbUFzc2V0WDE4IhNscFByaWNlSW5QckFzc2V0WDE4Ig9jYWxjdWxhdGVQcmljZXMiBnByaWNlcyIUZXN0aW1hdGVHZXRPcGVyYXRpb24iBnR4SWQ1OCIKcG10QXNzZXRJZCIIcG10THBBbXQiCWxwQXNzZXRJZCIJYW1Bc3NldElkIglwckFzc2V0SWQiCnBvb2xTdGF0dXMiCmxwRW1pc3Npb24iCWFtQmFsYW5jZSIMYW1CYWxhbmNlWDE4IglwckJhbGFuY2UiDHByQmFsYW5jZVgxOCILY3VyUHJpY2VYMTgiCGN1clByaWNlIgtwbXRMcEFtdFgxOCINbHBFbWlzc2lvblgxOCILb3V0QW1BbXRYMTgiC291dFByQW10WDE4IghvdXRBbUFtdCIIb3V0UHJBbXQiBXN0YXRlIhRlc3RpbWF0ZVB1dE9wZXJhdGlvbiIRc2xpcHBhZ2VUb2xlcmFuY2UiDGluQW1Bc3NldEFtdCILaW5BbUFzc2V0SWQiDGluUHJBc3NldEFtdCILaW5QckFzc2V0SWQiCmlzRXZhbHVhdGUiBmVtaXRMcCIMYW1Bc3NldElkU3RyIgxwckFzc2V0SWRTdHIiC2lBbXRBc3NldElkIg1pUHJpY2VBc3NldElkIg5pbkFtQXNzZXRJZFN0ciIOaW5QckFzc2V0SWRTdHIiD2luQW1Bc3NldEFtdFgxOCIPaW5QckFzc2V0QW10WDE4Igx1c2VyUHJpY2VYMTgiA3JlcyILc2xpcHBhZ2VYMTgiFHNsaXBwYWdlVG9sZXJhbmNlWDE4IgpwclZpYUFtWDE4IgphbVZpYVByWDE4IgxleHBlY3RlZEFtdHMiEWV4cEFtdEFzc2V0QW10WDE4IhNleHBQcmljZUFzc2V0QW10WDE4IgljYWxjTHBBbXQiDmNhbGNBbUFzc2V0UG10Ig5jYWxjUHJBc3NldFBtdCIMc2xpcHBhZ2VDYWxjIgllbWl0THBBbXQiBmFtRGlmZiIGcHJEaWZmIgtjb21tb25TdGF0ZSIbdmFsaWRhdGVNYXRjaGVyT3JkZXJBbGxvd2VkIgVvcmRlciIKYW10QXNzZXRJZCIMcHJpY2VBc3NldElkIhJhY2NBbXRBc3NldEJhbGFuY2UiFGFjY1ByaWNlQXNzZXRCYWxhbmNlIg1vcmRlckFtdEFzc2V0IhBvcmRlckFtdEFzc2V0U3RyIg9vcmRlclByaWNlQXNzZXQiEm9yZGVyUHJpY2VBc3NldFN0ciIKb3JkZXJQcmljZSIIcHJpY2VEY20iEGNhc3RlZE9yZGVyUHJpY2UiEWlzT3JkZXJQcmljZVZhbGlkIgljb21tb25HZXQiAWkiA3BtdCIGcG10QW10Igljb21tb25QdXQiCmFtQXNzZXRQbXQiCnByQXNzZXRQbXQiBmVzdFB1dCIEZW1pdCIGYW1vdW50IgdlbWl0SW52Ig1lbWl0SW52TGVnYWN5IhVsZWdhY3lGYWN0b3J5Q29udHJhY3QiB3Rha2VGZWUiCWZlZUFtb3VudCIPY2FsY1B1dE9uZVRva2VuIhBwYXltZW50QW1vdW50UmF3Ig5wYXltZW50QXNzZXRJZCIGaXNFdmFsIhBhbW91bnRCYWxhbmNlUmF3Ig9wcmljZUJhbGFuY2VSYXciFHBheW1lbnRJbkFtb3VudEFzc2V0Ig0kdDAyMjk0MzIzMjM2IhBhbW91bnRCYWxhbmNlT2xkIg9wcmljZUJhbGFuY2VPbGQiDSR0MDIzMjQwMjMzODkiFGFtb3VudEFzc2V0QW1vdW50UmF3IhNwcmljZUFzc2V0QW1vdW50UmF3IhFhbW91bnRBc3NldEFtb3VudCIQcHJpY2VBc3NldEFtb3VudCINJHQwMjM1MTEyMzU3MCINcGF5bWVudEFtb3VudCIQYW1vdW50QmFsYW5jZU5ldyIPcHJpY2VCYWxhbmNlTmV3IgtwcmljZU5ld1gxOCIIcHJpY2VOZXciDnBheW1lbnRCYWxhbmNlIhRwYXltZW50QmFsYW5jZUJpZ0ludCIMc3VwcGx5QmlnSW50IgtjaGVjaFN1cHBseSINZGVwb3NpdEJpZ0ludCILaXNzdWVBbW91bnQiC3ByaWNlT2xkWDE4IghwcmljZU9sZCIEbG9zcyINJHQwMjUwNDcyNTIxNCIHYmFsYW5jZSIPaXNzdWVBbW91bnRCb3RoIg9jYWxjR2V0T25lVG9rZW4iCm91dEFzc2V0SWQiBmNoZWNrcyIQb3V0SW5BbW91bnRBc3NldCINYmFsYW5jZUJpZ0ludCIMYW1CYWxhbmNlT2xkIgxwckJhbGFuY2VPbGQiCm91dEJhbGFuY2UiEG91dEJhbGFuY2VCaWdJbnQiDnJlZGVlbWVkQmlnSW50IglhbW91bnRSYXciDSR0MDI2Nzk0MjY4NDQiC3RvdGFsQW1vdW50Ig0kdDAyNjg0ODI3MDc0IgtvdXRBbUFtb3VudCILb3V0UHJBbW91bnQiDGFtQmFsYW5jZU5ldyIMcHJCYWxhbmNlTmV3IhhhbW91bnRCb3RoSW5QYXltZW50QXNzZXQiB2NhbGNLTHAiDWFtb3VudEJhbGFuY2UiDHByaWNlQmFsYW5jZSIKdXBkYXRlZEtMcCIScmVmcmVzaEtMcEludGVybmFsIg1hbW91bnRBc3NldElkIhJhbW91bnRBc3NldEJhbGFuY2UiEXByaWNlQXNzZXRCYWxhbmNlIhZtYW5hZ2VyUHVibGljS2V5T3JVbml0IgFzIh1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdCIJaXNNYW5hZ2VyIgJwayILbXVzdE1hbmFnZXIiAnBkIhdwZW5kaW5nTWFuYWdlclB1YmxpY0tleSILY2hlY2tDYWxsZXIiFWNoZWNrTWFuYWdlclB1YmxpY0tleSICcG0iBWhhc1BNIgdjaGVja1BNIg9zaG91bGRBdXRvU3Rha2UiBGFtSWQiBHBySWQiDHNsaXBwYWdlQUludiIMc2xpcHBhZ2VQSW52IgpscFRyYW5zZmVyIgtzbHBTdGFrZUludiILbWF4U2xpcHBhZ2UiDG1pbk91dEFtb3VudCIJYXV0b1N0YWtlIiBpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZCIBQCINaXNQdXREaXNhYmxlZCIHcGF5bWVudCINJHQwMzI2OTIzMjgxOSITZW1pdEFtb3VudEVzdGltYXRlZCIFYm9udXMiCmVtaXRBbW91bnQiCHN0YWtlSW52IgdzZW5kRmVlIg0kdDAzMzU0ODMzNjgzIg1vdXRBc3NldElkU3RyIg1pc0dldERpc2FibGVkIg0kdDAzNDQ4ODM0NjIwIg9hbW91bnRFc3RpbWF0ZWQiB2J1cm5JbnYiDWFzc2V0VHJhbnNmZXIiDSR0MDM1MjU1MzUzOTMiDXVuc3Rha2VBbW91bnQiCnVuc3Rha2VJbnYiDSR0MDM2MjE4MzYzNDgiCW91dEFtdEFtdCIUYnVybkxQQXNzZXRPbkZhY3RvcnkiEm5vTGVzc1RoZW5BbXRBc3NldCIUbm9MZXNzVGhlblByaWNlQXNzZXQiDWNoZWNrUGF5bWVudHMiD2NoZWNrUG9vbFN0YXR1cyIVbm9MZXNzVGhlbkFtb3VudEFzc2V0IgxjaGVja0Ftb3VudHMiC2FtdEFzc2V0U3RyIg1wcmljZUFzc2V0U3RyIhhsYXN0UmVmcmVzaGVkQmxvY2tIZWlnaHQiG2RlbGF5Tm90UmVhY2hlZEVycm9yTWVzc2FnZSIdY2hlY2tMYXN0UmVmcmVzaGVkQmxvY2tIZWlnaHQiDXBvb2xMUEJhbGFuY2UiCnByaWNlc0xpc3QiD2xwQW10QXNzZXRTaGFyZSIRbHBQcmljZUFzc2V0U2hhcmUiCnBvb2xXZWlnaHQiDGN1clByaWNlQ2FsYyIMYW1CYWxhbmNlUmF3IgxwckJhbGFuY2VSYXciD2FtQmFsYW5jZVJhd1gxOCIPcHJCYWxhbmNlUmF3WDE4IhBwYXltZW50THBBc3NldElkIgxwYXltZW50THBBbXQiAnR4IgZ2ZXJpZnkiD3RhcmdldFB1YmxpY0tleSIKbWF0Y2hlclB1YiIHbmV3SGFzaCILYWxsb3dlZEhhc2giC2N1cnJlbnRIYXNoagABYQAIAAFiAIDC1y8AAWMJALYCAQCAwtcvAAFkCQC2AgEAgICQu7rWrfANAAFlCQC2AgEAAAABZgkAtgIBAAAAAWcJALYCAQABAAFoCQC2AgEAAgABaQIFV0FWRVMAAWoCAl9fAAFrAAEAAWwAAgABbQADAAFuAAQAAW8AAQABcAACAAFxAAMAAXIABAABcwAFAAF0AAYAAXUABwABdgAIAAF3AAkAAXgACgABeQABAAF6AAIAAUEAAwABQgABAAFDAAcBAUQCAUUBRgkAvAIDCQC2AgEFAUUFAWQJALYCAQUBRgEBRwIBSAFJCQCgAwEJALwCAwUBSAkAtgIBBQFJBQFkAQFKAwFLAUwBTQkAawMFAUsFAUwFAU0BAU4BAUgDCQBmAgAABQFICQEBLQEFAUgFAUgBAU8BAUgDCQC/AgIFAWUFAUgJAL4CAQUBSAUBSAEBUAACEyVzX19mYWN0b3J5Q29udHJhY3QBAVEAAhQlc19fbWFuYWdlclB1YmxpY0tleQEBUgACGyVzX19wZW5kaW5nTWFuYWdlclB1YmxpY0tleQEBUwACESVzJXNfX3ByaWNlX19sYXN0AQFUAgFVAVYJALkJAgkAzAgCAhglcyVzJWQlZF9fcHJpY2VfX2hpc3RvcnkJAMwIAgkApAMBBQFVCQDMCAIJAKQDAQUBVgUDbmlsBQFqAQFXAgFYAVkJAKwCAgkArAICCQCsAgICCyVzJXMlc19fUF9fBQFYAgJfXwUBWQEBWgIBWAFZCQCsAgIJAKwCAgkArAICAgslcyVzJXNfX0dfXwUBWAICX18FAVkBAmFhAAIPJXNfX2Ftb3VudEFzc2V0AQJhYgACDiVzX19wcmljZUFzc2V0AAJhYwIHJXNfX2ZlZQACYWQJAGsDAAoFAWIAkE4AAmFlCQELdmFsdWVPckVsc2UCCQCaCAIFBHRoaXMFAmFjBQJhZAACYWYJALkJAgkAzAgCAgIlcwkAzAgCAgZrZXlLbHAFA25pbAUBagACYWcJALkJAgkAzAgCAgIlcwkAzAgCAhNrZXlMYXN0S0xwUmVmcmVzaGVkBQNuaWwFAWoAAmFoCQC5CQIJAMwIAgICJXMJAMwIAgISa2V5UmVmcmVzaEtMcERlbGF5BQNuaWwFAWoBAmFpAAIRJXNfX2ZhY3RvcnlDb25maWcBAmFqAAIYJXMlc19fbWF0Y2hlcl9fcHVibGljS2V5AQJhawECYWwJAKwCAgkArAICAgglcyVzJXNfXwUCYWwCIF9fbWFwcGluZ3NfX3Bvb2xDb250cmFjdDJMcEFzc2V0AQJhbQICYW4CYW8JAKwCAgkArAICCQCsAgIJAKwCAgIIJWQlZCVzX18FAmFuAgJfXwUCYW8CCF9fY29uZmlnAQJhcAECYXEJAKwCAgIoJXMlcyVzX19tYXBwaW5nc19fYmFzZUFzc2V0MmludGVybmFsSWRfXwUCYXEBAmFyAAIMJXNfX3NodXRkb3duAQJhcwECYXQJAKwCAgISJXMlc19fcG9vbFdlaWdodF9fBQJhdAECYXUAAhclc19fYWxsb3dlZExwU2NyaXB0SGFzaAACYXYCFyVzX19mZWVDb2xsZWN0b3JBZGRyZXNzAQJhdwMCYXgCYXkCYXoJAAIBCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgIkb3JkZXIgdmFsaWRhdGlvbiBmYWlsZWQ6IG9yZGVyVmFsaWQ9CQClAwEFAmF4Ag0gc2VuZGVyVmFsaWQ9CQClAwEFAmF5Ag4gbWF0Y2hlclZhbGlkPQkApQMBBQJhegECYUECAmFCAmFDCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUCYUIFAmFDCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmFCCQDMCAICAS4JAMwIAgUCYUMJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAECYUQCAmFCAmFDCQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUCYUIFAmFDCQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmFCCQDMCAICAS4JAMwIAgUCYUMJAMwIAgIPIGlzIG5vdCBkZWZpbmVkBQNuaWwCAAECYUUBAmFGCQACAQkAuQkCCQDMCAICCGxwLnJpZGU6CQDMCAIFAmFGBQNuaWwCASABAmFHAQJhRgkAuQkCCQDMCAICCGxwLnJpZGU6CQDMCAIFAmFGBQNuaWwCASABAmFIAQFIBAJhSQUBSAMJAAECBQJhSQIDSW50BAJhSgUCYUkFAmFKCQACAQIVZmFpbCB0byBjYXN0IGludG8gSW50AAJhSwkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFBAgUEdGhpcwkBAVAAAAJhTAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmFBAgUCYUsFAmF2AQJhTQAJAQt2YWx1ZU9yRWxzZQIJAJsIAgUCYUsJAQJhcgAHAQJhTgAJANkEAQkBAmFBAgUCYUsJAQJhagABAmFPAAQCYVAJAQJhQQIFBHRoaXMJAQJhYQAEAmFRCQECYUECBQR0aGlzCQECYWIABAJhbwkBAmFEAgUCYUsJAQJhcAEFAmFRBAJhbgkBAmFEAgUCYUsJAQJhcAEFAmFQCQC1CQIJAQJhQQIFAmFLCQECYW0CCQCkAwEFAmFuCQCkAwEFAmFvBQFqAQJhUgECYVMDCQAAAgUCYVMFAWkFBHVuaXQJANkEAQUCYVMBAmFUAQJhUwMJAAACBQJhUwUEdW5pdAUBaQkA2AQBCQEFdmFsdWUBBQJhUwECYVUBAmFWCQCZCgcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYVYFAW8JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJhVgUBcAkA2QQBCQCRAwIFAmFWBQFxCQECYVIBCQCRAwIFAmFWBQFyCQECYVIBCQCRAwIFAmFWBQFzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYVYFAXQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJhVgUBdQACYVcJAQJhVQEJAQJhTwAAAmFYBQJhVwACYVkIBQJhWAJfMQACYVoIBQJhWAJfMgACYmEIBQJhWAJfMwACYmIIBQJhWAJfNAACYmMIBQJhWAJfNQACYmQIBQJhWAJfNgACYmUIBQJhWAJfNwECYmYACQC1CQIJAQJhQQIFAmFLCQECYWkABQFqAAJiZwkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgkBAmJmAAUBQgIZaW5jb3JyZWN0IHN0YWtpbmcgYWRkcmVzcwACYmgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIJAQJiZgAFAUMCGWluY29ycmVjdCBzdGFraW5nIGFkZHJlc3MBAmJpCgJiagJiawJibAJibQJibgJibwJicAJicQJicgJicwkAuQkCCQDMCAICFCVkJWQlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYmoJAMwIAgkApAMBBQJiawkAzAgCCQCkAwEFAmJsCQDMCAIJAKQDAQUCYm0JAMwIAgkApAMBBQJibgkAzAgCCQCkAwEFAmJvCQDMCAIJAKQDAQUCYnAJAMwIAgkApAMBBQJicQkAzAgCCQCkAwEFAmJyCQDMCAIJAKQDAQUCYnMFA25pbAUBagECYnQGAmJ1AmJ2AmJ3AmJtAmJwAmJxCQC5CQIJAMwIAgIMJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYnUJAMwIAgkApAMBBQJidgkAzAgCCQCkAwEFAmJ3CQDMCAIJAKQDAQUCYm0JAMwIAgkApAMBBQJicAkAzAgCCQCkAwEFAmJxBQNuaWwFAWoBAmJ4AQJieQMJAAACBQJieQIFV0FWRVMICQDvBwEFBHRoaXMJYXZhaWxhYmxlCQDwBwIFBHRoaXMJANkEAQUCYnkBAmJ6AgJiQQJiQgkAvAIDBQJiQQUBZAUCYkIBAmJDBAJiRAJiRQJiRgJiRwQCYkgJAQFEAgUCYkYFAmJEBAJiSQkBAUQCBQJiRwUCYkUJAQJiegIFAmJJBQJiSAECYkoDAmJGAmJHAmJLBAJiTAkBAmFPAAQCYk0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiTAUBdAQCYk4JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiTAUBdQQCYk8JAQJiQwQFAmJNBQJiTgUCYkYFAmJHBAJiQgkBAUQCBQJiRgUCYk0EAmJBCQEBRAIFAmJHBQJiTgQCYlAJAQFEAgUCYksFAWIEAmJRCQECYnoCBQJiQgUCYlAEAmJSCQECYnoCBQJiQQUCYlAJAMwIAgUCYk8JAMwIAgUCYlEJAMwIAgUCYlIFA25pbAECYlMDAmJGAmJHAmJLBAJiVAkBAmJKAwUCYkYFAmJHBQJiSwkAzAgCCQEBRwIJAJEDAgUCYlQAAAUBYgkAzAgCCQEBRwIJAJEDAgUCYlQAAQUBYgkAzAgCCQEBRwIJAJEDAgUCYlQAAgUBYgUDbmlsAQJiVQQCYlYCYlcCYlgBWAQCYkwJAQJhTwAEAmJZCQCRAwIFAmJMBQFxBAJiWgkAkQMCBQJiTAUBcgQCY2EJAJEDAgUCYkwFAXMEAmJECQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkwFAXQEAmJFCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkwFAXUEAmNiCQCRAwIFAmJMBQFwBAJjYwgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFAmJZCQCsAgIJAKwCAgIGQXNzZXQgBQJiWQIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkDCQECIT0CBQJiWQUCYlcJAAIBAhVJbnZhbGlkIGFzc2V0IHBhc3NlZC4EAmNkCQECYngBBQJiWgQCY2UJAQFEAgUCY2QFAmJEBAJjZgkBAmJ4AQUCY2EEAmNnCQEBRAIFAmNmBQJiRQQCY2gJAQJiegIFAmNnBQJjZQQCY2kJAQFHAgUCY2gFAWIEAmNqCQEBRAIFAmJYBQFiBAJjawkBAUQCBQJjYwUBYgQCY2wJALwCAwUCY2UFAmNqBQJjawQCY20JALwCAwUCY2cFAmNqBQJjawQCY24JAQFHAgUCY2wFAmJEBAJjbwkBAUcCBQJjbQUCYkUEAmNwAwkAAAIFAmJWAgAFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQFYBQJjbgMJAAACBQJiWgIFV0FWRVMFBHVuaXQJANkEAQUCYloJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUBWAUCY28DCQAAAgUCY2ECBVdBVkVTBQR1bml0CQDZBAEFAmNhCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFaAgkApQgBBQFYBQJiVgkBAmJ0BgUCY24FAmNvBQJiWAUCY2kFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFTAAUCY2kJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFUAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCY2kFA25pbAkAnAoKBQJjbgUCY28FAmJaBQJjYQUCY2QFAmNmBQJjYwUCY2gFAmNiBQJjcAECY3EJAmJWAmNyAmNzAmN0AmN1AmN2AVgCY3cCY3gEAmJMCQECYU8ABAJiWQkA2QQBCQCRAwIFAmJMBQFxBAJjeQkAkQMCBQJiTAUBcgQCY3oJAJEDAgUCYkwFAXMEAmNBCQCRAwIFAmJMBQF2BAJjQgkAkQMCBQJiTAUBdwQCYk0JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiTAUBdAQCYk4JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiTAUBdQQCY2IJAJEDAgUCYkwFAXAEAmNjCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmJZCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmJZAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCY0MJANgEAQkBC3ZhbHVlT3JFbHNlAgUCY3QJANkEAQIFV0FWRVMEAmNECQDYBAEJAQt2YWx1ZU9yRWxzZQIFAmN2CQDZBAECBVdBVkVTAwMJAQIhPQIFAmN5BQJjQwYJAQIhPQIFAmN6BQJjRAkAAgECIkludmFsaWQgYW10IG9yIHByaWNlIGFzc2V0IHBhc3NlZC4EAmNkAwUCY3cJAQJieAEFAmN5CQBlAgkBAmJ4AQUCY3kFAmNzBAJjZgMFAmN3CQECYngBBQJjegkAZQIJAQJieAEFAmN6BQJjdQQCY0UJAQFEAgUCY3MFAmJNBAJjRgkBAUQCBQJjdQUCYk4EAmNHCQECYnoCBQJjRgUCY0UEAmNlCQEBRAIFAmNkBQJiTQQCY2cJAQFEAgUCY2YFAmJOBAJjSAMJAAACBQJjYwAABAJjaAUBZQQCY0kFAWUEAmJQCQB2BgkAuQICBQJjRQUCY0YAAAkAtgIBAAUAAQAABQRET1dOCQCXCgUJAQFHAgUCYlAFAWIJAQFHAgUCY0UFAmJNCQEBRwIFAmNGBQJiTgkBAmJ6AgkAtwICBQJjZwUCY0YJALcCAgUCY2UFAmNFBQJjSQQCY2gJAQJiegIFAmNnBQJjZQQCY0kJALwCAwkBAU8BCQC4AgIFAmNoBQJjRwUBZAUCY2gEAmNKCQEBRAIFAmNyBQFiAwMJAQIhPQIFAmNoBQFlCQC/AgIFAmNJBQJjSgcJAAIBCQCsAgIJAKwCAgkArAICAg9QcmljZSBzbGlwcGFnZSAJAKYDAQUCY0kCHiBleGNlZWRlZCB0aGUgcGFzc2VkIGxpbWl0IG9mIAkApgMBBQJjSgQCY2sJAQFEAgUCY2MFAWIEAmNLCQC8AgMFAmNFBQJjaAUBZAQCY0wJALwCAwUCY0YFAWQFAmNoBAJjTQMJAL8CAgUCY0sFAmNGCQCUCgIFAmNMBQJjRgkAlAoCBQJjRQUCY0sEAmNOCAUCY00CXzEEAmNPCAUCY00CXzIEAmJQCQC8AgMFAmNrBQJjTwUCY2cJAJcKBQkBAUcCBQJiUAUBYgkBAUcCBQJjTgUCYk0JAQFHAgUCY08FAmJOBQJjaAUCY0kEAmNQCAUCY0gCXzEEAmNRCAUCY0gCXzIEAmNSCAUCY0gCXzMEAmNpCQEBRwIIBQJjSAJfNAUBYgQCY1MJAQFHAggFAmNIAl81BQFiAwkAZwIAAAUCY1AJAAIBAjZJbnZhbGlkIGNhbGN1bGF0aW9ucy4gTFAgY2FsY3VsYXRlZCBpcyBsZXNzIHRoYW4gemVyby4EAmNUAwkBASEBBQJjeAAABQJjUAQCY1UJAGUCBQJjcwUCY1EEAmNWCQBlAgUCY3UFAmNSBAJjVwkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVMABQJjaQkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVQCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJjaQkAzAgCCQELU3RyaW5nRW50cnkCCQEBVwIFAVgFAmJWCQECYmkKBQJjUQUCY1IFAmNUBQJjaQUCY3IFAmNTBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJjVQUCY1YFA25pbAkAnwoNBQJjUAUCY1QFAmNpBQJjZAUCY2YFAmNjBQJiWQUCY2IFAmNXBQJjVQUCY1YFAmN0BQJjdgECY1gBAmNZBAJiTAkBAmFPAAQCY1oJAJEDAgUCYkwFAXIEAmRhCQCRAwIFAmJMBQFzBAJjYgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJMBQFwBAJiTQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJMBQF0BAJiTgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJMBQF1BAJkYgkBAmJ4AQUCY1oEAmRjCQECYngBBQJkYQQCY2gDCQAAAggFAmNZCW9yZGVyVHlwZQUDQnV5CQECYkMEBQJiTQUCYk4JAGQCBQJkYggFAmNZBmFtb3VudAUCZGMJAQJiQwQFAmJNBQJiTgkAZQIFAmRiCAUCY1kGYW1vdW50BQJkYwQCY2kJAQFHAgUCY2gFAWIDAwMJAQJhTQAGCQAAAgUCY2IFAW0GCQAAAgUCY2IFAW4JAAIBAhxFeGNoYW5nZSBvcGVyYXRpb25zIGRpc2FibGVkBAJkZAgIBQJjWQlhc3NldFBhaXILYW1vdW50QXNzZXQEAmRlAwkAAAIFAmRkBQR1bml0AgVXQVZFUwkA2AQBCQEFdmFsdWUBBQJkZAQCZGYICAUCY1kJYXNzZXRQYWlyCnByaWNlQXNzZXQEAmRnAwkAAAIFAmRmBQR1bml0AgVXQVZFUwkA2AQBCQEFdmFsdWUBBQJkZgMDCQECIT0CBQJkZQUCY1oGCQECIT0CBQJkZwUCZGEJAAIBAhNXcm9uZyBvcmRlciBhc3NldHMuBAJkaAgFAmNZBXByaWNlBAJkaQkAawMFAWIFAmJOBQJiTQQCZGoJAQFKAwUCZGgFAWIFAmRpBAJkawMJAAACCAUCY1kJb3JkZXJUeXBlBQNCdXkJAGcCBQJjaQUCZGoJAGcCBQJkagUCY2kGAQJkbAECZG0DCQECIT0CCQCQAwEIBQJkbQhwYXltZW50cwABCQACAQIdZXhhY3RseSAxIHBheW1lbnQgaXMgZXhwZWN0ZWQEAmRuCQEFdmFsdWUBCQCRAwIIBQJkbQhwYXltZW50cwAABAJiVwkBBXZhbHVlAQgFAmRuB2Fzc2V0SWQEAmRvCAUCZG4GYW1vdW50BAJjSAkBAmJVBAkA2AQBCAUCZG0NdHJhbnNhY3Rpb25JZAkA2AQBBQJiVwUCZG8IBQJkbQZjYWxsZXIEAmNuCAUCY0gCXzEEAmNvCAUCY0gCXzIEAmNiCQENcGFyc2VJbnRWYWx1ZQEIBQJjSAJfOQQCY3AIBQJjSANfMTADAwkBAmFNAAYJAAACBQJjYgUBbgkAAgEJAKwCAgIsR2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCY2IJAJcKBQUCY24FAmNvBQJkbwUCYlcFAmNwAQJkcAMCZG0CY3ICY3gDCQECIT0CCQCQAwEIBQJkbQhwYXltZW50cwACCQACAQIfZXhhY3RseSAyIHBheW1lbnRzIGFyZSBleHBlY3RlZAQCZHEJAQV2YWx1ZQEJAJEDAggFAmRtCHBheW1lbnRzAAAEAmRyCQEFdmFsdWUBCQCRAwIIBQJkbQhwYXltZW50cwABBAJkcwkBAmNxCQkA2AQBCAUCZG0NdHJhbnNhY3Rpb25JZAUCY3IIBQJkcQZhbW91bnQIBQJkcQdhc3NldElkCAUCZHIGYW1vdW50CAUCZHIHYXNzZXRJZAkApQgBCAUCZG0GY2FsbGVyBwUCY3gEAmNiCQENcGFyc2VJbnRWYWx1ZQEIBQJkcwJfOAMDAwkBAmFNAAYJAAACBQJjYgUBbAYJAAACBQJjYgUBbgkAAgEJAKwCAgIsUHV0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCY2IFAmRzAQJkdAECZHUEAmR2CQD8BwQFAmFLAgRlbWl0CQDMCAIFAmR1BQNuaWwFA25pbAMJAAACBQJkdgUCZHYEAmR3BAJhSQUCZHYDCQABAgUCYUkCB0FkZHJlc3MEAmR4BQJhSQkA/AcEBQJkeAIEZW1pdAkAzAgCBQJkdQUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZHcFAmR3BQJkdQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZHkBAmR1BAJkegkAawMFAmR1BQJhZQUBYgkAlAoCCQBlAgUCZHUFAmR6BQJkegECZEEEAmRCAmRDAVgBWQQCZEQJAAACBQFZBQR1bml0BAJkRQkBAmJ4AQkBAmFUAQUCYmIEAmRGCQECYngBCQECYVQBBQJiYwQCZEcDCQAAAgUCZEMFAmJiBgMJAAACBQJkQwUCYmMHCQECYUUBAg1pbnZhbGlkIGFzc2V0BAJkSAMFAmRECQCUCgIFAmRFBQJkRgMFAmRHCQCUCgIJAGUCBQJkRQUCZEIFAmRGCQCUCgIFAmRFCQBlAgUCZEYFAmRCBAJkSQgFAmRIAl8xBAJkSggFAmRIAl8yBAJkSwMFAmRHCQCUCgIFAmRCAAAJAJQKAgAABQJkQgQCZEwIBQJkSwJfMQQCZE0IBQJkSwJfMgQCZE4ICQECZHkBBQJkTAJfMQQCZE8ICQECZHkBBQJkTQJfMQQCZFAJAQJkeQEFAmRCBAJkUQgFAmRQAl8xBAJkeggFAmRQAl8yBAJkUgkAZAIFAmRJBQJkTgQCZFMJAGQCBQJkSgUCZE8EAmRUCQECYnoCCQEBRAIFAmRTBQJiZQkBAUQCBQJkUgUCYmQEAmRVCQEBRwIFAmRUBQFiBAJkVgMFAmRHBQJkSQUCZEoEAmRXCQC2AgEFAmRWBAJkWAkAtgIBCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmJhCQCsAgIJAKwCAgIGYXNzZXQgCQDYBAEFAmJhAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCZFkDCQC/AgIFAmRYBQFmBgkBAmFFAQIiaW5pdGlhbCBkZXBvc2l0IHJlcXVpcmVzIGFsbCBjb2lucwMJAAACBQJkWQUCZFkEAmRaCQC2AgEFAmRRBAJlYQkAlgMBCQDMCAIAAAkAzAgCCQCgAwEJALoCAgkAuQICBQJkWAkAuAICCQEKc3FydEJpZ0ludAQJALcCAgUBZAkAugICCQC5AgIFAmRaBQFkBQJkVwASABIFBERPV04FAWQFAWQFA25pbAQCY1cDBQJkRAUDbmlsCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBUwAFAmRVCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBVAIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmRVCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFXAgkApQgBCQEFdmFsdWUBBQFYCQDYBAEJAQV2YWx1ZQEFAVkJAQJiaQoFAmRMBQJkTQUCZWEFAmRVAAAAAAUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAAAAAAFA25pbAQCZWIJAQJiegIJAQFEAgUCZEoFAmJlCQEBRAIFAmRJBQJiZAQCZWMJAQFHAgUCZWIFAWIEAmVkBAJlZQMFAmRHCQCUCgIFAmRMBQJkSQkAlAoCBQJkTQUCZEoEAmR1CAUCZWUCXzEEAmVmCAUCZWUCXzIEAmVnCQCgAwEJALwCAwUCZFgJALYCAQkAaQIFAmR1AAIJALYCAQUCZWYJAGsDCQBlAgUCZWEFAmVnBQFiBQJlZwkAlgoEBQJlYQUCY1cFAmR6BQJlZAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZWgFAmVpAmRRAmRDAVgBWQQCZEQJAAACBQFZBQR1bml0BAJlagkAzAgCAwkAAAIFAmRDBQJiYQYJAQJhRQECEGludmFsaWQgbHAgYXNzZXQFA25pbAMJAAACBQJlagUCZWoEAmVrAwkAAAIFAmVpBQJiYgYDCQAAAgUCZWkFAmJjBwkBAmFFAQINaW52YWxpZCBhc3NldAQCZWwDBQJlawkAtgIBCQECYngBCQECYVQBBQJiYgkAtgIBCQECYngBCQECYVQBBQJiYwQCZW0JAQJieAEJAQJhVAEFAmJiBAJlbgkBAmJ4AQkBAmFUAQUCYmMEAmVvAwUCZWsFAmVtBQJlbgQCZXAJALYCAQUCZW8EAmRYCQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYmEJAKwCAgkArAICAgZhc3NldCAJANgEAQUCYmECDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJlcQkAtgIBBQJkUQQCZXIJAJYDAQkAzAgCAAAJAMwIAgkAoAMBCQC6AgIJALkCAgUCZWwJALgCAgUBZAkAdgYJALgCAgUBZAkAugICCQC5AgIFAmVxBQFkBQJkWAASBQFoAAAAEgUERE9XTgUBZAUDbmlsBAJlcwkBAmR5AQUCZXIEAmV0CAUCZXMCXzEEAmR6CAUCZXMCXzIEAmV1AwUCZWsJAJYKBAUCZXQAAAkAZQIFAmVtBQJlcgUCZW4JAJYKBAAABQJldAUCZW0JAGUCBQJlbgUCZXIEAmV2CAUCZXUCXzEEAmV3CAUCZXUCXzIEAmV4CAUCZXUCXzMEAmV5CAUCZXUCXzQEAmRUCQECYnoCCQEBRAIFAmV5BQJiZQkBAUQCBQJleAUCYmQEAmRVCQEBRwIFAmRUBQFiBAJjVwMFAmREBQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAVoCCQClCAEJAQV2YWx1ZQEFAVgJANgEAQkBBXZhbHVlAQUBWQkBAmJ0BgUCZXYFAmV3BQJkUQUCZFUFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFTAAUCZFUJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFUAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZFUFA25pbAQCZWIJAQJiegIJAQFEAgUCZW4FAmJlCQEBRAIFAmVtBQJiZAQCZWMJAQFHAgUCZWIFAWIEAmVkBAJlegkAaAIJAKADAQkAvAIDBQJlbAUCZXEFAmRYAAIJAGsDCQBlAgUCZXQFAmV6BQFiBQJlegkAlgoEBQJldAUCY1cFAmR6BQJlZAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZUEDAmVCAmVDAmNjBAJlRAkAaQIJAGwGCQBoAgUCZUIFAmVDAAAABQABAAAFBERPV04FAmNjBQJlRAECZUUABAJiTAkBAmFPAAQCYlkJANkEAQkAkQMCBQJiTAUBcQQCZUYJAJEDAgUCYkwFAXIEAmRhCQCRAwIFAmJMBQFzBAJlRwkBAmJ4AQUCZUYEAmVICQECYngBBQJkYQQCY2MICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYlkJAKwCAgkArAICAgZBc3NldCAJANgEAQUCYlkCDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJlRAkBAmVBAwUCZUcFAmVIBQJjYwUCZUQBAmVJAAQCYUkJAKIIAQkBAVEAAwkAAQIFAmFJAgZTdHJpbmcEAmVKBQJhSQkA2QQBBQJlSgMJAAECBQJhSQIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJlSwAEAmFJCQCiCAEJAQFSAAMJAAECBQJhSQIGU3RyaW5nBAJlSgUCYUkJANkEAQUCZUoDCQABAgUCYUkCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgECZUwBAmRtBAJhSQkBAmVJAAMJAAECBQJhSQIKQnl0ZVZlY3RvcgQCZU0FAmFJCQAAAggFAmRtD2NhbGxlclB1YmxpY0tleQUCZU0DCQABAgUCYUkCBFVuaXQJAAACCAUCZG0GY2FsbGVyBQR0aGlzCQACAQILTWF0Y2ggZXJyb3IBAmVOAQJkbQQCZU8JAAIBAhFQZXJtaXNzaW9uIGRlbmllZAQCYUkJAQJlSQADCQABAgUCYUkCCkJ5dGVWZWN0b3IEAmVNBQJhSQMJAAACCAUCZG0PY2FsbGVyUHVibGljS2V5BQJlTQYFAmVPAwkAAQIFAmFJAgRVbml0AwkAAAIIBQJkbQZjYWxsZXIFBHRoaXMGBQJlTwkAAgECC01hdGNoIGVycm9yGwJkbQEKc2V0TWFuYWdlcgECZVAEAmVRCQECZU4BBQJkbQMJAAACBQJlUQUCZVEEAmVSCQDZBAEFAmVQAwkAAAIFAmVSBQJlUgkAzAgCCQELU3RyaW5nRW50cnkCCQEBUgAFAmVQBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZG0BDmNvbmZpcm1NYW5hZ2VyAAQCZVMJAQJlSwAEAmVUAwkBCWlzRGVmaW5lZAEFAmVTBgkAAgECEk5vIHBlbmRpbmcgbWFuYWdlcgMJAAACBQJlVAUCZVQEAmVVAwkAAAIIBQJkbQ9jYWxsZXJQdWJsaWNLZXkJAQV2YWx1ZQEFAmVTBgkAAgECG1lvdSBhcmUgbm90IHBlbmRpbmcgbWFuYWdlcgMJAAACBQJlVQUCZVUJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAVEACQDYBAEJAQV2YWx1ZQEFAmVTCQDMCAIJAQtEZWxldGVFbnRyeQEJAQFSAAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRtAQNwdXQCAmNyAmVWAwkAZgIAAAUCY3IJAAIBAiBJbnZhbGlkIHNsaXBwYWdlVG9sZXJhbmNlIHBhc3NlZAQCZHMJAQJkcAMFAmRtBQJjcgYEAmNUCAUCZHMCXzIEAmJZCAUCZHMCXzcEAmNwCAUCZHMCXzkEAmNVCAUCZHMDXzEwBAJjVggFAmRzA18xMQQCZVcIBQJkcwNfMTIEAmVYCAUCZHMDXzEzBAJkdgkA/AcEBQJhSwIEZW1pdAkAzAgCBQJjVAUDbmlsBQNuaWwDCQAAAgUCZHYFAmR2BAJkdwQCYUkFAmR2AwkAAQIFAmFJAgdBZGRyZXNzBAJkeAUCYUkJAPwHBAUCZHgCBGVtaXQJAMwIAgUCY1QFA25pbAUDbmlsBQR1bml0AwkAAAIFAmR3BQJkdwQCZVkDCQBmAgUCY1UAAAkA/AcEBQJiaAIDcHV0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmVXBQJjVQUDbmlsBQNuaWwDCQAAAgUCZVkFAmVZBAJlWgMJAGYCBQJjVgAACQD8BwQFAmJoAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZVgFAmNWBQNuaWwFA25pbAMJAAACBQJlWgUCZVoEAmZhAwUCZVYEAmZiCQD8BwQFAmJnAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiWQUCY1QFA25pbAMJAAACBQJmYgUCZmIFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZG0GY2FsbGVyBQJjVAUCYlkFA25pbAkAzggCBQJjcAUCZmEJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZG0BCnB1dEZvckZyZWUBAmZjAwkAZgIAAAUCZmMJAAIBAhRJbnZhbGlkIHZhbHVlIHBhc3NlZAQCZHMJAQJkcAMFAmRtBQJmYwcIBQJkcwJfOQJkbQEJcHV0T25lVGtuAgJmZAJmZQQCZmYKAAJmZwkA/AcEBQJhSwIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmZnAgdCb29sZWFuBQJmZwkAAgEJAKwCAgkAAwEFAmZnAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJmaAMDAwkBAmFNAAYJAAACBQJhWgUBbAYJAAACBQJhWgUBbgYFAmZmBAJlagkAzAgCAwMJAQEhAQUCZmgGCQECZUwBBQJkbQYJAQJhRQECIXB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmRtCHBheW1lbnRzAAEGCQECYUUBAh5leGFjdGx5IDEgcGF5bWVudCBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJlagUCZWoEAmZpCQCRAwIIBQJkbQhwYXltZW50cwAABAJkQwgFAmZpB2Fzc2V0SWQEAmRCCAUCZmkGYW1vdW50BAFYCAUCZG0GY2FsbGVyBAFZCAUCZG0NdHJhbnNhY3Rpb25JZAQCZmoJAQJkQQQFAmRCBQJkQwUBWAUBWQQCZmsIBQJmagJfMQQCY1cIBQJmagJfMgQCZHoIBQJmagJfMwQCZmwIBQJmagJfNAQCZm0DAwkAZgIFAmZkAAAJAGYCBQJmZAUCZmsHCQECYUUBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmZkBQNuaWwCAAUCZmsEAmR2CQECZHQBBQJmbQMJAAACBQJkdgUCZHYEAmZhAwUCZmUEAmZuCQD8BwQFAmJnAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiYQUCZm0FA25pbAMJAAACBQJmbgUCZm4FA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZG0GY2FsbGVyBQJmbQUCYmEFA25pbAQCZm8DCQBmAgUCZHoAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhTAUCZHoFAmRDBQNuaWwFA25pbAkAlAoCCQDOCAIJAM4IAgUCY1cFAmZhBQJmbwUCZm0JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZG0BEXB1dE9uZVRrblJFQURPTkxZAgJkQwJkQgQCZnAJAQJkQQQFAmRCCQECYVIBBQJkQwUEdW5pdAUEdW5pdAQCZmsIBQJmcAJfMQQCY1cIBQJmcAJfMgQCZHoIBQJmcAJfMwQCZmwIBQJmcAJfNAkAlAoCBQNuaWwJAJUKAwUCZmsFAmR6BQJmbAJkbQEJZ2V0T25lVGtuAgJmcQJmZAQCZmYKAAJmZwkA/AcEBQJhSwIoaXNQb29sT25lVG9rZW5PcGVyYXRpb25zRGlzYWJsZWRSRUFET05MWQkAzAgCCQClCAEFBHRoaXMFA25pbAUDbmlsAwkAAQIFAmZnAgdCb29sZWFuBQJmZwkAAgEJAKwCAgkAAwEFAmZnAhwgY291bGRuJ3QgYmUgY2FzdCB0byBCb29sZWFuBAJmcgMDCQECYU0ABgkAAAIFAmFaBQFuBgUCZmYEAmVqCQDMCAIDAwkBASEBBQJmcgYJAQJlTAEFAmRtBgkBAmFFAQIhZ2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCZG0IcGF5bWVudHMAAQYJAQJhRQECHmV4YWN0bHkgMSBwYXltZW50IGFyZSBleHBlY3RlZAUDbmlsAwkAAAIFAmVqBQJlagQCZWkJAQJhUgEFAmZxBAJmaQkAkQMCCAUCZG0IcGF5bWVudHMAAAQCZEMIBQJmaQdhc3NldElkBAJkUQgFAmZpBmFtb3VudAQBWAgFAmRtBmNhbGxlcgQBWQgFAmRtDXRyYW5zYWN0aW9uSWQEAmZzCQECZWgFBQJlaQUCZFEFAmRDBQFYBQFZBAJmdAgFAmZzAl8xBAJjVwgFAmZzAl8yBAJkeggFAmZzAl8zBAJmbAgFAmZzAl80BAJkdQMDCQBmAgUCZmQAAAkAZgIFAmZkBQJmdAcJAQJhRQEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZmQFA25pbAIABQJmdAQCZnUJAPwHBAUCYUsCBGJ1cm4JAMwIAgUCZFEFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZEMFAmRRBQNuaWwDCQAAAgUCZnUFAmZ1BAJmdgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQFYBQJkdQUCZWkFA25pbAQCZm8DCQBmAgUCZHoAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhTAUCZHoFAmVpBQNuaWwFA25pbAkAlAoCCQDOCAIJAM4IAgUCY1cFAmZ2BQJmbwUCZHUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZG0BEWdldE9uZVRrblJFQURPTkxZAgJlaQJkUQQCZncJAQJlaAUJAQJhUgEFAmVpBQJkUQUCYmEFBHVuaXQFBHVuaXQEAmZ0CAUCZncCXzEEAmNXCAUCZncCXzIEAmR6CAUCZncCXzMEAmZsCAUCZncCXzQJAJQKAgUDbmlsCQCVCgMFAmZ0BQJkegUCZmwCZG0BE3Vuc3Rha2VBbmRHZXRPbmVUa24DAmZ4AmZxAmZkBAJmZgoAAmZnCQD8BwQFAmFLAihpc1Bvb2xPbmVUb2tlbk9wZXJhdGlvbnNEaXNhYmxlZFJFQURPTkxZCQDMCAIJAKUIAQUEdGhpcwUDbmlsBQNuaWwDCQABAgUCZmcCB0Jvb2xlYW4FAmZnCQACAQkArAICCQADAQUCZmcCHCBjb3VsZG4ndCBiZSBjYXN0IHRvIEJvb2xlYW4EAmZyAwMJAQJhTQAGCQAAAgUCYVoFAW4GBQJmZgQCZWoJAMwIAgMDCQEBIQEFAmZyBgkBAmVMAQUCZG0GCQECYUUBAiFnZXQgb3BlcmF0aW9uIGlzIGJsb2NrZWQgYnkgYWRtaW4JAMwIAgMJAAACCQCQAwEIBQJkbQhwYXltZW50cwAABgkBAmFFAQIYbm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBQNuaWwDCQAAAgUCZWoFAmVqBAJlaQkBAmFSAQUCZnEEAVgIBQJkbQZjYWxsZXIEAVkIBQJkbQ10cmFuc2FjdGlvbklkBAJmeQkA/AcEBQJiZwIHdW5zdGFrZQkAzAgCCQDYBAEFAmJhCQDMCAIFAmZ4BQNuaWwFA25pbAMJAAACBQJmeQUCZnkEAmZ6CQECZWgFBQJlaQUCZngFAmJhBQFYBQFZBAJmdAgFAmZ6Al8xBAJjVwgFAmZ6Al8yBAJkeggFAmZ6Al8zBAJmbAgFAmZ6Al80BAJkdQMDCQBmAgUCZmQAAAkAZgIFAmZkBQJmdAcJAQJhRQEJALkJAgkAzAgCAh9hbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZmQFA25pbAIABQJmdAQCZnUJAPwHBAUCYUsCBGJ1cm4JAMwIAgUCZngFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYmEFAmZ4BQNuaWwDCQAAAgUCZnUFAmZ1BAJmdgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZG0GY2FsbGVyBQJkdQUCZWkFA25pbAQCZm8DCQBmAgUCZHoAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhTAUCZHoFAmVpBQNuaWwFA25pbAkAlAoCCQDOCAIJAM4IAgUCY1cFAmZ2BQJmbwUCZHUJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZG0BA2dldAAEAmNICQECZGwBBQJkbQQCZkEIBQJjSAJfMQQCY28IBQJjSAJfMgQCZG8IBQJjSAJfMwQCYlcIBQJjSAJfNAQCY3AIBQJjSAJfNQQCZkIJAPwHBAUCYUsCBGJ1cm4JAMwIAgUCZG8FA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYlcFAmRvBQNuaWwDCQAAAgUCZkIFAmZCBQJjcAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkbQEJZ2V0Tm9MZXNzAgJmQwJmRAQCY0gJAQJkbAEFAmRtBAJjbggFAmNIAl8xBAJjbwgFAmNIAl8yBAJkbwgFAmNIAl8zBAJiVwgFAmNIAl80BAJjcAgFAmNIAl81AwkAZgIFAmZDBQJjbgkAAgEJAKwCAgkArAICCQCsAgICHG5vTGVzc1RoZW5BbXRBc3NldCBmYWlsZWQ6ICAJAKQDAQUCY24CAyA8IAkApAMBBQJmQwMJAGYCBQJmRAUCY28JAAIBCQCsAgIJAKwCAgkArAICAh1ub0xlc3NUaGVuUHJpY2VBc3NldCBmYWlsZWQ6IAkApAMBBQJjbwIDIDwgCQCkAwEFAmZEBAJmQgkA/AcEBQJhSwIEYnVybgkAzAgCBQJkbwUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiVwUCZG8FA25pbAMJAAACBQJmQgUCZkIFAmNwCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRtAQ11bnN0YWtlQW5kR2V0AQJkdQQCZkUDCQECIT0CCQCQAwEIBQJkbQhwYXltZW50cwAACQACAQIYTm8gcGF5bWVudHMgYXJlIGV4cGVjdGVkBgMJAAACBQJmRQUCZkUEAmJMCQECYU8ABAJiWQkA2QQBCQCRAwIFAmJMBQFxBAJmeQkA/AcEBQJiZwIHdW5zdGFrZQkAzAgCCQDYBAEFAmJZCQDMCAIFAmR1BQNuaWwFA25pbAMJAAACBQJmeQUCZnkEAmNICQECYlUECQDYBAEIBQJkbQ10cmFuc2FjdGlvbklkCQDYBAEFAmJZBQJkdQgFAmRtBmNhbGxlcgQCY2IJAQ1wYXJzZUludFZhbHVlAQgFAmNIAl85BAJjcAgFAmNIA18xMAQCZkYDAwkBAmFNAAYJAAACBQJjYgUBbgkAAgEJAKwCAgIsR2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCY2IGAwkAAAIFAmZGBQJmRgQCZkIJAPwHBAUCYUsCBGJ1cm4JAMwIAgUCZHUFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYlkFAmR1BQNuaWwDCQAAAgUCZkIFAmZCBQJjcAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkbQETdW5zdGFrZUFuZEdldE5vTGVzcwMCZngCZkcCZkQEAmZyAwkBAmFNAAYJAAACBQJhWgUBbgQCZWoJAMwIAgMJAQEhAQUCZnIGCQACAQIhZ2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluCQDMCAIDCQAAAgkAkAMBCAUCZG0IcGF5bWVudHMAAAYJAAIBAhhubyBwYXltZW50cyBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJlagUCZWoEAmZ5CQD8BwQFAmJnAgd1bnN0YWtlCQDMCAIJANgEAQUCYmEJAMwIAgUCZngFA25pbAUDbmlsAwkAAAIFAmZ5BQJmeQQCY0gJAQJiVQQJANgEAQgFAmRtDXRyYW5zYWN0aW9uSWQJANgEAQUCYmEFAmZ4CAUCZG0GY2FsbGVyBAJjbggFAmNIAl8xBAJjbwgFAmNIAl8yBAJjcAgFAmNIA18xMAQCZkgJAMwIAgMJAGcCBQJjbgUCZkcGCQACAQkAuQkCCQDMCAICLGFtb3VudCBhc3NldCBhbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZkcFA25pbAIACQDMCAIDCQBnAgUCY28FAmZEBgkAAgEJALkJAgkAzAgCAitwcmljZSBhc3NldCBhbW91bnQgdG8gcmVjZWl2ZSBpcyBsZXNzIHRoYW4gCQDMCAIJAKQDAQUCZkQFA25pbAIABQNuaWwDCQAAAgUCZkgFAmZIBAJmQgkA/AcEBQJhSwIEYnVybgkAzAgCBQJmeAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiYQUCZngFA25pbAMJAAACBQJmQgUCZkIFAmNwCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRtAQhhY3RpdmF0ZQICZkkCZkoDCQECIT0CCQClCAEIBQJkbQZjYWxsZXIJAKUIAQUCYUsJAAIBAhJwZXJtaXNzaW9ucyBkZW5pZWQJAJQKAgkAzAgCCQELU3RyaW5nRW50cnkCCQECYWEABQJmSQkAzAgCCQELU3RyaW5nRW50cnkCCQECYWIABQJmSgUDbmlsAgdzdWNjZXNzAmRtAQpyZWZyZXNoS0xwAAQCZksJAQt2YWx1ZU9yRWxzZQIJAJ8IAQUCYWcAAAQCZkwJAQJhRQEJALkJAgkAzAgCCQEFdmFsdWUBCQCiCAEFAmFoCQDMCAICLmJsb2NrcyBoYXZlIG5vdCBwYXNzZWQgc2luY2UgdGhlIHByZXZpb3VzIGNhbGwFA25pbAIBIAQCZk0DCQBnAgkAZQIFBmhlaWdodAUCZksAHgYFAmZMAwkAAAIFAmZNBQJmTQQCZUQJAQJhSAEJAQJlRQAJAMwIAgkBDEludGVnZXJFbnRyeQIFAmFnBQZoZWlnaHQJAMwIAgkBDEludGVnZXJFbnRyeQIFAmFmBQJlRAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRtARxnZXRQb29sQ29uZmlnV3JhcHBlclJFQURPTkxZAAkAlAoCBQNuaWwJAQJhTwACZG0BHGdldEFjY0JhbGFuY2VXcmFwcGVyUkVBRE9OTFkBAmJ5CQCUCgIFA25pbAkBAmJ4AQUCYnkCZG0BGWNhbGNQcmljZXNXcmFwcGVyUkVBRE9OTFkDAmJGAmJHAmJLBAJiVAkBAmJKAwUCYkYFAmJHBQJiSwkAlAoCBQNuaWwJAMwIAgkApgMBCQCRAwIFAmJUAAAJAMwIAgkApgMBCQCRAwIFAmJUAAEJAMwIAgkApgMBCQCRAwIFAmJUAAIFA25pbAJkbQEUdG9YMThXcmFwcGVyUkVBRE9OTFkCAUUBRgkAlAoCBQNuaWwJAKYDAQkBAUQCBQFFBQFGAmRtARZmcm9tWDE4V3JhcHBlclJFQURPTkxZAgFIAUkJAJQKAgUDbmlsCQEBRwIJAKcDAQUBSAUBSQJkbQEeY2FsY1ByaWNlQmlnSW50V3JhcHBlclJFQURPTkxZAgJiQQJiQgkAlAoCBQNuaWwJAKYDAQkBAmJ6AgkApwMBBQJiQQkApwMBBQJiQgJkbQEjZXN0aW1hdGVQdXRPcGVyYXRpb25XcmFwcGVyUkVBRE9OTFkJAmJWAmNyAmNzAmN0AmN1AmN2AVgCY3cCY3gJAJQKAgUDbmlsCQECY3EJBQJiVgUCY3IFAmNzBQJjdAUCY3UFAmN2BQFYBQJjdwUCY3gCZG0BI2VzdGltYXRlR2V0T3BlcmF0aW9uV3JhcHBlclJFQURPTkxZBAJiVgJiVwJiWAFYBAJjSAkBAmJVBAUCYlYFAmJXBQJiWAkBEUBleHRyTmF0aXZlKDEwNjIpAQUBWAkAlAoCBQNuaWwJAJwKCggFAmNIAl8xCAUCY0gCXzIIBQJjSAJfMwgFAmNIAl80CAUCY0gCXzUIBQJjSAJfNggFAmNIAl83CQCmAwEIBQJjSAJfOAgFAmNIAl85CAUCY0gDXzEwAmRtAQ1zdGF0c1JFQURPTkxZAAQCYkwJAQJhTwAEAmJZCQDZBAEJAJEDAgUCYkwFAXEEAmNaCQCRAwIFAmJMBQFyBAJkYQkAkQMCBQJiTAUBcwQCY0EJAJEDAgUCYkwFAXYEAmNCCQCRAwIFAmJMBQF3BAJiTQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJMBQF0BAJiTgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJMBQF1BAJmTggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJiWQkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJiWQIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmRiCQECYngBBQJjWgQCZGMJAQJieAEFAmRhBAJmTwMJAAACBQJmTgAACQDMCAIFAWUJAMwIAgUBZQkAzAgCBQFlBQNuaWwJAQJiSgMFAmRiBQJkYwUCZk4EAmNpAAAEAmZQCQEBRwIJAJEDAgUCZk8AAQUBYgQCZlEJAQFHAgkAkQMCBQJmTwACBQFiBAJmUgkBBXZhbHVlAQkAmggCBQJhSwkBAmFzAQkApQgBBQR0aGlzCQCUCgIFA25pbAkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCZGIJAMwIAgkApAMBBQJkYwkAzAgCCQCkAwEFAmZOCQDMCAIJAKQDAQUCY2kJAMwIAgkApAMBBQJmUAkAzAgCCQCkAwEFAmZRCQDMCAIJAKQDAQUCZlIFA25pbAUBagJkbQEgZXZhbHVhdGVQdXRCeUFtb3VudEFzc2V0UkVBRE9OTFkBAmNzBAJiTAkBAmFPAAQCYlkJANkEAQkAkQMCBQJiTAUBcQQCY3kJAJEDAgUCYkwFAXIEAmJaCQDZBAEFAmN5BAJjegkAkQMCBQJiTAUBcwQCY2EJANkEAQUCY3oEAmJNCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkwFAXQEAmJOCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkwFAXUEAmNiCQCRAwIFAmJMBQFwBAJmTggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJiWQkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJiWQIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmRiCQECYngBBQJjeQQCZGMJAQJieAEFAmN6BAJiSAkBAUQCBQJkYgUCYk0EAmJJCQEBRAIFAmRjBQJiTgQCY2gDCQAAAgUCZk4AAAUBZQkBAmJ6AgUCYkkFAmJIBAJjRQkBAUQCBQJjcwUCYk0EAmNGCQC8AgMFAmNFBQJjaAUBZAQCY3UJAQFHAgUCY0YFAmJOBAJkcwkBAmNxCQIAAKDCHgUCY3MFAmJaBQJjdQUCY2ECAAYHBAJjUAgFAmRzAl8xBAJmUwgFAmRzAl8zBAJjZAgFAmRzAl80BAJjZggFAmRzAl81BAJjYwgFAmRzAl82CQCUCgIFA25pbAkAuQkCCQDMCAICECVkJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJjUAkAzAgCCQCkAwEJAQFHAgUCY2gFAWIJAMwIAgkApAMBBQJjZAkAzAgCCQCkAwEFAmNmCQDMCAIJAKQDAQUCY2MJAMwIAgUCY2IJAMwIAgkApAMBBQJjcwkAzAgCCQCkAwEFAmN1BQNuaWwFAWoCZG0BH2V2YWx1YXRlUHV0QnlQcmljZUFzc2V0UkVBRE9OTFkBAmN1BAJiTAkBAmFPAAQCYlkJANkEAQkAkQMCBQJiTAUBcQQCY3kJAJEDAgUCYkwFAXIEAmJaCQDZBAEFAmN5BAJjegkAkQMCBQJiTAUBcwQCY2EJANkEAQUCY3oEAmJNCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkwFAXQEAmJOCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkwFAXUEAmNiCQCRAwIFAmJMBQFwBAJmTggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJiWQkArAICCQCsAgICBkFzc2V0IAkA2AQBBQJiWQIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmZUCQECYngBBQJjeQQCZlUJAQJieAEFAmN6BAJmVgkBAUQCBQJmVAUCYk0EAmZXCQEBRAIFAmZVBQJiTgQCY2gDCQAAAgUCZk4AAAUBZQkBAmJ6AgUCZlcFAmZWBAJjRgkBAUQCBQJjdQUCYk4EAmNFCQC8AgMFAmNGBQFkBQJjaAQCY3MJAQFHAgUCY0UFAmJNBAJkcwkBAmNxCQIAAKDCHgUCY3MFAmJaBQJjdQUCY2ECAAYHBAJjUAgFAmRzAl8xBAJmUwgFAmRzAl8zBAJjZAgFAmRzAl80BAJjZggFAmRzAl81BAJjYwgFAmRzAl82CQCUCgIFA25pbAkAuQkCCQDMCAICECVkJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJjUAkAzAgCCQCkAwEJAQFHAgUCY2gFAWIJAMwIAgkApAMBBQJjZAkAzAgCCQCkAwEFAmNmCQDMCAIJAKQDAQUCY2MJAMwIAgUCY2IJAMwIAgkApAMBBQJjcwkAzAgCCQCkAwEFAmN1BQNuaWwFAWoCZG0BE2V2YWx1YXRlR2V0UkVBRE9OTFkCAmZYAmZZBAJjSAkBAmJVBAIABQJmWAUCZlkFBHRoaXMEAmNuCAUCY0gCXzEEAmNvCAUCY0gCXzIEAmNkCAUCY0gCXzUEAmNmCAUCY0gCXzYEAmNjCAUCY0gCXzcEAmNpCAUCY0gCXzgEAmNiCQENcGFyc2VJbnRWYWx1ZQEIBQJjSAJfOQkAlAoCBQNuaWwJALkJAgkAzAgCAg4lZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmNuCQDMCAIJAKQDAQUCY28JAMwIAgkApAMBBQJjZAkAzAgCCQCkAwEFAmNmCQDMCAIJAKQDAQUCY2MJAMwIAgkApgMBBQJjaQkAzAgCCQCkAwEFAmNiBQNuaWwFAWoBAmZaAQJnYQAEAmdiBAJhSQkBAmVJAAMJAAECBQJhSQIKQnl0ZVZlY3RvcgQCZU0FAmFJBQJlTQMJAAECBQJhSQIEVW5pdAgFAmZaD3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yBAJhSQUCZloDCQABAgUCYUkCBU9yZGVyBAJjWQUCYUkEAmdjCQECYU4ABAJheAkBAmNYAQUCY1kEAmF5CQD0AwMIBQJjWQlib2R5Qnl0ZXMJAJEDAggFAmNZBnByb29mcwAACAUCY1kPc2VuZGVyUHVibGljS2V5BAJhegkA9AMDCAUCY1kJYm9keUJ5dGVzCQCRAwIIBQJjWQZwcm9vZnMAAQUCZ2MDAwMFAmF4BQJheQcFAmF6BwYJAQJhdwMFAmF4BQJheQUCYXoDCQABAgUCYUkCFFNldFNjcmlwdFRyYW5zYWN0aW9uBAJlSgUCYUkEAmdkCQD2AwEJAQV2YWx1ZQEIBQJlSgZzY3JpcHQEAmdlCQDbBAEJAQV2YWx1ZQEJAJ0IAgUCYUsJAQJhdQAEAmdmCQDxBwEFBHRoaXMDAwkAAAIFAmdlBQJnZAkBAiE9AgUCZ2YFAmdkBwYJAPQDAwgFAmZaCWJvZHlCeXRlcwkAkQMCCAUCZloGcHJvb2ZzAAAFAmdiCQD0AwMIBQJmWglib2R5Qnl0ZXMJAJEDAggFAmZaBnByb29mcwAABQJnYl7L510=", "chainId": 84, "height": 2331293, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: f7BQp7g3BRm7P338GrkgApNmZunkA87FNduT3FJPprM Next: GGy1hv9NfQWDYv6yVPTbtruADem49LBoSjkS6XDuWZeJ Diff:
OldNewDifferences
111111
112112 let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
113113
114+let keyKLp = makeString(["%s", "keyKlp"], SEP)
115+
116+let keyLastKLpRefreshed = makeString(["%s", "keyLastKLpRefreshed"], SEP)
117+
118+let keyRefreshKLpDelay = makeString(["%s", "keyRefreshKLpDelay"], SEP)
119+
114120 func keyFactoryConfig () = "%s__factoryConfig"
115121
116122
149155 func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
150156
151157
158+func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
159+
160+
161+func asInt (val) = match val {
162+ case valInt: Int =>
163+ valInt
164+ case _ =>
165+ throw("fail to cast into Int")
166+}
167+
168+
152169 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
153170
154171 let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
183200
184201 let poolConfigParsed = parsePoolConfig(getPoolConfig())
185202
186-let $t075447710 = poolConfigParsed
203+let $t079168082 = poolConfigParsed
187204
188-let cfgPoolAddress = $t075447710._1
205+let cfgPoolAddress = $t079168082._1
189206
190-let cfgPoolStatus = $t075447710._2
207+let cfgPoolStatus = $t079168082._2
191208
192-let cfgLpAssetId = $t075447710._3
209+let cfgLpAssetId = $t079168082._3
193210
194-let cfgAmountAssetId = $t075447710._4
211+let cfgAmountAssetId = $t079168082._4
195212
196-let cfgPriceAssetId = $t075447710._5
213+let cfgPriceAssetId = $t079168082._5
197214
198-let cfgAmountAssetDecimals = $t075447710._6
215+let cfgAmountAssetDecimals = $t079168082._6
199216
200-let cfgPriceAssetDecimals = $t075447710._7
217+let cfgPriceAssetDecimals = $t079168082._7
201218
202219 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
203220
474491 else if ((paymentAssetId == cfgPriceAssetId))
475492 then false
476493 else throwErr("invalid asset")
477- let $t02257122864 = if (isEval)
494+ let $t02294323236 = if (isEval)
478495 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
479496 else if (paymentInAmountAsset)
480497 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
481498 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
482- let amountBalanceOld = $t02257122864._1
483- let priceBalanceOld = $t02257122864._2
484- let $t02286823017 = if (paymentInAmountAsset)
499+ let amountBalanceOld = $t02294323236._1
500+ let priceBalanceOld = $t02294323236._2
501+ let $t02324023389 = if (paymentInAmountAsset)
485502 then $Tuple2(paymentAmountRaw, 0)
486503 else $Tuple2(0, paymentAmountRaw)
487- let amountAssetAmountRaw = $t02286823017._1
488- let priceAssetAmountRaw = $t02286823017._2
504+ let amountAssetAmountRaw = $t02324023389._1
505+ let priceAssetAmountRaw = $t02324023389._2
489506 let amountAssetAmount = takeFee(amountAssetAmountRaw)._1
490507 let priceAssetAmount = takeFee(priceAssetAmountRaw)._1
491- let $t02313923198 = takeFee(paymentAmountRaw)
492- let paymentAmount = $t02313923198._1
493- let feeAmount = $t02313923198._2
508+ let $t02351123570 = takeFee(paymentAmountRaw)
509+ let paymentAmount = $t02351123570._1
510+ let feeAmount = $t02351123570._2
494511 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
495512 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
496513 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
513530 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
514531 let priceOld = fromX18(priceOldX18, scale8)
515532 let loss = {
516- let $t02467524842 = if (paymentInAmountAsset)
533+ let $t02504725214 = if (paymentInAmountAsset)
517534 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
518535 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
519- let amount = $t02467524842._1
520- let balance = $t02467524842._2
536+ let amount = $t02504725214._1
537+ let balance = $t02504725214._2
521538 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
522539 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
523540 }
551568 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
552569 let redeemedBigInt = toBigInt(paymentAmount)
553570 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
554- let $t02642226472 = takeFee(amountRaw)
555- let totalAmount = $t02642226472._1
556- let feeAmount = $t02642226472._2
557- let $t02647626702 = if (outInAmountAsset)
571+ let $t02679426844 = takeFee(amountRaw)
572+ let totalAmount = $t02679426844._1
573+ let feeAmount = $t02679426844._2
574+ let $t02684827074 = if (outInAmountAsset)
558575 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
559576 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
560- let outAmAmount = $t02647626702._1
561- let outPrAmount = $t02647626702._2
562- let amBalanceNew = $t02647626702._3
563- let prBalanceNew = $t02647626702._4
577+ let outAmAmount = $t02684827074._1
578+ let outPrAmount = $t02684827074._2
579+ let amBalanceNew = $t02684827074._3
580+ let prBalanceNew = $t02684827074._4
564581 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
565582 let priceNew = fromX18(priceNewX18, scale8)
566583 let commonState = if (isEval)
575592 $Tuple4(totalAmount, commonState, feeAmount, loss)
576593 }
577594 else throw("Strict value is not equal to itself.")
595+ }
596+
597+
598+func calcKLp (amountBalance,priceBalance,lpEmission) = {
599+ let updatedKLp = (pow((amountBalance * priceBalance), 0, 5, 1, 0, DOWN) / lpEmission)
600+ updatedKLp
601+ }
602+
603+
604+func refreshKLpInternal () = {
605+ let cfg = getPoolConfig()
606+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
607+ let amountAssetId = cfg[idxAmtAssetId]
608+ let priceAssetId = cfg[idxPriceAssetId]
609+ let amountAssetBalance = getAccBalance(amountAssetId)
610+ let priceAssetBalance = getAccBalance(priceAssetId)
611+ let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
612+ let updatedKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpEmission)
613+ updatedKLp
578614 }
579615
580616
753789 let paymentAmountRaw = payment.amount
754790 let userAddress = i.caller
755791 let txId = i.transactionId
756- let $t03160931739 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
757- if (($t03160931739 == $t03160931739))
792+ let $t03269232819 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
793+ let emitAmountEstimated = $t03269232819._1
794+ let commonState = $t03269232819._2
795+ let feeAmount = $t03269232819._3
796+ let bonus = $t03269232819._4
797+ let emitAmount = if (if ((minOutAmount > 0))
798+ then (minOutAmount > emitAmountEstimated)
799+ else false)
800+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
801+ else emitAmountEstimated
802+ let emitInv = emit(emitAmount)
803+ if ((emitInv == emitInv))
758804 then {
759- let bonus = $t03160931739._4
760- let feeAmount = $t03160931739._3
761- let commonState = $t03160931739._2
762- let emitAmountEstimated = $t03160931739._1
763- let emitAmount = if (if ((minOutAmount > 0))
764- then (minOutAmount > emitAmountEstimated)
765- else false)
766- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
767- else emitAmountEstimated
768- let emitInv = emit(emitAmount)
769- if ((emitInv == emitInv))
805+ let lpTransfer = if (autoStake)
770806 then {
771- let lpTransfer = if (autoStake)
772- then {
773- let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
774- if ((stakeInv == stakeInv))
775- then nil
776- else throw("Strict value is not equal to itself.")
777- }
778- else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
779- let sendFee = if ((feeAmount > 0))
780- then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
781- else nil
782- $Tuple2(((commonState ++ lpTransfer) ++ sendFee), emitAmount)
807+ let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
808+ if ((stakeInv == stakeInv))
809+ then nil
810+ else throw("Strict value is not equal to itself.")
783811 }
784- else throw("Strict value is not equal to itself.")
812+ else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
813+ let sendFee = if ((feeAmount > 0))
814+ then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
815+ else nil
816+ $Tuple2(((commonState ++ lpTransfer) ++ sendFee), emitAmount)
785817 }
786818 else throw("Strict value is not equal to itself.")
787819 }
792824
793825 @Callable(i)
794826 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
795- let $t03246832603 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
796- let emitAmountEstimated = $t03246832603._1
797- let commonState = $t03246832603._2
798- let feeAmount = $t03246832603._3
799- let bonus = $t03246832603._4
827+ let $t03354833683 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
828+ let emitAmountEstimated = $t03354833683._1
829+ let commonState = $t03354833683._2
830+ let feeAmount = $t03354833683._3
831+ let bonus = $t03354833683._4
800832 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
801833 }
802834
830862 let paymentAmount = payment.amount
831863 let userAddress = i.caller
832864 let txId = i.transactionId
833- let $t03340833543 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
834- if (($t03340833543 == $t03340833543))
865+ let $t03448834620 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
866+ let amountEstimated = $t03448834620._1
867+ let commonState = $t03448834620._2
868+ let feeAmount = $t03448834620._3
869+ let bonus = $t03448834620._4
870+ let amount = if (if ((minOutAmount > 0))
871+ then (minOutAmount > amountEstimated)
872+ else false)
873+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
874+ else amountEstimated
875+ let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
876+ if ((burnInv == burnInv))
835877 then {
836- let bonus = $t03340833543._4
837- let feeAmount = $t03340833543._3
838- let commonState = $t03340833543._2
839- let amountEstimated = $t03340833543._1
840- let amount = if (if ((minOutAmount > 0))
841- then (minOutAmount > amountEstimated)
842- else false)
843- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
844- else amountEstimated
845- let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
846- if ((burnInv == burnInv))
847- then {
848- let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
849- let sendFee = if ((feeAmount > 0))
850- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
851- else nil
852- $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
853- }
854- else throw("Strict value is not equal to itself.")
878+ let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
879+ let sendFee = if ((feeAmount > 0))
880+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
881+ else nil
882+ $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
855883 }
856884 else throw("Strict value is not equal to itself.")
857885 }
862890
863891 @Callable(i)
864892 func getOneTknREADONLY (outAssetId,paymentAmount) = {
865- let $t03417834316 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
866- let amountEstimated = $t03417834316._1
867- let commonState = $t03417834316._2
868- let feeAmount = $t03417834316._3
869- let bonus = $t03417834316._4
893+ let $t03525535393 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
894+ let amountEstimated = $t03525535393._1
895+ let commonState = $t03525535393._2
896+ let feeAmount = $t03525535393._3
897+ let bonus = $t03525535393._4
870898 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
871899 }
872900
900928 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
901929 if ((unstakeInv == unstakeInv))
902930 then {
903- let $t03514135274 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
904- if (($t03514135274 == $t03514135274))
931+ let $t03621836348 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
932+ let amountEstimated = $t03621836348._1
933+ let commonState = $t03621836348._2
934+ let feeAmount = $t03621836348._3
935+ let bonus = $t03621836348._4
936+ let amount = if (if ((minOutAmount > 0))
937+ then (minOutAmount > amountEstimated)
938+ else false)
939+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
940+ else amountEstimated
941+ let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
942+ if ((burnInv == burnInv))
905943 then {
906- let bonus = $t03514135274._4
907- let feeAmount = $t03514135274._3
908- let commonState = $t03514135274._2
909- let amountEstimated = $t03514135274._1
910- let amount = if (if ((minOutAmount > 0))
911- then (minOutAmount > amountEstimated)
912- else false)
913- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
914- else amountEstimated
915- let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
916- if ((burnInv == burnInv))
917- then {
918- let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
919- let sendFee = if ((feeAmount > 0))
920- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
921- else nil
922- $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
923- }
924- else throw("Strict value is not equal to itself.")
944+ let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
945+ let sendFee = if ((feeAmount > 0))
946+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
947+ else nil
948+ $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
925949 }
926950 else throw("Strict value is not equal to itself.")
927951 }
10501074 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
10511075 then throw("permissions denied")
10521076 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
1077+
1078+
1079+
1080+@Callable(i)
1081+func refreshKLp () = {
1082+ let lastRefreshedBlockHeight = valueOrElse(getInteger(keyLastKLpRefreshed), 0)
1083+ let delayNotReachedErrorMessage = throwErr(makeString([value(getString(keyRefreshKLpDelay)), "blocks have not passed since the previous call"], " "))
1084+ let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= 30))
1085+ then true
1086+ else delayNotReachedErrorMessage
1087+ if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
1088+ then {
1089+ let updatedKLp = asInt(refreshKLpInternal())
1090+[IntegerEntry(keyLastKLpRefreshed, height), IntegerEntry(keyKLp, updatedKLp)]
1091+ }
1092+ else throw("Strict value is not equal to itself.")
1093+ }
10531094
10541095
10551096
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 fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
6666
6767
6868 func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
6969
7070
7171 func abs (val) = if ((0 > val))
7272 then -(val)
7373 else val
7474
7575
7676 func absBigInt (val) = if ((zeroBigInt > val))
7777 then -(val)
7878 else val
7979
8080
8181 func fc () = "%s__factoryContract"
8282
8383
8484 func mpk () = "%s__managerPublicKey"
8585
8686
8787 func pmpk () = "%s__pendingManagerPublicKey"
8888
8989
9090 func pl () = "%s%s__price__last"
9191
9292
9393 func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
9494
9595
9696 func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
9797
9898
9999 func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
100100
101101
102102 func aa () = "%s__amountAsset"
103103
104104
105105 func pa () = "%s__priceAsset"
106106
107107
108108 let keyFee = "%s__fee"
109109
110110 let feeDefault = fraction(10, scale8, 10000)
111111
112112 let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
113113
114+let keyKLp = makeString(["%s", "keyKlp"], SEP)
115+
116+let keyLastKLpRefreshed = makeString(["%s", "keyLastKLpRefreshed"], SEP)
117+
118+let keyRefreshKLpDelay = makeString(["%s", "keyRefreshKLpDelay"], SEP)
119+
114120 func keyFactoryConfig () = "%s__factoryConfig"
115121
116122
117123 func keyMatcherPub () = "%s%s__matcher__publicKey"
118124
119125
120126 func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
121127
122128
123129 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
124130
125131
126132 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
127133
128134
129135 func keyAllPoolsShutdown () = "%s__shutdown"
130136
131137
132138 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
133139
134140
135141 func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
136142
137143
138144 let keyFeeCollectorAddress = "%s__feeCollectorAddress"
139145
140146 func throwOrderError (orderValid,senderValid,matcherValid) = throw(((((("order validation failed: orderValid=" + toString(orderValid)) + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
141147
142148
143149 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
144150
145151
146152 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
147153
148154
149155 func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
150156
151157
158+func fmtErr (msg) = makeString(["lp.ride:", msg], " ")
159+
160+
161+func asInt (val) = match val {
162+ case valInt: Int =>
163+ valInt
164+ case _ =>
165+ throw("fail to cast into Int")
166+}
167+
168+
152169 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
153170
154171 let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
155172
156173 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
157174
158175
159176 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
160177
161178
162179 func getPoolConfig () = {
163180 let amtAsset = getStringOrFail(this, aa())
164181 let priceAsset = getStringOrFail(this, pa())
165182 let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
166183 let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
167184 split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
168185 }
169186
170187
171188 func parseAssetId (input) = if ((input == wavesString))
172189 then unit
173190 else fromBase58String(input)
174191
175192
176193 func assetIdToString (input) = if ((input == unit))
177194 then wavesString
178195 else toBase58String(value(input))
179196
180197
181198 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]))
182199
183200
184201 let poolConfigParsed = parsePoolConfig(getPoolConfig())
185202
186-let $t075447710 = poolConfigParsed
203+let $t079168082 = poolConfigParsed
187204
188-let cfgPoolAddress = $t075447710._1
205+let cfgPoolAddress = $t079168082._1
189206
190-let cfgPoolStatus = $t075447710._2
207+let cfgPoolStatus = $t079168082._2
191208
192-let cfgLpAssetId = $t075447710._3
209+let cfgLpAssetId = $t079168082._3
193210
194-let cfgAmountAssetId = $t075447710._4
211+let cfgAmountAssetId = $t079168082._4
195212
196-let cfgPriceAssetId = $t075447710._5
213+let cfgPriceAssetId = $t079168082._5
197214
198-let cfgAmountAssetDecimals = $t075447710._6
215+let cfgAmountAssetDecimals = $t079168082._6
199216
200-let cfgPriceAssetDecimals = $t075447710._7
217+let cfgPriceAssetDecimals = $t079168082._7
201218
202219 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
203220
204221
205222 let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
206223
207224 let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
208225
209226 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)
210227
211228
212229 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)
213230
214231
215232 func getAccBalance (assetId) = if ((assetId == "WAVES"))
216233 then wavesBalance(this).available
217234 else assetBalance(this, fromBase58String(assetId))
218235
219236
220237 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
221238
222239
223240 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
224241 let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
225242 let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
226243 calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
227244 }
228245
229246
230247 func calcPrices (amAmt,prAmt,lpAmt) = {
231248 let cfg = getPoolConfig()
232249 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
233250 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
234251 let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
235252 let amAmtX18 = toX18(amAmt, amtAssetDcm)
236253 let prAmtX18 = toX18(prAmt, priceAssetDcm)
237254 let lpAmtX18 = toX18(lpAmt, scale8)
238255 let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
239256 let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
240257 [priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
241258 }
242259
243260
244261 func calculatePrices (amAmt,prAmt,lpAmt) = {
245262 let prices = calcPrices(amAmt, prAmt, lpAmt)
246263 [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
247264 }
248265
249266
250267 func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
251268 let cfg = getPoolConfig()
252269 let lpAssetId = cfg[idxPoolLPAssetId]
253270 let amAssetId = cfg[idxAmtAssetId]
254271 let prAssetId = cfg[idxPriceAssetId]
255272 let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
256273 let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
257274 let poolStatus = cfg[idxPoolStatus]
258275 let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
259276 if ((lpAssetId != pmtAssetId))
260277 then throw("Invalid asset passed.")
261278 else {
262279 let amBalance = getAccBalance(amAssetId)
263280 let amBalanceX18 = toX18(amBalance, amAssetDcm)
264281 let prBalance = getAccBalance(prAssetId)
265282 let prBalanceX18 = toX18(prBalance, prAssetDcm)
266283 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
267284 let curPrice = fromX18(curPriceX18, scale8)
268285 let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
269286 let lpEmissionX18 = toX18(lpEmission, scale8)
270287 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
271288 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
272289 let outAmAmt = fromX18(outAmAmtX18, amAssetDcm)
273290 let outPrAmt = fromX18(outPrAmtX18, prAssetDcm)
274291 let state = if ((txId58 == ""))
275292 then nil
276293 else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
277294 then unit
278295 else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
279296 then unit
280297 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)]
281298 $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
282299 }
283300 }
284301
285302
286303 func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
287304 let cfg = getPoolConfig()
288305 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
289306 let amAssetIdStr = cfg[idxAmtAssetId]
290307 let prAssetIdStr = cfg[idxPriceAssetId]
291308 let iAmtAssetId = cfg[idxIAmtAssetId]
292309 let iPriceAssetId = cfg[idxIPriceAssetId]
293310 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
294311 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
295312 let poolStatus = cfg[idxPoolStatus]
296313 let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
297314 let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
298315 let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
299316 if (if ((amAssetIdStr != inAmAssetIdStr))
300317 then true
301318 else (prAssetIdStr != inPrAssetIdStr))
302319 then throw("Invalid amt or price asset passed.")
303320 else {
304321 let amBalance = if (isEvaluate)
305322 then getAccBalance(amAssetIdStr)
306323 else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
307324 let prBalance = if (isEvaluate)
308325 then getAccBalance(prAssetIdStr)
309326 else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
310327 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
311328 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
312329 let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
313330 let amBalanceX18 = toX18(amBalance, amtAssetDcm)
314331 let prBalanceX18 = toX18(prBalance, priceAssetDcm)
315332 let res = if ((lpEmission == 0))
316333 then {
317334 let curPriceX18 = zeroBigInt
318335 let slippageX18 = zeroBigInt
319336 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
320337 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
321338 }
322339 else {
323340 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
324341 let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
325342 let slippageToleranceX18 = toX18(slippageTolerance, scale8)
326343 if (if ((curPriceX18 != zeroBigInt))
327344 then (slippageX18 > slippageToleranceX18)
328345 else false)
329346 then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
330347 else {
331348 let lpEmissionX18 = toX18(lpEmission, scale8)
332349 let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
333350 let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
334351 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
335352 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
336353 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
337354 let expAmtAssetAmtX18 = expectedAmts._1
338355 let expPriceAssetAmtX18 = expectedAmts._2
339356 let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
340357 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(expAmtAssetAmtX18, amtAssetDcm), fromX18(expPriceAssetAmtX18, priceAssetDcm), curPriceX18, slippageX18)
341358 }
342359 }
343360 let calcLpAmt = res._1
344361 let calcAmAssetPmt = res._2
345362 let calcPrAssetPmt = res._3
346363 let curPrice = fromX18(res._4, scale8)
347364 let slippageCalc = fromX18(res._5, scale8)
348365 if ((0 >= calcLpAmt))
349366 then throw("Invalid calculations. LP calculated is less than zero.")
350367 else {
351368 let emitLpAmt = if (!(emitLp))
352369 then 0
353370 else calcLpAmt
354371 let amDiff = (inAmAssetAmt - calcAmAssetPmt)
355372 let prDiff = (inPrAssetAmt - calcPrAssetPmt)
356373 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))]
357374 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
358375 }
359376 }
360377 }
361378
362379
363380 func validateMatcherOrderAllowed (order) = {
364381 let cfg = getPoolConfig()
365382 let amtAssetId = cfg[idxAmtAssetId]
366383 let priceAssetId = cfg[idxPriceAssetId]
367384 let poolStatus = parseIntValue(cfg[idxPoolStatus])
368385 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
369386 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
370387 let accAmtAssetBalance = getAccBalance(amtAssetId)
371388 let accPriceAssetBalance = getAccBalance(priceAssetId)
372389 let curPriceX18 = if ((order.orderType == Buy))
373390 then privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
374391 else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance - order.amount), accPriceAssetBalance)
375392 let curPrice = fromX18(curPriceX18, scale8)
376393 if (if (if (isGlobalShutdown())
377394 then true
378395 else (poolStatus == PoolMatcherDisabled))
379396 then true
380397 else (poolStatus == PoolShutdown))
381398 then throw("Exchange operations disabled")
382399 else {
383400 let orderAmtAsset = order.assetPair.amountAsset
384401 let orderAmtAssetStr = if ((orderAmtAsset == unit))
385402 then "WAVES"
386403 else toBase58String(value(orderAmtAsset))
387404 let orderPriceAsset = order.assetPair.priceAsset
388405 let orderPriceAssetStr = if ((orderPriceAsset == unit))
389406 then "WAVES"
390407 else toBase58String(value(orderPriceAsset))
391408 if (if ((orderAmtAssetStr != amtAssetId))
392409 then true
393410 else (orderPriceAssetStr != priceAssetId))
394411 then throw("Wrong order assets.")
395412 else {
396413 let orderPrice = order.price
397414 let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
398415 let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
399416 let isOrderPriceValid = if ((order.orderType == Buy))
400417 then (curPrice >= castedOrderPrice)
401418 else (castedOrderPrice >= curPrice)
402419 true
403420 }
404421 }
405422 }
406423
407424
408425 func commonGet (i) = if ((size(i.payments) != 1))
409426 then throw("exactly 1 payment is expected")
410427 else {
411428 let pmt = value(i.payments[0])
412429 let pmtAssetId = value(pmt.assetId)
413430 let pmtAmt = pmt.amount
414431 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
415432 let outAmAmt = res._1
416433 let outPrAmt = res._2
417434 let poolStatus = parseIntValue(res._9)
418435 let state = res._10
419436 if (if (isGlobalShutdown())
420437 then true
421438 else (poolStatus == PoolShutdown))
422439 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
423440 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
424441 }
425442
426443
427444 func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
428445 then throw("exactly 2 payments are expected")
429446 else {
430447 let amAssetPmt = value(i.payments[0])
431448 let prAssetPmt = value(i.payments[1])
432449 let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
433450 let poolStatus = parseIntValue(estPut._8)
434451 if (if (if (isGlobalShutdown())
435452 then true
436453 else (poolStatus == PoolPutDisabled))
437454 then true
438455 else (poolStatus == PoolShutdown))
439456 then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
440457 else estPut
441458 }
442459
443460
444461 func emit (amount) = {
445462 let emitInv = invoke(factoryContract, "emit", [amount], nil)
446463 if ((emitInv == emitInv))
447464 then {
448465 let emitInvLegacy = match emitInv {
449466 case legacyFactoryContract: Address =>
450467 invoke(legacyFactoryContract, "emit", [amount], nil)
451468 case _ =>
452469 unit
453470 }
454471 if ((emitInvLegacy == emitInvLegacy))
455472 then amount
456473 else throw("Strict value is not equal to itself.")
457474 }
458475 else throw("Strict value is not equal to itself.")
459476 }
460477
461478
462479 func takeFee (amount) = {
463480 let feeAmount = fraction(amount, fee, scale8)
464481 $Tuple2((amount - feeAmount), feeAmount)
465482 }
466483
467484
468485 func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
469486 let isEval = (txId == unit)
470487 let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId))
471488 let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId))
472489 let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId))
473490 then true
474491 else if ((paymentAssetId == cfgPriceAssetId))
475492 then false
476493 else throwErr("invalid asset")
477- let $t02257122864 = if (isEval)
494+ let $t02294323236 = if (isEval)
478495 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
479496 else if (paymentInAmountAsset)
480497 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
481498 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
482- let amountBalanceOld = $t02257122864._1
483- let priceBalanceOld = $t02257122864._2
484- let $t02286823017 = if (paymentInAmountAsset)
499+ let amountBalanceOld = $t02294323236._1
500+ let priceBalanceOld = $t02294323236._2
501+ let $t02324023389 = if (paymentInAmountAsset)
485502 then $Tuple2(paymentAmountRaw, 0)
486503 else $Tuple2(0, paymentAmountRaw)
487- let amountAssetAmountRaw = $t02286823017._1
488- let priceAssetAmountRaw = $t02286823017._2
504+ let amountAssetAmountRaw = $t02324023389._1
505+ let priceAssetAmountRaw = $t02324023389._2
489506 let amountAssetAmount = takeFee(amountAssetAmountRaw)._1
490507 let priceAssetAmount = takeFee(priceAssetAmountRaw)._1
491- let $t02313923198 = takeFee(paymentAmountRaw)
492- let paymentAmount = $t02313923198._1
493- let feeAmount = $t02313923198._2
508+ let $t02351123570 = takeFee(paymentAmountRaw)
509+ let paymentAmount = $t02351123570._1
510+ let feeAmount = $t02351123570._2
494511 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
495512 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
496513 let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals))
497514 let priceNew = fromX18(priceNewX18, scale8)
498515 let paymentBalance = if (paymentInAmountAsset)
499516 then amountBalanceOld
500517 else priceBalanceOld
501518 let paymentBalanceBigInt = toBigInt(paymentBalance)
502519 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
503520 let chechSupply = if ((supplyBigInt > big0))
504521 then true
505522 else throwErr("initial deposit requires all coins")
506523 if ((chechSupply == chechSupply))
507524 then {
508525 let depositBigInt = toBigInt(paymentAmount)
509526 let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
510527 let commonState = if (isEval)
511528 then nil
512529 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))]
513530 let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals))
514531 let priceOld = fromX18(priceOldX18, scale8)
515532 let loss = {
516- let $t02467524842 = if (paymentInAmountAsset)
533+ let $t02504725214 = if (paymentInAmountAsset)
517534 then $Tuple2(amountAssetAmountRaw, amountBalanceOld)
518535 else $Tuple2(priceAssetAmountRaw, priceBalanceOld)
519- let amount = $t02467524842._1
520- let balance = $t02467524842._2
536+ let amount = $t02504725214._1
537+ let balance = $t02504725214._2
521538 let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance)))
522539 fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth)
523540 }
524541 $Tuple4(issueAmount, commonState, feeAmount, loss)
525542 }
526543 else throw("Strict value is not equal to itself.")
527544 }
528545
529546
530547 func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
531548 let isEval = (txId == unit)
532549 let checks = [if ((paymentAssetId == cfgLpAssetId))
533550 then true
534551 else throwErr("invalid lp asset")]
535552 if ((checks == checks))
536553 then {
537554 let outInAmountAsset = if ((outAssetId == cfgAmountAssetId))
538555 then true
539556 else if ((outAssetId == cfgPriceAssetId))
540557 then false
541558 else throwErr("invalid asset")
542559 let balanceBigInt = if (outInAmountAsset)
543560 then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId)))
544561 else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId)))
545562 let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId))
546563 let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId))
547564 let outBalance = if (outInAmountAsset)
548565 then amBalanceOld
549566 else prBalanceOld
550567 let outBalanceBigInt = toBigInt(outBalance)
551568 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity)
552569 let redeemedBigInt = toBigInt(paymentAmount)
553570 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
554- let $t02642226472 = takeFee(amountRaw)
555- let totalAmount = $t02642226472._1
556- let feeAmount = $t02642226472._2
557- let $t02647626702 = if (outInAmountAsset)
571+ let $t02679426844 = takeFee(amountRaw)
572+ let totalAmount = $t02679426844._1
573+ let feeAmount = $t02679426844._2
574+ let $t02684827074 = if (outInAmountAsset)
558575 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
559576 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
560- let outAmAmount = $t02647626702._1
561- let outPrAmount = $t02647626702._2
562- let amBalanceNew = $t02647626702._3
563- let prBalanceNew = $t02647626702._4
577+ let outAmAmount = $t02684827074._1
578+ let outPrAmount = $t02684827074._2
579+ let amBalanceNew = $t02684827074._3
580+ let prBalanceNew = $t02684827074._4
564581 let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals))
565582 let priceNew = fromX18(priceNewX18, scale8)
566583 let commonState = if (isEval)
567584 then nil
568585 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)]
569586 let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals))
570587 let priceOld = fromX18(priceOldX18, scale8)
571588 let loss = {
572589 let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2)
573590 fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset)
574591 }
575592 $Tuple4(totalAmount, commonState, feeAmount, loss)
576593 }
577594 else throw("Strict value is not equal to itself.")
595+ }
596+
597+
598+func calcKLp (amountBalance,priceBalance,lpEmission) = {
599+ let updatedKLp = (pow((amountBalance * priceBalance), 0, 5, 1, 0, DOWN) / lpEmission)
600+ updatedKLp
601+ }
602+
603+
604+func refreshKLpInternal () = {
605+ let cfg = getPoolConfig()
606+ let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
607+ let amountAssetId = cfg[idxAmtAssetId]
608+ let priceAssetId = cfg[idxPriceAssetId]
609+ let amountAssetBalance = getAccBalance(amountAssetId)
610+ let priceAssetBalance = getAccBalance(priceAssetId)
611+ let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
612+ let updatedKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpEmission)
613+ updatedKLp
578614 }
579615
580616
581617 func managerPublicKeyOrUnit () = match getString(mpk()) {
582618 case s: String =>
583619 fromBase58String(s)
584620 case _: Unit =>
585621 unit
586622 case _ =>
587623 throw("Match error")
588624 }
589625
590626
591627 func pendingManagerPublicKeyOrUnit () = match getString(pmpk()) {
592628 case s: String =>
593629 fromBase58String(s)
594630 case _: Unit =>
595631 unit
596632 case _ =>
597633 throw("Match error")
598634 }
599635
600636
601637 func isManager (i) = match managerPublicKeyOrUnit() {
602638 case pk: ByteVector =>
603639 (i.callerPublicKey == pk)
604640 case _: Unit =>
605641 (i.caller == this)
606642 case _ =>
607643 throw("Match error")
608644 }
609645
610646
611647 func mustManager (i) = {
612648 let pd = throw("Permission denied")
613649 match managerPublicKeyOrUnit() {
614650 case pk: ByteVector =>
615651 if ((i.callerPublicKey == pk))
616652 then true
617653 else pd
618654 case _: Unit =>
619655 if ((i.caller == this))
620656 then true
621657 else pd
622658 case _ =>
623659 throw("Match error")
624660 }
625661 }
626662
627663
628664 @Callable(i)
629665 func setManager (pendingManagerPublicKey) = {
630666 let checkCaller = mustManager(i)
631667 if ((checkCaller == checkCaller))
632668 then {
633669 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
634670 if ((checkManagerPublicKey == checkManagerPublicKey))
635671 then [StringEntry(pmpk(), pendingManagerPublicKey)]
636672 else throw("Strict value is not equal to itself.")
637673 }
638674 else throw("Strict value is not equal to itself.")
639675 }
640676
641677
642678
643679 @Callable(i)
644680 func confirmManager () = {
645681 let pm = pendingManagerPublicKeyOrUnit()
646682 let hasPM = if (isDefined(pm))
647683 then true
648684 else throw("No pending manager")
649685 if ((hasPM == hasPM))
650686 then {
651687 let checkPM = if ((i.callerPublicKey == value(pm)))
652688 then true
653689 else throw("You are not pending manager")
654690 if ((checkPM == checkPM))
655691 then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())]
656692 else throw("Strict value is not equal to itself.")
657693 }
658694 else throw("Strict value is not equal to itself.")
659695 }
660696
661697
662698
663699 @Callable(i)
664700 func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
665701 then throw("Invalid slippageTolerance passed")
666702 else {
667703 let estPut = commonPut(i, slippageTolerance, true)
668704 let emitLpAmt = estPut._2
669705 let lpAssetId = estPut._7
670706 let state = estPut._9
671707 let amDiff = estPut._10
672708 let prDiff = estPut._11
673709 let amId = estPut._12
674710 let prId = estPut._13
675711 let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
676712 if ((emitInv == emitInv))
677713 then {
678714 let emitInvLegacy = match emitInv {
679715 case legacyFactoryContract: Address =>
680716 invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
681717 case _ =>
682718 unit
683719 }
684720 if ((emitInvLegacy == emitInvLegacy))
685721 then {
686722 let slippageAInv = if ((amDiff > 0))
687723 then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
688724 else nil
689725 if ((slippageAInv == slippageAInv))
690726 then {
691727 let slippagePInv = if ((prDiff > 0))
692728 then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
693729 else nil
694730 if ((slippagePInv == slippagePInv))
695731 then {
696732 let lpTransfer = if (shouldAutoStake)
697733 then {
698734 let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
699735 if ((slpStakeInv == slpStakeInv))
700736 then nil
701737 else throw("Strict value is not equal to itself.")
702738 }
703739 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
704740 (state ++ lpTransfer)
705741 }
706742 else throw("Strict value is not equal to itself.")
707743 }
708744 else throw("Strict value is not equal to itself.")
709745 }
710746 else throw("Strict value is not equal to itself.")
711747 }
712748 else throw("Strict value is not equal to itself.")
713749 }
714750
715751
716752
717753 @Callable(i)
718754 func putForFree (maxSlippage) = if ((0 > maxSlippage))
719755 then throw("Invalid value passed")
720756 else {
721757 let estPut = commonPut(i, maxSlippage, false)
722758 estPut._9
723759 }
724760
725761
726762
727763 @Callable(i)
728764 func putOneTkn (minOutAmount,autoStake) = {
729765 let isPoolOneTokenOperationsDisabled = {
730766 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
731767 if ($isInstanceOf(@, "Boolean"))
732768 then @
733769 else throw(($getType(@) + " couldn't be cast to Boolean"))
734770 }
735771 let isPutDisabled = if (if (if (isGlobalShutdown())
736772 then true
737773 else (cfgPoolStatus == PoolPutDisabled))
738774 then true
739775 else (cfgPoolStatus == PoolShutdown))
740776 then true
741777 else isPoolOneTokenOperationsDisabled
742778 let checks = [if (if (!(isPutDisabled))
743779 then true
744780 else isManager(i))
745781 then true
746782 else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
747783 then true
748784 else throwErr("exactly 1 payment are expected")]
749785 if ((checks == checks))
750786 then {
751787 let payment = i.payments[0]
752788 let paymentAssetId = payment.assetId
753789 let paymentAmountRaw = payment.amount
754790 let userAddress = i.caller
755791 let txId = i.transactionId
756- let $t03160931739 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
757- if (($t03160931739 == $t03160931739))
792+ let $t03269232819 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
793+ let emitAmountEstimated = $t03269232819._1
794+ let commonState = $t03269232819._2
795+ let feeAmount = $t03269232819._3
796+ let bonus = $t03269232819._4
797+ let emitAmount = if (if ((minOutAmount > 0))
798+ then (minOutAmount > emitAmountEstimated)
799+ else false)
800+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
801+ else emitAmountEstimated
802+ let emitInv = emit(emitAmount)
803+ if ((emitInv == emitInv))
758804 then {
759- let bonus = $t03160931739._4
760- let feeAmount = $t03160931739._3
761- let commonState = $t03160931739._2
762- let emitAmountEstimated = $t03160931739._1
763- let emitAmount = if (if ((minOutAmount > 0))
764- then (minOutAmount > emitAmountEstimated)
765- else false)
766- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
767- else emitAmountEstimated
768- let emitInv = emit(emitAmount)
769- if ((emitInv == emitInv))
805+ let lpTransfer = if (autoStake)
770806 then {
771- let lpTransfer = if (autoStake)
772- then {
773- let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
774- if ((stakeInv == stakeInv))
775- then nil
776- else throw("Strict value is not equal to itself.")
777- }
778- else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
779- let sendFee = if ((feeAmount > 0))
780- then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
781- else nil
782- $Tuple2(((commonState ++ lpTransfer) ++ sendFee), emitAmount)
807+ let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
808+ if ((stakeInv == stakeInv))
809+ then nil
810+ else throw("Strict value is not equal to itself.")
783811 }
784- else throw("Strict value is not equal to itself.")
812+ else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
813+ let sendFee = if ((feeAmount > 0))
814+ then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
815+ else nil
816+ $Tuple2(((commonState ++ lpTransfer) ++ sendFee), emitAmount)
785817 }
786818 else throw("Strict value is not equal to itself.")
787819 }
788820 else throw("Strict value is not equal to itself.")
789821 }
790822
791823
792824
793825 @Callable(i)
794826 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
795- let $t03246832603 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
796- let emitAmountEstimated = $t03246832603._1
797- let commonState = $t03246832603._2
798- let feeAmount = $t03246832603._3
799- let bonus = $t03246832603._4
827+ let $t03354833683 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
828+ let emitAmountEstimated = $t03354833683._1
829+ let commonState = $t03354833683._2
830+ let feeAmount = $t03354833683._3
831+ let bonus = $t03354833683._4
800832 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
801833 }
802834
803835
804836
805837 @Callable(i)
806838 func getOneTkn (outAssetIdStr,minOutAmount) = {
807839 let isPoolOneTokenOperationsDisabled = {
808840 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
809841 if ($isInstanceOf(@, "Boolean"))
810842 then @
811843 else throw(($getType(@) + " couldn't be cast to Boolean"))
812844 }
813845 let isGetDisabled = if (if (isGlobalShutdown())
814846 then true
815847 else (cfgPoolStatus == PoolShutdown))
816848 then true
817849 else isPoolOneTokenOperationsDisabled
818850 let checks = [if (if (!(isGetDisabled))
819851 then true
820852 else isManager(i))
821853 then true
822854 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
823855 then true
824856 else throwErr("exactly 1 payment are expected")]
825857 if ((checks == checks))
826858 then {
827859 let outAssetId = parseAssetId(outAssetIdStr)
828860 let payment = i.payments[0]
829861 let paymentAssetId = payment.assetId
830862 let paymentAmount = payment.amount
831863 let userAddress = i.caller
832864 let txId = i.transactionId
833- let $t03340833543 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
834- if (($t03340833543 == $t03340833543))
865+ let $t03448834620 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
866+ let amountEstimated = $t03448834620._1
867+ let commonState = $t03448834620._2
868+ let feeAmount = $t03448834620._3
869+ let bonus = $t03448834620._4
870+ let amount = if (if ((minOutAmount > 0))
871+ then (minOutAmount > amountEstimated)
872+ else false)
873+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
874+ else amountEstimated
875+ let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
876+ if ((burnInv == burnInv))
835877 then {
836- let bonus = $t03340833543._4
837- let feeAmount = $t03340833543._3
838- let commonState = $t03340833543._2
839- let amountEstimated = $t03340833543._1
840- let amount = if (if ((minOutAmount > 0))
841- then (minOutAmount > amountEstimated)
842- else false)
843- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
844- else amountEstimated
845- let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
846- if ((burnInv == burnInv))
847- then {
848- let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
849- let sendFee = if ((feeAmount > 0))
850- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
851- else nil
852- $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
853- }
854- else throw("Strict value is not equal to itself.")
878+ let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
879+ let sendFee = if ((feeAmount > 0))
880+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
881+ else nil
882+ $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
855883 }
856884 else throw("Strict value is not equal to itself.")
857885 }
858886 else throw("Strict value is not equal to itself.")
859887 }
860888
861889
862890
863891 @Callable(i)
864892 func getOneTknREADONLY (outAssetId,paymentAmount) = {
865- let $t03417834316 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
866- let amountEstimated = $t03417834316._1
867- let commonState = $t03417834316._2
868- let feeAmount = $t03417834316._3
869- let bonus = $t03417834316._4
893+ let $t03525535393 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
894+ let amountEstimated = $t03525535393._1
895+ let commonState = $t03525535393._2
896+ let feeAmount = $t03525535393._3
897+ let bonus = $t03525535393._4
870898 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
871899 }
872900
873901
874902
875903 @Callable(i)
876904 func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
877905 let isPoolOneTokenOperationsDisabled = {
878906 let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil)
879907 if ($isInstanceOf(@, "Boolean"))
880908 then @
881909 else throw(($getType(@) + " couldn't be cast to Boolean"))
882910 }
883911 let isGetDisabled = if (if (isGlobalShutdown())
884912 then true
885913 else (cfgPoolStatus == PoolShutdown))
886914 then true
887915 else isPoolOneTokenOperationsDisabled
888916 let checks = [if (if (!(isGetDisabled))
889917 then true
890918 else isManager(i))
891919 then true
892920 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
893921 then true
894922 else throwErr("no payments are expected")]
895923 if ((checks == checks))
896924 then {
897925 let outAssetId = parseAssetId(outAssetIdStr)
898926 let userAddress = i.caller
899927 let txId = i.transactionId
900928 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
901929 if ((unstakeInv == unstakeInv))
902930 then {
903- let $t03514135274 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
904- if (($t03514135274 == $t03514135274))
931+ let $t03621836348 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId)
932+ let amountEstimated = $t03621836348._1
933+ let commonState = $t03621836348._2
934+ let feeAmount = $t03621836348._3
935+ let bonus = $t03621836348._4
936+ let amount = if (if ((minOutAmount > 0))
937+ then (minOutAmount > amountEstimated)
938+ else false)
939+ then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
940+ else amountEstimated
941+ let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
942+ if ((burnInv == burnInv))
905943 then {
906- let bonus = $t03514135274._4
907- let feeAmount = $t03514135274._3
908- let commonState = $t03514135274._2
909- let amountEstimated = $t03514135274._1
910- let amount = if (if ((minOutAmount > 0))
911- then (minOutAmount > amountEstimated)
912- else false)
913- then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
914- else amountEstimated
915- let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
916- if ((burnInv == burnInv))
917- then {
918- let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
919- let sendFee = if ((feeAmount > 0))
920- then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
921- else nil
922- $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
923- }
924- else throw("Strict value is not equal to itself.")
944+ let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
945+ let sendFee = if ((feeAmount > 0))
946+ then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
947+ else nil
948+ $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
925949 }
926950 else throw("Strict value is not equal to itself.")
927951 }
928952 else throw("Strict value is not equal to itself.")
929953 }
930954 else throw("Strict value is not equal to itself.")
931955 }
932956
933957
934958
935959 @Callable(i)
936960 func get () = {
937961 let res = commonGet(i)
938962 let outAmtAmt = res._1
939963 let outPrAmt = res._2
940964 let pmtAmt = res._3
941965 let pmtAssetId = res._4
942966 let state = res._5
943967 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
944968 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
945969 then state
946970 else throw("Strict value is not equal to itself.")
947971 }
948972
949973
950974
951975 @Callable(i)
952976 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
953977 let res = commonGet(i)
954978 let outAmAmt = res._1
955979 let outPrAmt = res._2
956980 let pmtAmt = res._3
957981 let pmtAssetId = res._4
958982 let state = res._5
959983 if ((noLessThenAmtAsset > outAmAmt))
960984 then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
961985 else if ((noLessThenPriceAsset > outPrAmt))
962986 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
963987 else {
964988 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
965989 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
966990 then state
967991 else throw("Strict value is not equal to itself.")
968992 }
969993 }
970994
971995
972996
973997 @Callable(i)
974998 func unstakeAndGet (amount) = {
975999 let checkPayments = if ((size(i.payments) != 0))
9761000 then throw("No payments are expected")
9771001 else true
9781002 if ((checkPayments == checkPayments))
9791003 then {
9801004 let cfg = getPoolConfig()
9811005 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
9821006 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
9831007 if ((unstakeInv == unstakeInv))
9841008 then {
9851009 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
9861010 let poolStatus = parseIntValue(res._9)
9871011 let state = res._10
9881012 let checkPoolStatus = if (if (isGlobalShutdown())
9891013 then true
9901014 else (poolStatus == PoolShutdown))
9911015 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
9921016 else true
9931017 if ((checkPoolStatus == checkPoolStatus))
9941018 then {
9951019 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
9961020 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
9971021 then state
9981022 else throw("Strict value is not equal to itself.")
9991023 }
10001024 else throw("Strict value is not equal to itself.")
10011025 }
10021026 else throw("Strict value is not equal to itself.")
10031027 }
10041028 else throw("Strict value is not equal to itself.")
10051029 }
10061030
10071031
10081032
10091033 @Callable(i)
10101034 func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = {
10111035 let isGetDisabled = if (isGlobalShutdown())
10121036 then true
10131037 else (cfgPoolStatus == PoolShutdown)
10141038 let checks = [if (!(isGetDisabled))
10151039 then true
10161040 else throw("get operation is blocked by admin"), if ((size(i.payments) == 0))
10171041 then true
10181042 else throw("no payments are expected")]
10191043 if ((checks == checks))
10201044 then {
10211045 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
10221046 if ((unstakeInv == unstakeInv))
10231047 then {
10241048 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller)
10251049 let outAmAmt = res._1
10261050 let outPrAmt = res._2
10271051 let state = res._10
10281052 let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset))
10291053 then true
10301054 else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset))
10311055 then true
10321056 else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))]
10331057 if ((checkAmounts == checkAmounts))
10341058 then {
10351059 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
10361060 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
10371061 then state
10381062 else throw("Strict value is not equal to itself.")
10391063 }
10401064 else throw("Strict value is not equal to itself.")
10411065 }
10421066 else throw("Strict value is not equal to itself.")
10431067 }
10441068 else throw("Strict value is not equal to itself.")
10451069 }
10461070
10471071
10481072
10491073 @Callable(i)
10501074 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
10511075 then throw("permissions denied")
10521076 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
1077+
1078+
1079+
1080+@Callable(i)
1081+func refreshKLp () = {
1082+ let lastRefreshedBlockHeight = valueOrElse(getInteger(keyLastKLpRefreshed), 0)
1083+ let delayNotReachedErrorMessage = throwErr(makeString([value(getString(keyRefreshKLpDelay)), "blocks have not passed since the previous call"], " "))
1084+ let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= 30))
1085+ then true
1086+ else delayNotReachedErrorMessage
1087+ if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight))
1088+ then {
1089+ let updatedKLp = asInt(refreshKLpInternal())
1090+[IntegerEntry(keyLastKLpRefreshed, height), IntegerEntry(keyKLp, updatedKLp)]
1091+ }
1092+ else throw("Strict value is not equal to itself.")
1093+ }
10531094
10541095
10551096
10561097 @Callable(i)
10571098 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
10581099
10591100
10601101
10611102 @Callable(i)
10621103 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
10631104
10641105
10651106
10661107 @Callable(i)
10671108 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
10681109 let prices = calcPrices(amAmt, prAmt, lpAmt)
10691110 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
10701111 }
10711112
10721113
10731114
10741115 @Callable(i)
10751116 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
10761117
10771118
10781119
10791120 @Callable(i)
10801121 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
10811122
10821123
10831124
10841125 @Callable(i)
10851126 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
10861127
10871128
10881129
10891130 @Callable(i)
10901131 func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
10911132
10921133
10931134
10941135 @Callable(i)
10951136 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
10961137 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
10971138 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
10981139 }
10991140
11001141
11011142
11021143 @Callable(i)
11031144 func statsREADONLY () = {
11041145 let cfg = getPoolConfig()
11051146 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
11061147 let amtAssetId = cfg[idxAmtAssetId]
11071148 let priceAssetId = cfg[idxPriceAssetId]
11081149 let iAmtAssetId = cfg[idxIAmtAssetId]
11091150 let iPriceAssetId = cfg[idxIPriceAssetId]
11101151 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
11111152 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
11121153 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
11131154 let accAmtAssetBalance = getAccBalance(amtAssetId)
11141155 let accPriceAssetBalance = getAccBalance(priceAssetId)
11151156 let pricesList = if ((poolLPBalance == 0))
11161157 then [zeroBigInt, zeroBigInt, zeroBigInt]
11171158 else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
11181159 let curPrice = 0
11191160 let lpAmtAssetShare = fromX18(pricesList[1], scale8)
11201161 let lpPriceAssetShare = fromX18(pricesList[2], scale8)
11211162 let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
11221163 $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))
11231164 }
11241165
11251166
11261167
11271168 @Callable(i)
11281169 func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
11291170 let cfg = getPoolConfig()
11301171 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
11311172 let amAssetIdStr = cfg[idxAmtAssetId]
11321173 let amAssetId = fromBase58String(amAssetIdStr)
11331174 let prAssetIdStr = cfg[idxPriceAssetId]
11341175 let prAssetId = fromBase58String(prAssetIdStr)
11351176 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
11361177 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
11371178 let poolStatus = cfg[idxPoolStatus]
11381179 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
11391180 let accAmtAssetBalance = getAccBalance(amAssetIdStr)
11401181 let accPriceAssetBalance = getAccBalance(prAssetIdStr)
11411182 let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
11421183 let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
11431184 let curPriceX18 = if ((poolLPBalance == 0))
11441185 then zeroBigInt
11451186 else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
11461187 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
11471188 let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
11481189 let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
11491190 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
11501191 let calcLpAmt = estPut._1
11511192 let curPriceCalc = estPut._3
11521193 let amBalance = estPut._4
11531194 let prBalance = estPut._5
11541195 let lpEmission = estPut._6
11551196 $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))
11561197 }
11571198
11581199
11591200
11601201 @Callable(i)
11611202 func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
11621203 let cfg = getPoolConfig()
11631204 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
11641205 let amAssetIdStr = cfg[idxAmtAssetId]
11651206 let amAssetId = fromBase58String(amAssetIdStr)
11661207 let prAssetIdStr = cfg[idxPriceAssetId]
11671208 let prAssetId = fromBase58String(prAssetIdStr)
11681209 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
11691210 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
11701211 let poolStatus = cfg[idxPoolStatus]
11711212 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
11721213 let amBalanceRaw = getAccBalance(amAssetIdStr)
11731214 let prBalanceRaw = getAccBalance(prAssetIdStr)
11741215 let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
11751216 let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
11761217 let curPriceX18 = if ((poolLPBalance == 0))
11771218 then zeroBigInt
11781219 else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
11791220 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
11801221 let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
11811222 let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
11821223 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
11831224 let calcLpAmt = estPut._1
11841225 let curPriceCalc = estPut._3
11851226 let amBalance = estPut._4
11861227 let prBalance = estPut._5
11871228 let lpEmission = estPut._6
11881229 $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))
11891230 }
11901231
11911232
11921233
11931234 @Callable(i)
11941235 func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
11951236 let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
11961237 let outAmAmt = res._1
11971238 let outPrAmt = res._2
11981239 let amBalance = res._5
11991240 let prBalance = res._6
12001241 let lpEmission = res._7
12011242 let curPrice = res._8
12021243 let poolStatus = parseIntValue(res._9)
12031244 $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))
12041245 }
12051246
12061247
12071248 @Verifier(tx)
12081249 func verify () = {
12091250 let targetPublicKey = match managerPublicKeyOrUnit() {
12101251 case pk: ByteVector =>
12111252 pk
12121253 case _: Unit =>
12131254 tx.senderPublicKey
12141255 case _ =>
12151256 throw("Match error")
12161257 }
12171258 match tx {
12181259 case order: Order =>
12191260 let matcherPub = getMatcherPubOrFail()
12201261 let orderValid = validateMatcherOrderAllowed(order)
12211262 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
12221263 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
12231264 if (if (if (orderValid)
12241265 then senderValid
12251266 else false)
12261267 then matcherValid
12271268 else false)
12281269 then true
12291270 else throwOrderError(orderValid, senderValid, matcherValid)
12301271 case s: SetScriptTransaction =>
12311272 let newHash = blake2b256(value(s.script))
12321273 let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
12331274 let currentHash = scriptHash(this)
12341275 if (if ((allowedHash == newHash))
12351276 then (currentHash != newHash)
12361277 else false)
12371278 then true
12381279 else sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
12391280 case _ =>
12401281 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
12411282 }
12421283 }
12431284

github/deemru/w8io/026f985 
121.84 ms