Potential front-run on initialize of FiatTokenV1
Description
The FiatTokenV1 contract is designed as an upgradable contract and does not include a constructor. Instead, it features an initialize function responsible for configuring token settings and assigning roles. However, the current implementation of the initialize function does not include verification checks to ensure that msg.sender is a trusted address.
If the contract is deployed but not initialized in the same transaction, this could potentially allow an attacker to front-run the initialize function and take control of the contract. We note that in the current deployment script, initialize is indeed called during deployment.
function initialize(
address defaultAdmin,
address pauser,
address minter,
address upgrader,
address rescuer,
address blacklister,
string memory tokenName,
string memory tokenSymbol
) public initializer {
__ERC20_init(tokenName, tokenSymbol);
__ERC20Capped_init(MAX_TOKEN_SUPPLY);
__ERC20Pausable_init();
__ERC20Burnable_init();
__AccessControl_init();
__ERC20Permit_init(tokenName);
__UUPSUpgradeable_init();
__ERC20Rescuable_init();
__ERC20Blacklistable_init();
_grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin);
_grantRole(PAUSER_ROLE, pauser);
_grantRole(MINTER_ROLE, minter);
_grantRole(UPGRADER_ROLE, upgrader);
_grantRole(RESCUER_ROLE, rescuer);
_grantRole(BLACKLISTER_ROLE, blacklister);
}Impact
The attacker can set token-related settings and grantRoles on an arbitrary address.
Recommendations
Consider adding the trusted address-check logic for the initialize function.
Remediation
This issue has been acknowledged by Trillion Network, and a fix was implemented in commit 69076f00↗.
The team resolved this issue by adding the trusted address for this function.