Skip to content
This repository has been archived by the owner on Nov 19, 2023. It is now read-only.

xiaoming90 - Return data from the external call not verified during deposit and redemption #181

Open
sherlock-admin opened this issue May 15, 2023 · 2 comments
Labels
Has Duplicates A valid issue with 1+ other issues describing the same vulnerability Medium A valid Medium severity issue Reward A payout will be made for this issue Sponsor Confirmed The sponsor acknowledged this issue is valid Won't Fix The sponsor confirmed this issue will not be fixed

Comments

@sherlock-admin
Copy link
Contributor

xiaoming90

medium

Return data from the external call not verified during deposit and redemption

Summary

The deposit and redemption functions did not verify the return data from the external call, which might cause the contract to wrongly assume that the deposit/redemption went well although the action has actually failed in the background.

Vulnerability Detail

https://github.com/sherlock-audit/2023-03-notional/blob/main/contracts-v2/contracts/internal/balances/protocols/GenericToken.sol#L63

File: GenericToken.sol
63:     function executeLowLevelCall(
64:         address target,
65:         uint256 msgValue,
66:         bytes memory callData
67:     ) internal {
68:         (bool status, bytes memory returnData) = target.call{value: msgValue}(callData);
69:         require(status, checkRevertMessage(returnData));
70:     }

When the external call within the GenericToken.executeLowLevelCall function reverts, the status returned from the .call will be false. In this case, Line 69 above will revert.

https://github.com/sherlock-audit/2023-03-notional/blob/main/contracts-v2/contracts/internal/balances/TokenHandler.sol#L375

File: TreasuryAction.sol
316:             for (uint256 j; j < depositData.targets.length; ++j) {
317:                 // This will revert if the individual call reverts.
318:                 GenericToken.executeLowLevelCall(
319:                     depositData.targets[j], 
320:                     depositData.msgValue[j], 
321:                     depositData.callData[j]
322:                 );
323:             }

For deposit and redeem, Notional assumes that all money markets will revert if the deposit/mint and redeem/burn has an error. Thus, it does not verify the return data from the external call. Refer to the comment in Line 317 above.

However, this is not always true due to the following reasons:

  • Some money markets might not revert when errors occur but instead return false (0). In this case, the current codebase will wrongly assume that the deposit/redemption went well although the action has failed.
  • Compound might upgrade its contracts to return errors instead of reverting in the future.

Impact

The gist of prime cash is to integrate with multiple markets. Thus, the codebase should be written in a manner that can handle multiple markets. Otherwise, the contract will wrongly assume that the deposit/redemption went well although the action has actually failed in the background, which might potentially lead to some edge cases where assets are sent to the users even though the redemption fails.

Code Snippet

https://github.com/sherlock-audit/2023-03-notional/blob/main/contracts-v2/contracts/internal/balances/TokenHandler.sol#L375

https://github.com/sherlock-audit/2023-03-notional/blob/main/contracts-v2/contracts/external/actions/TreasuryAction.sol#L318

Tool used

Manual Review

Recommendation

Consider checking the returnData to ensure that the external money market returns a successful response after deposit and redemption.

Note that the successful response returned from various money markets might be different. Some protocols return 1 on a successful action, while Compound return zero (NO_ERROR).

@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 May 19, 2023
@jeffywu jeffywu added Sponsor Disputed The sponsor disputed this issue's validity Disagree With Severity The sponsor disputed the severity of this issue and removed Sponsor Disputed The sponsor disputed this issue's validity labels May 22, 2023
@jeffywu
Copy link

jeffywu commented May 22, 2023

Since Compound V2 will not be used, this is a bit of a hypothetical. Also, if the external money market is trusted it should not "eat" the funds without reverting - it would be expected to return the funds which would cause the surrounding deposit amount checks to fail and the Notional transaction would revert.

I believe that this issue should be medium or low as suggested by the auditor.

@Trumpero Trumpero added Medium A valid Medium severity issue and removed High A valid High severity issue Disagree With Severity The sponsor disputed the severity of this issue labels May 28, 2023
@Trumpero
Copy link
Collaborator

I agree that the severity of this issue should be lower. Labeled it as a medium.

@hrishibhat hrishibhat added the Sponsor Confirmed The sponsor acknowledged this issue is valid label May 29, 2023
@sherlock-admin sherlock-admin added the Reward A payout will be made for this issue label May 29, 2023
@jeffywu jeffywu added the Won't Fix The sponsor confirmed this issue will not be fixed label Jul 11, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Has Duplicates A valid issue with 1+ other issues describing the same vulnerability Medium A valid Medium severity issue Reward A payout will be made for this issue Sponsor Confirmed The sponsor acknowledged this issue is valid Won't Fix The sponsor confirmed this issue will not be fixed
Projects
None yet
Development

No branches or pull requests

4 participants