Skip to content

Latest commit

 

History

History
77 lines (54 loc) · 2.44 KB

072.md

File metadata and controls

77 lines (54 loc) · 2.44 KB

Bent Sandstone Oyster

Medium

Reentrancy Risk in NumaMinter's mint Function

Summary

The lack of reentrancy protection in NumaMinter.sol will cause potential fund loss for users as malicious actors can reenter the mint function through the external call.

Root Cause

In NumaMinter.sol:31 the mint function makes an external call to another contract without implementing reentrancy protection and following the CEI (Checks-Effects-Interactions) pattern:

https://github.com/sherlock-audit/2024-12-numa-audit/blob/main/Numa/contracts/NumaProtocol/NumaMinter.sol#L35-L43

Internal pre-conditions

  1. Contract must have minting permissions on the Numa token
  2. Caller needs to be in the allowedMinters mapping
  3. numa token address must be set to a non-zero address

External pre-conditions

  1. The Numa token contract must be controlled by a malicious actor or have a vulnerability that allows reentrancy

Attack Path

  1. Attacker deploys a malicious token contract implementing INuma interface
  2. Owner calls setTokenAddress() with the malicious token address
  3. Attacker (who is an allowed minter) calls mint()
  4. During the external call to numa.mint(), the malicious contract calls back into NumaMinter's mint() function
  5. The cycle repeats until gas is exhausted or other limits are hit

Impact

The protocol suffers from uncontrolled minting of tokens. The attacker gains an excessive amount of tokens through repeated minting operations before any limits can be enforced.

PoC

contract MaliciousNuma is INuma {
    NumaMinter public minter;
    uint256 public count;
    constructor(address minter) {
        minter = NumaMinter(minter);
    }
    function mint(address to, uint256 amount) external override {
        if (count < 5) {
            // Prevent infinite loop in test
            count++;
            minter.mint(to, amount); // Reenter mint function
        }
    }
    // ... other required interface implementations
}

Mitigation

  1. Add ReentrancyGuard from OpenZeppelin.
contract NumaMinter is Ownable2Step, ReentrancyGuard {
    function mint(
        address to,
        uint256 amount
    ) external nonReentrant onlyMinters {
        require(address(numa) != address(0), "token address invalid");
        numa.mint(to, amount);
    }
}
  1. Consider implementing additional checks and balances such as minting limits per transaction or time-based restrictions.