Dizzy Rusty Osprey
Medium
Anyone can execute user's signed intent via Market.update
, not just the maker who has sent the best price
Summary According to intent specification doc, the user signs the intent with the best price received from the API, and the signature is then relayed to the Maker who provided that price, who then executes the transaction with this signed intent.
The issue is that if any party acquires this signed intent somehow (either listening via open communication channels or listening for mempool, which might be possible even in some L2 networks), it can execute this intent with its own account before the original maker, causing DOS to maker, which can potentially lose funds as it might hedge elsewhere, but the transaction with intent execution will revert due to nonce already used.
Root Cause
market.update
with intent can be called with any maker account, it is not part of the intent:
https://github.com/sherlock-audit/2024-08-perennial-v2-update-3/blob/main/perennial-v2/packages/perennial/contracts/Market.sol#L131
Internal pre-conditions None
External pre-conditions Signed user intent intercepted by the attacker
Attack Path Attacker executes user intent with his own account address
Impact
- Maker who quoted the price, can not execute the transaction with user's signed intent as it reverts. Maker might lose funds since the position is likely already hedged elsewhere in expectation that the transaction executes successfully.
PoC Not needed
Mitigation
Include maker's account in the signed intent (or maybe maker's operator account, so that maker can still choose his own account to apply position to after getting the signed intent). This will allow only the maker and nobody else to execute the intent. Also keep in mind the MultiInvoker
which can also execute intents.