Skip to content

Commit

Permalink
Update contract rent deposit logic + add query endpoint (#625)
Browse files Browse the repository at this point in the history
* Update contract rent deposit logic + add query endpoint

* fmt

---------

Co-authored-by: Cyson <cyson@Cysons-MBP.attlocal.net>
  • Loading branch information
Xingchen Liao and Cyson authored Mar 3, 2023
1 parent a19ab6c commit 8778cb7
Show file tree
Hide file tree
Showing 11 changed files with 814 additions and 193 deletions.
2 changes: 0 additions & 2 deletions proto/dex/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import "gogoproto/gogo.proto";
import "dex/params.proto";
import "dex/long_book.proto";
import "dex/short_book.proto";
import "dex/tick_size.proto";
import "dex/order.proto";
import "dex/contract.proto";
import "dex/pair.proto";
import "dex/match_result.proto";
import "dex/price.proto";
// this line is used by starport scaffolding # genesis/proto/import

Expand Down
18 changes: 16 additions & 2 deletions proto/dex/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import "cosmos/base/query/v1beta1/pagination.proto";
import "dex/params.proto";
import "dex/long_book.proto";
import "dex/short_book.proto";
import "dex/settlement.proto";
import "dex/enums.proto";
import "dex/price.proto";
import "dex/contract.proto";
import "dex/twap.proto";
import "dex/asset_list.proto";
import "dex/pair.proto";
Expand Down Expand Up @@ -76,6 +75,11 @@ service Query {
option (google.api.http).get = "/sei-protocol/seichain/dex/registered_pairs";
}

// Returns registered contract information
rpc GetRegisteredContract(QueryRegisteredContractRequest) returns (QueryRegisteredContractResponse) {
option (google.api.http).get = "/sei-protocol/seichain/dex/registered_contract/{contractAddr}";
}

rpc GetOrders(QueryGetOrdersRequest) returns (QueryGetOrdersResponse) {
option (google.api.http).get = "/sei-protocol/seichain/dex/get_orders/{contractAddr}/{account}";
}
Expand Down Expand Up @@ -231,6 +235,16 @@ message QueryRegisteredPairsResponse {
repeated Pair pairs = 1 [(gogoproto.nullable) = false];
}

message QueryRegisteredContractRequest {
string contractAddr = 1 [
(gogoproto.jsontag) = "contract_address"
];
}

message QueryRegisteredContractResponse {
ContractInfoV2 contract_info = 1;
}

message QueryGetOrdersRequest{
string contractAddr = 1 [
(gogoproto.jsontag) = "contract_address"
Expand Down
1 change: 1 addition & 0 deletions x/dex/client/cli/query/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func GetQueryCmd() *cobra.Command {
cmd.AddCommand(CmdGetAssetList())
cmd.AddCommand(CmdGetAssetMetadata())
cmd.AddCommand(CmdGetRegisteredPairs())
cmd.AddCommand(CmdGetRegisteredContract())
cmd.AddCommand(CmdGetOrders())
cmd.AddCommand(CmdGetOrdersByID())
cmd.AddCommand(CmdGetMatchResult())
Expand Down
48 changes: 48 additions & 0 deletions x/dex/client/cli/query/query_registered_contract.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package query

import (
"strconv"
"strings"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
"github.com/sei-protocol/sei-chain/x/dex/types"
"github.com/spf13/cobra"
)

var _ = strconv.Itoa(0)

func CmdGetRegisteredContract() *cobra.Command {
cmd := &cobra.Command{
Use: "get-registered-contract [contract address]",
Short: "Query Registered Contract",
Long: strings.TrimSpace(`
List the registered contract information specified by contract address.
`),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) (err error) {
contractAddr := args[0]
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

queryClient := types.NewQueryClient(clientCtx)

params := &types.QueryRegisteredContractRequest{
ContractAddr: contractAddr,
}

res, err := queryClient.GetRegisteredContract(cmd.Context(), params)
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}
14 changes: 6 additions & 8 deletions x/dex/keeper/msgserver/msg_server_contract_deposit_rent.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
appparams "github.com/sei-protocol/sei-chain/app/params"
"github.com/sei-protocol/sei-chain/x/dex/types"
)
Expand All @@ -27,27 +26,26 @@ func (k msgServer) ContractDepositRent(goCtx context.Context, msg *types.MsgCont
if err != nil {
return nil, err
}

// check if the balance post deposit exceeds the limit.
// not checking the sum because it might overflow.
if k.maxAllowedRentBalance()-msg.GetAmount() < contract.RentBalance {
return nil, fmt.Errorf("rent balance %d will exceed the limit of %d after depositing %d", contract.RentBalance, k.maxAllowedRentBalance(), msg.GetAmount())
}
if contract.RentBalance > 0 && contract.Creator != msg.Sender {
// a sender can only "claim" the contract if the rent balance is 0
return nil, sdkerrors.ErrUnauthorized
}

// deposit
creatorAddr, err := sdk.AccAddressFromBech32(contract.Creator)
senderAddr, err := sdk.AccAddressFromBech32(msg.Sender)
if err != nil {
return nil, err
}
if err := k.BankKeeper.SendCoins(ctx, creatorAddr, k.AccountKeeper.GetModuleAddress(types.ModuleName), sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(int64(msg.Amount))))); err != nil {
if err := k.BankKeeper.SendCoins(ctx, senderAddr, k.AccountKeeper.GetModuleAddress(types.ModuleName), sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewInt(int64(msg.Amount))))); err != nil {
return nil, err
}
contract.Creator = msg.Sender

contract.RentBalance += msg.Amount
if err := k.SetContract(ctx, &contract); err != nil {
return nil, err
}

return &types.MsgContractDepositRentResponse{}, nil
}
11 changes: 8 additions & 3 deletions x/dex/keeper/msgserver/msg_server_contract_deposit_rent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,14 @@ func TestDepositRent(t *testing.T) {
wctx := sdk.WrapSDKContext(ctx)
dexkeeper := testApp.DexKeeper

testAccount, _ := sdk.AccAddressFromBech32("sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx")
testAccount, _ := sdk.AccAddressFromBech32("sei1h9yjz89tl0dl6zu65dpxcqnxfhq60wxx8s5kag")
depositAccount, _ := sdk.AccAddressFromBech32("sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx")
amounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(10000000)), sdk.NewCoin("uusdc", sdk.NewInt(10000000)))
bankkeeper := testApp.BankKeeper
bankkeeper.MintCoins(ctx, minttypes.ModuleName, amounts)
bankkeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, testAccount, amounts)
bankkeeper.MintCoins(ctx, minttypes.ModuleName, amounts)
bankkeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, depositAccount, amounts)
wasm, err := ioutil.ReadFile("../../testdata/mars.wasm")
if err != nil {
panic(err)
Expand Down Expand Up @@ -94,15 +97,17 @@ func TestDepositRent(t *testing.T) {

handler := dex.NewHandler(dexkeeper)
_, err = handler(ctx, &types.MsgContractDepositRent{
Sender: testAccount.String(),
Sender: depositAccount.String(),
ContractAddr: TestContractA,
Amount: 1000000,
})
require.NoError(t, err)
_, err = dexkeeper.GetContract(ctx, TestContractA)
require.NoError(t, err)
balance = dexkeeper.BankKeeper.GetBalance(ctx, testAccount, "usei")
require.Equal(t, int64(7900000), balance.Amount.Int64())
require.Equal(t, int64(8900000), balance.Amount.Int64())
balance = dexkeeper.BankKeeper.GetBalance(ctx, depositAccount, "usei")
require.Equal(t, int64(9000000), balance.Amount.Int64())

// deposit exceeds limit
_, err = handler(ctx, &types.MsgContractDepositRent{
Expand Down
24 changes: 24 additions & 0 deletions x/dex/keeper/query/grpc_query_registered_contract.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package query

import (
"context"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/sei-protocol/sei-chain/x/dex/types"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

func (k KeeperWrapper) GetRegisteredContract(c context.Context, req *types.QueryRegisteredContractRequest) (*types.QueryRegisteredContractResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "invalid request")
}
ctx := sdk.UnwrapSDKContext(c)

contractInfo, err := k.GetContract(ctx, req.ContractAddr)
if err != nil {
return nil, err
}

return &types.QueryRegisteredContractResponse{ContractInfo: &contractInfo}, nil
}
42 changes: 42 additions & 0 deletions x/dex/keeper/query/grpc_query_registered_contract_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package query_test

import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
keepertest "github.com/sei-protocol/sei-chain/testutil/keeper"
"github.com/sei-protocol/sei-chain/x/dex/keeper/query"
"github.com/sei-protocol/sei-chain/x/dex/types"
"github.com/stretchr/testify/require"
)

func TestRegisteredContractQuery(t *testing.T) {
keeper, ctx := keepertest.DexKeeper(t)
wrapper := query.KeeperWrapper{Keeper: keeper}
wctx := sdk.WrapSDKContext(ctx)
expectedContractInfo := types.ContractInfoV2{
Creator: keepertest.TestAccount,
ContractAddr: keepertest.TestContract,
CodeId: 1,
RentBalance: 1000000,
}
err := keeper.SetContract(ctx, &types.ContractInfoV2{
Creator: keepertest.TestAccount,
ContractAddr: keepertest.TestContract,
CodeId: 1,
RentBalance: 1000000,
})
require.NoError(t, err)

request := types.QueryRegisteredContractRequest{
ContractAddr: keepertest.TestContract,
}
expectedResponse := types.QueryRegisteredContractResponse{
ContractInfo: &expectedContractInfo,
}
t.Run("Registered Contract query", func(t *testing.T) {
response, err := wrapper.GetRegisteredContract(wctx, &request)
require.NoError(t, err)
require.Equal(t, expectedResponse, *response)
})
}
65 changes: 32 additions & 33 deletions x/dex/types/genesis.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8778cb7

Please sign in to comment.