hats-finance / Metrom-0xfdfc6d4ac5807d7460da20a3a1c0c84ef2b9c5a2

Smart contracts for the Metrom project.
GNU General Public License v3.0
0 stars 0 forks source link

Anyone can Deposit Native Erc20 Token for Free and Steal Funds #63

Open hats-bug-reporter[bot] opened 2 months ago

hats-bug-reporter[bot] commented 2 months ago

Github username: -- Twitter username: -- Submission hash (on-chain): 0x7d9a15d6f211ead3f63e866a3efe8ee292765d7b8222d666872a80d9db660181 Severity: high

Description: Description\ as the metrom mentioned,all erc20 tokens are allowed.The createCampaigns function allows setting rewardTokens to the ERC20 native token address (0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) without throwing an error. When this address is used, the SafeERC20.safeTransferFrom call does not revert because it performs a low-level call to the native token address, which is an EOA. Low-level calls to EOAs always succeed, and the *safe version does not revert if the EOA does not return any data. This vulnerability allows an attacker to deposit infinite native tokens without paying anything. The contract will emit the same CreateCampaign event as a legitimate call, and the attacker can receive the funds.

Attack Scenario\ 1.Identifing the Vulnerability: The attacker identifies that the createCampaigns function does not properly validate the rewardTokens array, allowing the native token address (0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) to be used.

  1. Prepare Malicious Input: The attacker prepares a CreateBundle with rewardTokens set to the native token address and rewardAmounts set to any arbitrary value.
  2. Call createCampaigns Function: The attacker calls the createCampaigns function with the malicious CreateBundle.
  3. Bypass Transfer Check: The SafeERC20.safeTransferFrom call does not revert because it performs a low-level call to the native token address, which is an EOA. The call always succeeds, and the safe version does not revert if the EOA does not return any data.
  4. Emit Event: The contract emits the CreateCampaign event, making it appear as though a legitimate deposit has been made.

Attachments

  1. Proof of Concept (PoC) File

https://etherscan.io/address/0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee#tokentxns

https://github.com/hats-finance/Metrom-0xfdfc6d4ac5807d7460da20a3a1c0c84ef2b9c5a2/blob/e9d6b1e594d5bb3694bfe68f73399156ebb5d3a4/src/Metrom.sol#L195C16-L195C67

https://github.com/hats-finance/Metrom-0xfdfc6d4ac5807d7460da20a3a1c0c84ef2b9c5a2/blob/e9d6b1e594d5bb3694bfe68f73399156ebb5d3a4/src/Metrom.sol#L160C5-L231C6

  1. Revised Code File (Optional)

Add a check to ensure that the rewardTokens array does not contain the native token address (0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE).

function createCampaigns(CreateBundle[] calldata _bundles) external {

    ....
    ....
    for (uint256 _i = 0; _i < _bundles.length; _i++) {
        CreateBundle memory _bundle = _bundles[_i];
        for (uint256 _j = 0; _j < _bundle.rewardTokens.length; _j++) {
            address _token = _bundle.rewardTokens[_j];
            if (_token == address(0) || _token == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) {
                revert InvalidRewards();
            }
            uint256 _amount = _bundle.rewardAmounts[_j];
            IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount);
        }
    }
}

This check ensures that only valid ERC20 tokens are used in the rewardTokens array, preventing the exploitation of the native token address.

Files:

luzzif commented 2 months ago

I'm sorry but I'm not sure I get this. What's so special about the 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE address? It's an address like any other and it doesn't necessarily indicate a "native token address", whatever that is. Also, a reward token whitelist has been introduced to mitigate potential scenarios like this, but even without that using an EOA as a reward token address would still fail.