mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #11392 from ethereum/evmc-transfer
EVMHost: Fix selfdestruct with non-zero value at beneficiary and value-transfers with insufficient funds
This commit is contained in:
commit
85552b58d8
@ -168,12 +168,19 @@ void EVMHost::reset()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EVMHost::transfer(evmc::MockedAccount& _sender, evmc::MockedAccount& _recipient, u256 const& _value) noexcept
|
||||||
|
{
|
||||||
|
assertThrow(u256(convertFromEVMC(_sender.balance)) >= _value, Exception, "Insufficient balance for transfer");
|
||||||
|
_sender.balance = convertToEVMC(u256(convertFromEVMC(_sender.balance)) - _value);
|
||||||
|
_recipient.balance = convertToEVMC(u256(convertFromEVMC(_recipient.balance)) + _value);
|
||||||
|
}
|
||||||
|
|
||||||
void EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _beneficiary) noexcept
|
void EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _beneficiary) noexcept
|
||||||
{
|
{
|
||||||
// TODO actual selfdestruct is even more complicated.
|
// TODO actual selfdestruct is even more complicated.
|
||||||
evmc::uint256be balance = accounts[_addr].balance;
|
|
||||||
|
transfer(accounts[_addr], accounts[_beneficiary], convertFromEVMC(accounts[_addr].balance));
|
||||||
accounts.erase(_addr);
|
accounts.erase(_addr);
|
||||||
accounts[_beneficiary].balance = balance;
|
|
||||||
// Record self destructs
|
// Record self destructs
|
||||||
recorded_selfdestructs.push_back({_addr, _beneficiary});
|
recorded_selfdestructs.push_back({_addr, _beneficiary});
|
||||||
}
|
}
|
||||||
@ -271,8 +278,14 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
|||||||
|
|
||||||
if (value != 0 && message.kind != EVMC_DELEGATECALL && message.kind != EVMC_CALLCODE)
|
if (value != 0 && message.kind != EVMC_DELEGATECALL && message.kind != EVMC_CALLCODE)
|
||||||
{
|
{
|
||||||
sender.balance = convertToEVMC(u256(convertFromEVMC(sender.balance)) - value);
|
if (value > convertFromEVMC(sender.balance))
|
||||||
destination.balance = convertToEVMC(u256(convertFromEVMC(destination.balance)) + value);
|
{
|
||||||
|
evmc::result result({});
|
||||||
|
result.status_code = EVMC_INSUFFICIENT_BALANCE;
|
||||||
|
accounts = stateBackup;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
transfer(sender, destination, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate the access access list.
|
// Populate the access access list.
|
||||||
|
@ -91,6 +91,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
evmc::address m_currentAddress = {};
|
evmc::address m_currentAddress = {};
|
||||||
|
|
||||||
|
void transfer(evmc::MockedAccount& _sender, evmc::MockedAccount& _recipient, u256 const& _value) noexcept;
|
||||||
|
|
||||||
/// Records calls made via @param _message.
|
/// Records calls made via @param _message.
|
||||||
void recordCalls(evmc_message const& _message) noexcept;
|
void recordCalls(evmc_message const& _message) noexcept;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user