Partial trades update open-interest incorrectly
Description
The function registerPartialTrade
is used by _unregisterTrade
to register a partial trade in case the collateral to be withdrawn is less than the initial position of the trade. When this partial trade is registered, the open interest is updated using the function _updateOpenInterestUSDC
in registerPartialTrade
as shown below:
function registerPartialTrade(
address trader,
uint pairIndex,
uint index,
uint _amountReduced
) external override onlyTrading {
Trade storage t = _openTrades[trader][pairIndex][index];
TradeInfo storage i = _openTradesInfo[trader][pairIndex][index];
if (t.leverage == 0) {
return;
}
t.initialPosToken -= _amountReduced;
i.openInterestUSDC -= _amountReduced.mul(t.leverage);
_updateOpenInterestUSDC(trader, pairIndex, i.openInterestUSDC,
false, t.buy, t.openPrice);
}
function _updateOpenInterestUSDC(
address _trader,
uint _pairIndex,
uint _leveragedPosUSDC,
bool _open,
bool _long,
uint _price
) private {
uint index = _long ? 0 : 1;
uint[2] storage o = openInterestUSDC[_pairIndex];
// Fix beacuse of Dust during partial close
if (!_open) _leveragedPosUSDC =
_leveragedPosUSDC > o[index] ? o[index] : _leveragedPosUSDC;
o[index] = _open ?
o[index] + _leveragedPosUSDC : o[index] - _leveragedPosUSDC;
totalOI = _open ?
totalOI + _leveragedPosUSDC : totalOI - _leveragedPosUSDC;
_walletOI[_trader] = _open ?
_walletOI[_trader] + _leveragedPosUSDC :
_walletOI[_trader] - _leveragedPosUSDC;
emit OIUpdated(_open, _long, _pairIndex, _leveragedPosUSDC, _price);
}
Here, the amount of open interest to be reduced should be equal to _amountReduced.mul(t.leverage)
. But the argument passed to _updateOpenInterestUSDC
is i.openInterestUSDC
, which is the original open interest minus the new amount times leverage.
Impact
If the open interest is incorrectly updated, it would lead to incorrect returned values for the loss-protection tier, utilization multiplier, long multiplier, short multiplier, and rollover fees.
Recommendations
We recommend replacing i.openInterestUSDC
with _amountReduced.mul(t.leverage)
in the third parameter of the call to _updateOpenInterestUSDC
.
Remediation
This issue has been acknowledged by Avantis Labs, Inc., and a fix was implemented in commit cfb288e3↗.