2022.07.01 15:48 [3186208] smart account 3PPNhHYkkEy13gRWDCaruQyhNbX2GrjYSyV > SELF 0.00000000 Waves
{ "type": 13, "id": "2chdSb6tNz3g6M6QXnPZAP1KME7E1cFFNC9QGbBuLG8S", "fee": 300000000, "feeAssetId": null, "timestamp": 1656679698279, "version": 1, "sender": "3PPNhHYkkEy13gRWDCaruQyhNbX2GrjYSyV", "senderPublicKey": "EAtbDa63mS5omrvW7Pfr7DKWEVLuReJtu72vfiBLRXsx", "proofs": [ "3PE79K7CrW2CCkRCpW8bWT5scAFBwKGBMxwAWLK8zHfpELTbb7A6TQzUPfD2CvxhFYRMEdyUm9StgGoHhgsAs69c" ], "script": "base64:AAIFAAAAAAAAAGMIAhIECgIIGBIDCgEIEgUKAwgICBIDCgEIEgMKAQgSAwoBCBIECgIICBIECgIICBIECgIICBIDCgEIEgUKAwgIBBIECgIICBIECgIIBBIDCgEIEgMKARgSAwoBCBIAEgMKAQgAAAArAAAAAANTRVACAAAAAl9fAAAAAAVFTVBUWQIAAAAAAAAAAA5zdGF0dXNWZXJpZmllZAAAAAAAAAAAAgAAAAAQc3RhdHVzVW52ZXJpZmllZAAAAAAAAAAAAAAAAAAWbGFiZWxDb21tdW5pdHlWZXJpZmllZAIAAAASQ09NTVVOSVRZX1ZFUklGSUVEAAAAAAxsYWJlbFBvb2xzTHACAAAACFBPT0xTX0xQAAAAAA1kZWZhdWx0TGFiZWxzCQAETAAAAAIFAAAAFmxhYmVsQ29tbXVuaXR5VmVyaWZpZWQJAARMAAAAAgUAAAAMbGFiZWxQb29sc0xwBQAAAANuaWwBAAAAB3Rocm93UEQAAAAACQAAAgAAAAECAAAAEVBlcm1pc3Npb24gZGVuaWVkAQAAAAx0aHJvd05vQXNzZXQAAAAACQAAAgAAAAECAAAAFEFzc2V0IGRvZXNuJ3QgZXhpc3RzAQAAABNrZXlNYW5hZ2VyUHVibGljS2V5AAAAAAIAAAAUJXNfX21hbmFnZXJQdWJsaWNLZXkBAAAAGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAAAAAIAAAAbJXNfX3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AQAAAA9rZXlBZG1pblB1YktleXMAAAAAAgAAABAlc19fYWRtaW5QdWJLZXlzAQAAABRrZXlVc2VyUG9vbHNDb250cmFjdAAAAAACAAAAFSVzX191c2VyUG9vbHNDb250cmFjdAEAAAAZa2V5Vm90aW5nRW1pc3Npb25Db250cmFjdAAAAAACAAAAGiVzX192b3RpbmdFbWlzc2lvbkNvbnRyYWN0AQAAAAprZXlDcmVhdGVkAAAAAQAAAAdhc3NldElkCQABLAAAAAIJAAEsAAAAAgIAAAAJY3JlYXRlZF88BQAAAAdhc3NldElkAgAAAAE+AQAAAAdrZXlMb2dvAAAAAQAAAAdhc3NldElkCQABLAAAAAIJAAEsAAAAAgIAAAAGbG9nb188BQAAAAdhc3NldElkAgAA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AAABBQAAAAFpAwkAAAAAAAACBQAAAAlpc01hbmFnZXIFAAAACWlzTWFuYWdlcgYJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQAAAAlpc0NyZWF0ZWQAAAABAAAAB2Fzc2V0SWQJAQAAAAt2YWx1ZU9yRWxzZQAAAAIJAAQgAAAAAQkBAAAACmtleUNyZWF0ZWQAAAABBQAAAAdhc3NldElkBwEAAAAQdmVyaWZpZWRUb1N0YXR1cwAAAAEAAAAIdmVyaWZpZWQDBQAAAAh2ZXJpZmllZAUAAAAOc3RhdHVzVmVyaWZpZWQFAAAAEHN0YXR1c1VudmVyaWZpZWQBAAAAD2FkZExhYmVsQWN0aW9ucwAAAAMAAAAHYXNzZXRJZAAAAAVsYWJlbAAAAAx0aHJvd09uRXJyb3IEAAAABmxhYmVscwkBAAAACWdldExhYmVscwAAAAAEAAAAC2Fzc2V0TGFiZWxzCQEAAAAOZ2V0QXNzZXRMYWJlbHMAAAABBQAAAAdhc3NldElkBAAAAApjaGVja0xhYmVsAwkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIFAAAABmxhYmVscwUAAAAFbGFiZWwGCQAAAgAAAAECAAAAE0xhYmVsIGRvZXNuJ3QgZXhpc3QDCQAAAAAAAAIFAAAACmNoZWNrTGFiZWwFAAAACmNoZWNrTGFiZWwEAAAADm5ld0Fzc2V0TGFiZWxzAwkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIFAAAAC2Fzc2V0TGFiZWxzBQAAAAVsYWJlbAMFAAAADHRocm93T25FcnJvcgkAAAIAAAABAgAAABxMYWJlbCBoYXMgYWxyZWFkeSBiZWVuIGFkZGVkBQAAAAthc3NldExhYmVscwkABE0AAAACBQAAAAthc3NldExhYmVscwUAAAAFbGFiZWwJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAADmtleUFzc2V0TGFiZWxzAAAAAQUAAAAHYXNzZXRJZAkABLkAAAACBQAAAA5uZXdBc3NldExhYmVscwUAAAADU0VQBQAAAANuaWwJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAQAAABJkZWxldGVMYWJlbEFjdGlvbnMAAAADAAAAB2Fzc2V0SWQAAAAFbGFiZWwAAAAMdGhyb3dPbkVycm9yBAAAAAthc3NldExhYmVscwkBAAAADmdldEFzc2V0TGFiZWxzAAAAAQUAAAAHYXNzZXRJZAQAAAAObmV3QXNzZXRMYWJlbHMDCQEAAAAPY29udGFpbnNFbGVtZW50AAAAAgUAAAALYXNzZXRMYWJlbHMFAAAABWxhYmVsCQAEUQAAAAIFAAAAC2Fzc2V0TGFiZWxzCQEAAAAFdmFsdWUAAAABCQAETwAAAAIFAAAAC2Fzc2V0TGFiZWxzBQAAAAVsYWJlbAMFAAAADHRocm93T25FcnJvcgkAAAIAAAABAgAAABJMYWJlbCB3YXNuJ3QgYWRkZWQFAAAAC2Fzc2V0TGFiZWxzCQAETAAAAAIJAQAAAAtTdHJpbmdFbnRyeQAAAAIJAQAAAA5rZXlBc3NldExhYmVscwAAAAEFAAAAB2Fzc2V0SWQJAAS5AAAAAgUAAAAObmV3QXNzZXRMYWJlbHMFAAAAA1NFUAUAAAADbmlsAQAAABJzZXRWZXJpZmllZEFjdGlvbnMAAAACAAAAB2Fzc2V0SWQAAAAIdmVyaWZpZWQEAAAAHWxhYmVsQ29tbXVuaXR5VmVyaWZpZWRBY3Rpb25zAwUAAAAIdmVyaWZpZWQJAQAAAA9hZGRMYWJlbEFjdGlvbnMAAAADBQAAAAdhc3NldElkBQAAABZsYWJlbENvbW11bml0eVZlcmlmaWVkBwkBAAAAEmRlbGV0ZUxhYmVsQWN0aW9ucwAAAAMFAAAAB2Fzc2V0SWQFAAAAFmxhYmVsQ29tbXVuaXR5VmVyaWZpZWQHCQAETgAAAAIJAARMAAAAAgkBAAAADEludGVnZXJFbnRyeQAAAAIJAQAAAAlrZXlTdGF0dXMAAAABBQAAAAdhc3NldElkCQEAAAAQdmVyaWZpZWRUb1N0YXR1cwAAAAEFAAAACHZlcmlmaWVkBQAAAANuaWwFAAAAHWxhYmVsQ29tbXVuaXR5VmVyaWZpZWRBY3Rpb25zAQAAABN1cGRhdGVUaWNrZXJBY3Rpb25zAAAAAgAAAAdhc3NldElkAAAABnRpY2tlcgQAAAALY2hlY2tUaWNrZXIEAAAAE2xpbmtlZEFzc2V0SWRPclVuaXQJAAQiAAAAAQkBAAAAEmtleVRpY2tlclRvQXNzZXRJZAAAAAEFAAAABnRpY2tlcgQAAAANdGlja2VySXNWYWxpZAMJAQAAAAIhPQAAAAIFAAAABnRpY2tlcgIAAAAAAwkAAAAAAAACBQAAABNsaW5rZWRBc3NldElkT3JVbml0BQAAAAR1bml0BgkAAAAAAAACCQEAAAAFdmFsdWUAAAABBQAAABNsaW5rZWRBc3NldElkT3JVbml0BQAAAAdhc3NldElkBwMFAAAADXRpY2tlcklzVmFsaWQGCQAAAgAAAAECAAAADkludmFsaWQgdGlja2VyAwkAAAAAAAACBQAAAAtjaGVja1RpY2tlcgUAAAALY2hlY2tUaWNrZXIJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAEmtleUFzc2V0SWRUb1RpY2tlcgAAAAEFAAAAB2Fzc2V0SWQFAAAABnRpY2tlcgkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAASa2V5VGlja2VyVG9Bc3NldElkAAAAAQUAAAAGdGlja2VyBQAAAAdhc3NldElkBQAAAANuaWwJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAEgAAAAFpAQAAAAtjb25zdHJ1Y3RvcgAAAAIAAAARdXNlclBvb2xzQ29udHJhY3QAAAAGbGFiZWxzBAAAAAtjaGVja0NhbGxlcgkBAAAAC211c3RNYW5hZ2VyAAAAAQUAAAABaQMJAAAAAAAAAgUAAAALY2hlY2tDYWxsZXIFAAAAC2NoZWNrQ2FsbGVyBAAAAA1jaGVja3NBZGRyZXNzCQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQmAAAAAQUAAAARdXNlclBvb2xzQ29udHJhY3QCAAAAD0ludmFsaWQgYWRkcmVzcwMJAAAAAAAAAgUAAAANY2hlY2tzQWRkcmVzcwUAAAANY2hlY2tzQWRkcmVzcwkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAUa2V5VXNlclBvb2xzQ29udHJhY3QAAAAABQAAABF1c2VyUG9vbHNDb250cmFjdAkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAJa2V5TGFiZWxzAAAAAAkABLkAAAACCQAETgAAAAIFAAAADWRlZmF1bHRMYWJlbHMFAAAABmxhYmVscwUAAAADU0VQBQAAAANuaWwJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAA1jb25zdHJ1Y3RvclYyAAAAAQAAABZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0BAAAAAtjaGVja0NhbGxlcgkBAAAAC211c3RNYW5hZ2VyAAAAAQUAAAABaQMJAAAAAAAAAgUAAAALY2hlY2tDYWxsZXIFAAAAC2NoZWNrQ2FsbGVyBAAAAAxjaGVja0FkZHJlc3MJAQAAABN2YWx1ZU9yRXJyb3JNZXNzYWdlAAAAAgkABCYAAAABBQAAABZ2b3RpbmdFbWlzc2lvbkNvbnRyYWN0AgAAAChpbnZhbGlkIHZvdGluZyBlbWlzc2lvbiBjb250cmFjdCBhZGRyZXNzAwkAAAAAAAACBQAAAAxjaGVja0FkZHJlc3MFAAAADGNoZWNrQWRkcmVzcwkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAZa2V5Vm90aW5nRW1pc3Npb25Db250cmFjdAAAAAAFAAAAFnZvdGluZ0VtaXNzaW9uQ29udHJhY3QFAAAAA25pbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAADWFkZEFzc2V0c0xpbmsAAAADAAAAC2Ftb3VudEFzc2V0AAAACnByaWNlQXNzZXQAAAAHbHBBc3NldAQAAAALY2hlY2tDYWxsZXIJAQAAAAltdXN0QWRtaW4AAAABBQAAAAFpAwkAAAAAAAACBQAAAAtjaGVja0NhbGxlcgUAAAALY2hlY2tDYWxsZXIJAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAIGtleUFtb3VudEFuZFByaWNlQXNzZXRzVG9McEFzc2V0AAAAAgUAAAALYW1v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YXNzZXRJZAAAAAVsYWJlbAQAAAALY2hlY2tDYWxsZXIJAQAAAAltdXN0QWRtaW4AAAABBQAAAAFpAwkAAAAAAAACBQAAAAtjaGVja0NhbGxlcgUAAAALY2hlY2tDYWxsZXIJAQAAAA9hZGRMYWJlbEFjdGlvbnMAAAADBQAAAAdhc3NldElkBQAAAAVsYWJlbAYJAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAAC2RlbGV0ZUxhYmVsAAAAAgAAAAdhc3NldElkAAAABWxhYmVsBAAAAAtjaGVja0NhbGxlcgkBAAAACW11c3RBZG1pbgAAAAEFAAAAAWkDCQAAAAAAAAIFAAAAC2NoZWNrQ2FsbGVyBQAAAAtjaGVja0NhbGxlcgkBAAAAEmRlbGV0ZUxhYmVsQWN0aW9ucwAAAAMFAAAAB2Fzc2V0SWQFAAAABWxhYmVsBgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAMdXBkYXRlVGlja2VyAAAAAgAAAAdhc3NldElkAAAABnRpY2tlcgQAAAALY2hlY2tDYWxsZXIJAQAAAAltdXN0QWRtaW4AAAABBQAAAAFpAwkAAAAAAAACBQAAAAtjaGVja0NhbGxlcgUAAAALY2hlY2tDYWxsZXIEAAAACmNoZWNrQXNzZXQDCQEAAAAJaXNDcmVhdGVkAAAAAQUAAAAHYXNzZXRJZAYJAQAAAAx0aHJvd05vQXNzZXQAAAAAAwkAAAAAAAACBQAAAApjaGVja0Fzc2V0BQAAAApjaGVja0Fzc2V0CQEAAAATdXBkYXRlVGlja2VyQWN0aW9ucwAAAAIFAAAAB2Fzc2V0SWQFAAAABnRpY2tlcgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAADGRlbGV0ZVRpY2tlcgAAAAEAAAAHYXNzZXRJZAQAAAALY2hlY2tDYWxsZXIJAQAAAAltdXN0QWRtaW4AAAABBQAAAAFpAwkAAAAAAAACBQAA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Z2VyAAAAAQAAABdwZW5kaW5nTWFuYWdlclB1YmxpY0tleQQAAAALY2hlY2tDYWxsZXIJAQAAAAttdXN0TWFuYWdlcgAAAAEFAAAAAWkDCQAAAAAAAAIFAAAAC2NoZWNrQ2FsbGVyBQAAAAtjaGVja0NhbGxlcgQAAAAVY2hlY2tNYW5hZ2VyUHVibGljS2V5CQACWQAAAAEFAAAAF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AwkAAAAAAAACBQAAABVjaGVja01hbmFnZXJQdWJsaWNLZXkFAAAAFWNoZWNrTWFuYWdlclB1YmxpY0tleQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkAAAAABQAAABdwZW5kaW5nTWFuYWdlclB1YmxpY0tleQUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAOY29uZmlybU1hbmFnZXIAAAAABAAAAAJwbQkBAAAAHXBlbmRpbmdNYW5hZ2VyUHVibGljS2V5T3JVbml0AAAAAAQAAAAFaGFzUE0DCQEAAAAJaXNEZWZpbmVkAAAAAQUAAAACcG0GCQAAAgAAAAECAAAAEk5vIHBlbmRpbmcgbWFuYWdlcgMJAAAAAAAAAgUAAAAFaGFzUE0FAAAABWhhc1BNBAAAAAdjaGVja1BNAwkAAAAAAAACCAUAAAABaQAAAA9jYWxsZXJQdWJsaWNLZXkJAQAAAAV2YWx1ZQAAAAEFAAAAAnBtBgkAAAIAAAABAgAAABtZb3UgYXJlIG5vdCBwZW5kaW5nIG1hbmFnZXIDCQAAAAAAAAIFAAAAB2NoZWNrUE0FAAAAB2NoZWNrUE0JAARMAAAAAgkBAAAAC1N0cmluZ0VudHJ5AAAAAgkBAAAAE2tleU1hbmFnZXJQdWJsaWNLZXkAAAAACQACWAAAAAEJAQAAAAV2YWx1ZQAAAAEFAAAAAnBtCQAETAAAAAIJAQAAAAtEZWxldGVFbnRyeQAAAAEJAQAAABprZXlQZW5kaW5nTWFuYWdlclB1YmxpY0tleQAAAAAFAAAAA25pbAkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4JAAACAAAAAQIAAAAkU3RyaWN0IHZhbHVlIGlzIG5vdCBlcXVhbCB0byBpdHNlbGYuAAAAAWkBAAAAEmlzVmVyaWZpZWRSRUFET05MWQAAAAEAAAAHYXNzZXRJZAkABRQAAAACBQAAAANuaWwJAQAAAAppc1ZlcmlmaWVkAAAAAQUAAAAHYXNzZXRJZAAAAAEAAAACdHgBAAAABnZlcmlmeQAAAAAEAAAAD3RhcmdldFB1YmxpY0tleQQAAAAHJG1hdGNoMAkBAAAAFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQAAAAAAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAApCeXRlVmVjdG9yBAAAAAJwawUAAAAHJG1hdGNoMAUAAAACcGsDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABFVuaXQIBQAAAAJ0eAAAAA9zZW5kZXJQdWJsaWNLZXkJAAACAAAAAQIAAAALTWF0Y2ggZXJyb3IJAAH0AAAAAwgFAAAAAnR4AAAACWJvZHlCeXRlcwkAAZEAAAACCAUAAAACdHgAAAAGcHJvb2ZzAAAAAAAAAAAABQAAAA90YXJnZXRQdWJsaWNLZXnRF7am", "chainId": 87, "height": 3186208, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 5cRLYjibR8rMWd6WJXxpwa9qimRGtLnZVVLEGEFAv5Az Next: GT6yTgG6QTzTUbFRpfvatmJMS4pMAYozr99GpBtqZnxW Diff:
Old | New | Differences | |
---|---|---|---|
1 | - | {-# STDLIB_VERSION | |
1 | + | {-# STDLIB_VERSION 5 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | - | let SCALE8 = 8 | |
5 | - | ||
6 | - | let MULT8 = 100000000 | |
7 | - | ||
8 | - | let SCALE18 = 18 | |
9 | - | ||
10 | - | let MULT18 = toBigInt(1000000000000000000) | |
11 | - | ||
12 | 4 | let SEP = "__" | |
13 | 5 | ||
14 | - | let | |
6 | + | let EMPTY = "" | |
15 | 7 | ||
16 | - | let | |
8 | + | let statusVerified = 2 | |
17 | 9 | ||
18 | - | let | |
10 | + | let statusUnverified = 0 | |
19 | 11 | ||
20 | - | let | |
12 | + | let labelCommunityVerified = "COMMUNITY_VERIFIED" | |
21 | 13 | ||
22 | - | func asAnyList (val) = match val { | |
23 | - | case valAnyLyst: List[Any] => | |
24 | - | valAnyLyst | |
25 | - | case _ => | |
26 | - | throw("fail to cast into List[Any]") | |
27 | - | } | |
14 | + | let labelPoolsLp = "POOLS_LP" | |
15 | + | ||
16 | + | let defaultLabels = [labelCommunityVerified, labelPoolsLp] | |
17 | + | ||
18 | + | func throwPD () = throw("Permission denied") | |
28 | 19 | ||
29 | 20 | ||
30 | - | func asInt (val) = match val { | |
31 | - | case valInt: Int => | |
32 | - | valInt | |
33 | - | case _ => | |
34 | - | throw("fail to cast into Int") | |
35 | - | } | |
36 | - | ||
37 | - | ||
38 | - | func asString (val) = match val { | |
39 | - | case valStr: String => | |
40 | - | valStr | |
41 | - | case _ => | |
42 | - | throw("fail to cast into Int") | |
43 | - | } | |
44 | - | ||
45 | - | ||
46 | - | func asByteVector (val) = match val { | |
47 | - | case valBin: ByteVector => | |
48 | - | valBin | |
49 | - | case _ => | |
50 | - | throw("fail to cast into Int") | |
51 | - | } | |
52 | - | ||
53 | - | ||
54 | - | func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined")) | |
55 | - | ||
56 | - | ||
57 | - | func getStringByAddressOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined")) | |
58 | - | ||
59 | - | ||
60 | - | func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0) | |
61 | - | ||
62 | - | ||
63 | - | func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal) | |
64 | - | ||
65 | - | ||
66 | - | func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined")) | |
67 | - | ||
68 | - | ||
69 | - | func getBigIntFromStringOrZero (address,key) = value(parseBigInt(valueOrElse(getString(address, key), "0"))) | |
70 | - | ||
71 | - | ||
72 | - | func getBigIntFromStringOrDefault (address,key,defaultVal) = match getString(address, key) { | |
73 | - | case s: String => | |
74 | - | value(parseBigInt(s)) | |
75 | - | case _: Unit => | |
76 | - | defaultVal | |
77 | - | case _ => | |
78 | - | throw("Match error") | |
79 | - | } | |
80 | - | ||
81 | - | ||
82 | - | func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULT18, toBigInt(origScaleMult)) | |
83 | - | ||
84 | - | ||
85 | - | func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULT18)) | |
86 | - | ||
87 | - | ||
88 | - | func keyFactoryAddress () = "%s%s__config__factoryAddress" | |
89 | - | ||
90 | - | ||
91 | - | func keyVotingEmissionContract () = "%s__votingEmissionContract" | |
92 | - | ||
93 | - | ||
94 | - | let IdxFactoryCfgStakingDapp = 1 | |
95 | - | ||
96 | - | let IdxFactoryCfgBoostingDapp = 2 | |
97 | - | ||
98 | - | let IdxFactoryCfgIdoDapp = 3 | |
99 | - | ||
100 | - | let IdxFactoryCfgTeamDapp = 4 | |
101 | - | ||
102 | - | let IdxFactoryCfgEmissionDapp = 5 | |
103 | - | ||
104 | - | let IdxFactoryCfgRestDapp = 6 | |
105 | - | ||
106 | - | let IdxFactoryCfgSlippageDapp = 7 | |
107 | - | ||
108 | - | func keyFactoryCfg () = "%s__factoryConfig" | |
21 | + | func throwNoAsset () = throw("Asset doesn't exists") | |
109 | 22 | ||
110 | 23 | ||
111 | 24 | func keyManagerPublicKey () = "%s__managerPublicKey" | |
114 | 27 | func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey" | |
115 | 28 | ||
116 | 29 | ||
117 | - | func | |
30 | + | func keyAdminPubKeys () = "%s__adminPubKeys" | |
118 | 31 | ||
119 | 32 | ||
120 | - | func | |
33 | + | func keyUserPoolsContract () = "%s__userPoolsContract" | |
121 | 34 | ||
122 | 35 | ||
123 | - | func | |
36 | + | func keyVotingEmissionContract () = "%s__votingEmissionContract" | |
124 | 37 | ||
125 | 38 | ||
126 | - | func | |
39 | + | func keyCreated (assetId) = (("created_<" + assetId) + ">") | |
127 | 40 | ||
128 | 41 | ||
129 | - | func | |
42 | + | func keyLogo (assetId) = (("logo_<" + assetId) + ">") | |
130 | 43 | ||
131 | 44 | ||
132 | - | func | |
45 | + | func keyTicker (assetId) = (("ticker_<" + assetId) + ">") | |
133 | 46 | ||
134 | 47 | ||
135 | - | func | |
48 | + | func keyStatus (assetId) = (("status_<" + assetId) + ">") | |
136 | 49 | ||
137 | 50 | ||
138 | - | func | |
51 | + | func keyAssetPoolsNumber (assetId) = makeString(["%s%s", "pools", assetId], SEP) | |
139 | 52 | ||
140 | 53 | ||
141 | - | func | |
54 | + | func keyTickerToAssetId (ticker) = makeString(["%s%s", "ticker2assetId", ticker], SEP) | |
142 | 55 | ||
143 | 56 | ||
144 | - | func | |
57 | + | func keyAssetIdToTicker (assetId) = makeString(["%s%s", "assetId2ticker", assetId], SEP) | |
145 | 58 | ||
146 | 59 | ||
147 | - | func | |
60 | + | func keyAmountAndPriceAssetsToLpAsset (amountAsset,priceAsset) = makeString(["%s%s%s", "amountAndPriceAssetsToLpAsset", amountAsset, priceAsset], SEP) | |
148 | 61 | ||
149 | 62 | ||
150 | - | func | |
63 | + | func keyLpAssetToAmountAndPriceAssets (lpAsset) = makeString(["%s%s", "lpAssetToAmountAndPriceAssets", lpAsset], SEP) | |
151 | 64 | ||
152 | 65 | ||
153 | - | func | |
66 | + | func keyAssetLabels (assetId) = makeString(["%s%s", "labels", assetId], SEP) | |
154 | 67 | ||
155 | 68 | ||
156 | - | func | |
69 | + | func keyLabels () = makeString(["%s", "labels"], SEP) | |
157 | 70 | ||
158 | 71 | ||
159 | - | func keyEmissionEndBlock () = "%s%s__emission__endBlock" | |
160 | - | ||
161 | - | ||
162 | - | func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s__staked", userAddressStr, lpAssetIdStr], SEP) | |
163 | - | ||
164 | - | ||
165 | - | func keyStakedTotal (lpAssetIdStr) = ("%s%s%s__staked__total__" + lpAssetIdStr) | |
166 | - | ||
167 | - | ||
168 | - | func keyClaimedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimed", userAddressStr, lpAssetIdStr], SEP) | |
169 | - | ||
170 | - | ||
171 | - | func keyClaimedByUserMinReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedMinReward", userAddressStr, lpAssetIdStr], SEP) | |
172 | - | ||
173 | - | ||
174 | - | func keyClaimedByUserBoostReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedBoostReward", userAddressStr, lpAssetIdStr], SEP) | |
175 | - | ||
176 | - | ||
177 | - | func keyClaimedTotal (lpAssetIdStr) = makeString(["%s%s%s__claimed__total", lpAssetIdStr], SEP) | |
178 | - | ||
179 | - | ||
180 | - | func readStaked (key) = valueOrElse(getInteger(this, key), 0) | |
181 | - | ||
182 | - | ||
183 | - | func keyLastTotalLpBalance (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "bal"], SEP) | |
184 | - | ||
185 | - | ||
186 | - | func keyLastUserLpBalance (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "bal"], SEP) | |
187 | - | ||
188 | - | ||
189 | - | func keyTotalLpBalanceIntegral (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "balINT"], SEP) | |
190 | - | ||
191 | - | ||
192 | - | func keyUserLpBalanceIntegral (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "balINT"], SEP) | |
193 | - | ||
194 | - | ||
195 | - | func keyTotalLpBalanceIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "lastUpd"], SEP) | |
196 | - | ||
197 | - | ||
198 | - | func keyUserLpBalanceIntegralLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "lastUpd"], SEP) | |
199 | - | ||
200 | - | ||
201 | - | func keyWxPerLpIntegral (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpInt"], SEP) | |
202 | - | ||
203 | - | ||
204 | - | func keyWxPerLpIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpIntH"], SEP) | |
205 | - | ||
206 | - | ||
207 | - | func keyWxToClaimUser (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpInt"], SEP) | |
208 | - | ||
209 | - | ||
210 | - | func keyWxPerLpIntegralUserLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpIntH"], SEP) | |
211 | - | ||
212 | - | ||
213 | - | func keyWxPerLp (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLp"], SEP) | |
214 | - | ||
215 | - | ||
216 | - | func keyWxPerLpX18 (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLpX18"], SEP) | |
217 | - | ||
218 | - | ||
219 | - | func keyWxPerLpIntegralUserLast (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "uIntL"], SEP) | |
220 | - | ||
221 | - | ||
222 | - | func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP) | |
223 | - | ||
224 | - | ||
225 | - | func formatHistoryRecord (userAddress,lpAssetId,type,amount) = makeString(["%s%s%s%d%d%d", userAddress, lpAssetId, type, toString(height), toString(lastBlock.timestamp), toString(amount)], SEP) | |
226 | - | ||
227 | - | ||
228 | - | func OperationHistoryEntry (type,userAddress,lpAssetId,amount,txId) = StringEntry(keyOperationHistoryRecord(type, userAddress, toBase58String(txId)), formatHistoryRecord(userAddress, lpAssetId, type, amount)) | |
229 | - | ||
230 | - | ||
231 | - | let factoryAddress = getStringOrFail(this, keyFactoryAddress()) | |
232 | - | ||
233 | - | let factoryContract = addressFromStringValue(factoryAddress) | |
234 | - | ||
235 | - | let factoryCfg = readFactoryCfgOrFail(factoryContract) | |
236 | - | ||
237 | - | let emissionContract = getEmissionAddressOrFail(factoryCfg) | |
238 | - | ||
239 | - | let boostingContract = getBoostingAddressOrFail(factoryCfg) | |
240 | - | ||
241 | - | func keyNextUser (lpAssetId) = makeString(["%s%s", lpAssetId, "nextUser"], SEP) | |
242 | - | ||
243 | - | ||
244 | - | func getUsersListName (lpAssetId) = makeString(["users", lpAssetId], SEP) | |
245 | - | ||
246 | - | ||
247 | - | func keyListHead (listName) = makeString(["%s%s%s", listName, "head"], SEP) | |
248 | - | ||
249 | - | ||
250 | - | func keyListSize (listName) = makeString(["%s%s%s", listName, "size"], SEP) | |
251 | - | ||
252 | - | ||
253 | - | func keyListPrev (listName,id) = makeString(["%s%s%s%s", listName, id, "prev"], SEP) | |
254 | - | ||
255 | - | ||
256 | - | func keyListNext (listName,id) = makeString(["%s%s%s%s", listName, id, "next"], SEP) | |
257 | - | ||
258 | - | ||
259 | - | func containsNode (listName,id) = { | |
260 | - | let headOrUnit = getString(this, keyListHead(listName)) | |
261 | - | let prevOrUnit = getString(this, keyListPrev(listName, id)) | |
262 | - | let nextOrUnit = getString(this, keyListNext(listName, id)) | |
263 | - | if (if ((id == valueOrElse(headOrUnit, ""))) | |
264 | - | then true | |
265 | - | else (prevOrUnit != unit)) | |
266 | - | then true | |
267 | - | else (nextOrUnit != unit) | |
72 | + | func getValueOrFail (address,key,type) = { | |
73 | + | let error = makeString(["mandatory ", toString(address), ".", key, " is not defined"], "") | |
74 | + | valueOrErrorMessage( match type { | |
75 | + | case str: String => | |
76 | + | getString(address, key) | |
77 | + | case int: Int => | |
78 | + | getInteger(address, key) | |
79 | + | case _ => | |
80 | + | throw("invalid entry type") | |
81 | + | }, error) | |
268 | 82 | } | |
269 | 83 | ||
270 | 84 | ||
271 | - | func insertNodeActions (listName,id) = { | |
272 | - | let headOrUnit = getString(this, keyListHead(listName)) | |
273 | - | let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0) | |
274 | - | let checkNode = if (!(containsNode(listName, id))) | |
275 | - | then true | |
276 | - | else throw("Node exists") | |
277 | - | if ((checkNode == checkNode)) | |
278 | - | then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit)) | |
279 | - | then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)] | |
280 | - | else nil)) ++ [StringEntry(keyListHead(listName), id)]) | |
281 | - | else throw("Strict value is not equal to itself.") | |
85 | + | func getStrOrFail (address,key) = { | |
86 | + | let @ = getValueOrFail(address, key, 0) | |
87 | + | if ($isInstanceOf(@, "String")) | |
88 | + | then @ | |
89 | + | else throw("Couldn't cast Int|String to String") | |
282 | 90 | } | |
283 | 91 | ||
284 | 92 | ||
285 | - | func deleteNodeActions (listName,id) = { | |
286 | - | let headOrUnit = getString(this, keyListHead(listName)) | |
287 | - | let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0) | |
288 | - | let prevOrUnit = getString(this, keyListPrev(listName, id)) | |
289 | - | let nextOrUnit = getString(this, keyListNext(listName, id)) | |
290 | - | ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit)) | |
291 | - | then (nextOrUnit != unit) | |
292 | - | else false) | |
293 | - | then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))] | |
294 | - | else if ((nextOrUnit != unit)) | |
295 | - | then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))] | |
296 | - | else if ((prevOrUnit != unit)) | |
297 | - | then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))] | |
298 | - | else if ((id == valueOrElse(headOrUnit, ""))) | |
299 | - | then [DeleteEntry(keyListHead(listName))] | |
300 | - | else throw(((("invalid node: " + listName) + ".") + id)))) | |
93 | + | func getStrOrUnit (address,key) = { | |
94 | + | let @ = getValueOrFail(address, key, 0) | |
95 | + | if ($isInstanceOf(@, "String")) | |
96 | + | then @ | |
97 | + | else unit | |
301 | 98 | } | |
302 | 99 | ||
303 | 100 | ||
304 | - | func calcWxPerLpIntegralUserLast (stakedByUser,wxPerLpIntegralUserLastUpdHeightOrZero,wxPerLpIntegralNew,wxPerLpIntegralUserLastKEY) = if (if ((wxPerLpIntegralUserLastUpdHeightOrZero == zeroBigInt)) | |
305 | - | then (stakedByUser > zeroBigInt) | |
306 | - | else false) | |
307 | - | then zeroBigInt | |
308 | - | else if ((stakedByUser == zeroBigInt)) | |
309 | - | then wxPerLpIntegralNew | |
310 | - | else if (if ((wxPerLpIntegralUserLastUpdHeightOrZero > zeroBigInt)) | |
311 | - | then (stakedByUser > zeroBigInt) | |
312 | - | else false) | |
313 | - | then value(parseBigInt(getStringOrFail(this, wxPerLpIntegralUserLastKEY))) | |
314 | - | else throw("calcWxPerLpIntegralUserLast: unexpected state") | |
315 | - | ||
316 | - | ||
317 | - | func refreshPoolINTEGRALS (lpAssetIdStr,poolAddressStr,lpDeltaAmount) = { | |
318 | - | let stakedTotalKEY = keyStakedTotal(lpAssetIdStr) | |
319 | - | let stakedTotal = toBigInt(readStaked(stakedTotalKEY)) | |
320 | - | let nonZeroStakedTotal = if ((stakedTotal == zeroBigInt)) | |
321 | - | then oneBigInt | |
322 | - | else stakedTotal | |
323 | - | let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr)) | |
324 | - | let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock()) | |
325 | - | let MULT3 = 1000 | |
326 | - | let wxEmissionPerBlockX3 = (getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) * MULT3) | |
327 | - | let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * 3)) | |
328 | - | let wxPerLpIntegralKEY = keyWxPerLpIntegral(lpAssetIdStr) | |
329 | - | let wxPerLpIntegralLastUpdHeightKEY = keyWxPerLpIntegralLastUpdHeight(lpAssetIdStr) | |
330 | - | let wxPerLpKEY = keyWxPerLp(lpAssetIdStr) | |
331 | - | let wxPerLpIntegralLastUpdHeight = getIntOrDefault(this, wxPerLpIntegralLastUpdHeightKEY, emissionStartBlock) | |
332 | - | let wxPerLpIntegral = getBigIntFromStringOrZero(this, wxPerLpIntegralKEY) | |
333 | - | let wxPerLpOrZeroX3 = 0 | |
334 | - | let dh = max([(height - wxPerLpIntegralLastUpdHeight), 0]) | |
335 | - | let wxPerLpX3 = if ((wxPerLpOrZeroX3 != 0)) | |
336 | - | then toBigInt(wxPerLpOrZeroX3) | |
337 | - | else fraction(toBigInt(poolWxEmissionPerBlockX3), toBigInt(MULT8), nonZeroStakedTotal) | |
338 | - | let stakedTotalNew = (stakedTotal + toBigInt(lpDeltaAmount)) | |
339 | - | let nonZeroStakedTotalNew = if ((stakedTotalNew == zeroBigInt)) | |
340 | - | then oneBigInt | |
341 | - | else stakedTotalNew | |
342 | - | let wxPerLpIntegralNew = (wxPerLpIntegral + (wxPerLpX3 * toBigInt(dh))) | |
343 | - | let wxPerLpX3New = (toBigInt(poolWxEmissionPerBlockX3) / nonZeroStakedTotalNew) | |
344 | - | let wxPerLpIntegralLastUpdHeightNew = height | |
345 | - | let debug = makeString([toString(wxPerLpIntegralNew), toString(dh), toString(wxPerLpX3), toString(stakedTotal), toString(poolWxEmissionPerBlockX3), toString(wxEmissionPerBlockX3), toString(poolWeight)], "::") | |
346 | - | $Tuple3(wxPerLpIntegralNew, [StringEntry(wxPerLpIntegralKEY, toString(wxPerLpIntegralNew)), IntegerEntry(wxPerLpIntegralLastUpdHeightKEY, wxPerLpIntegralLastUpdHeightNew), StringEntry(wxPerLpKEY, toString(wxPerLpX3New))], debug) | |
101 | + | func getIntOrFail (address,key) = { | |
102 | + | let @ = getValueOrFail(address, key, 0) | |
103 | + | if ($isInstanceOf(@, "Int")) | |
104 | + | then @ | |
105 | + | else throw("Couldn't cast Int|String to Int") | |
347 | 106 | } | |
348 | 107 | ||
349 | 108 | ||
350 | - | func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = { | |
351 | - | let $t01424614368 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount) | |
352 | - | let wxPerLpIntegralNew = $t01424614368._1 | |
353 | - | let poolIntegralSTATE = $t01424614368._2 | |
354 | - | let poolDEBUG = $t01424614368._3 | |
355 | - | let MULT3 = 1000 | |
356 | - | let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr) | |
357 | - | let stakedByUser = readStaked(stakedByUserKEY) | |
358 | - | let wxToClaimUserKEY = keyWxToClaimUser(lpAssetIdStr, userAddressStr) | |
359 | - | let wxPerLpIntegralUserLastUpdHeightKEY = keyWxPerLpIntegralUserLastUpdHeight(lpAssetIdStr, userAddressStr) | |
360 | - | let wxPerLpIntegralUserLastKEY = keyWxPerLpIntegralUserLast(lpAssetIdStr, userAddressStr) | |
361 | - | let wxToClaimUser = getBigIntFromStringOrZero(this, wxToClaimUserKEY) | |
362 | - | let wxPerLpIntegralUserLastUpdHeightOrZero = getIntOrZero(this, wxPerLpIntegralUserLastUpdHeightKEY) | |
363 | - | let wxPerLpIntegralUserLast = calcWxPerLpIntegralUserLast(toBigInt(stakedByUser), toBigInt(wxPerLpIntegralUserLastUpdHeightOrZero), wxPerLpIntegralNew, wxPerLpIntegralUserLastKEY) | |
364 | - | let MULT11 = (MULT8 * MULT3) | |
365 | - | let wxToClaimUserNew = max([(wxToClaimUser + fraction((wxPerLpIntegralNew - wxPerLpIntegralUserLast), toBigInt(stakedByUser), toBigInt(MULT11))), zeroBigInt]) | |
366 | - | let wxPerLpIntegralUserLastNew = wxPerLpIntegralNew | |
367 | - | let wxPerLpIntegralUserLastUpdHeightNew = height | |
368 | - | let debug = makeString([toString(wxToClaimUser), toString(wxPerLpIntegralUserLast), toString(stakedByUser), poolDEBUG, toString(height)], "::") | |
369 | - | $Tuple3(wxToClaimUserNew, (poolIntegralSTATE ++ [StringEntry(wxToClaimUserKEY, toString(wxToClaimUserNew)), IntegerEntry(wxPerLpIntegralUserLastUpdHeightKEY, wxPerLpIntegralUserLastUpdHeightNew), StringEntry(wxPerLpIntegralUserLastKEY, toString(wxPerLpIntegralUserLastNew))]), debug) | |
109 | + | func getIntOrUnit (address,key) = { | |
110 | + | let @ = getValueOrFail(address, key, 0) | |
111 | + | if ($isInstanceOf(@, "Int")) | |
112 | + | then @ | |
113 | + | else unit | |
370 | 114 | } | |
115 | + | ||
116 | + | ||
117 | + | func isVerified (assetId) = (valueOrElse(getInteger(keyStatus(assetId)), statusUnverified) == statusVerified) | |
118 | + | ||
119 | + | ||
120 | + | func getLabels () = match getString(keyLabels()) { | |
121 | + | case s: String => | |
122 | + | if ((size(s) == 0)) | |
123 | + | then nil | |
124 | + | else split(s, SEP) | |
125 | + | case _ => | |
126 | + | nil | |
127 | + | } | |
128 | + | ||
129 | + | ||
130 | + | func getAssetLabels (assetId) = match getString(keyAssetLabels(assetId)) { | |
131 | + | case s: String => | |
132 | + | if ((size(s) == 0)) | |
133 | + | then nil | |
134 | + | else split(s, SEP) | |
135 | + | case _ => | |
136 | + | nil | |
137 | + | } | |
371 | 138 | ||
372 | 139 | ||
373 | 140 | func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) { | |
390 | 157 | } | |
391 | 158 | ||
392 | 159 | ||
393 | - | let permissionDeniedError = throw("Permission denied") | |
394 | - | ||
395 | - | func mustThis (i) = if ((i.caller == this)) | |
396 | - | then true | |
397 | - | else permissionDeniedError | |
398 | - | ||
399 | - | ||
400 | 160 | func mustManager (i) = match managerPublicKeyOrUnit() { | |
401 | 161 | case pk: ByteVector => | |
402 | 162 | if ((i.callerPublicKey == pk)) | |
403 | 163 | then true | |
404 | - | else | |
164 | + | else throwPD() | |
405 | 165 | case _: Unit => | |
406 | 166 | if ((i.caller == this)) | |
407 | 167 | then true | |
408 | - | else | |
168 | + | else throwPD() | |
409 | 169 | case _ => | |
410 | 170 | throw("Match error") | |
411 | 171 | } | |
412 | 172 | ||
413 | 173 | ||
174 | + | func mustAdmin (i) = { | |
175 | + | let adminPKs = split(valueOrElse(getString(keyAdminPubKeys()), EMPTY), SEP) | |
176 | + | if (containsElement(adminPKs, toBase58String(i.callerPublicKey))) | |
177 | + | then true | |
178 | + | else { | |
179 | + | let isManager = mustManager(i) | |
180 | + | if ((isManager == isManager)) | |
181 | + | then true | |
182 | + | else throw("Strict value is not equal to itself.") | |
183 | + | } | |
184 | + | } | |
185 | + | ||
186 | + | ||
187 | + | func isCreated (assetId) = valueOrElse(getBoolean(keyCreated(assetId)), false) | |
188 | + | ||
189 | + | ||
190 | + | func verifiedToStatus (verified) = if (verified) | |
191 | + | then statusVerified | |
192 | + | else statusUnverified | |
193 | + | ||
194 | + | ||
195 | + | func addLabelActions (assetId,label,throwOnError) = { | |
196 | + | let labels = getLabels() | |
197 | + | let assetLabels = getAssetLabels(assetId) | |
198 | + | let checkLabel = if (containsElement(labels, label)) | |
199 | + | then true | |
200 | + | else throw("Label doesn't exist") | |
201 | + | if ((checkLabel == checkLabel)) | |
202 | + | then { | |
203 | + | let newAssetLabels = if (containsElement(assetLabels, label)) | |
204 | + | then if (throwOnError) | |
205 | + | then throw("Label has already been added") | |
206 | + | else assetLabels | |
207 | + | else (assetLabels :+ label) | |
208 | + | [StringEntry(keyAssetLabels(assetId), makeString(newAssetLabels, SEP))] | |
209 | + | } | |
210 | + | else throw("Strict value is not equal to itself.") | |
211 | + | } | |
212 | + | ||
213 | + | ||
214 | + | func deleteLabelActions (assetId,label,throwOnError) = { | |
215 | + | let assetLabels = getAssetLabels(assetId) | |
216 | + | let newAssetLabels = if (containsElement(assetLabels, label)) | |
217 | + | then removeByIndex(assetLabels, value(indexOf(assetLabels, label))) | |
218 | + | else if (throwOnError) | |
219 | + | then throw("Label wasn't added") | |
220 | + | else assetLabels | |
221 | + | [StringEntry(keyAssetLabels(assetId), makeString(newAssetLabels, SEP))] | |
222 | + | } | |
223 | + | ||
224 | + | ||
225 | + | func setVerifiedActions (assetId,verified) = { | |
226 | + | let labelCommunityVerifiedActions = if (verified) | |
227 | + | then addLabelActions(assetId, labelCommunityVerified, false) | |
228 | + | else deleteLabelActions(assetId, labelCommunityVerified, false) | |
229 | + | ([IntegerEntry(keyStatus(assetId), verifiedToStatus(verified))] ++ labelCommunityVerifiedActions) | |
230 | + | } | |
231 | + | ||
232 | + | ||
233 | + | func updateTickerActions (assetId,ticker) = { | |
234 | + | let checkTicker = { | |
235 | + | let linkedAssetIdOrUnit = getString(keyTickerToAssetId(ticker)) | |
236 | + | let tickerIsValid = if ((ticker != "")) | |
237 | + | then if ((linkedAssetIdOrUnit == unit)) | |
238 | + | then true | |
239 | + | else (value(linkedAssetIdOrUnit) == assetId) | |
240 | + | else false | |
241 | + | if (tickerIsValid) | |
242 | + | then true | |
243 | + | else throw("Invalid ticker") | |
244 | + | } | |
245 | + | if ((checkTicker == checkTicker)) | |
246 | + | then [StringEntry(keyAssetIdToTicker(assetId), ticker), StringEntry(keyTickerToAssetId(ticker), assetId)] | |
247 | + | else throw("Strict value is not equal to itself.") | |
248 | + | } | |
249 | + | ||
250 | + | ||
414 | 251 | @Callable(i) | |
415 | - | func constructor ( | |
252 | + | func constructor (userPoolsContract,labels) = { | |
416 | 253 | let checkCaller = mustManager(i) | |
417 | 254 | if ((checkCaller == checkCaller)) | |
418 | - | then [StringEntry(keyFactoryAddress(), factoryAddressStr)] | |
255 | + | then { | |
256 | + | let checksAddress = valueOrErrorMessage(addressFromString(userPoolsContract), "Invalid address") | |
257 | + | if ((checksAddress == checksAddress)) | |
258 | + | then [StringEntry(keyUserPoolsContract(), userPoolsContract), StringEntry(keyLabels(), makeString((defaultLabels ++ labels), SEP))] | |
259 | + | else throw("Strict value is not equal to itself.") | |
260 | + | } | |
419 | 261 | else throw("Strict value is not equal to itself.") | |
420 | 262 | } | |
421 | 263 | ||
423 | 265 | ||
424 | 266 | @Callable(i) | |
425 | 267 | func constructorV2 (votingEmissionContract) = { | |
426 | - | let cheks = [mustManager(i), if ((addressFromString(votingEmissionContract) != unit)) | |
268 | + | let checkCaller = mustManager(i) | |
269 | + | if ((checkCaller == checkCaller)) | |
270 | + | then { | |
271 | + | let checkAddress = valueOrErrorMessage(addressFromString(votingEmissionContract), "invalid voting emission contract address") | |
272 | + | if ((checkAddress == checkAddress)) | |
273 | + | then [StringEntry(keyVotingEmissionContract(), votingEmissionContract)] | |
274 | + | else throw("Strict value is not equal to itself.") | |
275 | + | } | |
276 | + | else throw("Strict value is not equal to itself.") | |
277 | + | } | |
278 | + | ||
279 | + | ||
280 | + | ||
281 | + | @Callable(i) | |
282 | + | func addAssetsLink (amountAsset,priceAsset,lpAsset) = { | |
283 | + | let checkCaller = mustAdmin(i) | |
284 | + | if ((checkCaller == checkCaller)) | |
285 | + | then [StringEntry(keyAmountAndPriceAssetsToLpAsset(amountAsset, priceAsset), lpAsset), StringEntry(keyLpAssetToAmountAndPriceAssets(lpAsset), makeString([amountAsset, priceAsset], SEP))] | |
286 | + | else throw("Strict value is not equal to itself.") | |
287 | + | } | |
288 | + | ||
289 | + | ||
290 | + | ||
291 | + | @Callable(i) | |
292 | + | func increaseAssetPoolsNumber (assetId) = { | |
293 | + | let checkCaller = mustAdmin(i) | |
294 | + | if ((checkCaller == checkCaller)) | |
295 | + | then { | |
296 | + | let assetPoolsNumberKey = keyAssetPoolsNumber(assetId) | |
297 | + | let assetPoolsNumber = valueOrElse(getInteger(assetPoolsNumberKey), 0) | |
298 | + | [IntegerEntry(assetPoolsNumberKey, (assetPoolsNumber + 1))] | |
299 | + | } | |
300 | + | else throw("Strict value is not equal to itself.") | |
301 | + | } | |
302 | + | ||
303 | + | ||
304 | + | ||
305 | + | @Callable(i) | |
306 | + | func createLabel (label) = { | |
307 | + | let labels = getLabels() | |
308 | + | let checkCaller = mustAdmin(i) | |
309 | + | if ((checkCaller == checkCaller)) | |
310 | + | then { | |
311 | + | let checkLabel = [if (!(contains(label, SEP))) | |
312 | + | then true | |
313 | + | else throw("Invalid label name"), if (!(containsElement(labels, label))) | |
314 | + | then true | |
315 | + | else throw("Label exists")] | |
316 | + | if ((checkLabel == checkLabel)) | |
317 | + | then [StringEntry(keyLabels(), makeString((labels :+ label), SEP))] | |
318 | + | else throw("Strict value is not equal to itself.") | |
319 | + | } | |
320 | + | else throw("Strict value is not equal to itself.") | |
321 | + | } | |
322 | + | ||
323 | + | ||
324 | + | ||
325 | + | @Callable(i) | |
326 | + | func dropLabel (label) = { | |
327 | + | let labels = getLabels() | |
328 | + | let checkCaller = mustManager(i) | |
329 | + | if ((checkCaller == checkCaller)) | |
330 | + | then { | |
331 | + | let checkLabel = if (containsElement(labels, label)) | |
332 | + | then true | |
333 | + | else throw("Label doesn't exist") | |
334 | + | if ((checkLabel == checkLabel)) | |
335 | + | then [StringEntry(keyLabels(), makeString(removeByIndex(labels, value(indexOf(labels, label))), SEP))] | |
336 | + | else throw("Strict value is not equal to itself.") | |
337 | + | } | |
338 | + | else throw("Strict value is not equal to itself.") | |
339 | + | } | |
340 | + | ||
341 | + | ||
342 | + | ||
343 | + | @Callable(i) | |
344 | + | func addLabel (assetId,label) = { | |
345 | + | let checkCaller = mustAdmin(i) | |
346 | + | if ((checkCaller == checkCaller)) | |
347 | + | then addLabelActions(assetId, label, true) | |
348 | + | else throw("Strict value is not equal to itself.") | |
349 | + | } | |
350 | + | ||
351 | + | ||
352 | + | ||
353 | + | @Callable(i) | |
354 | + | func deleteLabel (assetId,label) = { | |
355 | + | let checkCaller = mustAdmin(i) | |
356 | + | if ((checkCaller == checkCaller)) | |
357 | + | then deleteLabelActions(assetId, label, true) | |
358 | + | else throw("Strict value is not equal to itself.") | |
359 | + | } | |
360 | + | ||
361 | + | ||
362 | + | ||
363 | + | @Callable(i) | |
364 | + | func updateTicker (assetId,ticker) = { | |
365 | + | let checkCaller = mustAdmin(i) | |
366 | + | if ((checkCaller == checkCaller)) | |
367 | + | then { | |
368 | + | let checkAsset = if (isCreated(assetId)) | |
369 | + | then true | |
370 | + | else throwNoAsset() | |
371 | + | if ((checkAsset == checkAsset)) | |
372 | + | then updateTickerActions(assetId, ticker) | |
373 | + | else throw("Strict value is not equal to itself.") | |
374 | + | } | |
375 | + | else throw("Strict value is not equal to itself.") | |
376 | + | } | |
377 | + | ||
378 | + | ||
379 | + | ||
380 | + | @Callable(i) | |
381 | + | func deleteTicker (assetId) = { | |
382 | + | let checkCaller = mustAdmin(i) | |
383 | + | if ((checkCaller == checkCaller)) | |
384 | + | then { | |
385 | + | let ticker = valueOrErrorMessage(getString(keyAssetIdToTicker(assetId)), "Invalid asset") | |
386 | + | [DeleteEntry(keyAssetIdToTicker(assetId)), DeleteEntry(keyTickerToAssetId(ticker))] | |
387 | + | } | |
388 | + | else throw("Strict value is not equal to itself.") | |
389 | + | } | |
390 | + | ||
391 | + | ||
392 | + | ||
393 | + | @Callable(i) | |
394 | + | func createOrUpdate (assetId,logo,verified) = { | |
395 | + | let checkCaller = mustAdmin(i) | |
396 | + | if ((checkCaller == checkCaller)) | |
397 | + | then { | |
398 | + | let isCreatedNow = !(isCreated(assetId)) | |
399 | + | if ((isCreatedNow == isCreatedNow)) | |
400 | + | then { | |
401 | + | let setLogoActions = if ((logo == "")) | |
402 | + | then nil | |
403 | + | else [StringEntry(keyLogo(assetId), logo)] | |
404 | + | $Tuple2((([BooleanEntry(keyCreated(assetId), true)] ++ setLogoActions) ++ setVerifiedActions(assetId, verified)), isCreatedNow) | |
405 | + | } | |
406 | + | else throw("Strict value is not equal to itself.") | |
407 | + | } | |
408 | + | else throw("Strict value is not equal to itself.") | |
409 | + | } | |
410 | + | ||
411 | + | ||
412 | + | ||
413 | + | @Callable(i) | |
414 | + | func setLogo (assetId,logo) = { | |
415 | + | let checks = [mustAdmin(i), if (isCreated(assetId)) | |
427 | 416 | then true | |
428 | - | else "invalid voting emission contract address"] | |
429 | - | if ((cheks == cheks)) | |
430 | - | then [StringEntry(keyVotingEmissionContract(), votingEmissionContract)] | |
417 | + | else throwNoAsset()] | |
418 | + | if ((checks == checks)) | |
419 | + | then { | |
420 | + | let action = if ((logo == "")) | |
421 | + | then DeleteEntry(keyLogo(assetId)) | |
422 | + | else StringEntry(keyLogo(assetId), logo) | |
423 | + | [action] | |
424 | + | } | |
425 | + | else throw("Strict value is not equal to itself.") | |
426 | + | } | |
427 | + | ||
428 | + | ||
429 | + | ||
430 | + | @Callable(i) | |
431 | + | func setVerified (assetId,verified) = { | |
432 | + | let checks = [mustAdmin(i), if (isCreated(assetId)) | |
433 | + | then true | |
434 | + | else throwNoAsset()] | |
435 | + | if ((checks == checks)) | |
436 | + | then { | |
437 | + | let onVerificationLossInv = if (!(verified)) | |
438 | + | then { | |
439 | + | let votingEmissionContract = valueOrErrorMessage(addressFromString(getStrOrFail(this, keyVotingEmissionContract())), "invalid voting emission contract address") | |
440 | + | invoke(votingEmissionContract, "onVerificationLoss", [assetId], nil) | |
441 | + | } | |
442 | + | else unit | |
443 | + | if ((onVerificationLossInv == onVerificationLossInv)) | |
444 | + | then $Tuple2(setVerifiedActions(assetId, verified), unit) | |
445 | + | else throw("Strict value is not equal to itself.") | |
446 | + | } | |
447 | + | else throw("Strict value is not equal to itself.") | |
448 | + | } | |
449 | + | ||
450 | + | ||
451 | + | ||
452 | + | @Callable(i) | |
453 | + | func onEliminate (assetId) = { | |
454 | + | let poolsNumber = valueOrElse(getInteger(keyAssetPoolsNumber(assetId)), 0) | |
455 | + | let actions = if ((poolsNumber > 0)) | |
456 | + | then nil | |
457 | + | else [DeleteEntry(keyLogo(assetId))] | |
458 | + | $Tuple2(actions, unit) | |
459 | + | } | |
460 | + | ||
461 | + | ||
462 | + | ||
463 | + | @Callable(i) | |
464 | + | func setAdmins (adminPubKeys) = { | |
465 | + | let checkCaller = mustManager(i) | |
466 | + | if ((checkCaller == checkCaller)) | |
467 | + | then [StringEntry(keyAdminPubKeys(), makeString(adminPubKeys, SEP))] | |
431 | 468 | else throw("Strict value is not equal to itself.") | |
432 | 469 | } | |
433 | 470 | ||
469 | 506 | ||
470 | 507 | ||
471 | 508 | @Callable(i) | |
472 | - | func stake () = { | |
473 | - | let migration = if ((getBinary(this, keyMigrator) != unit)) | |
474 | - | then throw("maintenance") | |
475 | - | else unit | |
476 | - | if ((migration == migration)) | |
477 | - | then if ((size(i.payments) != 1)) | |
478 | - | then throw("invalid payment - exact one payment must be attached") | |
479 | - | else { | |
480 | - | let pmt = i.payments[0] | |
481 | - | let lpAssetId = value(pmt.assetId) | |
482 | - | let lpAssetIdStr = toBase58String(lpAssetId) | |
483 | - | let amount = pmt.amount | |
484 | - | let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr)) | |
485 | - | let callerStr = toString(i.caller) | |
486 | - | let userAddressStr = if ((callerStr == poolAddressStr)) | |
487 | - | then toString(i.originCaller) | |
488 | - | else callerStr | |
489 | - | let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr) | |
490 | - | let stakedTotalKEY = keyStakedTotal(lpAssetIdStr) | |
491 | - | let stakedByUser = readStaked(stakedByUserKEY) | |
492 | - | let stakedTotal = readStaked(stakedTotalKEY) | |
493 | - | let $t01893619053 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount) | |
494 | - | let wxToClaimUserNew = $t01893619053._1 | |
495 | - | let integralSTATE = $t01893619053._2 | |
496 | - | let debug = $t01893619053._3 | |
497 | - | let listName = getUsersListName(lpAssetIdStr) | |
498 | - | let listActions = if (containsNode(listName, userAddressStr)) | |
499 | - | then nil | |
500 | - | else insertNodeActions(listName, userAddressStr) | |
501 | - | (([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions) | |
502 | - | } | |
503 | - | else throw("Strict value is not equal to itself.") | |
504 | - | } | |
505 | - | ||
506 | - | ||
507 | - | ||
508 | - | @Callable(i) | |
509 | - | func unstake (lpAssetIdStr,amount) = { | |
510 | - | let migration = if ((getBinary(this, keyMigrator) != unit)) | |
511 | - | then throw("maintenance") | |
512 | - | else unit | |
513 | - | if ((migration == migration)) | |
514 | - | then { | |
515 | - | let lpAssetId = fromBase58String(lpAssetIdStr) | |
516 | - | let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr)) | |
517 | - | let poolAddon = valueOrElse(getString(this, keyStablePoolAddonAddr()), poolAddressStr) | |
518 | - | let callerStr = toString(i.caller) | |
519 | - | let userAddressStr = if (if ((callerStr == poolAddressStr)) | |
520 | - | then true | |
521 | - | else (callerStr == poolAddon)) | |
522 | - | then toString(i.originCaller) | |
523 | - | else callerStr | |
524 | - | let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr) | |
525 | - | let stakedTotalKEY = keyStakedTotal(lpAssetIdStr) | |
526 | - | let stakedByUser = readStaked(stakedByUserKEY) | |
527 | - | let stakedTotal = readStaked(stakedTotalKEY) | |
528 | - | let integralSTATE = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))._2 | |
529 | - | let listName = getUsersListName(lpAssetIdStr) | |
530 | - | let listActions = if (if (containsNode(listName, userAddressStr)) | |
531 | - | then (amount == stakedByUser) | |
532 | - | else false) | |
533 | - | then deleteNodeActions(listName, userAddressStr) | |
534 | - | else nil | |
535 | - | let claimedByUser = getBigIntFromStringOrZero(this, keyClaimedByUser(lpAssetIdStr, userAddressStr)) | |
536 | - | let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr)) | |
537 | - | let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddress, 0)._1 | |
538 | - | let availableToClaim = (wxToClaimUserNew - claimedByUser) | |
539 | - | let r = if ((availableToClaim > zeroBigInt)) | |
540 | - | then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil) | |
541 | - | else unit | |
542 | - | if ((r == r)) | |
543 | - | then if ((amount > stakedByUser)) | |
544 | - | then throw("passed amount is less then available") | |
545 | - | else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions) | |
546 | - | else throw("Strict value is not equal to itself.") | |
547 | - | } | |
548 | - | else throw("Strict value is not equal to itself.") | |
549 | - | } | |
550 | - | ||
551 | - | ||
552 | - | ||
553 | - | @Callable(i) | |
554 | - | func claimWx (lpAssetIdStr) = { | |
555 | - | let userAddressStr = toString(i.caller) | |
556 | - | let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil) | |
557 | - | $Tuple2(nil, result) | |
558 | - | } | |
559 | - | ||
560 | - | ||
561 | - | ||
562 | - | @Callable(i) | |
563 | - | func claimWxINTERNAL (lpAssetIdStr,userAddressStr) = { | |
564 | - | let checkCaller = mustThis(i) | |
565 | - | if ((checkCaller == checkCaller)) | |
566 | - | then { | |
567 | - | let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), "claimWxINTERNAL: invalid user address") | |
568 | - | let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr)) | |
569 | - | let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr) | |
570 | - | let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr) | |
571 | - | let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr) | |
572 | - | let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr) | |
573 | - | let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY) | |
574 | - | let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY) | |
575 | - | let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY) | |
576 | - | let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY) | |
577 | - | let $t02288422996 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0) | |
578 | - | let wxToClaimUserNew = $t02288422996._1 | |
579 | - | let integralSTATE = $t02288422996._2 | |
580 | - | let debug = $t02288422996._3 | |
581 | - | let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt]) | |
582 | - | if ((zeroBigInt >= availableToClaim)) | |
583 | - | then throw("nothing to claim") | |
584 | - | else { | |
585 | - | let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0]) | |
586 | - | let minRewardPart = availableToClaim | |
587 | - | let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)]) | |
588 | - | let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0]) | |
589 | - | let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil)) | |
590 | - | if ((emitBoost == emitBoost)) | |
591 | - | then { | |
592 | - | let claimedByUserValue = (claimedByUser + availableToClaim) | |
593 | - | let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart) | |
594 | - | let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserMinReward + minRewardPart) | |
595 | - | let claimedTotalPlusAvailableToClaim = (claimedByUserMinReward + minRewardPart) | |
596 | - | [StringEntry(claimedByUserKEY, toString(claimedByUserValue)), StringEntry(claimedByUserMinRewardKEY, toString(claimedByUserMinRewardPlusPart)), StringEntry(claimedByUserBoostRewardKEY, toString(claimedByUserBoostRewardPlusBoostRewardPart)), StringEntry(claimedTotalKEY, toString(claimedTotalPlusAvailableToClaim)), ScriptTransfer(userAddress, toInt(minRewardPart), wxAssetId), ScriptTransfer(userAddress, toInt(boostRewardPart), wxAssetId), OperationHistoryEntry("claim", userAddressStr, lpAssetIdStr, toInt(availableToClaim), i.transactionId)] | |
597 | - | } | |
598 | - | else throw("Strict value is not equal to itself.") | |
599 | - | } | |
600 | - | } | |
601 | - | else throw("Strict value is not equal to itself.") | |
602 | - | } | |
603 | - | ||
604 | - | ||
605 | - | ||
606 | - | @Callable(i) | |
607 | - | func claimWxREADONLY (lpAssetIdStr,userAddressStr) = { | |
608 | - | let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr) | |
609 | - | let stakedTotalKEY = keyStakedTotal(lpAssetIdStr) | |
610 | - | let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr) | |
611 | - | let stakedByUser = readStaked(stakedByUserKEY) | |
612 | - | let stakedTotal = readStaked(stakedTotalKEY) | |
613 | - | let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY) | |
614 | - | let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr)) | |
615 | - | let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr)) | |
616 | - | let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) | |
617 | - | let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock()) | |
618 | - | let passedBlocks = if ((emissionStartBlock > height)) | |
619 | - | then 0 | |
620 | - | else (height - emissionStartBlock) | |
621 | - | let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT) | |
622 | - | let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal) | |
623 | - | let $t02563825750 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0) | |
624 | - | let wxToClaimUserNew = $t02563825750._1 | |
625 | - | let integralSTATE = $t02563825750._2 | |
626 | - | let debug = $t02563825750._3 | |
627 | - | let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt]) | |
628 | - | let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil)) | |
629 | - | let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0]) | |
630 | - | let boostDebug = asString(boostInvResult[1]) | |
631 | - | let minRewardPart = availableToClaim | |
632 | - | let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)]) | |
633 | - | let totalReward = (minRewardPart + boostRewardPart) | |
634 | - | $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), ((((debug + "::") + toString(userWxReward)) + "::BOOST::") + boostDebug)], SEP)) | |
635 | - | } | |
636 | - | ||
637 | - | ||
638 | - | ||
639 | - | @Callable(i) | |
640 | - | func usersListTraversal (lpAssetId) = { | |
641 | - | let checkCaller = if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionContract()), ""))) | |
642 | - | then true | |
643 | - | else mustManager(i) | |
644 | - | if ((checkCaller == checkCaller)) | |
645 | - | then { | |
646 | - | let listName = getUsersListName(lpAssetId) | |
647 | - | let userOrUnit = getString(keyNextUser(lpAssetId)) | |
648 | - | let headOrUnit = getString(keyListHead(listName)) | |
649 | - | match userOrUnit { | |
650 | - | case _: Unit => | |
651 | - | match headOrUnit { | |
652 | - | case _: Unit => | |
653 | - | $Tuple2(nil, false) | |
654 | - | case head: String => | |
655 | - | $Tuple2([StringEntry(keyNextUser(lpAssetId), head)], true) | |
656 | - | case _ => | |
657 | - | throw("Match error") | |
658 | - | } | |
659 | - | case userAddress: String => | |
660 | - | let claimedByUser = getBigIntFromStringOrZero(this, keyClaimedByUser(lpAssetId, userAddress)) | |
661 | - | let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetId)) | |
662 | - | let wxToClaimUserNew = refreshINTEGRALS(lpAssetId, userAddress, poolAddress, 0)._1 | |
663 | - | let availableToClaim = (wxToClaimUserNew - claimedByUser) | |
664 | - | let r = if ((availableToClaim > zeroBigInt)) | |
665 | - | then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress], nil) | |
666 | - | else unit | |
667 | - | if ((r == r)) | |
668 | - | then { | |
669 | - | let nextUserOrUnit = getString(keyListNext(listName, userAddress)) | |
670 | - | match nextUserOrUnit { | |
671 | - | case _: Unit => | |
672 | - | $Tuple2([DeleteEntry(keyNextUser(lpAssetId))], false) | |
673 | - | case nextUser: String => | |
674 | - | $Tuple2([StringEntry(keyNextUser(lpAssetId), nextUser)], true) | |
675 | - | case _ => | |
676 | - | throw("Match error") | |
677 | - | } | |
678 | - | } | |
679 | - | else throw("Strict value is not equal to itself.") | |
680 | - | case _ => | |
681 | - | throw("Match error") | |
682 | - | } | |
683 | - | } | |
684 | - | else throw("Strict value is not equal to itself.") | |
685 | - | } | |
686 | - | ||
687 | - | ||
688 | - | ||
689 | - | @Callable(i) | |
690 | - | func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract)) | |
691 | - | then throw("permissions denied") | |
692 | - | else { | |
693 | - | let $t02810128211 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0) | |
694 | - | let wxPerLpIntegralNew = $t02810128211._1 | |
695 | - | let poolIntegralSTATE = $t02810128211._2 | |
696 | - | let poolDEBUG = $t02810128211._3 | |
697 | - | poolIntegralSTATE | |
698 | - | } | |
699 | - | ||
700 | - | ||
701 | - | ||
702 | - | @Callable(i) | |
703 | - | func setMigrator (pk) = if ((pk == "")) | |
704 | - | then [DeleteEntry(keyMigrator)] | |
705 | - | else [BinaryEntry(keyMigrator, fromBase58String(pk))] | |
509 | + | func isVerifiedREADONLY (assetId) = $Tuple2(nil, isVerified(assetId)) | |
706 | 510 | ||
707 | 511 | ||
708 | 512 | @Verifier(tx) | |
715 | 519 | case _ => | |
716 | 520 | throw("Match error") | |
717 | 521 | } | |
718 | - | if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)) | |
719 | - | then true | |
720 | - | else sigVerify(tx.bodyBytes, tx.proofs[0], getBinaryValue(this, keyMigrator)) | |
522 | + | sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey) | |
721 | 523 | } | |
722 | 524 |
Old | New | Differences | |
---|---|---|---|
1 | - | {-# STDLIB_VERSION | |
1 | + | {-# STDLIB_VERSION 5 #-} | |
2 | 2 | {-# SCRIPT_TYPE ACCOUNT #-} | |
3 | 3 | {-# CONTENT_TYPE DAPP #-} | |
4 | - | let SCALE8 = 8 | |
5 | - | ||
6 | - | let MULT8 = 100000000 | |
7 | - | ||
8 | - | let SCALE18 = 18 | |
9 | - | ||
10 | - | let MULT18 = toBigInt(1000000000000000000) | |
11 | - | ||
12 | 4 | let SEP = "__" | |
13 | 5 | ||
14 | - | let | |
6 | + | let EMPTY = "" | |
15 | 7 | ||
16 | - | let | |
8 | + | let statusVerified = 2 | |
17 | 9 | ||
18 | - | let | |
10 | + | let statusUnverified = 0 | |
19 | 11 | ||
20 | - | let | |
12 | + | let labelCommunityVerified = "COMMUNITY_VERIFIED" | |
21 | 13 | ||
22 | - | func asAnyList (val) = match val { | |
23 | - | case valAnyLyst: List[Any] => | |
24 | - | valAnyLyst | |
25 | - | case _ => | |
26 | - | throw("fail to cast into List[Any]") | |
27 | - | } | |
14 | + | let labelPoolsLp = "POOLS_LP" | |
15 | + | ||
16 | + | let defaultLabels = [labelCommunityVerified, labelPoolsLp] | |
17 | + | ||
18 | + | func throwPD () = throw("Permission denied") | |
28 | 19 | ||
29 | 20 | ||
30 | - | func asInt (val) = match val { | |
31 | - | case valInt: Int => | |
32 | - | valInt | |
33 | - | case _ => | |
34 | - | throw("fail to cast into Int") | |
35 | - | } | |
36 | - | ||
37 | - | ||
38 | - | func asString (val) = match val { | |
39 | - | case valStr: String => | |
40 | - | valStr | |
41 | - | case _ => | |
42 | - | throw("fail to cast into Int") | |
43 | - | } | |
44 | - | ||
45 | - | ||
46 | - | func asByteVector (val) = match val { | |
47 | - | case valBin: ByteVector => | |
48 | - | valBin | |
49 | - | case _ => | |
50 | - | throw("fail to cast into Int") | |
51 | - | } | |
52 | - | ||
53 | - | ||
54 | - | func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), (("mandatory this." + key) + " is not defined")) | |
55 | - | ||
56 | - | ||
57 | - | func getStringByAddressOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined")) | |
58 | - | ||
59 | - | ||
60 | - | func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0) | |
61 | - | ||
62 | - | ||
63 | - | func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal) | |
64 | - | ||
65 | - | ||
66 | - | func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined")) | |
67 | - | ||
68 | - | ||
69 | - | func getBigIntFromStringOrZero (address,key) = value(parseBigInt(valueOrElse(getString(address, key), "0"))) | |
70 | - | ||
71 | - | ||
72 | - | func getBigIntFromStringOrDefault (address,key,defaultVal) = match getString(address, key) { | |
73 | - | case s: String => | |
74 | - | value(parseBigInt(s)) | |
75 | - | case _: Unit => | |
76 | - | defaultVal | |
77 | - | case _ => | |
78 | - | throw("Match error") | |
79 | - | } | |
80 | - | ||
81 | - | ||
82 | - | func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULT18, toBigInt(origScaleMult)) | |
83 | - | ||
84 | - | ||
85 | - | func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULT18)) | |
86 | - | ||
87 | - | ||
88 | - | func keyFactoryAddress () = "%s%s__config__factoryAddress" | |
89 | - | ||
90 | - | ||
91 | - | func keyVotingEmissionContract () = "%s__votingEmissionContract" | |
92 | - | ||
93 | - | ||
94 | - | let IdxFactoryCfgStakingDapp = 1 | |
95 | - | ||
96 | - | let IdxFactoryCfgBoostingDapp = 2 | |
97 | - | ||
98 | - | let IdxFactoryCfgIdoDapp = 3 | |
99 | - | ||
100 | - | let IdxFactoryCfgTeamDapp = 4 | |
101 | - | ||
102 | - | let IdxFactoryCfgEmissionDapp = 5 | |
103 | - | ||
104 | - | let IdxFactoryCfgRestDapp = 6 | |
105 | - | ||
106 | - | let IdxFactoryCfgSlippageDapp = 7 | |
107 | - | ||
108 | - | func keyFactoryCfg () = "%s__factoryConfig" | |
21 | + | func throwNoAsset () = throw("Asset doesn't exists") | |
109 | 22 | ||
110 | 23 | ||
111 | 24 | func keyManagerPublicKey () = "%s__managerPublicKey" | |
112 | 25 | ||
113 | 26 | ||
114 | 27 | func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey" | |
115 | 28 | ||
116 | 29 | ||
117 | - | func | |
30 | + | func keyAdminPubKeys () = "%s__adminPubKeys" | |
118 | 31 | ||
119 | 32 | ||
120 | - | func | |
33 | + | func keyUserPoolsContract () = "%s__userPoolsContract" | |
121 | 34 | ||
122 | 35 | ||
123 | - | func | |
36 | + | func keyVotingEmissionContract () = "%s__votingEmissionContract" | |
124 | 37 | ||
125 | 38 | ||
126 | - | func | |
39 | + | func keyCreated (assetId) = (("created_<" + assetId) + ">") | |
127 | 40 | ||
128 | 41 | ||
129 | - | func | |
42 | + | func keyLogo (assetId) = (("logo_<" + assetId) + ">") | |
130 | 43 | ||
131 | 44 | ||
132 | - | func | |
45 | + | func keyTicker (assetId) = (("ticker_<" + assetId) + ">") | |
133 | 46 | ||
134 | 47 | ||
135 | - | func | |
48 | + | func keyStatus (assetId) = (("status_<" + assetId) + ">") | |
136 | 49 | ||
137 | 50 | ||
138 | - | func | |
51 | + | func keyAssetPoolsNumber (assetId) = makeString(["%s%s", "pools", assetId], SEP) | |
139 | 52 | ||
140 | 53 | ||
141 | - | func | |
54 | + | func keyTickerToAssetId (ticker) = makeString(["%s%s", "ticker2assetId", ticker], SEP) | |
142 | 55 | ||
143 | 56 | ||
144 | - | func | |
57 | + | func keyAssetIdToTicker (assetId) = makeString(["%s%s", "assetId2ticker", assetId], SEP) | |
145 | 58 | ||
146 | 59 | ||
147 | - | func | |
60 | + | func keyAmountAndPriceAssetsToLpAsset (amountAsset,priceAsset) = makeString(["%s%s%s", "amountAndPriceAssetsToLpAsset", amountAsset, priceAsset], SEP) | |
148 | 61 | ||
149 | 62 | ||
150 | - | func | |
63 | + | func keyLpAssetToAmountAndPriceAssets (lpAsset) = makeString(["%s%s", "lpAssetToAmountAndPriceAssets", lpAsset], SEP) | |
151 | 64 | ||
152 | 65 | ||
153 | - | func | |
66 | + | func keyAssetLabels (assetId) = makeString(["%s%s", "labels", assetId], SEP) | |
154 | 67 | ||
155 | 68 | ||
156 | - | func | |
69 | + | func keyLabels () = makeString(["%s", "labels"], SEP) | |
157 | 70 | ||
158 | 71 | ||
159 | - | func keyEmissionEndBlock () = "%s%s__emission__endBlock" | |
160 | - | ||
161 | - | ||
162 | - | func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s__staked", userAddressStr, lpAssetIdStr], SEP) | |
163 | - | ||
164 | - | ||
165 | - | func keyStakedTotal (lpAssetIdStr) = ("%s%s%s__staked__total__" + lpAssetIdStr) | |
166 | - | ||
167 | - | ||
168 | - | func keyClaimedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimed", userAddressStr, lpAssetIdStr], SEP) | |
169 | - | ||
170 | - | ||
171 | - | func keyClaimedByUserMinReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedMinReward", userAddressStr, lpAssetIdStr], SEP) | |
172 | - | ||
173 | - | ||
174 | - | func keyClaimedByUserBoostReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedBoostReward", userAddressStr, lpAssetIdStr], SEP) | |
175 | - | ||
176 | - | ||
177 | - | func keyClaimedTotal (lpAssetIdStr) = makeString(["%s%s%s__claimed__total", lpAssetIdStr], SEP) | |
178 | - | ||
179 | - | ||
180 | - | func readStaked (key) = valueOrElse(getInteger(this, key), 0) | |
181 | - | ||
182 | - | ||
183 | - | func keyLastTotalLpBalance (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "bal"], SEP) | |
184 | - | ||
185 | - | ||
186 | - | func keyLastUserLpBalance (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "bal"], SEP) | |
187 | - | ||
188 | - | ||
189 | - | func keyTotalLpBalanceIntegral (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "balINT"], SEP) | |
190 | - | ||
191 | - | ||
192 | - | func keyUserLpBalanceIntegral (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "balINT"], SEP) | |
193 | - | ||
194 | - | ||
195 | - | func keyTotalLpBalanceIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "lastUpd"], SEP) | |
196 | - | ||
197 | - | ||
198 | - | func keyUserLpBalanceIntegralLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "lastUpd"], SEP) | |
199 | - | ||
200 | - | ||
201 | - | func keyWxPerLpIntegral (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpInt"], SEP) | |
202 | - | ||
203 | - | ||
204 | - | func keyWxPerLpIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpIntH"], SEP) | |
205 | - | ||
206 | - | ||
207 | - | func keyWxToClaimUser (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpInt"], SEP) | |
208 | - | ||
209 | - | ||
210 | - | func keyWxPerLpIntegralUserLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpIntH"], SEP) | |
211 | - | ||
212 | - | ||
213 | - | func keyWxPerLp (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLp"], SEP) | |
214 | - | ||
215 | - | ||
216 | - | func keyWxPerLpX18 (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLpX18"], SEP) | |
217 | - | ||
218 | - | ||
219 | - | func keyWxPerLpIntegralUserLast (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "uIntL"], SEP) | |
220 | - | ||
221 | - | ||
222 | - | func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP) | |
223 | - | ||
224 | - | ||
225 | - | func formatHistoryRecord (userAddress,lpAssetId,type,amount) = makeString(["%s%s%s%d%d%d", userAddress, lpAssetId, type, toString(height), toString(lastBlock.timestamp), toString(amount)], SEP) | |
226 | - | ||
227 | - | ||
228 | - | func OperationHistoryEntry (type,userAddress,lpAssetId,amount,txId) = StringEntry(keyOperationHistoryRecord(type, userAddress, toBase58String(txId)), formatHistoryRecord(userAddress, lpAssetId, type, amount)) | |
229 | - | ||
230 | - | ||
231 | - | let factoryAddress = getStringOrFail(this, keyFactoryAddress()) | |
232 | - | ||
233 | - | let factoryContract = addressFromStringValue(factoryAddress) | |
234 | - | ||
235 | - | let factoryCfg = readFactoryCfgOrFail(factoryContract) | |
236 | - | ||
237 | - | let emissionContract = getEmissionAddressOrFail(factoryCfg) | |
238 | - | ||
239 | - | let boostingContract = getBoostingAddressOrFail(factoryCfg) | |
240 | - | ||
241 | - | func keyNextUser (lpAssetId) = makeString(["%s%s", lpAssetId, "nextUser"], SEP) | |
242 | - | ||
243 | - | ||
244 | - | func getUsersListName (lpAssetId) = makeString(["users", lpAssetId], SEP) | |
245 | - | ||
246 | - | ||
247 | - | func keyListHead (listName) = makeString(["%s%s%s", listName, "head"], SEP) | |
248 | - | ||
249 | - | ||
250 | - | func keyListSize (listName) = makeString(["%s%s%s", listName, "size"], SEP) | |
251 | - | ||
252 | - | ||
253 | - | func keyListPrev (listName,id) = makeString(["%s%s%s%s", listName, id, "prev"], SEP) | |
254 | - | ||
255 | - | ||
256 | - | func keyListNext (listName,id) = makeString(["%s%s%s%s", listName, id, "next"], SEP) | |
257 | - | ||
258 | - | ||
259 | - | func containsNode (listName,id) = { | |
260 | - | let headOrUnit = getString(this, keyListHead(listName)) | |
261 | - | let prevOrUnit = getString(this, keyListPrev(listName, id)) | |
262 | - | let nextOrUnit = getString(this, keyListNext(listName, id)) | |
263 | - | if (if ((id == valueOrElse(headOrUnit, ""))) | |
264 | - | then true | |
265 | - | else (prevOrUnit != unit)) | |
266 | - | then true | |
267 | - | else (nextOrUnit != unit) | |
72 | + | func getValueOrFail (address,key,type) = { | |
73 | + | let error = makeString(["mandatory ", toString(address), ".", key, " is not defined"], "") | |
74 | + | valueOrErrorMessage( match type { | |
75 | + | case str: String => | |
76 | + | getString(address, key) | |
77 | + | case int: Int => | |
78 | + | getInteger(address, key) | |
79 | + | case _ => | |
80 | + | throw("invalid entry type") | |
81 | + | }, error) | |
268 | 82 | } | |
269 | 83 | ||
270 | 84 | ||
271 | - | func insertNodeActions (listName,id) = { | |
272 | - | let headOrUnit = getString(this, keyListHead(listName)) | |
273 | - | let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0) | |
274 | - | let checkNode = if (!(containsNode(listName, id))) | |
275 | - | then true | |
276 | - | else throw("Node exists") | |
277 | - | if ((checkNode == checkNode)) | |
278 | - | then (([IntegerEntry(keyListSize(listName), (listSize + 1))] ++ (if ((headOrUnit != unit)) | |
279 | - | then [StringEntry(keyListNext(listName, id), value(headOrUnit)), StringEntry(keyListPrev(listName, value(headOrUnit)), id)] | |
280 | - | else nil)) ++ [StringEntry(keyListHead(listName), id)]) | |
281 | - | else throw("Strict value is not equal to itself.") | |
85 | + | func getStrOrFail (address,key) = { | |
86 | + | let @ = getValueOrFail(address, key, 0) | |
87 | + | if ($isInstanceOf(@, "String")) | |
88 | + | then @ | |
89 | + | else throw("Couldn't cast Int|String to String") | |
282 | 90 | } | |
283 | 91 | ||
284 | 92 | ||
285 | - | func deleteNodeActions (listName,id) = { | |
286 | - | let headOrUnit = getString(this, keyListHead(listName)) | |
287 | - | let listSize = valueOrElse(getInteger(this, keyListSize(listName)), 0) | |
288 | - | let prevOrUnit = getString(this, keyListPrev(listName, id)) | |
289 | - | let nextOrUnit = getString(this, keyListNext(listName, id)) | |
290 | - | ([IntegerEntry(keyListSize(listName), (listSize - 1))] ++ (if (if ((prevOrUnit != unit)) | |
291 | - | then (nextOrUnit != unit) | |
292 | - | else false) | |
293 | - | then [StringEntry(keyListNext(listName, value(prevOrUnit)), value(nextOrUnit)), StringEntry(keyListPrev(listName, value(nextOrUnit)), value(prevOrUnit)), DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, id))] | |
294 | - | else if ((nextOrUnit != unit)) | |
295 | - | then [StringEntry(keyListHead(listName), value(nextOrUnit)), DeleteEntry(keyListNext(listName, id)), DeleteEntry(keyListPrev(listName, value(nextOrUnit)))] | |
296 | - | else if ((prevOrUnit != unit)) | |
297 | - | then [DeleteEntry(keyListPrev(listName, id)), DeleteEntry(keyListNext(listName, value(prevOrUnit)))] | |
298 | - | else if ((id == valueOrElse(headOrUnit, ""))) | |
299 | - | then [DeleteEntry(keyListHead(listName))] | |
300 | - | else throw(((("invalid node: " + listName) + ".") + id)))) | |
93 | + | func getStrOrUnit (address,key) = { | |
94 | + | let @ = getValueOrFail(address, key, 0) | |
95 | + | if ($isInstanceOf(@, "String")) | |
96 | + | then @ | |
97 | + | else unit | |
301 | 98 | } | |
302 | 99 | ||
303 | 100 | ||
304 | - | func calcWxPerLpIntegralUserLast (stakedByUser,wxPerLpIntegralUserLastUpdHeightOrZero,wxPerLpIntegralNew,wxPerLpIntegralUserLastKEY) = if (if ((wxPerLpIntegralUserLastUpdHeightOrZero == zeroBigInt)) | |
305 | - | then (stakedByUser > zeroBigInt) | |
306 | - | else false) | |
307 | - | then zeroBigInt | |
308 | - | else if ((stakedByUser == zeroBigInt)) | |
309 | - | then wxPerLpIntegralNew | |
310 | - | else if (if ((wxPerLpIntegralUserLastUpdHeightOrZero > zeroBigInt)) | |
311 | - | then (stakedByUser > zeroBigInt) | |
312 | - | else false) | |
313 | - | then value(parseBigInt(getStringOrFail(this, wxPerLpIntegralUserLastKEY))) | |
314 | - | else throw("calcWxPerLpIntegralUserLast: unexpected state") | |
315 | - | ||
316 | - | ||
317 | - | func refreshPoolINTEGRALS (lpAssetIdStr,poolAddressStr,lpDeltaAmount) = { | |
318 | - | let stakedTotalKEY = keyStakedTotal(lpAssetIdStr) | |
319 | - | let stakedTotal = toBigInt(readStaked(stakedTotalKEY)) | |
320 | - | let nonZeroStakedTotal = if ((stakedTotal == zeroBigInt)) | |
321 | - | then oneBigInt | |
322 | - | else stakedTotal | |
323 | - | let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr)) | |
324 | - | let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock()) | |
325 | - | let MULT3 = 1000 | |
326 | - | let wxEmissionPerBlockX3 = (getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) * MULT3) | |
327 | - | let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * 3)) | |
328 | - | let wxPerLpIntegralKEY = keyWxPerLpIntegral(lpAssetIdStr) | |
329 | - | let wxPerLpIntegralLastUpdHeightKEY = keyWxPerLpIntegralLastUpdHeight(lpAssetIdStr) | |
330 | - | let wxPerLpKEY = keyWxPerLp(lpAssetIdStr) | |
331 | - | let wxPerLpIntegralLastUpdHeight = getIntOrDefault(this, wxPerLpIntegralLastUpdHeightKEY, emissionStartBlock) | |
332 | - | let wxPerLpIntegral = getBigIntFromStringOrZero(this, wxPerLpIntegralKEY) | |
333 | - | let wxPerLpOrZeroX3 = 0 | |
334 | - | let dh = max([(height - wxPerLpIntegralLastUpdHeight), 0]) | |
335 | - | let wxPerLpX3 = if ((wxPerLpOrZeroX3 != 0)) | |
336 | - | then toBigInt(wxPerLpOrZeroX3) | |
337 | - | else fraction(toBigInt(poolWxEmissionPerBlockX3), toBigInt(MULT8), nonZeroStakedTotal) | |
338 | - | let stakedTotalNew = (stakedTotal + toBigInt(lpDeltaAmount)) | |
339 | - | let nonZeroStakedTotalNew = if ((stakedTotalNew == zeroBigInt)) | |
340 | - | then oneBigInt | |
341 | - | else stakedTotalNew | |
342 | - | let wxPerLpIntegralNew = (wxPerLpIntegral + (wxPerLpX3 * toBigInt(dh))) | |
343 | - | let wxPerLpX3New = (toBigInt(poolWxEmissionPerBlockX3) / nonZeroStakedTotalNew) | |
344 | - | let wxPerLpIntegralLastUpdHeightNew = height | |
345 | - | let debug = makeString([toString(wxPerLpIntegralNew), toString(dh), toString(wxPerLpX3), toString(stakedTotal), toString(poolWxEmissionPerBlockX3), toString(wxEmissionPerBlockX3), toString(poolWeight)], "::") | |
346 | - | $Tuple3(wxPerLpIntegralNew, [StringEntry(wxPerLpIntegralKEY, toString(wxPerLpIntegralNew)), IntegerEntry(wxPerLpIntegralLastUpdHeightKEY, wxPerLpIntegralLastUpdHeightNew), StringEntry(wxPerLpKEY, toString(wxPerLpX3New))], debug) | |
101 | + | func getIntOrFail (address,key) = { | |
102 | + | let @ = getValueOrFail(address, key, 0) | |
103 | + | if ($isInstanceOf(@, "Int")) | |
104 | + | then @ | |
105 | + | else throw("Couldn't cast Int|String to Int") | |
347 | 106 | } | |
348 | 107 | ||
349 | 108 | ||
350 | - | func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = { | |
351 | - | let $t01424614368 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount) | |
352 | - | let wxPerLpIntegralNew = $t01424614368._1 | |
353 | - | let poolIntegralSTATE = $t01424614368._2 | |
354 | - | let poolDEBUG = $t01424614368._3 | |
355 | - | let MULT3 = 1000 | |
356 | - | let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr) | |
357 | - | let stakedByUser = readStaked(stakedByUserKEY) | |
358 | - | let wxToClaimUserKEY = keyWxToClaimUser(lpAssetIdStr, userAddressStr) | |
359 | - | let wxPerLpIntegralUserLastUpdHeightKEY = keyWxPerLpIntegralUserLastUpdHeight(lpAssetIdStr, userAddressStr) | |
360 | - | let wxPerLpIntegralUserLastKEY = keyWxPerLpIntegralUserLast(lpAssetIdStr, userAddressStr) | |
361 | - | let wxToClaimUser = getBigIntFromStringOrZero(this, wxToClaimUserKEY) | |
362 | - | let wxPerLpIntegralUserLastUpdHeightOrZero = getIntOrZero(this, wxPerLpIntegralUserLastUpdHeightKEY) | |
363 | - | let wxPerLpIntegralUserLast = calcWxPerLpIntegralUserLast(toBigInt(stakedByUser), toBigInt(wxPerLpIntegralUserLastUpdHeightOrZero), wxPerLpIntegralNew, wxPerLpIntegralUserLastKEY) | |
364 | - | let MULT11 = (MULT8 * MULT3) | |
365 | - | let wxToClaimUserNew = max([(wxToClaimUser + fraction((wxPerLpIntegralNew - wxPerLpIntegralUserLast), toBigInt(stakedByUser), toBigInt(MULT11))), zeroBigInt]) | |
366 | - | let wxPerLpIntegralUserLastNew = wxPerLpIntegralNew | |
367 | - | let wxPerLpIntegralUserLastUpdHeightNew = height | |
368 | - | let debug = makeString([toString(wxToClaimUser), toString(wxPerLpIntegralUserLast), toString(stakedByUser), poolDEBUG, toString(height)], "::") | |
369 | - | $Tuple3(wxToClaimUserNew, (poolIntegralSTATE ++ [StringEntry(wxToClaimUserKEY, toString(wxToClaimUserNew)), IntegerEntry(wxPerLpIntegralUserLastUpdHeightKEY, wxPerLpIntegralUserLastUpdHeightNew), StringEntry(wxPerLpIntegralUserLastKEY, toString(wxPerLpIntegralUserLastNew))]), debug) | |
109 | + | func getIntOrUnit (address,key) = { | |
110 | + | let @ = getValueOrFail(address, key, 0) | |
111 | + | if ($isInstanceOf(@, "Int")) | |
112 | + | then @ | |
113 | + | else unit | |
370 | 114 | } | |
115 | + | ||
116 | + | ||
117 | + | func isVerified (assetId) = (valueOrElse(getInteger(keyStatus(assetId)), statusUnverified) == statusVerified) | |
118 | + | ||
119 | + | ||
120 | + | func getLabels () = match getString(keyLabels()) { | |
121 | + | case s: String => | |
122 | + | if ((size(s) == 0)) | |
123 | + | then nil | |
124 | + | else split(s, SEP) | |
125 | + | case _ => | |
126 | + | nil | |
127 | + | } | |
128 | + | ||
129 | + | ||
130 | + | func getAssetLabels (assetId) = match getString(keyAssetLabels(assetId)) { | |
131 | + | case s: String => | |
132 | + | if ((size(s) == 0)) | |
133 | + | then nil | |
134 | + | else split(s, SEP) | |
135 | + | case _ => | |
136 | + | nil | |
137 | + | } | |
371 | 138 | ||
372 | 139 | ||
373 | 140 | func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) { | |
374 | 141 | case s: String => | |
375 | 142 | fromBase58String(s) | |
376 | 143 | case _: Unit => | |
377 | 144 | unit | |
378 | 145 | case _ => | |
379 | 146 | throw("Match error") | |
380 | 147 | } | |
381 | 148 | ||
382 | 149 | ||
383 | 150 | func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) { | |
384 | 151 | case s: String => | |
385 | 152 | fromBase58String(s) | |
386 | 153 | case _: Unit => | |
387 | 154 | unit | |
388 | 155 | case _ => | |
389 | 156 | throw("Match error") | |
390 | 157 | } | |
391 | 158 | ||
392 | 159 | ||
393 | - | let permissionDeniedError = throw("Permission denied") | |
394 | - | ||
395 | - | func mustThis (i) = if ((i.caller == this)) | |
396 | - | then true | |
397 | - | else permissionDeniedError | |
398 | - | ||
399 | - | ||
400 | 160 | func mustManager (i) = match managerPublicKeyOrUnit() { | |
401 | 161 | case pk: ByteVector => | |
402 | 162 | if ((i.callerPublicKey == pk)) | |
403 | 163 | then true | |
404 | - | else | |
164 | + | else throwPD() | |
405 | 165 | case _: Unit => | |
406 | 166 | if ((i.caller == this)) | |
407 | 167 | then true | |
408 | - | else | |
168 | + | else throwPD() | |
409 | 169 | case _ => | |
410 | 170 | throw("Match error") | |
411 | 171 | } | |
412 | 172 | ||
413 | 173 | ||
174 | + | func mustAdmin (i) = { | |
175 | + | let adminPKs = split(valueOrElse(getString(keyAdminPubKeys()), EMPTY), SEP) | |
176 | + | if (containsElement(adminPKs, toBase58String(i.callerPublicKey))) | |
177 | + | then true | |
178 | + | else { | |
179 | + | let isManager = mustManager(i) | |
180 | + | if ((isManager == isManager)) | |
181 | + | then true | |
182 | + | else throw("Strict value is not equal to itself.") | |
183 | + | } | |
184 | + | } | |
185 | + | ||
186 | + | ||
187 | + | func isCreated (assetId) = valueOrElse(getBoolean(keyCreated(assetId)), false) | |
188 | + | ||
189 | + | ||
190 | + | func verifiedToStatus (verified) = if (verified) | |
191 | + | then statusVerified | |
192 | + | else statusUnverified | |
193 | + | ||
194 | + | ||
195 | + | func addLabelActions (assetId,label,throwOnError) = { | |
196 | + | let labels = getLabels() | |
197 | + | let assetLabels = getAssetLabels(assetId) | |
198 | + | let checkLabel = if (containsElement(labels, label)) | |
199 | + | then true | |
200 | + | else throw("Label doesn't exist") | |
201 | + | if ((checkLabel == checkLabel)) | |
202 | + | then { | |
203 | + | let newAssetLabels = if (containsElement(assetLabels, label)) | |
204 | + | then if (throwOnError) | |
205 | + | then throw("Label has already been added") | |
206 | + | else assetLabels | |
207 | + | else (assetLabels :+ label) | |
208 | + | [StringEntry(keyAssetLabels(assetId), makeString(newAssetLabels, SEP))] | |
209 | + | } | |
210 | + | else throw("Strict value is not equal to itself.") | |
211 | + | } | |
212 | + | ||
213 | + | ||
214 | + | func deleteLabelActions (assetId,label,throwOnError) = { | |
215 | + | let assetLabels = getAssetLabels(assetId) | |
216 | + | let newAssetLabels = if (containsElement(assetLabels, label)) | |
217 | + | then removeByIndex(assetLabels, value(indexOf(assetLabels, label))) | |
218 | + | else if (throwOnError) | |
219 | + | then throw("Label wasn't added") | |
220 | + | else assetLabels | |
221 | + | [StringEntry(keyAssetLabels(assetId), makeString(newAssetLabels, SEP))] | |
222 | + | } | |
223 | + | ||
224 | + | ||
225 | + | func setVerifiedActions (assetId,verified) = { | |
226 | + | let labelCommunityVerifiedActions = if (verified) | |
227 | + | then addLabelActions(assetId, labelCommunityVerified, false) | |
228 | + | else deleteLabelActions(assetId, labelCommunityVerified, false) | |
229 | + | ([IntegerEntry(keyStatus(assetId), verifiedToStatus(verified))] ++ labelCommunityVerifiedActions) | |
230 | + | } | |
231 | + | ||
232 | + | ||
233 | + | func updateTickerActions (assetId,ticker) = { | |
234 | + | let checkTicker = { | |
235 | + | let linkedAssetIdOrUnit = getString(keyTickerToAssetId(ticker)) | |
236 | + | let tickerIsValid = if ((ticker != "")) | |
237 | + | then if ((linkedAssetIdOrUnit == unit)) | |
238 | + | then true | |
239 | + | else (value(linkedAssetIdOrUnit) == assetId) | |
240 | + | else false | |
241 | + | if (tickerIsValid) | |
242 | + | then true | |
243 | + | else throw("Invalid ticker") | |
244 | + | } | |
245 | + | if ((checkTicker == checkTicker)) | |
246 | + | then [StringEntry(keyAssetIdToTicker(assetId), ticker), StringEntry(keyTickerToAssetId(ticker), assetId)] | |
247 | + | else throw("Strict value is not equal to itself.") | |
248 | + | } | |
249 | + | ||
250 | + | ||
414 | 251 | @Callable(i) | |
415 | - | func constructor ( | |
252 | + | func constructor (userPoolsContract,labels) = { | |
416 | 253 | let checkCaller = mustManager(i) | |
417 | 254 | if ((checkCaller == checkCaller)) | |
418 | - | then [StringEntry(keyFactoryAddress(), factoryAddressStr)] | |
255 | + | then { | |
256 | + | let checksAddress = valueOrErrorMessage(addressFromString(userPoolsContract), "Invalid address") | |
257 | + | if ((checksAddress == checksAddress)) | |
258 | + | then [StringEntry(keyUserPoolsContract(), userPoolsContract), StringEntry(keyLabels(), makeString((defaultLabels ++ labels), SEP))] | |
259 | + | else throw("Strict value is not equal to itself.") | |
260 | + | } | |
419 | 261 | else throw("Strict value is not equal to itself.") | |
420 | 262 | } | |
421 | 263 | ||
422 | 264 | ||
423 | 265 | ||
424 | 266 | @Callable(i) | |
425 | 267 | func constructorV2 (votingEmissionContract) = { | |
426 | - | let cheks = [mustManager(i), if ((addressFromString(votingEmissionContract) != unit)) | |
268 | + | let checkCaller = mustManager(i) | |
269 | + | if ((checkCaller == checkCaller)) | |
270 | + | then { | |
271 | + | let checkAddress = valueOrErrorMessage(addressFromString(votingEmissionContract), "invalid voting emission contract address") | |
272 | + | if ((checkAddress == checkAddress)) | |
273 | + | then [StringEntry(keyVotingEmissionContract(), votingEmissionContract)] | |
274 | + | else throw("Strict value is not equal to itself.") | |
275 | + | } | |
276 | + | else throw("Strict value is not equal to itself.") | |
277 | + | } | |
278 | + | ||
279 | + | ||
280 | + | ||
281 | + | @Callable(i) | |
282 | + | func addAssetsLink (amountAsset,priceAsset,lpAsset) = { | |
283 | + | let checkCaller = mustAdmin(i) | |
284 | + | if ((checkCaller == checkCaller)) | |
285 | + | then [StringEntry(keyAmountAndPriceAssetsToLpAsset(amountAsset, priceAsset), lpAsset), StringEntry(keyLpAssetToAmountAndPriceAssets(lpAsset), makeString([amountAsset, priceAsset], SEP))] | |
286 | + | else throw("Strict value is not equal to itself.") | |
287 | + | } | |
288 | + | ||
289 | + | ||
290 | + | ||
291 | + | @Callable(i) | |
292 | + | func increaseAssetPoolsNumber (assetId) = { | |
293 | + | let checkCaller = mustAdmin(i) | |
294 | + | if ((checkCaller == checkCaller)) | |
295 | + | then { | |
296 | + | let assetPoolsNumberKey = keyAssetPoolsNumber(assetId) | |
297 | + | let assetPoolsNumber = valueOrElse(getInteger(assetPoolsNumberKey), 0) | |
298 | + | [IntegerEntry(assetPoolsNumberKey, (assetPoolsNumber + 1))] | |
299 | + | } | |
300 | + | else throw("Strict value is not equal to itself.") | |
301 | + | } | |
302 | + | ||
303 | + | ||
304 | + | ||
305 | + | @Callable(i) | |
306 | + | func createLabel (label) = { | |
307 | + | let labels = getLabels() | |
308 | + | let checkCaller = mustAdmin(i) | |
309 | + | if ((checkCaller == checkCaller)) | |
310 | + | then { | |
311 | + | let checkLabel = [if (!(contains(label, SEP))) | |
312 | + | then true | |
313 | + | else throw("Invalid label name"), if (!(containsElement(labels, label))) | |
314 | + | then true | |
315 | + | else throw("Label exists")] | |
316 | + | if ((checkLabel == checkLabel)) | |
317 | + | then [StringEntry(keyLabels(), makeString((labels :+ label), SEP))] | |
318 | + | else throw("Strict value is not equal to itself.") | |
319 | + | } | |
320 | + | else throw("Strict value is not equal to itself.") | |
321 | + | } | |
322 | + | ||
323 | + | ||
324 | + | ||
325 | + | @Callable(i) | |
326 | + | func dropLabel (label) = { | |
327 | + | let labels = getLabels() | |
328 | + | let checkCaller = mustManager(i) | |
329 | + | if ((checkCaller == checkCaller)) | |
330 | + | then { | |
331 | + | let checkLabel = if (containsElement(labels, label)) | |
332 | + | then true | |
333 | + | else throw("Label doesn't exist") | |
334 | + | if ((checkLabel == checkLabel)) | |
335 | + | then [StringEntry(keyLabels(), makeString(removeByIndex(labels, value(indexOf(labels, label))), SEP))] | |
336 | + | else throw("Strict value is not equal to itself.") | |
337 | + | } | |
338 | + | else throw("Strict value is not equal to itself.") | |
339 | + | } | |
340 | + | ||
341 | + | ||
342 | + | ||
343 | + | @Callable(i) | |
344 | + | func addLabel (assetId,label) = { | |
345 | + | let checkCaller = mustAdmin(i) | |
346 | + | if ((checkCaller == checkCaller)) | |
347 | + | then addLabelActions(assetId, label, true) | |
348 | + | else throw("Strict value is not equal to itself.") | |
349 | + | } | |
350 | + | ||
351 | + | ||
352 | + | ||
353 | + | @Callable(i) | |
354 | + | func deleteLabel (assetId,label) = { | |
355 | + | let checkCaller = mustAdmin(i) | |
356 | + | if ((checkCaller == checkCaller)) | |
357 | + | then deleteLabelActions(assetId, label, true) | |
358 | + | else throw("Strict value is not equal to itself.") | |
359 | + | } | |
360 | + | ||
361 | + | ||
362 | + | ||
363 | + | @Callable(i) | |
364 | + | func updateTicker (assetId,ticker) = { | |
365 | + | let checkCaller = mustAdmin(i) | |
366 | + | if ((checkCaller == checkCaller)) | |
367 | + | then { | |
368 | + | let checkAsset = if (isCreated(assetId)) | |
369 | + | then true | |
370 | + | else throwNoAsset() | |
371 | + | if ((checkAsset == checkAsset)) | |
372 | + | then updateTickerActions(assetId, ticker) | |
373 | + | else throw("Strict value is not equal to itself.") | |
374 | + | } | |
375 | + | else throw("Strict value is not equal to itself.") | |
376 | + | } | |
377 | + | ||
378 | + | ||
379 | + | ||
380 | + | @Callable(i) | |
381 | + | func deleteTicker (assetId) = { | |
382 | + | let checkCaller = mustAdmin(i) | |
383 | + | if ((checkCaller == checkCaller)) | |
384 | + | then { | |
385 | + | let ticker = valueOrErrorMessage(getString(keyAssetIdToTicker(assetId)), "Invalid asset") | |
386 | + | [DeleteEntry(keyAssetIdToTicker(assetId)), DeleteEntry(keyTickerToAssetId(ticker))] | |
387 | + | } | |
388 | + | else throw("Strict value is not equal to itself.") | |
389 | + | } | |
390 | + | ||
391 | + | ||
392 | + | ||
393 | + | @Callable(i) | |
394 | + | func createOrUpdate (assetId,logo,verified) = { | |
395 | + | let checkCaller = mustAdmin(i) | |
396 | + | if ((checkCaller == checkCaller)) | |
397 | + | then { | |
398 | + | let isCreatedNow = !(isCreated(assetId)) | |
399 | + | if ((isCreatedNow == isCreatedNow)) | |
400 | + | then { | |
401 | + | let setLogoActions = if ((logo == "")) | |
402 | + | then nil | |
403 | + | else [StringEntry(keyLogo(assetId), logo)] | |
404 | + | $Tuple2((([BooleanEntry(keyCreated(assetId), true)] ++ setLogoActions) ++ setVerifiedActions(assetId, verified)), isCreatedNow) | |
405 | + | } | |
406 | + | else throw("Strict value is not equal to itself.") | |
407 | + | } | |
408 | + | else throw("Strict value is not equal to itself.") | |
409 | + | } | |
410 | + | ||
411 | + | ||
412 | + | ||
413 | + | @Callable(i) | |
414 | + | func setLogo (assetId,logo) = { | |
415 | + | let checks = [mustAdmin(i), if (isCreated(assetId)) | |
427 | 416 | then true | |
428 | - | else "invalid voting emission contract address"] | |
429 | - | if ((cheks == cheks)) | |
430 | - | then [StringEntry(keyVotingEmissionContract(), votingEmissionContract)] | |
417 | + | else throwNoAsset()] | |
418 | + | if ((checks == checks)) | |
419 | + | then { | |
420 | + | let action = if ((logo == "")) | |
421 | + | then DeleteEntry(keyLogo(assetId)) | |
422 | + | else StringEntry(keyLogo(assetId), logo) | |
423 | + | [action] | |
424 | + | } | |
425 | + | else throw("Strict value is not equal to itself.") | |
426 | + | } | |
427 | + | ||
428 | + | ||
429 | + | ||
430 | + | @Callable(i) | |
431 | + | func setVerified (assetId,verified) = { | |
432 | + | let checks = [mustAdmin(i), if (isCreated(assetId)) | |
433 | + | then true | |
434 | + | else throwNoAsset()] | |
435 | + | if ((checks == checks)) | |
436 | + | then { | |
437 | + | let onVerificationLossInv = if (!(verified)) | |
438 | + | then { | |
439 | + | let votingEmissionContract = valueOrErrorMessage(addressFromString(getStrOrFail(this, keyVotingEmissionContract())), "invalid voting emission contract address") | |
440 | + | invoke(votingEmissionContract, "onVerificationLoss", [assetId], nil) | |
441 | + | } | |
442 | + | else unit | |
443 | + | if ((onVerificationLossInv == onVerificationLossInv)) | |
444 | + | then $Tuple2(setVerifiedActions(assetId, verified), unit) | |
445 | + | else throw("Strict value is not equal to itself.") | |
446 | + | } | |
447 | + | else throw("Strict value is not equal to itself.") | |
448 | + | } | |
449 | + | ||
450 | + | ||
451 | + | ||
452 | + | @Callable(i) | |
453 | + | func onEliminate (assetId) = { | |
454 | + | let poolsNumber = valueOrElse(getInteger(keyAssetPoolsNumber(assetId)), 0) | |
455 | + | let actions = if ((poolsNumber > 0)) | |
456 | + | then nil | |
457 | + | else [DeleteEntry(keyLogo(assetId))] | |
458 | + | $Tuple2(actions, unit) | |
459 | + | } | |
460 | + | ||
461 | + | ||
462 | + | ||
463 | + | @Callable(i) | |
464 | + | func setAdmins (adminPubKeys) = { | |
465 | + | let checkCaller = mustManager(i) | |
466 | + | if ((checkCaller == checkCaller)) | |
467 | + | then [StringEntry(keyAdminPubKeys(), makeString(adminPubKeys, SEP))] | |
431 | 468 | else throw("Strict value is not equal to itself.") | |
432 | 469 | } | |
433 | 470 | ||
434 | 471 | ||
435 | 472 | ||
436 | 473 | @Callable(i) | |
437 | 474 | func setManager (pendingManagerPublicKey) = { | |
438 | 475 | let checkCaller = mustManager(i) | |
439 | 476 | if ((checkCaller == checkCaller)) | |
440 | 477 | then { | |
441 | 478 | let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey) | |
442 | 479 | if ((checkManagerPublicKey == checkManagerPublicKey)) | |
443 | 480 | then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)] | |
444 | 481 | else throw("Strict value is not equal to itself.") | |
445 | 482 | } | |
446 | 483 | else throw("Strict value is not equal to itself.") | |
447 | 484 | } | |
448 | 485 | ||
449 | 486 | ||
450 | 487 | ||
451 | 488 | @Callable(i) | |
452 | 489 | func confirmManager () = { | |
453 | 490 | let pm = pendingManagerPublicKeyOrUnit() | |
454 | 491 | let hasPM = if (isDefined(pm)) | |
455 | 492 | then true | |
456 | 493 | else throw("No pending manager") | |
457 | 494 | if ((hasPM == hasPM)) | |
458 | 495 | then { | |
459 | 496 | let checkPM = if ((i.callerPublicKey == value(pm))) | |
460 | 497 | then true | |
461 | 498 | else throw("You are not pending manager") | |
462 | 499 | if ((checkPM == checkPM)) | |
463 | 500 | then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())] | |
464 | 501 | else throw("Strict value is not equal to itself.") | |
465 | 502 | } | |
466 | 503 | else throw("Strict value is not equal to itself.") | |
467 | 504 | } | |
468 | 505 | ||
469 | 506 | ||
470 | 507 | ||
471 | 508 | @Callable(i) | |
472 | - | func stake () = { | |
473 | - | let migration = if ((getBinary(this, keyMigrator) != unit)) | |
474 | - | then throw("maintenance") | |
475 | - | else unit | |
476 | - | if ((migration == migration)) | |
477 | - | then if ((size(i.payments) != 1)) | |
478 | - | then throw("invalid payment - exact one payment must be attached") | |
479 | - | else { | |
480 | - | let pmt = i.payments[0] | |
481 | - | let lpAssetId = value(pmt.assetId) | |
482 | - | let lpAssetIdStr = toBase58String(lpAssetId) | |
483 | - | let amount = pmt.amount | |
484 | - | let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr)) | |
485 | - | let callerStr = toString(i.caller) | |
486 | - | let userAddressStr = if ((callerStr == poolAddressStr)) | |
487 | - | then toString(i.originCaller) | |
488 | - | else callerStr | |
489 | - | let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr) | |
490 | - | let stakedTotalKEY = keyStakedTotal(lpAssetIdStr) | |
491 | - | let stakedByUser = readStaked(stakedByUserKEY) | |
492 | - | let stakedTotal = readStaked(stakedTotalKEY) | |
493 | - | let $t01893619053 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount) | |
494 | - | let wxToClaimUserNew = $t01893619053._1 | |
495 | - | let integralSTATE = $t01893619053._2 | |
496 | - | let debug = $t01893619053._3 | |
497 | - | let listName = getUsersListName(lpAssetIdStr) | |
498 | - | let listActions = if (containsNode(listName, userAddressStr)) | |
499 | - | then nil | |
500 | - | else insertNodeActions(listName, userAddressStr) | |
501 | - | (([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions) | |
502 | - | } | |
503 | - | else throw("Strict value is not equal to itself.") | |
504 | - | } | |
505 | - | ||
506 | - | ||
507 | - | ||
508 | - | @Callable(i) | |
509 | - | func unstake (lpAssetIdStr,amount) = { | |
510 | - | let migration = if ((getBinary(this, keyMigrator) != unit)) | |
511 | - | then throw("maintenance") | |
512 | - | else unit | |
513 | - | if ((migration == migration)) | |
514 | - | then { | |
515 | - | let lpAssetId = fromBase58String(lpAssetIdStr) | |
516 | - | let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr)) | |
517 | - | let poolAddon = valueOrElse(getString(this, keyStablePoolAddonAddr()), poolAddressStr) | |
518 | - | let callerStr = toString(i.caller) | |
519 | - | let userAddressStr = if (if ((callerStr == poolAddressStr)) | |
520 | - | then true | |
521 | - | else (callerStr == poolAddon)) | |
522 | - | then toString(i.originCaller) | |
523 | - | else callerStr | |
524 | - | let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr) | |
525 | - | let stakedTotalKEY = keyStakedTotal(lpAssetIdStr) | |
526 | - | let stakedByUser = readStaked(stakedByUserKEY) | |
527 | - | let stakedTotal = readStaked(stakedTotalKEY) | |
528 | - | let integralSTATE = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))._2 | |
529 | - | let listName = getUsersListName(lpAssetIdStr) | |
530 | - | let listActions = if (if (containsNode(listName, userAddressStr)) | |
531 | - | then (amount == stakedByUser) | |
532 | - | else false) | |
533 | - | then deleteNodeActions(listName, userAddressStr) | |
534 | - | else nil | |
535 | - | let claimedByUser = getBigIntFromStringOrZero(this, keyClaimedByUser(lpAssetIdStr, userAddressStr)) | |
536 | - | let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr)) | |
537 | - | let wxToClaimUserNew = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddress, 0)._1 | |
538 | - | let availableToClaim = (wxToClaimUserNew - claimedByUser) | |
539 | - | let r = if ((availableToClaim > zeroBigInt)) | |
540 | - | then invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil) | |
541 | - | else unit | |
542 | - | if ((r == r)) | |
543 | - | then if ((amount > stakedByUser)) | |
544 | - | then throw("passed amount is less then available") | |
545 | - | else (([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE) ++ listActions) | |
546 | - | else throw("Strict value is not equal to itself.") | |
547 | - | } | |
548 | - | else throw("Strict value is not equal to itself.") | |
549 | - | } | |
550 | - | ||
551 | - | ||
552 | - | ||
553 | - | @Callable(i) | |
554 | - | func claimWx (lpAssetIdStr) = { | |
555 | - | let userAddressStr = toString(i.caller) | |
556 | - | let result = invoke(this, "claimWxINTERNAL", [lpAssetIdStr, userAddressStr], nil) | |
557 | - | $Tuple2(nil, result) | |
558 | - | } | |
559 | - | ||
560 | - | ||
561 | - | ||
562 | - | @Callable(i) | |
563 | - | func claimWxINTERNAL (lpAssetIdStr,userAddressStr) = { | |
564 | - | let checkCaller = mustThis(i) | |
565 | - | if ((checkCaller == checkCaller)) | |
566 | - | then { | |
567 | - | let userAddress = valueOrErrorMessage(addressFromString(userAddressStr), "claimWxINTERNAL: invalid user address") | |
568 | - | let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr)) | |
569 | - | let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr) | |
570 | - | let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr) | |
571 | - | let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr) | |
572 | - | let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr) | |
573 | - | let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY) | |
574 | - | let claimedByUserMinReward = getBigIntFromStringOrZero(this, claimedByUserMinRewardKEY) | |
575 | - | let claimedByUserBoostReward = getBigIntFromStringOrZero(this, claimedByUserBoostRewardKEY) | |
576 | - | let claimedTotal = getBigIntFromStringOrZero(this, claimedTotalKEY) | |
577 | - | let $t02288422996 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0) | |
578 | - | let wxToClaimUserNew = $t02288422996._1 | |
579 | - | let integralSTATE = $t02288422996._2 | |
580 | - | let debug = $t02288422996._3 | |
581 | - | let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt]) | |
582 | - | if ((zeroBigInt >= availableToClaim)) | |
583 | - | then throw("nothing to claim") | |
584 | - | else { | |
585 | - | let wxAmountBoostTotal = max([asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0]), 0]) | |
586 | - | let minRewardPart = availableToClaim | |
587 | - | let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)]) | |
588 | - | let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [toInt(minRewardPart)], nil))[0]) | |
589 | - | let emitBoost = asAnyList(invoke(emissionContract, "emit", [toInt(boostRewardPart)], nil)) | |
590 | - | if ((emitBoost == emitBoost)) | |
591 | - | then { | |
592 | - | let claimedByUserValue = (claimedByUser + availableToClaim) | |
593 | - | let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart) | |
594 | - | let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserMinReward + minRewardPart) | |
595 | - | let claimedTotalPlusAvailableToClaim = (claimedByUserMinReward + minRewardPart) | |
596 | - | [StringEntry(claimedByUserKEY, toString(claimedByUserValue)), StringEntry(claimedByUserMinRewardKEY, toString(claimedByUserMinRewardPlusPart)), StringEntry(claimedByUserBoostRewardKEY, toString(claimedByUserBoostRewardPlusBoostRewardPart)), StringEntry(claimedTotalKEY, toString(claimedTotalPlusAvailableToClaim)), ScriptTransfer(userAddress, toInt(minRewardPart), wxAssetId), ScriptTransfer(userAddress, toInt(boostRewardPart), wxAssetId), OperationHistoryEntry("claim", userAddressStr, lpAssetIdStr, toInt(availableToClaim), i.transactionId)] | |
597 | - | } | |
598 | - | else throw("Strict value is not equal to itself.") | |
599 | - | } | |
600 | - | } | |
601 | - | else throw("Strict value is not equal to itself.") | |
602 | - | } | |
603 | - | ||
604 | - | ||
605 | - | ||
606 | - | @Callable(i) | |
607 | - | func claimWxREADONLY (lpAssetIdStr,userAddressStr) = { | |
608 | - | let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr) | |
609 | - | let stakedTotalKEY = keyStakedTotal(lpAssetIdStr) | |
610 | - | let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr) | |
611 | - | let stakedByUser = readStaked(stakedByUserKEY) | |
612 | - | let stakedTotal = readStaked(stakedTotalKEY) | |
613 | - | let claimedByUser = getBigIntFromStringOrZero(this, claimedByUserKEY) | |
614 | - | let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr)) | |
615 | - | let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr)) | |
616 | - | let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) | |
617 | - | let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock()) | |
618 | - | let passedBlocks = if ((emissionStartBlock > height)) | |
619 | - | then 0 | |
620 | - | else (height - emissionStartBlock) | |
621 | - | let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT) | |
622 | - | let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal) | |
623 | - | let $t02563825750 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0) | |
624 | - | let wxToClaimUserNew = $t02563825750._1 | |
625 | - | let integralSTATE = $t02563825750._2 | |
626 | - | let debug = $t02563825750._3 | |
627 | - | let availableToClaim = max([(wxToClaimUserNew - claimedByUser), zeroBigInt]) | |
628 | - | let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil)) | |
629 | - | let wxAmountBoostTotal = max([asInt(boostInvResult[0]), 0]) | |
630 | - | let boostDebug = asString(boostInvResult[1]) | |
631 | - | let minRewardPart = availableToClaim | |
632 | - | let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)]) | |
633 | - | let totalReward = (minRewardPart + boostRewardPart) | |
634 | - | $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), ((((debug + "::") + toString(userWxReward)) + "::BOOST::") + boostDebug)], SEP)) | |
635 | - | } | |
636 | - | ||
637 | - | ||
638 | - | ||
639 | - | @Callable(i) | |
640 | - | func usersListTraversal (lpAssetId) = { | |
641 | - | let checkCaller = if ((toBase58String(i.caller.bytes) == valueOrElse(getString(this, keyVotingEmissionContract()), ""))) | |
642 | - | then true | |
643 | - | else mustManager(i) | |
644 | - | if ((checkCaller == checkCaller)) | |
645 | - | then { | |
646 | - | let listName = getUsersListName(lpAssetId) | |
647 | - | let userOrUnit = getString(keyNextUser(lpAssetId)) | |
648 | - | let headOrUnit = getString(keyListHead(listName)) | |
649 | - | match userOrUnit { | |
650 | - | case _: Unit => | |
651 | - | match headOrUnit { | |
652 | - | case _: Unit => | |
653 | - | $Tuple2(nil, false) | |
654 | - | case head: String => | |
655 | - | $Tuple2([StringEntry(keyNextUser(lpAssetId), head)], true) | |
656 | - | case _ => | |
657 | - | throw("Match error") | |
658 | - | } | |
659 | - | case userAddress: String => | |
660 | - | let claimedByUser = getBigIntFromStringOrZero(this, keyClaimedByUser(lpAssetId, userAddress)) | |
661 | - | let poolAddress = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetId)) | |
662 | - | let wxToClaimUserNew = refreshINTEGRALS(lpAssetId, userAddress, poolAddress, 0)._1 | |
663 | - | let availableToClaim = (wxToClaimUserNew - claimedByUser) | |
664 | - | let r = if ((availableToClaim > zeroBigInt)) | |
665 | - | then invoke(this, "claimWxINTERNAL", [lpAssetId, userAddress], nil) | |
666 | - | else unit | |
667 | - | if ((r == r)) | |
668 | - | then { | |
669 | - | let nextUserOrUnit = getString(keyListNext(listName, userAddress)) | |
670 | - | match nextUserOrUnit { | |
671 | - | case _: Unit => | |
672 | - | $Tuple2([DeleteEntry(keyNextUser(lpAssetId))], false) | |
673 | - | case nextUser: String => | |
674 | - | $Tuple2([StringEntry(keyNextUser(lpAssetId), nextUser)], true) | |
675 | - | case _ => | |
676 | - | throw("Match error") | |
677 | - | } | |
678 | - | } | |
679 | - | else throw("Strict value is not equal to itself.") | |
680 | - | case _ => | |
681 | - | throw("Match error") | |
682 | - | } | |
683 | - | } | |
684 | - | else throw("Strict value is not equal to itself.") | |
685 | - | } | |
686 | - | ||
687 | - | ||
688 | - | ||
689 | - | @Callable(i) | |
690 | - | func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract)) | |
691 | - | then throw("permissions denied") | |
692 | - | else { | |
693 | - | let $t02810128211 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0) | |
694 | - | let wxPerLpIntegralNew = $t02810128211._1 | |
695 | - | let poolIntegralSTATE = $t02810128211._2 | |
696 | - | let poolDEBUG = $t02810128211._3 | |
697 | - | poolIntegralSTATE | |
698 | - | } | |
699 | - | ||
700 | - | ||
701 | - | ||
702 | - | @Callable(i) | |
703 | - | func setMigrator (pk) = if ((pk == "")) | |
704 | - | then [DeleteEntry(keyMigrator)] | |
705 | - | else [BinaryEntry(keyMigrator, fromBase58String(pk))] | |
509 | + | func isVerifiedREADONLY (assetId) = $Tuple2(nil, isVerified(assetId)) | |
706 | 510 | ||
707 | 511 | ||
708 | 512 | @Verifier(tx) | |
709 | 513 | func verify () = { | |
710 | 514 | let targetPublicKey = match managerPublicKeyOrUnit() { | |
711 | 515 | case pk: ByteVector => | |
712 | 516 | pk | |
713 | 517 | case _: Unit => | |
714 | 518 | tx.senderPublicKey | |
715 | 519 | case _ => | |
716 | 520 | throw("Match error") | |
717 | 521 | } | |
718 | - | if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)) | |
719 | - | then true | |
720 | - | else sigVerify(tx.bodyBytes, tx.proofs[0], getBinaryValue(this, keyMigrator)) | |
522 | + | sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey) | |
721 | 523 | } | |
722 | 524 |
github/deemru/w8io/786bc32 94.39 ms ◑