Skip to content

Commit

Permalink
[EVM-Equivalence-YUL] Restrict functions to only be called from inter…
Browse files Browse the repository at this point in the history
…preter (#745)

Co-authored-by: IAvecilla <[email protected]>
Co-authored-by: Javier Chatruc <[email protected]>
  • Loading branch information
3 people authored Aug 29, 2024
1 parent 5cdc5dd commit 253d370
Show file tree
Hide file tree
Showing 8 changed files with 498 additions and 410 deletions.
21 changes: 14 additions & 7 deletions system-contracts/contracts/ContractDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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]));
Expand Down Expand Up @@ -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;
Expand All @@ -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.
Expand Down
9 changes: 6 additions & 3 deletions system-contracts/contracts/EvmGasManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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");
_;
}

Expand Down Expand Up @@ -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];
Expand All @@ -141,7 +144,7 @@ contract EvmGasManager {
evmStackFrames[evmStackFrames.length - 1].passGas = INF_PASS_GAS;
}

function popEVMFrame() external {
function popEVMFrame() external onlySystemEvm {
evmStackFrames.pop();
}
}
2 changes: 1 addition & 1 deletion system-contracts/contracts/EvmInterpreter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
15 changes: 14 additions & 1 deletion system-contracts/contracts/EvmInterpreter.template.yul
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading

0 comments on commit 253d370

Please sign in to comment.