tx · 6ars5eZGD6U9sTU58KQVMv8QnLL5Ggm2K8QTgK6UyFhv

3N9SbhVEu6NbUtNXiarejsn3FFTQw4TdQba:  -0.02900000 Waves

2022.10.26 09:38 [2289041] smart account 3N9SbhVEu6NbUtNXiarejsn3FFTQw4TdQba > SELF 0.00000000 Waves

{ "type": 13, "id": "6ars5eZGD6U9sTU58KQVMv8QnLL5Ggm2K8QTgK6UyFhv", "fee": 2900000, "feeAssetId": null, "timestamp": 1666766061935, "version": 1, "sender": "3N9SbhVEu6NbUtNXiarejsn3FFTQw4TdQba", "senderPublicKey": "HfkkTzjsVGtKhtCp2bBGJbWRXAUWa57mqVCD9pCLF64V", "proofs": [ "4TVB5Ly1PYJFVkjutmvHX2nyf6hTyiCFUv5Zs8ucDk9K9MogwcDWt8D7NoJc4fLNF1MHF15q2KWih7hzNmVfgV3j" ], "script": "base64:BgKfJwgCEgMKAQgSABIECgIBBBIDCgEBEgQKAgEEEgQKAggBEgQKAggBEgQKAggBEgUKAwEIARIAEgQKAgEBEgMKAQESBAoCCAgSABIDCgEIEgUKAwEBARIECgIBARIECgIIARIECgIICBILCgkIAQECAQIIBAQSBgoECAgBCBIAEgMKAQESAwoBARIECgIIASIKbFBkZWNpbWFscyIGc2NhbGU4IgxzY2FsZThCaWdJbnQiB3NjYWxlMTgiCnplcm9CaWdJbnQiBGJpZzAiBGJpZzEiBGJpZzIiC3dhdmVzU3RyaW5nIgNTRVAiClBvb2xBY3RpdmUiD1Bvb2xQdXREaXNhYmxlZCITUG9vbE1hdGNoZXJEaXNhYmxlZCIMUG9vbFNodXRkb3duIg5pZHhQb29sQWRkcmVzcyINaWR4UG9vbFN0YXR1cyIQaWR4UG9vbExQQXNzZXRJZCINaWR4QW10QXNzZXRJZCIPaWR4UHJpY2VBc3NldElkIg5pZHhBbXRBc3NldERjbSIQaWR4UHJpY2VBc3NldERjbSIOaWR4SUFtdEFzc2V0SWQiEGlkeElQcmljZUFzc2V0SWQiDWlkeExQQXNzZXREY20iEmlkeFBvb2xBbXRBc3NldEFtdCIUaWR4UG9vbFByaWNlQXNzZXRBbXQiEWlkeFBvb2xMUEFzc2V0QW10IhlpZHhGYWN0b3J5U3Rha2luZ0NvbnRyYWN0IhppZHhGYWN0b3J5U2xpcHBhZ2VDb250cmFjdCIFdG9YMTgiB29yaWdWYWwiDW9yaWdTY2FsZU11bHQiB2Zyb21YMTgiA3ZhbCIPcmVzdWx0U2NhbGVNdWx0Igd0b1NjYWxlIgNhbXQiCHJlc1NjYWxlIghjdXJTY2FsZSIDYWJzIglhYnNCaWdJbnQiAmZjIgNtcGsiBHBtcGsiAnBsIgJwaCIBaCIJdGltZXN0YW1wIgNwYXUiC3VzZXJBZGRyZXNzIgR0eElkIgNnYXUiAmFhIgJwYSIGa2V5RmVlIgpmZWVEZWZhdWx0IgNmZWUiEGtleUZhY3RvcnlDb25maWciDWtleU1hdGNoZXJQdWIiKWtleU1hcHBpbmdQb29sQ29udHJhY3RBZGRyZXNzVG9Qb29sQXNzZXRzIhNwb29sQ29udHJhY3RBZGRyZXNzIg1rZXlQb29sQ29uZmlnIglpQW10QXNzZXQiC2lQcmljZUFzc2V0Ih9rZXlNYXBwaW5nc0Jhc2VBc3NldDJpbnRlcm5hbElkIgxiYXNlQXNzZXRTdHIiE2tleUFsbFBvb2xzU2h1dGRvd24iDWtleVBvb2xXZWlnaHQiD2NvbnRyYWN0QWRkcmVzcyIWa2V5QWxsb3dlZExwU2NyaXB0SGFzaCIWa2V5RmVlQ29sbGVjdG9yQWRkcmVzcyIPdGhyb3dPcmRlckVycm9yIgpvcmRlclZhbGlkIgtzZW5kZXJWYWxpZCIMbWF0Y2hlclZhbGlkIg9nZXRTdHJpbmdPckZhaWwiB2FkZHJlc3MiA2tleSIMZ2V0SW50T3JGYWlsIgh0aHJvd0VyciIDbXNnIg9mYWN0b3J5Q29udHJhY3QiE2ZlZUNvbGxlY3RvckFkZHJlc3MiEGlzR2xvYmFsU2h1dGRvd24iE2dldE1hdGNoZXJQdWJPckZhaWwiDWdldFBvb2xDb25maWciCGFtdEFzc2V0IgpwcmljZUFzc2V0IgxwYXJzZUFzc2V0SWQiBWlucHV0Ig9hc3NldElkVG9TdHJpbmciD3BhcnNlUG9vbENvbmZpZyIKcG9vbENvbmZpZyIQcG9vbENvbmZpZ1BhcnNlZCILJHQwNzU0Mzc3MDkiDmNmZ1Bvb2xBZGRyZXNzIg1jZmdQb29sU3RhdHVzIgxjZmdMcEFzc2V0SWQiEGNmZ0Ftb3VudEFzc2V0SWQiD2NmZ1ByaWNlQXNzZXRJZCIWY2ZnQW1vdW50QXNzZXREZWNpbWFscyIVY2ZnUHJpY2VBc3NldERlY2ltYWxzIhBnZXRGYWN0b3J5Q29uZmlnIg9zdGFraW5nQ29udHJhY3QiEHNsaXBwYWdlQ29udHJhY3QiEWRhdGFQdXRBY3Rpb25JbmZvIg1pbkFtdEFzc2V0QW10Ig9pblByaWNlQXNzZXRBbXQiCG91dExwQW10IgVwcmljZSIdc2xpcHBhZ2VUb2xlcmFuY2VQYXNzZWRCeVVzZXIiFXNsaXBwYWdlVG9sZXJhbmNlUmVhbCIIdHhIZWlnaHQiC3R4VGltZXN0YW1wIhJzbGlwYWdlQW10QXNzZXRBbXQiFHNsaXBhZ2VQcmljZUFzc2V0QW10IhFkYXRhR2V0QWN0aW9uSW5mbyIOb3V0QW10QXNzZXRBbXQiEG91dFByaWNlQXNzZXRBbXQiB2luTHBBbXQiDWdldEFjY0JhbGFuY2UiB2Fzc2V0SWQiD2NhbGNQcmljZUJpZ0ludCIIcHJBbXRYMTgiCGFtQW10WDE4IhBwcml2YXRlQ2FsY1ByaWNlIgphbUFzc2V0RGNtIgpwckFzc2V0RGNtIgVhbUFtdCIFcHJBbXQiDmFtdEFzc2V0QW10WDE4IhBwcmljZUFzc2V0QW10WDE4IgpjYWxjUHJpY2VzIgVscEFtdCIDY2ZnIgthbXRBc3NldERjbSINcHJpY2VBc3NldERjbSIIcHJpY2VYMTgiCGxwQW10WDE4IhNscFByaWNlSW5BbUFzc2V0WDE4IhNscFByaWNlSW5QckFzc2V0WDE4Ig9jYWxjdWxhdGVQcmljZXMiBnByaWNlcyIUZXN0aW1hdGVHZXRPcGVyYXRpb24iBnR4SWQ1OCIKcG10QXNzZXRJZCIIcG10THBBbXQiCWxwQXNzZXRJZCIJYW1Bc3NldElkIglwckFzc2V0SWQiCnBvb2xTdGF0dXMiCmxwRW1pc3Npb24iCWFtQmFsYW5jZSIMYW1CYWxhbmNlWDE4IglwckJhbGFuY2UiDHByQmFsYW5jZVgxOCILY3VyUHJpY2VYMTgiCGN1clByaWNlIgtwbXRMcEFtdFgxOCINbHBFbWlzc2lvblgxOCILb3V0QW1BbXRYMTgiC291dFByQW10WDE4IghvdXRBbUFtdCIIb3V0UHJBbXQiBXN0YXRlIhRlc3RpbWF0ZVB1dE9wZXJhdGlvbiIRc2xpcHBhZ2VUb2xlcmFuY2UiDGluQW1Bc3NldEFtdCILaW5BbUFzc2V0SWQiDGluUHJBc3NldEFtdCILaW5QckFzc2V0SWQiCmlzRXZhbHVhdGUiBmVtaXRMcCIMYW1Bc3NldElkU3RyIgxwckFzc2V0SWRTdHIiC2lBbXRBc3NldElkIg1pUHJpY2VBc3NldElkIg5pbkFtQXNzZXRJZFN0ciIOaW5QckFzc2V0SWRTdHIiD2luQW1Bc3NldEFtdFgxOCIPaW5QckFzc2V0QW10WDE4Igx1c2VyUHJpY2VYMTgiA3JlcyILc2xpcHBhZ2VYMTgiFHNsaXBwYWdlVG9sZXJhbmNlWDE4IgpwclZpYUFtWDE4IgphbVZpYVByWDE4IgxleHBlY3RlZEFtdHMiEWV4cEFtdEFzc2V0QW10WDE4IhNleHBQcmljZUFzc2V0QW10WDE4IgljYWxjTHBBbXQiDmNhbGNBbUFzc2V0UG10Ig5jYWxjUHJBc3NldFBtdCIMc2xpcHBhZ2VDYWxjIgllbWl0THBBbXQiBmFtRGlmZiIGcHJEaWZmIgtjb21tb25TdGF0ZSIbdmFsaWRhdGVNYXRjaGVyT3JkZXJBbGxvd2VkIgVvcmRlciIKYW10QXNzZXRJZCIMcHJpY2VBc3NldElkIhJhY2NBbXRBc3NldEJhbGFuY2UiFGFjY1ByaWNlQXNzZXRCYWxhbmNlIg1vcmRlckFtdEFzc2V0IhBvcmRlckFtdEFzc2V0U3RyIg9vcmRlclByaWNlQXNzZXQiEm9yZGVyUHJpY2VBc3NldFN0ciIKb3JkZXJQcmljZSIIcHJpY2VEY20iEGNhc3RlZE9yZGVyUHJpY2UiEWlzT3JkZXJQcmljZVZhbGlkIgljb21tb25HZXQiAWkiA3BtdCIGcG10QW10Igljb21tb25QdXQiCmFtQXNzZXRQbXQiCnByQXNzZXRQbXQiBmVzdFB1dCIEZW1pdCIGYW1vdW50IgdlbWl0SW52Ig1lbWl0SW52TGVnYWN5IgckbWF0Y2gwIhVsZWdhY3lGYWN0b3J5Q29udHJhY3QiB3Rha2VGZWUiCWZlZUFtb3VudCIPY2FsY1B1dE9uZVRva2VuIhBwYXltZW50QW1vdW50UmF3Ig5wYXltZW50QXNzZXRJZCIGaXNFdmFsIg0kdDAyMjIzMjIyNDEwIgtwb29sQWRkcmVzcyINYW1vdW50QXNzZXRJZCITYW1vdW50QXNzZXREZWNpbWFscyIScHJpY2VBc3NldERlY2ltYWxzIhBhbW91bnRCYWxhbmNlUmF3Ig9wcmljZUJhbGFuY2VSYXciFHBheW1lbnRJbkFtb3VudEFzc2V0Ig0kdDAyMjc0MDIzMDMzIhBhbW91bnRCYWxhbmNlT2xkIg9wcmljZUJhbGFuY2VPbGQiDSR0MDIzMDM3MjMxODYiFGFtb3VudEFzc2V0QW1vdW50UmF3IhNwcmljZUFzc2V0QW1vdW50UmF3IhFhbW91bnRBc3NldEFtb3VudCIQcHJpY2VBc3NldEFtb3VudCINJHQwMjMzMDgyMzM2NyINcGF5bWVudEFtb3VudCIQYW1vdW50QmFsYW5jZU5ldyIPcHJpY2VCYWxhbmNlTmV3IgtwcmljZU5ld1gxOCIIcHJpY2VOZXciDnBheW1lbnRCYWxhbmNlIhRwYXltZW50QmFsYW5jZUJpZ0ludCIMc3VwcGx5QmlnSW50IgtjaGVjaFN1cHBseSINZGVwb3NpdEJpZ0ludCILaXNzdWVBbW91bnQiC3ByaWNlT2xkWDE4IghwcmljZU9sZCILcHJpY2VJbXBhY3QiD2NhbGNHZXRPbmVUb2tlbiIKb3V0QXNzZXRJZCINJHQwMjUxODkyNTM1MCIKYW1EZWNpbWFscyIKcHJEZWNpbWFscyIGY2hlY2tzIhBvdXRJbkFtb3VudEFzc2V0Ig1iYWxhbmNlQmlnSW50IgxhbUJhbGFuY2VPbGQiDHByQmFsYW5jZU9sZCIKb3V0QmFsYW5jZSIQb3V0QmFsYW5jZUJpZ0ludCIOcmVkZWVtZWRCaWdJbnQiCWFtb3VudFJhdyINJHQwMjY0MjUyNjQ3NSILdG90YWxBbW91bnQiDSR0MDI2NDc5MjY3MDUiC291dEFtQW1vdW50IgtvdXRQckFtb3VudCIMYW1CYWxhbmNlTmV3IgxwckJhbGFuY2VOZXciFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQiAXMiHXBlbmRpbmdNYW5hZ2VyUHVibGljS2V5T3JVbml0IgttdXN0TWFuYWdlciICcGQiAnBrIhdwZW5kaW5nTWFuYWdlclB1YmxpY0tleSILY2hlY2tDYWxsZXIiFWNoZWNrTWFuYWdlclB1YmxpY0tleSICcG0iBWhhc1BNIgdjaGVja1BNIg9zaG91bGRBdXRvU3Rha2UiBGFtSWQiBHBySWQiDHNsaXBwYWdlQUludiIMc2xpcHBhZ2VQSW52IgpscFRyYW5zZmVyIgtzbHBTdGFrZUludiILbWF4U2xpcHBhZ2UiDG1pbk91dEFtb3VudCIJYXV0b1N0YWtlIg1pc1B1dERpc2FibGVkIgdwYXltZW50Ig0kdDAzMTA1NzMxMTg0IhNlbWl0QW1vdW50RXN0aW1hdGVkIgVib251cyIKZW1pdEFtb3VudCIIc3Rha2VJbnYiB3NlbmRGZWUiDSR0MDMxOTEzMzIwNDgiDW91dEFzc2V0SWRTdHIiDWlzR2V0RGlzYWJsZWQiDSR0MDMyNjM2MzI3NjgiD2Ftb3VudEVzdGltYXRlZCIHYnVybkludiINYXNzZXRUcmFuc2ZlciINJHQwMzM0MDMzMzU0MSINdW5zdGFrZUFtb3VudCIKdW5zdGFrZUludiINJHQwMzQwOTEzNDIxNCIJb3V0QW10QW10IhRidXJuTFBBc3NldE9uRmFjdG9yeSISbm9MZXNzVGhlbkFtdEFzc2V0IhRub0xlc3NUaGVuUHJpY2VBc3NldCINY2hlY2tQYXltZW50cyIPY2hlY2tQb29sU3RhdHVzIgthbXRBc3NldFN0ciINcHJpY2VBc3NldFN0ciINcG9vbExQQmFsYW5jZSIKcHJpY2VzTGlzdCIPbHBBbXRBc3NldFNoYXJlIhFscFByaWNlQXNzZXRTaGFyZSIKcG9vbFdlaWdodCIMY3VyUHJpY2VDYWxjIgxhbUJhbGFuY2VSYXciDHByQmFsYW5jZVJhdyIPYW1CYWxhbmNlUmF3WDE4Ig9wckJhbGFuY2VSYXdYMTgiEHBheW1lbnRMcEFzc2V0SWQiDHBheW1lbnRMcEFtdCICdHgiBnZlcmlmeSIPdGFyZ2V0UHVibGljS2V5IgptYXRjaGVyUHViIgduZXdIYXNoIgthbGxvd2VkSGFzaCILY3VycmVudEhhc2hiAAFhAAgAAWIAgMLXLwABYwkAtgIBAIDC1y8AAWQJALYCAQCAgJC7utat8A0AAWUJALYCAQAAAAFmCQC2AgEAAAABZwkAtgIBAAEAAWgJALYCAQACAAFpAgVXQVZFUwABagICX18AAWsAAQABbAACAAFtAAMAAW4ABAABbwABAAFwAAIAAXEAAwABcgAEAAFzAAUAAXQABgABdQAHAAF2AAgAAXcACQABeAAKAAF5AAEAAXoAAgABQQADAAFCAAEAAUMABwEBRAIBRQFGCQC8AgMJALYCAQUBRQUBZAkAtgIBBQFGAQFHAgFIAUkJAKADAQkAvAIDBQFICQC2AgEFAUkFAWQBAUoDAUsBTAFNCQBrAwUBSwUBTAUBTQEBTgEBSAMJAGYCAAAFAUgJAQEtAQUBSAUBSAEBTwEBSAMJAL8CAgUBZQUBSAkAvgIBBQFIBQFIAQFQAAITJXNfX2ZhY3RvcnlDb250cmFjdAEBUQACFCVzX19tYW5hZ2VyUHVibGljS2V5AQFSAAIbJXNfX3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AQFTAAIRJXMlc19fcHJpY2VfX2xhc3QBAVQCAVUBVgkAuQkCCQDMCAICGCVzJXMlZCVkX19wcmljZV9faGlzdG9yeQkAzAgCCQCkAwEFAVUJAMwIAgkApAMBBQFWBQNuaWwFAWoBAVcCAVgBWQkArAICCQCsAgIJAKwCAgILJXMlcyVzX19QX18FAVgCAl9fBQFZAQFaAgFYAVkJAKwCAgkArAICCQCsAgICCyVzJXMlc19fR19fBQFYAgJfXwUBWQECYWEAAg8lc19fYW1vdW50QXNzZXQBAmFiAAIOJXNfX3ByaWNlQXNzZXQAAmFjAgclc19fZmVlAAJhZAkAawMABQUBYgCQTgACYWUJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUCYWMFAmFkAQJhZgACESVzX19mYWN0b3J5Q29uZmlnAQJhZwACGCVzJXNfX21hdGNoZXJfX3B1YmxpY0tleQECYWgBAmFpCQCsAgIJAKwCAgIIJXMlcyVzX18FAmFpAiBfX21hcHBpbmdzX19wb29sQ29udHJhY3QyTHBBc3NldAECYWoCAmFrAmFsCQCsAgIJAKwCAgkArAICCQCsAgICCCVkJWQlc19fBQJhawICX18FAmFsAghfX2NvbmZpZwECYW0BAmFuCQCsAgICKCVzJXMlc19fbWFwcGluZ3NfX2Jhc2VBc3NldDJpbnRlcm5hbElkX18FAmFuAQJhbwACDCVzX19zaHV0ZG93bgECYXABAmFxCQCsAgICEiVzJXNfX3Bvb2xXZWlnaHRfXwUCYXEBAmFyAAIXJXNfX2FsbG93ZWRMcFNjcmlwdEhhc2gAAmFzAhclc19fZmVlQ29sbGVjdG9yQWRkcmVzcwECYXQDAmF1AmF2AmF3CQACAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICJG9yZGVyIHZhbGlkYXRpb24gZmFpbGVkOiBvcmRlclZhbGlkPQkApQMBBQJhdQINIHNlbmRlclZhbGlkPQkApQMBBQJhdgIOIG1hdGNoZXJWYWxpZD0JAKUDAQUCYXcBAmF4AgJheQJhegkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCdCAIFAmF5BQJhegkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQJheQkAzAgCAgEuCQDMCAIFAmF6CQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABAmFBAgJheQJhegkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCaCAIFAmF5BQJhegkAuQkCCQDMCAICCm1hbmRhdG9yeSAJAMwIAgkApQgBBQJheQkAzAgCAgEuCQDMCAIFAmF6CQDMCAICDyBpcyBub3QgZGVmaW5lZAUDbmlsAgABAmFCAQJhQwkAAgEJALkJAgkAzAgCAghscC5yaWRlOgkAzAgCBQJhQwUDbmlsAgEgAAJhRAkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmF4AgUEdGhpcwkBAVAAAAJhRQkBEUBleHRyTmF0aXZlKDEwNjIpAQkBAmF4AgUCYUQFAmFzAQJhRgAJAQt2YWx1ZU9yRWxzZQIJAJsIAgUCYUQJAQJhbwAHAQJhRwAJANkEAQkBAmF4AgUCYUQJAQJhZwABAmFIAAQCYUkJAQJheAIFBHRoaXMJAQJhYQAEAmFKCQECYXgCBQR0aGlzCQECYWIABAJhbAkBAmFBAgUCYUQJAQJhbQEFAmFKBAJhawkBAmFBAgUCYUQJAQJhbQEFAmFJCQC1CQIJAQJheAIFAmFECQECYWoCCQCkAwEFAmFrCQCkAwEFAmFsBQFqAQJhSwECYUwDCQAAAgUCYUwFAWkFBHVuaXQJANkEAQUCYUwBAmFNAQJhTAMJAAACBQJhTAUEdW5pdAUBaQkA2AQBCQEFdmFsdWUBBQJhTAECYU4BAmFPCQCZCgcJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAJEDAgUCYU8FAW8JAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJhTwUBcAkA2QQBCQCRAwIFAmFPBQFxCQECYUsBCQCRAwIFAmFPBQFyCQECYUsBCQCRAwIFAmFPBQFzCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYU8FAXQJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJhTwUBdQACYVAJAQJhTgEJAQJhSAAAAmFRBQJhUAACYVIIBQJhUQJfMQACYVMIBQJhUQJfMgACYVQIBQJhUQJfMwACYVUIBQJhUQJfNAACYVYIBQJhUQJfNQACYVcIBQJhUQJfNgACYVgIBQJhUQJfNwECYVkACQC1CQIJAQJheAIFAmFECQECYWYABQFqAAJhWgkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgkBAmFZAAUBQgIZaW5jb3JyZWN0IHN0YWtpbmcgYWRkcmVzcwACYmEJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIJAQJhWQAFAUMCGWluY29ycmVjdCBzdGFraW5nIGFkZHJlc3MBAmJiCgJiYwJiZAJiZQJiZgJiZwJiaAJiaQJiagJiawJibAkAuQkCCQDMCAICFCVkJWQlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYmMJAMwIAgkApAMBBQJiZAkAzAgCCQCkAwEFAmJlCQDMCAIJAKQDAQUCYmYJAMwIAgkApAMBBQJiZwkAzAgCCQCkAwEFAmJoCQDMCAIJAKQDAQUCYmkJAMwIAgkApAMBBQJiagkAzAgCCQCkAwEFAmJrCQDMCAIJAKQDAQUCYmwFA25pbAUBagECYm0GAmJuAmJvAmJwAmJmAmJpAmJqCQC5CQIJAMwIAgIMJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYm4JAMwIAgkApAMBBQJibwkAzAgCCQCkAwEFAmJwCQDMCAIJAKQDAQUCYmYJAMwIAgkApAMBBQJiaQkAzAgCCQCkAwEFAmJqBQNuaWwFAWoBAmJxAQJicgMJAAACBQJicgIFV0FWRVMICQDvBwEFBHRoaXMJYXZhaWxhYmxlCQDwBwIFBHRoaXMJANkEAQUCYnIBAmJzAgJidAJidQkAvAIDBQJidAUBZAUCYnUBAmJ2BAJidwJieAJieQJiegQCYkEJAQFEAgUCYnkFAmJ3BAJiQgkBAUQCBQJiegUCYngJAQJicwIFAmJCBQJiQQECYkMDAmJ5AmJ6AmJEBAJiRQkBAmFIAAQCYkYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiRQUBdAQCYkcJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiRQUBdQQCYkgJAQJidgQFAmJGBQJiRwUCYnkFAmJ6BAJidQkBAUQCBQJieQUCYkYEAmJ0CQEBRAIFAmJ6BQJiRwQCYkkJAQFEAgUCYkQFAWIEAmJKCQECYnMCBQJidQUCYkkEAmJLCQECYnMCBQJidAUCYkkJAMwIAgUCYkgJAMwIAgUCYkoJAMwIAgUCYksFA25pbAECYkwDAmJ5AmJ6AmJEBAJiTQkBAmJDAwUCYnkFAmJ6BQJiRAkAzAgCCQEBRwIJAJEDAgUCYk0AAAUBYgkAzAgCCQEBRwIJAJEDAgUCYk0AAQUBYgkAzAgCCQEBRwIJAJEDAgUCYk0AAgUBYgUDbmlsAQJiTgQCYk8CYlACYlEBWAQCYkUJAQJhSAAEAmJSCQCRAwIFAmJFBQFxBAJiUwkAkQMCBQJiRQUBcgQCYlQJAJEDAgUCYkUFAXMEAmJ3CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkUFAXQEAmJ4CQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkUFAXUEAmJVCQCRAwIFAmJFBQFwBAJiVggJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBCQDZBAEFAmJSCQCsAgIJAKwCAgIGQXNzZXQgBQJiUgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkDCQECIT0CBQJiUgUCYlAJAAIBAhVJbnZhbGlkIGFzc2V0IHBhc3NlZC4EAmJXCQECYnEBBQJiUwQCYlgJAQFEAgUCYlcFAmJ3BAJiWQkBAmJxAQUCYlQEAmJaCQEBRAIFAmJZBQJieAQCY2EJAQJicwIFAmJaBQJiWAQCY2IJAQFHAgUCY2EFAWIEAmNjCQEBRAIFAmJRBQFiBAJjZAkBAUQCBQJiVgUBYgQCY2UJALwCAwUCYlgFAmNjBQJjZAQCY2YJALwCAwUCYloFAmNjBQJjZAQCY2cJAQFHAgUCY2UFAmJ3BAJjaAkBAUcCBQJjZgUCYngEAmNpAwkAAAIFAmJPAgAFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQFYBQJjZwMJAAACBQJiUwIFV0FWRVMFBHVuaXQJANkEAQUCYlMJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUBWAUCY2gDCQAAAgUCYlQCBVdBVkVTBQR1bml0CQDZBAEFAmJUCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFaAgkApQgBBQFYBQJiTwkBAmJtBgUCY2cFAmNoBQJiUQUCY2IFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFTAAUCY2IJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFUAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCY2IFA25pbAkAnAoKBQJjZwUCY2gFAmJTBQJiVAUCYlcFAmJZBQJiVgUCY2EFAmJVBQJjaQECY2oJAmJPAmNrAmNsAmNtAmNuAmNvAVgCY3ACY3EEAmJFCQECYUgABAJiUgkA2QQBCQCRAwIFAmJFBQFxBAJjcgkAkQMCBQJiRQUBcgQCY3MJAJEDAgUCYkUFAXMEAmN0CQCRAwIFAmJFBQF2BAJjdQkAkQMCBQJiRQUBdwQCYkYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiRQUBdAQCYkcJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiRQUBdQQCYlUJAJEDAgUCYkUFAXAEAmJWCAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmJSCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmJSAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCY3YJANgEAQkBC3ZhbHVlT3JFbHNlAgUCY20JANkEAQIFV0FWRVMEAmN3CQDYBAEJAQt2YWx1ZU9yRWxzZQIFAmNvCQDZBAECBVdBVkVTAwMJAQIhPQIFAmNyBQJjdgYJAQIhPQIFAmNzBQJjdwkAAgECIkludmFsaWQgYW10IG9yIHByaWNlIGFzc2V0IHBhc3NlZC4EAmJXAwUCY3AJAQJicQEFAmNyCQBlAgkBAmJxAQUCY3IFAmNsBAJiWQMFAmNwCQECYnEBBQJjcwkAZQIJAQJicQEFAmNzBQJjbgQCY3gJAQFEAgUCY2wFAmJGBAJjeQkBAUQCBQJjbgUCYkcEAmN6CQECYnMCBQJjeQUCY3gEAmJYCQEBRAIFAmJXBQJiRgQCYloJAQFEAgUCYlkFAmJHBAJjQQMJAAACBQJiVgAABAJjYQUBZQQCY0IFAWUEAmJJCQB2BgkAuQICBQJjeAUCY3kAAAkAtgIBAAUAAQAABQRET1dOCQCXCgUJAQFHAgUCYkkFAWIJAQFHAgUCY3gFAmJGCQEBRwIFAmN5BQJiRwkBAmJzAgkAtwICBQJiWgUCY3kJALcCAgUCYlgFAmN4BQJjQgQCY2EJAQJicwIFAmJaBQJiWAQCY0IJALwCAwkBAU8BCQC4AgIFAmNhBQJjegUBZAUCY2EEAmNDCQEBRAIFAmNrBQFiAwMJAQIhPQIFAmNhBQFlCQC/AgIFAmNCBQJjQwcJAAIBCQCsAgIJAKwCAgkArAICAg9QcmljZSBzbGlwcGFnZSAJAKYDAQUCY0ICHiBleGNlZWRlZCB0aGUgcGFzc2VkIGxpbWl0IG9mIAkApgMBBQJjQwQCY2QJAQFEAgUCYlYFAWIEAmNECQC8AgMFAmN4BQJjYQUBZAQCY0UJALwCAwUCY3kFAWQFAmNhBAJjRgMJAL8CAgUCY0QFAmN5CQCUCgIFAmNFBQJjeQkAlAoCBQJjeAUCY0QEAmNHCAUCY0YCXzEEAmNICAUCY0YCXzIEAmJJCQC8AgMFAmNkBQJjSAUCYloJAJcKBQkBAUcCBQJiSQUBYgkBAUcCBQJjRwUCYkYJAQFHAgUCY0gFAmJHBQJjYQUCY0IEAmNJCAUCY0ECXzEEAmNKCAUCY0ECXzIEAmNLCAUCY0ECXzMEAmNiCQEBRwIIBQJjQQJfNAUBYgQCY0wJAQFHAggFAmNBAl81BQFiAwkAZwIAAAUCY0kJAAIBAjZJbnZhbGlkIGNhbGN1bGF0aW9ucy4gTFAgY2FsY3VsYXRlZCBpcyBsZXNzIHRoYW4gemVyby4EAmNNAwkBASEBBQJjcQAABQJjSQQCY04JAGUCBQJjbAUCY0oEAmNPCQBlAgUCY24FAmNLBAJjUAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVMABQJjYgkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVQCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJjYgkAzAgCCQELU3RyaW5nRW50cnkCCQEBVwIFAVgFAmJPCQECYmIKBQJjSgUCY0sFAmNNBQJjYgUCY2sFAmNMBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJjTgUCY08FA25pbAkAnwoNBQJjSQUCY00FAmNiBQJiVwUCYlkFAmJWBQJiUgUCYlUFAmNQBQJjTgUCY08FAmNtBQJjbwECY1EBAmNSBAJiRQkBAmFIAAQCY1MJAJEDAgUCYkUFAXIEAmNUCQCRAwIFAmJFBQFzBAJiVQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJFBQFwBAJiRgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJFBQF0BAJiRwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJFBQF1BAJjVQkBAmJxAQUCY1MEAmNWCQECYnEBBQJjVAQCY2EDCQAAAggFAmNSCW9yZGVyVHlwZQUDQnV5CQECYnYEBQJiRgUCYkcJAGQCBQJjVQgFAmNSBmFtb3VudAUCY1YJAQJidgQFAmJGBQJiRwkAZQIFAmNVCAUCY1IGYW1vdW50BQJjVgQCY2IJAQFHAgUCY2EFAWIDAwMJAQJhRgAGCQAAAgUCYlUFAW0GCQAAAgUCYlUFAW4JAAIBAhxFeGNoYW5nZSBvcGVyYXRpb25zIGRpc2FibGVkBAJjVwgIBQJjUglhc3NldFBhaXILYW1vdW50QXNzZXQEAmNYAwkAAAIFAmNXBQR1bml0AgVXQVZFUwkA2AQBCQEFdmFsdWUBBQJjVwQCY1kICAUCY1IJYXNzZXRQYWlyCnByaWNlQXNzZXQEAmNaAwkAAAIFAmNZBQR1bml0AgVXQVZFUwkA2AQBCQEFdmFsdWUBBQJjWQMDCQECIT0CBQJjWAUCY1MGCQECIT0CBQJjWgUCY1QJAAIBAhNXcm9uZyBvcmRlciBhc3NldHMuBAJkYQgFAmNSBXByaWNlBAJkYgkAawMFAWIFAmJHBQJiRgQCZGMJAQFKAwUCZGEFAWIFAmRiBAJkZAMJAAACCAUCY1IJb3JkZXJUeXBlBQNCdXkJAGcCBQJjYgUCZGMJAGcCBQJkYwUCY2IGAQJkZQECZGYDCQECIT0CCQCQAwEIBQJkZghwYXltZW50cwABCQACAQIdZXhhY3RseSAxIHBheW1lbnQgaXMgZXhwZWN0ZWQEAmRnCQEFdmFsdWUBCQCRAwIIBQJkZghwYXltZW50cwAABAJiUAkBBXZhbHVlAQgFAmRnB2Fzc2V0SWQEAmRoCAUCZGcGYW1vdW50BAJjQQkBAmJOBAkA2AQBCAUCZGYNdHJhbnNhY3Rpb25JZAkA2AQBBQJiUAUCZGgIBQJkZgZjYWxsZXIEAmNnCAUCY0ECXzEEAmNoCAUCY0ECXzIEAmJVCQENcGFyc2VJbnRWYWx1ZQEIBQJjQQJfOQQCY2kIBQJjQQNfMTADAwkBAmFGAAYJAAACBQJiVQUBbgkAAgEJAKwCAgIsR2V0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCYlUJAJcKBQUCY2cFAmNoBQJkaAUCYlAFAmNpAQJkaQMCZGYCY2sCY3EDCQECIT0CCQCQAwEIBQJkZghwYXltZW50cwACCQACAQIfZXhhY3RseSAyIHBheW1lbnRzIGFyZSBleHBlY3RlZAQCZGoJAQV2YWx1ZQEJAJEDAggFAmRmCHBheW1lbnRzAAAEAmRrCQEFdmFsdWUBCQCRAwIIBQJkZghwYXltZW50cwABBAJkbAkBAmNqCQkA2AQBCAUCZGYNdHJhbnNhY3Rpb25JZAUCY2sIBQJkagZhbW91bnQIBQJkagdhc3NldElkCAUCZGsGYW1vdW50CAUCZGsHYXNzZXRJZAkApQgBCAUCZGYGY2FsbGVyBwUCY3EEAmJVCQENcGFyc2VJbnRWYWx1ZQEIBQJkbAJfOAMDAwkBAmFGAAYJAAACBQJiVQUBbAYJAAACBQJiVQUBbgkAAgEJAKwCAgIsUHV0IG9wZXJhdGlvbiBpcyBibG9ja2VkIGJ5IGFkbWluLiBTdGF0dXMgPSAJAKQDAQUCYlUFAmRsAQJkbQECZG4EAmRvCQD8BwQFAmFEAgRlbWl0CQDMCAIFAmRuBQNuaWwFA25pbAMJAAACBQJkbwUCZG8EAmRwBAJkcQUCZG8DCQABAgUCZHECB0FkZHJlc3MEAmRyBQJkcQkA/AcEBQJkcgIEZW1pdAkAzAgCBQJkbgUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZHAFAmRwBQJkbgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZHMBAmRuBAJkdAkAawMFAmRuBQJhZQUBYgkAlAoCCQBlAgUCZG4FAmR0BQJkdAECZHUEAmR2AmR3AVgBWQQCZHgJAAACBQFZBQR1bml0BAJkeQkBAmFOAQkBAmFIAAQCZHoIBQJkeQJfMQQCYlUIBQJkeQJfMgQCYlIIBQJkeQJfMwQCZEEIBQJkeQJfNAQCY1QIBQJkeQJfNQQCZEIIBQJkeQJfNgQCZEMIBQJkeQJfNwQCZEQJAQJicQEJAQJhTQEFAmRBBAJkRQkBAmJxAQkBAmFNAQUCY1QEAmRGAwkAAAIFAmR3BQJkQQYDCQAAAgUCZHcFAmNUBwkBAmFCAQINaW52YWxpZCBhc3NldAQCZEcDBQJkeAkAlAoCBQJkRAUCZEUDBQJkRgkAlAoCCQBlAgUCZEQFAmR2BQJkRQkAlAoCBQJkRAkAZQIFAmRFBQJkdgQCZEgIBQJkRwJfMQQCZEkIBQJkRwJfMgQCZEoDBQJkRgkAlAoCBQJkdgAACQCUCgIAAAUCZHYEAmRLCAUCZEoCXzEEAmRMCAUCZEoCXzIEAmRNCAkBAmRzAQUCZEsCXzEEAmROCAkBAmRzAQUCZEwCXzEEAmRPCQECZHMBBQJkdgQCZFAIBQJkTwJfMQQCZHQIBQJkTwJfMgQCZFEJAGQCBQJkSAUCZE0EAmRSCQBkAgUCZEkFAmROBAJkUwkBAmJzAgkBAUQCBQJkUgUCZEMJAQFEAgUCZFEFAmRCBAJkVAkBAUcCBQJkUwUBYgQCZFUDBQJkRgUCZEgFAmRJBAJkVgkAtgIBBQJkVQQCZFcJALYCAQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJiUgkArAICCQCsAgICBmFzc2V0IAkA2AQBBQJiUgIOIGRvZXNuJ3QgZXhpc3QIcXVhbnRpdHkEAmRYAwkAvwICBQJkVwUBZgYJAQJhQgECImluaXRpYWwgZGVwb3NpdCByZXF1aXJlcyBhbGwgY29pbnMDCQAAAgUCZFgFAmRYBAJkWQkAtgIBBQJkUAQCZFoJAJYDAQkAzAgCAAAJAMwIAgkAoAMBCQC6AgIJALkCAgUCZFcJALgCAgkBCnNxcnRCaWdJbnQECQC3AgIFAWQJALoCAgkAuQICBQJkWQUBZAUCZFYAEgASBQRET1dOBQFkBQFkBQNuaWwEAmNQAwUCZHgFA25pbAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVMABQJkVAkAzAgCCQEMSW50ZWdlckVudHJ5AgkBAVQCBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJkVAkAzAgCCQELU3RyaW5nRW50cnkCCQEBVwIJAKUIAQkBBXZhbHVlAQUBWAkA2AQBCQEFdmFsdWUBBQFZCQECYmIKBQJkSwUCZEwFAmRaBQJkVAAAAAAFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAAAAAABQNuaWwEAmVhCQECYnMCCQEBRAIFAmRJBQJkQwkBAUQCBQJkSAUCZEIEAmViCQEBRwIFAmVhBQFiBAJlYwkBAU4BCQBpAgkAaAIJAGUCBQJkVAUCZWIFAWIFAmViCQCWCgQFAmRaBQJjUAUCZHQFAmVjCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQJlZAUCZWUCZFACZHcBWAFZBAJkeAkAAAIFAVkFBHVuaXQEAmVmCQECYU4BCQECYUgABAJkeggFAmVmAl8xBAJiVQgFAmVmAl8yBAJiUggFAmVmAl8zBAJkQQgFAmVmAl80BAJjVAgFAmVmAl81BAJlZwgFAmVmAl82BAJlaAgFAmVmAl83BAJlaQkAzAgCAwkAAAIFAmR3BQJiUgYJAQJhQgECEGludmFsaWQgbHAgYXNzZXQFA25pbAMJAAACBQJlaQUCZWkEAmVqAwkAAAIFAmVlBQJkQQYDCQAAAgUCZWUFAmNUBwkBAmFCAQINaW52YWxpZCBhc3NldAQCZWsDBQJlagkAtgIBCQECYnEBCQECYU0BBQJkQQkAtgIBCQECYnEBCQECYU0BBQJjVAQCZWwJAQJicQEJAQJhTQEFAmRBBAJlbQkBAmJxAQkBAmFNAQUCY1QEAmVuAwUCZWoFAmVsBQJlbQQCZW8JALYCAQUCZW4EAmRXCQC2AgEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQUCYlIJAKwCAgkArAICAgZhc3NldCAJANgEAQUCYlICDiBkb2Vzbid0IGV4aXN0CHF1YW50aXR5BAJlcAkAtgIBBQJkUAQCZXEJAJYDAQkAzAgCAAAJAMwIAgkAoAMBCQC6AgIJALkCAgUCZWsJALgCAgUBZAkAdgYJALgCAgUBZAkAugICCQC5AgIFAmVwBQFkBQJkVwASBQFoAAAAEgUERE9XTgUBZAUDbmlsBAJlcgkBAmRzAQUCZXEEAmVzCAUCZXICXzEEAmR0CAUCZXICXzIEAmV0AwUCZWoJAJYKBAUCZXMAAAkAZQIFAmVsBQJlcQUCZW0JAJYKBAAABQJlcwUCZWwJAGUCBQJlbQUCZXEEAmV1CAUCZXQCXzEEAmV2CAUCZXQCXzIEAmV3CAUCZXQCXzMEAmV4CAUCZXQCXzQEAmRTCQECYnMCCQEBRAIFAmV4BQJlaAkBAUQCBQJldwUCZWcEAmRUCQEBRwIFAmRTBQFiBAJjUAMFAmR4BQNuaWwJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAVoCCQClCAEJAQV2YWx1ZQEFAVgJANgEAQkBBXZhbHVlAQUBWQkBAmJtBgUCZXUFAmV2BQJkUAUCZFQFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFTAAUCZFQJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFUAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCZFQFA25pbAQCZWEJAQJicwIJAQFEAgUCZW0FAmVoCQEBRAIFAmVsBQJlZwQCZWIJAQFHAgUCZWEFAWIEAmVjCQEBTgEJAGkCCQBoAgkAZQIFAmRUBQJlYgUBYgUCZWIJAJYKBAUCZXMFAmNQBQJkdAUCZWMJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4BAmV5AAQCZHEJAKIIAQkBAVEAAwkAAQIFAmRxAgZTdHJpbmcEAmV6BQJkcQkA2QQBBQJlegMJAAECBQJkcQIEVW5pdAUEdW5pdAkAAgECC01hdGNoIGVycm9yAQJlQQAEAmRxCQCiCAEJAQFSAAMJAAECBQJkcQIGU3RyaW5nBAJlegUCZHEJANkEAQUCZXoDCQABAgUCZHECBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgECZUIBAmRmBAJlQwkAAgECEVBlcm1pc3Npb24gZGVuaWVkBAJkcQkBAmV5AAMJAAECBQJkcQIKQnl0ZVZlY3RvcgQCZUQFAmRxAwkAAAIIBQJkZg9jYWxsZXJQdWJsaWNLZXkFAmVEBgUCZUMDCQABAgUCZHECBFVuaXQDCQAAAggFAmRmBmNhbGxlcgUEdGhpcwYFAmVDCQACAQILTWF0Y2ggZXJyb3IZAmRmAQpzZXRNYW5hZ2VyAQJlRQQCZUYJAQJlQgEFAmRmAwkAAAIFAmVGBQJlRgQCZUcJANkEAQUCZUUDCQAAAgUCZUcFAmVHCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFSAAUCZUUFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkZgEOY29uZmlybU1hbmFnZXIABAJlSAkBAmVBAAQCZUkDCQEJaXNEZWZpbmVkAQUCZUgGCQACAQISTm8gcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmVJBQJlSQQCZUoDCQAAAggFAmRmD2NhbGxlclB1YmxpY0tleQkBBXZhbHVlAQUCZUgGCQACAQIbWW91IGFyZSBub3QgcGVuZGluZyBtYW5hZ2VyAwkAAAIFAmVKBQJlSgkAzAgCCQELU3RyaW5nRW50cnkCCQEBUQAJANgEAQkBBXZhbHVlAQUCZUgJAMwIAgkBC0RlbGV0ZUVudHJ5AQkBAVIABQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGYBA3B1dAICY2sCZUsDCQBmAgAABQJjawkAAgECIEludmFsaWQgc2xpcHBhZ2VUb2xlcmFuY2UgcGFzc2VkBAJkbAkBAmRpAwUCZGYFAmNrBgQCY00IBQJkbAJfMgQCYlIIBQJkbAJfNwQCY2kIBQJkbAJfOQQCY04IBQJkbANfMTAEAmNPCAUCZGwDXzExBAJlTAgFAmRsA18xMgQCZU0IBQJkbANfMTMEAmRvCQD8BwQFAmFEAgRlbWl0CQDMCAIFAmNNBQNuaWwFA25pbAMJAAACBQJkbwUCZG8EAmRwBAJkcQUCZG8DCQABAgUCZHECB0FkZHJlc3MEAmRyBQJkcQkA/AcEBQJkcgIEZW1pdAkAzAgCBQJjTQUDbmlsBQNuaWwFBHVuaXQDCQAAAgUCZHAFAmRwBAJlTgMJAGYCBQJjTgAACQD8BwQFAmJhAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCZUwFAmNOBQNuaWwFA25pbAMJAAACBQJlTgUCZU4EAmVPAwkAZgIFAmNPAAAJAPwHBAUCYmECA3B1dAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJlTQUCY08FA25pbAUDbmlsAwkAAAIFAmVPBQJlTwQCZVADBQJlSwQCZVEJAPwHBAUCYVoCBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJSBQJjTQUDbmlsAwkAAAIFAmVRBQJlUQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJkZgZjYWxsZXIFAmNNBQJiUgUDbmlsCQDOCAIFAmNpBQJlUAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkZgEKcHV0Rm9yRnJlZQECZVIDCQBmAgAABQJlUgkAAgECFEludmFsaWQgdmFsdWUgcGFzc2VkBAJkbAkBAmRpAwUCZGYFAmVSBwgFAmRsAl85AmRmAQlwdXRPbmVUa24CAmVTAmVUBAJlVQMDCQECYUYABgkAAAIFAmFTBQFsBgkAAAIFAmFTBQFuBAJlaQkAzAgCAwkBASEBBQJlVQYJAQJhQgECIXB1dCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmRmCHBheW1lbnRzAAEGCQECYUIBAh5leGFjdGx5IDEgcGF5bWVudCBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJlaQUCZWkEAmVWCQCRAwIIBQJkZghwYXltZW50cwAABAJkdwgFAmVWB2Fzc2V0SWQEAmR2CAUCZVYGYW1vdW50BAFYCAUCZGYGY2FsbGVyBAFZCAUCZGYNdHJhbnNhY3Rpb25JZAQCZVcJAQJkdQQFAmR2BQJkdwUBWAUBWQQCZVgIBQJlVwJfMQQCY1AIBQJlVwJfMgQCZHQIBQJlVwJfMwQCZVkIBQJlVwJfNAQCZVoDAwkAZgIFAmVTAAAJAGYCBQJlUwUCZVgHCQECYUIBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmVTBQNuaWwCAAUCZVgEAmRvCQECZG0BBQJlWgMJAAACBQJkbwUCZG8EAmVQAwUCZVQEAmZhCQD8BwQFAmFaAgVzdGFrZQUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJhVAUCZVoFA25pbAMJAAACBQJmYQUCZmEFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDCAUCZGYGY2FsbGVyBQJlWgUCYVQFA25pbAQCZmIDCQBmAgUCZHQAAAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJhRQUCZHQFAmR3BQNuaWwFA25pbAkAlAoCCQDOCAIJAM4IAgUCY1AFAmVQBQJmYgUCZVoJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGYBEXB1dE9uZVRrblJFQURPTkxZAgJkdwJkdgQCZmMJAQJkdQQFAmR2CQECYUsBBQJkdwUEdW5pdAUEdW5pdAQCZVgIBQJmYwJfMQQCY1AIBQJmYwJfMgQCZHQIBQJmYwJfMwQCZVkIBQJmYwJfNAkAlAoCBQNuaWwJAJUKAwUCZVgFAmR0BQJlWQJkZgEJZ2V0T25lVGtuAgJmZAJlUwQCZmUDCQECYUYABgkAAAIFAmFTBQFuBAJlaQkAzAgCAwkBASEBBQJmZQYJAQJhQgECIWdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmRmCHBheW1lbnRzAAEGCQECYUIBAh5leGFjdGx5IDEgcGF5bWVudCBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJlaQUCZWkEAmVlCQECYUsBBQJmZAQCZVYJAJEDAggFAmRmCHBheW1lbnRzAAAEAmR3CAUCZVYHYXNzZXRJZAQCZFAIBQJlVgZhbW91bnQEAVgIBQJkZgZjYWxsZXIEAVkIBQJkZg10cmFuc2FjdGlvbklkBAJmZgkBAmVkBQUCZWUFAmRQBQJkdwUBWAUBWQQCZmcIBQJmZgJfMQQCY1AIBQJmZgJfMgQCZHQIBQJmZgJfMwQCZVkIBQJmZgJfNAQCZG4DAwkAZgIFAmVTAAAJAGYCBQJlUwUCZmcHCQECYUIBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmVTBQNuaWwCAAUCZmcEAmZoCQD8BwQFAmFEAgRidXJuCQDMCAIFAmRQBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmR3BQJkUAUDbmlsAwkAAAIFAmZoBQJmaAQCZmkJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUBWAUCZG4FAmVlBQNuaWwEAmZiAwkAZgIFAmR0AAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYUUFAmR0BQJlZQUDbmlsBQNuaWwJAJQKAgkAzggCCQDOCAIFAmNQBQJmaQUCZmIFAmRuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRmARFnZXRPbmVUa25SRUFET05MWQICZWUCZFAEAmZqCQECZWQFCQECYUsBBQJlZQUCZFAFAmFUBQR1bml0BQR1bml0BAJmZwgFAmZqAl8xBAJjUAgFAmZqAl8yBAJkdAgFAmZqAl8zBAJlWQgFAmZqAl80CQCUCgIFA25pbAkAlQoDBQJmZwUCZHQFAmVZAmRmARN1bnN0YWtlQW5kR2V0T25lVGtuAwJmawJmZAJlUwQCZmUDCQECYUYABgkAAAIFAmFTBQFuBAJlaQkAzAgCAwkBASEBBQJmZQYJAQJhQgECIWdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbgkAzAgCAwkAAAIJAJADAQgFAmRmCHBheW1lbnRzAAAGCQECYUIBAhhubyBwYXltZW50cyBhcmUgZXhwZWN0ZWQFA25pbAMJAAACBQJlaQUCZWkEAmVlCQECYUsBBQJmZAQCZmwJAPwHBAUCYVoCB3Vuc3Rha2UJAMwIAgkA2AQBBQJhVAkAzAgCBQJmawUDbmlsBQNuaWwDCQAAAgUCZmwFAmZsBAJmbQkBAmVkBQUCZWUFAmZrBQJhVAUEdW5pdAUEdW5pdAQCZmcIBQJmbQJfMQQCY1AIBQJmbQJfMgQCZHQIBQJmbQJfMwQCZVkIBQJmbQJfNAQCZG4DAwkAZgIFAmVTAAAJAGYCBQJlUwUCZmcHCQECYUIBCQC5CQIJAMwIAgIfYW1vdW50IHRvIHJlY2VpdmUgaXMgbGVzcyB0aGFuIAkAzAgCCQCkAwEFAmVTBQNuaWwCAAUCZmcEAmZoCQD8BwQFAmFEAgRidXJuCQDMCAIFAmZrBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmFUBQJmawUDbmlsAwkAAAIFAmZoBQJmaAQCZmkJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmRmBmNhbGxlcgUCZG4FAmVlBQNuaWwEAmZiAwkAZgIFAmR0AAAJAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwUCYUUFAmR0BQJlZQUDbmlsBQNuaWwJAJQKAgkAzggCCQDOCAIFAmNQBQJmaQUCZmIFAmRuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRmAQNnZXQABAJjQQkBAmRlAQUCZGYEAmZuCAUCY0ECXzEEAmNoCAUCY0ECXzIEAmRoCAUCY0ECXzMEAmJQCAUCY0ECXzQEAmNpCAUCY0ECXzUEAmZvCQD8BwQFAmFEAgRidXJuCQDMCAIFAmRoBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJQBQJkaAUDbmlsAwkAAAIFAmZvBQJmbwUCY2kJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGYBCWdldE5vTGVzcwICZnACZnEEAmNBCQECZGUBBQJkZgQCY2cIBQJjQQJfMQQCY2gIBQJjQQJfMgQCZGgIBQJjQQJfMwQCYlAIBQJjQQJfNAQCY2kIBQJjQQJfNQMJAGYCBQJmcAUCY2cJAAIBCQCsAgIJAKwCAgkArAICAhxub0xlc3NUaGVuQW10QXNzZXQgZmFpbGVkOiAgCQCkAwEFAmNnAgMgPCAJAKQDAQUCZnADCQBmAgUCZnEFAmNoCQACAQkArAICCQCsAgIJAKwCAgIdbm9MZXNzVGhlblByaWNlQXNzZXQgZmFpbGVkOiAJAKQDAQUCY2gCAyA8IAkApAMBBQJmcQQCZm8JAPwHBAUCYUQCBGJ1cm4JAMwIAgUCZGgFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYlAFAmRoBQNuaWwDCQAAAgUCZm8FAmZvBQJjaQkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkZgENdW5zdGFrZUFuZEdldAECZG4EAmZyAwkBAiE9AgkAkAMBCAUCZGYIcGF5bWVudHMAAAkAAgECGE5vIHBheW1lbnRzIGFyZSBleHBlY3RlZAYDCQAAAgUCZnIFAmZyBAJiRQkBAmFIAAQCYlIJANkEAQkAkQMCBQJiRQUBcQQCZmwJAPwHBAUCYVoCB3Vuc3Rha2UJAMwIAgkA2AQBBQJiUgkAzAgCBQJkbgUDbmlsBQNuaWwDCQAAAgUCZmwFAmZsBAJjQQkBAmJOBAkA2AQBCAUCZGYNdHJhbnNhY3Rpb25JZAkA2AQBBQJiUgUCZG4IBQJkZgZjYWxsZXIEAmJVCQENcGFyc2VJbnRWYWx1ZQEIBQJjQQJfOQQCY2kIBQJjQQNfMTAEAmZzAwMJAQJhRgAGCQAAAgUCYlUFAW4JAAIBCQCsAgICLEdldCBvcGVyYXRpb24gaXMgYmxvY2tlZCBieSBhZG1pbi4gU3RhdHVzID0gCQCkAwEFAmJVBgMJAAACBQJmcwUCZnMEAmZvCQD8BwQFAmFEAgRidXJuCQDMCAIFAmRuBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJSBQJkbgUDbmlsAwkAAAIFAmZvBQJmbwUCY2kJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGYBCGFjdGl2YXRlAgJmdAJmdQMJAQIhPQIJAKUIAQgFAmRmBmNhbGxlcgkApQgBBQJhRAkAAgECEnBlcm1pc3Npb25zIGRlbmllZAkAlAoCCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhYQAFAmZ0CQDMCAIJAQtTdHJpbmdFbnRyeQIJAQJhYgAFAmZ1BQNuaWwCB3N1Y2Nlc3MCZGYBHGdldFBvb2xDb25maWdXcmFwcGVyUkVBRE9OTFkACQCUCgIFA25pbAkBAmFIAAJkZgEcZ2V0QWNjQmFsYW5jZVdyYXBwZXJSRUFET05MWQECYnIJAJQKAgUDbmlsCQECYnEBBQJicgJkZgEZY2FsY1ByaWNlc1dyYXBwZXJSRUFET05MWQMCYnkCYnoCYkQEAmJNCQECYkMDBQJieQUCYnoFAmJECQCUCgIFA25pbAkAzAgCCQCmAwEJAJEDAgUCYk0AAAkAzAgCCQCmAwEJAJEDAgUCYk0AAQkAzAgCCQCmAwEJAJEDAgUCYk0AAgUDbmlsAmRmARR0b1gxOFdyYXBwZXJSRUFET05MWQIBRQFGCQCUCgIFA25pbAkApgMBCQEBRAIFAUUFAUYCZGYBFmZyb21YMThXcmFwcGVyUkVBRE9OTFkCAUgBSQkAlAoCBQNuaWwJAQFHAgkApwMBBQFIBQFJAmRmAR5jYWxjUHJpY2VCaWdJbnRXcmFwcGVyUkVBRE9OTFkCAmJ0AmJ1CQCUCgIFA25pbAkApgMBCQECYnMCCQCnAwEFAmJ0CQCnAwEFAmJ1AmRmASNlc3RpbWF0ZVB1dE9wZXJhdGlvbldyYXBwZXJSRUFET05MWQkCYk8CY2sCY2wCY20CY24CY28BWAJjcAJjcQkAlAoCBQNuaWwJAQJjagkFAmJPBQJjawUCY2wFAmNtBQJjbgUCY28FAVgFAmNwBQJjcQJkZgEjZXN0aW1hdGVHZXRPcGVyYXRpb25XcmFwcGVyUkVBRE9OTFkEAmJPAmJQAmJRAVgEAmNBCQECYk4EBQJiTwUCYlAFAmJRCQERQGV4dHJOYXRpdmUoMTA2MikBBQFYCQCUCgIFA25pbAkAnAoKCAUCY0ECXzEIBQJjQQJfMggFAmNBAl8zCAUCY0ECXzQIBQJjQQJfNQgFAmNBAl82CAUCY0ECXzcJAKYDAQgFAmNBAl84CAUCY0ECXzkIBQJjQQNfMTACZGYBDXN0YXRzUkVBRE9OTFkABAJiRQkBAmFIAAQCYlIJANkEAQkAkQMCBQJiRQUBcQQCY1MJAJEDAgUCYkUFAXIEAmNUCQCRAwIFAmJFBQFzBAJjdAkAkQMCBQJiRQUBdgQCY3UJAJEDAgUCYkUFAXcEAmJGCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkUFAXQEAmJHCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYkUFAXUEAmZ2CAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmJSCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmJSAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCY1UJAQJicQEFAmNTBAJjVgkBAmJxAQUCY1QEAmZ3AwkAAAIFAmZ2AAAJAMwIAgUBZQkAzAgCBQFlCQDMCAIFAWUFA25pbAkBAmJDAwUCY1UFAmNWBQJmdgQCY2IAAAQCZngJAQFHAgkAkQMCBQJmdwABBQFiBAJmeQkBAUcCCQCRAwIFAmZ3AAIFAWIEAmZ6CQEFdmFsdWUBCQCaCAIFAmFECQECYXABCQClCAEFBHRoaXMJAJQKAgUDbmlsCQC5CQIJAMwIAgIOJWQlZCVkJWQlZCVkJWQJAMwIAgkApAMBBQJjVQkAzAgCCQCkAwEFAmNWCQDMCAIJAKQDAQUCZnYJAMwIAgkApAMBBQJjYgkAzAgCCQCkAwEFAmZ4CQDMCAIJAKQDAQUCZnkJAMwIAgkApAMBBQJmegUDbmlsBQFqAmRmASBldmFsdWF0ZVB1dEJ5QW1vdW50QXNzZXRSRUFET05MWQECY2wEAmJFCQECYUgABAJiUgkA2QQBCQCRAwIFAmJFBQFxBAJjcgkAkQMCBQJiRQUBcgQCYlMJANkEAQUCY3IEAmNzCQCRAwIFAmJFBQFzBAJiVAkA2QQBBQJjcwQCYkYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiRQUBdAQCYkcJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiRQUBdQQCYlUJAJEDAgUCYkUFAXAEAmZ2CAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmJSCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmJSAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCY1UJAQJicQEFAmNyBAJjVgkBAmJxAQUCY3MEAmJBCQEBRAIFAmNVBQJiRgQCYkIJAQFEAgUCY1YFAmJHBAJjYQMJAAACBQJmdgAABQFlCQECYnMCBQJiQgUCYkEEAmN4CQEBRAIFAmNsBQJiRgQCY3kJALwCAwUCY3gFAmNhBQFkBAJjbgkBAUcCBQJjeQUCYkcEAmRsCQECY2oJAgAAoMIeBQJjbAUCYlMFAmNuBQJiVAIABgcEAmNJCAUCZGwCXzEEAmZBCAUCZGwCXzMEAmJXCAUCZGwCXzQEAmJZCAUCZGwCXzUEAmJWCAUCZGwCXzYJAJQKAgUDbmlsCQC5CQIJAMwIAgIQJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmNJCQDMCAIJAKQDAQkBAUcCBQJjYQUBYgkAzAgCCQCkAwEFAmJXCQDMCAIJAKQDAQUCYlkJAMwIAgkApAMBBQJiVgkAzAgCBQJiVQkAzAgCCQCkAwEFAmNsCQDMCAIJAKQDAQUCY24FA25pbAUBagJkZgEfZXZhbHVhdGVQdXRCeVByaWNlQXNzZXRSRUFET05MWQECY24EAmJFCQECYUgABAJiUgkA2QQBCQCRAwIFAmJFBQFxBAJjcgkAkQMCBQJiRQUBcgQCYlMJANkEAQUCY3IEAmNzCQCRAwIFAmJFBQFzBAJiVAkA2QQBBQJjcwQCYkYJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiRQUBdAQCYkcJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJiRQUBdQQCYlUJAJEDAgUCYkUFAXAEAmZ2CAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQDsBwEFAmJSCQCsAgIJAKwCAgIGQXNzZXQgCQDYBAEFAmJSAg4gZG9lc24ndCBleGlzdAhxdWFudGl0eQQCZkIJAQJicQEFAmNyBAJmQwkBAmJxAQUCY3MEAmZECQEBRAIFAmZCBQJiRgQCZkUJAQFEAgUCZkMFAmJHBAJjYQMJAAACBQJmdgAABQFlCQECYnMCBQJmRQUCZkQEAmN5CQEBRAIFAmNuBQJiRwQCY3gJALwCAwUCY3kFAWQFAmNhBAJjbAkBAUcCBQJjeAUCYkYEAmRsCQECY2oJAgAAoMIeBQJjbAUCYlMFAmNuBQJiVAIABgcEAmNJCAUCZGwCXzEEAmZBCAUCZGwCXzMEAmJXCAUCZGwCXzQEAmJZCAUCZGwCXzUEAmJWCAUCZGwCXzYJAJQKAgUDbmlsCQC5CQIJAMwIAgIQJWQlZCVkJWQlZCVkJWQlZAkAzAgCCQCkAwEFAmNJCQDMCAIJAKQDAQkBAUcCBQJjYQUBYgkAzAgCCQCkAwEFAmJXCQDMCAIJAKQDAQUCYlkJAMwIAgkApAMBBQJiVgkAzAgCBQJiVQkAzAgCCQCkAwEFAmNsCQDMCAIJAKQDAQUCY24FA25pbAUBagJkZgETZXZhbHVhdGVHZXRSRUFET05MWQICZkYCZkcEAmNBCQECYk4EAgAFAmZGBQJmRwUEdGhpcwQCY2cIBQJjQQJfMQQCY2gIBQJjQQJfMgQCYlcIBQJjQQJfNQQCYlkIBQJjQQJfNgQCYlYIBQJjQQJfNwQCY2IIBQJjQQJfOAQCYlUJAQ1wYXJzZUludFZhbHVlAQgFAmNBAl85CQCUCgIFA25pbAkAuQkCCQDMCAICDiVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCY2cJAMwIAgkApAMBBQJjaAkAzAgCCQCkAwEFAmJXCQDMCAIJAKQDAQUCYlkJAMwIAgkApAMBBQJiVgkAzAgCCQCmAwEFAmNiCQDMCAIJAKQDAQUCYlUFA25pbAUBagECZkgBAmZJAAQCZkoEAmRxCQECZXkAAwkAAQIFAmRxAgpCeXRlVmVjdG9yBAJlRAUCZHEFAmVEAwkAAQIFAmRxAgRVbml0CAUCZkgPc2VuZGVyUHVibGljS2V5CQACAQILTWF0Y2ggZXJyb3IEAmRxBQJmSAMJAAECBQJkcQIFT3JkZXIEAmNSBQJkcQQCZksJAQJhRwAEAmF1CQECY1EBBQJjUgQCYXYJAPQDAwgFAmNSCWJvZHlCeXRlcwkAkQMCCAUCY1IGcHJvb2ZzAAAIBQJjUg9zZW5kZXJQdWJsaWNLZXkEAmF3CQD0AwMIBQJjUglib2R5Qnl0ZXMJAJEDAggFAmNSBnByb29mcwABBQJmSwMDAwUCYXUFAmF2BwUCYXcHBgkBAmF0AwUCYXUFAmF2BQJhdwMJAAECBQJkcQIUU2V0U2NyaXB0VHJhbnNhY3Rpb24EAmV6BQJkcQQCZkwJAPYDAQkBBXZhbHVlAQgFAmV6BnNjcmlwdAQCZk0JANsEAQkBBXZhbHVlAQkAnQgCBQJhRAkBAmFyAAQCZk4JAPEHAQUEdGhpcwMDCQAAAgUCZk0FAmZMCQECIT0CBQJmTgUCZkwHBgkA9AMDCAUCZkgJYm9keUJ5dGVzCQCRAwIIBQJmSAZwcm9vZnMAAAUCZkoJAPQDAwgFAmZICWJvZHlCeXRlcwkAkQMCCAUCZkgGcHJvb2ZzAAAFAmZKgGPfUg==", "chainId": 84, "height": 2289041, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: BK9LqMSt713rJi2edsJK1CeFtCwVHzTM83tq7B1CVoP3 Next: BG7m97m8mxcMFWhkpuCZDKM11DTTWqDtu12AvSEhFp7M Diff:
OldNewDifferences
6868 func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
6969
7070
71-func abs (val) = if ((zeroBigInt > val))
71+func abs (val) = if ((0 > val))
72+ then -(val)
73+ else val
74+
75+
76+func absBigInt (val) = if ((zeroBigInt > val))
7277 then -(val)
7378 else val
7479
178183
179184 let poolConfigParsed = parsePoolConfig(getPoolConfig())
180185
181-let $t074847650 = poolConfigParsed
186+let $t075437709 = poolConfigParsed
182187
183-let cfgPoolAddress = $t074847650._1
188+let cfgPoolAddress = $t075437709._1
184189
185-let cfgPoolStatus = $t074847650._2
190+let cfgPoolStatus = $t075437709._2
186191
187-let cfgLpAssetId = $t074847650._3
192+let cfgLpAssetId = $t075437709._3
188193
189-let cfgAmountAssetId = $t074847650._4
194+let cfgAmountAssetId = $t075437709._4
190195
191-let cfgPriceAssetId = $t074847650._5
196+let cfgPriceAssetId = $t075437709._5
192197
193-let cfgAmountAssetDecimals = $t074847650._6
198+let cfgAmountAssetDecimals = $t075437709._6
194199
195-let cfgPriceAssetDecimals = $t074847650._7
200+let cfgPriceAssetDecimals = $t075437709._7
196201
197202 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
198203
316321 }
317322 else {
318323 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
319- let slippageX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
324+ let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
320325 let slippageToleranceX18 = toX18(slippageTolerance, scale8)
321326 if (if ((curPriceX18 != zeroBigInt))
322327 then (slippageX18 > slippageToleranceX18)
462467
463468 func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
464469 let isEval = (txId == unit)
465- let $t02216722345 = parsePoolConfig(getPoolConfig())
466- let poolAddress = $t02216722345._1
467- let poolStatus = $t02216722345._2
468- let lpAssetId = $t02216722345._3
469- let amountAssetId = $t02216722345._4
470- let priceAssetId = $t02216722345._5
471- let amountAssetDecimals = $t02216722345._6
472- let priceAssetDecimals = $t02216722345._7
470+ let $t02223222410 = parsePoolConfig(getPoolConfig())
471+ let poolAddress = $t02223222410._1
472+ let poolStatus = $t02223222410._2
473+ let lpAssetId = $t02223222410._3
474+ let amountAssetId = $t02223222410._4
475+ let priceAssetId = $t02223222410._5
476+ let amountAssetDecimals = $t02223222410._6
477+ let priceAssetDecimals = $t02223222410._7
473478 let amountBalanceRaw = getAccBalance(assetIdToString(amountAssetId))
474479 let priceBalanceRaw = getAccBalance(assetIdToString(priceAssetId))
475480 let paymentInAmountAsset = if ((paymentAssetId == amountAssetId))
477482 else if ((paymentAssetId == priceAssetId))
478483 then false
479484 else throwErr("invalid asset")
480- let $t02267522968 = if (isEval)
485+ let $t02274023033 = if (isEval)
481486 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
482487 else if (paymentInAmountAsset)
483488 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
484489 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
485- let amountBalanceOld = $t02267522968._1
486- let priceBalanceOld = $t02267522968._2
487- let $t02297223121 = if (paymentInAmountAsset)
490+ let amountBalanceOld = $t02274023033._1
491+ let priceBalanceOld = $t02274023033._2
492+ let $t02303723186 = if (paymentInAmountAsset)
488493 then $Tuple2(paymentAmountRaw, 0)
489494 else $Tuple2(0, paymentAmountRaw)
490- let amountAssetAmountRaw = $t02297223121._1
491- let priceAssetAmountRaw = $t02297223121._2
495+ let amountAssetAmountRaw = $t02303723186._1
496+ let priceAssetAmountRaw = $t02303723186._2
492497 let amountAssetAmount = takeFee(amountAssetAmountRaw)._1
493498 let priceAssetAmount = takeFee(priceAssetAmountRaw)._1
494- let $t02324323302 = takeFee(paymentAmountRaw)
495- let paymentAmount = $t02324323302._1
496- let feeAmount = $t02324323302._2
499+ let $t02330823367 = takeFee(paymentAmountRaw)
500+ let paymentAmount = $t02330823367._1
501+ let feeAmount = $t02330823367._2
497502 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
498503 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
499- let curPrice = fromX18(calcPriceBigInt(toX18(priceBalanceNew, priceAssetDecimals), toX18(amountBalanceNew, amountAssetDecimals)), scale8)
504+ let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, priceAssetDecimals), toX18(amountBalanceNew, amountAssetDecimals))
505+ let priceNew = fromX18(priceNewX18, scale8)
500506 let paymentBalance = if (paymentInAmountAsset)
501507 then amountBalanceOld
502508 else priceBalanceOld
511517 let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
512518 let commonState = if (isEval)
513519 then nil
514- else [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(toString(value(userAddress)), toBase58String(value(txId))), dataPutActionInfo(amountAssetAmountRaw, priceAssetAmountRaw, issueAmount, curPrice, 0, 0, height, lastBlock.timestamp, 0, 0))]
515- let poolProportion = fraction(priceBalanceOld, scale8, amountBalanceOld)
516- let amountAssetPart = fraction(paymentAmountRaw, scale8, (poolProportion + scale8))
517- let priceAssetPart = (paymentAmountRaw - amountAssetPart)
518- let lpAmtBoth = toInt(fraction(supplyBigInt, toBigInt(priceAssetPart), toBigInt(priceBalanceOld)))
519- let bonus = if ((lpAmtBoth == 0))
520- then if ((issueAmount == 0))
521- then 0
522- else throwErr("bonus calculation error")
523- else fraction((issueAmount - lpAmtBoth), scale8, lpAmtBoth)
524- $Tuple4(issueAmount, commonState, feeAmount, bonus)
520+ 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))]
521+ let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, priceAssetDecimals), toX18(amountBalanceOld, amountAssetDecimals))
522+ let priceOld = fromX18(priceOldX18, scale8)
523+ let priceImpact = abs((((priceNew - priceOld) * scale8) / priceOld))
524+ $Tuple4(issueAmount, commonState, feeAmount, priceImpact)
525525 }
526526 else throw("Strict value is not equal to itself.")
527527 }
529529
530530 func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
531531 let isEval = (txId == unit)
532- let $t02536425525 = parsePoolConfig(getPoolConfig())
533- let poolAddress = $t02536425525._1
534- let poolStatus = $t02536425525._2
535- let lpAssetId = $t02536425525._3
536- let amountAssetId = $t02536425525._4
537- let priceAssetId = $t02536425525._5
538- let amDecimals = $t02536425525._6
539- let prDecimals = $t02536425525._7
532+ let $t02518925350 = parsePoolConfig(getPoolConfig())
533+ let poolAddress = $t02518925350._1
534+ let poolStatus = $t02518925350._2
535+ let lpAssetId = $t02518925350._3
536+ let amountAssetId = $t02518925350._4
537+ let priceAssetId = $t02518925350._5
538+ let amDecimals = $t02518925350._6
539+ let prDecimals = $t02518925350._7
540540 let checks = [if ((paymentAssetId == lpAssetId))
541541 then true
542542 else throwErr("invalid lp asset")]
559559 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(lpAssetId), (("asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity)
560560 let redeemedBigInt = toBigInt(paymentAmount)
561561 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
562- let $t02660026650 = takeFee(amountRaw)
563- let totalAmount = $t02660026650._1
564- let feeAmount = $t02660026650._2
565- let $t02665426880 = if (outInAmountAsset)
562+ let $t02642526475 = takeFee(amountRaw)
563+ let totalAmount = $t02642526475._1
564+ let feeAmount = $t02642526475._2
565+ let $t02647926705 = if (outInAmountAsset)
566566 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
567567 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
568- let outAmAmount = $t02665426880._1
569- let outPrAmount = $t02665426880._2
570- let amBalanceNew = $t02665426880._3
571- let prBalanceNew = $t02665426880._4
572- let curPrX18 = calcPriceBigInt(toX18(prBalanceNew, prDecimals), toX18(amBalanceNew, amDecimals))
573- let curPrice = fromX18(curPrX18, scale8)
568+ let outAmAmount = $t02647926705._1
569+ let outPrAmount = $t02647926705._2
570+ let amBalanceNew = $t02647926705._3
571+ let prBalanceNew = $t02647926705._4
572+ let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, prDecimals), toX18(amBalanceNew, amDecimals))
573+ let priceNew = fromX18(priceNewX18, scale8)
574574 let commonState = if (isEval)
575575 then nil
576- else [StringEntry(gau(toString(value(userAddress)), toBase58String(value(txId))), dataGetActionInfo(outAmAmount, outPrAmount, paymentAmount, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
577- let r = estimateGetOperation("", assetIdToString(lpAssetId), paymentAmount, this)
578- let sumOfGetAssets = (r._1 + r._2)
579- let bonus = if ((sumOfGetAssets == 0))
580- then if ((totalAmount == 0))
581- then 0
582- else throwErr("bonus calculation error")
583- else fraction((totalAmount - sumOfGetAssets), scale8, sumOfGetAssets)
584- $Tuple4(totalAmount, commonState, feeAmount, bonus)
576+ 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)]
577+ let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, prDecimals), toX18(amBalanceOld, amDecimals))
578+ let priceOld = fromX18(priceOldX18, scale8)
579+ let priceImpact = abs((((priceNew - priceOld) * scale8) / priceOld))
580+ $Tuple4(totalAmount, commonState, feeAmount, priceImpact)
585581 }
586582 else throw("Strict value is not equal to itself.")
587583 }
742738 let paymentAmountRaw = payment.amount
743739 let userAddress = i.caller
744740 let txId = i.transactionId
745- let $t03134731474 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
746- let emitAmountEstimated = $t03134731474._1
747- let commonState = $t03134731474._2
748- let feeAmount = $t03134731474._3
749- let bonus = $t03134731474._4
741+ let $t03105731184 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
742+ let emitAmountEstimated = $t03105731184._1
743+ let commonState = $t03105731184._2
744+ let feeAmount = $t03105731184._3
745+ let bonus = $t03105731184._4
750746 let emitAmount = if (if ((minOutAmount > 0))
751747 then (minOutAmount > emitAmountEstimated)
752748 else false)
777773
778774 @Callable(i)
779775 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
780- let $t03220332338 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
781- let emitAmountEstimated = $t03220332338._1
782- let commonState = $t03220332338._2
783- let feeAmount = $t03220332338._3
784- let bonus = $t03220332338._4
776+ let $t03191332048 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
777+ let emitAmountEstimated = $t03191332048._1
778+ let commonState = $t03191332048._2
779+ let feeAmount = $t03191332048._3
780+ let bonus = $t03191332048._4
785781 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
786782 }
787783
805801 let paymentAmount = payment.amount
806802 let userAddress = i.caller
807803 let txId = i.transactionId
808- let $t03292633058 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
809- let amountEstimated = $t03292633058._1
810- let commonState = $t03292633058._2
811- let feeAmount = $t03292633058._3
812- let bonus = $t03292633058._4
804+ let $t03263632768 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
805+ let amountEstimated = $t03263632768._1
806+ let commonState = $t03263632768._2
807+ let feeAmount = $t03263632768._3
808+ let bonus = $t03263632768._4
813809 let amount = if (if ((minOutAmount > 0))
814810 then (minOutAmount > amountEstimated)
815811 else false)
833829
834830 @Callable(i)
835831 func getOneTknREADONLY (outAssetId,paymentAmount) = {
836- let $t03369333831 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
837- let amountEstimated = $t03369333831._1
838- let commonState = $t03369333831._2
839- let feeAmount = $t03369333831._3
840- let bonus = $t03369333831._4
832+ let $t03340333541 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
833+ let amountEstimated = $t03340333541._1
834+ let commonState = $t03340333541._2
835+ let feeAmount = $t03340333541._3
836+ let bonus = $t03340333541._4
841837 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
842838 }
843839
859855 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
860856 if ((unstakeInv == unstakeInv))
861857 then {
862- let $t03438134504 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, unit, unit)
863- let amountEstimated = $t03438134504._1
864- let commonState = $t03438134504._2
865- let feeAmount = $t03438134504._3
866- let bonus = $t03438134504._4
858+ let $t03409134214 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, unit, unit)
859+ let amountEstimated = $t03409134214._1
860+ let commonState = $t03409134214._2
861+ let feeAmount = $t03409134214._3
862+ let bonus = $t03409134214._4
867863 let amount = if (if ((minOutAmount > 0))
868864 then (minOutAmount > amountEstimated)
869865 else false)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let lPdecimals = 8
55
66 let scale8 = 100000000
77
88 let scale8BigInt = toBigInt(100000000)
99
1010 let scale18 = toBigInt(1000000000000000000)
1111
1212 let zeroBigInt = toBigInt(0)
1313
1414 let big0 = toBigInt(0)
1515
1616 let big1 = toBigInt(1)
1717
1818 let big2 = toBigInt(2)
1919
2020 let wavesString = "WAVES"
2121
2222 let SEP = "__"
2323
2424 let PoolActive = 1
2525
2626 let PoolPutDisabled = 2
2727
2828 let PoolMatcherDisabled = 3
2929
3030 let PoolShutdown = 4
3131
3232 let idxPoolAddress = 1
3333
3434 let idxPoolStatus = 2
3535
3636 let idxPoolLPAssetId = 3
3737
3838 let idxAmtAssetId = 4
3939
4040 let idxPriceAssetId = 5
4141
4242 let idxAmtAssetDcm = 6
4343
4444 let idxPriceAssetDcm = 7
4545
4646 let idxIAmtAssetId = 8
4747
4848 let idxIPriceAssetId = 9
4949
5050 let idxLPAssetDcm = 10
5151
5252 let idxPoolAmtAssetAmt = 1
5353
5454 let idxPoolPriceAssetAmt = 2
5555
5656 let idxPoolLPAssetAmt = 3
5757
5858 let idxFactoryStakingContract = 1
5959
6060 let idxFactorySlippageContract = 7
6161
6262 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
6363
6464
6565 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
6666
6767
6868 func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale)
6969
7070
71-func abs (val) = if ((zeroBigInt > val))
71+func abs (val) = if ((0 > val))
72+ then -(val)
73+ else val
74+
75+
76+func absBigInt (val) = if ((zeroBigInt > val))
7277 then -(val)
7378 else val
7479
7580
7681 func fc () = "%s__factoryContract"
7782
7883
7984 func mpk () = "%s__managerPublicKey"
8085
8186
8287 func pmpk () = "%s__pendingManagerPublicKey"
8388
8489
8590 func pl () = "%s%s__price__last"
8691
8792
8893 func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP)
8994
9095
9196 func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId)
9297
9398
9499 func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId)
95100
96101
97102 func aa () = "%s__amountAsset"
98103
99104
100105 func pa () = "%s__priceAsset"
101106
102107
103108 let keyFee = "%s__fee"
104109
105110 let feeDefault = fraction(5, scale8, 10000)
106111
107112 let fee = valueOrElse(getInteger(this, keyFee), feeDefault)
108113
109114 func keyFactoryConfig () = "%s__factoryConfig"
110115
111116
112117 func keyMatcherPub () = "%s%s__matcher__publicKey"
113118
114119
115120 func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset")
116121
117122
118123 func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config")
119124
120125
121126 func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr)
122127
123128
124129 func keyAllPoolsShutdown () = "%s__shutdown"
125130
126131
127132 func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress)
128133
129134
130135 func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash"
131136
132137
133138 let keyFeeCollectorAddress = "%s__feeCollectorAddress"
134139
135140 func throwOrderError (orderValid,senderValid,matcherValid) = throw(((((("order validation failed: orderValid=" + toString(orderValid)) + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid)))
136141
137142
138143 func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
139144
140145
141146 func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], ""))
142147
143148
144149 func throwErr (msg) = throw(makeString(["lp.ride:", msg], " "))
145150
146151
147152 let factoryContract = addressFromStringValue(getStringOrFail(this, fc()))
148153
149154 let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress))
150155
151156 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false)
152157
153158
154159 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub()))
155160
156161
157162 func getPoolConfig () = {
158163 let amtAsset = getStringOrFail(this, aa())
159164 let priceAsset = getStringOrFail(this, pa())
160165 let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset))
161166 let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset))
162167 split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP)
163168 }
164169
165170
166171 func parseAssetId (input) = if ((input == wavesString))
167172 then unit
168173 else fromBase58String(input)
169174
170175
171176 func assetIdToString (input) = if ((input == unit))
172177 then wavesString
173178 else toBase58String(value(input))
174179
175180
176181 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]))
177182
178183
179184 let poolConfigParsed = parsePoolConfig(getPoolConfig())
180185
181-let $t074847650 = poolConfigParsed
186+let $t075437709 = poolConfigParsed
182187
183-let cfgPoolAddress = $t074847650._1
188+let cfgPoolAddress = $t075437709._1
184189
185-let cfgPoolStatus = $t074847650._2
190+let cfgPoolStatus = $t075437709._2
186191
187-let cfgLpAssetId = $t074847650._3
192+let cfgLpAssetId = $t075437709._3
188193
189-let cfgAmountAssetId = $t074847650._4
194+let cfgAmountAssetId = $t075437709._4
190195
191-let cfgPriceAssetId = $t074847650._5
196+let cfgPriceAssetId = $t075437709._5
192197
193-let cfgAmountAssetDecimals = $t074847650._6
198+let cfgAmountAssetDecimals = $t075437709._6
194199
195-let cfgPriceAssetDecimals = $t074847650._7
200+let cfgPriceAssetDecimals = $t075437709._7
196201
197202 func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
198203
199204
200205 let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address")
201206
202207 let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address")
203208
204209 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)
205210
206211
207212 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)
208213
209214
210215 func getAccBalance (assetId) = if ((assetId == "WAVES"))
211216 then wavesBalance(this).available
212217 else assetBalance(this, fromBase58String(assetId))
213218
214219
215220 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
216221
217222
218223 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
219224 let amtAssetAmtX18 = toX18(amAmt, amAssetDcm)
220225 let priceAssetAmtX18 = toX18(prAmt, prAssetDcm)
221226 calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
222227 }
223228
224229
225230 func calcPrices (amAmt,prAmt,lpAmt) = {
226231 let cfg = getPoolConfig()
227232 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
228233 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
229234 let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt)
230235 let amAmtX18 = toX18(amAmt, amtAssetDcm)
231236 let prAmtX18 = toX18(prAmt, priceAssetDcm)
232237 let lpAmtX18 = toX18(lpAmt, scale8)
233238 let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
234239 let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
235240 [priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18]
236241 }
237242
238243
239244 func calculatePrices (amAmt,prAmt,lpAmt) = {
240245 let prices = calcPrices(amAmt, prAmt, lpAmt)
241246 [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)]
242247 }
243248
244249
245250 func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
246251 let cfg = getPoolConfig()
247252 let lpAssetId = cfg[idxPoolLPAssetId]
248253 let amAssetId = cfg[idxAmtAssetId]
249254 let prAssetId = cfg[idxPriceAssetId]
250255 let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
251256 let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
252257 let poolStatus = cfg[idxPoolStatus]
253258 let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity
254259 if ((lpAssetId != pmtAssetId))
255260 then throw("Invalid asset passed.")
256261 else {
257262 let amBalance = getAccBalance(amAssetId)
258263 let amBalanceX18 = toX18(amBalance, amAssetDcm)
259264 let prBalance = getAccBalance(prAssetId)
260265 let prBalanceX18 = toX18(prBalance, prAssetDcm)
261266 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
262267 let curPrice = fromX18(curPriceX18, scale8)
263268 let pmtLpAmtX18 = toX18(pmtLpAmt, scale8)
264269 let lpEmissionX18 = toX18(lpEmission, scale8)
265270 let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18)
266271 let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18)
267272 let outAmAmt = fromX18(outAmAmtX18, amAssetDcm)
268273 let outPrAmt = fromX18(outPrAmtX18, prAssetDcm)
269274 let state = if ((txId58 == ""))
270275 then nil
271276 else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES"))
272277 then unit
273278 else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES"))
274279 then unit
275280 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)]
276281 $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state)
277282 }
278283 }
279284
280285
281286 func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = {
282287 let cfg = getPoolConfig()
283288 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
284289 let amAssetIdStr = cfg[idxAmtAssetId]
285290 let prAssetIdStr = cfg[idxPriceAssetId]
286291 let iAmtAssetId = cfg[idxIAmtAssetId]
287292 let iPriceAssetId = cfg[idxIPriceAssetId]
288293 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
289294 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
290295 let poolStatus = cfg[idxPoolStatus]
291296 let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
292297 let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES")))
293298 let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES")))
294299 if (if ((amAssetIdStr != inAmAssetIdStr))
295300 then true
296301 else (prAssetIdStr != inPrAssetIdStr))
297302 then throw("Invalid amt or price asset passed.")
298303 else {
299304 let amBalance = if (isEvaluate)
300305 then getAccBalance(amAssetIdStr)
301306 else (getAccBalance(amAssetIdStr) - inAmAssetAmt)
302307 let prBalance = if (isEvaluate)
303308 then getAccBalance(prAssetIdStr)
304309 else (getAccBalance(prAssetIdStr) - inPrAssetAmt)
305310 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
306311 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
307312 let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18)
308313 let amBalanceX18 = toX18(amBalance, amtAssetDcm)
309314 let prBalanceX18 = toX18(prBalance, priceAssetDcm)
310315 let res = if ((lpEmission == 0))
311316 then {
312317 let curPriceX18 = zeroBigInt
313318 let slippageX18 = zeroBigInt
314319 let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN)
315320 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18)
316321 }
317322 else {
318323 let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18)
319- let slippageX18 = fraction(abs((curPriceX18 - userPriceX18)), scale18, curPriceX18)
324+ let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18)
320325 let slippageToleranceX18 = toX18(slippageTolerance, scale8)
321326 if (if ((curPriceX18 != zeroBigInt))
322327 then (slippageX18 > slippageToleranceX18)
323328 else false)
324329 then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18)))
325330 else {
326331 let lpEmissionX18 = toX18(lpEmission, scale8)
327332 let prViaAmX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
328333 let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
329334 let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18))
330335 then $Tuple2(amViaPrX18, inPrAssetAmtX18)
331336 else $Tuple2(inAmAssetAmtX18, prViaAmX18)
332337 let expAmtAssetAmtX18 = expectedAmts._1
333338 let expPriceAssetAmtX18 = expectedAmts._2
334339 let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18)
335340 $Tuple5(fromX18(lpAmtX18, scale8), fromX18(expAmtAssetAmtX18, amtAssetDcm), fromX18(expPriceAssetAmtX18, priceAssetDcm), curPriceX18, slippageX18)
336341 }
337342 }
338343 let calcLpAmt = res._1
339344 let calcAmAssetPmt = res._2
340345 let calcPrAssetPmt = res._3
341346 let curPrice = fromX18(res._4, scale8)
342347 let slippageCalc = fromX18(res._5, scale8)
343348 if ((0 >= calcLpAmt))
344349 then throw("Invalid calculations. LP calculated is less than zero.")
345350 else {
346351 let emitLpAmt = if (!(emitLp))
347352 then 0
348353 else calcLpAmt
349354 let amDiff = (inAmAssetAmt - calcAmAssetPmt)
350355 let prDiff = (inPrAssetAmt - calcPrAssetPmt)
351356 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))]
352357 $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId)
353358 }
354359 }
355360 }
356361
357362
358363 func validateMatcherOrderAllowed (order) = {
359364 let cfg = getPoolConfig()
360365 let amtAssetId = cfg[idxAmtAssetId]
361366 let priceAssetId = cfg[idxPriceAssetId]
362367 let poolStatus = parseIntValue(cfg[idxPoolStatus])
363368 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
364369 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
365370 let accAmtAssetBalance = getAccBalance(amtAssetId)
366371 let accPriceAssetBalance = getAccBalance(priceAssetId)
367372 let curPriceX18 = if ((order.orderType == Buy))
368373 then privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance + order.amount), accPriceAssetBalance)
369374 else privateCalcPrice(amtAssetDcm, priceAssetDcm, (accAmtAssetBalance - order.amount), accPriceAssetBalance)
370375 let curPrice = fromX18(curPriceX18, scale8)
371376 if (if (if (isGlobalShutdown())
372377 then true
373378 else (poolStatus == PoolMatcherDisabled))
374379 then true
375380 else (poolStatus == PoolShutdown))
376381 then throw("Exchange operations disabled")
377382 else {
378383 let orderAmtAsset = order.assetPair.amountAsset
379384 let orderAmtAssetStr = if ((orderAmtAsset == unit))
380385 then "WAVES"
381386 else toBase58String(value(orderAmtAsset))
382387 let orderPriceAsset = order.assetPair.priceAsset
383388 let orderPriceAssetStr = if ((orderPriceAsset == unit))
384389 then "WAVES"
385390 else toBase58String(value(orderPriceAsset))
386391 if (if ((orderAmtAssetStr != amtAssetId))
387392 then true
388393 else (orderPriceAssetStr != priceAssetId))
389394 then throw("Wrong order assets.")
390395 else {
391396 let orderPrice = order.price
392397 let priceDcm = fraction(scale8, priceAssetDcm, amtAssetDcm)
393398 let castedOrderPrice = toScale(orderPrice, scale8, priceDcm)
394399 let isOrderPriceValid = if ((order.orderType == Buy))
395400 then (curPrice >= castedOrderPrice)
396401 else (castedOrderPrice >= curPrice)
397402 true
398403 }
399404 }
400405 }
401406
402407
403408 func commonGet (i) = if ((size(i.payments) != 1))
404409 then throw("exactly 1 payment is expected")
405410 else {
406411 let pmt = value(i.payments[0])
407412 let pmtAssetId = value(pmt.assetId)
408413 let pmtAmt = pmt.amount
409414 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller)
410415 let outAmAmt = res._1
411416 let outPrAmt = res._2
412417 let poolStatus = parseIntValue(res._9)
413418 let state = res._10
414419 if (if (isGlobalShutdown())
415420 then true
416421 else (poolStatus == PoolShutdown))
417422 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
418423 else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state)
419424 }
420425
421426
422427 func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2))
423428 then throw("exactly 2 payments are expected")
424429 else {
425430 let amAssetPmt = value(i.payments[0])
426431 let prAssetPmt = value(i.payments[1])
427432 let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp)
428433 let poolStatus = parseIntValue(estPut._8)
429434 if (if (if (isGlobalShutdown())
430435 then true
431436 else (poolStatus == PoolPutDisabled))
432437 then true
433438 else (poolStatus == PoolShutdown))
434439 then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus)))
435440 else estPut
436441 }
437442
438443
439444 func emit (amount) = {
440445 let emitInv = invoke(factoryContract, "emit", [amount], nil)
441446 if ((emitInv == emitInv))
442447 then {
443448 let emitInvLegacy = match emitInv {
444449 case legacyFactoryContract: Address =>
445450 invoke(legacyFactoryContract, "emit", [amount], nil)
446451 case _ =>
447452 unit
448453 }
449454 if ((emitInvLegacy == emitInvLegacy))
450455 then amount
451456 else throw("Strict value is not equal to itself.")
452457 }
453458 else throw("Strict value is not equal to itself.")
454459 }
455460
456461
457462 func takeFee (amount) = {
458463 let feeAmount = fraction(amount, fee, scale8)
459464 $Tuple2((amount - feeAmount), feeAmount)
460465 }
461466
462467
463468 func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = {
464469 let isEval = (txId == unit)
465- let $t02216722345 = parsePoolConfig(getPoolConfig())
466- let poolAddress = $t02216722345._1
467- let poolStatus = $t02216722345._2
468- let lpAssetId = $t02216722345._3
469- let amountAssetId = $t02216722345._4
470- let priceAssetId = $t02216722345._5
471- let amountAssetDecimals = $t02216722345._6
472- let priceAssetDecimals = $t02216722345._7
470+ let $t02223222410 = parsePoolConfig(getPoolConfig())
471+ let poolAddress = $t02223222410._1
472+ let poolStatus = $t02223222410._2
473+ let lpAssetId = $t02223222410._3
474+ let amountAssetId = $t02223222410._4
475+ let priceAssetId = $t02223222410._5
476+ let amountAssetDecimals = $t02223222410._6
477+ let priceAssetDecimals = $t02223222410._7
473478 let amountBalanceRaw = getAccBalance(assetIdToString(amountAssetId))
474479 let priceBalanceRaw = getAccBalance(assetIdToString(priceAssetId))
475480 let paymentInAmountAsset = if ((paymentAssetId == amountAssetId))
476481 then true
477482 else if ((paymentAssetId == priceAssetId))
478483 then false
479484 else throwErr("invalid asset")
480- let $t02267522968 = if (isEval)
485+ let $t02274023033 = if (isEval)
481486 then $Tuple2(amountBalanceRaw, priceBalanceRaw)
482487 else if (paymentInAmountAsset)
483488 then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw)
484489 else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw))
485- let amountBalanceOld = $t02267522968._1
486- let priceBalanceOld = $t02267522968._2
487- let $t02297223121 = if (paymentInAmountAsset)
490+ let amountBalanceOld = $t02274023033._1
491+ let priceBalanceOld = $t02274023033._2
492+ let $t02303723186 = if (paymentInAmountAsset)
488493 then $Tuple2(paymentAmountRaw, 0)
489494 else $Tuple2(0, paymentAmountRaw)
490- let amountAssetAmountRaw = $t02297223121._1
491- let priceAssetAmountRaw = $t02297223121._2
495+ let amountAssetAmountRaw = $t02303723186._1
496+ let priceAssetAmountRaw = $t02303723186._2
492497 let amountAssetAmount = takeFee(amountAssetAmountRaw)._1
493498 let priceAssetAmount = takeFee(priceAssetAmountRaw)._1
494- let $t02324323302 = takeFee(paymentAmountRaw)
495- let paymentAmount = $t02324323302._1
496- let feeAmount = $t02324323302._2
499+ let $t02330823367 = takeFee(paymentAmountRaw)
500+ let paymentAmount = $t02330823367._1
501+ let feeAmount = $t02330823367._2
497502 let amountBalanceNew = (amountBalanceOld + amountAssetAmount)
498503 let priceBalanceNew = (priceBalanceOld + priceAssetAmount)
499- let curPrice = fromX18(calcPriceBigInt(toX18(priceBalanceNew, priceAssetDecimals), toX18(amountBalanceNew, amountAssetDecimals)), scale8)
504+ let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, priceAssetDecimals), toX18(amountBalanceNew, amountAssetDecimals))
505+ let priceNew = fromX18(priceNewX18, scale8)
500506 let paymentBalance = if (paymentInAmountAsset)
501507 then amountBalanceOld
502508 else priceBalanceOld
503509 let paymentBalanceBigInt = toBigInt(paymentBalance)
504510 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(lpAssetId), (("asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity)
505511 let chechSupply = if ((supplyBigInt > big0))
506512 then true
507513 else throwErr("initial deposit requires all coins")
508514 if ((chechSupply == chechSupply))
509515 then {
510516 let depositBigInt = toBigInt(paymentAmount)
511517 let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))])
512518 let commonState = if (isEval)
513519 then nil
514- else [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(toString(value(userAddress)), toBase58String(value(txId))), dataPutActionInfo(amountAssetAmountRaw, priceAssetAmountRaw, issueAmount, curPrice, 0, 0, height, lastBlock.timestamp, 0, 0))]
515- let poolProportion = fraction(priceBalanceOld, scale8, amountBalanceOld)
516- let amountAssetPart = fraction(paymentAmountRaw, scale8, (poolProportion + scale8))
517- let priceAssetPart = (paymentAmountRaw - amountAssetPart)
518- let lpAmtBoth = toInt(fraction(supplyBigInt, toBigInt(priceAssetPart), toBigInt(priceBalanceOld)))
519- let bonus = if ((lpAmtBoth == 0))
520- then if ((issueAmount == 0))
521- then 0
522- else throwErr("bonus calculation error")
523- else fraction((issueAmount - lpAmtBoth), scale8, lpAmtBoth)
524- $Tuple4(issueAmount, commonState, feeAmount, bonus)
520+ 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))]
521+ let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, priceAssetDecimals), toX18(amountBalanceOld, amountAssetDecimals))
522+ let priceOld = fromX18(priceOldX18, scale8)
523+ let priceImpact = abs((((priceNew - priceOld) * scale8) / priceOld))
524+ $Tuple4(issueAmount, commonState, feeAmount, priceImpact)
525525 }
526526 else throw("Strict value is not equal to itself.")
527527 }
528528
529529
530530 func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = {
531531 let isEval = (txId == unit)
532- let $t02536425525 = parsePoolConfig(getPoolConfig())
533- let poolAddress = $t02536425525._1
534- let poolStatus = $t02536425525._2
535- let lpAssetId = $t02536425525._3
536- let amountAssetId = $t02536425525._4
537- let priceAssetId = $t02536425525._5
538- let amDecimals = $t02536425525._6
539- let prDecimals = $t02536425525._7
532+ let $t02518925350 = parsePoolConfig(getPoolConfig())
533+ let poolAddress = $t02518925350._1
534+ let poolStatus = $t02518925350._2
535+ let lpAssetId = $t02518925350._3
536+ let amountAssetId = $t02518925350._4
537+ let priceAssetId = $t02518925350._5
538+ let amDecimals = $t02518925350._6
539+ let prDecimals = $t02518925350._7
540540 let checks = [if ((paymentAssetId == lpAssetId))
541541 then true
542542 else throwErr("invalid lp asset")]
543543 if ((checks == checks))
544544 then {
545545 let outInAmountAsset = if ((outAssetId == amountAssetId))
546546 then true
547547 else if ((outAssetId == priceAssetId))
548548 then false
549549 else throwErr("invalid asset")
550550 let balanceBigInt = if (outInAmountAsset)
551551 then toBigInt(getAccBalance(assetIdToString(amountAssetId)))
552552 else toBigInt(getAccBalance(assetIdToString(priceAssetId)))
553553 let amBalanceOld = getAccBalance(assetIdToString(amountAssetId))
554554 let prBalanceOld = getAccBalance(assetIdToString(priceAssetId))
555555 let outBalance = if (outInAmountAsset)
556556 then amBalanceOld
557557 else prBalanceOld
558558 let outBalanceBigInt = toBigInt(outBalance)
559559 let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(lpAssetId), (("asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity)
560560 let redeemedBigInt = toBigInt(paymentAmount)
561561 let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))])
562- let $t02660026650 = takeFee(amountRaw)
563- let totalAmount = $t02660026650._1
564- let feeAmount = $t02660026650._2
565- let $t02665426880 = if (outInAmountAsset)
562+ let $t02642526475 = takeFee(amountRaw)
563+ let totalAmount = $t02642526475._1
564+ let feeAmount = $t02642526475._2
565+ let $t02647926705 = if (outInAmountAsset)
566566 then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld)
567567 else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw))
568- let outAmAmount = $t02665426880._1
569- let outPrAmount = $t02665426880._2
570- let amBalanceNew = $t02665426880._3
571- let prBalanceNew = $t02665426880._4
572- let curPrX18 = calcPriceBigInt(toX18(prBalanceNew, prDecimals), toX18(amBalanceNew, amDecimals))
573- let curPrice = fromX18(curPrX18, scale8)
568+ let outAmAmount = $t02647926705._1
569+ let outPrAmount = $t02647926705._2
570+ let amBalanceNew = $t02647926705._3
571+ let prBalanceNew = $t02647926705._4
572+ let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, prDecimals), toX18(amBalanceNew, amDecimals))
573+ let priceNew = fromX18(priceNewX18, scale8)
574574 let commonState = if (isEval)
575575 then nil
576- else [StringEntry(gau(toString(value(userAddress)), toBase58String(value(txId))), dataGetActionInfo(outAmAmount, outPrAmount, paymentAmount, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)]
577- let r = estimateGetOperation("", assetIdToString(lpAssetId), paymentAmount, this)
578- let sumOfGetAssets = (r._1 + r._2)
579- let bonus = if ((sumOfGetAssets == 0))
580- then if ((totalAmount == 0))
581- then 0
582- else throwErr("bonus calculation error")
583- else fraction((totalAmount - sumOfGetAssets), scale8, sumOfGetAssets)
584- $Tuple4(totalAmount, commonState, feeAmount, bonus)
576+ 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)]
577+ let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, prDecimals), toX18(amBalanceOld, amDecimals))
578+ let priceOld = fromX18(priceOldX18, scale8)
579+ let priceImpact = abs((((priceNew - priceOld) * scale8) / priceOld))
580+ $Tuple4(totalAmount, commonState, feeAmount, priceImpact)
585581 }
586582 else throw("Strict value is not equal to itself.")
587583 }
588584
589585
590586 func managerPublicKeyOrUnit () = match getString(mpk()) {
591587 case s: String =>
592588 fromBase58String(s)
593589 case _: Unit =>
594590 unit
595591 case _ =>
596592 throw("Match error")
597593 }
598594
599595
600596 func pendingManagerPublicKeyOrUnit () = match getString(pmpk()) {
601597 case s: String =>
602598 fromBase58String(s)
603599 case _: Unit =>
604600 unit
605601 case _ =>
606602 throw("Match error")
607603 }
608604
609605
610606 func mustManager (i) = {
611607 let pd = throw("Permission denied")
612608 match managerPublicKeyOrUnit() {
613609 case pk: ByteVector =>
614610 if ((i.callerPublicKey == pk))
615611 then true
616612 else pd
617613 case _: Unit =>
618614 if ((i.caller == this))
619615 then true
620616 else pd
621617 case _ =>
622618 throw("Match error")
623619 }
624620 }
625621
626622
627623 @Callable(i)
628624 func setManager (pendingManagerPublicKey) = {
629625 let checkCaller = mustManager(i)
630626 if ((checkCaller == checkCaller))
631627 then {
632628 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
633629 if ((checkManagerPublicKey == checkManagerPublicKey))
634630 then [StringEntry(pmpk(), pendingManagerPublicKey)]
635631 else throw("Strict value is not equal to itself.")
636632 }
637633 else throw("Strict value is not equal to itself.")
638634 }
639635
640636
641637
642638 @Callable(i)
643639 func confirmManager () = {
644640 let pm = pendingManagerPublicKeyOrUnit()
645641 let hasPM = if (isDefined(pm))
646642 then true
647643 else throw("No pending manager")
648644 if ((hasPM == hasPM))
649645 then {
650646 let checkPM = if ((i.callerPublicKey == value(pm)))
651647 then true
652648 else throw("You are not pending manager")
653649 if ((checkPM == checkPM))
654650 then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())]
655651 else throw("Strict value is not equal to itself.")
656652 }
657653 else throw("Strict value is not equal to itself.")
658654 }
659655
660656
661657
662658 @Callable(i)
663659 func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance))
664660 then throw("Invalid slippageTolerance passed")
665661 else {
666662 let estPut = commonPut(i, slippageTolerance, true)
667663 let emitLpAmt = estPut._2
668664 let lpAssetId = estPut._7
669665 let state = estPut._9
670666 let amDiff = estPut._10
671667 let prDiff = estPut._11
672668 let amId = estPut._12
673669 let prId = estPut._13
674670 let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil)
675671 if ((emitInv == emitInv))
676672 then {
677673 let emitInvLegacy = match emitInv {
678674 case legacyFactoryContract: Address =>
679675 invoke(legacyFactoryContract, "emit", [emitLpAmt], nil)
680676 case _ =>
681677 unit
682678 }
683679 if ((emitInvLegacy == emitInvLegacy))
684680 then {
685681 let slippageAInv = if ((amDiff > 0))
686682 then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)])
687683 else nil
688684 if ((slippageAInv == slippageAInv))
689685 then {
690686 let slippagePInv = if ((prDiff > 0))
691687 then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)])
692688 else nil
693689 if ((slippagePInv == slippagePInv))
694690 then {
695691 let lpTransfer = if (shouldAutoStake)
696692 then {
697693 let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)])
698694 if ((slpStakeInv == slpStakeInv))
699695 then nil
700696 else throw("Strict value is not equal to itself.")
701697 }
702698 else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)]
703699 (state ++ lpTransfer)
704700 }
705701 else throw("Strict value is not equal to itself.")
706702 }
707703 else throw("Strict value is not equal to itself.")
708704 }
709705 else throw("Strict value is not equal to itself.")
710706 }
711707 else throw("Strict value is not equal to itself.")
712708 }
713709
714710
715711
716712 @Callable(i)
717713 func putForFree (maxSlippage) = if ((0 > maxSlippage))
718714 then throw("Invalid value passed")
719715 else {
720716 let estPut = commonPut(i, maxSlippage, false)
721717 estPut._9
722718 }
723719
724720
725721
726722 @Callable(i)
727723 func putOneTkn (minOutAmount,autoStake) = {
728724 let isPutDisabled = if (if (isGlobalShutdown())
729725 then true
730726 else (cfgPoolStatus == PoolPutDisabled))
731727 then true
732728 else (cfgPoolStatus == PoolShutdown)
733729 let checks = [if (!(isPutDisabled))
734730 then true
735731 else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1))
736732 then true
737733 else throwErr("exactly 1 payment are expected")]
738734 if ((checks == checks))
739735 then {
740736 let payment = i.payments[0]
741737 let paymentAssetId = payment.assetId
742738 let paymentAmountRaw = payment.amount
743739 let userAddress = i.caller
744740 let txId = i.transactionId
745- let $t03134731474 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
746- let emitAmountEstimated = $t03134731474._1
747- let commonState = $t03134731474._2
748- let feeAmount = $t03134731474._3
749- let bonus = $t03134731474._4
741+ let $t03105731184 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId)
742+ let emitAmountEstimated = $t03105731184._1
743+ let commonState = $t03105731184._2
744+ let feeAmount = $t03105731184._3
745+ let bonus = $t03105731184._4
750746 let emitAmount = if (if ((minOutAmount > 0))
751747 then (minOutAmount > emitAmountEstimated)
752748 else false)
753749 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
754750 else emitAmountEstimated
755751 let emitInv = emit(emitAmount)
756752 if ((emitInv == emitInv))
757753 then {
758754 let lpTransfer = if (autoStake)
759755 then {
760756 let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)])
761757 if ((stakeInv == stakeInv))
762758 then nil
763759 else throw("Strict value is not equal to itself.")
764760 }
765761 else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)]
766762 let sendFee = if ((feeAmount > 0))
767763 then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)]
768764 else nil
769765 $Tuple2(((commonState ++ lpTransfer) ++ sendFee), emitAmount)
770766 }
771767 else throw("Strict value is not equal to itself.")
772768 }
773769 else throw("Strict value is not equal to itself.")
774770 }
775771
776772
777773
778774 @Callable(i)
779775 func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = {
780- let $t03220332338 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
781- let emitAmountEstimated = $t03220332338._1
782- let commonState = $t03220332338._2
783- let feeAmount = $t03220332338._3
784- let bonus = $t03220332338._4
776+ let $t03191332048 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit)
777+ let emitAmountEstimated = $t03191332048._1
778+ let commonState = $t03191332048._2
779+ let feeAmount = $t03191332048._3
780+ let bonus = $t03191332048._4
785781 $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus))
786782 }
787783
788784
789785
790786 @Callable(i)
791787 func getOneTkn (outAssetIdStr,minOutAmount) = {
792788 let isGetDisabled = if (isGlobalShutdown())
793789 then true
794790 else (cfgPoolStatus == PoolShutdown)
795791 let checks = [if (!(isGetDisabled))
796792 then true
797793 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1))
798794 then true
799795 else throwErr("exactly 1 payment are expected")]
800796 if ((checks == checks))
801797 then {
802798 let outAssetId = parseAssetId(outAssetIdStr)
803799 let payment = i.payments[0]
804800 let paymentAssetId = payment.assetId
805801 let paymentAmount = payment.amount
806802 let userAddress = i.caller
807803 let txId = i.transactionId
808- let $t03292633058 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
809- let amountEstimated = $t03292633058._1
810- let commonState = $t03292633058._2
811- let feeAmount = $t03292633058._3
812- let bonus = $t03292633058._4
804+ let $t03263632768 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId)
805+ let amountEstimated = $t03263632768._1
806+ let commonState = $t03263632768._2
807+ let feeAmount = $t03263632768._3
808+ let bonus = $t03263632768._4
813809 let amount = if (if ((minOutAmount > 0))
814810 then (minOutAmount > amountEstimated)
815811 else false)
816812 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
817813 else amountEstimated
818814 let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
819815 if ((burnInv == burnInv))
820816 then {
821817 let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)]
822818 let sendFee = if ((feeAmount > 0))
823819 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
824820 else nil
825821 $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
826822 }
827823 else throw("Strict value is not equal to itself.")
828824 }
829825 else throw("Strict value is not equal to itself.")
830826 }
831827
832828
833829
834830 @Callable(i)
835831 func getOneTknREADONLY (outAssetId,paymentAmount) = {
836- let $t03369333831 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
837- let amountEstimated = $t03369333831._1
838- let commonState = $t03369333831._2
839- let feeAmount = $t03369333831._3
840- let bonus = $t03369333831._4
832+ let $t03340333541 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit)
833+ let amountEstimated = $t03340333541._1
834+ let commonState = $t03340333541._2
835+ let feeAmount = $t03340333541._3
836+ let bonus = $t03340333541._4
841837 $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus))
842838 }
843839
844840
845841
846842 @Callable(i)
847843 func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = {
848844 let isGetDisabled = if (isGlobalShutdown())
849845 then true
850846 else (cfgPoolStatus == PoolShutdown)
851847 let checks = [if (!(isGetDisabled))
852848 then true
853849 else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0))
854850 then true
855851 else throwErr("no payments are expected")]
856852 if ((checks == checks))
857853 then {
858854 let outAssetId = parseAssetId(outAssetIdStr)
859855 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil)
860856 if ((unstakeInv == unstakeInv))
861857 then {
862- let $t03438134504 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, unit, unit)
863- let amountEstimated = $t03438134504._1
864- let commonState = $t03438134504._2
865- let feeAmount = $t03438134504._3
866- let bonus = $t03438134504._4
858+ let $t03409134214 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, unit, unit)
859+ let amountEstimated = $t03409134214._1
860+ let commonState = $t03409134214._2
861+ let feeAmount = $t03409134214._3
862+ let bonus = $t03409134214._4
867863 let amount = if (if ((minOutAmount > 0))
868864 then (minOutAmount > amountEstimated)
869865 else false)
870866 then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], ""))
871867 else amountEstimated
872868 let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)])
873869 if ((burnInv == burnInv))
874870 then {
875871 let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)]
876872 let sendFee = if ((feeAmount > 0))
877873 then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)]
878874 else nil
879875 $Tuple2(((commonState ++ assetTransfer) ++ sendFee), amount)
880876 }
881877 else throw("Strict value is not equal to itself.")
882878 }
883879 else throw("Strict value is not equal to itself.")
884880 }
885881 else throw("Strict value is not equal to itself.")
886882 }
887883
888884
889885
890886 @Callable(i)
891887 func get () = {
892888 let res = commonGet(i)
893889 let outAmtAmt = res._1
894890 let outPrAmt = res._2
895891 let pmtAmt = res._3
896892 let pmtAssetId = res._4
897893 let state = res._5
898894 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
899895 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
900896 then state
901897 else throw("Strict value is not equal to itself.")
902898 }
903899
904900
905901
906902 @Callable(i)
907903 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
908904 let res = commonGet(i)
909905 let outAmAmt = res._1
910906 let outPrAmt = res._2
911907 let pmtAmt = res._3
912908 let pmtAssetId = res._4
913909 let state = res._5
914910 if ((noLessThenAmtAsset > outAmAmt))
915911 then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset)))
916912 else if ((noLessThenPriceAsset > outPrAmt))
917913 then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset)))
918914 else {
919915 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)])
920916 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
921917 then state
922918 else throw("Strict value is not equal to itself.")
923919 }
924920 }
925921
926922
927923
928924 @Callable(i)
929925 func unstakeAndGet (amount) = {
930926 let checkPayments = if ((size(i.payments) != 0))
931927 then throw("No payments are expected")
932928 else true
933929 if ((checkPayments == checkPayments))
934930 then {
935931 let cfg = getPoolConfig()
936932 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
937933 let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil)
938934 if ((unstakeInv == unstakeInv))
939935 then {
940936 let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
941937 let poolStatus = parseIntValue(res._9)
942938 let state = res._10
943939 let checkPoolStatus = if (if (isGlobalShutdown())
944940 then true
945941 else (poolStatus == PoolShutdown))
946942 then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus)))
947943 else true
948944 if ((checkPoolStatus == checkPoolStatus))
949945 then {
950946 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
951947 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
952948 then state
953949 else throw("Strict value is not equal to itself.")
954950 }
955951 else throw("Strict value is not equal to itself.")
956952 }
957953 else throw("Strict value is not equal to itself.")
958954 }
959955 else throw("Strict value is not equal to itself.")
960956 }
961957
962958
963959
964960 @Callable(i)
965961 func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract)))
966962 then throw("permissions denied")
967963 else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success")
968964
969965
970966
971967 @Callable(i)
972968 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
973969
974970
975971
976972 @Callable(i)
977973 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
978974
979975
980976
981977 @Callable(i)
982978 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
983979 let prices = calcPrices(amAmt, prAmt, lpAmt)
984980 $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])])
985981 }
986982
987983
988984
989985 @Callable(i)
990986 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
991987
992988
993989
994990 @Callable(i)
995991 func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult))
996992
997993
998994
999995 @Callable(i)
1000996 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
1001997
1002998
1003999
10041000 @Callable(i)
10051001 func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp))
10061002
10071003
10081004
10091005 @Callable(i)
10101006 func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = {
10111007 let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress))
10121008 $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10))
10131009 }
10141010
10151011
10161012
10171013 @Callable(i)
10181014 func statsREADONLY () = {
10191015 let cfg = getPoolConfig()
10201016 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
10211017 let amtAssetId = cfg[idxAmtAssetId]
10221018 let priceAssetId = cfg[idxPriceAssetId]
10231019 let iAmtAssetId = cfg[idxIAmtAssetId]
10241020 let iPriceAssetId = cfg[idxIPriceAssetId]
10251021 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
10261022 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
10271023 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
10281024 let accAmtAssetBalance = getAccBalance(amtAssetId)
10291025 let accPriceAssetBalance = getAccBalance(priceAssetId)
10301026 let pricesList = if ((poolLPBalance == 0))
10311027 then [zeroBigInt, zeroBigInt, zeroBigInt]
10321028 else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance)
10331029 let curPrice = 0
10341030 let lpAmtAssetShare = fromX18(pricesList[1], scale8)
10351031 let lpPriceAssetShare = fromX18(pricesList[2], scale8)
10361032 let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this))))
10371033 $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))
10381034 }
10391035
10401036
10411037
10421038 @Callable(i)
10431039 func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = {
10441040 let cfg = getPoolConfig()
10451041 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
10461042 let amAssetIdStr = cfg[idxAmtAssetId]
10471043 let amAssetId = fromBase58String(amAssetIdStr)
10481044 let prAssetIdStr = cfg[idxPriceAssetId]
10491045 let prAssetId = fromBase58String(prAssetIdStr)
10501046 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
10511047 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
10521048 let poolStatus = cfg[idxPoolStatus]
10531049 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
10541050 let accAmtAssetBalance = getAccBalance(amAssetIdStr)
10551051 let accPriceAssetBalance = getAccBalance(prAssetIdStr)
10561052 let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm)
10571053 let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm)
10581054 let curPriceX18 = if ((poolLPBalance == 0))
10591055 then zeroBigInt
10601056 else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18)
10611057 let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm)
10621058 let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18)
10631059 let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm)
10641060 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
10651061 let calcLpAmt = estPut._1
10661062 let curPriceCalc = estPut._3
10671063 let amBalance = estPut._4
10681064 let prBalance = estPut._5
10691065 let lpEmission = estPut._6
10701066 $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))
10711067 }
10721068
10731069
10741070
10751071 @Callable(i)
10761072 func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = {
10771073 let cfg = getPoolConfig()
10781074 let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId])
10791075 let amAssetIdStr = cfg[idxAmtAssetId]
10801076 let amAssetId = fromBase58String(amAssetIdStr)
10811077 let prAssetIdStr = cfg[idxPriceAssetId]
10821078 let prAssetId = fromBase58String(prAssetIdStr)
10831079 let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm])
10841080 let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm])
10851081 let poolStatus = cfg[idxPoolStatus]
10861082 let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity
10871083 let amBalanceRaw = getAccBalance(amAssetIdStr)
10881084 let prBalanceRaw = getAccBalance(prAssetIdStr)
10891085 let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm)
10901086 let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm)
10911087 let curPriceX18 = if ((poolLPBalance == 0))
10921088 then zeroBigInt
10931089 else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18)
10941090 let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm)
10951091 let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18)
10961092 let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm)
10971093 let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false)
10981094 let calcLpAmt = estPut._1
10991095 let curPriceCalc = estPut._3
11001096 let amBalance = estPut._4
11011097 let prBalance = estPut._5
11021098 let lpEmission = estPut._6
11031099 $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))
11041100 }
11051101
11061102
11071103
11081104 @Callable(i)
11091105 func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = {
11101106 let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this)
11111107 let outAmAmt = res._1
11121108 let outPrAmt = res._2
11131109 let amBalance = res._5
11141110 let prBalance = res._6
11151111 let lpEmission = res._7
11161112 let curPrice = res._8
11171113 let poolStatus = parseIntValue(res._9)
11181114 $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))
11191115 }
11201116
11211117
11221118 @Verifier(tx)
11231119 func verify () = {
11241120 let targetPublicKey = match managerPublicKeyOrUnit() {
11251121 case pk: ByteVector =>
11261122 pk
11271123 case _: Unit =>
11281124 tx.senderPublicKey
11291125 case _ =>
11301126 throw("Match error")
11311127 }
11321128 match tx {
11331129 case order: Order =>
11341130 let matcherPub = getMatcherPubOrFail()
11351131 let orderValid = validateMatcherOrderAllowed(order)
11361132 let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
11371133 let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub)
11381134 if (if (if (orderValid)
11391135 then senderValid
11401136 else false)
11411137 then matcherValid
11421138 else false)
11431139 then true
11441140 else throwOrderError(orderValid, senderValid, matcherValid)
11451141 case s: SetScriptTransaction =>
11461142 let newHash = blake2b256(value(s.script))
11471143 let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash())))
11481144 let currentHash = scriptHash(this)
11491145 if (if ((allowedHash == newHash))
11501146 then (currentHash != newHash)
11511147 else false)
11521148 then true
11531149 else sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
11541150 case _ =>
11551151 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
11561152 }
11571153 }
11581154

github/deemru/w8io/873ac7e 
651.50 ms