DittoETH

Ditto
DeFiFoundryOracle
55,000 USDC
View results
Submission Details
Severity: medium
Invalid

Misscalculation of the `netBalance`

Summary

Potential misscalculation of the netBalance in function unstake() in BridgeReth.sol contract.

Vulnerability Details

In the context of the function unstake(), originalBalance is the Ether balance of the contract before the burnoperation is performed on the rocketETHToken. The burn operation is expected to increase the contract's Ether balance. Therefore, originalBalance should be less than address(this).balance after the burn operation.

However, if for some reason the burn operation does not increase the contract's Ether balance (for example, if it fails or reverts), or if Ether is somehow removed from the contract in between the time originalBalance is set and the burn operation is performed, then originalBalance could be equal to or even greater than address(this).balance. This would cause the calculation of netBalance to underflow, resulting in a very large value due to the way Solidity handles underflows.

Impact

If for any reason, like receiving Ether through a selfdestruct from another contract or through a direct send or transfer, the contract's balance increases between the lines where originalBalance is set and where burn is called, netBalance will be larger than the actual amount of Ether received from the burn operation. This could lead to the contract sending more Ether than it should when making the call to the to address.

To fix this, you should recalculate the originalBalance immediately after the burn operation and/or add a check after the burn operation to ensure that the contract's balance has indeed increased.

Tools Used

Manual review, VS Code

Recommendations

Recalculate the originalBalance immediately after the burn operation and/or add a check after the burn operation to ensure that the contract's balance has indeed increased. This way, netBalance will accurately reflect the amount of Ether received from the burn operation.

function unstake(address to, uint256 amount) external onlyDiamond {
IRocketTokenRETH rocketETHToken = _getRethContract();
uint256 rethValue = rocketETHToken.getRethValue(amount);
uint256 originalBalance = address(this).balance;
rocketETHToken.burn(rethValue);
originalBalance = address(this).balance - originalBalance;
require(address(this).balance > originalBalance, "Contract balance did not increase");
uint256 netBalance = address(this).balance - originalBalance;
if (netBalance == 0) revert NetBalanceZero();
(bool sent,) = to.call{value: netBalance}("");
assert(sent);
}
Updates

Lead Judging Commences

0xnevi Lead Judge
almost 2 years ago
0xnevi Lead Judge almost 2 years ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.