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

Feat: cw dex bindings #365

Merged
merged 20 commits into from
Feb 26, 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
32 changes: 28 additions & 4 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,14 @@ func New(
authtypes.NewModuleAddress(adminmoduletypes.ModuleName).String(),
)

app.FeeKeeper = feekeeper.NewKeeper(appCodec, keys[feetypes.StoreKey], memKeys[feetypes.MemStoreKey], app.IBCKeeper.ChannelKeeper, app.BankKeeper, authtypes.NewModuleAddress(adminmoduletypes.ModuleName).String())
app.FeeKeeper = feekeeper.NewKeeper(
appCodec,
keys[feetypes.StoreKey],
memKeys[feetypes.MemStoreKey],
app.IBCKeeper.ChannelKeeper,
app.BankKeeper,
authtypes.NewModuleAddress(adminmoduletypes.ModuleName).String(),
)
feeModule := feerefunder.NewAppModule(appCodec, *app.FeeKeeper, app.AccountKeeper, app.BankKeeper)

app.FeeBurnerKeeper = feeburnerkeeper.NewKeeper(
Expand Down Expand Up @@ -694,8 +701,24 @@ func New(
authtypes.NewModuleAddress(adminmoduletypes.ModuleName).String(),
)

app.CronKeeper = *cronkeeper.NewKeeper(appCodec, keys[crontypes.StoreKey], keys[crontypes.MemStoreKey], app.AccountKeeper, authtypes.NewModuleAddress(adminmoduletypes.ModuleName).String())
wasmOpts = append(wasmbinding.RegisterCustomPlugins(&app.InterchainTxsKeeper, &app.InterchainQueriesKeeper, app.TransferKeeper, &app.AdminmoduleKeeper, app.FeeBurnerKeeper, app.FeeKeeper, &app.BankKeeper, app.TokenFactoryKeeper, &app.CronKeeper, &app.ContractManagerKeeper), wasmOpts...)
app.CronKeeper = *cronkeeper.NewKeeper(
appCodec,
keys[crontypes.StoreKey],
keys[crontypes.MemStoreKey],
app.AccountKeeper,
authtypes.NewModuleAddress(adminmoduletypes.ModuleName).String(),
)
wasmOpts = append(wasmbinding.RegisterCustomPlugins(
&app.InterchainTxsKeeper,
&app.InterchainQueriesKeeper,
app.TransferKeeper,
&app.AdminmoduleKeeper,
app.FeeBurnerKeeper,
app.FeeKeeper, &app.BankKeeper,
app.TokenFactoryKeeper, &app.CronKeeper,
&app.ContractManagerKeeper,
&app.DexKeeper,
), wasmOpts...)

queryPlugins := wasmkeeper.WithQueryPlugins(
&wasmkeeper.QueryPlugins{Stargate: wasmkeeper.AcceptListStargateQuerier(wasmbinding.AcceptedStargateQueries(), app.GRPCQueryRouter(), appCodec)})
Expand Down Expand Up @@ -813,7 +836,8 @@ func New(
swapModule,
dexModule,
auction.NewAppModule(appCodec, app.AuctionKeeper),
crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)), // always be last to make sure that it checks for all invariants and not only part of them
// always be last to make sure that it checks for all invariants and not only part of them
crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants, app.GetSubspace(crisistypes.ModuleName)),
)

// During begin block slashing happens after distr.BeginBlocker so that
Expand Down
Binary file modified contracts/credits_vault.wasm
Binary file not shown.
Binary file modified contracts/cwd_core.wasm
Binary file not shown.
Binary file modified contracts/cwd_pre_propose_multiple.wasm
Binary file not shown.
Binary file modified contracts/cwd_pre_propose_overrule.wasm
Binary file not shown.
Binary file modified contracts/cwd_pre_propose_single.wasm
Binary file not shown.
Binary file modified contracts/cwd_proposal_multiple.wasm
Binary file not shown.
Binary file modified contracts/cwd_proposal_single.wasm
Binary file not shown.
Binary file modified contracts/cwd_security_subdao_pre_propose.wasm
Binary file not shown.
Binary file modified contracts/cwd_subdao_core.wasm
Binary file not shown.
Binary file modified contracts/cwd_subdao_pre_propose_single.wasm
Binary file not shown.
Binary file modified contracts/cwd_subdao_proposal_single.wasm
Binary file not shown.
Binary file modified contracts/cwd_subdao_timelock_single.wasm
Binary file not shown.
Binary file modified contracts/investors_vesting_vault.wasm
Binary file not shown.
Binary file modified contracts/lockdrop_vault.wasm
Binary file not shown.
Binary file modified contracts/neutron_distribution.wasm
Binary file not shown.
Binary file modified contracts/neutron_reserve.wasm
Binary file not shown.
Binary file modified contracts/neutron_vault.wasm
Binary file not shown.
Binary file modified contracts/neutron_voting_registry.wasm
Binary file not shown.
Binary file modified contracts/vesting_investors.wasm
Binary file not shown.
Binary file modified contracts/vesting_lp_vault.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion proto/neutron/dex/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ service Query {
option (google.api.http).get = "/neutron/dex/estimate_multi_hop_swap";
}

// Queries the simulated result of a multihop swap
// Queries the simulated result of a PlaceLimit order
rpc EstimatePlaceLimitOrder(QueryEstimatePlaceLimitOrderRequest) returns (QueryEstimatePlaceLimitOrderResponse) {
option (google.api.http).get = "/neutron/dex/estimate_place_limit_order";
}
Expand Down
28 changes: 28 additions & 0 deletions wasmbinding/bindings/msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
paramChange "github.com/cosmos/cosmos-sdk/x/params/types/proposal"

dextypes "github.com/neutron-org/neutron/v2/x/dex/types"
feetypes "github.com/neutron-org/neutron/v2/x/feerefunder/types"
icqtypes "github.com/neutron-org/neutron/v2/x/interchainqueries/types"
transferwrappertypes "github.com/neutron-org/neutron/v2/x/transfer/types"
Expand Down Expand Up @@ -61,6 +62,9 @@ type NeutronMsg struct {
// Contractmanager types
/// A contract that has failed acknowledgement can resubmit it
ResubmitFailure *ResubmitFailure `json:"resubmit_failure,omitempty"`

// dex module bindings
Dex *Dex `json:"dex,omitempty"`
}

// SubmitTx submits interchain transaction on a remote chain.
Expand Down Expand Up @@ -244,3 +248,27 @@ type ResubmitFailure struct {
type ResubmitFailureResponse struct {
FailureId uint64 `json:"failure_id"`
}

type Dex struct {
Deposit *dextypes.MsgDeposit `json:"deposit"`
Withdrawal *dextypes.MsgWithdrawal `json:"withdrawal"`
PlaceLimitOrder *MsgPlaceLimitOrder `json:"place_limit_order"`
WithdrawFilledLimitOrder *dextypes.MsgWithdrawFilledLimitOrder `json:"withdraw_filled_limit_order"`
CancelLimitOrder *dextypes.MsgCancelLimitOrder `json:"cancel_limit_order"`
MultiHopSwap *dextypes.MsgMultiHopSwap `json:"multi_hop_swap"`
}

// MsgPlaceLimitOrder is a copy dextypes.MsgPlaceLimitOrder with altered ExpirationTime field,
// it's a preferable way to pass timestamp as unixtime to contracts
type MsgPlaceLimitOrder struct {
pr0n00gler marked this conversation as resolved.
Show resolved Hide resolved
Creator string `json:"creator,omitempty"`
Receiver string `json:"receiver,omitempty"`
TokenIn string `json:"token_in,omitempty"`
TokenOut string `json:"token_out,omitempty"`
TickIndexInToOut int64 `json:"tick_index_in_to_out,omitempty"`
AmountIn math.Int `json:"amount_in"`
OrderType string `json:"order_type,omitempty"`
// expirationTime is only valid iff orderType == GOOD_TIL_TIME.
ExpirationTime *uint64 `json:"expiration_time,omitempty"`
MaxAmountOut *math.Int `json:"max_amount_out"`
}
59 changes: 59 additions & 0 deletions wasmbinding/bindings/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package bindings
import (
"encoding/json"

"cosmossdk.io/math"

contractmanagertypes "github.com/neutron-org/neutron/v2/x/contractmanager/types"
dextypes "github.com/neutron-org/neutron/v2/x/dex/types"

feerefundertypes "github.com/neutron-org/neutron/v2/x/feerefunder/types"

Expand Down Expand Up @@ -40,6 +43,8 @@ type NeutronQuery struct {
// Contractmanager queries
// Query all failures for address
Failures *Failures `json:"failures,omitempty"`
// dex module queries
Dex *DexQuery `json:"dex,omitempty"`
}

/* Requests */
Expand Down Expand Up @@ -210,3 +215,57 @@ type Failures struct {
type FailuresResponse struct {
Failures []contractmanagertypes.Failure `json:"failures"`
}

type DexQuery struct {
// Parameters queries the parameters of the module.
Params *dextypes.QueryParamsRequest `json:"params"`
// Queries a LimitOrderTrancheUser by index.
LimitOrderTrancheUser *dextypes.QueryGetLimitOrderTrancheUserRequest `json:"limit_order_tranche_user,omitempty"`
// Queries a list of LimitOrderTrancheUser items.
LimitOrderTrancheUserAll *dextypes.QueryAllLimitOrderTrancheUserRequest `json:"limit_order_tranche_user_all"`
// Queries a list of LimitOrderTrancheUser items for a given address.
LimitOrderTrancheUserAllByAddress *dextypes.QueryAllUserLimitOrdersRequest `json:"limit_order_tranche_user_all_by_address"`
// Queries a LimitOrderTranche by index.
LimitOrderTranche *dextypes.QueryGetLimitOrderTrancheRequest `json:"limit_order_tranche"`
// Queries a list of LimitOrderTranche items for a given pairID / TokenIn combination.
LimitOrderTrancheAll *dextypes.QueryAllLimitOrderTrancheRequest `json:"limit_order_tranche_all"`
// Queries a list of UserDeposits items.
UserDepositsAll *dextypes.QueryAllUserDepositsRequest `json:"user_deposit_all"`
// Queries a list of TickLiquidity items.
TickLiquidityAll *dextypes.QueryAllTickLiquidityRequest `json:"tick_liquidity_all"`
// Queries a InactiveLimitOrderTranche by index.
InactiveLimitOrderTranche *dextypes.QueryGetInactiveLimitOrderTrancheRequest `json:"inactive_limit_order_tranche"`
// Queries a list of InactiveLimitOrderTranche items.
InactiveLimitOrderTrancheAll *dextypes.QueryAllInactiveLimitOrderTrancheRequest `json:"inactive_limit_order_tranche_all"`
// Queries a list of PoolReserves items.
PoolReservesAll *dextypes.QueryAllPoolReservesRequest `json:"pool_reserves_all"`
// Queries a PoolReserve by index
PoolReserves *dextypes.QueryGetPoolReservesRequest `json:"pool_reserves"`
// Queries the simulated result of a multihop swap
EstimateMultiHopSwap *dextypes.QueryEstimateMultiHopSwapRequest `json:"estimate_multi_hop_swap"`
// Queries the simulated result of a PlaceLimit order
EstimatePlaceLimitOrder *QueryEstimatePlaceLimitOrderRequest `json:"estimate_place_limit_order"`
// Queries a pool by pair, tick and fee
Pool *dextypes.QueryPoolRequest `json:"pool"`
// Queries a pool by ID
PoolByID *dextypes.QueryPoolByIDRequest `json:"pool_by_id"`
// Queries a PoolMetadata by ID
PoolMetadata *dextypes.QueryGetPoolMetadataRequest `json:"pool_metadata"`
// Queries a list of PoolMetadata items.
PoolMetadataAll *dextypes.QueryAllPoolMetadataRequest `json:"pool_metadata_all"`
}

// QueryEstimatePlaceLimitOrderRequest is a copy dextypes.QueryEstimatePlaceLimitOrderRequest with altered ExpirationTime field,
// it's a preferable way to pass timestamp as unixtime to contracts
type QueryEstimatePlaceLimitOrderRequest struct {
pr0n00gler marked this conversation as resolved.
Show resolved Hide resolved
Creator string `json:"creator,omitempty"`
Receiver string `json:"receiver,omitempty"`
TokenIn string `json:"token_in,omitempty"`
TokenOut string `json:"token_out,omitempty"`
TickIndexInToOut int64 `json:"tick_index_in_to_out,omitempty"`
AmountIn math.Int `json:"amount_in"`
OrderType string `json:"order_type,omitempty"`
// expirationTime is only valid iff orderType == GOOD_TIL_TIME.
ExpirationTime *uint64 `json:"expiration_time,omitempty"`
MaxAmountOut *math.Int `json:"max_amount_out"`
}
5 changes: 5 additions & 0 deletions wasmbinding/bindings/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package bindings

type BindingMarshaller interface {
MarshalBinding() ([]byte, error)
}
3 changes: 3 additions & 0 deletions wasmbinding/custom_querier.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ func CustomQuerier(qp *QueryPlugin) func(ctx sdk.Context, request json.RawMessag

return bz, nil

case contractQuery.Dex != nil:
return qp.DexQuery(ctx, *contractQuery.Dex)

default:
return nil, wasmvmtypes.UnsupportedRequest{Kind: "unknown neutron query type"}
}
Expand Down
100 changes: 100 additions & 0 deletions wasmbinding/message_plugin.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
package wasmbinding

import (
"context"
"encoding/json"
"fmt"
"strings"
"time"

"golang.org/x/exp/maps"

dexkeeper "github.com/neutron-org/neutron/v2/x/dex/keeper"
dextypes "github.com/neutron-org/neutron/v2/x/dex/types"

contractmanagerkeeper "github.com/neutron-org/neutron/v2/x/contractmanager/keeper"

Expand Down Expand Up @@ -49,6 +57,7 @@ func CustomMessageDecorator(
tokenFactoryKeeper *tokenfactorykeeper.Keeper,
cronKeeper *cronkeeper.Keeper,
contractmanagerKeeper *contractmanagerkeeper.Keeper,
dexKeeper *dexkeeper.Keeper,
) func(messenger wasmkeeper.Messenger) wasmkeeper.Messenger {
return func(old wasmkeeper.Messenger) wasmkeeper.Messenger {
return &CustomMessenger{
Expand All @@ -63,6 +72,7 @@ func CustomMessageDecorator(
CronKeeper: cronKeeper,
AdminKeeper: adminKeeper,
ContractmanagerKeeper: contractmanagerKeeper,
DexMsgServer: dexkeeper.NewMsgServerImpl(*dexKeeper),
}
}
}
Expand All @@ -79,6 +89,7 @@ type CustomMessenger struct {
CronKeeper *cronkeeper.Keeper
AdminKeeper *adminmodulekeeper.Keeper
ContractmanagerKeeper *contractmanagerkeeper.Keeper
DexMsgServer dextypes.MsgServer
}

var _ wasmkeeper.Messenger = (*CustomMessenger)(nil)
Expand Down Expand Up @@ -153,11 +164,100 @@ func (m *CustomMessenger) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddre
if contractMsg.ResubmitFailure != nil {
return m.resubmitFailure(ctx, contractAddr, contractMsg.ResubmitFailure)
}
if contractMsg.Dex != nil {
data, err := m.dispatchDexMsg(ctx, contractAddr, *(contractMsg.Dex))
pr0n00gler marked this conversation as resolved.
Show resolved Hide resolved
return nil, data, err
}

// If none of the conditions are met, forward the message to the wrapped handler
return m.Wrapped.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg)
}

func handleDexMsg[T sdk.Msg, R any](ctx sdk.Context, msg T, handler func(ctx context.Context, msg T) (R, error)) ([][]byte, error) {
if err := msg.ValidateBasic(); err != nil {
return nil, errors.Wrapf(err, "failed to validate %T", msg)
}

if len(msg.GetSigners()) != 1 {
// should never happen
panic("should be 1 signer")
}
signer := msg.GetSigners()[0].String()

resp, err := handler(ctx, msg)
if err != nil {
ctx.Logger().Debug(fmt.Sprintf("%T: failed to execute", msg),
"from_address", signer,
"msg", msg,
"error", err,
)
return nil, errors.Wrapf(err, "failed to execute %T", msg)
}

data, err := json.Marshal(resp)
if err != nil {
ctx.Logger().Error(fmt.Sprintf("json.Marshal: failed to marshal %T response to JSON", resp),
"from_address", signer,
"error", err,
)
return nil, errors.Wrap(err, fmt.Sprintf("marshal %T failed", resp))
}

ctx.Logger().Debug(fmt.Sprintf("%T execution completed", msg),
"from_address", signer,
"msg", msg,
)
return [][]byte{data}, nil
}

func (m *CustomMessenger) dispatchDexMsg(ctx sdk.Context, contractAddr sdk.AccAddress, dex bindings.Dex) ([][]byte, error) {
switch {
case dex.Deposit != nil:
dex.Deposit.Creator = contractAddr.String()
return handleDexMsg(ctx, dex.Deposit, m.DexMsgServer.Deposit)
case dex.Withdrawal != nil:
dex.Withdrawal.Creator = contractAddr.String()
return handleDexMsg(ctx, dex.Withdrawal, m.DexMsgServer.Withdrawal)
case dex.PlaceLimitOrder != nil:
msg := dextypes.MsgPlaceLimitOrder{
Creator: contractAddr.String(),
Receiver: dex.PlaceLimitOrder.Receiver,
TokenIn: dex.PlaceLimitOrder.TokenIn,
TokenOut: dex.PlaceLimitOrder.TokenOut,
TickIndexInToOut: dex.PlaceLimitOrder.TickIndexInToOut,
AmountIn: dex.PlaceLimitOrder.AmountIn,
MaxAmountOut: dex.PlaceLimitOrder.MaxAmountOut,
}
orderTypeInt, ok := dextypes.LimitOrderType_value[dex.PlaceLimitOrder.OrderType]
if !ok {
return nil, errors.Wrap(dextypes.ErrInvalidOrderType,
fmt.Sprintf(
"got \"%s\", expected one of %s",
dex.PlaceLimitOrder.OrderType,
strings.Join(maps.Keys(dextypes.LimitOrderType_value), ", ")),
)
}
msg.OrderType = dextypes.LimitOrderType(orderTypeInt)

if dex.PlaceLimitOrder.ExpirationTime != nil {
t := time.Unix(int64(*(dex.PlaceLimitOrder.ExpirationTime)), 0)
msg.ExpirationTime = &t
}
return handleDexMsg(ctx, &msg, m.DexMsgServer.PlaceLimitOrder)
case dex.CancelLimitOrder != nil:
dex.CancelLimitOrder.Creator = contractAddr.String()
return handleDexMsg(ctx, dex.CancelLimitOrder, m.DexMsgServer.CancelLimitOrder)
case dex.WithdrawFilledLimitOrder != nil:
dex.WithdrawFilledLimitOrder.Creator = contractAddr.String()
return handleDexMsg(ctx, dex.WithdrawFilledLimitOrder, m.DexMsgServer.WithdrawFilledLimitOrder)
case dex.MultiHopSwap != nil:
dex.MultiHopSwap.Creator = contractAddr.String()
return handleDexMsg(ctx, dex.MultiHopSwap, m.DexMsgServer.MultiHopSwap)
}

return nil, sdkerrors.ErrUnknownRequest
}

func (m *CustomMessenger) ibcTransfer(ctx sdk.Context, contractAddr sdk.AccAddress, ibcTransferMsg transferwrappertypes.MsgTransfer) ([]sdk.Event, [][]byte, error) {
ibcTransferMsg.Sender = contractAddr.String()

Expand Down
Loading
Loading