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↗.