The OrderFacet.cancelOrder function run by ROLE_KEEPER may run into malicious external contracts
Summary
The OrderFacet.createOrderRequest and OrderFacet.cancelOrder functions do not check if the marginToken (passed in by the external user) is valid or supported. This allows a callback into an arbitrary contract at the address marginToken when transferring tokens.
Vulnerability Detail
The marginToken of an Order.OrderInfo object may be any address as the OrderFacet.createOrderRequest does not apply checks on it.
function createOrderRequest(
PlaceOrderParams calldata params
) external payable override nonReentrant {
address account = msg.sender;
if (
params.posSide == Order.PositionSide.INCREASE &&
!params.isCrossMargin
) {
require(
!params.isNativeToken || msg.value == params.orderMargin,
"Deposit native token amount error!"
);
// [Suspicious-1] Do not check if token is a valid ERC20 token.
AssetsProcess.depositToVault(
AssetsProcess.DepositParams(
account,
params.marginToken,
params.orderMargin,
AssetsProcess.DepositFrom.ORDER,
params.isNativeToken
)
);
}
Account.Props storage accountProps = Account.loadOrCreate(account);
OrderProcess.createOrderRequest(accountProps, params, true);
}
When the keeper fails to call executeOrder, it will call cancelOrder to cancel the order and then run into CancelOrderProcess.cancelOrder. In the case that Order.PositionSide.INCREASE == order.posSide && !order.isCrossMargin holds, it will transfer the order.orderMargin amount of order.marginToken back and finally run into the contract at order.marginToken.
The OrderFacet.cancelOrder function run by ROLE_KEEPER may run into malicious external contracts.
At least, it can unexpectedly cost more gas than the executionFee provided by the user (cause loss of profit for the keeper).
link
High
The
OrderFacet.cancelOrder
function run by ROLE_KEEPER may run into malicious external contractsSummary
The
OrderFacet.createOrderRequest
andOrderFacet.cancelOrder
functions do not check if themarginToken
(passed in by the external user) is valid or supported. This allows a callback into an arbitrary contract at the addressmarginToken
when transferring tokens.Vulnerability Detail
The
marginToken
of anOrder.OrderInfo
object may be any address as theOrderFacet.createOrderRequest
does not apply checks on it.When the keeper fails to call
executeOrder
, it will callcancelOrder
to cancel the order and then run intoCancelOrderProcess.cancelOrder
. In the case thatOrder.PositionSide.INCREASE == order.posSide && !order.isCrossMargin
holds, it will transfer theorder.orderMargin
amount oforder.marginToken
back and finally run into the contract atorder.marginToken
.Impact
The
OrderFacet.cancelOrder
function run by ROLE_KEEPER may run into malicious external contracts. At least, it can unexpectedly cost more gas than theexecutionFee
provided by the user (cause loss of profit for the keeper).Code Snippet
Tool used
Manual Review
Recommendation
Check if the
marginToken
(passed in by the external user) is valid or supported inOrderFacet.createOrderRequest
.