Summary
The getPriceImpactInCollateral
function in VaultReader.sol contains a calculation error that can lead to underflows when calculating position size deltas, potentially causing transaction reverts or incorrect price impact calculations.
Vulnerability Details
function getPriceImpactInCollateral(
bytes32 positionKey,
uint256 sizeDeltaInUsd,
uint256 prevSizeInTokens,
MarketPrices memory prices
) external view returns (int256) {
uint256 expectedSizeInTokensDelta = sizeDeltaInUsd / prices.indexTokenPrice.min;
uint256 curSizeInTokens = getPositionSizeInTokens(positionKey);
uint256 realSizeInTokensDelta = prevSizeInTokens - curSizeInTokens;
int256 priceImpactInTokens = expectedSizeInTokensDelta.toInt256() - realSizeInTokensDelta.toInt256();
return priceImpactInTokens * prices.indexTokenPrice.min.toInt256() / prices.shortTokenPrice.min.toInt256();
}
Problems:
Unsigned arithmetic for realSizeInTokensDelta
calculation
No validation of size parameters
Potential precision loss in division operations
Impact
Severity: Medium
Reasons:
No direct fund loss
Affects price impact calculations
Can cause position operations to fail
Recoverable through contract upgrades
Tools Used
Recommendations
Use signed arithmetic for delta calculations:
function getPriceImpactInCollateral(
bytes32 positionKey,
uint256 sizeDeltaInUsd,
uint256 prevSizeInTokens,
MarketPrices memory prices
) external view returns (int256) {
uint256 expectedSizeInTokensDelta = sizeDeltaInUsd / prices.indexTokenPrice.min;
uint256 curSizeInTokens = getPositionSizeInTokens(positionKey);
int256 realSizeInTokensDelta = int256(prevSizeInTokens) - int256(curSizeInTokens);
int256 expectedDeltaSigned = int256(expectedSizeInTokensDelta);
int256 priceImpactInTokens = expectedDeltaSigned - realSizeInTokensDelta;
require(
prices.indexTokenPrice.min > 0 && prices.shortTokenPrice.min > 0,
"Invalid prices"
);
return priceImpactInTokens *
int256(prices.indexTokenPrice.min) /
int256(prices.shortTokenPrice.min);
}
Add input validation:
modifier validatePrices(MarketPrices memory prices) {
require(prices.indexTokenPrice.min > 0, "Invalid index price");
require(prices.shortTokenPrice.min > 0, "Invalid short price");
_;
}
function getPriceImpactInCollateral(
bytes32 positionKey,
uint256 sizeDeltaInUsd,
uint256 prevSizeInTokens,
MarketPrices memory prices
) external view validatePrices(prices) returns (int256) {
}
Add events for monitoring:
event PriceImpactCalculated(
bytes32 indexed positionKey,
int256 priceImpact,
uint256 prevSize,
uint256 currentSize
);
The recommended changes will:
Prevent arithmetic underflows
Improve calculation accuracy
Add safety checks
Enable better monitoring