From e375627e7a14a0099adec1d20620ed8aad9ecb44 Mon Sep 17 00:00:00 2001 From: Oliver Townsend Date: Wed, 15 Jan 2025 16:02:45 -0800 Subject: [PATCH] Add logic to calculate gas deviation based on fitted curve --- .../ocr2/plugins/ccip/ccipcommit/ocr2_test.go | 1 + .../plugins/ccip/internal/ccipcalc/calc.go | 26 +++++++++++++++++++ .../plugins/ccip/prices/da_price_estimator.go | 3 ++- .../ccip/prices/exec_price_estimator.go | 3 ++- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go b/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go index ecc0c56b982..0486a57ea65 100644 --- a/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go +++ b/core/services/ocr2/plugins/ccip/ccipcommit/ocr2_test.go @@ -27,6 +27,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/merklemulti" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/mocks" mocks2 "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" diff --git a/core/services/ocr2/plugins/ccip/internal/ccipcalc/calc.go b/core/services/ocr2/plugins/ccip/internal/ccipcalc/calc.go index 7b503ab12eb..3f91af6238b 100644 --- a/core/services/ocr2/plugins/ccip/internal/ccipcalc/calc.go +++ b/core/services/ocr2/plugins/ccip/internal/ccipcalc/calc.go @@ -1,6 +1,7 @@ package ccipcalc import ( + "math" "math/big" "sort" @@ -64,6 +65,31 @@ func Deviates(x1, x2 *big.Int, ppb int64) bool { return diff.CmpAbs(big.NewInt(ppb)) > 0 // abs(diff) > ppb } +// DeviatesOnGasCurve calculates a deviation threshold on the fly using xNew. For now it's only used for gas price +// deviation calculation. It's important to make sure the order of xNew and xOld is correct when passed into this +// function to get an accurate deviation threshold. +func DeviatesOnGasCurve(xNew, xOld *big.Int, ppb int64) bool { + // If ppb from config is not equal to 4000000000, do not apply the gas curve. This is a temporary gating mechanism + // that ensures we only apply the gas curve deviation logic to eth-bound price updates. + if ppb != 4000000000 { + return Deviates(xOld, xNew, ppb) + } + + xNewFloat := new(big.Float).SetInt(xNew) + xNewFloat64, _ := xNewFloat.Float64() + + // Calculate the deviation threshold percentage with xNew using the formula: y = (5.64e10) / (x^0.654) + const constantFactor = 5.64e10 + const exponent = 0.654 + xNewPower := math.Pow(xNewFloat64, exponent) + threshold := constantFactor / xNewPower + + // Convert percentage to PPB + thresholdPPB := int64(threshold * 1e7) + + return Deviates(xOld, xNew, thresholdPPB) +} + func MergeEpochAndRound(epoch uint32, round uint8) uint64 { return uint64(epoch)<<8 + uint64(round) } diff --git a/core/services/ocr2/plugins/ccip/prices/da_price_estimator.go b/core/services/ocr2/plugins/ccip/prices/da_price_estimator.go index 04002002f5c..5757d6f331f 100644 --- a/core/services/ocr2/plugins/ccip/prices/da_price_estimator.go +++ b/core/services/ocr2/plugins/ccip/prices/da_price_estimator.go @@ -8,6 +8,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipdata" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas/rollups" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" @@ -134,7 +135,7 @@ func (g DAGasPriceEstimator) Deviates(ctx context.Context, p1, p2 *big.Int) (boo return execDeviates, nil } - return ccipcalc.Deviates(p1DAGasPrice, p2DAGasPrice, g.daDeviationPPB), nil + return ccipcalc.DeviatesOnGasCurve(p1DAGasPrice, p2DAGasPrice, g.daDeviationPPB), nil } func (g DAGasPriceEstimator) EstimateMsgCostUSD(ctx context.Context, p *big.Int, wrappedNativePrice *big.Int, msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error) { diff --git a/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go index c6e132e3a75..16307b24440 100644 --- a/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go +++ b/core/services/ocr2/plugins/ccip/prices/exec_price_estimator.go @@ -6,6 +6,7 @@ import ( "math/big" cciptypes "github.com/smartcontractkit/chainlink-common/pkg/types/ccip" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" "github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ccip/internal/ccipcalc" @@ -51,7 +52,7 @@ func (g ExecGasPriceEstimator) Median(ctx context.Context, gasPrices []*big.Int) } func (g ExecGasPriceEstimator) Deviates(ctx context.Context, p1 *big.Int, p2 *big.Int) (bool, error) { - return ccipcalc.Deviates(p1, p2, g.deviationPPB), nil + return ccipcalc.DeviatesOnGasCurve(p1, p2, g.deviationPPB), nil } func (g ExecGasPriceEstimator) EstimateMsgCostUSD(ctx context.Context, p *big.Int, wrappedNativePrice *big.Int, msg cciptypes.EVM2EVMOnRampCCIPSendRequestedWithMeta) (*big.Int, error) {