Skip to content

Commit cdc5ab6

Browse files
committed
improve lending msg validation and errors
1 parent 34e189f commit cdc5ab6

File tree

13 files changed

+178
-78
lines changed

13 files changed

+178
-78
lines changed

x/lending/keeper/msg_server.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,12 @@ type msgServer struct {
2222

2323
// CreateLoan implements types.MsgServer.
2424
func (m msgServer) Apply(goCtx context.Context, msg *types.MsgApply) (*types.MsgApplyResponse, error) {
25+
if err := msg.ValidateBasic(); err != nil {
26+
return nil, err
27+
}
2528

2629
ctx := sdk.UnwrapSDKContext(goCtx)
2730

28-
// _borrower, errb := sdk.AccAddressFromBech32(msg.Borrower)
29-
// if errb != nil {
30-
// return nil, errb
31-
// }
32-
3331
if !m.dlcKeeper.HasEvent(ctx, msg.EventId) {
3432
return nil, types.ErrInvalidPriceEvent
3533
}
@@ -143,16 +141,19 @@ func (m msgServer) Apply(goCtx context.Context, msg *types.MsgApply) (*types.Msg
143141

144142
// Approve implements types.MsgServer.
145143
func (m msgServer) Approve(goCtx context.Context, msg *types.MsgApprove) (*types.MsgApproveResponse, error) {
144+
if err := msg.ValidateBasic(); err != nil {
145+
return nil, err
146+
}
146147

147148
ctx := sdk.UnwrapSDKContext(goCtx)
148149

149150
if !m.HasDepositLog(ctx, msg.DepositTxId) {
150-
return nil, types.ErrDepositTxNotExists
151+
return nil, types.ErrDepositTxDoesNotExist
151152
}
152153

153154
log := m.GetDepositLog(ctx, msg.DepositTxId)
154155
if !m.HasLoan(ctx, log.VaultAddress) {
155-
return nil, types.ErrLoanNotExists
156+
return nil, types.ErrLoanDoesNotExist
156157
}
157158

158159
if _, _, err := m.btcbridgeKeeper.ValidateTransaction(ctx, log.DepositTx, "", msg.BlockHash, msg.Proof); err != nil {
@@ -176,6 +177,10 @@ func (m msgServer) Approve(goCtx context.Context, msg *types.MsgApprove) (*types
176177

177178
// Redeem implements types.MsgServer.
178179
func (m msgServer) Redeem(goCtx context.Context, msg *types.MsgRedeem) (*types.MsgRedeemResponse, error) {
180+
if err := msg.ValidateBasic(); err != nil {
181+
return nil, err
182+
}
183+
179184
ctx := sdk.UnwrapSDKContext(goCtx)
180185

181186
borrower, err := sdk.AccAddressFromBech32(msg.Borrower)
@@ -184,7 +189,7 @@ func (m msgServer) Redeem(goCtx context.Context, msg *types.MsgRedeem) (*types.M
184189
}
185190

186191
if !m.HasLoan(ctx, msg.LoanId) {
187-
return nil, types.ErrLoanNotExists
192+
return nil, types.ErrLoanDoesNotExist
188193
}
189194

190195
loan := m.GetLoan(ctx, msg.LoanId)
@@ -194,7 +199,7 @@ func (m msgServer) Redeem(goCtx context.Context, msg *types.MsgRedeem) (*types.M
194199
}
195200

196201
if types.HashLoanSecret(msg.LoanSecret) != loan.HashLoanSecret {
197-
return nil, types.ErrMismatchLoanSecret
202+
return nil, types.ErrMismatchedLoanSecret
198203
}
199204

200205
m.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, borrower, sdk.NewCoins(*loan.BorrowAmount))
@@ -214,6 +219,10 @@ func (m msgServer) Redeem(goCtx context.Context, msg *types.MsgRedeem) (*types.M
214219

215220
// Repay implements types.MsgServer.
216221
func (m msgServer) Repay(goCtx context.Context, msg *types.MsgRepay) (*types.MsgRepayResponse, error) {
222+
if err := msg.ValidateBasic(); err != nil {
223+
return nil, err
224+
}
225+
217226
ctx := sdk.UnwrapSDKContext(goCtx)
218227

219228
borrower, err := sdk.AccAddressFromBech32(msg.Borrower)
@@ -222,7 +231,7 @@ func (m msgServer) Repay(goCtx context.Context, msg *types.MsgRepay) (*types.Msg
222231
}
223232

224233
if !m.HasLoan(ctx, msg.LoanId) {
225-
return nil, types.ErrLoanNotExists
234+
return nil, types.ErrLoanDoesNotExist
226235
}
227236

228237
loan := m.GetLoan(ctx, msg.LoanId)
@@ -282,7 +291,7 @@ func (m msgServer) SubmitRepaymentAdaptorSignature(goCtx context.Context, msg *t
282291
ctx := sdk.UnwrapSDKContext(goCtx)
283292

284293
if !m.HasLoan(ctx, msg.LoanId) {
285-
return nil, types.ErrLoanNotExists
294+
return nil, types.ErrLoanDoesNotExist
286295
}
287296

288297
if !m.HasRepayment(ctx, msg.LoanId) {
@@ -320,10 +329,14 @@ func (m msgServer) SubmitRepaymentAdaptorSignature(goCtx context.Context, msg *t
320329

321330
// Close implements types.MsgServer.
322331
func (m msgServer) Close(goCtx context.Context, msg *types.MsgClose) (*types.MsgCloseResponse, error) {
332+
if err := msg.ValidateBasic(); err != nil {
333+
return nil, err
334+
}
335+
323336
ctx := sdk.UnwrapSDKContext(goCtx)
324337

325338
if !m.HasLoan(ctx, msg.LoanId) {
326-
return nil, types.ErrLoanNotExists
339+
return nil, types.ErrLoanDoesNotExist
327340
}
328341

329342
if !m.HasRepayment(ctx, msg.LoanId) {

x/lending/keeper/pool.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func (m msgServer) AddLiquidity(goCtx context.Context, msg *types.MsgAddLiquidit
6262
}
6363

6464
if !m.HasPool(ctx, msg.PoolId) {
65-
return nil, types.ErrPootNotExists
65+
return nil, types.ErrPoolDoesNotExist
6666
}
6767

6868
pool := m.GetPool(ctx, msg.PoolId)
@@ -127,7 +127,7 @@ func (m msgServer) RemoveLiquidity(goCtx context.Context, msg *types.MsgRemoveLi
127127
}
128128

129129
if !m.HasPool(ctx, msg.Shares.Denom) {
130-
return nil, types.ErrPootNotExists
130+
return nil, types.ErrPoolDoesNotExist
131131
}
132132

133133
pool := m.GetPool(ctx, msg.Shares.Denom)

x/lending/types/errors.go

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,38 +7,39 @@ import (
77
)
88

99
var (
10-
ErrEmptySender = errorsmod.Register(ModuleName, 1000, "invalid tx sender")
11-
ErrInvalidAmount = errorsmod.Register(ModuleName, 1100, "invalid amount")
12-
ErrInvalidParams = errorsmod.Register(ModuleName, 1101, "invalid params")
10+
ErrInvalidAmount = errorsmod.Register(ModuleName, 1000, "invalid amount")
11+
ErrInvalidParams = errorsmod.Register(ModuleName, 1001, "invalid params")
1312
ErrInvalidSender = errorsmod.Register(ModuleName, 1002, "invalid tx sender")
1413

15-
ErrInvalidLiquidation = errorsmod.Register(ModuleName, 2100, "invalid liquidation")
16-
ErrEmptyPoolId = errorsmod.Register(ModuleName, 2200, "invalid pool id")
17-
ErrNotAuthorized = errorsmod.Register(ModuleName, 2201, "not authorized")
18-
ErrDuplicatedPoolId = errorsmod.Register(ModuleName, 2202, "duplicated pool id")
19-
ErrPootNotExists = errorsmod.Register(ModuleName, 2203, "pool not exists")
20-
ErrInactivePool = errorsmod.Register(ModuleName, 2203, "inactive pool")
14+
ErrInvalidLiquidity = errorsmod.Register(ModuleName, 2100, "invalid liquidity")
15+
ErrInvalidPoolId = errorsmod.Register(ModuleName, 2200, "invalid pool id")
16+
ErrInvalidLendingAsset = errorsmod.Register(ModuleName, 2201, "invalid lending asset")
17+
ErrNotAuthorized = errorsmod.Register(ModuleName, 2202, "not authorized")
18+
ErrDuplicatedPoolId = errorsmod.Register(ModuleName, 2203, "duplicated pool id")
19+
ErrPoolDoesNotExist = errorsmod.Register(ModuleName, 2204, "pool does not exist")
20+
ErrInactivePool = errorsmod.Register(ModuleName, 2205, "inactive pool")
2121

22-
ErrEmptyBorrowerPubkey = errorsmod.Register(ModuleName, 3001, "invalid pubkey of borrower")
22+
ErrInvalidBorrowerPubkey = errorsmod.Register(ModuleName, 3001, "invalid pubkey of borrower")
2323
ErrInvalidMaturityTime = errorsmod.Register(ModuleName, 3002, "maturity time great than 0")
2424
ErrInvalidFinalTimeout = errorsmod.Register(ModuleName, 3003, "final time great than maturity time")
25-
ErrInvalidLoanSecret = errorsmod.Register(ModuleName, 3003, "invalid loan secret")
26-
ErrDuplicatedVault = errorsmod.Register(ModuleName, 3004, "duplicated vault address")
27-
ErrInvalidPriceEvent = errorsmod.Register(ModuleName, 3005, "invalid price event")
28-
ErrInvalidFunding = errorsmod.Register(ModuleName, 3006, "invalid funding")
29-
ErrInvalidCET = errorsmod.Register(ModuleName, 3007, "invalid cet")
30-
ErrInsufficientCollateral = errorsmod.Register(ModuleName, 3008, "insufficient collateral")
31-
ErrLoanNotExists = errorsmod.Register(ModuleName, 3009, "loan not exists")
32-
33-
ErrEmptyDepositTx = errorsmod.Register(ModuleName, 4001, "invalid deposit tx")
34-
ErrInvalidProof = errorsmod.Register(ModuleName, 4002, "invalid proof")
35-
ErrDepositTxNotExists = errorsmod.Register(ModuleName, 4002, "deposit not exists")
36-
37-
ErrMismatchedBorrower = errorsmod.Register(ModuleName, 5001, "mismatched borrower")
38-
ErrEmptyLoanSecret = errorsmod.Register(ModuleName, 5002, "invalid loan secret")
39-
ErrMismatchLoanSecret = errorsmod.Register(ModuleName, 5003, "mismatch loan secret")
40-
41-
ErrEmptyAdaptorPoint = errorsmod.Register(ModuleName, 6001, "invalid adaptor point")
25+
ErrInvalidLoanSecret = errorsmod.Register(ModuleName, 3004, "invalid loan secret")
26+
ErrDuplicatedVault = errorsmod.Register(ModuleName, 3005, "duplicated vault address")
27+
ErrInvalidPriceEvent = errorsmod.Register(ModuleName, 3006, "invalid price event")
28+
ErrInvalidFunding = errorsmod.Register(ModuleName, 3007, "invalid funding")
29+
ErrInvalidCET = errorsmod.Register(ModuleName, 3008, "invalid cet")
30+
ErrInsufficientCollateral = errorsmod.Register(ModuleName, 3009, "insufficient collateral")
31+
ErrLoanDoesNotExist = errorsmod.Register(ModuleName, 3010, "loan does not exist")
32+
33+
ErrInvalidDepositTx = errorsmod.Register(ModuleName, 4001, "invalid deposit tx")
34+
ErrInvalidBlockHash = errorsmod.Register(ModuleName, 4002, "invalid block hash")
35+
ErrInvalidProof = errorsmod.Register(ModuleName, 4003, "invalid proof")
36+
ErrDepositTxDoesNotExist = errorsmod.Register(ModuleName, 4004, "deposit tx does not exist")
37+
38+
ErrMismatchedBorrower = errorsmod.Register(ModuleName, 5001, "mismatched borrower")
39+
ErrInvalidLoanSecretHash = errorsmod.Register(ModuleName, 5002, "invalid loan secret hash")
40+
ErrMismatchedLoanSecret = errorsmod.Register(ModuleName, 5003, "mismatched loan secret")
41+
42+
ErrInvalidAdaptorPoint = errorsmod.Register(ModuleName, 6001, "invalid adaptor point")
4243
ErrInvalidRepayment = errorsmod.Register(ModuleName, 6002, "invalid repayment")
4344
ErrInvalidRepaymentTx = errorsmod.Register(ModuleName, 6003, "invalid repayment tx")
4445
ErrInvalidRepaymentSecret = errorsmod.Register(ModuleName, 6004, "invalid repayment secret")

x/lending/types/lending.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ import (
66
sdkmath "cosmossdk.io/math"
77
)
88

9+
const (
10+
// minimum pool id length
11+
MinPoolIdLength = 2
12+
13+
// loan secret length
14+
LoanSecretLength = 32
15+
16+
// loan secret hash length
17+
LoanSecretHashLength = 32
18+
)
19+
920
// GetLiquidationPrice gets the liquidation price according to the liquidation LTV
1021
func GetLiquidationPrice(collateralAmout sdkmath.Int, borrowedAmount sdkmath.Int, lltv sdkmath.Int) sdkmath.Int {
1122
liquidationValue := new(big.Int).Div(borrowedAmount.BigInt(), lltv.BigInt())

x/lending/types/msg_add_liquidity.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package types
22

33
import (
4+
fmt "fmt"
5+
6+
errorsmod "cosmossdk.io/errors"
47
"cosmossdk.io/math"
58
sdk "github.com/cosmos/cosmos-sdk/types"
69
)
@@ -9,20 +12,24 @@ var _ sdk.Msg = &MsgAddLiquidity{}
912

1013
func NewMsgAddLiquidity(lender string, poolId string, amount sdk.Coin) *MsgAddLiquidity {
1114
return &MsgAddLiquidity{
12-
PoolId: poolId,
1315
Lender: lender,
16+
PoolId: poolId,
1417
Amount: &amount,
1518
}
1619
}
1720

1821
// ValidateBasic performs basic MsgAddLiquidity message validation.
1922
func (m *MsgAddLiquidity) ValidateBasic() error {
20-
if m.Amount.Amount.LTE(math.NewInt(0)) {
21-
return ErrInvalidLiquidation
23+
if _, err := sdk.AccAddressFromBech32(m.Lender); err != nil {
24+
return errorsmod.Wrap(err, "invalid sender address")
2225
}
2326

24-
if len(m.PoolId) == 0 {
25-
return ErrEmptyPoolId
27+
if len(m.PoolId) < MinPoolIdLength {
28+
return errorsmod.Wrap(ErrInvalidPoolId, fmt.Sprintf("minimum length of the pool id is %d", MinPoolIdLength))
29+
}
30+
31+
if m.Amount.Amount.LTE(math.NewInt(0)) {
32+
return ErrInvalidLiquidity
2633
}
2734

2835
return nil

x/lending/types/msg_apply.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package types
22

33
import (
4+
"encoding/hex"
5+
6+
"github.com/btcsuite/btcd/btcec/v2/schnorr"
7+
8+
errorsmod "cosmossdk.io/errors"
49
sdk "github.com/cosmos/cosmos-sdk/types"
510
)
611

@@ -18,6 +23,10 @@ func NewMsgApply(borrower string, borrowerPubkey string, hashLoanSecret string,
1823

1924
// ValidateBasic performs basic MsgAddLiquidity message validation.
2025
func (m *MsgApply) ValidateBasic() error {
26+
if _, err := sdk.AccAddressFromBech32(m.Borrower); err != nil {
27+
return errorsmod.Wrap(err, "invalid sender address")
28+
}
29+
2130
if m.MaturityTime <= 0 {
2231
return ErrInvalidMaturityTime
2332
}
@@ -26,16 +35,17 @@ func (m *MsgApply) ValidateBasic() error {
2635
return ErrInvalidFinalTimeout
2736
}
2837

29-
if len(m.Borrower) == 0 {
30-
return ErrEmptySender
38+
if secretHashBytes, err := hex.DecodeString(m.LoanSecretHash); err != nil || len(secretHashBytes) != LoanSecretHashLength {
39+
return ErrInvalidLoanSecretHash
3140
}
3241

33-
if len(m.LoanSecretHash) == 0 {
34-
return ErrInvalidLoanSecret
42+
pubKeyBytes, err := hex.DecodeString(m.BorrowerPubkey)
43+
if err != nil {
44+
return ErrInvalidBorrowerPubkey
3545
}
3646

37-
if len(m.BorrowerPubkey) == 0 {
38-
return ErrEmptyBorrowerPubkey
47+
if _, err := schnorr.ParsePubKey(pubKeyBytes); err != nil {
48+
return ErrInvalidBorrowerPubkey
3949
}
4050

4151
return nil

x/lending/types/msg_approve.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package types
22

33
import (
4+
"github.com/btcsuite/btcd/chaincfg/chainhash"
5+
6+
errorsmod "cosmossdk.io/errors"
47
sdk "github.com/cosmos/cosmos-sdk/types"
58
)
69

@@ -17,8 +20,16 @@ func NewMsgApprove(relayer string, depositTxId string, blockHash string, proof [
1720

1821
// ValidateBasic performs basic MsgAddLiquidity message validation.
1922
func (m *MsgApprove) ValidateBasic() error {
20-
if len(m.DepositTxId) == 0 {
21-
return ErrEmptyDepositTx
23+
if _, err := sdk.AccAddressFromBech32(m.Relayer); err != nil {
24+
return errorsmod.Wrap(err, "invalid sender address")
25+
}
26+
27+
if _, err := chainhash.NewHashFromStr(m.DepositTxId); err != nil {
28+
return ErrInvalidDepositTx
29+
}
30+
31+
if _, err := chainhash.NewHashFromStr(m.BlockHash); err != nil {
32+
return ErrInvalidBlockHash
2233
}
2334

2435
if len(m.Proof) == 0 {

x/lending/types/msg_close.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
package types
22

33
import (
4+
"encoding/hex"
5+
6+
"github.com/btcsuite/btcd/btcec/v2/schnorr"
7+
8+
errorsmod "cosmossdk.io/errors"
49
sdk "github.com/cosmos/cosmos-sdk/types"
510
)
611

@@ -16,15 +21,20 @@ func NewMsgClose(relayer string, loanId string, signature string) *MsgClose {
1621

1722
// ValidateBasic performs basic message validation.
1823
func (m *MsgClose) ValidateBasic() error {
19-
if len(m.Relayer) == 0 {
20-
return ErrEmptySender
24+
if _, err := sdk.AccAddressFromBech32(m.Relayer); err != nil {
25+
return errorsmod.Wrap(err, "invalid sender address")
2126
}
2227

2328
if len(m.LoanId) == 0 {
2429
return ErrEmptyLoanId
2530
}
2631

27-
if len(m.Signature) == 0 {
32+
sigBytes, err := hex.DecodeString(m.Signature)
33+
if err != nil {
34+
return ErrInvalidSignature
35+
}
36+
37+
if _, err := schnorr.ParseSignature(sigBytes); err != nil {
2838
return ErrInvalidSignature
2939
}
3040

0 commit comments

Comments
 (0)