tx · CR7HYJ2SYBv3L3H1UrJryGEYv4bsidURs2RcTwyud9yL

3P5fnEVxY8DFCNqfigRqFJRCjBAUbpP6Rr4:  -0.01400000 Waves

2021.05.06 14:13 [2578395] smart account 3P5fnEVxY8DFCNqfigRqFJRCjBAUbpP6Rr4 > SELF 0.00000000 Waves

{ "type": 13, "id": "CR7HYJ2SYBv3L3H1UrJryGEYv4bsidURs2RcTwyud9yL", "fee": 1400000, "feeAssetId": null, "timestamp": 1620299629947, "version": 1, "sender": "3P5fnEVxY8DFCNqfigRqFJRCjBAUbpP6Rr4", "senderPublicKey": "3Bb6XrvrXqjKXcBrLrLXbbA95A1voNpDuejTkSrYGuQs", "proofs": [ "66nqyWuQhVvuNZbbErRqKAtJEDxLFcTFpsnRsYmzaRCfS17ks84ZGPASwgPExVnuVVftfCgk8XXH6pQKg6inLJE4" ], "script": "base64:AAIEAAAAAAAAABMIAhIAEgASBAoCCAgSABIDCgEIAAAAdwEAAAARa2V5QWNjdW11bGF0ZWRGZWUAAAAAAgAAABIlc19fYWNjdW11bGF0ZWRGZWUBAAAAGWtleUFjY3VtdWxhdGVkUHJvdG9jb2xGZWUAAAAAAgAAABolc19fYWNjdW11bGF0ZWRQcm90b2NvbEZlZQEAAAAOa2V5VWNvbGxhdGVyYWwAAAAAAgAAAA8lc19fdWNvbGxhdGVyYWwBAAAAGWtleVRvdGFsTGVuZGVkQXRPdGhlckFjY3MAAAAAAgAAABolc19fdG90YWxMZW5kZWRBdE90aGVyQWNjcwEAAAATa2V5QXNzZXRMb2NrZWRUb3RhbAAAAAEAAAAHYXNzZXRJZAkAASwAAAACAgAAABglcyVzX19hc3NldExvY2tlZFRvdGFsX18FAAAAB2Fzc2V0SWQBAAAAE2tleUFjY291bnRPcGVyYXRpb24AAAADAAAADHVubG9ja0hlaWdodAAAAAdhZGRyZXNzAAAABnN0YXR1cwkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAHiVzJXMlZCVzX19kZWZvQXNzZXRPcGVyYXRpb25fXwUAAAAHYWRkcmVzcwIAAAACX18JAAGkAAAAAQUAAAAMdW5sb2NrSGVpZ2h0AgAAAAJfXwUAAAAGc3RhdHVzAQAAAAprZXlGYWN0b3J5AAAAAAIAAAALJXNfX2ZhY3RvcnkBAAAAGmtleUxlbmRlZEFtb3VudEJ5QXNzZXRDb2RlAAAAAQAAAAlhc3NldENvZGUJAAEsAAAAAgIAAAAdJXMlc19fbGVuZGVkQmFzZUFzc2V0QW1vdW50X18FAAAACWFzc2V0Q29kZQEAAAAIa2V5UHJpY2UAAAABAAAACWFzc2V0Q29kZQkAASwAAAACAgAAAA0lcyVzX19wcmljZV9fBQAAAAlhc3NldENvZGUBAAAAFGtleUNvbnRyb2xMYXN0SGVpZ2h0AAAAAQAAAAlhc3NldENvZGUJAAEsAAAAAgIAAAASJXMlc19fbGFzdEhlaWdodF9fBQAAAAlhc3NldENvZGUAAAAAFElkeE9wZXJhdGlvbkFtb3VudEluAAAAAAAAAAABAAAAABNJZHhPcGVyYXRpb25Bc3NldEluAAAAAAAAAAACAAAAABFJZHhPcGVyYXRpb25QcmljZQAAAAAAAAAAAwAAAAAVSWR4T3BlcmF0aW9uQW1vdW50T3V0AAAAAAAAAAAEAAAAABRJZHhPcGVyYXRpb25Bc3NldE91dAAAAAAAAAAABQEAAAAWYXNzZXREYXRhU3dhcE9wZXJhdGlvbgAAAAgAAAAIYW1vdW50SW4AAAAHYXNzZXRJbgAAAAVwcmljZQAAAAlhbW91bnRPdXQAAAAIYXNzZXRPdXQAAAAMYnJ1dHRvQW1vdW50AAAACWZlZUFtb3VudAAAABFwcm90b2NvbEZlZUFtb3VudAkABLkAAAACCQAETAAAAAICAAAAECVkJXMlZCVzJWQlZCVkJWQJAARMAAAAAgkAAaQAAAABBQAAAAhhbW91bnRJbgkABEwAAAACBQAAAAdhc3NldEluCQAETAAAAAIJAAGkAAAAAQUAAAAJYW1vdW50T3V0CQAETAAAAAIFAAAACGFzc2V0T3V0CQAETAAAAAIJAAGkAAAAAQUAAAAFcHJpY2UJAARMAAAAAgkAAaQAAAABBQAAAAxicnV0dG9BbW91bnQJAARMAAAAAgkAAaQAAAABBQAAAAlmZWVBbW91bnQJAARMAAAAAgkAAaQAAAABBQAAABFwcm90b2NvbEZlZUFtb3VudAUAAAADbmlsAgAAAAJfXwEAAAAXYXNzZXREYXRhUmViYWxhbmNlVHJhY2UAAAAFAAAAD2RlYnRvckFzc2V0Q29kZQAAAAdkZWJ0UG10AAAAB2Jhc2VQbXQAAAAPbGVuZGVkQW10QmVmb3JlAAAADmxlbmRlZEFtdEFmdGVyCQAEuQAAAAIJAARMAAAAAgIAAAAOJXMlcyVkJXMlZCVkJWQJAARMAAAAAgUAAAAPZGVidG9yQXNzZXRDb2RlCQAETAAAAAIJAAJYAAAAAQkBAAAABXZhbHVlAAAAAQgFAAAAB2RlYnRQbXQAAAAHYXNzZXRJZAkABEwAAAACCQABpAAAAAEIBQAAAAdkZWJ0UG10AAAABmFtb3VudAkABEwAAAACCQACWAAAAAEJAQAAAAV2YWx1ZQAAAAEIBQAAAAdiYXNlUG10AAAAB2Fzc2V0SWQJAARMAAAAAgkAAaQAAAABCAUAAAAHYmFzZVBtdAAAAAZhbW91bnQJAARMAAAAAgkAAaQAAAABBQAAAA9sZW5kZWRBbXRCZWZvcmUJAARMAAAAAgkAAaQAAAABBQAAAA5sZW5kZWRBbXRBZnRlcgUAAAADbmlsAgAAAAJfXwEAAAAcYXNzZXRSZWFkU3dhcERhdGFBcnJheU9yRmFpbAAAAAEAAAAPYWNjT3BlcmF0aW9uS2V5BAAAABNhY2NPcGVyYXRpb25EYXRhU3RyCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwUAAAAPYWNjT3BlcmF0aW9uS2V5CQABLAAAAAICAAAAKlRoZXJlIGlzIG5vIHJlcXVlc3QgZm9yIHBhc3NlZCBhcmd1bWVudHM6IAUAAAAPYWNjT3BlcmF0aW9uS2V5CQAEtQAAAAIFAAAAE2FjY09wZXJhdGlvbkRhdGFTdHICAAAAAl9fAAAAAAdudWxsSW50AP//////////AAAAAAdudWxsU3RyAgAAAAROVUxMAAAAAApmYWN0b3J5QWNjCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAEdGhpcwkBAAAACmtleUZhY3RvcnkAAAAACQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABJObyBjb25maWcgYXQgdGhpcz0JAAQlAAAAAQUAAAAEdGhpcwIAAAAJIGZvciBrZXk9CQEAAAAKa2V5RmFjdG9yeQAAAAABAAAAJGtleUZhY3RvcnlOZXV0cmlub0NvbnRyYWN0QWRkcmVzc0tleQAAAAACAAAAKyVzJXNfX2NvbW1vbkNvbmZpZ19fbmV1dHJpbm9Db250cmFjdEFkZHJlc3MBAAAAFWtleUZhY3RvcnlEZWJ0QXNzZXRJZAAAAAACAAAAHyVzJXNfX2NvbW1vbkNvbmZpZ19fZGVidEFzc2V0SWQBAAAAIGtleUZhY3RvcnlEZWJ0QXNzZXRFdGFsb25CYWxhbmNlAAAAAAIAAAAqJXMlc19fY29tbW9uQ29uZmlnX19kZWJ0QXNzZXRFdGFsb25CYWxhbmNlAQAAABJrZXlGYWN0b3J5QXNzZXRDZmcAAAABAAAAD2Fzc2V0QWRkcmVzc1N0cgkAASwAAAACCQABLAAAAAICAAAAEyVzJXMlc19fZGVmb0Fzc2V0X18FAAAAD2Fzc2V0QWRkcmVzc1N0cgIAAAAIX19jb25maWcBAAAAGmtleUZhY3RvcnlBc3NldEN1cnJlbnRQb29sAAAAAQAAAA9hc3NldEFjY0FkZHJlc3MJAAEsAAAAAgkAASwAAAACAgAAABMlcyVzJXNfX2RlZm9Bc3NldF9fCQAEJQAAAAEFAAAAD2Fzc2V0QWNjQWRkcmVzcwIAAAANX19jdXJyZW50UG9vbAEAAAAga2V5RmFjdG9yeURlZm9BZGRyZXNzQnlBc3NldENvZGUAAAABAAAACWFzc2V0Q29kZQkAASwAAAACCQABLAAAAAICAAAAEyVzJXMlc19fZGVmb0Fzc2V0X18FAAAACWFzc2V0Q29kZQIAAAAUX19hZGRyZXNzQnlBc3NldENvZGUBAAAAGWtleUZhY3RvcnlBc3NldFBvb2xNYWtlcnMAAAABAAAADGFzc2V0QWRkcmVzcwkAASwAAAACCQABLAAAAAICAAAAEyVzJXMlc19fZGVmb0Fzc2V0X18FAAAADGFzc2V0QWRkcmVzcwIAAAAMX19wb29sTWFrZXJzAQAAACFrZXlGYWN0b3J5RGVmb1N0YWtpbmdQYWNlbWFrZXJQdWIAAAAAAgAAACslcyVzX19jb21tb25Db25maWdfX2RlZm9TdGFraW5nUGFjZW1ha2VyUHViAQAAACNrZXlGYWN0b3J5UG9vbE1ha2VyTGlxdWlkaXR5UmVxdWVzdAAAAAMAAAAMYXNzZXRBZGRyZXNzAAAAEHBvb2xNYWtlckFkZHJlc3MAAAABaAkABLkAAAACCQAETAAAAAICAAAAECVzJXMlcyVkJXNfX3Bvb2wJAARMAAAAAgUAAAAMYXNzZXRBZGRyZXNzCQAETAAAAAIFAAAAEHBvb2xNYWtlckFkZHJlc3MJAARMAAAAAgkAAaQAAAABBQAAAAFoCQAETAAAAAICAAAAEGxpcXVpZGl0eVJlcXVlc3QFAAAAA25pbAIAAAACX18BAAAAH2tleUZhY3RvcnlQb29sTWFrZXJVbmxvY2tIZWlnaHQAAAACAAAADGFzc2V0QWRkcmVzcwAAABBwb29sTWFrZXJBZGRyZXNzCQAEuQAAAAIJAARMAAAAAgIAAAAOJXMlcyVzJXNfX3Bvb2wJAARMAAAAAgUAAAAMYXNzZXRBZGRyZXNzCQAETAAAAAIFAAAAEHBvb2xNYWtlckFkZHJlc3MJAARMAAAAAgIAAAAMdW5sb2NrSGVpZ2h0BQAAAANuaWwCAAAAAl9fAQAAABZmYWN0b3J5UmVhZERlYnRBc3NldElkAAAAAAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAACmZhY3RvcnlBY2MJAQAAABVrZXlGYWN0b3J5RGVidEFzc2V0SWQAAAAACQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABVObyBjb25maWcgYXQgZmFjdG9yeT0JAAQlAAAAAQUAAAAKZmFjdG9yeUFjYwIAAAAJIGZvciBrZXk9CQEAAAAVa2V5RmFjdG9yeURlYnRBc3NldElkAAAAAAEAAAAcZmFjdG9yeVJlYWRBc3NldENmZ0J5QWRkcmVzcwAAAAEAAAAPYXNzZXRBZGRyZXNzU3RyCQAEtQAAAAIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAApmYWN0b3J5QWNjCQEAAAASa2V5RmFjdG9yeUFzc2V0Q2ZnAAAAAQUAAAAPYXNzZXRBZGRyZXNzU3RyCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABVObyBjb25maWcgYXQgZmFjdG9yeT0JAAQlAAAAAQUAAAAKZmFjdG9yeUFjYwIAAAAJIGZvciBrZXk9CQEAAAASa2V5RmFjdG9yeUFzc2V0Q2ZnAAAAAQUAAAAPYXNzZXRBZGRyZXNzU3RyAgAAAAJfXwEAAAAZZmFjdG9yeVJlYWRBc3NldENmZ0J5Q29kZQAAAAEAAAAJYXNzZXRDb2RlBAAAAA9hc3NldEFkZHJlc3NTdHIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAApmYWN0b3J5QWNjCQEAAAAga2V5RmFjdG9yeURlZm9BZGRyZXNzQnlBc3NldENvZGUAAAABBQAAAAlhc3NldENvZGUJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAFU5vIGNvbmZpZyBhdCBmYWN0b3J5PQkABCUAAAABBQAAAApmYWN0b3J5QWNjAgAAAAkgZm9yIGtleT0JAQAAACBrZXlGYWN0b3J5RGVmb0FkZHJlc3NCeUFzc2V0Q29kZQAAAAEFAAAACWFzc2V0Q29kZQkABRQAAAACBQAAAA9hc3NldEFkZHJlc3NTdHIJAQAAABxmYWN0b3J5UmVhZEFzc2V0Q2ZnQnlBZGRyZXNzAAAAAQUAAAAPYXNzZXRBZGRyZXNzU3RyAQAAACdmYWN0b3J5UmVhZE5leHRQb29sTWFrZXJUb0Rpc3RyaWJ1dGVGZWUAAAABAAAAD2Fzc2V0QWRkcmVzc1N0cgkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQIAAAAjM1BFczE5YnY0cVQ0R3o1aWRqY1d5bmtReXJIOXBzR2lwbXcBAAAAImZhY3RvcnlSZWFkRGVmb1N0YWtpbmdQYWNlbWFrZXJQdWIAAAAACQACWQAAAAEJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAApmYWN0b3J5QWNjCQEAAAAha2V5RmFjdG9yeURlZm9TdGFraW5nUGFjZW1ha2VyUHViAAAAAAkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAVTm8gY29uZmlnIGF0IGZhY3Rvcnk9CQAEJQAAAAEFAAAACmZhY3RvcnlBY2MCAAAACSBmb3Iga2V5PQkBAAAAIWtleUZhY3RvcnlEZWZvU3Rha2luZ1BhY2VtYWtlclB1YgAAAAAAAAAAEElkeERlZm9Bc3NldENvZGUAAAAAAAAAAAEAAAAADklkeERlZm9Bc3NldElkAAAAAAAAAAACAAAAABJJZHhEZWZvQXNzZXRTdGF0dXMAAAAAAAAAAAMAAAAAEElkeFByaWNlRGVjaW1hbHMAAAAAAAAAAAQAAAAADklkeEJhc2VBc3NldElkAAAAAAAAAAAFAAAAABhJZHhPdmVyQ29sbGF0ZXJhbFBlcmNlbnQAAAAAAAAAAAYAAAAADklkeE1pbkluaXRQb29sAAAAAAAAAAAHAAAAABVJZHhQcmljZU9yYWNsZUFkZHJlc3MAAAAAAAAAAAgAAAAAEElkeE1pbkJ1eVBheW1lbnQAAAAAAAAAAAkAAAAAEUlkeE1pblNlbGxQYXltZW50AAAAAAAAAAAKAAAAABJJZHhCdXlMb2NrSW50ZXJ2YWwAAAAAAAAAAAsAAAAAE0lkeFNlbGxMb2NrSW50ZXJ2YWwAAAAAAAAAAAwAAAAAEElkeEJ1eUZlZVBlcmNlbnQAAAAAAAAAAA0AAAAAEUlkeFNlbGxGZWVQZXJjZW50AAAAAAAAAAAOAAAAABhJZHhQb29sUmVkZW1wdGlvblRpbWVvdXQAAAAAAAAAAA8AAAAAIUlkeFdlZWtlbmRzUHJpY2VDaGFuZ2VDb2VmZmljaWVudAAAAAAAAAAAEAAAAAAYSWR4QXNzZXRBY2NvdW50UHVibGljU3RyAAAAAAAAAAARAAAAACBJZHhBc3NldFN0YWtpbmdSZWZlcnJhbFB1YmxpY1N0cgAAAAAAAAAAEgAAAAAbSWR4Q3Jvc3NFeGNoYW5nZUNvZWZmaWNpZW50AAAAAAAAAAATAAAAACNJZHhTdGFraW5nTWluQW10RnJvbVNlbGxDb2VmZmljaWVudAAAAAAAAAAAFAAAAAAXSWR4UG9vbFN0YWJpbGl0eUZlZVBhcnQAAAAAAAAAABUAAAAAFUlkeFByb3RvY29sRmVlUGVyY2VudAAAAAAAAAAAFgAAAAAMdGhpc0NmZ0FycmF5CQEAAAAcZmFjdG9yeVJlYWRBc3NldENmZ0J5QWRkcmVzcwAAAAEJAAQlAAAAAQUAAAAEdGhpcwAAAAANZGVmb0Fzc2V0Q29kZQkAAZEAAAACBQAAAAx0aGlzQ2ZnQXJyYXkFAAAAEElkeERlZm9Bc3NldENvZGUAAAAADmRlZm9Bc3NldElkU3RyCQABkQAAAAIFAAAADHRoaXNDZmdBcnJheQUAAAAOSWR4RGVmb0Fzc2V0SWQAAAAAC2RlZm9Bc3NldElkCQACWQAAAAEFAAAADmRlZm9Bc3NldElkU3RyAAAAAA5wcmljZU9yYWNsZUFjYwkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkAAZEAAAACBQAAAAx0aGlzQ2ZnQXJyYXkFAAAAFUlkeFByaWNlT3JhY2xlQWRkcmVzcwAAAAAVb3ZlckNvbGxhdGVyYWxQZXJjZW50CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAABhJZHhPdmVyQ29sbGF0ZXJhbFBlcmNlbnQAAAAADmJhc2VBc3NldElkU3RyCQABkQAAAAIFAAAADHRoaXNDZmdBcnJheQUAAAAOSWR4QmFzZUFzc2V0SWQAAAAAC2Jhc2VBc3NldElkCQACWQAAAAEFAAAADmJhc2VBc3NldElkU3RyAAAAAA1wcmljZURlY2ltYWxzCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAABBJZHhQcmljZURlY2ltYWxzAAAAABFtaW5CYXNpY0J1eUFtb3VudAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAADHRoaXNDZmdBcnJheQUAAAAQSWR4TWluQnV5UGF5bWVudAAAAAASbWluU3ludGhTZWxsQW1vdW50CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAABFJZHhNaW5TZWxsUGF5bWVudAAAAAAPYnV5TG9ja0ludGVydmFsCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAABJJZHhCdXlMb2NrSW50ZXJ2YWwAAAAAEHNlbGxMb2NrSW50ZXJ2YWwJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAx0aGlzQ2ZnQXJyYXkFAAAAE0lkeFNlbGxMb2NrSW50ZXJ2YWwAAAAADWJ1eUZlZVBlcmNlbnQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAx0aGlzQ2ZnQXJyYXkFAAAAEElkeEJ1eUZlZVBlcmNlbnQAAAAADnNlbGxGZWVQZXJjZW50CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAABFJZHhTZWxsRmVlUGVyY2VudAAAAAAed2Vla2VuZHNQcmljZUNoYW5nZUNvZWZmaWNpZW50CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAACFJZHhXZWVrZW5kc1ByaWNlQ2hhbmdlQ29lZmZpY2llbnQAAAAAFWFzc2V0QWNjb3VudFB1YmxpY1N0cgkAAZEAAAACBQAAAAx0aGlzQ2ZnQXJyYXkFAAAAGElkeEFzc2V0QWNjb3VudFB1YmxpY1N0cgAAAAAdYXNzZXRTdGFraW5nUmVmZXJyYWxQdWJsaWNTdHIJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAACBJZHhBc3NldFN0YWtpbmdSZWZlcnJhbFB1YmxpY1N0cgAAAAAYY3Jvc3NFeGNoYW5nZUNvZWZmaWNpZW50CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAABtJZHhDcm9zc0V4Y2hhbmdlQ29lZmZpY2llbnQAAAAAIHN0YWtpbmdNaW5BbXRGcm9tU2VsbENvZWZmaWNpZW50CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAACNJZHhTdGFraW5nTWluQW10RnJvbVNlbGxDb2VmZmljaWVudAAAAAAUcG9vbFN0YWJpbGl0eUZlZVBhcnQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAx0aGlzQ2ZnQXJyYXkFAAAAF0lkeFBvb2xTdGFiaWxpdHlGZWVQYXJ0AAAAABJwcm90b2NvbEZlZVBlcmNlbnQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAx0aGlzQ2ZnQXJyYXkFAAAAFUlkeFByb3RvY29sRmVlUGVyY2VudAEAAAAMa2V5SXNCbG9ja2VkAAAAAAIAAAANJXNfX2lzQmxvY2tlZAEAAAARa2V5SXNNYXJrZXRPcGVuZWQAAAABAAAACWFzc2V0Q29kZQkAASwAAAACAgAAABYlcyVzX19pc01hcmtldE9wZW5lZF9fBQAAAAlhc3NldENvZGUAAAAACWlzQmxvY2tlZAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBsAAAACBQAAAA5wcmljZU9yYWNsZUFjYwkBAAAADGtleUlzQmxvY2tlZAAAAAAHAAAAAA5pc01hcmtldE9wZW5lZAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBsAAAACBQAAAA5wcmljZU9yYWNsZUFjYwkBAAAAEWtleUlzTWFya2V0T3BlbmVkAAAAAQUAAAANZGVmb0Fzc2V0Q29kZQcBAAAAE2NvbnRyb2xBY2NSZWFkUHJpY2UAAAABAAAACWFzc2V0Q29kZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAADnByaWNlT3JhY2xlQWNjCQEAAAAIa2V5UHJpY2UAAAABBQAAAAlhc3NldENvZGUJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAGE5vIHByaWNlIGF0IHByaWNlT3JhY2xlPQkABCUAAAABBQAAAA5wcmljZU9yYWNsZUFjYwIAAAAJIGZvciBrZXk9CQEAAAAIa2V5UHJpY2UAAAABBQAAAAlhc3NldENvZGUBAAAAGGNvbnRyb2xBY2NSZWFkTGFzdEhlaWdodAAAAAEAAAAJYXNzZXRDb2RlCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAOcHJpY2VPcmFjbGVBY2MJAQAAABRrZXlDb250cm9sTGFzdEhlaWdodAAAAAEFAAAACWFzc2V0Q29kZQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAdTm8gbGFzdEhlaWdodCBhdCBwcmljZU9yYWNsZT0JAAQlAAAAAQUAAAAOcHJpY2VPcmFjbGVBY2MCAAAACSBmb3Iga2V5PQkBAAAAFGtleUNvbnRyb2xMYXN0SGVpZ2h0AAAAAQUAAAAJYXNzZXRDb2RlAQAAABtjb250cm9sQWNjUmVhZEN1cnJJZHhPckZhaWwAAAAACQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAOcHJpY2VPcmFjbGVBY2MCAAAAB2N1cnJJZHgJAAEsAAAAAgIAAAAZTm8gY3VycklkeCBhdCBjb250cm9sQWNjPQkABCUAAAABBQAAAA5wcmljZU9yYWNsZUFjYwEAAAAXY29udHJvbEFjY1JlYWRJZHhIZWlnaHQAAAABAAAAA2lkeAQAAAAMaWR4SGVpZ2h0S2V5CQABLAAAAAICAAAACmlkeEhlaWdodF8JAAGkAAAAAQUAAAADaWR4CQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAADnByaWNlT3JhY2xlQWNjBQAAAAxpZHhIZWlnaHRLZXkAAAAAAAAAAAABAAAAG2NvbnRyb2xBY2NSZWFkUHJpY2VCeUhlaWdodAAAAAEAAAALcHJpY2VIZWlnaHQEAAAAEHByaWNlQnlIZWlnaHRLZXkJAAEsAAAAAgIAAAAGcHJpY2VfCQABpAAAAAEFAAAAC3ByaWNlSGVpZ2h0CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAOcHJpY2VPcmFjbGVBY2MFAAAAEHByaWNlQnlIZWlnaHRLZXkJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAA05vIAUAAAAQcHJpY2VCeUhlaWdodEtleQIAAAAPIGF0IGNvbnRyb2xBY2M9CQAEJQAAAAEFAAAADnByaWNlT3JhY2xlQWNjAAAAAA9wcmljZUxhc3RIZWlnaHQJAQAAABhjb250cm9sQWNjUmVhZExhc3RIZWlnaHQAAAABBQAAAA1kZWZvQXNzZXRDb2RlAAAAABVpc0Jsb2NrZWRCeUxhc3RIZWlnaHQJAABmAAAAAgkAAGUAAAACBQAAAAZoZWlnaHQFAAAAD3ByaWNlTGFzdEhlaWdodAAAAAAAAAAABQEAAAAYa2V5RmVlc01hbmFnZXJBZGRyZXNzS2V5AAAAAAIAAAAUZmVlc19tYW5hZ2VyX2FkZHJlc3MAAAAAD25ldXRyaW5vTWFpbkFjYwkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAACmZhY3RvcnlBY2MJAQAAACRrZXlGYWN0b3J5TmV1dHJpbm9Db250cmFjdEFkZHJlc3NLZXkAAAAACQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABVObyBjb25maWcgYXQgZmFjdG9yeT0JAAQlAAAAAQUAAAAKZmFjdG9yeUFjYwIAAAAJIGZvciBrZXk9CQEAAAAka2V5RmFjdG9yeU5ldXRyaW5vQ29udHJhY3RBZGRyZXNzS2V5AAAAAAAAAAARZmVlTWFuYWdlckFkZHJlc3MJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAPbmV1dHJpbm9NYWluQWNjCQEAAAAYa2V5RmVlc01hbmFnZXJBZGRyZXNzS2V5AAAAAAkAASwAAAACCQEAAAAYa2V5RmVlc01hbmFnZXJBZGRyZXNzS2V5AAAAAAIAAAARIGlzIG5vdCBzcGVjaWZpZWQJAAEsAAAAAgkBAAAAGGtleUZlZXNNYW5hZ2VyQWRkcmVzc0tleQAAAAACAAAAFyBpbnZhbGlkIGFkZHJlc3MgZm9ybWF0AAAAABVrZXlEZWZvU3Rha2luZ0FkZHJlc3MCAAAAJiVzJXNfX2NvbW1vbkNvbmZpZ19fZGVmb1N0YWtpbmdBZGRyZXNzAAAAABlrZXlOZXV0cmlub1N0YWtpbmdBZGRyZXNzAgAAAColcyVzX19jb21tb25Db25maWdfX25ldXRyaW5vU3Rha2luZ0FkZHJlc3MBAAAAGmtleURlZm9TdGFraW5nQXNzZXRCYWxhbmNlAAAAAQAAAAdhc3NldElkCQABLAAAAAICAAAAFiVzJXNfX3N0YWtpbmdCYWxhbmNlX18FAAAAB2Fzc2V0SWQBAAAAGWtleU5ldXRyaW5vU3Rha2luZ0JhbGFuY2UAAAAACQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAAxycGRfYmFsYW5jZV8FAAAADmJhc2VBc3NldElkU3RyAgAAAAFfCQAEJQAAAAEFAAAABHRoaXMAAAAADmRlZm9TdGFraW5nQWNjCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQmAAAAAQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAACmZhY3RvcnlBY2MFAAAAFWtleURlZm9TdGFraW5nQWRkcmVzcwkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAXTm8gY29uZmlnIGF0IGZhY3RvcnlBY2MJAAQlAAAAAQUAAAAKZmFjdG9yeUFjYwIAAAAJIGZvciBrZXk9BQAAABVrZXlEZWZvU3Rha2luZ0FkZHJlc3MJAAEsAAAAAgIAAAAhYWRkcmVzcyBleHRyYWN0aW9uIGVycm9yIGZvciBrZXk9BQAAABVrZXlEZWZvU3Rha2luZ0FkZHJlc3MAAAAAEm5ldXRyaW5vU3Rha2luZ0FjYwkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEJgAAAAEJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAApmYWN0b3J5QWNjBQAAABlrZXlOZXV0cmlub1N0YWtpbmdBZGRyZXNzCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABdObyBjb25maWcgYXQgZmFjdG9yeUFjYwkABCUAAAABBQAAAApmYWN0b3J5QWNjAgAAAAkgZm9yIGtleT0FAAAAGWtleU5ldXRyaW5vU3Rha2luZ0FkZHJlc3MJAAEsAAAAAgIAAAAhYWRkcmVzcyBleHRyYWN0aW9uIGVycm9yIGZvciBrZXk9BQAAABlrZXlOZXV0cmlub1N0YWtpbmdBZGRyZXNzAQAAABlnZXRUaGlzRGVmb1N0YWtpbmdCYWxhbmNlAAAAAAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAA5kZWZvU3Rha2luZ0FjYwkBAAAAGmtleURlZm9TdGFraW5nQXNzZXRCYWxhbmNlAAAAAQUAAAAOZGVmb0Fzc2V0SWRTdHIAAAAAAAAAAAABAAAAHWdldFRoaXNOZXV0cmlub1N0YWtpbmdCYWxhbmNlAAAAAAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAABJuZXV0cmlub1N0YWtpbmdBY2MJAQAAABlrZXlOZXV0cmlub1N0YWtpbmdCYWxhbmNlAAAAAAAAAAAAAAAAAAAAAAALdWNvbGxhdGVyYWwJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwkBAAAADmtleVVjb2xsYXRlcmFsAAAAAAAAAAAAAAAAAAAAAAAOYWNjdW11bGF0ZWRGZWUJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwkBAAAAEWtleUFjY3VtdWxhdGVkRmVlAAAAAAAAAAAAAAAAAAAAAAAWYWNjdW11bGF0ZWRQcm90b2NvbEZlZQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAZa2V5QWNjdW11bGF0ZWRQcm90b2NvbEZlZQAAAAAAAAAAAAAAAAAAAAAADmN1cnJQb29sQW1vdW50CQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAApmYWN0b3J5QWNjCQEAAAAaa2V5RmFjdG9yeUFzc2V0Q3VycmVudFBvb2wAAAABBQAAAAR0aGlzAAAAAAtkZWJ0QXNzZXRJZAkAAlkAAAABCQEAAAAWZmFjdG9yeVJlYWREZWJ0QXNzZXRJZAAAAAAAAAAAFmRlYnRBc3NldEV0YWxvbkJhbGFuY2UJAQAAABFAZXh0ck5hdGl2ZSgxMDUwKQAAAAIFAAAACmZhY3RvcnlBY2MJAQAAACBrZXlGYWN0b3J5RGVidEFzc2V0RXRhbG9uQmFsYW5jZQAAAAAAAAAAEmxlbmRlZE9yRGVidEFtb3VudAkAAGUAAAACBQAAABZkZWJ0QXNzZXRFdGFsb25CYWxhbmNlCQAD8AAAAAIFAAAABHRoaXMFAAAAC2RlYnRBc3NldElkAAAAABdjdXJyZW50QmFzZUFzc2V0QmFsYW5jZQkAAGQAAAACCQAAZAAAAAIJAAPwAAAAAgUAAAAEdGhpcwUAAAALYmFzZUFzc2V0SWQJAQAAAB1nZXRUaGlzTmV1dHJpbm9TdGFraW5nQmFsYW5jZQAAAAAFAAAAEmxlbmRlZE9yRGVidEFtb3VudAAAAAAMY29udHJvbFByaWNlCQEAAAATY29udHJvbEFjY1JlYWRQcmljZQAAAAEJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAABBJZHhEZWZvQXNzZXRDb2RlAAAAAAhlbWlzc2lvbgkAAGUAAAACCAkBAAAABXZhbHVlAAAAAQkAA+wAAAABBQAAAAtkZWZvQXNzZXRJZAAAAAhxdWFudGl0eQkAA/AAAAACBQAAAAR0aGlzBQAAAAtkZWZvQXNzZXRJZAEAAAALZ2V0QnV5UHJpY2UAAAABAAAAC2NoYW5nZUNvZWZmAwUAAAAOaXNNYXJrZXRPcGVuZWQFAAAADGNvbnRyb2xQcmljZQkAAGsAAAADCQAAZQAAAAIFAAAADXByaWNlRGVjaW1hbHMFAAAAC2NoYW5nZUNvZWZmBQAAAAxjb250cm9sUHJpY2UFAAAADXByaWNlRGVjaW1hbHMBAAAAI2dldEJ1eUZlZUNvbnNpZGVyaW5nU3Rha2luZ1JlZmVycmFsAAAAAQAAAA5jYWxsZXJQdWI1OFN0cgMJAAAAAAAAAgUAAAAdYXNzZXRTdGFraW5nUmVmZXJyYWxQdWJsaWNTdHIFAAAADmNhbGxlclB1YjU4U3RyAAAAAAAAAAAABQAAAA1idXlGZWVQZXJjZW50AQAAAChnZXRQcm90b2NvbEZlZUNvbnNpZGVyaW5nU3Rha2luZ1JlZmVycmFsAAAAAQAAAA5jYWxsZXJQdWI1OFN0cgMJAAAAAAAAAgUAAAAdYXNzZXRTdGFraW5nUmVmZXJyYWxQdWJsaWNTdHIFAAAADmNhbGxlclB1YjU4U3RyAAAAAAAAAAAABQAAABJwcm90b2NvbEZlZVBlcmNlbnQBAAAAJWdldEJ1eVByaWNlQ29uc2lkZXJpbmdTdGFraW5nUmVmZXJyYWwAAAACAAAAC2NoYW5nZUNvZWZmAAAADmNhbGxlclB1YjU4U3RyAwkAAAAAAAACBQAAAB1hc3NldFN0YWtpbmdSZWZlcnJhbFB1YmxpY1N0cgUAAAAOY2FsbGVyUHViNThTdHIFAAAADGNvbnRyb2xQcmljZQkBAAAAC2dldEJ1eVByaWNlAAAAAQUAAAALY2hhbmdlQ29lZmYBAAAADGdldFNlbGxQcmljZQAAAAEAAAALY2hhbmdlQ29lZmYDBQAAAA5pc01hcmtldE9wZW5lZAUAAAAMY29udHJvbFByaWNlCQAAawAAAAMJAABkAAAAAgUAAAANcHJpY2VEZWNpbWFscwUAAAALY2hhbmdlQ29lZmYFAAAADGNvbnRyb2xQcmljZQUAAAANcHJpY2VEZWNpbWFscwEAAAAQZ2V0U2VsbFByaWNlRnJvbQAAAAIAAAAJZnJvbVByaWNlAAAAC2NoYW5nZUNvZWZmAwUAAAAOaXNNYXJrZXRPcGVuZWQFAAAACWZyb21QcmljZQkAAGsAAAADCQAAZAAAAAIFAAAADXByaWNlRGVjaW1hbHMFAAAAC2NoYW5nZUNvZWZmBQAAAAlmcm9tUHJpY2UFAAAADXByaWNlRGVjaW1hbHMBAAAAEGludGVybmFsQnV5QXNzZXQAAAAHAAAACnNlbGxlckFkZHIAAAAHc2VsbEFtdAAAAAtzZWxsQXNzZXRJZAAAAAptaW5TZWxsQW10AAAADWJ1eTJzZWxsUHJpY2UAAAARcG9vbE1ha2Vyc0ZlZVBhcnQAAAAPcHJvdG9jb2xGZWVQYXJ0BAAAABRkZWZvQXNzZXRBbW91bnRHcm9zcwkAAGsAAAADBQAAAAdzZWxsQW10BQAAAA1idXkyc2VsbFByaWNlBQAAAA1wcmljZURlY2ltYWxzBAAAABZzdGFiaWxpdHlGZWVEZWZvQW1vdW50CQAAawAAAAMFAAAAFHBvb2xTdGFiaWxpdHlGZWVQYXJ0BQAAABRkZWZvQXNzZXRBbW91bnRHcm9zcwUAAAANcHJpY2VEZWNpbWFscwQAAAAXcG9vbE1ha2Vyc0ZlZURlZm9BbW91bnQJAABrAAAAAwUAAAARcG9vbE1ha2Vyc0ZlZVBhcnQFAAAAFGRlZm9Bc3NldEFtb3VudEdyb3NzBQAAAA1wcmljZURlY2ltYWxzBAAAABVwcm90b2NvbEZlZURlZm9BbW91bnQJAABrAAAAAwUAAAAPcHJvdG9jb2xGZWVQYXJ0BQAAABRkZWZvQXNzZXRBbW91bnRHcm9zcwUAAAANcHJpY2VEZWNpbWFscwQAAAAPZGVmb0Fzc2V0QW1vdW50CQAAZQAAAAIJAABlAAAAAgkAAGUAAAACBQAAABRkZWZvQXNzZXRBbW91bnRHcm9zcwUAAAAWc3RhYmlsaXR5RmVlRGVmb0Ftb3VudAUAAAAXcG9vbE1ha2Vyc0ZlZURlZm9BbW91bnQFAAAAFXByb3RvY29sRmVlRGVmb0Ftb3VudAQAAAAYcmVxdWlyZWRCYXNpY0Fzc2V0QW1vdW50CQAAawAAAAMFAAAAFGRlZm9Bc3NldEFtb3VudEdyb3NzBQAAAA1wcmljZURlY2ltYWxzBQAAAA1idXkyc2VsbFByaWNlBAAAAAZjaGFuZ2UJAABlAAAAAgUAAAAHc2VsbEFtdAUAAAAYcmVxdWlyZWRCYXNpY0Fzc2V0QW1vdW50AwMJAABmAAAAAgUAAAAKbWluU2VsbEFtdAUAAAAHc2VsbEFtdAkBAAAAAiE9AAAAAgkABCUAAAABBQAAAApzZWxsZXJBZGRyCQAEJQAAAAEFAAAADmRlZm9TdGFraW5nQWNjBwkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAYaW1wb3NzaWJsZSB0byBpc3N1ZSBuZXcgBQAAAA1kZWZvQXNzZXRDb2RlAgAAAAo6IHBheW1lbnQ9CQABpAAAAAEFAAAAB3NlbGxBbXQCAAAAGGlzIGxlc3MgdGhlbiBtaW4gYW1vdW50PQkAAaQAAAABBQAAAAptaW5TZWxsQW10CQAFFAAAAAIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAA5rZXlVY29sbGF0ZXJhbAAAAAAJAABkAAAAAgUAAAALdWNvbGxhdGVyYWwFAAAAGHJlcXVpcmVkQmFzaWNBc3NldEFtb3VudAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAATa2V5QWNjb3VudE9wZXJhdGlvbgAAAAMFAAAABmhlaWdodAkABCUAAAABBQAAAApzZWxsZXJBZGRyAgAAAAhGSU5JU0hFRAkBAAAAFmFzc2V0RGF0YVN3YXBPcGVyYXRpb24AAAAIBQAAAAdzZWxsQW10CQACWAAAAAEFAAAAC3NlbGxBc3NldElkBQAAAAxjb250cm9sUHJpY2UFAAAAD2RlZm9Bc3NldEFtb3VudAkAAlgAAAABBQAAAAtkZWZvQXNzZXRJZAUAAAAUZGVmb0Fzc2V0QW1vdW50R3Jvc3MFAAAAF3Bvb2xNYWtlcnNGZWVEZWZvQW1vdW50BQAAABVwcm90b2NvbEZlZURlZm9BbW91bnQJAARMAAAAAgkBAAAAB1JlaXNzdWUAAAADBQAAAAtkZWZvQXNzZXRJZAkAAGQAAAACCQAAZAAAAAIFAAAAD2RlZm9Bc3NldEFtb3VudAUAAAAXcG9vbE1ha2Vyc0ZlZURlZm9BbW91bnQFAAAAFXByb3RvY29sRmVlRGVmb0Ftb3VudAYJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAAKc2VsbGVyQWRkcgUAAAAPZGVmb0Fzc2V0QW1vdW50BQAAAAtkZWZvQXNzZXRJZAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAAApzZWxsZXJBZGRyBQAAAAZjaGFuZ2UFAAAAC3NlbGxBc3NldElkCQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMJAQAAACdmYWN0b3J5UmVhZE5leHRQb29sTWFrZXJUb0Rpc3RyaWJ1dGVGZWUAAAABCQAEJQAAAAEFAAAABHRoaXMFAAAAF3Bvb2xNYWtlcnNGZWVEZWZvQW1vdW50BQAAAAtkZWZvQXNzZXRJZAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAABFmZWVNYW5hZ2VyQWRkcmVzcwUAAAAVcHJvdG9jb2xGZWVEZWZvQW1vdW50BQAAAAtkZWZvQXNzZXRJZAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAEWtleUFjY3VtdWxhdGVkRmVlAAAAAAkAAGQAAAACBQAAAA5hY2N1bXVsYXRlZEZlZQUAAAAXcG9vbE1ha2Vyc0ZlZURlZm9BbW91bnQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABlrZXlBY2N1bXVsYXRlZFByb3RvY29sRmVlAAAAAAkAAGQAAAACBQAAABZhY2N1bXVsYXRlZFByb3RvY29sRmVlBQAAABVwcm90b2NvbEZlZURlZm9BbW91bnQFAAAAA25pbAUAAAAGY2hhbmdlAAAABQAAAAFpAQAAAAhidXlBc3NldAAAAAAEAAAAA3BtdAkBAAAABXZhbHVlAAAAAQkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAQAAAAKcG10QXNzZXRJZAkBAAAABXZhbHVlAAAAAQgFAAAAA3BtdAAAAAdhc3NldElkBAAAAA5jYWxsZXJQdWI1OFN0cgkAAlgAAAABCAUAAAABaQAAAA9jYWxsZXJQdWJsaWNLZXkDBQAAAAlpc0Jsb2NrZWQJAAACAAAAAQIAAABaY29udHJhY3QgaXMgYmxvY2tlZCBieSBFTUVSR0VOQ1kgU0hVVERPV04gYWN0aW9ucyB1bnRpbGwgcmVhY3RpdmF0aW9uIGJ5IGVtZXJnZW5jeSBvcmFjbGVzAwUAAAAVaXNCbG9ja2VkQnlMYXN0SGVpZ2h0CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAASWxhc3QgcHJpY2UgZmluYWxpemF0aW9uIGhhcyBiZWVuIG1vcmUgdGhlbiA1IGJsb2NrcyBhZ286IHByaWNlTGFzdEhlaWdodD0JAAGkAAAAAQUAAAAPcHJpY2VMYXN0SGVpZ2h0AgAAAAwgY3VyckhlaWdodD0JAAGkAAAAAQUAAAAGaGVpZ2h0AwkBAAAAAiE9AAAAAgUAAAAKcG10QXNzZXRJZAUAAAALYmFzZUFzc2V0SWQJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAA1UGF5bWVudCBhc3NldCBpZCBkb2Vzbid0IG1hdGNoIGJhc2ljIGFzc2V0OiBleHBlY3RlZD0JAAJYAAAAAQUAAAALYmFzZUFzc2V0SWQCAAAACCBhY3R1YWw9CQACWAAAAAEFAAAACnBtdEFzc2V0SWQICQEAAAAQaW50ZXJuYWxCdXlBc3NldAAAAAcIBQAAAAFpAAAABmNhbGxlcggFAAAAA3BtdAAAAAZhbW91bnQFAAAACnBtdEFzc2V0SWQFAAAAEW1pbkJhc2ljQnV5QW1vdW50CQEAAAAlZ2V0QnV5UHJpY2VDb25zaWRlcmluZ1N0YWtpbmdSZWZlcnJhbAAAAAIFAAAAHndlZWtlbmRzUHJpY2VDaGFuZ2VDb2VmZmljaWVudAUAAAAOY2FsbGVyUHViNThTdHIJAQAAACNnZXRCdXlGZWVDb25zaWRlcmluZ1N0YWtpbmdSZWZlcnJhbAAAAAEFAAAADmNhbGxlclB1YjU4U3RyCQEAAAAoZ2V0UHJvdG9jb2xGZWVDb25zaWRlcmluZ1N0YWtpbmdSZWZlcnJhbAAAAAEFAAAADmNhbGxlclB1YjU4U3RyAAAAAl8xAAAAAWkBAAAACXNlbGxBc3NldAAAAAAEAAAAA3BtdAkBAAAABXZhbHVlAAAAAQkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAQAAAAIcG10QXNzZXQJAQAAAAV2YWx1ZQAAAAEIBQAAAANwbXQAAAAHYXNzZXRJZAQAAAANY2FsbGVyQWRkcmVzcwkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAACXNlbGxQcmljZQkBAAAADGdldFNlbGxQcmljZQAAAAEFAAAAHndlZWtlbmRzUHJpY2VDaGFuZ2VDb2VmZmljaWVudAMFAAAACWlzQmxvY2tlZAkAAAIAAAABAgAAAFpjb250cmFjdCBpcyBibG9ja2VkIGJ5IEVNRVJHRU5DWSBTSFVURE9XTiBhY3Rpb25zIHVudGlsbCByZWFjdGl2YXRpb24gYnkgZW1lcmdlbmN5IG9yYWNsZXMDBQAAABVpc0Jsb2NrZWRCeUxhc3RIZWlnaHQJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAABJbGFzdCBwcmljZSBmaW5hbGl6YXRpb24gaGFzIGJlZW4gbW9yZSB0aGVuIDUgYmxvY2tzIGFnbzogcHJpY2VMYXN0SGVpZ2h0PQkAAaQAAAABBQAAAA9wcmljZUxhc3RIZWlnaHQCAAAADCBjdXJySGVpZ2h0PQkAAaQAAAABBQAAAAZoZWlnaHQDCQEAAAACIT0AAAACBQAAAAhwbXRBc3NldAUAAAALZGVmb0Fzc2V0SWQJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAjSW52YWxpZCBwYXltZW50IGFzc2V0IGlkOiBleHBlY3RlZD0JAAJYAAAAAQUAAAALZGVmb0Fzc2V0SWQCAAAACCBhY3R1YWw9CQACWAAAAAEFAAAACHBtdEFzc2V0AwkAAGYAAAACBQAAABJtaW5TeW50aFNlbGxBbW91bnQIBQAAAANwbXQAAAAGYW1vdW50CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAOlBheW1lbnQgYW1vdW50IGxlc3MgdGhlbiBtaW5pbmltYWwgYWxsb3dlZDogcGF5bWVudEFtb3VudD0JAAGkAAAAAQgFAAAAA3BtdAAAAAZhbW91bnQCAAAACyBtaW5BbW91bnQ9CQABpAAAAAEFAAAAEm1pblN5bnRoU2VsbEFtb3VudAQAAAAdYmFzZUFzc2V0QW1vdW50Tm9CYWxhbmNlTGltaXQJAABrAAAAAwgFAAAAA3BtdAAAAAZhbW91bnQFAAAADXByaWNlRGVjaW1hbHMFAAAACXNlbGxQcmljZQQAAAAYYmFzZUFzc2V0QW1vdW50QXZhaWxhYmxlAwkAAGYAAAACBQAAAB1iYXNlQXNzZXRBbW91bnROb0JhbGFuY2VMaW1pdAUAAAAXY3VycmVudEJhc2VBc3NldEJhbGFuY2UFAAAAF2N1cnJlbnRCYXNlQXNzZXRCYWxhbmNlBQAAAB1iYXNlQXNzZXRBbW91bnROb0JhbGFuY2VMaW1pdAQAAAAYc29sZERlZm9Bc3NldEFtb3VudEdyb3NzCQAAawAAAAMFAAAAGGJhc2VBc3NldEFtb3VudEF2YWlsYWJsZQUAAAAJc2VsbFByaWNlBQAAAA1wcmljZURlY2ltYWxzBAAAAAZjaGFuZ2UJAABlAAAAAggFAAAAA3BtdAAAAAZhbW91bnQFAAAAGHNvbGREZWZvQXNzZXRBbW91bnRHcm9zcwQAAAAWc3RhYmlsaXR5RmVlRGVmb0Ftb3VudAkAAGsAAAADBQAAABRwb29sU3RhYmlsaXR5RmVlUGFydAUAAAAYc29sZERlZm9Bc3NldEFtb3VudEdyb3NzBQAAAA1wcmljZURlY2ltYWxzBAAAABdwb29sTWFrZXJzRmVlRGVmb0Ftb3VudAkAAGsAAAADBQAAAA5zZWxsRmVlUGVyY2VudAUAAAAYc29sZERlZm9Bc3NldEFtb3VudEdyb3NzBQAAAA1wcmljZURlY2ltYWxzBAAAABVwcm90b2NvbEZlZURlZm9BbW91bnQJAABrAAAAAwUAAAAScHJvdG9jb2xGZWVQZXJjZW50BQAAABhzb2xkRGVmb0Fzc2V0QW1vdW50R3Jvc3MFAAAADXByaWNlRGVjaW1hbHMEAAAAE3NvbGREZWZvQXNzZXRBbW91bnQJAABlAAAAAgkAAGUAAAACCQAAZQAAAAIFAAAAGHNvbGREZWZvQXNzZXRBbW91bnRHcm9zcwUAAAAWc3RhYmlsaXR5RmVlRGVmb0Ftb3VudAUAAAAXcG9vbE1ha2Vyc0ZlZURlZm9BbW91bnQFAAAAFXByb3RvY29sRmVlRGVmb0Ftb3VudAQAAAAVYmFzZUFzc2V0QW1vdW50VG9TZW5kCQAAawAAAAMFAAAAE3NvbGREZWZvQXNzZXRBbW91bnQFAAAADXByaWNlRGVjaW1hbHMFAAAACXNlbGxQcmljZQkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAADmtleVVjb2xsYXRlcmFsAAAAAAkAAGUAAAACBQAAAAt1Y29sbGF0ZXJhbAUAAAAVYmFzZUFzc2V0QW1vdW50VG9TZW5kCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAABNrZXlBY2NvdW50T3BlcmF0aW9uAAAAAwUAAAAGaGVpZ2h0BQAAAA1jYWxsZXJBZGRyZXNzAgAAAAhGSU5JU0hFRAkBAAAAFmFzc2V0RGF0YVN3YXBPcGVyYXRpb24AAAAICAUAAAADcG10AAAABmFtb3VudAkAAlgAAAABBQAAAAhwbXRBc3NldAUAAAAJc2VsbFByaWNlBQAAABViYXNlQXNzZXRBbW91bnRUb1NlbmQFAAAADmJhc2VBc3NldElkU3RyBQAAABhzb2xkRGVmb0Fzc2V0QW1vdW50R3Jvc3MFAAAAF3Bvb2xNYWtlcnNGZWVEZWZvQW1vdW50BQAAABVwcm90b2NvbEZlZURlZm9BbW91bnQJAARMAAAAAgkBAAAABEJ1cm4AAAACBQAAAAtkZWZvQXNzZXRJZAkAAGQAAAACBQAAABNzb2xkRGVmb0Fzc2V0QW1vdW50BQAAABZzdGFiaWxpdHlGZWVEZWZvQW1vdW50CQAETAAAAAIJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMIBQAAAAFpAAAABmNhbGxlcgUAAAAVYmFzZUFzc2V0QW1vdW50VG9TZW5kBQAAAAtiYXNlQXNzZXRJZAkABEwAAAACCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCAUAAAABaQAAAAZjYWxsZXIFAAAABmNoYW5nZQUAAAALZGVmb0Fzc2V0SWQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAARZmVlTWFuYWdlckFkZHJlc3MFAAAAFXByb3RvY29sRmVlRGVmb0Ftb3VudAUAAAALZGVmb0Fzc2V0SWQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwkBAAAAJ2ZhY3RvcnlSZWFkTmV4dFBvb2xNYWtlclRvRGlzdHJpYnV0ZUZlZQAAAAEJAAQlAAAAAQUAAAAEdGhpcwUAAAAXcG9vbE1ha2Vyc0ZlZURlZm9BbW91bnQFAAAAC2RlZm9Bc3NldElkCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAARa2V5QWNjdW11bGF0ZWRGZWUAAAAACQAAZAAAAAIFAAAADmFjY3VtdWxhdGVkRmVlBQAAABdwb29sTWFrZXJzRmVlRGVmb0Ftb3VudAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAGWtleUFjY3VtdWxhdGVkUHJvdG9jb2xGZWUAAAAACQAAZAAAAAIFAAAAFmFjY3VtdWxhdGVkUHJvdG9jb2xGZWUFAAAAFXByb3RvY29sRmVlRGVmb0Ftb3VudAUAAAADbmlsAAAAAWkBAAAADWNyb3NzRXhjaGFuZ2UAAAACAAAAE2J1eUFzc2V0Q29kZUNvbmZpcm0AAAAUc2VsbEFzc2V0Q29kZUNvbmZpcm0EAAAAA3BtdAkBAAAABXZhbHVlAAAAAQkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAQAAAAIcG10QXNzZXQJAQAAAAV2YWx1ZQAAAAEIBQAAAANwbXQAAAAHYXNzZXRJZAQAAAALcG10QXNzZXRTdHIJAAJYAAAAAQUAAAAIcG10QXNzZXQEAAAACXBtdEFtb3VudAgFAAAAA3BtdAAAAAZhbW91bnQEAAAADWNhbGxlckFkZHJlc3MJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAAAtidXlBc3NldENmZwUAAAAMdGhpc0NmZ0FycmF5BAAAAA5zZWxsQXNzZXRUdXBsZQkBAAAAGWZhY3RvcnlSZWFkQXNzZXRDZmdCeUNvZGUAAAABBQAAABRzZWxsQXNzZXRDb2RlQ29uZmlybQQAAAAMc2VsbEFzc2V0Q2ZnCAUAAAAOc2VsbEFzc2V0VHVwbGUAAAACXzIEAAAAE3NlbGxBc3NldEFjY0FkZHJlc3MJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABCAUAAAAOc2VsbEFzc2V0VHVwbGUAAAACXzEJAAEsAAAAAgIAAAAxY291bGRuJ3QgcGFyc2UgYWRkcmVzcyBmcm9tIHN0cmluZyBmb3IgYXNzZXRDb2RlPQUAAAAUc2VsbEFzc2V0Q29kZUNvbmZpcm0EAAAACm1pblNlbGxQbXQJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABLYAAAABCQABkQAAAAIFAAAADHNlbGxBc3NldENmZwUAAAARSWR4TWluU2VsbFBheW1lbnQJAAEsAAAAAgIAAAAhbWluU2VsbFBtdCBwYXJzaW5nIGVycm9yOiByYXdWYWw9CQABkQAAAAIFAAAADHNlbGxBc3NldENmZwUAAAARSWR4TWluU2VsbFBheW1lbnQEAAAAE3NlbGxQcmljZUxhc3RIZWlnaHQJAQAAABhjb250cm9sQWNjUmVhZExhc3RIZWlnaHQAAAABBQAAABRzZWxsQXNzZXRDb2RlQ29uZmlybQQAAAAZaXNTZWxsQmxvY2tlZEJ5TGFzdEhlaWdodAkAAGYAAAACCQAAZQAAAAIFAAAABmhlaWdodAUAAAATc2VsbFByaWNlTGFzdEhlaWdodAAAAAAAAAAABQMFAAAACWlzQmxvY2tlZAkAAAIAAAABAgAAAFpjb250cmFjdCBpcyBibG9ja2VkIGJ5IEVNRVJHRU5DWSBTSFVURE9XTiBhY3Rpb25zIHVudGlsbCByZWFjdGl2YXRpb24gYnkgZW1lcmdlbmN5IG9yYWNsZXMDCQEAAAACIT0AAAACCQABkQAAAAIFAAAADHRoaXNDZmdBcnJheQUAAAAQSWR4RGVmb0Fzc2V0Q29kZQUAAAATYnV5QXNzZXRDb2RlQ29uZmlybQkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAADBidXlBc3NldCBjb25maXJtYXRpb24gZmFpbGVkOiBidXlBc3NldElkQ29uZmlybT0JAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAABBJZHhEZWZvQXNzZXRDb2RlAgAAABAgQlVUIGJ1eUFzc2V0SWQ9BQAAABNidXlBc3NldENvZGVDb25maXJtAwkBAAAAAiE9AAAAAgkAAZEAAAACBQAAAAxzZWxsQXNzZXRDZmcFAAAADklkeERlZm9Bc3NldElkBQAAAAtwbXRBc3NldFN0cgkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAADJzZWxsQXNzZXQgY29uZmlybWF0aW9uIGZhaWxlZDogc2VsbEFzc2V0SWRDb25maXJtPQkAAZEAAAACBQAAAAxzZWxsQXNzZXRDZmcFAAAADklkeERlZm9Bc3NldElkAgAAAA1CVVQgcG10QXNzZXQ9BQAAAAtwbXRBc3NldFN0cgMJAQAAAAIhPQAAAAIJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAABJJZHhEZWZvQXNzZXRTdGF0dXMCAAAABklTU1VFRAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAACx0b0Fzc2V0IGhhcyBub3QgYmVlbiBpc3N1ZWQgeWV0OiBidXlBc3NldElkPQUAAAATYnV5QXNzZXRDb2RlQ29uZmlybQIAAAAMIEJVVCBzdGF0dXM9CQABkQAAAAIFAAAADHRoaXNDZmdBcnJheQUAAAASSWR4RGVmb0Fzc2V0U3RhdHVzAwkBAAAAAiE9AAAAAgkAAZEAAAACBQAAAAxzZWxsQXNzZXRDZmcFAAAAEklkeERlZm9Bc3NldFN0YXR1cwIAAAAGSVNTVUVECQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAMmZyb21Bc3NldENmZyBoYXMgbm90IGJlZW4gaXNzdWVkIHlldDogc2VsbEFzc2V0SWQ9BQAAAAtwbXRBc3NldFN0cgIAAAAMIEJVVCBzdGF0dXM9CQABkQAAAAIFAAAADHNlbGxBc3NldENmZwUAAAASSWR4RGVmb0Fzc2V0U3RhdHVzAwUAAAAVaXNCbG9ja2VkQnlMYXN0SGVpZ2h0CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAE1idXkgbGFzdCBwcmljZSBmaW5hbGl6YXRpb24gaGFzIGJlZW4gbW9yZSB0aGVuIDUgYmxvY2tzIGFnbzogcHJpY2VMYXN0SGVpZ2h0PQkAAaQAAAABBQAAAA9wcmljZUxhc3RIZWlnaHQCAAAADCBjdXJySGVpZ2h0PQkAAaQAAAABBQAAAAZoZWlnaHQCAAAACSBidXlDb2RlPQUAAAATYnV5QXNzZXRDb2RlQ29uZmlybQMFAAAAGWlzU2VsbEJsb2NrZWRCeUxhc3RIZWlnaHQJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAATnNlbGwgbGFzdCBwcmljZSBmaW5hbGl6YXRpb24gaGFzIGJlZW4gbW9yZSB0aGVuIDUgYmxvY2tzIGFnbzogcHJpY2VMYXN0SGVpZ2h0PQkAAaQAAAABBQAAAA9wcmljZUxhc3RIZWlnaHQCAAAADCBjdXJySGVpZ2h0PQkAAaQAAAABBQAAAAZoZWlnaHQCAAAACiBzZWxsQ29kZT0FAAAAFHNlbGxBc3NldENvZGVDb25maXJtBAAAABBidXlBc3NldFVzZFByaWNlCQEAAAALZ2V0QnV5UHJpY2UAAAABCQAAaQAAAAIFAAAAHndlZWtlbmRzUHJpY2VDaGFuZ2VDb2VmZmljaWVudAAAAAAAAAAAAgQAAAARc2VsbEFzc2V0VXNkUHJpY2UJAQAAABBnZXRTZWxsUHJpY2VGcm9tAAAAAgkBAAAAE2NvbnRyb2xBY2NSZWFkUHJpY2UAAAABBQAAABRzZWxsQXNzZXRDb2RlQ29uZmlybQkAAGkAAAACBQAAAB53ZWVrZW5kc1ByaWNlQ2hhbmdlQ29lZmZpY2llbnQAAAAAAAAAAAIEAAAADWJ1eTJzZWxsUHJpY2UJAABrAAAAAwUAAAAQYnV5QXNzZXRVc2RQcmljZQUAAAANcHJpY2VEZWNpbWFscwUAAAARc2VsbEFzc2V0VXNkUHJpY2UEAAAACHVzZG5EZWJ0CQAAawAAAAMFAAAACXBtdEFtb3VudAUAAAANcHJpY2VEZWNpbWFscwUAAAARc2VsbEFzc2V0VXNkUHJpY2UEAAAAFnRvdGFsTGVuZGVkQXRPdGhlckFjY3MJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwkBAAAAGWtleVRvdGFsTGVuZGVkQXRPdGhlckFjY3MAAAAAAAAAAAAAAAAABAAAABpsZW5kZWRBbW91bnRCeUFzc2V0Q29kZUtleQkBAAAAGmtleUxlbmRlZEFtb3VudEJ5QXNzZXRDb2RlAAAAAQUAAAAUc2VsbEFzc2V0Q29kZUNvbmZpcm0EAAAAFGxlbmRlZEFtdEJ5QXNzZXRDb2RlCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAGmxlbmRlZEFtb3VudEJ5QXNzZXRDb2RlS2V5AAAAAAAAAAAABAAAABdzZWxsQXNzZXRTZWxsRmVlUGVyY2VudAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAADHNlbGxBc3NldENmZwUAAAARSWR4U2VsbEZlZVBlcmNlbnQEAAAAD2Nyb3NzRmVlUGVyY2VudAkAAGsAAAADCQAAZAAAAAIFAAAADWJ1eUZlZVBlcmNlbnQFAAAAF3NlbGxBc3NldFNlbGxGZWVQZXJjZW50BQAAABhjcm9zc0V4Y2hhbmdlQ29lZmZpY2llbnQFAAAADXByaWNlRGVjaW1hbHMEAAAADmJ1eUFzc2V0UmVzdWx0CQEAAAAQaW50ZXJuYWxCdXlBc3NldAAAAAcIBQAAAAFpAAAABmNhbGxlcgUAAAAJcG10QW1vdW50BQAAAAhwbXRBc3NldAUAAAAKbWluU2VsbFBtdAUAAAANYnV5MnNlbGxQcmljZQUAAAAPY3Jvc3NGZWVQZXJjZW50BQAAABJwcm90b2NvbEZlZVBlcmNlbnQJAARNAAAAAgkABE0AAAACCQAETQAAAAIJAARNAAAAAggFAAAADmJ1eUFzc2V0UmVzdWx0AAAAAl8xCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADBQAAABNzZWxsQXNzZXRBY2NBZGRyZXNzBQAAAAh1c2RuRGVidAUAAAALZGVidEFzc2V0SWQJAQAAAA5TY3JpcHRUcmFuc2ZlcgAAAAMFAAAAE3NlbGxBc3NldEFjY0FkZHJlc3MJAABlAAAAAgUAAAAJcG10QW1vdW50CAUAAAAOYnV5QXNzZXRSZXN1bHQAAAACXzIFAAAACHBtdEFzc2V0CQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAabGVuZGVkQW1vdW50QnlBc3NldENvZGVLZXkJAABkAAAAAgUAAAAUbGVuZGVkQW10QnlBc3NldENvZGUFAAAACHVzZG5EZWJ0CQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAGWtleVRvdGFsTGVuZGVkQXRPdGhlckFjY3MAAAAACQAAZAAAAAIFAAAAFnRvdGFsTGVuZGVkQXRPdGhlckFjY3MFAAAACHVzZG5EZWJ0AAAAAWkBAAAADnJlYmFsYW5jZURlYnRzAAAAAAQAAAAIZGVidFBtdDAJAQAAAAV2YWx1ZQAAAAEJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAEAAAADWRlYnRQbXRBc3NldDAJAQAAAAV2YWx1ZQAAAAEIBQAAAAhkZWJ0UG10MAAAAAdhc3NldElkBAAAAAhiYXNlUG10MQkBAAAABXZhbHVlAAAAAQkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAQQAAAANYmFzZVBtdEFzc2V0MQkBAAAABXZhbHVlAAAAAQgFAAAACGJhc2VQbXQxAAAAB2Fzc2V0SWQEAAAADWRlYnRvckFkZHJlc3MJAAQlAAAAAQgFAAAAAWkAAAAGY2FsbGVyBAAAAA5kZWJ0b3JBc3NldENmZwkBAAAAHGZhY3RvcnlSZWFkQXNzZXRDZmdCeUFkZHJlc3MAAAABBQAAAA1kZWJ0b3JBZGRyZXNzBAAAAA9kZWJ0b3JBc3NldENvZGUJAAGRAAAAAgUAAAAOZGVidG9yQXNzZXRDZmcFAAAAEElkeERlZm9Bc3NldENvZGUEAAAAGmxlbmRlZEFtb3VudEJ5QXNzZXRDb2RlS2V5CQEAAAAaa2V5TGVuZGVkQW1vdW50QnlBc3NldENvZGUAAAABBQAAAA9kZWJ0b3JBc3NldENvZGUEAAAACWxlbmRlZEFtdAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAGmxlbmRlZEFtb3VudEJ5QXNzZXRDb2RlS2V5CQABLAAAAAICAAAADU5vIGRlYnRzIGZvciAFAAAAD2RlYnRvckFzc2V0Q29kZQMFAAAACWlzQmxvY2tlZAkAAAIAAAABAgAAAFpjb250cmFjdCBpcyBibG9ja2VkIGJ5IEVNRVJHRU5DWSBTSFVURE9XTiBhY3Rpb25zIHVudGlsbCByZWFjdGl2YXRpb24gYnkgZW1lcmdlbmN5IG9yYWNsZXMDCQEAAAACIT0AAAACBQAAAAtkZWJ0QXNzZXRJZAUAAAANZGVidFBtdEFzc2V0MAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAADRpbnZhbGlkIGRlYnQgYXNzZXQgaWQgaW4gdGhlIGZpcnN0IHBheW1ldDogZXhwZWN0ZWQ9CQACWAAAAAEFAAAAC2RlYnRBc3NldElkAgAAAAggYWN0dWFsPQkAAlgAAAABBQAAAA1kZWJ0UG10QXNzZXQwAwkBAAAAAiE9AAAAAgUAAAALYmFzZUFzc2V0SWQFAAAADWJhc2VQbXRBc3NldDEJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAA2aW52YWxpZCBiYXNlIGFzc2V0IGlkIGluIHRoZSBzZWNvbmQgcGF5bWVudDogZXhwZWN0ZWQ9CQACWAAAAAEFAAAAC2Jhc2VBc3NldElkAgAAAAggYWN0dWFsPQkAAlgAAAABBQAAAA1iYXNlUG10QXNzZXQxAwkBAAAAAiE9AAAAAggFAAAACGRlYnRQbXQwAAAABmFtb3VudAgFAAAACGJhc2VQbXQxAAAABmFtb3VudAkAAAIAAAABAgAAAD9maXJzdCBwYXltZW50IGFtb3VudCBkb2Vzbid0IG1hdGNoIHRvIHRoZSBzZWNvbmQgcGF5bWVudCBhbW91bnQDCQAAZwAAAAIAAAAAAAAAAAAFAAAACWxlbmRlZEFtdAkAAAIAAAABCQABLAAAAAICAAAAJ2xlbmRlZEFtdCBpcyBsZXNzIHRoZW4gemVybzogbGVuZGVkQW10PQkAAaQAAAABBQAAAAlsZW5kZWRBbXQDCQAAZwAAAAIJAABoAAAAAgAAAAAAAAAAZAUAAAANcHJpY2VEZWNpbWFscwgFAAAACGRlYnRQbXQwAAAABmFtb3VudAkAAAIAAAABCQABLAAAAAICAAAAN2F0dGFjaGVkIHBheW1lbnQgbXVzdCBiZSBncmVhdGVyIHRoZW4gMTAwOiBwbXQwLmFtb3VudD0JAAGkAAAAAQgFAAAACGRlYnRQbXQwAAAABmFtb3VudAMJAABmAAAAAggFAAAACGRlYnRQbXQwAAAABmFtb3VudAUAAAAJbGVuZGVkQW10CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAANGF0dGFjaGVkIHBheW1lbnQgaXMgZ3JhdGVyIHRoYW4gcmVxdWlyZWQ6IHBtdEFtb3VudD0JAAGkAAAAAQgFAAAACGRlYnRQbXQwAAAABmFtb3VudAIAAAALIGxlbmRlZEFtdD0JAAGkAAAAAQUAAAAJbGVuZGVkQW10BAAAABZ0b3RhbExlbmRlZEF0T3RoZXJBY2NzCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAABlrZXlUb3RhbExlbmRlZEF0T3RoZXJBY2NzAAAAAAAAAAAAAAAAAAQAAAAObGVuZGVkQW10QWZ0ZXIJAABlAAAAAgUAAAAJbGVuZGVkQW10CAUAAAAIZGVidFBtdDAAAAAGYW1vdW50CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABpsZW5kZWRBbW91bnRCeUFzc2V0Q29kZUtleQUAAAAObGVuZGVkQW10QWZ0ZXIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABlrZXlUb3RhbExlbmRlZEF0T3RoZXJBY2NzAAAAAAkAAGUAAAACBQAAABZ0b3RhbExlbmRlZEF0T3RoZXJBY2NzCAUAAAAIZGVidFBtdDAAAAAGYW1vdW50CQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAAEsAAAAAgIAAAAWJXMlc19fcmViYWxhbmNlVHJhY2VfXwkAAlgAAAABCAUAAAABaQAAAA10cmFuc2FjdGlvbklkCQEAAAAXYXNzZXREYXRhUmViYWxhbmNlVHJhY2UAAAAFBQAAAA9kZWJ0b3JBc3NldENvZGUFAAAACGRlYnRQbXQwBQAAAAhiYXNlUG10MQUAAAAJbGVuZGVkQW10BQAAAA5sZW5kZWRBbXRBZnRlcgUAAAADbmlsAAAAAWkBAAAAFGZ1bGZpbGxSZWRlZW1SZXF1ZXN0AAAAAQAAABBwb29sTWFrZXJBZGRyZXNzBAAAAA50aGlzQWRkcmVzc1N0cgkABCUAAAABBQAAAAR0aGlzBAAAABhwb29sTWFrZXJVbmxvY2tIZWlnaHRLZXkJAQAAAB9rZXlGYWN0b3J5UG9vbE1ha2VyVW5sb2NrSGVpZ2h0AAAAAgUAAAAOdGhpc0FkZHJlc3NTdHIFAAAAEHBvb2xNYWtlckFkZHJlc3MEAAAAFXBvb2xNYWtlclVubG9ja0hlaWdodAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAApmYWN0b3J5QWNjBQAAABhwb29sTWFrZXJVbmxvY2tIZWlnaHRLZXkAAAAAAAAAAAADCQAAZwAAAAIAAAAAAAAAAAAFAAAAFXBvb2xNYWtlclVubG9ja0hlaWdodAkAAAIAAAABAgAAAB9BbGwgbGlxdWlkaXR5IHJlcXVlc3QgZnVsZmlsbGVkBAAAABxwb29sTWFrZXJMaXF1aWRpdHlSZXF1ZXN0S2V5CQEAAAAja2V5RmFjdG9yeVBvb2xNYWtlckxpcXVpZGl0eVJlcXVlc3QAAAADBQAAAA50aGlzQWRkcmVzc1N0cgUAAAAQcG9vbE1ha2VyQWRkcmVzcwUAAAAVcG9vbE1ha2VyVW5sb2NrSGVpZ2h0BAAAAB9wb29sTWFrZXJMaXF1aWRpdHlSZXF1ZXN0QW1vdW50CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAKZmFjdG9yeUFjYwUAAAAccG9vbE1ha2VyTGlxdWlkaXR5UmVxdWVzdEtleQIAAAAxRW1wdHkgcG9vbE1ha2VyTGlxdWlkaXR5UmVxdWVzdEtleSBhdCBmYWN0b3J5IGFjYwMJAQAAAAlpc0RlZmluZWQAAAABCQAEGgAAAAIFAAAABHRoaXMFAAAAHHBvb2xNYWtlckxpcXVpZGl0eVJlcXVlc3RLZXkJAAACAAAAAQIAAAAsTGlxdWlkaXR5IHJlcXVlc3QgaGFzIGJlZW4gYWxyZWFkeSBmdWxmaWxsZWQJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIFAAAAHHBvb2xNYWtlckxpcXVpZGl0eVJlcXVlc3RLZXkFAAAAH3Bvb2xNYWtlckxpcXVpZGl0eVJlcXVlc3RBbW91bnQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAAKZmFjdG9yeUFjYwUAAAAfcG9vbE1ha2VyTGlxdWlkaXR5UmVxdWVzdEFtb3VudAUAAAALYmFzZUFzc2V0SWQFAAAAA25pbAAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAAEAAAAByRtYXRjaDAFAAAAAnR4AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAABdJbnZva2VTY3JpcHRUcmFuc2FjdGlvbgQAAAADaW52BQAAAAckbWF0Y2gwAwkAAGYAAAACCAUAAAADaW52AAAAA2ZlZQkAAGgAAAACAAAAAAAAAAOEAAAAAAAAAAPoCQAAAgAAAAEJAAEsAAAAAgIAAAAoZmVlIGFtb3VudCBpcyBncmVhdGVyIHRoYW4gbWF4IGFsbG93ZWQ6IAkAAaQAAAABCAUAAAADaW52AAAAA2ZlZQMJAQAAAAlpc0RlZmluZWQAAAABCAUAAAADaW52AAAACmZlZUFzc2V0SWQJAAACAAAAAQIAAAAjb25seSBXYXZlcyBpcyBhbGxvd2VkIGFzIGZlZUFzc2V0SWQDCQAAAAAAAAIIBQAAAANpbnYAAAAIZnVuY3Rpb24CAAAADnJlYmFsYW5jZURlYnRzBAAAAA5pbnZEYXBwQWRkcmVzcwkABCUAAAABCQAEJAAAAAEIBQAAAANpbnYAAAAEZEFwcAMJAQAAAAIhPQAAAAIJAAGRAAAAAgkBAAAAHGZhY3RvcnlSZWFkQXNzZXRDZmdCeUFkZHJlc3MAAAABBQAAAA5pbnZEYXBwQWRkcmVzcwUAAAASSWR4RGVmb0Fzc2V0U3RhdHVzAgAAAAZJU1NVRUQJAAACAAAAAQIAAAAZb25seSBkZWZvIGRhcHAgaXMgYWxsb3dlZAMJAAAAAAAAAgUAAAAOaW52RGFwcEFkZHJlc3MJAAQlAAAAAQUAAAAEdGhpcwkAAAIAAAABAgAAACVpbXBvc3NpYmxlIHRvIGNhbGwgc2VsZiByZWJlYWxuY2VEZWJ0BgMDAwkAAAAAAAACCAUAAAADaW52AAAACGZ1bmN0aW9uAgAAAAxsb2NrTmV1dHJpbm8GCQAAAAAAAAIIBQAAAANpbnYAAAAIZnVuY3Rpb24CAAAADmxvY2tOZXV0cmlub1NQBgkAAAAAAAACCAUAAAADaW52AAAACGZ1bmN0aW9uAgAAAA51bmxvY2tOZXV0cmlubwMJAQAAAAIhPQAAAAIJAAQlAAAAAQUAAAASbmV1dHJpbm9TdGFraW5nQWNjCQAEJQAAAAEJAAQkAAAAAQgFAAAAA2ludgAAAARkQXBwCQAAAgAAAAECAAAAJWludmFsaWQgbmV1dHJpbm8gc3Rha2luZyBkYXBwIGFkZHJlc3MJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAACQEAAAAiZmFjdG9yeVJlYWREZWZvU3Rha2luZ1BhY2VtYWtlclB1YgAAAAAJAAACAAAAAQIAAAAjTm90IGFsbG93ZWQgaW52b2NhdGlvbiBtZXRob2QgY2FsbHMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAACAUAAAACdHgAAAAPc2VuZGVyUHVibGljS2V5MxvBEw==", "chainId": 87, "height": 2578395, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: EoH2FG9DC8Jo3McV9Mkgus5USkCvr58XNywYxDqkX27a Next: 5R4cUac1ZWemCDd9qa9p1DpxsFV6tP68VQMfBDiCeatj Diff:
OldNewDifferences
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func keyAccumulatedFee () = "%s__accumulatedFee"
5+
6+
7+func keyAccumulatedProtocolFee () = "%s__accumulatedProtocolFee"
58
69
710 func keyUcollateral () = "%s__ucollateral"
3841
3942 let IdxOperationAssetOut = 5
4043
41-func assetDataSwapOperation (amountIn,assetIn,price,amountOut,assetOut,bruttoAmount,feeAmount) = makeString(["%d%s%d%s%d%d%d", toString(amountIn), assetIn, toString(amountOut), assetOut, toString(price), toString(bruttoAmount), toString(feeAmount)], "__")
44+func assetDataSwapOperation (amountIn,assetIn,price,amountOut,assetOut,bruttoAmount,feeAmount,protocolFeeAmount) = makeString(["%d%s%d%s%d%d%d%d", toString(amountIn), assetIn, toString(amountOut), assetOut, toString(price), toString(bruttoAmount), toString(feeAmount), toString(protocolFeeAmount)], "__")
4245
4346
4447 func assetDataRebalanceTrace (debtorAssetCode,debtPmt,basePmt,lendedAmtBefore,lendedAmtAfter) = makeString(["%s%s%d%s%d%d%d", debtorAssetCode, toBase58String(value(debtPmt.assetId)), toString(debtPmt.amount), toBase58String(value(basePmt.assetId)), toString(basePmt.amount), toString(lendedAmtBefore), toString(lendedAmtAfter)], "__")
5558 let nullStr = "NULL"
5659
5760 let factoryAcc = addressFromStringValue(valueOrErrorMessage(getString(this, keyFactory()), ((("No config at this=" + toString(this)) + " for key=") + keyFactory())))
61+
62+func keyFactoryNeutrinoContractAddressKey () = "%s%s__commonConfig__neutrinoContractAddress"
63+
5864
5965 func keyFactoryDebtAssetId () = "%s%s__commonConfig__debtAssetId"
6066
143149
144150 let IdxPoolStabilityFeePart = 21
145151
152+let IdxProtocolFeePercent = 22
153+
146154 let thisCfgArray = factoryReadAssetCfgByAddress(toString(this))
147155
148156 let defoAssetCode = thisCfgArray[IdxDefoAssetCode]
185193
186194 let poolStabilityFeePart = parseIntValue(thisCfgArray[IdxPoolStabilityFeePart])
187195
196+let protocolFeePercent = parseIntValue(thisCfgArray[IdxProtocolFeePercent])
197+
188198 func keyIsBlocked () = "%s__isBlocked"
189199
190200
220230
221231 let isBlockedByLastHeight = ((height - priceLastHeight) > 5)
222232
233+func keyFeesManagerAddressKey () = "fees_manager_address"
234+
235+
236+let neutrinoMainAcc = addressFromStringValue(valueOrErrorMessage(getString(factoryAcc, keyFactoryNeutrinoContractAddressKey()), ((("No config at factory=" + toString(factoryAcc)) + " for key=") + keyFactoryNeutrinoContractAddressKey())))
237+
238+let feeManagerAddress = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(neutrinoMainAcc, keyFeesManagerAddressKey()), (keyFeesManagerAddressKey() + " is not specified"))), (keyFeesManagerAddressKey() + " invalid address format"))
239+
223240 let keyDefoStakingAddress = "%s%s__commonConfig__defoStakingAddress"
224241
225242 let keyNeutrinoStakingAddress = "%s%s__commonConfig__neutrinoStakingAddress"
243260 let ucollateral = valueOrElse(getInteger(this, keyUcollateral()), 0)
244261
245262 let accumulatedFee = valueOrElse(getInteger(this, keyAccumulatedFee()), 0)
263+
264+let accumulatedProtocolFee = valueOrElse(getInteger(this, keyAccumulatedProtocolFee()), 0)
246265
247266 let currPoolAmount = getIntegerValue(factoryAcc, keyFactoryAssetCurrentPool(this))
248267
268287 else buyFeePercent
269288
270289
290+func getProtocolFeeConsideringStakingReferral (callerPub58Str) = if ((assetStakingReferralPublicStr == callerPub58Str))
291+ then 0
292+ else protocolFeePercent
293+
294+
271295 func getBuyPriceConsideringStakingReferral (changeCoeff,callerPub58Str) = if ((assetStakingReferralPublicStr == callerPub58Str))
272296 then controlPrice
273297 else getBuyPrice(changeCoeff)
283307 else fraction((priceDecimals + changeCoeff), fromPrice, priceDecimals)
284308
285309
286-func internalBuyAsset (sellerAddr,sellAmt,sellAssetId,minSellAmt,buy2sellPrice,poolMakersFeePart) = {
310+func internalBuyAsset (sellerAddr,sellAmt,sellAssetId,minSellAmt,buy2sellPrice,poolMakersFeePart,protocolFeePart) = {
287311 let defoAssetAmountGross = fraction(sellAmt, buy2sellPrice, priceDecimals)
288312 let stabilityFeeDefoAmount = fraction(poolStabilityFeePart, defoAssetAmountGross, priceDecimals)
289313 let poolMakersFeeDefoAmount = fraction(poolMakersFeePart, defoAssetAmountGross, priceDecimals)
290- let defoAssetAmount = ((defoAssetAmountGross - stabilityFeeDefoAmount) - poolMakersFeeDefoAmount)
314+ let protocolFeeDefoAmount = fraction(protocolFeePart, defoAssetAmountGross, priceDecimals)
315+ let defoAssetAmount = (((defoAssetAmountGross - stabilityFeeDefoAmount) - poolMakersFeeDefoAmount) - protocolFeeDefoAmount)
291316 let requiredBasicAssetAmount = fraction(defoAssetAmountGross, priceDecimals, buy2sellPrice)
292317 let change = (sellAmt - requiredBasicAssetAmount)
293318 if (if ((minSellAmt > sellAmt))
294319 then (toString(sellerAddr) != toString(defoStakingAcc))
295320 else false)
296321 then throw(((((("impossible to issue new " + defoAssetCode) + ": payment=") + toString(sellAmt)) + "is less then min amount=") + toString(minSellAmt)))
297- else $Tuple2([IntegerEntry(keyUcollateral(), (ucollateral + requiredBasicAssetAmount)), StringEntry(keyAccountOperation(height, toString(sellerAddr), "FINISHED"), assetDataSwapOperation(sellAmt, toBase58String(sellAssetId), controlPrice, defoAssetAmount, toBase58String(defoAssetId), defoAssetAmountGross, poolMakersFeeDefoAmount)), Reissue(defoAssetId, (defoAssetAmount + poolMakersFeeDefoAmount), true), ScriptTransfer(sellerAddr, defoAssetAmount, defoAssetId), ScriptTransfer(sellerAddr, change, sellAssetId), ScriptTransfer(factoryReadNextPoolMakerToDistributeFee(toString(this)), poolMakersFeeDefoAmount, defoAssetId), IntegerEntry(keyAccumulatedFee(), (accumulatedFee + poolMakersFeeDefoAmount))], change)
322+ else $Tuple2([IntegerEntry(keyUcollateral(), (ucollateral + requiredBasicAssetAmount)), StringEntry(keyAccountOperation(height, toString(sellerAddr), "FINISHED"), assetDataSwapOperation(sellAmt, toBase58String(sellAssetId), controlPrice, defoAssetAmount, toBase58String(defoAssetId), defoAssetAmountGross, poolMakersFeeDefoAmount, protocolFeeDefoAmount)), Reissue(defoAssetId, ((defoAssetAmount + poolMakersFeeDefoAmount) + protocolFeeDefoAmount), true), ScriptTransfer(sellerAddr, defoAssetAmount, defoAssetId), ScriptTransfer(sellerAddr, change, sellAssetId), ScriptTransfer(factoryReadNextPoolMakerToDistributeFee(toString(this)), poolMakersFeeDefoAmount, defoAssetId), ScriptTransfer(feeManagerAddress, protocolFeeDefoAmount, defoAssetId), IntegerEntry(keyAccumulatedFee(), (accumulatedFee + poolMakersFeeDefoAmount)), IntegerEntry(keyAccumulatedProtocolFee(), (accumulatedProtocolFee + protocolFeeDefoAmount))], change)
298323 }
299324
300325
309334 then throw(((("last price finalization has been more then 5 blocks ago: priceLastHeight=" + toString(priceLastHeight)) + " currHeight=") + toString(height)))
310335 else if ((pmtAssetId != baseAssetId))
311336 then throw(((("Payment asset id doesn't match basic asset: expected=" + toBase58String(baseAssetId)) + " actual=") + toBase58String(pmtAssetId)))
312- else internalBuyAsset(i.caller, pmt.amount, pmtAssetId, minBasicBuyAmount, getBuyPriceConsideringStakingReferral(weekendsPriceChangeCoefficient, callerPub58Str), getBuyFeeConsideringStakingReferral(callerPub58Str))._1
337+ else internalBuyAsset(i.caller, pmt.amount, pmtAssetId, minBasicBuyAmount, getBuyPriceConsideringStakingReferral(weekendsPriceChangeCoefficient, callerPub58Str), getBuyFeeConsideringStakingReferral(callerPub58Str), getProtocolFeeConsideringStakingReferral(callerPub58Str))._1
313338 }
314339
315340
337362 let change = (pmt.amount - soldDefoAssetAmountGross)
338363 let stabilityFeeDefoAmount = fraction(poolStabilityFeePart, soldDefoAssetAmountGross, priceDecimals)
339364 let poolMakersFeeDefoAmount = fraction(sellFeePercent, soldDefoAssetAmountGross, priceDecimals)
340- let soldDefoAssetAmount = ((soldDefoAssetAmountGross - stabilityFeeDefoAmount) - poolMakersFeeDefoAmount)
365+ let protocolFeeDefoAmount = fraction(protocolFeePercent, soldDefoAssetAmountGross, priceDecimals)
366+ let soldDefoAssetAmount = (((soldDefoAssetAmountGross - stabilityFeeDefoAmount) - poolMakersFeeDefoAmount) - protocolFeeDefoAmount)
341367 let baseAssetAmountToSend = fraction(soldDefoAssetAmount, priceDecimals, sellPrice)
342-[IntegerEntry(keyUcollateral(), (ucollateral - baseAssetAmountToSend)), StringEntry(keyAccountOperation(height, callerAddress, "FINISHED"), assetDataSwapOperation(pmt.amount, toBase58String(pmtAsset), sellPrice, baseAssetAmountToSend, baseAssetIdStr, soldDefoAssetAmountGross, poolMakersFeeDefoAmount)), Burn(defoAssetId, (soldDefoAssetAmount + stabilityFeeDefoAmount)), ScriptTransfer(i.caller, baseAssetAmountToSend, baseAssetId), ScriptTransfer(i.caller, change, defoAssetId), ScriptTransfer(factoryReadNextPoolMakerToDistributeFee(toString(this)), poolMakersFeeDefoAmount, defoAssetId), IntegerEntry(keyAccumulatedFee(), (accumulatedFee + poolMakersFeeDefoAmount))]
368+[IntegerEntry(keyUcollateral(), (ucollateral - baseAssetAmountToSend)), StringEntry(keyAccountOperation(height, callerAddress, "FINISHED"), assetDataSwapOperation(pmt.amount, toBase58String(pmtAsset), sellPrice, baseAssetAmountToSend, baseAssetIdStr, soldDefoAssetAmountGross, poolMakersFeeDefoAmount, protocolFeeDefoAmount)), Burn(defoAssetId, (soldDefoAssetAmount + stabilityFeeDefoAmount)), ScriptTransfer(i.caller, baseAssetAmountToSend, baseAssetId), ScriptTransfer(i.caller, change, defoAssetId), ScriptTransfer(feeManagerAddress, protocolFeeDefoAmount, defoAssetId), ScriptTransfer(factoryReadNextPoolMakerToDistributeFee(toString(this)), poolMakersFeeDefoAmount, defoAssetId), IntegerEntry(keyAccumulatedFee(), (accumulatedFee + poolMakersFeeDefoAmount)), IntegerEntry(keyAccumulatedProtocolFee(), (accumulatedProtocolFee + protocolFeeDefoAmount))]
343369 }
344370 }
345371
383409 let lendedAmtByAssetCode = valueOrElse(getInteger(this, lendedAmountByAssetCodeKey), 0)
384410 let sellAssetSellFeePercent = parseIntValue(sellAssetCfg[IdxSellFeePercent])
385411 let crossFeePercent = fraction((buyFeePercent + sellAssetSellFeePercent), crossExchangeCoefficient, priceDecimals)
386- let buyAssetResult = internalBuyAsset(i.caller, pmtAmount, pmtAsset, minSellPmt, buy2sellPrice, crossFeePercent)
412+ let buyAssetResult = internalBuyAsset(i.caller, pmtAmount, pmtAsset, minSellPmt, buy2sellPrice, crossFeePercent, protocolFeePercent)
387413 ((((buyAssetResult._1 :+ ScriptTransfer(sellAssetAccAddress, usdnDebt, debtAssetId)) :+ ScriptTransfer(sellAssetAccAddress, (pmtAmount - buyAssetResult._2), pmtAsset)) :+ IntegerEntry(lendedAmountByAssetCodeKey, (lendedAmtByAssetCode + usdnDebt))) :+ IntegerEntry(keyTotalLendedAtOtherAccs(), (totalLendedAtOtherAccs + usdnDebt)))
388414 }
389415 }
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 4 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
44 func keyAccumulatedFee () = "%s__accumulatedFee"
5+
6+
7+func keyAccumulatedProtocolFee () = "%s__accumulatedProtocolFee"
58
69
710 func keyUcollateral () = "%s__ucollateral"
811
912
1013 func keyTotalLendedAtOtherAccs () = "%s__totalLendedAtOtherAccs"
1114
1215
1316 func keyAssetLockedTotal (assetId) = ("%s%s__assetLockedTotal__" + assetId)
1417
1518
1619 func keyAccountOperation (unlockHeight,address,status) = ((((("%s%s%d%s__defoAssetOperation__" + address) + "__") + toString(unlockHeight)) + "__") + status)
1720
1821
1922 func keyFactory () = "%s__factory"
2023
2124
2225 func keyLendedAmountByAssetCode (assetCode) = ("%s%s__lendedBaseAssetAmount__" + assetCode)
2326
2427
2528 func keyPrice (assetCode) = ("%s%s__price__" + assetCode)
2629
2730
2831 func keyControlLastHeight (assetCode) = ("%s%s__lastHeight__" + assetCode)
2932
3033
3134 let IdxOperationAmountIn = 1
3235
3336 let IdxOperationAssetIn = 2
3437
3538 let IdxOperationPrice = 3
3639
3740 let IdxOperationAmountOut = 4
3841
3942 let IdxOperationAssetOut = 5
4043
41-func assetDataSwapOperation (amountIn,assetIn,price,amountOut,assetOut,bruttoAmount,feeAmount) = makeString(["%d%s%d%s%d%d%d", toString(amountIn), assetIn, toString(amountOut), assetOut, toString(price), toString(bruttoAmount), toString(feeAmount)], "__")
44+func assetDataSwapOperation (amountIn,assetIn,price,amountOut,assetOut,bruttoAmount,feeAmount,protocolFeeAmount) = makeString(["%d%s%d%s%d%d%d%d", toString(amountIn), assetIn, toString(amountOut), assetOut, toString(price), toString(bruttoAmount), toString(feeAmount), toString(protocolFeeAmount)], "__")
4245
4346
4447 func assetDataRebalanceTrace (debtorAssetCode,debtPmt,basePmt,lendedAmtBefore,lendedAmtAfter) = makeString(["%s%s%d%s%d%d%d", debtorAssetCode, toBase58String(value(debtPmt.assetId)), toString(debtPmt.amount), toBase58String(value(basePmt.assetId)), toString(basePmt.amount), toString(lendedAmtBefore), toString(lendedAmtAfter)], "__")
4548
4649
4750 func assetReadSwapDataArrayOrFail (accOperationKey) = {
4851 let accOperationDataStr = valueOrErrorMessage(getString(this, accOperationKey), ("There is no request for passed arguments: " + accOperationKey))
4952 split(accOperationDataStr, "__")
5053 }
5154
5255
5356 let nullInt = -1
5457
5558 let nullStr = "NULL"
5659
5760 let factoryAcc = addressFromStringValue(valueOrErrorMessage(getString(this, keyFactory()), ((("No config at this=" + toString(this)) + " for key=") + keyFactory())))
61+
62+func keyFactoryNeutrinoContractAddressKey () = "%s%s__commonConfig__neutrinoContractAddress"
63+
5864
5965 func keyFactoryDebtAssetId () = "%s%s__commonConfig__debtAssetId"
6066
6167
6268 func keyFactoryDebtAssetEtalonBalance () = "%s%s__commonConfig__debtAssetEtalonBalance"
6369
6470
6571 func keyFactoryAssetCfg (assetAddressStr) = (("%s%s%s__defoAsset__" + assetAddressStr) + "__config")
6672
6773
6874 func keyFactoryAssetCurrentPool (assetAccAddress) = (("%s%s%s__defoAsset__" + toString(assetAccAddress)) + "__currentPool")
6975
7076
7177 func keyFactoryDefoAddressByAssetCode (assetCode) = (("%s%s%s__defoAsset__" + assetCode) + "__addressByAssetCode")
7278
7379
7480 func keyFactoryAssetPoolMakers (assetAddress) = (("%s%s%s__defoAsset__" + assetAddress) + "__poolMakers")
7581
7682
7783 func keyFactoryDefoStakingPacemakerPub () = "%s%s__commonConfig__defoStakingPacemakerPub"
7884
7985
8086 func keyFactoryPoolMakerLiquidityRequest (assetAddress,poolMakerAddress,h) = makeString(["%s%s%s%d%s__pool", assetAddress, poolMakerAddress, toString(h), "liquidityRequest"], "__")
8187
8288
8389 func keyFactoryPoolMakerUnlockHeight (assetAddress,poolMakerAddress) = makeString(["%s%s%s%s__pool", assetAddress, poolMakerAddress, "unlockHeight"], "__")
8490
8591
8692 func factoryReadDebtAssetId () = valueOrErrorMessage(getString(factoryAcc, keyFactoryDebtAssetId()), ((("No config at factory=" + toString(factoryAcc)) + " for key=") + keyFactoryDebtAssetId()))
8793
8894
8995 func factoryReadAssetCfgByAddress (assetAddressStr) = split(valueOrErrorMessage(getString(factoryAcc, keyFactoryAssetCfg(assetAddressStr)), ((("No config at factory=" + toString(factoryAcc)) + " for key=") + keyFactoryAssetCfg(assetAddressStr))), "__")
9096
9197
9298 func factoryReadAssetCfgByCode (assetCode) = {
9399 let assetAddressStr = valueOrErrorMessage(getString(factoryAcc, keyFactoryDefoAddressByAssetCode(assetCode)), ((("No config at factory=" + toString(factoryAcc)) + " for key=") + keyFactoryDefoAddressByAssetCode(assetCode)))
94100 $Tuple2(assetAddressStr, factoryReadAssetCfgByAddress(assetAddressStr))
95101 }
96102
97103
98104 func factoryReadNextPoolMakerToDistributeFee (assetAddressStr) = addressFromStringValue("3PEs19bv4qT4Gz5idjcWynkQyrH9psGipmw")
99105
100106
101107 func factoryReadDefoStakingPacemakerPub () = fromBase58String(valueOrErrorMessage(getString(factoryAcc, keyFactoryDefoStakingPacemakerPub()), ((("No config at factory=" + toString(factoryAcc)) + " for key=") + keyFactoryDefoStakingPacemakerPub())))
102108
103109
104110 let IdxDefoAssetCode = 1
105111
106112 let IdxDefoAssetId = 2
107113
108114 let IdxDefoAssetStatus = 3
109115
110116 let IdxPriceDecimals = 4
111117
112118 let IdxBaseAssetId = 5
113119
114120 let IdxOverCollateralPercent = 6
115121
116122 let IdxMinInitPool = 7
117123
118124 let IdxPriceOracleAddress = 8
119125
120126 let IdxMinBuyPayment = 9
121127
122128 let IdxMinSellPayment = 10
123129
124130 let IdxBuyLockInterval = 11
125131
126132 let IdxSellLockInterval = 12
127133
128134 let IdxBuyFeePercent = 13
129135
130136 let IdxSellFeePercent = 14
131137
132138 let IdxPoolRedemptionTimeout = 15
133139
134140 let IdxWeekendsPriceChangeCoefficient = 16
135141
136142 let IdxAssetAccountPublicStr = 17
137143
138144 let IdxAssetStakingReferralPublicStr = 18
139145
140146 let IdxCrossExchangeCoefficient = 19
141147
142148 let IdxStakingMinAmtFromSellCoefficient = 20
143149
144150 let IdxPoolStabilityFeePart = 21
145151
152+let IdxProtocolFeePercent = 22
153+
146154 let thisCfgArray = factoryReadAssetCfgByAddress(toString(this))
147155
148156 let defoAssetCode = thisCfgArray[IdxDefoAssetCode]
149157
150158 let defoAssetIdStr = thisCfgArray[IdxDefoAssetId]
151159
152160 let defoAssetId = fromBase58String(defoAssetIdStr)
153161
154162 let priceOracleAcc = addressFromStringValue(thisCfgArray[IdxPriceOracleAddress])
155163
156164 let overCollateralPercent = parseIntValue(thisCfgArray[IdxOverCollateralPercent])
157165
158166 let baseAssetIdStr = thisCfgArray[IdxBaseAssetId]
159167
160168 let baseAssetId = fromBase58String(baseAssetIdStr)
161169
162170 let priceDecimals = parseIntValue(thisCfgArray[IdxPriceDecimals])
163171
164172 let minBasicBuyAmount = parseIntValue(thisCfgArray[IdxMinBuyPayment])
165173
166174 let minSynthSellAmount = parseIntValue(thisCfgArray[IdxMinSellPayment])
167175
168176 let buyLockInterval = parseIntValue(thisCfgArray[IdxBuyLockInterval])
169177
170178 let sellLockInterval = parseIntValue(thisCfgArray[IdxSellLockInterval])
171179
172180 let buyFeePercent = parseIntValue(thisCfgArray[IdxBuyFeePercent])
173181
174182 let sellFeePercent = parseIntValue(thisCfgArray[IdxSellFeePercent])
175183
176184 let weekendsPriceChangeCoefficient = parseIntValue(thisCfgArray[IdxWeekendsPriceChangeCoefficient])
177185
178186 let assetAccountPublicStr = thisCfgArray[IdxAssetAccountPublicStr]
179187
180188 let assetStakingReferralPublicStr = thisCfgArray[IdxAssetStakingReferralPublicStr]
181189
182190 let crossExchangeCoefficient = parseIntValue(thisCfgArray[IdxCrossExchangeCoefficient])
183191
184192 let stakingMinAmtFromSellCoefficient = parseIntValue(thisCfgArray[IdxStakingMinAmtFromSellCoefficient])
185193
186194 let poolStabilityFeePart = parseIntValue(thisCfgArray[IdxPoolStabilityFeePart])
187195
196+let protocolFeePercent = parseIntValue(thisCfgArray[IdxProtocolFeePercent])
197+
188198 func keyIsBlocked () = "%s__isBlocked"
189199
190200
191201 func keyIsMarketOpened (assetCode) = ("%s%s__isMarketOpened__" + assetCode)
192202
193203
194204 let isBlocked = valueOrElse(getBoolean(priceOracleAcc, keyIsBlocked()), false)
195205
196206 let isMarketOpened = valueOrElse(getBoolean(priceOracleAcc, keyIsMarketOpened(defoAssetCode)), false)
197207
198208 func controlAccReadPrice (assetCode) = valueOrErrorMessage(getInteger(priceOracleAcc, keyPrice(assetCode)), ((("No price at priceOracle=" + toString(priceOracleAcc)) + " for key=") + keyPrice(assetCode)))
199209
200210
201211 func controlAccReadLastHeight (assetCode) = valueOrErrorMessage(getInteger(priceOracleAcc, keyControlLastHeight(assetCode)), ((("No lastHeight at priceOracle=" + toString(priceOracleAcc)) + " for key=") + keyControlLastHeight(assetCode)))
202212
203213
204214 func controlAccReadCurrIdxOrFail () = valueOrErrorMessage(getInteger(priceOracleAcc, "currIdx"), ("No currIdx at controlAcc=" + toString(priceOracleAcc)))
205215
206216
207217 func controlAccReadIdxHeight (idx) = {
208218 let idxHeightKey = ("idxHeight_" + toString(idx))
209219 valueOrElse(getInteger(priceOracleAcc, idxHeightKey), 0)
210220 }
211221
212222
213223 func controlAccReadPriceByHeight (priceHeight) = {
214224 let priceByHeightKey = ("price_" + toString(priceHeight))
215225 valueOrErrorMessage(getInteger(priceOracleAcc, priceByHeightKey), ((("No " + priceByHeightKey) + " at controlAcc=") + toString(priceOracleAcc)))
216226 }
217227
218228
219229 let priceLastHeight = controlAccReadLastHeight(defoAssetCode)
220230
221231 let isBlockedByLastHeight = ((height - priceLastHeight) > 5)
222232
233+func keyFeesManagerAddressKey () = "fees_manager_address"
234+
235+
236+let neutrinoMainAcc = addressFromStringValue(valueOrErrorMessage(getString(factoryAcc, keyFactoryNeutrinoContractAddressKey()), ((("No config at factory=" + toString(factoryAcc)) + " for key=") + keyFactoryNeutrinoContractAddressKey())))
237+
238+let feeManagerAddress = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(neutrinoMainAcc, keyFeesManagerAddressKey()), (keyFeesManagerAddressKey() + " is not specified"))), (keyFeesManagerAddressKey() + " invalid address format"))
239+
223240 let keyDefoStakingAddress = "%s%s__commonConfig__defoStakingAddress"
224241
225242 let keyNeutrinoStakingAddress = "%s%s__commonConfig__neutrinoStakingAddress"
226243
227244 func keyDefoStakingAssetBalance (assetId) = ("%s%s__stakingBalance__" + assetId)
228245
229246
230247 func keyNeutrinoStakingBalance () = ((("rpd_balance_" + baseAssetIdStr) + "_") + toString(this))
231248
232249
233250 let defoStakingAcc = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(factoryAcc, keyDefoStakingAddress), ((("No config at factoryAcc" + toString(factoryAcc)) + " for key=") + keyDefoStakingAddress))), ("address extraction error for key=" + keyDefoStakingAddress))
234251
235252 let neutrinoStakingAcc = valueOrErrorMessage(addressFromString(valueOrErrorMessage(getString(factoryAcc, keyNeutrinoStakingAddress), ((("No config at factoryAcc" + toString(factoryAcc)) + " for key=") + keyNeutrinoStakingAddress))), ("address extraction error for key=" + keyNeutrinoStakingAddress))
236253
237254 func getThisDefoStakingBalance () = valueOrElse(getInteger(defoStakingAcc, keyDefoStakingAssetBalance(defoAssetIdStr)), 0)
238255
239256
240257 func getThisNeutrinoStakingBalance () = valueOrElse(getInteger(neutrinoStakingAcc, keyNeutrinoStakingBalance()), 0)
241258
242259
243260 let ucollateral = valueOrElse(getInteger(this, keyUcollateral()), 0)
244261
245262 let accumulatedFee = valueOrElse(getInteger(this, keyAccumulatedFee()), 0)
263+
264+let accumulatedProtocolFee = valueOrElse(getInteger(this, keyAccumulatedProtocolFee()), 0)
246265
247266 let currPoolAmount = getIntegerValue(factoryAcc, keyFactoryAssetCurrentPool(this))
248267
249268 let debtAssetId = fromBase58String(factoryReadDebtAssetId())
250269
251270 let debtAssetEtalonBalance = getIntegerValue(factoryAcc, keyFactoryDebtAssetEtalonBalance())
252271
253272 let lendedOrDebtAmount = (debtAssetEtalonBalance - assetBalance(this, debtAssetId))
254273
255274 let currentBaseAssetBalance = ((assetBalance(this, baseAssetId) + getThisNeutrinoStakingBalance()) + lendedOrDebtAmount)
256275
257276 let controlPrice = controlAccReadPrice(thisCfgArray[IdxDefoAssetCode])
258277
259278 let emission = (value(assetInfo(defoAssetId)).quantity - assetBalance(this, defoAssetId))
260279
261280 func getBuyPrice (changeCoeff) = if (isMarketOpened)
262281 then controlPrice
263282 else fraction((priceDecimals - changeCoeff), controlPrice, priceDecimals)
264283
265284
266285 func getBuyFeeConsideringStakingReferral (callerPub58Str) = if ((assetStakingReferralPublicStr == callerPub58Str))
267286 then 0
268287 else buyFeePercent
269288
270289
290+func getProtocolFeeConsideringStakingReferral (callerPub58Str) = if ((assetStakingReferralPublicStr == callerPub58Str))
291+ then 0
292+ else protocolFeePercent
293+
294+
271295 func getBuyPriceConsideringStakingReferral (changeCoeff,callerPub58Str) = if ((assetStakingReferralPublicStr == callerPub58Str))
272296 then controlPrice
273297 else getBuyPrice(changeCoeff)
274298
275299
276300 func getSellPrice (changeCoeff) = if (isMarketOpened)
277301 then controlPrice
278302 else fraction((priceDecimals + changeCoeff), controlPrice, priceDecimals)
279303
280304
281305 func getSellPriceFrom (fromPrice,changeCoeff) = if (isMarketOpened)
282306 then fromPrice
283307 else fraction((priceDecimals + changeCoeff), fromPrice, priceDecimals)
284308
285309
286-func internalBuyAsset (sellerAddr,sellAmt,sellAssetId,minSellAmt,buy2sellPrice,poolMakersFeePart) = {
310+func internalBuyAsset (sellerAddr,sellAmt,sellAssetId,minSellAmt,buy2sellPrice,poolMakersFeePart,protocolFeePart) = {
287311 let defoAssetAmountGross = fraction(sellAmt, buy2sellPrice, priceDecimals)
288312 let stabilityFeeDefoAmount = fraction(poolStabilityFeePart, defoAssetAmountGross, priceDecimals)
289313 let poolMakersFeeDefoAmount = fraction(poolMakersFeePart, defoAssetAmountGross, priceDecimals)
290- let defoAssetAmount = ((defoAssetAmountGross - stabilityFeeDefoAmount) - poolMakersFeeDefoAmount)
314+ let protocolFeeDefoAmount = fraction(protocolFeePart, defoAssetAmountGross, priceDecimals)
315+ let defoAssetAmount = (((defoAssetAmountGross - stabilityFeeDefoAmount) - poolMakersFeeDefoAmount) - protocolFeeDefoAmount)
291316 let requiredBasicAssetAmount = fraction(defoAssetAmountGross, priceDecimals, buy2sellPrice)
292317 let change = (sellAmt - requiredBasicAssetAmount)
293318 if (if ((minSellAmt > sellAmt))
294319 then (toString(sellerAddr) != toString(defoStakingAcc))
295320 else false)
296321 then throw(((((("impossible to issue new " + defoAssetCode) + ": payment=") + toString(sellAmt)) + "is less then min amount=") + toString(minSellAmt)))
297- else $Tuple2([IntegerEntry(keyUcollateral(), (ucollateral + requiredBasicAssetAmount)), StringEntry(keyAccountOperation(height, toString(sellerAddr), "FINISHED"), assetDataSwapOperation(sellAmt, toBase58String(sellAssetId), controlPrice, defoAssetAmount, toBase58String(defoAssetId), defoAssetAmountGross, poolMakersFeeDefoAmount)), Reissue(defoAssetId, (defoAssetAmount + poolMakersFeeDefoAmount), true), ScriptTransfer(sellerAddr, defoAssetAmount, defoAssetId), ScriptTransfer(sellerAddr, change, sellAssetId), ScriptTransfer(factoryReadNextPoolMakerToDistributeFee(toString(this)), poolMakersFeeDefoAmount, defoAssetId), IntegerEntry(keyAccumulatedFee(), (accumulatedFee + poolMakersFeeDefoAmount))], change)
322+ else $Tuple2([IntegerEntry(keyUcollateral(), (ucollateral + requiredBasicAssetAmount)), StringEntry(keyAccountOperation(height, toString(sellerAddr), "FINISHED"), assetDataSwapOperation(sellAmt, toBase58String(sellAssetId), controlPrice, defoAssetAmount, toBase58String(defoAssetId), defoAssetAmountGross, poolMakersFeeDefoAmount, protocolFeeDefoAmount)), Reissue(defoAssetId, ((defoAssetAmount + poolMakersFeeDefoAmount) + protocolFeeDefoAmount), true), ScriptTransfer(sellerAddr, defoAssetAmount, defoAssetId), ScriptTransfer(sellerAddr, change, sellAssetId), ScriptTransfer(factoryReadNextPoolMakerToDistributeFee(toString(this)), poolMakersFeeDefoAmount, defoAssetId), ScriptTransfer(feeManagerAddress, protocolFeeDefoAmount, defoAssetId), IntegerEntry(keyAccumulatedFee(), (accumulatedFee + poolMakersFeeDefoAmount)), IntegerEntry(keyAccumulatedProtocolFee(), (accumulatedProtocolFee + protocolFeeDefoAmount))], change)
298323 }
299324
300325
301326 @Callable(i)
302327 func buyAsset () = {
303328 let pmt = value(i.payments[0])
304329 let pmtAssetId = value(pmt.assetId)
305330 let callerPub58Str = toBase58String(i.callerPublicKey)
306331 if (isBlocked)
307332 then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
308333 else if (isBlockedByLastHeight)
309334 then throw(((("last price finalization has been more then 5 blocks ago: priceLastHeight=" + toString(priceLastHeight)) + " currHeight=") + toString(height)))
310335 else if ((pmtAssetId != baseAssetId))
311336 then throw(((("Payment asset id doesn't match basic asset: expected=" + toBase58String(baseAssetId)) + " actual=") + toBase58String(pmtAssetId)))
312- else internalBuyAsset(i.caller, pmt.amount, pmtAssetId, minBasicBuyAmount, getBuyPriceConsideringStakingReferral(weekendsPriceChangeCoefficient, callerPub58Str), getBuyFeeConsideringStakingReferral(callerPub58Str))._1
337+ else internalBuyAsset(i.caller, pmt.amount, pmtAssetId, minBasicBuyAmount, getBuyPriceConsideringStakingReferral(weekendsPriceChangeCoefficient, callerPub58Str), getBuyFeeConsideringStakingReferral(callerPub58Str), getProtocolFeeConsideringStakingReferral(callerPub58Str))._1
313338 }
314339
315340
316341
317342 @Callable(i)
318343 func sellAsset () = {
319344 let pmt = value(i.payments[0])
320345 let pmtAsset = value(pmt.assetId)
321346 let callerAddress = toString(i.caller)
322347 let sellPrice = getSellPrice(weekendsPriceChangeCoefficient)
323348 if (isBlocked)
324349 then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
325350 else if (isBlockedByLastHeight)
326351 then throw(((("last price finalization has been more then 5 blocks ago: priceLastHeight=" + toString(priceLastHeight)) + " currHeight=") + toString(height)))
327352 else if ((pmtAsset != defoAssetId))
328353 then throw(((("Invalid payment asset id: expected=" + toBase58String(defoAssetId)) + " actual=") + toBase58String(pmtAsset)))
329354 else if ((minSynthSellAmount > pmt.amount))
330355 then throw(((("Payment amount less then mininimal allowed: paymentAmount=" + toString(pmt.amount)) + " minAmount=") + toString(minSynthSellAmount)))
331356 else {
332357 let baseAssetAmountNoBalanceLimit = fraction(pmt.amount, priceDecimals, sellPrice)
333358 let baseAssetAmountAvailable = if ((baseAssetAmountNoBalanceLimit > currentBaseAssetBalance))
334359 then currentBaseAssetBalance
335360 else baseAssetAmountNoBalanceLimit
336361 let soldDefoAssetAmountGross = fraction(baseAssetAmountAvailable, sellPrice, priceDecimals)
337362 let change = (pmt.amount - soldDefoAssetAmountGross)
338363 let stabilityFeeDefoAmount = fraction(poolStabilityFeePart, soldDefoAssetAmountGross, priceDecimals)
339364 let poolMakersFeeDefoAmount = fraction(sellFeePercent, soldDefoAssetAmountGross, priceDecimals)
340- let soldDefoAssetAmount = ((soldDefoAssetAmountGross - stabilityFeeDefoAmount) - poolMakersFeeDefoAmount)
365+ let protocolFeeDefoAmount = fraction(protocolFeePercent, soldDefoAssetAmountGross, priceDecimals)
366+ let soldDefoAssetAmount = (((soldDefoAssetAmountGross - stabilityFeeDefoAmount) - poolMakersFeeDefoAmount) - protocolFeeDefoAmount)
341367 let baseAssetAmountToSend = fraction(soldDefoAssetAmount, priceDecimals, sellPrice)
342-[IntegerEntry(keyUcollateral(), (ucollateral - baseAssetAmountToSend)), StringEntry(keyAccountOperation(height, callerAddress, "FINISHED"), assetDataSwapOperation(pmt.amount, toBase58String(pmtAsset), sellPrice, baseAssetAmountToSend, baseAssetIdStr, soldDefoAssetAmountGross, poolMakersFeeDefoAmount)), Burn(defoAssetId, (soldDefoAssetAmount + stabilityFeeDefoAmount)), ScriptTransfer(i.caller, baseAssetAmountToSend, baseAssetId), ScriptTransfer(i.caller, change, defoAssetId), ScriptTransfer(factoryReadNextPoolMakerToDistributeFee(toString(this)), poolMakersFeeDefoAmount, defoAssetId), IntegerEntry(keyAccumulatedFee(), (accumulatedFee + poolMakersFeeDefoAmount))]
368+[IntegerEntry(keyUcollateral(), (ucollateral - baseAssetAmountToSend)), StringEntry(keyAccountOperation(height, callerAddress, "FINISHED"), assetDataSwapOperation(pmt.amount, toBase58String(pmtAsset), sellPrice, baseAssetAmountToSend, baseAssetIdStr, soldDefoAssetAmountGross, poolMakersFeeDefoAmount, protocolFeeDefoAmount)), Burn(defoAssetId, (soldDefoAssetAmount + stabilityFeeDefoAmount)), ScriptTransfer(i.caller, baseAssetAmountToSend, baseAssetId), ScriptTransfer(i.caller, change, defoAssetId), ScriptTransfer(feeManagerAddress, protocolFeeDefoAmount, defoAssetId), ScriptTransfer(factoryReadNextPoolMakerToDistributeFee(toString(this)), poolMakersFeeDefoAmount, defoAssetId), IntegerEntry(keyAccumulatedFee(), (accumulatedFee + poolMakersFeeDefoAmount)), IntegerEntry(keyAccumulatedProtocolFee(), (accumulatedProtocolFee + protocolFeeDefoAmount))]
343369 }
344370 }
345371
346372
347373
348374 @Callable(i)
349375 func crossExchange (buyAssetCodeConfirm,sellAssetCodeConfirm) = {
350376 let pmt = value(i.payments[0])
351377 let pmtAsset = value(pmt.assetId)
352378 let pmtAssetStr = toBase58String(pmtAsset)
353379 let pmtAmount = pmt.amount
354380 let callerAddress = toString(i.caller)
355381 let buyAssetCfg = thisCfgArray
356382 let sellAssetTuple = factoryReadAssetCfgByCode(sellAssetCodeConfirm)
357383 let sellAssetCfg = sellAssetTuple._2
358384 let sellAssetAccAddress = valueOrErrorMessage(addressFromString(sellAssetTuple._1), ("couldn't parse address from string for assetCode=" + sellAssetCodeConfirm))
359385 let minSellPmt = valueOrErrorMessage(parseInt(sellAssetCfg[IdxMinSellPayment]), ("minSellPmt parsing error: rawVal=" + sellAssetCfg[IdxMinSellPayment]))
360386 let sellPriceLastHeight = controlAccReadLastHeight(sellAssetCodeConfirm)
361387 let isSellBlockedByLastHeight = ((height - sellPriceLastHeight) > 5)
362388 if (isBlocked)
363389 then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
364390 else if ((thisCfgArray[IdxDefoAssetCode] != buyAssetCodeConfirm))
365391 then throw(((("buyAsset confirmation failed: buyAssetIdConfirm=" + thisCfgArray[IdxDefoAssetCode]) + " BUT buyAssetId=") + buyAssetCodeConfirm))
366392 else if ((sellAssetCfg[IdxDefoAssetId] != pmtAssetStr))
367393 then throw(((("sellAsset confirmation failed: sellAssetIdConfirm=" + sellAssetCfg[IdxDefoAssetId]) + "BUT pmtAsset=") + pmtAssetStr))
368394 else if ((thisCfgArray[IdxDefoAssetStatus] != "ISSUED"))
369395 then throw(((("toAsset has not been issued yet: buyAssetId=" + buyAssetCodeConfirm) + " BUT status=") + thisCfgArray[IdxDefoAssetStatus]))
370396 else if ((sellAssetCfg[IdxDefoAssetStatus] != "ISSUED"))
371397 then throw(((("fromAssetCfg has not been issued yet: sellAssetId=" + pmtAssetStr) + " BUT status=") + sellAssetCfg[IdxDefoAssetStatus]))
372398 else if (isBlockedByLastHeight)
373399 then throw(((((("buy last price finalization has been more then 5 blocks ago: priceLastHeight=" + toString(priceLastHeight)) + " currHeight=") + toString(height)) + " buyCode=") + buyAssetCodeConfirm))
374400 else if (isSellBlockedByLastHeight)
375401 then throw(((((("sell last price finalization has been more then 5 blocks ago: priceLastHeight=" + toString(priceLastHeight)) + " currHeight=") + toString(height)) + " sellCode=") + sellAssetCodeConfirm))
376402 else {
377403 let buyAssetUsdPrice = getBuyPrice((weekendsPriceChangeCoefficient / 2))
378404 let sellAssetUsdPrice = getSellPriceFrom(controlAccReadPrice(sellAssetCodeConfirm), (weekendsPriceChangeCoefficient / 2))
379405 let buy2sellPrice = fraction(buyAssetUsdPrice, priceDecimals, sellAssetUsdPrice)
380406 let usdnDebt = fraction(pmtAmount, priceDecimals, sellAssetUsdPrice)
381407 let totalLendedAtOtherAccs = valueOrElse(getInteger(this, keyTotalLendedAtOtherAccs()), 0)
382408 let lendedAmountByAssetCodeKey = keyLendedAmountByAssetCode(sellAssetCodeConfirm)
383409 let lendedAmtByAssetCode = valueOrElse(getInteger(this, lendedAmountByAssetCodeKey), 0)
384410 let sellAssetSellFeePercent = parseIntValue(sellAssetCfg[IdxSellFeePercent])
385411 let crossFeePercent = fraction((buyFeePercent + sellAssetSellFeePercent), crossExchangeCoefficient, priceDecimals)
386- let buyAssetResult = internalBuyAsset(i.caller, pmtAmount, pmtAsset, minSellPmt, buy2sellPrice, crossFeePercent)
412+ let buyAssetResult = internalBuyAsset(i.caller, pmtAmount, pmtAsset, minSellPmt, buy2sellPrice, crossFeePercent, protocolFeePercent)
387413 ((((buyAssetResult._1 :+ ScriptTransfer(sellAssetAccAddress, usdnDebt, debtAssetId)) :+ ScriptTransfer(sellAssetAccAddress, (pmtAmount - buyAssetResult._2), pmtAsset)) :+ IntegerEntry(lendedAmountByAssetCodeKey, (lendedAmtByAssetCode + usdnDebt))) :+ IntegerEntry(keyTotalLendedAtOtherAccs(), (totalLendedAtOtherAccs + usdnDebt)))
388414 }
389415 }
390416
391417
392418
393419 @Callable(i)
394420 func rebalanceDebts () = {
395421 let debtPmt0 = value(i.payments[0])
396422 let debtPmtAsset0 = value(debtPmt0.assetId)
397423 let basePmt1 = value(i.payments[1])
398424 let basePmtAsset1 = value(basePmt1.assetId)
399425 let debtorAddress = toString(i.caller)
400426 let debtorAssetCfg = factoryReadAssetCfgByAddress(debtorAddress)
401427 let debtorAssetCode = debtorAssetCfg[IdxDefoAssetCode]
402428 let lendedAmountByAssetCodeKey = keyLendedAmountByAssetCode(debtorAssetCode)
403429 let lendedAmt = valueOrErrorMessage(getInteger(this, lendedAmountByAssetCodeKey), ("No debts for " + debtorAssetCode))
404430 if (isBlocked)
405431 then throw("contract is blocked by EMERGENCY SHUTDOWN actions untill reactivation by emergency oracles")
406432 else if ((debtAssetId != debtPmtAsset0))
407433 then throw(((("invalid debt asset id in the first paymet: expected=" + toBase58String(debtAssetId)) + " actual=") + toBase58String(debtPmtAsset0)))
408434 else if ((baseAssetId != basePmtAsset1))
409435 then throw(((("invalid base asset id in the second payment: expected=" + toBase58String(baseAssetId)) + " actual=") + toBase58String(basePmtAsset1)))
410436 else if ((debtPmt0.amount != basePmt1.amount))
411437 then throw("first payment amount doesn't match to the second payment amount")
412438 else if ((0 >= lendedAmt))
413439 then throw(("lendedAmt is less then zero: lendedAmt=" + toString(lendedAmt)))
414440 else if (((100 * priceDecimals) >= debtPmt0.amount))
415441 then throw(("attached payment must be greater then 100: pmt0.amount=" + toString(debtPmt0.amount)))
416442 else if ((debtPmt0.amount > lendedAmt))
417443 then throw(((("attached payment is grater than required: pmtAmount=" + toString(debtPmt0.amount)) + " lendedAmt=") + toString(lendedAmt)))
418444 else {
419445 let totalLendedAtOtherAccs = valueOrElse(getInteger(this, keyTotalLendedAtOtherAccs()), 0)
420446 let lendedAmtAfter = (lendedAmt - debtPmt0.amount)
421447 [IntegerEntry(lendedAmountByAssetCodeKey, lendedAmtAfter), IntegerEntry(keyTotalLendedAtOtherAccs(), (totalLendedAtOtherAccs - debtPmt0.amount)), StringEntry(("%s%s__rebalanceTrace__" + toBase58String(i.transactionId)), assetDataRebalanceTrace(debtorAssetCode, debtPmt0, basePmt1, lendedAmt, lendedAmtAfter))]
422448 }
423449 }
424450
425451
426452
427453 @Callable(i)
428454 func fulfillRedeemRequest (poolMakerAddress) = {
429455 let thisAddressStr = toString(this)
430456 let poolMakerUnlockHeightKey = keyFactoryPoolMakerUnlockHeight(thisAddressStr, poolMakerAddress)
431457 let poolMakerUnlockHeight = valueOrElse(getInteger(factoryAcc, poolMakerUnlockHeightKey), 0)
432458 if ((0 >= poolMakerUnlockHeight))
433459 then throw("All liquidity request fulfilled")
434460 else {
435461 let poolMakerLiquidityRequestKey = keyFactoryPoolMakerLiquidityRequest(thisAddressStr, poolMakerAddress, poolMakerUnlockHeight)
436462 let poolMakerLiquidityRequestAmount = valueOrErrorMessage(getInteger(factoryAcc, poolMakerLiquidityRequestKey), "Empty poolMakerLiquidityRequestKey at factory acc")
437463 if (isDefined(getInteger(this, poolMakerLiquidityRequestKey)))
438464 then throw("Liquidity request has been already fulfilled")
439465 else [IntegerEntry(poolMakerLiquidityRequestKey, poolMakerLiquidityRequestAmount), ScriptTransfer(factoryAcc, poolMakerLiquidityRequestAmount, baseAssetId)]
440466 }
441467 }
442468
443469
444470 @Verifier(tx)
445471 func verify () = match tx {
446472 case inv: InvokeScriptTransaction =>
447473 if ((inv.fee > (900 * 1000)))
448474 then throw(("fee amount is greater than max allowed: " + toString(inv.fee)))
449475 else if (isDefined(inv.feeAssetId))
450476 then throw("only Waves is allowed as feeAssetId")
451477 else if ((inv.function == "rebalanceDebts"))
452478 then {
453479 let invDappAddress = toString(addressFromRecipient(inv.dApp))
454480 if ((factoryReadAssetCfgByAddress(invDappAddress)[IdxDefoAssetStatus] != "ISSUED"))
455481 then throw("only defo dapp is allowed")
456482 else if ((invDappAddress == toString(this)))
457483 then throw("impossible to call self rebealnceDebt")
458484 else true
459485 }
460486 else if (if (if ((inv.function == "lockNeutrino"))
461487 then true
462488 else (inv.function == "lockNeutrinoSP"))
463489 then true
464490 else (inv.function == "unlockNeutrino"))
465491 then if ((toString(neutrinoStakingAcc) != toString(addressFromRecipient(inv.dApp))))
466492 then throw("invalid neutrino staking dapp address")
467493 else sigVerify(tx.bodyBytes, tx.proofs[0], factoryReadDefoStakingPacemakerPub())
468494 else throw("Not allowed invocation method calls")
469495 case _ =>
470496 sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey)
471497 }
472498

github/deemru/w8io/6500d08 
98.16 ms