stdError.arithmeticError
Original Implementation
function withdraw(uint amount) external {
require(balances[msg.sender] >= amount, "Insufficient balance!");
emit Withdrawal(msg.sender, amount);
balances[msg.sender] -= amount;
(bool success) = wmdToken.transfer(address(this), amount);
require(success, "Token transfer frm User to Vendor failed!");
}
function testUserCannotWithdraw(uint amount) public {
console2.log("User cannot withdraw with no balance");
vm.assume(amount > 0);
vm.prank(user);
vm.expectRevert("Insufficient balance!");
vault.withdraw(amount);
}
Alberto said:
testUserCannotWithdraw and testUserCannotWithdrawExcessDeposit should revert because of underflow in balances[msg.sender], not because of ERC20 properties.
Richie elaborated:
Alberto said he wanted to see this revert because of the underflow, not because of the erc20 balance. so u can:
make sure the user has an balance of the token
change this to vm.assume
(amount > 0 && amount < wmd.balanceOf(user))
instead of expectRevert -- use forge-std standard errors https://book.getfoundry.sh/reference/forge-std/std-errors.html
Correct Implementation
function withdraw(uint amount) external {
balances[msg.sender] -= amount;
bool success = wmdToken.transfer(msg.sender, amount);
require(success, "Withdrawal failed!");
emit Withdrawal(msg.sender, amount);
}
function testFuzzUserCannotWithdraw(uint amount) public {
console2.log("User cannot withdraw with no balance");
vm.startPrank(user);
wmd.mint(user, amount);
vm.assume(amount > 0 && amount < wmd.balanceOf(user));
vm.expectRevert(stdError.arithmeticError);
vault.withdraw(amount);
vm.stopPrank();
}
The takeaway here is that:
the user has some wmd tokens.
he will attempt to withdraw some tokens within the range (0, amount), from the vault
since he does not have any deposits to begin with, we run into an underflow error, resulting from:
balances[msg.sender] -= amount;
as this is going to work out to subtracting a positive figure (amount) from 0 -> hence underflow.
Last updated