diff --git a/system-contracts/contracts/EvmEmulator.yul b/system-contracts/contracts/EvmEmulator.yul index f9a9c0d75..27913afc0 100644 --- a/system-contracts/contracts/EvmEmulator.yul +++ b/system-contracts/contracts/EvmEmulator.yul @@ -296,6 +296,12 @@ object "EvmEmulator" { } } + function insufficientBalance(value) -> res { + if value { + res := gt(value, selfbalance()) + } + } + // It is the responsibility of the caller to ensure that ip is correct function readIP(ip, bytecodeEndOffset) -> opcode { if lt(ip, bytecodeEndOffset) { @@ -817,12 +823,19 @@ object "EvmEmulator" { } } default { - pushEvmFrame(gasToPass, isStatic) - // pass all remaining native gas - success := call(gas(), addr, value, argsOffset, argsSize, 0, 0) - frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) - if iszero(success) { - resetEvmFrame() + switch insufficientBalance(value) + case 0 { + pushEvmFrame(gasToPass, isStatic) + // pass all remaining native gas + success := call(gas(), addr, value, argsOffset, argsSize, 0, 0) + frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) + if iszero(success) { + resetEvmFrame() + } + } + default { + frameGasLeft := gasToPass + _eraseReturndataPointer() } } } @@ -1053,12 +1066,7 @@ object "EvmEmulator" { _eraseReturndataPointer() - let err := 0 - if value { - if gt(value, selfbalance()) { - err := 1 - } - } + let err := insufficientBalance(value) if iszero(err) { offset := add(MEM_OFFSET(), offset) // caller must ensure that it doesn't overflow @@ -3344,6 +3352,12 @@ object "EvmEmulator" { } } + function insufficientBalance(value) -> res { + if value { + res := gt(value, selfbalance()) + } + } + // It is the responsibility of the caller to ensure that ip is correct function readIP(ip, bytecodeEndOffset) -> opcode { if lt(ip, bytecodeEndOffset) { @@ -3865,12 +3879,19 @@ object "EvmEmulator" { } } default { - pushEvmFrame(gasToPass, isStatic) - // pass all remaining native gas - success := call(gas(), addr, value, argsOffset, argsSize, 0, 0) - frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) - if iszero(success) { - resetEvmFrame() + switch insufficientBalance(value) + case 0 { + pushEvmFrame(gasToPass, isStatic) + // pass all remaining native gas + success := call(gas(), addr, value, argsOffset, argsSize, 0, 0) + frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) + if iszero(success) { + resetEvmFrame() + } + } + default { + frameGasLeft := gasToPass + _eraseReturndataPointer() } } } @@ -4101,12 +4122,7 @@ object "EvmEmulator" { _eraseReturndataPointer() - let err := 0 - if value { - if gt(value, selfbalance()) { - err := 1 - } - } + let err := insufficientBalance(value) if iszero(err) { offset := add(MEM_OFFSET(), offset) // caller must ensure that it doesn't overflow diff --git a/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul b/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul index 58736a58d..68c96ef2a 100644 --- a/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul +++ b/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul @@ -234,6 +234,12 @@ function checkOverflow(data1, data2) { } } +function insufficientBalance(value) -> res { + if value { + res := gt(value, selfbalance()) + } +} + // It is the responsibility of the caller to ensure that ip is correct function readIP(ip, bytecodeEndOffset) -> opcode { if lt(ip, bytecodeEndOffset) { @@ -755,12 +761,19 @@ function _genericCall(addr, gasToPass, value, argsOffset, argsSize, retOffset, r } } default { - pushEvmFrame(gasToPass, isStatic) - // pass all remaining native gas - success := call(gas(), addr, value, argsOffset, argsSize, 0, 0) - frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) - if iszero(success) { - resetEvmFrame() + switch insufficientBalance(value) + case 0 { + pushEvmFrame(gasToPass, isStatic) + // pass all remaining native gas + success := call(gas(), addr, value, argsOffset, argsSize, 0, 0) + frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) + if iszero(success) { + resetEvmFrame() + } + } + default { + frameGasLeft := gasToPass + _eraseReturndataPointer() } } } @@ -991,12 +1004,7 @@ function $llvm_NoInline_llvm$_genericCreate(offset, size, value, evmGasLeftOld, _eraseReturndataPointer() - let err := 0 - if value { - if gt(value, selfbalance()) { - err := 1 - } - } + let err := insufficientBalance(value) if iszero(err) { offset := add(MEM_OFFSET(), offset) // caller must ensure that it doesn't overflow