Skip to content

Commit

Permalink
refactor: calculations
Browse files Browse the repository at this point in the history
  • Loading branch information
harsh-98 committed Oct 25, 2023
1 parent 17c193e commit 9d89bc0
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 70 deletions.
47 changes: 38 additions & 9 deletions calc/account_fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,33 @@ type TokenDetailsForCalcI interface {
GetLiqThreshold(ts uint64, cm, token string) *big.Int
}

type DebtDetails struct {
total *big.Int
interest *big.Int
borrowedAmount *big.Int
}

func NewDebtDetails(total, interest, borrowedAmount *big.Int) *DebtDetails {
return &DebtDetails{
total: total,
interest: interest,
borrowedAmount: borrowedAmount,
}
}

func (d DebtDetails) Total() *big.Int {
return d.total
}
func (d DebtDetails) Interest() *big.Int {
return d.interest
}
func (d DebtDetails) BorrowedAmount() *big.Int {
return d.borrowedAmount
}
func (d DebtDetails) BorrowedAmountWithInterest() *big.Int {
return new(big.Int).Add(d.borrowedAmount, d.interest)
}

type AccountForCalcI interface {
GetCM() string
GetBalances() core.DBBalanceFormat
Expand All @@ -30,7 +57,7 @@ type Calculator struct {
func (c Calculator) CalcAccountFields(ts uint64, blockNum int64,
poolDetails PoolForCalcI,
account AccountForCalcI, feeInterest uint16,
) (calHF, calBorrowWithInterestAndFees, calTotalValue, calThresholdValue, calBorrowWithInterest *big.Int) {
) (calHF, calTotalValue, calThresholdValue *big.Int, debtDetails *DebtDetails) {
version := account.GetVersion()
if version.Eq(300) {
return c.CalcAccountFieldsv3(ts, blockNum, poolDetails, account, feeInterest)
Expand All @@ -53,9 +80,14 @@ func (c Calculator) CalcAccountFields(ts uint64, blockNum int64,
}
}

calBorrowWithInterest = new(big.Int).Quo(
calBorrowWithInterest := new(big.Int).Quo(
new(big.Int).Mul(poolDetails.GetCumIndexNow(), account.GetBorrowedAmount()),
account.GetCumulativeIndex())
debtDetails = &DebtDetails{
borrowedAmount: account.GetBorrowedAmount(),
total: calBorrowWithInterest,
interest: new(big.Int).Sub(calBorrowWithInterest, account.GetBorrowedAmount()),
}
//
calTotalValue = c.convertFromUSD(calTotalValueInUSD, underlyingToken, version, blockNum)
calThresholdValue = utils.GetInt64(
Expand All @@ -69,18 +101,15 @@ func (c Calculator) CalcAccountFields(ts uint64, blockNum int64,
if version.Eq(1) {
calHF = new(big.Int).Quo(
utils.GetInt64(calThresholdValue, -4),
calBorrowWithInterest,
debtDetails.Total(),
)
// set calBorrowWithInterestAndFees
calBorrowWithInterestAndFees = calBorrowWithInterest
} else if version.Eq(2) {
//https://github.com/Gearbox-protocol/core-v2/blob/da38b329f0c59e4a3dcedc993192bbc849d981f5/contracts/credit/CreditFacade.sol#L1206
interest := new(big.Int).Sub(calBorrowWithInterest, account.GetBorrowedAmount())
fees := utils.PercentMul(interest, big.NewInt(int64(feeInterest)))
calBorrowWithInterestAndFees = new(big.Int).Add(calBorrowWithInterest, fees)
fees := utils.PercentMul(debtDetails.Interest(), big.NewInt(int64(feeInterest)))
debtDetails.total = new(big.Int).Add(debtDetails.total, fees)
calHF = new(big.Int).Quo(
utils.GetInt64(calThresholdValue, -4),
calBorrowWithInterestAndFees,
debtDetails.Total(),
)
}
return
Expand Down
12 changes: 6 additions & 6 deletions calc/account_fields_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func TestCalcFields(t *testing.T) {
utils.ReadJsonAndSetInterface("../inputs/calc_account_fields.json", &input)
// //

calHF, calDebt, calTotalValue, calThresholdValue, _ := Calculator{Store: input.store}.CalcAccountFields(
calHF, calTotalValue, calThresholdValue, calDebtDetails := Calculator{Store: input.store}.CalcAccountFields(
0,
0,
input.PoolDetails,
Expand All @@ -110,8 +110,8 @@ func TestCalcFields(t *testing.T) {
if calHF.Cmp(utils.StringToInt("13225")) != 0 {
t.Fatalf("calculated HF(%d) is wrong", calHF)
}
if calDebt.Cmp(utils.StringToInt("8319356395")) != 0 {
t.Fatalf("calculated borrowedamount + interest(%d) is wrong", calDebt)
if calDebtDetails.Total().Cmp(utils.StringToInt("8319356395")) != 0 {
t.Fatalf("calculated borrowedamount + interest(%d) is wrong", calDebtDetails.Total())
}
if calTotalValue.Cmp(utils.StringToInt("12944049438")) != 0 {
t.Fatalf("calculated totalvalue(%d) is wrong", calTotalValue)
Expand All @@ -129,7 +129,7 @@ func TestCalcFieldsWithFeeInterest(t *testing.T) {
utils.ReadJsonAndSetInterface("../inputs/calc_account_fields_v2.json", &input)
// //

calHF, calDebt, calTotalValue, calThresholdValue, _ := Calculator{Store: input.store}.CalcAccountFields(
calHF, calTotalValue, calThresholdValue, calDebtDetails := Calculator{Store: input.store}.CalcAccountFields(
0,
0,
//
Expand All @@ -141,8 +141,8 @@ func TestCalcFieldsWithFeeInterest(t *testing.T) {
if calHF.Cmp(utils.StringToInt("2725195")) != 0 {
t.Fatalf("calculated HF(%d) is wrong", calHF)
}
if calDebt.Cmp(utils.StringToInt("5000008908519365762")) != 0 {
t.Fatalf("calculated borrowedamount + interest(%d) is wrong", calDebt)
if calDebtDetails.Total().Cmp(utils.StringToInt("5000008908519365762")) != 0 {
t.Fatalf("calculated borrowedamount + interest(%d) is wrong", calDebtDetails.Total())
}
if calTotalValue.Cmp(utils.StringToInt("1651636475399519415042")) != 0 {
t.Fatalf("calculated totalvalue(%d) is wrong", calTotalValue)
Expand Down
17 changes: 9 additions & 8 deletions calc/account_fields_v3.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ func GetbaseInterest(poolCumIndexNow *big.Int, session AccountForCalcI) *big.Int
// - whenever there is updateQuota, cumulative quota intereest and fees are stored in creditManager and cumulativeQuotaIndex for account is updated.
// cumulative quota interest and quotafees increase on every updateQuota and decrase on decrease debt.

func (c Calculator) CalcAccountFieldsv3(ts uint64, blockNum int64, poolDetails PoolForCalcI, session AccountForCalcI, feeInterest uint16) (calHF, calBorrowWithInterestAndFees, calTotalValue, calThresholdValue, calBorrowWithInterest *big.Int) {
func (c Calculator) CalcAccountFieldsv3(ts uint64, blockNum int64, poolDetails PoolForCalcI, session AccountForCalcI, feeInterest uint16) (calHF, calTotalValue, calThresholdValue *big.Int, debtDetails *DebtDetails) {
version := core.NewVersion(300)
accruedFees, accruedInterest, borrowedAmount := c.getDebt(ts, poolDetails, session, feeInterest)
debtDetails = c.getDebtDetails(ts, poolDetails, session, feeInterest)

underlying := poolDetails.GetUnderlying()
// quotaedTokens := poolQuotaDetails.GetPoolQuotaDetails(underlying)
Expand Down Expand Up @@ -69,11 +69,8 @@ func (c Calculator) CalcAccountFieldsv3(ts uint64, blockNum int64, poolDetails P
//
calTotalValue = c.convertFromUSD(totalValueInUSD, underlying, version, blockNum)
calThresholdValue = c.convertFromUSD(tvwValueInUSD, underlying, version, blockNum)
// calBorrowWithInterestAndFees := totalDebt
calBorrowWithInterest = new(big.Int).Add(borrowedAmount, accruedInterest)
calBorrowWithInterestAndFees = new(big.Int).Add(calBorrowWithInterest, accruedFees)

calHF = new(big.Int).Quo(utils.GetInt64(calThresholdValue, -4), calBorrowWithInterestAndFees)
calHF = new(big.Int).Quo(utils.GetInt64(calThresholdValue, -4), debtDetails.Total())
return
}

Expand All @@ -85,7 +82,7 @@ func minBigInt(a, b *big.Int) *big.Int {
}
}

func (c Calculator) getDebt(ts uint64, poolDetails PoolForCalcI, session AccountForCalcI, feeInterest uint16) (*big.Int, *big.Int, *big.Int) {
func (c Calculator) getDebtDetails(ts uint64, poolDetails PoolForCalcI, session AccountForCalcI, feeInterest uint16) *DebtDetails {
borrowedAmount := session.GetBorrowedAmount()
baseInterestSinceUpdate := GetbaseInterest(poolDetails.GetCumIndexNow(), session)

Expand All @@ -105,7 +102,11 @@ func (c Calculator) getDebt(ts uint64, poolDetails PoolForCalcI, session Account

accruedInterest := new(big.Int).Add(cumQuotaInterest, totalNewInterest)

return accruedFees, accruedInterest, borrowedAmount
return &DebtDetails{
total: utils.BigIntAdd3(accruedFees, accruedInterest, borrowedAmount),
interest: accruedInterest,
borrowedAmount: borrowedAmount,
}
}

func calcExtraQuotaInterest(ts uint64, poolQuotas map[string]*schemas_v3.QuotaDetails, session AccountForCalcI) *big.Int {
Expand Down
24 changes: 11 additions & 13 deletions calc/close_amount.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ import (
"github.com/Gearbox-protocol/sdk-go/utils"
)

func CalCloseAmount(params *schemas.Parameters, version core.VersionType, totalValue *big.Int, closureStatus int, borrowedAmountWithInterest, borrowedAmount *big.Int) (amountToPool, remainingFunds, profit, loss *big.Int) {
func CalCloseAmount(params *schemas.Parameters, version core.VersionType, totalValue *big.Int, closureStatus int, debtDetails *DebtDetails) (amountToPool, remainingFunds, profit, loss *big.Int) {
if version.Eq(1) {
return calCloseAmountV1(params, totalValue, schemas.IsStatusLiquidated(closureStatus), borrowedAmountWithInterest, borrowedAmount)
} else if version.Eq(2) {
amountToPool, remainingFunds, profit, loss = calCloseAmountV2(params, totalValue, closureStatus, borrowedAmountWithInterest, borrowedAmount)
return calCloseAmountV1(params, totalValue, schemas.IsStatusLiquidated(closureStatus), debtDetails)
} else if version.Eq(2) || version.Eq(300) {
amountToPool, remainingFunds, profit, loss = calCloseAmountV2(params, totalValue, closureStatus, debtDetails)
}
return
}

func calCloseAmountV1(params *schemas.Parameters, totalValue *big.Int, isLiquidated bool, borrowedAmountWithInterest, borrowedAmount *big.Int) (amountToPool, remainingFunds, profit, loss *big.Int) {
func calCloseAmountV1(params *schemas.Parameters, totalValue *big.Int, isLiquidated bool, debtDetails *DebtDetails) (amountToPool, remainingFunds, profit, loss *big.Int) {
loss = big.NewInt(0)
profit = big.NewInt(0)
remainingFunds = new(big.Int)
Expand All @@ -27,6 +27,7 @@ func calCloseAmountV1(params *schemas.Parameters, totalValue *big.Int, isLiquida
} else {
totalFunds = totalValue
}
borrowedAmountWithInterest := debtDetails.BorrowedAmountWithInterest()
// borrow amt is greater than total funds
if totalFunds.Cmp(borrowedAmountWithInterest) < 0 {
amountToPool = new(big.Int).Sub(totalFunds, big.NewInt(1))
Expand All @@ -36,7 +37,7 @@ func calCloseAmountV1(params *schemas.Parameters, totalValue *big.Int, isLiquida
amountToPool = utils.PercentMulByUInt16(totalFunds, params.FeeLiquidation)
amountToPool = new(big.Int).Add(borrowedAmountWithInterest, amountToPool)
} else {
interestAmt := new(big.Int).Sub(borrowedAmountWithInterest, borrowedAmount)
interestAmt := debtDetails.Interest()
fee := utils.PercentMulByUInt16(interestAmt, params.FeeInterest)
amountToPool = new(big.Int).Add(borrowedAmountWithInterest, fee)
}
Expand All @@ -53,16 +54,12 @@ func calCloseAmountV1(params *schemas.Parameters, totalValue *big.Int, isLiquida
}

// https://github.com/Gearbox-protocol/core-v2/blob/da38b329f0c59e4a3dcedc993192bbc849d981f5/contracts/credit/CreditManager.sol#L1238
func calCloseAmountV2(params *schemas.Parameters, totalValue *big.Int, closureStatus int, borrowedAmountWithInterest, borrowedAmount *big.Int) (amountToPool, remainingFunds, profit, loss *big.Int) {
func calCloseAmountV2(params *schemas.Parameters, totalValue *big.Int, closureStatus int, debtDetails *DebtDetails) (amountToPool, remainingFunds, profit, loss *big.Int) {
loss = big.NewInt(0)
profit = big.NewInt(0)
remainingFunds = new(big.Int)

amountToPool = utils.PercentMulByUInt16(
new(big.Int).Sub(borrowedAmountWithInterest, borrowedAmount),
params.FeeInterest,
)
amountToPool = new(big.Int).Add(amountToPool, borrowedAmountWithInterest)
amountToPool = debtDetails.Total()

if schemas.IsStatusLiquidated(closureStatus) {
var totalFunds *big.Int
Expand All @@ -89,13 +86,14 @@ func calCloseAmountV2(params *schemas.Parameters, totalValue *big.Int, closureSt
amountToPool = totalFunds
}

borrowedAmountWithInterest := debtDetails.BorrowedAmountWithInterest()
if totalFunds.Cmp(borrowedAmountWithInterest) >= 0 {
profit = new(big.Int).Sub(amountToPool, borrowedAmountWithInterest)
} else {
loss = new(big.Int).Sub(borrowedAmountWithInterest, amountToPool)
}
} else {
profit = new(big.Int).Sub(amountToPool, borrowedAmountWithInterest)
profit = new(big.Int).Sub(amountToPool, debtDetails.BorrowedAmountWithInterest())
// reminaingFunds is totalValue - debt
remainingFunds = new(big.Int).Sub(totalValue, amountToPool)
}
Expand Down
7 changes: 5 additions & 2 deletions calc/close_amount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ func TestCalcCloseAmount(t *testing.T) {
core.NewVersion(2),
utils.StringToInt("2003445408514560318103"),
schemas.Liquidated,
utils.StringToInt("2000036753743938235"),
utils.StringToInt("1999999990917566710"),
&DebtDetails{
total: utils.StringToInt("2000037121372201950"),
interest: utils.StringToInt("36762826371525"),
borrowedAmount: utils.StringToInt("1999999990917566710"),
},
)
expectedAmounToPool := utils.StringToInt("42068945291663408312")
expectedRemainingFunds := utils.StringToInt("1861204192797168893884")
Expand Down
9 changes: 4 additions & 5 deletions core/schemas/debt.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import (
type CommonDebtFields struct {
BlockNumber int64 `gorm:"column:block_num" json:"blockNum"`
//
CalHealthFactor *core.BigInt `gorm:"column:cal_health_factor" json:"calHealthFactor"`
CalTotalValueBI *core.BigInt `gorm:"column:cal_total_value_bi" json:"calTotalValue"`
CalDebtBI *core.BigInt `gorm:"column:cal_borrowed_amt_with_interest_bi" json:"calBorrowedAmountPlusInterest"`
CalBorrowedWithInterestBI *core.BigInt `gorm:"-" json:"-"`
CalThresholdValueBI *core.BigInt `gorm:"column:cal_threshold_value_bi" json:"calThresholdValue"`
CalHealthFactor *core.BigInt `gorm:"column:cal_health_factor" json:"calHealthFactor"`
CalTotalValueBI *core.BigInt `gorm:"column:cal_total_value_bi" json:"calTotalValue"`
CalDebtBI *core.BigInt `gorm:"column:cal_borrowed_amt_with_interest_bi" json:"calBorrowedAmountPlusInterest"`
CalThresholdValueBI *core.BigInt `gorm:"column:cal_threshold_value_bi" json:"calThresholdValue"`
// these usd fields uses price at block collateral was updated, so collateralInUSD doesn't change if there is no change in collateral but change in price of collateral assets. As a result, profitInUSD too might not change.
ProfitInUSD float64 `gorm:"column:profit_usd" json:"profitUSD"`
CollateralInUSD float64 `gorm:"column:collateral_usd" json:"collateralUSD"`
Expand Down
14 changes: 7 additions & 7 deletions pkg/dc/dc_calls.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ type CMCallData struct {
}

type CreditAccountCallData struct {
Addr common.Address `json:"address"`
Borrower common.Address `json:"borrower"`
CreditManager common.Address `json:"creditManager"`
Underlying common.Address `json:"underlyingToken"`
BorrowedAmount *core.BigInt `json:"borrowedAmount"` // DC_CHANGED
BorrowedAmountPlusInterest *core.BigInt `json:"borrowedAmountPlusInterest"`
Addr common.Address `json:"address"`
Borrower common.Address `json:"borrower"`
CreditManager common.Address `json:"creditManager"`
Underlying common.Address `json:"underlyingToken"`
BorrowedAmount *core.BigInt `json:"borrowedAmount"` // DC_CHANGED
Debt *core.BigInt `json:"debt"`
// TODO:"totalBorrowedWithInterst" is removed
CumulativeIndexAtOpen *core.BigInt `json:"cumulativeIndexAtOpen"`
CumulativeQuotaInterest *core.BigInt `json:"cumulativeQuotaInterest,omitempty"`
Expand All @@ -111,7 +111,7 @@ type QuotaFeeCalc struct {
}

func (data QuotaFeeCalc) GetQuotaFees(feeInterest uint16) *big.Int {
if !data.Version.Eq(3) {
if !data.Version.Eq(300) {
return new(big.Int)
}
interestFees := new(big.Int).Quo(
Expand Down
13 changes: 8 additions & 5 deletions pkg/dc/dcv1.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,20 @@ func getCreditAccountDatav1(client core.ClientI, cfAddrv1 common.Address, blockN
Underlying: data.UnderlyingToken,
// CreditFacade
// Underlying
BorrowedAmount: (*core.BigInt)(data.BorrowedAmount),
BorrowedAmountPlusInterest: (*core.BigInt)(data.BorrowedAmountPlusInterest),
BorrowedAmount: (*core.BigInt)(data.BorrowedAmount),
Debt: (*core.BigInt)(data.BorrowedAmountPlusInterest),
//: data.BorrowedAmountPlusInterest,
CumulativeIndexAtOpen: (*core.BigInt)(data.CumulativeIndexAtOpen),
// CumulativeIndexLastUpdate: nil,
CumulativeQuotaInterest: new(core.BigInt), // D_BY_US
//
QuotaFeeCalc: QuotaFeeCalc{
AccruedInterest: (*core.BigInt)(new(big.Int)),
AccruedFees: (*core.BigInt)(new(big.Int)),
Version: core.NewVersion(1),
AccruedInterest: (*core.BigInt)(new(big.Int).Sub(
data.BorrowedAmountPlusInterest,
data.BorrowedAmount,
)),
AccruedFees: (*core.BigInt)(new(big.Int)),
Version: core.NewVersion(1),
},
// TotalDebtUSD
TotalValue: (*core.BigInt)(data.TotalValue),
Expand Down
24 changes: 15 additions & 9 deletions pkg/dc/dcv2.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,26 @@ func getCMDatav2(values dcv2.CreditManagerData) CMCallData {
}
func getAccountDatav2(values dcv2.CreditAccountData) CreditAccountCallData {
return CreditAccountCallData{
Addr: values.Addr,
Borrower: values.Borrower,
CreditManager: values.CreditManager,
Underlying: values.Underlying,
BorrowedAmount: (*core.BigInt)(values.BorrowedAmount),
BorrowedAmountPlusInterest: (*core.BigInt)(values.BorrowedAmountPlusInterest),
Addr: values.Addr,
Borrower: values.Borrower,
CreditManager: values.CreditManager,
Underlying: values.Underlying,
BorrowedAmount: (*core.BigInt)(values.BorrowedAmount),
Debt: (*core.BigInt)(values.BorrowedAmountPlusInterestAndFees),
// (*core.BigInt)(values.BorrowedAmountPlusInterest),
CumulativeIndexAtOpen: (*core.BigInt)(values.CumulativeIndexAtOpen),
CumulativeQuotaInterest: new(core.BigInt), // D_BY_US
//
QuotaFeeCalc: QuotaFeeCalc{
Version: core.NewVersion(int16(values.Version)),
AccruedInterest: new(core.BigInt),
AccruedFees: new(core.BigInt),
Version: core.NewVersion(int16(values.Version)),
AccruedInterest: (*core.BigInt)(new(big.Int).Sub(
values.BorrowedAmountPlusInterest,
values.BorrowedAmount,
)),
AccruedFees: (*core.BigInt)(new(big.Int).Sub(
values.BorrowedAmountPlusInterestAndFees,
values.BorrowedAmountPlusInterest,
)),
},
//
TotalValue: (*core.BigInt)(values.TotalValue),
Expand Down
13 changes: 7 additions & 6 deletions pkg/dc/dcv3.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package dc
import (
dcv3 "github.com/Gearbox-protocol/sdk-go/artifacts/dataCompressorv3"
"github.com/Gearbox-protocol/sdk-go/core"
"github.com/Gearbox-protocol/sdk-go/utils"
)

func getPoolDatav3(values dcv3.PoolData) PoolCallData {
Expand Down Expand Up @@ -44,12 +45,12 @@ func getCMDatav3(values dcv3.CreditManagerData) CMCallData {
}
func getAccountDatav3(values dcv3.CreditAccountData) CreditAccountCallData {
return CreditAccountCallData{
Addr: values.Addr,
Borrower: values.Borrower,
CreditManager: values.CreditManager,
Underlying: values.Underlying,
BorrowedAmount: (*core.BigInt)(values.Debt),
BorrowedAmountPlusInterest: nil, // DC_CHANGED
Addr: values.Addr,
Borrower: values.Borrower,
CreditManager: values.CreditManager,
Underlying: values.Underlying,
BorrowedAmount: (*core.BigInt)(values.Debt),
Debt: (*core.BigInt)(utils.BigIntAdd3(values.Debt, values.AccruedFees, values.AccruedInterest)), // DC_CHANGED

CumulativeIndexAtOpen: (*core.BigInt)(values.CumulativeIndexLastUpdate),
CumulativeQuotaInterest: (*core.BigInt)(values.CumulativeQuotaInterest),
Expand Down
4 changes: 4 additions & 0 deletions utils/bigint.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,7 @@ func DiffMoreThanFraction(oldValue, newValue *big.Int, diff *big.Float) bool {
func BytesToUInt16(data []byte) uint16 {
return uint16(new(big.Int).SetBytes(data).Int64())
}

func BigIntAdd3(a, b, c *big.Int) *big.Int {
return new(big.Int).Add(a, new(big.Int).Add(b, c))
}

0 comments on commit 9d89bc0

Please sign in to comment.