Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ Ref: https://keepachangelog.com/en/1.0.0/

## [Unreleased]

### State Machine Breaking

- [1479](https://github.com/umee-network/umee/pull/1479) Add MsgSupplyCollateral.

## [v3.0.2](https://github.com/umee-network/umee/releases/tag/v3.0.2) - 2022-09-29

### Fixes
Expand Down
16 changes: 16 additions & 0 deletions proto/umee/leverage/v1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ service Msg {
// Liquidate allows a user to repay a different user's borrowed coins in exchange for some
// of the target's collateral.
rpc Liquidate(MsgLiquidate) returns (MsgLiquidateResponse);

// SupplyCollateral combines the Supply and Collateralize actions.
rpc SupplyCollateral(MsgSupplyCollateral) returns (MsgSupplyCollateralResponse);
}

// MsgSupply represents a user's request to supply assets to the module.
Expand Down Expand Up @@ -104,6 +107,13 @@ message MsgLiquidate {
string reward_denom = 4;
}

// MsgSupplyCollateral represents a user's request to supply and collateralize assets to the module.
message MsgSupplyCollateral {
// Supplier is the account address supplying assets and the signer of the message.
string supplier = 1;
cosmos.base.v1beta1.Coin asset = 2 [(gogoproto.nullable) = false];
}

// MsgSupplyResponse defines the Msg/Supply response type.
message MsgSupplyResponse {
// Received is the amount of uTokens received.
Expand Down Expand Up @@ -143,3 +153,9 @@ message MsgLiquidateResponse {
// the module as reward for the liquidation.
cosmos.base.v1beta1.Coin reward = 3 [(gogoproto.nullable) = false];
}

// MsgSupplyCollateralResponse defines the Msg/SupplyCollateral response type.
message MsgSupplyCollateralResponse {
// Collateralized is the amount of uTokens collateralized.
cosmos.base.v1beta1.Coin collateralized = 1 [(gogoproto.nullable) = false];
}
30 changes: 30 additions & 0 deletions x/leverage/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func GetTxCmd() *cobra.Command {
GetCmdBorrow(),
GetCmdRepay(),
GetCmdLiquidate(),
GetCmdSupplyCollateral(),
)

return cmd
Expand Down Expand Up @@ -264,6 +265,35 @@ $ umeed tx leverage liquidate %s 50000000uumee u/uumee --from mykey`,
return cmd
}

// GetCmdSupplyCollateral creates a Cobra command to generate or broadcast a
// transaction with a MsgSupply message.
func GetCmdSupplyCollateral() *cobra.Command {
cmd := &cobra.Command{
Use: "supply-collateral [amount]",
Args: cobra.ExactArgs(1),
Short: "Supply and collateralize a specified amount of a supported asset",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

asset, err := sdk.ParseCoinNormalized(args[0])
if err != nil {
return err
}

msg := types.NewMsgSupplyCollateral(clientCtx.GetFromAddress(), asset)

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

flags.AddTxFlagsToCmd(cmd)

return cmd
}

// NewCmdSubmitUpdateRegistryProposal creates a Cobra command to generate
// or broadcast a transaction with a governance proposal message containing a
// UpdateRegistryProposal.
Expand Down
14 changes: 12 additions & 2 deletions x/leverage/client/tests/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func (s *IntegrationTestSuite) TestLeverageScenario() {
"supply",
cli.GetCmdSupply(),
[]string{
"1000uumee",
"700uumee",
},
nil,
}
Expand All @@ -143,7 +143,16 @@ func (s *IntegrationTestSuite) TestLeverageScenario() {
"add collateral",
cli.GetCmdCollateralize(),
[]string{
"1000u/uumee",
"700u/uumee",
},
nil,
}

supplyCollateral := testTransaction{
"supply collateral",
cli.GetCmdSupplyCollateral(),
[]string{
"300uumee",
},
nil,
}
Expand Down Expand Up @@ -270,6 +279,7 @@ func (s *IntegrationTestSuite) TestLeverageScenario() {
s.runTestTransactions(
supply,
addCollateral,
supplyCollateral,
borrow,
)

Expand Down
45 changes: 45 additions & 0 deletions x/leverage/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,51 @@ func (s msgServer) Collateralize(
return &types.MsgCollateralizeResponse{}, err
}

func (s msgServer) SupplyCollateral(
goCtx context.Context,
msg *types.MsgSupplyCollateral,
) (*types.MsgSupplyCollateralResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

supplierAddr, err := sdk.AccAddressFromBech32(msg.Supplier)
if err != nil {
return nil, err
}
uToken, err := s.keeper.Supply(ctx, supplierAddr, msg.Asset)
if err != nil {
return nil, err
}
if err = s.keeper.Collateralize(ctx, supplierAddr, uToken); err != nil {
return nil, err
}

s.keeper.Logger(ctx).Debug(
"assets supplied",
"supplier", msg.Supplier,
"supplied", msg.Asset.String(),
"received", uToken.String(),
)
if err = ctx.EventManager().EmitTypedEvent(&types.EventSupply{
Supplier: msg.Supplier,
Asset: msg.Asset,
Utoken: uToken,
}); err != nil {
return nil, err
}
s.keeper.Logger(ctx).Debug(
"collateral added",
"borrower", msg.Supplier,
"amount", uToken.String(),
)
err = ctx.EventManager().EmitTypedEvent(&types.EventCollaterize{
Borrower: msg.Supplier,
Utoken: uToken,
})
return &types.MsgSupplyCollateralResponse{
Collateralized: uToken,
}, err
}

func (s msgServer) Decollateralize(
goCtx context.Context,
msg *types.MsgDecollateralize,
Expand Down
24 changes: 24 additions & 0 deletions x/leverage/types/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,30 @@ func (msg *MsgCollateralize) GetSignBytes() []byte {
return sdk.MustSortJSON(bz)
}

func NewMsgSupplyCollateral(supplier sdk.AccAddress, asset sdk.Coin) *MsgSupplyCollateral {
return &MsgSupplyCollateral{
Supplier: supplier.String(),
Asset: asset,
}
}

func (msg MsgSupplyCollateral) Route() string { return sdk.MsgTypeURL(&msg) }
func (msg MsgSupplyCollateral) Type() string { return sdk.MsgTypeURL(&msg) }

func (msg *MsgSupplyCollateral) ValidateBasic() error {
return validateSenderAndAsset(msg.Supplier, &msg.Asset)
}

func (msg *MsgSupplyCollateral) GetSigners() []sdk.AccAddress {
return checkers.Signers(msg.Supplier)
}

// GetSignBytes get the bytes for the message signer to sign on
func (msg *MsgSupplyCollateral) GetSignBytes() []byte {
bz := ModuleCdc.MustMarshalJSON(msg)
return sdk.MustSortJSON(bz)
}

func NewMsgDecollateralize(borrower sdk.AccAddress, asset sdk.Coin) *MsgDecollateralize {
return &MsgDecollateralize{
Borrower: borrower.String(),
Expand Down
Loading