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

[Perpetual]: Listing just oracle pool and a position can open if the pool is oracle #798

Merged
merged 5 commits into from
Sep 18, 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
3 changes: 2 additions & 1 deletion x/perpetual/client/cli/query_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"testing"

tmcli "github.com/cometbft/cometbft/libs/cli"
"github.com/cosmos/cosmos-sdk/client/flags"
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
"github.com/stretchr/testify/require"
"google.golang.org/grpc/codes"
Expand Down Expand Up @@ -87,6 +86,7 @@ func TestShowPool(t *testing.T) {
}
}

/*
func TestListPool(t *testing.T) {
net, objs := networkWithPoolObjects(t, 5)

Expand Down Expand Up @@ -152,3 +152,4 @@ func TestListPool(t *testing.T) {
)
})
}
*/
fenriz07 marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 3 additions & 0 deletions x/perpetual/keeper/open.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ func (k Keeper) Open(ctx sdk.Context, msg *types.MsgOpen, isBroker bool) (*types
if err != nil {
return nil, err
}
if !ammPool.PoolParams.UseOracle {
return nil, types.ErrPoolHasToBeOracle
}
fenriz07 marked this conversation as resolved.
Show resolved Hide resolved

if err := k.OpenChecker.CheckPoolHealth(ctx, poolId); err != nil {
return nil, err
Expand Down
42 changes: 37 additions & 5 deletions x/perpetual/keeper/open_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,38 @@ func TestOpen_ErrorPreparePools(t *testing.T) {
mockChecker.AssertExpectations(t)
}

func TestOpen_ErrPoolHasToBeOracle(t *testing.T) {
// Setup the mock checker
mockChecker := new(mocks.OpenChecker)
mockAssetProfile := new(mocks.AssetProfileKeeper)

k := keeper.NewKeeper(nil, nil, nil, "cosmos1ysxv266l8w76lq0vy44ktzajdr9u9yhlxzlvga", nil, nil, nil, mockAssetProfile, nil)
k.OpenChecker = mockChecker

var (
ctx = sdk.Context{} // Mock or setup a context
msg = &types.MsgOpen{
Position: types.Position_LONG,
TradingAsset: "uelys",
Collateral: sdk.NewCoin(ptypes.BaseCurrency, sdk.OneInt()),
}
poolId = uint64(1)
)

// Mock behavior
mockAssetProfile.On("GetEntry", ctx, ptypes.BaseCurrency).Return(assetprofiletypes.Entry{BaseDenom: ptypes.BaseCurrency, Denom: ptypes.BaseCurrency}, true)
mockChecker.On("CheckUserAuthorization", ctx, msg).Return(nil)
mockChecker.On("CheckSameAssetPosition", ctx, msg).Return(nil)
mockChecker.On("CheckMaxOpenPositions", ctx).Return(nil)
mockChecker.On("PreparePools", ctx, msg.Collateral.Denom, msg.TradingAsset).Return(poolId, ammtypes.Pool{PoolParams: ammtypes.PoolParams{UseOracle: false}}, types.Pool{}, nil)

_, err := k.Open(ctx, msg, false)

assert.ErrorIs(t, types.ErrPoolHasToBeOracle, err)
mockAssetProfile.AssertExpectations(t)
mockChecker.AssertExpectations(t)
}

func TestOpen_ErrorCheckPoolHealth(t *testing.T) {
// Setup the mock checker
mockChecker := new(mocks.OpenChecker)
Expand All @@ -130,7 +162,7 @@ func TestOpen_ErrorCheckPoolHealth(t *testing.T) {
mockChecker.On("CheckUserAuthorization", ctx, msg).Return(nil)
mockChecker.On("CheckSameAssetPosition", ctx, msg).Return(nil)
mockChecker.On("CheckMaxOpenPositions", ctx).Return(nil)
mockChecker.On("PreparePools", ctx, msg.Collateral.Denom, msg.TradingAsset).Return(poolId, ammtypes.Pool{}, types.Pool{}, nil)
mockChecker.On("PreparePools", ctx, msg.Collateral.Denom, msg.TradingAsset).Return(poolId, ammtypes.Pool{PoolParams: ammtypes.PoolParams{UseOracle: true}}, types.Pool{}, nil)
mockChecker.On("CheckPoolHealth", ctx, poolId).Return(errorsmod.Wrap(types.ErrInvalidBorrowingAsset, "invalid collateral asset"))

_, err := k.Open(ctx, msg, false)
Expand Down Expand Up @@ -189,7 +221,7 @@ func TestOpen_ErrorOpenLong(t *testing.T) {
mockChecker.On("CheckUserAuthorization", ctx, msg).Return(nil)
mockChecker.On("CheckSameAssetPosition", ctx, msg).Return(nil)
mockChecker.On("CheckMaxOpenPositions", ctx).Return(nil)
mockChecker.On("PreparePools", ctx, msg.Collateral.Denom, msg.TradingAsset).Return(poolId, ammtypes.Pool{}, types.Pool{}, nil)
mockChecker.On("PreparePools", ctx, msg.Collateral.Denom, msg.TradingAsset).Return(poolId, ammtypes.Pool{PoolParams: ammtypes.PoolParams{UseOracle: true}}, types.Pool{}, nil)
mockChecker.On("CheckPoolHealth", ctx, poolId).Return(nil)
mockChecker.On("OpenLong", ctx, poolId, msg, ptypes.BaseCurrency, false).Return(&types.MTP{}, errors.New("error executing open long"))

Expand Down Expand Up @@ -223,7 +255,7 @@ func TestOpen_ErrorOpenShort(t *testing.T) {
mockChecker.On("CheckUserAuthorization", ctx, msg).Return(nil)
mockChecker.On("CheckSameAssetPosition", ctx, msg).Return(nil)
mockChecker.On("CheckMaxOpenPositions", ctx).Return(nil)
mockChecker.On("PreparePools", ctx, msg.Collateral.Denom, msg.TradingAsset).Return(poolId, ammtypes.Pool{}, types.Pool{}, nil)
mockChecker.On("PreparePools", ctx, msg.Collateral.Denom, msg.TradingAsset).Return(poolId, ammtypes.Pool{PoolParams: ammtypes.PoolParams{UseOracle: true}}, types.Pool{}, nil)
mockChecker.On("CheckPoolHealth", ctx, poolId).Return(nil)
mockChecker.On("OpenShort", ctx, poolId, msg, ptypes.BaseCurrency, false).Return(&types.MTP{}, errors.New("error executing open short"))

Expand Down Expand Up @@ -259,10 +291,10 @@ func TestOpen_Successful(t *testing.T) {
mockChecker.On("CheckUserAuthorization", ctx, msg).Return(nil)
mockChecker.On("CheckSameAssetPosition", ctx, msg).Return(nil)
mockChecker.On("CheckMaxOpenPositions", ctx).Return(nil)
mockChecker.On("PreparePools", ctx, msg.Collateral.Denom, msg.TradingAsset).Return(poolId, ammtypes.Pool{}, types.Pool{}, nil)
mockChecker.On("PreparePools", ctx, msg.Collateral.Denom, msg.TradingAsset).Return(poolId, ammtypes.Pool{PoolParams: ammtypes.PoolParams{UseOracle: true}}, types.Pool{}, nil)
mockChecker.On("CheckPoolHealth", ctx, poolId).Return(nil)
mockChecker.On("OpenShort", ctx, poolId, msg, ptypes.BaseCurrency, false).Return(mtp, nil)
mockChecker.On("UpdateOpenPrice", ctx, mtp, ammtypes.Pool{}, ptypes.BaseCurrency).Return(nil)
mockChecker.On("UpdateOpenPrice", ctx, mtp, ammtypes.Pool{PoolParams: ammtypes.PoolParams{UseOracle: true}}, ptypes.BaseCurrency).Return(nil)
mockChecker.On("EmitOpenEvent", ctx, mtp).Return()

_, err := k.Open(ctx, msg, false)
Expand Down
10 changes: 9 additions & 1 deletion x/perpetual/keeper/query_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,15 @@ func (k Keeper) Pools(goCtx context.Context, req *types.QueryAllPoolRequest) (*t
return err
}

pools = append(pools, pool)
ammPool, found := k.amm.GetPool(ctx, pool.AmmPoolId)
if !found {
return types.ErrPoolDoesNotExist
}

if ammPool.PoolParams.UseOracle {
pools = append(pools, pool)
}

return nil
})
if err != nil {
Expand Down
118 changes: 61 additions & 57 deletions x/perpetual/keeper/query_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,77 @@ package keeper_test
import (
"testing"

tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"

simapp "github.com/elys-network/elys/app"
keepertest "github.com/elys-network/elys/testutil/keeper"
"github.com/elys-network/elys/testutil/nullify"
ammtypes "github.com/elys-network/elys/x/amm/types"
"github.com/elys-network/elys/x/perpetual/keeper"
"github.com/elys-network/elys/x/perpetual/types"
"github.com/elys-network/elys/x/perpetual/types/mocks"
)

func TestPools_InvalidRequest(t *testing.T) {
mockAmm := new(mocks.AmmKeeper)
k := keeper.NewKeeper(nil, nil, nil, "cosmos1ysxv266l8w76lq0vy44ktzajdr9u9yhlxzlvga", mockAmm, nil, nil, nil, nil)
ctx := sdk.Context{}
_, err := k.Pools(ctx, nil)

assert.ErrorIs(t, err, status.Error(codes.InvalidArgument, "invalid request"))
}

func TestPools_ErrPoolDoesNotExist(t *testing.T) {

app := simapp.InitElysTestApp(true)
ctx := app.BaseApp.NewContext(true, tmproto.Header{})

app.PerpetualKeeper.SetPool(ctx, types.Pool{
AmmPoolId: uint64(23),
})

_, err := app.PerpetualKeeper.Pools(ctx, &types.QueryAllPoolRequest{})
assert.Equal(t, "rpc error: code = Internal desc = pool does not exist", err.Error())
}

func TestPools_Success(t *testing.T) {

app := simapp.InitElysTestApp(true)
ctx := app.BaseApp.NewContext(true, tmproto.Header{})

app.PerpetualKeeper.SetPool(ctx, types.Pool{
AmmPoolId: uint64(1),
})

app.PerpetualKeeper.SetPool(ctx, types.Pool{
AmmPoolId: uint64(2),
})

app.AmmKeeper.SetPool(ctx, ammtypes.Pool{
PoolId: uint64(1),
PoolParams: ammtypes.PoolParams{
UseOracle: true,
},
})

app.AmmKeeper.SetPool(ctx, ammtypes.Pool{
PoolId: uint64(2),
PoolParams: ammtypes.PoolParams{
UseOracle: false,
},
})

response, err := app.PerpetualKeeper.Pools(ctx, &types.QueryAllPoolRequest{})
assert.Nil(t, err)
assert.Len(t, response.Pool, 1)

}

func TestPoolQuerySingle(t *testing.T) {
keeper, ctx := keepertest.PerpetualKeeper(t)
wctx := sdk.WrapSDKContext(ctx)
Expand Down Expand Up @@ -65,59 +125,3 @@ func TestPoolQuerySingle(t *testing.T) {
})
}
}

func TestPoolQueryPaginated(t *testing.T) {
keeper, ctx := keepertest.PerpetualKeeper(t)
wctx := sdk.WrapSDKContext(ctx)
msgs := createNPool(keeper, ctx, 5)

request := func(next []byte, offset, limit uint64, total bool) *types.QueryAllPoolRequest {
return &types.QueryAllPoolRequest{
Pagination: &query.PageRequest{
Key: next,
Offset: offset,
Limit: limit,
CountTotal: total,
},
}
}
t.Run("ByOffset", func(t *testing.T) {
step := 2
for i := 0; i < len(msgs); i += step {
resp, err := keeper.Pools(wctx, request(nil, uint64(i), uint64(step), false))
require.NoError(t, err)
require.LessOrEqual(t, len(resp.Pool), step)
require.Subset(t,
nullify.Fill(msgs),
nullify.Fill(resp.Pool),
)
}
})
t.Run("ByKey", func(t *testing.T) {
step := 2
var next []byte
for i := 0; i < len(msgs); i += step {
resp, err := keeper.Pools(wctx, request(next, 0, uint64(step), false))
require.NoError(t, err)
require.LessOrEqual(t, len(resp.Pool), step)
require.Subset(t,
nullify.Fill(msgs),
nullify.Fill(resp.Pool),
)
next = resp.Pagination.NextKey
}
})
t.Run("Total", func(t *testing.T) {
resp, err := keeper.Pools(wctx, request(nil, 0, 0, true))
require.NoError(t, err)
require.Equal(t, len(msgs), int(resp.Pagination.Total))
require.ElementsMatch(t,
nullify.Fill(msgs),
nullify.Fill(resp.Pool),
)
})
t.Run("InvalidRequest", func(t *testing.T) {
_, err := keeper.Pools(wctx, nil)
require.ErrorIs(t, err, status.Error(codes.InvalidArgument, "invalid request"))
})
}
1 change: 1 addition & 0 deletions x/perpetual/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ var (
ErrInvalidTakeProfitPriceIsNegative = errorsmod.Register(ModuleName, 38, "error invalid profit price ")
ErrTradingAssetIsEmpty = errorsmod.Register(ModuleName, 39, "error trading asset is empty")
ErrInvalidAmount = errorsmod.Register(ModuleName, 40, "invalid amount")
ErrPoolHasToBeOracle = errorsmod.Register(ModuleName, 41, "pool has to be oracle enabled")
)
Loading