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

xiaoming90 - Residual ETH will not be sent back to users during the minting of wfCash #25

Open
sherlock-admin2 opened this issue Jan 18, 2024 · 3 comments
Labels
Has Duplicates A valid issue with 1+ other issues describing the same vulnerability High A valid High severity issue Reward A payout will be made for this issue Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed

Comments

@sherlock-admin2
Copy link
Contributor

sherlock-admin2 commented Jan 18, 2024

xiaoming90

high

Residual ETH will not be sent back to users during the minting of wfCash

Summary

Residual ETH will not be sent back to users, resulting in a loss of assets.

Vulnerability Detail

At Line 67, residual ETH within the depositUnderlyingToken function will be sent as Native ETH back to the msg.sender, which is this wfCash Wrapper contract.

https://github.com/sherlock-audit/2023-12-notional-update-5/blob/main/wrapped-fcash/contracts/wfCashLogic.sol#L67

File: wfCashLogic.sol
35:     function _mintInternal(
..SNIP..
60:         if (maxFCash < fCashAmount) {
61:             // NOTE: lending at zero
62:             uint256 fCashAmountExternal = fCashAmount * precision / uint256(Constants.INTERNAL_TOKEN_PRECISION); 
63:             require(fCashAmountExternal <= depositAmountExternal); 
64: 
65:             // NOTE: Residual (depositAmountExternal - fCashAmountExternal) will be transferred
66:             // back to the account
67:             NotionalV2.depositUnderlyingToken{value: msgValue}(address(this), currencyId, fCashAmountExternal);
..SNIP..
87:         // Residual tokens will be sent back to msg.sender, not the receiver. The msg.sender
88:         // was used to transfer tokens in and these are any residual tokens left that were not
89:         // lent out. Sending these tokens back to the receiver risks them getting locked on a
90:         // contract that does not have the capability to transfer them off
91:         _sendTokensToReceiver(token, msg.sender, isETH, balanceBefore);

Within the depositUnderlyingToken function Line 108 below, the returnExcessWrapped parameter is set to false, which means it will not wrap the residual ETH, and that Native ETH will be sent back to the caller (wrapper contract)

https://github.com/sherlock-audit/2023-12-notional-update-5/blob/main/contracts-v3/contracts/external/actions/AccountAction.sol#L108

File: AccountAction.sol
89:     function depositUnderlyingToken(
90:         address account,
91:         uint16 currencyId,
92:         uint256 amountExternalPrecision
93:     ) external payable nonReentrant returns (uint256) {
..SNIP..
File: AccountAction.sol
105:         int256 primeCashReceived = balanceState.depositUnderlyingToken(
106:             msg.sender,
107:             SafeInt256.toInt(amountExternalPrecision),
108:             false // there should never be excess ETH here by definition
109:         );

balanceBefore = amount of WETH before the deposit, balanceAfter = amount of WETH after the deposit.

When the _sendTokensToReceiver is executed, these two values are going to be the same since it is Native ETH that is sent to the wrapper instead of WETH. As a result, the Native ETH that the wrapper received is not forwarded to the users.

https://github.com/sherlock-audit/2023-12-notional-update-5/blob/main/wrapped-fcash/contracts/wfCashLogic.sol#L331

File: wfCashLogic.sol
331:     function _sendTokensToReceiver( 
332:         IERC20 token,
333:         address receiver,
334:         bool isETH,
335:         uint256 balanceBefore
336:     ) private returns (uint256 tokensTransferred) {
337:         uint256 balanceAfter = isETH ? WETH.balanceOf(address(this)) : token.balanceOf(address(this)); 
338:         tokensTransferred = balanceAfter - balanceBefore; 
339: 
340:         if (isETH) {
341:             // No need to use safeTransfer for WETH since it is known to be compatible
342:             IERC20(address(WETH)).transfer(receiver, tokensTransferred); 
343:         } else if (tokensTransferred > 0) { 
344:             token.safeTransfer(receiver, tokensTransferred); 
345:         }
346:     }

Impact

Loss of assets as the residual ETH is not sent to the users.

Code Snippet

https://github.com/sherlock-audit/2023-12-notional-update-5/blob/main/wrapped-fcash/contracts/wfCashLogic.sol#L67

https://github.com/sherlock-audit/2023-12-notional-update-5/blob/main/contracts-v3/contracts/external/actions/AccountAction.sol#L108

https://github.com/sherlock-audit/2023-12-notional-update-5/blob/main/wrapped-fcash/contracts/wfCashLogic.sol#L331

Tool used

Manual Review

Recommendation

If the underlying is ETH, measure the Native ETH balance before and after the depositUnderlyingToken is executed. Forward any residual Native ETH to the users, if any.

@github-actions github-actions bot added High A valid High severity issue Has Duplicates A valid issue with 1+ other issues describing the same vulnerability labels Jan 22, 2024
@sherlock-admin2
Copy link
Contributor Author

1 comment(s) were left on this issue during the judging contest.

takarez commented:

valid because { This is a valid findings as the watson was able to explained how excess ETH will be stuck and not sent back to user as intended; hight findings}

@jeffywu jeffywu added the Sponsor Confirmed The sponsor acknowledged this issue is valid label Jan 27, 2024
@sherlock-admin sherlock-admin changed the title Strong Leather Toad - Residual ETH will not be sent back to users during the minting of wfCash xiaoming90 - Residual ETH will not be sent back to users during the minting of wfCash Feb 3, 2024
@sherlock-admin sherlock-admin added the Reward A payout will be made for this issue label Feb 3, 2024
jeffywu added a commit to notional-finance/wrapped-fcash that referenced this issue Feb 5, 2024
@sherlock-admin2 sherlock-admin2 added the Will Fix The sponsor confirmed this issue will be fixed label Feb 7, 2024
jeffywu added a commit to notional-finance/wrapped-fcash that referenced this issue Feb 12, 2024
* fix: add test

* fix: add second test

* fix: sherlock-audit/2023-12-notional-update-5-judging#25 sherlock-audit/2023-12-notional-update-5-judging#30 update eth refund logic

* fix: adding another test
@sherlock-admin
Copy link
Contributor

The protocol team fixed this issue in PR/commit notional-finance/wrapped-fcash#20.

@sherlock-admin
Copy link
Contributor

The Lead Senior Watson signed-off on the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Has Duplicates A valid issue with 1+ other issues describing the same vulnerability High A valid High severity issue Reward A payout will be made for this issue Sponsor Confirmed The sponsor acknowledged this issue is valid Will Fix The sponsor confirmed this issue will be fixed
Projects
None yet
Development

No branches or pull requests

3 participants