Good Entry - Limbooo's results

The best day trading platform to make every trade entry a Good Entry.

General Information

Platform: Code4rena

Start Date: 01/08/2023

Pot Size: $91,500 USDC

Total HM: 14

Participants: 80

Period: 6 days

Judge: gzeon

Total Solo HM: 6

Id: 269

League: ETH

Good Entry

Findings Distribution

Researcher Performance

Rank: 19/80

Findings: 1

Award: $625.44

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: 3docSec

Also found by: DanielArmstrong, Fulum, Krace, Limbooo, T1MOH

Labels

bug
3 (High Risk)
satisfactory
upgraded by judge
duplicate-64

Awards

625.436 USDC - $625.44

External Links

Lines of code

https://github.com/code-423n4/2023-08-goodentry/blob/71c0c0eca8af957202ccdbf5ce2f2a514ffe2e24/contracts/helper/V3Proxy.sol#L160-#L176

Vulnerability details

In "V3Proxy" contract, the swapTokensForExactETH function does not fully refund the unspent tokens back to the user when performing a token-to-ETH swap.

Impact

Users may lose some of their tokens unnecessarily when executing a token-to-ETH swap using the swapTokensForExactETH function. If the actual amount of tokens needed for the swap is less than the provided amountInMax, the excess tokens are not refunded to the user, resulting in an unavoidable loss.

Proof of Concept

To demonstrate the issue, the following steps can be taken:

  1. Call the swapTokensForExactETH function with a larger amountInMax than required for the swap.
  2. Observe that the contract successfully performs the swap and transfers the corresponding amount of ETH to the user.
  3. However, the contract does not refund the excess tokens back to the user, leading to a loss of tokens.
  1. Within the swapTokensForExactETH function, check if the actual amount of tokens needed for the swap (amounts[0]) is less than the provided amountInMax.
  2. If there is a difference between amounts[0] and amountInMax, refund the unspent tokens back to the user using the safeTransfer function of the ERC20 token contract.
function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) payable external returns (uint[] memory amounts) {
    require(path.length == 2, "Direct swap only");
    require(path[1] == ROUTER.WETH9(), "Invalid path");
    ERC20 ogInAsset = ERC20(path[0]);
    ogInAsset.safeTransferFrom(msg.sender, address(this), amountInMax);
    ogInAsset.safeApprove(address(ROUTER), amountInMax);
    amounts = new uint[](2);
    amounts[0] = ROUTER.exactOutputSingle(ISwapRouter.ExactOutputSingleParams(path[0], path[1], feeTier, address(this), deadline, amountOut, amountInMax, 0));
    amounts[1] = amountOut;
+   if (amounts[0] < amountInMax) {
+       uint256 refundAmount = amountInMax - amounts[0];
+       ogInAsset.safeTransfer(msg.sender, refundAmount); // Refund the unspent tokens back to the user
+   }
    ogInAsset.safeApprove(address(ROUTER), 0);
    IWETH9 weth = IWETH9(ROUTER.WETH9());
    acceptPayable = true;
    weth.withdraw(amountOut);
    acceptPayable = false;
    payable(msg.sender).call{value: amountOut}("");
    emit Swap(msg.sender, path[0], path[1], amounts[0], amounts[1]); 
}

Assessed type

Uniswap

#0 - c4-pre-sort

2023-08-09T08:23:06Z

141345 marked the issue as duplicate of #64

#1 - c4-judge

2023-08-20T17:31:48Z

gzeon-c4 changed the severity to 3 (High Risk)

#2 - c4-judge

2023-08-20T17:31:51Z

gzeon-c4 marked the issue as satisfactory

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter