From 11c217c9e419d787bc852b535137d9a92c592d82 Mon Sep 17 00:00:00 2001 From: bra1nsurfer Date: Fri, 23 Jun 2023 14:46:38 +0300 Subject: [PATCH 1/3] Validate if new KLp/DLp is big0 calcKLp/calcDLp function returns big0 if lp asset quantity is 0 --- ride/lp.ride | 2 +- ride/lp_stable.ride | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ride/lp.ride b/ride/lp.ride index ec5b413e..3dbb4f10 100644 --- a/ride/lp.ride +++ b/ride/lp.ride @@ -665,7 +665,7 @@ func skipOrderValidation() = { } func validateUpdatedKLp(oldKLp: BigInt, updatedKLp: BigInt) = { - updatedKLp >= oldKLp || + updatedKLp == big0 || updatedKLp >= oldKLp || [ "updated KLp lower than current KLp", oldKLp.toString(), diff --git a/ride/lp_stable.ride b/ride/lp_stable.ride index 0341f96a..84827215 100644 --- a/ride/lp_stable.ride +++ b/ride/lp_stable.ride @@ -656,7 +656,7 @@ func refreshDLpInternal(amountAssetBalanceDelta: Int, priceAssetBalanceDelta: In } func validateUpdatedDLp(oldDLp: BigInt, updatedDLp: BigInt) = { - updatedDLp >= oldDLp || "updated DLp lower than current DLp".throwErr() + updatedDLp == big0 || updatedDLp >= oldDLp || "updated DLp lower than current DLp".throwErr() } func validateMatcherOrderAllowed(order: Order) = { From 9c38ec948f22804542f9b0673fc9420a927232ea Mon Sep 17 00:00:00 2001 From: bra1nsurfer Date: Mon, 26 Jun 2023 10:31:12 +0300 Subject: [PATCH 2/3] Update tests Changed to unstake and get all LP tokens --- test/components/lp/unstakeAndGet.mjs | 8 ++++---- test/components/lp_stable/unstakeAndGet.mjs | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/components/lp/unstakeAndGet.mjs b/test/components/lp/unstakeAndGet.mjs index dac2757e..f8c42ce8 100644 --- a/test/components/lp/unstakeAndGet.mjs +++ b/test/components/lp/unstakeAndGet.mjs @@ -19,14 +19,14 @@ describe('lp: unstakeAndGet.mjs', /** @this {MochaSuiteModified} */() => { async function () { const usdnAmount = 10e6; const shibAmount = 10e2; - const lpAmount = 1e9 - 1; + const lpAmount = 1e9; const shouldAutoStake = true; const expectedPriceLast = 1e8; const expectedPriceHistory = 1e8; const expectedInvokesCount = 4; - const expectedUsdnAmount = usdnAmount - 1; - const expectedShibAmount = shibAmount - 1; + const expectedUsdnAmount = usdnAmount; + const expectedShibAmount = shibAmount; const lp = address(this.accounts.lp, chainId); @@ -87,7 +87,7 @@ describe('lp: unstakeAndGet.mjs', /** @this {MochaSuiteModified} */() => { }, { key: '%s__kLp', type: 'string', - value: '100000000000000000000000000000000', + value: '0', }]); expect(stateChanges.transfers).to.eql([{ diff --git a/test/components/lp_stable/unstakeAndGet.mjs b/test/components/lp_stable/unstakeAndGet.mjs index dbf9999c..66cff69e 100644 --- a/test/components/lp_stable/unstakeAndGet.mjs +++ b/test/components/lp_stable/unstakeAndGet.mjs @@ -18,7 +18,7 @@ describe('lp_stable: unstakeAndGet.mjs', /** @this {MochaSuiteModified} */() => async function () { const usdnAmount = 1e16 / 10; const usdtAmount = 1e8 / 10; - const lpStableAmount = 268990720838218; + const lpStableAmount = 2689907208382172; const shouldAutoStake = true; const priceLast = 1e16; const priceHistory = 1e16; @@ -62,7 +62,7 @@ describe('lp_stable: unstakeAndGet.mjs', /** @this {MochaSuiteModified} */() => expect(stateChanges.data).to.eql([{ key: `%s%s%s__G__${address(this.accounts.user1, chainId)}__${id}`, type: 'string', - value: `%d%d%d%d%d%d__${usdtAmount / 10}__${usdnAmount / 10}__${lpStableAmount}__${priceLast}__${height}__${timestamp}`, + value: `%d%d%d%d%d%d__${usdtAmount}__${usdnAmount}__${lpStableAmount}__${priceLast}__${height}__${timestamp}`, }, { key: '%s%s__price__last', type: 'integer', @@ -78,17 +78,17 @@ describe('lp_stable: unstakeAndGet.mjs', /** @this {MochaSuiteModified} */() => }, { key: '%s__dLp', type: 'string', - value: '10000000000000006424805538327', + value: '0', }]); expect(stateChanges.transfers).to.eql([{ address: address(this.accounts.user1, chainId), asset: this.usdtAssetId, - amount: usdtAmount / 10, + amount: usdtAmount, }, { address: address(this.accounts.user1, chainId), asset: this.usdnAssetId, - amount: (usdnAmount / 10).toString(), + amount: (usdnAmount).toString(), }]); expect(stateChanges.invokes.map((item) => [item.dApp, item.call.function])) From 19116b1c7abb8f8aa3c10a58cfd1225984ea6e30 Mon Sep 17 00:00:00 2001 From: bra1nsurfer Date: Mon, 10 Jul 2023 14:15:13 +0300 Subject: [PATCH 3/3] Removed single wavelet in staked balance Added check, if stakedAsset is zero, additional balance should also be zero Some refactoring variable names --- ride/lp.ride | 80 ++++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/ride/lp.ride b/ride/lp.ride index 2ad91fd2..bbc0d56c 100644 --- a/ride/lp.ride +++ b/ride/lp.ride @@ -122,12 +122,12 @@ let keyKLpRefreshDelay = ["%s", "refreshKLpDelay"].makeString(SEP) let kLpRefreshDelayDefault = 30 let kLpRefreshDelay = this.getInteger(keyKLpRefreshDelay).valueOrElse(kLpRefreshDelayDefault) -# Additional balances keys -func keyAdditionalBalance(assetId: String) = makeString(["%s%s", "stakedBalance", assetId], SEP) -func keyStakingAssetBalance(assetId: String) = makeString(["%s%s", "shareAssetBalance", assetId], SEP) -# Additional balance value or zero -func getAdditionalBalanceOrZero(assetId: String) = this.getInteger(keyAdditionalBalance(assetId)).valueOrElse(0) -func getStakingAssetBalanceOrZero(assetId: String) = this.getInteger(keyStakingAssetBalance(assetId)).valueOrElse(0) +# Staked balance keys +func keyStakedBalance(assetId: String) = makeString(["%s%s", "stakedBalance", assetId], SEP) +func keyShareAssetBalance(assetId: String) = makeString(["%s%s", "shareAssetBalance", assetId], SEP) +# Staked balance value or zero +func getStakedBalanceOrZero(assetId: String) = this.getInteger(keyStakedBalance(assetId)).valueOrElse(0) +func getShareAssetBalanceOrZero(assetId: String) = this.getInteger(keyShareAssetBalance(assetId)).valueOrElse(0) #------------------------ # KEYS ON OTHER CONTRACTS @@ -264,7 +264,7 @@ func getAccBalance(assetId: String) = { } else { assetBalance(this, fromBase58String(assetId)) } - let totalBalance = balanceOnPool + getAdditionalBalanceOrZero(assetId) - getStakingAssetBalanceOrZero(assetId) + let totalBalance = balanceOnPool + getStakedBalanceOrZero(assetId) - getShareAssetBalanceOrZero(assetId) max([0, totalBalance]) } @@ -291,21 +291,21 @@ func getRate(proxy: Address) = { } # Deposit amount of assetId to Leasing through Proxy -# Write new additionalBalalnce and stakingAssetBalance -func deposit(assetId: String, amount: Int, stakingAssetId: String, proxy: Address) = { - strict currentAdditionalBalance = getAdditionalBalanceOrZero(assetId) - strict currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId) +# Write new stakedBalance and shareAssetBalance +func deposit(assetId: String, amount: Int, shareAssetId: String, proxy: Address) = { + strict currentStakedBalance = getStakedBalanceOrZero(assetId) + strict currentShareAssetBalance = getShareAssetBalanceOrZero(shareAssetId) let asset = parseAssetId(assetId) if (amount > 0) then { strict depositInvoke = proxy.invoke("deposit", [], [AttachedPayment(asset, amount)]) match depositInvoke { - case receivedStakingAsset:Int => { - let newAdditionalBalance = currentAdditionalBalance + amount - let newStakingAssetBalance = currentStakingAssetBalance + receivedStakingAsset + case receivedShareAsset:Int => { + let newStakedBalance = currentStakedBalance + amount + let newShareAssetBalance = currentShareAssetBalance + receivedShareAsset [ - IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), - IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance) + IntegerEntry(keyStakedBalance(assetId), newStakedBalance), + IntegerEntry(keyShareAssetBalance(shareAssetId), newShareAssetBalance) ] } case _ => [] @@ -314,28 +314,28 @@ func deposit(assetId: String, amount: Int, stakingAssetId: String, proxy: Addres } # Withdraw requested amount of assetId from Leased assets through Proxy -# Amount of attached stakingAsset is calculated from Proxy rate +# Amount of attached shareAsset is calculated from Proxy rate # Diff amount of sWaves from old Rate is sent to Profit Address -func withdraw(assetId: String, amount: Int, stakingAssetId: String, proxy: Address, proxyRateMul: Int, profitAddress: Address) = { - strict currentAdditionalBalance = getAdditionalBalanceOrZero(assetId) - strict currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId) +func withdraw(assetId: String, amount: Int, shareAssetId: String, proxy: Address, proxyRateMul: Int, profitAddress: Address) = { + strict currentStakedBalance = getStakedBalanceOrZero(assetId) + strict currentShareAssetBalance = getShareAssetBalanceOrZero(shareAssetId) strict currentProxyRate = getRate(proxy) - let oldRate = fraction(proxyRateMul, currentAdditionalBalance, currentStakingAssetBalance) - let stakingAsset = parseAssetId(stakingAssetId) + let oldRate = fraction(proxyRateMul, currentStakedBalance, currentShareAssetBalance) + let shareAsset = parseAssetId(shareAssetId) let oldSendStakingAmount = fraction(proxyRateMul, amount, oldRate) - let sendStakingAssetAmount = fraction(proxyRateMul, amount, currentProxyRate) - let profitAmount = max([0, oldSendStakingAmount - sendStakingAssetAmount]) - if (sendStakingAssetAmount > 0) then { - strict withdrawInvoke = proxy.invoke("withdraw", [], [AttachedPayment(stakingAsset, sendStakingAssetAmount)]) + let sendShareAssetAmount = fraction(proxyRateMul, amount, currentProxyRate) + let profitAmount = max([0, oldSendStakingAmount - sendShareAssetAmount]) + if (sendShareAssetAmount > 0) then { + strict withdrawInvoke = proxy.invoke("withdraw", [], [AttachedPayment(shareAsset, sendShareAssetAmount)]) match withdrawInvoke { case receivedAssets:Int => { - let newAdditionalBalance = currentAdditionalBalance - receivedAssets - let newStakingAssetBalance = currentStakingAssetBalance - sendStakingAssetAmount - profitAmount + let newShareAssetBalance = currentShareAssetBalance - sendShareAssetAmount - profitAmount + let newStakedBalance = if (newShareAssetBalance == 0) then 0 else currentStakedBalance - receivedAssets [ - IntegerEntry(keyAdditionalBalance(assetId), newAdditionalBalance), - IntegerEntry(keyStakingAssetBalance(stakingAssetId), newStakingAssetBalance), - ScriptTransfer(profitAddress, profitAmount, parseAssetId(stakingAssetId)) + IntegerEntry(keyStakedBalance(assetId), newStakedBalance), + IntegerEntry(keyShareAssetBalance(shareAssetId), newShareAssetBalance), + ScriptTransfer(profitAddress, profitAmount, parseAssetId(shareAssetId)) ] } case _ => [] @@ -356,21 +356,21 @@ func getLeaseProxyConfig(assetId: String) = { } # Rebalance assetId to targetRatio and minBalance through Proxy -func rebalanceInternal(targetRatio: Int, assetId: String, stakingAssetId: String, minBalance: Int, proxy: Address, proxyRateMul: Int, profitAddress: Address) = { - strict currentAdditionalBalance = getAdditionalBalanceOrZero(assetId) - strict currentStakingAssetBalance = getStakingAssetBalanceOrZero(stakingAssetId) +func rebalanceInternal(targetRatio: Int, assetId: String, shareAssetId: String, minBalance: Int, proxy: Address, proxyRateMul: Int, profitAddress: Address) = { + strict currentStakedBalance = getStakedBalanceOrZero(assetId) + strict currentShareAssetBalance = getShareAssetBalanceOrZero(shareAssetId) let leasableTotalBalance = max([0, getAccBalance(assetId) - minBalance]) - let targetAdditionalBalance = fraction(targetRatio, leasableTotalBalance, 100) - let diff = currentAdditionalBalance - targetAdditionalBalance + let targetStakedBalance = fraction(targetRatio, leasableTotalBalance, 100) + let diff = currentStakedBalance - targetStakedBalance if (diff == 0) then { [] } else if (diff < 0) then { let sendAssetAmount = -diff - deposit(assetId, sendAssetAmount, stakingAssetId, proxy) + deposit(assetId, sendAssetAmount, shareAssetId, proxy) } else { let getAssetAmount = diff - withdraw(assetId, getAssetAmount, stakingAssetId, proxy, proxyRateMul, profitAddress) + withdraw(assetId, getAssetAmount, shareAssetId, proxy, proxyRateMul, profitAddress) } } @@ -389,8 +389,8 @@ func withdrawAndRebalanceAsset(assetId: String, getAmount: Int) = { let (isLeasable, leasedRatio, minBalance, proxyAddress, proxyAssetId, proxyRateMul, stakingProfitAddress) = getLeaseProxyConfig(assetId) if (isLeasable) then { strict newTotalLeasableBalance = max([0, getAccBalance(assetId) - getAmount - minBalance]) - strict newAdditionalBalance = fraction(leasedRatio, newTotalLeasableBalance, 100) - strict withdrawAmount = getAdditionalBalanceOrZero(assetId) - newAdditionalBalance + strict newStakedBalance = fraction(leasedRatio, newTotalLeasableBalance, 100) + strict withdrawAmount = getStakedBalanceOrZero(assetId) - newStakedBalance if (withdrawAmount < 0) then { deposit(assetId, -withdrawAmount, proxyAssetId, addressFromStringValue(proxyAddress)) } else {