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.