29111 - [SC - Insight] Silent Failure of ERC Permit Calls in PufferDep...
Submitted on Mar 7th 2024 at 07:55:01 UTC by @cheatcode for Boost | Puffer Finance
Report ID: #29111
Report type: Smart Contract
Report severity: Insight
Target: https://etherscan.io/address/0x7276925e42f9c4054afa2fad80fa79520c453d6a
Impacts:
Contract fails to deliver promised returns, but doesn't lose value
Description
Brief/Intro
The swapAndDepositWithPermit1Inch
and swapAndDepositWithPermit
functions in the PufferDepositor
contract fail to handle errors that may occur during the execution of the ERC20 permit
method. This method is used to obtain approval for token transfers by signing a message, instead of making a separate transaction to call the approve
function.
Vulnerability Details
Steps to Reproduce:
Deploy the
PufferDepositor
contract.Call either the
swapAndDepositWithPermit1Inch
orswapAndDepositWithPermit
function with invalidpermit
data (e.g., expired deadline, signature mismatch, invalid nonce).Observe the contract execution.
Expected Behavior: If the permit
method fails to execute successfully, the contract should revert the transaction and provide an appropriate error message, preventing the swap operation from proceeding without the necessary token allowance.
Actual Behavior: The PufferDepositor
contract wraps the permit
method call in a try-catch
block, silently ignoring any errors that may occur during the execution of permit
. As a result, the function execution continues even if the permit
method fails, potentially leading to the swap function being called without the necessary token allowance being set.
Impact Details
Since the swap functions (like those calling 1Inch or SushiSwap) expect the contract to have permission to spend the user's tokens, the absence of such permission due to a failed permit
call would likely cause the swap to fail.
References
Add any relevant links to documentation or code
Mitigation
The PufferDepositor
contract should handle permit
failures appropriately, preventing the continuation of the function if the permit
operation fails. This can be achieved by either:
Remove
try-catch
:Remove the
try-catch
block around thepermit
call, allowing any exceptions to propagate and revert the transaction if thepermit
is not successful.
Explicit Error Handling:
Maintain the
try-catch
block but add logic in thecatch
block to handle the error appropriately, such as reverting the transaction with a custom error message that explains why the transaction failed.
Recommended Code Change:
Proof of Concept
poc.py
The output will be:
Here's what's happening:
In the "Demonstrating the issue" section, the expired
permit
is ignored, and the swap proceeds without the necessary allowance, leading to a successful but incorrect swap.In the "Demonstrating the fix" section, the fixed functions check if the
permit
was successful by verifying if the allowance was set correctly. If thepermit
failed, the functions raise an exception and prevent the swap from occurring.
This shows the issue where the contract silently ignores permit
failures and allows swaps to proceed without proper allowance, potentially leading to incorrect token transfers. The fix section demonstrates how the proposed solution addresses this issue by explicitly checking the outcome of the permit
operation and reverting the transaction if the permit
failed.
Last updated