Tangy Hotpink Monkey
High
The update
function in the Market
contract allows users to manipulate their market positions by providing an unchecked amount
parameter. This lack of validation can lead to significant market imbalances, allowing malicious actors to influence market prices or avoid liquidation, posing a high risk to the contract's integrity and the overall market stability.
Issue: The amount
parameter is not subject to any validation checks, allowing users to input extreme values. This can lead to:
- Market Imbalance: Users can drastically alter their positions, affecting the market's supply-demand equilibrium.
- Price Manipulation: By changing positions significantly, users can influence the market price reported by the oracle.
- Avoiding Liquidation: Users can adjust their positions to avoid liquidation, even when they should be liquidated according to market rules.
function update(
address account,
Fixed6 amount,
Fixed6 collateral,
address referrer
) external nonReentrant whenNotPaused {
(Context memory context, UpdateContext memory updateContext) =
_loadForUpdate(account, address(0), referrer, address(0), UFixed6Lib.ZERO, UFixed6Lib.ZERO);
// create new order & guarantee
Order memory newOrder = OrderLib.from(
context.currentTimestamp,
updateContext.currentPositionLocal,
amount,
collateral,
updateContext.orderReferralFee
);
Guarantee memory newGuarantee; // no guarantee is created for a market order
// process update
@=> _updateAndStore(context, updateContext, newOrder, newGuarantee, referrer, address(0));
}
The unchecked manipulation of positions can lead to severe market imbalances, affecting all participants.
Manual Review
Implement strict validation checks on the amount
parameter to ensure it falls within acceptable limits and does not allow extreme values that could disrupt the market.
function update(
address account,
Fixed6 amount,
Fixed6 collateral,
address referrer
) external nonReentrant whenNotPaused {
// Validate the amount value to ensure it is within an acceptable range.
+ require(amount > MIN_AMOUNT && amount < MAX_AMOUNT, "Invalid amount");
(Context memory context, UpdateContext memory updateContext) =
_loadForUpdate(account, address(0), referrer, address(0), UFixed6Lib.ZERO, UFixed6Lib.ZERO);
// create new order & guarantee
Order memory newOrder = OrderLib.from(
context.currentTimestamp,
updateContext.currentPositionLocal,
amount,
collateral,
updateContext.orderReferralFee
);
Guarantee memory newGuarantee; // no guarantee is created for a market order
// process update
_updateAndStore(context, updateContext, newOrder, newGuarantee, referrer, address(0));
}