Summary
The RAACMinter contract has the Minter role but not the Owner role in the RAACToken contract. As a result, RAACMinter cannot modify critical parameters such as swap tax rate, burn tax rate, or fee collector address, as these functions (setSwapTaxRate(), setBurnTaxRate(), setFeeCollector()) are restricted to the onlyOwner modifier.
Vulnerability Details
The RAACToken contract includes several onlyOwner functions that allow governance-level modifications:
Since RAACMinter does not have ownership privileges, it cannot call these functions.
function setSwapTaxRate(uint256 _swapTaxRate) external onlyRole(UPDATER_ROLE) {
if (_swapTaxRate > 1000) revert SwapTaxRateExceedsLimit();
@> raacToken.setSwapTaxRate(_swapTaxRate);
emit ParameterUpdated("swapTaxRate", _swapTaxRate);
}
function setBurnTaxRate(uint256 _burnTaxRate) external onlyRole(UPDATER_ROLE) {
if (_burnTaxRate > 1000) revert BurnTaxRateExceedsLimit();
@> raacToken.setBurnTaxRate(_burnTaxRate);
emit ParameterUpdated("burnTaxRate", _burnTaxRate);
}
function setFeeCollector(address _feeCollector) external onlyRole(UPDATER_ROLE) {
if (_feeCollector == address(0)) revert FeeCollectorCannotBeZeroAddress();
@> raacToken.setFeeCollector(_feeCollector);
emit ParameterUpdated("feeCollector", uint256(uint160(_feeCollector)));
}
https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/minters/RAACMinter/RAACMinter.sol#L146C1-L174C6
This implies that the contract owner must separately manage these configurations, potentially affecting operational efficiency if adjustments need to be made dynamically.
Impact
RAACMintercannot able to update the above mentioned functions
Tools Used
Manual Review
Recommendations
Use onlyMinter role which RAACMinteralready have
- function setFeeCollector(address _feeCollector) external onlyOwner {
+ function setFeeCollector(address _feeCollector) external onlyMinter {
// Fee collector can be set to zero address to disable fee collection
if(feeCollector == address(0) && _feeCollector != address(0)){
emit FeeCollectionEnabled(_feeCollector);
}
if (_feeCollector == address(0)){
emit FeeCollectionDisabled();
}
feeCollector = _feeCollector;
emit FeeCollectorSet(_feeCollector);
}
/**
* @dev Sets the swap tax rate
* @param rate The new swap tax rate (in basis points)
*/
- function setSwapTaxRate(uint256 rate) external onlyOwner { _setTaxRate(rate, true); }
+ function setSwapTaxRate(uint256 rate) external onlyMinter { _setTaxRate(rate, true); }
/**
* @dev Sets the burn tax rate
* @param rate The new burn tax rate (in basis points)
*/
- function setBurnTaxRate(uint256 rate) external onlyOwner { _setTaxRate(rate, false); }
+ function setBurnTaxRate(uint256 rate) external onlyMinter { _setTaxRate(rate, false); }