VTVL contest - Franfran's results

Building no-code token management tools to empower web3 founders and investors, starting with token vesting.

General Information

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

VTVL

Findings Distribution

Researcher Performance

Rank: 196/198

Findings: 1

Award: $0.74

🌟 Selected for report: 0

🚀 Solo Findings: 0

Awards

0.7375 USDC - $0.74

Labels

bug
duplicate
2 (Med Risk)
old-submission-method

External Links

Lines of code

https://github.com/code-423n4/2022-09-vtvl/blob/main/contracts/token/VariableSupplyERC20Token.sol#L40

Vulnerability details

Impact

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.

Proof of Concept

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); } }

Tools Used

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

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter