Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is not following the SafeERC20 rule. #20

Open
hats-bug-reporter bot opened this issue Nov 19, 2024 · 1 comment
Open

Is not following the SafeERC20 rule. #20

hats-bug-reporter bot opened this issue Nov 19, 2024 · 1 comment
Labels
bug Something isn't working invalid This doesn't seem right

Comments

@hats-bug-reporter
Copy link

Github username: --
Twitter username: --
Submission hash (on-chain): 0xf06a90d82ba79b0685abde5ac113a18355390a4d170c2bb137f29688d81ea7b3
Severity: high

Description:

Description

The Router.sol contract does not implementing the SafeERC20::forceApprove() correctly. As per the SafeERC20::forceApprove() natspec the dev must need to set the allowance to 0 before using forceApprove(), see it here:

Meant to be used with tokens that require the approval
to be set to zero before setting it to a non-zero value, such as USDT

So if USDT is used as token here so the approval should be set to 0 before applying the forceApprove.

Affected code

if (allowance < repayAmount) {
            // Approve the lender to pull the funds if needed
            IERC20(_token).forceApprove(msg.sender, repayAmount);
}

PoC

if (allowance < repayAmount) {
// Approve the lender to pull the funds if needed
IERC20(_token).forceApprove(msg.sender, repayAmount);
}

@hats-bug-reporter hats-bug-reporter bot added the bug Something isn't working label Nov 19, 2024
@yanisepfl yanisepfl added the invalid This doesn't seem right label Nov 20, 2024
@yanisepfl
Copy link
Collaborator

Hello,

We classified this issue as Invalid.

Indeed, the SafeERC20::forceApprove() function is explicitly designed to handle tokens like USDT that require the allowance to be reset to zero before setting it to a new value. Its implementation ensures that the intermediate step of setting the allowance to zero is automatically handled. Thus, developers do not need to manually set the allowance to zero when using forceApprove().

When forceApprove() is invoked, it does the following:

  • Checks the current allowance.
  • If the allowance is not equal to the desired amount, it first sets the allowance to zero (if required by the token logic).
  • Then, it sets the allowance to the desired non-zero value.

This behavior satisfies the requirements of tokens like USDT without requiring additional manual intervention from the us.

The NatSpec comment in SafeERC20::forceApprove() was misunderstood by the reporter. Indeed, it explains the purpose of the method but does not imply that we need to explicitly call approve(0) before using forceApprove(). The method encapsulates this behavior internally.

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working invalid This doesn't seem right
Projects
None yet
Development

No branches or pull requests

1 participant