Platform: Code4rena
Start Date: 01/05/2024
Pot Size: $12,100 USDC
Total HM: 1
Participants: 47
Period: 7 days
Judge: Koolex
Id: 371
League: ETH
Rank: 29/47
Findings: 1
Award: $71.11
๐ Selected for report: 0
๐ Solo Findings: 0
๐ Selected for report: 0xnev
Also found by: 0x04bytes, 0xBugSlayer, 0xJoyBoy03, 0xSecuri, 0xrex, Bigsam, DMoore, Evo, Greed, Kirkeelee, Krace, Pechenite, Rhaydden, SBSecurity, Sajjad, TheFabled, Topmark, XDZIBECX, ZanyBonzy, _karanel, bbl4de, btk, d3e4, gumgumzum, nfmelendez, novamanbg, petarP1998, samuraii77, sandy, shaflow2, sldtyenj12, web3er, y4y, yovchev_yoan
71.1111 USDC - $71.11
The bug can lead to incorrect issuance of lpETH tokens during the claim process, potentially resulting in financial loss or discrepancy for users. If the contract holds any ETH before a swap, the claimedAmount calculation will be incorrect, causing either over-minting or under-minting of lpETH.
the bug is in the assumption that the entire ETH balance of the contract post-swap corresponds to the amount of _token swapped. And The current implementation does not account for any pre-existing ETH balance in the contract. We have The _claim function is designed to allow users to claim their vested lpETH. If the _token is ETH, it calculates claimedAmount based on the user's share of totalLpETH. If the _token is not ETH, it calls _fillQuote to swap the token to ETH and then converts the received ETH to lpETH.
if (_token == ETH) { claimedAmount = userStake.mulDiv(totalLpETH, totalSupply); balances[msg.sender][_token] = 0; lpETH.safeTransfer(_receiver, claimedAmount); } else { uint256 userClaim = userStake * _percentage / 100; _validateData(_token, userClaim, _exchange, _data); balances[msg.sender][_token] = userStake - userClaim; // Swap token to ETH _fillQuote(IERC20(_token), userClaim, _data); // Convert swapped ETH to lpETH (1 to 1 conversion) claimedAmount = address(this).balance; lpETH.deposit{value: claimedAmount}(_receiver); }
The vulnerability Is in this line :
claimedAmount = address(this).balance;
Here in this calculation assumes that the entire ETH balance of the contract after calling _fillQuote is the result of the token swap. This assumption fails if the contract had any pre-existing ETH balance.
The calculation does not isolate the ETH received from the swap but instead uses the total ETH balance of the contract, which can be misleading if there was already ETH in the contract before the swap.
Here is the scenario that I test with:
Scenario Demonstration
Consider the following scenario:
Manual review
the ETH received from the swap should be calculated separately
Other
#0 - c4-judge
2024-05-15T13:36:09Z
koolexcrypto marked the issue as duplicate of #18
#1 - c4-judge
2024-05-15T13:36:20Z
koolexcrypto marked the issue as partial-75
#2 - c4-judge
2024-06-05T07:29:36Z
koolexcrypto changed the severity to 2 (Med Risk)
#3 - c4-judge
2024-06-05T09:37:27Z
koolexcrypto marked the issue as partial-50
#4 - c4-judge
2024-06-05T09:41:00Z
koolexcrypto changed the severity to 3 (High Risk)
#5 - c4-judge
2024-06-05T09:41:25Z
koolexcrypto marked the issue as duplicate of #33
#6 - c4-judge
2024-06-11T07:48:14Z
koolexcrypto marked the issue as partial-25
#7 - c4-judge
2024-06-11T07:50:02Z
koolexcrypto marked the issue as not a duplicate
#8 - c4-judge
2024-06-11T07:50:07Z
koolexcrypto changed the severity to QA (Quality Assurance)
#9 - c4-judge
2024-06-11T07:50:15Z
koolexcrypto marked the issue as grade-c
#10 - c4-judge
2024-06-11T08:17:45Z
koolexcrypto removed the grade
#11 - c4-judge
2024-06-11T08:17:57Z
This previously downgraded issue has been upgraded by koolexcrypto
#12 - c4-judge
2024-06-11T08:18:11Z
koolexcrypto marked the issue as duplicate of #33
#13 - c4-judge
2024-06-11T08:18:14Z
koolexcrypto marked the issue as partial-25