From 89245adabca554747502e4294c838639468ef1f5 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 28 Aug 2024 17:01:37 +0200 Subject: [PATCH 1/3] Simplify _fetchDeployedCodeLen --- .../EvmInterpreterFunctions.template.yul | 23 ++++------ .../contracts/EvmInterpreterPreprocessed.yul | 46 +++++++------------ 2 files changed, 24 insertions(+), 45 deletions(-) diff --git a/system-contracts/contracts/EvmInterpreterFunctions.template.yul b/system-contracts/contracts/EvmInterpreterFunctions.template.yul index c6f7d0b2f..387885695 100644 --- a/system-contracts/contracts/EvmInterpreterFunctions.template.yul +++ b/system-contracts/contracts/EvmInterpreterFunctions.template.yul @@ -264,24 +264,17 @@ function _fetchDeployedCodeWithDest(addr, _offset, _len, dest) -> codeLen { function _fetchDeployedCodeLen(addr) -> codeLen { let codeHash := _getRawCodeHash(addr) - mstore(0, codeHash) - - let success := staticcall(gas(), CODE_ORACLE_SYSTEM_CONTRACT(), 0, 32, 0, 0) - - switch iszero(success) + switch shr(248, codeHash) case 1 { - // The code oracle call can only fail in the case where the contract - // we are querying is the current one executing and it has not yet been - // deployed, i.e., if someone calls codesize (or extcodesize(address())) - // inside the constructor. In that case, code length is zero. - codeLen := 0 + // EraVM + let codeLengthInWords := and(shr(224, codeHash), 0xffff) + codeLen := shl(5, codeLengthInWords) // codeLengthInWords * 32 } - default { - // The first word is the true length of the bytecode - returndatacopy(0, 0, 32) - codeLen := mload(0) + case 2 { + // EVM + let codeLengthInBytes := and(shr(224, codeHash), 0xffff) + codeLen := codeLengthInBytes } - } function getDeployedBytecode() { diff --git a/system-contracts/contracts/EvmInterpreterPreprocessed.yul b/system-contracts/contracts/EvmInterpreterPreprocessed.yul index 6d1fe6fe9..6caa979c2 100644 --- a/system-contracts/contracts/EvmInterpreterPreprocessed.yul +++ b/system-contracts/contracts/EvmInterpreterPreprocessed.yul @@ -333,24 +333,17 @@ object "EVMInterpreter" { function _fetchDeployedCodeLen(addr) -> codeLen { let codeHash := _getRawCodeHash(addr) - mstore(0, codeHash) - - let success := staticcall(gas(), CODE_ORACLE_SYSTEM_CONTRACT(), 0, 32, 0, 0) - - switch iszero(success) + switch shr(248, codeHash) case 1 { - // The code oracle call can only fail in the case where the contract - // we are querying is the current one executing and it has not yet been - // deployed, i.e., if someone calls codesize (or extcodesize(address())) - // inside the constructor. In that case, code length is zero. - codeLen := 0 + // EraVM + let codeLengthInWords := and(shr(224, codeHash), 0xffff) + codeLen := shl(5, codeLengthInWords) // codeLengthInWords * 32 } - default { - // The first word is the true length of the bytecode - returndatacopy(0, 0, 32) - codeLen := mload(0) + case 2 { + // EVM + let codeLengthInBytes := and(shr(224, codeHash), 0xffff) + codeLen := codeLengthInBytes } - } function getDeployedBytecode() { @@ -3299,24 +3292,17 @@ object "EVMInterpreter" { function _fetchDeployedCodeLen(addr) -> codeLen { let codeHash := _getRawCodeHash(addr) - mstore(0, codeHash) - - let success := staticcall(gas(), CODE_ORACLE_SYSTEM_CONTRACT(), 0, 32, 0, 0) - - switch iszero(success) + switch shr(248, codeHash) case 1 { - // The code oracle call can only fail in the case where the contract - // we are querying is the current one executing and it has not yet been - // deployed, i.e., if someone calls codesize (or extcodesize(address())) - // inside the constructor. In that case, code length is zero. - codeLen := 0 + // EraVM + let codeLengthInWords := and(shr(224, codeHash), 0xffff) + codeLen := shl(5, codeLengthInWords) // codeLengthInWords * 32 } - default { - // The first word is the true length of the bytecode - returndatacopy(0, 0, 32) - codeLen := mload(0) + case 2 { + // EVM + let codeLengthInBytes := and(shr(224, codeHash), 0xffff) + codeLen := codeLengthInBytes } - } function getDeployedBytecode() { From 448bc978c4f59558baf99538e508e035335fc93e Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 28 Aug 2024 17:09:29 +0200 Subject: [PATCH 2/3] Use _fetchDeployedCodeLen for both code types --- .../contracts/EvmInterpreterLoop.template.yul | 4 +--- system-contracts/contracts/EvmInterpreterPreprocessed.yul | 8 ++------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/system-contracts/contracts/EvmInterpreterLoop.template.yul b/system-contracts/contracts/EvmInterpreterLoop.template.yul index dc3346988..5880cd1f4 100644 --- a/system-contracts/contracts/EvmInterpreterLoop.template.yul +++ b/system-contracts/contracts/EvmInterpreterLoop.template.yul @@ -480,9 +480,7 @@ for { } true { } { evmGasLeft := chargeGas(evmGasLeft, 2500) } - switch _isEVM(addr) - case 0 { sp := pushStackItemWithoutCheck(sp, extcodesize(addr)) } - default { sp := pushStackItemWithoutCheck(sp, _fetchDeployedCodeLen(addr)) } + sp := pushStackItemWithoutCheck(sp, _fetchDeployedCodeLen(addr)) ip := add(ip, 1) } case 0x3C { // OP_EXTCODECOPY diff --git a/system-contracts/contracts/EvmInterpreterPreprocessed.yul b/system-contracts/contracts/EvmInterpreterPreprocessed.yul index 6caa979c2..654007bc3 100644 --- a/system-contracts/contracts/EvmInterpreterPreprocessed.yul +++ b/system-contracts/contracts/EvmInterpreterPreprocessed.yul @@ -2010,9 +2010,7 @@ object "EVMInterpreter" { evmGasLeft := chargeGas(evmGasLeft, 2500) } - switch _isEVM(addr) - case 0 { sp := pushStackItemWithoutCheck(sp, extcodesize(addr)) } - default { sp := pushStackItemWithoutCheck(sp, _fetchDeployedCodeLen(addr)) } + sp := pushStackItemWithoutCheck(sp, _fetchDeployedCodeLen(addr)) ip := add(ip, 1) } case 0x3C { // OP_EXTCODECOPY @@ -4969,9 +4967,7 @@ object "EVMInterpreter" { evmGasLeft := chargeGas(evmGasLeft, 2500) } - switch _isEVM(addr) - case 0 { sp := pushStackItemWithoutCheck(sp, extcodesize(addr)) } - default { sp := pushStackItemWithoutCheck(sp, _fetchDeployedCodeLen(addr)) } + sp := pushStackItemWithoutCheck(sp, _fetchDeployedCodeLen(addr)) ip := add(ip, 1) } case 0x3C { // OP_EXTCODECOPY From 253d370d7f506d59c15842695d9d68634018b819 Mon Sep 17 00:00:00 2001 From: Gianbelinche <39842759+gianbelinche@users.noreply.github.com> Date: Thu, 29 Aug 2024 10:45:43 -0300 Subject: [PATCH 3/3] [EVM-Equivalence-YUL] Restrict functions to only be called from interpreter (#745) Co-authored-by: IAvecilla Co-authored-by: Javier Chatruc --- .../contracts/ContractDeployer.sol | 21 +- system-contracts/contracts/EvmGasManager.sol | 9 +- system-contracts/contracts/EvmInterpreter.sol | 2 +- .../contracts/EvmInterpreter.template.yul | 15 +- .../EvmInterpreterFunctions.template.yul | 280 +++++---- .../contracts/EvmInterpreterPreprocessed.yul | 575 ++++++++++-------- system-contracts/contracts/NonceHolder.sol | 4 +- .../interfaces/IContractDeployer.sol | 2 - 8 files changed, 498 insertions(+), 410 deletions(-) diff --git a/system-contracts/contracts/ContractDeployer.sol b/system-contracts/contracts/ContractDeployer.sol index ba7a733de..3eeb09757 100644 --- a/system-contracts/contracts/ContractDeployer.sol +++ b/system-contracts/contracts/ContractDeployer.sol @@ -37,7 +37,13 @@ contract ContractDeployer is IContractDeployer, ISystemContract { uint256 public constructorReturnGas; - function setDeployedCode(uint256 constructorGasLeft, bytes calldata paddedNewDeployedCode) external { + modifier onlySystemEvm() { + require(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.isAccountEVM(msg.sender), "only system evm"); + require(SystemContractHelper.isSystemCall(), "This method require system call flag"); + _; + } + + function setDeployedCode(uint256 constructorGasLeft, bytes calldata paddedNewDeployedCode) external onlySystemEvm { require(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.isAccountEVM(msg.sender)); uint256 bytecodeLen = uint256(bytes32(paddedNewDeployedCode[:32])); @@ -185,9 +191,15 @@ contract ContractDeployer is IContractDeployer, ISystemContract { function createEVM(bytes calldata _initCode) external payable override returns (address) { // If the account is an EOA, use the min nonce. If it's a contract, use deployment nonce // Subtract 1 for EOA since the nonce has already been incremented for this transaction + + uint256 deploymentNonce = NONCE_HOLDER_SYSTEM_CONTRACT.getDeploymentNonce(msg.sender); + if ((msg.sender != tx.origin) && deploymentNonce == 0) { + NONCE_HOLDER_SYSTEM_CONTRACT.incrementDeploymentNonce(msg.sender); + } + uint256 senderNonce = msg.sender == tx.origin ? NONCE_HOLDER_SYSTEM_CONTRACT.getMinNonce(msg.sender) - 1 - : NONCE_HOLDER_SYSTEM_CONTRACT.incrementDeploymentNonce(msg.sender) + 1; + : NONCE_HOLDER_SYSTEM_CONTRACT.incrementDeploymentNonce(msg.sender); address newAddress = Utils.getNewAddressCreateEVM(msg.sender, senderNonce); _evmDeployOnAddress(newAddress, _initCode); return newAddress; @@ -209,11 +221,6 @@ contract ContractDeployer is IContractDeployer, ISystemContract { return newAddress; } - function createEVMInternal(address _newAddress, bytes calldata _initCode) external payable { - require(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.isAccountEVM(msg.sender)); - _evmDeployOnAddress(_newAddress, _initCode); - } - /// @notice Deploys a contract account with similar address derivation rules to the EVM's `CREATE2` opcode. /// @param _salt The CREATE2 salt /// @param _bytecodeHash The correctly formatted hash of the bytecode. diff --git a/system-contracts/contracts/EvmGasManager.sol b/system-contracts/contracts/EvmGasManager.sol index 57623e39e..549033c3c 100644 --- a/system-contracts/contracts/EvmGasManager.sol +++ b/system-contracts/contracts/EvmGasManager.sol @@ -4,6 +4,8 @@ pragma solidity ^0.8.0; import "./EvmConstants.sol"; import {ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT} from "./Constants.sol"; +import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; // We consider all the contracts (including system ones) as warm. uint160 constant PRECOMPILES_END = 0xffff; @@ -79,6 +81,7 @@ contract EvmGasManager { modifier onlySystemEvm() { require(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.isAccountEVM(msg.sender), "only system evm"); + require(SystemContractHelper.isSystemCall(), "This method require system call flag"); _; } @@ -123,13 +126,13 @@ contract EvmGasManager { */ - function pushEVMFrame(uint256 _passGas, bool _isStatic) external { + function pushEVMFrame(uint256 _passGas, bool _isStatic) external onlySystemEvm { EVMStackFrameInfo memory frame = EVMStackFrameInfo({passGas: _passGas, isStatic: _isStatic}); evmStackFrames.push(frame); } - function consumeEvmFrame() external returns (uint256 passGas, bool isStatic) { + function consumeEvmFrame() external onlySystemEvm returns (uint256 passGas, bool isStatic) { if (evmStackFrames.length == 0) return (INF_PASS_GAS, false); EVMStackFrameInfo memory frameInfo = evmStackFrames[evmStackFrames.length - 1]; @@ -141,7 +144,7 @@ contract EvmGasManager { evmStackFrames[evmStackFrames.length - 1].passGas = INF_PASS_GAS; } - function popEVMFrame() external { + function popEVMFrame() external onlySystemEvm { evmStackFrames.pop(); } } diff --git a/system-contracts/contracts/EvmInterpreter.sol b/system-contracts/contracts/EvmInterpreter.sol index 058601335..9350fa87c 100644 --- a/system-contracts/contracts/EvmInterpreter.sol +++ b/system-contracts/contracts/EvmInterpreter.sol @@ -980,7 +980,7 @@ contract EvmInterpreter { return (_createdAddress, _gasLeft); } - uint32 constant CREATE_EVM_INTERNAL_SELECTOR = uint32(DEPLOYER_SYSTEM_CONTRACT.createEVMInternal.selector); + uint32 constant CREATE_EVM_INTERNAL_SELECTOR = uint32(DEPLOYER_SYSTEM_CONTRACT.createEVM.selector); function _performCreateCall( address _deployedAddress, diff --git a/system-contracts/contracts/EvmInterpreter.template.yul b/system-contracts/contracts/EvmInterpreter.template.yul index 32ca6ed92..aec7ae61d 100644 --- a/system-contracts/contracts/EvmInterpreter.template.yul +++ b/system-contracts/contracts/EvmInterpreter.template.yul @@ -26,7 +26,20 @@ object "EVMInterpreter" { mstore(sub(offset, 64), 0x40) mstore(sub(offset, 32), len) - let success := call(gas(), DEPLOYER_SYSTEM_CONTRACT(), 0, sub(offset, 100), add(len, 100), 0, 0) + let farCallAbi := getFarCallABI( + 0, + 0, + sub(offset, 100), + add(len, 100), + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + let to := DEPLOYER_SYSTEM_CONTRACT() + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(success) { // This error should never happen diff --git a/system-contracts/contracts/EvmInterpreterFunctions.template.yul b/system-contracts/contracts/EvmInterpreterFunctions.template.yul index c6f7d0b2f..c4d566f2a 100644 --- a/system-contracts/contracts/EvmInterpreterFunctions.template.yul +++ b/system-contracts/contracts/EvmInterpreterFunctions.template.yul @@ -298,13 +298,28 @@ function consumeEvmFrame() -> passGas, isStatic, callerEVM { // function consumeEvmFrame() external returns (uint256 passGas, bool isStatic) mstore(0, 0x04C14E9E00000000000000000000000000000000000000000000000000000000) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 4, 0, 64) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 4, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + let to := EVM_GAS_MANAGER_CONTRACT() + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(success) { // Should never happen revert(0, 0) } + returndatacopy(0,0,64) + passGas := mload(0) isStatic := mload(32) @@ -566,13 +581,28 @@ function warmSlot(key,currentValue) -> isWarm, originalValue { mstore(4, key) mstore(36,currentValue) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 68, 0, 64) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 68, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + let to := EVM_GAS_MANAGER_CONTRACT() + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(success) { // This error should never happen revert(0, 0) } + returndatacopy(0, 0, 64) + isWarm := mload(0) originalValue := mload(32) } @@ -590,84 +620,50 @@ function isEOA(addr) -> ret { } } -function getNewAddress(addr) -> newAddr { - let digest, nonce, addressEncoded, nonceEncoded, nonceEncodedLength, listLength, listLengthEconded - - nonce := getNonce(addr) - - addressEncoded := and( - add(addr, shl(160, 0x94)), - 0xffffffffffffffffffffffffffffffffffffffffff - ) - - nonceEncoded := nonce - nonceEncodedLength := 1 - if iszero(nonce) { - nonceEncoded := 128 - } - switch gt(nonce, 0xFFFF) - case 1 { - switch gt(nonce, 0xFFFFFF) - case 1 { - // The nonce has 4 bytes - nonceEncoded := shl(32, 0x84) - nonceEncodedLength := 5 - } - default { - // The nonce has 3 bytes - nonceEncoded := shl(24, 0x83) - nonceEncodedLength := 4 - } - nonceEncoded := add(nonceEncoded, nonce) - } - default { - // The nonce has 2 bytes - if gt(nonce, 0xFF) { - nonceEncoded := shl(16, 0x82) - nonceEncoded := add(nonceEncoded, nonce) - nonceEncodedLength := 3 - } - // The nonce has 1 byte and it's in [0x80, 0xFF] - if and(gt(nonce, 0x7F), lt(nonce, 0x100)) { - nonceEncoded := shl(8, 0x81) - nonceEncoded := add(nonceEncoded, nonce) - nonceEncodedLength := 2 - } - } - - listLength := add(21, nonceEncodedLength) - listLengthEconded := add(listLength, 0xC0) - - let arrayLength := add(168, mul(8, nonceEncodedLength)) - - digest := add( - shl(arrayLength, listLengthEconded), - add( - shl( - mul(8, nonceEncodedLength), - addressEncoded - ), - nonceEncoded - ) - ) - - mstore(0, shl(sub(248, arrayLength), digest)) - - newAddr := and( - keccak256(0, add(div(arrayLength, 8), 1)), - 0xffffffffffffffffffffffffffffffffffffffff - ) -} - function incrementNonce(addr) { mstore(0, 0x306395C600000000000000000000000000000000000000000000000000000000) mstore(4, addr) - let result := call(gas(), NONCE_HOLDER_SYSTEM_CONTRACT(), 0, 0, 36, 0, 0) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 36, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + let to := NONCE_HOLDER_SYSTEM_CONTRACT() + let result := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(result) { revert(0, 0) } +} + +function getFarCallABI( + dataOffset, + memoryPage, + dataStart, + dataLength, + gasPassed, + shardId, + forwardingMode, + isConstructorCall, + isSystemCall +) -> ret { + let farCallAbi := 0 + farCallAbi := or(farCallAbi, dataOffset) + farCallAbi := or(farCallAbi, shl(64, dataStart)) + farCallAbi := or(farCallAbi, shl(96, dataLength)) + farCallAbi := or(farCallAbi, shl(192, gasPassed)) + farCallAbi := or(farCallAbi, shl(224, shardId)) + farCallAbi := or(farCallAbi, shl(232, forwardingMode)) + farCallAbi := or(farCallAbi, shl(248, 1)) + ret := farCallAbi } function ensureAcceptableMemLocation(location) { @@ -695,29 +691,30 @@ function $llvm_AlwaysInline_llvm$_warmAddress(addr) -> isWarm { mstore(0, 0x8DB2BA7800000000000000000000000000000000000000000000000000000000) mstore(4, addr) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 36, 0, 32) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 36, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + let to := EVM_GAS_MANAGER_CONTRACT() + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(success) { // This error should never happen revert(0, 0) } + returndatacopy(0, 0, 32) isWarm := mload(0) } -function getNonce(addr) -> nonce { - mstore(0, 0xFB1A9A5700000000000000000000000000000000000000000000000000000000) - mstore(4, addr) - - let result := staticcall(gas(), NONCE_HOLDER_SYSTEM_CONTRACT(), 0, 36, 0, 32) - - if iszero(result) { - revert(0, 0) - } - - nonce := mload(0) -} - function getRawNonce(addr) -> nonce { mstore(0, 0x5AA9B6B500000000000000000000000000000000000000000000000000000000) mstore(4, addr) @@ -758,7 +755,23 @@ function _pushEVMFrame(_passGas, _isStatic) { mstore(4, _passGas) mstore(36, _isStatic) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 68, 0, 0) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 68, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + + let to := EVM_GAS_MANAGER_CONTRACT() + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) + + // let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 68, 0, 0) if iszero(success) { // This error should never happen revert(0, 0) @@ -768,9 +781,24 @@ function _pushEVMFrame(_passGas, _isStatic) { function _popEVMFrame() { // function popEVMFrame() external + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 4, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + + let to := EVM_GAS_MANAGER_CONTRACT() + mstore(0, 0xE467D2F000000000000000000000000000000000000000000000000000000000) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 4, 0, 0) + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(success) { // This error should never happen revert(0, 0) @@ -1218,7 +1246,7 @@ function _fetchConstructorReturnGas() -> gasLeft { gasLeft := mload(0) } -function $llvm_NoInline_llvm$_genericCreate(addr, offset, size, sp, value, evmGasLeftOld) -> result, evmGasLeft { +function $llvm_NoInline_llvm$_genericCreate(offset, size, sp, value, evmGasLeftOld,isCreate2, salt) -> result, evmGasLeft, addr { pop($llvm_AlwaysInline_llvm$_warmAddress(addr)) _eraseReturndataPointer() @@ -1237,19 +1265,36 @@ function $llvm_NoInline_llvm$_genericCreate(addr, offset, size, sp, value, evmGa sp := pushStackItemWithoutCheck(sp, mload(sub(offset, 0x40))) sp := pushStackItemWithoutCheck(sp, mload(sub(offset, 0x20))) - // Selector - mstore(sub(offset, 0x80), 0x5b16a23c) - // Arg1: address - mstore(sub(offset, 0x60), addr) - // Arg2: init code - // Where the arg starts (third word) - mstore(sub(offset, 0x40), 0x40) - // Length of the init code - mstore(sub(offset, 0x20), size) - _pushEVMFrame(gasForTheCall, false) - result := call(INF_PASS_GAS(), DEPLOYER_SYSTEM_CONTRACT(), value, sub(offset, 0x64), add(size, 0x64), 0, 0) + if isCreate2 { + // Create2EVM selector + mstore(sub(offset, 0x80), 0x4e96f4c0) + // salt + mstore(sub(offset, 0x60), salt) + // Where the arg starts (third word) + mstore(sub(offset, 0x40), 0x40) + // Length of the init code + mstore(sub(offset, 0x20), size) + + + result := call(gas(), DEPLOYER_SYSTEM_CONTRACT(), value, sub(offset, 0x64), add(size, 0x64), 0, 32) + } + + + if iszero(isCreate2) { + // CreateEVM selector + mstore(sub(offset, 0x60), 0xff311601) + // Where the arg starts (second word) + mstore(sub(offset, 0x40), 0x20) + // Length of the init code + mstore(sub(offset, 0x20), size) + + + result := call(gas(), DEPLOYER_SYSTEM_CONTRACT(), value, sub(offset, 0x44), add(size, 0x44), 0, 32) + } + + addr := mload(0) let gasLeft switch result @@ -1259,24 +1304,12 @@ function $llvm_NoInline_llvm$_genericCreate(addr, offset, size, sp, value, evmGa default { gasLeft := _fetchConstructorReturnGas() } - + let gasUsed := sub(gasForTheCall, gasLeft) evmGasLeft := chargeGas(evmGasLeftOld, gasUsed) _popEVMFrame() - switch result - case 1 { - incrementNonce(address()) - } - default { - switch isEOA(address()) - case 1 { - incrementNonce(address()) - } - default {} - } - let back // skipping check since we pushed exactly 4 items earlier @@ -1394,10 +1427,8 @@ function performCreate(evmGas,oldSp,isStatic) -> evmGasLeft, sp { ) evmGasLeft := chargeGas(evmGasLeft, dynamicGas) - let addr := getNewAddress(address()) - - let result - result, evmGasLeft := $llvm_NoInline_llvm$_genericCreate(addr, offset, size, sp, value, evmGasLeft) + let result, addr + result, evmGasLeft, addr := $llvm_NoInline_llvm$_genericCreate(offset, size, sp, value, evmGasLeft,false,0) switch result case 0 { sp := pushStackItem(sp, 0, evmGasLeft) } @@ -1440,18 +1471,5 @@ function performCreate2(evmGas, oldSp, isStatic) -> evmGasLeft, sp, result, addr shr(2, add(size, 31)) )) - { - let hashedBytecode := keccak256(add(MEM_OFFSET_INNER(), offset), size) - mstore(0, 0xFF00000000000000000000000000000000000000000000000000000000000000) - mstore(0x01, shl(0x60, address())) - mstore(0x15, salt) - mstore(0x35, hashedBytecode) - } - - addr := and( - keccak256(0, 0x55), - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - ) - - result, evmGasLeft := $llvm_NoInline_llvm$_genericCreate(addr, offset, size, sp, value, evmGasLeft) + result, evmGasLeft, addr := $llvm_NoInline_llvm$_genericCreate(offset, size, sp, value, evmGasLeft,true,salt) } diff --git a/system-contracts/contracts/EvmInterpreterPreprocessed.yul b/system-contracts/contracts/EvmInterpreterPreprocessed.yul index 6d1fe6fe9..10678988e 100644 --- a/system-contracts/contracts/EvmInterpreterPreprocessed.yul +++ b/system-contracts/contracts/EvmInterpreterPreprocessed.yul @@ -26,7 +26,20 @@ object "EVMInterpreter" { mstore(sub(offset, 64), 0x40) mstore(sub(offset, 32), len) - let success := call(gas(), DEPLOYER_SYSTEM_CONTRACT(), 0, sub(offset, 100), add(len, 100), 0, 0) + let farCallAbi := getFarCallABI( + 0, + 0, + sub(offset, 100), + add(len, 100), + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + let to := DEPLOYER_SYSTEM_CONTRACT() + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(success) { // This error should never happen @@ -367,13 +380,28 @@ object "EVMInterpreter" { // function consumeEvmFrame() external returns (uint256 passGas, bool isStatic) mstore(0, 0x04C14E9E00000000000000000000000000000000000000000000000000000000) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 4, 0, 64) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 4, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + let to := EVM_GAS_MANAGER_CONTRACT() + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(success) { // Should never happen revert(0, 0) } + returndatacopy(0,0,64) + passGas := mload(0) isStatic := mload(32) @@ -635,13 +663,28 @@ object "EVMInterpreter" { mstore(4, key) mstore(36,currentValue) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 68, 0, 64) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 68, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + let to := EVM_GAS_MANAGER_CONTRACT() + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(success) { // This error should never happen revert(0, 0) } + returndatacopy(0, 0, 64) + isWarm := mload(0) originalValue := mload(32) } @@ -659,84 +702,50 @@ object "EVMInterpreter" { } } - function getNewAddress(addr) -> newAddr { - let digest, nonce, addressEncoded, nonceEncoded, nonceEncodedLength, listLength, listLengthEconded - - nonce := getNonce(addr) - - addressEncoded := and( - add(addr, shl(160, 0x94)), - 0xffffffffffffffffffffffffffffffffffffffffff - ) - - nonceEncoded := nonce - nonceEncodedLength := 1 - if iszero(nonce) { - nonceEncoded := 128 - } - switch gt(nonce, 0xFFFF) - case 1 { - switch gt(nonce, 0xFFFFFF) - case 1 { - // The nonce has 4 bytes - nonceEncoded := shl(32, 0x84) - nonceEncodedLength := 5 - } - default { - // The nonce has 3 bytes - nonceEncoded := shl(24, 0x83) - nonceEncodedLength := 4 - } - nonceEncoded := add(nonceEncoded, nonce) - } - default { - // The nonce has 2 bytes - if gt(nonce, 0xFF) { - nonceEncoded := shl(16, 0x82) - nonceEncoded := add(nonceEncoded, nonce) - nonceEncodedLength := 3 - } - // The nonce has 1 byte and it's in [0x80, 0xFF] - if and(gt(nonce, 0x7F), lt(nonce, 0x100)) { - nonceEncoded := shl(8, 0x81) - nonceEncoded := add(nonceEncoded, nonce) - nonceEncodedLength := 2 - } - } - - listLength := add(21, nonceEncodedLength) - listLengthEconded := add(listLength, 0xC0) - - let arrayLength := add(168, mul(8, nonceEncodedLength)) - - digest := add( - shl(arrayLength, listLengthEconded), - add( - shl( - mul(8, nonceEncodedLength), - addressEncoded - ), - nonceEncoded - ) - ) - - mstore(0, shl(sub(248, arrayLength), digest)) - - newAddr := and( - keccak256(0, add(div(arrayLength, 8), 1)), - 0xffffffffffffffffffffffffffffffffffffffff - ) - } - function incrementNonce(addr) { mstore(0, 0x306395C600000000000000000000000000000000000000000000000000000000) mstore(4, addr) - let result := call(gas(), NONCE_HOLDER_SYSTEM_CONTRACT(), 0, 0, 36, 0, 0) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 36, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + let to := NONCE_HOLDER_SYSTEM_CONTRACT() + let result := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(result) { revert(0, 0) } + } + + function getFarCallABI( + dataOffset, + memoryPage, + dataStart, + dataLength, + gasPassed, + shardId, + forwardingMode, + isConstructorCall, + isSystemCall + ) -> ret { + let farCallAbi := 0 + farCallAbi := or(farCallAbi, dataOffset) + farCallAbi := or(farCallAbi, shl(64, dataStart)) + farCallAbi := or(farCallAbi, shl(96, dataLength)) + farCallAbi := or(farCallAbi, shl(192, gasPassed)) + farCallAbi := or(farCallAbi, shl(224, shardId)) + farCallAbi := or(farCallAbi, shl(232, forwardingMode)) + farCallAbi := or(farCallAbi, shl(248, 1)) + ret := farCallAbi } function ensureAcceptableMemLocation(location) { @@ -764,29 +773,30 @@ object "EVMInterpreter" { mstore(0, 0x8DB2BA7800000000000000000000000000000000000000000000000000000000) mstore(4, addr) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 36, 0, 32) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 36, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + let to := EVM_GAS_MANAGER_CONTRACT() + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(success) { // This error should never happen revert(0, 0) } + returndatacopy(0, 0, 32) isWarm := mload(0) } - function getNonce(addr) -> nonce { - mstore(0, 0xFB1A9A5700000000000000000000000000000000000000000000000000000000) - mstore(4, addr) - - let result := staticcall(gas(), NONCE_HOLDER_SYSTEM_CONTRACT(), 0, 36, 0, 32) - - if iszero(result) { - revert(0, 0) - } - - nonce := mload(0) - } - function getRawNonce(addr) -> nonce { mstore(0, 0x5AA9B6B500000000000000000000000000000000000000000000000000000000) mstore(4, addr) @@ -827,7 +837,23 @@ object "EVMInterpreter" { mstore(4, _passGas) mstore(36, _isStatic) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 68, 0, 0) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 68, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + + let to := EVM_GAS_MANAGER_CONTRACT() + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) + + // let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 68, 0, 0) if iszero(success) { // This error should never happen revert(0, 0) @@ -837,9 +863,24 @@ object "EVMInterpreter" { function _popEVMFrame() { // function popEVMFrame() external + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 4, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + + let to := EVM_GAS_MANAGER_CONTRACT() + mstore(0, 0xE467D2F000000000000000000000000000000000000000000000000000000000) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 4, 0, 0) + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(success) { // This error should never happen revert(0, 0) @@ -1287,7 +1328,7 @@ object "EVMInterpreter" { gasLeft := mload(0) } - function $llvm_NoInline_llvm$_genericCreate(addr, offset, size, sp, value, evmGasLeftOld) -> result, evmGasLeft { + function $llvm_NoInline_llvm$_genericCreate(offset, size, sp, value, evmGasLeftOld,isCreate2, salt) -> result, evmGasLeft, addr { pop($llvm_AlwaysInline_llvm$_warmAddress(addr)) _eraseReturndataPointer() @@ -1306,19 +1347,36 @@ object "EVMInterpreter" { sp := pushStackItemWithoutCheck(sp, mload(sub(offset, 0x40))) sp := pushStackItemWithoutCheck(sp, mload(sub(offset, 0x20))) - // Selector - mstore(sub(offset, 0x80), 0x5b16a23c) - // Arg1: address - mstore(sub(offset, 0x60), addr) - // Arg2: init code - // Where the arg starts (third word) - mstore(sub(offset, 0x40), 0x40) - // Length of the init code - mstore(sub(offset, 0x20), size) - _pushEVMFrame(gasForTheCall, false) - result := call(INF_PASS_GAS(), DEPLOYER_SYSTEM_CONTRACT(), value, sub(offset, 0x64), add(size, 0x64), 0, 0) + if isCreate2 { + // Create2EVM selector + mstore(sub(offset, 0x80), 0x4e96f4c0) + // salt + mstore(sub(offset, 0x60), salt) + // Where the arg starts (third word) + mstore(sub(offset, 0x40), 0x40) + // Length of the init code + mstore(sub(offset, 0x20), size) + + + result := call(gas(), DEPLOYER_SYSTEM_CONTRACT(), value, sub(offset, 0x64), add(size, 0x64), 0, 32) + } + + + if iszero(isCreate2) { + // CreateEVM selector + mstore(sub(offset, 0x60), 0xff311601) + // Where the arg starts (second word) + mstore(sub(offset, 0x40), 0x20) + // Length of the init code + mstore(sub(offset, 0x20), size) + + + result := call(gas(), DEPLOYER_SYSTEM_CONTRACT(), value, sub(offset, 0x44), add(size, 0x44), 0, 32) + } + + addr := mload(0) let gasLeft switch result @@ -1328,24 +1386,12 @@ object "EVMInterpreter" { default { gasLeft := _fetchConstructorReturnGas() } - + let gasUsed := sub(gasForTheCall, gasLeft) evmGasLeft := chargeGas(evmGasLeftOld, gasUsed) _popEVMFrame() - switch result - case 1 { - incrementNonce(address()) - } - default { - switch isEOA(address()) - case 1 { - incrementNonce(address()) - } - default {} - } - let back // skipping check since we pushed exactly 4 items earlier @@ -1463,10 +1509,8 @@ object "EVMInterpreter" { ) evmGasLeft := chargeGas(evmGasLeft, dynamicGas) - let addr := getNewAddress(address()) - - let result - result, evmGasLeft := $llvm_NoInline_llvm$_genericCreate(addr, offset, size, sp, value, evmGasLeft) + let result, addr + result, evmGasLeft, addr := $llvm_NoInline_llvm$_genericCreate(offset, size, sp, value, evmGasLeft,false,0) switch result case 0 { sp := pushStackItem(sp, 0, evmGasLeft) } @@ -1509,20 +1553,7 @@ object "EVMInterpreter" { shr(2, add(size, 31)) )) - { - let hashedBytecode := keccak256(add(MEM_OFFSET_INNER(), offset), size) - mstore(0, 0xFF00000000000000000000000000000000000000000000000000000000000000) - mstore(0x01, shl(0x60, address())) - mstore(0x15, salt) - mstore(0x35, hashedBytecode) - } - - addr := and( - keccak256(0, 0x55), - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - ) - - result, evmGasLeft := $llvm_NoInline_llvm$_genericCreate(addr, offset, size, sp, value, evmGasLeft) + result, evmGasLeft, addr := $llvm_NoInline_llvm$_genericCreate(offset, size, sp, value, evmGasLeft,true,salt) } @@ -3333,13 +3364,28 @@ object "EVMInterpreter" { // function consumeEvmFrame() external returns (uint256 passGas, bool isStatic) mstore(0, 0x04C14E9E00000000000000000000000000000000000000000000000000000000) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 4, 0, 64) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 4, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + let to := EVM_GAS_MANAGER_CONTRACT() + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(success) { // Should never happen revert(0, 0) } + returndatacopy(0,0,64) + passGas := mload(0) isStatic := mload(32) @@ -3601,13 +3647,28 @@ object "EVMInterpreter" { mstore(4, key) mstore(36,currentValue) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 68, 0, 64) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 68, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + let to := EVM_GAS_MANAGER_CONTRACT() + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(success) { // This error should never happen revert(0, 0) } + returndatacopy(0, 0, 64) + isWarm := mload(0) originalValue := mload(32) } @@ -3625,84 +3686,50 @@ object "EVMInterpreter" { } } - function getNewAddress(addr) -> newAddr { - let digest, nonce, addressEncoded, nonceEncoded, nonceEncodedLength, listLength, listLengthEconded - - nonce := getNonce(addr) - - addressEncoded := and( - add(addr, shl(160, 0x94)), - 0xffffffffffffffffffffffffffffffffffffffffff - ) - - nonceEncoded := nonce - nonceEncodedLength := 1 - if iszero(nonce) { - nonceEncoded := 128 - } - switch gt(nonce, 0xFFFF) - case 1 { - switch gt(nonce, 0xFFFFFF) - case 1 { - // The nonce has 4 bytes - nonceEncoded := shl(32, 0x84) - nonceEncodedLength := 5 - } - default { - // The nonce has 3 bytes - nonceEncoded := shl(24, 0x83) - nonceEncodedLength := 4 - } - nonceEncoded := add(nonceEncoded, nonce) - } - default { - // The nonce has 2 bytes - if gt(nonce, 0xFF) { - nonceEncoded := shl(16, 0x82) - nonceEncoded := add(nonceEncoded, nonce) - nonceEncodedLength := 3 - } - // The nonce has 1 byte and it's in [0x80, 0xFF] - if and(gt(nonce, 0x7F), lt(nonce, 0x100)) { - nonceEncoded := shl(8, 0x81) - nonceEncoded := add(nonceEncoded, nonce) - nonceEncodedLength := 2 - } - } - - listLength := add(21, nonceEncodedLength) - listLengthEconded := add(listLength, 0xC0) - - let arrayLength := add(168, mul(8, nonceEncodedLength)) - - digest := add( - shl(arrayLength, listLengthEconded), - add( - shl( - mul(8, nonceEncodedLength), - addressEncoded - ), - nonceEncoded - ) - ) - - mstore(0, shl(sub(248, arrayLength), digest)) - - newAddr := and( - keccak256(0, add(div(arrayLength, 8), 1)), - 0xffffffffffffffffffffffffffffffffffffffff - ) - } - function incrementNonce(addr) { mstore(0, 0x306395C600000000000000000000000000000000000000000000000000000000) mstore(4, addr) - let result := call(gas(), NONCE_HOLDER_SYSTEM_CONTRACT(), 0, 0, 36, 0, 0) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 36, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + let to := NONCE_HOLDER_SYSTEM_CONTRACT() + let result := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(result) { revert(0, 0) } + } + + function getFarCallABI( + dataOffset, + memoryPage, + dataStart, + dataLength, + gasPassed, + shardId, + forwardingMode, + isConstructorCall, + isSystemCall + ) -> ret { + let farCallAbi := 0 + farCallAbi := or(farCallAbi, dataOffset) + farCallAbi := or(farCallAbi, shl(64, dataStart)) + farCallAbi := or(farCallAbi, shl(96, dataLength)) + farCallAbi := or(farCallAbi, shl(192, gasPassed)) + farCallAbi := or(farCallAbi, shl(224, shardId)) + farCallAbi := or(farCallAbi, shl(232, forwardingMode)) + farCallAbi := or(farCallAbi, shl(248, 1)) + ret := farCallAbi } function ensureAcceptableMemLocation(location) { @@ -3730,29 +3757,30 @@ object "EVMInterpreter" { mstore(0, 0x8DB2BA7800000000000000000000000000000000000000000000000000000000) mstore(4, addr) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 36, 0, 32) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 36, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + let to := EVM_GAS_MANAGER_CONTRACT() + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(success) { // This error should never happen revert(0, 0) } + returndatacopy(0, 0, 32) isWarm := mload(0) } - function getNonce(addr) -> nonce { - mstore(0, 0xFB1A9A5700000000000000000000000000000000000000000000000000000000) - mstore(4, addr) - - let result := staticcall(gas(), NONCE_HOLDER_SYSTEM_CONTRACT(), 0, 36, 0, 32) - - if iszero(result) { - revert(0, 0) - } - - nonce := mload(0) - } - function getRawNonce(addr) -> nonce { mstore(0, 0x5AA9B6B500000000000000000000000000000000000000000000000000000000) mstore(4, addr) @@ -3793,7 +3821,23 @@ object "EVMInterpreter" { mstore(4, _passGas) mstore(36, _isStatic) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 68, 0, 0) + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 68, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + + let to := EVM_GAS_MANAGER_CONTRACT() + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) + + // let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 68, 0, 0) if iszero(success) { // This error should never happen revert(0, 0) @@ -3803,9 +3847,24 @@ object "EVMInterpreter" { function _popEVMFrame() { // function popEVMFrame() external + let farCallAbi := getFarCallABI( + 0, + 0, + 0, + 4, + gas(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) + + let to := EVM_GAS_MANAGER_CONTRACT() + mstore(0, 0xE467D2F000000000000000000000000000000000000000000000000000000000) - let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 4, 0, 0) + let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) if iszero(success) { // This error should never happen revert(0, 0) @@ -4253,7 +4312,7 @@ object "EVMInterpreter" { gasLeft := mload(0) } - function $llvm_NoInline_llvm$_genericCreate(addr, offset, size, sp, value, evmGasLeftOld) -> result, evmGasLeft { + function $llvm_NoInline_llvm$_genericCreate(offset, size, sp, value, evmGasLeftOld,isCreate2, salt) -> result, evmGasLeft, addr { pop($llvm_AlwaysInline_llvm$_warmAddress(addr)) _eraseReturndataPointer() @@ -4272,19 +4331,36 @@ object "EVMInterpreter" { sp := pushStackItemWithoutCheck(sp, mload(sub(offset, 0x40))) sp := pushStackItemWithoutCheck(sp, mload(sub(offset, 0x20))) - // Selector - mstore(sub(offset, 0x80), 0x5b16a23c) - // Arg1: address - mstore(sub(offset, 0x60), addr) - // Arg2: init code - // Where the arg starts (third word) - mstore(sub(offset, 0x40), 0x40) - // Length of the init code - mstore(sub(offset, 0x20), size) - _pushEVMFrame(gasForTheCall, false) - result := call(INF_PASS_GAS(), DEPLOYER_SYSTEM_CONTRACT(), value, sub(offset, 0x64), add(size, 0x64), 0, 0) + if isCreate2 { + // Create2EVM selector + mstore(sub(offset, 0x80), 0x4e96f4c0) + // salt + mstore(sub(offset, 0x60), salt) + // Where the arg starts (third word) + mstore(sub(offset, 0x40), 0x40) + // Length of the init code + mstore(sub(offset, 0x20), size) + + + result := call(gas(), DEPLOYER_SYSTEM_CONTRACT(), value, sub(offset, 0x64), add(size, 0x64), 0, 32) + } + + + if iszero(isCreate2) { + // CreateEVM selector + mstore(sub(offset, 0x60), 0xff311601) + // Where the arg starts (second word) + mstore(sub(offset, 0x40), 0x20) + // Length of the init code + mstore(sub(offset, 0x20), size) + + + result := call(gas(), DEPLOYER_SYSTEM_CONTRACT(), value, sub(offset, 0x44), add(size, 0x44), 0, 32) + } + + addr := mload(0) let gasLeft switch result @@ -4294,24 +4370,12 @@ object "EVMInterpreter" { default { gasLeft := _fetchConstructorReturnGas() } - + let gasUsed := sub(gasForTheCall, gasLeft) evmGasLeft := chargeGas(evmGasLeftOld, gasUsed) _popEVMFrame() - switch result - case 1 { - incrementNonce(address()) - } - default { - switch isEOA(address()) - case 1 { - incrementNonce(address()) - } - default {} - } - let back // skipping check since we pushed exactly 4 items earlier @@ -4429,10 +4493,8 @@ object "EVMInterpreter" { ) evmGasLeft := chargeGas(evmGasLeft, dynamicGas) - let addr := getNewAddress(address()) - - let result - result, evmGasLeft := $llvm_NoInline_llvm$_genericCreate(addr, offset, size, sp, value, evmGasLeft) + let result, addr + result, evmGasLeft, addr := $llvm_NoInline_llvm$_genericCreate(offset, size, sp, value, evmGasLeft,false,0) switch result case 0 { sp := pushStackItem(sp, 0, evmGasLeft) } @@ -4475,20 +4537,7 @@ object "EVMInterpreter" { shr(2, add(size, 31)) )) - { - let hashedBytecode := keccak256(add(MEM_OFFSET_INNER(), offset), size) - mstore(0, 0xFF00000000000000000000000000000000000000000000000000000000000000) - mstore(0x01, shl(0x60, address())) - mstore(0x15, salt) - mstore(0x35, hashedBytecode) - } - - addr := and( - keccak256(0, 0x55), - 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF - ) - - result, evmGasLeft := $llvm_NoInline_llvm$_genericCreate(addr, offset, size, sp, value, evmGasLeft) + result, evmGasLeft, addr := $llvm_NoInline_llvm$_genericCreate(offset, size, sp, value, evmGasLeft,true,salt) } diff --git a/system-contracts/contracts/NonceHolder.sol b/system-contracts/contracts/NonceHolder.sol index 3df337f1a..61aebc207 100644 --- a/system-contracts/contracts/NonceHolder.sol +++ b/system-contracts/contracts/NonceHolder.sol @@ -134,10 +134,10 @@ contract NonceHolder is INonceHolder, ISystemContract { /// @return prevDeploymentNonce The deployment nonce at the time this function is called. function incrementDeploymentNonce(address _address) external returns (uint256 prevDeploymentNonce) { require( - msg.sender == address(DEPLOYER_SYSTEM_CONTRACT) || - ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.isAccountEVM(msg.sender), + msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), "Only the contract deployer can increment the deployment nonce" ); + uint256 addressAsKey = uint256(uint160(_address)); uint256 oldRawNonce = rawNonces[addressAsKey]; diff --git a/system-contracts/contracts/interfaces/IContractDeployer.sol b/system-contracts/contracts/interfaces/IContractDeployer.sol index 0aa2155fd..b9e095a29 100644 --- a/system-contracts/contracts/interfaces/IContractDeployer.sol +++ b/system-contracts/contracts/interfaces/IContractDeployer.sol @@ -115,8 +115,6 @@ interface IContractDeployer { function create2EVM(bytes32 _salt, bytes calldata _initCode) external payable returns (address); - function createEVMInternal(address _newAddress, bytes calldata _initCode) external payable; - function evmCodeHash(address) external view returns (bytes32); // TODO: this is a hack before rewriting to assembly.