Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
a98974f
WIP: add the custom handlers for cosmwasm
gsk967 Apr 14, 2023
67ad3e7
Merge branch 'main' into sai/wasm_handler
gsk967 Apr 14, 2023
3046ee0
fix: fix the lint
gsk967 Apr 14, 2023
6642c3d
Merge branch 'main' into sai/wasm_handler
gsk967 Apr 17, 2023
8c2df41
review: address the pr comments
gsk967 Apr 17, 2023
ac87616
rename MsgSupplyCollaterize to Collateral
gsk967 Apr 18, 2023
c5288ac
Merge branch 'main' into sai/wasm_handler
gsk967 Apr 19, 2023
13404a4
Merge branch 'main' into sai/wasm_handler
gsk967 Apr 24, 2023
ab7156b
Merge branch 'main' into sai/wasm_handler
gsk967 Apr 25, 2023
a3c878d
Merge branch 'main' into sai/wasm_handler
gsk967 Apr 26, 2023
ded7f34
Merge branch 'main' into sai/wasm_handler
gsk967 Apr 26, 2023
73729d8
tests: cw20 integration test (#2007)
gsk967 May 1, 2023
b8d9379
Merge branch 'main' into sai/wasm_handler
gsk967 May 1, 2023
964521e
Merge branch 'main' into sai/wasm_handler
gsk967 May 2, 2023
3767abc
Merge branch 'main' into sai/wasm_handler
gsk967 May 4, 2023
c5f579d
fix: fix the supply collateral in wasm leverage tx
gsk967 May 5, 2023
ed5dca8
Merge branch 'main' into sai/wasm_handler
gsk967 May 5, 2023
8330260
fix: fix the leverage custom msg execute by wasm
gsk967 May 5, 2023
bb55e58
Merge remote-tracking branch 'origin' into sai/wasm_handler
gsk967 May 5, 2023
b44ba19
Merge remote-tracking branch 'origin/sai/wasm_handler' into sai/wasm_…
gsk967 May 5, 2023
2832c7c
Merge branch 'main' into sai/wasm_handler
gsk967 May 8, 2023
22654fe
Merge branch 'main' into sai/wasm_handler
gsk967 May 10, 2023
cca9e21
Merge branch 'main' into sai/wasm_handler
gsk967 May 15, 2023
21de827
Merge branch 'main' into sai/wasm_handler
gsk967 May 17, 2023
79c7f37
Merge branch 'main' into sai/wasm_handler
gsk967 May 19, 2023
27fd80b
Merge branch 'main' into sai/wasm_handler
gsk967 May 20, 2023
8245c72
Merge branch 'main' into sai/wasm_handler
gsk967 May 22, 2023
785f190
Merge branch 'main' into sai/wasm_handler
gsk967 May 22, 2023
ae810d6
Merge branch 'main' into sai/wasm_handler
gsk967 May 24, 2023
1ef846e
chore: remove types using from umee wasm queries
gsk967 May 24, 2023
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ private*

#IntelliJ
.idea/
.vscode
5 changes: 5 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ import (
ugovmodule "github.com/umee-network/umee/v4/x/ugov/module"

// umee ibc-transfer and quota for ibc-transfer
uwasm "github.com/umee-network/umee/v4/app/wasm"
"github.com/umee-network/umee/v4/x/uibc"
uibcmodule "github.com/umee-network/umee/v4/x/uibc/module"
uibcoracle "github.com/umee-network/umee/v4/x/uibc/oracle"
Expand Down Expand Up @@ -648,6 +649,10 @@ func New(
// The last arguments can contain custom message handlers, and custom query handlers,
// if we want to allow any custom callbacks
availableCapabilities := "iterator,staking,stargate,cosmwasm_1_1,umee"

// Register umee custom plugin to wasm
wasmOpts = append(uwasm.RegisterCustomPlugins(app.LeverageKeeper, app.OracleKeeper), wasmOpts...)

app.WasmKeeper = wasm.NewKeeper(
appCodec,
keys[wasm.StoreKey],
Expand Down
29 changes: 29 additions & 0 deletions app/wasm/custom_plugins.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package wasm

import (
"github.com/CosmWasm/wasmd/x/wasm"
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"

"github.com/umee-network/umee/v4/app/wasm/msg"
"github.com/umee-network/umee/v4/app/wasm/query"
leveragekeeper "github.com/umee-network/umee/v4/x/leverage/keeper"
oraclekeeper "github.com/umee-network/umee/v4/x/oracle/keeper"
)

// RegisterCustomPlugins expose the queries and msgs of native modules to wasm.
func RegisterCustomPlugins(
leverageKeeper leveragekeeper.Keeper,
oracleKeeper oraclekeeper.Keeper,
) []wasmkeeper.Option {
wasmQueryPlugin := query.NewQueryPlugin(leverageKeeper, oracleKeeper)
queryPluginOpt := wasmkeeper.WithQueryPlugins(&wasmkeeper.QueryPlugins{
Custom: wasmQueryPlugin.CustomQuerier(),
})

messagePluginOpt := wasmkeeper.WithMessageHandlerDecorator(msg.NewMessagePlugin(leverageKeeper))

return []wasm.Option{
queryPluginOpt,
messagePluginOpt,
}
}
106 changes: 106 additions & 0 deletions app/wasm/msg/handler_leverage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package msg

import (
"context"

"github.com/gogo/protobuf/proto"

lvtypes "github.com/umee-network/umee/v4/x/leverage/types"
)

// HandleSupply handles the Supply value of an address.
func (m UmeeMsg) HandleSupply(
ctx context.Context, sender string,
s lvtypes.MsgServer,
) (proto.Message, error) {
req := &lvtypes.MsgSupply{Supplier: sender, Asset: m.Supply.Asset}
return s.Supply(ctx, req)
}

// HandleWithdraw handles the Withdraw value of an address.
func (m UmeeMsg) HandleWithdraw(
ctx context.Context, sender string,
s lvtypes.MsgServer,
) (proto.Message, error) {
req := &lvtypes.MsgWithdraw{Supplier: sender, Asset: m.Withdraw.Asset}
return s.Withdraw(ctx, req)
}

// HandleMaxWithdraw handles the maximum withdraw value of an address.
func (m UmeeMsg) HandleMaxWithdraw(
ctx context.Context, sender string,
s lvtypes.MsgServer,
) (proto.Message, error) {
req := &lvtypes.MsgMaxWithdraw{Supplier: sender, Denom: m.MaxWithdraw.Denom}
return s.MaxWithdraw(ctx, req)
}

// HandleCollateralize handles the enable selected uTokens as collateral.
func (m UmeeMsg) HandleCollateralize(
ctx context.Context, sender string,
s lvtypes.MsgServer,
) (proto.Message, error) {
req := &lvtypes.MsgCollateralize{Borrower: sender, Asset: m.Collateralize.Asset}
return s.Collateralize(ctx, req)
}

// HandleDecollateralize handles the disable amount of an selected uTokens
// as collateral.
func (m UmeeMsg) HandleDecollateralize(
ctx context.Context, sender string,
s lvtypes.MsgServer,
) (proto.Message, error) {
req := &lvtypes.MsgDecollateralize{Borrower: sender, Asset: m.Decollateralize.Asset}
return s.Decollateralize(ctx, req)
}

// HandleBorrow handles the borrowing coins from the capital facility.
func (m UmeeMsg) HandleBorrow(
ctx context.Context, sender string,
s lvtypes.MsgServer,
) (proto.Message, error) {
req := &lvtypes.MsgBorrow{Borrower: sender, Asset: m.Borrow.Asset}
return s.Borrow(ctx, req)
}

// HandleMaxBorrow handles the borrowing maximum coins from the capital facility.
func (m UmeeMsg) HandleMaxBorrow(
ctx context.Context, sender string,
s lvtypes.MsgServer,
) (proto.Message, error) {
req := &lvtypes.MsgMaxBorrow{Borrower: sender, Denom: m.MaxBorrow.Denom}
return s.MaxBorrow(ctx, req)
}

// HandleRepay handles repaying borrowed coins to the capital facility.
func (m UmeeMsg) HandleRepay(
ctx context.Context, sender string,
s lvtypes.MsgServer,
) (proto.Message, error) {
req := &lvtypes.MsgRepay{Borrower: sender, Asset: m.Repay.Asset}
return s.Repay(ctx, req)
}

// HandleLiquidate handles the repaying a different user's borrowed coins
// to the capital facility in exchange for some of their collateral.
func (m UmeeMsg) HandleLiquidate(
ctx context.Context, sender string,
s lvtypes.MsgServer,
) (proto.Message, error) {
req := &lvtypes.MsgLiquidate{
Liquidator: sender,
Borrower: m.Liquidate.Borrower,
Repayment: m.Liquidate.Repayment,
RewardDenom: m.Liquidate.RewardDenom,
}
return s.Liquidate(ctx, req)
}

// HandleSupplyCollateral handles the supply the assets and collateral their assets.
func (m UmeeMsg) HandleSupplyCollateral(
ctx context.Context, sender string,
s lvtypes.MsgServer,
) (proto.Message, error) {
req := &lvtypes.MsgSupplyCollateral{Supplier: sender, Asset: m.SupplyCollateral.Asset}
return s.SupplyCollateral(ctx, req)
}
82 changes: 82 additions & 0 deletions app/wasm/msg/plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package msg

import (
"encoding/json"

sdkerrors "cosmossdk.io/errors"
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
sdk "github.com/cosmos/cosmos-sdk/types"

lvkeeper "github.com/umee-network/umee/v4/x/leverage/keeper"
lvtypes "github.com/umee-network/umee/v4/x/leverage/types"
)

// Plugin wraps the msg plugin with Messengers.
type Plugin struct {
lvMsgServer lvtypes.MsgServer
wrapped wasmkeeper.Messenger
}

var _ wasmkeeper.Messenger = (*Plugin)(nil)

// CustomMessageDecorator returns decorator for custom CosmWasm bindings messages
func NewMessagePlugin(leverageKeeper lvkeeper.Keeper) func(wasmkeeper.Messenger) wasmkeeper.Messenger {
return func(old wasmkeeper.Messenger) wasmkeeper.Messenger {
return &Plugin{
wrapped: old,
lvMsgServer: lvkeeper.NewMsgServerImpl(leverageKeeper),
}
}
}

// DispatchCustomMsg responsible for handling custom messages (umee native messages).
func (plugin *Plugin) DispatchCustomMsg(ctx sdk.Context, contractAddr sdk.AccAddress, rawMsg json.RawMessage) error {
var smartcontractMessage UmeeMsg
if err := json.Unmarshal(rawMsg, &smartcontractMessage); err != nil {
return sdkerrors.Wrap(err, "invalid umee custom msg")
}

sender := contractAddr.String()
var err error
sdkCtx := sdk.WrapSDKContext(ctx)
switch {
case smartcontractMessage.Supply != nil:
_, err = smartcontractMessage.HandleSupply(sdkCtx, sender, plugin.lvMsgServer)
case smartcontractMessage.Withdraw != nil:
_, err = smartcontractMessage.HandleWithdraw(sdkCtx, sender, plugin.lvMsgServer)
case smartcontractMessage.MaxWithdraw != nil:
_, err = smartcontractMessage.HandleMaxWithdraw(sdkCtx, sender, plugin.lvMsgServer)
case smartcontractMessage.Collateralize != nil:
_, err = smartcontractMessage.HandleCollateralize(sdkCtx, sender, plugin.lvMsgServer)
case smartcontractMessage.Decollateralize != nil:
_, err = smartcontractMessage.HandleDecollateralize(sdkCtx, sender, plugin.lvMsgServer)
case smartcontractMessage.Borrow != nil:
_, err = smartcontractMessage.HandleBorrow(sdkCtx, sender, plugin.lvMsgServer)
case smartcontractMessage.MaxBorrow != nil:
_, err = smartcontractMessage.HandleMaxBorrow(sdkCtx, sender, plugin.lvMsgServer)
case smartcontractMessage.Repay != nil:
_, err = smartcontractMessage.HandleRepay(sdkCtx, sender, plugin.lvMsgServer)
case smartcontractMessage.Liquidate != nil:
_, err = smartcontractMessage.HandleLiquidate(sdkCtx, sender, plugin.lvMsgServer)
case smartcontractMessage.SupplyCollateral != nil:
_, err = smartcontractMessage.HandleSupplyCollateral(sdkCtx, sender, plugin.lvMsgServer)
default:
err = wasmvmtypes.UnsupportedRequest{Kind: "invalid assigned umee msg"}
}

return err
}

// DispatchMsg encodes the wasmVM message and dispatches it.
func (plugin *Plugin) DispatchMsg(
ctx sdk.Context,
contractAddr sdk.AccAddress,
contractIBCPortID string,
msg wasmvmtypes.CosmosMsg,
) (events []sdk.Event, data [][]byte, err error) {
if msg.Custom != nil {
return nil, nil, plugin.DispatchCustomMsg(ctx, contractAddr, msg.Custom)
}
return plugin.wrapped.DispatchMsg(ctx, contractAddr, contractIBCPortID, msg)
}
30 changes: 30 additions & 0 deletions app/wasm/msg/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package msg

import (
lvtypes "github.com/umee-network/umee/v4/x/leverage/types"
)

// UmeeMsg wraps all the messages availables for cosmwasm smartcontracts.
type UmeeMsg struct {
// Used to supply coins to the capital facility.
Supply *lvtypes.MsgSupply `json:"supply,omitempty"`
// Used to withdraw previously loaned coins from the capital facility.
Withdraw *lvtypes.MsgWithdraw `json:"withdraw,omitempty"`
// Used to do withdraw maximum assets by supplier.
MaxWithdraw *lvtypes.MsgMaxWithdraw `json:"max_withdraw,omitempty"`
// Used to enable an amount of selected uTokens as collateral.
Collateralize *lvtypes.MsgCollateralize `json:"collateralize,omitempty"`
// Used to disable amount of an selected uTokens as collateral.
Decollateralize *lvtypes.MsgDecollateralize `json:"decollateralize,omitempty"`
// Used to borrowing coins from the capital facility.
Borrow *lvtypes.MsgBorrow `json:"borrow,omitempty"`
// Used to borrowing coins from the capital facility.
MaxBorrow *lvtypes.MsgMaxBorrow `json:"max_borrow,omitempty"`
// Used to repaying borrowed coins to the capital facility.
Repay *lvtypes.MsgRepay `json:"repay,omitempty"`
// Used to repaying a different user's borrowed coins
// to the capital facility in exchange for some of their collateral.
Liquidate *lvtypes.MsgLiquidate `json:"liquidate,omitempty"`
// Used to do supply and collateralize their assets.
SupplyCollateral *lvtypes.MsgSupplyCollateral `json:"supply_collateral,omitempty"`
}
91 changes: 91 additions & 0 deletions app/wasm/query/handle_leverage.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package query

import (
"context"

"github.com/gogo/protobuf/proto"

lvtypes "github.com/umee-network/umee/v4/x/leverage/types"
)

// HandleLeverageParams handles the get the x/leverage module's parameters.
func (q UmeeQuery) HandleLeverageParams(
ctx context.Context,
qs lvtypes.QueryServer,
) (proto.Message, error) {
return qs.Params(ctx, &lvtypes.QueryParams{})
}

// HandleRegisteredTokens handles the get all registered tokens query and response.
func (q UmeeQuery) HandleRegisteredTokens(
ctx context.Context,
qs lvtypes.QueryServer,
) (proto.Message, error) {
if len(q.RegisteredTokens.BaseDenom) != 0 {
return qs.RegisteredTokens(ctx, &lvtypes.QueryRegisteredTokens{
BaseDenom: q.RegisteredTokens.BaseDenom,
})
}
return qs.RegisteredTokens(ctx, &lvtypes.QueryRegisteredTokens{})
}

// HandleMarketSummary queries a base asset's current borrowing and supplying conditions.
func (q UmeeQuery) HandleMarketSummary(
ctx context.Context,
qs lvtypes.QueryServer,
) (proto.Message, error) {
return qs.MarketSummary(ctx, &lvtypes.QueryMarketSummary{Denom: q.MarketSummary.Denom})
}

// HandleAccountBalances queries an account's current supply, collateral, and borrow positions.
func (q UmeeQuery) HandleAccountBalances(
ctx context.Context,
qs lvtypes.QueryServer,
) (proto.Message, error) {
req := &lvtypes.QueryAccountBalances{Address: q.AccountBalances.Address}
return qs.AccountBalances(ctx, req)
}

// HandleAccountSummary queries USD values representing an account's total
// positions and borrowing limits. It requires oracle prices to return successfully.
func (q UmeeQuery) HandleAccountSummary(
ctx context.Context,
qs lvtypes.QueryServer,
) (proto.Message, error) {
req := &lvtypes.QueryAccountSummary{Address: q.AccountSummary.Address}
return qs.AccountSummary(ctx, req)
}

// HandleLiquidationTargets queries a list of all borrower account addresses eligible for liquidation.
func (q UmeeQuery) HandleLiquidationTargets(
ctx context.Context,
qs lvtypes.QueryServer,
) (proto.Message, error) {
return qs.LiquidationTargets(ctx, &lvtypes.QueryLiquidationTargets{})
}

// HandleBadDebts queries bad debts.
func (q UmeeQuery) HandleBadDebts(
ctx context.Context,
qs lvtypes.QueryServer,
) (proto.Message, error) {
return qs.BadDebts(ctx, &lvtypes.QueryBadDebts{})
}

// HandleBadDebts queries bad debts.
func (q UmeeQuery) HandleMaxWithdraw(
ctx context.Context,
qs lvtypes.QueryServer,
) (proto.Message, error) {
req := &lvtypes.QueryMaxWithdraw{Address: q.MaxWithdraw.Address, Denom: q.MaxWithdraw.Denom}
return qs.MaxWithdraw(ctx, req)
}

// HandleMaxBorrow queries max borrow.
func (q UmeeQuery) HandleMaxBorrow(
ctx context.Context,
qs lvtypes.QueryServer,
) (proto.Message, error) {
req := &lvtypes.QueryMaxBorrow{Address: q.MaxBorrow.Address, Denom: q.MaxBorrow.Address}
return qs.MaxBorrow(ctx, req)
}
Loading