2021.03.16 19:56 [2505171] smart account 3P9ZegsKUtsEpdRPNVrMH7nHEEqY5MrmjDp > SELF 0.00000000 Waves
{ "type": 13, "id": "FME1ftFJS9X58ARtT2mSb19qHiAZf6Y7HYhDKVbNxNbc", "fee": 1400000, "feeAssetId": null, "timestamp": 1615912598713, "version": 1, "sender": "3P9ZegsKUtsEpdRPNVrMH7nHEEqY5MrmjDp", "senderPublicKey": "7ziFsWp9eo6kUB6ovqQzJfjgQarifNfpCGNW9DZi8YhN", "proofs": [ "3Ur65Sta7EXzwKmSdJVZwX2dhCSkDdNntKwUNLvshVNxu8p4cp8MretyU4jFmH9sN5zSFeyUrcdEdGPkRdN8Gnpg", "jJLHo2P2ZGidQuDq9kxUjMfex47swe6hQgsLDq9LdTzcW76H8Wxe5E4RiLCNfZUhHkSgFP3YcSuRg1A1TqrGZmc" ], "script": "base64:AAIEAAAAAAAAADgIAhINCgsICAgICAgICAgBARIDCgEBEgASAwoBARIDCgEIEgQKAggBEgASAwoBARIAEgMKAQESAAAAAG0BAAAAAlNFAAAAAgAAAAFrAAAAAXYJAQAAAAtTdHJpbmdFbnRyeQAAAAIFAAAAAWsFAAAAAXYBAAAAAklFAAAAAgAAAAFrAAAAAXYJAQAAAAxJbnRlZ2VyRW50cnkAAAACBQAAAAFrBQAAAAF2AQAAAAJTVAAAAAMAAAABYQAAAANhbXQAAAABdAkBAAAADlNjcmlwdFRyYW5zZmVyAAAAAwUAAAABYQUAAAADYW10BQAAAAF0AAAAAAR0ZW42AAAAAAAAD0JAAAAAAAR0ZW44AAAAAAAF9eEAAAAAAANNQVgAf/////////8AAAAAEWNvbmZpZ1Byb3ZpZGVyS2V5AgAAAA5jb25maWdQcm92aWRlcgAAAAAOY29uZmlnUHJvdmlkZXIEAAAAByRtYXRjaDAJAAQdAAAAAgUAAAAEdGhpcwUAAAARY29uZmlnUHJvdmlkZXJLZXkDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABcwUAAAAHJG1hdGNoMAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQUAAAABcwUAAAAEdGhpcwEAAAAGbG9jYWxJAAAAAgAAAAFrAAAAAWUJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAAAFrBQAAAAFlAQAAAAZsb2NhbFMAAAACAAAAAWsAAAABZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAABHRoaXMFAAAAAWsFAAAAAWUBAAAABWNvbmZJAAAAAgAAAAFrAAAAAWUJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAA5jb25maWdQcm92aWRlcgUAAAABawUAAAABZQEAAAAFY29uZlMAAAACAAAAAWsAAAABZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEHQAAAAIFAAAADmNvbmZpZ1Byb3ZpZGVyBQAAAAFrBQAAAAFlAAAAAAVCVUxMSwIAAAAGQlVMTElkAAAAAAVCRUFSSwIAAAAGQkVBUklkAAAAAAVVU0ROSwIAAAALbWFpblRva2VuSWQAAAAACEJVTExDT0xLAgAAAA5idWxsQ29sbGF0ZXJhbAAAAAAIQkVBUkNPTEsCAAAADmJlYXJDb2xsYXRlcmFsAAAAAAlCVUxMQ0lSQ0sCAAAAD2J1bGxDaXJjdWxhdGlvbgAAAAAJQkVBUkNJUkNLAgAAAA9iZWFyQ2lyY3VsYXRpb24AAAAACElTU1BFUkNLAgAAAA9pc3N1ZVBlcmNlbnRpbGUAAAAACFJFRFBFUkNLAgAAABByZWRlZW1QZXJjZW50aWxlAAAAAAdNSU5JU1NLAgAAAAhtaW5Jc3N1ZQAAAAAHTUlOUkVESwIAAAAJbWluUmVkZWVtAAAAAAhNSU5QT09MSwIAAAAHbWluUG9vbAAAAAAHRkVFQUNDSwIAAAAPZmVlc0FjY3VtdWxhdGVkAAAAAAZXTElTVEsCAAAADmlzc3VlV2hpdGVMaXN0AAAAAAhSRUJQRVJDSwIAAAATcmViYWxhbmNlUGVyY2VudGlsZQAAAAAHUkVCSURYSwIAAAAVbGFzdFNldHRsZW1lbnRQcmljZUlkAAAAAAVIRUFESwIAAAALaGVhZFBvaW50ZXIAAAAABVRBSUxLAgAAAAt0YWlsUG9pbnRlcgAAAAAGUVNJWkVLAgAAAAlxdWV1ZVNpemUAAAAACVBPT0xVU0ROSwIAAAAScG9vbE1haW5Ub2tlblZhbHVlAAAAAAdQT09MVVBLAgAAAAZwb29sVXAAAAAACFBPT0xEV05LAgAAAAdwb29sRHduAAAAAAlQT09MQ0lSQ0sCAAAAFHBvb2xUb2tlbkNpcmN1bGF0aW9uAAAAAAVQT09MSwIAAAAJcG9vbFRva2VuAAAAAAhBU1NOQU1FSwIAAAANZGVmb0Fzc2V0TmFtZQAAAAAETEVWSwIAAAAIbGV2ZXJhZ2UAAAAACVdBVkVTRkVFSwIAAAARd2F2ZXNQYWNlbWFrZXJGZWUAAAAACFVTRE5GRUVLAgAAABB1c2RuUGFjZW1ha2VyRmVlAAAAAAtvcmFjbGVQS0tleQIAAAAGb3JhY2xlAQAAABFsYXN0UHJpY2VJbmRleEtleQAAAAEAAAAHYXNzZXRJZAMJAAAAAAAAAgUAAAAHYXNzZXRJZAIAAAAAAgAAAAtwcmljZV9pbmRleAkAASwAAAAC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AGsAAAADBQAAAAdiZWFyQ29sBQAAAAdwb29sRHduBQAAAAhiZWFyQ2lyYwAAAAAJcG9vbFZhbHVlCQAAZAAAAAIJAABkAAAAAgUAAAAIcG9vbE1haW4FAAAAEHBvb2xCdWxsRXhwb3N1cmUFAAAAEHBvb2xCZWFyRXhwb3N1cmUAAAAABm9yYWNsZQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQEAAAAUYWRkcmVzc0Zyb21QdWJsaWNLZXkAAAABCQACWQAAAAEJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABB0AAAACBQAAAAR0aGlzBQAAAAtvcmFjbGVQS0tleQIAAAAObm8gb3JhY2xlUEtLZXkCAAAAEmJhZCBvcmFjbGUgYWRkcmVzcwAAAAAUcmViYWxhbmNlZFByaWNlSW5kZXgJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAAAdSRUJJRFhLAgAAABdubyBsYXN0IHJlYmFsYW5jZSBwcmljZQAAAAAQb3JhY2xlUHJpY2VJbmRleAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABm9yYWNsZQkBAAAAEWxhc3RQcmljZUluZGV4S2V5AAAAAQUAAAAJYXNzZXROYW1lCQABLAAAAAIJAAEsAAAAAgkAASwAAAACAgAAABNiYWQgb3JhY2xlIGRhdGEgYXQgCQAEJQAAAAEFAAAABm9yYWNsZQIAAAAQOiBubyBpbnRlZ2VyIGF0IAkBAAAAEWxhc3RQcmljZUluZGV4S2V5AAAAAQUAAAAJYXNzZXROYW1lAAAAAAhsZXZlcmFnZQkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABBoAAAACBQAAAAR0aGlzBQAAAARMRVZLAAAAAAAAAAADAQAAAA1oZWlnaHRCeUluZGV4AAAAAgAAAAlhc3NldE5hbWUAAAAKcHJpY2VJbmRleAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABm9yYWNsZQkAASwAAAACCQEAAAAQcHJpY2VJbmRleFByZWZpeAAAAAEFAAAACWFzc2V0TmFtZQkAAaQAAAABBQAAAApwcmljZUluZGV4CQABLAAAAAICAAAAEW5vIGRhdGEgYXQgaW5kZXggCQABpAAAAAEFAAAACnByaWNlSW5kZXgBAAAADXByaWNlQnlIZWlnaHQAAAACAAAACWFzc2V0TmFtZQAAAAtwcmljZUhlaWdodAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABm9yYWNsZQkAASwAAAACCQEAAAARcHJpY2VIZWlnaHRQcmVmaXgAAAABBQAAAAlhc3NldE5hbWUJAAGkAAAAAQUAAAALcHJpY2VIZWlnaHQJAAEsAAAAAgIAAAATbm8gZGF0YSBmb3IgaGVpZ2h0IAkAAaQAAAABBQAAAAtwcmljZUhlaWdodAEAAAAMcHJpY2VCeUluZGV4AAAAAgAAAAlhc3NldE5hbWUAAAAKcHJpY2VJbmRleAkBAAAADXByaWNlQnlIZWlnaHQAAAACBQAAAAlhc3NldE5hbWUJAQAAAA1oZWlnaHRCeUluZGV4AAAAAgUAAAAJYXNzZXROYW1lBQAAAApwcmljZUluZGV4AAAAAAlxdWV1ZVNpemUJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAGUVNJWkVLAAAAAAAAAAAAAAAAAAtoZWFkUG9pbnRlcgkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACBQAAAAR0aGlzBQAAAAVIRUFESwIAAAAAAAAAAAt0YWlsUG9pbnRlcgkBAAAAC3ZhbHVlT3JFbHNlAAAAAgkABB0AAAACBQAAAAR0aGlzBQAAAAVUQUlMSwIAAAAAAAAAAA9mZWVzQWNjdW11bGF0ZWQJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQaAAAAAgUAAAAEdGhpcwUAAAAHRkVFQUNDSwAAAAAAAAAAAAAAAAAFSVNTVUUCAAAABUlTU1VFAAAAAAZSRURFRU0CAAAABlJFREVFTQAAAAAEUE9PTAIAAAAEUE9PTAAAAAAGVU5QT09MAgAAAAZVTlBPT0wAAAAACmZlZUFkZHJLZXkCAAAACmZlZUFkZHJlc3MAAAAADnN0YWtpbmdBZGRyS2V5AgAAAA5zdGFraW5nQWRkcmVzcwAAAAAPZGFlbW9uUHViS2V5S2V5AgAAAA9kYWVtb25QdWJsaWNLZXkAAAAACmZlZUFkZHJlc3MJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABCQEAAAAFY29uZlMAAAACBQAAAApmZWVBZGRyS2V5AgAAAA1ubyBmZWVBZGRyZXNzAgAAAA5iYWQgZmVlQWRkcmVzcwAAAAAOc3Rha2luZ0FkZHJlc3MJAQAAAAVjb25mUwAAAAIFAAAADnN0YWtpbmdBZGRyS2V5AgAAABFubyBzdGFraW5nQWRkcmVzcwAAAAAPZGFlbW9uUHVibGljS2V5CQACWQAAAAEJAQAAAAVjb25mUwAAAAIFAAAAD2RhZW1vblB1YktleUtleQIAAAASbm8gZGFlbW9uUHVibGljS2V5AAAAAApycGRBZGRyZXNzCQAEJgAAAAECAAAAIzNQTmlrTTZ5cDROcWNTVThndXhRdG1SNW9ucjJENGU4eVRKAAAAAAZhZG1pbnMJAARMAAAAAgIAAAAsMkhIcVY4VzlESmF5VjVSNnRCRDJTYjhzcnBocG9ib0RpN3IxdDFhUGl1bUMJAARMAAAAAgIAAAAsNVpYZTgyUlJBU1U3cXNoWE0ySjlKTllocUo5R1dZampWcTJnd1VWNU5hejkJAARMAAAAAgIAAAAsNVdSWEZTandjVGJOZktjSnM4WnFYbVNTV1lzU1ZKVXRNdk1xWmo1aEg0TmMFAAAAA25pbAAAAAADb3BuCQEAAAALdmFsdWVPckVsc2UAAAACCQAEGwAAAAIFAAAABm9yYWNsZQkAASwAAAACAgAAABYlcyVzX19pc01hcmtldE9wZW5lZF9fBQAAAAlhc3NldE5hbWUGAQAAAAxidWlsZE5ld0l0ZW0AAAAHAAAABmFjdGlvbgAAAANhbXQAAAAFdG9rZW4AAAAKcHJpY2VJbmRleAAAAAdpbnZva2VyAAAACW1pblBheW91dAAAAAltYXhQYXlvdXQJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAIJAAEsAAAAAgUAAAAGYWN0aW9uAgAAAAF8CQABpAAAAAEFAAAAA2FtdAIAAAABfAUAAAAFdG9rZW4CAAAAAXwJAAGkAAAAAQUAAAAKcHJpY2VJ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bmRleD0JAAGkAAAAAQUAAAAUcmViYWxhbmNlZFByaWNlSW5kZXgCAAAAEywgcmVxdWVzdCBwcmljZSBpZD0JAAGkAAAAAQUAAAAKcHJpY2VJbmRleAMJAABmAAAAAgUAAAAKcHJpY2VJbmRleAUAAAAUcmViYWxhbmNlZFByaWNlSW5kZXgJAAACAAAAAQIAAAApY2FuJ3QgZGVxdWV1ZSwgdG9vIGVhcmx5LCByZWJhbGFuY2UgZmlyc3QDCQAAAAAAAAIFAAAABmFjdGlvbgUAAAAFSVNTVUUEAAAAB2ZlZVNpemUJAABrAAAAAwUAAAADYW10BQAAAA9pc3N1ZVBlcmNlbnRpbGUAAAAAAAAAJxAEAAAAD2FkZGVkQ29sbGF0ZXJhbAkAAGUAAAACBQAAAANhbXQFAAAAB2ZlZVNpemUEAAAAEmRlZmF1bHRBZGRlZFRva2VucwMJAAAAAAAAAgUAAAAFdG9rZW4FAAAABEJVTEwJAABrAAAAAwUAAAAIYnVsbENpcmMFAAAAD2FkZGVkQ29sbGF0ZXJhbAUAAAAHYnVsbENvbAMJAAAAAAAAAgUAAAAFdG9rZW4FAAAABEJFQVIJAABrAAAAAwUAAAAIYmVhckNpcmMFAAAAD2FkZGVkQ29sbGF0ZXJhbAUAAAAHYmVhckNvbAkAAAIAAAABAgAAAAxiYWQgdG9rZW4gaWQEAAAADSR0MDE0MjcwMTQzNDMJAQAAAAJzcAAAAAIFAAAAEmRlZmF1bHRBZGRlZFRva2VucwUAAAAJbWF4UGF5b3V0BAAAABJhZGRlZFRvQ2lyY3VsYXRpb24IBQAAAA0kdDAxNDI3MDE0MzQzAAAAAl8xBAAAAAtleHRyYVRva2VucwgFAAAADSR0MDE0MjcwMTQzNDMAAAACXzIEAAAADSR0MDE0MzYwMTQ1MzEDCQAAAAAAAAIFAAAABXRva2VuBQAAAARCVUxMCQAFFgAAAAQFAAAAEmRlZmF1bHRBZGRlZFRva2VucwUAAAAPYWRkZWRDb2xsYXRlcmFsAAAAAAAAAAAAAAAAAAAAAAAACQAFFgAAAAQAAAAAAAAAAAAAAAAAAAAAAAAFAAAAEmRlZmF1bHRBZGRlZFRva2VucwUAAAAPYWRkZWRDb2xsYXRlcmFsBAAAAAlwbHVzQnVsbHMIBQAAAA0kdDAxNDM2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AAFhBQAAAAFiBAAAABFzZXR0bGVkUHJpY2VJbmRleAkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABHRoaXMFAAAAB1JFQklEWEsCAAAAEWluY29uc2lzdGVudCBkYXRhBAAAABN1bnNldHRsZWRQcmljZUluZGV4CQAAZAAAAAIFAAAAEXNldHRsZWRQcmljZUluZGV4AAAAAAAAAAABAwkBAAAAASEAAAABBQAAAANvcG4JAARMAAAAAgkBAAAAAklFAAAAAgUAAAAHUkVCSURYSwUAAAATdW5zZXR0bGVkUHJpY2VJbmRleAUAAAADbmlsBAAAAAxzZXR0bGVkUHJpY2UJAQAAAAxwcmljZUJ5SW5kZXgAAAACBQAAAAlhc3NldE5hbWUFAAAAEXNldHRsZWRQcmljZUluZGV4BAAAAAluZXh0UHJpY2UJAQAAAAxwcmljZUJ5SW5kZXgAAAACBQAAAAlhc3NldE5hbWUFAAAAE3Vuc2V0dGxlZFByaWNlSW5kZXgEAAAABm1pblZvbAMJAABmAAAAAgUAAAAHYmVhckNvbAUAAAAHYnVsbENvbAUAAAAHYnVsbENvbAUAAAAHYmVhckNvbAQAAAAGcmVkaXN0CQEAAAACTFYAAAAEBQAAAAZtaW5Wb2wFAAAADHNldHRsZWRQcmljZQUAAAAJbmV4dFByaWNlBQAAAAhsZXZlcmFnZQQAAAATcHJpY2VVcEdvb2RGb3JCdWxscwkAAAAAAAACBQAAAAlhc3NldE5hbWUCAAAAAAQAAAALcHJpY2VHb2VzVXAJAABmAAAAAgUAAAAJbmV4dFByaWNlBQAAAAxzZXR0bGVkUHJpY2UEAAAACWJ1bGxzRWFybgkAAAAAAAACBQAAABNwcmljZVVwR29vZEZvckJ1bGxzBQAAAAtwcmljZUdvZXNVcAQAAAAKbmV3QnVsbENvbAMFAAAACWJ1bGxzRWFybgkAAGQAAAACBQAAAAdidWxsQ29sBQAAAAZyZWRpc3QJAABlAAAAAgUAAAAHYnVsbENvbAUAAAAGcmVkaXN0BAAAAApuZXdCZWFyQ29sAwUAAAAJYnVsbHNFYXJuCQAAZQAAAAIFAAAAB2JlYXJDb2wFAAAABnJlZGlzdAkAAGQAAAACBQAAAAdiZWFyQ29sBQAAAAZy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YWRtaW5BY3Rpb24JAABmAAAAAgkAAGQAAAACCQAAZAAAAAIDCQAB9AAAAAMIBQAAAAJ0eAAAAAlib2R5Qnl0ZXMJAAGRAAAAAggFAAAAAnR4AAAABnByb29mcwAAAAAAAAAAAAkAAlkAAAABCQABkQAAAAIFAAAABmFkbWlucwAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAMJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAABCQACWQAAAAEJAAGRAAAAAgUAAAAGYWRtaW5zAAAAAAAAAAABAAAAAAAAAAABAAAAAAAAAAAAAwkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAIJAAJZAAAAAQkAAZEAAAACBQAAAAZhZG1pbnMAAAAAAAAAAAIAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAEEAAAADXN0YWtpbmdBY3Rpb24EAAAAByRtYXRjaDAFAAAAAnR4AwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAABdJbnZva2VTY3JpcHRUcmFuc2FjdGlvbgQAAAACdHgFAAAAByRtYXRjaDAEAAAAD3NpZ25lZENvcnJlY3RseQkAAfQAAAADCAUAAAACdHgAAAAJYm9keUJ5dGVzCQABkQAAAAIIBQAAAAJ0eAAAAAZwcm9vZnMAAAAAAAAAAAAFAAAAD2RhZW1vblB1YmxpY0tleQQAAAALZmVlc0NvcnJlY3QDCQAAAAAAAAIIBQAAAAJ0eAAAAApmZWVBc3NldElkBQAAAAR1bml0CQAAZwAAAAIJAABoAAAAAgAAAAAAAAAD6AAAAAAAAAAD6AgFAAAAAnR4AAAAA2ZlZQcEAAAAC2RhcHBDb3JyZWN0CQAAAAAAAAIIBQAAAAJ0eAAAAARkQXBwBQAAAApycGRBZGRyZXNzBAAAAAZ1bmxvY2sJAAAAAAAAAggFAAAAAnR4AAAACGZ1bmN0aW9uAgAAAA51bmxvY2tOZXV0cmlubwQAAAAEbG9jawMDCQAAAAAAAAIIBQAAAAJ0eAAAAAhmdW5jdGlvbgIAAAAObG9ja05ldXRyaW5vU1AJAAAAAAAAAgkAAZEAAAACCAUAAAACdHgAAAAEYXJncwAAAAAAAAAAAAUAAAAOc3Rha2luZ0FkZHJlc3MHCQAAZwAAAAIICQAD7wAAAAEFAAAABHRoaXMAAAAJYXZhaWxhYmxlBQAAAAR0ZW44BwQAAAALZnVuY0NvcnJlY3QDBQAAAARsb2NrBgUAAAAGdW5sb2NrAwMDBQAAAA9zaWduZWRDb3JyZWN0bHkFAAAAC2ZlZXNDb3JyZWN0BwUAAAALZGFwcENvcnJlY3QHBQAAAAtmdW5jQ29ycmVjdAcHAwMFAAAAB2luaXRpYWwGBQAAAAthZG1pbkFjdGlvbgYFAAAADXN0YWtpbmdBY3Rpb24fOtDY", "chainId": 87, "height": 2505171, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 5i1hDiMHv7QhuYsVhcggdNTP3dd8P66tbbnySD1yyLsj Next: 78rdPnjXLm4fYKaXMQYyoQYZPnbQ56XtR1Svvg9BCZQP Diff:
Old | New | Differences | |
---|---|---|---|
8 | 8 | ||
9 | 9 | ||
10 | 10 | func ST (a,amt,t) = ScriptTransfer(a, amt, t) | |
11 | - | ||
12 | - | ||
13 | - | func debug (k,v) = SE(("__dbg__" + k), v) | |
14 | 11 | ||
15 | 12 | ||
16 | 13 | let ten6 = 1000000 | |
217 | 214 | ||
218 | 215 | let admins = ["2HHqV8W9DJayV5R6tBD2Sb8srphpoboDi7r1t1aPiumC", "5ZXe82RRASU7qshXM2J9JNYhqJ9GWYjjVq2gwUV5Naz9", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"] | |
219 | 216 | ||
217 | + | let opn = valueOrElse(getBoolean(oracle, ("%s%s__isMarketOpened__" + assetName)), true) | |
218 | + | ||
220 | 219 | func buildNewItem (action,amt,token,priceIndex,invoker,minPayout,maxPayout) = (((((((((((((action + "|") + toString(amt)) + "|") + token) + "|") + toString(priceIndex)) + "|") + invoker) + "|") + toString(minPayout)) + "|") + toString(maxPayout)) + "|") | |
221 | 220 | ||
222 | 221 | ||
223 | 222 | func userDiffAbs () = { | |
224 | - | let $ | |
225 | - | let userBullCol = $ | |
226 | - | let userBearCol = $ | |
223 | + | let $t058835972 = $Tuple2((bullCol - poolBullExposure), (bearCol - poolBearExposure)) | |
224 | + | let userBullCol = $t058835972._1 | |
225 | + | let userBearCol = $t058835972._2 | |
227 | 226 | let diff = (userBullCol - userBearCol) | |
228 | 227 | if ((diff > 0)) | |
229 | 228 | then diff | |
344 | 343 | $Tuple7((c1 + spentPoolValue), c2, (a0 + acquiredTokens), a1, (c0 - spentPoolValue), (pu + acquiredTokens), pd) | |
345 | 344 | } | |
346 | 345 | ||
347 | - | let $ | |
346 | + | let $t01034111376 = if ((curBullCol0 > curBearCol0)) | |
348 | 347 | then { | |
349 | 348 | let afterCloseUp = closeUp(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0) | |
350 | - | let $ | |
351 | - | let a = $ | |
352 | - | let b = $ | |
353 | - | let c = $ | |
354 | - | let d = $ | |
355 | - | let e = $ | |
356 | - | let f = $ | |
357 | - | let g = $ | |
349 | + | let $t01056710704 = afterCloseUp | |
350 | + | let a = $t01056710704._1 | |
351 | + | let b = $t01056710704._2 | |
352 | + | let c = $t01056710704._3 | |
353 | + | let d = $t01056710704._4 | |
354 | + | let e = $t01056710704._5 | |
355 | + | let f = $t01056710704._6 | |
356 | + | let g = $t01056710704._7 | |
358 | 357 | if ((f > 0)) | |
359 | 358 | then afterCloseUp | |
360 | 359 | else if ((f == 0)) | |
363 | 362 | } | |
364 | 363 | else { | |
365 | 364 | let afterCloseDwn = closeDwn(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0) | |
366 | - | let $ | |
367 | - | let a = $ | |
368 | - | let b = $ | |
369 | - | let c = $ | |
370 | - | let d = $ | |
371 | - | let e = $ | |
372 | - | let f = $ | |
373 | - | let g = $ | |
365 | + | let $t01105511195 = afterCloseDwn | |
366 | + | let a = $t01105511195._1 | |
367 | + | let b = $t01105511195._2 | |
368 | + | let c = $t01105511195._3 | |
369 | + | let d = $t01105511195._4 | |
370 | + | let e = $t01105511195._5 | |
371 | + | let f = $t01105511195._6 | |
372 | + | let g = $t01105511195._7 | |
374 | 373 | if ((g > 0)) | |
375 | 374 | then afterCloseDwn | |
376 | 375 | else if ((g == 0)) | |
377 | 376 | then openUp(a, b, c, d, e, f, g) | |
378 | 377 | else throw("poolDwn < 0") | |
379 | 378 | } | |
380 | - | let c1 = $ | |
381 | - | let c2 = $ | |
382 | - | let a0 = $ | |
383 | - | let a1 = $ | |
384 | - | let c0 = $ | |
385 | - | let pu = $ | |
386 | - | let pd = $ | |
379 | + | let c1 = $t01034111376._1 | |
380 | + | let c2 = $t01034111376._2 | |
381 | + | let a0 = $t01034111376._3 | |
382 | + | let a1 = $t01034111376._4 | |
383 | + | let c0 = $t01034111376._5 | |
384 | + | let pu = $t01034111376._6 | |
385 | + | let pd = $t01034111376._7 | |
387 | 386 | let charge = fraction(userDiffAbs(), rebalancePercentile, ((1440 * 100) * 100)) | |
388 | 387 | let percentileActivated = (height >= valueOrElse(getInteger(configProvider, "percentileActivationHeight"), 10000000)) | |
389 | 388 | let c1SplitP = if (if (percentileActivated) | |
401 | 400 | ||
402 | 401 | ||
403 | 402 | func poolSup (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0) = { | |
404 | - | let $ | |
405 | - | let bullCol1 = $ | |
406 | - | let bearCol1 = $ | |
407 | - | let bullCic1 = $ | |
408 | - | let bearCirc1 = $ | |
409 | - | let poolMain1 = $ | |
410 | - | let poolUp1 = $ | |
411 | - | let poolDwn1 = $ | |
403 | + | let $t01195712139 = poolSupport(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, poolMain, poolUp, poolDwn) | |
404 | + | let bullCol1 = $t01195712139._1 | |
405 | + | let bearCol1 = $t01195712139._2 | |
406 | + | let bullCic1 = $t01195712139._3 | |
407 | + | let bearCirc1 = $t01195712139._4 | |
408 | + | let poolMain1 = $t01195712139._5 | |
409 | + | let poolUp1 = $t01195712139._6 | |
410 | + | let poolDwn1 = $t01195712139._7 | |
412 | 411 | [IE(BULLCOLK, bullCol1), IE(BULLCIRCK, bullCic1), IE(BEARCOLK, bearCol1), IE(BEARCIRCK, bearCirc1), IE(POOLUSDNK, poolMain1), IE(POOLUPK, poolUp1), IE(POOLDWNK, poolDwn1)] | |
413 | 412 | } | |
414 | 413 | ||
450 | 449 | then { | |
451 | 450 | let feeSize = fraction(amt, issuePercentile, 10000) | |
452 | 451 | let addedCollateral = (amt - feeSize) | |
453 | - | let | |
452 | + | let defaultAddedTokens = if ((token == BULL)) | |
454 | 453 | then fraction(bullCirc, addedCollateral, bullCol) | |
455 | 454 | else if ((token == BEAR)) | |
456 | 455 | then fraction(bearCirc, addedCollateral, bearCol) | |
457 | 456 | else throw("bad token id") | |
458 | - | let $ | |
459 | - | let addedToCirculation = $ | |
460 | - | let extraTokens = $ | |
461 | - | let $ | |
462 | - | then $Tuple4( | |
463 | - | else $Tuple4(0, 0, | |
464 | - | let plusBulls = $ | |
465 | - | let plusBullCol = $ | |
466 | - | let plusBears = $ | |
467 | - | let plusBearCol = $ | |
457 | + | let $t01427014343 = sp(defaultAddedTokens, maxPayout) | |
458 | + | let addedToCirculation = $t01427014343._1 | |
459 | + | let extraTokens = $t01427014343._2 | |
460 | + | let $t01436014531 = if ((token == BULL)) | |
461 | + | then $Tuple4(defaultAddedTokens, addedCollateral, 0, 0) | |
462 | + | else $Tuple4(0, 0, defaultAddedTokens, addedCollateral) | |
463 | + | let plusBulls = $t01436014531._1 | |
464 | + | let plusBullCol = $t01436014531._2 | |
465 | + | let plusBears = $t01436014531._3 | |
466 | + | let plusBearCol = $t01436014531._4 | |
468 | 467 | if ((minPayout > addedToCirculation)) | |
469 | 468 | then payback(mainToken) | |
470 | 469 | else (poolSup((bullCol + plusBullCol), (bearCol + plusBearCol), (bullCirc + plusBulls), (bearCirc + plusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, addedToCirculation, fromBase58String(token)), ST(feeAddress, extraTokens, fromBase58String(token))]) | |
472 | 471 | else if ((action == REDEEM)) | |
473 | 472 | then { | |
474 | 473 | let removedTokens = amt | |
475 | - | let | |
474 | + | let estimatedPayout = if ((token == BULL)) | |
476 | 475 | then fraction(bullCol, removedTokens, bullCirc) | |
477 | 476 | else if ((token == BEAR)) | |
478 | 477 | then fraction(bearCol, removedTokens, bearCirc) | |
479 | 478 | else throw("bad token id") | |
480 | - | let $t01532615375 = sp(calcPo, maxPayout) | |
481 | - | let payoutCapped = $t01532615375._1 | |
482 | - | let extra = $t01532615375._2 | |
483 | - | let feeSize = fraction(payoutCapped, redeemPercentile, 10000) | |
484 | - | let payout = if ((payoutCapped > feeSize)) | |
485 | - | then (payoutCapped - feeSize) | |
486 | - | else 0 | |
487 | - | let $t01556115720 = if ((token == BULL)) | |
488 | - | then $Tuple4(removedTokens, payoutCapped, 0, 0) | |
489 | - | else $Tuple4(0, 0, removedTokens, payoutCapped) | |
490 | - | let minusBulls = $t01556115720._1 | |
491 | - | let minusBullCol = $t01556115720._2 | |
492 | - | let minusBears = $t01556115720._3 | |
493 | - | let minusBearCol = $t01556115720._4 | |
494 | - | if ((minPayout > payout)) | |
479 | + | let feeSize = fraction(estimatedPayout, redeemPercentile, 10000) | |
480 | + | let defaultPayout = (estimatedPayout - feeSize) | |
481 | + | let $t01559815652 = sp(defaultPayout, maxPayout) | |
482 | + | let userPayout = $t01559815652._1 | |
483 | + | let extra = $t01559815652._2 | |
484 | + | let $t01566915834 = if ((token == BULL)) | |
485 | + | then $Tuple4(removedTokens, estimatedPayout, 0, 0) | |
486 | + | else $Tuple4(0, 0, removedTokens, estimatedPayout) | |
487 | + | let minusBulls = $t01566915834._1 | |
488 | + | let minusBullCol = $t01566915834._2 | |
489 | + | let minusBears = $t01566915834._3 | |
490 | + | let minusBearCol = $t01566915834._4 | |
491 | + | if ((minPayout > userPayout)) | |
495 | 492 | then payback(token) | |
496 | - | else (poolSup((bullCol - minusBullCol), (bearCol - minusBearCol), (bullCirc - minusBulls), (bearCirc - minusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, | |
493 | + | else (poolSup((bullCol - minusBullCol), (bearCol - minusBearCol), (bullCirc - minusBulls), (bearCirc - minusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, userPayout, fromBase58String(mainToken)), ST(feeAddress, extra, fromBase58String(mainToken))]) | |
497 | 494 | } | |
498 | 495 | else if ((action == POOL)) | |
499 | 496 | then { | |
550 | 547 | ||
551 | 548 | let settledPriceIndex = valueOrErrorMessage(getInteger(this, REBIDXK), "inconsistent data") | |
552 | 549 | let unsettledPriceIndex = (settledPriceIndex + 1) | |
553 | - | let settledPrice = priceByIndex(assetName, settledPriceIndex) | |
554 | - | let nextPrice = priceByIndex(assetName, unsettledPriceIndex) | |
555 | - | let minVol = if ((bearCol > bullCol)) | |
556 | - | then bullCol | |
557 | - | else bearCol | |
558 | - | let redist = LV(minVol, settledPrice, nextPrice, leverage) | |
559 | - | let priceUpGoodForBulls = (assetName == "") | |
560 | - | let priceGoesUp = (nextPrice > settledPrice) | |
561 | - | let bullsEarn = (priceUpGoodForBulls == priceGoesUp) | |
562 | - | let newBullCol = if (bullsEarn) | |
563 | - | then (bullCol + redist) | |
564 | - | else (bullCol - redist) | |
565 | - | let newBearCol = if (bullsEarn) | |
566 | - | then (bearCol - redist) | |
567 | - | else (bearCol + redist) | |
568 | - | let $t01960819794 = poolSupport(newBullCol, newBearCol, bullCirc, bearCirc, poolMain, poolUp, poolDwn) | |
569 | - | let updBullCol = $t01960819794._1 | |
570 | - | let updBearCol = $t01960819794._2 | |
571 | - | let updBullCirc = $t01960819794._3 | |
572 | - | let updBearCirc = $t01960819794._4 | |
573 | - | let updPoolMain = $t01960819794._5 | |
574 | - | let updPoolUp = $t01960819794._6 | |
575 | - | let updPoolDwn = $t01960819794._7 | |
550 | + | if (!(opn)) | |
551 | + | then [IE(REBIDXK, unsettledPriceIndex)] | |
552 | + | else { | |
553 | + | let settledPrice = priceByIndex(assetName, settledPriceIndex) | |
554 | + | let nextPrice = priceByIndex(assetName, unsettledPriceIndex) | |
555 | + | let minVol = if ((bearCol > bullCol)) | |
556 | + | then bullCol | |
557 | + | else bearCol | |
558 | + | let redist = LV(minVol, settledPrice, nextPrice, leverage) | |
559 | + | let priceUpGoodForBulls = (assetName == "") | |
560 | + | let priceGoesUp = (nextPrice > settledPrice) | |
561 | + | let bullsEarn = (priceUpGoodForBulls == priceGoesUp) | |
562 | + | let newBullCol = if (bullsEarn) | |
563 | + | then (bullCol + redist) | |
564 | + | else (bullCol - redist) | |
565 | + | let newBearCol = if (bullsEarn) | |
566 | + | then (bearCol - redist) | |
567 | + | else (bearCol + redist) | |
568 | + | let $t01982820018 = poolSupport(newBullCol, newBearCol, bullCirc, bearCirc, poolMain, poolUp, poolDwn) | |
569 | + | let updBullCol = $t01982820018._1 | |
570 | + | let updBearCol = $t01982820018._2 | |
571 | + | let updBullCirc = $t01982820018._3 | |
572 | + | let updBearCirc = $t01982820018._4 | |
573 | + | let updPoolMain = $t01982820018._5 | |
574 | + | let updPoolUp = $t01982820018._6 | |
575 | + | let updPoolDwn = $t01982820018._7 | |
576 | 576 | [IE(BULLCOLK, updBullCol), IE(BEARCOLK, updBearCol), IE(BULLCIRCK, updBullCirc), IE(BEARCIRCK, updBearCirc), IE(POOLUSDNK, updPoolMain), IE(POOLUPK, updPoolUp), IE(POOLDWNK, updPoolDwn), IE(REBIDXK, unsettledPriceIndex)] | |
577 | + | } | |
577 | 578 | } | |
578 | 579 | ||
579 | 580 | ||
582 | 583 | else ((avg + avg) - min) | |
583 | 584 | ||
584 | 585 | ||
585 | - | func requestIssueInternal (inv,tokenId,minPayout) = if (if ((tokenId != BULL)) | |
586 | - | then (tokenId != BEAR) | |
587 | - | else false) | |
588 | - | then throw("bad token req") | |
589 | - | else if ((inv.caller == this)) | |
590 | - | then throw("can't do") | |
591 | - | else if (!(allowed(inv.caller))) | |
592 | - | then throw("only whitelisted can do") | |
593 | - | else { | |
594 | - | let errorMessage = (((("bad token req, only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") allowed") | |
595 | - | if ((inv.payments[0].assetId != fromBase58String(mainToken))) | |
596 | - | then throw("bad token att") | |
597 | - | else { | |
598 | - | let amt = inv.payments[0].amount | |
599 | - | let $t02080020978 = if ((tokenId == BULL)) | |
600 | - | then $Tuple2(bullCol, bullCirc) | |
601 | - | else if ((tokenId == BEAR)) | |
602 | - | then $Tuple2(bearCol, bearCirc) | |
603 | - | else throw(errorMessage) | |
604 | - | let col = $t02080020978._1 | |
605 | - | let circ = $t02080020978._2 | |
606 | - | let est = fraction(amt, circ, col) | |
607 | - | let $t02102021114 = if ((minPayout == 0)) | |
608 | - | then $Tuple2(0, MAX) | |
609 | - | else $Tuple2(minPayout, calcMax(minPayout, est)) | |
610 | - | let minP = $t02102021114._1 | |
611 | - | let maxP = $t02102021114._2 | |
612 | - | if ((minIssue > amt)) | |
613 | - | then throw((("Attached payment too small. Min required: " + toString((minIssue / 1000000))) + " USDN")) | |
614 | - | else { | |
615 | - | let maxAllowed = maxIssue(tokenId) | |
616 | - | if (if ((whitelist == "")) | |
617 | - | then (inv.payments[0].amount > maxAllowed) | |
618 | - | else false) | |
619 | - | then throw((("trying to issue more than pool can handle. Max attachment allowed = " + toString((maxAllowed / 1000000))) + " USDN")) | |
620 | - | else (enqueue(toBase58String(inv.transactionId), ISSUE, amt, tokenId, (oraclePriceIndex + 1), toString(inv.caller), minP, maxP) ++ [debug("requested", tokenId), debug("bull", BULL), debug("bear", BEAR)]) | |
621 | - | } | |
622 | - | } | |
623 | - | } | |
586 | + | func requestIssueInternal (inv,tokenId,minPayout) = if (!(opn)) | |
587 | + | then throw("markets closed") | |
588 | + | else if (if ((tokenId != BULL)) | |
589 | + | then (tokenId != BEAR) | |
590 | + | else false) | |
591 | + | then throw("bad token req") | |
592 | + | else if ((inv.caller == this)) | |
593 | + | then throw("can't do") | |
594 | + | else if (!(allowed(inv.caller))) | |
595 | + | then throw("only whitelisted can do") | |
596 | + | else { | |
597 | + | let errorMessage = (((("bad token req, only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") allowed") | |
598 | + | if ((inv.payments[0].assetId != fromBase58String(mainToken))) | |
599 | + | then throw("bad token att") | |
600 | + | else { | |
601 | + | let amt = inv.payments[0].amount | |
602 | + | let $t02110921287 = if ((tokenId == BULL)) | |
603 | + | then $Tuple2(bullCol, bullCirc) | |
604 | + | else if ((tokenId == BEAR)) | |
605 | + | then $Tuple2(bearCol, bearCirc) | |
606 | + | else throw(errorMessage) | |
607 | + | let col = $t02110921287._1 | |
608 | + | let circ = $t02110921287._2 | |
609 | + | let est = fraction(amt, circ, col) | |
610 | + | let $t02132921423 = if ((minPayout == 0)) | |
611 | + | then $Tuple2(0, MAX) | |
612 | + | else $Tuple2(minPayout, calcMax(minPayout, est)) | |
613 | + | let minP = $t02132921423._1 | |
614 | + | let maxP = $t02132921423._2 | |
615 | + | if ((minIssue > amt)) | |
616 | + | then throw((("Attached payment too small. Min required: " + toString((minIssue / 1000000))) + " USDN")) | |
617 | + | else { | |
618 | + | let maxAllowed = maxIssue(tokenId) | |
619 | + | if (if ((whitelist == "")) | |
620 | + | then (inv.payments[0].amount > maxAllowed) | |
621 | + | else false) | |
622 | + | then throw((("trying to issue more than pool can handle. Max attachment allowed = " + toString((maxAllowed / 1000000))) + " USDN")) | |
623 | + | else enqueue(toBase58String(inv.transactionId), ISSUE, amt, tokenId, (oraclePriceIndex + 1), toString(inv.caller), minP, maxP) | |
624 | + | } | |
625 | + | } | |
626 | + | } | |
624 | 627 | ||
625 | 628 | ||
626 | 629 | func requestRedeemInternal (inv,minPayout) = { | |
631 | 634 | else false) | |
632 | 635 | then throw("bad token req") | |
633 | 636 | else { | |
634 | - | let $ | |
637 | + | let $t02238522524 = if ((tokenId == BULL)) | |
635 | 638 | then $Tuple2(bullCol, bullCirc) | |
636 | 639 | else if ((tokenId == BEAR)) | |
637 | 640 | then $Tuple2(bearCol, bearCirc) | |
638 | 641 | else throw("bad token req") | |
639 | - | let col = $ | |
640 | - | let circ = $ | |
642 | + | let col = $t02238522524._1 | |
643 | + | let circ = $t02238522524._2 | |
641 | 644 | let est = fraction(amt, col, circ) | |
642 | - | let $ | |
645 | + | let $t02257222666 = if ((minPayout == 0)) | |
643 | 646 | then $Tuple2(0, MAX) | |
644 | 647 | else $Tuple2(minPayout, calcMax(minPayout, est)) | |
645 | - | let minP = $ | |
646 | - | let maxP = $ | |
648 | + | let minP = $t02257222666._1 | |
649 | + | let maxP = $t02257222666._2 | |
647 | 650 | if ((validateRequestRedeem(inv) == unit)) | |
648 | 651 | then enqueue(toBase58String(inv.transactionId), REDEEM, amt, tokenId, (oraclePriceIndex + 1), toString(inv.caller), minP, maxP) | |
649 | 652 | else throw("doesn't happen") | |
654 | 657 | func requestPoolInternal (inv,minPayout) = if (!(allowed(inv.caller))) | |
655 | 658 | then throw("only whitelisted can do") | |
656 | 659 | else { | |
657 | - | let errMessage = | |
660 | + | let errMessage = "USDN required" | |
658 | 661 | let pmt = inv.payments[0] | |
659 | 662 | if ((pmt.assetId != fromBase58String(mainToken))) | |
660 | 663 | then throw(errMessage) | |
661 | 664 | else if ((minPool > pmt.amount)) | |
662 | - | then throw(( | |
665 | + | then throw(("pool min: " + toString(minPool))) | |
663 | 666 | else { | |
664 | 667 | let estimate = fraction(poolTokenCirculation, pmt.amount, poolValue) | |
665 | - | let $ | |
668 | + | let $t02345923558 = if ((minPayout == 0)) | |
666 | 669 | then $Tuple2(0, MAX) | |
667 | 670 | else $Tuple2(minPayout, calcMax(minPayout, estimate)) | |
668 | - | let minP = $ | |
669 | - | let maxP = $ | |
671 | + | let minP = $t02345923558._1 | |
672 | + | let maxP = $t02345923558._2 | |
670 | 673 | enqueue(toBase58String(inv.transactionId), POOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller), minP, maxP) | |
671 | 674 | } | |
672 | 675 | } | |
682 | 685 | if ((minPool > estimate)) | |
683 | 686 | then throw(((("unpool at least for" + toString(minPool)) + " ") + mainToken)) | |
684 | 687 | else { | |
685 | - | let $ | |
688 | + | let $t02421524314 = if ((minPayout == 0)) | |
686 | 689 | then $Tuple2(0, MAX) | |
687 | 690 | else $Tuple2(minPayout, calcMax(minPayout, estimate)) | |
688 | - | let minP = $ | |
689 | - | let maxP = $ | |
691 | + | let minP = $t02421524314._1 | |
692 | + | let maxP = $t02421524314._2 | |
690 | 693 | enqueue(toBase58String(inv.transactionId), UNPOOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller), minP, maxP) | |
691 | 694 | } | |
692 | 695 | } | |
708 | 711 | else (pools == 0)) | |
709 | 712 | then throw("can't init balances") | |
710 | 713 | else { | |
711 | - | let oracleCurrentPriceIndex = valueOrErrorMessage(getInteger(valueOrErrorMessage(addressFromPublicKey(fromBase58String(oraclePK)), "bad oracle address"), lastPriceIndexKey(defoAssetName)), " | |
714 | + | let oracleCurrentPriceIndex = valueOrErrorMessage(getInteger(valueOrErrorMessage(addressFromPublicKey(fromBase58String(oraclePK)), "bad oracle address"), lastPriceIndexKey(defoAssetName)), "no last price index") | |
712 | 715 | let bull = Issue(nameup, descUp, ((100 * ten6) * ten6), 6, true) | |
713 | 716 | let bear = Issue(namedwn, descDwn, ((100 * ten6) * ten6), 6, true) | |
714 | 717 | let pool = Issue(poolName, poolDesc, ((100 * ten6) * ten6), 6, true) |
Old | New | Differences | |
---|---|---|---|
1 | 1 | {-# STDLIB_VERSION 4 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | 4 | func SE (k,v) = StringEntry(k, v) | |
5 | 5 | ||
6 | 6 | ||
7 | 7 | func IE (k,v) = IntegerEntry(k, v) | |
8 | 8 | ||
9 | 9 | ||
10 | 10 | func ST (a,amt,t) = ScriptTransfer(a, amt, t) | |
11 | - | ||
12 | - | ||
13 | - | func debug (k,v) = SE(("__dbg__" + k), v) | |
14 | 11 | ||
15 | 12 | ||
16 | 13 | let ten6 = 1000000 | |
17 | 14 | ||
18 | 15 | let ten8 = 100000000 | |
19 | 16 | ||
20 | 17 | let MAX = 9223372036854775807 | |
21 | 18 | ||
22 | 19 | let configProviderKey = "configProvider" | |
23 | 20 | ||
24 | 21 | let configProvider = match getString(this, configProviderKey) { | |
25 | 22 | case s: String => | |
26 | 23 | addressFromStringValue(s) | |
27 | 24 | case _ => | |
28 | 25 | this | |
29 | 26 | } | |
30 | 27 | ||
31 | 28 | func localI (k,e) = valueOrErrorMessage(getInteger(this, k), e) | |
32 | 29 | ||
33 | 30 | ||
34 | 31 | func localS (k,e) = valueOrErrorMessage(getString(this, k), e) | |
35 | 32 | ||
36 | 33 | ||
37 | 34 | func confI (k,e) = valueOrErrorMessage(getInteger(configProvider, k), e) | |
38 | 35 | ||
39 | 36 | ||
40 | 37 | func confS (k,e) = valueOrErrorMessage(getString(configProvider, k), e) | |
41 | 38 | ||
42 | 39 | ||
43 | 40 | let BULLK = "BULLId" | |
44 | 41 | ||
45 | 42 | let BEARK = "BEARId" | |
46 | 43 | ||
47 | 44 | let USDNK = "mainTokenId" | |
48 | 45 | ||
49 | 46 | let BULLCOLK = "bullCollateral" | |
50 | 47 | ||
51 | 48 | let BEARCOLK = "bearCollateral" | |
52 | 49 | ||
53 | 50 | let BULLCIRCK = "bullCirculation" | |
54 | 51 | ||
55 | 52 | let BEARCIRCK = "bearCirculation" | |
56 | 53 | ||
57 | 54 | let ISSPERCK = "issuePercentile" | |
58 | 55 | ||
59 | 56 | let REDPERCK = "redeemPercentile" | |
60 | 57 | ||
61 | 58 | let MINISSK = "minIssue" | |
62 | 59 | ||
63 | 60 | let MINREDK = "minRedeem" | |
64 | 61 | ||
65 | 62 | let MINPOOLK = "minPool" | |
66 | 63 | ||
67 | 64 | let FEEACCK = "feesAccumulated" | |
68 | 65 | ||
69 | 66 | let WLISTK = "issueWhiteList" | |
70 | 67 | ||
71 | 68 | let REBPERCK = "rebalancePercentile" | |
72 | 69 | ||
73 | 70 | let REBIDXK = "lastSettlementPriceId" | |
74 | 71 | ||
75 | 72 | let HEADK = "headPointer" | |
76 | 73 | ||
77 | 74 | let TAILK = "tailPointer" | |
78 | 75 | ||
79 | 76 | let QSIZEK = "queueSize" | |
80 | 77 | ||
81 | 78 | let POOLUSDNK = "poolMainTokenValue" | |
82 | 79 | ||
83 | 80 | let POOLUPK = "poolUp" | |
84 | 81 | ||
85 | 82 | let POOLDWNK = "poolDwn" | |
86 | 83 | ||
87 | 84 | let POOLCIRCK = "poolTokenCirculation" | |
88 | 85 | ||
89 | 86 | let POOLK = "poolToken" | |
90 | 87 | ||
91 | 88 | let ASSNAMEK = "defoAssetName" | |
92 | 89 | ||
93 | 90 | let LEVK = "leverage" | |
94 | 91 | ||
95 | 92 | let WAVESFEEK = "wavesPacemakerFee" | |
96 | 93 | ||
97 | 94 | let USDNFEEK = "usdnPacemakerFee" | |
98 | 95 | ||
99 | 96 | let oraclePKKey = "oracle" | |
100 | 97 | ||
101 | 98 | func lastPriceIndexKey (assetId) = if ((assetId == "")) | |
102 | 99 | then "price_index" | |
103 | 100 | else ("%s%s__idxCurrent__" + assetId) | |
104 | 101 | ||
105 | 102 | ||
106 | 103 | func priceIndexPrefix (assetId) = if ((assetId == "")) | |
107 | 104 | then "price_index_" | |
108 | 105 | else (("%s%s%d__idx2Height__" + assetId) + "__") | |
109 | 106 | ||
110 | 107 | ||
111 | 108 | func priceHeightPrefix (assetId) = if ((assetId == "")) | |
112 | 109 | then "price_" | |
113 | 110 | else (("%s%s%d__priceByHeight__" + assetId) + "__") | |
114 | 111 | ||
115 | 112 | ||
116 | 113 | let minUsdnFee = valueOrElse(getInteger(configProvider, USDNFEEK), 0) | |
117 | 114 | ||
118 | 115 | let minWavesFee = valueOrElse(getInteger(configProvider, WAVESFEEK), 0) | |
119 | 116 | ||
120 | 117 | let assetName = valueOrElse(getString(this, ASSNAMEK), "") | |
121 | 118 | ||
122 | 119 | let bullCol = localI(BULLCOLK, "no 0") | |
123 | 120 | ||
124 | 121 | let bearCol = localI(BEARCOLK, "no 1") | |
125 | 122 | ||
126 | 123 | let bullCirc = localI(BULLCIRCK, "no 2") | |
127 | 124 | ||
128 | 125 | let bearCirc = localI(BEARCIRCK, "no 3") | |
129 | 126 | ||
130 | 127 | let BULL = localS(BULLK, "no 14") | |
131 | 128 | ||
132 | 129 | let BEAR = localS(BEARK, "no 15") | |
133 | 130 | ||
134 | 131 | let mainToken = localS(USDNK, "no 16") | |
135 | 132 | ||
136 | 133 | let issuePercentile = confI(ISSPERCK, "no 4") | |
137 | 134 | ||
138 | 135 | let redeemPercentile = confI(REDPERCK, "no 5") | |
139 | 136 | ||
140 | 137 | let minIssue = confI(MINISSK, "no 6") | |
141 | 138 | ||
142 | 139 | let minRedeem = confI(MINREDK, "no 7") | |
143 | 140 | ||
144 | 141 | let minPool = confI(MINPOOLK, "no 8") | |
145 | 142 | ||
146 | 143 | let rebalancePercentile = valueOrElse(getInteger(configProvider, ((toString(this) + "_") + REBPERCK)), 0) | |
147 | 144 | ||
148 | 145 | let whitelist = confS(WLISTK, "no 9") | |
149 | 146 | ||
150 | 147 | func allowed (a) = if ((whitelist == "")) | |
151 | 148 | then true | |
152 | 149 | else isDefined(indexOf(whitelist, toString(a))) | |
153 | 150 | ||
154 | 151 | ||
155 | 152 | let poolMain = localI(POOLUSDNK, "no") | |
156 | 153 | ||
157 | 154 | let poolUp = localI(POOLUPK, "no 10") | |
158 | 155 | ||
159 | 156 | let poolDwn = localI(POOLDWNK, "no 11") | |
160 | 157 | ||
161 | 158 | let poolToken = localS(POOLK, "no 12") | |
162 | 159 | ||
163 | 160 | let poolTokenCirculation = localI(POOLCIRCK, "no 13") | |
164 | 161 | ||
165 | 162 | let poolBullExposure = fraction(bullCol, poolUp, bullCirc) | |
166 | 163 | ||
167 | 164 | let poolBearExposure = fraction(bearCol, poolDwn, bearCirc) | |
168 | 165 | ||
169 | 166 | let poolValue = ((poolMain + poolBullExposure) + poolBearExposure) | |
170 | 167 | ||
171 | 168 | let oracle = valueOrErrorMessage(addressFromPublicKey(fromBase58String(valueOrErrorMessage(getString(this, oraclePKKey), "no oraclePKKey"))), "bad oracle address") | |
172 | 169 | ||
173 | 170 | let rebalancedPriceIndex = valueOrErrorMessage(getInteger(this, REBIDXK), "no last rebalance price") | |
174 | 171 | ||
175 | 172 | let oraclePriceIndex = valueOrErrorMessage(getInteger(oracle, lastPriceIndexKey(assetName)), ((("bad oracle data at " + toString(oracle)) + ": no integer at ") + lastPriceIndexKey(assetName))) | |
176 | 173 | ||
177 | 174 | let leverage = valueOrElse(getInteger(this, LEVK), 3) | |
178 | 175 | ||
179 | 176 | func heightByIndex (assetName,priceIndex) = valueOrErrorMessage(getInteger(oracle, (priceIndexPrefix(assetName) + toString(priceIndex))), ("no data at index " + toString(priceIndex))) | |
180 | 177 | ||
181 | 178 | ||
182 | 179 | func priceByHeight (assetName,priceHeight) = valueOrErrorMessage(getInteger(oracle, (priceHeightPrefix(assetName) + toString(priceHeight))), ("no data for height " + toString(priceHeight))) | |
183 | 180 | ||
184 | 181 | ||
185 | 182 | func priceByIndex (assetName,priceIndex) = priceByHeight(assetName, heightByIndex(assetName, priceIndex)) | |
186 | 183 | ||
187 | 184 | ||
188 | 185 | let queueSize = valueOrElse(getInteger(this, QSIZEK), 0) | |
189 | 186 | ||
190 | 187 | let headPointer = valueOrElse(getString(this, HEADK), "") | |
191 | 188 | ||
192 | 189 | let tailPointer = valueOrElse(getString(this, TAILK), "") | |
193 | 190 | ||
194 | 191 | let feesAccumulated = valueOrElse(getInteger(this, FEEACCK), 0) | |
195 | 192 | ||
196 | 193 | let ISSUE = "ISSUE" | |
197 | 194 | ||
198 | 195 | let REDEEM = "REDEEM" | |
199 | 196 | ||
200 | 197 | let POOL = "POOL" | |
201 | 198 | ||
202 | 199 | let UNPOOL = "UNPOOL" | |
203 | 200 | ||
204 | 201 | let feeAddrKey = "feeAddress" | |
205 | 202 | ||
206 | 203 | let stakingAddrKey = "stakingAddress" | |
207 | 204 | ||
208 | 205 | let daemonPubKeyKey = "daemonPublicKey" | |
209 | 206 | ||
210 | 207 | let feeAddress = valueOrErrorMessage(addressFromString(confS(feeAddrKey, "no feeAddress")), "bad feeAddress") | |
211 | 208 | ||
212 | 209 | let stakingAddress = confS(stakingAddrKey, "no stakingAddress") | |
213 | 210 | ||
214 | 211 | let daemonPublicKey = fromBase58String(confS(daemonPubKeyKey, "no daemonPublicKey")) | |
215 | 212 | ||
216 | 213 | let rpdAddress = addressFromString("3PNikM6yp4NqcSU8guxQtmR5onr2D4e8yTJ") | |
217 | 214 | ||
218 | 215 | let admins = ["2HHqV8W9DJayV5R6tBD2Sb8srphpoboDi7r1t1aPiumC", "5ZXe82RRASU7qshXM2J9JNYhqJ9GWYjjVq2gwUV5Naz9", "5WRXFSjwcTbNfKcJs8ZqXmSSWYsSVJUtMvMqZj5hH4Nc"] | |
219 | 216 | ||
217 | + | let opn = valueOrElse(getBoolean(oracle, ("%s%s__isMarketOpened__" + assetName)), true) | |
218 | + | ||
220 | 219 | func buildNewItem (action,amt,token,priceIndex,invoker,minPayout,maxPayout) = (((((((((((((action + "|") + toString(amt)) + "|") + token) + "|") + toString(priceIndex)) + "|") + invoker) + "|") + toString(minPayout)) + "|") + toString(maxPayout)) + "|") | |
221 | 220 | ||
222 | 221 | ||
223 | 222 | func userDiffAbs () = { | |
224 | - | let $ | |
225 | - | let userBullCol = $ | |
226 | - | let userBearCol = $ | |
223 | + | let $t058835972 = $Tuple2((bullCol - poolBullExposure), (bearCol - poolBearExposure)) | |
224 | + | let userBullCol = $t058835972._1 | |
225 | + | let userBearCol = $t058835972._2 | |
227 | 226 | let diff = (userBullCol - userBearCol) | |
228 | 227 | if ((diff > 0)) | |
229 | 228 | then diff | |
230 | 229 | else (0 - diff) | |
231 | 230 | } | |
232 | 231 | ||
233 | 232 | ||
234 | 233 | func maxIssue (tokenId) = { | |
235 | 234 | let poolInvestment = if ((poolUp > 0)) | |
236 | 235 | then BULL | |
237 | 236 | else BEAR | |
238 | 237 | if ((tokenId != poolInvestment)) | |
239 | 238 | then poolMain | |
240 | 239 | else (userDiffAbs() + poolValue) | |
241 | 240 | } | |
242 | 241 | ||
243 | 242 | ||
244 | 243 | func validatePMFee (i,minPayout) = if ((0 > minPayout)) | |
245 | 244 | then throw("negative min payout") | |
246 | 245 | else { | |
247 | 246 | let p = i.payments[1] | |
248 | 247 | let ok = match p.assetId { | |
249 | 248 | case bv: ByteVector => | |
250 | 249 | if ((toBase58String(bv) == mainToken)) | |
251 | 250 | then (p.amount >= minUsdnFee) | |
252 | 251 | else false | |
253 | 252 | case waves: Unit => | |
254 | 253 | (p.amount >= minWavesFee) | |
255 | 254 | case _ => | |
256 | 255 | throw("Match error") | |
257 | 256 | } | |
258 | 257 | if (!(ok)) | |
259 | 258 | then throw("incorrect pacemaker fee") | |
260 | 259 | else true | |
261 | 260 | } | |
262 | 261 | ||
263 | 262 | ||
264 | 263 | func validateRequestRedeem (inv) = if ((inv.caller == this)) | |
265 | 264 | then throw("can't do") | |
266 | 265 | else { | |
267 | 266 | func errorMessage (got) = throw(((((("bad token att: only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") tokens are accepted, received: ") + got)) | |
268 | 267 | ||
269 | 268 | let assetId = toBase58String(valueOrErrorMessage(value(inv.payments[0]).assetId, "bad token att")) | |
270 | 269 | if (if ((assetId != BEAR)) | |
271 | 270 | then (assetId != BULL) | |
272 | 271 | else false) | |
273 | 272 | then errorMessage(assetId) | |
274 | 273 | else { | |
275 | 274 | let attachedAmount = inv.payments[0].amount | |
276 | 275 | let col = if ((assetId == BEAR)) | |
277 | 276 | then bearCol | |
278 | 277 | else bullCol | |
279 | 278 | let circ = if ((assetId == BEAR)) | |
280 | 279 | then bearCirc | |
281 | 280 | else bullCirc | |
282 | 281 | let estimated = fraction(col, attachedAmount, circ) | |
283 | 282 | if ((minRedeem > estimated)) | |
284 | 283 | then throw((((((((((("Attached payment too small. Min redeem amount is " + toString((minRedeem / 1000000))) + " USDN, ") + "attached amount: ") + toString(attachedAmount)) + ", col: ") + toString(col)) + ", circ: ") + toString(circ)) + ", estimated: ") + toString(estimated))) | |
285 | 284 | else unit | |
286 | 285 | } | |
287 | 286 | } | |
288 | 287 | ||
289 | 288 | ||
290 | 289 | func enqueue (id,action,amt,token,priceIndex,invoker,minPayout,maxPayout) = { | |
291 | 290 | let increaseQueueSize = IE(QSIZEK, (queueSize + 1)) | |
292 | 291 | let itm = buildNewItem(action, amt, token, priceIndex, invoker, minPayout, maxPayout) | |
293 | 292 | if ((queueSize == 0)) | |
294 | 293 | then [SE(HEADK, id), SE(TAILK, id), SE(id, itm), increaseQueueSize] | |
295 | 294 | else { | |
296 | 295 | let prevId = localS(TAILK, "can't get tail pointer") | |
297 | 296 | let prevItm = localS(prevId, "can't resolve pointer") | |
298 | 297 | let updatedPrevItm = (prevItm + id) | |
299 | 298 | [SE(prevId, updatedPrevItm), SE(id, itm), SE(TAILK, id), increaseQueueSize] | |
300 | 299 | } | |
301 | 300 | } | |
302 | 301 | ||
303 | 302 | ||
304 | 303 | func poolSupport (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0,curPoolMain0,curPoolUp0,curPoolDwn0) = { | |
305 | 304 | func closeUp (c1,c2,a0,a1,c0,pu,pd) = { | |
306 | 305 | let diff = (c1 - c2) | |
307 | 306 | let exp = fraction(c1, pu, a0) | |
308 | 307 | let liquidatedTokens = if ((diff > exp)) | |
309 | 308 | then pu | |
310 | 309 | else fraction(diff, a0, c1) | |
311 | 310 | let liquidatedValue = if ((diff > exp)) | |
312 | 311 | then exp | |
313 | 312 | else fraction(liquidatedTokens, c1, a0) | |
314 | 313 | $Tuple7((c1 - liquidatedValue), c2, (a0 - liquidatedTokens), a1, (c0 + liquidatedValue), (pu - liquidatedTokens), pd) | |
315 | 314 | } | |
316 | 315 | ||
317 | 316 | func closeDwn (c1,c2,a0,a1,c0,pu,pd) = { | |
318 | 317 | let diff = (c2 - c1) | |
319 | 318 | let exp = fraction(c2, pd, a1) | |
320 | 319 | let liquidatedTokens = if ((diff > exp)) | |
321 | 320 | then pd | |
322 | 321 | else fraction(diff, a1, c2) | |
323 | 322 | let liquidatedValue = if ((diff > exp)) | |
324 | 323 | then exp | |
325 | 324 | else fraction(liquidatedTokens, c2, a1) | |
326 | 325 | $Tuple7(c1, (c2 - liquidatedValue), a0, (a1 - liquidatedTokens), (c0 + liquidatedValue), pu, (pd - liquidatedTokens)) | |
327 | 326 | } | |
328 | 327 | ||
329 | 328 | func openDwn (c1,c2,a0,a1,c0,pu,pd) = { | |
330 | 329 | let diff = (c1 - c2) | |
331 | 330 | let spentPoolValue = if ((c0 > diff)) | |
332 | 331 | then diff | |
333 | 332 | else c0 | |
334 | 333 | let acquiredTokens = fraction(spentPoolValue, a1, c2) | |
335 | 334 | $Tuple7(c1, (c2 + spentPoolValue), a0, (a1 + acquiredTokens), (c0 - spentPoolValue), pu, (pd + acquiredTokens)) | |
336 | 335 | } | |
337 | 336 | ||
338 | 337 | func openUp (c1,c2,a0,a1,c0,pu,pd) = { | |
339 | 338 | let diff = (c2 - c1) | |
340 | 339 | let spentPoolValue = if ((c0 > diff)) | |
341 | 340 | then diff | |
342 | 341 | else c0 | |
343 | 342 | let acquiredTokens = fraction(spentPoolValue, a0, c1) | |
344 | 343 | $Tuple7((c1 + spentPoolValue), c2, (a0 + acquiredTokens), a1, (c0 - spentPoolValue), (pu + acquiredTokens), pd) | |
345 | 344 | } | |
346 | 345 | ||
347 | - | let $ | |
346 | + | let $t01034111376 = if ((curBullCol0 > curBearCol0)) | |
348 | 347 | then { | |
349 | 348 | let afterCloseUp = closeUp(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0) | |
350 | - | let $ | |
351 | - | let a = $ | |
352 | - | let b = $ | |
353 | - | let c = $ | |
354 | - | let d = $ | |
355 | - | let e = $ | |
356 | - | let f = $ | |
357 | - | let g = $ | |
349 | + | let $t01056710704 = afterCloseUp | |
350 | + | let a = $t01056710704._1 | |
351 | + | let b = $t01056710704._2 | |
352 | + | let c = $t01056710704._3 | |
353 | + | let d = $t01056710704._4 | |
354 | + | let e = $t01056710704._5 | |
355 | + | let f = $t01056710704._6 | |
356 | + | let g = $t01056710704._7 | |
358 | 357 | if ((f > 0)) | |
359 | 358 | then afterCloseUp | |
360 | 359 | else if ((f == 0)) | |
361 | 360 | then openDwn(a, b, c, d, e, f, g) | |
362 | 361 | else throw("poolUp < 0") | |
363 | 362 | } | |
364 | 363 | else { | |
365 | 364 | let afterCloseDwn = closeDwn(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, curPoolMain0, curPoolUp0, curPoolDwn0) | |
366 | - | let $ | |
367 | - | let a = $ | |
368 | - | let b = $ | |
369 | - | let c = $ | |
370 | - | let d = $ | |
371 | - | let e = $ | |
372 | - | let f = $ | |
373 | - | let g = $ | |
365 | + | let $t01105511195 = afterCloseDwn | |
366 | + | let a = $t01105511195._1 | |
367 | + | let b = $t01105511195._2 | |
368 | + | let c = $t01105511195._3 | |
369 | + | let d = $t01105511195._4 | |
370 | + | let e = $t01105511195._5 | |
371 | + | let f = $t01105511195._6 | |
372 | + | let g = $t01105511195._7 | |
374 | 373 | if ((g > 0)) | |
375 | 374 | then afterCloseDwn | |
376 | 375 | else if ((g == 0)) | |
377 | 376 | then openUp(a, b, c, d, e, f, g) | |
378 | 377 | else throw("poolDwn < 0") | |
379 | 378 | } | |
380 | - | let c1 = $ | |
381 | - | let c2 = $ | |
382 | - | let a0 = $ | |
383 | - | let a1 = $ | |
384 | - | let c0 = $ | |
385 | - | let pu = $ | |
386 | - | let pd = $ | |
379 | + | let c1 = $t01034111376._1 | |
380 | + | let c2 = $t01034111376._2 | |
381 | + | let a0 = $t01034111376._3 | |
382 | + | let a1 = $t01034111376._4 | |
383 | + | let c0 = $t01034111376._5 | |
384 | + | let pu = $t01034111376._6 | |
385 | + | let pd = $t01034111376._7 | |
387 | 386 | let charge = fraction(userDiffAbs(), rebalancePercentile, ((1440 * 100) * 100)) | |
388 | 387 | let percentileActivated = (height >= valueOrElse(getInteger(configProvider, "percentileActivationHeight"), 10000000)) | |
389 | 388 | let c1SplitP = if (if (percentileActivated) | |
390 | 389 | then (pd > 0) | |
391 | 390 | else false) | |
392 | 391 | then charge | |
393 | 392 | else 0 | |
394 | 393 | let c2SplitP = if (if (percentileActivated) | |
395 | 394 | then (pu > 0) | |
396 | 395 | else false) | |
397 | 396 | then charge | |
398 | 397 | else 0 | |
399 | 398 | $Tuple7((c1 - c1SplitP), (c2 - c2SplitP), a0, a1, ((c0 + c1SplitP) + c2SplitP), pu, pd) | |
400 | 399 | } | |
401 | 400 | ||
402 | 401 | ||
403 | 402 | func poolSup (curBullCol0,curBearCol0,curBullCirc0,curBearCirc0) = { | |
404 | - | let $ | |
405 | - | let bullCol1 = $ | |
406 | - | let bearCol1 = $ | |
407 | - | let bullCic1 = $ | |
408 | - | let bearCirc1 = $ | |
409 | - | let poolMain1 = $ | |
410 | - | let poolUp1 = $ | |
411 | - | let poolDwn1 = $ | |
403 | + | let $t01195712139 = poolSupport(curBullCol0, curBearCol0, curBullCirc0, curBearCirc0, poolMain, poolUp, poolDwn) | |
404 | + | let bullCol1 = $t01195712139._1 | |
405 | + | let bearCol1 = $t01195712139._2 | |
406 | + | let bullCic1 = $t01195712139._3 | |
407 | + | let bearCirc1 = $t01195712139._4 | |
408 | + | let poolMain1 = $t01195712139._5 | |
409 | + | let poolUp1 = $t01195712139._6 | |
410 | + | let poolDwn1 = $t01195712139._7 | |
412 | 411 | [IE(BULLCOLK, bullCol1), IE(BULLCIRCK, bullCic1), IE(BEARCOLK, bearCol1), IE(BEARCIRCK, bearCirc1), IE(POOLUSDNK, poolMain1), IE(POOLUPK, poolUp1), IE(POOLDWNK, poolDwn1)] | |
413 | 412 | } | |
414 | 413 | ||
415 | 414 | ||
416 | 415 | func dequeue () = { | |
417 | 416 | func sp (a,mx) = if ((mx >= a)) | |
418 | 417 | then $Tuple2(a, 0) | |
419 | 418 | else $Tuple2(mx, (a - mx)) | |
420 | 419 | ||
421 | 420 | if ((queueSize == 0)) | |
422 | 421 | then throw("nothing to settle") | |
423 | 422 | else { | |
424 | 423 | func collectFee (fees) = IE(FEEACCK, (feesAccumulated + fees)) | |
425 | 424 | ||
426 | 425 | let decreaseQueueSize = IE(QSIZEK, (queueSize - 1)) | |
427 | 426 | let isLastElement = (headPointer == tailPointer) | |
428 | 427 | let overwriteTail = SE(TAILK, "") | |
429 | 428 | let dataStr = localS(headPointer, "bad head pointer(dequeue)") | |
430 | 429 | let data = split(dataStr, "|") | |
431 | 430 | let action = data[0] | |
432 | 431 | let amt = parseIntValue(data[1]) | |
433 | 432 | let token = data[2] | |
434 | 433 | let priceIndex = parseIntValue(data[3]) | |
435 | 434 | let invoker = addressFromStringValue(data[4]) | |
436 | 435 | let minPayout = if ((8 > size(data))) | |
437 | 436 | then 0 | |
438 | 437 | else parseIntValue(data[5]) | |
439 | 438 | let maxPayout = if ((8 > size(data))) | |
440 | 439 | then MAX | |
441 | 440 | else parseIntValue(data[6]) | |
442 | 441 | let next = data[(size(data) - 1)] | |
443 | 442 | func payback (tkn) = [SE(HEADK, next), decreaseQueueSize, ST(invoker, amt, fromBase58String(tkn))] | |
444 | 443 | ||
445 | 444 | let items = if ((rebalancedPriceIndex > priceIndex)) | |
446 | 445 | then throw(((("corrupt state, rebalancedPriceIndex=" + toString(rebalancedPriceIndex)) + ", request price id=") + toString(priceIndex))) | |
447 | 446 | else if ((priceIndex > rebalancedPriceIndex)) | |
448 | 447 | then throw("can't dequeue, too early, rebalance first") | |
449 | 448 | else if ((action == ISSUE)) | |
450 | 449 | then { | |
451 | 450 | let feeSize = fraction(amt, issuePercentile, 10000) | |
452 | 451 | let addedCollateral = (amt - feeSize) | |
453 | - | let | |
452 | + | let defaultAddedTokens = if ((token == BULL)) | |
454 | 453 | then fraction(bullCirc, addedCollateral, bullCol) | |
455 | 454 | else if ((token == BEAR)) | |
456 | 455 | then fraction(bearCirc, addedCollateral, bearCol) | |
457 | 456 | else throw("bad token id") | |
458 | - | let $ | |
459 | - | let addedToCirculation = $ | |
460 | - | let extraTokens = $ | |
461 | - | let $ | |
462 | - | then $Tuple4( | |
463 | - | else $Tuple4(0, 0, | |
464 | - | let plusBulls = $ | |
465 | - | let plusBullCol = $ | |
466 | - | let plusBears = $ | |
467 | - | let plusBearCol = $ | |
457 | + | let $t01427014343 = sp(defaultAddedTokens, maxPayout) | |
458 | + | let addedToCirculation = $t01427014343._1 | |
459 | + | let extraTokens = $t01427014343._2 | |
460 | + | let $t01436014531 = if ((token == BULL)) | |
461 | + | then $Tuple4(defaultAddedTokens, addedCollateral, 0, 0) | |
462 | + | else $Tuple4(0, 0, defaultAddedTokens, addedCollateral) | |
463 | + | let plusBulls = $t01436014531._1 | |
464 | + | let plusBullCol = $t01436014531._2 | |
465 | + | let plusBears = $t01436014531._3 | |
466 | + | let plusBearCol = $t01436014531._4 | |
468 | 467 | if ((minPayout > addedToCirculation)) | |
469 | 468 | then payback(mainToken) | |
470 | 469 | else (poolSup((bullCol + plusBullCol), (bearCol + plusBearCol), (bullCirc + plusBulls), (bearCirc + plusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, addedToCirculation, fromBase58String(token)), ST(feeAddress, extraTokens, fromBase58String(token))]) | |
471 | 470 | } | |
472 | 471 | else if ((action == REDEEM)) | |
473 | 472 | then { | |
474 | 473 | let removedTokens = amt | |
475 | - | let | |
474 | + | let estimatedPayout = if ((token == BULL)) | |
476 | 475 | then fraction(bullCol, removedTokens, bullCirc) | |
477 | 476 | else if ((token == BEAR)) | |
478 | 477 | then fraction(bearCol, removedTokens, bearCirc) | |
479 | 478 | else throw("bad token id") | |
480 | - | let $t01532615375 = sp(calcPo, maxPayout) | |
481 | - | let payoutCapped = $t01532615375._1 | |
482 | - | let extra = $t01532615375._2 | |
483 | - | let feeSize = fraction(payoutCapped, redeemPercentile, 10000) | |
484 | - | let payout = if ((payoutCapped > feeSize)) | |
485 | - | then (payoutCapped - feeSize) | |
486 | - | else 0 | |
487 | - | let $t01556115720 = if ((token == BULL)) | |
488 | - | then $Tuple4(removedTokens, payoutCapped, 0, 0) | |
489 | - | else $Tuple4(0, 0, removedTokens, payoutCapped) | |
490 | - | let minusBulls = $t01556115720._1 | |
491 | - | let minusBullCol = $t01556115720._2 | |
492 | - | let minusBears = $t01556115720._3 | |
493 | - | let minusBearCol = $t01556115720._4 | |
494 | - | if ((minPayout > payout)) | |
479 | + | let feeSize = fraction(estimatedPayout, redeemPercentile, 10000) | |
480 | + | let defaultPayout = (estimatedPayout - feeSize) | |
481 | + | let $t01559815652 = sp(defaultPayout, maxPayout) | |
482 | + | let userPayout = $t01559815652._1 | |
483 | + | let extra = $t01559815652._2 | |
484 | + | let $t01566915834 = if ((token == BULL)) | |
485 | + | then $Tuple4(removedTokens, estimatedPayout, 0, 0) | |
486 | + | else $Tuple4(0, 0, removedTokens, estimatedPayout) | |
487 | + | let minusBulls = $t01566915834._1 | |
488 | + | let minusBullCol = $t01566915834._2 | |
489 | + | let minusBears = $t01566915834._3 | |
490 | + | let minusBearCol = $t01566915834._4 | |
491 | + | if ((minPayout > userPayout)) | |
495 | 492 | then payback(token) | |
496 | - | else (poolSup((bullCol - minusBullCol), (bearCol - minusBearCol), (bullCirc - minusBulls), (bearCirc - minusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, | |
493 | + | else (poolSup((bullCol - minusBullCol), (bearCol - minusBearCol), (bullCirc - minusBulls), (bearCirc - minusBears)) ++ [SE(HEADK, next), collectFee(feeSize), decreaseQueueSize, ST(invoker, userPayout, fromBase58String(mainToken)), ST(feeAddress, extra, fromBase58String(mainToken))]) | |
497 | 494 | } | |
498 | 495 | else if ((action == POOL)) | |
499 | 496 | then { | |
500 | 497 | let issueTokens = fraction(poolTokenCirculation, amt, poolValue) | |
501 | 498 | if ((minPayout > issueTokens)) | |
502 | 499 | then payback(mainToken) | |
503 | 500 | else [IE(POOLUSDNK, (poolMain + amt)), IE(POOLCIRCK, (poolTokenCirculation + issueTokens)), SE(HEADK, next), decreaseQueueSize, ST(invoker, issueTokens, fromBase58String(poolToken))] | |
504 | 501 | } | |
505 | 502 | else if ((action == UNPOOL)) | |
506 | 503 | then { | |
507 | 504 | func share (a) = fraction(a, amt, poolTokenCirculation) | |
508 | 505 | ||
509 | 506 | let unpooledMain = share(poolMain) | |
510 | 507 | let unpooledUp = share(poolUp) | |
511 | 508 | let unpooledDwn = share(poolDwn) | |
512 | 509 | let unpooledUpValue = fraction(unpooledUp, bullCol, bullCirc) | |
513 | 510 | let unpooledDwnValue = fraction(unpooledDwn, bearCol, bearCirc) | |
514 | 511 | let totalUnpooledValue = ((unpooledMain + unpooledUpValue) + unpooledDwnValue) | |
515 | 512 | if ((minPayout > totalUnpooledValue)) | |
516 | 513 | then payback(poolToken) | |
517 | 514 | else [IE(POOLUSDNK, (poolMain - unpooledMain)), IE(POOLCIRCK, (poolTokenCirculation - amt)), IE(POOLUPK, (poolUp - unpooledUp)), IE(POOLDWNK, (poolDwn - unpooledDwn)), IE(BULLCIRCK, (bullCirc - unpooledUp)), IE(BEARCIRCK, (bearCirc - unpooledDwn)), IE(BULLCOLK, (bullCol - unpooledUpValue)), IE(BEARCOLK, (bearCol - unpooledDwnValue)), SE(HEADK, next), decreaseQueueSize, ST(invoker, totalUnpooledValue, fromBase58String(mainToken))] | |
518 | 515 | } | |
519 | 516 | else throw(("bad action: " + action)) | |
520 | 517 | if (isLastElement) | |
521 | 518 | then overwriteTail :: items | |
522 | 519 | else items | |
523 | 520 | } | |
524 | 521 | } | |
525 | 522 | ||
526 | 523 | ||
527 | 524 | func rebalance () = { | |
528 | 525 | func LV (v,p0,p1,m) = { | |
529 | 526 | let denom = { | |
530 | 527 | let md = (((2 * (if ((p1 > p0)) | |
531 | 528 | then p1 | |
532 | 529 | else p0)) * m) / 3037000499) | |
533 | 530 | if ((10 > md)) | |
534 | 531 | then 10 | |
535 | 532 | else if ((100 > md)) | |
536 | 533 | then 100 | |
537 | 534 | else 1000 | |
538 | 535 | } | |
539 | 536 | let pmax = ((if ((p1 > p0)) | |
540 | 537 | then p1 | |
541 | 538 | else p0) / denom) | |
542 | 539 | let pmin = ((if ((p0 > p1)) | |
543 | 540 | then p1 | |
544 | 541 | else p0) / denom) | |
545 | 542 | let a = (pmin * pmin) | |
546 | 543 | let b = ((((m * m) * pmax) * pmax) - (((((2 * m) * m) - m) * pmax) * pmin)) | |
547 | 544 | let ma = ((m * m) - m) | |
548 | 545 | fraction(v, ((ma * a) + b), (((ma + 1) * a) + b)) | |
549 | 546 | } | |
550 | 547 | ||
551 | 548 | let settledPriceIndex = valueOrErrorMessage(getInteger(this, REBIDXK), "inconsistent data") | |
552 | 549 | let unsettledPriceIndex = (settledPriceIndex + 1) | |
553 | - | let settledPrice = priceByIndex(assetName, settledPriceIndex) | |
554 | - | let nextPrice = priceByIndex(assetName, unsettledPriceIndex) | |
555 | - | let minVol = if ((bearCol > bullCol)) | |
556 | - | then bullCol | |
557 | - | else bearCol | |
558 | - | let redist = LV(minVol, settledPrice, nextPrice, leverage) | |
559 | - | let priceUpGoodForBulls = (assetName == "") | |
560 | - | let priceGoesUp = (nextPrice > settledPrice) | |
561 | - | let bullsEarn = (priceUpGoodForBulls == priceGoesUp) | |
562 | - | let newBullCol = if (bullsEarn) | |
563 | - | then (bullCol + redist) | |
564 | - | else (bullCol - redist) | |
565 | - | let newBearCol = if (bullsEarn) | |
566 | - | then (bearCol - redist) | |
567 | - | else (bearCol + redist) | |
568 | - | let $t01960819794 = poolSupport(newBullCol, newBearCol, bullCirc, bearCirc, poolMain, poolUp, poolDwn) | |
569 | - | let updBullCol = $t01960819794._1 | |
570 | - | let updBearCol = $t01960819794._2 | |
571 | - | let updBullCirc = $t01960819794._3 | |
572 | - | let updBearCirc = $t01960819794._4 | |
573 | - | let updPoolMain = $t01960819794._5 | |
574 | - | let updPoolUp = $t01960819794._6 | |
575 | - | let updPoolDwn = $t01960819794._7 | |
550 | + | if (!(opn)) | |
551 | + | then [IE(REBIDXK, unsettledPriceIndex)] | |
552 | + | else { | |
553 | + | let settledPrice = priceByIndex(assetName, settledPriceIndex) | |
554 | + | let nextPrice = priceByIndex(assetName, unsettledPriceIndex) | |
555 | + | let minVol = if ((bearCol > bullCol)) | |
556 | + | then bullCol | |
557 | + | else bearCol | |
558 | + | let redist = LV(minVol, settledPrice, nextPrice, leverage) | |
559 | + | let priceUpGoodForBulls = (assetName == "") | |
560 | + | let priceGoesUp = (nextPrice > settledPrice) | |
561 | + | let bullsEarn = (priceUpGoodForBulls == priceGoesUp) | |
562 | + | let newBullCol = if (bullsEarn) | |
563 | + | then (bullCol + redist) | |
564 | + | else (bullCol - redist) | |
565 | + | let newBearCol = if (bullsEarn) | |
566 | + | then (bearCol - redist) | |
567 | + | else (bearCol + redist) | |
568 | + | let $t01982820018 = poolSupport(newBullCol, newBearCol, bullCirc, bearCirc, poolMain, poolUp, poolDwn) | |
569 | + | let updBullCol = $t01982820018._1 | |
570 | + | let updBearCol = $t01982820018._2 | |
571 | + | let updBullCirc = $t01982820018._3 | |
572 | + | let updBearCirc = $t01982820018._4 | |
573 | + | let updPoolMain = $t01982820018._5 | |
574 | + | let updPoolUp = $t01982820018._6 | |
575 | + | let updPoolDwn = $t01982820018._7 | |
576 | 576 | [IE(BULLCOLK, updBullCol), IE(BEARCOLK, updBearCol), IE(BULLCIRCK, updBullCirc), IE(BEARCIRCK, updBearCirc), IE(POOLUSDNK, updPoolMain), IE(POOLUPK, updPoolUp), IE(POOLDWNK, updPoolDwn), IE(REBIDXK, unsettledPriceIndex)] | |
577 | + | } | |
577 | 578 | } | |
578 | 579 | ||
579 | 580 | ||
580 | 581 | func calcMax (min,avg) = if ((min > avg)) | |
581 | 582 | then throw(((("price too old: minPayout " + toString(min)) + " > avg = ") + toString(avg))) | |
582 | 583 | else ((avg + avg) - min) | |
583 | 584 | ||
584 | 585 | ||
585 | - | func requestIssueInternal (inv,tokenId,minPayout) = if (if ((tokenId != BULL)) | |
586 | - | then (tokenId != BEAR) | |
587 | - | else false) | |
588 | - | then throw("bad token req") | |
589 | - | else if ((inv.caller == this)) | |
590 | - | then throw("can't do") | |
591 | - | else if (!(allowed(inv.caller))) | |
592 | - | then throw("only whitelisted can do") | |
593 | - | else { | |
594 | - | let errorMessage = (((("bad token req, only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") allowed") | |
595 | - | if ((inv.payments[0].assetId != fromBase58String(mainToken))) | |
596 | - | then throw("bad token att") | |
597 | - | else { | |
598 | - | let amt = inv.payments[0].amount | |
599 | - | let $t02080020978 = if ((tokenId == BULL)) | |
600 | - | then $Tuple2(bullCol, bullCirc) | |
601 | - | else if ((tokenId == BEAR)) | |
602 | - | then $Tuple2(bearCol, bearCirc) | |
603 | - | else throw(errorMessage) | |
604 | - | let col = $t02080020978._1 | |
605 | - | let circ = $t02080020978._2 | |
606 | - | let est = fraction(amt, circ, col) | |
607 | - | let $t02102021114 = if ((minPayout == 0)) | |
608 | - | then $Tuple2(0, MAX) | |
609 | - | else $Tuple2(minPayout, calcMax(minPayout, est)) | |
610 | - | let minP = $t02102021114._1 | |
611 | - | let maxP = $t02102021114._2 | |
612 | - | if ((minIssue > amt)) | |
613 | - | then throw((("Attached payment too small. Min required: " + toString((minIssue / 1000000))) + " USDN")) | |
614 | - | else { | |
615 | - | let maxAllowed = maxIssue(tokenId) | |
616 | - | if (if ((whitelist == "")) | |
617 | - | then (inv.payments[0].amount > maxAllowed) | |
618 | - | else false) | |
619 | - | then throw((("trying to issue more than pool can handle. Max attachment allowed = " + toString((maxAllowed / 1000000))) + " USDN")) | |
620 | - | else (enqueue(toBase58String(inv.transactionId), ISSUE, amt, tokenId, (oraclePriceIndex + 1), toString(inv.caller), minP, maxP) ++ [debug("requested", tokenId), debug("bull", BULL), debug("bear", BEAR)]) | |
621 | - | } | |
622 | - | } | |
623 | - | } | |
586 | + | func requestIssueInternal (inv,tokenId,minPayout) = if (!(opn)) | |
587 | + | then throw("markets closed") | |
588 | + | else if (if ((tokenId != BULL)) | |
589 | + | then (tokenId != BEAR) | |
590 | + | else false) | |
591 | + | then throw("bad token req") | |
592 | + | else if ((inv.caller == this)) | |
593 | + | then throw("can't do") | |
594 | + | else if (!(allowed(inv.caller))) | |
595 | + | then throw("only whitelisted can do") | |
596 | + | else { | |
597 | + | let errorMessage = (((("bad token req, only BULL(" + BULL) + ") or BEAR(") + BEAR) + ") allowed") | |
598 | + | if ((inv.payments[0].assetId != fromBase58String(mainToken))) | |
599 | + | then throw("bad token att") | |
600 | + | else { | |
601 | + | let amt = inv.payments[0].amount | |
602 | + | let $t02110921287 = if ((tokenId == BULL)) | |
603 | + | then $Tuple2(bullCol, bullCirc) | |
604 | + | else if ((tokenId == BEAR)) | |
605 | + | then $Tuple2(bearCol, bearCirc) | |
606 | + | else throw(errorMessage) | |
607 | + | let col = $t02110921287._1 | |
608 | + | let circ = $t02110921287._2 | |
609 | + | let est = fraction(amt, circ, col) | |
610 | + | let $t02132921423 = if ((minPayout == 0)) | |
611 | + | then $Tuple2(0, MAX) | |
612 | + | else $Tuple2(minPayout, calcMax(minPayout, est)) | |
613 | + | let minP = $t02132921423._1 | |
614 | + | let maxP = $t02132921423._2 | |
615 | + | if ((minIssue > amt)) | |
616 | + | then throw((("Attached payment too small. Min required: " + toString((minIssue / 1000000))) + " USDN")) | |
617 | + | else { | |
618 | + | let maxAllowed = maxIssue(tokenId) | |
619 | + | if (if ((whitelist == "")) | |
620 | + | then (inv.payments[0].amount > maxAllowed) | |
621 | + | else false) | |
622 | + | then throw((("trying to issue more than pool can handle. Max attachment allowed = " + toString((maxAllowed / 1000000))) + " USDN")) | |
623 | + | else enqueue(toBase58String(inv.transactionId), ISSUE, amt, tokenId, (oraclePriceIndex + 1), toString(inv.caller), minP, maxP) | |
624 | + | } | |
625 | + | } | |
626 | + | } | |
624 | 627 | ||
625 | 628 | ||
626 | 629 | func requestRedeemInternal (inv,minPayout) = { | |
627 | 630 | let amt = inv.payments[0].amount | |
628 | 631 | let tokenId = toBase58String(valueOrErrorMessage(inv.payments[0].assetId, "bad token att")) | |
629 | 632 | if (if ((tokenId != BULL)) | |
630 | 633 | then (tokenId != BEAR) | |
631 | 634 | else false) | |
632 | 635 | then throw("bad token req") | |
633 | 636 | else { | |
634 | - | let $ | |
637 | + | let $t02238522524 = if ((tokenId == BULL)) | |
635 | 638 | then $Tuple2(bullCol, bullCirc) | |
636 | 639 | else if ((tokenId == BEAR)) | |
637 | 640 | then $Tuple2(bearCol, bearCirc) | |
638 | 641 | else throw("bad token req") | |
639 | - | let col = $ | |
640 | - | let circ = $ | |
642 | + | let col = $t02238522524._1 | |
643 | + | let circ = $t02238522524._2 | |
641 | 644 | let est = fraction(amt, col, circ) | |
642 | - | let $ | |
645 | + | let $t02257222666 = if ((minPayout == 0)) | |
643 | 646 | then $Tuple2(0, MAX) | |
644 | 647 | else $Tuple2(minPayout, calcMax(minPayout, est)) | |
645 | - | let minP = $ | |
646 | - | let maxP = $ | |
648 | + | let minP = $t02257222666._1 | |
649 | + | let maxP = $t02257222666._2 | |
647 | 650 | if ((validateRequestRedeem(inv) == unit)) | |
648 | 651 | then enqueue(toBase58String(inv.transactionId), REDEEM, amt, tokenId, (oraclePriceIndex + 1), toString(inv.caller), minP, maxP) | |
649 | 652 | else throw("doesn't happen") | |
650 | 653 | } | |
651 | 654 | } | |
652 | 655 | ||
653 | 656 | ||
654 | 657 | func requestPoolInternal (inv,minPayout) = if (!(allowed(inv.caller))) | |
655 | 658 | then throw("only whitelisted can do") | |
656 | 659 | else { | |
657 | - | let errMessage = | |
660 | + | let errMessage = "USDN required" | |
658 | 661 | let pmt = inv.payments[0] | |
659 | 662 | if ((pmt.assetId != fromBase58String(mainToken))) | |
660 | 663 | then throw(errMessage) | |
661 | 664 | else if ((minPool > pmt.amount)) | |
662 | - | then throw(( | |
665 | + | then throw(("pool min: " + toString(minPool))) | |
663 | 666 | else { | |
664 | 667 | let estimate = fraction(poolTokenCirculation, pmt.amount, poolValue) | |
665 | - | let $ | |
668 | + | let $t02345923558 = if ((minPayout == 0)) | |
666 | 669 | then $Tuple2(0, MAX) | |
667 | 670 | else $Tuple2(minPayout, calcMax(minPayout, estimate)) | |
668 | - | let minP = $ | |
669 | - | let maxP = $ | |
671 | + | let minP = $t02345923558._1 | |
672 | + | let maxP = $t02345923558._2 | |
670 | 673 | enqueue(toBase58String(inv.transactionId), POOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller), minP, maxP) | |
671 | 674 | } | |
672 | 675 | } | |
673 | 676 | ||
674 | 677 | ||
675 | 678 | func requestUnpoolInternal (inv,minPayout) = { | |
676 | 679 | let errMessage = (("only pool token allowed(" + poolToken) + ")") | |
677 | 680 | let pmt = inv.payments[0] | |
678 | 681 | if ((pmt.assetId != fromBase58String(poolToken))) | |
679 | 682 | then throw(errMessage) | |
680 | 683 | else { | |
681 | 684 | let estimate = fraction(poolValue, pmt.amount, poolTokenCirculation) | |
682 | 685 | if ((minPool > estimate)) | |
683 | 686 | then throw(((("unpool at least for" + toString(minPool)) + " ") + mainToken)) | |
684 | 687 | else { | |
685 | - | let $ | |
688 | + | let $t02421524314 = if ((minPayout == 0)) | |
686 | 689 | then $Tuple2(0, MAX) | |
687 | 690 | else $Tuple2(minPayout, calcMax(minPayout, estimate)) | |
688 | - | let minP = $ | |
689 | - | let maxP = $ | |
691 | + | let minP = $t02421524314._1 | |
692 | + | let maxP = $t02421524314._2 | |
690 | 693 | enqueue(toBase58String(inv.transactionId), UNPOOL, inv.payments[0].amount, "", (oraclePriceIndex + 1), toString(inv.caller), minP, maxP) | |
691 | 694 | } | |
692 | 695 | } | |
693 | 696 | } | |
694 | 697 | ||
695 | 698 | ||
696 | 699 | @Callable(inv) | |
697 | 700 | func init (config,oraclePK,nameup,namedwn,descUp,descDwn,poolName,poolDesc,defoAssetName,denom,lev) = if (isDefined(getString(this, BULLK))) | |
698 | 701 | then throw("already initialized") | |
699 | 702 | else { | |
700 | 703 | let totalOwnedMainToken = inv.payments[0].amount | |
701 | 704 | let bulls = (totalOwnedMainToken / 3) | |
702 | 705 | let bears = bulls | |
703 | 706 | let pools = ((totalOwnedMainToken - bulls) - bears) | |
704 | 707 | if (if (if ((bears == 0)) | |
705 | 708 | then true | |
706 | 709 | else (bulls == 0)) | |
707 | 710 | then true | |
708 | 711 | else (pools == 0)) | |
709 | 712 | then throw("can't init balances") | |
710 | 713 | else { | |
711 | - | let oracleCurrentPriceIndex = valueOrErrorMessage(getInteger(valueOrErrorMessage(addressFromPublicKey(fromBase58String(oraclePK)), "bad oracle address"), lastPriceIndexKey(defoAssetName)), " | |
714 | + | let oracleCurrentPriceIndex = valueOrErrorMessage(getInteger(valueOrErrorMessage(addressFromPublicKey(fromBase58String(oraclePK)), "bad oracle address"), lastPriceIndexKey(defoAssetName)), "no last price index") | |
712 | 715 | let bull = Issue(nameup, descUp, ((100 * ten6) * ten6), 6, true) | |
713 | 716 | let bear = Issue(namedwn, descDwn, ((100 * ten6) * ten6), 6, true) | |
714 | 717 | let pool = Issue(poolName, poolDesc, ((100 * ten6) * ten6), 6, true) | |
715 | 718 | let buid = calculateAssetId(bull) | |
716 | 719 | let beid = calculateAssetId(bear) | |
717 | 720 | let poid = calculateAssetId(pool) | |
718 | 721 | [bull, bear, pool, SE(BULLK, toBase58String(buid)), SE(BEARK, toBase58String(beid)), SE(USDNK, toBase58String(value(inv.payments[0].assetId))), SE(POOLK, toBase58String(poid)), SE(ASSNAMEK, defoAssetName), SE(oraclePKKey, oraclePK), IE(REBIDXK, oracleCurrentPriceIndex), IE(BULLCOLK, bulls), IE(BEARCOLK, bears), IE(BULLCIRCK, (bulls / denom)), IE(BEARCIRCK, (bears / denom)), IE(POOLCIRCK, (pools / denom)), IE(POOLDWNK, 0), IE(POOLUPK, 0), IE(POOLUSDNK, pools), SE(configProviderKey, config), IE(LEVK, lev), ST(inv.caller, (bulls / denom), buid), ST(inv.caller, (bears / denom), beid), ST(inv.caller, (pools / denom), poid)] | |
719 | 722 | } | |
720 | 723 | } | |
721 | 724 | ||
722 | 725 | ||
723 | 726 | ||
724 | 727 | @Callable(i) | |
725 | 728 | func withdrawFee (amount) = if ((amount > feesAccumulated)) | |
726 | 729 | then throw(("too much. available: " + toString(feesAccumulated))) | |
727 | 730 | else [IE(FEEACCK, (feesAccumulated - amount)), ST(feeAddress, amount, fromBase58String(mainToken))] | |
728 | 731 | ||
729 | 732 | ||
730 | 733 | ||
731 | 734 | @Callable(inv) | |
732 | 735 | func requestRedeem () = requestRedeemInternal(inv, 0) | |
733 | 736 | ||
734 | 737 | ||
735 | 738 | ||
736 | 739 | @Callable(inv) | |
737 | 740 | func requestRedeemSl (sl) = if (validatePMFee(inv, sl)) | |
738 | 741 | then requestRedeemInternal(inv, sl) | |
739 | 742 | else throw() | |
740 | 743 | ||
741 | 744 | ||
742 | 745 | ||
743 | 746 | @Callable(inv) | |
744 | 747 | func requestIssue (tokenId) = requestIssueInternal(inv, tokenId, 0) | |
745 | 748 | ||
746 | 749 | ||
747 | 750 | ||
748 | 751 | @Callable(inv) | |
749 | 752 | func requestIssueSl (tokenId,sl) = if (validatePMFee(inv, sl)) | |
750 | 753 | then requestIssueInternal(inv, tokenId, sl) | |
751 | 754 | else throw() | |
752 | 755 | ||
753 | 756 | ||
754 | 757 | ||
755 | 758 | @Callable(inv) | |
756 | 759 | func requestPool () = requestPoolInternal(inv, 0) | |
757 | 760 | ||
758 | 761 | ||
759 | 762 | ||
760 | 763 | @Callable(inv) | |
761 | 764 | func requestPoolSl (sl) = if (validatePMFee(inv, sl)) | |
762 | 765 | then requestPoolInternal(inv, sl) | |
763 | 766 | else throw() | |
764 | 767 | ||
765 | 768 | ||
766 | 769 | ||
767 | 770 | @Callable(inv) | |
768 | 771 | func requestUnpool () = requestUnpoolInternal(inv, 0) | |
769 | 772 | ||
770 | 773 | ||
771 | 774 | ||
772 | 775 | @Callable(inv) | |
773 | 776 | func requestUnpoolSl (sl) = if (validatePMFee(inv, sl)) | |
774 | 777 | then requestUnpoolInternal(inv, sl) | |
775 | 778 | else throw() | |
776 | 779 | ||
777 | 780 | ||
778 | 781 | ||
779 | 782 | @Callable(inv) | |
780 | 783 | func settle () = { | |
781 | 784 | let queueEmpty = (headPointer == "") | |
782 | 785 | let canRebalance = (oraclePriceIndex > rebalancedPriceIndex) | |
783 | 786 | if (queueEmpty) | |
784 | 787 | then if (canRebalance) | |
785 | 788 | then rebalance() | |
786 | 789 | else throw("[OK] all done, carry on") | |
787 | 790 | else { | |
788 | 791 | let data = split(valueOrErrorMessage(getString(this, headPointer), ("bad head pointer(settle): " + headPointer)), "|") | |
789 | 792 | let priceIndex = parseIntValue(data[3]) | |
790 | 793 | if ((priceIndex > rebalancedPriceIndex)) | |
791 | 794 | then if (canRebalance) | |
792 | 795 | then rebalance() | |
793 | 796 | else throw("[OK] need to wait") | |
794 | 797 | else if ((priceIndex == rebalancedPriceIndex)) | |
795 | 798 | then dequeue() | |
796 | 799 | else throw("future price already rebalanced") | |
797 | 800 | } | |
798 | 801 | } | |
799 | 802 | ||
800 | 803 | ||
801 | 804 | @Verifier(tx) | |
802 | 805 | func verify () = { | |
803 | 806 | let initial = if (!(isDefined(getString(this, BULLK)))) | |
804 | 807 | then sigVerify(tx.bodyBytes, tx.proofs[0], tx.senderPublicKey) | |
805 | 808 | else false | |
806 | 809 | let adminAction = ((((if (sigVerify(tx.bodyBytes, tx.proofs[0], fromBase58String(admins[0]))) | |
807 | 810 | then 1 | |
808 | 811 | else 0) + (if (sigVerify(tx.bodyBytes, tx.proofs[1], fromBase58String(admins[1]))) | |
809 | 812 | then 1 | |
810 | 813 | else 0)) + (if (sigVerify(tx.bodyBytes, tx.proofs[2], fromBase58String(admins[2]))) | |
811 | 814 | then 1 | |
812 | 815 | else 0)) > 1) | |
813 | 816 | let stakingAction = match tx { | |
814 | 817 | case tx: InvokeScriptTransaction => | |
815 | 818 | let signedCorrectly = sigVerify(tx.bodyBytes, tx.proofs[0], daemonPublicKey) | |
816 | 819 | let feesCorrect = if ((tx.feeAssetId == unit)) | |
817 | 820 | then ((1000 * 1000) >= tx.fee) | |
818 | 821 | else false | |
819 | 822 | let dappCorrect = (tx.dApp == rpdAddress) | |
820 | 823 | let unlock = (tx.function == "unlockNeutrino") | |
821 | 824 | let lock = if (if ((tx.function == "lockNeutrinoSP")) | |
822 | 825 | then (tx.args[0] == stakingAddress) | |
823 | 826 | else false) | |
824 | 827 | then (wavesBalance(this).available >= ten8) | |
825 | 828 | else false | |
826 | 829 | let funcCorrect = if (lock) | |
827 | 830 | then true | |
828 | 831 | else unlock | |
829 | 832 | if (if (if (signedCorrectly) | |
830 | 833 | then feesCorrect | |
831 | 834 | else false) | |
832 | 835 | then dappCorrect | |
833 | 836 | else false) | |
834 | 837 | then funcCorrect | |
835 | 838 | else false | |
836 | 839 | case _ => | |
837 | 840 | false | |
838 | 841 | } | |
839 | 842 | if (if (initial) | |
840 | 843 | then true | |
841 | 844 | else adminAction) | |
842 | 845 | then true | |
843 | 846 | else stakingAction | |
844 | 847 | } | |
845 | 848 |
github/deemru/w8io/786bc32 378.53 ms ◑