tx · CdbCYxmNV28TzyPCjFTv7DxdhA1frANgFsVqtj4raUMj 3N31yX7N3xk5GJhcMjtKRGpFkBNfkc6KK3j: -0.01000000 Waves 2020.09.22 19:28 [1188749] smart account 3N31yX7N3xk5GJhcMjtKRGpFkBNfkc6KK3j > SELF 0.00000000 Waves
{ "type": 13, "id": "CdbCYxmNV28TzyPCjFTv7DxdhA1frANgFsVqtj4raUMj", "fee": 1000000, "feeAssetId": null, "timestamp": 1600792216248, "version": 1, "sender": "3N31yX7N3xk5GJhcMjtKRGpFkBNfkc6KK3j", "senderPublicKey": "BCuUe9A1b1EY38ghAwYPZX6RwcJqBdrdRD9z1QwKjBxp", "proofs": [ "4DWFWmHiBDEFYDjJNiu6sB4rctnkNCwL6C7h2nP4WxSqV892FNMdXzqQ5VohjGwAPc39ZEWPHYpF6w268H9n2qX5" ], "script": "base64:AAIEAAAAAAAAABYIAhIAEgASBQoDCAgIEgASBQoDCAEBAAAARwEAAAARa2V5QWNjdW11bGF0ZWRGZWUAAAAAAgAAABIlc19fYWNjdW11bGF0ZWRGZWUBAAAADmtleVVjb2xsYXRlcmFsAAAAAAIAAAAPJXNfX3Vjb2xsYXRlcmFsAQAAABlrZXlUb3RhbExlbmRlZEF0T3RoZXJBY2NzAAAAAAIAAAAaJXNfX3RvdGFsTGVuZGVkQXRPdGhlckFjY3MBAAAAE2tleUFzc2V0TG9ja2VkVG90YWwAAAABAAAAB2Fzc2V0SWQJAAEsAAAAAgIAAAAYJXMlc19fYXNzZXRMb2NrZWRUb3RhbF9fBQAAAAdhc3NldElkAQAAABNrZXlBY2NvdW50T3BlcmF0aW9uAAAAAwAAAAx1bmxvY2tIZWlnaHQAAAAHYWRkcmVzcwAAAAZzdGF0dXMJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAB4lcyVzJWQlc19fZGVmb0Fzc2V0T3BlcmF0aW9uX18FAAAAB2FkZHJlc3MCAAAAAl9fCQABpAAAAAEFAAAADHVubG9ja0hlaWdodAIAAAACX18FAAAABnN0YXR1cwEAAAAKa2V5RmFjdG9yeQAAAAACAAAACyVzX19mYWN0b3J5AQAAABprZXlMZW5kZWRBbW91bnRCeUFzc2V0Q29kZQAAAAEAAAAJYXNzZXRDb2RlCQABLAAAAAICAAAAHSVzJXNfX2xlbmRlZEJhc2VBc3NldEFtb3VudF9fBQAAAAlhc3NldENvZGUBAAAACGtleVByaWNlAAAAAQAAAAlhc3NldENvZGUJAAEsAAAAAgIAAAANJXMlc19fcHJpY2VfXwUAAAAJYXNzZXRDb2RlAAAAABRJZHhPcGVyYXRpb25BbW91bnRJbgAAAAAAAAAAAQAAAAATSWR4T3BlcmF0aW9uQXNzZXRJbgAAAAAAAAAAAgAAAAARSWR4T3BlcmF0aW9uUHJpY2UAAAAAAAAAAAMAAAAAFUlkeE9wZXJhdGlvbkFtb3VudE91dAAAAAAAAAAABAAAAAAUSWR4T3BlcmF0aW9uQXNzZXRPdXQAAAAAAAAAAAUBAAAAFmFzc2V0RGF0YVN3YXBPcGVyYXRpb24AAAAHAAAACGFtb3VudEluAAAAB2Fzc2V0SW4AAAAFcHJpY2UAAAAJYW1vdW50T3V0AAAACGFzc2V0T3V0AAAADGJydXR0b0Ftb3VudAAAAAlmZWVBbW91bnQJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAAQJWQlcyVkJXMlZCVkJWRfXwkAAaQAAAABBQAAAAhhbW91bnRJbgIAAAACX18FAAAAB2Fzc2V0SW4CAAAAAl9fCQABpAAAAAEFAAAACWFtb3VudE91dAIAAAACX18FAAAACGFzc2V0T3V0AgAAAAJfXwkAAaQAAAABBQAAAAVwcmljZQIAAAACX18JAAGkAAAAAQUAAAAMYnJ1dHRvQW1vdW50AgAAAAJfXwkAAaQAAAABBQAAAAlmZWVBbW91bnQBAAAAF2Fzc2V0RGF0YVJlYmFsYW5jZVRyYWNlAAAABQAAAA9kZWJ0b3JBc3NldENvZGUAAAAHZGVidFBtdAAAAAdiYXNlUG10AAAAD2xlbmRlZEFtdEJlZm9yZQAAAA5sZW5kZWRBbXRBZnRlcgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABAlcyVzJWQlcyVkJWQlZF9fBQAAAA9kZWJ0b3JBc3NldENvZGUCAAAAAl9fCQACWAAAAAEJAQAAAAV2YWx1ZQAAAAEIBQAAAAdkZWJ0UG10AAAAB2Fzc2V0SWQCAAAAAl9fCQABpAAAAAEIBQAAAAdkZWJ0UG10AAAABmFtb3VudAIAAAACX18JAAJYAAAAAQkBAAAABXZhbHVlAAAAAQgFAAAAB2Jhc2VQbXQAAAAHYXNzZXRJZAIAAAACX18JAAGkAAAAAQgFAAAAB2Jhc2VQbXQAAAAGYW1vdW50AgAAAAJfXwkAAaQAAAABBQAAAA9sZW5kZWRBbXRCZWZvcmUCAAAAAl9fCQABpAAAAAEFAAAADmxlbmRlZEFtdEFmdGVyAQAAABxhc3NldFJlYWRTd2FwRGF0YUFycmF5T3JGYWlsAAAAAQAAAA9hY2NPcGVyYXRpb25LZXkEAAAAE2FjY09wZXJhdGlvbkRhdGFTdHIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAR0aGlzBQAAAA9hY2NPcGVyYXRpb25LZXkJAAEsAAAAAgIAAAAqVGhlcmUgaXMgbm8gcmVxdWVzdCBmb3IgcGFzc2VkIGFyZ3VtZW50czogBQAAAA9hY2NPcGVyYXRpb25LZXkJAAS1AAAAAgUAAAATYWNjT3BlcmF0aW9uRGF0YVN0cgIAAAACX18AAAAAB251bGxJbnQA//////////8AAAAAB251bGxTdHICAAAABE5VTEwAAAAACmZhY3RvcnlBY2MJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAR0aGlzCQEAAAAKa2V5RmFjdG9yeQAAAAAJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAEk5vIGNvbmZpZyBhdCB0aGlzPQkABCUAAAABBQAAAAR0aGlzAgAAAAkgZm9yIGtleT0JAQAAAAprZXlGYWN0b3J5AAAAAAEAAAAVa2V5RmFjdG9yeURlYnRBc3NldElkAAAAAAIAAAAfJXMlc19fY29tbW9uQ29uZmlnX19kZWJ0QXNzZXRJZAEAAAASa2V5RmFjdG9yeUFzc2V0Q2ZnAAAAAQAAAA9hc3NldEFkZHJlc3NTdHIJAAEsAAAAAgkAASwAAAACAgAAABMlcyVzJXNfX2RlZm9Bc3NldF9fBQAAAA9hc3NldEFkZHJlc3NTdHICAAAACF9fY29uZmlnAQAAABprZXlGYWN0b3J5QXNzZXRDdXJyZW50UG9vbAAAAAEAAAAPYXNzZXRBY2NBZGRyZXNzCQABLAAAAAIJAAEsAAAAAgIAAAATJXMlcyVzX19kZWZvQXNzZXRfXwkABCUAAAABBQAAAA9hc3NldEFjY0FkZHJlc3MCAAAADV9fY3VycmVudFBvb2wBAAAAIGtleUZhY3RvcnlEZWZvQWRkcmVzc0J5QXNzZXRDb2RlAAAAAQAAAAlhc3NldENvZGUJAAEsAAAAAgkAASwAAAACAgAAABMlcyVzJXNfX2RlZm9Bc3NldF9fBQAAAAlhc3NldENvZGUCAAAAFF9fYWRkcmVzc0J5QXNzZXRDb2RlAQAAABZmYWN0b3J5UmVhZERlYnRBc3NldElkAAAAAAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAACmZhY3RvcnlBY2MJAQAAABVrZXlGYWN0b3J5RGVidEFzc2V0SWQAAAAACQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABVObyBjb25maWcgYXQgZmFjdG9yeT0JAAQlAAAAAQUAAAAKZmFjdG9yeUFjYwIAAAAJIGZvciBrZXk9CQEAAAAVa2V5RmFjdG9yeURlYnRBc3NldElkAAAAAAEAAAAcZmFjdG9yeVJlYWRBc3NldENmZ0J5QWRkcmVzcwAAAAEAAAAPYXNzZXRBZGRyZXNzU3RyCQAEtQAAAAIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAApmYWN0b3J5QWNjCQEAAAASa2V5RmFjdG9yeUFzc2V0Q2ZnAAAAAQUAAAAPYXNzZXRBZGRyZXNzU3RyCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABVObyBjb25maWcgYXQgZmFjdG9yeT0JAAQlAAAAAQUAAAAKZmFjdG9yeUFjYwIAAAAJIGZvciBrZXk9CQEAAAASa2V5RmFjdG9yeUFzc2V0Q2ZnAAAAAQUAAAAPYXNzZXRBZGRyZXNzU3RyAgAAAAJfXwEAAAAZZmFjdG9yeVJlYWRBc3NldENmZ0J5Q29kZQAAAAEAAAAJYXNzZXRDb2RlBAAAAA9hc3NldEFkZHJlc3NTdHIJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAApmYWN0b3J5QWNjCQEAAAAga2V5RmFjdG9yeURlZm9BZGRyZXNzQnlBc3NldENvZGUAAAABBQAAAAlhc3NldENvZGUJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAFU5vIGNvbmZpZyBhdCBmYWN0b3J5PQkABCUAAAABBQAAAApmYWN0b3J5QWNjAgAAAAkgZm9yIGtleT0JAQAAACBrZXlGYWN0b3J5RGVmb0FkZHJlc3NCeUFzc2V0Q29kZQAAAAEFAAAACWFzc2V0Q29kZQkABRQAAAACBQAAAA9hc3NldEFkZHJlc3NTdHIJAQAAABxmYWN0b3J5UmVhZEFzc2V0Q2ZnQnlBZGRyZXNzAAAAAQUAAAAPYXNzZXRBZGRyZXNzU3RyAAAAABBJZHhEZWZvQXNzZXRDb2RlAAAAAAAAAAABAAAAAA5JZHhEZWZvQXNzZXRJZAAAAAAAAAAAAgAAAAASSWR4RGVmb0Fzc2V0U3RhdHVzAAAAAAAAAAADAAAAABBJZHhQcmljZURlY2ltYWxzAAAAAAAAAAAEAAAAAA5JZHhCYXNlQXNzZXRJZAAAAAAAAAAABQAAAAAYSWR4T3ZlckNvbGxhdGVyYWxQZXJjZW50AAAAAAAAAAAGAAAAAA5JZHhNaW5Jbml0UG9vbAAAAAAAAAAABwAAAAAVSWR4UHJpY2VPcmFjbGVBZGRyZXNzAAAAAAAAAAAIAAAAABBJZHhNaW5CdXlQYXltZW50AAAAAAAAAAAJAAAAABFJZHhNaW5TZWxsUGF5bWVudAAAAAAAAAAACgAAAAASSWR4QnV5TG9ja0ludGVydmFsAAAAAAAAAAALAAAAABNJZHhTZWxsTG9ja0ludGVydmFsAAAAAAAAAAAMAAAAABBJZHhCdXlGZWVQZXJjZW50AAAAAAAAAAANAAAAABFJZHhTZWxsRmVlUGVyY2VudAAAAAAAAAAADgAAAAAMdGhpc0NmZ0FycmF5CQEAAAAcZmFjdG9yeVJlYWRBc3NldENmZ0J5QWRkcmVzcwAAAAEJAAQlAAAAAQUAAAAEdGhpcwAAAAANZGVmb0Fzc2V0Q29kZQkAAZEAAAACBQAAAAx0aGlzQ2ZnQXJyYXkFAAAAEElkeERlZm9Bc3NldENvZGUAAAAAC2RlZm9Bc3NldElkCQACWQAAAAEJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAAA5JZHhEZWZvQXNzZXRJZAAAAAAOcHJpY2VPcmFjbGVBY2MJAQAAABFAZXh0ck5hdGl2ZSgxMDYyKQAAAAEJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAABVJZHhQcmljZU9yYWNsZUFkZHJlc3MAAAAAFW92ZXJDb2xsYXRlcmFsUGVyY2VudAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAADHRoaXNDZmdBcnJheQUAAAAYSWR4T3ZlckNvbGxhdGVyYWxQZXJjZW50AAAAAA5iYXNlQXNzZXRJZFN0cgkAAZEAAAACBQAAAAx0aGlzQ2ZnQXJyYXkFAAAADklkeEJhc2VBc3NldElkAAAAAAtiYXNlQXNzZXRJZAkAAlkAAAABBQAAAA5iYXNlQXNzZXRJZFN0cgAAAAANcHJpY2VEZWNpbWFscwkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAADHRoaXNDZmdBcnJheQUAAAAQSWR4UHJpY2VEZWNpbWFscwAAAAARbWluQmFzaWNCdXlBbW91bnQJAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAAAx0aGlzQ2ZnQXJyYXkFAAAAEElkeE1pbkJ1eVBheW1lbnQAAAAAEm1pblN5bnRoU2VsbEFtb3VudAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAADHRoaXNDZmdBcnJheQUAAAARSWR4TWluU2VsbFBheW1lbnQAAAAAD2J1eUxvY2tJbnRlcnZhbAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAADHRoaXNDZmdBcnJheQUAAAASSWR4QnV5TG9ja0ludGVydmFsAAAAABBzZWxsTG9ja0ludGVydmFsCQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAABNJZHhTZWxsTG9ja0ludGVydmFsAAAAAA1idXlGZWVQZXJjZW50CQEAAAANcGFyc2VJbnRWYWx1ZQAAAAEJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAABBJZHhCdXlGZWVQZXJjZW50AAAAAA5zZWxsRmVlUGVyY2VudAkBAAAADXBhcnNlSW50VmFsdWUAAAABCQABkQAAAAIFAAAADHRoaXNDZmdBcnJheQUAAAARSWR4U2VsbEZlZVBlcmNlbnQBAAAAE2NvbnRyb2xBY2NSZWFkUHJpY2UAAAABAAAACWFzc2V0Q29kZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAADnByaWNlT3JhY2xlQWNjCQEAAAAIa2V5UHJpY2UAAAABBQAAAAlhc3NldENvZGUJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAGE5vIHByaWNlIGF0IHByaWNlT3JhY2xlPQkABCUAAAABBQAAAA5wcmljZU9yYWNsZUFjYwIAAAAJIGZvciBrZXk9CQEAAAAIa2V5UHJpY2UAAAABBQAAAAlhc3NldENvZGUBAAAAG2NvbnRyb2xBY2NSZWFkQ3VycklkeE9yRmFpbAAAAAAJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAA5wcmljZU9yYWNsZUFjYwIAAAAHY3VycklkeAkAASwAAAACAgAAABlObyBjdXJySWR4IGF0IGNvbnRyb2xBY2M9CQAEJQAAAAEFAAAADnByaWNlT3JhY2xlQWNjAQAAABdjb250cm9sQWNjUmVhZElkeEhlaWdodAAAAAEAAAADaWR4BAAAAAxpZHhIZWlnaHRLZXkJAAEsAAAAAgIAAAAKaWR4SGVpZ2h0XwkAAaQAAAABBQAAAANpZHgJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAOcHJpY2VPcmFjbGVBY2MFAAAADGlkeEhlaWdodEtleQAAAAAAAAAAAAEAAAAbY29udHJvbEFjY1JlYWRQcmljZUJ5SGVpZ2h0AAAAAQAAAAtwcmljZUhlaWdodAQAAAAQcHJpY2VCeUhlaWdodEtleQkAASwAAAACAgAAAAZwcmljZV8JAAGkAAAAAQUAAAALcHJpY2VIZWlnaHQJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAA5wcmljZU9yYWNsZUFjYwUAAAAQcHJpY2VCeUhlaWdodEtleQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAADTm8gBQAAABBwcmljZUJ5SGVpZ2h0S2V5AgAAAA8gYXQgY29udHJvbEFjYz0JAAQlAAAAAQUAAAAOcHJpY2VPcmFjbGVBY2MBAAAAEWdldFN0YWtpbmdCYWxhbmNlAAAAAAkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAAAxycGRfYmFsYW5jZV8FAAAADmJhc2VBc3NldElkU3RyAgAAAAFfCQAEJQAAAAEFAAAABHRoaXMAAAAAAAAAAAAAAAAAC3Vjb2xsYXRlcmFsCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAAA5rZXlVY29sbGF0ZXJhbAAAAAAAAAAAAAAAAAAAAAAADmFjY3VtdWxhdGVkRmVlCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAABFrZXlBY2N1bXVsYXRlZEZlZQAAAAAAAAAAAAAAAAAAAAAADmN1cnJQb29sQW1vdW50CQEAAAARQGV4dHJOYXRpdmUoMTA1MCkAAAACBQAAAApmYWN0b3J5QWNjCQEAAAAaa2V5RmFjdG9yeUFzc2V0Q3VycmVudFBvb2wAAAABBQAAAAR0aGlzAAAAABdkb3VibGVDaGVja0Jhc2ljQmFsYW5jZQkAAGQAAAACCQAD8AAAAAIFAAAABHRoaXMFAAAAC2Jhc2VBc3NldElkCQEAAAARZ2V0U3Rha2luZ0JhbGFuY2UAAAAAAAAAABZkb3VibGVDaGVja1Vjb2xsYXRlcmFsAwkAAGYAAAACAAAAAAAAAAAABQAAAAt1Y29sbGF0ZXJhbAAAAAAAAAAAAAUAAAALdWNvbGxhdGVyYWwAAAAAGWRvdWJsZUNoZWNrQ3VyclBvb2xBbW91bnQJAABlAAAAAgUAAAAXZG91YmxlQ2hlY2tCYXNpY0JhbGFuY2UFAAAAC3Vjb2xsYXRlcmFsAAAAAAVwcmljZQkBAAAAE2NvbnRyb2xBY2NSZWFkUHJpY2UAAAABCQABkQAAAAIFAAAADHRoaXNDZmdBcnJheQUAAAAQSWR4RGVmb0Fzc2V0Q29kZQAAAAAJb3ZlclByaWNlCQAAaQAAAAIJAABoAAAAAgkAAGQAAAACBQAAAA1wcmljZURlY2ltYWxzBQAAABVvdmVyQ29sbGF0ZXJhbFBlcmNlbnQFAAAABXByaWNlBQAAAA1wcmljZURlY2ltYWxzAAAAAAhlbWlzc2lvbggJAQAAAAV2YWx1ZQAAAAEJAAPsAAAAAQUAAAALZGVmb0Fzc2V0SWQAAAAIcXVhbnRpdHkAAAAAE2Jhc2ljQXNzZXRMb2NrZWRBbXQJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwkBAAAAE2tleUFzc2V0TG9ja2VkVG90YWwAAAABBQAAAA5iYXNlQXNzZXRJZFN0cgAAAAAAAAAAAAAAAAAUYXZhaWxhYmxlUG9vbEJhbGFuY2UJAABlAAAAAgUAAAAOY3VyclBvb2xBbW91bnQFAAAAE2Jhc2ljQXNzZXRMb2NrZWRBbXQBAAAAEGludGVybmFsQnV5QXNzZXQAAAAGAAAACnNlbGxlckFkZHIAAAAHc2VsbEFtdAAAAAtzZWxsQXNzZXRJZAAAAAptaW5TZWxsQW10AAAADWJ1eTJzZWxsUHJpY2UAAAAKZmVlUGVyY2VudAQAAAAYYXZhaWxhYmxlRGVmb0Fzc2V0SW5Qb29sCQAAZQAAAAIJAABrAAAAAwUAAAAUYXZhaWxhYmxlUG9vbEJhbGFuY2UFAAAADXByaWNlRGVjaW1hbHMFAAAACW92ZXJQcmljZQUAAAAIZW1pc3Npb24EAAAAHmZ1bGxEZWZvQXNzZXRBbW91bnROb1Bvb2xMaW1pdAkAAGsAAAADBQAAAAdzZWxsQW10BQAAAA1wcmljZURlY2ltYWxzBQAAAA1idXkyc2VsbFByaWNlBAAAABlmdWxsRGVmb0Fzc2V0QW1vdW50QnJ1dHRvAwkAAGYAAAACBQAAAB5mdWxsRGVmb0Fzc2V0QW1vdW50Tm9Qb29sTGltaXQFAAAAGGF2YWlsYWJsZURlZm9Bc3NldEluUG9vbAUAAAAYYXZhaWxhYmxlRGVmb0Fzc2V0SW5Qb29sBQAAAB5mdWxsRGVmb0Fzc2V0QW1vdW50Tm9Qb29sTGltaXQEAAAAD2RlZm9Bc3NldEFtb3VudAkAAGsAAAADCQAAZQAAAAIFAAAADXByaWNlRGVjaW1hbHMFAAAACmZlZVBlcmNlbnQFAAAAGWZ1bGxEZWZvQXNzZXRBbW91bnRCcnV0dG8FAAAADXByaWNlRGVjaW1hbHMEAAAACWZlZUFtb3VudAkAAGUAAAACBQAAABlmdWxsRGVmb0Fzc2V0QW1vdW50QnJ1dHRvBQAAAA9kZWZvQXNzZXRBbW91bnQEAAAAGHJlcXVpcmVkQmFzaWNBc3NldEFtb3VudAkAAGsAAAADBQAAABlmdWxsRGVmb0Fzc2V0QW1vdW50QnJ1dHRvBQAAAA1idXkyc2VsbFByaWNlBQAAAA1wcmljZURlY2ltYWxzBAAAAAZjaGFu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AAIhPQAAAAIFAAAACHBtdEFzc2V0BQAAAAtkZWZvQXNzZXRJZAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAACNJbnZhbGlkIHBheW1lbnQgYXNzZXQgaWQ6IGV4cGVjdGVkPQkAAlgAAAABBQAAAAtkZWZvQXNzZXRJZAIAAAAIIGFjdHVhbD0JAAJYAAAAAQUAAAAIcG10QXNzZXQDCQAAZgAAAAIFAAAAEm1pblN5bnRoU2VsbEFtb3VudAgFAAAAA3BtdAAAAAZhbW91bnQJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAA6UGF5bWVudCBhbW91bnQgbGVzcyB0aGVuIG1pbmluaW1hbCBhbGxvd2VkOiBwYXltZW50QW1vdW50PQkAAaQAAAABCAUAAAADcG10AAAABmFtb3VudAIAAAALIG1pbkFtb3VudD0JAAGkAAAAAQUAAAASbWluU3ludGhTZWxsQW1vdW50BAAAABJwbXREZWZvQW1vdW50R3Jvc3MIBQAAAANwbXQAAAAGYW1vdW50BAAAAA1kZWZvQW1vdW50RmVlCQAAawAAAAMJAABlAAAAAgUAAAANcHJpY2VEZWNpbWFscwUAAAAOc2VsbEZlZVBlcmNlbnQFAAAAEnBtdERlZm9BbW91bnRHcm9zcwUAAAANcHJpY2VEZWNpbWFscwQAAAAScG10RGVmb0Ftb3VudE5vRmVlCQAAZQAAAAIFAAAAEnBtdERlZm9BbW91bnRHcm9zcwUAAAANZGVmb0Ftb3VudEZlZQQAAAAdYmFzZUFzc2V0QW1vdW50Tm9CYWxhbmNlTGltaXQJAABrAAAAAwUAAAAScG10RGVmb0Ftb3VudE5vRmVlBQAAAAVwcmljZQUAAAANcHJpY2VEZWNpbWFscwQAAAAUYmFzZUFzc2V0QW1vdW50Tm9GZWUDCQAAZgAAAAIFAAAAHWJhc2VBc3NldEFtb3VudE5vQmFsYW5jZUxpbWl0BQAAABlkb3VibGVDaGVja0N1cnJQb29sQW1vdW50BQAAABlkb3VibGVDaGVja0N1cnJQb29sQW1vdW50BQAAAB1iYXNlQXNzZXRBbW91bnROb0JhbGFuY2VMaW1pdAQAAAAXcmVxdWlyZWREZWZvQXNzZXRBbW91bnQJAABrAAAAAwUAAAAUYmFzZUFzc2V0QW1vdW50Tm9GZWUFAAAADXByaWNlRGVjaW1hbHMFAAAABXByaWNlBAAAAAZjaGFuZ2UJAABlAAAAAgUAAAAScG10RGVmb0Ftb3VudE5vRmVlBQAAABdyZXF1aXJlZERlZm9Bc3NldEFtb3VudAkABEwAAAACCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAADmtleVVjb2xsYXRlcmFsAAAAAAkAAGUAAAACBQAAAAt1Y29sbGF0ZXJhbAUAAAAUYmFzZUFzc2V0QW1vdW50Tm9GZWUJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAE2tleUFjY291bnRPcGVyYXRpb24AAAADBQAAAAZoZWlnaHQFAAAADWNhbGxlckFkZHJlc3MCAAAACEZJTklTSEVECQEAAAAWYXNzZXREYXRhU3dhcE9wZXJhdGlvbgAAAAcIBQAAAANwbXQAAAAGYW1vdW50CQACWAAAAAEFAAAACHBtdEFzc2V0BQAAAAVwcmljZQUAAAAUYmFzZUFzc2V0QW1vdW50Tm9GZWUFAAAADmJhc2VBc3NldElkU3RyBQAAABJwbXREZWZvQW1vdW50R3Jvc3MFAAAADWRlZm9BbW91bnRGZWUJAARMAAAAAgkBAAAABEJ1cm4AAAACBQAAAAtkZWZvQXNzZXRJZAUAAAAXcmVxdWlyZWREZWZvQXNzZXRBbW91bnQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAABRiYXNlQXNzZXRBbW91bnROb0ZlZQUAAAALYmFzZUFzc2V0SWQJAARMAAAAAgkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwgFAAAAAWkAAAAGY2FsbGVyBQAAAAZjaGFuZ2UFAAAAC2RlZm9Bc3NldElkCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACCQEAAAARa2V5QWNjdW11bGF0ZWRGZWUAAAAACQAAZAAAAAIFAAAADmFjY3VtdWxhdGVkRmVlBQAAAA1kZWZvQW1vdW50RmVlBQAAAANuaWwAAAABaQEAAAANY3Jvc3NFeGNoYW5nZQAAAAMAAAAKYnV5QXNzZXRJZAAAABNidXlBc3NldENvZGVDb25maXJtAAAAFHNlbGxBc3NldENvZGVDb25maXJtBAAAAANwbXQJAQAAAAV2YWx1ZQAAAAEJAAGRAAAAAggFAAAAAWkAAAAIcGF5bWVudHMAAAAAAAAAAAAEAAAACHBtdEFzc2V0CQEAAAAFdmFsdWUAAAABCAUAAAADcG10AAAAB2Fzc2V0SWQEAAAAC3BtdEFzc2V0U3RyCQACWAAAAAEFAAAACHBtdEFzc2V0BAAAAAlwbXRBbW91bnQIBQAAAANwbXQAAAAGYW1vdW50BAAAAA1jYWxsZXJBZGRyZXNzCQAEJQAAAAEIBQAAAAFpAAAABmNhbGxlcgQAAAALYnV5QXNzZXRDZmcFAAAADHRoaXNDZmdBcnJheQQAAAAOc2VsbEFzc2V0VHVwbGUJAQAAABlmYWN0b3J5UmVhZEFzc2V0Q2ZnQnlDb2RlAAAAAQUAAAAUc2VsbEFzc2V0Q29kZUNvbmZpcm0EAAAADHNlbGxBc3NldENmZwgFAAAADnNlbGxBc3NldFR1cGxlAAAAAl8yBAAAABNzZWxsQXNzZXRBY2NBZGRyZXNzCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQmAAAAAQgFAAAADnNlbGxBc3NldFR1cGxlAAAAAl8xCQABLAAAAAICAAAAMWNvdWxkbid0IHBhcnNlIGFkZHJlc3MgZnJvbSBzdHJpbmcgZm9yIGFzc2V0Q29kZT0FAAAAFHNlbGxBc3NldENvZGVDb25maXJtBAAAAAptaW5TZWxsUG10CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAS2AAAAAQkAAZEAAAACBQAAAAxzZWxsQXNzZXRDZmcFAAAAEUlkeE1pblNlbGxQYXltZW50CQABLAAAAAICAAAAIW1pblNlbGxQbXQgcGFyc2luZyBlcnJvcjogcmF3VmFsPQkAAZEAAAACBQAAAAxzZWxsQXNzZXRDZmcFAAAAEUlkeE1pblNlbGxQYXltZW50AwkBAAAAAiE9AAAAAgkAAZEAAAACBQAAAAx0aGlzQ2ZnQXJyYXkFAAAADklkeERlZm9Bc3NldElkBQAAAApidXlBc3NldElkCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAMGJ1eUFzc2V0IGNvbmZpcm1hdGlvbiBmYWlsZWQ6IGJ1eUFzc2V0SWRDb25maXJtPQkAAZEAAAACBQAAAAx0aGlzQ2ZnQXJyYXkFAAAADklkeERlZm9Bc3NldElkAgAAABAgQlVUIGJ1eUFzc2V0SWQ9BQAAAApidXlBc3NldElkAwkBAAAAAiE9AAAAAgkAAZEAAAACBQAAAAxzZWxsQXNzZXRDZmcFAAAADklkeERlZm9Bc3NldElkBQAAAAtwbXRBc3NldFN0cgkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAADJzZWxsQXNzZXQgY29uZmlybWF0aW9uIGZhaWxlZDogc2VsbEFzc2V0SWRDb25maXJtPQkAAZEAAAACBQAAAAxzZWxsQXNzZXRDZmcFAAAADklkeERlZm9Bc3NldElkAgAAAA1CVVQgcG10QXNzZXQ9BQAAAAtwbXRBc3NldFN0cgMJAQAAAAIhPQAAAAIJAAGRAAAAAgUAAAAMdGhpc0NmZ0FycmF5BQAAABJJZHhEZWZvQXNzZXRTdGF0dXMCAAAABklTU1VFRAkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAACx0b0Fzc2V0IGhhcyBub3QgYmVlbiBpc3N1ZWQgeWV0OiBidXlBc3NldElkPQUAAAAKYnV5QXNzZXRJZAIAAAAMIEJVVCBzdGF0dXM9CQABkQAAAAIFAAAADHRoaXNDZmdBcnJheQUAAAASSWR4RGVmb0Fzc2V0U3RhdHVzAwkBAAAAAiE9AAAAAgkAAZEAAAACBQAAAAxzZWxsQXNzZXRDZmcFAAAAEklkeERlZm9Bc3NldFN0YXR1cwIAAAAGSVNTVUVECQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAAMmZyb21Bc3NldENmZyBoYXMgbm90IGJlZW4gaXNzdWVkIHlldDogc2VsbEFzc2V0SWQ9BQAAAAtwbXRBc3NldFN0cgIAAAAMIEJVVCBzdGF0dXM9CQABkQAAAAIFAAAADHNlbGxBc3NldENmZwUAAAASSWR4RGVmb0Fzc2V0U3RhdHVzBAAAABBidXlBc3NldFVzZFByaWNlBQAAAAVwcmljZQQAAAARc2VsbEFzc2V0VXNkUHJpY2UJAQAAABNjb250cm9sQWNjUmVhZFByaWNlAAAAAQUAAAAUc2VsbEFzc2V0Q29kZUNvbmZpcm0EAAAADWJ1eTJzZWxsUHJpY2UJAABrAAAAAwUAAAAQYnV5QXNzZXRVc2RQcmljZQUAAAANcHJpY2VEZWNpbWFscwUAAAARc2VsbEFzc2V0VXNkUHJpY2UEAAAAC2RlYnRBc3NldElkCQACWQAAAAEJAQAAABZmYWN0b3J5UmVhZERlYnRBc3NldElkAAAAAAQAAAAIdXNkbkRlYnQJAABrAAAAAwUAAAARc2VsbEFzc2V0VXNkUHJpY2UFAAAACXBtdEFtb3VudAUAAAANcHJpY2VEZWNpbWFscwQAAAAWdG90YWxMZW5kZWRBdE90aGVyQWNjcwkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzCQEAAAAZa2V5VG90YWxMZW5kZWRBdE90aGVyQWNjcwAAAAAAAAAAAAAAAAAEAAAAGmxlbmRlZEFtb3VudEJ5QXNzZXRDb2RlS2V5CQEAAAAaa2V5TGVuZGVkQW1vdW50QnlBc3NldENvZGUAAAABBQAAABRzZWxsQXNzZXRDb2RlQ29uZmlybQQAAAAUbGVuZGVkQW10QnlBc3NldENvZGUJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAabGVuZGVkQW1vdW50QnlBc3NldENvZGVLZXkAAAAAAAAAAAAEAAAADmJ1eUFzc2V0UmVzdWx0CQEAAAAQaW50ZXJuYWxCdXlBc3NldAAAAAYIBQAAAAFpAAAABmNhbGxlcgUAAAAJcG10QW1vdW50BQAAAAhwbXRBc3NldAUAAAAKbWluU2VsbFBtdAUAAAANYnV5MnNlbGxQcmljZQkAAGsAAAADBQAAAA1idXlGZWVQZXJjZW50AAAAAAAAAACWAAAAAAAAAABkCQAETQAAAAIJAARNAAAAAggFAAAADmJ1eUFzc2V0UmVzdWx0AAAAAl8xCQEAAAAMSW50ZWdlckVudHJ5AAAAAgUAAAAabGVuZGVkQW1vdW50QnlBc3NldENvZGVLZXkJAABkAAAAAgUAAAAUbGVuZGVkQW10QnlBc3NldENvZGUFAAAACHVzZG5EZWJ0CQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAAGWtleVRvdGFsTGVuZGVkQXRPdGhlckFjY3MAAAAACQAAZAAAAAIFAAAAFnRvdGFsTGVuZGVkQXRPdGhlckFjY3MFAAAACHVzZG5EZWJ0AAAAAWkBAAAADnJlYmFsYW5jZURlYnRzAAAAAAQAAAALZGVidEFzc2V0SWQJAAJZAAAAAQkBAAAAFmZhY3RvcnlSZWFkRGVidEFzc2V0SWQAAAAABAAAAAhkZWJ0UG10MAkBAAAABXZhbHVlAAAAAQkAAZEAAAACCAUAAAABaQAAAAhwYXltZW50cwAAAAAAAAAAAAQAAAANZGVidFBtdEFzc2V0MAkBAAAABXZhbHVlAAAAAQgFAAAACGRlYnRQbXQwAAAAB2Fzc2V0SWQEAAAACGJhc2VQbXQxCQEAAAAFdmFsdWUAAAABCQABkQAAAAIIBQAAAAFpAAAACHBheW1lbnRzAAAAAAAAAAABBAAAAA1iYXNlUG10QXNzZXQxCQEAAAAFdmFsdWUAAAABCAUAAAAIYmFzZVBtdDEAAAAHYXNzZXRJZAQAAAANZGVidG9yQWRkcmVzcwkABCUAAAABCAUAAAABaQAAAAZjYWxsZXIEAAAADmRlYnRvckFzc2V0Q2ZnCQEAAAAcZmFjdG9yeVJlYWRBc3NldENmZ0J5QWRkcmVzcwAAAAEFAAAADWRlYnRvckFkZHJlc3MEAAAAD2RlYnRvckFzc2V0Q29kZQkAAZEAAAACBQAAAA5kZWJ0b3JBc3NldENmZwUAAAAQSWR4RGVmb0Fzc2V0Q29kZQQAAAAabGVuZGVkQW1vdW50QnlBc3NldENvZGVLZXkJAQAAABprZXlMZW5kZWRBbW91bnRCeUFzc2V0Q29kZQAAAAEFAAAAD2RlYnRvckFzc2V0Q29kZQQAAAAJbGVuZGVkQW10CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAabGVuZGVkQW1vdW50QnlBc3NldENvZGVLZXkJAAEsAAAAAgIAAAANTm8gZGVidHMgZm9yIAUAAAAPZGVidG9yQXNzZXRDb2RlAwkBAAAAAiE9AAAAAgUAAAALZGVidEFzc2V0SWQFAAAADWRlYnRQbXRBc3NldDAJAAACAAAAAQkAASwAAAACCQABLAAAAAIJAAEsAAAAAgIAAAA0aW52YWxpZCBkZWJ0IGFzc2V0IGlkIGluIHRoZSBmaXJzdCBwYXltZXQ6IGV4cGVjdGVkPQkAAlgAAAABBQAAAAtkZWJ0QXNzZXRJZAIAAAAIIGFjdHVhbD0JAAJYAAAAAQUAAAANZGVidFBtdEFzc2V0MAMJAQAAAAIhPQAAAAIFAAAAC2Jhc2VBc3NldElkBQAAAA1iYXNlUG10QXNzZXQxCQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAANmludmFsaWQgYmFzZSBhc3NldCBpZCBpbiB0aGUgc2Vjb25kIHBheW1lbnQ6IGV4cGVjdGVkPQkAAlgAAAABBQAAAAtiYXNlQXNzZXRJZAIAAAAIIGFjdHVhbD0JAAJYAAAAAQUAAAANYmFzZVBtdEFzc2V0MQMJAQAAAAIhPQAAAAIIBQAAAAhkZWJ0UG10MAAAAAZhbW91bnQIBQAAAAhiYXNlUG10MQAAAAZhbW91bnQJAAACAAAAAQIAAAA/Zmlyc3QgcGF5bWVudCBhbW91bnQgZG9lc24ndCBtYXRjaCB0byB0aGUgc2Vjb25kIHBheW1lbnQgYW1vdW50AwkAAGcAAAACAAAAAAAAAAAABQAAAAlsZW5kZWRBbXQJAAACAAAAAQkAASwAAAACAgAAACdsZW5kZWRBbXQgaXMgbGVzcyB0aGVuIHplcm86IGxlbmRlZEFtdD0JAAGkAAAAAQUAAAAJbGVuZGVkQW10AwkAAGcAAAACAAAAAAAAAAAACAUAAAAIZGVidFBtdDAAAAAGYW1vdW50CQAAAgAAAAEJAAEsAAAAAgIAAAA1YXR0YWNoZWQgcGF5bWVudCBtdXN0IGJlIGdyZWF0ZXIgdGhlbiAwOiBwbXQwLmFtb3VudD0JAAGkAAAAAQgFAAAACGRlYnRQbXQwAAAABmFtb3VudAMJAABmAAAAAggFAAAACGRlYnRQbXQwAAAABmFtb3VudAUAAAAJbGVuZGVkQW10CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAANGF0dGFjaGVkIHBheW1lbnQgaXMgZ3JhdGVyIHRoYW4gcmVxdWlyZWQ6IHBtdEFtb3VudD0JAAGkAAAAAQgFAAAACGRlYnRQbXQwAAAABmFtb3VudAIAAAALIGxlbmRlZEFtdD0JAAGkAAAAAQUAAAAJbGVuZGVkQW10BAAAABZ0b3RhbExlbmRlZEF0T3RoZXJBY2NzCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGgAAAAIFAAAABHRoaXMJAQAAABlrZXlUb3RhbExlbmRlZEF0T3RoZXJBY2NzAAAAAAAAAAAAAAAAAAQAAAAObGVuZGVkQW10QWZ0ZXIJAABlAAAAAgUAAAAJbGVuZGVkQW10CAUAAAAIZGVidFBtdDAAAAAGYW1vdW50CQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABpsZW5kZWRBbW91bnRCeUFzc2V0Q29kZUtleQUAAAAObGVuZGVkQW10QWZ0ZXIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAABlrZXlUb3RhbExlbmRlZEF0T3RoZXJBY2NzAAAAAAkAAGUAAAACBQAAABZ0b3RhbExlbmRlZEF0T3RoZXJBY2NzCAUAAAAIZGVidFBtdDAAAAAGYW1vdW50CQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAAEsAAAAAgIAAAAWJXMlc19fcmViYWxhbmNlVHJhY2VfXwkAAlgAAAABCAUAAAABaQAAAA10cmFuc2FjdGlvbklkCQEAAAAXYXNzZXREYXRhUmViYWxhbmNlVHJhY2UAAAAFBQAAAA9kZWJ0b3JBc3NldENvZGUFAAAACGRlYnRQbXQwBQAAAAhiYXNlUG10MQUAAAAJbGVuZGVkQW10BQAAAA5sZW5kZWRBbXRBZnRlcgUAAAADbmlsAAAAAWkBAAAACHdpdGhkcmF3AAAAAwAAAA5hY2NvdW50QWRkcmVzcwAAAAx1bmxvY2tIZWlnaHQAAAADaWR4BAAAAA9hY2NPcGVyYXRpb25LZXkJAQAAABNrZXlBY2NvdW50T3BlcmF0aW9uAAAAAwUAAAAMdW5sb2NrSGVpZ2h0BQAAAA5hY2NvdW50QWRkcmVzcwIAAAAHUEVORElORwQAAAAVYWNjT3BlcmF0aW9uRGF0YUFycmF5CQEAAAAcYXNzZXRSZWFkU3dhcERhdGFBcnJheU9yRmFpbAAAAAEFAAAAD2FjY09wZXJhdGlvbktleQQAAAAIYW1vdW50SW4JAQAAAA1wYXJzZUludFZhbHVlAAAAAQkAAZEAAAACBQAAABVhY2NPcGVyYXRpb25EYXRhQXJyYXkFAAAAFElkeE9wZXJhdGlvbkFtb3VudEluBAAAAAdhc3NldEluCQABkQAAAAIFAAAAFWFjY09wZXJhdGlvbkRhdGFBcnJheQUAAAATSWR4T3BlcmF0aW9uQXNzZXRJbgQAAAAIYXNzZXRPdXQJAAGRAAAAAgUAAAAVYWNjT3BlcmF0aW9uRGF0YUFycmF5BQAAABRJZHhPcGVyYXRpb25Bc3NldE91dAMJAABmAAAAAgUAAAAMdW5sb2NrSGVpZ2h0BQAAAAZoZWlnaHQJAAACAAAAAQkAASwAAAACCQABLAAAAAICAAAADFBsZWFzZSB3YWl0IAkAAaQAAAABBQAAAAx1bmxvY2tIZWlnaHQCAAAAFyB0byB3aXRoZHJhdyB5b3VyIGZ1bmRzBAAAABBhY2NvdW50TG9ja2VkQW10BQAAAAhhbW91bnRJbgMJAABnAAAAAgAAAAAAAAAAAAUAAAAQYWNjb3VudExvY2tlZEFtdAkAAAIAAAABAgAAABFMb2NrZWRBbW91bnQgPD0gMAQAAAATYXNzZXRMb2NrZWRUb3RhbEtleQkBAAAAE2tleUFzc2V0TG9ja2VkVG90YWwAAAABCQABkQAAAAIFAAAAFWFjY09wZXJhdGlvbkRhdGFBcnJheQUAAAATSWR4T3BlcmF0aW9uQXNzZXRJbgQAAAAUY3VyckFzc2V0TG9ja2VkVG90YWwJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAABNhc3NldExvY2tlZFRvdGFsS2V5CQABLAAAAAIJAAEsAAAAAgIAAAAgU3RhdGUgY29udGFpbnMgc2VsbEFzc2V0UmVxdWVzdD0FAAAAD2FjY09wZXJhdGlvbktleQIAAAATIEJVVCBubyB0b3RhbExvY2tlZAQAAAAJaWR4SGVpZ2h0CQEAAAAXY29udHJvbEFjY1JlYWRJZHhIZWlnaHQAAAABBQAAAANpZHgEAAAADXByZXZJZHhIZWlnaHQJAQAAABdjb250cm9sQWNjUmVhZElkeEhlaWdodAAAAAEJAABlAAAAAgUAAAADaWR4AAAAAAAAAAABBAAAAAdjdXJySWR4CQEAAAAbY29udHJvbEFjY1JlYWRDdXJySWR4T3JGYWlsAAAAAAMDAwkAAGYAAAACBQAAAANpZHgFAAAAB2N1cnJJZHgGCQAAZgAAAAIFAAAADHVubG9ja0hlaWdodAUAAAAJaWR4SGVpZ2h0BgMJAQAAAAIhPQAAAAIFAAAADXByZXZJZHhIZWlnaHQAAAAAAAAAAAAJAABnAAAAAgUAAAANcHJldklkeEhlaWdodAUAAAAMdW5sb2NrSGVpZ2h0BwkAAAIAAAABCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABdpbnZhbGlkIHByaWNlIGlkeDogaWR4PQkAAaQAAAABBQAAAANpZHgCAAAACSBjdXJySWR4PQkAAaQAAAABBQAAAAdjdXJySWR4AgAAAAsgaWR4SGVpZ2h0PQkAAaQAAAABBQAAAAlpZHhIZWlnaHQCAAAADiB1bmxvY2tIZWlnaHQ9CQABpAAAAAEFAAAADHVubG9ja0hlaWdodAIAAAAPIHByZXZJZHhIZWlnaHQ9CQABpAAAAAEFAAAADXByZXZJZHhIZWlnaHQEAAAAEHN5bnRoMmJhc2ljUHJpY2UJAQAAABtjb250cm9sQWNjUmVhZFByaWNlQnlIZWlnaHQAAAABBQAAAAlpZHhIZWlnaHQEAAAADGFzc2V0SW5CeXRlcwkAAlkAAAABBQAAAAdhc3NldEluBAAAAA0kdDAxODYyMzE5NDkzAwkAAAAAAAACBQAAAAxhc3NldEluQnl0ZXMFAAAAC2Jhc2VBc3NldElkBAAAAAhzeW50aEFtdAkAAGsAAAADBQAAAAhhbW91bnRJbgUAAAANcHJpY2VEZWNpbWFscwUAAAAQc3ludGgyYmFzaWNQcmljZQkABRYAAAAEBQAAAAhzeW50aEFtdAkBAAAAB1JlaXNzdWUAAAADBQAAAAtkZWZvQXNzZXRJZAUAAAAIc3ludGhBbXQGCQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAAA5hY2NvdW50QWRkcmVzcwUAAAAIc3ludGhBbXQFAAAAC2RlZm9Bc3NldElkCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAADmtleVVjb2xsYXRlcmFsAAAAAAkAAGQAAAACBQAAAAt1Y29sbGF0ZXJhbAUAAAAIYW1vdW50SW4DCQAAAAAAAAIFAAAADGFzc2V0SW5CeXRlcwUAAAALZGVmb0Fzc2V0SWQEAAAACGJhc2ljQW10CQAAawAAAAMFAAAACGFtb3VudEluBQAAABBzeW50aDJiYXNpY1ByaWNlBQAAAA1wcmljZURlY2ltYWxzBAAAAA5uZXdVY29sbGF0ZXJhbAkAAGUAAAACBQAAAAt1Y29sbGF0ZXJhbAUAAAAIYmFzaWNBbXQJAAUWAAAABAUAAAAIYmFzaWNBbXQJAQAAAARCdXJuAAAAAgUAAAALYmFzZUFzc2V0SWQFAAAACGJhc2ljQW10CQEAAAAOU2NyaXB0VHJhbnNmZXIAAAADCQEAAAARQGV4dHJOYXRpdmUoMTA2MikAAAABBQAAAA5hY2NvdW50QWRkcmVzcwUAAAAIYmFzaWNBbXQFAAAAC2Jhc2VBc3NldElkCQEAAAAMSW50ZWdlckVudHJ5AAAAAgkBAAAADmtleVVjb2xsYXRlcmFsAAAAAAkAAGUAAAACBQAAAAt1Y29sbGF0ZXJhbAUAAAAIYmFzaWNBbXQJAAACAAAAAQkAASwAAAACAgAAABRVbnN1cHBvcnRlZCBhc3NldEluPQUAAAAHYXNzZXRJbgQAAAAJYW1vdW50T3V0CAUAAAANJHQwMTg2MjMxOTQ5MwAAAAJfMQQAAAALYnVybk9ySXNzdWUIBQAAAA0kdDAxODYyMzE5NDkzAAAAAl8yBAAAABR0cmFuc2ZlclN5bnRoT3JCYXNpYwgFAAAADSR0MDE4NjIzMTk0OTMAAAACXzMEAAAAEHVjb2xsYXRlcmFsRW50cnkIBQAAAA0kdDAxODYyMzE5NDkzAAAAAl80AwkAAGYAAAACAAAAAAAAAAAACQAAZQAAAAIFAAAAFGN1cnJBc3NldExvY2tlZFRvdGFsBQAAABBhY2NvdW50TG9ja2VkQW10CQAAAgAAAAEJAAEsAAAAAgkAASwAAAACAgAAABRJbnZhbGlkIGRhdGEgc3RhdGU6IAUAAAATYXNzZXRMb2NrZWRUb3RhbEtleQIAAAAMIGxlc3MgdGhlbiAwCQAETQAAAAIJAARNAAAAAgkABE0AAAACCQAETAAAAAIJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAABNhc3NldExvY2tlZFRvdGFsS2V5CQAAZQAAAAIFAAAAFGN1cnJBc3NldExvY2tlZFRvdGFsBQAAABBhY2NvdW50TG9ja2VkQW10CQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEFAAAAD2FjY09wZXJhdGlvbktleQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAATa2V5QWNjb3VudE9wZXJhdGlvbgAAAAMFAAAADHVubG9ja0hlaWdodAUAAAAOYWNjb3VudEFkZHJlc3MCAAAACEZJTklTSEVECQEAAAAWYXNzZXREYXRhU3dhcE9wZXJhdGlvbgAAAAcFAAAACGFtb3VudEluBQAAAAdhc3NldEluBQAAABBzeW50aDJiYXNpY1ByaWNlBQAAAAlhbW91bnRPdXQFAAAACGFzc2V0T3V0AAAAAAAAAAAAAAAAAAAAAAAABQAAAANuaWwFAAAAC2J1cm5Pcklzc3VlBQAAABR0cmFuc2ZlclN5bnRoT3JCYXNpYwUAAAAQdWNvbGxhdGVyYWxFbnRyeQAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAAEAAAAByRtYXRjaDAFAAAAAnR4AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAABdJbnZva2VTY3JpcHRUcmFuc2FjdGlvbgQAAAADaW52BQAAAAckbWF0Y2gwAwkBAAAAAiE9AAAAAggFAAAAA2ludgAAAAhmdW5jdGlvbgIAAAAOcmViYWxhbmNlRGVidHMJAAACAAAAAQIAAAAjb25seSByZWJhbGFuY2VEZWJ0cyBjYWxsIGlzIGFsbG93ZWQDCQEAAAACIT0AAAACCQABkQAAAAIJAQAAABxmYWN0b3J5UmVhZEFzc2V0Q2ZnQnlBZGRyZXNzAAAAAQkABCUAAAABCQAEJAAAAAEIBQAAAANpbnYAAAAEZEFwcAUAAAASSWR4RGVmb0Fzc2V0U3RhdHVzAgAAAAZJU1NVRUQJAAACAAAAAQIAAAAZb25seSBkZWZvIGRhcHAgaXMgYWxsb3dlZAMJAABmAAAAAggFAAAAA2ludgAAAANmZWUJAABoAAAAAgAAAAAAAAADhAAAAAAAAAAD6AkAAAIAAAABCQABLAAAAAICAAAAKGZlZSBhbW91bnQgaXMgZ3JlYXRlciB0aGFuIG1heCBhbGxvd2VkOiAJAAGkAAAAAQgFAAAAA2ludgAAAANmZWUDCQEAAAAJaXNEZWZpbmVkAAAAAQgFAAAAA2ludgAAAApmZWVBc3NldElkCQAAAgAAAAECAAAAI29ubHkgV2F2ZXMgaXMgYWxsb3dlZCBhcyBmZWVBc3NldElkBgkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAIBQAAAAJ0eAAAAA9zZW5kZXJQdWJsaWNLZXnZqYEL", "chainId": 84, "height": 1188749, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: none Next: none Full:
Old | New | Differences | |
---|---|---|---|
1 | - | # no script | |
1 | + | {-# STDLIB_VERSION 4 #-} | |
2 | + | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | + | {-# CONTENT_TYPE DAPP #-} | |
4 | + | func keyAccumulatedFee () = "%s__accumulatedFee" | |
5 | + | ||
6 | + | ||
7 | + | func keyUcollateral () = "%s__ucollateral" | |
8 | + | ||
9 | + | ||
10 | + | func keyTotalLendedAtOtherAccs () = "%s__totalLendedAtOtherAccs" | |
11 | + | ||
12 | + | ||
13 | + | func keyAssetLockedTotal (assetId) = ("%s%s__assetLockedTotal__" + assetId) | |
14 | + | ||
15 | + | ||
16 | + | func keyAccountOperation (unlockHeight,address,status) = ((((("%s%s%d%s__defoAssetOperation__" + address) + "__") + toString(unlockHeight)) + "__") + status) | |
17 | + | ||
18 | + | ||
19 | + | func keyFactory () = "%s__factory" | |
20 | + | ||
21 | + | ||
22 | + | func keyLendedAmountByAssetCode (assetCode) = ("%s%s__lendedBaseAssetAmount__" + assetCode) | |
23 | + | ||
24 | + | ||
25 | + | func keyPrice (assetCode) = ("%s%s__price__" + assetCode) | |
26 | + | ||
27 | + | ||
28 | + | let IdxOperationAmountIn = 1 | |
29 | + | ||
30 | + | let IdxOperationAssetIn = 2 | |
31 | + | ||
32 | + | let IdxOperationPrice = 3 | |
33 | + | ||
34 | + | let IdxOperationAmountOut = 4 | |
35 | + | ||
36 | + | let IdxOperationAssetOut = 5 | |
37 | + | ||
38 | + | func assetDataSwapOperation (amountIn,assetIn,price,amountOut,assetOut,bruttoAmount,feeAmount) = ((((((((((((("%d%s%d%s%d%d%d__" + toString(amountIn)) + "__") + assetIn) + "__") + toString(amountOut)) + "__") + assetOut) + "__") + toString(price)) + "__") + toString(bruttoAmount)) + "__") + toString(feeAmount)) | |
39 | + | ||
40 | + | ||
41 | + | func assetDataRebalanceTrace (debtorAssetCode,debtPmt,basePmt,lendedAmtBefore,lendedAmtAfter) = ((((((((((((("%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)) | |
42 | + | ||
43 | + | ||
44 | + | func assetReadSwapDataArrayOrFail (accOperationKey) = { | |
45 | + | let accOperationDataStr = valueOrErrorMessage(getString(this, accOperationKey), ("There is no request for passed arguments: " + accOperationKey)) | |
46 | + | split(accOperationDataStr, "__") | |
47 | + | } | |
48 | + | ||
49 | + | ||
50 | + | let nullInt = -1 | |
51 | + | ||
52 | + | let nullStr = "NULL" | |
53 | + | ||
54 | + | let factoryAcc = addressFromStringValue(valueOrErrorMessage(getString(this, keyFactory()), ((("No config at this=" + toString(this)) + " for key=") + keyFactory()))) | |
55 | + | ||
56 | + | func keyFactoryDebtAssetId () = "%s%s__commonConfig__debtAssetId" | |
57 | + | ||
58 | + | ||
59 | + | func keyFactoryAssetCfg (assetAddressStr) = (("%s%s%s__defoAsset__" + assetAddressStr) + "__config") | |
60 | + | ||
61 | + | ||
62 | + | func keyFactoryAssetCurrentPool (assetAccAddress) = (("%s%s%s__defoAsset__" + toString(assetAccAddress)) + "__currentPool") | |
63 | + | ||
64 | + | ||
65 | + | func keyFactoryDefoAddressByAssetCode (assetCode) = (("%s%s%s__defoAsset__" + assetCode) + "__addressByAssetCode") | |
66 | + | ||
67 | + | ||
68 | + | func factoryReadDebtAssetId () = valueOrErrorMessage(getString(factoryAcc, keyFactoryDebtAssetId()), ((("No config at factory=" + toString(factoryAcc)) + " for key=") + keyFactoryDebtAssetId())) | |
69 | + | ||
70 | + | ||
71 | + | func factoryReadAssetCfgByAddress (assetAddressStr) = split(valueOrErrorMessage(getString(factoryAcc, keyFactoryAssetCfg(assetAddressStr)), ((("No config at factory=" + toString(factoryAcc)) + " for key=") + keyFactoryAssetCfg(assetAddressStr))), "__") | |
72 | + | ||
73 | + | ||
74 | + | func factoryReadAssetCfgByCode (assetCode) = { | |
75 | + | let assetAddressStr = valueOrErrorMessage(getString(factoryAcc, keyFactoryDefoAddressByAssetCode(assetCode)), ((("No config at factory=" + toString(factoryAcc)) + " for key=") + keyFactoryDefoAddressByAssetCode(assetCode))) | |
76 | + | $Tuple2(assetAddressStr, factoryReadAssetCfgByAddress(assetAddressStr)) | |
77 | + | } | |
78 | + | ||
79 | + | ||
80 | + | let IdxDefoAssetCode = 1 | |
81 | + | ||
82 | + | let IdxDefoAssetId = 2 | |
83 | + | ||
84 | + | let IdxDefoAssetStatus = 3 | |
85 | + | ||
86 | + | let IdxPriceDecimals = 4 | |
87 | + | ||
88 | + | let IdxBaseAssetId = 5 | |
89 | + | ||
90 | + | let IdxOverCollateralPercent = 6 | |
91 | + | ||
92 | + | let IdxMinInitPool = 7 | |
93 | + | ||
94 | + | let IdxPriceOracleAddress = 8 | |
95 | + | ||
96 | + | let IdxMinBuyPayment = 9 | |
97 | + | ||
98 | + | let IdxMinSellPayment = 10 | |
99 | + | ||
100 | + | let IdxBuyLockInterval = 11 | |
101 | + | ||
102 | + | let IdxSellLockInterval = 12 | |
103 | + | ||
104 | + | let IdxBuyFeePercent = 13 | |
105 | + | ||
106 | + | let IdxSellFeePercent = 14 | |
107 | + | ||
108 | + | let thisCfgArray = factoryReadAssetCfgByAddress(toString(this)) | |
109 | + | ||
110 | + | let defoAssetCode = thisCfgArray[IdxDefoAssetCode] | |
111 | + | ||
112 | + | let defoAssetId = fromBase58String(thisCfgArray[IdxDefoAssetId]) | |
113 | + | ||
114 | + | let priceOracleAcc = addressFromStringValue(thisCfgArray[IdxPriceOracleAddress]) | |
115 | + | ||
116 | + | let overCollateralPercent = parseIntValue(thisCfgArray[IdxOverCollateralPercent]) | |
117 | + | ||
118 | + | let baseAssetIdStr = thisCfgArray[IdxBaseAssetId] | |
119 | + | ||
120 | + | let baseAssetId = fromBase58String(baseAssetIdStr) | |
121 | + | ||
122 | + | let priceDecimals = parseIntValue(thisCfgArray[IdxPriceDecimals]) | |
123 | + | ||
124 | + | let minBasicBuyAmount = parseIntValue(thisCfgArray[IdxMinBuyPayment]) | |
125 | + | ||
126 | + | let minSynthSellAmount = parseIntValue(thisCfgArray[IdxMinSellPayment]) | |
127 | + | ||
128 | + | let buyLockInterval = parseIntValue(thisCfgArray[IdxBuyLockInterval]) | |
129 | + | ||
130 | + | let sellLockInterval = parseIntValue(thisCfgArray[IdxSellLockInterval]) | |
131 | + | ||
132 | + | let buyFeePercent = parseIntValue(thisCfgArray[IdxBuyFeePercent]) | |
133 | + | ||
134 | + | let sellFeePercent = parseIntValue(thisCfgArray[IdxSellFeePercent]) | |
135 | + | ||
136 | + | func controlAccReadPrice (assetCode) = valueOrErrorMessage(getInteger(priceOracleAcc, keyPrice(assetCode)), ((("No price at priceOracle=" + toString(priceOracleAcc)) + " for key=") + keyPrice(assetCode))) | |
137 | + | ||
138 | + | ||
139 | + | func controlAccReadCurrIdxOrFail () = valueOrErrorMessage(getInteger(priceOracleAcc, "currIdx"), ("No currIdx at controlAcc=" + toString(priceOracleAcc))) | |
140 | + | ||
141 | + | ||
142 | + | func controlAccReadIdxHeight (idx) = { | |
143 | + | let idxHeightKey = ("idxHeight_" + toString(idx)) | |
144 | + | valueOrElse(getInteger(priceOracleAcc, idxHeightKey), 0) | |
145 | + | } | |
146 | + | ||
147 | + | ||
148 | + | func controlAccReadPriceByHeight (priceHeight) = { | |
149 | + | let priceByHeightKey = ("price_" + toString(priceHeight)) | |
150 | + | valueOrErrorMessage(getInteger(priceOracleAcc, priceByHeightKey), ((("No " + priceByHeightKey) + " at controlAcc=") + toString(priceOracleAcc))) | |
151 | + | } | |
152 | + | ||
153 | + | ||
154 | + | func getStakingBalance () = valueOrElse(getInteger(this, ((("rpd_balance_" + baseAssetIdStr) + "_") + toString(this))), 0) | |
155 | + | ||
156 | + | ||
157 | + | let ucollateral = valueOrElse(getInteger(this, keyUcollateral()), 0) | |
158 | + | ||
159 | + | let accumulatedFee = valueOrElse(getInteger(this, keyAccumulatedFee()), 0) | |
160 | + | ||
161 | + | let currPoolAmount = getIntegerValue(factoryAcc, keyFactoryAssetCurrentPool(this)) | |
162 | + | ||
163 | + | let doubleCheckBasicBalance = (assetBalance(this, baseAssetId) + getStakingBalance()) | |
164 | + | ||
165 | + | let doubleCheckUcollateral = if ((0 > ucollateral)) | |
166 | + | then 0 | |
167 | + | else ucollateral | |
168 | + | ||
169 | + | let doubleCheckCurrPoolAmount = (doubleCheckBasicBalance - ucollateral) | |
170 | + | ||
171 | + | let price = controlAccReadPrice(thisCfgArray[IdxDefoAssetCode]) | |
172 | + | ||
173 | + | let overPrice = (((priceDecimals + overCollateralPercent) * price) / priceDecimals) | |
174 | + | ||
175 | + | let emission = value(assetInfo(defoAssetId)).quantity | |
176 | + | ||
177 | + | let basicAssetLockedAmt = valueOrElse(getInteger(this, keyAssetLockedTotal(baseAssetIdStr)), 0) | |
178 | + | ||
179 | + | let availablePoolBalance = (currPoolAmount - basicAssetLockedAmt) | |
180 | + | ||
181 | + | func internalBuyAsset (sellerAddr,sellAmt,sellAssetId,minSellAmt,buy2sellPrice,feePercent) = { | |
182 | + | let availableDefoAssetInPool = (fraction(availablePoolBalance, priceDecimals, overPrice) - emission) | |
183 | + | let fullDefoAssetAmountNoPoolLimit = fraction(sellAmt, priceDecimals, buy2sellPrice) | |
184 | + | let fullDefoAssetAmountBrutto = if ((fullDefoAssetAmountNoPoolLimit > availableDefoAssetInPool)) | |
185 | + | then availableDefoAssetInPool | |
186 | + | else fullDefoAssetAmountNoPoolLimit | |
187 | + | let defoAssetAmount = fraction((priceDecimals - feePercent), fullDefoAssetAmountBrutto, priceDecimals) | |
188 | + | let feeAmount = (fullDefoAssetAmountBrutto - defoAssetAmount) | |
189 | + | let requiredBasicAssetAmount = fraction(fullDefoAssetAmountBrutto, buy2sellPrice, priceDecimals) | |
190 | + | let change = (sellAmt - requiredBasicAssetAmount) | |
191 | + | if ((0 >= availableDefoAssetInPool)) | |
192 | + | then throw((("impossible to issue new " + defoAssetCode) + ": not enough collateral")) | |
193 | + | else if ((minSellAmt > sellAmt)) | |
194 | + | then throw(((((("impossible to issue new " + defoAssetCode) + ": payment=") + toString(sellAmt)) + "is less then min amount=") + toString(minSellAmt))) | |
195 | + | else $Tuple2([IntegerEntry(keyUcollateral(), (ucollateral + requiredBasicAssetAmount)), StringEntry(keyAccountOperation(height, toString(sellerAddr), "FINISHED"), assetDataSwapOperation(sellAmt, toBase58String(sellAssetId), price, defoAssetAmount, toBase58String(defoAssetId), fullDefoAssetAmountBrutto, feeAmount)), Reissue(defoAssetId, (defoAssetAmount + feeAmount), true), ScriptTransfer(sellerAddr, defoAssetAmount, defoAssetId), ScriptTransfer(sellerAddr, change, sellAssetId), IntegerEntry(keyAccumulatedFee(), (accumulatedFee + feeAmount))], change) | |
196 | + | } | |
197 | + | ||
198 | + | ||
199 | + | @Callable(i) | |
200 | + | func buyAsset () = { | |
201 | + | let pmt = value(i.payments[0]) | |
202 | + | let pmtAssetId = value(pmt.assetId) | |
203 | + | if ((pmtAssetId != baseAssetId)) | |
204 | + | then throw(((("Payment asset id doesn't match basic asset: expected=" + toBase58String(baseAssetId)) + " actual=") + toBase58String(pmtAssetId))) | |
205 | + | else internalBuyAsset(i.caller, pmt.amount, pmtAssetId, minBasicBuyAmount, price, buyFeePercent)._1 | |
206 | + | } | |
207 | + | ||
208 | + | ||
209 | + | ||
210 | + | @Callable(i) | |
211 | + | func sellAsset () = { | |
212 | + | let pmt = value(i.payments[0]) | |
213 | + | let pmtAsset = value(pmt.assetId) | |
214 | + | let callerAddress = toString(i.caller) | |
215 | + | if ((pmtAsset != defoAssetId)) | |
216 | + | then throw(((("Invalid payment asset id: expected=" + toBase58String(defoAssetId)) + " actual=") + toBase58String(pmtAsset))) | |
217 | + | else if ((minSynthSellAmount > pmt.amount)) | |
218 | + | then throw(((("Payment amount less then mininimal allowed: paymentAmount=" + toString(pmt.amount)) + " minAmount=") + toString(minSynthSellAmount))) | |
219 | + | else { | |
220 | + | let pmtDefoAmountGross = pmt.amount | |
221 | + | let defoAmountFee = fraction((priceDecimals - sellFeePercent), pmtDefoAmountGross, priceDecimals) | |
222 | + | let pmtDefoAmountNoFee = (pmtDefoAmountGross - defoAmountFee) | |
223 | + | let baseAssetAmountNoBalanceLimit = fraction(pmtDefoAmountNoFee, price, priceDecimals) | |
224 | + | let baseAssetAmountNoFee = if ((baseAssetAmountNoBalanceLimit > doubleCheckCurrPoolAmount)) | |
225 | + | then doubleCheckCurrPoolAmount | |
226 | + | else baseAssetAmountNoBalanceLimit | |
227 | + | let requiredDefoAssetAmount = fraction(baseAssetAmountNoFee, priceDecimals, price) | |
228 | + | let change = (pmtDefoAmountNoFee - requiredDefoAssetAmount) | |
229 | + | [IntegerEntry(keyUcollateral(), (ucollateral - baseAssetAmountNoFee)), StringEntry(keyAccountOperation(height, callerAddress, "FINISHED"), assetDataSwapOperation(pmt.amount, toBase58String(pmtAsset), price, baseAssetAmountNoFee, baseAssetIdStr, pmtDefoAmountGross, defoAmountFee)), Burn(defoAssetId, requiredDefoAssetAmount), ScriptTransfer(i.caller, baseAssetAmountNoFee, baseAssetId), ScriptTransfer(i.caller, change, defoAssetId), IntegerEntry(keyAccumulatedFee(), (accumulatedFee + defoAmountFee))] | |
230 | + | } | |
231 | + | } | |
232 | + | ||
233 | + | ||
234 | + | ||
235 | + | @Callable(i) | |
236 | + | func crossExchange (buyAssetId,buyAssetCodeConfirm,sellAssetCodeConfirm) = { | |
237 | + | let pmt = value(i.payments[0]) | |
238 | + | let pmtAsset = value(pmt.assetId) | |
239 | + | let pmtAssetStr = toBase58String(pmtAsset) | |
240 | + | let pmtAmount = pmt.amount | |
241 | + | let callerAddress = toString(i.caller) | |
242 | + | let buyAssetCfg = thisCfgArray | |
243 | + | let sellAssetTuple = factoryReadAssetCfgByCode(sellAssetCodeConfirm) | |
244 | + | let sellAssetCfg = sellAssetTuple._2 | |
245 | + | let sellAssetAccAddress = valueOrErrorMessage(addressFromString(sellAssetTuple._1), ("couldn't parse address from string for assetCode=" + sellAssetCodeConfirm)) | |
246 | + | let minSellPmt = valueOrErrorMessage(parseInt(sellAssetCfg[IdxMinSellPayment]), ("minSellPmt parsing error: rawVal=" + sellAssetCfg[IdxMinSellPayment])) | |
247 | + | if ((thisCfgArray[IdxDefoAssetId] != buyAssetId)) | |
248 | + | then throw(((("buyAsset confirmation failed: buyAssetIdConfirm=" + thisCfgArray[IdxDefoAssetId]) + " BUT buyAssetId=") + buyAssetId)) | |
249 | + | else if ((sellAssetCfg[IdxDefoAssetId] != pmtAssetStr)) | |
250 | + | then throw(((("sellAsset confirmation failed: sellAssetIdConfirm=" + sellAssetCfg[IdxDefoAssetId]) + "BUT pmtAsset=") + pmtAssetStr)) | |
251 | + | else if ((thisCfgArray[IdxDefoAssetStatus] != "ISSUED")) | |
252 | + | then throw(((("toAsset has not been issued yet: buyAssetId=" + buyAssetId) + " BUT status=") + thisCfgArray[IdxDefoAssetStatus])) | |
253 | + | else if ((sellAssetCfg[IdxDefoAssetStatus] != "ISSUED")) | |
254 | + | then throw(((("fromAssetCfg has not been issued yet: sellAssetId=" + pmtAssetStr) + " BUT status=") + sellAssetCfg[IdxDefoAssetStatus])) | |
255 | + | else { | |
256 | + | let buyAssetUsdPrice = price | |
257 | + | let sellAssetUsdPrice = controlAccReadPrice(sellAssetCodeConfirm) | |
258 | + | let buy2sellPrice = fraction(buyAssetUsdPrice, priceDecimals, sellAssetUsdPrice) | |
259 | + | let debtAssetId = fromBase58String(factoryReadDebtAssetId()) | |
260 | + | let usdnDebt = fraction(sellAssetUsdPrice, pmtAmount, priceDecimals) | |
261 | + | let totalLendedAtOtherAccs = valueOrElse(getInteger(this, keyTotalLendedAtOtherAccs()), 0) | |
262 | + | let lendedAmountByAssetCodeKey = keyLendedAmountByAssetCode(sellAssetCodeConfirm) | |
263 | + | let lendedAmtByAssetCode = valueOrElse(getInteger(this, lendedAmountByAssetCodeKey), 0) | |
264 | + | let buyAssetResult = internalBuyAsset(i.caller, pmtAmount, pmtAsset, minSellPmt, buy2sellPrice, fraction(buyFeePercent, 150, 100)) | |
265 | + | ((buyAssetResult._1 :+ IntegerEntry(lendedAmountByAssetCodeKey, (lendedAmtByAssetCode + usdnDebt))) :+ IntegerEntry(keyTotalLendedAtOtherAccs(), (totalLendedAtOtherAccs + usdnDebt))) | |
266 | + | } | |
267 | + | } | |
268 | + | ||
269 | + | ||
270 | + | ||
271 | + | @Callable(i) | |
272 | + | func rebalanceDebts () = { | |
273 | + | let debtAssetId = fromBase58String(factoryReadDebtAssetId()) | |
274 | + | let debtPmt0 = value(i.payments[0]) | |
275 | + | let debtPmtAsset0 = value(debtPmt0.assetId) | |
276 | + | let basePmt1 = value(i.payments[1]) | |
277 | + | let basePmtAsset1 = value(basePmt1.assetId) | |
278 | + | let debtorAddress = toString(i.caller) | |
279 | + | let debtorAssetCfg = factoryReadAssetCfgByAddress(debtorAddress) | |
280 | + | let debtorAssetCode = debtorAssetCfg[IdxDefoAssetCode] | |
281 | + | let lendedAmountByAssetCodeKey = keyLendedAmountByAssetCode(debtorAssetCode) | |
282 | + | let lendedAmt = valueOrErrorMessage(getInteger(this, lendedAmountByAssetCodeKey), ("No debts for " + debtorAssetCode)) | |
283 | + | if ((debtAssetId != debtPmtAsset0)) | |
284 | + | then throw(((("invalid debt asset id in the first paymet: expected=" + toBase58String(debtAssetId)) + " actual=") + toBase58String(debtPmtAsset0))) | |
285 | + | else if ((baseAssetId != basePmtAsset1)) | |
286 | + | then throw(((("invalid base asset id in the second payment: expected=" + toBase58String(baseAssetId)) + " actual=") + toBase58String(basePmtAsset1))) | |
287 | + | else if ((debtPmt0.amount != basePmt1.amount)) | |
288 | + | then throw("first payment amount doesn't match to the second payment amount") | |
289 | + | else if ((0 >= lendedAmt)) | |
290 | + | then throw(("lendedAmt is less then zero: lendedAmt=" + toString(lendedAmt))) | |
291 | + | else if ((0 >= debtPmt0.amount)) | |
292 | + | then throw(("attached payment must be greater then 0: pmt0.amount=" + toString(debtPmt0.amount))) | |
293 | + | else if ((debtPmt0.amount > lendedAmt)) | |
294 | + | then throw(((("attached payment is grater than required: pmtAmount=" + toString(debtPmt0.amount)) + " lendedAmt=") + toString(lendedAmt))) | |
295 | + | else { | |
296 | + | let totalLendedAtOtherAccs = valueOrElse(getInteger(this, keyTotalLendedAtOtherAccs()), 0) | |
297 | + | let lendedAmtAfter = (lendedAmt - debtPmt0.amount) | |
298 | + | [IntegerEntry(lendedAmountByAssetCodeKey, lendedAmtAfter), IntegerEntry(keyTotalLendedAtOtherAccs(), (totalLendedAtOtherAccs - debtPmt0.amount)), StringEntry(("%s%s__rebalanceTrace__" + toBase58String(i.transactionId)), assetDataRebalanceTrace(debtorAssetCode, debtPmt0, basePmt1, lendedAmt, lendedAmtAfter))] | |
299 | + | } | |
300 | + | } | |
301 | + | ||
302 | + | ||
303 | + | ||
304 | + | @Callable(i) | |
305 | + | func withdraw (accountAddress,unlockHeight,idx) = { | |
306 | + | let accOperationKey = keyAccountOperation(unlockHeight, accountAddress, "PENDING") | |
307 | + | let accOperationDataArray = assetReadSwapDataArrayOrFail(accOperationKey) | |
308 | + | let amountIn = parseIntValue(accOperationDataArray[IdxOperationAmountIn]) | |
309 | + | let assetIn = accOperationDataArray[IdxOperationAssetIn] | |
310 | + | let assetOut = accOperationDataArray[IdxOperationAssetOut] | |
311 | + | if ((unlockHeight > height)) | |
312 | + | then throw((("Please wait " + toString(unlockHeight)) + " to withdraw your funds")) | |
313 | + | else { | |
314 | + | let accountLockedAmt = amountIn | |
315 | + | if ((0 >= accountLockedAmt)) | |
316 | + | then throw("LockedAmount <= 0") | |
317 | + | else { | |
318 | + | let assetLockedTotalKey = keyAssetLockedTotal(accOperationDataArray[IdxOperationAssetIn]) | |
319 | + | let currAssetLockedTotal = valueOrErrorMessage(getInteger(this, assetLockedTotalKey), (("State contains sellAssetRequest=" + accOperationKey) + " BUT no totalLocked")) | |
320 | + | let idxHeight = controlAccReadIdxHeight(idx) | |
321 | + | let prevIdxHeight = controlAccReadIdxHeight((idx - 1)) | |
322 | + | let currIdx = controlAccReadCurrIdxOrFail() | |
323 | + | if (if (if ((idx > currIdx)) | |
324 | + | then true | |
325 | + | else (unlockHeight > idxHeight)) | |
326 | + | then true | |
327 | + | else if ((prevIdxHeight != 0)) | |
328 | + | then (prevIdxHeight >= unlockHeight) | |
329 | + | else false) | |
330 | + | then throw(((((((((("invalid price idx: idx=" + toString(idx)) + " currIdx=") + toString(currIdx)) + " idxHeight=") + toString(idxHeight)) + " unlockHeight=") + toString(unlockHeight)) + " prevIdxHeight=") + toString(prevIdxHeight))) | |
331 | + | else { | |
332 | + | let synth2basicPrice = controlAccReadPriceByHeight(idxHeight) | |
333 | + | let assetInBytes = fromBase58String(assetIn) | |
334 | + | let $t01862319493 = if ((assetInBytes == baseAssetId)) | |
335 | + | then { | |
336 | + | let synthAmt = fraction(amountIn, priceDecimals, synth2basicPrice) | |
337 | + | $Tuple4(synthAmt, Reissue(defoAssetId, synthAmt, true), ScriptTransfer(addressFromStringValue(accountAddress), synthAmt, defoAssetId), IntegerEntry(keyUcollateral(), (ucollateral + amountIn))) | |
338 | + | } | |
339 | + | else if ((assetInBytes == defoAssetId)) | |
340 | + | then { | |
341 | + | let basicAmt = fraction(amountIn, synth2basicPrice, priceDecimals) | |
342 | + | let newUcollateral = (ucollateral - basicAmt) | |
343 | + | $Tuple4(basicAmt, Burn(baseAssetId, basicAmt), ScriptTransfer(addressFromStringValue(accountAddress), basicAmt, baseAssetId), IntegerEntry(keyUcollateral(), (ucollateral - basicAmt))) | |
344 | + | } | |
345 | + | else throw(("Unsupported assetIn=" + assetIn)) | |
346 | + | let amountOut = $t01862319493._1 | |
347 | + | let burnOrIssue = $t01862319493._2 | |
348 | + | let transferSynthOrBasic = $t01862319493._3 | |
349 | + | let ucollateralEntry = $t01862319493._4 | |
350 | + | if ((0 > (currAssetLockedTotal - accountLockedAmt))) | |
351 | + | then throw((("Invalid data state: " + assetLockedTotalKey) + " less then 0")) | |
352 | + | else ((([IntegerEntry(assetLockedTotalKey, (currAssetLockedTotal - accountLockedAmt)), DeleteEntry(accOperationKey), StringEntry(keyAccountOperation(unlockHeight, accountAddress, "FINISHED"), assetDataSwapOperation(amountIn, assetIn, synth2basicPrice, amountOut, assetOut, 0, 0))] :+ burnOrIssue) :+ transferSynthOrBasic) :+ ucollateralEntry) | |
353 | + | } | |
354 | + | } | |
355 | + | } | |
356 | + | } | |
357 | + | ||
358 | + | ||
359 | + | @Verifier(tx) | |
360 | + | func verify () = match tx { | |
361 | + | case inv: InvokeScriptTransaction => | |
362 | + | if ((inv.function != "rebalanceDebts")) | |
363 | + | then throw("only rebalanceDebts call is allowed") | |
364 | + | else if ((factoryReadAssetCfgByAddress(toString(addressFromRecipient(inv.dApp)))[IdxDefoAssetStatus] != "ISSUED")) | |
365 | + | then throw("only defo dapp is allowed") | |
366 | + | else if ((inv.fee > (900 * 1000))) | |
367 | + | then throw(("fee amount is greater than max allowed: " + toString(inv.fee))) | |
368 | + | else if (isDefined(inv.feeAssetId)) | |
369 | + | then throw("only Waves is allowed as feeAssetId") | |
370 | + | else true | |
371 | + | case _ => | |
372 | + | sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
373 | + | } | |
374 | + |
github/deemru/w8io/026f985 27.04 ms ◑