Skip to content

Commit

Permalink
fix: check if the orderer has sufficient balance to make an order
Browse files Browse the repository at this point in the history
Note that there already exists such check.
This commit fixes the problem when the orderer has less balances
than the offer coin, but has enough balances to make the order.
Since this fix, orders cannot make an order with too much offer coin.
  • Loading branch information
hallazzang committed Apr 19, 2022
1 parent 7fa5f2b commit 2fdddd6
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
14 changes: 14 additions & 0 deletions x/liquidity/keeper/swap.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ import (
// ValidateMsgLimitOrder validates types.MsgLimitOrder with state and returns
// calculated offer coin and price that is fit into ticks.
func (k Keeper) ValidateMsgLimitOrder(ctx sdk.Context, msg *types.MsgLimitOrder) (offerCoin sdk.Coin, price sdk.Dec, err error) {
spendable := k.bankKeeper.SpendableCoins(ctx, msg.GetOrderer())
if spendableAmt := spendable.AmountOf(msg.OfferCoin.Denom); spendableAmt.LT(msg.OfferCoin.Amount) {
return sdk.Coin{}, sdk.Dec{}, sdkerrors.Wrapf(
sdkerrors.ErrInsufficientFunds, "%s is smaller than %s",
sdk.NewCoin(msg.OfferCoin.Denom, spendableAmt), msg.OfferCoin)
}

params := k.GetParams(ctx)

if msg.OrderLifespan > params.MaxOrderLifespan {
Expand Down Expand Up @@ -122,6 +129,13 @@ func (k Keeper) LimitOrder(ctx sdk.Context, msg *types.MsgLimitOrder) (types.Ord
// ValidateMsgMarketOrder validates types.MsgMarketOrder with state and returns
// calculated offer coin and price.
func (k Keeper) ValidateMsgMarketOrder(ctx sdk.Context, msg *types.MsgMarketOrder) (offerCoin sdk.Coin, price sdk.Dec, err error) {
spendable := k.bankKeeper.SpendableCoins(ctx, msg.GetOrderer())
if spendableAmt := spendable.AmountOf(msg.OfferCoin.Denom); spendableAmt.LT(msg.OfferCoin.Amount) {
return sdk.Coin{}, sdk.Dec{}, sdkerrors.Wrapf(
sdkerrors.ErrInsufficientFunds, "%s is smaller than %s",
sdk.NewCoin(msg.OfferCoin.Denom, spendableAmt), msg.OfferCoin)
}

params := k.GetParams(ctx)

if msg.OrderLifespan > params.MaxOrderLifespan {
Expand Down
35 changes: 35 additions & 0 deletions x/liquidity/keeper/swap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

utils "github.com/cosmosquad-labs/squad/types"
"github.com/cosmosquad-labs/squad/x/liquidity"
Expand Down Expand Up @@ -113,6 +114,23 @@ func (s *KeeperTestSuite) TestLimitOrder() {
}
}

func (s *KeeperTestSuite) TestLimitOrderInsufficientOfferCoin() {
pair := s.createPair(s.addr(0), "denom1", "denom2", true)

orderer := s.addr(1)
s.fundAddr(orderer, utils.ParseCoins("1000000denom2"))
_, err := s.keeper.LimitOrder(s.ctx, types.NewMsgLimitOrder(
orderer, pair.Id, types.OrderDirectionBuy, utils.ParseCoin("1000001denom2"), "denom1",
utils.ParseDec("1.0"), sdk.NewInt(1000000), 0))
s.Require().ErrorIs(err, sdkerrors.ErrInsufficientFunds)

s.fundAddr(orderer, utils.ParseCoins("1000000denom1"))
_, err = s.keeper.LimitOrder(s.ctx, types.NewMsgLimitOrder(
orderer, pair.Id, types.OrderDirectionSell, utils.ParseCoin("1000001denom1"), "denom2",
utils.ParseDec("1.0"), sdk.NewInt(1000000), 0))
s.Require().ErrorIs(err, sdkerrors.ErrInsufficientFunds)
}

func (s *KeeperTestSuite) TestLimitOrderRefund() {
pair := s.createPair(s.addr(0), "denom1", "denom2", true)
orderer := s.addr(1)
Expand Down Expand Up @@ -196,6 +214,23 @@ func (s *KeeperTestSuite) TestMarketOrder() {
s.Require().True(coinsEq(utils.ParseCoins("10800denom2"), s.getBalances(s.addr(4))))
}

func (s *KeeperTestSuite) TestMarketOrderInsufficientOfferCoin() {
pair := s.createPair(s.addr(0), "denom1", "denom2", true)

orderer := s.addr(1)
s.fundAddr(orderer, utils.ParseCoins("1000000denom2"))
_, err := s.keeper.MarketOrder(s.ctx, types.NewMsgMarketOrder(
orderer, pair.Id, types.OrderDirectionBuy, utils.ParseCoin("1000001denom2"), "denom1",
sdk.NewInt(1000000), 0))
s.Require().ErrorIs(err, sdkerrors.ErrInsufficientFunds)

s.fundAddr(orderer, utils.ParseCoins("1000000denom1"))
_, err = s.keeper.MarketOrder(s.ctx, types.NewMsgMarketOrder(
orderer, pair.Id, types.OrderDirectionSell, utils.ParseCoin("1000001denom1"), "denom2",
sdk.NewInt(1000000), 0))
s.Require().ErrorIs(err, sdkerrors.ErrInsufficientFunds)
}

func (s *KeeperTestSuite) TestMarketOrderRefund() {
pair := s.createPair(s.addr(0), "denom1", "denom2", true)
p := utils.ParseDec("1.0")
Expand Down

0 comments on commit 2fdddd6

Please sign in to comment.