Platform: Code4rena
Start Date: 12/04/2023
Pot Size: $60,500 USDC
Total HM: 21
Participants: 199
Period: 7 days
Judge: hansfriese
Total Solo HM: 5
Id: 231
League: ETH
Rank: 68/199
Findings: 2
Award: $56.43
🌟 Selected for report: 0
🚀 Solo Findings: 0
33.835 USDC - $33.83
https://github.com/code-423n4/2023-04-frankencoin/blob/1022cb106919fba963a89205d3b90bf62543f68f/contracts/Frankencoin.sol#L83-L90 https://github.com/code-423n4/2023-04-frankencoin/blob/1022cb106919fba963a89205d3b90bf62543f68f/contracts/Frankencoin.sol#L88
An attacker can exploit the smart contract's minting mechanism, which allows them to create an unlimited amount of Frankencoin tokens.
Firstly, this can result in a drastic reduction in the value of the tokens, as the sudden influx of an unlimited number of tokens can cause the market to become oversaturated
. This, in turn, can reduce demand for the token, as there are now too many tokens in circulation, making them less valuable.
Secondly, the overall functionality of the smart contract can be affected as well. The unlimited creation of tokens can potentially cause the contract to become overloaded, leading to delays or even complete breakdowns in the system.
Diagram of possible exploit:
+---------------------------------------------------------------+ | | | Frankencoin | | | | +------------------+ +----------------+ +----------+ | | | Equity |<--->| Frankencoin |<--->| ERC20 | | | | (IReserve) | | (IFrankencoin)| | (Permit) | | | +------------------+ +----------------+ +----------+ | | ^ ^ | | | | | | +-----------+ +-----------+ | | | Minter 1| | Minter 2 | | | +-----------+ +-----------+ | | ^ ^ | | | | | | +---------------+ +----------------+ | | | Position 1 | | Position 2 | | | +---------------+ +----------------+ | | | | +-----------------------------+ | | | Compromised Minter Contract | | | +-----------------------------+ | | ^ | | | | | v | | +---------------+ +----------------+ | | | Exploit | | Unaffected | | | +---------------+ +----------------+ | | | +---------------------------------------------------------------+
The exploit takes advantage of the compromised minter contract, which allows an attacker to create and mint new Frankencoin
tokens without permission. The attacker can then use these tokens to manipulate the positions and gain a financial advantage.
If a minter contract is approved and the attacker gets access to the minter contract, they can mint as many Frankencoin
tokens as they want, thereby flooding the market with tokens and devaluing them.
Overall, the Frankencoin
exploit is a complex setup that involves multiple smart contracts and interactions between them. It is designed to give the attacker control over the creation and use of Frankencoin
tokens, which can then be used to manipulate the positions and gain a financial advantage.
Affected Code Block of the function: Frankencoin.sol#L83-90
function suggestMinter(address _minter, uint256 _applicationPeriod, uint256 _applicationFee, string calldata _message) override external { if (_applicationPeriod < MIN_APPLICATION_PERIOD && totalSupply() > 0) revert PeriodTooShort(); if (_applicationFee < MIN_FEE && totalSupply() > 0) revert FeeTooLow(); if (minters[_minter] != 0) revert AlreadyRegistered(); _transfer(msg.sender, address(reserve), _applicationFee); minters[_minter] = block.timestamp + _applicationPeriod; emit MinterApplied(_minter, _applicationPeriod, _applicationFee, _message); }
The suggestMinter
function above allows anyone to suggest a new minter contract by paying an application fee. If the application period and fee are sufficient and the _minter
contract has not been previously registered, the function stores the timestamp when the _minter
contract is approved in the minters mapping.
However, there is no mechanism to remove a registered _minter
contract from the minters mapping, the minterReserveE6
is reserved for minters and is continually filled with newly minted tokens. Therefore, a compromised _minter
contract can continue to mint tokens indefinitely, leading to potential inflation of the token.
While the suggestMinter function does include some checks to prevent certain types of attacks, it still does not include a mechanism to remove an approved minter contract from the minters mapping. Once a minter contract has been approved, it can continue to mint tokens indefinitely without any way to stop it, unless the contract itself includes a mechanism to revoke its own permission.
The if
statements in the function are simply additional checks to ensure that the application period and fee meet certain minimum requirements, and that the minter contract being suggested has not already been registered. These checks help prevent certain types of attacks, but they do not address the core vulnerability of allowing a minter contract
to mint tokens indefinitely without any way to revoke its permission.
Affected Line: #L88
minters[_minter] = block.timestamp + _applicationPeriod;
It's highly important to implement a mechanism to remove approved minter contracts, and the minters mapping should be updated to include a method to revoke a minter's approval. Additionally, the contract should have a limit on the maximum number of tokens that can be minted by an approved minter contract.
#0 - c4-pre-sort
2023-04-22T13:20:25Z
0xA5DF marked the issue as duplicate of #230
#1 - c4-judge
2023-05-18T13:41:46Z
hansfriese changed the severity to 2 (Med Risk)
#2 - c4-judge
2023-05-18T13:42:16Z
hansfriese marked the issue as satisfactory