44 "context"
55 "database/sql"
66 "fmt"
7- "math"
87 "math/big"
98 "time"
109
@@ -13,6 +12,7 @@ import (
1312 "github.com/gobitfly/beaconchain/pkg/api/services"
1413 t "github.com/gobitfly/beaconchain/pkg/api/types"
1514 "github.com/gobitfly/beaconchain/pkg/commons/cache"
15+ "github.com/gobitfly/beaconchain/pkg/commons/price"
1616 "github.com/gobitfly/beaconchain/pkg/commons/utils"
1717 "github.com/lib/pq"
1818 "github.com/pkg/errors"
@@ -210,10 +210,11 @@ func (d *DataAccessService) getElClAPR(ctx context.Context, dashboardId t.VDBId,
210210 if hours == - 1 { // for all time APR
211211 aprDivisor = 90 * 24
212212 }
213- clAPR = ((float64 (rewardsResultTable .Reward .Int64 ) / float64 (aprDivisor )) / (float64 (32e9 ) * float64 (rewardsResultTable .ValidatorCount ))) * 24.0 * 365.0 * 100.0
214- if math .IsNaN (clAPR ) {
215- clAPR = 0
216- }
213+
214+ // invested amount is not post-pectra safe
215+ investedAmount := d .convertClToMain (decimal .NewFromUint64 (d .config .ClConfig .MaxEffectiveBalance ))
216+
217+ clAPR = calcAPR (d .convertClToMain (decimal .NewFromInt (rewardsResultTable .Reward .Int64 )), investedAmount , aprDivisor , rewardsResultTable .ValidatorCount )
217218
218219 clIncome = decimal .NewFromInt (rewardsResultTable .Reward .Int64 ).Mul (decimal .NewFromInt (1e9 ))
219220
@@ -235,7 +236,7 @@ func (d *DataAccessService) getElClAPR(ctx context.Context, dashboardId t.VDBId,
235236 }
236237
237238 elDs := goqu .Dialect ("postgres" ).
238- Select (goqu .COALESCE (goqu .SUM (goqu .L ("value / 1e18 " )), 0 )).
239+ Select (goqu .COALESCE (goqu .SUM (goqu .L ("value" )), 0 )).
239240 From (goqu .I ("execution_rewards_finalized" ).As ("b" ))
240241
241242 if len (dashboardId .Validators ) > 0 {
@@ -264,11 +265,8 @@ func (d *DataAccessService) getElClAPR(ctx context.Context, dashboardId t.VDBId,
264265 if err != nil {
265266 return decimal .Zero , 0 , decimal .Zero , 0 , err
266267 }
267- elIncomeFloat , _ := elIncome .Float64 () // EL income is in ETH
268- elAPR = ((elIncomeFloat / float64 (aprDivisor )) / (float64 (32 ) * float64 (rewardsResultTable .ValidatorCount ))) * 24.0 * 365.0 * 100.0
269- if math .IsNaN (elAPR ) {
270- elAPR = 0
271- }
268+
269+ elAPR = calcAPR (d .convertElToMain (elIncome ), investedAmount , aprDivisor , rewardsResultTable .ValidatorCount )
272270
273271 if hours == - 1 {
274272 elTotalDs := elDs .
@@ -284,11 +282,30 @@ func (d *DataAccessService) getElClAPR(ctx context.Context, dashboardId t.VDBId,
284282 return decimal .Zero , 0 , decimal .Zero , 0 , err
285283 }
286284 }
287- elIncome = elIncome .Mul (decimal .NewFromInt (1e18 ))
288285
289286 return elIncome , elAPR , clIncome , clAPR , nil
290287}
291288
289+ // precondition: invested amount and rewards are in the same currency
290+ func calcAPR (rewards , investedAmount decimal.Decimal , aprDivisor int , validatorCount uint64 ) float64 {
291+ if rewards .IsZero () || investedAmount .IsZero () || validatorCount == 0 {
292+ return 0
293+ }
294+ return (rewards .Div (decimal .NewFromInt (int64 (aprDivisor ))).Div (investedAmount .Mul (decimal .NewFromInt (int64 (validatorCount )))).Mul (decimal .NewFromInt (24 * 365 * 100 ))).InexactFloat64 ()
295+ }
296+
297+ // converts a cl amount to the main currency
298+ func (d * DataAccessService ) convertClToMain (amount decimal.Decimal ) decimal.Decimal {
299+ price := decimal .NewFromFloat (price .GetPrice (d .config .Frontend .MainCurrency , d .config .Frontend .ClCurrency ))
300+ return amount .Div (decimal .NewFromInt (d .config .Frontend .ClCurrencyDivisor )).Div (price )
301+ }
302+
303+ // converts a el amount to the main currency
304+ func (d * DataAccessService ) convertElToMain (amount decimal.Decimal ) decimal.Decimal {
305+ price := decimal .NewFromFloat (price .GetPrice (d .config .Frontend .MainCurrency , d .config .Frontend .ElCurrency ))
306+ return amount .Div (decimal .NewFromInt (d .config .Frontend .ElCurrencyDivisor )).Div (price )
307+ }
308+
292309type RpOperatorInfo struct {
293310 ValidatorIndex uint64 `db:"validatorindex"`
294311 NodeFee float64 `db:"node_fee"`
0 commit comments