tx · 7TWuUDmGmaHU9G5CzN24GHdhCC47BJSULNmFnTyEkjjf

3MzKSdTH2jFbypLsoNfrH7QgkzSbx3EYwCA:  -0.02600000 Waves

2022.08.15 17:50 [2185721] smart account 3MzKSdTH2jFbypLsoNfrH7QgkzSbx3EYwCA > SELF 0.00000000 Waves

{ "type": 13, "id": "7TWuUDmGmaHU9G5CzN24GHdhCC47BJSULNmFnTyEkjjf", "fee": 2600000, "feeAssetId": null, "timestamp": 1660575010319, "version": 1, "sender": "3MzKSdTH2jFbypLsoNfrH7QgkzSbx3EYwCA", "senderPublicKey": "35yd3qw1gxKDxKwGAykHN9fANbXNWwseaUwbWDj24o3x", "proofs": [ "4eFYMrEWe4Equ6vU71eipVXHFuS3JpwAauwzTmEPvZajaaG8nx1r4c41oXni7YEdzqhM7Trrhdj2VLXyDHjdmpzV" ], "script": "base64:BgL+HwgCEgMKAQgSAwoBCBIAEgQKAgEEEgcKBQEBAQEEEgMKAQESABIHCgUBAQEIARIECgIBARIDCgEBEgQKAggIEgQKAggIEgQKAggBEgASAwoBCBIFCgMBAQESBAoCCAESBAoCAQESBAoCCAgSCwoJCAEBAgECCAQEEgYKBAgIAQgiBnNjYWxlOCIMc2NhbGU4QmlnSW50IgdzY2FsZTE4Igh0aG91c2FuZCIKemVyb0JpZ0ludCIJb25lQmlnSW50IgpzbGlwcGFnZTREIgVBbXVsdCIFRGNvbnYiA1NFUCIFRU1QVFkiClBvb2xBY3RpdmUiClBvb2xQdXREaXMiDlBvb2xNYXRjaGVyRGlzIgxQb29sU2h1dGRvd24iDmlkeFBvb2xBZGRyZXNzIglpZHhQb29sU3QiCWlkeExQQXNJZCIJaWR4QW1Bc0lkIglpZHhQckFzSWQiC2lkeEFtdEFzRGNtIg1pZHhQcmljZUFzRGNtIgtpZHhJQW10QXNJZCINaWR4SVByaWNlQXNJZCIPaWR4RmFjdFN0YWtDbnRyIhBpZHhGYWN0U2xpcHBDbnRyIhFpZHhGYWN0R3d4UmV3Q250ciISZmVlUGVybWlsbGVEZWZhdWx0IgV0b1gxOCIHb3JpZ1ZhbCINb3JpZ1NjYWxlTXVsdCIHZnJvbVgxOCIDdmFsIg9yZXN1bHRTY2FsZU11bHQiAnRzIgNhbXQiCHJlc1NjYWxlIghjdXJTY2FsZSIDYWJzIhFrZXlGYWN0b3J5Q29udGFjdCITa2V5TWFuYWdlclB1YmxpY0tleSIaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkiDGtleVByaWNlTGFzdCIPa2V5UHJpY2VIaXN0b3J5IgFoIgF0IhJrZXlQdXRBY3Rpb25CeVVzZXIiAnVhIgR0eElkIhJrZXlHZXRBY3Rpb25CeVVzZXIiDmtleUFtb3VudEFzc2V0Ig1rZXlQcmljZUFzc2V0Ig9rZXlBbXBsaWZpY2F0b3IiD2tleUFkZG9uQWRkcmVzcyIOa2V5RmVlUGVybWlsbGUiC2ZlZVBlcm1pbGxlIgRmY2ZnIgRtdHBrIgJwYyIGaUFtdEFzIgVpUHJBcyIDbWJhIgViQVN0ciIDYXBzIgh0aHJvd0VyciIDbXNnIg90aHJvd09yZGVyRXJyb3IiA29yViIGc2VuZHJWIgZtYXRjaFYiA3N0ciIHJG1hdGNoMCIGdmFsU3RyIg9nZXRTdHJpbmdPckZhaWwiBGFkZHIiA2tleSIMZ2V0SW50T3JGYWlsIg9mYWN0b3J5Q29udHJhY3QiDGFtcGxpZmljYXRvciIQaXNHbG9iYWxTaHV0ZG93biITZ2V0TWF0Y2hlclB1Yk9yRmFpbCIObWF0Y2hlckFkZHJlc3MiDWdldFBvb2xDb25maWciBWFtdEFzIgdwcmljZUFzIghpUHJpY2VBcyIQZ2V0RmFjdG9yeUNvbmZpZyIRZGF0YVB1dEFjdGlvbkluZm8iDWluQW10QXNzZXRBbXQiD2luUHJpY2VBc3NldEFtdCIIb3V0THBBbXQiBXByaWNlIgpzbGlwQnlVc2VyIgxzbGlwcGFnZVJlYWwiCHR4SGVpZ2h0Igt0eFRpbWVzdGFtcCIMc2xpcGFnZUFtQW10IgxzbGlwYWdlUHJBbXQiEWRhdGFHZXRBY3Rpb25JbmZvIg5vdXRBbXRBc3NldEFtdCIQb3V0UHJpY2VBc3NldEFtdCIHaW5McEFtdCINZ2V0QWNjQmFsYW5jZSIHYXNzZXRJZCIPY2FsY1ByaWNlQmlnSW50IghwckFtdFgxOCIIYW1BbXRYMTgiD3ZhbGlkYXRlQWJzRGlmZiIKZXN0aW1hdGVMUCIFb3V0THAiCHNsaXBwYWdlIgRkaWZmIgRwYXNzIgl2YWxpZGF0ZUQiAkQxIgJEMCIEZmFpbCIQcHJpdmF0ZUNhbGNQcmljZSIKYW1Bc3NldERjbSIKcHJBc3NldERjbSIFYW1BbXQiBXByQW10IgthbXRBc0FtdFgxOCIKcHJBc0FtdFgxOCIKY2FsY1ByaWNlcyIFbHBBbXQiA2NmZyIIYW10QXNEY20iB3ByQXNEY20iCHByaWNlWDE4IghscEFtdFgxOCINbHBQckluQW1Bc1gxOCINbHBQckluUHJBc1gxOCIPY2FsY3VsYXRlUHJpY2VzIgFwIhRlc3RpbWF0ZUdldE9wZXJhdGlvbiIGdHhJZDU4Ig5wYXltZW50QXNzZXRJZCIPcGF5bWVudExwQW1vdW50Igt1c2VyQWRkcmVzcyIJbHBBc3NldElkIghhbW91bnRJZCIHcHJpY2VJZCIOYW1vdW50RGVjaW1hbHMiDXByaWNlRGVjaW1hbHMiA3N0cyIKbHBFbWlzc2lvbiIPdmFsaWRhdGlvbkJsb2NrIghkZWNpbWFscyINYW1vdW50QmFsYW5jZSIQYW1vdW50QmFsYW5jZVgxOCIMcHJpY2VCYWxhbmNlIg9wcmljZUJhbGFuY2VYMTgiD2N1cnJlbnRQcmljZVgxOCIIY3VyUHJpY2UiEnBheW1lbnRMcEFtb3VudFgxOCINbHBFbWlzc2lvblgxOCISb3V0QW1vdW50QW1vdW50WDE4IhFvdXRQcmljZUFtb3VudFgxOCIPb3V0QW1vdW50QW1vdW50Ig5vdXRQcmljZUFtb3VudCIFc3RhdGUiFGVzdGltYXRlUHV0T3BlcmF0aW9uIhFzbGlwcGFnZVRvbGVyYW5jZSITaW5BbW91bnRBc3NldEFtb3VudCIPaW5BbW91bnRBc3NldElkIhJpblByaWNlQXNzZXRBbW91bnQiDmluUHJpY2VBc3NldElkIgppc0V2YWx1YXRlIgZlbWl0THAiCmlzT25lQXNzZXQiDXBheW1lbnRBbW91bnQiCXBheW1lbnRJZCILYW1vdW50SWRTdHIiCnByaWNlSWRTdHIiDWluQW1vdW50SWRTdHIiDGluUHJpY2VJZFN0ciIWaW5BbW91bnRBc3NldEFtb3VudFgxOCIVaW5QcmljZUFzc2V0QW1vdW50WDE4Igx1c2VyUHJpY2VYMTgiAXIiC3NsaXBwYWdlWDE4IgtscEFtb3VudFgxOCIPc2xpcHBhZ2VSZWFsWDE4IgpwclZpYUFtWDE4IgphbVZpYVByWDE4Ig9leHBlY3RlZEFtb3VudHMiHGV4cGVjdGVkQW1vdW50QXNzZXRBbW91bnRYMTgiG2V4cGVjdGVkUHJpY2VBc3NldEFtb3VudFgxOCIRY2FsY3VsYXRlTHBBbW91bnQiG2NhbGN1bGF0ZUFtb3VudEFzc2V0UGF5bWVudCIaY2FsY3VsYXRlUHJpY2VBc3NldFBheW1lbnQiDGN1cnJlbnRQcmljZSIRc2xpcHBhZ2VDYWxjdWxhdGUiEWNoZWNrQ2FsY0xwQW1vdW50IgxlbWl0THBBbW91bnQiCmFtb3VudERpZmYiCXByaWNlRGlmZiINJHQwMTYxODkxNjQ0OCIKd3JpdGVBbUFtdCIKd3JpdGVQckFtdCILY29tbW9uU3RhdGUiG3ZhbGlkYXRlTWF0Y2hlck9yZGVyQWxsb3dlZCIFb3JkZXIiB2FtdEFzSWQiBnByQXNJZCIPYWNjQW10QXNCYWxhbmNlIg5hY2NQckFzQmFsYW5jZSIKb3JBbXRBc3NldCIKb3JBbXRBc1N0ciIJb3JQckFzc2V0IglvclByQXNTdHIiCm9yZGVyUHJpY2UiDmNhc3RPcmRlclByaWNlIhFpc09yZGVyUHJpY2VWYWxpZCIJY29tbW9uR2V0IgFpIg1jaGVja1BheW1lbnRzIgdwYXltZW50Igljb21tb25QdXQiBmNhbGxlciISYW1vdW50QXNzZXRQYXltZW50IhFwcmljZUFzc2V0UGF5bWVudCIHdGFrZUZlZSIGYW1vdW50IgNmZWUiFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQiAXMiHXBlbmRpbmdNYW5hZ2VyUHVibGljS2V5T3JVbml0IgJwZCILbXVzdE1hbmFnZXIiAnBrIgtjaGVja0NhbGxlciIXcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkiFWNoZWNrTWFuYWdlclB1YmxpY0tleSICcG0iBWhhc1BNIgdjaGVja1BNIglhdXRvU3Rha2UiB2ZhY3RDZmciD3N0YWtpbmdDb250cmFjdCIQc2xpcHBhZ2VDb250cmFjdCINc2xpcHBhZ2VDaGVjayINcGF5bWVudHNDaGVjayILZXN0aW1hdGVQdXQiAmVsIgZsZWdhY3kiAnNhIgJzcCIJbHBUcmFzZmVyIgJzcyIPYW1vdW50QXNzZXRQYXJ0Ig5wcmljZUFzc2V0UGFydCIRZ3d4UmV3YXJkQ29udHJhY3QiB3Bvb2xDZmciBWFkZG9uIhBwYXltZW50QW1vdW50UmF3Ig0kdDAyNTYxNzI1Njc2IglmZWVBbW91bnQiDSR0MDI1OTQwMjYzOTUiEGFtb3VudEJhbGFuY2VOb3ciD3ByaWNlQmFsYW5jZU5vdyIMdmlydFN3YXBJbkFtIg12aXJ0U3dhcE91dFByIgx2aXJ0U3dhcEluUHIiDXZpcnRTd2FwT3V0QW0iBkQwdnNEMSIJbHBDYWxjUmVzIgFlIhBzZW5kRmVlVG9NYXRjaGVyIgttYXhzbGlwcGFnZSIJb3V0QW10QW10IgFiIgpleGNoUmVzdWx0Igdub3RVc2VkIglvdXRBbW91bnQiCm91dEFzc2V0SWQiCmVzdGltQW1BbXQiCmVzdGltUHJBbXQiDSR0MDMxNTM0MzIwMDIiCHRvdGFsR2V0IghmaW5hbFJlcyINJHQwMzI2NzEzMjc3OSIFb3V0QW0iBW91dFByIg50b3RhbEFtb3VudFJhdyINJHQwMzI4MTkzMjg3NCILdG90YWxBbW91bnQiEW91dEFzc2V0SWRPcldhdmVzIghjdXJQclgxOCIFY3VyUHIiBGJ1cm4iEm5vTGVzc1RoZW5BbXRBc3NldCIUbm9MZXNzVGhlblByaWNlQXNzZXQiFGNoZWNrT3V0QW1vdW50QW1vdW50IhNjaGVja091dFByaWNlQW1vdW50IhRidXJuTFBBc3NldE9uRmFjdG9yeSIKZmFjdG9yeUNmZyIHc3Rha2luZyIKdW5zdGFrZUludiIBdiIFYnVybkEiCGFtdEFzU3RyIgdwckFzU3RyIgFrIgJwciIMcmVzU2NhbGVNdWx0IgZpbkFtSWQiBmluUHJJZCIHdXNyQWRkciILcGF5bWVudEFzSWQiAnR4IgZ2ZXJpZnkiB210Y2hQdWIiBXNuZHJWIgVtdGNoViIPdGFyZ2V0UHVibGljS2V5IgckbWF0Y2gxUQABYQCAwtcvAAFiCQC2AgEAgMLXLwABYwkAtgIBAICAkLu61q3wDQABZADoBwABZQkAtgIBAAAAAWYJALYCAQABAAFnCQC2AgEJAGUCBQFhCQBpAgkAaAIFAWEAAQUBYQABaAIDMTAwAAFpAgExAAFqAgJfXwABawIAAAFsAAEAAW0AAgABbgADAAFvAAQAAXAAAQABcQACAAFyAAMAAXMABAABdAAFAAF1AAYAAXYABwABdwAIAAF4AAkAAXkAAQABegAHAAFBAAoAAUIAAAEBQwIBRAFFCQC8AgMJALYCAQUBRAUBYwkAtgIBBQFFAQFGAgFHAUgJAKADAQkAvAIDBQFHCQC2AgEFAUgFAWMBAUkDAUoBSwFMCQBrAwUBSgUBSwUBTAEBTQEBRwMJAL8CAgUBZQUBRwkAvgIBBQFHBQFHAQFOAAITJXNfX2ZhY3RvcnlDb250cmFjdAEBTwACFCVzX19tYW5hZ2VyUHVibGljS2V5AQFQAAIbJXNfX3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AQFRAAIRJXMlc19fcHJpY2VfX2xhc3QBAVICAVMBVAkAuQkCCQDMCAICGCVzJXMlZCVkX19wcmljZV9faGlzdG9yeQkAzAgCCQCkAwEFAVMJAMwIAgkApAMBBQFUBQNuaWwFAWoBAVUCAVYBVwkArAICCQCsAgIJAKwCAgILJXMlcyVzX19QX18FAVYCAl9fBQFXAQFYAgFWAVcJAKwCAgkArAICCQCsAgICCyVzJXMlc19fR19fBQFWAgJfXwUBVwEBWQACDyVzX19hbW91bnRBc3NldAEBWgACDiVzX19wcmljZUFzc2V0AQJhYQACByVzX19hbXABAmFiAAINJXNfX2FkZG9uQWRkcgACYWMCDyVzX19mZWVQZXJtaWxsZQACYWQJAQt2YWx1ZU9yRWxzZQIJAJoIAgUEdGhpcwUCYWMFAUIBAmFlAAIRJXNfX2ZhY3RvcnlDb25maWcBAmFmAAIYJXMlc19fbWF0Y2hlcl9fcHVibGljS2V5AQJhZwICYWgCYWkJAKwCAgkArAICCQCsAgIJAKwCAgIIJWQlZCVzX18FAmFoAgJfXwUCYWkCCF9fY29uZmlnAQJhagECYWsJAKwCAgIoJXMlcyVzX19tYXBwaW5nc19fYmFzZUFzc2V0MmludGVybmFsSWRfXwUCYWsBAmFsAAIMJXNfX3NodXRkb3duAQJhbQECYW4JAAIBCQC5CQIJAMwIAgIPbHBfc3RhYmxlLnJpZGU6CQDMCAIFAmFuBQNuaWwCASABAmFvAwJhcAJhcQJhcgkBAmFtAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgICEUZhaWxlZDogb3JkVmFsaWQ9CQClAwEFAmFwAgsgc25kclZhbGlkPQkApQMBBQJhcQIMIG10Y2hyVmFsaWQ9CQClAwEFAmFyAQJhcwEBRwQCYXQFAUcDCQABAgUCYXQCBlN0cmluZwQCYXUFAmF0BQJhdQkBAmFtAQITZmFpbCBjYXN0IHRvIFN0cmluZwECYXYCAmF3AmF4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJ0IAgUCYXcFAmF4CQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmF3CQDMCAICAS4JAMwIAgUCYXgJAMwIAgIMIG5vdCBkZWZpbmVkBQNuaWwCAAECYXkCAmF3AmF4CQETdmFsdWVPckVycm9yTWVzc2FnZQIJAJoIAgUCYXcFAmF4CQC5CQIJAMwIAgIKbWFuZGF0b3J5IAkAzAgCCQClCAEFAmF3CQDMCAICAS4JAMwIAgUCYXgJAMwIAgIMIG5vdCBkZWZpbmVkBQNuaWwCAAACYXoJARFAZXh0ck5hdGl2ZSgxMDYyKQEJAQJhdgIFBHRoaXMJAQFOAAACYUEJAQJhdgIFBHRoaXMJAQJhYQABAmFCAAkBC3ZhbHVlT3JFbHNlAgkAmwgCBQJhegkBAmFsAAcBAmFDAAkA2QQBCQECYXYCBQJhegkBAmFmAAACYUQJAKcIAQkBAmFDAAECYUUABAJhRgkBAmF2AgUEdGhpcwkBAVkABAJhRwkBAmF2AgUEdGhpcwkBAVoABAJhSAkBAmF5AgUCYXoJAQJhagEFAmFHBAJhaAkBAmF5AgUCYXoJAQJhagEFAmFGCQC1CQIJAQJhdgIFAmF6CQECYWcCCQCkAwEFAmFoCQCkAwEFAmFIBQFqAQJhSQAJALUJAgkBAmF2AgUCYXoJAQJhZQAFAWoBAmFKCgJhSwJhTAJhTQJhTgJhTwJhUAJhUQJhUgJhUwJhVAkAuQkCCQDMCAICFCVkJWQlZCVkJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYUsJAMwIAgkApAMBBQJhTAkAzAgCCQCkAwEFAmFNCQDMCAIJAKQDAQUCYU4JAMwIAgkApAMBBQJhTwkAzAgCCQCkAwEFAmFQCQDMCAIJAKQDAQUCYVEJAMwIAgkApAMBBQJhUgkAzAgCCQCkAwEFAmFTCQDMCAIJAKQDAQUCYVQFA25pbAUBagECYVUGAmFWAmFXAmFYAmFOAmFRAmFSCQC5CQIJAMwIAgIMJWQlZCVkJWQlZCVkCQDMCAIJAKQDAQUCYVYJAMwIAgkApAMBBQJhVwkAzAgCCQCkAwEFAmFYCQDMCAIJAKQDAQUCYU4JAMwIAgkApAMBBQJhUQkAzAgCCQCkAwEFAmFSBQNuaWwFAWoBAmFZAQJhWgMJAAACBQJhWgIFV0FWRVMICQDvBwEFBHRoaXMJYXZhaWxhYmxlCQDwBwIFBHRoaXMJANkEAQUCYVoBAmJhAgJiYgJiYwkAvAIDBQJiYgUBYwUCYmMBAmJkAwJiZQJiZgJiZwQCYmgJALwCAwkAuAICBQJiZQUCYmYFAWIFAmJmBAJiaQkAvwICCQC4AgIFAmJnCQEBTQEFAmJoBQFlAwkBASEBBQJiaQkBAmFtAQkArAICAg5CaWcgc2xpcHBhZ2U6IAkApgMBBQJiaAkAlAoCBQJiaQkAmQMBCQDMCAIFAmJlCQDMCAIFAmJmBQNuaWwBAmJqAwJiawJibAJiZwQCYmgJALwCAwUCYmwFAWIFAmJrBAJibQkAvwICBQJiZwUCYmgDAwUCYm0GCQC/AgIFAmJsBQJiawkBAmFtAQkArAICCQCsAgIJAKwCAgkArAICCQCsAgIJAKwCAgkApgMBBQJibAIBIAkApgMBBQJiawIBIAkApgMBBQJiaAIBIAkApgMBBQJiZwUCYm0BAmJuBAJibwJicAJicQJicgQCYnMJAQFDAgUCYnEFAmJvBAJidAkBAUMCBQJicgUCYnAJAQJiYQIFAmJ0BQJicwECYnUDAmJxAmJyAmJ2BAJidwkBAmFFAAQCYngJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJidwUBdQQCYnkJAQ1wYXJzZUludFZhbHVlAQkAkQMCBQJidwUBdgQCYnoJAQJibgQFAmJ4BQJieQUCYnEFAmJyBAJiYwkBAUMCBQJicQUCYngEAmJiCQEBQwIFAmJyBQJieQQCYkEJAQFDAgUCYnYFAWEEAmJCCQECYmECBQJiYwUCYkEEAmJDCQECYmECBQJiYgUCYkEJAMwIAgUCYnoJAMwIAgUCYkIJAMwIAgUCYkMFA25pbAECYkQDAmJxAmJyAmJ2BAJiRQkBAmJ1AwUCYnEFAmJyBQJidgkAzAgCCQEBRgIJAJEDAgUCYkUAAAUBYQkAzAgCCQEBRgIJAJEDAgUCYkUAAQUBYQkAzAgCCQEBRgIJAJEDAgUCYkUAAgUBYQUDbmlsAQJiRgQCYkcCYkgCYkkCYkoEAmJ3CQECYUUABAJiSwkAkQMCBQJidwUBcgQCYkwJAJEDAgUCYncFAXMEAmJNCQCRAwIFAmJ3BQF0BAJiTgkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJ3BQF1BAJiTwkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJ3BQF2BAJiUAkAkQMCBQJidwUBcQQCYlEICQETdmFsdWVPckVycm9yTWVzc2FnZQIJAOwHAQkA2QQBBQJiSwILV3JvbmcgTFAgaWQIcXVhbnRpdHkEAmJSAwkAAAIFAmJLBQJiSAYJAQJhbQECE1dyb25nIHBheW1lbnQgYXNzZXQDCQAAAgUCYlIFAmJSBAJiUwMJAGcCBQJiTgUCYk8FAmJOBQJiTwMJAAACBQJiUwUCYlMEAmJUCQECYVkBBQJiTAQCYlUJAQFDAgUCYlQFAmJTBAJiVgkBAmFZAQUCYk0EAmJXCQEBQwIFAmJWBQJiUwQCYlgJAQJiYQIFAmJXBQJiVQQCYlkJAQFGAgUCYlgFAWEEAmJaCQEBQwIFAmJJBQFhBAJjYQkBAUMCBQJiUQUBYQQCY2IJALwCAwUCYlUFAmJaBQJjYQQCY2MJALwCAwUCYlcFAmJaBQJjYQQCY2QJAQFGAgUCY2IFAmJTBAJjZQkBAUYCBQJjYwUCYlMEAmNmAwkAAAIFAmJHAgAFA25pbAkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJiSgUCY2QDCQAAAgUCYkwCBVdBVkVTBQR1bml0CQDZBAEFAmJMCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmJKBQJjZQMJAAACBQJiTQIFV0FWRVMFBHVuaXQJANkEAQUCYk0JAMwIAgkBC1N0cmluZ0VudHJ5AgkBAVgCCQClCAEFAmJKBQJiRwkBAmFVBgUCY2QFAmNlBQJiSQUCYlkFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFRAAUCYlkJAMwIAgkBDEludGVnZXJFbnRyeQIJAQFSAgUGaGVpZ2h0CAUJbGFzdEJsb2NrCXRpbWVzdGFtcAUCYlkFA25pbAkAnAoKBQJjZAUCY2UFAmJMBQJiTQUCYlQFAmJWBQJiUQUCYlgFAmJQBQJjZgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY2cMAmJHAmNoAmNpAmNqAmNrAmNsAmJKAmNtAmNuAmNvAmNwAmNxBAJidwkBAmFFAAQCYksJANkEAQkAkQMCBQJidwUBcgQCY3IJAJEDAgUCYncFAXMEAmNzCQCRAwIFAmJ3BQF0BAJjdAkAkQMCBQJidwUBdwQCY3UJAJEDAgUCYncFAXgEAmJOCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYncFAXUEAmJPCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYncFAXYEAmJQCQCRAwIFAmJ3BQFxBAJiUQgJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkA7AcBBQJiSwIOV3JvbmcgbHAgYXNzZXQIcXVhbnRpdHkEAmJUAwUCY20JAQJhWQEFAmNyAwMFAmNvCQAAAgUCY3EFAmNyBwkAZQIJAQJhWQEFAmNyBQJjcAMFAmNvCQECYVkBBQJjcgkAZQIJAQJhWQEFAmNyBQJjaQQCYlYDBQJjbQkBAmFZAQUCY3MDAwUCY28JAAACBQJjcQUCY3MHCQBlAgkBAmFZAQUCY3MFAmNwAwUCY28JAQJhWQEFAmNzCQBlAgkBAmFZAQUCY3MFAmNrBAJiUwMJAGcCBQJiTgUCYk8FAmJOBQJiTwMJAAACBQJiUwUCYlMEAmN2CQEBQwIFAmNpBQJiUwQCY3cJAQFDAgUCY2sFAmJTBAJjeAkBAmJhAgUCY3cFAmN2BAJiVQkBAUMCBQJiVAUCYlMEAmJXCQEBQwIFAmJWBQJiUwQCY3kDCQAAAgUCYlEAAAQCYlgFAWUEAmN6BQFlBAJjQQkAdgYJALkCAgUCY3YFAmN3AAAJALYCAQAFAAEAAAUERE9XTgkAlwoFCQEBRgIFAmNBBQFhCQEBRgIFAmN2BQJiUwkBAUYCBQJjdwUCYlMJAQJiYQIJALcCAgUCYlcFAmN3CQC3AgIFAmJVBQJjdgUCY3oEAmJYCQECYmECBQJiVwUCYlUEAmNCCQC8AgMJAQFNAQkAuAICBQJiWAUCY3gFAWMFAmJYBAJjegkBAUMCBQJjaAUBYQMDCQECIT0CBQJiWAUBZQkAvwICBQJjQgUCY3oHCQECYW0BCQCsAgIJAKwCAgkArAICAg9QcmljZSBzbGlwcGFnZSAJAKYDAQUCY0ICAyA+IAkApgMBBQJjegQCY2EJAQFDAgUCYlEFAWEEAmNDCQC8AgMFAmN2BQJiWAUBYwQCY0QJALwCAwUCY3cFAWMFAmJYBAJjRQMJAL8CAgUCY0MFAmN3CQCUCgIFAmNEBQJjdgkAlAoCBQJjdgUCY0MEAmNGCAUCY0UCXzEEAmNHCAUCY0UCXzIEAmNBCQC8AgMFAmNhBQJjRwUCYlcJAJcKBQkBAUYCBQJjQQUBYQkBAUYCBQJjRgUCYlMJAQFGAgUCY0cFAmJTBQJiWAUCY3oEAmNICAUCY3kCXzEEAmNJCAUCY3kCXzIEAmNKCAUCY3kCXzMEAmNLCQEBRgIIBQJjeQJfNAUBYQQCY0wJAQFGAggFAmN5Al81BQFhBAJjTQMJAGYCBQJjSAAABgkBAmFtAQIHTFAgPD0gMAMJAAACBQJjTQUCY00EAmNOAwkBASEBBQJjbgAABQJjSAQCY08JAGUCBQJjaQUCY0kEAmNQCQBlAgUCY2sFAmNKBAJjUQMDBQJjbwkAAAIFAmNxBQJjcgcJAJQKAgUCY3AAAAMDBQJjbwkAAAIFAmNxBQJjcwcJAJQKAgAABQJjcAkAlAoCBQJjSQUCY0oEAmNSCAUCY1ECXzEEAmNTCAUCY1ECXzIEAmNUCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBUQAFAmNLCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBUgIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmNLCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFVAgUCYkoFAmJHCQECYUoKBQJjUgUCY1MFAmNOBQJjSwUCY2gFAmNMBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wBQJjTwUCY1AFA25pbAkAnwoNBQJjSAUCY04FAmNLBQJiVAUCYlYFAmJRBQJiSwUCYlAFAmNUBQJjTwUCY1AFAmNqBQJjbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECY1UBAmNWBAJidwkBAmFFAAQCY1cJAJEDAgUCYncFAXMEAmNYCQCRAwIFAmJ3BQF0BAJiUAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJ3BQFxBAJieAkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJ3BQF1BAJieQkBDXBhcnNlSW50VmFsdWUBCQCRAwIFAmJ3BQF2BAJjWQkBAmFZAQUCY1cEAmNaCQECYVkBBQJjWAQCYlgDCQAAAggFAmNWCW9yZGVyVHlwZQUDQnV5CQECYm4EBQJieAUCYnkJAGQCBQJjWQgFAmNWBmFtb3VudAUCY1oJAQJibgQFAmJ4BQJieQkAZQIFAmNZCAUCY1YGYW1vdW50BQJjWgQCYlkJAQFGAgUCYlgFAWEDAwMJAQJhQgAGCQAAAgUCYlAFAW4GCQAAAgUCYlAFAW8JAQJhbQECDUFkbWluIGJsb2NrZWQEAmRhCAgFAmNWCWFzc2V0UGFpcgthbW91bnRBc3NldAQCZGIDCQAAAgUCZGEFBHVuaXQCBVdBVkVTCQDYBAEJAQV2YWx1ZQEFAmRhBAJkYwgIBQJjVglhc3NldFBhaXIKcHJpY2VBc3NldAQCZGQDCQAAAgUCZGMFBHVuaXQCBVdBVkVTCQDYBAEJAQV2YWx1ZQEFAmRjAwMJAQIhPQIFAmRiBQJjVwYJAQIhPQIFAmRkBQJjWAkBAmFtAQIJV3IgYXNzZXRzBAJkZQgFAmNWBXByaWNlBAJiTwkAawMFAWEFAmJ5BQJieAQCZGYJAQFJAwUCZGUFAWEFAmJPBAJkZwMJAAACCAUCY1YJb3JkZXJUeXBlBQNCdXkJAGcCBQJiWQUCZGYJAGcCBQJkZgUCYlkGAQJkaAECZGkEAmRqAwkAAAIJAJADAQgFAmRpCHBheW1lbnRzAAEGCQECYW0BAhIxIHBheW1lbnQgZXhwZWN0ZWQDCQAAAgUCZGoFAmRqBAJkawkBBXZhbHVlAQkAkQMCCAUCZGkIcGF5bWVudHMAAAQCYkgJAQV2YWx1ZQEIBQJkawdhc3NldElkBAJjcAgFAmRrBmFtb3VudAQCY3kJAQJiRgQJANgEAQgFAmRpDXRyYW5zYWN0aW9uSWQJANgEAQUCYkgFAmNwCAUCZGkGY2FsbGVyBAJjZAgFAmN5Al8xBAJjZQgFAmN5Al8yBAJiUAkBDXBhcnNlSW50VmFsdWUBCAUCY3kCXzkEAmNmCAUCY3kDXzEwAwMJAQJhQgAGCQAAAgUCYlAFAW8JAQJhbQEJAKwCAgIPQWRtaW4gYmxvY2tlZDogCQCkAwEFAmJQCQCXCgUFAmNkBQJjZQUCY3AFAmJIBQJjZgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgECZGwJAmRtAVcCZG4CZG8CYmcCY24CY28CY3ACY3EEAmN5CQECY2cMBQFXBQJiZwgJAQV2YWx1ZQEFAmRuBmFtb3VudAgJAQV2YWx1ZQEFAmRuB2Fzc2V0SWQICQEFdmFsdWUBBQJkbwZhbW91bnQICQEFdmFsdWUBBQJkbwdhc3NldElkBQJkbQcFAmNuBQJjbwUCY3AFAmNxBAJiUAkBDXBhcnNlSW50VmFsdWUBCAUCY3kCXzgDAwMJAQJhQgAGCQAAAgUCYlAFAW0GCQAAAgUCYlAFAW8JAQJhbQEJAKwCAgIIQmxvY2tlZDoJAKQDAQUCYlAFAmN5AQJkcAECZHEEAmRyCQBrAwUCZHEFAmFkBQFkCQCUCgIJAGUCBQJkcQUCZHIFAmRyAQJkcwAEAmF0CQCiCAEJAQFPAAMJAAECBQJhdAIGU3RyaW5nBAJkdAUCYXQJANkEAQUCZHQDCQABAgUCYXQCBFVuaXQFBHVuaXQJAAIBAgtNYXRjaCBlcnJvcgECZHUABAJhdAkAoggBCQEBUAADCQABAgUCYXQCBlN0cmluZwQCZHQFAmF0CQDZBAEFAmR0AwkAAQIFAmF0AgRVbml0BQR1bml0CQACAQILTWF0Y2ggZXJyb3IAAmR2CQECYW0BAhFQZXJtaXNzaW9uIGRlbmllZAECZHcBAmRpBAJhdAkBAmRzAAMJAAECBQJhdAIKQnl0ZVZlY3RvcgQCZHgFAmF0AwkAAAIIBQJkaQ9jYWxsZXJQdWJsaWNLZXkFAmR4BgUCZHYDCQABAgUCYXQCBFVuaXQDCQAAAggFAmRpBmNhbGxlcgUEdGhpcwYFAmR2CQACAQILTWF0Y2ggZXJyb3IVAmRpAQtjb25zdHJ1Y3RvcgECYXoEAmR5CQECZHcBBQJkaQMJAAACBQJkeQUCZHkJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAU4ABQJhegUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRpAQpzZXRNYW5hZ2VyAQJkegQCZHkJAQJkdwEFAmRpAwkAAAIFAmR5BQJkeQQCZEEJANkEAQUCZHoDCQAAAgUCZEEFAmRBCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFQAAUCZHoFA25pbAkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkaQEOY29uZmlybU1hbmFnZXIABAJkQgkBAmR1AAQCZEMDCQEJaXNEZWZpbmVkAQUCZEIGCQECYW0BAhJObyBwZW5kaW5nIG1hbmFnZXIDCQAAAgUCZEMFAmRDBAJkRAMJAAACCAUCZGkPY2FsbGVyUHVibGljS2V5CQEFdmFsdWUBBQJkQgYJAQJhbQECG1lvdSBhcmUgbm90IHBlbmRpbmcgbWFuYWdlcgMJAAACBQJkRAUCZEQJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAU8ACQDYBAEJAQV2YWx1ZQEFAmRCCQDMCAIJAQtEZWxldGVFbnRyeQEJAQFQAAUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRpAQNwdXQCAmJnAmRFBAJkRgkBAmFJAAQCZEcJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFAmRGBQF5AhZXcm9uZyBzdGFraW5nIGNvbnRyYWN0BAJkSAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUCZEYFAXoCF1dyb2duIHNsaXBwYWdlIGNvbnRyYWN0BAJkSQMJAGcCBQJiZwAABgkBAmFtAQIOd3Jvbmcgc2xpcHBhZ2UDCQAAAgUCZEkFAmRJBAJkSgMJAAACCQCQAwEIBQJkaQhwYXltZW50cwACBgkBAmFtAQITMiBwYXltZW50cyBleHBlY3RlZAMJAAACBQJkSgUCZEoEAmRLCQECZGwJCQClCAEIBQJkaQZjYWxsZXIJANgEAQgFAmRpDXRyYW5zYWN0aW9uSWQJAQ9BdHRhY2hlZFBheW1lbnQCCAkBBXZhbHVlAQkAkQMCCAUCZGkIcGF5bWVudHMAAAdhc3NldElkCAkBBXZhbHVlAQkAkQMCCAUCZGkIcGF5bWVudHMAAAZhbW91bnQJAJEDAggFAmRpCHBheW1lbnRzAAEFAmJnBgcAAAIABAJjTggFAmRLAl8yBAJiSwgFAmRLAl83BAJjZggFAmRLAl85BAJjTwgFAmRLA18xMAQCY1AIBQJkSwNfMTEEAmJMCAUCZEsDXzEyBAJiTQgFAmRLA18xMwQCY3kJAPwHBAUCYXoCBGVtaXQJAMwIAgUCY04FA25pbAUDbmlsAwkAAAIFAmN5BQJjeQQCZEwEAmF0BQJjeQMJAAECBQJhdAIHQWRkcmVzcwQCZE0FAmF0CQD8BwQFAmRNAgRlbWl0CQDMCAIFAmNOBQNuaWwFA25pbAUEdW5pdAMJAAACBQJkTAUCZEwEAmROAwkAZgIFAmNPAAAJAPwHBAUCZEgCA3B1dAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiTAUCY08FA25pbAUDbmlsAwkAAAIFAmROBQJkTgQCZE8DCQBmAgUCY1AAAAkA/AcEBQJkSAIDcHV0BQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJNBQJjUAUDbmlsBQNuaWwDCQAAAgUCZE8FAmRPBAJkUAMFAmRFBAJkUQkA/AcEBQJkRwIFc3Rha2UFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYksFAmNOBQNuaWwDCQAAAgUCZFEFAmRRBQNuaWwJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAMwIAgkBDlNjcmlwdFRyYW5zZmVyAwgFAmRpBmNhbGxlcgUCY04FAmJLBQNuaWwJAM4IAgUCY2YFAmRQCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRpAQlwdXRPbmVUa24FAmRSAmRTAmJmAmJnAmRFBAJidwkBAmFJAAQCZEcJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFAmJ3BQF5AhZXcm9uZyBzdGFraW5nIGNvbnRyYWN0BAJkSAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUCYncFAXoCF1dyb25nIHNsaXBwYWdlIGNvbnRyYWN0BAJkVAkBE3ZhbHVlT3JFcnJvck1lc3NhZ2UCCQCmCAEJAJEDAgUCYncFAUECGVdyb25nIGd3eCByZXdhcmQgY29udHJhY3QEAmRVCQECYUUABAJiTAkAkQMCBQJkVQUBcwQCYk0JAJEDAgUCZFUFAXQEAmJOCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZFUFAXUEAmJPCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCZFUFAXYEAmRWCQELdmFsdWVPckVsc2UCCQCdCAIFBHRoaXMJAQJhYgACAAQCYkoDCQAAAgUCZFYJAKUIAQgFAmRpBmNhbGxlcggFAmRpDG9yaWdpbkNhbGxlcggFAmRpBmNhbGxlcgMDAwMJAGcCAAAFAmJnBgkAZwIAAAUCZFIGCQBnAgAABQJkUwYJAGcCAAAFAmJmCQECYW0BAgxXcm9uZyBwYXJhbXMDCQECIT0CCQCQAwEIBQJkaQhwYXltZW50cwABCQECYW0BAhIxIHBheW1lbnQgZXhwZWN0ZWQEAmRrCQEFdmFsdWUBCQCRAwIIBQJkaQhwYXltZW50cwAABAJiSAkA2AQBCQEFdmFsdWUBCAUCZGsHYXNzZXRJZAQCZFcIBQJkawZhbW91bnQEAmRYCQECZHABBQJkVwQCY3AIBQJkWAJfMQQCZFkIBQJkWAJfMgMDAwkAZgIFAmRSBQJjcAYJAGYCBQJkUwUCY3AGCQBmAgCAreIEBQJjcAkBAmFtAQIUd3JvbmcgcGF5bWVudCBhbW91bnQEAmJUCQECYVkBBQJiTAQCYlYJAQJhWQEFAmJNBAJkWgMJAAACBQJiSAUCYkwJAJgKBgkAZQIFAmJUBQJjcAUCYlYJAGUCBQJjcAUCZFIFAmRTAAAAAAMJAAACBQJiSAUCYk0JAJgKBgUCYlQJAGUCBQJiVgUCY3AAAAAACQBlAgUCY3AFAmRTBQJkUgkBAmFtAQIUd3JvbmcgcGF5bWVudEFzc2V0SWQEAmVhCAUCZFoCXzEEAmViCAUCZFoCXzIEAmVjCAUCZFoCXzMEAmVkCAUCZFoCXzQEAmVlCAUCZFoCXzUEAmVmCAUCZFoCXzYEAmJsCQD8BwQFAmRUAgVjYWxjRAkAzAgCCQCkAwEFAmVhCQDMCAIJAKQDAQUCZWIJAMwIAgUCYUEJAMwIAgUBaAkAzAgCBQFpBQNuaWwFA25pbAQCYmsJAPwHBAUCZFQCBWNhbGNECQDMCAIJAKYDAQkAtgIBCQBlAgkAZAIFAmVhBQJlYwUCZWYJAMwIAgkApgMBCQC2AgEJAGUCCQBkAgUCZWIFAmVlBQJlZAkAzAgCBQJhQQkAzAgCBQFoCQDMCAIFAWkFA25pbAUDbmlsBAJlZwkBAmJqAwkApwMBCQECYXMBBQJiawkApwMBCQECYXMBBQJibAUBZwMJAAACBQJlZwUCZWcEAmRLCQECZGwJCQClCAEIBQJkaQZjYWxsZXIJANgEAQgFAmRpDXRyYW5zYWN0aW9uSWQJAQ9BdHRhY2hlZFBheW1lbnQCCQDZBAEFAmJMBQJkUgkBD0F0dGFjaGVkUGF5bWVudAIJANkEAQUCYk0FAmRTBQJiZwYGBQJjcAUCYkgEAmJlCAUCZEsCXzIEAmJLCAUCZEsCXzcEAmNmCAUCZEsCXzkEAmNPCAUCZEsDXzEwBAJjUAgFAmRLA18xMQQCZWgJAQJiZAMJALYCAQUCYmUJALYCAQUCYmYJALYCAQUCYmcEAmNOCQCgAwEIBQJlaAJfMgQCZWkJAPwHBAUCYXoCBGVtaXQJAMwIAgUCY04FA25pbAUDbmlsAwkAAAIFAmVpBQJlaQQCZEwEAmF0BQJlaQMJAAECBQJhdAIHQWRkcmVzcwQCZE0FAmF0CQD8BwQFAmRNAgRlbWl0CQDMCAIFAmNOBQNuaWwFA25pbAUEdW5pdAMJAAACBQJkTAUCZEwEAmROAwkAZgIFAmNPAAAJAPwHBAUCZEgCA3B1dAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCCQDZBAEFAmJMBQJjTwUDbmlsBQNuaWwDCQAAAgUCZE4FAmROBAJkTwMJAGYCBQJjUAAACQD8BwQFAmRIAgNwdXQFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgkA2QQBBQJiTQUCY1AFA25pbAUDbmlsAwkAAAIFAmRPBQJkTwQCZFADBQJkRQQCZFEJAPwHBAUCZEcCBXN0YWtlBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJLBQJjTgUDbmlsAwkAAAIFAmRRBQJkUQUDbmlsCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMIBQJkaQZjYWxsZXIFAmNOBQJiSwUDbmlsBAJlagMJAGYCBQJkWQAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFEBQJkWQkA2QQBBQJiSAUDbmlsBQNuaWwJAM4IAgkAzggCBQJjZgUCZFAFAmVqCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRpAQpwdXRGb3JGcmVlAQJlawMJAGYCAAAFAmVrCQECYW0BAg53cm9uZyBzbGlwcGFnZQMJAQIhPQIJAJADAQgFAmRpCHBheW1lbnRzAAIJAQJhbQECEzIgcGF5bWVudHMgZXhwZWN0ZWQEAmRLCQECZGwJCQClCAEIBQJkaQZjYWxsZXIJANgEAQgFAmRpDXRyYW5zYWN0aW9uSWQJAQ9BdHRhY2hlZFBheW1lbnQCCAkBBXZhbHVlAQkAkQMCCAUCZGkIcGF5bWVudHMAAAdhc3NldElkCAkBBXZhbHVlAQkAkQMCCAUCZGkIcGF5bWVudHMAAAZhbW91bnQJAJEDAggFAmRpCHBheW1lbnRzAAEFAmVrBwcAAAIACAUCZEsCXzkCZGkBA2dldAAEAmN5CQECZGgBBQJkaQQCZWwIBQJjeQJfMQQCY2UIBQJjeQJfMgQCY3AIBQJjeQJfMwQCYkgIBQJjeQJfNAQCY2YIBQJjeQJfNQQCZW0JAPwHBAUCYXoCBGJ1cm4JAMwIAgUCY3AFA25pbAkAzAgCCQEPQXR0YWNoZWRQYXltZW50AgUCYkgFAmNwBQNuaWwDCQAAAgUCZW0FAmVtBQJjZgkAAgECJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgJkaQEJZ2V0T25lVGtuBQJlbgJlbwJlcAJlcQJiZwMJAQIhPQIJAJADAQgFAmRpCHBheW1lbnRzAAEJAQJhbQECEjEgcGF5bWVudCBleHBlY3RlZAQCYncJAQJhRQAEAmJLCQCRAwIFAmJ3BQFyBAJiTAkAkQMCBQJidwUBcwQCYk0JAJEDAgUCYncFAXQEAmJOCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYncFAXUEAmJPCQENcGFyc2VJbnRWYWx1ZQEJAJEDAgUCYncFAXYEAmJQCQCRAwIFAmJ3BQFxBAJkRgkBAmFJAAQCZFQJARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFAmRGBQFBAh9Xcm9uZyBnd3hSZXdhcmRDb250cmFjdCBhZGRyZXNzBAJkawkBBXZhbHVlAQkAkQMCCAUCZGkIcGF5bWVudHMAAAQCZFYJAQt2YWx1ZU9yRWxzZQIJAJ0IAgUEdGhpcwkBAmFiAAIABAJiSgMJAAACBQJkVgkApQgBCAUCZGkGY2FsbGVyCAUCZGkMb3JpZ2luQ2FsbGVyCAUCZGkGY2FsbGVyBAJiRwkA2AQBCAUCZGkNdHJhbnNhY3Rpb25JZAQCYkgJAQV2YWx1ZQEIBQJkawdhc3NldElkBAJjcAgFAmRrBmFtb3VudAMJAGYCAICU69wDBQJjcAkBAmFtAQIRTWluIHBheW1lbnQgMTAgTFADAwMJAGYCAAAFAmJnBgkAZgIAAAUCZW4GCQBmAgAABQJlcAkBAmFtAQIMV3JvbmcgcGFyYW1zAwkBAiE9AgUCYksJANgEAQUCYkgJAQJhbQECCFdyb25nIExQBAJjeQkBAmJGBAkA2AQBCAUCZGkNdHJhbnNhY3Rpb25JZAkA2AQBBQJiSAUCY3AIBQJkaQZjYWxsZXIEAmVyCAUCY3kCXzEEAmVzCAUCY3kCXzIEAmJUCQECYVkBBQJiTAQCYlYJAQJhWQEFAmJNBAJldAMJAAACBQJlcQUCYkwJAJkKBwkAZQIFAmJUBQJlcgkAZQIFAmJWBQJlcwUCZW4FAmVzAAAAAAkAZAIFAmVyBQJlbgMJAAACBQJlcQUCYk0JAJkKBwkAZQIFAmJUBQJlcgkAZQIFAmJWBQJlcwAAAAAFAmVuBQJlcgkAZAIFAmVzBQJlbgkBAmFtAQIQd3Jvbmcgb3V0QXNzZXRJZAQCZWEIBQJldAJfMQQCZWIIBQJldAJfMgQCZWMIBQJldAJfMwQCZWQIBQJldAJfNAQCZWUIBQJldAJfNQQCZWYIBQJldAJfNgQCZXUIBQJldAJfNwMDCQBmAgAABQJlYwYJAGYCAAAFAmVlCQECYW0BAgpXcm9uZyBjYWxjBAJibAkA/AcEBQJkVAIFY2FsY0QJAMwIAgkApAMBBQJlYQkAzAgCCQCkAwEFAmViCQDMCAIFAmFBCQDMCAIFAWgJAMwIAgUBaQUDbmlsBQNuaWwEAmJrCQD8BwQFAmRUAgVjYWxjRAkAzAgCCQCkAwEJAGQCCQBlAgUCZWEFAmVjBQJlZgkAzAgCCQCkAwEJAGUCCQBkAgUCZWIFAmVkBQJlZQkAzAgCBQJhQQkAzAgCBQFoCQDMCAIFAWkFA25pbAUDbmlsBAJlZwkBAmJqAwkApwMBCQECYXMBBQJiawkApwMBCQECYXMBBQJibAUBZwMJAAACBQJlZwUCZWcEAmV2CQECYmQDCQC2AgEFAmV1CQC2AgEFAmVwCQC2AgEFAmJnAwkAAAIFAmV2BQJldgQCZXcDCQAAAgUCZXEFAmJMCQCUCgIJAKADAQgFAmV2Al8yAAAJAJQKAgAACQCgAwEIBQJldgJfMgQCZXgIBQJldwJfMQQCZXkIBQJldwJfMgQCZXoJAGQCBQJleAUCZXkEAmVBCQECZHABBQJlegQCZUIIBQJlQQJfMQQCZFkIBQJlQQJfMgQCZUMDCQAAAgUCZXECBVdBVkVTBQR1bml0CQDZBAEFAmVxBAJlagMJAGYCBQJkWQAACQDMCAIJAQ5TY3JpcHRUcmFuc2ZlcgMFAmFEBQJkWQUCZUMFA25pbAUDbmlsBAJiUwMJAGcCBQJiTgUCYk8FAmJOBQJiTwMJAAACBQJiUwUCYlMEAmVECQECYmECCQEBQwIFAmJWBQJiUwkBAUMCBQJiVAUCYlMEAmVFCQEBRgIFAmVEBQFhBAJjZgkAzAgCCQEOU2NyaXB0VHJhbnNmZXIDBQJiSgUCZUIFAmVDCQDMCAIJAQtTdHJpbmdFbnRyeQIJAQFYAgkApQgBBQJiSgUCYkcJAQJhVQYFAmV4BQJleQUCY3AFAmVFBQZoZWlnaHQIBQlsYXN0QmxvY2sJdGltZXN0YW1wCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBUQAFAmVFCQDMCAIJAQxJbnRlZ2VyRW50cnkCCQEBUgIFBmhlaWdodAgFCWxhc3RCbG9jawl0aW1lc3RhbXAFAmVFBQNuaWwDCQAAAgUCY2YFAmNmBAJlRgkA/AcEBQJhegIEYnVybgkAzAgCBQJjcAUDbmlsCQDMCAIJAQ9BdHRhY2hlZFBheW1lbnQCBQJiSAUCY3AFA25pbAMJAAACBQJlRgUCZUYJAM4IAgUCY2YFAmVqCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQACAQIkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAmRpAQlnZXROb0xlc3MCAmVHAmVIBAJjeQkBAmRoAQUCZGkEAmNkCAUCY3kCXzEEAmNlCAUCY3kCXzIEAmNwCAUCY3kCXzMEAmJICAUCY3kCXzQEAmNmCAUCY3kCXzUEAmVJAwkAZwIFAmNkBQJlRwYJAQJhbQEJAKwCAgkArAICCQCsAgICCUZhaWxlZDogIAkApAMBBQJjZAIDIDwgCQCkAwEFAmVHAwkAAAIFAmVJBQJlSQQCZUoDCQBnAgUCY2UFAmVIBgkBAmFtAQkArAICCQCsAgIJAKwCAgIIRmFpbGVkOiAJAKQDAQUCY2UCAyA8IAkApAMBBQJlSAMJAAACBQJlSgUCZUoEAmVLCQD8BwQFAmF6AgRidXJuCQDMCAIFAmNwBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJIBQJjcAUDbmlsAwkAAAIFAmVLBQJlSwUCY2YJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGkBDXVuc3Rha2VBbmRHZXQBAmRxBAJkagMJAQIhPQIJAJADAQgFAmRpCHBheW1lbnRzAAAJAQJhbQECFG5vIHBheW1lbnRzIGV4cGVjdGVkBgMJAAACBQJkagUCZGoEAmJ3CQECYUUABAJlTAkBAmFJAAQCYksJANkEAQkAkQMCBQJidwUBcgQCZU0JARN2YWx1ZU9yRXJyb3JNZXNzYWdlAgkApggBCQCRAwIFAmVMBQF5AgV3cm9uZwQCZU4JAPwHBAUCZU0CB3Vuc3Rha2UJAMwIAgkA2AQBBQJiSwkAzAgCBQJkcQUDbmlsBQNuaWwDCQAAAgUCZU4FAmVOBAJjeQkBAmJGBAkA2AQBCAUCZGkNdHJhbnNhY3Rpb25JZAkA2AQBBQJiSwUCZHEIBQJkaQZjYWxsZXIEAmJQCQENcGFyc2VJbnRWYWx1ZQEIBQJjeQJfOQQCY2YIBQJjeQNfMTAEAmVPAwMJAQJhQgAGCQAAAgUCYlAFAW8JAQJhbQEJAKwCAgIJQmxvY2tlZDogCQCkAwEFAmJQBgMJAAACBQJlTwUCZU8EAmVQCQD8BwQFAmF6AgRidXJuCQDMCAIFAmRxBQNuaWwJAMwIAgkBD0F0dGFjaGVkUGF5bWVudAIFAmJLBQJkcQUDbmlsAwkAAAIFAmVQBQJlUAUCY2YJAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAIBAiRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4CZGkBCGFjdGl2YXRlAgJlUQJlUgMJAQIhPQIJAKUIAQgFAmRpBmNhbGxlcgkApQgBBQJhegkBAmFtAQIGZGVuaWVkCQCUCgIJAMwIAgkBC1N0cmluZ0VudHJ5AgkBAVkABQJlUQkAzAgCCQELU3RyaW5nRW50cnkCCQEBWgAFAmVSBQNuaWwCB3N1Y2Nlc3MCZGkBBHNldFMCAmVTAmVPAwkBAiE9AgkApQgBCAUCZGkGY2FsbGVyCQECYXYCBQR0aGlzCQECYWIABQJkdgkAzAgCCQELU3RyaW5nRW50cnkCBQJlUwUCZU8FA25pbAJkaQEEc2V0SQICZVMCZU8DCQECIT0CCQClCAEIBQJkaQZjYWxsZXIJAQJhdgIFBHRoaXMJAQJhYgAFAmR2CQDMCAIJAQxJbnRlZ2VyRW50cnkCBQJlUwUCZU8FA25pbAJkaQEcZ2V0UG9vbENvbmZpZ1dyYXBwZXJSRUFET05MWQAJAJQKAgUDbmlsCQECYUUAAmRpARxnZXRBY2NCYWxhbmNlV3JhcHBlclJFQURPTkxZAQJhWgkAlAoCBQNuaWwJAQJhWQEFAmFaAmRpARljYWxjUHJpY2VzV3JhcHBlclJFQURPTkxZAwJicQJicgJidgQCZVQJAQJidQMFAmJxBQJicgUCYnYJAJQKAgUDbmlsCQDMCAIJAKYDAQkAkQMCBQJlVAAACQDMCAIJAKYDAQkAkQMCBQJlVAABCQDMCAIJAKYDAQkAkQMCBQJlVAACBQNuaWwCZGkBFmZyb21YMThXcmFwcGVyUkVBRE9OTFkCAUcCZVUJAJQKAgUDbmlsCQEBRgIJAKcDAQUBRwUCZVUCZGkBFHRvWDE4V3JhcHBlclJFQURPTkxZAgFEAUUJAJQKAgUDbmlsCQCmAwEJAQFDAgUBRAUBRQJkaQEeY2FsY1ByaWNlQmlnSW50V3JhcHBlclJFQURPTkxZAgJiYgJiYwkAlAoCBQNuaWwJAKYDAQkBAmJhAgkApwMBBQJiYgkApwMBBQJiYwJkaQEjZXN0aW1hdGVQdXRPcGVyYXRpb25XcmFwcGVyUkVBRE9OTFkJAmJHAmJnAmNpAmVWAmNrAmVXAmVYAmNtAmNuCQCUCgIFA25pbAkBAmNnDAUCYkcFAmJnBQJjaQUCZVYFAmNrBQJlVwUCZVgFAmNtBQJjbgcAAAIAAmRpASNlc3RpbWF0ZUdldE9wZXJhdGlvbldyYXBwZXJSRUFET05MWQQCYkcCZVkCYkkCZVgEAmN5CQECYkYEBQJiRwUCZVkFAmJJCQERQGV4dHJOYXRpdmUoMTA2MikBBQJlWAkAlAoCBQNuaWwJAJwKCggFAmN5Al8xCAUCY3kCXzIIBQJjeQJfMwgFAmN5Al80CAUCY3kCXzUIBQJjeQJfNggFAmN5Al83CQCmAwEIBQJjeQJfOAgFAmN5Al85CAUCY3kDXzEwAQJlWgECZmEABAJhdAUCZVoDCQABAgUCYXQCBU9yZGVyBAJjVgUCYXQEAmZiCQECYUMABAJhcAkBAmNVAQUCY1YEAmZjCQD0AwMIBQJjVglib2R5Qnl0ZXMJAJEDAggFAmNWBnByb29mcwAACAUCY1YPc2VuZGVyUHVibGljS2V5BAJmZAkA9AMDCAUCY1YJYm9keUJ5dGVzCQCRAwIIBQJjVgZwcm9vZnMAAQUCZmIDAwMFAmFwBQJmYwcFAmZkBwYJAQJhbwMFAmFwBQJmYwUCZmQEAmZlBAJmZgkBAmRzAAMJAAECBQJmZgIKQnl0ZVZlY3RvcgQCZHgFAmZmBQJkeAMJAAECBQJmZgIEVW5pdAgFAmVaD3NlbmRlclB1YmxpY0tleQkAAgECC01hdGNoIGVycm9yCQD0AwMIBQJlWglib2R5Qnl0ZXMJAJEDAggFAmVaBnByb29mcwAABQJmZd18zmc=", "chainId": 84, "height": 2185721, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 57oomHZowvc4bbyAq6vCSay5jsR46pp9aAPxKRFFQKy4 Next: FHFuEo3f5gS9dkWkpYJUAm5ft2KwiFXorwrhz6WGbojB Diff:
OldNewDifferences
66 let scale8BigInt = toBigInt(100000000)
77
88 let scale18 = toBigInt(1000000000000000000)
9+
10+let thousand = 1000
911
1012 let zeroBigInt = toBigInt(0)
1113
5355
5456 let idxFactGwxRewCntr = 10
5557
56-let delay = "%s__delay"
58+let feePermilleDefault = 0
5759
5860 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
5961
102104 func keyAddonAddress () = "%s__addonAddr"
103105
104106
105-func lgotc (caller) = makeString(["%s%s__lastGetOneTknCall", caller], SEP)
107+let keyFeePermille = "%s__feePermille"
106108
107-
108-func lsotc (caller) = makeString(["%s%s__lastPutOneTknCall", caller], SEP)
109-
109+let feePermille = valueOrElse(getInteger(this, keyFeePermille), feePermilleDefault)
110110
111111 func fcfg () = "%s__factoryConfig"
112112
152152
153153 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, mtpk()))
154154
155+
156+let matcherAddress = addressFromPublicKey(getMatcherPubOrFail())
155157
156158 func getPoolConfig () = {
157159 let amtAs = getStringOrFail(this, keyAmountAsset())
322324 let currentPriceX18 = calcPriceBigInt(priceBalanceX18, amountBalanceX18)
323325 let slippageRealX18 = fraction(abs((currentPriceX18 - userPriceX18)), scale18, currentPriceX18)
324326 let slippageX18 = toX18(slippageTolerance, scale8)
325- let validateSlippage = if (((if ((currentPriceX18 != zeroBigInt))
327+ if (if ((currentPriceX18 != zeroBigInt))
326328 then (slippageRealX18 > slippageX18)
327- else false) == false))
328- then true
329- else throwErr(((("Price slippage " + toString(slippageRealX18)) + " > ") + toString(slippageX18)))
330- if ((validateSlippage == validateSlippage))
331- then {
329+ else false)
330+ then throwErr(((("Price slippage " + toString(slippageRealX18)) + " > ") + toString(slippageX18)))
331+ else {
332332 let lpEmissionX18 = toX18(lpEmission, scale8)
333333 let prViaAmX18 = fraction(inAmountAssetAmountX18, currentPriceX18, scale18)
334334 let amViaPrX18 = fraction(inPriceAssetAmountX18, scale18, currentPriceX18)
340340 let lpAmountX18 = fraction(lpEmissionX18, expectedPriceAssetAmountX18, priceBalanceX18)
341341 $Tuple5(fromX18(lpAmountX18, scale8), fromX18(expectedAmountAssetAmountX18, decimals), fromX18(expectedPriceAssetAmountX18, decimals), currentPriceX18, slippageX18)
342342 }
343- else throw("Strict value is not equal to itself.")
344343 }
345344 let calculateLpAmount = r._1
346345 let calculateAmountAssetPayment = r._2
357356 else calculateLpAmount
358357 let amountDiff = (inAmountAssetAmount - calculateAmountAssetPayment)
359358 let priceDiff = (inPriceAssetAmount - calculatePriceAssetPayment)
360- let $t01622016479 = if (if (isOneAsset)
359+ let $t01618916448 = if (if (isOneAsset)
361360 then (paymentId == amountIdStr)
362361 else false)
363362 then $Tuple2(paymentAmount, 0)
366365 else false)
367366 then $Tuple2(0, paymentAmount)
368367 else $Tuple2(calculateAmountAssetPayment, calculatePriceAssetPayment)
369- let writeAmAmt = $t01622016479._1
370- let writePrAmt = $t01622016479._2
368+ let writeAmAmt = $t01618916448._1
369+ let writePrAmt = $t01618916448._2
371370 let commonState = [IntegerEntry(keyPriceLast(), currentPrice), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), currentPrice), StringEntry(keyPutActionByUser(userAddress, txId58), dataPutActionInfo(writeAmAmt, writePrAmt, emitLpAmount, currentPrice, slippageTolerance, slippageCalculate, height, lastBlock.timestamp, amountDiff, priceDiff))]
372371 $Tuple13(calculateLpAmount, emitLpAmount, currentPrice, amountBalance, priceBalance, lpEmission, lpAssetId, sts, commonState, amountDiff, priceDiff, inAmountAssetId, inPriceAssetId)
373372 }
456455 else (sts == PoolShutdown))
457456 then throwErr(("Blocked:" + toString(sts)))
458457 else r
458+ }
459+
460+
461+func takeFee (amount) = {
462+ let fee = fraction(amount, feePermille, thousand)
463+ $Tuple2((amount - fee), fee)
459464 }
460465
461466
624629 let userAddress = if ((addon == toString(i.caller)))
625630 then i.originCaller
626631 else i.caller
627- let addonContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(keyAddonAddress()), "no addons")), "addon address in not valid")
628- let check = reentrantInvoke(addonContract, "ensureCanPutOneTkn", [toString(userAddress)], nil)
629- if ((check == check))
630- then if (if (if (if ((0 >= slippage))
631- then true
632- else (0 >= amountAssetPart))
633- then true
634- else (0 >= priceAssetPart))
635- then true
636- else (0 >= outLp))
637- then throwErr("Wrong params")
638- else if ((size(i.payments) != 1))
639- then throwErr("1 payment expected")
640- else {
641- let payment = value(i.payments[0])
642- let paymentAssetId = toBase58String(value(payment.assetId))
643- let paymentAmount = payment.amount
644- if (if (if ((amountAssetPart > paymentAmount))
645- then true
646- else (priceAssetPart > paymentAmount))
647- then true
648- else (10000000 > paymentAmount))
649- then throwErr("wrong payment amount")
650- else {
651- let amountBalance = getAccBalance(amountId)
652- let priceBalance = getAccBalance(priceId)
653- let $t02607126526 = if ((paymentAssetId == amountId))
654- then $Tuple6((amountBalance - paymentAmount), priceBalance, (paymentAmount - amountAssetPart), priceAssetPart, 0, 0)
655- else if ((paymentAssetId == priceId))
656- then $Tuple6(amountBalance, (priceBalance - paymentAmount), 0, 0, (paymentAmount - priceAssetPart), amountAssetPart)
657- else throwErr("wrong paymentAssetId")
658- let amountBalanceNow = $t02607126526._1
659- let priceBalanceNow = $t02607126526._2
660- let virtSwapInAm = $t02607126526._3
661- let virtSwapOutPr = $t02607126526._4
662- let virtSwapInPr = $t02607126526._5
663- let virtSwapOutAm = $t02607126526._6
664- let D0 = invoke(gwxRewardContract, "calcD", [toString(amountBalanceNow), toString(priceBalanceNow), amplificator, Amult, Dconv], nil)
665- let D1 = invoke(gwxRewardContract, "calcD", [toString(toBigInt(((amountBalanceNow + virtSwapInAm) - virtSwapOutAm))), toString(toBigInt(((priceBalanceNow + virtSwapInPr) - virtSwapOutPr))), amplificator, Amult, Dconv], nil)
666- let D0vsD1 = validateD(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
667- if ((D0vsD1 == D0vsD1))
668- then {
669- let estimatePut = commonPut(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amountId), amountAssetPart), AttachedPayment(fromBase58String(priceId), priceAssetPart), slippage, true, true, paymentAmount, paymentAssetId)
670- let estimateLP = estimatePut._2
671- let lpAssetId = estimatePut._7
672- let state = estimatePut._9
673- let amountDiff = estimatePut._10
674- let priceDiff = estimatePut._11
675- let lpCalcRes = validateAbsDiff(toBigInt(estimateLP), toBigInt(outLp), toBigInt(slippage))
676- let emitLpAmount = toInt(lpCalcRes._2)
677- let e = invoke(factoryContract, "emit", [emitLpAmount], nil)
678- if ((e == e))
679- then {
680- let el = match e {
681- case legacy: Address =>
682- invoke(legacy, "emit", [emitLpAmount], nil)
683- case _ =>
684- unit
685- }
686- if ((el == el))
687- then {
688- let sa = if ((amountDiff > 0))
689- then invoke(slippageContract, "put", nil, [AttachedPayment(fromBase58String(amountId), amountDiff)])
690- else nil
691- if ((sa == sa))
692- then {
693- let sp = if ((priceDiff > 0))
694- then invoke(slippageContract, "put", nil, [AttachedPayment(fromBase58String(priceId), priceDiff)])
695- else nil
696- if ((sp == sp))
697- then {
698- let lpTrasfer = if (autoStake)
699- then {
700- let ss = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmount)])
701- if ((ss == ss))
702- then nil
703- else throw("Strict value is not equal to itself.")
704- }
705- else [ScriptTransfer(i.caller, emitLpAmount, lpAssetId)]
706- (state ++ lpTrasfer)
707- }
708- else throw("Strict value is not equal to itself.")
709- }
710- else throw("Strict value is not equal to itself.")
711- }
712- else throw("Strict value is not equal to itself.")
713- }
714- else throw("Strict value is not equal to itself.")
715- }
716- else throw("Strict value is not equal to itself.")
717- }
718- }
719- else throw("Strict value is not equal to itself.")
632+ if (if (if (if ((0 >= slippage))
633+ then true
634+ else (0 >= amountAssetPart))
635+ then true
636+ else (0 >= priceAssetPart))
637+ then true
638+ else (0 >= outLp))
639+ then throwErr("Wrong params")
640+ else if ((size(i.payments) != 1))
641+ then throwErr("1 payment expected")
642+ else {
643+ let payment = value(i.payments[0])
644+ let paymentAssetId = toBase58String(value(payment.assetId))
645+ let paymentAmountRaw = payment.amount
646+ let $t02561725676 = takeFee(paymentAmountRaw)
647+ let paymentAmount = $t02561725676._1
648+ let feeAmount = $t02561725676._2
649+ if (if (if ((amountAssetPart > paymentAmount))
650+ then true
651+ else (priceAssetPart > paymentAmount))
652+ then true
653+ else (10000000 > paymentAmount))
654+ then throwErr("wrong payment amount")
655+ else {
656+ let amountBalance = getAccBalance(amountId)
657+ let priceBalance = getAccBalance(priceId)
658+ let $t02594026395 = if ((paymentAssetId == amountId))
659+ then $Tuple6((amountBalance - paymentAmount), priceBalance, (paymentAmount - amountAssetPart), priceAssetPart, 0, 0)
660+ else if ((paymentAssetId == priceId))
661+ then $Tuple6(amountBalance, (priceBalance - paymentAmount), 0, 0, (paymentAmount - priceAssetPart), amountAssetPart)
662+ else throwErr("wrong paymentAssetId")
663+ let amountBalanceNow = $t02594026395._1
664+ let priceBalanceNow = $t02594026395._2
665+ let virtSwapInAm = $t02594026395._3
666+ let virtSwapOutPr = $t02594026395._4
667+ let virtSwapInPr = $t02594026395._5
668+ let virtSwapOutAm = $t02594026395._6
669+ let D0 = invoke(gwxRewardContract, "calcD", [toString(amountBalanceNow), toString(priceBalanceNow), amplificator, Amult, Dconv], nil)
670+ let D1 = invoke(gwxRewardContract, "calcD", [toString(toBigInt(((amountBalanceNow + virtSwapInAm) - virtSwapOutAm))), toString(toBigInt(((priceBalanceNow + virtSwapInPr) - virtSwapOutPr))), amplificator, Amult, Dconv], nil)
671+ let D0vsD1 = validateD(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
672+ if ((D0vsD1 == D0vsD1))
673+ then {
674+ let estimatePut = commonPut(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amountId), amountAssetPart), AttachedPayment(fromBase58String(priceId), priceAssetPart), slippage, true, true, paymentAmount, paymentAssetId)
675+ let estimateLP = estimatePut._2
676+ let lpAssetId = estimatePut._7
677+ let state = estimatePut._9
678+ let amountDiff = estimatePut._10
679+ let priceDiff = estimatePut._11
680+ let lpCalcRes = validateAbsDiff(toBigInt(estimateLP), toBigInt(outLp), toBigInt(slippage))
681+ let emitLpAmount = toInt(lpCalcRes._2)
682+ let e = invoke(factoryContract, "emit", [emitLpAmount], nil)
683+ if ((e == e))
684+ then {
685+ let el = match e {
686+ case legacy: Address =>
687+ invoke(legacy, "emit", [emitLpAmount], nil)
688+ case _ =>
689+ unit
690+ }
691+ if ((el == el))
692+ then {
693+ let sa = if ((amountDiff > 0))
694+ then invoke(slippageContract, "put", nil, [AttachedPayment(fromBase58String(amountId), amountDiff)])
695+ else nil
696+ if ((sa == sa))
697+ then {
698+ let sp = if ((priceDiff > 0))
699+ then invoke(slippageContract, "put", nil, [AttachedPayment(fromBase58String(priceId), priceDiff)])
700+ else nil
701+ if ((sp == sp))
702+ then {
703+ let lpTrasfer = if (autoStake)
704+ then {
705+ let ss = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmount)])
706+ if ((ss == ss))
707+ then nil
708+ else throw("Strict value is not equal to itself.")
709+ }
710+ else [ScriptTransfer(i.caller, emitLpAmount, lpAssetId)]
711+ let sendFeeToMatcher = if ((feeAmount > 0))
712+ then [ScriptTransfer(matcherAddress, feeAmount, fromBase58String(paymentAssetId))]
713+ else nil
714+ ((state ++ lpTrasfer) ++ sendFeeToMatcher)
715+ }
716+ else throw("Strict value is not equal to itself.")
717+ }
718+ else throw("Strict value is not equal to itself.")
719+ }
720+ else throw("Strict value is not equal to itself.")
721+ }
722+ else throw("Strict value is not equal to itself.")
723+ }
724+ else throw("Strict value is not equal to itself.")
725+ }
726+ }
720727 }
721728
722729
770777 let txId58 = toBase58String(i.transactionId)
771778 let paymentAssetId = value(payment.assetId)
772779 let paymentAmount = payment.amount
773- let addonContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(keyAddonAddress()), "no addons")), "addon address in not valid")
774- let check = reentrantInvoke(addonContract, "ensureCanGetOneTkn", [toString(userAddress)], nil)
775- if ((check == check))
776- then if ((1000000000 > paymentAmount))
777- then throwErr("Min payment 10 LP")
778- else if (if (if ((0 > slippage))
779- then true
780- else (0 > exchResult))
781- then true
782- else (0 > outAmount))
783- then throwErr("Wrong params")
784- else if ((lpAssetId != toBase58String(paymentAssetId)))
785- then throwErr("Wrong LP")
786- else {
787- let r = estimateGetOperation(toBase58String(i.transactionId), toBase58String(paymentAssetId), paymentAmount, i.caller)
788- let estimAmAmt = r._1
789- let estimPrAmt = r._2
790- let amountBalance = getAccBalance(amountId)
791- let priceBalance = getAccBalance(priceId)
792- let $t03176632234 = if ((outAssetId == amountId))
793- then $Tuple7((amountBalance - estimAmAmt), (priceBalance - estimPrAmt), exchResult, estimPrAmt, 0, 0, (estimAmAmt + exchResult))
794- else if ((outAssetId == priceId))
795- then $Tuple7((amountBalance - estimAmAmt), (priceBalance - estimPrAmt), 0, 0, exchResult, estimAmAmt, (estimPrAmt + exchResult))
796- else throwErr("wrong outAssetId")
797- let amountBalanceNow = $t03176632234._1
798- let priceBalanceNow = $t03176632234._2
799- let virtSwapInAm = $t03176632234._3
800- let virtSwapOutPr = $t03176632234._4
801- let virtSwapInPr = $t03176632234._5
802- let virtSwapOutAm = $t03176632234._6
803- let totalGet = $t03176632234._7
804- if (if ((0 > virtSwapInAm))
805- then true
806- else (0 > virtSwapInPr))
807- then throwErr("Wrong calc")
808- else {
809- let D0 = invoke(gwxRewardContract, "calcD", [toString(amountBalanceNow), toString(priceBalanceNow), amplificator, Amult, Dconv], nil)
810- let D1 = invoke(gwxRewardContract, "calcD", [toString(((amountBalanceNow - virtSwapInAm) + virtSwapOutAm)), toString(((priceBalanceNow + virtSwapOutPr) - virtSwapInPr)), amplificator, Amult, Dconv], nil)
811- let D0vsD1 = validateD(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
812- if ((D0vsD1 == D0vsD1))
813- then {
814- let finalRes = validateAbsDiff(toBigInt(totalGet), toBigInt(outAmount), toBigInt(slippage))
815- if ((finalRes == finalRes))
816- then {
817- let $t03290333011 = if ((outAssetId == amountId))
818- then $Tuple2(toInt(finalRes._2), 0)
819- else $Tuple2(0, toInt(finalRes._2))
820- let outAm = $t03290333011._1
821- let outPr = $t03290333011._2
822- let decimals = if ((amountDecimals >= priceDecimals))
823- then amountDecimals
824- else priceDecimals
825- if ((decimals == decimals))
826- then {
827- let curPrX18 = calcPriceBigInt(toX18(priceBalance, decimals), toX18(amountBalance, decimals))
828- let curPr = fromX18(curPrX18, scale8)
829- let state = [ScriptTransfer(userAddress, (outAm + outPr), if ((outAssetId == "WAVES"))
830- then unit
831- else fromBase58String(outAssetId)), StringEntry(keyGetActionByUser(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, paymentAmount, curPr, height, lastBlock.timestamp)), IntegerEntry(keyPriceLast(), curPr), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), curPr)]
832- if ((state == state))
833- then {
834- let burn = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
835- if ((burn == burn))
836- then state
837- else throw("Strict value is not equal to itself.")
838- }
839- else throw("Strict value is not equal to itself.")
840- }
841- else throw("Strict value is not equal to itself.")
842- }
843- else throw("Strict value is not equal to itself.")
844- }
845- else throw("Strict value is not equal to itself.")
846- }
847- }
848- else throw("Strict value is not equal to itself.")
780+ if ((1000000000 > paymentAmount))
781+ then throwErr("Min payment 10 LP")
782+ else if (if (if ((0 > slippage))
783+ then true
784+ else (0 > exchResult))
785+ then true
786+ else (0 > outAmount))
787+ then throwErr("Wrong params")
788+ else if ((lpAssetId != toBase58String(paymentAssetId)))
789+ then throwErr("Wrong LP")
790+ else {
791+ let r = estimateGetOperation(toBase58String(i.transactionId), toBase58String(paymentAssetId), paymentAmount, i.caller)
792+ let estimAmAmt = r._1
793+ let estimPrAmt = r._2
794+ let amountBalance = getAccBalance(amountId)
795+ let priceBalance = getAccBalance(priceId)
796+ let $t03153432002 = if ((outAssetId == amountId))
797+ then $Tuple7((amountBalance - estimAmAmt), (priceBalance - estimPrAmt), exchResult, estimPrAmt, 0, 0, (estimAmAmt + exchResult))
798+ else if ((outAssetId == priceId))
799+ then $Tuple7((amountBalance - estimAmAmt), (priceBalance - estimPrAmt), 0, 0, exchResult, estimAmAmt, (estimPrAmt + exchResult))
800+ else throwErr("wrong outAssetId")
801+ let amountBalanceNow = $t03153432002._1
802+ let priceBalanceNow = $t03153432002._2
803+ let virtSwapInAm = $t03153432002._3
804+ let virtSwapOutPr = $t03153432002._4
805+ let virtSwapInPr = $t03153432002._5
806+ let virtSwapOutAm = $t03153432002._6
807+ let totalGet = $t03153432002._7
808+ if (if ((0 > virtSwapInAm))
809+ then true
810+ else (0 > virtSwapInPr))
811+ then throwErr("Wrong calc")
812+ else {
813+ let D0 = invoke(gwxRewardContract, "calcD", [toString(amountBalanceNow), toString(priceBalanceNow), amplificator, Amult, Dconv], nil)
814+ let D1 = invoke(gwxRewardContract, "calcD", [toString(((amountBalanceNow - virtSwapInAm) + virtSwapOutAm)), toString(((priceBalanceNow + virtSwapOutPr) - virtSwapInPr)), amplificator, Amult, Dconv], nil)
815+ let D0vsD1 = validateD(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
816+ if ((D0vsD1 == D0vsD1))
817+ then {
818+ let finalRes = validateAbsDiff(toBigInt(totalGet), toBigInt(outAmount), toBigInt(slippage))
819+ if ((finalRes == finalRes))
820+ then {
821+ let $t03267132779 = if ((outAssetId == amountId))
822+ then $Tuple2(toInt(finalRes._2), 0)
823+ else $Tuple2(0, toInt(finalRes._2))
824+ let outAm = $t03267132779._1
825+ let outPr = $t03267132779._2
826+ let totalAmountRaw = (outAm + outPr)
827+ let $t03281932874 = takeFee(totalAmountRaw)
828+ let totalAmount = $t03281932874._1
829+ let feeAmount = $t03281932874._2
830+ let outAssetIdOrWaves = if ((outAssetId == "WAVES"))
831+ then unit
832+ else fromBase58String(outAssetId)
833+ let sendFeeToMatcher = if ((feeAmount > 0))
834+ then [ScriptTransfer(matcherAddress, feeAmount, outAssetIdOrWaves)]
835+ else nil
836+ let decimals = if ((amountDecimals >= priceDecimals))
837+ then amountDecimals
838+ else priceDecimals
839+ if ((decimals == decimals))
840+ then {
841+ let curPrX18 = calcPriceBigInt(toX18(priceBalance, decimals), toX18(amountBalance, decimals))
842+ let curPr = fromX18(curPrX18, scale8)
843+ let state = [ScriptTransfer(userAddress, totalAmount, outAssetIdOrWaves), StringEntry(keyGetActionByUser(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, paymentAmount, curPr, height, lastBlock.timestamp)), IntegerEntry(keyPriceLast(), curPr), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), curPr)]
844+ if ((state == state))
845+ then {
846+ let burn = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
847+ if ((burn == burn))
848+ then (state ++ sendFeeToMatcher)
849+ else throw("Strict value is not equal to itself.")
850+ }
851+ else throw("Strict value is not equal to itself.")
852+ }
853+ else throw("Strict value is not equal to itself.")
854+ }
855+ else throw("Strict value is not equal to itself.")
856+ }
857+ else throw("Strict value is not equal to itself.")
858+ }
859+ }
849860 }
850861
851862
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 6 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 let scale8 = 100000000
55
66 let scale8BigInt = toBigInt(100000000)
77
88 let scale18 = toBigInt(1000000000000000000)
9+
10+let thousand = 1000
911
1012 let zeroBigInt = toBigInt(0)
1113
1214 let oneBigInt = toBigInt(1)
1315
1416 let slippage4D = toBigInt((scale8 - ((scale8 * 1) / scale8)))
1517
1618 let Amult = "100"
1719
1820 let Dconv = "1"
1921
2022 let SEP = "__"
2123
2224 let EMPTY = ""
2325
2426 let PoolActive = 1
2527
2628 let PoolPutDis = 2
2729
2830 let PoolMatcherDis = 3
2931
3032 let PoolShutdown = 4
3133
3234 let idxPoolAddress = 1
3335
3436 let idxPoolSt = 2
3537
3638 let idxLPAsId = 3
3739
3840 let idxAmAsId = 4
3941
4042 let idxPrAsId = 5
4143
4244 let idxAmtAsDcm = 6
4345
4446 let idxPriceAsDcm = 7
4547
4648 let idxIAmtAsId = 8
4749
4850 let idxIPriceAsId = 9
4951
5052 let idxFactStakCntr = 1
5153
5254 let idxFactSlippCntr = 7
5355
5456 let idxFactGwxRewCntr = 10
5557
56-let delay = "%s__delay"
58+let feePermilleDefault = 0
5759
5860 func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult))
5961
6062
6163 func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18))
6264
6365
6466 func ts (amt,resScale,curScale) = fraction(amt, resScale, curScale)
6567
6668
6769 func abs (val) = if ((zeroBigInt > val))
6870 then -(val)
6971 else val
7072
7173
7274 func keyFactoryContact () = "%s__factoryContract"
7375
7476
7577 func keyManagerPublicKey () = "%s__managerPublicKey"
7678
7779
7880 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
7981
8082
8183 func keyPriceLast () = "%s%s__price__last"
8284
8385
8486 func keyPriceHistory (h,t) = makeString(["%s%s%d%d__price__history", toString(h), toString(t)], SEP)
8587
8688
8789 func keyPutActionByUser (ua,txId) = ((("%s%s%s__P__" + ua) + "__") + txId)
8890
8991
9092 func keyGetActionByUser (ua,txId) = ((("%s%s%s__G__" + ua) + "__") + txId)
9193
9294
9395 func keyAmountAsset () = "%s__amountAsset"
9496
9597
9698 func keyPriceAsset () = "%s__priceAsset"
9799
98100
99101 func keyAmplificator () = "%s__amp"
100102
101103
102104 func keyAddonAddress () = "%s__addonAddr"
103105
104106
105-func lgotc (caller) = makeString(["%s%s__lastGetOneTknCall", caller], SEP)
107+let keyFeePermille = "%s__feePermille"
106108
107-
108-func lsotc (caller) = makeString(["%s%s__lastPutOneTknCall", caller], SEP)
109-
109+let feePermille = valueOrElse(getInteger(this, keyFeePermille), feePermilleDefault)
110110
111111 func fcfg () = "%s__factoryConfig"
112112
113113
114114 func mtpk () = "%s%s__matcher__publicKey"
115115
116116
117117 func pc (iAmtAs,iPrAs) = (((("%d%d%s__" + iAmtAs) + "__") + iPrAs) + "__config")
118118
119119
120120 func mba (bAStr) = ("%s%s%s__mappings__baseAsset2internalId__" + bAStr)
121121
122122
123123 func aps () = "%s__shutdown"
124124
125125
126126 func throwErr (msg) = throw(makeString(["lp_stable.ride:", msg], " "))
127127
128128
129129 func throwOrderError (orV,sendrV,matchV) = throwErr(((((("Failed: ordValid=" + toString(orV)) + " sndrValid=") + toString(sendrV)) + " mtchrValid=") + toString(matchV)))
130130
131131
132132 func str (val) = match val {
133133 case valStr: String =>
134134 valStr
135135 case _ =>
136136 throwErr("fail cast to String")
137137 }
138138
139139
140140 func getStringOrFail (addr,key) = valueOrErrorMessage(getString(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
141141
142142
143143 func getIntOrFail (addr,key) = valueOrErrorMessage(getInteger(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
144144
145145
146146 let factoryContract = addressFromStringValue(getStringOrFail(this, keyFactoryContact()))
147147
148148 let amplificator = getStringOrFail(this, keyAmplificator())
149149
150150 func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, aps()), false)
151151
152152
153153 func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, mtpk()))
154154
155+
156+let matcherAddress = addressFromPublicKey(getMatcherPubOrFail())
155157
156158 func getPoolConfig () = {
157159 let amtAs = getStringOrFail(this, keyAmountAsset())
158160 let priceAs = getStringOrFail(this, keyPriceAsset())
159161 let iPriceAs = getIntOrFail(factoryContract, mba(priceAs))
160162 let iAmtAs = getIntOrFail(factoryContract, mba(amtAs))
161163 split(getStringOrFail(factoryContract, pc(toString(iAmtAs), toString(iPriceAs))), SEP)
162164 }
163165
164166
165167 func getFactoryConfig () = split(getStringOrFail(factoryContract, fcfg()), SEP)
166168
167169
168170 func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slipByUser,slippageReal,txHeight,txTimestamp,slipageAmAmt,slipagePrAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slipByUser), toString(slippageReal), toString(txHeight), toString(txTimestamp), toString(slipageAmAmt), toString(slipagePrAmt)], SEP)
169171
170172
171173 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)
172174
173175
174176 func getAccBalance (assetId) = if ((assetId == "WAVES"))
175177 then wavesBalance(this).available
176178 else assetBalance(this, fromBase58String(assetId))
177179
178180
179181 func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18)
180182
181183
182184 func validateAbsDiff (estimateLP,outLp,slippage) = {
183185 let diff = fraction((estimateLP - outLp), scale8BigInt, outLp)
184186 let pass = ((slippage - abs(diff)) > zeroBigInt)
185187 if (!(pass))
186188 then throwErr(("Big slippage: " + toString(diff)))
187189 else $Tuple2(pass, min([estimateLP, outLp]))
188190 }
189191
190192
191193 func validateD (D1,D0,slippage) = {
192194 let diff = fraction(D0, scale8BigInt, D1)
193195 let fail = (slippage > diff)
194196 if (if (fail)
195197 then true
196198 else (D0 > D1))
197199 then throwErr(((((((toString(D0) + " ") + toString(D1)) + " ") + toString(diff)) + " ") + toString(slippage)))
198200 else fail
199201 }
200202
201203
202204 func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = {
203205 let amtAsAmtX18 = toX18(amAmt, amAssetDcm)
204206 let prAsAmtX18 = toX18(prAmt, prAssetDcm)
205207 calcPriceBigInt(prAsAmtX18, amtAsAmtX18)
206208 }
207209
208210
209211 func calcPrices (amAmt,prAmt,lpAmt) = {
210212 let cfg = getPoolConfig()
211213 let amtAsDcm = parseIntValue(cfg[idxAmtAsDcm])
212214 let prAsDcm = parseIntValue(cfg[idxPriceAsDcm])
213215 let priceX18 = privateCalcPrice(amtAsDcm, prAsDcm, amAmt, prAmt)
214216 let amAmtX18 = toX18(amAmt, amtAsDcm)
215217 let prAmtX18 = toX18(prAmt, prAsDcm)
216218 let lpAmtX18 = toX18(lpAmt, scale8)
217219 let lpPrInAmAsX18 = calcPriceBigInt(amAmtX18, lpAmtX18)
218220 let lpPrInPrAsX18 = calcPriceBigInt(prAmtX18, lpAmtX18)
219221 [priceX18, lpPrInAmAsX18, lpPrInPrAsX18]
220222 }
221223
222224
223225 func calculatePrices (amAmt,prAmt,lpAmt) = {
224226 let p = calcPrices(amAmt, prAmt, lpAmt)
225227 [fromX18(p[0], scale8), fromX18(p[1], scale8), fromX18(p[2], scale8)]
226228 }
227229
228230
229231 func estimateGetOperation (txId58,paymentAssetId,paymentLpAmount,userAddress) = {
230232 let cfg = getPoolConfig()
231233 let lpAssetId = cfg[idxLPAsId]
232234 let amountId = cfg[idxAmAsId]
233235 let priceId = cfg[idxPrAsId]
234236 let amountDecimals = parseIntValue(cfg[idxAmtAsDcm])
235237 let priceDecimals = parseIntValue(cfg[idxPriceAsDcm])
236238 let sts = cfg[idxPoolSt]
237239 let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), "Wrong LP id").quantity
238240 let validationBlock = if ((lpAssetId == paymentAssetId))
239241 then true
240242 else throwErr("Wrong payment asset")
241243 if ((validationBlock == validationBlock))
242244 then {
243245 let decimals = if ((amountDecimals >= priceDecimals))
244246 then amountDecimals
245247 else priceDecimals
246248 if ((decimals == decimals))
247249 then {
248250 let amountBalance = getAccBalance(amountId)
249251 let amountBalanceX18 = toX18(amountBalance, decimals)
250252 let priceBalance = getAccBalance(priceId)
251253 let priceBalanceX18 = toX18(priceBalance, decimals)
252254 let currentPriceX18 = calcPriceBigInt(priceBalanceX18, amountBalanceX18)
253255 let curPrice = fromX18(currentPriceX18, scale8)
254256 let paymentLpAmountX18 = toX18(paymentLpAmount, scale8)
255257 let lpEmissionX18 = toX18(lpEmission, scale8)
256258 let outAmountAmountX18 = fraction(amountBalanceX18, paymentLpAmountX18, lpEmissionX18)
257259 let outPriceAmountX18 = fraction(priceBalanceX18, paymentLpAmountX18, lpEmissionX18)
258260 let outAmountAmount = fromX18(outAmountAmountX18, decimals)
259261 let outPriceAmount = fromX18(outPriceAmountX18, decimals)
260262 let state = if ((txId58 == ""))
261263 then nil
262264 else [ScriptTransfer(userAddress, outAmountAmount, if ((amountId == "WAVES"))
263265 then unit
264266 else fromBase58String(amountId)), ScriptTransfer(userAddress, outPriceAmount, if ((priceId == "WAVES"))
265267 then unit
266268 else fromBase58String(priceId)), StringEntry(keyGetActionByUser(toString(userAddress), txId58), dataGetActionInfo(outAmountAmount, outPriceAmount, paymentLpAmount, curPrice, height, lastBlock.timestamp)), IntegerEntry(keyPriceLast(), curPrice), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), curPrice)]
267269 $Tuple10(outAmountAmount, outPriceAmount, amountId, priceId, amountBalance, priceBalance, lpEmission, currentPriceX18, sts, state)
268270 }
269271 else throw("Strict value is not equal to itself.")
270272 }
271273 else throw("Strict value is not equal to itself.")
272274 }
273275
274276
275277 func estimatePutOperation (txId58,slippageTolerance,inAmountAssetAmount,inAmountAssetId,inPriceAssetAmount,inPriceAssetId,userAddress,isEvaluate,emitLp,isOneAsset,paymentAmount,paymentId) = {
276278 let cfg = getPoolConfig()
277279 let lpAssetId = fromBase58String(cfg[idxLPAsId])
278280 let amountIdStr = cfg[idxAmAsId]
279281 let priceIdStr = cfg[idxPrAsId]
280282 let inAmountIdStr = cfg[idxIAmtAsId]
281283 let inPriceIdStr = cfg[idxIPriceAsId]
282284 let amountDecimals = parseIntValue(cfg[idxAmtAsDcm])
283285 let priceDecimals = parseIntValue(cfg[idxPriceAsDcm])
284286 let sts = cfg[idxPoolSt]
285287 let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), "Wrong lp asset").quantity
286288 let amountBalance = if (isEvaluate)
287289 then getAccBalance(amountIdStr)
288290 else if (if (isOneAsset)
289291 then (paymentId == amountIdStr)
290292 else false)
291293 then (getAccBalance(amountIdStr) - paymentAmount)
292294 else if (isOneAsset)
293295 then getAccBalance(amountIdStr)
294296 else (getAccBalance(amountIdStr) - inAmountAssetAmount)
295297 let priceBalance = if (isEvaluate)
296298 then getAccBalance(priceIdStr)
297299 else if (if (isOneAsset)
298300 then (paymentId == priceIdStr)
299301 else false)
300302 then (getAccBalance(priceIdStr) - paymentAmount)
301303 else if (isOneAsset)
302304 then getAccBalance(priceIdStr)
303305 else (getAccBalance(priceIdStr) - inPriceAssetAmount)
304306 let decimals = if ((amountDecimals >= priceDecimals))
305307 then amountDecimals
306308 else priceDecimals
307309 if ((decimals == decimals))
308310 then {
309311 let inAmountAssetAmountX18 = toX18(inAmountAssetAmount, decimals)
310312 let inPriceAssetAmountX18 = toX18(inPriceAssetAmount, decimals)
311313 let userPriceX18 = calcPriceBigInt(inPriceAssetAmountX18, inAmountAssetAmountX18)
312314 let amountBalanceX18 = toX18(amountBalance, decimals)
313315 let priceBalanceX18 = toX18(priceBalance, decimals)
314316 let r = if ((lpEmission == 0))
315317 then {
316318 let currentPriceX18 = zeroBigInt
317319 let slippageX18 = zeroBigInt
318320 let lpAmountX18 = pow((inAmountAssetAmountX18 * inPriceAssetAmountX18), 0, toBigInt(5), 1, 0, DOWN)
319321 $Tuple5(fromX18(lpAmountX18, scale8), fromX18(inAmountAssetAmountX18, decimals), fromX18(inPriceAssetAmountX18, decimals), calcPriceBigInt((priceBalanceX18 + inPriceAssetAmountX18), (amountBalanceX18 + inAmountAssetAmountX18)), slippageX18)
320322 }
321323 else {
322324 let currentPriceX18 = calcPriceBigInt(priceBalanceX18, amountBalanceX18)
323325 let slippageRealX18 = fraction(abs((currentPriceX18 - userPriceX18)), scale18, currentPriceX18)
324326 let slippageX18 = toX18(slippageTolerance, scale8)
325- let validateSlippage = if (((if ((currentPriceX18 != zeroBigInt))
327+ if (if ((currentPriceX18 != zeroBigInt))
326328 then (slippageRealX18 > slippageX18)
327- else false) == false))
328- then true
329- else throwErr(((("Price slippage " + toString(slippageRealX18)) + " > ") + toString(slippageX18)))
330- if ((validateSlippage == validateSlippage))
331- then {
329+ else false)
330+ then throwErr(((("Price slippage " + toString(slippageRealX18)) + " > ") + toString(slippageX18)))
331+ else {
332332 let lpEmissionX18 = toX18(lpEmission, scale8)
333333 let prViaAmX18 = fraction(inAmountAssetAmountX18, currentPriceX18, scale18)
334334 let amViaPrX18 = fraction(inPriceAssetAmountX18, scale18, currentPriceX18)
335335 let expectedAmounts = if ((prViaAmX18 > inPriceAssetAmountX18))
336336 then $Tuple2(amViaPrX18, inAmountAssetAmountX18)
337337 else $Tuple2(inAmountAssetAmountX18, prViaAmX18)
338338 let expectedAmountAssetAmountX18 = expectedAmounts._1
339339 let expectedPriceAssetAmountX18 = expectedAmounts._2
340340 let lpAmountX18 = fraction(lpEmissionX18, expectedPriceAssetAmountX18, priceBalanceX18)
341341 $Tuple5(fromX18(lpAmountX18, scale8), fromX18(expectedAmountAssetAmountX18, decimals), fromX18(expectedPriceAssetAmountX18, decimals), currentPriceX18, slippageX18)
342342 }
343- else throw("Strict value is not equal to itself.")
344343 }
345344 let calculateLpAmount = r._1
346345 let calculateAmountAssetPayment = r._2
347346 let calculatePriceAssetPayment = r._3
348347 let currentPrice = fromX18(r._4, scale8)
349348 let slippageCalculate = fromX18(r._5, scale8)
350349 let checkCalcLpAmount = if ((calculateLpAmount > 0))
351350 then true
352351 else throwErr("LP <= 0")
353352 if ((checkCalcLpAmount == checkCalcLpAmount))
354353 then {
355354 let emitLpAmount = if (!(emitLp))
356355 then 0
357356 else calculateLpAmount
358357 let amountDiff = (inAmountAssetAmount - calculateAmountAssetPayment)
359358 let priceDiff = (inPriceAssetAmount - calculatePriceAssetPayment)
360- let $t01622016479 = if (if (isOneAsset)
359+ let $t01618916448 = if (if (isOneAsset)
361360 then (paymentId == amountIdStr)
362361 else false)
363362 then $Tuple2(paymentAmount, 0)
364363 else if (if (isOneAsset)
365364 then (paymentId == priceIdStr)
366365 else false)
367366 then $Tuple2(0, paymentAmount)
368367 else $Tuple2(calculateAmountAssetPayment, calculatePriceAssetPayment)
369- let writeAmAmt = $t01622016479._1
370- let writePrAmt = $t01622016479._2
368+ let writeAmAmt = $t01618916448._1
369+ let writePrAmt = $t01618916448._2
371370 let commonState = [IntegerEntry(keyPriceLast(), currentPrice), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), currentPrice), StringEntry(keyPutActionByUser(userAddress, txId58), dataPutActionInfo(writeAmAmt, writePrAmt, emitLpAmount, currentPrice, slippageTolerance, slippageCalculate, height, lastBlock.timestamp, amountDiff, priceDiff))]
372371 $Tuple13(calculateLpAmount, emitLpAmount, currentPrice, amountBalance, priceBalance, lpEmission, lpAssetId, sts, commonState, amountDiff, priceDiff, inAmountAssetId, inPriceAssetId)
373372 }
374373 else throw("Strict value is not equal to itself.")
375374 }
376375 else throw("Strict value is not equal to itself.")
377376 }
378377
379378
380379 func validateMatcherOrderAllowed (order) = {
381380 let cfg = getPoolConfig()
382381 let amtAsId = cfg[idxAmAsId]
383382 let prAsId = cfg[idxPrAsId]
384383 let sts = parseIntValue(cfg[idxPoolSt])
385384 let amtAsDcm = parseIntValue(cfg[idxAmtAsDcm])
386385 let prAsDcm = parseIntValue(cfg[idxPriceAsDcm])
387386 let accAmtAsBalance = getAccBalance(amtAsId)
388387 let accPrAsBalance = getAccBalance(prAsId)
389388 let currentPriceX18 = if ((order.orderType == Buy))
390389 then privateCalcPrice(amtAsDcm, prAsDcm, (accAmtAsBalance + order.amount), accPrAsBalance)
391390 else privateCalcPrice(amtAsDcm, prAsDcm, (accAmtAsBalance - order.amount), accPrAsBalance)
392391 let curPrice = fromX18(currentPriceX18, scale8)
393392 if (if (if (isGlobalShutdown())
394393 then true
395394 else (sts == PoolMatcherDis))
396395 then true
397396 else (sts == PoolShutdown))
398397 then throwErr("Admin blocked")
399398 else {
400399 let orAmtAsset = order.assetPair.amountAsset
401400 let orAmtAsStr = if ((orAmtAsset == unit))
402401 then "WAVES"
403402 else toBase58String(value(orAmtAsset))
404403 let orPrAsset = order.assetPair.priceAsset
405404 let orPrAsStr = if ((orPrAsset == unit))
406405 then "WAVES"
407406 else toBase58String(value(orPrAsset))
408407 if (if ((orAmtAsStr != amtAsId))
409408 then true
410409 else (orPrAsStr != prAsId))
411410 then throwErr("Wr assets")
412411 else {
413412 let orderPrice = order.price
414413 let priceDecimals = fraction(scale8, prAsDcm, amtAsDcm)
415414 let castOrderPrice = ts(orderPrice, scale8, priceDecimals)
416415 let isOrderPriceValid = if ((order.orderType == Buy))
417416 then (curPrice >= castOrderPrice)
418417 else (castOrderPrice >= curPrice)
419418 true
420419 }
421420 }
422421 }
423422
424423
425424 func commonGet (i) = {
426425 let checkPayments = if ((size(i.payments) == 1))
427426 then true
428427 else throwErr("1 payment expected")
429428 if ((checkPayments == checkPayments))
430429 then {
431430 let payment = value(i.payments[0])
432431 let paymentAssetId = value(payment.assetId)
433432 let paymentAmount = payment.amount
434433 let r = estimateGetOperation(toBase58String(i.transactionId), toBase58String(paymentAssetId), paymentAmount, i.caller)
435434 let outAmountAmount = r._1
436435 let outPriceAmount = r._2
437436 let sts = parseIntValue(r._9)
438437 let state = r._10
439438 if (if (isGlobalShutdown())
440439 then true
441440 else (sts == PoolShutdown))
442441 then throwErr(("Admin blocked: " + toString(sts)))
443442 else $Tuple5(outAmountAmount, outPriceAmount, paymentAmount, paymentAssetId, state)
444443 }
445444 else throw("Strict value is not equal to itself.")
446445 }
447446
448447
449448 func commonPut (caller,txId,amountAssetPayment,priceAssetPayment,slippage,emitLp,isOneAsset,paymentAmount,paymentId) = {
450449 let r = estimatePutOperation(txId, slippage, value(amountAssetPayment).amount, value(amountAssetPayment).assetId, value(priceAssetPayment).amount, value(priceAssetPayment).assetId, caller, false, emitLp, isOneAsset, paymentAmount, paymentId)
451450 let sts = parseIntValue(r._8)
452451 if (if (if (isGlobalShutdown())
453452 then true
454453 else (sts == PoolPutDis))
455454 then true
456455 else (sts == PoolShutdown))
457456 then throwErr(("Blocked:" + toString(sts)))
458457 else r
458+ }
459+
460+
461+func takeFee (amount) = {
462+ let fee = fraction(amount, feePermille, thousand)
463+ $Tuple2((amount - fee), fee)
459464 }
460465
461466
462467 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
463468 case s: String =>
464469 fromBase58String(s)
465470 case _: Unit =>
466471 unit
467472 case _ =>
468473 throw("Match error")
469474 }
470475
471476
472477 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
473478 case s: String =>
474479 fromBase58String(s)
475480 case _: Unit =>
476481 unit
477482 case _ =>
478483 throw("Match error")
479484 }
480485
481486
482487 let pd = throwErr("Permission denied")
483488
484489 func mustManager (i) = match managerPublicKeyOrUnit() {
485490 case pk: ByteVector =>
486491 if ((i.callerPublicKey == pk))
487492 then true
488493 else pd
489494 case _: Unit =>
490495 if ((i.caller == this))
491496 then true
492497 else pd
493498 case _ =>
494499 throw("Match error")
495500 }
496501
497502
498503 @Callable(i)
499504 func constructor (factoryContract) = {
500505 let checkCaller = mustManager(i)
501506 if ((checkCaller == checkCaller))
502507 then [StringEntry(keyFactoryContact(), factoryContract)]
503508 else throw("Strict value is not equal to itself.")
504509 }
505510
506511
507512
508513 @Callable(i)
509514 func setManager (pendingManagerPublicKey) = {
510515 let checkCaller = mustManager(i)
511516 if ((checkCaller == checkCaller))
512517 then {
513518 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
514519 if ((checkManagerPublicKey == checkManagerPublicKey))
515520 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
516521 else throw("Strict value is not equal to itself.")
517522 }
518523 else throw("Strict value is not equal to itself.")
519524 }
520525
521526
522527
523528 @Callable(i)
524529 func confirmManager () = {
525530 let pm = pendingManagerPublicKeyOrUnit()
526531 let hasPM = if (isDefined(pm))
527532 then true
528533 else throwErr("No pending manager")
529534 if ((hasPM == hasPM))
530535 then {
531536 let checkPM = if ((i.callerPublicKey == value(pm)))
532537 then true
533538 else throwErr("You are not pending manager")
534539 if ((checkPM == checkPM))
535540 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
536541 else throw("Strict value is not equal to itself.")
537542 }
538543 else throw("Strict value is not equal to itself.")
539544 }
540545
541546
542547
543548 @Callable(i)
544549 func put (slippage,autoStake) = {
545550 let factCfg = getFactoryConfig()
546551 let stakingContract = valueOrErrorMessage(addressFromString(factCfg[idxFactStakCntr]), "Wrong staking contract")
547552 let slippageContract = valueOrErrorMessage(addressFromString(factCfg[idxFactSlippCntr]), "Wrogn slippage contract")
548553 let slippageCheck = if ((slippage >= 0))
549554 then true
550555 else throwErr("wrong slippage")
551556 if ((slippageCheck == slippageCheck))
552557 then {
553558 let paymentsCheck = if ((size(i.payments) == 2))
554559 then true
555560 else throwErr("2 payments expected")
556561 if ((paymentsCheck == paymentsCheck))
557562 then {
558563 let estimatePut = commonPut(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], slippage, true, false, 0, "")
559564 let emitLpAmount = estimatePut._2
560565 let lpAssetId = estimatePut._7
561566 let state = estimatePut._9
562567 let amountDiff = estimatePut._10
563568 let priceDiff = estimatePut._11
564569 let amountId = estimatePut._12
565570 let priceId = estimatePut._13
566571 let r = invoke(factoryContract, "emit", [emitLpAmount], nil)
567572 if ((r == r))
568573 then {
569574 let el = match r {
570575 case legacy: Address =>
571576 invoke(legacy, "emit", [emitLpAmount], nil)
572577 case _ =>
573578 unit
574579 }
575580 if ((el == el))
576581 then {
577582 let sa = if ((amountDiff > 0))
578583 then invoke(slippageContract, "put", nil, [AttachedPayment(amountId, amountDiff)])
579584 else nil
580585 if ((sa == sa))
581586 then {
582587 let sp = if ((priceDiff > 0))
583588 then invoke(slippageContract, "put", nil, [AttachedPayment(priceId, priceDiff)])
584589 else nil
585590 if ((sp == sp))
586591 then {
587592 let lpTrasfer = if (autoStake)
588593 then {
589594 let ss = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmount)])
590595 if ((ss == ss))
591596 then nil
592597 else throw("Strict value is not equal to itself.")
593598 }
594599 else [ScriptTransfer(i.caller, emitLpAmount, lpAssetId)]
595600 (state ++ lpTrasfer)
596601 }
597602 else throw("Strict value is not equal to itself.")
598603 }
599604 else throw("Strict value is not equal to itself.")
600605 }
601606 else throw("Strict value is not equal to itself.")
602607 }
603608 else throw("Strict value is not equal to itself.")
604609 }
605610 else throw("Strict value is not equal to itself.")
606611 }
607612 else throw("Strict value is not equal to itself.")
608613 }
609614
610615
611616
612617 @Callable(i)
613618 func putOneTkn (amountAssetPart,priceAssetPart,outLp,slippage,autoStake) = {
614619 let cfg = getFactoryConfig()
615620 let stakingContract = valueOrErrorMessage(addressFromString(cfg[idxFactStakCntr]), "Wrong staking contract")
616621 let slippageContract = valueOrErrorMessage(addressFromString(cfg[idxFactSlippCntr]), "Wrong slippage contract")
617622 let gwxRewardContract = valueOrErrorMessage(addressFromString(cfg[idxFactGwxRewCntr]), "Wrong gwx reward contract")
618623 let poolCfg = getPoolConfig()
619624 let amountId = poolCfg[idxAmAsId]
620625 let priceId = poolCfg[idxPrAsId]
621626 let amountDecimals = parseIntValue(poolCfg[idxAmtAsDcm])
622627 let priceDecimals = parseIntValue(poolCfg[idxPriceAsDcm])
623628 let addon = valueOrElse(getString(this, keyAddonAddress()), "")
624629 let userAddress = if ((addon == toString(i.caller)))
625630 then i.originCaller
626631 else i.caller
627- let addonContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(keyAddonAddress()), "no addons")), "addon address in not valid")
628- let check = reentrantInvoke(addonContract, "ensureCanPutOneTkn", [toString(userAddress)], nil)
629- if ((check == check))
630- then if (if (if (if ((0 >= slippage))
631- then true
632- else (0 >= amountAssetPart))
633- then true
634- else (0 >= priceAssetPart))
635- then true
636- else (0 >= outLp))
637- then throwErr("Wrong params")
638- else if ((size(i.payments) != 1))
639- then throwErr("1 payment expected")
640- else {
641- let payment = value(i.payments[0])
642- let paymentAssetId = toBase58String(value(payment.assetId))
643- let paymentAmount = payment.amount
644- if (if (if ((amountAssetPart > paymentAmount))
645- then true
646- else (priceAssetPart > paymentAmount))
647- then true
648- else (10000000 > paymentAmount))
649- then throwErr("wrong payment amount")
650- else {
651- let amountBalance = getAccBalance(amountId)
652- let priceBalance = getAccBalance(priceId)
653- let $t02607126526 = if ((paymentAssetId == amountId))
654- then $Tuple6((amountBalance - paymentAmount), priceBalance, (paymentAmount - amountAssetPart), priceAssetPart, 0, 0)
655- else if ((paymentAssetId == priceId))
656- then $Tuple6(amountBalance, (priceBalance - paymentAmount), 0, 0, (paymentAmount - priceAssetPart), amountAssetPart)
657- else throwErr("wrong paymentAssetId")
658- let amountBalanceNow = $t02607126526._1
659- let priceBalanceNow = $t02607126526._2
660- let virtSwapInAm = $t02607126526._3
661- let virtSwapOutPr = $t02607126526._4
662- let virtSwapInPr = $t02607126526._5
663- let virtSwapOutAm = $t02607126526._6
664- let D0 = invoke(gwxRewardContract, "calcD", [toString(amountBalanceNow), toString(priceBalanceNow), amplificator, Amult, Dconv], nil)
665- let D1 = invoke(gwxRewardContract, "calcD", [toString(toBigInt(((amountBalanceNow + virtSwapInAm) - virtSwapOutAm))), toString(toBigInt(((priceBalanceNow + virtSwapInPr) - virtSwapOutPr))), amplificator, Amult, Dconv], nil)
666- let D0vsD1 = validateD(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
667- if ((D0vsD1 == D0vsD1))
668- then {
669- let estimatePut = commonPut(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amountId), amountAssetPart), AttachedPayment(fromBase58String(priceId), priceAssetPart), slippage, true, true, paymentAmount, paymentAssetId)
670- let estimateLP = estimatePut._2
671- let lpAssetId = estimatePut._7
672- let state = estimatePut._9
673- let amountDiff = estimatePut._10
674- let priceDiff = estimatePut._11
675- let lpCalcRes = validateAbsDiff(toBigInt(estimateLP), toBigInt(outLp), toBigInt(slippage))
676- let emitLpAmount = toInt(lpCalcRes._2)
677- let e = invoke(factoryContract, "emit", [emitLpAmount], nil)
678- if ((e == e))
679- then {
680- let el = match e {
681- case legacy: Address =>
682- invoke(legacy, "emit", [emitLpAmount], nil)
683- case _ =>
684- unit
685- }
686- if ((el == el))
687- then {
688- let sa = if ((amountDiff > 0))
689- then invoke(slippageContract, "put", nil, [AttachedPayment(fromBase58String(amountId), amountDiff)])
690- else nil
691- if ((sa == sa))
692- then {
693- let sp = if ((priceDiff > 0))
694- then invoke(slippageContract, "put", nil, [AttachedPayment(fromBase58String(priceId), priceDiff)])
695- else nil
696- if ((sp == sp))
697- then {
698- let lpTrasfer = if (autoStake)
699- then {
700- let ss = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmount)])
701- if ((ss == ss))
702- then nil
703- else throw("Strict value is not equal to itself.")
704- }
705- else [ScriptTransfer(i.caller, emitLpAmount, lpAssetId)]
706- (state ++ lpTrasfer)
707- }
708- else throw("Strict value is not equal to itself.")
709- }
710- else throw("Strict value is not equal to itself.")
711- }
712- else throw("Strict value is not equal to itself.")
713- }
714- else throw("Strict value is not equal to itself.")
715- }
716- else throw("Strict value is not equal to itself.")
717- }
718- }
719- else throw("Strict value is not equal to itself.")
632+ if (if (if (if ((0 >= slippage))
633+ then true
634+ else (0 >= amountAssetPart))
635+ then true
636+ else (0 >= priceAssetPart))
637+ then true
638+ else (0 >= outLp))
639+ then throwErr("Wrong params")
640+ else if ((size(i.payments) != 1))
641+ then throwErr("1 payment expected")
642+ else {
643+ let payment = value(i.payments[0])
644+ let paymentAssetId = toBase58String(value(payment.assetId))
645+ let paymentAmountRaw = payment.amount
646+ let $t02561725676 = takeFee(paymentAmountRaw)
647+ let paymentAmount = $t02561725676._1
648+ let feeAmount = $t02561725676._2
649+ if (if (if ((amountAssetPart > paymentAmount))
650+ then true
651+ else (priceAssetPart > paymentAmount))
652+ then true
653+ else (10000000 > paymentAmount))
654+ then throwErr("wrong payment amount")
655+ else {
656+ let amountBalance = getAccBalance(amountId)
657+ let priceBalance = getAccBalance(priceId)
658+ let $t02594026395 = if ((paymentAssetId == amountId))
659+ then $Tuple6((amountBalance - paymentAmount), priceBalance, (paymentAmount - amountAssetPart), priceAssetPart, 0, 0)
660+ else if ((paymentAssetId == priceId))
661+ then $Tuple6(amountBalance, (priceBalance - paymentAmount), 0, 0, (paymentAmount - priceAssetPart), amountAssetPart)
662+ else throwErr("wrong paymentAssetId")
663+ let amountBalanceNow = $t02594026395._1
664+ let priceBalanceNow = $t02594026395._2
665+ let virtSwapInAm = $t02594026395._3
666+ let virtSwapOutPr = $t02594026395._4
667+ let virtSwapInPr = $t02594026395._5
668+ let virtSwapOutAm = $t02594026395._6
669+ let D0 = invoke(gwxRewardContract, "calcD", [toString(amountBalanceNow), toString(priceBalanceNow), amplificator, Amult, Dconv], nil)
670+ let D1 = invoke(gwxRewardContract, "calcD", [toString(toBigInt(((amountBalanceNow + virtSwapInAm) - virtSwapOutAm))), toString(toBigInt(((priceBalanceNow + virtSwapInPr) - virtSwapOutPr))), amplificator, Amult, Dconv], nil)
671+ let D0vsD1 = validateD(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
672+ if ((D0vsD1 == D0vsD1))
673+ then {
674+ let estimatePut = commonPut(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(fromBase58String(amountId), amountAssetPart), AttachedPayment(fromBase58String(priceId), priceAssetPart), slippage, true, true, paymentAmount, paymentAssetId)
675+ let estimateLP = estimatePut._2
676+ let lpAssetId = estimatePut._7
677+ let state = estimatePut._9
678+ let amountDiff = estimatePut._10
679+ let priceDiff = estimatePut._11
680+ let lpCalcRes = validateAbsDiff(toBigInt(estimateLP), toBigInt(outLp), toBigInt(slippage))
681+ let emitLpAmount = toInt(lpCalcRes._2)
682+ let e = invoke(factoryContract, "emit", [emitLpAmount], nil)
683+ if ((e == e))
684+ then {
685+ let el = match e {
686+ case legacy: Address =>
687+ invoke(legacy, "emit", [emitLpAmount], nil)
688+ case _ =>
689+ unit
690+ }
691+ if ((el == el))
692+ then {
693+ let sa = if ((amountDiff > 0))
694+ then invoke(slippageContract, "put", nil, [AttachedPayment(fromBase58String(amountId), amountDiff)])
695+ else nil
696+ if ((sa == sa))
697+ then {
698+ let sp = if ((priceDiff > 0))
699+ then invoke(slippageContract, "put", nil, [AttachedPayment(fromBase58String(priceId), priceDiff)])
700+ else nil
701+ if ((sp == sp))
702+ then {
703+ let lpTrasfer = if (autoStake)
704+ then {
705+ let ss = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmount)])
706+ if ((ss == ss))
707+ then nil
708+ else throw("Strict value is not equal to itself.")
709+ }
710+ else [ScriptTransfer(i.caller, emitLpAmount, lpAssetId)]
711+ let sendFeeToMatcher = if ((feeAmount > 0))
712+ then [ScriptTransfer(matcherAddress, feeAmount, fromBase58String(paymentAssetId))]
713+ else nil
714+ ((state ++ lpTrasfer) ++ sendFeeToMatcher)
715+ }
716+ else throw("Strict value is not equal to itself.")
717+ }
718+ else throw("Strict value is not equal to itself.")
719+ }
720+ else throw("Strict value is not equal to itself.")
721+ }
722+ else throw("Strict value is not equal to itself.")
723+ }
724+ else throw("Strict value is not equal to itself.")
725+ }
726+ }
720727 }
721728
722729
723730
724731 @Callable(i)
725732 func putForFree (maxslippage) = if ((0 > maxslippage))
726733 then throwErr("wrong slippage")
727734 else if ((size(i.payments) != 2))
728735 then throwErr("2 payments expected")
729736 else {
730737 let estimatePut = commonPut(toString(i.caller), toBase58String(i.transactionId), AttachedPayment(value(i.payments[0]).assetId, value(i.payments[0]).amount), i.payments[1], maxslippage, false, false, 0, "")
731738 estimatePut._9
732739 }
733740
734741
735742
736743 @Callable(i)
737744 func get () = {
738745 let r = commonGet(i)
739746 let outAmtAmt = r._1
740747 let outPriceAmount = r._2
741748 let paymentAmount = r._3
742749 let paymentAssetId = r._4
743750 let state = r._5
744751 let b = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
745752 if ((b == b))
746753 then state
747754 else throw("Strict value is not equal to itself.")
748755 }
749756
750757
751758
752759 @Callable(i)
753760 func getOneTkn (exchResult,notUsed,outAmount,outAssetId,slippage) = if ((size(i.payments) != 1))
754761 then throwErr("1 payment expected")
755762 else {
756763 let cfg = getPoolConfig()
757764 let lpAssetId = cfg[idxLPAsId]
758765 let amountId = cfg[idxAmAsId]
759766 let priceId = cfg[idxPrAsId]
760767 let amountDecimals = parseIntValue(cfg[idxAmtAsDcm])
761768 let priceDecimals = parseIntValue(cfg[idxPriceAsDcm])
762769 let sts = cfg[idxPoolSt]
763770 let factCfg = getFactoryConfig()
764771 let gwxRewardContract = valueOrErrorMessage(addressFromString(factCfg[idxFactGwxRewCntr]), "Wrong gwxRewardContract address")
765772 let payment = value(i.payments[0])
766773 let addon = valueOrElse(getString(this, keyAddonAddress()), "")
767774 let userAddress = if ((addon == toString(i.caller)))
768775 then i.originCaller
769776 else i.caller
770777 let txId58 = toBase58String(i.transactionId)
771778 let paymentAssetId = value(payment.assetId)
772779 let paymentAmount = payment.amount
773- let addonContract = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(keyAddonAddress()), "no addons")), "addon address in not valid")
774- let check = reentrantInvoke(addonContract, "ensureCanGetOneTkn", [toString(userAddress)], nil)
775- if ((check == check))
776- then if ((1000000000 > paymentAmount))
777- then throwErr("Min payment 10 LP")
778- else if (if (if ((0 > slippage))
779- then true
780- else (0 > exchResult))
781- then true
782- else (0 > outAmount))
783- then throwErr("Wrong params")
784- else if ((lpAssetId != toBase58String(paymentAssetId)))
785- then throwErr("Wrong LP")
786- else {
787- let r = estimateGetOperation(toBase58String(i.transactionId), toBase58String(paymentAssetId), paymentAmount, i.caller)
788- let estimAmAmt = r._1
789- let estimPrAmt = r._2
790- let amountBalance = getAccBalance(amountId)
791- let priceBalance = getAccBalance(priceId)
792- let $t03176632234 = if ((outAssetId == amountId))
793- then $Tuple7((amountBalance - estimAmAmt), (priceBalance - estimPrAmt), exchResult, estimPrAmt, 0, 0, (estimAmAmt + exchResult))
794- else if ((outAssetId == priceId))
795- then $Tuple7((amountBalance - estimAmAmt), (priceBalance - estimPrAmt), 0, 0, exchResult, estimAmAmt, (estimPrAmt + exchResult))
796- else throwErr("wrong outAssetId")
797- let amountBalanceNow = $t03176632234._1
798- let priceBalanceNow = $t03176632234._2
799- let virtSwapInAm = $t03176632234._3
800- let virtSwapOutPr = $t03176632234._4
801- let virtSwapInPr = $t03176632234._5
802- let virtSwapOutAm = $t03176632234._6
803- let totalGet = $t03176632234._7
804- if (if ((0 > virtSwapInAm))
805- then true
806- else (0 > virtSwapInPr))
807- then throwErr("Wrong calc")
808- else {
809- let D0 = invoke(gwxRewardContract, "calcD", [toString(amountBalanceNow), toString(priceBalanceNow), amplificator, Amult, Dconv], nil)
810- let D1 = invoke(gwxRewardContract, "calcD", [toString(((amountBalanceNow - virtSwapInAm) + virtSwapOutAm)), toString(((priceBalanceNow + virtSwapOutPr) - virtSwapInPr)), amplificator, Amult, Dconv], nil)
811- let D0vsD1 = validateD(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
812- if ((D0vsD1 == D0vsD1))
813- then {
814- let finalRes = validateAbsDiff(toBigInt(totalGet), toBigInt(outAmount), toBigInt(slippage))
815- if ((finalRes == finalRes))
816- then {
817- let $t03290333011 = if ((outAssetId == amountId))
818- then $Tuple2(toInt(finalRes._2), 0)
819- else $Tuple2(0, toInt(finalRes._2))
820- let outAm = $t03290333011._1
821- let outPr = $t03290333011._2
822- let decimals = if ((amountDecimals >= priceDecimals))
823- then amountDecimals
824- else priceDecimals
825- if ((decimals == decimals))
826- then {
827- let curPrX18 = calcPriceBigInt(toX18(priceBalance, decimals), toX18(amountBalance, decimals))
828- let curPr = fromX18(curPrX18, scale8)
829- let state = [ScriptTransfer(userAddress, (outAm + outPr), if ((outAssetId == "WAVES"))
830- then unit
831- else fromBase58String(outAssetId)), StringEntry(keyGetActionByUser(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, paymentAmount, curPr, height, lastBlock.timestamp)), IntegerEntry(keyPriceLast(), curPr), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), curPr)]
832- if ((state == state))
833- then {
834- let burn = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
835- if ((burn == burn))
836- then state
837- else throw("Strict value is not equal to itself.")
838- }
839- else throw("Strict value is not equal to itself.")
840- }
841- else throw("Strict value is not equal to itself.")
842- }
843- else throw("Strict value is not equal to itself.")
844- }
845- else throw("Strict value is not equal to itself.")
846- }
847- }
848- else throw("Strict value is not equal to itself.")
780+ if ((1000000000 > paymentAmount))
781+ then throwErr("Min payment 10 LP")
782+ else if (if (if ((0 > slippage))
783+ then true
784+ else (0 > exchResult))
785+ then true
786+ else (0 > outAmount))
787+ then throwErr("Wrong params")
788+ else if ((lpAssetId != toBase58String(paymentAssetId)))
789+ then throwErr("Wrong LP")
790+ else {
791+ let r = estimateGetOperation(toBase58String(i.transactionId), toBase58String(paymentAssetId), paymentAmount, i.caller)
792+ let estimAmAmt = r._1
793+ let estimPrAmt = r._2
794+ let amountBalance = getAccBalance(amountId)
795+ let priceBalance = getAccBalance(priceId)
796+ let $t03153432002 = if ((outAssetId == amountId))
797+ then $Tuple7((amountBalance - estimAmAmt), (priceBalance - estimPrAmt), exchResult, estimPrAmt, 0, 0, (estimAmAmt + exchResult))
798+ else if ((outAssetId == priceId))
799+ then $Tuple7((amountBalance - estimAmAmt), (priceBalance - estimPrAmt), 0, 0, exchResult, estimAmAmt, (estimPrAmt + exchResult))
800+ else throwErr("wrong outAssetId")
801+ let amountBalanceNow = $t03153432002._1
802+ let priceBalanceNow = $t03153432002._2
803+ let virtSwapInAm = $t03153432002._3
804+ let virtSwapOutPr = $t03153432002._4
805+ let virtSwapInPr = $t03153432002._5
806+ let virtSwapOutAm = $t03153432002._6
807+ let totalGet = $t03153432002._7
808+ if (if ((0 > virtSwapInAm))
809+ then true
810+ else (0 > virtSwapInPr))
811+ then throwErr("Wrong calc")
812+ else {
813+ let D0 = invoke(gwxRewardContract, "calcD", [toString(amountBalanceNow), toString(priceBalanceNow), amplificator, Amult, Dconv], nil)
814+ let D1 = invoke(gwxRewardContract, "calcD", [toString(((amountBalanceNow - virtSwapInAm) + virtSwapOutAm)), toString(((priceBalanceNow + virtSwapOutPr) - virtSwapInPr)), amplificator, Amult, Dconv], nil)
815+ let D0vsD1 = validateD(parseBigIntValue(str(D1)), parseBigIntValue(str(D0)), slippage4D)
816+ if ((D0vsD1 == D0vsD1))
817+ then {
818+ let finalRes = validateAbsDiff(toBigInt(totalGet), toBigInt(outAmount), toBigInt(slippage))
819+ if ((finalRes == finalRes))
820+ then {
821+ let $t03267132779 = if ((outAssetId == amountId))
822+ then $Tuple2(toInt(finalRes._2), 0)
823+ else $Tuple2(0, toInt(finalRes._2))
824+ let outAm = $t03267132779._1
825+ let outPr = $t03267132779._2
826+ let totalAmountRaw = (outAm + outPr)
827+ let $t03281932874 = takeFee(totalAmountRaw)
828+ let totalAmount = $t03281932874._1
829+ let feeAmount = $t03281932874._2
830+ let outAssetIdOrWaves = if ((outAssetId == "WAVES"))
831+ then unit
832+ else fromBase58String(outAssetId)
833+ let sendFeeToMatcher = if ((feeAmount > 0))
834+ then [ScriptTransfer(matcherAddress, feeAmount, outAssetIdOrWaves)]
835+ else nil
836+ let decimals = if ((amountDecimals >= priceDecimals))
837+ then amountDecimals
838+ else priceDecimals
839+ if ((decimals == decimals))
840+ then {
841+ let curPrX18 = calcPriceBigInt(toX18(priceBalance, decimals), toX18(amountBalance, decimals))
842+ let curPr = fromX18(curPrX18, scale8)
843+ let state = [ScriptTransfer(userAddress, totalAmount, outAssetIdOrWaves), StringEntry(keyGetActionByUser(toString(userAddress), txId58), dataGetActionInfo(outAm, outPr, paymentAmount, curPr, height, lastBlock.timestamp)), IntegerEntry(keyPriceLast(), curPr), IntegerEntry(keyPriceHistory(height, lastBlock.timestamp), curPr)]
844+ if ((state == state))
845+ then {
846+ let burn = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
847+ if ((burn == burn))
848+ then (state ++ sendFeeToMatcher)
849+ else throw("Strict value is not equal to itself.")
850+ }
851+ else throw("Strict value is not equal to itself.")
852+ }
853+ else throw("Strict value is not equal to itself.")
854+ }
855+ else throw("Strict value is not equal to itself.")
856+ }
857+ else throw("Strict value is not equal to itself.")
858+ }
859+ }
849860 }
850861
851862
852863
853864 @Callable(i)
854865 func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = {
855866 let r = commonGet(i)
856867 let outAmountAmount = r._1
857868 let outPriceAmount = r._2
858869 let paymentAmount = r._3
859870 let paymentAssetId = r._4
860871 let state = r._5
861872 let checkOutAmountAmount = if ((outAmountAmount >= noLessThenAmtAsset))
862873 then true
863874 else throwErr(((("Failed: " + toString(outAmountAmount)) + " < ") + toString(noLessThenAmtAsset)))
864875 if ((checkOutAmountAmount == checkOutAmountAmount))
865876 then {
866877 let checkOutPriceAmount = if ((outPriceAmount >= noLessThenPriceAsset))
867878 then true
868879 else throwErr(((("Failed: " + toString(outPriceAmount)) + " < ") + toString(noLessThenPriceAsset)))
869880 if ((checkOutPriceAmount == checkOutPriceAmount))
870881 then {
871882 let burnLPAssetOnFactory = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)])
872883 if ((burnLPAssetOnFactory == burnLPAssetOnFactory))
873884 then state
874885 else throw("Strict value is not equal to itself.")
875886 }
876887 else throw("Strict value is not equal to itself.")
877888 }
878889 else throw("Strict value is not equal to itself.")
879890 }
880891
881892
882893
883894 @Callable(i)
884895 func unstakeAndGet (amount) = {
885896 let checkPayments = if ((size(i.payments) != 0))
886897 then throwErr("no payments expected")
887898 else true
888899 if ((checkPayments == checkPayments))
889900 then {
890901 let cfg = getPoolConfig()
891902 let factoryCfg = getFactoryConfig()
892903 let lpAssetId = fromBase58String(cfg[idxLPAsId])
893904 let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "wrong")
894905 let unstakeInv = invoke(staking, "unstake", [toBase58String(lpAssetId), amount], nil)
895906 if ((unstakeInv == unstakeInv))
896907 then {
897908 let r = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller)
898909 let sts = parseIntValue(r._9)
899910 let state = r._10
900911 let v = if (if (isGlobalShutdown())
901912 then true
902913 else (sts == PoolShutdown))
903914 then throwErr(("Blocked: " + toString(sts)))
904915 else true
905916 if ((v == v))
906917 then {
907918 let burnA = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)])
908919 if ((burnA == burnA))
909920 then state
910921 else throw("Strict value is not equal to itself.")
911922 }
912923 else throw("Strict value is not equal to itself.")
913924 }
914925 else throw("Strict value is not equal to itself.")
915926 }
916927 else throw("Strict value is not equal to itself.")
917928 }
918929
919930
920931
921932 @Callable(i)
922933 func activate (amtAsStr,prAsStr) = if ((toString(i.caller) != toString(factoryContract)))
923934 then throwErr("denied")
924935 else $Tuple2([StringEntry(keyAmountAsset(), amtAsStr), StringEntry(keyPriceAsset(), prAsStr)], "success")
925936
926937
927938
928939 @Callable(i)
929940 func setS (k,v) = if ((toString(i.caller) != getStringOrFail(this, keyAddonAddress())))
930941 then pd
931942 else [StringEntry(k, v)]
932943
933944
934945
935946 @Callable(i)
936947 func setI (k,v) = if ((toString(i.caller) != getStringOrFail(this, keyAddonAddress())))
937948 then pd
938949 else [IntegerEntry(k, v)]
939950
940951
941952
942953 @Callable(i)
943954 func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig())
944955
945956
946957
947958 @Callable(i)
948959 func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId))
949960
950961
951962
952963 @Callable(i)
953964 func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = {
954965 let pr = calcPrices(amAmt, prAmt, lpAmt)
955966 $Tuple2(nil, [toString(pr[0]), toString(pr[1]), toString(pr[2])])
956967 }
957968
958969
959970
960971 @Callable(i)
961972 func fromX18WrapperREADONLY (val,resScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resScaleMult))
962973
963974
964975
965976 @Callable(i)
966977 func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult)))
967978
968979
969980
970981 @Callable(i)
971982 func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18))))
972983
973984
974985
975986 @Callable(i)
976987 func estimatePutOperationWrapperREADONLY (txId58,slippage,inAmountAssetAmount,inAmId,inPriceAssetAmount,inPrId,usrAddr,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippage, inAmountAssetAmount, inAmId, inPriceAssetAmount, inPrId, usrAddr, isEvaluate, emitLp, false, 0, ""))
977988
978989
979990
980991 @Callable(i)
981992 func estimateGetOperationWrapperREADONLY (txId58,paymentAsId,paymentLpAmount,usrAddr) = {
982993 let r = estimateGetOperation(txId58, paymentAsId, paymentLpAmount, addressFromStringValue(usrAddr))
983994 $Tuple2(nil, $Tuple10(r._1, r._2, r._3, r._4, r._5, r._6, r._7, toString(r._8), r._9, r._10))
984995 }
985996
986997
987998 @Verifier(tx)
988999 func verify () = match tx {
9891000 case order: Order =>
9901001 let mtchPub = getMatcherPubOrFail()
9911002 let orV = validateMatcherOrderAllowed(order)
9921003 let sndrV = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey)
9931004 let mtchV = sigVerify(order.bodyBytes, order.proofs[1], mtchPub)
9941005 if (if (if (orV)
9951006 then sndrV
9961007 else false)
9971008 then mtchV
9981009 else false)
9991010 then true
10001011 else throwOrderError(orV, sndrV, mtchV)
10011012 case _ =>
10021013 let targetPublicKey = match managerPublicKeyOrUnit() {
10031014 case pk: ByteVector =>
10041015 pk
10051016 case _: Unit =>
10061017 tx.senderPublicKey
10071018 case _ =>
10081019 throw("Match error")
10091020 }
10101021 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
10111022 }
10121023

github/deemru/w8io/026f985 
111.86 ms