tx · 5NChLH48U9yoomh6XV6XoE15GrHXjDydyGTeMn4QLBYR

3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz:  -0.03500000 Waves

2022.06.08 16:48 [2087469] smart account 3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz > SELF 0.00000000 Waves

{ "type": 13, "id": "5NChLH48U9yoomh6XV6XoE15GrHXjDydyGTeMn4QLBYR", "fee": 3500000, "feeAssetId": null, "timestamp": 1654696121777, "version": 1, "sender": "3Mx3zmXrMcLFCafMuPtXAzR4ZPVeZYb6qLz", "senderPublicKey": "D28XoueZWsMfm8Y5pa6C5ZFuYoWgre2Wm8tzJANJgMnq", "proofs": [ "53kNL3BYjKZxvaxNkB7oezgTHw6MUouZNCnqMMZPNVHNQFFoKM6HZeSmWZ8AQquj3AL8hcQsuS4ADnu2NYor3oAn" ], "script": "base64:AAIFAAAAAAAAACcIAhIDCgEIEgMKAQgSABIDCgEYEggKBgEBAQEIARIDCgEIEgMKAQgAAAAhAAAAAANTRVACAAAAAl9fAAAAAAVFTVBUWQIAAAAAAAAAAA5pZHhQb29sQWRkcmVzcwAAAAAAAAAAAQAAAAAJaWR4TFBBc0lkAAAAAAAAAAADAAAAAAlpZHhBbUFzSWQAAAAAAAAAAAQAAAAACWlkeFByQXNJZAAAAAAAAAAABQAAAAAPaWR4RmFjdFN0YWtDbnRyAAAAAAAAAAABAAAAAAVkZWxheQIAAAAJJXNfX2RlbGF5AQAAAAtrZXlGYWN0Q250cgAAAAACAAAAEyVzX19mYWN0b3J5Q29udHJhY3QBAAAAE2tleU1hbmFnZXJQdWJsaWNLZXkAAAAAAgAAABQlc19fbWFuYWdlclB1YmxpY0tleQEAAAAaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkAAAAAAgAAABslc19fcGVuZGluZ01hbmFnZXJQdWJsaWNLZXkBAAAAC2tleVBvb2xBZGRyAAAAAAIAAAAPJXNfX3Bvb2xBZGRyZXNzAQAAAAtrZXlBbXRBc3NldAAAAAACAAAADyVzX19hbW91bnRBc3NldAEAAAANa2V5UHJpY2VBc3NldAAAAAACAAAADiVzX19wcmljZUFzc2V0AQAAAA9rZXlBZG1pblB1YktleXMAAAAAAgAAABAlc19fYWRtaW5QdWJLZXlzAQAAAAZrZXlBbXAAAAAAAgAAAAclc19fYW1wAQAAAA1rZXlBbXBIaXN0b3J5AAAAAQAAAAZoZWlnaHQJAAEsAAAAAgIAAAALJXMlZF9fYW1wX18JAAGkAAAAAQUAAAAGaGVpZ2h0AQAAABZsYXN0R2V0T3JQdXRPbmVUa25DYWxsAAAAAQAAAAZjYWxsZXIJAAS5AAAAAgkABEwAAAACAgAAABwlcyVzX19sYXN0R2V0T3JQdXRPbmVUa25DYWxsCQAETAAAAAIFAAAABmNhbGxlcgUAAAADbmlsBQAAAANTRVABAAAAEGtleUZhY3RvcnlDb25maWcAAAAAAgAAABElc19fZmFjdG9yeUNvbmZpZwEAAAANa2V5UG9vbENvbmZpZwAAAAIAAAAGaUFtdEFzAAAABWlQckFzCQABLAAAAAIJAAEsAAAAAgkAASwAAAACCQABLAAAAAICAAAACCVkJWQlc19fBQAAAAZpQW10QXMCAAAAAl9fBQAAAAVpUHJBcwIAAAAIX19jb25maWcBAAAAH2tleU1hcHBpbmdzQmFzZUFzc2V0MmludGVybmFsSWQAAAABAAAABWJBU3RyCQABLAAAAAICAAAAKCVzJXMlc19fbWFwcGluZ3NfX2Jhc2VBc3NldDJpbnRlcm5hbElkX18FAAAABWJBU3RyAQAAAA9nZXRTdHJpbmdPckZhaWwAAAACAAAABGFkZHIAAAADa2V5CQEAAAATdmFsdWVPckVycm9yTWVzc2FnZQAAAAIJAAQdAAAAAgUAAAAEYWRkcgUAAAADa2V5CQAEuQAAAAIJAARMAAAAAgIAAAAKbWFuZGF0b3J5IAkABEwAAAACCQAEJQAAAAEFAAAABGFkZHIJAARMAAAAAgIAAAABLgkABEwAAAACBQAAAANrZXkJAARMAAAAAgIAAAAMIG5vdCBkZWZpbmVkBQAAAANuaWwCAAAAAAEAAAAMZ2V0SW50T3JGYWlsAAAAAgAAAARhZGRyAAAAA2tleQkBAAAAE3ZhbHVlT3JFcnJvck1lc3NhZ2UAAAACCQAEGgAAAAIFAAAABGFkZHIFAAAAA2tleQkABLkAAAACCQAETAAAAAICAAAACm1hbmRhdG9yeSAJAARMAAAAAgkABCUAAAABBQAAAARhZGRyCQAETAAAAAICAAAAAS4JAARMAAAAAgUAAAADa2V5CQAETAAAAAICAAAADCBub3QgZGVmaW5lZAUAAAADbmlsAgAAAAAAAAAADHBvb2xDb250cmFjdAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAIFAAAABHRoaXMJAQAAAAtrZXlQb29sQWRkcgAAAAAAAAAAD2ZhY3RvcnlDb250cmFjdAkBAAAAEUBleHRyTmF0aXZlKDEwNjIpAAAAAQkBAAAAD2dldFN0cmluZ09yRmFpbAAAAAIFAAAADHBvb2xDb250cmFjdAkBAAAAC2tleUZhY3RDbnRyAAAAAAEAAAANZ2V0UG9vbENvbmZpZwAAAAAEAAAABWFtdEFzCQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAgUAAAAMcG9vbENvbnRyYWN0CQEAAAALa2V5QW10QXNzZXQAAAAABAAAAAdwcmljZUFzCQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAgUAAAAMcG9vbENvbnRyYWN0CQEAAAANa2V5UHJpY2VBc3NldAAAAAAEAAAACGlQcmljZUFzCQEAAAAMZ2V0SW50T3JGYWlsAAAAAgUAAAAPZmFjdG9yeUNvbnRyYWN0CQEAAAAfa2V5TWFwcGluZ3NCYXNlQXNzZXQyaW50ZXJuYWxJZAAAAAEFAAAAB3ByaWNlQXMEAAAABmlBbXRBcwkBAAAADGdldEludE9yRmFpbAAAAAIFAAAAD2ZhY3RvcnlDb250cmFjdAkBAAAAH2tleU1hcHBpbmdzQmFzZUFzc2V0MmludGVybmFsSWQAAAABBQAAAAVhbXRBcwkABLUAAAACCQEAAAAPZ2V0U3RyaW5nT3JGYWlsAAAAAgUAAAAPZmFjdG9yeUNvbnRyYWN0CQEAAAANa2V5UG9vbENvbmZpZwAAAAIJAAGkAAAAAQUAAAAGaUFtdEFzCQABpAAAAAEFAAAACGlQcmljZUFzBQAAAANTRVABAAAAEGdldEZhY3RvcnlDb25maWcAAAAACQAEtQAAAAIJAQAAAA9nZXRTdHJpbmdPckZhaWwAAAACBQAAAA9mYWN0b3J5Q29udHJhY3QJAQAAABBrZXlGYWN0b3J5Q29uZmlnAAAAAAUAAAADU0VQAQAAABZtYW5hZ2VyUHVibGljS2V5T3JVbml0AAAAAAQAAAAHJG1hdGNoMAkABCIAAAABCQEAAAATa2V5TWFuYWdlclB1YmxpY0tleQAAAAADCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABlN0cmluZwQAAAABcwUAAAAHJG1hdGNoMAkAAlkAAAABBQAAAAFzAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAARVbml0BQAAAAR1bml0CQAAAgAAAAECAAAAC01hdGNoIGVycm9yAQAAAB1wZW5kaW5nTWFuYWdlclB1YmxpY0tleU9yVW5pdAAAAAAEAAAAByRtYXRjaDAJAAQiAAAAAQkBAAAAGmtleVBlbmRpbmdNYW5hZ2VyUHVibGljS2V5AAAAAAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAGU3RyaW5nBAAAAAFzBQAAAAckbWF0Y2gwCQACWQAAAAEFAAAAAXMDCQAAAQAAAAIFAAAAByRtYXRjaDACAAAABFVuaXQFAAAABHVuaXQJAAACAAAAAQIAAAALTWF0Y2ggZXJyb3IBAAAAC211c3RNYW5hZ2VyAAAAAQAAAAFpBAAAAAJwZAkAAAIAAAABAgAAABFQZXJtaXNzaW9uIGRlbmllZAQAAAAHJG1hdGNoMAkBAAAAFm1hbmFnZXJQdWJsaWNLZXlPclVuaXQAAAAAAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAApCeXRlVmVjdG9yBAAAAAJwawUAAAAHJG1hdGNoMAMJAAAAAAAAAggFAAAAAWkAAAAPY2FsbGVyUHVibGljS2V5BQAAAAJwawYFAAAAAnBkAwkAAAEAAAACBQAAAAckbWF0Y2gwAgAAAARVbml0AwkAAAAAAAACCAUAAAABaQAAAAZjYWxsZXIFAAAABHRoaXMGBQAAAAJwZAkAAAIAAAABAgAAAAtNYXRjaCBlcnJvcgEAAAAJZ2V0QWRtaW5zAAAAAAQAAAAHJG1hdGNoMAkABCIAAAABCQEAAAAPa2V5QWRtaW5QdWJLZXlzAAAAAAMJAAABAAAAAgUAAAAHJG1hdGNoMAIAAAAGU3RyaW5nBAAAAAFzBQAAAAckbWF0Y2gwAwkAAAAAAAACCQABMQAAAAEFAAAAAXMAAAAAAAAAAAAFAAAAA25pbAkABLUAAAACBQAAAAFzBQAAAANTRVAFAAAAA25pbAEAAAAJbXVzdEFkbWluAAAAAQAAAAFpAwkBAAAAD2NvbnRhaW5zRWxlbWVudAAAAAIJAQAAAAlnZXRBZG1pbnMAAAAACQACWAAAAAEIBQAAAAFpAAAAD2NhbGxlclB1YmxpY0tleQYJAQAAAAttdXN0TWFuYWdlcgAAAAEFAAAAAWkBAAAACG11c3RQb29sAAAAAQAAAAFpAwkAAAAAAAACCAUAAAABaQAAAAZjYWxsZXIFAAAADHBvb2xDb250cmFjdAYJAAACAAAAAQIAAAAXY2FsbGVyIG11c3QgYmUgdGhlIHBvb2wAAAAHAAAAAWkBAAAAC2NvbnN0cnVjdG9yAAAAAQAAAAtwb29sQWRkcmVzcwQAAAALY2hlY2tDYWxsZXIJAQAAAAttdXN0TWFuYWdlcgAAAAEFAAAAAWkDCQAAAAAAAAIFAAAAC2NoZWNrQ2FsbGVyBQAAAAtjaGVja0NhbGxlcgkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAALa2V5UG9vbEFkZHIAAAAABQAAAAtwb29sQWRkcmVzcwUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgAAAAFpAQAAAApzZXRNYW5hZ2VyAAAAAQAAABdwZW5kaW5nTWFuYWdlclB1YmxpY0tleQQAAAALY2hlY2tDYWxsZXIJAQAAAAttdXN0TWFuYWdlcgAAAAEFAAAAAWkDCQAAAAAAAAIFAAAAC2NoZWNrQ2FsbGVyBQAAAAtjaGVja0NhbGxlcgQAAAAVY2hlY2tNYW5hZ2VyUHVibGljS2V5CQACWQAAAAEFAAAAF3BlbmRpbmdNYW5hZ2VyUHVibGljS2V5AwkAAAAAAAACBQAAABVjaGVja01hbmFnZXJQdWJsaWNLZXkFAAAAFWNoZWNrTWFuYWdlclB1YmxpY0tleQkABEwAAAACCQEAAAALU3RyaW5nRW50cnkAAAACCQEAAAAaa2V5UGVuZGluZ01hbmFnZXJQdWJsaWNLZXkAAAAABQAAABdwZW5kaW5nTWFuYWdlclB1YmxpY0tleQUAAAADbmlsCQAAAgAAAAECAAAAJFN0cmljdCB2YWx1ZSBpcyBub3QgZXF1YWwgdG8gaXRzZWxmLgkAAAIAAAABAgAAACRTdHJpY3QgdmFsdWUgaXMgbm90IGVxdWFsIHRvIGl0c2VsZi4AAAABaQEAAAAOY29uZmlybU1hbmFnZXIAAAAABAAAAAJwbQkBAAAAHXBlbmRpbmdNYW5hZ2VyUHVibGljS2V5T3JVbml0AAAAAAQAAAAFaGFzUE0DCQEAAAAJaXNEZWZpbmVkAAAAAQUAAAACcG0GCQAAAgAAAAECAAAAEk5vIHBlbmRpbmcgbWFuYWdlcgMJAAAAAAAAAgUAAAAFaGFzUE0FAAAABWhhc1BNBAAAAAdjaGVja1BNAwkAAAAAAAACCAUAAAABaQAAAA9jYWxsZXJQdWJsaWNLZXkJAQAAAAV2YWx1ZQAAAAEFAAAAAnBtBgkAAAIAAAABAgAAABtZb3UgYXJlIG5vdCBwZW5kaW5nIG1hbmFnZXIDCQAAAAAAAAIFAAAAB2NoZWNrUE0F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", "chainId": 84, "height": 2087469, "applicationStatus": "succeeded", "spentComplexity": 0 } View: original | compacted Prev: 8uMk9gcyqxTjm1s5RQa5WmmZnXwcQo1h8TbrHR3552Cc Next: AFS1mCWzWcF6e2753EkEzzhWHyvU1GVBGgf4WXFpQfxF Diff:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let SCALE8 = 8
5-
6-let MULT8 = 100000000
7-
8-let SCALE18 = 18
9-
10-let MULT18 = toBigInt(1000000000000000000)
11-
124 let SEP = "__"
135
14-let POOLWEIGHTMULT = MULT8
6+let EMPTY = ""
157
16-func asAnyList (val) = match val {
17- case valAnyLyst: List[Any] =>
18- valAnyLyst
19- case _ =>
20- throw("fail to cast into List[Any]")
21-}
8+let idxPoolAddress = 1
229
10+let idxLPAsId = 3
2311
24-func asInt (val) = match val {
25- case valInt: Int =>
26- valInt
27- case _ =>
28- throw("fail to cast into Int")
29-}
12+let idxAmAsId = 4
3013
14+let idxPrAsId = 5
3115
32-func asString (val) = match val {
33- case valStr: String =>
34- valStr
35- case _ =>
36- throw("fail to cast into Int")
37-}
16+let idxFactStakCntr = 1
3817
18+let delay = "%s__delay"
3919
40-func asByteVector (val) = match val {
41- case valBin: ByteVector =>
42- valBin
43- case _ =>
44- throw("fail to cast into Int")
45-}
46-
47-
48-func getStringOrFail (key) = valueOrErrorMessage(getString(key), (("mandatory this." + key) + " is not defined"))
49-
50-
51-func getStringByAddressOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
52-
53-
54-func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
55-
56-
57-func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
58-
59-
60-func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
61-
62-
63-func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULT18, toBigInt(origScaleMult))
64-
65-
66-func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULT18))
67-
68-
69-func keyFactoryAddress () = "%s%s__config__factoryAddress"
70-
71-
72-let IdxFactoryCfgStakingDapp = 1
73-
74-let IdxFactoryCfgBoostingDapp = 2
75-
76-let IdxFactoryCfgIdoDapp = 3
77-
78-let IdxFactoryCfgTeamDapp = 4
79-
80-let IdxFactoryCfgEmissionDapp = 5
81-
82-let IdxFactoryCfgRestDapp = 6
83-
84-let IdxFactoryCfgSlippageDapp = 7
85-
86-func keyFactoryCfg () = "%s__factoryConfig"
20+func keyFactCntr () = "%s__factoryContract"
8721
8822
8923 func keyManagerPublicKey () = "%s__managerPublicKey"
9226 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
9327
9428
95-func keyStablePoolAddonAddr () = "%s__stablePoolAddonAddr"
29+func keyPoolAddr () = "%s__poolAddress"
9630
9731
98-func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
32+func keyAmtAsset () = "%s__amountAsset"
9933
10034
101-func keyFactoryLpList () = "%s__lpTokensList"
35+func keyPriceAsset () = "%s__priceAsset"
10236
10337
104-func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
38+func keyAdminPubKeys () = "%s__adminPubKeys"
10539
10640
107-func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
41+func keyAmp () = "%s__amp"
10842
10943
110-func readLpList (factory) = split(valueOrElse(getString(factory, keyFactoryLpList()), ""), SEP)
44+func keyAmpHistory (height) = ("%s%d__amp__" + toString(height))
11145
11246
113-func readFactoryCfgOrFail (factory) = split(getStringByAddressOrFail(factory, keyFactoryCfg()), SEP)
47+func lastGetOrPutOneTknCall (caller) = makeString(["%s%s__lastGetOrPutOneTknCall", caller], SEP)
11448
11549
116-func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
50+func keyFactoryConfig () = "%s__factoryConfig"
11751
11852
119-func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
53+func keyPoolConfig (iAmtAs,iPrAs) = (((("%d%d%s__" + iAmtAs) + "__") + iPrAs) + "__config")
12054
12155
122-func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
56+func keyMappingsBaseAsset2internalId (bAStr) = ("%s%s%s__mappings__baseAsset2internalId__" + bAStr)
12357
12458
125-func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
59+func getStringOrFail (addr,key) = valueOrErrorMessage(getString(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
12660
12761
128-func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
62+func getIntOrFail (addr,key) = valueOrErrorMessage(getInteger(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
12963
13064
131-func keyEmissionStartBlock () = "%s%s__emission__startBlock"
65+let poolContract = addressFromStringValue(getStringOrFail(this, keyPoolAddr()))
13266
67+let factoryContract = addressFromStringValue(getStringOrFail(poolContract, keyFactCntr()))
13368
134-func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
135-
136-
137-func keyEmissionEndBlock () = "%s%s__emission__endBlock"
138-
139-
140-func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s__staked", userAddressStr, lpAssetIdStr], SEP)
141-
142-
143-func keyStakedTotal (lpAssetIdStr) = ("%s%s%s__staked__total__" + lpAssetIdStr)
144-
145-
146-func keyClaimedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimed", userAddressStr, lpAssetIdStr], SEP)
147-
148-
149-func keyClaimedByUserMinReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedMinReward", userAddressStr, lpAssetIdStr], SEP)
150-
151-
152-func keyClaimedByUserBoostReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedBoostReward", userAddressStr, lpAssetIdStr], SEP)
153-
154-
155-func keyClaimedTotal (lpAssetIdStr) = makeString(["%s%s%s__claimed", "total", lpAssetIdStr], SEP)
156-
157-
158-func readStaked (key) = valueOrElse(getInteger(this, key), 0)
159-
160-
161-func keyLastTotalLpBalance (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "bal"], SEP)
162-
163-
164-func keyLastUserLpBalance (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "bal"], SEP)
165-
166-
167-func keyTotalLpBalanceIntegral (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "balINT"], SEP)
168-
169-
170-func keyUserLpBalanceIntegral (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "balINT"], SEP)
171-
172-
173-func keyTotalLpBalanceIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "lastUpd"], SEP)
174-
175-
176-func keyUserLpBalanceIntegralLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "lastUpd"], SEP)
177-
178-
179-func keyWxPerLpIntegral (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpInt"], SEP)
180-
181-
182-func keyWxPerLpIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpIntH"], SEP)
183-
184-
185-func keyWxToClaimUser (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpInt"], SEP)
186-
187-
188-func keyWxPerLpIntegralUserLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpIntH"], SEP)
189-
190-
191-func keyWxPerLp (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLp"], SEP)
192-
193-
194-func keyWxPerLpX18 (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLpX18"], SEP)
195-
196-
197-func keyWxPerLpIntegralUserLast (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "uIntL"], SEP)
198-
199-
200-func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
201-
202-
203-func formatHistoryRecord (userAddress,lpAssetId,type,amount) = makeString(["%s%s%s%d%d%d", userAddress, lpAssetId, type, toString(height), toString(lastBlock.timestamp), toString(amount)], SEP)
204-
205-
206-func OperationHistoryEntry (type,userAddress,lpAssetId,amount,txId) = StringEntry(keyOperationHistoryRecord(type, userAddress, toBase58String(txId)), formatHistoryRecord(userAddress, lpAssetId, type, amount))
207-
208-
209-let factoryAddress = getStringOrFail(keyFactoryAddress())
210-
211-let factoryContract = addressFromStringValue(factoryAddress)
212-
213-let factoryCfg = readFactoryCfgOrFail(factoryContract)
214-
215-let emissionContract = getEmissionAddressOrFail(factoryCfg)
216-
217-let boostingContract = getBoostingAddressOrFail(factoryCfg)
218-
219-func calcWxPerLpIntegralUserLast (stakedByUser,wxPerLpIntegralUserLastUpdHeightOrZero,wxPerLpIntegralNew,wxPerLpIntegralUserLastKEY) = if (if ((wxPerLpIntegralUserLastUpdHeightOrZero == toBigInt(0)))
220- then (stakedByUser > toBigInt(0))
221- else false)
222- then toBigInt(0)
223- else if ((stakedByUser == toBigInt(0)))
224- then wxPerLpIntegralNew
225- else if (if ((wxPerLpIntegralUserLastUpdHeightOrZero > toBigInt(0)))
226- then (stakedByUser > toBigInt(0))
227- else false)
228- then toBigInt(getIntOrFail(this, wxPerLpIntegralUserLastKEY))
229- else throw("calcWxPerLpIntegralUserLast: unexpected state")
230-
231-
232-func refreshPoolINTEGRALS (lpAssetIdStr,poolAddressStr,lpDeltaAmount) = {
233- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
234- let stakedTotal = readStaked(stakedTotalKEY)
235- let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
236- let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
237- let MULT3 = 1000
238- let wxEmissionPerBlockX3 = (getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) * MULT3)
239- let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * 3))
240- let wxPerLpIntegralKEY = keyWxPerLpIntegral(lpAssetIdStr)
241- let wxPerLpIntegralLastUpdHeightKEY = keyWxPerLpIntegralLastUpdHeight(lpAssetIdStr)
242- let wxPerLpKEY = keyWxPerLp(lpAssetIdStr)
243- let wxPerLpIntegralLastUpdHeight = getIntOrDefault(this, wxPerLpIntegralLastUpdHeightKEY, emissionStartBlock)
244- let wxPerLpIntegral = getIntOrZero(this, wxPerLpIntegralKEY)
245- let wxPerLpOrZeroX3 = 0
246- let dh = max([(height - wxPerLpIntegralLastUpdHeight), 0])
247- let wxPerLpX3 = if ((wxPerLpOrZeroX3 != 0))
248- then wxPerLpOrZeroX3
249- else fraction(poolWxEmissionPerBlockX3, MULT8, stakedTotal)
250- let stakedTotalNew = (stakedTotal + lpDeltaAmount)
251- let wxPerLpIntegralNew = (toBigInt(wxPerLpIntegral) + (toBigInt(wxPerLpX3) * toBigInt(dh)))
252- let wxPerLpX3New = (poolWxEmissionPerBlockX3 / stakedTotalNew)
253- let wxPerLpIntegralLastUpdHeightNew = height
254- let debug = makeString([toString(wxPerLpIntegralNew), toString(dh), toString(wxPerLpX3), toString(stakedTotal), toString(poolWxEmissionPerBlockX3), toString(wxEmissionPerBlockX3), toString(poolWeight)], "::")
255- $Tuple3(wxPerLpIntegralNew, [StringEntry(wxPerLpIntegralKEY, toString(wxPerLpIntegralNew)), IntegerEntry(wxPerLpIntegralLastUpdHeightKEY, wxPerLpIntegralLastUpdHeightNew), IntegerEntry(wxPerLpKEY, wxPerLpX3New)], debug)
69+func getPoolConfig () = {
70+ let amtAs = getStringOrFail(poolContract, keyAmtAsset())
71+ let priceAs = getStringOrFail(poolContract, keyPriceAsset())
72+ let iPriceAs = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAs))
73+ let iAmtAs = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAs))
74+ split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAs), toString(iPriceAs))), SEP)
25675 }
25776
25877
259-func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
260- let $t01110811230 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
261- let wxPerLpIntegralNew = $t01110811230._1
262- let poolIntegralSTATE = $t01110811230._2
263- let poolDEBUG = $t01110811230._3
264- let MULT3 = 1000
265- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
266- let stakedByUser = readStaked(stakedByUserKEY)
267- let wxToClaimUserKEY = keyWxToClaimUser(lpAssetIdStr, userAddressStr)
268- let wxPerLpIntegralUserLastUpdHeightKEY = keyWxPerLpIntegralUserLastUpdHeight(lpAssetIdStr, userAddressStr)
269- let wxPerLpIntegralUserLastKEY = keyWxPerLpIntegralUserLast(lpAssetIdStr, userAddressStr)
270- let wxToClaimUser = getIntOrZero(this, wxToClaimUserKEY)
271- let wxPerLpIntegralUserLastUpdHeightOrZero = getIntOrZero(this, wxPerLpIntegralUserLastUpdHeightKEY)
272- let wxPerLpIntegralUserLast = calcWxPerLpIntegralUserLast(toBigInt(stakedByUser), toBigInt(wxPerLpIntegralUserLastUpdHeightOrZero), wxPerLpIntegralNew, wxPerLpIntegralUserLastKEY)
273- let MULT11 = (MULT8 * MULT3)
274- let wxToClaimUserNew = (toBigInt(wxToClaimUser) + fraction((wxPerLpIntegralNew - wxPerLpIntegralUserLast), toBigInt(stakedByUser), toBigInt(MULT11)))
275- let wxPerLpIntegralUserLastNew = wxPerLpIntegralNew
276- let wxPerLpIntegralUserLastUpdHeightNew = height
277- let debug = makeString([toString(wxToClaimUserNew), toString(wxPerLpIntegralUserLast), toString(stakedByUser), poolDEBUG, toString(height)], "::")
278- $Tuple3(wxToClaimUserNew, (poolIntegralSTATE ++ [StringEntry(wxToClaimUserKEY, toString(wxToClaimUserNew)), IntegerEntry(wxPerLpIntegralUserLastUpdHeightKEY, wxPerLpIntegralUserLastUpdHeightNew), StringEntry(wxPerLpIntegralUserLastKEY, toString(wxPerLpIntegralUserLastNew))]), debug)
279- }
78+func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
28079
28180
28281 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
316115 }
317116
318117
118+func getAdmins () = match getString(keyAdminPubKeys()) {
119+ case s: String =>
120+ if ((size(s) == 0))
121+ then nil
122+ else split(s, SEP)
123+ case _ =>
124+ nil
125+}
126+
127+
128+func mustAdmin (i) = if (containsElement(getAdmins(), toBase58String(i.callerPublicKey)))
129+ then true
130+ else mustManager(i)
131+
132+
133+func mustPool (i) = if ((i.caller == poolContract))
134+ then true
135+ else throw("caller must be the pool")
136+
137+
319138 @Callable(i)
320-func constructor (factoryAddressStr) = {
139+func constructor (poolAddress) = {
321140 let checkCaller = mustManager(i)
322141 if ((checkCaller == checkCaller))
323- then [StringEntry(keyFactoryAddress(), factoryAddressStr)]
142+ then [StringEntry(keyPoolAddr(), poolAddress)]
324143 else throw("Strict value is not equal to itself.")
325144 }
326145
362181
363182
364183 @Callable(i)
365-func stake () = if ((size(i.payments) != 1))
366- then throw("invalid payment - exact one payment must be attached")
367- else {
368- let pmt = i.payments[0]
369- let lpAssetId = value(pmt.assetId)
370- let lpAssetIdStr = toBase58String(lpAssetId)
371- let amount = pmt.amount
372- let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
373- let callerStr = toString(i.caller)
374- let userAddressStr = if ((callerStr == poolAddressStr))
375- then toString(i.originCaller)
376- else callerStr
377- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
378- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
379- let stakedByUser = readStaked(stakedByUserKEY)
380- let stakedTotal = readStaked(stakedTotalKEY)
381- let $t01522115338 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
382- let wxToClaimUserNew = $t01522115338._1
383- let integralSTATE = $t01522115338._2
384- let debug = $t01522115338._3
385- ([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE)
386- }
387-
388-
389-
390-@Callable(i)
391-func unstake (lpAssetIdStr,amount) = {
392- let lpAssetId = fromBase58String(lpAssetIdStr)
393- let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
394- let poolAddon = valueOrElse(getString(this, keyStablePoolAddonAddr()), poolAddressStr)
395- let callerStr = toString(i.caller)
396- let userAddressStr = if (if ((callerStr == poolAddressStr))
397- then true
398- else (callerStr == poolAddon))
399- then toString(i.originCaller)
400- else callerStr
401- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
402- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
403- let stakedByUser = readStaked(stakedByUserKEY)
404- let stakedTotal = readStaked(stakedTotalKEY)
405- let $t01647516593 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))
406- let wxToClaimUserNew = $t01647516593._1
407- let integralSTATE = $t01647516593._2
408- let debug = $t01647516593._3
409- if ((amount > stakedByUser))
410- then throw("passed amount is less then available")
411- else ([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE)
184+func setAdmins (adminPubKeys) = {
185+ let checkCaller = mustManager(i)
186+ if ((checkCaller == checkCaller))
187+ then [StringEntry(keyAdminPubKeys(), makeString(adminPubKeys, SEP))]
188+ else throw("Strict value is not equal to itself.")
412189 }
413190
414191
415192
416193 @Callable(i)
417-func claimWx (lpAssetIdStr) = {
418- let userAddress = i.caller
419- let userAddressStr = toString(i.caller)
420- let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
421- let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
422- let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr)
423- let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
424- let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr)
425- let claimedByUser = toBigInt(getIntOrZero(this, claimedByUserKEY))
426- let claimedByUserMinReward = toBigInt(getIntOrZero(this, claimedByUserMinRewardKEY))
427- let claimedByUserBoostReward = toBigInt(getIntOrZero(this, claimedByUserBoostRewardKEY))
428- let claimedTotal = toBigInt(getIntOrZero(this, claimedTotalKEY))
429- let $t01782917941 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
430- let wxToClaimUserNew = $t01782917941._1
431- let integralSTATE = $t01782917941._2
432- let debug = $t01782917941._3
433- let availableToClaim = (wxToClaimUserNew - claimedByUser)
434- if ((toBigInt(0) >= availableToClaim))
435- then throw("nothing to claim")
436- else {
437- let wxAmountBoostTotal = asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0])
438- let minRewardPart = availableToClaim
439- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
440- let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [minRewardPart], nil))[0])
441- let emitBoost = asAnyList(invoke(emissionContract, "emit", [boostRewardPart], nil))
442- if ((emitBoost == emitBoost))
194+func unstakeAndGetOneTkn (amount,exchResult,notUsed,outAmount,outAssetId,slippage) = {
195+ let checkPayments = if ((size(i.payments) != 0))
196+ then throw("No pmnts expd")
197+ else true
198+ if ((checkPayments == checkPayments))
199+ then {
200+ let cfg = getPoolConfig()
201+ let factoryCfg = getFactoryConfig()
202+ let lpAssetId = fromBase58String(cfg[idxLPAsId])
203+ let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
204+ let unstakeInv = invoke(staking, "unstake", [toBase58String(lpAssetId), amount], nil)
205+ if ((unstakeInv == unstakeInv))
443206 then {
444- let claimedByUserValue = (claimedByUser + availableToClaim)
445- let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
446- let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserMinReward + minRewardPart)
447- let claimedTotalPlusAvailableToClaim = (claimedByUserMinReward + minRewardPart)
448-[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)]
207+ let getOneTkn = reentrantInvoke(poolContract, "getOneTkn", [exchResult, notUsed, outAmount, outAssetId, slippage], [AttachedPayment(lpAssetId, amount)])
208+ if ((getOneTkn == getOneTkn))
209+ then nil
210+ else throw("Strict value is not equal to itself.")
449211 }
450212 else throw("Strict value is not equal to itself.")
451213 }
214+ else throw("Strict value is not equal to itself.")
452215 }
453216
454217
455218
456219 @Callable(i)
457-func claimWxREADONLY (lpAssetIdStr,userAddressStr) = {
458- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
459- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
460- let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
461- let stakedByUser = readStaked(stakedByUserKEY)
462- let stakedTotal = readStaked(stakedTotalKEY)
463- let claimedByUser = getIntOrZero(this, claimedByUserKEY)
464- let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
465- let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
466- let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
467- let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
468- let passedBlocks = if ((emissionStartBlock > height))
469- then 0
470- else (height - emissionStartBlock)
471- let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
472- let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
473- let $t02052820640 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
474- let wxToClaimUserNew = $t02052820640._1
475- let integralSTATE = $t02052820640._2
476- let debug = $t02052820640._3
477- let availableToClaim = (wxToClaimUserNew - toBigInt(claimedByUser))
478- let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
479- let wxAmountBoostTotal = asInt(boostInvResult[0])
480- let boostDebug = asString(boostInvResult[1])
481- let minRewardPart = availableToClaim
482- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
483- let totalReward = (minRewardPart + boostRewardPart)
484- $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), ((((debug + "::") + toString(userWxReward)) + "::BOOSTDEBUG::") + boostDebug)], SEP))
220+func setAmp (amp) = {
221+ let checkCaller = mustAdmin(i)
222+ if ((checkCaller == checkCaller))
223+ then {
224+ let res1 = invoke(poolContract, "setS", [keyAmp(), amp], nil)
225+ let res2 = invoke(poolContract, "setS", [keyAmpHistory(height), amp], nil)
226+ $Tuple2(nil, $Tuple2(res1, res2))
227+ }
228+ else throw("Strict value is not equal to itself.")
485229 }
486230
487231
488232
489233 @Callable(i)
490-func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
491- then throw("permissions denied")
492- else {
493- let $t02155321663 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
494- let wxPerLpIntegralNew = $t02155321663._1
495- let poolIntegralSTATE = $t02155321663._2
496- let poolDEBUG = $t02155321663._3
497- poolIntegralSTATE
498- }
234+func ensureCanGetOrPutOneTkn (caller) = {
235+ let checkCaller = mustPool(i)
236+ if ((checkCaller == checkCaller))
237+ then {
238+ let ensureCanPut = match getInteger(poolContract, lastGetOrPutOneTknCall(caller)) {
239+ case int: Int =>
240+ let permittedHeight = (int + value(getInteger(poolContract, delay)))
241+ let isReadyforPutOneTkn = (height >= permittedHeight)
242+ let needBlocks = (permittedHeight - height)
243+ if (isReadyforPutOneTkn)
244+ then true
245+ else throw(makeString(["you should wait", toString(needBlocks), "blocks more to perform the action"], " "))
246+ case _ =>
247+ true
248+ }
249+ if ((ensureCanPut == ensureCanPut))
250+ then {
251+ let setI = invoke(poolContract, "setI", [lastGetOrPutOneTknCall(caller), height], nil)
252+ if ((setI == setI))
253+ then nil
254+ else throw("Strict value is not equal to itself.")
255+ }
256+ else throw("Strict value is not equal to itself.")
257+ }
258+ else throw("Strict value is not equal to itself.")
259+ }
499260
500261
501262 @Verifier(tx)
Full:
OldNewDifferences
11 {-# STDLIB_VERSION 5 #-}
22 {-# SCRIPT_TYPE ACCOUNT #-}
33 {-# CONTENT_TYPE DAPP #-}
4-let SCALE8 = 8
5-
6-let MULT8 = 100000000
7-
8-let SCALE18 = 18
9-
10-let MULT18 = toBigInt(1000000000000000000)
11-
124 let SEP = "__"
135
14-let POOLWEIGHTMULT = MULT8
6+let EMPTY = ""
157
16-func asAnyList (val) = match val {
17- case valAnyLyst: List[Any] =>
18- valAnyLyst
19- case _ =>
20- throw("fail to cast into List[Any]")
21-}
8+let idxPoolAddress = 1
229
10+let idxLPAsId = 3
2311
24-func asInt (val) = match val {
25- case valInt: Int =>
26- valInt
27- case _ =>
28- throw("fail to cast into Int")
29-}
12+let idxAmAsId = 4
3013
14+let idxPrAsId = 5
3115
32-func asString (val) = match val {
33- case valStr: String =>
34- valStr
35- case _ =>
36- throw("fail to cast into Int")
37-}
16+let idxFactStakCntr = 1
3817
18+let delay = "%s__delay"
3919
40-func asByteVector (val) = match val {
41- case valBin: ByteVector =>
42- valBin
43- case _ =>
44- throw("fail to cast into Int")
45-}
46-
47-
48-func getStringOrFail (key) = valueOrErrorMessage(getString(key), (("mandatory this." + key) + " is not defined"))
49-
50-
51-func getStringByAddressOrFail (address,key) = valueOrErrorMessage(getString(address, key), (((("mandatory " + toString(address)) + ".") + key) + " is not defined"))
52-
53-
54-func getIntOrZero (address,key) = valueOrElse(getInteger(address, key), 0)
55-
56-
57-func getIntOrDefault (address,key,defaultVal) = valueOrElse(getInteger(address, key), defaultVal)
58-
59-
60-func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), (("mandatory this." + key) + " is not defined"))
61-
62-
63-func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), MULT18, toBigInt(origScaleMult))
64-
65-
66-func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), MULT18))
67-
68-
69-func keyFactoryAddress () = "%s%s__config__factoryAddress"
70-
71-
72-let IdxFactoryCfgStakingDapp = 1
73-
74-let IdxFactoryCfgBoostingDapp = 2
75-
76-let IdxFactoryCfgIdoDapp = 3
77-
78-let IdxFactoryCfgTeamDapp = 4
79-
80-let IdxFactoryCfgEmissionDapp = 5
81-
82-let IdxFactoryCfgRestDapp = 6
83-
84-let IdxFactoryCfgSlippageDapp = 7
85-
86-func keyFactoryCfg () = "%s__factoryConfig"
20+func keyFactCntr () = "%s__factoryContract"
8721
8822
8923 func keyManagerPublicKey () = "%s__managerPublicKey"
9024
9125
9226 func keyPendingManagerPublicKey () = "%s__pendingManagerPublicKey"
9327
9428
95-func keyStablePoolAddonAddr () = "%s__stablePoolAddonAddr"
29+func keyPoolAddr () = "%s__poolAddress"
9630
9731
98-func keyFactoryLp2AssetsMapping (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
32+func keyAmtAsset () = "%s__amountAsset"
9933
10034
101-func keyFactoryLpList () = "%s__lpTokensList"
35+func keyPriceAsset () = "%s__priceAsset"
10236
10337
104-func keyFactoryLpAssetToPoolContractAddress (lpAssetStr) = makeString(["%s%s%s", lpAssetStr, "mappings__lpAsset2PoolContract"], SEP)
38+func keyAdminPubKeys () = "%s__adminPubKeys"
10539
10640
107-func keyFactoryPoolWeight (contractAddress) = makeString(["%s%s", "poolWeight", contractAddress], SEP)
41+func keyAmp () = "%s__amp"
10842
10943
110-func readLpList (factory) = split(valueOrElse(getString(factory, keyFactoryLpList()), ""), SEP)
44+func keyAmpHistory (height) = ("%s%d__amp__" + toString(height))
11145
11246
113-func readFactoryCfgOrFail (factory) = split(getStringByAddressOrFail(factory, keyFactoryCfg()), SEP)
47+func lastGetOrPutOneTknCall (caller) = makeString(["%s%s__lastGetOrPutOneTknCall", caller], SEP)
11448
11549
116-func getBoostingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgBoostingDapp])
50+func keyFactoryConfig () = "%s__factoryConfig"
11751
11852
119-func getEmissionAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgEmissionDapp])
53+func keyPoolConfig (iAmtAs,iPrAs) = (((("%d%d%s__" + iAmtAs) + "__") + iPrAs) + "__config")
12054
12155
122-func getStakingAddressOrFail (factoryCfg) = addressFromStringValue(factoryCfg[IdxFactoryCfgStakingDapp])
56+func keyMappingsBaseAsset2internalId (bAStr) = ("%s%s%s__mappings__baseAsset2internalId__" + bAStr)
12357
12458
125-func keyEmissionRatePerBlockCurrent () = "%s%s__ratePerBlock__current"
59+func getStringOrFail (addr,key) = valueOrErrorMessage(getString(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
12660
12761
128-func keyEmissionRatePerBlockMaxCurrent () = "%s%s__ratePerBlockMax__current"
62+func getIntOrFail (addr,key) = valueOrErrorMessage(getInteger(addr, key), makeString(["mandatory ", toString(addr), ".", key, " not defined"], ""))
12963
13064
131-func keyEmissionStartBlock () = "%s%s__emission__startBlock"
65+let poolContract = addressFromStringValue(getStringOrFail(this, keyPoolAddr()))
13266
67+let factoryContract = addressFromStringValue(getStringOrFail(poolContract, keyFactCntr()))
13368
134-func keyEmissionDurationInBlocks () = "%s%s__emission__duration"
135-
136-
137-func keyEmissionEndBlock () = "%s%s__emission__endBlock"
138-
139-
140-func keyStakedByUser (userAddressStr,lpAssetIdStr) = makeString(["%s%s%s__staked", userAddressStr, lpAssetIdStr], SEP)
141-
142-
143-func keyStakedTotal (lpAssetIdStr) = ("%s%s%s__staked__total__" + lpAssetIdStr)
144-
145-
146-func keyClaimedByUser (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimed", userAddressStr, lpAssetIdStr], SEP)
147-
148-
149-func keyClaimedByUserMinReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedMinReward", userAddressStr, lpAssetIdStr], SEP)
150-
151-
152-func keyClaimedByUserBoostReward (lpAssetIdStr,userAddressStr) = makeString(["%s%s%s__claimedBoostReward", userAddressStr, lpAssetIdStr], SEP)
153-
154-
155-func keyClaimedTotal (lpAssetIdStr) = makeString(["%s%s%s__claimed", "total", lpAssetIdStr], SEP)
156-
157-
158-func readStaked (key) = valueOrElse(getInteger(this, key), 0)
159-
160-
161-func keyLastTotalLpBalance (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "bal"], SEP)
162-
163-
164-func keyLastUserLpBalance (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "bal"], SEP)
165-
166-
167-func keyTotalLpBalanceIntegral (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "balINT"], SEP)
168-
169-
170-func keyUserLpBalanceIntegral (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "balINT"], SEP)
171-
172-
173-func keyTotalLpBalanceIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s", lpAssetId, "total", "lastUpd"], SEP)
174-
175-
176-func keyUserLpBalanceIntegralLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s", lpAssetId, userAddress, "lastUpd"], SEP)
177-
178-
179-func keyWxPerLpIntegral (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpInt"], SEP)
180-
181-
182-func keyWxPerLpIntegralLastUpdHeight (lpAssetId) = makeString(["%s%s%s%s", lpAssetId, "common", "lpIntH"], SEP)
183-
184-
185-func keyWxToClaimUser (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpInt"], SEP)
186-
187-
188-func keyWxPerLpIntegralUserLastUpdHeight (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "lpIntH"], SEP)
189-
190-
191-func keyWxPerLp (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLp"], SEP)
192-
193-
194-func keyWxPerLpX18 (lpAssetId) = makeString(["%s", lpAssetId, "wxPerLpX18"], SEP)
195-
196-
197-func keyWxPerLpIntegralUserLast (lpAssetId,userAddress) = makeString(["%s%s%s%s", lpAssetId, userAddress, "uIntL"], SEP)
198-
199-
200-func keyOperationHistoryRecord (type,userAddress,txId58) = makeString(["%s%s%s%s__history", type, userAddress, txId58], SEP)
201-
202-
203-func formatHistoryRecord (userAddress,lpAssetId,type,amount) = makeString(["%s%s%s%d%d%d", userAddress, lpAssetId, type, toString(height), toString(lastBlock.timestamp), toString(amount)], SEP)
204-
205-
206-func OperationHistoryEntry (type,userAddress,lpAssetId,amount,txId) = StringEntry(keyOperationHistoryRecord(type, userAddress, toBase58String(txId)), formatHistoryRecord(userAddress, lpAssetId, type, amount))
207-
208-
209-let factoryAddress = getStringOrFail(keyFactoryAddress())
210-
211-let factoryContract = addressFromStringValue(factoryAddress)
212-
213-let factoryCfg = readFactoryCfgOrFail(factoryContract)
214-
215-let emissionContract = getEmissionAddressOrFail(factoryCfg)
216-
217-let boostingContract = getBoostingAddressOrFail(factoryCfg)
218-
219-func calcWxPerLpIntegralUserLast (stakedByUser,wxPerLpIntegralUserLastUpdHeightOrZero,wxPerLpIntegralNew,wxPerLpIntegralUserLastKEY) = if (if ((wxPerLpIntegralUserLastUpdHeightOrZero == toBigInt(0)))
220- then (stakedByUser > toBigInt(0))
221- else false)
222- then toBigInt(0)
223- else if ((stakedByUser == toBigInt(0)))
224- then wxPerLpIntegralNew
225- else if (if ((wxPerLpIntegralUserLastUpdHeightOrZero > toBigInt(0)))
226- then (stakedByUser > toBigInt(0))
227- else false)
228- then toBigInt(getIntOrFail(this, wxPerLpIntegralUserLastKEY))
229- else throw("calcWxPerLpIntegralUserLast: unexpected state")
230-
231-
232-func refreshPoolINTEGRALS (lpAssetIdStr,poolAddressStr,lpDeltaAmount) = {
233- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
234- let stakedTotal = readStaked(stakedTotalKEY)
235- let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
236- let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
237- let MULT3 = 1000
238- let wxEmissionPerBlockX3 = (getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent()) * MULT3)
239- let poolWxEmissionPerBlockX3 = fraction(wxEmissionPerBlockX3, poolWeight, (POOLWEIGHTMULT * 3))
240- let wxPerLpIntegralKEY = keyWxPerLpIntegral(lpAssetIdStr)
241- let wxPerLpIntegralLastUpdHeightKEY = keyWxPerLpIntegralLastUpdHeight(lpAssetIdStr)
242- let wxPerLpKEY = keyWxPerLp(lpAssetIdStr)
243- let wxPerLpIntegralLastUpdHeight = getIntOrDefault(this, wxPerLpIntegralLastUpdHeightKEY, emissionStartBlock)
244- let wxPerLpIntegral = getIntOrZero(this, wxPerLpIntegralKEY)
245- let wxPerLpOrZeroX3 = 0
246- let dh = max([(height - wxPerLpIntegralLastUpdHeight), 0])
247- let wxPerLpX3 = if ((wxPerLpOrZeroX3 != 0))
248- then wxPerLpOrZeroX3
249- else fraction(poolWxEmissionPerBlockX3, MULT8, stakedTotal)
250- let stakedTotalNew = (stakedTotal + lpDeltaAmount)
251- let wxPerLpIntegralNew = (toBigInt(wxPerLpIntegral) + (toBigInt(wxPerLpX3) * toBigInt(dh)))
252- let wxPerLpX3New = (poolWxEmissionPerBlockX3 / stakedTotalNew)
253- let wxPerLpIntegralLastUpdHeightNew = height
254- let debug = makeString([toString(wxPerLpIntegralNew), toString(dh), toString(wxPerLpX3), toString(stakedTotal), toString(poolWxEmissionPerBlockX3), toString(wxEmissionPerBlockX3), toString(poolWeight)], "::")
255- $Tuple3(wxPerLpIntegralNew, [StringEntry(wxPerLpIntegralKEY, toString(wxPerLpIntegralNew)), IntegerEntry(wxPerLpIntegralLastUpdHeightKEY, wxPerLpIntegralLastUpdHeightNew), IntegerEntry(wxPerLpKEY, wxPerLpX3New)], debug)
69+func getPoolConfig () = {
70+ let amtAs = getStringOrFail(poolContract, keyAmtAsset())
71+ let priceAs = getStringOrFail(poolContract, keyPriceAsset())
72+ let iPriceAs = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAs))
73+ let iAmtAs = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAs))
74+ split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAs), toString(iPriceAs))), SEP)
25675 }
25776
25877
259-func refreshINTEGRALS (lpAssetIdStr,userAddressStr,poolAddressStr,lpDeltaAmount) = {
260- let $t01110811230 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, lpDeltaAmount)
261- let wxPerLpIntegralNew = $t01110811230._1
262- let poolIntegralSTATE = $t01110811230._2
263- let poolDEBUG = $t01110811230._3
264- let MULT3 = 1000
265- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
266- let stakedByUser = readStaked(stakedByUserKEY)
267- let wxToClaimUserKEY = keyWxToClaimUser(lpAssetIdStr, userAddressStr)
268- let wxPerLpIntegralUserLastUpdHeightKEY = keyWxPerLpIntegralUserLastUpdHeight(lpAssetIdStr, userAddressStr)
269- let wxPerLpIntegralUserLastKEY = keyWxPerLpIntegralUserLast(lpAssetIdStr, userAddressStr)
270- let wxToClaimUser = getIntOrZero(this, wxToClaimUserKEY)
271- let wxPerLpIntegralUserLastUpdHeightOrZero = getIntOrZero(this, wxPerLpIntegralUserLastUpdHeightKEY)
272- let wxPerLpIntegralUserLast = calcWxPerLpIntegralUserLast(toBigInt(stakedByUser), toBigInt(wxPerLpIntegralUserLastUpdHeightOrZero), wxPerLpIntegralNew, wxPerLpIntegralUserLastKEY)
273- let MULT11 = (MULT8 * MULT3)
274- let wxToClaimUserNew = (toBigInt(wxToClaimUser) + fraction((wxPerLpIntegralNew - wxPerLpIntegralUserLast), toBigInt(stakedByUser), toBigInt(MULT11)))
275- let wxPerLpIntegralUserLastNew = wxPerLpIntegralNew
276- let wxPerLpIntegralUserLastUpdHeightNew = height
277- let debug = makeString([toString(wxToClaimUserNew), toString(wxPerLpIntegralUserLast), toString(stakedByUser), poolDEBUG, toString(height)], "::")
278- $Tuple3(wxToClaimUserNew, (poolIntegralSTATE ++ [StringEntry(wxToClaimUserKEY, toString(wxToClaimUserNew)), IntegerEntry(wxPerLpIntegralUserLastUpdHeightKEY, wxPerLpIntegralUserLastUpdHeightNew), StringEntry(wxPerLpIntegralUserLastKEY, toString(wxPerLpIntegralUserLastNew))]), debug)
279- }
78+func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP)
28079
28180
28281 func managerPublicKeyOrUnit () = match getString(keyManagerPublicKey()) {
28382 case s: String =>
28483 fromBase58String(s)
28584 case _: Unit =>
28685 unit
28786 case _ =>
28887 throw("Match error")
28988 }
29089
29190
29291 func pendingManagerPublicKeyOrUnit () = match getString(keyPendingManagerPublicKey()) {
29392 case s: String =>
29493 fromBase58String(s)
29594 case _: Unit =>
29695 unit
29796 case _ =>
29897 throw("Match error")
29998 }
30099
301100
302101 func mustManager (i) = {
303102 let pd = throw("Permission denied")
304103 match managerPublicKeyOrUnit() {
305104 case pk: ByteVector =>
306105 if ((i.callerPublicKey == pk))
307106 then true
308107 else pd
309108 case _: Unit =>
310109 if ((i.caller == this))
311110 then true
312111 else pd
313112 case _ =>
314113 throw("Match error")
315114 }
316115 }
317116
318117
118+func getAdmins () = match getString(keyAdminPubKeys()) {
119+ case s: String =>
120+ if ((size(s) == 0))
121+ then nil
122+ else split(s, SEP)
123+ case _ =>
124+ nil
125+}
126+
127+
128+func mustAdmin (i) = if (containsElement(getAdmins(), toBase58String(i.callerPublicKey)))
129+ then true
130+ else mustManager(i)
131+
132+
133+func mustPool (i) = if ((i.caller == poolContract))
134+ then true
135+ else throw("caller must be the pool")
136+
137+
319138 @Callable(i)
320-func constructor (factoryAddressStr) = {
139+func constructor (poolAddress) = {
321140 let checkCaller = mustManager(i)
322141 if ((checkCaller == checkCaller))
323- then [StringEntry(keyFactoryAddress(), factoryAddressStr)]
142+ then [StringEntry(keyPoolAddr(), poolAddress)]
324143 else throw("Strict value is not equal to itself.")
325144 }
326145
327146
328147
329148 @Callable(i)
330149 func setManager (pendingManagerPublicKey) = {
331150 let checkCaller = mustManager(i)
332151 if ((checkCaller == checkCaller))
333152 then {
334153 let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey)
335154 if ((checkManagerPublicKey == checkManagerPublicKey))
336155 then [StringEntry(keyPendingManagerPublicKey(), pendingManagerPublicKey)]
337156 else throw("Strict value is not equal to itself.")
338157 }
339158 else throw("Strict value is not equal to itself.")
340159 }
341160
342161
343162
344163 @Callable(i)
345164 func confirmManager () = {
346165 let pm = pendingManagerPublicKeyOrUnit()
347166 let hasPM = if (isDefined(pm))
348167 then true
349168 else throw("No pending manager")
350169 if ((hasPM == hasPM))
351170 then {
352171 let checkPM = if ((i.callerPublicKey == value(pm)))
353172 then true
354173 else throw("You are not pending manager")
355174 if ((checkPM == checkPM))
356175 then [StringEntry(keyManagerPublicKey(), toBase58String(value(pm))), DeleteEntry(keyPendingManagerPublicKey())]
357176 else throw("Strict value is not equal to itself.")
358177 }
359178 else throw("Strict value is not equal to itself.")
360179 }
361180
362181
363182
364183 @Callable(i)
365-func stake () = if ((size(i.payments) != 1))
366- then throw("invalid payment - exact one payment must be attached")
367- else {
368- let pmt = i.payments[0]
369- let lpAssetId = value(pmt.assetId)
370- let lpAssetIdStr = toBase58String(lpAssetId)
371- let amount = pmt.amount
372- let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
373- let callerStr = toString(i.caller)
374- let userAddressStr = if ((callerStr == poolAddressStr))
375- then toString(i.originCaller)
376- else callerStr
377- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
378- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
379- let stakedByUser = readStaked(stakedByUserKEY)
380- let stakedTotal = readStaked(stakedTotalKEY)
381- let $t01522115338 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, amount)
382- let wxToClaimUserNew = $t01522115338._1
383- let integralSTATE = $t01522115338._2
384- let debug = $t01522115338._3
385- ([IntegerEntry(stakedByUserKEY, (stakedByUser + amount)), IntegerEntry(stakedTotalKEY, (stakedTotal + amount)), OperationHistoryEntry("stake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE)
386- }
387-
388-
389-
390-@Callable(i)
391-func unstake (lpAssetIdStr,amount) = {
392- let lpAssetId = fromBase58String(lpAssetIdStr)
393- let poolAddressStr = valueOrErrorMessage(getString(factoryContract, keyFactoryLp2AssetsMapping(lpAssetIdStr)), ("unsupported lp asset " + lpAssetIdStr))
394- let poolAddon = valueOrElse(getString(this, keyStablePoolAddonAddr()), poolAddressStr)
395- let callerStr = toString(i.caller)
396- let userAddressStr = if (if ((callerStr == poolAddressStr))
397- then true
398- else (callerStr == poolAddon))
399- then toString(i.originCaller)
400- else callerStr
401- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
402- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
403- let stakedByUser = readStaked(stakedByUserKEY)
404- let stakedTotal = readStaked(stakedTotalKEY)
405- let $t01647516593 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, -(amount))
406- let wxToClaimUserNew = $t01647516593._1
407- let integralSTATE = $t01647516593._2
408- let debug = $t01647516593._3
409- if ((amount > stakedByUser))
410- then throw("passed amount is less then available")
411- else ([IntegerEntry(stakedByUserKEY, (stakedByUser - amount)), IntegerEntry(stakedTotalKEY, (stakedTotal - amount)), ScriptTransfer(i.caller, amount, lpAssetId), OperationHistoryEntry("unstake", userAddressStr, lpAssetIdStr, amount, i.transactionId)] ++ integralSTATE)
184+func setAdmins (adminPubKeys) = {
185+ let checkCaller = mustManager(i)
186+ if ((checkCaller == checkCaller))
187+ then [StringEntry(keyAdminPubKeys(), makeString(adminPubKeys, SEP))]
188+ else throw("Strict value is not equal to itself.")
412189 }
413190
414191
415192
416193 @Callable(i)
417-func claimWx (lpAssetIdStr) = {
418- let userAddress = i.caller
419- let userAddressStr = toString(i.caller)
420- let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
421- let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
422- let claimedTotalKEY = keyClaimedTotal(lpAssetIdStr)
423- let claimedByUserMinRewardKEY = keyClaimedByUserMinReward(lpAssetIdStr, userAddressStr)
424- let claimedByUserBoostRewardKEY = keyClaimedByUserBoostReward(lpAssetIdStr, userAddressStr)
425- let claimedByUser = toBigInt(getIntOrZero(this, claimedByUserKEY))
426- let claimedByUserMinReward = toBigInt(getIntOrZero(this, claimedByUserMinRewardKEY))
427- let claimedByUserBoostReward = toBigInt(getIntOrZero(this, claimedByUserBoostRewardKEY))
428- let claimedTotal = toBigInt(getIntOrZero(this, claimedTotalKEY))
429- let $t01782917941 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
430- let wxToClaimUserNew = $t01782917941._1
431- let integralSTATE = $t01782917941._2
432- let debug = $t01782917941._3
433- let availableToClaim = (wxToClaimUserNew - claimedByUser)
434- if ((toBigInt(0) >= availableToClaim))
435- then throw("nothing to claim")
436- else {
437- let wxAmountBoostTotal = asInt(asAnyList(invoke(boostingContract, "claimWxBoost", [lpAssetIdStr, userAddressStr], nil))[0])
438- let minRewardPart = availableToClaim
439- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
440- let wxAssetId = asByteVector(asAnyList(invoke(emissionContract, "emit", [minRewardPart], nil))[0])
441- let emitBoost = asAnyList(invoke(emissionContract, "emit", [boostRewardPart], nil))
442- if ((emitBoost == emitBoost))
194+func unstakeAndGetOneTkn (amount,exchResult,notUsed,outAmount,outAssetId,slippage) = {
195+ let checkPayments = if ((size(i.payments) != 0))
196+ then throw("No pmnts expd")
197+ else true
198+ if ((checkPayments == checkPayments))
199+ then {
200+ let cfg = getPoolConfig()
201+ let factoryCfg = getFactoryConfig()
202+ let lpAssetId = fromBase58String(cfg[idxLPAsId])
203+ let staking = valueOrErrorMessage(addressFromString(factoryCfg[idxFactStakCntr]), "Wr st addr")
204+ let unstakeInv = invoke(staking, "unstake", [toBase58String(lpAssetId), amount], nil)
205+ if ((unstakeInv == unstakeInv))
443206 then {
444- let claimedByUserValue = (claimedByUser + availableToClaim)
445- let claimedByUserMinRewardPlusPart = (claimedByUserMinReward + minRewardPart)
446- let claimedByUserBoostRewardPlusBoostRewardPart = (claimedByUserMinReward + minRewardPart)
447- let claimedTotalPlusAvailableToClaim = (claimedByUserMinReward + minRewardPart)
448-[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)]
207+ let getOneTkn = reentrantInvoke(poolContract, "getOneTkn", [exchResult, notUsed, outAmount, outAssetId, slippage], [AttachedPayment(lpAssetId, amount)])
208+ if ((getOneTkn == getOneTkn))
209+ then nil
210+ else throw("Strict value is not equal to itself.")
449211 }
450212 else throw("Strict value is not equal to itself.")
451213 }
214+ else throw("Strict value is not equal to itself.")
452215 }
453216
454217
455218
456219 @Callable(i)
457-func claimWxREADONLY (lpAssetIdStr,userAddressStr) = {
458- let stakedByUserKEY = keyStakedByUser(userAddressStr, lpAssetIdStr)
459- let stakedTotalKEY = keyStakedTotal(lpAssetIdStr)
460- let claimedByUserKEY = keyClaimedByUser(lpAssetIdStr, userAddressStr)
461- let stakedByUser = readStaked(stakedByUserKEY)
462- let stakedTotal = readStaked(stakedTotalKEY)
463- let claimedByUser = getIntOrZero(this, claimedByUserKEY)
464- let poolAddressStr = getStringByAddressOrFail(factoryContract, keyFactoryLpAssetToPoolContractAddress(lpAssetIdStr))
465- let poolWeight = getIntegerValue(factoryContract, keyFactoryPoolWeight(poolAddressStr))
466- let wxEmissionPerBlock = getIntOrFail(emissionContract, keyEmissionRatePerBlockCurrent())
467- let emissionStartBlock = getIntOrFail(emissionContract, keyEmissionStartBlock())
468- let passedBlocks = if ((emissionStartBlock > height))
469- then 0
470- else (height - emissionStartBlock)
471- let poolWxEmission = fraction((wxEmissionPerBlock * passedBlocks), poolWeight, POOLWEIGHTMULT)
472- let userWxReward = fraction(poolWxEmission, stakedByUser, stakedTotal)
473- let $t02052820640 = refreshINTEGRALS(lpAssetIdStr, userAddressStr, poolAddressStr, 0)
474- let wxToClaimUserNew = $t02052820640._1
475- let integralSTATE = $t02052820640._2
476- let debug = $t02052820640._3
477- let availableToClaim = (wxToClaimUserNew - toBigInt(claimedByUser))
478- let boostInvResult = asAnyList(invoke(boostingContract, "claimWxBoostREADONLY", [lpAssetIdStr, userAddressStr], nil))
479- let wxAmountBoostTotal = asInt(boostInvResult[0])
480- let boostDebug = asString(boostInvResult[1])
481- let minRewardPart = availableToClaim
482- let boostRewardPart = min([(minRewardPart * toBigInt(2)), toBigInt(wxAmountBoostTotal)])
483- let totalReward = (minRewardPart + boostRewardPart)
484- $Tuple2(nil, makeString(["%s%s%d%d%d%d%s", lpAssetIdStr, userAddressStr, toString(totalReward), toString(claimedByUser), toString(minRewardPart), toString(boostRewardPart), ((((debug + "::") + toString(userWxReward)) + "::BOOSTDEBUG::") + boostDebug)], SEP))
220+func setAmp (amp) = {
221+ let checkCaller = mustAdmin(i)
222+ if ((checkCaller == checkCaller))
223+ then {
224+ let res1 = invoke(poolContract, "setS", [keyAmp(), amp], nil)
225+ let res2 = invoke(poolContract, "setS", [keyAmpHistory(height), amp], nil)
226+ $Tuple2(nil, $Tuple2(res1, res2))
227+ }
228+ else throw("Strict value is not equal to itself.")
485229 }
486230
487231
488232
489233 @Callable(i)
490-func onModifyWeight (lpAssetIdStr,poolAddressStr) = if ((i.caller != factoryContract))
491- then throw("permissions denied")
492- else {
493- let $t02155321663 = refreshPoolINTEGRALS(lpAssetIdStr, poolAddressStr, 0)
494- let wxPerLpIntegralNew = $t02155321663._1
495- let poolIntegralSTATE = $t02155321663._2
496- let poolDEBUG = $t02155321663._3
497- poolIntegralSTATE
498- }
234+func ensureCanGetOrPutOneTkn (caller) = {
235+ let checkCaller = mustPool(i)
236+ if ((checkCaller == checkCaller))
237+ then {
238+ let ensureCanPut = match getInteger(poolContract, lastGetOrPutOneTknCall(caller)) {
239+ case int: Int =>
240+ let permittedHeight = (int + value(getInteger(poolContract, delay)))
241+ let isReadyforPutOneTkn = (height >= permittedHeight)
242+ let needBlocks = (permittedHeight - height)
243+ if (isReadyforPutOneTkn)
244+ then true
245+ else throw(makeString(["you should wait", toString(needBlocks), "blocks more to perform the action"], " "))
246+ case _ =>
247+ true
248+ }
249+ if ((ensureCanPut == ensureCanPut))
250+ then {
251+ let setI = invoke(poolContract, "setI", [lastGetOrPutOneTknCall(caller), height], nil)
252+ if ((setI == setI))
253+ then nil
254+ else throw("Strict value is not equal to itself.")
255+ }
256+ else throw("Strict value is not equal to itself.")
257+ }
258+ else throw("Strict value is not equal to itself.")
259+ }
499260
500261
501262 @Verifier(tx)
502263 func verify () = {
503264 let targetPublicKey = match managerPublicKeyOrUnit() {
504265 case pk: ByteVector =>
505266 pk
506267 case _: Unit =>
507268 tx.senderPublicKey
508269 case _ =>
509270 throw("Match error")
510271 }
511272 sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)
512273 }
513274

github/deemru/w8io/169f3d6 
77.79 ms