code-423n4 / redacted-bug-bounty

13 stars 9 forks source link

The distributeFees function does not have explicit access controls, any address can trigger it. #56

Closed c4-bot-8 closed 5 months ago

c4-bot-8 commented 5 months ago

Lines of code

https://github.com/redacted-cartel/pirex-eth-contracts/blob/master/src/PirexFees.sol#L78

Vulnerability details

The distributeFees function does not have explicit access controls, meaning any address can trigger it as long as it provides valid parameters.

To make the distributeFees function in the PirexFees contract properly controlled, we can introduce an access control mechanism. A simple and effective approach is to utilize role-based access control, specifically by using a FEE_DISTRIBUTOR_ROLE. This role can be managed by the contract owner (or another designated admin role), and only addresses granted this role should be allowed to execute the distributeFees function.

Original function:

function distributeFees( address from, address token, uint256 amount ) external { emit DistributeFees(token, amount);

    ERC20 t = ERC20(token);

    // Favoring push over pull to reduce accounting complexity for different tokens
    t.safeTransferFrom(from, recipient, amount);
}

Here is how you could modify the PirexFees contract to include this security enhancement:

Updated Contract with Access Control:

// SPDX-License-Identifier: MIT pragma solidity 0.8.19;

import {Ownable2Step} from "openzeppelin-contracts/contracts/access/Ownable2Step.sol"; import {ERC20} from "solmate/tokens/ERC20.sol"; import {SafeTransferLib} from "solmate/utils/SafeTransferLib.sol"; import {AccessControl} from "openzeppelin-contracts/contracts/access/AccessControl.sol"; import {DataTypes} from "./libraries/DataTypes.sol"; import {Errors} from "./libraries/Errors.sol";

/**

Key Changes Explained

  1. Import AccessControl: Import AccessControl from OpenZeppelin to manage role-based access controls effectively.
  2. Define FEE_DISTRIBUTOR_ROLE: A role specifically for addresses that can distribute fees. This ensures that only authorized entities can perform fee distributions.
  3. Role Setup in Constructor: The owner is set up with the default admin role, which allows the owner to manage other roles. This is useful for granting or revoking the FEE_DISTRIBUTOR_ROLE to other addresses.
  4. Modify distributeFees Function: The function is modified to include onlyRole(FEE_DISTRIBUTOR_ROLE), which checks that the caller has the necessary role to execute the function. This prevents unauthorized access and ensures that fee distribution is controlled.

These changes introduce a robust control mechanism to manage who can distribute fees, aligning with best practices in contract security, particularly in the context of decentralized finance where managing financial transactions securely is crucial.

c4-bot-9 commented 5 months ago

Discord id(s) for hunter(s): [object Object]

MiloTruck commented 5 months ago

Invalid. distributeFees() can be called by anyone as the tokens will be sent to recipient regardless.