Solidity – Fixing Arithmetic Operation Overflow/Underflow in Hardhat Test

hardhatsoliditysolidity-0.8.xunittesting

I created a vault contract in solidity v0.8.11:

struct User {
  uint256 totalAmount;
}

mapping(address => mapping(address => User)) Users;

function withdraw(
   address _token,
   address _user,
   uint256 _amount
) external {
   User storage user = Users[_token][_user];
   user.totalAmount -= _amount;

   // transfer access token amount to the user
   IERC20(_token).safeTransfer(_user, _amount);
}

When I call withdraw() in the hardhat test script, I get this error:
Error: VM Exception while processing transaction: reverted with panic code 0x11 (Arithmetic operation underflowed or overflowed outside of an unchecked block)

The contract A has 250000 token, the user's totalAmount is also 250000, and I tried to withdraw 50000 token from this contract.

I already know about solution which uses unchecked { ... }, but it doesn't change the userPositoin.totalAmount.

I can't understand why this happens. Please help me if you have a experience in such case.

Best Answer

My guess would be Users[_token][_user] wasn't actually set then the operation user.totalAmount -= _amount; resulted in an underflow (i.e. 0 - 50000)

It costs some gas, but maybe just put a simple require:

require(user.totalAmount >= _amount, "Empty wallet");