Skip to content

Commit

Permalink
feat: cosmwasmpool core logic and tests (#5354)
Browse files Browse the repository at this point in the history
* feat: cosmwasmpool core logic and tests

* changelog

* updates

* updates

* rename cast helpers

* rename

* remove error check
  • Loading branch information
p0mvn authored May 31, 2023
1 parent dfdac4a commit 4206fd9
Show file tree
Hide file tree
Showing 32 changed files with 1,391 additions and 143 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Features

* [#5354](https://github.com/osmosis-labs/osmosis/pull/5354) implement x/cosmwasmpool module.
* [#4659](https://github.com/osmosis-labs/osmosis/pull/4659) implement AllPools query in x/poolmanager.
* [#4783](https://github.com/osmosis-labs/osmosis/pull/4783) Update wasmd to 0.31.0
* [#4629](https://github.com/osmosis-labs/osmosis/pull/4629) add amino proto annotations
Expand Down
36 changes: 27 additions & 9 deletions app/apptesting/pool_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

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

"github.com/osmosis-labs/osmosis/v15/x/gamm/pool-models/balancer"
poolmanager "github.com/osmosis-labs/osmosis/v15/x/poolmanager"
poolmanagertypes "github.com/osmosis-labs/osmosis/v15/x/poolmanager/types"
)
Expand Down Expand Up @@ -40,21 +41,38 @@ func (s *KeeperTestHelper) CreatePoolFromType(poolType poolmanagertypes.PoolType
case poolmanagertypes.Concentrated:
s.PrepareConcentratedPool()
return
case poolmanagertypes.CosmWasm:
s.PrepareCosmWasmPool()
return
}
}

// CreatePoolFromTypeWithCoins creates a pool with the given type and initialized with the given coins.
func (s *KeeperTestHelper) CreatePoolFromTypeWithCoins(poolType poolmanagertypes.PoolType, coins sdk.Coins) uint64 {
var poolId uint64
if poolType == poolmanagertypes.Balancer {
poolId = s.PrepareBalancerPoolWithCoins(coins...)
} else if poolType == poolmanagertypes.Concentrated {
return s.CreatePoolFromTypeWithCoinsAndSpreadFactor(poolType, coins, sdk.ZeroDec())
}

// CreatePoolFromTypeWithCoinsAndSpreadFactor creates a pool with given type, initialized with the given coins as initial liquidity and spread factor.
func (s *KeeperTestHelper) CreatePoolFromTypeWithCoinsAndSpreadFactor(poolType poolmanagertypes.PoolType, coins sdk.Coins, spreadFactor sdk.Dec) uint64 {
switch poolType {
case poolmanagertypes.Balancer:
poolId := s.PrepareCustomBalancerPoolFromCoins(coins, balancer.PoolParams{
SwapFee: spreadFactor,
ExitFee: sdk.ZeroDec(),
})
return poolId
case poolmanagertypes.Concentrated:
s.Require().Len(coins, 2)
pool := s.PrepareCustomConcentratedPool(s.TestAccs[0], coins[0].Denom, coins[1].Denom, DefaultTickSpacing, spreadFactor)
s.CreateFullRangePosition(pool, coins)
return pool.GetId()
case poolmanagertypes.CosmWasm:
s.Require().Len(coins, 2)
clPool := s.PrepareConcentratedPoolWithCoins(coins[0].Denom, coins[1].Denom)
s.CreateFullRangePosition(clPool, coins)
poolId = clPool.GetId()
} else {
pool := s.PrepareCustomTransmuterPool(s.TestAccs[0], []string{coins[0].Denom, coins[1].Denom})
s.JoinTransmuterPool(s.TestAccs[0], pool.GetId(), coins)
return pool.GetId()
default:
s.FailNow(fmt.Sprintf("unsupported pool type for this operation (%s)", poolmanagertypes.PoolType_name[int32(poolType)]))
}
return poolId
return 0
}
12 changes: 10 additions & 2 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
icqtypes "github.com/cosmos/ibc-apps/modules/async-icq/v4/types"

"github.com/osmosis-labs/osmosis/v15/x/cosmwasmpool"
cosmwasmpooltypes "github.com/osmosis-labs/osmosis/v15/x/cosmwasmpool/types"
downtimedetector "github.com/osmosis-labs/osmosis/v15/x/downtime-detector"
downtimetypes "github.com/osmosis-labs/osmosis/v15/x/downtime-detector/types"
"github.com/osmosis-labs/osmosis/v15/x/gamm"
Expand Down Expand Up @@ -147,8 +148,7 @@ type AppKeepers struct {
PoolManagerKeeper *poolmanager.Keeper
ValidatorSetPreferenceKeeper *valsetpref.Keeper
ConcentratedLiquidityKeeper *concentratedliquidity.Keeper
// TODO: initialize this keeper: https://github.com/osmosis-labs/osmosis/issues/5329
CosmwasmPoolKeeper *cosmwasmpool.Keeper
CosmwasmPoolKeeper *cosmwasmpool.Keeper

// IBC modules
// transfer module
Expand Down Expand Up @@ -327,17 +327,21 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
appKeepers.GAMMKeeper = &gammKeeper
appKeepers.ConcentratedLiquidityKeeper.SetGammKeeper(appKeepers.GAMMKeeper)

appKeepers.CosmwasmPoolKeeper = cosmwasmpool.NewKeeper(appCodec, appKeepers.keys[cosmwasmpooltypes.StoreKey], appKeepers.GetSubspace(cosmwasmpooltypes.ModuleName), appKeepers.AccountKeeper, appKeepers.BankKeeper)

appKeepers.PoolManagerKeeper = poolmanager.NewKeeper(
appKeepers.keys[poolmanagertypes.StoreKey],
appKeepers.GetSubspace(poolmanagertypes.ModuleName),
appKeepers.GAMMKeeper,
appKeepers.ConcentratedLiquidityKeeper,
appKeepers.CosmwasmPoolKeeper,
appKeepers.BankKeeper,
appKeepers.AccountKeeper,
appKeepers.DistrKeeper,
)
appKeepers.GAMMKeeper.SetPoolManager(appKeepers.PoolManagerKeeper)
appKeepers.ConcentratedLiquidityKeeper.SetPoolManagerKeeper(appKeepers.PoolManagerKeeper)
appKeepers.CosmwasmPoolKeeper.SetPoolManagerKeeper(appKeepers.PoolManagerKeeper)

appKeepers.TwapKeeper = twap.NewKeeper(
appKeepers.keys[twaptypes.StoreKey],
Expand Down Expand Up @@ -454,11 +458,13 @@ func (appKeepers *AppKeepers) InitNormalKeepers(
wasmOpts...,
)
appKeepers.WasmKeeper = &wasmKeeper
appKeepers.CosmwasmPoolKeeper.SetWasmKeeper(appKeepers.WasmKeeper)

// Pass the contract keeper to all the structs (generally ICS4Wrappers for ibc middlewares) that need it
appKeepers.ContractKeeper = wasmkeeper.NewDefaultPermissionKeeper(appKeepers.WasmKeeper)
appKeepers.RateLimitingICS4Wrapper.ContractKeeper = appKeepers.ContractKeeper
appKeepers.Ics20WasmHooks.ContractKeeper = appKeepers.ContractKeeper
appKeepers.CosmwasmPoolKeeper.SetContractKeeper(appKeepers.ContractKeeper)

// wire up x/wasm to IBC
ibcRouter.AddRoute(wasm.ModuleName, wasm.NewIBCHandler(appKeepers.WasmKeeper, appKeepers.IBCKeeper.ChannelKeeper, appKeepers.IBCKeeper.ChannelKeeper))
Expand Down Expand Up @@ -648,6 +654,7 @@ func (appKeepers *AppKeepers) initParamsKeeper(appCodec codec.BinaryCodec, legac
paramsKeeper.Subspace(concentratedliquiditytypes.ModuleName)
paramsKeeper.Subspace(icqtypes.ModuleName)
paramsKeeper.Subspace(packetforwardtypes.ModuleName).WithKeyTable(packetforwardtypes.ParamKeyTable())
paramsKeeper.Subspace(cosmwasmpooltypes.ModuleName)

return paramsKeeper
}
Expand Down Expand Up @@ -763,5 +770,6 @@ func KVStoreKeys() []string {
ibchookstypes.StoreKey,
icqtypes.StoreKey,
packetforwardtypes.StoreKey,
cosmwasmpooltypes.StoreKey,
}
}
2 changes: 2 additions & 0 deletions app/keepers/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
_ "github.com/osmosis-labs/osmosis/v15/client/docs/statik"
clclient "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/client"
concentratedliquidity "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/clmodule"
cosmwasmpoolmodule "github.com/osmosis-labs/osmosis/v15/x/cosmwasmpool/module"
downtimemodule "github.com/osmosis-labs/osmosis/v15/x/downtime-detector/module"
"github.com/osmosis-labs/osmosis/v15/x/gamm"
gammclient "github.com/osmosis-labs/osmosis/v15/x/gamm/client"
Expand Down Expand Up @@ -111,4 +112,5 @@ var AppModuleBasics = []module.AppModuleBasic{
ibc_hooks.AppModuleBasic{},
ibcratelimitmodule.AppModuleBasic{},
router.AppModuleBasic{},
cosmwasmpoolmodule.AppModuleBasic{},
}
2 changes: 2 additions & 0 deletions app/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import (
"github.com/osmosis-labs/osmosis/v15/simulation/simtypes"
concentratedliquidity "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/clmodule"
concentratedliquiditytypes "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/types"
cosmwasmpooltypes "github.com/osmosis-labs/osmosis/v15/x/cosmwasmpool/types"
"github.com/osmosis-labs/osmosis/v15/x/gamm"
gammtypes "github.com/osmosis-labs/osmosis/v15/x/gamm/types"
"github.com/osmosis-labs/osmosis/v15/x/ibc-rate-limit/ibcratelimitmodule"
Expand Down Expand Up @@ -119,6 +120,7 @@ var moduleAccountPermissions = map[string][]string{
tokenfactorytypes.ModuleName: {authtypes.Minter, authtypes.Burner},
valsetpreftypes.ModuleName: {authtypes.Staking},
poolmanagertypes.ModuleName: nil,
cosmwasmpooltypes.ModuleName: nil,
}

// appModules return modules to initialize module manager.
Expand Down
3 changes: 2 additions & 1 deletion app/upgrades/v16/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
store "github.com/cosmos/cosmos-sdk/store/types"

cltypes "github.com/osmosis-labs/osmosis/v15/x/concentrated-liquidity/types"
cosmwasmpooltypes "github.com/osmosis-labs/osmosis/v15/x/cosmwasmpool/types"
)

// UpgradeName defines the on-chain upgrade name for the Osmosis v16 upgrade.
Expand All @@ -21,7 +22,7 @@ var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
CreateUpgradeHandler: CreateUpgradeHandler,
StoreUpgrades: store.StoreUpgrades{
Added: []string{cltypes.StoreKey},
Added: []string{cltypes.StoreKey, cosmwasmpooltypes.StoreKey},
Deleted: []string{},
},
}
8 changes: 4 additions & 4 deletions x/concentrated-liquidity/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,12 @@ func (k Keeper) PrepareClaimableSpreadRewards(ctx sdk.Context, positionId uint64
return k.prepareClaimableSpreadRewards(ctx, positionId)
}

func ConvertConcentratedToPoolInterface(concentratedPool types.ConcentratedPoolExtension) (poolmanagertypes.PoolI, error) {
return convertConcentratedToPoolInterface(concentratedPool)
func AsPoolI(concentratedPool types.ConcentratedPoolExtension) (poolmanagertypes.PoolI, error) {
return asPoolI(concentratedPool)
}

func ConvertPoolInterfaceToConcentrated(poolI poolmanagertypes.PoolI) (types.ConcentratedPoolExtension, error) {
return convertPoolInterfaceToConcentrated(poolI)
func AsConcentrated(poolI poolmanagertypes.PoolI) (types.ConcentratedPoolExtension, error) {
return asConcentrated(poolI)
}

func (k Keeper) ValidateSpreadFactor(ctx sdk.Context, params types.Params, spreadFactor sdk.Dec) bool {
Expand Down
14 changes: 7 additions & 7 deletions x/concentrated-liquidity/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
// - There is an error creating the fee or uptime accumulator.
// - There is an error setting the pool in the keeper's state.
func (k Keeper) InitializePool(ctx sdk.Context, poolI poolmanagertypes.PoolI, creatorAddress sdk.AccAddress) error {
concentratedPool, err := convertPoolInterfaceToConcentrated(poolI)
concentratedPool, err := asConcentrated(poolI)
if err != nil {
return err
}
Expand Down Expand Up @@ -76,7 +76,7 @@ func (k Keeper) GetPool(ctx sdk.Context, poolId uint64) (poolmanagertypes.PoolI,
if err != nil {
return nil, types.PoolNotFoundError{PoolId: poolId}
}
poolI, err := convertConcentratedToPoolInterface(concentratedPool)
poolI, err := asPoolI(concentratedPool)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -185,10 +185,10 @@ func (k Keeper) GetTotalPoolLiquidity(ctx sdk.Context, poolId uint64) (sdk.Coins
return filteredPoolBalance, nil
}

// convertConcentratedToPoolInterface takes a types.ConcentratedPoolExtension and attempts to convert it to a
// asPoolI takes a types.ConcentratedPoolExtension and attempts to convert it to a
// poolmanagertypes.PoolI. If the conversion is successful, the converted value is returned. If the conversion fails,
// an error is returned.
func convertConcentratedToPoolInterface(concentratedPool types.ConcentratedPoolExtension) (poolmanagertypes.PoolI, error) {
func asPoolI(concentratedPool types.ConcentratedPoolExtension) (poolmanagertypes.PoolI, error) {
// Attempt to convert the concentratedPool to a poolmanagertypes.PoolI
pool, ok := concentratedPool.(poolmanagertypes.PoolI)
if !ok {
Expand All @@ -199,10 +199,10 @@ func convertConcentratedToPoolInterface(concentratedPool types.ConcentratedPoolE
return pool, nil
}

// convertPoolInterfaceToConcentrated takes a poolmanagertypes.PoolI and attempts to convert it to a
// asConcentrated takes a poolmanagertypes.PoolI and attempts to convert it to a
// types.ConcentratedPoolExtension. If the conversion is successful, the converted value is returned. If the conversion fails,
// an error is returned.
func convertPoolInterfaceToConcentrated(poolI poolmanagertypes.PoolI) (types.ConcentratedPoolExtension, error) {
func asConcentrated(poolI poolmanagertypes.PoolI) (types.ConcentratedPoolExtension, error) {
// Attempt to convert poolmanagertypes.PoolI to a concentratedPool
concentratedPool, ok := poolI.(types.ConcentratedPoolExtension)
if !ok {
Expand All @@ -220,7 +220,7 @@ func (k Keeper) GetConcentratedPoolById(ctx sdk.Context, poolId uint64) (types.C
if err != nil {
return nil, err
}
return convertPoolInterfaceToConcentrated(poolI)
return asConcentrated(poolI)
}

func (k Keeper) GetSerializedPools(ctx sdk.Context, pagination *query.PageRequest) ([]*codectypes.Any, *query.PageResponse, error) {
Expand Down
8 changes: 4 additions & 4 deletions x/concentrated-liquidity/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,14 @@ func (s *KeeperTestSuite) TestGetPoolById() {
}
}

func (s *KeeperTestSuite) TestConvertConcentratedToPoolInterface() {
func (s *KeeperTestSuite) TestAsPoolI() {
s.SetupTest()

// Create default CL pool
concentratedPool := s.PrepareConcentratedPool()

// Ensure no error occurs when converting to PoolInterface
_, err := cl.ConvertConcentratedToPoolInterface(concentratedPool)
_, err := cl.AsPoolI(concentratedPool)
s.Require().NoError(err)
}

Expand All @@ -197,7 +197,7 @@ func (s *KeeperTestSuite) TestPoolIToConcentratedPool() {
s.Require().True(ok)

// Ensure no error occurs when converting to ConcentratedPool
_, err := cl.ConvertPoolInterfaceToConcentrated(poolI)
_, err := cl.AsConcentrated(poolI)
s.Require().NoError(err)

// Create a default stableswap pool
Expand All @@ -206,7 +206,7 @@ func (s *KeeperTestSuite) TestPoolIToConcentratedPool() {
s.Require().NoError(err)

// Ensure error occurs when converting to ConcentratedPool
_, err = cl.ConvertPoolInterfaceToConcentrated(stableswapPool)
_, err = cl.AsConcentrated(stableswapPool)
s.Require().Error(err)
s.Require().ErrorContains(err, fmt.Errorf("given pool does not implement ConcentratedPoolExtension, implements %T", stableswapPool).Error())
}
Expand Down
4 changes: 2 additions & 2 deletions x/concentrated-liquidity/swaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (k Keeper) SwapExactAmountIn(
}

// Convert pool interface to CL pool type
pool, err := convertPoolInterfaceToConcentrated(poolI)
pool, err := asConcentrated(poolI)
if err != nil {
return sdk.Int{}, err
}
Expand Down Expand Up @@ -129,7 +129,7 @@ func (k Keeper) SwapExactAmountOut(
return sdk.Int{}, types.DenomDuplicatedError{TokenInDenom: tokenInDenom, TokenOutDenom: tokenOut.Denom}
}

pool, err := convertPoolInterfaceToConcentrated(poolI)
pool, err := asConcentrated(poolI)
if err != nil {
return sdk.Int{}, err
}
Expand Down
48 changes: 38 additions & 10 deletions x/cosmwasmpool/keeper.go
Original file line number Diff line number Diff line change
@@ -1,36 +1,35 @@
package cosmwasmpool

import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/osmosis-labs/osmosis/v15/x/cosmwasmpool/types"
poolmanagertypes "github.com/osmosis-labs/osmosis/v15/x/poolmanager/types"

paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
)

type Keeper struct {
cdc codec.BinaryCodec
storeKey sdk.StoreKey
paramSpace paramtypes.Subspace

// keepers
// TODO: remove nolint once added.
// nolint: unused
accountKeeper types.AccountKeeper
bankKeeper types.BankKeeper
poolmanagerKeeper types.PoolManagerKeeper
// TODO: remove nolint once added.
// nolint: unused
contractKeeper types.ContractKeeper
// TODO: remove nolint once added.
// nolint: unused
wasmKeeper types.WasmKeeper
contractKeeper types.ContractKeeper
wasmKeeper types.WasmKeeper
}

func NewKeeper(storeKey sdk.StoreKey, paramSpace paramtypes.Subspace) *Keeper {
func NewKeeper(cdc codec.BinaryCodec, storeKey sdk.StoreKey, paramSpace paramtypes.Subspace, accountKeeper types.AccountKeeper, bankKeeper types.BankKeeper) *Keeper {
// set KeyTable if it has not already been set
if !paramSpace.HasKeyTable() {
paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable())
}

return &Keeper{storeKey: storeKey, paramSpace: paramSpace}
return &Keeper{cdc: cdc, storeKey: storeKey, paramSpace: paramSpace, accountKeeper: accountKeeper, bankKeeper: bankKeeper}
}

// GetParams returns the total set of cosmwasmpool parameters.
Expand All @@ -43,3 +42,32 @@ func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) {
func (k Keeper) SetParams(ctx sdk.Context, params types.Params) {
k.paramSpace.SetParamSet(ctx, &params)
}

// Set the poolmanager keeper.
func (k *Keeper) SetPoolManagerKeeper(poolmanagerKeeper types.PoolManagerKeeper) {
k.poolmanagerKeeper = poolmanagerKeeper
}

// Set the contract keeper.
func (k *Keeper) SetContractKeeper(contractKeeper types.ContractKeeper) {
k.contractKeeper = contractKeeper
}

// Set the wasm keeper.
func (k *Keeper) SetWasmKeeper(wasmKeeper types.WasmKeeper) {
k.wasmKeeper = wasmKeeper
}

// asCosmwasmPool converts a poolI to a CosmWasmExtension.
func (k *Keeper) asCosmwasmPool(poolI poolmanagertypes.PoolI) (types.CosmWasmExtension, error) {
cosmwasmPool, ok := poolI.(types.CosmWasmExtension)
if !ok {
return nil, types.InvalidPoolTypeError{
ActualPool: poolI,
}
}

cosmwasmPool.SetWasmKeeper(k.wasmKeeper)

return cosmwasmPool, nil
}
Loading

0 comments on commit 4206fd9

Please sign in to comment.