Skip to content
Request an audit

‹ All findings

SpiritVestingFactory::setTreasury() could be 2 factor, as well as the AccessControl OZ contract used in the codebase

Low/InfoSpirit Protocol·0xSimao · AI revenue sharing · 28th November 2025I-2

Description:

SpiritVestingFactory::setTreasury() is single factor, so a single mistake can lose treasury access forever, which is responsible for cancelling the treasury in the SpiritVesting contract.

solidity
function setTreasury(address newTreasury) external onlyTreasury {
    // Ensure the new treasury address is not the zero address
    if (newTreasury == address(0)) revert FORBIDDEN();
    treasury = newTreasury;
}

Additionally, throughout the codebase, AccessControl is used, which also doesn't have 2 factor. The SpiritFactory is mostly stateless, besides the fact that it is a role in the RewardsController, so the ability to set staking pools could be compromised. The RewardController relies on roles for upgrades, rewards distributions, so it is also a pain point.

Impact:

Lost roles.

Recommended Mitigation:

Use the AccessControlDefaultAdminRules for better role management.