You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
looking at the Manager _raiseKeeper Fee function, it uses controller. chargeFee to pull fees from the user's account. If chargeFee fails (e.g., insufficient funds), the entire transaction reverts. But the order is already marked as spent, so the user can't retry. This could lock funds permanently, which is a critical problem.
If _raiseKeeperFee fails (e.g., due to insufficient user funds), the order is marked as isSpent = true, but the fee is not charged. This permanently locks the order, preventing retries.
function executeOrder(...) external {
// ... marks order as spent BEFORE fee handling ...
order.isSpent =true; // ❌ State changed before fee transfer_handleKeeperFee(...); // May revert due to insufficient funds
}
Internal Pre-conditions
No response
External Pre-conditions
No response
Attack Path
Scenario:
User Action: Alice places an order with maxFee = 5 DSU.
Keeper Execution: Bob spends gas to execute the order.
Failure: Alice’s account has only 3 DSU, causing _raiseKeeperFee to revert.
Result: Order is marked isSpent, but Alice cannot retry.
Impact
Funds Locked: Users cannot retry failed orders, losing access to their collateral.
Denial-of-Service: Attackers can exploit this to lock legitimate users’ orders.
PoC
No response
Mitigation
Mark orders as spent after successful fee handling.
Use a temporary state to track execution progress.
The text was updated successfully, but these errors were encountered:
Clean Hemp Barracuda
High
Irreversible Order State on Fee Handling Failure
Summary
looking at the Manager
_raiseKeeper
Fee function, it uses controller. chargeFee to pull fees from the user's account. If chargeFee fails (e.g., insufficient funds), the entire transaction reverts. But the order is already marked as spent, so the user can't retry. This could lock funds permanently, which is a critical problem.If
_raiseKeeperFee
fails (e.g., due to insufficient user funds), the order is marked asisSpent = true
, but the fee is not charged. This permanently locks the order, preventing retries.https://github.com/sherlock-audit/2025-01-perennial-v2-4-update/blob/main/perennial-v2/packages/periphery/contracts/TriggerOrders/Manager.sol#L186
Root Cause
Code Reference:
Internal Pre-conditions
No response
External Pre-conditions
No response
Attack Path
Scenario:
maxFee = 5 DSU
.3 DSU
, causing_raiseKeeperFee
to revert.isSpent
, but Alice cannot retry.Impact
PoC
No response
Mitigation
The text was updated successfully, but these errors were encountered: