TON Pool decreasePerpPosition deletes potentially pending order
Description
Before returning, the TON pool decreasePerpPosition function deletes the order associated with the orderId passed by the caller:
fun decreasePerpPosition(trxId: Int, orderId: Int, opType: Int, account: Address, tokenId: Int, isLong: Bool, marginDelta: Int, sizeDelta: Int, tradePrice: Int, fundingFeeGrowth: Int, rolloverFeeGrowth: Int): Int {
// [...]
accountPerpPosition.positions.set(account, directionPerpPosition);
self.perpPositions.set(tokenId, accountPerpPosition);
self.globalPositions.set(tokenId, globalPosition);
self.globalLPPositions.set(tokenId, globalLPPosition);
self.perpOrders.del(orderId);
send(SendParameters{ to: account, value: payout, mode: SendIgnoreErrors | SendPayGasSeparately});
// [...]
return payout;
}The decreasePerpPosition function of the USDT pool does not perform this operation.
Impact
The difference in behavior does not appear to be intentional. In the version of the codebase under review, there is no impact: the decreasePerpPosition function is called for two reasons:
when executing an order -- in this case, the code of both pools explicitly removes the order after calling
decreasePerpPosition; thedelfunction does not fail if the map does not contain the key being removed, so no error is thrown.when performing auto deleverage -- in this case, the
orderIdgiven todecreasePerpPositionis fictitious, and the map does not actually contain an order with the given ID.
However, this kind of differences in behavior in otherwise identical functions is subtle and could cause bugs to be introduced in future revisions of the code.
Recommendations
We recommend to revise the code so the behavior of the decreasePerpPosition function is uniform for both contracts; alternatively, clearly document the difference in behavior and its rationale.