code-423n4 / 2024-02-wise-lending-findings

11 stars 8 forks source link

Tokens are not been send it to the user in the aave hub contract. #151

Closed c4-bot-5 closed 6 months ago

c4-bot-5 commented 6 months ago

Lines of code

https://github.com/code-423n4/2024-02-wise-lending/blob/79186b243d8553e66358c05497e5ccfd9488b5e2/contracts/WrapperHub/AaveHub.sol#L281

Vulnerability details

When a user deposit through the aave hub this is the order of the events:

  1. the tokens are send it to the aave hub contract from the user through the deposit function.
  2. the token are supplied in the aave lending protocol and aave hub mint some atokens.
  3. This atokens are depositing to the wiseLending main contract.

When a user want to borrow or witdraw this is the order of the events:

  1. The atoken are send it from the wiseLending main contract to the aave hub.
  2. this atoken are been burned, in the avee hub
  3. the underlying token is send it back to the user.

The problem is that the tokens are never send it back to the user.

Impact

User loss his money borrowing or withdrawing tokens (This not affect function using eth directly) in the aave hub because the contract is never send it back the token to the user.

Proof of Concept

If we follow the orden present in the begining:

file:/contracts/WrapperHub/AaveHub.sol

function depositExactAmount(
        uint256 _nftId,
        address _underlyingAsset,
        uint256 _amount
    )
        public
        nonReentrant
        validToken(_underlyingAsset)
        returns (uint256)
    {
        _safeTransferFrom(  <------
            _underlyingAsset,
            msg.sender,
            address(this),
            _amount
        );

        uint256 lendingShares = _wrapDepositExactAmount(  <-----
            _nftId,
            _underlyingAsset,
            _amount
        );

        emit IsDepositAave(
            _nftId,
            block.timestamp
        );

        return lendingShares;
    }

[Link]

When you deposit the token are been send it to the aave hub and in the _wrapDepositExactAmount the contract is suplying in the aave protocol and depositing on the wiseLending on behalf of the user.

Now when a user atemp to withdraw:

file:/contracts/WrapperHub/AaveHub.sol

 function withdrawExactShares(
        uint256 _nftId,
        address _underlyingAsset,
        uint256 _shareAmount
    )
        external
        nonReentrant
        validToken(_underlyingAsset)
        returns (uint256)
    {
        _checkOwner(
            _nftId
        );

        uint256 withdrawAmount = _wrapWithdrawExactShares(  <------
            _nftId,
            _underlyingAsset,
            msg.sender,
            _shareAmount
        );

        emit IsWithdrawAave(
            _nftId,
            block.timestamp
        );

        return withdrawAmount;
    }

[Link]

function _wrapWithdrawExactShares(
        uint256 _nftId,
        address _underlyingAsset,
        address _underlyingAssetRecipient,
        uint256 _shareAmount
    )
        internal
        returns (uint256)
    {
        address aaveToken = aaveTokenAddress[
            _underlyingAsset
        ];

        uint256 withdrawAmount = WISE_LENDING.withdrawOnBehalfExactShares(
            _nftId,
            aaveToken,
            _shareAmount
        );  

        withdrawAmount = AAVE.withdraw(  <------
            _underlyingAsset,
            withdrawAmount,
            _underlyingAssetRecipient
        );

        return withdrawAmount;
    }

[Link]

The atoken are been withdrawing from from the wiseLendindg and burned in the AAVE.withdraw functions but the underlying token is never send it back to the user.

This problem is happening in the next functions:

Tools Used

Manual review.

Recommended Mitigation Steps

Send the tokens back to the user in the borrowExactAmount, withdrawExactAmount and the withdrawExactShares.

   function withdrawExactShares(
        uint256 _nftId,
        address _underlyingAsset,
        uint256 _shareAmount
    )
        external
        nonReentrant
        validToken(_underlyingAsset)
        returns (uint256)
    {
        _checkOwner(
            _nftId
        );

        uint256 withdrawAmount = _wrapWithdrawExactShares(
            _nftId,
            _underlyingAsset,
            msg.sender,
            _shareAmount
        );

         _safeTransferFrom(
            _underlyingAsset,
            address(this),
            msg.sender,
            _amount
        );

        emit IsWithdrawAave(
            _nftId,
            block.timestamp
        );

        return withdrawAmount;
    }

same for the borrowExactAmount and withdrawExactAmount.

Assessed type

Error

c4-bot-4 commented 6 months ago

Withdrawn by Jorgect