hats-finance / Intuition-0x538dbadc50cc87b281cd655f1edbc6ebda02a66a

The smart contracts of the Intuition protocol v1.
https://intuition.systems
Other
0 stars 1 forks source link

Lack of WETH Fallback in redeemAtom Function for Failed ETH Transfers #73

Open hats-bug-reporter[bot] opened 3 days ago

hats-bug-reporter[bot] commented 3 days ago

Github username: -- Twitter username: -- Submission hash (on-chain): 0xfe48c86ee5fde1eaae0770dab56021baee6c579c2aa94c61a309134d82982c86 Severity: medium

Description: Description\ The redeemAtom function in the EthMultiVault contract attempts to transfer ETH directly to the receiver. If this transfer fails, the function simply reverts instead of attempting a fallback method using WETH. This approach can lead to unnecessary transaction failures and a poor user experience, especially when interacting with contracts that can't receive ETH directly but can handle WETH.

Attack Scenario\ While not a direct security vulnerability, this issue can lead to the following problems:

  1. A user attempts to redeem their shares to a contract address that doesn't have a payable fallback function but can handle WETH.
  2. The ETH transfer fails, causing the entire transaction to revert.
  3. The user is unable to redeem their shares, despite the receiving contract being capable of handling the assets in WETH form.
  4. This limits the contract's interoperability with other DeFi protocols and smart contracts.

Attachments

  1. Proof of Concept (PoC) File https://github.com/hats-finance/Intuition-0x538dbadc50cc87b281cd655f1edbc6ebda02a66a/blob/b2e422ff0c3e3729e58d2699fdf2ef8699fbd172/src/EthMultiVault.sol#L726-L729

  2. Revised Code File (Optional)

    function redeemAtom(uint256 shares, address receiver, uint256 id) external nonReentrant returns (uint256) {
        if (id == 0 || id > count) {
            revert Errors.MultiVault_VaultDoesNotExist();
        }
    
        if (isTripleId(id)) {
            revert Errors.MultiVault_VaultNotAtom();
        }
    
        (uint256 assets, uint256 protocolFee) = _redeem(id, msg.sender, shares);
    
        // Try to transfer ETH first
        (bool success,) = payable(receiver).call{value: assets}("");
        if (!success) {
            // If ETH transfer fails, fallback to WETH
            WETH.deposit{value: assets}();
            require(WETH.transfer(receiver, assets), "WETH transfer failed");
        }
    
        _transferFeesToProtocolVault(protocolFee);
    
        return assets;
    }