Summary
Should ensure order fee and settlement fee rate are unchanged when filling an order.
Vulnerability Details
When an order is being filled, order fee and settlement fee is charged.
ctx.orderFeeUsdX18 = perpMarket.getOrderFeeUsd(sizeDeltaX18, fillPriceX18);
ctx.settlementFeeUsdX18 = ud60x18(uint256(settlementConfiguration.fee));
...
tradingAccount.deductAccountMargin({
feeRecipients: FeeRecipients.Data({
marginCollateralRecipient: globalConfiguration.marginCollateralRecipient,
orderFeeRecipient: globalConfiguration.orderFeeRecipient,
settlementFeeRecipient: globalConfiguration.settlementFeeRecipient
}),
pnlUsdX18: ctx.pnlUsdX18.lt(SD59x18_ZERO) ? ctx.pnlUsdX18.abs().intoUD60x18() : UD60x18_ZERO,
@> orderFeeUsdX18: ctx.orderFeeUsdX18,
@> settlementFeeUsdX18: ctx.settlementFeeUsdX18
});
Even if an order is expected to be filled right after creation, but there still could be a delay and it's possible that order fee and settlement fee are changed by admin before the order is filled, and the fees can be larger than the fees were when the order is created. So the order could be filled with a fee which the traders are not satisfied with.
Impact
Trader can charged of a fee which they are not satisfied with.
Tools Used
Manual Review
Recommendations
Store fee info in MarketOrder, when filling an order, check the current fee against the stored info and revert if fee is increased.
MarketOrder
struct Data {
uint128 marketId;
int128 sizeDelta;
uint128 timestamp;
+ uint80 settlementFee;
+ uint128 makerFee;
+ uint128 takerFee;
}
- function update(Data storage self, uint128 marketId, int128 sizeDelta) internal {
+ function update(Data storage self, uint128 marketId, int128 sizeDelta, uint80 settlementFee, uint128 makerFee, uint128 takerFee) internal {
self.marketId = marketId;
self.sizeDelta = sizeDelta;
self.timestamp = uint128(block.timestamp);
+ self.settlementFee = settlementFee;
+ self.makerFee = makerFee;
+ self.takerFee = takerFee;
}