1 | | - | # no script |
---|
| 1 | + | {-# STDLIB_VERSION 6 #-} |
---|
| 2 | + | {-# SCRIPT_TYPE ACCOUNT #-} |
---|
| 3 | + | {-# CONTENT_TYPE DAPP #-} |
---|
| 4 | + | let lPdecimals = 8 |
---|
| 5 | + | |
---|
| 6 | + | let scale8 = 100000000 |
---|
| 7 | + | |
---|
| 8 | + | let scale8BigInt = toBigInt(100000000) |
---|
| 9 | + | |
---|
| 10 | + | let scale18 = toBigInt(1000000000000000000) |
---|
| 11 | + | |
---|
| 12 | + | let zeroBigInt = toBigInt(0) |
---|
| 13 | + | |
---|
| 14 | + | let big0 = toBigInt(0) |
---|
| 15 | + | |
---|
| 16 | + | let big1 = toBigInt(1) |
---|
| 17 | + | |
---|
| 18 | + | let big2 = toBigInt(2) |
---|
| 19 | + | |
---|
| 20 | + | let wavesString = "WAVES" |
---|
| 21 | + | |
---|
| 22 | + | let SEP = "__" |
---|
| 23 | + | |
---|
| 24 | + | let PoolActive = 1 |
---|
| 25 | + | |
---|
| 26 | + | let PoolPutDisabled = 2 |
---|
| 27 | + | |
---|
| 28 | + | let PoolMatcherDisabled = 3 |
---|
| 29 | + | |
---|
| 30 | + | let PoolShutdown = 4 |
---|
| 31 | + | |
---|
| 32 | + | let idxPoolAddress = 1 |
---|
| 33 | + | |
---|
| 34 | + | let idxPoolStatus = 2 |
---|
| 35 | + | |
---|
| 36 | + | let idxPoolLPAssetId = 3 |
---|
| 37 | + | |
---|
| 38 | + | let idxAmtAssetId = 4 |
---|
| 39 | + | |
---|
| 40 | + | let idxPriceAssetId = 5 |
---|
| 41 | + | |
---|
| 42 | + | let idxAmtAssetDcm = 6 |
---|
| 43 | + | |
---|
| 44 | + | let idxPriceAssetDcm = 7 |
---|
| 45 | + | |
---|
| 46 | + | let idxIAmtAssetId = 8 |
---|
| 47 | + | |
---|
| 48 | + | let idxIPriceAssetId = 9 |
---|
| 49 | + | |
---|
| 50 | + | let idxLPAssetDcm = 10 |
---|
| 51 | + | |
---|
| 52 | + | let idxPoolAmtAssetAmt = 1 |
---|
| 53 | + | |
---|
| 54 | + | let idxPoolPriceAssetAmt = 2 |
---|
| 55 | + | |
---|
| 56 | + | let idxPoolLPAssetAmt = 3 |
---|
| 57 | + | |
---|
| 58 | + | let idxFactoryStakingContract = 1 |
---|
| 59 | + | |
---|
| 60 | + | let idxFactorySlippageContract = 7 |
---|
| 61 | + | |
---|
| 62 | + | func toX18 (origVal,origScaleMult) = fraction(toBigInt(origVal), scale18, toBigInt(origScaleMult)) |
---|
| 63 | + | |
---|
| 64 | + | |
---|
| 65 | + | func toX18BigInt (origVal,origScaleMult) = fraction(origVal, scale18, origScaleMult) |
---|
| 66 | + | |
---|
| 67 | + | |
---|
| 68 | + | func fromX18 (val,resultScaleMult) = toInt(fraction(val, toBigInt(resultScaleMult), scale18)) |
---|
| 69 | + | |
---|
| 70 | + | |
---|
| 71 | + | func fromX18Round (val,resultScaleMult,round) = toInt(fraction(val, toBigInt(resultScaleMult), scale18, round)) |
---|
| 72 | + | |
---|
| 73 | + | |
---|
| 74 | + | func toScale (amt,resScale,curScale) = fraction(amt, resScale, curScale) |
---|
| 75 | + | |
---|
| 76 | + | |
---|
| 77 | + | func abs (val) = if ((0 > val)) |
---|
| 78 | + | then -(val) |
---|
| 79 | + | else val |
---|
| 80 | + | |
---|
| 81 | + | |
---|
| 82 | + | func absBigInt (val) = if ((zeroBigInt > val)) |
---|
| 83 | + | then -(val) |
---|
| 84 | + | else val |
---|
| 85 | + | |
---|
| 86 | + | |
---|
| 87 | + | func swapContract () = "%s__swapContract" |
---|
| 88 | + | |
---|
| 89 | + | |
---|
| 90 | + | func fc () = "%s__factoryContract" |
---|
| 91 | + | |
---|
| 92 | + | |
---|
| 93 | + | func mpk () = "%s__managerPublicKey" |
---|
| 94 | + | |
---|
| 95 | + | |
---|
| 96 | + | func pmpk () = "%s__pendingManagerPublicKey" |
---|
| 97 | + | |
---|
| 98 | + | |
---|
| 99 | + | func pl () = "%s%s__price__last" |
---|
| 100 | + | |
---|
| 101 | + | |
---|
| 102 | + | func ph (h,timestamp) = makeString(["%s%s%d%d__price__history", toString(h), toString(timestamp)], SEP) |
---|
| 103 | + | |
---|
| 104 | + | |
---|
| 105 | + | func pau (userAddress,txId) = ((("%s%s%s__P__" + userAddress) + "__") + txId) |
---|
| 106 | + | |
---|
| 107 | + | |
---|
| 108 | + | func gau (userAddress,txId) = ((("%s%s%s__G__" + userAddress) + "__") + txId) |
---|
| 109 | + | |
---|
| 110 | + | |
---|
| 111 | + | func aa () = "%s__amountAsset" |
---|
| 112 | + | |
---|
| 113 | + | |
---|
| 114 | + | func pa () = "%s__priceAsset" |
---|
| 115 | + | |
---|
| 116 | + | |
---|
| 117 | + | let keyFee = "%s__fee" |
---|
| 118 | + | |
---|
| 119 | + | let feeDefault = fraction(10, scale8, 10000) |
---|
| 120 | + | |
---|
| 121 | + | let fee = valueOrElse(getInteger(this, keyFee), feeDefault) |
---|
| 122 | + | |
---|
| 123 | + | let keyKLp = makeString(["%s", "kLp"], SEP) |
---|
| 124 | + | |
---|
| 125 | + | let keyKLpRefreshedHeight = makeString(["%s", "kLpRefreshedHeight"], SEP) |
---|
| 126 | + | |
---|
| 127 | + | let keyKLpRefreshDelay = makeString(["%s", "refreshKLpDelay"], SEP) |
---|
| 128 | + | |
---|
| 129 | + | let kLpRefreshDelayDefault = 30 |
---|
| 130 | + | |
---|
| 131 | + | let kLpRefreshDelay = valueOrElse(getInteger(this, keyKLpRefreshDelay), kLpRefreshDelayDefault) |
---|
| 132 | + | |
---|
| 133 | + | func keyFactoryConfig () = "%s__factoryConfig" |
---|
| 134 | + | |
---|
| 135 | + | |
---|
| 136 | + | func keyMatcherPub () = "%s%s__matcher__publicKey" |
---|
| 137 | + | |
---|
| 138 | + | |
---|
| 139 | + | func keyMappingPoolContractAddressToPoolAssets (poolContractAddress) = (("%s%s%s__" + poolContractAddress) + "__mappings__poolContract2LpAsset") |
---|
| 140 | + | |
---|
| 141 | + | |
---|
| 142 | + | func keyPoolConfig (iAmtAsset,iPriceAsset) = (((("%d%d%s__" + iAmtAsset) + "__") + iPriceAsset) + "__config") |
---|
| 143 | + | |
---|
| 144 | + | |
---|
| 145 | + | func keyMappingsBaseAsset2internalId (baseAssetStr) = ("%s%s%s__mappings__baseAsset2internalId__" + baseAssetStr) |
---|
| 146 | + | |
---|
| 147 | + | |
---|
| 148 | + | func keyAllPoolsShutdown () = "%s__shutdown" |
---|
| 149 | + | |
---|
| 150 | + | |
---|
| 151 | + | func keyPoolWeight (contractAddress) = ("%s%s__poolWeight__" + contractAddress) |
---|
| 152 | + | |
---|
| 153 | + | |
---|
| 154 | + | func keyAllowedLpScriptHash () = "%s__allowedLpScriptHash" |
---|
| 155 | + | |
---|
| 156 | + | |
---|
| 157 | + | let keyFeeCollectorAddress = "%s__feeCollectorAddress" |
---|
| 158 | + | |
---|
| 159 | + | func throwOrderError (orderValid,orderValidInfo,senderValid,matcherValid) = throw((((((((("order validation failed: orderValid=" + toString(orderValid)) + " (") + orderValidInfo) + ")") + " senderValid=") + toString(senderValid)) + " matcherValid=") + toString(matcherValid))) |
---|
| 160 | + | |
---|
| 161 | + | |
---|
| 162 | + | func getStringOrFail (address,key) = valueOrErrorMessage(getString(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], "")) |
---|
| 163 | + | |
---|
| 164 | + | |
---|
| 165 | + | func getIntOrFail (address,key) = valueOrErrorMessage(getInteger(address, key), makeString(["mandatory ", toString(address), ".", key, " is not defined"], "")) |
---|
| 166 | + | |
---|
| 167 | + | |
---|
| 168 | + | func throwErr (msg) = throw(makeString(["lp.ride:", msg], " ")) |
---|
| 169 | + | |
---|
| 170 | + | |
---|
| 171 | + | func fmtErr (msg) = makeString(["lp.ride:", msg], " ") |
---|
| 172 | + | |
---|
| 173 | + | |
---|
| 174 | + | let factoryContract = addressFromStringValue(getStringOrFail(this, fc())) |
---|
| 175 | + | |
---|
| 176 | + | let feeCollectorAddress = addressFromStringValue(getStringOrFail(factoryContract, keyFeeCollectorAddress)) |
---|
| 177 | + | |
---|
| 178 | + | let inFee = { |
---|
| 179 | + | let @ = invoke(factoryContract, "getInFeeREADONLY", [toString(this)], nil) |
---|
| 180 | + | if ($isInstanceOf(@, "Int")) |
---|
| 181 | + | then @ |
---|
| 182 | + | else throw(($getType(@) + " couldn't be cast to Int")) |
---|
| 183 | + | } |
---|
| 184 | + | |
---|
| 185 | + | let outFee = { |
---|
| 186 | + | let @ = invoke(factoryContract, "getOutFeeREADONLY", [toString(this)], nil) |
---|
| 187 | + | if ($isInstanceOf(@, "Int")) |
---|
| 188 | + | then @ |
---|
| 189 | + | else throw(($getType(@) + " couldn't be cast to Int")) |
---|
| 190 | + | } |
---|
| 191 | + | |
---|
| 192 | + | func isGlobalShutdown () = valueOrElse(getBoolean(factoryContract, keyAllPoolsShutdown()), false) |
---|
| 193 | + | |
---|
| 194 | + | |
---|
| 195 | + | func getMatcherPubOrFail () = fromBase58String(getStringOrFail(factoryContract, keyMatcherPub())) |
---|
| 196 | + | |
---|
| 197 | + | |
---|
| 198 | + | func getPoolConfig () = { |
---|
| 199 | + | let amtAsset = getStringOrFail(this, aa()) |
---|
| 200 | + | let priceAsset = getStringOrFail(this, pa()) |
---|
| 201 | + | let iPriceAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(priceAsset)) |
---|
| 202 | + | let iAmtAsset = getIntOrFail(factoryContract, keyMappingsBaseAsset2internalId(amtAsset)) |
---|
| 203 | + | split(getStringOrFail(factoryContract, keyPoolConfig(toString(iAmtAsset), toString(iPriceAsset))), SEP) |
---|
| 204 | + | } |
---|
| 205 | + | |
---|
| 206 | + | |
---|
| 207 | + | func parseAssetId (input) = if ((input == wavesString)) |
---|
| 208 | + | then unit |
---|
| 209 | + | else fromBase58String(input) |
---|
| 210 | + | |
---|
| 211 | + | |
---|
| 212 | + | func assetIdToString (input) = if ((input == unit)) |
---|
| 213 | + | then wavesString |
---|
| 214 | + | else toBase58String(value(input)) |
---|
| 215 | + | |
---|
| 216 | + | |
---|
| 217 | + | func parsePoolConfig (poolConfig) = $Tuple7(addressFromStringValue(poolConfig[idxPoolAddress]), parseIntValue(poolConfig[idxPoolStatus]), fromBase58String(poolConfig[idxPoolLPAssetId]), parseAssetId(poolConfig[idxAmtAssetId]), parseAssetId(poolConfig[idxPriceAssetId]), parseIntValue(poolConfig[idxAmtAssetDcm]), parseIntValue(poolConfig[idxPriceAssetDcm])) |
---|
| 218 | + | |
---|
| 219 | + | |
---|
| 220 | + | let poolConfigParsed = parsePoolConfig(getPoolConfig()) |
---|
| 221 | + | |
---|
| 222 | + | let $t086758849 = poolConfigParsed |
---|
| 223 | + | |
---|
| 224 | + | let cfgPoolAddress = $t086758849._1 |
---|
| 225 | + | |
---|
| 226 | + | let cfgPoolStatus = $t086758849._2 |
---|
| 227 | + | |
---|
| 228 | + | let cfgLpAssetId = $t086758849._3 |
---|
| 229 | + | |
---|
| 230 | + | let cfgAmountAssetId = $t086758849._4 |
---|
| 231 | + | |
---|
| 232 | + | let cfgPriceAssetId = $t086758849._5 |
---|
| 233 | + | |
---|
| 234 | + | let cfgAmountAssetDecimals = $t086758849._6 |
---|
| 235 | + | |
---|
| 236 | + | let cfgPriceAssetDecimals = $t086758849._7 |
---|
| 237 | + | |
---|
| 238 | + | func getFactoryConfig () = split(getStringOrFail(factoryContract, keyFactoryConfig()), SEP) |
---|
| 239 | + | |
---|
| 240 | + | |
---|
| 241 | + | let stakingContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactoryStakingContract]), "incorrect staking address") |
---|
| 242 | + | |
---|
| 243 | + | let slippageContract = valueOrErrorMessage(addressFromString(getFactoryConfig()[idxFactorySlippageContract]), "incorrect staking address") |
---|
| 244 | + | |
---|
| 245 | + | func dataPutActionInfo (inAmtAssetAmt,inPriceAssetAmt,outLpAmt,price,slippageTolerancePassedByUser,slippageToleranceReal,txHeight,txTimestamp,slipageAmtAssetAmt,slipagePriceAssetAmt) = makeString(["%d%d%d%d%d%d%d%d%d%d", toString(inAmtAssetAmt), toString(inPriceAssetAmt), toString(outLpAmt), toString(price), toString(slippageTolerancePassedByUser), toString(slippageToleranceReal), toString(txHeight), toString(txTimestamp), toString(slipageAmtAssetAmt), toString(slipagePriceAssetAmt)], SEP) |
---|
| 246 | + | |
---|
| 247 | + | |
---|
| 248 | + | func dataGetActionInfo (outAmtAssetAmt,outPriceAssetAmt,inLpAmt,price,txHeight,txTimestamp) = makeString(["%d%d%d%d%d%d", toString(outAmtAssetAmt), toString(outPriceAssetAmt), toString(inLpAmt), toString(price), toString(txHeight), toString(txTimestamp)], SEP) |
---|
| 249 | + | |
---|
| 250 | + | |
---|
| 251 | + | func getAccBalance (assetId) = if ((assetId == "WAVES")) |
---|
| 252 | + | then wavesBalance(this).available |
---|
| 253 | + | else assetBalance(this, fromBase58String(assetId)) |
---|
| 254 | + | |
---|
| 255 | + | |
---|
| 256 | + | func calcPriceBigInt (prAmtX18,amAmtX18) = fraction(prAmtX18, scale18, amAmtX18) |
---|
| 257 | + | |
---|
| 258 | + | |
---|
| 259 | + | func calcPriceBigIntRound (prAmtX18,amAmtX18,round) = fraction(prAmtX18, scale18, amAmtX18, round) |
---|
| 260 | + | |
---|
| 261 | + | |
---|
| 262 | + | func privateCalcPrice (amAssetDcm,prAssetDcm,amAmt,prAmt) = { |
---|
| 263 | + | let amtAssetAmtX18 = toX18(amAmt, amAssetDcm) |
---|
| 264 | + | let priceAssetAmtX18 = toX18(prAmt, prAssetDcm) |
---|
| 265 | + | calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18) |
---|
| 266 | + | } |
---|
| 267 | + | |
---|
| 268 | + | |
---|
| 269 | + | func calcPrices (amAmt,prAmt,lpAmt) = { |
---|
| 270 | + | let cfg = getPoolConfig() |
---|
| 271 | + | let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm]) |
---|
| 272 | + | let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm]) |
---|
| 273 | + | let priceX18 = privateCalcPrice(amtAssetDcm, priceAssetDcm, amAmt, prAmt) |
---|
| 274 | + | let amAmtX18 = toX18(amAmt, amtAssetDcm) |
---|
| 275 | + | let prAmtX18 = toX18(prAmt, priceAssetDcm) |
---|
| 276 | + | let lpAmtX18 = toX18(lpAmt, scale8) |
---|
| 277 | + | let lpPriceInAmAssetX18 = calcPriceBigInt(amAmtX18, lpAmtX18) |
---|
| 278 | + | let lpPriceInPrAssetX18 = calcPriceBigInt(prAmtX18, lpAmtX18) |
---|
| 279 | + | [priceX18, lpPriceInAmAssetX18, lpPriceInPrAssetX18] |
---|
| 280 | + | } |
---|
| 281 | + | |
---|
| 282 | + | |
---|
| 283 | + | func calculatePrices (amAmt,prAmt,lpAmt) = { |
---|
| 284 | + | let prices = calcPrices(amAmt, prAmt, lpAmt) |
---|
| 285 | + | [fromX18(prices[0], scale8), fromX18(prices[1], scale8), fromX18(prices[2], scale8)] |
---|
| 286 | + | } |
---|
| 287 | + | |
---|
| 288 | + | |
---|
| 289 | + | func estimateGetOperation (txId58,pmtAssetId,pmtLpAmt,userAddress) = { |
---|
| 290 | + | let cfg = getPoolConfig() |
---|
| 291 | + | let lpAssetId = cfg[idxPoolLPAssetId] |
---|
| 292 | + | let amAssetId = cfg[idxAmtAssetId] |
---|
| 293 | + | let prAssetId = cfg[idxPriceAssetId] |
---|
| 294 | + | let amAssetDcm = parseIntValue(cfg[idxAmtAssetDcm]) |
---|
| 295 | + | let prAssetDcm = parseIntValue(cfg[idxPriceAssetDcm]) |
---|
| 296 | + | let poolStatus = cfg[idxPoolStatus] |
---|
| 297 | + | let lpEmission = valueOrErrorMessage(assetInfo(fromBase58String(lpAssetId)), (("Asset " + lpAssetId) + " doesn't exist")).quantity |
---|
| 298 | + | if ((lpAssetId != pmtAssetId)) |
---|
| 299 | + | then throw("Invalid asset passed.") |
---|
| 300 | + | else { |
---|
| 301 | + | let amBalance = getAccBalance(amAssetId) |
---|
| 302 | + | let amBalanceX18 = toX18(amBalance, amAssetDcm) |
---|
| 303 | + | let prBalance = getAccBalance(prAssetId) |
---|
| 304 | + | let prBalanceX18 = toX18(prBalance, prAssetDcm) |
---|
| 305 | + | let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18) |
---|
| 306 | + | let curPrice = fromX18(curPriceX18, scale8) |
---|
| 307 | + | let pmtLpAmtX18 = toX18(pmtLpAmt, scale8) |
---|
| 308 | + | let lpEmissionX18 = toX18(lpEmission, scale8) |
---|
| 309 | + | let outAmAmtX18 = fraction(amBalanceX18, pmtLpAmtX18, lpEmissionX18) |
---|
| 310 | + | let outPrAmtX18 = fraction(prBalanceX18, pmtLpAmtX18, lpEmissionX18) |
---|
| 311 | + | let outAmAmt = fromX18Round(outAmAmtX18, amAssetDcm, FLOOR) |
---|
| 312 | + | let outPrAmt = fromX18Round(outPrAmtX18, prAssetDcm, FLOOR) |
---|
| 313 | + | let state = if ((txId58 == "")) |
---|
| 314 | + | then nil |
---|
| 315 | + | else [ScriptTransfer(userAddress, outAmAmt, if ((amAssetId == "WAVES")) |
---|
| 316 | + | then unit |
---|
| 317 | + | else fromBase58String(amAssetId)), ScriptTransfer(userAddress, outPrAmt, if ((prAssetId == "WAVES")) |
---|
| 318 | + | then unit |
---|
| 319 | + | else fromBase58String(prAssetId)), StringEntry(gau(toString(userAddress), txId58), dataGetActionInfo(outAmAmt, outPrAmt, pmtLpAmt, curPrice, height, lastBlock.timestamp)), IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice)] |
---|
| 320 | + | $Tuple10(outAmAmt, outPrAmt, amAssetId, prAssetId, amBalance, prBalance, lpEmission, curPriceX18, poolStatus, state) |
---|
| 321 | + | } |
---|
| 322 | + | } |
---|
| 323 | + | |
---|
| 324 | + | |
---|
| 325 | + | func estimatePutOperation (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = { |
---|
| 326 | + | let cfg = getPoolConfig() |
---|
| 327 | + | let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId]) |
---|
| 328 | + | let amAssetIdStr = cfg[idxAmtAssetId] |
---|
| 329 | + | let prAssetIdStr = cfg[idxPriceAssetId] |
---|
| 330 | + | let iAmtAssetId = cfg[idxIAmtAssetId] |
---|
| 331 | + | let iPriceAssetId = cfg[idxIPriceAssetId] |
---|
| 332 | + | let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm]) |
---|
| 333 | + | let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm]) |
---|
| 334 | + | let poolStatus = cfg[idxPoolStatus] |
---|
| 335 | + | let lpEmission = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity |
---|
| 336 | + | let inAmAssetIdStr = toBase58String(valueOrElse(inAmAssetId, fromBase58String("WAVES"))) |
---|
| 337 | + | let inPrAssetIdStr = toBase58String(valueOrElse(inPrAssetId, fromBase58String("WAVES"))) |
---|
| 338 | + | if (if ((amAssetIdStr != inAmAssetIdStr)) |
---|
| 339 | + | then true |
---|
| 340 | + | else (prAssetIdStr != inPrAssetIdStr)) |
---|
| 341 | + | then throw("Invalid amt or price asset passed.") |
---|
| 342 | + | else { |
---|
| 343 | + | let amBalance = if (isEvaluate) |
---|
| 344 | + | then getAccBalance(amAssetIdStr) |
---|
| 345 | + | else (getAccBalance(amAssetIdStr) - inAmAssetAmt) |
---|
| 346 | + | let prBalance = if (isEvaluate) |
---|
| 347 | + | then getAccBalance(prAssetIdStr) |
---|
| 348 | + | else (getAccBalance(prAssetIdStr) - inPrAssetAmt) |
---|
| 349 | + | let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm) |
---|
| 350 | + | let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm) |
---|
| 351 | + | let userPriceX18 = calcPriceBigInt(inPrAssetAmtX18, inAmAssetAmtX18) |
---|
| 352 | + | let amBalanceX18 = toX18(amBalance, amtAssetDcm) |
---|
| 353 | + | let prBalanceX18 = toX18(prBalance, priceAssetDcm) |
---|
| 354 | + | let res = if ((lpEmission == 0)) |
---|
| 355 | + | then { |
---|
| 356 | + | let curPriceX18 = zeroBigInt |
---|
| 357 | + | let slippageX18 = zeroBigInt |
---|
| 358 | + | let lpAmtX18 = pow((inAmAssetAmtX18 * inPrAssetAmtX18), 0, toBigInt(5), 1, 0, DOWN) |
---|
| 359 | + | $Tuple5(fromX18(lpAmtX18, scale8), fromX18(inAmAssetAmtX18, amtAssetDcm), fromX18(inPrAssetAmtX18, priceAssetDcm), calcPriceBigInt((prBalanceX18 + inPrAssetAmtX18), (amBalanceX18 + inAmAssetAmtX18)), slippageX18) |
---|
| 360 | + | } |
---|
| 361 | + | else { |
---|
| 362 | + | let curPriceX18 = calcPriceBigInt(prBalanceX18, amBalanceX18) |
---|
| 363 | + | let slippageX18 = fraction(absBigInt((curPriceX18 - userPriceX18)), scale18, curPriceX18) |
---|
| 364 | + | let slippageToleranceX18 = toX18(slippageTolerance, scale8) |
---|
| 365 | + | if (if ((curPriceX18 != zeroBigInt)) |
---|
| 366 | + | then (slippageX18 > slippageToleranceX18) |
---|
| 367 | + | else false) |
---|
| 368 | + | then throw(((("Price slippage " + toString(slippageX18)) + " exceeded the passed limit of ") + toString(slippageToleranceX18))) |
---|
| 369 | + | else { |
---|
| 370 | + | let lpEmissionX18 = toX18(lpEmission, scale8) |
---|
| 371 | + | let prViaAmX18 = fraction(inAmAssetAmtX18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, CEILING), scale18, CEILING) |
---|
| 372 | + | let amViaPrX18 = fraction(inPrAssetAmtX18, scale18, calcPriceBigIntRound(prBalanceX18, amBalanceX18, FLOOR), CEILING) |
---|
| 373 | + | let expectedAmts = if ((prViaAmX18 > inPrAssetAmtX18)) |
---|
| 374 | + | then $Tuple2(amViaPrX18, inPrAssetAmtX18) |
---|
| 375 | + | else $Tuple2(inAmAssetAmtX18, prViaAmX18) |
---|
| 376 | + | let expAmtAssetAmtX18 = expectedAmts._1 |
---|
| 377 | + | let expPriceAssetAmtX18 = expectedAmts._2 |
---|
| 378 | + | let lpAmtX18 = fraction(lpEmissionX18, expPriceAssetAmtX18, prBalanceX18, FLOOR) |
---|
| 379 | + | $Tuple5(fromX18Round(lpAmtX18, scale8, FLOOR), fromX18Round(expAmtAssetAmtX18, amtAssetDcm, CEILING), fromX18Round(expPriceAssetAmtX18, priceAssetDcm, CEILING), curPriceX18, slippageX18) |
---|
| 380 | + | } |
---|
| 381 | + | } |
---|
| 382 | + | let calcLpAmt = res._1 |
---|
| 383 | + | let calcAmAssetPmt = res._2 |
---|
| 384 | + | let calcPrAssetPmt = res._3 |
---|
| 385 | + | let curPrice = fromX18(res._4, scale8) |
---|
| 386 | + | let slippageCalc = fromX18(res._5, scale8) |
---|
| 387 | + | if ((0 >= calcLpAmt)) |
---|
| 388 | + | then throw("Invalid calculations. LP calculated is less than zero.") |
---|
| 389 | + | else { |
---|
| 390 | + | let emitLpAmt = if (!(emitLp)) |
---|
| 391 | + | then 0 |
---|
| 392 | + | else calcLpAmt |
---|
| 393 | + | let amDiff = (inAmAssetAmt - calcAmAssetPmt) |
---|
| 394 | + | let prDiff = (inPrAssetAmt - calcPrAssetPmt) |
---|
| 395 | + | let commonState = [IntegerEntry(pl(), curPrice), IntegerEntry(ph(height, lastBlock.timestamp), curPrice), StringEntry(pau(userAddress, txId58), dataPutActionInfo(calcAmAssetPmt, calcPrAssetPmt, emitLpAmt, curPrice, slippageTolerance, slippageCalc, height, lastBlock.timestamp, amDiff, prDiff))] |
---|
| 396 | + | $Tuple13(calcLpAmt, emitLpAmt, curPrice, amBalance, prBalance, lpEmission, lpAssetId, poolStatus, commonState, amDiff, prDiff, inAmAssetId, inPrAssetId) |
---|
| 397 | + | } |
---|
| 398 | + | } |
---|
| 399 | + | } |
---|
| 400 | + | |
---|
| 401 | + | |
---|
| 402 | + | func calcKLp (amountBalance,priceBalance,lpEmission) = { |
---|
| 403 | + | let amountBalanceX18 = toX18BigInt(amountBalance, toBigInt(cfgAmountAssetDecimals)) |
---|
| 404 | + | let priceBalanceX18 = toX18BigInt(priceBalance, toBigInt(cfgPriceAssetDecimals)) |
---|
| 405 | + | let updatedKLp = fraction(pow((amountBalanceX18 * priceBalanceX18), 0, toBigInt(5), 1, 18, DOWN), big1, lpEmission) |
---|
| 406 | + | if ((lpEmission == big0)) |
---|
| 407 | + | then big0 |
---|
| 408 | + | else updatedKLp |
---|
| 409 | + | } |
---|
| 410 | + | |
---|
| 411 | + | |
---|
| 412 | + | func calcCurrentKLp (amountAssetDelta,priceAssetDelta,lpAssetEmissionDelta) = { |
---|
| 413 | + | let amountAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) - amountAssetDelta) |
---|
| 414 | + | let priceAssetBalance = (toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) - priceAssetDelta) |
---|
| 415 | + | let lpAssetEmission = (toBigInt(value(assetInfo(cfgLpAssetId)).quantity) - lpAssetEmissionDelta) |
---|
| 416 | + | let currentKLp = calcKLp(amountAssetBalance, priceAssetBalance, lpAssetEmission) |
---|
| 417 | + | currentKLp |
---|
| 418 | + | } |
---|
| 419 | + | |
---|
| 420 | + | |
---|
| 421 | + | func refreshKLpInternal (amountAssetBalanceDelta,priceAssetBalanceDelta,lpAssetEmissionDelta) = { |
---|
| 422 | + | let amountAssetBalance = (getAccBalance(assetIdToString(cfgAmountAssetId)) + amountAssetBalanceDelta) |
---|
| 423 | + | let priceAssetBalance = (getAccBalance(assetIdToString(cfgPriceAssetId)) + priceAssetBalanceDelta) |
---|
| 424 | + | let lpAssetEmission = (value(assetInfo(cfgLpAssetId)).quantity + lpAssetEmissionDelta) |
---|
| 425 | + | let updatedKLp = calcKLp(toBigInt(amountAssetBalance), toBigInt(priceAssetBalance), toBigInt(lpAssetEmission)) |
---|
| 426 | + | let actions = [IntegerEntry(keyKLpRefreshedHeight, height), StringEntry(keyKLp, toString(updatedKLp))] |
---|
| 427 | + | $Tuple2(actions, updatedKLp) |
---|
| 428 | + | } |
---|
| 429 | + | |
---|
| 430 | + | |
---|
| 431 | + | func validateUpdatedKLp (oldKLp,updatedKLp) = if ((updatedKLp >= oldKLp)) |
---|
| 432 | + | then true |
---|
| 433 | + | else throwErr(makeString(["updated KLp lower than current KLp", toString(oldKLp), toString(updatedKLp)], " ")) |
---|
| 434 | + | |
---|
| 435 | + | |
---|
| 436 | + | func validateMatcherOrderAllowed (order) = { |
---|
| 437 | + | let amountAssetBalance = getAccBalance(assetIdToString(cfgAmountAssetId)) |
---|
| 438 | + | let priceAssetBalance = getAccBalance(assetIdToString(cfgPriceAssetId)) |
---|
| 439 | + | let amountAssetAmount = order.amount |
---|
| 440 | + | let priceAssetAmount = fraction(order.amount, order.price, scale8, FLOOR) |
---|
| 441 | + | let $t02205422273 = if ((order.orderType == Buy)) |
---|
| 442 | + | then $Tuple2(amountAssetAmount, -(priceAssetAmount)) |
---|
| 443 | + | else $Tuple2(-(amountAssetAmount), priceAssetAmount) |
---|
| 444 | + | let amountAssetBalanceDelta = $t02205422273._1 |
---|
| 445 | + | let priceAssetBalanceDelta = $t02205422273._2 |
---|
| 446 | + | if (if (if (isGlobalShutdown()) |
---|
| 447 | + | then true |
---|
| 448 | + | else (cfgPoolStatus == PoolMatcherDisabled)) |
---|
| 449 | + | then true |
---|
| 450 | + | else (cfgPoolStatus == PoolShutdown)) |
---|
| 451 | + | then throw("Exchange operations disabled") |
---|
| 452 | + | else if (if ((order.assetPair.amountAsset != cfgAmountAssetId)) |
---|
| 453 | + | then true |
---|
| 454 | + | else (order.assetPair.priceAsset != cfgPriceAssetId)) |
---|
| 455 | + | then throw("Wrong order assets.") |
---|
| 456 | + | else { |
---|
| 457 | + | let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp")) |
---|
| 458 | + | let $t02272222822 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0) |
---|
| 459 | + | let unusedActions = $t02272222822._1 |
---|
| 460 | + | let kLpNew = $t02272222822._2 |
---|
| 461 | + | let isOrderValid = (kLpNew >= kLp) |
---|
| 462 | + | let info = makeString(["kLp=", toString(kLp), " kLpNew=", toString(kLpNew), " amountAssetBalance=", toString(amountAssetBalance), " priceAssetBalance=", toString(priceAssetBalance), " amountAssetBalanceDelta=", toString(amountAssetBalanceDelta), " priceAssetBalanceDelta=", toString(priceAssetBalanceDelta), " height=", toString(height)], "") |
---|
| 463 | + | $Tuple2(isOrderValid, info) |
---|
| 464 | + | } |
---|
| 465 | + | } |
---|
| 466 | + | |
---|
| 467 | + | |
---|
| 468 | + | func commonGet (i) = if ((size(i.payments) != 1)) |
---|
| 469 | + | then throw("exactly 1 payment is expected") |
---|
| 470 | + | else { |
---|
| 471 | + | let pmt = value(i.payments[0]) |
---|
| 472 | + | let pmtAssetId = value(pmt.assetId) |
---|
| 473 | + | let pmtAmt = pmt.amount |
---|
| 474 | + | let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(pmtAssetId), pmtAmt, i.caller) |
---|
| 475 | + | let outAmAmt = res._1 |
---|
| 476 | + | let outPrAmt = res._2 |
---|
| 477 | + | let poolStatus = parseIntValue(res._9) |
---|
| 478 | + | let state = res._10 |
---|
| 479 | + | if (if (isGlobalShutdown()) |
---|
| 480 | + | then true |
---|
| 481 | + | else (poolStatus == PoolShutdown)) |
---|
| 482 | + | then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus))) |
---|
| 483 | + | else $Tuple5(outAmAmt, outPrAmt, pmtAmt, pmtAssetId, state) |
---|
| 484 | + | } |
---|
| 485 | + | |
---|
| 486 | + | |
---|
| 487 | + | func commonPut (i,slippageTolerance,emitLp) = if ((size(i.payments) != 2)) |
---|
| 488 | + | then throw("exactly 2 payments are expected") |
---|
| 489 | + | else { |
---|
| 490 | + | let amAssetPmt = value(i.payments[0]) |
---|
| 491 | + | let prAssetPmt = value(i.payments[1]) |
---|
| 492 | + | let estPut = estimatePutOperation(toBase58String(i.transactionId), slippageTolerance, amAssetPmt.amount, amAssetPmt.assetId, prAssetPmt.amount, prAssetPmt.assetId, toString(i.caller), false, emitLp) |
---|
| 493 | + | let poolStatus = parseIntValue(estPut._8) |
---|
| 494 | + | if (if (if (isGlobalShutdown()) |
---|
| 495 | + | then true |
---|
| 496 | + | else (poolStatus == PoolPutDisabled)) |
---|
| 497 | + | then true |
---|
| 498 | + | else (poolStatus == PoolShutdown)) |
---|
| 499 | + | then throw(("Put operation is blocked by admin. Status = " + toString(poolStatus))) |
---|
| 500 | + | else estPut |
---|
| 501 | + | } |
---|
| 502 | + | |
---|
| 503 | + | |
---|
| 504 | + | func emit (amount) = { |
---|
| 505 | + | let emitInv = invoke(factoryContract, "emit", [amount], nil) |
---|
| 506 | + | if ((emitInv == emitInv)) |
---|
| 507 | + | then { |
---|
| 508 | + | let emitInvLegacy = match emitInv { |
---|
| 509 | + | case legacyFactoryContract: Address => |
---|
| 510 | + | invoke(legacyFactoryContract, "emit", [amount], nil) |
---|
| 511 | + | case _ => |
---|
| 512 | + | unit |
---|
| 513 | + | } |
---|
| 514 | + | if ((emitInvLegacy == emitInvLegacy)) |
---|
| 515 | + | then amount |
---|
| 516 | + | else throw("Strict value is not equal to itself.") |
---|
| 517 | + | } |
---|
| 518 | + | else throw("Strict value is not equal to itself.") |
---|
| 519 | + | } |
---|
| 520 | + | |
---|
| 521 | + | |
---|
| 522 | + | func takeFee (amount,fee) = { |
---|
| 523 | + | let feeAmount = if ((fee == 0)) |
---|
| 524 | + | then 0 |
---|
| 525 | + | else fraction(amount, fee, scale8) |
---|
| 526 | + | $Tuple2((amount - feeAmount), feeAmount) |
---|
| 527 | + | } |
---|
| 528 | + | |
---|
| 529 | + | |
---|
| 530 | + | func calcPutOneToken (paymentAmountRaw,paymentAssetId,userAddress,txId) = { |
---|
| 531 | + | let isEval = (txId == unit) |
---|
| 532 | + | let amountBalanceRaw = getAccBalance(assetIdToString(cfgAmountAssetId)) |
---|
| 533 | + | let priceBalanceRaw = getAccBalance(assetIdToString(cfgPriceAssetId)) |
---|
| 534 | + | let paymentInAmountAsset = if ((paymentAssetId == cfgAmountAssetId)) |
---|
| 535 | + | then true |
---|
| 536 | + | else if ((paymentAssetId == cfgPriceAssetId)) |
---|
| 537 | + | then false |
---|
| 538 | + | else throwErr("invalid asset") |
---|
| 539 | + | let $t02603226333 = if (isEval) |
---|
| 540 | + | then $Tuple2(amountBalanceRaw, priceBalanceRaw) |
---|
| 541 | + | else if (paymentInAmountAsset) |
---|
| 542 | + | then $Tuple2((amountBalanceRaw - paymentAmountRaw), priceBalanceRaw) |
---|
| 543 | + | else $Tuple2(amountBalanceRaw, (priceBalanceRaw - paymentAmountRaw)) |
---|
| 544 | + | let amountBalanceOld = $t02603226333._1 |
---|
| 545 | + | let priceBalanceOld = $t02603226333._2 |
---|
| 546 | + | let $t02633926492 = if (paymentInAmountAsset) |
---|
| 547 | + | then $Tuple2(paymentAmountRaw, 0) |
---|
| 548 | + | else $Tuple2(0, paymentAmountRaw) |
---|
| 549 | + | let amountAssetAmountRaw = $t02633926492._1 |
---|
| 550 | + | let priceAssetAmountRaw = $t02633926492._2 |
---|
| 551 | + | let amountAssetAmount = takeFee(amountAssetAmountRaw, inFee)._1 |
---|
| 552 | + | let priceAssetAmount = takeFee(priceAssetAmountRaw, inFee)._1 |
---|
| 553 | + | let $t02662826692 = takeFee(paymentAmountRaw, inFee) |
---|
| 554 | + | let paymentAmount = $t02662826692._1 |
---|
| 555 | + | let feeAmount = $t02662826692._2 |
---|
| 556 | + | let amountBalanceNew = (amountBalanceOld + amountAssetAmount) |
---|
| 557 | + | let priceBalanceNew = (priceBalanceOld + priceAssetAmount) |
---|
| 558 | + | let priceNewX18 = calcPriceBigInt(toX18(priceBalanceNew, cfgPriceAssetDecimals), toX18(amountBalanceNew, cfgAmountAssetDecimals)) |
---|
| 559 | + | let priceNew = fromX18(priceNewX18, scale8) |
---|
| 560 | + | let paymentBalance = if (paymentInAmountAsset) |
---|
| 561 | + | then amountBalanceOld |
---|
| 562 | + | else priceBalanceOld |
---|
| 563 | + | let paymentBalanceBigInt = toBigInt(paymentBalance) |
---|
| 564 | + | let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity) |
---|
| 565 | + | let chechSupply = if ((supplyBigInt > big0)) |
---|
| 566 | + | then true |
---|
| 567 | + | else throwErr("initial deposit requires all coins") |
---|
| 568 | + | if ((chechSupply == chechSupply)) |
---|
| 569 | + | then { |
---|
| 570 | + | let depositBigInt = toBigInt(paymentAmount) |
---|
| 571 | + | let issueAmount = max([0, toInt(((supplyBigInt * (sqrtBigInt((scale18 + ((depositBigInt * scale18) / paymentBalanceBigInt)), 18, 18, DOWN) - scale18)) / scale18))]) |
---|
| 572 | + | let commonState = if (isEval) |
---|
| 573 | + | then nil |
---|
| 574 | + | else [IntegerEntry(pl(), priceNew), IntegerEntry(ph(height, lastBlock.timestamp), priceNew), StringEntry(pau(toString(value(userAddress)), toBase58String(value(txId))), dataPutActionInfo(amountAssetAmountRaw, priceAssetAmountRaw, issueAmount, priceNew, 0, 0, height, lastBlock.timestamp, 0, 0))] |
---|
| 575 | + | let priceOldX18 = calcPriceBigInt(toX18(priceBalanceOld, cfgPriceAssetDecimals), toX18(amountBalanceOld, cfgAmountAssetDecimals)) |
---|
| 576 | + | let priceOld = fromX18(priceOldX18, scale8) |
---|
| 577 | + | let loss = { |
---|
| 578 | + | let $t02840928580 = if (paymentInAmountAsset) |
---|
| 579 | + | then $Tuple2(amountAssetAmountRaw, amountBalanceOld) |
---|
| 580 | + | else $Tuple2(priceAssetAmountRaw, priceBalanceOld) |
---|
| 581 | + | let amount = $t02840928580._1 |
---|
| 582 | + | let balance = $t02840928580._2 |
---|
| 583 | + | let issueAmountBoth = toInt(fraction(supplyBigInt, toBigInt((amount / 2)), toBigInt(balance))) |
---|
| 584 | + | fraction((issueAmount - issueAmountBoth), scale8, issueAmountBoth) |
---|
| 585 | + | } |
---|
| 586 | + | $Tuple5(issueAmount, commonState, feeAmount, loss, paymentInAmountAsset) |
---|
| 587 | + | } |
---|
| 588 | + | else throw("Strict value is not equal to itself.") |
---|
| 589 | + | } |
---|
| 590 | + | |
---|
| 591 | + | |
---|
| 592 | + | func calcGetOneToken (outAssetId,paymentAmount,paymentAssetId,userAddress,txId) = { |
---|
| 593 | + | let isEval = (txId == unit) |
---|
| 594 | + | let cfg = getPoolConfig() |
---|
| 595 | + | let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm]) |
---|
| 596 | + | let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm]) |
---|
| 597 | + | let checks = [if ((paymentAssetId == cfgLpAssetId)) |
---|
| 598 | + | then true |
---|
| 599 | + | else throwErr("invalid lp asset")] |
---|
| 600 | + | if ((checks == checks)) |
---|
| 601 | + | then { |
---|
| 602 | + | let outInAmountAsset = if ((outAssetId == cfgAmountAssetId)) |
---|
| 603 | + | then true |
---|
| 604 | + | else if ((outAssetId == cfgPriceAssetId)) |
---|
| 605 | + | then false |
---|
| 606 | + | else throwErr("invalid asset") |
---|
| 607 | + | let balanceBigInt = if (outInAmountAsset) |
---|
| 608 | + | then toBigInt(getAccBalance(assetIdToString(cfgAmountAssetId))) |
---|
| 609 | + | else toBigInt(getAccBalance(assetIdToString(cfgPriceAssetId))) |
---|
| 610 | + | let outInAmountAssetDecimals = if (outInAmountAsset) |
---|
| 611 | + | then amtAssetDcm |
---|
| 612 | + | else priceAssetDcm |
---|
| 613 | + | let amBalanceOld = getAccBalance(assetIdToString(cfgAmountAssetId)) |
---|
| 614 | + | let prBalanceOld = getAccBalance(assetIdToString(cfgPriceAssetId)) |
---|
| 615 | + | let outBalance = if (outInAmountAsset) |
---|
| 616 | + | then amBalanceOld |
---|
| 617 | + | else prBalanceOld |
---|
| 618 | + | let outBalanceBigInt = toBigInt(outBalance) |
---|
| 619 | + | let supplyBigInt = toBigInt(valueOrErrorMessage(assetInfo(cfgLpAssetId), (("asset " + toBase58String(cfgLpAssetId)) + " doesn't exist")).quantity) |
---|
| 620 | + | let redeemedBigInt = toBigInt(paymentAmount) |
---|
| 621 | + | let amountRaw = max([0, toInt(((balanceBigInt * (scale18 - pow((scale18 - ((redeemedBigInt * scale18) / supplyBigInt)), 18, big2, 0, 18, DOWN))) / scale18))]) |
---|
| 622 | + | let $t03071730773 = takeFee(amountRaw, outFee) |
---|
| 623 | + | let totalAmount = $t03071730773._1 |
---|
| 624 | + | let feeAmount = $t03071730773._2 |
---|
| 625 | + | let $t03077931009 = if (outInAmountAsset) |
---|
| 626 | + | then $Tuple4(totalAmount, 0, (amBalanceOld - amountRaw), prBalanceOld) |
---|
| 627 | + | else $Tuple4(0, totalAmount, amBalanceOld, (prBalanceOld - amountRaw)) |
---|
| 628 | + | let outAmAmount = $t03077931009._1 |
---|
| 629 | + | let outPrAmount = $t03077931009._2 |
---|
| 630 | + | let amBalanceNew = $t03077931009._3 |
---|
| 631 | + | let prBalanceNew = $t03077931009._4 |
---|
| 632 | + | let priceNewX18 = calcPriceBigInt(toX18(prBalanceNew, cfgPriceAssetDecimals), toX18(amBalanceNew, cfgAmountAssetDecimals)) |
---|
| 633 | + | let priceNew = fromX18(priceNewX18, scale8) |
---|
| 634 | + | let commonState = if (isEval) |
---|
| 635 | + | then nil |
---|
| 636 | + | else [StringEntry(gau(toString(value(userAddress)), toBase58String(value(txId))), dataGetActionInfo(outAmAmount, outPrAmount, paymentAmount, priceNew, height, lastBlock.timestamp)), IntegerEntry(pl(), priceNew), IntegerEntry(ph(height, lastBlock.timestamp), priceNew)] |
---|
| 637 | + | let priceOldX18 = calcPriceBigInt(toX18(prBalanceOld, cfgPriceAssetDecimals), toX18(amBalanceOld, cfgAmountAssetDecimals)) |
---|
| 638 | + | let priceOld = fromX18(priceOldX18, scale8) |
---|
| 639 | + | let loss = { |
---|
| 640 | + | let amountBothInPaymentAsset = (toInt(fraction(balanceBigInt, redeemedBigInt, supplyBigInt)) * 2) |
---|
| 641 | + | fraction((totalAmount - amountBothInPaymentAsset), scale8, amountBothInPaymentAsset) |
---|
| 642 | + | } |
---|
| 643 | + | $Tuple5(totalAmount, commonState, feeAmount, loss, outInAmountAsset) |
---|
| 644 | + | } |
---|
| 645 | + | else throw("Strict value is not equal to itself.") |
---|
| 646 | + | } |
---|
| 647 | + | |
---|
| 648 | + | |
---|
| 649 | + | func managerPublicKeyOrUnit () = match getString(mpk()) { |
---|
| 650 | + | case s: String => |
---|
| 651 | + | fromBase58String(s) |
---|
| 652 | + | case _: Unit => |
---|
| 653 | + | unit |
---|
| 654 | + | case _ => |
---|
| 655 | + | throw("Match error") |
---|
| 656 | + | } |
---|
| 657 | + | |
---|
| 658 | + | |
---|
| 659 | + | func pendingManagerPublicKeyOrUnit () = match getString(pmpk()) { |
---|
| 660 | + | case s: String => |
---|
| 661 | + | fromBase58String(s) |
---|
| 662 | + | case _: Unit => |
---|
| 663 | + | unit |
---|
| 664 | + | case _ => |
---|
| 665 | + | throw("Match error") |
---|
| 666 | + | } |
---|
| 667 | + | |
---|
| 668 | + | |
---|
| 669 | + | func isManager (i) = match managerPublicKeyOrUnit() { |
---|
| 670 | + | case pk: ByteVector => |
---|
| 671 | + | (i.callerPublicKey == pk) |
---|
| 672 | + | case _: Unit => |
---|
| 673 | + | (i.caller == this) |
---|
| 674 | + | case _ => |
---|
| 675 | + | throw("Match error") |
---|
| 676 | + | } |
---|
| 677 | + | |
---|
| 678 | + | |
---|
| 679 | + | func mustManager (i) = { |
---|
| 680 | + | let pd = throw("Permission denied") |
---|
| 681 | + | match managerPublicKeyOrUnit() { |
---|
| 682 | + | case pk: ByteVector => |
---|
| 683 | + | if ((i.callerPublicKey == pk)) |
---|
| 684 | + | then true |
---|
| 685 | + | else pd |
---|
| 686 | + | case _: Unit => |
---|
| 687 | + | if ((i.caller == this)) |
---|
| 688 | + | then true |
---|
| 689 | + | else pd |
---|
| 690 | + | case _ => |
---|
| 691 | + | throw("Match error") |
---|
| 692 | + | } |
---|
| 693 | + | } |
---|
| 694 | + | |
---|
| 695 | + | |
---|
| 696 | + | @Callable(i) |
---|
| 697 | + | func calculateAmountOutForSwapREADONLY (cleanAmountIn,isReverse,feePoolAmount) = { |
---|
| 698 | + | let $t03277833091 = if ((isReverse == false)) |
---|
| 699 | + | then { |
---|
| 700 | + | let assetOut = getStringOrFail(this, pa()) |
---|
| 701 | + | let assetIn = getStringOrFail(this, aa()) |
---|
| 702 | + | $Tuple2(assetOut, assetIn) |
---|
| 703 | + | } |
---|
| 704 | + | else { |
---|
| 705 | + | let assetOut = getStringOrFail(this, aa()) |
---|
| 706 | + | let assetIn = getStringOrFail(this, pa()) |
---|
| 707 | + | $Tuple2(assetOut, assetIn) |
---|
| 708 | + | } |
---|
| 709 | + | let assetOut = $t03277833091._1 |
---|
| 710 | + | let assetIn = $t03277833091._2 |
---|
| 711 | + | let poolAssetInBalance = getAccBalance(assetIn) |
---|
| 712 | + | let poolAssetOutBalance = getAccBalance(assetOut) |
---|
| 713 | + | let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn)) |
---|
| 714 | + | let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance)) |
---|
| 715 | + | let newK = (((toBigInt(getAccBalance(assetIn)) + toBigInt(cleanAmountIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut))) |
---|
| 716 | + | let checkK = if ((newK >= oldK)) |
---|
| 717 | + | then true |
---|
| 718 | + | else throw("new K is fewer error") |
---|
| 719 | + | if ((checkK == checkK)) |
---|
| 720 | + | then $Tuple2(nil, amountOut) |
---|
| 721 | + | else throw("Strict value is not equal to itself.") |
---|
| 722 | + | } |
---|
| 723 | + | |
---|
| 724 | + | |
---|
| 725 | + | |
---|
| 726 | + | @Callable(i) |
---|
| 727 | + | func calculateAmountOutForSwapAndSendTokens (cleanAmountIn,isReverse,amountOutMin,addressTo,feePoolAmount) = { |
---|
| 728 | + | let swapContact = { |
---|
| 729 | + | let @ = invoke(factoryContract, "getSwapContractREADONLY", nil, nil) |
---|
| 730 | + | if ($isInstanceOf(@, "String")) |
---|
| 731 | + | then @ |
---|
| 732 | + | else throw(($getType(@) + " couldn't be cast to String")) |
---|
| 733 | + | } |
---|
| 734 | + | let checks = [if ((value(i.payments[0]).amount >= cleanAmountIn)) |
---|
| 735 | + | then true |
---|
| 736 | + | else throwErr("Wrong amount"), if ((i.caller == addressFromStringValue(swapContact))) |
---|
| 737 | + | then true |
---|
| 738 | + | else throwErr("Permission denied")] |
---|
| 739 | + | if ((checks == checks)) |
---|
| 740 | + | then { |
---|
| 741 | + | let pmt = value(i.payments[0]) |
---|
| 742 | + | let assetIn = assetIdToString(pmt.assetId) |
---|
| 743 | + | let assetOut = if ((isReverse == false)) |
---|
| 744 | + | then getStringOrFail(this, pa()) |
---|
| 745 | + | else getStringOrFail(this, aa()) |
---|
| 746 | + | let poolAssetInBalance = (getAccBalance(assetIn) - value(i.payments[0]).amount) |
---|
| 747 | + | let poolAssetOutBalance = getAccBalance(assetOut) |
---|
| 748 | + | let amountOut = fraction(poolAssetOutBalance, cleanAmountIn, (poolAssetInBalance + cleanAmountIn)) |
---|
| 749 | + | let oldK = (toBigInt(poolAssetInBalance) * toBigInt(poolAssetOutBalance)) |
---|
| 750 | + | let newK = ((toBigInt(getAccBalance(assetIn)) + toBigInt(feePoolAmount)) * (toBigInt(getAccBalance(assetOut)) - toBigInt(amountOut))) |
---|
| 751 | + | let checkK = if ((newK >= oldK)) |
---|
| 752 | + | then true |
---|
| 753 | + | else throw("new K is fewer error") |
---|
| 754 | + | if ((checkK == checkK)) |
---|
| 755 | + | then { |
---|
| 756 | + | let checkMin = if ((amountOut >= amountOutMin)) |
---|
| 757 | + | then true |
---|
| 758 | + | else throw("Exchange result is fewer coins than expected") |
---|
| 759 | + | if ((checkMin == checkMin)) |
---|
| 760 | + | then $Tuple2([ScriptTransfer(addressFromStringValue(addressTo), amountOut, parseAssetId(assetOut))], amountOut) |
---|
| 761 | + | else throw("Strict value is not equal to itself.") |
---|
| 762 | + | } |
---|
| 763 | + | else throw("Strict value is not equal to itself.") |
---|
| 764 | + | } |
---|
| 765 | + | else throw("Strict value is not equal to itself.") |
---|
| 766 | + | } |
---|
| 767 | + | |
---|
| 768 | + | |
---|
| 769 | + | |
---|
| 770 | + | @Callable(i) |
---|
| 771 | + | func setManager (pendingManagerPublicKey) = { |
---|
| 772 | + | let checkCaller = mustManager(i) |
---|
| 773 | + | if ((checkCaller == checkCaller)) |
---|
| 774 | + | then { |
---|
| 775 | + | let checkManagerPublicKey = fromBase58String(pendingManagerPublicKey) |
---|
| 776 | + | if ((checkManagerPublicKey == checkManagerPublicKey)) |
---|
| 777 | + | then [StringEntry(pmpk(), pendingManagerPublicKey)] |
---|
| 778 | + | else throw("Strict value is not equal to itself.") |
---|
| 779 | + | } |
---|
| 780 | + | else throw("Strict value is not equal to itself.") |
---|
| 781 | + | } |
---|
| 782 | + | |
---|
| 783 | + | |
---|
| 784 | + | |
---|
| 785 | + | @Callable(i) |
---|
| 786 | + | func confirmManager () = { |
---|
| 787 | + | let pm = pendingManagerPublicKeyOrUnit() |
---|
| 788 | + | let hasPM = if (isDefined(pm)) |
---|
| 789 | + | then true |
---|
| 790 | + | else throw("No pending manager") |
---|
| 791 | + | if ((hasPM == hasPM)) |
---|
| 792 | + | then { |
---|
| 793 | + | let checkPM = if ((i.callerPublicKey == value(pm))) |
---|
| 794 | + | then true |
---|
| 795 | + | else throw("You are not pending manager") |
---|
| 796 | + | if ((checkPM == checkPM)) |
---|
| 797 | + | then [StringEntry(mpk(), toBase58String(value(pm))), DeleteEntry(pmpk())] |
---|
| 798 | + | else throw("Strict value is not equal to itself.") |
---|
| 799 | + | } |
---|
| 800 | + | else throw("Strict value is not equal to itself.") |
---|
| 801 | + | } |
---|
| 802 | + | |
---|
| 803 | + | |
---|
| 804 | + | |
---|
| 805 | + | @Callable(i) |
---|
| 806 | + | func put (slippageTolerance,shouldAutoStake) = if ((0 > slippageTolerance)) |
---|
| 807 | + | then throw("Invalid slippageTolerance passed") |
---|
| 808 | + | else { |
---|
| 809 | + | let estPut = commonPut(i, slippageTolerance, true) |
---|
| 810 | + | let emitLpAmt = estPut._2 |
---|
| 811 | + | let lpAssetId = estPut._7 |
---|
| 812 | + | let state = estPut._9 |
---|
| 813 | + | let amDiff = estPut._10 |
---|
| 814 | + | let prDiff = estPut._11 |
---|
| 815 | + | let amId = estPut._12 |
---|
| 816 | + | let prId = estPut._13 |
---|
| 817 | + | let amAssetPmt = toBigInt(value(i.payments[0]).amount) |
---|
| 818 | + | let prAssetPmt = toBigInt(value(i.payments[1]).amount) |
---|
| 819 | + | let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0)) |
---|
| 820 | + | if ((currentKLp == currentKLp)) |
---|
| 821 | + | then { |
---|
| 822 | + | let emitInv = invoke(factoryContract, "emit", [emitLpAmt], nil) |
---|
| 823 | + | if ((emitInv == emitInv)) |
---|
| 824 | + | then { |
---|
| 825 | + | let emitInvLegacy = match emitInv { |
---|
| 826 | + | case legacyFactoryContract: Address => |
---|
| 827 | + | invoke(legacyFactoryContract, "emit", [emitLpAmt], nil) |
---|
| 828 | + | case _ => |
---|
| 829 | + | unit |
---|
| 830 | + | } |
---|
| 831 | + | if ((emitInvLegacy == emitInvLegacy)) |
---|
| 832 | + | then { |
---|
| 833 | + | let slippageAInv = if ((amDiff > 0)) |
---|
| 834 | + | then invoke(slippageContract, "put", nil, [AttachedPayment(amId, amDiff)]) |
---|
| 835 | + | else nil |
---|
| 836 | + | if ((slippageAInv == slippageAInv)) |
---|
| 837 | + | then { |
---|
| 838 | + | let slippagePInv = if ((prDiff > 0)) |
---|
| 839 | + | then invoke(slippageContract, "put", nil, [AttachedPayment(prId, prDiff)]) |
---|
| 840 | + | else nil |
---|
| 841 | + | if ((slippagePInv == slippagePInv)) |
---|
| 842 | + | then { |
---|
| 843 | + | let lpTransfer = if (shouldAutoStake) |
---|
| 844 | + | then { |
---|
| 845 | + | let slpStakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(lpAssetId, emitLpAmt)]) |
---|
| 846 | + | if ((slpStakeInv == slpStakeInv)) |
---|
| 847 | + | then nil |
---|
| 848 | + | else throw("Strict value is not equal to itself.") |
---|
| 849 | + | } |
---|
| 850 | + | else [ScriptTransfer(i.caller, emitLpAmt, lpAssetId)] |
---|
| 851 | + | let $t03809638572 = refreshKLpInternal(0, 0, 0) |
---|
| 852 | + | if (($t03809638572 == $t03809638572)) |
---|
| 853 | + | then { |
---|
| 854 | + | let updatedKLp = $t03809638572._2 |
---|
| 855 | + | let refreshKLpActions = $t03809638572._1 |
---|
| 856 | + | let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp) |
---|
| 857 | + | if ((isUpdatedKLpValid == isUpdatedKLpValid)) |
---|
| 858 | + | then ((state ++ lpTransfer) ++ refreshKLpActions) |
---|
| 859 | + | else throw("Strict value is not equal to itself.") |
---|
| 860 | + | } |
---|
| 861 | + | else throw("Strict value is not equal to itself.") |
---|
| 862 | + | } |
---|
| 863 | + | else throw("Strict value is not equal to itself.") |
---|
| 864 | + | } |
---|
| 865 | + | else throw("Strict value is not equal to itself.") |
---|
| 866 | + | } |
---|
| 867 | + | else throw("Strict value is not equal to itself.") |
---|
| 868 | + | } |
---|
| 869 | + | else throw("Strict value is not equal to itself.") |
---|
| 870 | + | } |
---|
| 871 | + | else throw("Strict value is not equal to itself.") |
---|
| 872 | + | } |
---|
| 873 | + | |
---|
| 874 | + | |
---|
| 875 | + | |
---|
| 876 | + | @Callable(i) |
---|
| 877 | + | func putForFree (maxSlippage) = if ((0 > maxSlippage)) |
---|
| 878 | + | then throw("Invalid value passed") |
---|
| 879 | + | else { |
---|
| 880 | + | let estPut = commonPut(i, maxSlippage, false) |
---|
| 881 | + | let state = estPut._9 |
---|
| 882 | + | let amAssetPmt = toBigInt(value(i.payments[0]).amount) |
---|
| 883 | + | let prAssetPmt = toBigInt(value(i.payments[1]).amount) |
---|
| 884 | + | let currentKLp = calcCurrentKLp(amAssetPmt, prAssetPmt, toBigInt(0)) |
---|
| 885 | + | if ((currentKLp == currentKLp)) |
---|
| 886 | + | then { |
---|
| 887 | + | let $t03915439219 = refreshKLpInternal(0, 0, 0) |
---|
| 888 | + | let refreshKLpActions = $t03915439219._1 |
---|
| 889 | + | let updatedKLp = $t03915439219._2 |
---|
| 890 | + | let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp) |
---|
| 891 | + | if ((isUpdatedKLpValid == isUpdatedKLpValid)) |
---|
| 892 | + | then (state ++ refreshKLpActions) |
---|
| 893 | + | else throw("Strict value is not equal to itself.") |
---|
| 894 | + | } |
---|
| 895 | + | else throw("Strict value is not equal to itself.") |
---|
| 896 | + | } |
---|
| 897 | + | |
---|
| 898 | + | |
---|
| 899 | + | |
---|
| 900 | + | @Callable(i) |
---|
| 901 | + | func putOneTkn (minOutAmount,autoStake) = { |
---|
| 902 | + | let isPoolOneTokenOperationsDisabled = { |
---|
| 903 | + | let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil) |
---|
| 904 | + | if ($isInstanceOf(@, "Boolean")) |
---|
| 905 | + | then @ |
---|
| 906 | + | else throw(($getType(@) + " couldn't be cast to Boolean")) |
---|
| 907 | + | } |
---|
| 908 | + | let isPutDisabled = if (if (if (isGlobalShutdown()) |
---|
| 909 | + | then true |
---|
| 910 | + | else (cfgPoolStatus == PoolPutDisabled)) |
---|
| 911 | + | then true |
---|
| 912 | + | else (cfgPoolStatus == PoolShutdown)) |
---|
| 913 | + | then true |
---|
| 914 | + | else isPoolOneTokenOperationsDisabled |
---|
| 915 | + | let checks = [if (if (!(isPutDisabled)) |
---|
| 916 | + | then true |
---|
| 917 | + | else isManager(i)) |
---|
| 918 | + | then true |
---|
| 919 | + | else throwErr("put operation is blocked by admin"), if ((size(i.payments) == 1)) |
---|
| 920 | + | then true |
---|
| 921 | + | else throwErr("exactly 1 payment are expected")] |
---|
| 922 | + | if ((checks == checks)) |
---|
| 923 | + | then { |
---|
| 924 | + | let payment = i.payments[0] |
---|
| 925 | + | let paymentAssetId = payment.assetId |
---|
| 926 | + | let paymentAmountRaw = payment.amount |
---|
| 927 | + | let currentKLp = if ((paymentAssetId == cfgAmountAssetId)) |
---|
| 928 | + | then calcCurrentKLp(toBigInt(paymentAmountRaw), toBigInt(0), toBigInt(0)) |
---|
| 929 | + | else if ((paymentAssetId == cfgPriceAssetId)) |
---|
| 930 | + | then calcCurrentKLp(toBigInt(0), toBigInt(paymentAmountRaw), toBigInt(0)) |
---|
| 931 | + | else throwErr("payment asset is not supported") |
---|
| 932 | + | if ((currentKLp == currentKLp)) |
---|
| 933 | + | then { |
---|
| 934 | + | let userAddress = i.caller |
---|
| 935 | + | let txId = i.transactionId |
---|
| 936 | + | let $t04044340595 = calcPutOneToken(paymentAmountRaw, paymentAssetId, userAddress, txId) |
---|
| 937 | + | if (($t04044340595 == $t04044340595)) |
---|
| 938 | + | then { |
---|
| 939 | + | let paymentInAmountAsset = $t04044340595._5 |
---|
| 940 | + | let bonus = $t04044340595._4 |
---|
| 941 | + | let feeAmount = $t04044340595._3 |
---|
| 942 | + | let commonState = $t04044340595._2 |
---|
| 943 | + | let emitAmountEstimated = $t04044340595._1 |
---|
| 944 | + | let emitAmount = if (if ((minOutAmount > 0)) |
---|
| 945 | + | then (minOutAmount > emitAmountEstimated) |
---|
| 946 | + | else false) |
---|
| 947 | + | then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], "")) |
---|
| 948 | + | else emitAmountEstimated |
---|
| 949 | + | let emitInv = emit(emitAmount) |
---|
| 950 | + | if ((emitInv == emitInv)) |
---|
| 951 | + | then { |
---|
| 952 | + | let lpTransfer = if (autoStake) |
---|
| 953 | + | then { |
---|
| 954 | + | let stakeInv = invoke(stakingContract, "stake", nil, [AttachedPayment(cfgLpAssetId, emitAmount)]) |
---|
| 955 | + | if ((stakeInv == stakeInv)) |
---|
| 956 | + | then nil |
---|
| 957 | + | else throw("Strict value is not equal to itself.") |
---|
| 958 | + | } |
---|
| 959 | + | else [ScriptTransfer(i.caller, emitAmount, cfgLpAssetId)] |
---|
| 960 | + | let sendFee = if ((feeAmount > 0)) |
---|
| 961 | + | then [ScriptTransfer(feeCollectorAddress, feeAmount, paymentAssetId)] |
---|
| 962 | + | else nil |
---|
| 963 | + | let $t04119741398 = if ((this == feeCollectorAddress)) |
---|
| 964 | + | then $Tuple2(0, 0) |
---|
| 965 | + | else if (paymentInAmountAsset) |
---|
| 966 | + | then $Tuple2(-(feeAmount), 0) |
---|
| 967 | + | else $Tuple2(0, -(feeAmount)) |
---|
| 968 | + | let amountAssetBalanceDelta = $t04119741398._1 |
---|
| 969 | + | let priceAssetBalanceDelta = $t04119741398._2 |
---|
| 970 | + | let $t04140241510 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0) |
---|
| 971 | + | let refreshKLpActions = $t04140241510._1 |
---|
| 972 | + | let updatedKLp = $t04140241510._2 |
---|
| 973 | + | let kLp = value(getString(keyKLp)) |
---|
| 974 | + | let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp) |
---|
| 975 | + | if ((isUpdatedKLpValid == isUpdatedKLpValid)) |
---|
| 976 | + | then $Tuple2((((commonState ++ lpTransfer) ++ sendFee) ++ refreshKLpActions), emitAmount) |
---|
| 977 | + | else throw("Strict value is not equal to itself.") |
---|
| 978 | + | } |
---|
| 979 | + | else throw("Strict value is not equal to itself.") |
---|
| 980 | + | } |
---|
| 981 | + | else throw("Strict value is not equal to itself.") |
---|
| 982 | + | } |
---|
| 983 | + | else throw("Strict value is not equal to itself.") |
---|
| 984 | + | } |
---|
| 985 | + | else throw("Strict value is not equal to itself.") |
---|
| 986 | + | } |
---|
| 987 | + | |
---|
| 988 | + | |
---|
| 989 | + | |
---|
| 990 | + | @Callable(i) |
---|
| 991 | + | func putOneTknREADONLY (paymentAssetId,paymentAmountRaw) = { |
---|
| 992 | + | let $t04183341990 = calcPutOneToken(paymentAmountRaw, parseAssetId(paymentAssetId), unit, unit) |
---|
| 993 | + | let emitAmountEstimated = $t04183341990._1 |
---|
| 994 | + | let commonState = $t04183341990._2 |
---|
| 995 | + | let feeAmount = $t04183341990._3 |
---|
| 996 | + | let bonus = $t04183341990._4 |
---|
| 997 | + | let paymentInAmountAsset = $t04183341990._5 |
---|
| 998 | + | $Tuple2(nil, $Tuple3(emitAmountEstimated, feeAmount, bonus)) |
---|
| 999 | + | } |
---|
| 1000 | + | |
---|
| 1001 | + | |
---|
| 1002 | + | |
---|
| 1003 | + | @Callable(i) |
---|
| 1004 | + | func getOneTkn (outAssetIdStr,minOutAmount) = { |
---|
| 1005 | + | let isPoolOneTokenOperationsDisabled = { |
---|
| 1006 | + | let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil) |
---|
| 1007 | + | if ($isInstanceOf(@, "Boolean")) |
---|
| 1008 | + | then @ |
---|
| 1009 | + | else throw(($getType(@) + " couldn't be cast to Boolean")) |
---|
| 1010 | + | } |
---|
| 1011 | + | let isGetDisabled = if (if (isGlobalShutdown()) |
---|
| 1012 | + | then true |
---|
| 1013 | + | else (cfgPoolStatus == PoolShutdown)) |
---|
| 1014 | + | then true |
---|
| 1015 | + | else isPoolOneTokenOperationsDisabled |
---|
| 1016 | + | let checks = [if (if (!(isGetDisabled)) |
---|
| 1017 | + | then true |
---|
| 1018 | + | else isManager(i)) |
---|
| 1019 | + | then true |
---|
| 1020 | + | else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 1)) |
---|
| 1021 | + | then true |
---|
| 1022 | + | else throwErr("exactly 1 payment are expected")] |
---|
| 1023 | + | if ((checks == checks)) |
---|
| 1024 | + | then { |
---|
| 1025 | + | let outAssetId = parseAssetId(outAssetIdStr) |
---|
| 1026 | + | let payment = i.payments[0] |
---|
| 1027 | + | let paymentAssetId = payment.assetId |
---|
| 1028 | + | let paymentAmount = payment.amount |
---|
| 1029 | + | let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0)) |
---|
| 1030 | + | if ((currentKLp == currentKLp)) |
---|
| 1031 | + | then { |
---|
| 1032 | + | let userAddress = i.caller |
---|
| 1033 | + | let txId = i.transactionId |
---|
| 1034 | + | let $t04290543058 = calcGetOneToken(outAssetId, paymentAmount, paymentAssetId, userAddress, txId) |
---|
| 1035 | + | if (($t04290543058 == $t04290543058)) |
---|
| 1036 | + | then { |
---|
| 1037 | + | let outInAmountAsset = $t04290543058._5 |
---|
| 1038 | + | let bonus = $t04290543058._4 |
---|
| 1039 | + | let feeAmount = $t04290543058._3 |
---|
| 1040 | + | let commonState = $t04290543058._2 |
---|
| 1041 | + | let amountEstimated = $t04290543058._1 |
---|
| 1042 | + | let amount = if (if ((minOutAmount > 0)) |
---|
| 1043 | + | then (minOutAmount > amountEstimated) |
---|
| 1044 | + | else false) |
---|
| 1045 | + | then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], "")) |
---|
| 1046 | + | else amountEstimated |
---|
| 1047 | + | let burnInv = invoke(factoryContract, "burn", [paymentAmount], [AttachedPayment(paymentAssetId, paymentAmount)]) |
---|
| 1048 | + | if ((burnInv == burnInv)) |
---|
| 1049 | + | then { |
---|
| 1050 | + | let assetTransfer = [ScriptTransfer(userAddress, amount, outAssetId)] |
---|
| 1051 | + | let sendFee = if ((feeAmount > 0)) |
---|
| 1052 | + | then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)] |
---|
| 1053 | + | else nil |
---|
| 1054 | + | let $t04357043820 = { |
---|
| 1055 | + | let feeAmountForCalc = if ((this == feeCollectorAddress)) |
---|
| 1056 | + | then 0 |
---|
| 1057 | + | else feeAmount |
---|
| 1058 | + | if (outInAmountAsset) |
---|
| 1059 | + | then $Tuple2(-((amount + feeAmountForCalc)), 0) |
---|
| 1060 | + | else $Tuple2(0, -((amount + feeAmountForCalc))) |
---|
| 1061 | + | } |
---|
| 1062 | + | let amountAssetBalanceDelta = $t04357043820._1 |
---|
| 1063 | + | let priceAssetBalanceDelta = $t04357043820._2 |
---|
| 1064 | + | let $t04382443932 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0) |
---|
| 1065 | + | let refreshKLpActions = $t04382443932._1 |
---|
| 1066 | + | let updatedKLp = $t04382443932._2 |
---|
| 1067 | + | let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp) |
---|
| 1068 | + | if ((isUpdatedKLpValid == isUpdatedKLpValid)) |
---|
| 1069 | + | then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount) |
---|
| 1070 | + | else throw("Strict value is not equal to itself.") |
---|
| 1071 | + | } |
---|
| 1072 | + | else throw("Strict value is not equal to itself.") |
---|
| 1073 | + | } |
---|
| 1074 | + | else throw("Strict value is not equal to itself.") |
---|
| 1075 | + | } |
---|
| 1076 | + | else throw("Strict value is not equal to itself.") |
---|
| 1077 | + | } |
---|
| 1078 | + | else throw("Strict value is not equal to itself.") |
---|
| 1079 | + | } |
---|
| 1080 | + | |
---|
| 1081 | + | |
---|
| 1082 | + | |
---|
| 1083 | + | @Callable(i) |
---|
| 1084 | + | func getOneTknREADONLY (outAssetId,paymentAmount) = { |
---|
| 1085 | + | let $t04420444360 = calcGetOneToken(parseAssetId(outAssetId), paymentAmount, cfgLpAssetId, unit, unit) |
---|
| 1086 | + | let amountEstimated = $t04420444360._1 |
---|
| 1087 | + | let commonState = $t04420444360._2 |
---|
| 1088 | + | let feeAmount = $t04420444360._3 |
---|
| 1089 | + | let bonus = $t04420444360._4 |
---|
| 1090 | + | let outInAmountAsset = $t04420444360._5 |
---|
| 1091 | + | $Tuple2(nil, $Tuple3(amountEstimated, feeAmount, bonus)) |
---|
| 1092 | + | } |
---|
| 1093 | + | |
---|
| 1094 | + | |
---|
| 1095 | + | |
---|
| 1096 | + | @Callable(i) |
---|
| 1097 | + | func unstakeAndGetOneTkn (unstakeAmount,outAssetIdStr,minOutAmount) = { |
---|
| 1098 | + | let isPoolOneTokenOperationsDisabled = { |
---|
| 1099 | + | let @ = invoke(factoryContract, "isPoolOneTokenOperationsDisabledREADONLY", [toString(this)], nil) |
---|
| 1100 | + | if ($isInstanceOf(@, "Boolean")) |
---|
| 1101 | + | then @ |
---|
| 1102 | + | else throw(($getType(@) + " couldn't be cast to Boolean")) |
---|
| 1103 | + | } |
---|
| 1104 | + | let isGetDisabled = if (if (isGlobalShutdown()) |
---|
| 1105 | + | then true |
---|
| 1106 | + | else (cfgPoolStatus == PoolShutdown)) |
---|
| 1107 | + | then true |
---|
| 1108 | + | else isPoolOneTokenOperationsDisabled |
---|
| 1109 | + | let checks = [if (if (!(isGetDisabled)) |
---|
| 1110 | + | then true |
---|
| 1111 | + | else isManager(i)) |
---|
| 1112 | + | then true |
---|
| 1113 | + | else throwErr("get operation is blocked by admin"), if ((size(i.payments) == 0)) |
---|
| 1114 | + | then true |
---|
| 1115 | + | else throwErr("no payments are expected")] |
---|
| 1116 | + | if ((checks == checks)) |
---|
| 1117 | + | then { |
---|
| 1118 | + | let outAssetId = parseAssetId(outAssetIdStr) |
---|
| 1119 | + | let userAddress = i.caller |
---|
| 1120 | + | let txId = i.transactionId |
---|
| 1121 | + | let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0)) |
---|
| 1122 | + | if ((currentKLp == currentKLp)) |
---|
| 1123 | + | then { |
---|
| 1124 | + | let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil) |
---|
| 1125 | + | if ((unstakeInv == unstakeInv)) |
---|
| 1126 | + | then { |
---|
| 1127 | + | let $t04529145442 = calcGetOneToken(outAssetId, unstakeAmount, cfgLpAssetId, userAddress, txId) |
---|
| 1128 | + | if (($t04529145442 == $t04529145442)) |
---|
| 1129 | + | then { |
---|
| 1130 | + | let outInAmountAsset = $t04529145442._5 |
---|
| 1131 | + | let bonus = $t04529145442._4 |
---|
| 1132 | + | let feeAmount = $t04529145442._3 |
---|
| 1133 | + | let commonState = $t04529145442._2 |
---|
| 1134 | + | let amountEstimated = $t04529145442._1 |
---|
| 1135 | + | let amount = if (if ((minOutAmount > 0)) |
---|
| 1136 | + | then (minOutAmount > amountEstimated) |
---|
| 1137 | + | else false) |
---|
| 1138 | + | then throwErr(makeString(["amount to receive is less than ", toString(minOutAmount)], "")) |
---|
| 1139 | + | else amountEstimated |
---|
| 1140 | + | let burnInv = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)]) |
---|
| 1141 | + | if ((burnInv == burnInv)) |
---|
| 1142 | + | then { |
---|
| 1143 | + | let assetTransfer = [ScriptTransfer(i.caller, amount, outAssetId)] |
---|
| 1144 | + | let sendFee = if ((feeAmount > 0)) |
---|
| 1145 | + | then [ScriptTransfer(feeCollectorAddress, feeAmount, outAssetId)] |
---|
| 1146 | + | else nil |
---|
| 1147 | + | let $t04594946199 = { |
---|
| 1148 | + | let feeAmountForCalc = if ((this == feeCollectorAddress)) |
---|
| 1149 | + | then 0 |
---|
| 1150 | + | else feeAmount |
---|
| 1151 | + | if (outInAmountAsset) |
---|
| 1152 | + | then $Tuple2(-((amount + feeAmountForCalc)), 0) |
---|
| 1153 | + | else $Tuple2(0, -((amount + feeAmountForCalc))) |
---|
| 1154 | + | } |
---|
| 1155 | + | let amountAssetBalanceDelta = $t04594946199._1 |
---|
| 1156 | + | let priceAssetBalanceDelta = $t04594946199._2 |
---|
| 1157 | + | let $t04620346311 = refreshKLpInternal(amountAssetBalanceDelta, priceAssetBalanceDelta, 0) |
---|
| 1158 | + | let refreshKLpActions = $t04620346311._1 |
---|
| 1159 | + | let updatedKLp = $t04620346311._2 |
---|
| 1160 | + | let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp) |
---|
| 1161 | + | if ((isUpdatedKLpValid == isUpdatedKLpValid)) |
---|
| 1162 | + | then $Tuple2((((commonState ++ assetTransfer) ++ sendFee) ++ refreshKLpActions), amount) |
---|
| 1163 | + | else throw("Strict value is not equal to itself.") |
---|
| 1164 | + | } |
---|
| 1165 | + | else throw("Strict value is not equal to itself.") |
---|
| 1166 | + | } |
---|
| 1167 | + | else throw("Strict value is not equal to itself.") |
---|
| 1168 | + | } |
---|
| 1169 | + | else throw("Strict value is not equal to itself.") |
---|
| 1170 | + | } |
---|
| 1171 | + | else throw("Strict value is not equal to itself.") |
---|
| 1172 | + | } |
---|
| 1173 | + | else throw("Strict value is not equal to itself.") |
---|
| 1174 | + | } |
---|
| 1175 | + | |
---|
| 1176 | + | |
---|
| 1177 | + | |
---|
| 1178 | + | @Callable(i) |
---|
| 1179 | + | func get () = { |
---|
| 1180 | + | let res = commonGet(i) |
---|
| 1181 | + | let outAmtAmt = res._1 |
---|
| 1182 | + | let outPrAmt = res._2 |
---|
| 1183 | + | let pmtAmt = res._3 |
---|
| 1184 | + | let pmtAssetId = res._4 |
---|
| 1185 | + | let state = res._5 |
---|
| 1186 | + | let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0)) |
---|
| 1187 | + | if ((currentKLp == currentKLp)) |
---|
| 1188 | + | then { |
---|
| 1189 | + | let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)]) |
---|
| 1190 | + | if ((burnLPAssetOnFactory == burnLPAssetOnFactory)) |
---|
| 1191 | + | then { |
---|
| 1192 | + | let $t04729747379 = refreshKLpInternal(-(outAmtAmt), -(outPrAmt), 0) |
---|
| 1193 | + | let refreshKLpActions = $t04729747379._1 |
---|
| 1194 | + | let updatedKLp = $t04729747379._2 |
---|
| 1195 | + | let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp) |
---|
| 1196 | + | if ((isUpdatedKLpValid == isUpdatedKLpValid)) |
---|
| 1197 | + | then (state ++ refreshKLpActions) |
---|
| 1198 | + | else throw("Strict value is not equal to itself.") |
---|
| 1199 | + | } |
---|
| 1200 | + | else throw("Strict value is not equal to itself.") |
---|
| 1201 | + | } |
---|
| 1202 | + | else throw("Strict value is not equal to itself.") |
---|
| 1203 | + | } |
---|
| 1204 | + | |
---|
| 1205 | + | |
---|
| 1206 | + | |
---|
| 1207 | + | @Callable(i) |
---|
| 1208 | + | func getNoLess (noLessThenAmtAsset,noLessThenPriceAsset) = { |
---|
| 1209 | + | let res = commonGet(i) |
---|
| 1210 | + | let outAmAmt = res._1 |
---|
| 1211 | + | let outPrAmt = res._2 |
---|
| 1212 | + | let pmtAmt = res._3 |
---|
| 1213 | + | let pmtAssetId = res._4 |
---|
| 1214 | + | let state = res._5 |
---|
| 1215 | + | if ((noLessThenAmtAsset > outAmAmt)) |
---|
| 1216 | + | then throw(((("noLessThenAmtAsset failed: " + toString(outAmAmt)) + " < ") + toString(noLessThenAmtAsset))) |
---|
| 1217 | + | else if ((noLessThenPriceAsset > outPrAmt)) |
---|
| 1218 | + | then throw(((("noLessThenPriceAsset failed: " + toString(outPrAmt)) + " < ") + toString(noLessThenPriceAsset))) |
---|
| 1219 | + | else { |
---|
| 1220 | + | let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0)) |
---|
| 1221 | + | if ((currentKLp == currentKLp)) |
---|
| 1222 | + | then { |
---|
| 1223 | + | let burnLPAssetOnFactory = invoke(factoryContract, "burn", [pmtAmt], [AttachedPayment(pmtAssetId, pmtAmt)]) |
---|
| 1224 | + | if ((burnLPAssetOnFactory == burnLPAssetOnFactory)) |
---|
| 1225 | + | then { |
---|
| 1226 | + | let $t04835348434 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0) |
---|
| 1227 | + | let refreshKLpActions = $t04835348434._1 |
---|
| 1228 | + | let updatedKLp = $t04835348434._2 |
---|
| 1229 | + | let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp) |
---|
| 1230 | + | if ((isUpdatedKLpValid == isUpdatedKLpValid)) |
---|
| 1231 | + | then (state ++ refreshKLpActions) |
---|
| 1232 | + | else throw("Strict value is not equal to itself.") |
---|
| 1233 | + | } |
---|
| 1234 | + | else throw("Strict value is not equal to itself.") |
---|
| 1235 | + | } |
---|
| 1236 | + | else throw("Strict value is not equal to itself.") |
---|
| 1237 | + | } |
---|
| 1238 | + | } |
---|
| 1239 | + | |
---|
| 1240 | + | |
---|
| 1241 | + | |
---|
| 1242 | + | @Callable(i) |
---|
| 1243 | + | func unstakeAndGet (amount) = { |
---|
| 1244 | + | let checkPayments = if ((size(i.payments) != 0)) |
---|
| 1245 | + | then throw("No payments are expected") |
---|
| 1246 | + | else true |
---|
| 1247 | + | if ((checkPayments == checkPayments)) |
---|
| 1248 | + | then { |
---|
| 1249 | + | let cfg = getPoolConfig() |
---|
| 1250 | + | let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId]) |
---|
| 1251 | + | let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0)) |
---|
| 1252 | + | if ((currentKLp == currentKLp)) |
---|
| 1253 | + | then { |
---|
| 1254 | + | let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(lpAssetId), amount], nil) |
---|
| 1255 | + | if ((unstakeInv == unstakeInv)) |
---|
| 1256 | + | then { |
---|
| 1257 | + | let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(lpAssetId), amount, i.caller) |
---|
| 1258 | + | let outAmAmt = res._1 |
---|
| 1259 | + | let outPrAmt = res._2 |
---|
| 1260 | + | let poolStatus = parseIntValue(res._9) |
---|
| 1261 | + | let state = res._10 |
---|
| 1262 | + | let checkPoolStatus = if (if (isGlobalShutdown()) |
---|
| 1263 | + | then true |
---|
| 1264 | + | else (poolStatus == PoolShutdown)) |
---|
| 1265 | + | then throw(("Get operation is blocked by admin. Status = " + toString(poolStatus))) |
---|
| 1266 | + | else true |
---|
| 1267 | + | if ((checkPoolStatus == checkPoolStatus)) |
---|
| 1268 | + | then { |
---|
| 1269 | + | let burnLPAssetOnFactory = invoke(factoryContract, "burn", [amount], [AttachedPayment(lpAssetId, amount)]) |
---|
| 1270 | + | if ((burnLPAssetOnFactory == burnLPAssetOnFactory)) |
---|
| 1271 | + | then { |
---|
| 1272 | + | let $t04959349674 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0) |
---|
| 1273 | + | let refreshKLpActions = $t04959349674._1 |
---|
| 1274 | + | let updatedKLp = $t04959349674._2 |
---|
| 1275 | + | let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp) |
---|
| 1276 | + | if ((isUpdatedKLpValid == isUpdatedKLpValid)) |
---|
| 1277 | + | then (state ++ refreshKLpActions) |
---|
| 1278 | + | else throw("Strict value is not equal to itself.") |
---|
| 1279 | + | } |
---|
| 1280 | + | else throw("Strict value is not equal to itself.") |
---|
| 1281 | + | } |
---|
| 1282 | + | else throw("Strict value is not equal to itself.") |
---|
| 1283 | + | } |
---|
| 1284 | + | else throw("Strict value is not equal to itself.") |
---|
| 1285 | + | } |
---|
| 1286 | + | else throw("Strict value is not equal to itself.") |
---|
| 1287 | + | } |
---|
| 1288 | + | else throw("Strict value is not equal to itself.") |
---|
| 1289 | + | } |
---|
| 1290 | + | |
---|
| 1291 | + | |
---|
| 1292 | + | |
---|
| 1293 | + | @Callable(i) |
---|
| 1294 | + | func unstakeAndGetNoLess (unstakeAmount,noLessThenAmountAsset,noLessThenPriceAsset) = { |
---|
| 1295 | + | let isGetDisabled = if (isGlobalShutdown()) |
---|
| 1296 | + | then true |
---|
| 1297 | + | else (cfgPoolStatus == PoolShutdown) |
---|
| 1298 | + | let checks = [if (!(isGetDisabled)) |
---|
| 1299 | + | then true |
---|
| 1300 | + | else throw("get operation is blocked by admin"), if ((size(i.payments) == 0)) |
---|
| 1301 | + | then true |
---|
| 1302 | + | else throw("no payments are expected")] |
---|
| 1303 | + | if ((checks == checks)) |
---|
| 1304 | + | then { |
---|
| 1305 | + | let currentKLp = calcCurrentKLp(toBigInt(0), toBigInt(0), toBigInt(0)) |
---|
| 1306 | + | if ((currentKLp == currentKLp)) |
---|
| 1307 | + | then { |
---|
| 1308 | + | let unstakeInv = invoke(stakingContract, "unstake", [toBase58String(cfgLpAssetId), unstakeAmount], nil) |
---|
| 1309 | + | if ((unstakeInv == unstakeInv)) |
---|
| 1310 | + | then { |
---|
| 1311 | + | let res = estimateGetOperation(toBase58String(i.transactionId), toBase58String(cfgLpAssetId), unstakeAmount, i.caller) |
---|
| 1312 | + | let outAmAmt = res._1 |
---|
| 1313 | + | let outPrAmt = res._2 |
---|
| 1314 | + | let state = res._10 |
---|
| 1315 | + | let checkAmounts = [if ((outAmAmt >= noLessThenAmountAsset)) |
---|
| 1316 | + | then true |
---|
| 1317 | + | else throw(makeString(["amount asset amount to receive is less than ", toString(noLessThenAmountAsset)], "")), if ((outPrAmt >= noLessThenPriceAsset)) |
---|
| 1318 | + | then true |
---|
| 1319 | + | else throw(makeString(["price asset amount to receive is less than ", toString(noLessThenPriceAsset)], ""))] |
---|
| 1320 | + | if ((checkAmounts == checkAmounts)) |
---|
| 1321 | + | then { |
---|
| 1322 | + | let burnLPAssetOnFactory = invoke(factoryContract, "burn", [unstakeAmount], [AttachedPayment(cfgLpAssetId, unstakeAmount)]) |
---|
| 1323 | + | if ((burnLPAssetOnFactory == burnLPAssetOnFactory)) |
---|
| 1324 | + | then { |
---|
| 1325 | + | let $t05100151082 = refreshKLpInternal(-(outAmAmt), -(outPrAmt), 0) |
---|
| 1326 | + | let refreshKLpActions = $t05100151082._1 |
---|
| 1327 | + | let updatedKLp = $t05100151082._2 |
---|
| 1328 | + | let isUpdatedKLpValid = validateUpdatedKLp(currentKLp, updatedKLp) |
---|
| 1329 | + | if ((isUpdatedKLpValid == isUpdatedKLpValid)) |
---|
| 1330 | + | then (state ++ refreshKLpActions) |
---|
| 1331 | + | else throw("Strict value is not equal to itself.") |
---|
| 1332 | + | } |
---|
| 1333 | + | else throw("Strict value is not equal to itself.") |
---|
| 1334 | + | } |
---|
| 1335 | + | else throw("Strict value is not equal to itself.") |
---|
| 1336 | + | } |
---|
| 1337 | + | else throw("Strict value is not equal to itself.") |
---|
| 1338 | + | } |
---|
| 1339 | + | else throw("Strict value is not equal to itself.") |
---|
| 1340 | + | } |
---|
| 1341 | + | else throw("Strict value is not equal to itself.") |
---|
| 1342 | + | } |
---|
| 1343 | + | |
---|
| 1344 | + | |
---|
| 1345 | + | |
---|
| 1346 | + | @Callable(i) |
---|
| 1347 | + | func activate (amtAssetStr,priceAssetStr) = if ((toString(i.caller) != toString(factoryContract))) |
---|
| 1348 | + | then throw("permissions denied") |
---|
| 1349 | + | else $Tuple2([StringEntry(aa(), amtAssetStr), StringEntry(pa(), priceAssetStr)], "success") |
---|
| 1350 | + | |
---|
| 1351 | + | |
---|
| 1352 | + | |
---|
| 1353 | + | @Callable(i) |
---|
| 1354 | + | func refreshKLp () = { |
---|
| 1355 | + | let lastRefreshedBlockHeight = valueOrElse(getInteger(keyKLpRefreshedHeight), 0) |
---|
| 1356 | + | let checkLastRefreshedBlockHeight = if (((height - lastRefreshedBlockHeight) >= kLpRefreshDelay)) |
---|
| 1357 | + | then unit |
---|
| 1358 | + | else throwErr(makeString([toString(kLpRefreshDelay), " blocks have not passed since the previous call"], "")) |
---|
| 1359 | + | if ((checkLastRefreshedBlockHeight == checkLastRefreshedBlockHeight)) |
---|
| 1360 | + | then { |
---|
| 1361 | + | let kLp = valueOrErrorMessage(parseBigInt(valueOrElse(getString(this, keyKLp), "0")), fmtErr("invalid kLp")) |
---|
| 1362 | + | let $t05231152375 = refreshKLpInternal(0, 0, 0) |
---|
| 1363 | + | let kLpUpdateActions = $t05231152375._1 |
---|
| 1364 | + | let updatedKLp = $t05231152375._2 |
---|
| 1365 | + | let actions = if ((kLp != updatedKLp)) |
---|
| 1366 | + | then kLpUpdateActions |
---|
| 1367 | + | else throwErr("nothing to refresh") |
---|
| 1368 | + | $Tuple2(actions, toString(updatedKLp)) |
---|
| 1369 | + | } |
---|
| 1370 | + | else throw("Strict value is not equal to itself.") |
---|
| 1371 | + | } |
---|
| 1372 | + | |
---|
| 1373 | + | |
---|
| 1374 | + | |
---|
| 1375 | + | @Callable(i) |
---|
| 1376 | + | func getPoolConfigWrapperREADONLY () = $Tuple2(nil, getPoolConfig()) |
---|
| 1377 | + | |
---|
| 1378 | + | |
---|
| 1379 | + | |
---|
| 1380 | + | @Callable(i) |
---|
| 1381 | + | func getAccBalanceWrapperREADONLY (assetId) = $Tuple2(nil, getAccBalance(assetId)) |
---|
| 1382 | + | |
---|
| 1383 | + | |
---|
| 1384 | + | |
---|
| 1385 | + | @Callable(i) |
---|
| 1386 | + | func calcPricesWrapperREADONLY (amAmt,prAmt,lpAmt) = { |
---|
| 1387 | + | let prices = calcPrices(amAmt, prAmt, lpAmt) |
---|
| 1388 | + | $Tuple2(nil, [toString(prices[0]), toString(prices[1]), toString(prices[2])]) |
---|
| 1389 | + | } |
---|
| 1390 | + | |
---|
| 1391 | + | |
---|
| 1392 | + | |
---|
| 1393 | + | @Callable(i) |
---|
| 1394 | + | func toX18WrapperREADONLY (origVal,origScaleMult) = $Tuple2(nil, toString(toX18(origVal, origScaleMult))) |
---|
| 1395 | + | |
---|
| 1396 | + | |
---|
| 1397 | + | |
---|
| 1398 | + | @Callable(i) |
---|
| 1399 | + | func fromX18WrapperREADONLY (val,resultScaleMult) = $Tuple2(nil, fromX18(parseBigIntValue(val), resultScaleMult)) |
---|
| 1400 | + | |
---|
| 1401 | + | |
---|
| 1402 | + | |
---|
| 1403 | + | @Callable(i) |
---|
| 1404 | + | func calcPriceBigIntWrapperREADONLY (prAmtX18,amAmtX18) = $Tuple2(nil, toString(calcPriceBigInt(parseBigIntValue(prAmtX18), parseBigIntValue(amAmtX18)))) |
---|
| 1405 | + | |
---|
| 1406 | + | |
---|
| 1407 | + | |
---|
| 1408 | + | @Callable(i) |
---|
| 1409 | + | func estimatePutOperationWrapperREADONLY (txId58,slippageTolerance,inAmAssetAmt,inAmAssetId,inPrAssetAmt,inPrAssetId,userAddress,isEvaluate,emitLp) = $Tuple2(nil, estimatePutOperation(txId58, slippageTolerance, inAmAssetAmt, inAmAssetId, inPrAssetAmt, inPrAssetId, userAddress, isEvaluate, emitLp)) |
---|
| 1410 | + | |
---|
| 1411 | + | |
---|
| 1412 | + | |
---|
| 1413 | + | @Callable(i) |
---|
| 1414 | + | func estimateGetOperationWrapperREADONLY (txId58,pmtAssetId,pmtLpAmt,userAddress) = { |
---|
| 1415 | + | let res = estimateGetOperation(txId58, pmtAssetId, pmtLpAmt, addressFromStringValue(userAddress)) |
---|
| 1416 | + | $Tuple2(nil, $Tuple10(res._1, res._2, res._3, res._4, res._5, res._6, res._7, toString(res._8), res._9, res._10)) |
---|
| 1417 | + | } |
---|
| 1418 | + | |
---|
| 1419 | + | |
---|
| 1420 | + | |
---|
| 1421 | + | @Callable(i) |
---|
| 1422 | + | func statsREADONLY () = { |
---|
| 1423 | + | let cfg = getPoolConfig() |
---|
| 1424 | + | let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId]) |
---|
| 1425 | + | let amtAssetId = cfg[idxAmtAssetId] |
---|
| 1426 | + | let priceAssetId = cfg[idxPriceAssetId] |
---|
| 1427 | + | let iAmtAssetId = cfg[idxIAmtAssetId] |
---|
| 1428 | + | let iPriceAssetId = cfg[idxIPriceAssetId] |
---|
| 1429 | + | let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm]) |
---|
| 1430 | + | let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm]) |
---|
| 1431 | + | let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity |
---|
| 1432 | + | let accAmtAssetBalance = getAccBalance(amtAssetId) |
---|
| 1433 | + | let accPriceAssetBalance = getAccBalance(priceAssetId) |
---|
| 1434 | + | let pricesList = if ((poolLPBalance == 0)) |
---|
| 1435 | + | then [zeroBigInt, zeroBigInt, zeroBigInt] |
---|
| 1436 | + | else calcPrices(accAmtAssetBalance, accPriceAssetBalance, poolLPBalance) |
---|
| 1437 | + | let curPrice = 0 |
---|
| 1438 | + | let lpAmtAssetShare = fromX18(pricesList[1], scale8) |
---|
| 1439 | + | let lpPriceAssetShare = fromX18(pricesList[2], scale8) |
---|
| 1440 | + | let poolWeight = value(getInteger(factoryContract, keyPoolWeight(toString(this)))) |
---|
| 1441 | + | $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(accAmtAssetBalance), toString(accPriceAssetBalance), toString(poolLPBalance), toString(curPrice), toString(lpAmtAssetShare), toString(lpPriceAssetShare), toString(poolWeight)], SEP)) |
---|
| 1442 | + | } |
---|
| 1443 | + | |
---|
| 1444 | + | |
---|
| 1445 | + | |
---|
| 1446 | + | @Callable(i) |
---|
| 1447 | + | func evaluatePutByAmountAssetREADONLY (inAmAssetAmt) = { |
---|
| 1448 | + | let cfg = getPoolConfig() |
---|
| 1449 | + | let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId]) |
---|
| 1450 | + | let amAssetIdStr = cfg[idxAmtAssetId] |
---|
| 1451 | + | let amAssetId = fromBase58String(amAssetIdStr) |
---|
| 1452 | + | let prAssetIdStr = cfg[idxPriceAssetId] |
---|
| 1453 | + | let prAssetId = fromBase58String(prAssetIdStr) |
---|
| 1454 | + | let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm]) |
---|
| 1455 | + | let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm]) |
---|
| 1456 | + | let poolStatus = cfg[idxPoolStatus] |
---|
| 1457 | + | let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity |
---|
| 1458 | + | let accAmtAssetBalance = getAccBalance(amAssetIdStr) |
---|
| 1459 | + | let accPriceAssetBalance = getAccBalance(prAssetIdStr) |
---|
| 1460 | + | let amtAssetAmtX18 = toX18(accAmtAssetBalance, amtAssetDcm) |
---|
| 1461 | + | let priceAssetAmtX18 = toX18(accPriceAssetBalance, priceAssetDcm) |
---|
| 1462 | + | let curPriceX18 = if ((poolLPBalance == 0)) |
---|
| 1463 | + | then zeroBigInt |
---|
| 1464 | + | else calcPriceBigInt(priceAssetAmtX18, amtAssetAmtX18) |
---|
| 1465 | + | let inAmAssetAmtX18 = toX18(inAmAssetAmt, amtAssetDcm) |
---|
| 1466 | + | let inPrAssetAmtX18 = fraction(inAmAssetAmtX18, curPriceX18, scale18) |
---|
| 1467 | + | let inPrAssetAmt = fromX18(inPrAssetAmtX18, priceAssetDcm) |
---|
| 1468 | + | let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false) |
---|
| 1469 | + | let calcLpAmt = estPut._1 |
---|
| 1470 | + | let curPriceCalc = estPut._3 |
---|
| 1471 | + | let amBalance = estPut._4 |
---|
| 1472 | + | let prBalance = estPut._5 |
---|
| 1473 | + | let lpEmission = estPut._6 |
---|
| 1474 | + | $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(calcLpAmt), toString(fromX18(curPriceX18, scale8)), toString(amBalance), toString(prBalance), toString(lpEmission), poolStatus, toString(inAmAssetAmt), toString(inPrAssetAmt)], SEP)) |
---|
| 1475 | + | } |
---|
| 1476 | + | |
---|
| 1477 | + | |
---|
| 1478 | + | |
---|
| 1479 | + | @Callable(i) |
---|
| 1480 | + | func evaluatePutByPriceAssetREADONLY (inPrAssetAmt) = { |
---|
| 1481 | + | let cfg = getPoolConfig() |
---|
| 1482 | + | let lpAssetId = fromBase58String(cfg[idxPoolLPAssetId]) |
---|
| 1483 | + | let amAssetIdStr = cfg[idxAmtAssetId] |
---|
| 1484 | + | let amAssetId = fromBase58String(amAssetIdStr) |
---|
| 1485 | + | let prAssetIdStr = cfg[idxPriceAssetId] |
---|
| 1486 | + | let prAssetId = fromBase58String(prAssetIdStr) |
---|
| 1487 | + | let amtAssetDcm = parseIntValue(cfg[idxAmtAssetDcm]) |
---|
| 1488 | + | let priceAssetDcm = parseIntValue(cfg[idxPriceAssetDcm]) |
---|
| 1489 | + | let poolStatus = cfg[idxPoolStatus] |
---|
| 1490 | + | let poolLPBalance = valueOrErrorMessage(assetInfo(lpAssetId), (("Asset " + toBase58String(lpAssetId)) + " doesn't exist")).quantity |
---|
| 1491 | + | let amBalanceRaw = getAccBalance(amAssetIdStr) |
---|
| 1492 | + | let prBalanceRaw = getAccBalance(prAssetIdStr) |
---|
| 1493 | + | let amBalanceRawX18 = toX18(amBalanceRaw, amtAssetDcm) |
---|
| 1494 | + | let prBalanceRawX18 = toX18(prBalanceRaw, priceAssetDcm) |
---|
| 1495 | + | let curPriceX18 = if ((poolLPBalance == 0)) |
---|
| 1496 | + | then zeroBigInt |
---|
| 1497 | + | else calcPriceBigInt(prBalanceRawX18, amBalanceRawX18) |
---|
| 1498 | + | let inPrAssetAmtX18 = toX18(inPrAssetAmt, priceAssetDcm) |
---|
| 1499 | + | let inAmAssetAmtX18 = fraction(inPrAssetAmtX18, scale18, curPriceX18) |
---|
| 1500 | + | let inAmAssetAmt = fromX18(inAmAssetAmtX18, amtAssetDcm) |
---|
| 1501 | + | let estPut = estimatePutOperation("", 500000, inAmAssetAmt, amAssetId, inPrAssetAmt, prAssetId, "", true, false) |
---|
| 1502 | + | let calcLpAmt = estPut._1 |
---|
| 1503 | + | let curPriceCalc = estPut._3 |
---|
| 1504 | + | let amBalance = estPut._4 |
---|
| 1505 | + | let prBalance = estPut._5 |
---|
| 1506 | + | let lpEmission = estPut._6 |
---|
| 1507 | + | $Tuple2(nil, makeString(["%d%d%d%d%d%d%d%d", toString(calcLpAmt), toString(fromX18(curPriceX18, scale8)), toString(amBalance), toString(prBalance), toString(lpEmission), poolStatus, toString(inAmAssetAmt), toString(inPrAssetAmt)], SEP)) |
---|
| 1508 | + | } |
---|
| 1509 | + | |
---|
| 1510 | + | |
---|
| 1511 | + | |
---|
| 1512 | + | @Callable(i) |
---|
| 1513 | + | func evaluateGetREADONLY (paymentLpAssetId,paymentLpAmt) = { |
---|
| 1514 | + | let res = estimateGetOperation("", paymentLpAssetId, paymentLpAmt, this) |
---|
| 1515 | + | let outAmAmt = res._1 |
---|
| 1516 | + | let outPrAmt = res._2 |
---|
| 1517 | + | let amBalance = res._5 |
---|
| 1518 | + | let prBalance = res._6 |
---|
| 1519 | + | let lpEmission = res._7 |
---|
| 1520 | + | let curPrice = res._8 |
---|
| 1521 | + | let poolStatus = parseIntValue(res._9) |
---|
| 1522 | + | $Tuple2(nil, makeString(["%d%d%d%d%d%d%d", toString(outAmAmt), toString(outPrAmt), toString(amBalance), toString(prBalance), toString(lpEmission), toString(curPrice), toString(poolStatus)], SEP)) |
---|
| 1523 | + | } |
---|
| 1524 | + | |
---|
| 1525 | + | |
---|
| 1526 | + | @Verifier(tx) |
---|
| 1527 | + | func verify () = { |
---|
| 1528 | + | let targetPublicKey = match managerPublicKeyOrUnit() { |
---|
| 1529 | + | case pk: ByteVector => |
---|
| 1530 | + | pk |
---|
| 1531 | + | case _: Unit => |
---|
| 1532 | + | tx.senderPublicKey |
---|
| 1533 | + | case _ => |
---|
| 1534 | + | throw("Match error") |
---|
| 1535 | + | } |
---|
| 1536 | + | match tx { |
---|
| 1537 | + | case order: Order => |
---|
| 1538 | + | let matcherPub = getMatcherPubOrFail() |
---|
| 1539 | + | let $t06130661375 = validateMatcherOrderAllowed(order) |
---|
| 1540 | + | let orderValid = $t06130661375._1 |
---|
| 1541 | + | let orderValidInfo = $t06130661375._2 |
---|
| 1542 | + | let senderValid = sigVerify(order.bodyBytes, order.proofs[0], order.senderPublicKey) |
---|
| 1543 | + | let matcherValid = sigVerify(order.bodyBytes, order.proofs[1], matcherPub) |
---|
| 1544 | + | if (if (if (orderValid) |
---|
| 1545 | + | then senderValid |
---|
| 1546 | + | else false) |
---|
| 1547 | + | then matcherValid |
---|
| 1548 | + | else false) |
---|
| 1549 | + | then true |
---|
| 1550 | + | else throwOrderError(orderValid, orderValidInfo, senderValid, matcherValid) |
---|
| 1551 | + | case s: SetScriptTransaction => |
---|
| 1552 | + | if (sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey)) |
---|
| 1553 | + | then true |
---|
| 1554 | + | else { |
---|
| 1555 | + | let newHash = blake2b256(value(s.script)) |
---|
| 1556 | + | let allowedHash = fromBase64String(value(getString(factoryContract, keyAllowedLpScriptHash()))) |
---|
| 1557 | + | let currentHash = scriptHash(this) |
---|
| 1558 | + | if ((allowedHash == newHash)) |
---|
| 1559 | + | then (currentHash != newHash) |
---|
| 1560 | + | else false |
---|
| 1561 | + | } |
---|
| 1562 | + | case _ => |
---|
| 1563 | + | sigVerify(tx.bodyBytes, tx.proofs[0], targetPublicKey) |
---|
| 1564 | + | } |
---|
| 1565 | + | } |
---|
| 1566 | + | |
---|