diff --git a/system-contracts/contracts/ContractDeployer.sol b/system-contracts/contracts/ContractDeployer.sol index ba7a733de..e958cb057 100644 --- a/system-contracts/contracts/ContractDeployer.sol +++ b/system-contracts/contracts/ContractDeployer.sol @@ -37,7 +37,12 @@ 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"); + _; + } + + function setDeployedCode(uint256 constructorGasLeft, bytes calldata paddedNewDeployedCode) onlySystemCall onlySystemEvm external { require(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.isAccountEVM(msg.sender)); uint256 bytecodeLen = uint256(bytes32(paddedNewDeployedCode[:32])); @@ -209,8 +214,7 @@ 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)); + function createEVMInternal(address _newAddress, bytes calldata _initCode) onlySystemCall onlySystemEvm external payable { _evmDeployOnAddress(_newAddress, _initCode); } diff --git a/system-contracts/contracts/EvmGasManager.sol b/system-contracts/contracts/EvmGasManager.sol index 57623e39e..44f4dc920 100644 --- a/system-contracts/contracts/EvmGasManager.sol +++ b/system-contracts/contracts/EvmGasManager.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.0; import "./EvmConstants.sol"; import {ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT} from "./Constants.sol"; +import {ISystemContract} from "./interfaces/ISystemContract.sol"; // We consider all the contracts (including system ones) as warm. uint160 constant PRECOMPILES_END = 0xffff; @@ -11,7 +12,7 @@ uint160 constant PRECOMPILES_END = 0xffff; // Denotes that passGas has been consumed uint256 constant INF_PASS_GAS = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; -contract EvmGasManager { +contract EvmGasManager is ISystemContract { // We need strust to use `storage` pointers struct WarmAccountInfo { bool isWarm; @@ -123,13 +124,13 @@ contract EvmGasManager { */ - function pushEVMFrame(uint256 _passGas, bool _isStatic) external { + function pushEVMFrame(uint256 _passGas, bool _isStatic) onlySystemCall onlySystemEvm external { EVMStackFrameInfo memory frame = EVMStackFrameInfo({passGas: _passGas, isStatic: _isStatic}); evmStackFrames.push(frame); } - function consumeEvmFrame() external returns (uint256 passGas, bool isStatic) { + function consumeEvmFrame() onlySystemCall onlySystemEvm external returns (uint256 passGas, bool isStatic) { if (evmStackFrames.length == 0) return (INF_PASS_GAS, false); EVMStackFrameInfo memory frameInfo = evmStackFrames[evmStackFrames.length - 1]; @@ -141,7 +142,7 @@ contract EvmGasManager { evmStackFrames[evmStackFrames.length - 1].passGas = INF_PASS_GAS; } - function popEVMFrame() external { + function popEVMFrame() onlySystemCall onlySystemEvm external { evmStackFrames.pop(); } } 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..bbde6d824 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) @@ -663,11 +678,59 @@ 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 + // farCallAbi |= dataOffset; + // farCallAbi |= (uint256(memoryPage) << 32); + // farCallAbi |= (uint256(dataStart) << 64); + // farCallAbi |= (uint256(dataLength) << 96); + // farCallAbi |= (uint256(gasPassed) << 192); + // farCallAbi |= (uint256(shardId) << 224); + // farCallAbi |= (uint256(forwardingMode) << 232); + // if (isConstructorCall) { + // farCallAbi |= (1 << 240); + // } + // if (isSystemCall) { + // farCallAbi |= (1 << 248); + // } } function ensureAcceptableMemLocation(location) { @@ -758,7 +821,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 +847,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) @@ -1237,6 +1331,8 @@ 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))) + _pushEVMFrame(gasForTheCall, false) + // Selector mstore(sub(offset, 0x80), 0x5b16a23c) // Arg1: address @@ -1247,9 +1343,21 @@ function $llvm_NoInline_llvm$_genericCreate(addr, offset, size, sp, value, evmGa // Length of the init code mstore(sub(offset, 0x20), size) - _pushEVMFrame(gasForTheCall, false) + let farCallAbi := getFarCallABI( + 0, + 0, + sub(offset, 0x64), + add(size, 0x64), + INF_PASS_GAS(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) - result := call(INF_PASS_GAS(), DEPLOYER_SYSTEM_CONTRACT(), value, sub(offset, 0x64), add(size, 0x64), 0, 0) + let to := DEPLOYER_SYSTEM_CONTRACT() + result := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) let gasLeft switch result @@ -1259,7 +1367,7 @@ function $llvm_NoInline_llvm$_genericCreate(addr, offset, size, sp, value, evmGa default { gasLeft := _fetchConstructorReturnGas() } - + let gasUsed := sub(gasForTheCall, gasLeft) evmGasLeft := chargeGas(evmGasLeftOld, gasUsed) diff --git a/system-contracts/contracts/EvmInterpreterPreprocessed.yul b/system-contracts/contracts/EvmInterpreterPreprocessed.yul index 6d1fe6fe9..241c17878 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) @@ -732,11 +760,59 @@ object "EVMInterpreter" { 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 + // farCallAbi |= dataOffset; + // farCallAbi |= (uint256(memoryPage) << 32); + // farCallAbi |= (uint256(dataStart) << 64); + // farCallAbi |= (uint256(dataLength) << 96); + // farCallAbi |= (uint256(gasPassed) << 192); + // farCallAbi |= (uint256(shardId) << 224); + // farCallAbi |= (uint256(forwardingMode) << 232); + // if (isConstructorCall) { + // farCallAbi |= (1 << 240); + // } + // if (isSystemCall) { + // farCallAbi |= (1 << 248); + // } } function ensureAcceptableMemLocation(location) { @@ -827,7 +903,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 +929,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) @@ -1306,6 +1413,8 @@ object "EVMInterpreter" { sp := pushStackItemWithoutCheck(sp, mload(sub(offset, 0x40))) sp := pushStackItemWithoutCheck(sp, mload(sub(offset, 0x20))) + _pushEVMFrame(gasForTheCall, false) + // Selector mstore(sub(offset, 0x80), 0x5b16a23c) // Arg1: address @@ -1316,9 +1425,21 @@ object "EVMInterpreter" { // Length of the init code mstore(sub(offset, 0x20), size) - _pushEVMFrame(gasForTheCall, false) + let farCallAbi := getFarCallABI( + 0, + 0, + sub(offset, 0x64), + add(size, 0x64), + INF_PASS_GAS(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) - result := call(INF_PASS_GAS(), DEPLOYER_SYSTEM_CONTRACT(), value, sub(offset, 0x64), add(size, 0x64), 0, 0) + let to := DEPLOYER_SYSTEM_CONTRACT() + result := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) let gasLeft switch result @@ -1328,7 +1449,7 @@ object "EVMInterpreter" { default { gasLeft := _fetchConstructorReturnGas() } - + let gasUsed := sub(gasForTheCall, gasLeft) evmGasLeft := chargeGas(evmGasLeftOld, gasUsed) @@ -3333,13 +3454,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) @@ -3698,11 +3834,59 @@ object "EVMInterpreter" { 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 + // farCallAbi |= dataOffset; + // farCallAbi |= (uint256(memoryPage) << 32); + // farCallAbi |= (uint256(dataStart) << 64); + // farCallAbi |= (uint256(dataLength) << 96); + // farCallAbi |= (uint256(gasPassed) << 192); + // farCallAbi |= (uint256(shardId) << 224); + // farCallAbi |= (uint256(forwardingMode) << 232); + // if (isConstructorCall) { + // farCallAbi |= (1 << 240); + // } + // if (isSystemCall) { + // farCallAbi |= (1 << 248); + // } } function ensureAcceptableMemLocation(location) { @@ -3793,7 +3977,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 +4003,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) @@ -4272,6 +4487,8 @@ object "EVMInterpreter" { sp := pushStackItemWithoutCheck(sp, mload(sub(offset, 0x40))) sp := pushStackItemWithoutCheck(sp, mload(sub(offset, 0x20))) + _pushEVMFrame(gasForTheCall, false) + // Selector mstore(sub(offset, 0x80), 0x5b16a23c) // Arg1: address @@ -4282,9 +4499,21 @@ object "EVMInterpreter" { // Length of the init code mstore(sub(offset, 0x20), size) - _pushEVMFrame(gasForTheCall, false) + let farCallAbi := getFarCallABI( + 0, + 0, + sub(offset, 0x64), + add(size, 0x64), + INF_PASS_GAS(), + // Only rollup is supported for now + 0, + 0, + 0, + 1 + ) - result := call(INF_PASS_GAS(), DEPLOYER_SYSTEM_CONTRACT(), value, sub(offset, 0x64), add(size, 0x64), 0, 0) + let to := DEPLOYER_SYSTEM_CONTRACT() + result := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) let gasLeft switch result @@ -4294,7 +4523,7 @@ object "EVMInterpreter" { default { gasLeft := _fetchConstructorReturnGas() } - + let gasUsed := sub(gasForTheCall, gasLeft) evmGasLeft := chargeGas(evmGasLeftOld, gasUsed) diff --git a/system-contracts/contracts/NonceHolder.sol b/system-contracts/contracts/NonceHolder.sol index 3df337f1a..609a20257 100644 --- a/system-contracts/contracts/NonceHolder.sol +++ b/system-contracts/contracts/NonceHolder.sol @@ -132,12 +132,13 @@ contract NonceHolder is INonceHolder, ISystemContract { /// @notice Increments the deployment nonce for the account and returns the previous one. /// @param _address The address of the account which to return the deploy nonce for. /// @return prevDeploymentNonce The deployment nonce at the time this function is called. - function incrementDeploymentNonce(address _address) external returns (uint256 prevDeploymentNonce) { + function incrementDeploymentNonce(address _address) external onlySystemCall returns (uint256 prevDeploymentNonce) { require( msg.sender == address(DEPLOYER_SYSTEM_CONTRACT) || ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.isAccountEVM(msg.sender), "Only the contract deployer can increment the deployment nonce" ); + uint256 addressAsKey = uint256(uint160(_address)); uint256 oldRawNonce = rawNonces[addressAsKey];