Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Commitment]: Skip funds locked #816

Merged
merged 6 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions x/amm/keeper/apply_exit_pool_state_change.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import (
"github.com/elys-network/elys/x/amm/types"
)

func (k Keeper) ApplyExitPoolStateChange(ctx sdk.Context, pool types.Pool, exiter sdk.AccAddress, numShares math.Int, exitCoins sdk.Coins) (sdk.Coins, error) {
func (k Keeper) ApplyExitPoolStateChange(ctx sdk.Context, pool types.Pool, exiter sdk.AccAddress, numShares math.Int, exitCoins sdk.Coins, isLiquidation bool) (sdk.Coins, error) {
// Withdraw exit amount of token from commitment module to exiter's wallet.
poolShareDenom := types.GetPoolShareDenom(pool.GetPoolId())

// Withdraw committed LP tokens
err := k.commitmentKeeper.UncommitTokens(ctx, exiter, poolShareDenom, numShares)
err := k.commitmentKeeper.UncommitTokens(ctx, exiter, poolShareDenom, numShares, isLiquidation)
if err != nil {
return sdk.Coins{}, err
}
Expand Down
2 changes: 1 addition & 1 deletion x/amm/keeper/apply_exit_pool_state_change_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,6 @@ func (suite *KeeperTestSuite) TestApplyExitPoolStateChange_WithdrawFromCommitmen
suite.Require().True(lpTokenBalance.Amount.Equal(sdk.ZeroInt()))

ctx = ctx.WithBlockTime(ctx.BlockTime().Add(time.Hour))
_, err = app.AmmKeeper.ApplyExitPoolStateChange(ctx, pool, addrs[0], pool.TotalShares.Amount, coins)
_, err = app.AmmKeeper.ApplyExitPoolStateChange(ctx, pool, addrs[0], pool.TotalShares.Amount, coins, false)
suite.Require().NoError(err)
}
3 changes: 2 additions & 1 deletion x/amm/keeper/keeper_exit_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func (k Keeper) ExitPool(
shareInAmount math.Int,
tokenOutMins sdk.Coins,
tokenOutDenom string,
isLiquidation bool,
) (exitCoins, exitCoinsAfterExitFee sdk.Coins, err error) {
pool, poolExists := k.GetPool(ctx, poolId)
if !poolExists {
Expand All @@ -36,7 +37,7 @@ func (k Keeper) ExitPool(
exitCoins, tokenOutMins)
}

exitCoinsAfterExitFee, err = k.ApplyExitPoolStateChange(ctx, pool, sender, shareInAmount, exitCoins)
exitCoinsAfterExitFee, err = k.ApplyExitPoolStateChange(ctx, pool, sender, shareInAmount, exitCoins, isLiquidation)
if err != nil {
return sdk.Coins{}, sdk.Coins{}, err
}
Expand Down
2 changes: 1 addition & 1 deletion x/amm/keeper/msg_server_exit_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (k msgServer) ExitPool(goCtx context.Context, msg *types.MsgExitPool) (*typ
return nil, err
}

exitCoins, _, err := k.Keeper.ExitPool(ctx, sender, msg.PoolId, msg.ShareAmountIn, msg.MinAmountsOut, msg.TokenOutDenom)
exitCoins, _, err := k.Keeper.ExitPool(ctx, sender, msg.PoolId, msg.ShareAmountIn, msg.MinAmountsOut, msg.TokenOutDenom, false)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion x/commitment/keeper/commitments.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@
}

// Subtract the amount from the committed balance
err = commitments.DeductFromCommitted(denom, amount, uint64(ctx.BlockTime().Unix()))
err = commitments.DeductFromCommitted(denom, amount, uint64(ctx.BlockTime().Unix()), false)

Check warning on line 184 in x/commitment/keeper/commitments.go

View check run for this annotation

Codecov / codecov/patch

x/commitment/keeper/commitments.go#L184

Added line #L184 was not covered by tests
if err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions x/commitment/keeper/msg_server_uncommit_tokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
ptypes "github.com/elys-network/elys/x/parameter/types"
)

func (k Keeper) UncommitTokens(ctx sdk.Context, addr sdk.AccAddress, denom string, amount math.Int) error {
func (k Keeper) UncommitTokens(ctx sdk.Context, addr sdk.AccAddress, denom string, amount math.Int, isLiquidation bool) error {
assetProfile, found := k.assetProfileKeeper.GetEntry(ctx, denom)
if !found {
return errorsmod.Wrapf(assetprofiletypes.ErrAssetProfileNotFound, "denom: %s", denom)
Expand Down Expand Up @@ -40,7 +40,7 @@
}

// Deduct from committed tokens
err := commitments.DeductFromCommitted(denom, amount, uint64(ctx.BlockTime().Unix()))
err := commitments.DeductFromCommitted(denom, amount, uint64(ctx.BlockTime().Unix()), isLiquidation)
if err != nil {
return err
}
Expand Down Expand Up @@ -107,7 +107,7 @@
return nil, types.ErrUnsupportedUncommitToken
}

err = k.Keeper.UncommitTokens(ctx, addr, msg.Denom, msg.Amount)
err = k.Keeper.UncommitTokens(ctx, addr, msg.Denom, msg.Amount, false)

Check warning on line 110 in x/commitment/keeper/msg_server_uncommit_tokens.go

View check run for this annotation

Codecov / codecov/patch

x/commitment/keeper/msg_server_uncommit_tokens.go#L110

Added line #L110 was not covered by tests
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion x/commitment/keeper/msg_server_uncommit_tokens_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestUncommitTokens(t *testing.T) {
require.NoError(t, err)

// Call the UncommitTokens function
err = keeper.UncommitTokens(ctx, addr[0], denom, uncommitAmount)
err = keeper.UncommitTokens(ctx, addr[0], denom, uncommitAmount, false)
require.NoError(t, err)

// Check if the committed tokens have been added to the store
Expand Down
4 changes: 2 additions & 2 deletions x/commitment/types/commitments.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (c Commitments) CommittedTokensLocked(ctx sdk.Context) (sdk.Coins, sdk.Coin
return totalLocked, totalCommitted
}

func (c *Commitments) DeductFromCommitted(denom string, amount math.Int, currTime uint64) error {
func (c *Commitments) DeductFromCommitted(denom string, amount math.Int, currTime uint64, isLiquidation bool) error {
for i, token := range c.CommittedTokens {
if token.Denom == denom {
c.CommittedTokens[i].Amount = token.Amount.Sub(amount)
Expand All @@ -92,7 +92,7 @@ func (c *Commitments) DeductFromCommitted(denom string, amount math.Int, currTim
newLockups := []Lockup{}
lockedAmount := sdk.ZeroInt()
for _, lockup := range token.Lockups {
if lockup.UnlockTimestamp > currTime {
if lockup.UnlockTimestamp > currTime && !isLiquidation {
newLockups = append(newLockups, lockup)
lockedAmount = lockedAmount.Add(lockup.Amount)
}
Expand Down
8 changes: 4 additions & 4 deletions x/commitment/types/commitments_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ func TestCommitments_WithdrawCommitedTokens(t *testing.T) {
commitments.AddCommittedTokens("lp/1", sdk.NewInt(100), 200)
commitments.AddCommittedTokens("lp/2", sdk.NewInt(100), 100)

err := commitments.DeductFromCommitted("lp/1", sdk.NewInt(100), 100)
err := commitments.DeductFromCommitted("lp/1", sdk.NewInt(100), 100, false)
require.NoError(t, err)

err = commitments.DeductFromCommitted("lp/1", sdk.NewInt(100), 100)
err = commitments.DeductFromCommitted("lp/1", sdk.NewInt(100), 100, false)
require.Error(t, err)

err = commitments.DeductFromCommitted("lp/2", sdk.NewInt(200), 100)
err = commitments.DeductFromCommitted("lp/2", sdk.NewInt(200), 100, false)
require.Error(t, err)
}

Expand All @@ -69,6 +69,6 @@ func TestLockupAmount_WithdrawCommited(t *testing.T) {
commitments.AddCommittedTokens("lp/1", sdk.NewInt(5000), 2)
commitments.AddCommittedTokens("lp/1", sdk.NewInt(3000), 4)

err := commitments.DeductFromCommitted("lp/1", sdk.NewInt(9000), 3)
err := commitments.DeductFromCommitted("lp/1", sdk.NewInt(9000), 3, false)
require.Error(t, err)
}
4 changes: 2 additions & 2 deletions x/leveragelp/keeper/begin_blocker.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (k Keeper) CheckAndLiquidateUnhealthyPosition(ctx sdk.Context, position *ty
return true, false, h, fmt.Errorf("position is healthy to close")
}

repayAmount, err := k.ForceCloseLong(ctx, *position, pool, position.LeveragedLpAmount)
repayAmount, err := k.ForceCloseLong(ctx, *position, pool, position.LeveragedLpAmount, true)
if err != nil {
ctx.Logger().Debug(errors.Wrap(err, "error executing liquidation").Error())
return isHealthy, true, h, err
Expand Down Expand Up @@ -127,7 +127,7 @@ func (k Keeper) CheckAndCloseAtStopLoss(ctx sdk.Context, position *types.Positio
return underStopLossPrice, false, fmt.Errorf("position stop loss price is not <= lp token price")
}

repayAmount, err := k.ForceCloseLong(ctx, *position, pool, position.LeveragedLpAmount)
repayAmount, err := k.ForceCloseLong(ctx, *position, pool, position.LeveragedLpAmount, false)
if err != nil {
ctx.Logger().Error(errors.Wrap(err, "error executing close for stopLossPrice").Error())
return underStopLossPrice, true, err
Expand Down
8 changes: 4 additions & 4 deletions x/leveragelp/keeper/begin_blocker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,17 +241,17 @@ func (suite *KeeperTestSuite) TestCheckAndLiquidateUnhealthyPosition() {
},
},
{
"closing position before 1 hour",
true,
"funds will be locked for 1 hour",
"success", // liquidating position before lockup period should be successful
false,
"",
func() *types.Position {
suite.ResetSuite()
suite.SetupCoinPrices(suite.ctx)
initializeForOpen(suite, addresses, asset1, asset2)
openMsg := types.MsgOpen{
Creator: addresses[1].String(),
CollateralAsset: "uusdc",
CollateralAmount: sdk.NewInt(1000_000_000),
CollateralAmount: sdk.NewInt(1000_000),
AmmPoolId: 1,
Leverage: leverage,
StopLossPrice: sdk.NewDec(2),
Expand Down
6 changes: 3 additions & 3 deletions x/leveragelp/keeper/position_close.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import (
"github.com/elys-network/elys/x/leveragelp/types"
)

func (k Keeper) ForceCloseLong(ctx sdk.Context, position types.Position, pool types.Pool, lpAmount math.Int) (math.Int, error) {
func (k Keeper) ForceCloseLong(ctx sdk.Context, position types.Position, pool types.Pool, lpAmount math.Int, isLiquidation bool) (math.Int, error) {
if lpAmount.GT(position.LeveragedLpAmount) || lpAmount.IsNegative() {
return sdk.ZeroInt(), types.ErrInvalidCloseSize
}

// Exit liquidity with collateral token
_, exitCoinsAfterExitFee, err := k.amm.ExitPool(ctx, position.GetPositionAddress(), position.AmmPoolId, lpAmount, sdk.Coins{}, position.Collateral.Denom)
_, exitCoinsAfterExitFee, err := k.amm.ExitPool(ctx, position.GetPositionAddress(), position.AmmPoolId, lpAmount, sdk.Coins{}, position.Collateral.Denom, isLiquidation)
if err != nil {
return sdk.ZeroInt(), err
}
Expand Down Expand Up @@ -117,6 +117,6 @@ func (k Keeper) CloseLong(ctx sdk.Context, msg *types.MsgClose) (*types.Position
lpAmount = position.LeveragedLpAmount
}

repayAmount, err := k.ForceCloseLong(ctx, position, pool, lpAmount)
repayAmount, err := k.ForceCloseLong(ctx, position, pool, lpAmount, false)
return &position, repayAmount, err
}
6 changes: 3 additions & 3 deletions x/leveragelp/keeper/position_close_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (suite KeeperTestSuite) TestForceCloseLong() {
Quo(sdk.NewDec(86400 * 365))).RoundInt()

suite.ctx = suite.ctx.WithBlockTime(suite.ctx.BlockTime().Add(time.Hour))
repayAmountOut, err := k.ForceCloseLong(suite.ctx, *position, pool, position.LeveragedLpAmount)
repayAmountOut, err := k.ForceCloseLong(suite.ctx, *position, pool, position.LeveragedLpAmount, false)
suite.Require().NoError(err)
suite.Require().Equal(repayAmount.String(), repayAmountOut.String())
}
Expand All @@ -148,7 +148,7 @@ func (suite KeeperTestSuite) TestForceCloseLongWithNoFullRepayment() {
Quo(sdk.NewDec(86400 * 365))).RoundInt()

suite.ctx = suite.ctx.WithBlockTime(suite.ctx.BlockTime().Add(time.Hour * 24 * 365 * 5))
repayAmountOut, err := k.ForceCloseLong(suite.ctx, *position, pool, position.LeveragedLpAmount)
repayAmountOut, err := k.ForceCloseLong(suite.ctx, *position, pool, position.LeveragedLpAmount, false)
suite.Require().NoError(err)
suite.Require().Greater(repayAmount.String(), repayAmountOut.String())
}
Expand All @@ -166,7 +166,7 @@ func (suite KeeperTestSuite) TestForceCloseLongPartial() {
Quo(sdk.NewDec(86400 * 365))).RoundInt()
suite.ctx = suite.ctx.WithBlockTime(suite.ctx.BlockTime().Add(time.Hour))
// close 50%
repayAmountOut, err := k.ForceCloseLong(suite.ctx, *position, pool, position.LeveragedLpAmount.Quo(sdk.NewInt(2)))
repayAmountOut, err := k.ForceCloseLong(suite.ctx, *position, pool, position.LeveragedLpAmount.Quo(sdk.NewInt(2)), false)
suite.Require().NoError(err)
suite.Require().Equal(repayAmount.Quo(sdk.NewInt(2)).String(), repayAmountOut.String())
}
Expand Down
2 changes: 1 addition & 1 deletion x/leveragelp/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type AmmKeeper interface {
CalcOutAmtGivenIn(ctx sdk.Context, poolId uint64, oracle ammtypes.OracleKeeper, snapshot *ammtypes.Pool, tokensIn sdk.Coins, tokenOutDenom string, swapFee sdk.Dec) (sdk.Coin, sdk.Dec, error)
CalcInAmtGivenOut(ctx sdk.Context, poolId uint64, oracle ammtypes.OracleKeeper, snapshot *ammtypes.Pool, tokensOut sdk.Coins, tokenInDenom string, swapFee sdk.Dec) (tokenIn sdk.Coin, slippage sdk.Dec, err error)
JoinPoolNoSwap(ctx sdk.Context, sender sdk.AccAddress, poolId uint64, shareOutAmount math.Int, tokenInMaxs sdk.Coins) (tokenIn sdk.Coins, sharesOut math.Int, err error)
ExitPool(ctx sdk.Context, sender sdk.AccAddress, poolId uint64, shareInAmount math.Int, tokenOutMins sdk.Coins, tokenOutDenom string) (exitCoins, exitCoinsAfterExitFee sdk.Coins, err error)
ExitPool(ctx sdk.Context, sender sdk.AccAddress, poolId uint64, shareInAmount math.Int, tokenOutMins sdk.Coins, tokenOutDenom string, isLiquidation bool) (exitCoins, exitCoinsAfterExitFee sdk.Coins, err error)
}

// BankKeeper defines the expected interface needed to retrieve account balances.
Expand Down
4 changes: 2 additions & 2 deletions x/masterchef/keeper/hooks_masterchef_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func TestHookMasterchef(t *testing.T) {
// check length of pools
require.Equal(t, len(pools), 1)

_, _, err = amm.ExitPool(ctx, addr[0], pools[0].PoolId, math.NewIntWithDecimal(1, 21), sdk.NewCoins(), "")
_, _, err = amm.ExitPool(ctx, addr[0], pools[0].PoolId, math.NewIntWithDecimal(1, 21), sdk.NewCoins(), "", false)
require.NoError(t, err)

// new user join pool with same shares
Expand Down Expand Up @@ -255,7 +255,7 @@ func TestHookMasterchef(t *testing.T) {
require.Len(t, res.TotalRewards, 0)

// first user exit pool
_, _, err = amm.ExitPool(ctx, addr[1], pools[0].PoolId, share.Quo(math.NewInt(2)), sdk.NewCoins(), "")
_, _, err = amm.ExitPool(ctx, addr[1], pools[0].PoolId, share.Quo(math.NewInt(2)), sdk.NewCoins(), "", false)
require.NoError(t, err)

// check rewards after 100 block
Expand Down
2 changes: 1 addition & 1 deletion x/stablestake/keeper/msg_server_unbond.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func (k msgServer) Unbond(goCtx context.Context, msg *types.MsgUnbond) (*types.M
shareDenom := types.GetShareDenom()

// Withdraw committed LP tokens
err := k.commitmentKeeper.UncommitTokens(ctx, creator, shareDenom, msg.Amount)
err := k.commitmentKeeper.UncommitTokens(ctx, creator, shareDenom, msg.Amount, false)
if err != nil {
return nil, err
}
Expand Down
Loading