From ef6016eeaa26a0339cb83bf01e29b5bd9a398fee Mon Sep 17 00:00:00 2001 From: Serhat Dolmaci Date: Thu, 18 Jun 2026 23:13:29 +0300 Subject: [PATCH] feat: add configurable minOEVFee to ChainlinkFeedOEVWrapper The updatePriceEarly fee formula (gasprice - basefee) * feeMultiplier produces a negligible amount on L2s like Base and Optimism, regardless of the liquidation value. This means the protocol captures essentially zero OEV for profitable liquidations. Add a minOEVFee storage variable that sets a floor on the fee. Governance can adjust it via setMinOEVFee(). Defaults to 0 for backwards compatibility with existing deployments. --- src/oracles/ChainlinkFeedOEVWrapper.sol | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/oracles/ChainlinkFeedOEVWrapper.sol b/src/oracles/ChainlinkFeedOEVWrapper.sol index e1881e33d..e15ced291 100644 --- a/src/oracles/ChainlinkFeedOEVWrapper.sol +++ b/src/oracles/ChainlinkFeedOEVWrapper.sol @@ -35,6 +35,11 @@ contract ChainlinkFeedOEVWrapper is AggregatorV3Interface, Ownable { /// @param newMaxRoundDelay The new maximum round delay event NewMaxRoundDelay(uint8 oldMaxRoundDelay, uint8 newMaxRoundDelay); + /// @notice Emitted when the minimum OEV fee is changed + /// @param oldFee The old minimum fee + /// @param newFee The new minimum fee + event MinOEVFeeChanged(uint256 oldFee, uint256 newFee); + /// @notice The original Chainlink price feed contract AggregatorV3Interface public immutable originalFeed; @@ -48,6 +53,11 @@ contract ChainlinkFeedOEVWrapper is AggregatorV3Interface, Ownable { /// @dev Represented as a percentage uint8 public feeMultiplier; + /// @notice The minimum fee for an early price update, in wei + /// @dev Prevents zero-cost OEV capture on low-gas chains. Set by owner. + /// A value of 0 means no minimum (backwards compatible). + uint256 public minOEVFee; + /// @notice The maximum number of times to decrement the round before falling back to latest price uint8 public maxDecrements; @@ -201,7 +211,8 @@ contract ChainlinkFeedOEVWrapper is AggregatorV3Interface, Ownable { /// @dev Requires payment of a fee based on gas price and fee multiplier function updatePriceEarly() external payable returns (uint256) { require( - msg.value >= (tx.gasprice - block.basefee) * uint256(feeMultiplier), + msg.value >= (tx.gasprice - block.basefee) * uint256(feeMultiplier) && + msg.value >= minOEVFee, "ChainlinkOEVWrapper: Insufficient tax" ); @@ -256,6 +267,16 @@ contract ChainlinkFeedOEVWrapper is AggregatorV3Interface, Ownable { emit FeeMultiplierChanged(oldMultiplier, newMultiplier); } + /// @notice Set the minimum OEV fee for early price updates + /// @param _minOEVFee The new minimum fee in wei + /// @dev Only callable by the contract owner. Set to 0 to disable minimum. + function setMinOEVFee(uint256 _minOEVFee) external onlyOwner { + uint256 oldFee = minOEVFee; + minOEVFee = _minOEVFee; + + emit MinOEVFeeChanged(oldFee, _minOEVFee); + } + /// @notice Set the maximum number of decrements before falling back to latest price /// @param _maxDecrements The new maximum number of decrements function setMaxDecrements(uint8 _maxDecrements) external onlyOwner {