Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Invalid

Unchecked Overflow and Underflow in Solmate ERC20::_burn() & ERC20::_mint() respectively

Summary

The Solmate ERC20 code that is being imported in SantaToken.sol contract, has underflow vulnerability in the _burn function and overflow vulnerability in _mint. Since, SantaToken contract is importing this ERC20 contract, the vulnerability will also affect that (SantaToken) contract.

Vulnerability Details

Since the balance is checked against totalSupply, it is unlikely to underflow or overflow in a correctly implemented burn and mint mechanism. But it never hurts to be careful.

Since Solidity 0.8.0 includes automatic overflow/underflow checks, this would revert in case of an overflow/underflow. However, the unchecked block is used, which disables these checks.

In the _burn function, the balance of the burner is decreased by the amount being burned. If the burner's balance is less than the amount being burned, an underflow will occur, and the burner's balance will wrap around to the maximum possible value. This is also a serious vulnerability because it allows the burner to burn more tokens than they actually have.

In the _mint function, the total supply of the token is increased by the amount being minted. If the amount being minted is added to the total supply, an overflow will occur if the total supply is already at the maximum possible value for a uint256. This is a serious vulnerability because it allows the total supply to exceed the maximum possible value, which could lead to unexpected behavior in other parts of the contract that rely on the total supply.

The _mint function also increases the balance of the recipient by the amount being minted. If the recipient's balance is already at the maximum possible value for a uint256, an overflow will occur when the amount being minted is added to the recipient's balance. This is another serious vulnerability because it allows the recipient's balance to exceed the maximum possible value, which could lead to unexpected behavior in other parts of the contract that rely on the recipient's balance.

Impact

Depending on the value assigned to a variable, and depending on whether the value assigned goes above or below a certain threshold, the code could end up giving unexpected results. This unexpected OVERFLOW and UNDERFLOW will result in unexpected and wrong calculations, which in turn will result in wrong data being used and presented to the users.

Tools Used

Manual review.

Recommendations

Two ways to fix this: Remove Unchecked Block & Use SafeMath.
(NOTE - can also use a different library or mechanism)

Removing the unchecked block:

  1. Modify _burn function:

function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
// Cannot underflow because a user's balance
// will never be larger than the total supply.
- unchecked {
- totalSupply -= amount;
- }
+ totalSupply -= amount;
emit Transfer(from, address(0), amount);
}
  1. Modify _mint function:

function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
- unchecked {
- balanceOf[to] += amount;
- }
+ balanceOf[to] += amount;
emit Transfer(address(0), to, amount);
}

Further secure with SafeMath:
We can use the sub and add function from the SafeMath library, which reverts the transaction if an underflow and overflow occurs.

Here is the corrected code:

  1. Import SafeMath from Openzeppelin:

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
  1. Mention this inside the contract:

using SafeMath for uint256;
  1. Modify _burn function:

function _burn(address from, uint256 amount) internal virtual {
- balanceOf[from] -= amount;
+ balanceOf[from] = balanceOf[from].sub(amount);
- totalSupply -= amount;
+ totalSupply = totalSupply.sub(amount);
emit Transfer(from, address(0), amount);
}
  1. Modify _mint function:

function _mint(address to, uint256 amount) internal virtual {
- totalSupply += amount;
+ totalSupply = totalSupply.add(amount);
- balanceOf[to] += amount;
+ balanceOf[to] = balanceOf[to].add(amount);
emit Transfer(address(0), to, amount);
}

In this version of the contract, the add and sub function from the SafeMath library will revert the transaction if any overflow and underflow occurs.

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 2 years ago
inallhonesty Lead Judge about 2 years ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!