11package debts
22
33import (
4- "fmt"
54 "math/big"
65 "sort"
76 "time"
@@ -93,11 +92,30 @@ func (eng *DebtEngine) updateLocalState(blockNum int64, block *schemas.Block) (p
9392 eng .AddTokenLTRamp (ltRamp )
9493 }
9594
95+ for _ , to := range block .TokenOracles {
96+ if ! to .Reserve { // only main
97+ eng .priceHandler .AddTokenOracle (to )
98+ }
99+ }
100+ //
101+ for _ , relation := range block .Relations {
102+ if relation .Type == "PoolOracle" {
103+ eng .priceHandler .poolToPriceOracle [relation .Owner ] = schemas .PriceOracleT (relation .Dependent )
104+ }
105+ }
96106 // C3.b: updated price
97107 for _ , pf := range block .GetPriceFeeds () {
98108 // L5
99- eng .AddTokenLastPrice (pf )
100- tokensUpdated [pf .Token ] = true
109+ eng .priceHandler .AddTokenLastPrice (pf )
110+ // TIMECOMPLEX
111+ // use mdl.repo.getsyncadapter(pf.Feed).gettokens(block_num)
112+ for _ , oracles := range eng .priceHandler .poTotokenOracle {
113+ for _ , oracle := range oracles {
114+ if pf .Feed == oracle .Feed {
115+ tokensUpdated [oracle .Token ] = true
116+ }
117+ }
118+ }
101119 }
102120 // updates complete
103121 return poolsUpdated , tokensUpdated , sessionsUpdated
@@ -123,7 +141,7 @@ func (eng *DebtEngine) CalculateDebt() {
123141 cmToPoolDetails := eng .GetCumulativeIndexAndDecimalForCMs (blockNum , block .Timestamp )
124142
125143 //
126- var caTotalValueInUSD float64 = 0
144+ marketToTvl := make ( MarketToTvl )
127145 // check if session's debt needs to be recalculated
128146 for _ , session := range sessions {
129147 if (session .ClosedAt != 0 && session .ClosedAt <= blockNum ) || session .Since > blockNum {
@@ -135,11 +153,23 @@ func (eng *DebtEngine) CalculateDebt() {
135153 }
136154 // #C3
137155 sessionSnapshot := eng .lastCSS [session .ID ]
138- caTotalValueInUSD + = utils .GetFloat64Decimal (
156+ caValue : = utils .GetFloat64Decimal (
139157 eng .GetAmountInUSD (
158+ session .CreditManager ,
140159 cmToPoolDetails [session .CreditManager ].Token ,
141- sessionSnapshot .TotalValueBI .Convert (), schemas . VersionToPFVersion ( session .Version , false ) ,
160+ sessionSnapshot .TotalValueBI .Convert (), session .Version ,
142161 ), 8 )
162+ {
163+ pool := eng .priceHandler .GetPoolFromCM (session .CreditManager )
164+ adapter := eng .repo .GetAdapter (pool )
165+ state := adapter .GetUnderlyingState ()
166+ if state == nil {
167+ log .Fatal ("State for pool not found for address: " , pool )
168+ }
169+ //
170+ market := state .(* schemas.PoolState ).Market
171+ marketToTvl .add (market , caValue , 0 , 0 )
172+ }
143173
144174 for token , tokenBalance := range * sessionSnapshot .Balances {
145175 if tokenBalance .IsEnabled && tokenBalance .HasBalanceMoreThanOne () {
@@ -171,19 +201,17 @@ func (eng *DebtEngine) CalculateDebt() {
171201 }
172202 }
173203 //
174- eng .createTvlSnapshots (blockNum , caTotalValueInUSD )
204+ eng .createTvlSnapshots (blockNum , marketToTvl )
175205 if len (sessionsUpdated ) > 0 {
176206 log .Debugf ("Calculated %d debts for block %d" , len (sessionsUpdated ), blockNum )
177207 }
178208 }
179209}
180210
181- func (eng * DebtEngine ) createTvlSnapshots (blockNum int64 , caTotalValueInUSD float64 ) {
182- if eng .lastTvlSnapshot != nil && blockNum - eng .lastTvlSnapshot .BlockNum < core .BlockPer (core .GetChainId (eng .client ), time .Hour ) { // tvl snapshot every hour
183- return
184- }
185- var totalAvailableLiquidityInUSD , expectedLiqInUSD float64 = 0 , 0
186- log .Info ("tvl for block" , blockNum )
211+ func (eng * DebtEngine ) createTvlSnapshots (blockNum int64 , marketToTvl MarketToTvl ) {
212+ // if eng.lastTvlSnapshot != nil && blockNum-eng.lastTvlSnapshot.BlockNum < core.NoOfBlocksPerHr { // tvl snapshot every hour
213+ // return
214+ // }
187215 for _ , entry := range eng .poolLastInterestData {
188216 adapter := eng .repo .GetAdapter (entry .Address )
189217 state := adapter .GetUnderlyingState ()
@@ -193,33 +221,41 @@ func (eng *DebtEngine) createTvlSnapshots(blockNum int64, caTotalValueInUSD floa
193221 //
194222 underlyingToken := state .(* schemas.PoolState ).UnderlyingToken
195223 //
196- version := schemas .V1PF
197- if eng .tokenLastPrice [schemas .V2PF ] != nil && eng.tokenLastPrice [schemas.V2PF ][underlyingToken ] != nil {
198- version = schemas .V2PF
224+ latestOracle , version , err := eng .repo .GetActivePriceOracleByBlockNum (blockNum )
225+ log .CheckFatal (err )
226+ //
227+ fn := func (amount * core.BigInt ) float64 {
228+ return utils .GetFloat64Decimal (
229+ eng .GetAmountInUSDByOracle (
230+ latestOracle ,
231+ underlyingToken ,
232+ amount .Convert (), version ), 8 )
199233 }
200- if eng .tokenLastPrice [schemas .V3PF_MAIN ] != nil && eng.tokenLastPrice [schemas.V3PF_MAIN ][underlyingToken ] != nil {
201- version = schemas .V3PF_MAIN
234+ availLiq := fn (entry .AvailableLiquidityBI )
235+ expectedLiqInUSD := fn (entry .ExpectedLiqBI )
236+ marketToTvl .add (state .(* schemas.PoolState ).Market , 0 , availLiq , expectedLiqInUSD )
237+ }
238+ // save as last tvl snapshot and add to db
239+ addedMarket := []string {}
240+ for market , details := range marketToTvl {
241+ if lastTvlBlock , ok := eng .marketTolastTvlBlock [market ]; ok && blockNum - lastTvlBlock < core .BlockPer (core .GetBaseChainId (eng .client ), time .Hour ) { // only snap her hr.
242+ continue
202243 }
203244 //
204- totalAvailableLiquidityInUSD += utils .GetFloat64Decimal (
205- eng .GetAmountInUSD (
206- underlyingToken ,
207- entry .AvailableLiquidityBI .Convert (), version ), 8 )
208- expectedLiqInUSD += utils .GetFloat64Decimal (
209- eng .GetAmountInUSD (
210- underlyingToken ,
211- entry .ExpectedLiqBI .Convert (), version ), 8 )
212-
245+ tvl := & schemas.TvlSnapshots {
246+ BlockNum : blockNum ,
247+ AvailableLiquidity : details .totalAvailableLiquidity ,
248+ CATotalValue : details .caTotalValue ,
249+ ExpectedLiq : details .expectedLiq ,
250+ Market : market ,
251+ }
252+ addedMarket = append (addedMarket , market )
253+ eng .tvlSnapshots = append (eng .tvlSnapshots , tvl )
254+ eng .marketTolastTvlBlock [tvl .Market ] = tvl .BlockNum
213255 }
214- // save as last tvl snapshot and add to db
215- tvls := & schemas.TvlSnapshots {
216- BlockNum : blockNum ,
217- AvailableLiquidity : totalAvailableLiquidityInUSD ,
218- ExpectedLiq : expectedLiqInUSD ,
219- CATotalValue : caTotalValueInUSD ,
256+ if len (addedMarket ) > 0 {
257+ log .Infof ("%d:Tvl snapshot added for market %s" , blockNum , addedMarket )
220258 }
221- eng .tvlSnapshots = append (eng .tvlSnapshots , tvls )
222- eng .lastTvlSnapshot = tvls
223259}
224260
225261func (eng * DebtEngine ) ifAccountLiquidated (sessionId , cmAddr string , closedAt int64 , status int ) {
@@ -291,10 +327,6 @@ func (eng *DebtEngine) GetCumulativeIndexAndDecimalForCMs(blockNum int64, ts uin
291327 return cmToCumIndex
292328}
293329
294- func (eng * DebtEngine ) getTokenPriceFeed (token string , pfVersion schemas.PFVersion ) * schemas.PriceFeed {
295- return eng.tokenLastPrice [pfVersion ][token ]
296- }
297-
298330func (eng * DebtEngine ) SessionDebtHandler (blockNum int64 , session * schemas.CreditSession , cumIndexAndUToken * ds.CumIndexAndUToken ) {
299331 sessionId := session .ID
300332 sessionSnapshot := eng .lastCSS [sessionId ]
@@ -307,14 +339,16 @@ func (eng *DebtEngine) SessionDebtHandler(blockNum int64, session *schemas.Credi
307339 retryFeeds := eng .repo .GetRetryFeedForDebts ()
308340 for tokenAddr , details := range * sessionSnapshot .Balances {
309341 if details .IsEnabled && details .HasBalanceMoreThanOne () {
310- lastPriceEvent := eng .getTokenPriceFeed (tokenAddr , schemas .VersionToPFVersion (session .Version , false )) // don't use reserve
311342 //
312- if tokenAddr != eng .repo .GetWETHAddr () && lastPriceEvent .BlockNumber != blockNum {
313- feedAddr := lastPriceEvent .Feed
314- for _ , retryFeed := range retryFeeds {
315- if retryFeed .GetAddress () == feedAddr {
316- eng .requestPriceFeed (blockNum , retryFeed , tokenAddr , lastPriceEvent .MergedPFVersion )
317-
343+ if tokenAddr != eng .repo .GetWETHAddr () { // REDUNDANT
344+ lastPriceEvent := eng .priceHandler .GetLastPriceFeed (session .CreditManager , tokenAddr , session .Version ) // don't use reserve
345+ if lastPriceEvent .BlockNumber != blockNum {
346+ feedAddr := lastPriceEvent .Feed
347+ for _ , retryFeed := range retryFeeds {
348+ if retryFeed .GetAddress () == feedAddr {
349+ // log.Info("hf ", debt.CalHealthFactor.Convert(), "of", sessionId, "at", blockNum)
350+ eng .priceHandler .requestPriceFeed (blockNum , eng .client , retryFeed , tokenAddr , profile != nil )
351+ }
318352 }
319353 }
320354 }
@@ -400,7 +434,7 @@ func (eng *DebtEngine) CalculateSessionDebt(blockNum int64, session *schemas.Cre
400434 for tokenAddr , details := range * sessionSnapshot .Balances {
401435 if details .IsEnabled {
402436 profile .Tokens [tokenAddr ] = ds.TokenDetails {
403- Price : eng .GetTokenLastPrice ( tokenAddr , schemas . VersionToPFVersion ( session .Version , false ) ), // don't use reserve
437+ Price : eng .priceHandler . GetLastPrice ( session . CreditManager , tokenAddr , session .Version ), // don't use reserve
404438 Decimals : eng .repo .GetToken (tokenAddr ).Decimals ,
405439 TokenLiqThreshold : eng.tokenLTRamp [session.CreditManager ][tokenAddr ].GetLTForTs (eng .currentTs ),
406440 }
@@ -424,12 +458,15 @@ func (eng *DebtEngine) CalculateSessionDebt(blockNum int64, session *schemas.Cre
424458 notMatched = true
425459 }
426460 // even if data compressor matching is disabled check the calc values with session data at block where last credit snapshot was taken
427- } else if sessionSnapshot .BlockNum == blockNum && sessionSnapshot .HealthFactor .Convert ().Cmp (new (big.Int )) != 0 { // it is 0 when the issuccessful is false for redstone credit accounts
461+ // // 20563217 and 0xe8f5F52842D7AF4BbcF5Fe731A336147B51F09D5_19980779_297 on mainnet has creditsessionsnapshot but isSuccessful for dv3 is false.
462+ } else if sessionSnapshot .BlockNum == blockNum && sessionSnapshot .HealthFactor .Convert ().Cmp (new (big.Int )) != 0 &&
463+ ! (utils .Contains ([]int64 {20563217 , 20671148 }, blockNum ) && sessionSnapshot .TotalValueBI .Convert ().Cmp (new (big.Int )) == 0 ) {
464+ // it is 0 when the issuccessful is false for redstone credit accounts
428465 if IsChangeMoreThanFraction (debt .CalTotalValueBI , sessionSnapshot .TotalValueBI , big .NewFloat (0.001 )) ||
429466 // hf value calculated are on different side of 1
430467 core .ValueDifferSideOf10000 (debt .CalHealthFactor , sessionSnapshot .HealthFactor ) ||
431468 // if healhFactor diff by 4 %
432- core .DiffMoreThanFraction (debt .CalHealthFactor , sessionSnapshot .HealthFactor , big .NewFloat (0.04 )) {
469+ core .DiffMoreThanFraction (debt .CalHealthFactor , sessionSnapshot .HealthFactor , big .NewFloat (0.01 )) {
433470 // log.Info(debt.CalHealthFactor, sessionSnapshot.HealthFactor, blockNum)
434471 // log.Info(debt.CalTotalValueBI, sessionSnapshot.TotalValueBI, blockNum)
435472 if log .GetBaseNet (core .GetChainId (eng .client )) == "ARBITRUM" {
@@ -446,11 +483,12 @@ func (eng *DebtEngine) CalculateSessionDebt(blockNum int64, session *schemas.Cre
446483 notMatched = true
447484 }
448485 log .Info (
486+ debt .CalTotalValueBI , sessionSnapshot .TotalValueBI , sessionId ,
449487 IsChangeMoreThanFraction (debt .CalTotalValueBI , sessionSnapshot .TotalValueBI , big .NewFloat (0.001 )),
450488 // hf value calculated are on different side of 1
451489 core .ValueDifferSideOf10000 (debt .CalHealthFactor , sessionSnapshot .HealthFactor ),
452490 // if healhFactor diff by 4 %
453- core .DiffMoreThanFraction (debt .CalHealthFactor , sessionSnapshot .HealthFactor , big .NewFloat (0.04 )),
491+ core .DiffMoreThanFraction (debt .CalHealthFactor , sessionSnapshot .HealthFactor , big .NewFloat (0.01 )),
454492 )
455493 }
456494 }
@@ -467,15 +505,31 @@ func (eng *DebtEngine) CalculateSessionDebt(blockNum int64, session *schemas.Cre
467505}
468506
469507// helper methods
470- func (eng * DebtEngine ) GetAmountInUSD (tokenAddr string , amount * big.Int , pfVersion schemas.PFVersion ) * big.Int {
471- tokenPrice := eng .GetTokenLastPrice (tokenAddr , pfVersion )
508+ func (eng * DebtEngine ) GetAmountInUSDByOracle (priceOracle schemas.PriceOracleT , tokenAddr string , amount * big.Int , version core.VersionType ) * big.Int {
509+ tokenPrice := eng .priceHandler .GetLastPriceFeedByOracle (priceOracle , tokenAddr , version )
510+ tokenDecimals := eng .repo .GetToken (tokenAddr ).Decimals
511+ if version .MoreThan (core .NewVersion (1 )) { // than decimals 8
512+ return utils .GetInt64 (new (big.Int ).Mul (tokenPrice .PriceBI .Convert (), amount ), tokenDecimals )
513+ }
514+ // for v1
515+ usdcAddr := eng .repo .GetUSDCAddr ()
516+ usdcPrice := eng .priceHandler .GetLastPriceFeedByOracle (priceOracle , usdcAddr , version )
517+ usdcDecimals := eng .repo .GetToken (usdcAddr ).Decimals
518+
519+ value := new (big.Int ).Mul (amount , tokenPrice .PriceBI .Convert ())
520+ value = utils .GetInt64 (value , tokenDecimals - usdcDecimals )
521+ value = new (big.Int ).Quo (value , usdcPrice .PriceBI .Convert ())
522+ return new (big.Int ).Mul (value , big .NewInt (100 ))
523+ }
524+ func (eng * DebtEngine ) GetAmountInUSD (cm string , tokenAddr string , amount * big.Int , version core.VersionType ) * big.Int {
525+ tokenPrice := eng .priceHandler .GetLastPrice (cm , tokenAddr , version )
472526 tokenDecimals := eng .repo .GetToken (tokenAddr ).Decimals
473- if pfVersion . Decimals () == 8 {
527+ if version . MoreThan ( core . NewVersion ( 1 )) { // than decimals 8
474528 return utils .GetInt64 (new (big.Int ).Mul (tokenPrice , amount ), tokenDecimals )
475529 }
476530 // for v1
477531 usdcAddr := eng .repo .GetUSDCAddr ()
478- usdcPrice := eng .GetTokenLastPrice ( usdcAddr , pfVersion )
532+ usdcPrice := eng .priceHandler . GetLastPrice ( cm , usdcAddr , version )
479533 usdcDecimals := eng .repo .GetToken (usdcAddr ).Decimals
480534
481535 value := new (big.Int ).Mul (amount , tokenPrice )
@@ -484,21 +538,6 @@ func (eng *DebtEngine) GetAmountInUSD(tokenAddr string, amount *big.Int, pfVersi
484538 return new (big.Int ).Mul (value , big .NewInt (100 ))
485539}
486540
487- func (eng * DebtEngine ) GetTokenLastPrice (addr string , pfVersion schemas.PFVersion , dontFail ... bool ) * big.Int {
488- if pfVersion .ToVersion ().Eq (1 ) && eng .repo .GetWETHAddr () == addr {
489- return core .WETHPrice
490- }
491- if eng.tokenLastPrice [pfVersion ][addr ] != nil {
492- return eng.tokenLastPrice [pfVersion ][addr ].PriceBI .Convert ()
493- }
494- //
495- if len (dontFail ) > 0 && dontFail [0 ] {
496- return nil
497- }
498- log .Fatal (fmt .Sprintf ("Price not found for %s pfversion: %d" , addr , pfVersion ))
499- return nil
500- }
501-
502541func (eng * DebtEngine ) SessionDataFromDC (version core.VersionType , blockNum int64 , cmAddr , borrower , account string ) dc.CreditAccountCallData {
503542 call , resultFn , err := eng .repo .GetDCWrapper ().GetCreditAccountData (version , blockNum ,
504543 common .HexToAddress (cmAddr ),
@@ -518,28 +557,3 @@ func (eng *DebtEngine) SessionDataFromDC(version core.VersionType, blockNum int6
518557 }
519558 return data
520559}
521-
522- func (eng * DebtEngine ) requestPriceFeed (blockNum int64 , retryFeed ds.QueryPriceFeedI , token string , pfVersion schemas.MergedPFVersion ) {
523- // defer func() {
524- // if err:= recover(); err != nil {
525- // log.Warn("err", err, "in getting yearn price feed in debt", feed, token, blockNum, pfVersion)
526- // }
527- // }()
528- // PFFIX
529- calls , isQueryable := retryFeed .GetCalls (blockNum )
530- if ! isQueryable {
531- return
532- }
533- log .Info ("getting price for " , token , "at" , blockNum )
534- results := core .MakeMultiCall (eng .client , blockNum , false , calls )
535- price := retryFeed .ProcessResult (blockNum , results , true )
536- eng .AddTokenLastPrice (& schemas.PriceFeed {
537- BlockNumber : blockNum ,
538- Token : token ,
539- Feed : retryFeed .GetAddress (),
540- RoundId : price .RoundId ,
541- PriceBI : price .PriceBI ,
542- Price : price .Price ,
543- MergedPFVersion : pfVersion ,
544- })
545- }
0 commit comments