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

bin2chen - repayAccountPrimeDebtAtSettlement() user lost residual cash #172

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 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-admin
Copy link
Contributor

bin2chen

high

repayAccountPrimeDebtAtSettlement() user lost residual cash

Summary

in repayAccountPrimeDebtAtSettlement()
Incorrect calculation of primeCashRefund value (always == 0)
Resulting in the loss of the user's residual cash

Vulnerability Detail

when settle Vault Account
will execute settleVaultAccount()->repayAccountPrimeDebtAtSettlement()
In the repayAccountPrimeDebtAtSettlement() method the residual amount will be refunded to the user
The code is as follows.

    function repayAccountPrimeDebtAtSettlement(
        PrimeRate memory pr,
        VaultStateStorage storage primeVaultState,
        uint16 currencyId,
        address vault,
        address account,
        int256 accountPrimeCash,
        int256 accountPrimeStorageValue
    ) internal returns (int256 finalPrimeDebtStorageValue, bool didTransfer) {
...

            if (netPrimeDebtRepaid < accountPrimeStorageValue) {
                // If the net debt change is greater than the debt held by the account, then only
                // decrease the total prime debt by what is held by the account. The residual amount
                // will be refunded to the account via a direct transfer.
                netPrimeDebtChange = accountPrimeStorageValue;
                finalPrimeDebtStorageValue = 0;

                int256 primeCashRefund = pr.convertFromUnderlying(
                    pr.convertDebtStorageToUnderlying(netPrimeDebtChange.sub(accountPrimeStorageValue)) //<--------@audit always ==0
                );
                TokenHandler.withdrawPrimeCash(
                    account, currencyId, primeCashRefund, pr, false // ETH will be transferred natively
                );
                didTransfer = true;
            } else {

From the above code we can see that there is a spelling error

  1. netPrimeDebtChange = accountPrimeStorageValue;
  2. primeCashRefund = netPrimeDebtChange.sub(accountPrimeStorageValue)
    so primeCashRefund always ==0

should be primeCashRefund = netPrimeDebtRepaid - accountPrimeStorageValue

Impact

primeCashRefund always == 0 , user lost residual cash

Code Snippet

https://github.com/sherlock-audit/2023-03-notional/blob/main/contracts-v2/contracts/internal/vaults/VaultAccount.sol#L575

Tool used

Manual Review

Recommendation

    function repayAccountPrimeDebtAtSettlement(
        PrimeRate memory pr,
        VaultStateStorage storage primeVaultState,
        uint16 currencyId,
        address vault,
        address account,
        int256 accountPrimeCash,
        int256 accountPrimeStorageValue
    ) internal returns (int256 finalPrimeDebtStorageValue, bool didTransfer) {
...

            if (netPrimeDebtRepaid < accountPrimeStorageValue) {
                // If the net debt change is greater than the debt held by the account, then only
                // decrease the total prime debt by what is held by the account. The residual amount
                // will be refunded to the account via a direct transfer.
                netPrimeDebtChange = accountPrimeStorageValue;
                finalPrimeDebtStorageValue = 0;

                int256 primeCashRefund = pr.convertFromUnderlying(
-                   pr.convertDebtStorageToUnderlying(netPrimeDebtChange.sub(accountPrimeStorageValue))
+                   pr.convertDebtStorageToUnderlying(netPrimeDebtRepaid.sub(accountPrimeStorageValue)) 
                );
                TokenHandler.withdrawPrimeCash(
                    account, currencyId, primeCashRefund, pr, false // ETH will be transferred natively
                );
                didTransfer = true;
            } else {
@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
@T-Woodward T-Woodward added the Sponsor Confirmed The sponsor acknowledged this issue is valid label May 21, 2023
@sherlock-admin sherlock-admin added the Reward A payout will be made for this issue label May 29, 2023
@jeffywu
Copy link

jeffywu commented Jul 11, 2023

Fixed: notional-finance/contracts-v2#135

@jeffywu jeffywu added the Will Fix The sponsor confirmed this issue will be fixed label Jul 11, 2023
@xiaoming9090
Copy link
Collaborator

@0xleastwood + @xiaoming9090 : Verified. Fixed in PR notional-finance/contracts-v2#135

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 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

4 participants