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: