The MarketConfiguration::update
function does not update the priceFeedHeartbeatSeconds
parameter, making it impossible to obtain the index price of a perpetual market.
The MarketConfiguration::update
function fails to update the priceFeedHeartbeatSeconds
parameter, leaving it set to 0 for all perpetual markets.
When the PerpMarket::getIndexPrice
function is called, it invokes the ChainlinkUtil::getPrice
function with the priceFeedHeartbeatSeconds
parameter set to 0. This will most often cause a revert due to the check block.timestamp - updatedAt > priceFeedHeartbeatSeconds
, which ensures that a stale price is not used for the index price. For this check to pass, block.timestamp - updatedAt == 0
must be true, meaning block.timestamp
must equal updatedAt
.
For this condition to be met, the index price must be retrieved at the exact second it is updated, making it nearly impossible to get the index price of a perpetual market.
This vulnerability causes the PerpMarket::getIndexPrice
function to revert almost every time it is executed, which in turn causes any function that calls it (or calls another function that calls it) to revert as well. This includes:
LiquidationBranch::liquidateAccounts
OrderBranch::simulateTrade
OrderBranch::getMarginRequirementForTrade
TradingAccountBranch::getAccountMarginBreakdown
TradingAccountBranch::getAccountLeverage
TradingAccount::getAccountMarginRequirementUsdAndUnrealizedPnlUsd
TradingAccount::getAccountUnrealizedPnlUsd
LiquidationBranch::checkLiquidatableAccounts
SettlementBranch::fillMarketOrder
TradingAccountBranch::withdrawMargin
Manual Review.
To resolve this issue, update the priceFeedHeartbeatSeconds
parameter in the MarketConfiguration::update
function as follows:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.