Skip to content

Commit f47e8e8

Browse files
committed
add liquidation queue
1 parent 36f50fa commit f47e8e8

4 files changed

Lines changed: 96 additions & 76 deletions

File tree

x/lending/keeper/loan.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,20 @@ func (k Keeper) RemoveLoanStatus(ctx sdk.Context, id string) {
5555
store.Delete(types.LoanByStatusKey(loan.Status, id))
5656
}
5757

58+
// AddToLiquidationQueue adds the given loan to the liquidation queue
59+
func (k Keeper) AddToLiquidationQueue(ctx sdk.Context, loanId string) {
60+
store := ctx.KVStore(k.storeKey)
61+
62+
store.Set(types.LiquidationQueueKey(loanId), []byte{})
63+
}
64+
65+
// RemoveFromLiquidationQueue removes the given loan from the liquidation queue
66+
func (k Keeper) RemoveFromLiquidationQueue(ctx sdk.Context, loanId string) {
67+
store := ctx.KVStore(k.storeKey)
68+
69+
store.Delete(types.LiquidationQueueKey(loanId))
70+
}
71+
5872
// HasLoan returns true if the given loan exists, false otherwise
5973
func (k Keeper) HasLoan(ctx sdk.Context, id string) bool {
6074
store := ctx.KVStore(k.storeKey)
@@ -192,6 +206,18 @@ func (k Keeper) GetPendingLoans(ctx sdk.Context) []*types.Loan {
192206
return loans
193207
}
194208

209+
// GetLiquidatedLoans gets the liquidated loans from the liquidation queue
210+
func (k Keeper) GetLiquidatedLoans(ctx sdk.Context) []*types.Loan {
211+
var loans []*types.Loan
212+
213+
k.IterateLiquidationQueue(ctx, func(loan *types.Loan) (stop bool) {
214+
loans = append(loans, loan)
215+
return false
216+
})
217+
218+
return loans
219+
}
220+
195221
// GetAllLoans returns all loans
196222
func (k Keeper) GetAllLoans(ctx sdk.Context) []*types.Loan {
197223
var loans []*types.Loan
@@ -242,6 +268,23 @@ func (k Keeper) IterateLoansByStatus(ctx sdk.Context, status types.LoanStatus, c
242268
}
243269
}
244270

271+
// IterateLiquidationQueue iterates through the liquidation queue
272+
func (k Keeper) IterateLiquidationQueue(ctx sdk.Context, cb func(loan *types.Loan) (stop bool)) {
273+
store := ctx.KVStore(k.storeKey)
274+
275+
iterator := storetypes.KVStorePrefixIterator(store, types.LiquidationQueueKeyPrefix)
276+
defer iterator.Close()
277+
278+
for ; iterator.Valid(); iterator.Next() {
279+
id := string(iterator.Key()[1:])
280+
loan := k.GetLoan(ctx, id)
281+
282+
if cb(loan) {
283+
break
284+
}
285+
}
286+
}
287+
245288
// SetDepositLog sets the given deposit log
246289
func (k Keeper) SetDepositLog(ctx sdk.Context, depositLog *types.DepositLog) {
247290
store := ctx.KVStore(k.storeKey)

x/lending/module/abci.go

Lines changed: 23 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) {
2525
handleActiveLoans(ctx, k)
2626

2727
handleLiquidatedLoans(ctx, k)
28-
handleDefaultedLoans(ctx, k)
29-
3028
handleRepayments(ctx, k)
3129
}
3230

@@ -199,6 +197,9 @@ func handleActiveLoans(ctx sdk.Context, k keeper.Keeper) {
199197
loan.LiquidationId = liquidation.Id
200198
k.SetLoan(ctx, loan)
201199

200+
// add to liquidation queue
201+
k.AddToLiquidationQueue(ctx, loan.VaultAddress)
202+
202203
// trigger dlc event if not triggered yet
203204
if !k.DLCKeeper().GetEvent(ctx, loan.DlcEventId).HasTriggered {
204205
k.DLCKeeper().TriggerDLCEvent(ctx, loan.DlcEventId, outcomeIndex)
@@ -221,18 +222,18 @@ func handleActiveLoans(ctx sdk.Context, k keeper.Keeper) {
221222

222223
// handleLiquidatedLoans handles liquidated loans
223224
func handleLiquidatedLoans(ctx sdk.Context, k keeper.Keeper) {
224-
// get all liquidated loans
225-
loans := k.GetLoans(ctx, types.LoanStatus_Liquidated)
225+
// get liquidated loans
226+
loans := k.GetLiquidatedLoans(ctx)
226227

227228
for _, loan := range loans {
228-
// check if the liquidation cet has been signed
229+
// get dlc meta
229230
dlcMeta := k.GetDLCMeta(ctx, loan.VaultAddress)
230-
if len(dlcMeta.LiquidationCet.SignedTxHex) != 0 {
231-
continue
232-
}
231+
232+
// get liquidation cet and type
233+
cet, cetType := types.GetLiquidationCetAndType(dlcMeta, loan.Status)
233234

234235
// check if the borrower adapted signatures already exist
235-
if len(dlcMeta.LiquidationCet.BorrowerAdaptedSignatures) == 0 {
236+
if len(cet.BorrowerAdaptedSignatures) == 0 {
236237
// check if the event attestation has been submitted
237238
attestation := k.DLCKeeper().GetAttestationByEvent(ctx, loan.DlcEventId)
238239
if attestation == nil {
@@ -243,94 +244,43 @@ func handleLiquidatedLoans(ctx sdk.Context, k keeper.Keeper) {
243244
adaptorSecret := eventSignature[32:]
244245

245246
// decrypt the adaptor signatures
246-
for _, adaptorSignature := range dlcMeta.LiquidationCet.BorrowerAdaptorSignatures {
247+
for _, adaptorSignature := range cet.BorrowerAdaptorSignatures {
247248
adaptorSignature, _ := hex.DecodeString(adaptorSignature)
248249
adaptedSignature := adaptor.Adapt(adaptorSignature, adaptorSecret)
249250

250251
// update the adapted signatures
251-
dlcMeta.LiquidationCet.BorrowerAdaptedSignatures = append(
252-
dlcMeta.LiquidationCet.BorrowerAdaptedSignatures,
252+
cet.BorrowerAdaptedSignatures = append(
253+
cet.BorrowerAdaptedSignatures,
253254
hex.EncodeToString(adaptedSignature))
254255
}
255256
}
256257

257258
// build signed liquidation cet if both borrower adapted signatures(obviously exist) and DCM signatures already exist
258-
if len(dlcMeta.LiquidationCet.DCMSignatures) != 0 {
259-
signedTx, txHash, err := types.BuildSignedCet(dlcMeta.LiquidationCet.Tx, loan.BorrowerAuthPubKey, dlcMeta.LiquidationCet.BorrowerAdaptedSignatures, loan.DCM, dlcMeta.LiquidationCet.DCMSignatures)
259+
if len(cet.DCMSignatures) != 0 {
260+
signedTx, txHash, err := types.BuildSignedCet(cet.Tx, loan.BorrowerAuthPubKey, cet.BorrowerAdaptedSignatures, loan.DCM, cet.DCMSignatures)
260261
if err != nil {
261262
k.Logger(ctx).Info("failed to build signed liquidation cet", "loan id", loan.VaultAddress, "err", err)
262263
} else {
263-
dlcMeta.LiquidationCet.SignedTxHex = hex.EncodeToString(signedTx)
264-
265-
// emit event
266-
ctx.EventManager().EmitEvent(
267-
sdk.NewEvent(types.EventTypeGenerateSignedCet,
268-
sdk.NewAttribute(types.AttributeKeyLoanId, loan.VaultAddress),
269-
sdk.NewAttribute(types.AttributeKeyCetType, fmt.Sprintf("%d", types.CetType_LIQUIDATION)),
270-
sdk.NewAttribute(types.AttributeKeyTxHash, txHash.String()),
271-
),
272-
)
273-
}
274-
}
275-
276-
k.SetDLCMeta(ctx, loan.VaultAddress, dlcMeta)
277-
}
278-
}
279-
280-
// handleDefaultedLoans handles defaulted loans
281-
func handleDefaultedLoans(ctx sdk.Context, k keeper.Keeper) {
282-
// get all defaulted loans
283-
loans := k.GetLoans(ctx, types.LoanStatus_Defaulted)
264+
cet.SignedTxHex = hex.EncodeToString(signedTx)
284265

285-
for _, loan := range loans {
286-
// check if the default liquidation cet has been signed
287-
dlcMeta := k.GetDLCMeta(ctx, loan.VaultAddress)
288-
if len(dlcMeta.DefaultLiquidationCet.SignedTxHex) != 0 {
289-
continue
290-
}
291-
292-
// check if the borrower adapted signatures already exist
293-
if len(dlcMeta.DefaultLiquidationCet.BorrowerAdaptedSignatures) == 0 {
294-
// check if the event attestation has been submitted
295-
attestation := k.DLCKeeper().GetAttestationByEvent(ctx, loan.DlcEventId)
296-
if attestation == nil {
297-
continue
298-
}
299-
300-
eventSignature, _ := hex.DecodeString(attestation.Signature)
301-
adaptorSecret := eventSignature[32:]
302-
303-
// decrypt the adaptor signatures
304-
for _, adaptorSignature := range dlcMeta.DefaultLiquidationCet.BorrowerAdaptorSignatures {
305-
adaptorSignature, _ := hex.DecodeString(adaptorSignature)
306-
adaptedSignature := adaptor.Adapt(adaptorSignature, adaptorSecret)
307-
308-
// update the adapted signatures
309-
dlcMeta.DefaultLiquidationCet.BorrowerAdaptedSignatures = append(
310-
dlcMeta.DefaultLiquidationCet.BorrowerAdaptedSignatures,
311-
hex.EncodeToString(adaptedSignature))
312-
}
313-
}
314-
315-
// build signed default liquidation cet if both borrower adapted signatures(obviously exist) and DCM signatures already exist
316-
if len(dlcMeta.DefaultLiquidationCet.DCMSignatures) != 0 {
317-
signedTx, txHash, err := types.BuildSignedCet(dlcMeta.DefaultLiquidationCet.Tx, loan.BorrowerAuthPubKey, dlcMeta.DefaultLiquidationCet.BorrowerAdaptedSignatures, loan.DCM, dlcMeta.DefaultLiquidationCet.DCMSignatures)
318-
if err != nil {
319-
k.Logger(ctx).Info("failed to build signed default liquidation cet", "loan id", loan.VaultAddress, "err", err)
320-
} else {
321-
dlcMeta.DefaultLiquidationCet.SignedTxHex = hex.EncodeToString(signedTx)
266+
// remove from the liquidation queue
267+
k.RemoveFromLiquidationQueue(ctx, loan.VaultAddress)
322268

323269
// emit event
324270
ctx.EventManager().EmitEvent(
325271
sdk.NewEvent(types.EventTypeGenerateSignedCet,
326272
sdk.NewAttribute(types.AttributeKeyLoanId, loan.VaultAddress),
327-
sdk.NewAttribute(types.AttributeKeyCetType, fmt.Sprintf("%d", types.CetType_DEFAULT_LIQUIDATION)),
273+
sdk.NewAttribute(types.AttributeKeyCetType, fmt.Sprintf("%d", cetType)),
328274
sdk.NewAttribute(types.AttributeKeyTxHash, txHash.String()),
329275
),
330276
)
331277
}
332278
}
333279

280+
// update liquidation cet
281+
types.UpdateLiquidationCet(dlcMeta, cetType, cet)
282+
283+
// update dlc meta
334284
k.SetDLCMeta(ctx, loan.VaultAddress, dlcMeta)
335285
}
336286
}

x/lending/types/dlc.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,28 @@ func BuildSignedCet(cet string, borrowerPubKey string, borrowerSignatures []stri
455455
return buf.Bytes(), &txHash, nil
456456
}
457457

458+
// GetCet gets the liquidation cet and corresponding type according to the given loan status
459+
func GetLiquidationCetAndType(dlcMeta *DLCMeta, loanStatus LoanStatus) (LiquidationCet, CetType) {
460+
switch loanStatus {
461+
case LoanStatus_Liquidated:
462+
return dlcMeta.LiquidationCet, CetType_LIQUIDATION
463+
464+
default:
465+
return dlcMeta.DefaultLiquidationCet, CetType_DEFAULT_LIQUIDATION
466+
}
467+
}
468+
469+
// UpdateLiquidationCet updates the liquidation cet by the given type
470+
func UpdateLiquidationCet(dlcMeta *DLCMeta, cetType CetType, cet LiquidationCet) {
471+
switch cetType {
472+
case CetType_LIQUIDATION:
473+
dlcMeta.LiquidationCet = cet
474+
475+
default:
476+
dlcMeta.DefaultLiquidationCet = cet
477+
}
478+
}
479+
458480
// GetCetInfo gets the cet info from the given event and script
459481
func GetCetInfo(event *dlctypes.DLCEvent, outcomeIndex int, script []byte, controlBlock []byte) (*CetInfo, error) {
460482
if event == nil {

x/lending/types/keys.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ var (
4040
DLCMetaKeyPrefix = []byte{0x16}
4141
RedemptionKeyPrefix = []byte{0x17}
4242

43-
ReferrerKeyPrefix = []byte{0x20}
44-
LoanByStatusKeyPrefix = []byte{0x21}
45-
LoanByOracleKeyPrefix = []byte{0x22}
43+
ReferrerKeyPrefix = []byte{0x20}
44+
LoanByStatusKeyPrefix = []byte{0x21}
45+
LoanByOracleKeyPrefix = []byte{0x22}
46+
LiquidationQueueKeyPrefix = []byte{0x23}
4647
)
4748

4849
func PoolKey(id string) []byte {
@@ -71,6 +72,10 @@ func LoanByOracleKey(oraclePubKey string, id string) []byte {
7172
return append(key, []byte(id)...)
7273
}
7374

75+
func LiquidationQueueKey(loanId string) []byte {
76+
return append(LiquidationQueueKeyPrefix, []byte(loanId)...)
77+
}
78+
7479
func AuthorizationIdKey(loanId string) []byte {
7580
return append(AuthorizationIdKeyPrefix, []byte(loanId)...)
7681
}

0 commit comments

Comments
 (0)