From 4207b0366f9e5af0ba541b434312dc9b35d8c4a7 Mon Sep 17 00:00:00 2001 From: Denis Fadeev Date: Mon, 4 Oct 2021 15:51:17 +0500 Subject: [PATCH] feat: Added custom logic for loan functionality * Modified messages * Fix AccAddressFromBech32 and use SendCoinsFromAccountToModule * Fixed the flow * Error if wrong state --- x/loan/keeper/msg_server_approve_loan.go | 24 ++++++++++++++++-- x/loan/keeper/msg_server_liquidate_loan.go | 25 +++++++++++++++++-- x/loan/keeper/msg_server_repay_loan.go | 26 +++++++++++++++++-- x/loan/keeper/msg_server_request_loan.go | 29 +++++++++++++++++++++- x/loan/types/errors.go | 2 +- x/loan/types/expected_keepers.go | 7 ++++++ 6 files changed, 105 insertions(+), 8 deletions(-) diff --git a/x/loan/keeper/msg_server_approve_loan.go b/x/loan/keeper/msg_server_approve_loan.go index b360912..73d0b55 100644 --- a/x/loan/keeper/msg_server_approve_loan.go +++ b/x/loan/keeper/msg_server_approve_loan.go @@ -2,16 +2,36 @@ package keeper import ( "context" + "fmt" "github.com/cosmonaut/loan/x/loan/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) func (k msgServer) ApproveLoan(goCtx context.Context, msg *types.MsgApproveLoan) (*types.MsgApproveLoanResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - // TODO: Handling the message - _ = ctx + loan, found := k.GetLoan(ctx, msg.Id) + if !found { + return nil, sdkerrors.Wrapf(sdkerrors.ErrKeyNotFound, fmt.Sprintf("key %d doesn't exist", msg.Id)) + } + + // TODO: for some reason the error doesn't get printed to the terminal + if loan.State != "requested" { + return nil, sdkerrors.Wrapf(types.ErrWrongLoanState, "%v", loan.State) + } + + lender, _ := sdk.AccAddressFromBech32(msg.Creator) + borrower, _ := sdk.AccAddressFromBech32(loan.Borrower) + amount, _ := sdk.ParseCoinsNormalized(loan.Amount) + + k.bankKeeper.SendCoins(ctx, lender, borrower, amount) + + loan.Lender = msg.Creator + loan.State = "approved" + + k.SetLoan(ctx, loan) return &types.MsgApproveLoanResponse{}, nil } diff --git a/x/loan/keeper/msg_server_liquidate_loan.go b/x/loan/keeper/msg_server_liquidate_loan.go index adfc362..3e68f81 100644 --- a/x/loan/keeper/msg_server_liquidate_loan.go +++ b/x/loan/keeper/msg_server_liquidate_loan.go @@ -2,16 +2,37 @@ package keeper import ( "context" + "fmt" + "strconv" "github.com/cosmonaut/loan/x/loan/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) func (k msgServer) LiquidateLoan(goCtx context.Context, msg *types.MsgLiquidateLoan) (*types.MsgLiquidateLoanResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - // TODO: Handling the message - _ = ctx + loan, found := k.GetLoan(ctx, msg.Id) + if !found { + return nil, sdkerrors.Wrap(sdkerrors.ErrKeyNotFound, fmt.Sprintf("key %d doesn't exist", msg.Id)) + } + + if loan.State != "approved" { + return nil, sdkerrors.Wrapf(types.ErrWrongLoanState, "%v", loan.State) + } + + lender, _ := sdk.AccAddressFromBech32(loan.Lender) + amount, _ := sdk.ParseCoinsNormalized(loan.Amount) + + deadline, err := strconv.ParseInt(loan.Deadline, 10, 64) + if err != nil { + panic(err) + } + + if ctx.BlockHeight() > deadline { + k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, lender, amount) + } return &types.MsgLiquidateLoanResponse{}, nil } diff --git a/x/loan/keeper/msg_server_repay_loan.go b/x/loan/keeper/msg_server_repay_loan.go index 2e291ef..1e131fa 100644 --- a/x/loan/keeper/msg_server_repay_loan.go +++ b/x/loan/keeper/msg_server_repay_loan.go @@ -2,16 +2,38 @@ package keeper import ( "context" + "fmt" "github.com/cosmonaut/loan/x/loan/types" sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) func (k msgServer) RepayLoan(goCtx context.Context, msg *types.MsgRepayLoan) (*types.MsgRepayLoanResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - // TODO: Handling the message - _ = ctx + loan, found := k.GetLoan(ctx, msg.Id) + if !found { + return nil, sdkerrors.Wrap(sdkerrors.ErrKeyNotFound, fmt.Sprintf("key %d doesn't exist", msg.Id)) + } + + if loan.State != "approved" { + return nil, sdkerrors.Wrapf(types.ErrWrongLoanState, "%v", loan.State) + } + + lender, _ := sdk.AccAddressFromBech32(loan.Lender) + borrower, _ := sdk.AccAddressFromBech32(loan.Borrower) + amount, _ := sdk.ParseCoinsNormalized(loan.Amount) + fee, _ := sdk.ParseCoinsNormalized(loan.Fee) + collateral, _ := sdk.ParseCoinsNormalized(loan.Collateral) + + k.bankKeeper.SendCoins(ctx, borrower, lender, amount) + k.bankKeeper.SendCoins(ctx, borrower, lender, fee) + k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, borrower, collateral) + + loan.State = "repayed" + + k.SetLoan(ctx, loan) return &types.MsgRepayLoanResponse{}, nil } diff --git a/x/loan/keeper/msg_server_request_loan.go b/x/loan/keeper/msg_server_request_loan.go index 306411b..f665e28 100644 --- a/x/loan/keeper/msg_server_request_loan.go +++ b/x/loan/keeper/msg_server_request_loan.go @@ -11,7 +11,34 @@ func (k msgServer) RequestLoan(goCtx context.Context, msg *types.MsgRequestLoan) ctx := sdk.UnwrapSDKContext(goCtx) // TODO: Handling the message - _ = ctx + var loan = types.Loan{ + Amount: msg.Amount, + Fee: msg.Fee, + Collateral: msg.Collateral, + Deadline: msg.Deadline, + State: "requested", + Borrower: msg.Creator, + } + + // TODO: collateral has to be more than the amount (+fee?) + + // moduleAcc := sdk.AccAddress(crypto.AddressHash([]byte(types.ModuleName))) + borrower, _ := sdk.AccAddressFromBech32(msg.Creator) + + collateral, err := sdk.ParseCoinsNormalized(loan.Collateral) + if err != nil { + panic(err) + } + + sdkError := k.bankKeeper.SendCoinsFromAccountToModule(ctx, borrower, types.ModuleName, collateral) + if sdkError != nil { + return nil, sdkError + } + + k.AppendLoan( + ctx, + loan, + ) return &types.MsgRequestLoanResponse{}, nil } diff --git a/x/loan/types/errors.go b/x/loan/types/errors.go index 1328e28..83ebe61 100644 --- a/x/loan/types/errors.go +++ b/x/loan/types/errors.go @@ -8,5 +8,5 @@ import ( // x/loan module sentinel errors var ( - ErrSample = sdkerrors.Register(ModuleName, 1100, "sample error") + ErrWrongLoanState = sdkerrors.Register(ModuleName, 1, "wrong loan state") ) diff --git a/x/loan/types/expected_keepers.go b/x/loan/types/expected_keepers.go index 6dcd053..04597ad 100644 --- a/x/loan/types/expected_keepers.go +++ b/x/loan/types/expected_keepers.go @@ -1,5 +1,12 @@ package types +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + type BankKeeper interface { // Methods imported from bank should be defined here + SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error + SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error }