Platform: Code4rena
Start Date: 20/09/2022
Pot Size: $30,000 USDC
Total HM: 12
Participants: 198
Period: 3 days
Judge: 0xean
Total Solo HM: 2
Id: 164
League: ETH
Rank: 196/198
Findings: 1
Award: $0.74
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Czar102
Also found by: 0xDecorativePineapple, 0xNazgul, 0xSky, 0xbepresent, 0xmatt, Atarpara, Bahurum, DimitarDimitrov, Franfran, GimelSec, JGcarv, JLevick, Junnon, OptimismSec, Rolezn, Ruhum, Soosh, Tomo, Trust, __141345__, adriro, ajtra, bin2chen, cRat1st0s, cccz, cryptonue, d3e4, innertia, jag, joestakey, neumo, obront, pashov, pauliax, pcarranzav, peanuts, rajatbeladiya, rbserver, reassor, seyni, wagmi, zzykxx, zzzitron
0.7375 USDC - $0.74
The owner of the VariableSupplyERC20Token
can mint an infinite amount of tokens, even if it was deployed as a "fixed supply" ERC20 token because of a wrong logic in the contract.
In order to do this, just create a contract with a fixed supply (with maxSupply_ > 0)
Then mint some tokens to reduce mintableSupply
to 0 (So minting mintableSupply)
Now the if(mintableSupply > 0) {
is never reached because mintableSupply
is 0.
//SPDX-License-Identifier: Unlicense pragma solidity 0.8.14; import "../../contracts/token/VariableSupplyERC20Token.sol"; import "forge-std/Test.sol"; contract VariableToken is Test { VariableSupplyERC20Token t; uint maxSupply = 1_000_000 ether; function setUp() public { t = new VariableSupplyERC20Token("TEST", "TestToken", 0, maxSupply); } function testInfinite() public { assertEq(t.mintableSupply(), maxSupply); t.mint(address(this), maxSupply); assertEq(t.balanceOf(address(this)), maxSupply); assertEq(t.mintableSupply(), 0); uint256 bigAmount = 1_234_567 ether; t.mint(address(this), bigAmount); assertEq(t.balanceOf(address(this)), maxSupply + bigAmount); } }
helix
Add a boolean that switches on or off the state of the contract supply, either variable or infinite, that could look like that:
bool public isVariable; constructor(string memory name_, string memory symbol_, uint256 initialSupply_, uint256 maxSupply_) ERC20(name_, symbol_) { require(initialSupply_ > 0 || maxSupply_ > 0, "INVALID_AMOUNT"); if (maxSupply_ > 0) { isVariable = true; mintableSupply = maxSupply_; } if(initialSupply_ > 0) { mint(_msgSender(), initialSupply_); } }
And then add a check in the mint()
function
if(mintableSupply > 0 && isVariable) { .... }
#0 - 0xean
2022-09-24T00:35:19Z
dupe of #3