Commit fd703948 authored by pengjun's avatar pengjun

#627 删除清算罚金;增加借贷超时时间和超时清算

parent c9fbaf73
......@@ -140,3 +140,16 @@ func (c *Collateralize) deleteCollateralizeRecordStatus(collateralizelog *pty.Re
kvs = append(kvs, kv)
return kvs
}
// CheckReceiptExecOk return true to check if receipt ty is ok
func (c *Collateralize) CheckReceiptExecOk() bool {
return true
}
// ExecutorOrder 设置localdb的EnableRead
func (c *Collateralize) ExecutorOrder() int64 {
if types.IsFork(c.GetHeight(), "ForkLocalDBAccess") {
return drivers.ExecLocalSameTime
}
return c.DriverBase.ExecutorOrder()
}
\ No newline at end of file
......@@ -27,9 +27,8 @@ const (
MaxDebtCeiling = 10000 // 最大借贷限额
MinLiquidationRatio = 0.3 // 最小质押比
MaxStabilityFee = 1000 // 最大稳定费
MaxLiquidationPenalty = 1000 // 最大清算罚金
MinCreatorAccount = 1000000 // 借贷创建者账户最小ccny余额
PriceWarningRate = 1.3
PriceWarningRate = 1.3 // 价格提前预警率
ExpireWarningTime = 3600 * 24 * 10 // 提前10天超时预警
)
// CollateralizeDB def
......@@ -193,6 +192,18 @@ func getLatestLiquidationPrice(coll *pty.Collateralize) float32 {
return latest
}
func getLatestExpireTime(coll *pty.Collateralize) int64 {
var latest int64 = 0x7fffffffffffffff
for _, collRecord := range coll.BorrowRecords {
if collRecord.ExpireTime < latest {
latest = collRecord.ExpireTime
}
}
return latest
}
// CollateralizeCreate 创建借贷,持有一定数量ccny的用户可创建借贷,提供给其他用户借贷
func (action *Action) CollateralizeCreate(create *pty.CollateralizeCreate) (*types.Receipt, error) {
var logs []*types.ReceiptLog
......@@ -204,9 +215,7 @@ func (action *Action) CollateralizeCreate(create *pty.CollateralizeCreate) (*typ
// 参数校验
if create.DebtCeiling > MaxDebtCeiling || create.DebtCeiling < 0 ||
create.LiquidationRatio < MinLiquidationRatio || create.LiquidationRatio >= 1 ||
create.StabilityFee > MaxStabilityFee || create.StabilityFee < 0 ||
create.LiquidationPenalty > MaxLiquidationPenalty || create.LiquidationPenalty < 0 ||
create.TotalBalance < MinCreatorAccount {
create.StabilityFee > MaxStabilityFee || create.StabilityFee < 0 {
return nil, pty.ErrRiskParam
}
......@@ -237,7 +246,6 @@ func (action *Action) CollateralizeCreate(create *pty.CollateralizeCreate) (*typ
coll.LiquidationRatio = create.LiquidationRatio
coll.TotalBalance = create.TotalBalance
coll.DebtCeiling = create.DebtCeiling
coll.LiquidationPenalty = create.LiquidationPenalty
coll.StabilityFee = create.StabilityFee
coll.Balance = create.TotalBalance
coll.CreateAddr = action.fromaddr
......@@ -433,6 +441,7 @@ func (action *Action) CollateralizeBorrow(borrow *pty.CollateralizeBorrow) (*typ
borrowRecord.DebtValue = borrow.Value
borrowRecord.LiquidationPrice = coll.LiquidationRatio * lastPrice * pty.CollateralizePreLiquidationRatio
borrowRecord.Status = pty.CollateralizeUserStatusCreate
borrowRecord.ExpireTime = action.blocktime + coll.Period
// 记录当前借贷的最高自动清算价格
if coll.LatestLiquidationPrice < borrowRecord.LiquidationPrice {
......@@ -478,9 +487,12 @@ func (action *Action) CollateralizeRepay(repay *pty.CollateralizeRepay) (*types.
// 查找借出记录
var borrowRecord *pty.BorrowRecord
for _, record := range coll.BorrowRecords {
var index int
for i, record := range coll.BorrowRecords {
if record.AccountAddr == action.fromaddr {
borrowRecord = record
index = i
break
}
}
......@@ -527,7 +539,10 @@ func (action *Action) CollateralizeRepay(repay *pty.CollateralizeRepay) (*types.
// 保存
coll.Balance += repay.Value
coll.BorrowRecords = append(coll.BorrowRecords[:index], coll.BorrowRecords[index+1:]...)
coll.InvalidRecords = append(coll.InvalidRecords, borrowRecord)
coll.LatestLiquidationPrice = getLatestLiquidationPrice(&coll.Collateralize)
coll.LatestExpireTime = getLatestExpireTime(&coll.Collateralize)
coll.Save(action.db)
kv = append(kv, coll.GetKVSet()...)
......@@ -612,6 +627,7 @@ func (action *Action) CollateralizeAppend(cAppend *pty.CollateralizeAppend) (*ty
// 记录当前借贷的最高自动清算价格
coll.LatestLiquidationPrice = getLatestLiquidationPrice(&coll.Collateralize)
coll.LatestExpireTime = getLatestExpireTime(&coll.Collateralize)
coll.Save(action.db)
kv = append(kv, coll.GetKVSet()...)
......@@ -691,9 +707,13 @@ func (action *Action) systemLiquidation(coll *pty.Collateralize, price float32)
var kv []*types.KeyValue
collDB := &CollateralizeDB{*coll}
for _, borrowRecord := range coll.BorrowRecords {
for index, borrowRecord := range coll.BorrowRecords {
var preStatus int32
if borrowRecord.LiquidationPrice * PriceWarningRate >= price {
if borrowRecord.LiquidationPrice * PriceWarningRate < price {
continue
}
if borrowRecord.LiquidationPrice >= price {
getGuarantorAddr, err := getGuarantorAddr(action.db)
if err != nil {
......@@ -716,6 +736,8 @@ func (action *Action) systemLiquidation(coll *pty.Collateralize, price float32)
borrowRecord.LiquidateTime = action.blocktime
preStatus = borrowRecord.Status
borrowRecord.Status = pty.CollateralizeUserStatusSystemLiquidate
coll.BorrowRecords = append(coll.BorrowRecords[:index], coll.BorrowRecords[index+1:]...)
coll.InvalidRecords = append(coll.InvalidRecords, borrowRecord)
} else {
preStatus = borrowRecord.Status
borrowRecord.Status = pty.CollateralizeUserStatusWarning
......@@ -724,10 +746,66 @@ func (action *Action) systemLiquidation(coll *pty.Collateralize, price float32)
log := action.GetFeedReceiptLog(coll, borrowRecord, preStatus)
logs = append(logs, log)
}
// 保存
coll.LatestLiquidationPrice = getLatestLiquidationPrice(coll)
coll.LatestExpireTime = getLatestExpireTime(coll)
collDB.Save(action.db)
kv = append(kv, collDB.GetKVSet()...)
receipt := &types.Receipt{Ty: types.ExecOk, KV: kv, Logs: logs}
return receipt, nil
}
// 超时清算
func (action *Action) expireLiquidation(coll *pty.Collateralize) (*types.Receipt, error) {
var logs []*types.ReceiptLog
var kv []*types.KeyValue
collDB := &CollateralizeDB{*coll}
for index, borrowRecord := range coll.BorrowRecords {
var preStatus int32
if borrowRecord.ExpireTime - ExpireWarningTime > action.blocktime {
continue
}
if borrowRecord.ExpireTime >= action.blocktime {
getGuarantorAddr, err := getGuarantorAddr(action.db)
if err != nil {
if err != nil {
clog.Error("systemLiquidation", "getGuarantorAddr", err)
continue
}
}
// 抵押物转移
receipt, err := action.coinsAccount.ExecTransferFrozen(action.fromaddr, getGuarantorAddr, action.execaddr, borrowRecord.CollateralValue)
if err != nil {
clog.Error("systemLiquidation", "addr", action.fromaddr, "execaddr", action.execaddr, "amount", borrowRecord.CollateralValue, "err", err)
continue
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
// 借贷记录清算
borrowRecord.LiquidateTime = action.blocktime
preStatus = borrowRecord.Status
borrowRecord.Status = pty.CollateralizeUserStatusSystemLiquidate
coll.BorrowRecords = append(coll.BorrowRecords[:index], coll.BorrowRecords[index+1:]...)
coll.InvalidRecords = append(coll.InvalidRecords, borrowRecord)
} else {
preStatus = borrowRecord.Status
borrowRecord.Status = pty.CollateralizeUserStatusWarning
}
log := action.GetFeedReceiptLog(coll, borrowRecord, preStatus)
logs = append(logs, log)
}
// 保存
coll.LatestLiquidationPrice = getLatestLiquidationPrice(coll)
coll.LatestExpireTime = getLatestExpireTime(coll)
collDB.Save(action.db)
kv = append(kv, collDB.GetKVSet()...)
......@@ -760,6 +838,7 @@ func (action *Action) CollateralizeFeed(feed *pty.CollateralizeFeed) (*types.Rec
return nil, types.ErrInvalidParam
}
// 是否后台管理用户
if !isRightPriceFeed(action.fromaddr, action.db) {
clog.Error("CollateralizePriceFeed", "addr", action.fromaddr, "error", "Address has no permission to feed price")
return nil, pty.ErrPriceFeedPermissionDeny
......@@ -784,7 +863,8 @@ func (action *Action) CollateralizeFeed(feed *pty.CollateralizeFeed) (*types.Rec
continue
}
if coll.LatestLiquidationPrice >= price {
// 系统清算判断
if coll.LatestLiquidationPrice * PriceWarningRate >= price {
receipt, err := action.systemLiquidation(coll, price)
if err != nil {
clog.Error("CollateralizePriceFeed", "Collateralize ID", coll.CollateralizeId, "system liquidation error", err)
......@@ -793,6 +873,17 @@ func (action *Action) CollateralizeFeed(feed *pty.CollateralizeFeed) (*types.Rec
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
}
// 超时清算判断
if coll.LatestExpireTime - ExpireWarningTime <= action.blocktime {
receipt, err := action.expireLiquidation(coll)
if err != nil {
clog.Error("CollateralizePriceFeed", "Collateralize ID", coll.CollateralizeId, "expire liquidation error", err)
continue
}
logs = append(logs, receipt.Logs...)
kv = append(kv, receipt.KV...)
}
}
var priceRecord pty.AssetPriceRecord
......
......@@ -21,7 +21,6 @@ func (c *Collateralize) Query_CollateralizeInfoByID(req *pty.ReqCollateralizeInf
TotalBalance: coll.TotalBalance,
DebtCeiling: coll.DebtCeiling,
LiquidationRatio: coll.LiquidationRatio,
LiquidationPenalty: coll.LiquidationPenalty,
StabilityFee: coll.StabilityFee,
CreateAddr: coll.CreateAddr,
Balance: coll.Balance,
......@@ -42,7 +41,6 @@ func (c *Collateralize) Query_CollateralizeInfoByIDs(req *pty.ReqCollateralizeIn
TotalBalance: coll.TotalBalance,
DebtCeiling: coll.DebtCeiling,
LiquidationRatio: coll.LiquidationRatio,
LiquidationPenalty: coll.LiquidationPenalty,
StabilityFee: coll.StabilityFee,
CreateAddr: coll.CreateAddr,
Balance: coll.Balance,
......@@ -89,6 +87,7 @@ func (c *Collateralize) Query_CollateralizeBorrowInfoByAddr(req *pty.ReqCollater
return nil, err
}
ret := &pty.RepCollateralizeBorrowInfos{}
for _, record := range records {
if record.CollateralizeId == req.CollateralizeId {
coll, err := queryCollateralizeByID(c.GetStateDB(), record.CollateralizeId)
......@@ -99,9 +98,13 @@ func (c *Collateralize) Query_CollateralizeBorrowInfoByAddr(req *pty.ReqCollater
for _, borrowRecord := range coll.BorrowRecords {
if borrowRecord.AccountAddr == req.Addr {
ret := &pty.RepCollateralizeBorrowInfo{}
ret.Record = borrowRecord
return ret, nil
ret.Record = append(ret.Record, borrowRecord)
}
}
for _, borrowRecord := range coll.InvalidRecords {
if borrowRecord.AccountAddr == req.Addr {
ret.Record = append(ret.Record, borrowRecord)
}
}
}
......@@ -130,6 +133,12 @@ func (c *Collateralize) Query_CollateralizeBorrowInfoByStatus(req *pty.ReqCollat
ret.Record = append(ret.Record, borrowRecord)
}
}
for _, borrowRecord := range coll.InvalidRecords {
if borrowRecord.Status == req.Status {
ret.Record = append(ret.Record, borrowRecord)
}
}
}
return ret, nil
......
......@@ -9,13 +9,15 @@ message Collateralize {
int64 debtCeiling = 3; //单用户可借出的限额(ccny)
float liquidationRatio = 4; //清算比例
int64 stabilityFee = 5; //稳定费
int64 liquidationPenalty = 6; //清算罚金
string createAddr = 7; //创建人地址
int64 balance = 8; //剩余可借贷金额(ccny)
repeated BorrowRecord borrowRecords = 9; //借贷记录
string createAddr = 6; //创建人地址
int64 balance = 7; //剩余可借贷金额(ccny)
repeated BorrowRecord borrowRecords = 8; //借贷记录
repeated BorrowRecord InvalidRecords = 9; //失效的借贷记录
int32 status = 10;//当期借贷的状态,是否关闭
int32 collType = 11;//质押资产类型(1,bty,2,btc,3,eth...)
float latestLiquidationPrice = 12;//最大清算价格
float latestLiquidationPrice = 12;//最高清算价格
int64 period = 13;//借贷最大期限
int64 latestExpireTime = 14;//最近超期时间
}
// 借出记录
......@@ -28,6 +30,7 @@ message BorrowRecord {
float liquidationPrice = 6; //抵押物清算价格
int32 status = 7; //抵押状态,是否被清算
int64 liquidateTime = 8; //清算时间
int64 expireTime = 9; //超时清算时间
}
// 资产价格记录
......@@ -57,8 +60,7 @@ message CollateralizeCreate {
int64 debtCeiling = 1; //单用户可借出的限额(ccny)
float liquidationRatio = 2; //清算比例
int64 stabilityFee = 3; //稳定费
int64 liquidationPenalty = 4; //清算罚金
int64 totalBalance = 5; //可借贷总金额
int64 totalBalance = 4; //可借贷总金额
}
// 质押借出
......@@ -162,11 +164,6 @@ message ReqCollateralizeBorrowInfoByAddr {
string addr = 2;
}
// 返回借贷记录
message RepCollateralizeBorrowInfo {
BorrowRecord record = 1;
}
// 根据状态和借贷ID混合查询具体借贷记录
message ReqCollateralizeBorrowInfoByStatus {
string collateralizeId = 1;
......
......@@ -137,7 +137,6 @@ func CreateRawCollateralizeCreateTx(parm *CollateralizeCreateTx) (*types.Transac
DebtCeiling: parm.DebtCeiling,
LiquidationRatio: parm.LiquidationRatio,
StabilityFee: parm.StabilityFee,
LiquidationPenalty: parm.LiquidationPenalty,
TotalBalance: parm.TotalBalance,
}
create := &CollateralizeAction{
......
......@@ -9,7 +9,6 @@ type CollateralizeCreateTx struct {
DebtCeiling int64 `json:"debtCeiling"`
LiquidationRatio float32 `json:"liquidationRatio"`
StabilityFee int64 `json:"stabilityFee"`
LiquidationPenalty int64 `json:"liquidationPenalty"`
TotalBalance int64 `json:"totalBalance"`
Fee int64 `json:"fee"`
}
......@@ -37,7 +36,7 @@ type CollateralizeAppendTx struct {
// CollateralizeFeedTx for construction
type CollateralizeFeedTx struct {
Price []int64 `json:"price"`
Price []float32 `json:"price"`
Volume []int64 `json:"volume"`
Fee int64 `json:"fee"`
}
......
......@@ -45,5 +45,6 @@ const (
CollateralizeUserStatusCreate = 1 + iota
CollateralizeUserStatusWarning
CollateralizeUserStatusSystemLiquidate
CollateralizeUserStatusExpire
CollateralizeUserStatusClose
)
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment