Summary
The priceFeedHeartbeatSeconds parameter in MarketConfiguration.sol is not updated, yet it is used in PerpMarket.sol to validate the freshness of price data. This can lead to the use of stale price data or unexpected reverts in the system.
Vulnerability Details
The priceFeedHeartbeatSeconds parameter is not updated within the update function as seen in the following code;
struct Data {
string name;
string symbol;
address priceAdapter;
uint128 initialMarginRateX18;
uint128 maintenanceMarginRateX18;
uint128 maxOpenInterest;
uint128 maxSkew;
uint128 maxFundingVelocity;
uint128 minTradeSizeX18;
uint256 skewScale;
OrderFees.Data orderFees;
uint32 priceFeedHeartbeatSeconds
}
function update(Data storage self, Data memory params) internal {
self.name = params.name;
self.symbol = params.symbol;
self.priceAdapter = params.priceAdapter;
self.initialMarginRateX18 = params.initialMarginRateX18;
self.maintenanceMarginRateX18 = params.maintenanceMarginRateX18;
self.maxOpenInterest = params.maxOpenInterest;
self.maxSkew = params.maxSkew;
self.maxFundingVelocity = params.maxFundingVelocity;
self.minTradeSizeX18 = params.minTradeSizeX18;
self.skewScale = params.skewScale;
self.orderFees = params.orderFees;
}
The unupdated priceFeedHeartbeatSeconds parameter is then called in PerpMarket.getIndexPrice function
Impact
The priceFeedHeartbeatSeconds parameter will not reflect the updated value, leading to potential mismatches between the intended and actual market configurations. This can cause issues in the price feed mechanism, potentially leading to operational disruptions or incorrect market behavior.
Tools Used
Manual Review
Recommendations
Modify the MarketConfiguration.update function to include the priceFeedHeartbeatSeconds parameter as follows
function update(Data storage self, Data memory params) internal {
self.name = params.name;
self.symbol = params.symbol;
self.priceAdapter = params.priceAdapter;
self.initialMarginRateX18 = params.initialMarginRateX18;
self.maintenanceMarginRateX18 = params.maintenanceMarginRateX18;
self.maxOpenInterest = params.maxOpenInterest;
self.maxSkew = params.maxSkew;
self.maxFundingVelocity = params.maxFundingVelocity;
self.minTradeSizeX18 = params.minTradeSizeX18;
self.skewScale = params.skewScale;
self.orderFees = params.orderFees;
+ self.priceFeedHeartbeatSeconds = params.priceFeedHeartbeatSeconds;
}