DOS attack to SwapAction.transferAndSwap() when using an ERC20 permit transferFrom. #205
Labels
2 (Med Risk)
Assets not at direct risk, but function/availability of the protocol could be impacted or leak value
bug
Something isn't working
edited-by-warden
M-14
primary issue
Highest quality submission among a set of duplicates
🤖_primary
AI based primary recommendation
🤖_202_group
AI based duplicate group recommendation
satisfactory
satisfies C4 submission criteria; eligible for awards
selected for report
This submission will be included/highlighted in the audit report
sponsor acknowledged
Technically the issue is correct, but we're not going to resolve it for XYZ reasons
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/code-423n4/2024-07-loopfi/blob/57871f64bdea450c1f04c9a53dc1a78223719164/src/proxy/TransferAction.sol#L65-L77
Vulnerability details
Impact
Detailed description of the impact of this finding.
SwapAction.transferAndSwap()
will perform a_transferFrom
to transfer the input tokens to the user proxy and then perform a swap via a router.When it uses an ERC20 permit
transferFrom
, an attacker can extract thev, r, s
from the safePermit() call and frontruns it with a direct safePermit() with the same arguments. As a result,SwapAction.transferAndSwap()
will fail due to the advancing of nonce. Effectively, this is a DOS attack.Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
First,
SwapAction.transferAndSwap()
will perform a_transferFrom
to transfer the input tokens to the user proxy and then perform a swap via a router.https://github.com/code-423n4/2024-07-loopfi/blob/57871f64bdea450c1f04c9a53dc1a78223719164/src/proxy/SwapAction.sol#L93C14-L103
Second,
_transferFrom
has three cases: permit2, permit or standard transferFrom:https://github.com/code-423n4/2024-07-loopfi/blob/57871f64bdea450c1f04c9a53dc1a78223719164/src/proxy/TransferAction.sol#L46-L82
The vulnerability lies in the second case, there are two parts: 1) call token.safePermit(); 2) call token.safeTransferFrom. The first component will set the proper allowance when successful.
The problem is that an attacker can observe the mempool and extract the
v, r, s
from the safePermit() call and frontruns it with a direct safePermit() with the same arguments. As a result, the _transferFrom and thusSwapAction.transferAndSwap()
will fail due to the advancement of the nonce.This permit DOS attack has been reported by Immunifi earlier: https://www.trust-security.xyz/post/permission-denied
The following POC confirms the finding:
We simulate the front-running by calling USDC.SafePermit() right before the call of
userProxy.execute()
.The result shows we have the right allowance but
SwapAction.transferAndSwap()
fails due to wrong verification of signature since the nonce has increased by 1.run
forge test --match-test testSwapDOS -vv
Tools Used
Foundry
Recommended Mitigation Steps
Change the logic to either there is sufficient allowance or the safePermit succeeds using a try-catch clause:
Assessed type
DoS
The text was updated successfully, but these errors were encountered: