The _gtlHook is not triggered when a GTL limit order is fully filled, resulting in inflated GTL totalAssets
Description
When GTL's non--reduce-only limit order is filled, the _gtlHook function should be triggered to update the GTL's orderbookCollateral. However, in the _matchIncomingOrder function within PerpCLOB, _gtlHook is only triggered if the orderRemoved flag is false.
function _matchIncomingOrder(
PerpBook storage ds,
Order storage matchedOrder,
Order memory incomingOrder,
bool amountIsBase // true if incomingOrder is in base, false if in quote
) internal returns (MatchData memory matchData) {
// [...]
bool orderRemoved = matchData.baseDelta == matchedOrder.amount;
if (matchData.baseDelta > 0) {
// [...]
if (unfillable) {
_removeUnfillableOrder(ds, matchedOrder);
return MatchData(0, 0, 0, 0);
} else if (!orderRemoved) {
if (matchedOwner == GTL && !matchedOrder.reduceOnly) {
_gtlHook(-int256(matchData.quoteDelta.fullMulDiv(1e18, matchedOrder.leverage)));
}
// [...]
}
// [...]
}
// [...]
}Consequently, if a GTL limit order is fully filled (which sets orderRemoved to true), _gtlHook is not triggered. This prevents the corresponding decrease in GTL's orderbookCollateral.
Impact
GTL's totalAssets value becomes inflated. This could allow a user to withdraw more assets from GTL than they are entitled to based on their original shares.
Recommendations
We recommend triggering _gtlHook in the _matchIncomingOrder function, regardless of the state of the orderRemoved flag.
Remediation
This issue has been acknowledged by Liquid Labs, Inc., and a fix was implemented in commit 8f495ef1↗.