Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions AllContractsHashes.json
Original file line number Diff line number Diff line change
Expand Up @@ -1778,7 +1778,7 @@
{
"contractName": "Bootloader",
"zkBytecodePath": "/system-contracts/zkout/fee_estimate.yul/Bootloader.json",
"zkBytecodeHash": "0x0100099732072f1c0971a7bd5adcb42af1c7c0356feb759eca9700698c78dc33",
"zkBytecodeHash": "0x01000a17fd11b0c9e6bf15535008bc9c3e6c58e74a7f19979476773059654519",
"evmBytecodePath": null,
"evmBytecodeHash": null,
"evmDeployedBytecodeHash": null
Expand All @@ -1794,7 +1794,7 @@
{
"contractName": "Bootloader",
"zkBytecodePath": "/system-contracts/zkout/playground_batch.yul/Bootloader.json",
"zkBytecodeHash": "0x0100099d7ad408efd46c3c419952c09b6cdfefb5d71cb39893f49c6685a55e6b",
"zkBytecodeHash": "0x01000a1de0968a951a71effd9333d901eed2dd177c79a2603081d0624f56294d",
"evmBytecodePath": null,
"evmBytecodeHash": null,
"evmDeployedBytecodeHash": null
Expand Down
2 changes: 2 additions & 0 deletions _typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ extend-exclude = [
# Don't correct the surname "Teh"
FOT = "FOT"
ue = "ue"
# Valid Rust module naming convention for constants
consts = "consts"
4 changes: 2 additions & 2 deletions l1-contracts/deploy-scripts/DeployL2Contracts.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ contract DeployL2Script is Script {
using stdToml for string;

Config internal config;
DeployedContrats internal deployed;
DeployedContracts internal deployed;

enum DAValidatorType {
Rollup,
Expand All @@ -43,7 +43,7 @@ contract DeployL2Script is Script {
address consensusRegistryOwner;
}

struct DeployedContrats {
struct DeployedContracts {
address l2DaValidatorAddress;
address forceDeployUpgraderAddress;
address consensusRegistryImplementation;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {GettersFacetTest} from "./_Getters_Shared.t.sol";
import {InvalidSelector} from "contracts/common/L1ContractErrors.sol";

contract IsFunctionFreezableTest is GettersFacetTest {
function test_when_facetAddressIzZero() public {
function test_when_facetAddressIsZero() public {
bytes4 selector = bytes4(keccak256("asdfghfjtyhrewd"));
gettersFacetWrapper.util_setIsFunctionFreezable(selector, true);

Expand Down
153 changes: 151 additions & 2 deletions system-contracts/bootloader/bootloader.yul
Original file line number Diff line number Diff line change
Expand Up @@ -2103,13 +2103,20 @@ object "Bootloader" {

let value := getValue(innerTxDataOffset)

let success := msgValueSimulatorMimicCall(
let isEvmDeployment, actualTo, actualDataPtr := prepareEthCallForEvmDeployment(
to,
from,
value,
innerTxDataOffset,
dataPtr
)

let success := msgValueSimulatorMimicCall(
actualTo,
from,
value,
actualDataPtr
)

if iszero(success) {
// If success is 0, we need to revert
revertWithReason(
Expand All @@ -2135,12 +2142,154 @@ object "Bootloader" {

// Store results of the call in the memory.
if success {
if isEvmDeployment {
returnEvmDeploymentBytecode()
}

let returnsize := returndatasize()
returndatacopy(0,0,returnsize)
return(0,returnsize)
}

}

function isEvmDeploymentEthCall(to, innerTxDataOffset) -> ret {
ret := and(
eq(to, 0),
eq(getReserved1(innerTxDataOffset), 1)
)
}

function bumpNonceForEvmDeployment(from, innerTxDataOffset) {
let nonce := getNonce(innerTxDataOffset)

let nonceBumpDataPtr := 0
mstore(nonceBumpDataPtr, 36)
mstore(add(nonceBumpDataPtr, 32), shl(224, {{INCREMENT_MIN_NONCE_IF_EQUALS_SELECTOR}}))
mstore(add(nonceBumpDataPtr, 36), nonce)

let nonceBumpSuccess := mimicCallOnlyResult(
NONCE_HOLDER_ADDR(),
from,
nonceBumpDataPtr,
0,
1,
0,
0,
0
)
if iszero(nonceBumpSuccess) {
revertWithReason(
ETH_CALL_ERR_CODE(),
1
)
}
}

function encodeCreateEvmCalldata(dataPtr) -> ret {
// `createEVM(bytes)` call encoding:
// [selector (4)][offset (32)][length (32)][initCode (N)].
// We place metadata right before the existing initCode bytes, so copying is not needed.
let initCodeLength := mload(dataPtr)
ret := safeSub(dataPtr, 68, "ev1")
mstore(ret, safeAdd(initCodeLength, 68, "ev2"))
mstore(add(ret, 32), shl(224, {{CREATE_EVM_SELECTOR}}))
mstore(add(ret, 36), 32)
mstore(add(ret, 68), initCodeLength)
}

function prepareEthCallForEvmDeployment(
to,
from,
innerTxDataOffset,
dataPtr
) -> isEvmDeployment, actualTo, actualDataPtr {
actualTo := to
actualDataPtr := dataPtr
isEvmDeployment := isEvmDeploymentEthCall(to, innerTxDataOffset)

if isEvmDeployment {
if isEOA(from) {
// If the `from` is EOA, we need to bump the nonce before the deployment
bumpNonceForEvmDeployment(from, innerTxDataOffset)
}
actualDataPtr := encodeCreateEvmCalldata(dataPtr)
actualTo := CONTRACT_DEPLOYER_ADDR()
}
}

function getCreateEvmDeployedAddressFromReturndata() -> deployedAddress {
let createEvmReturndataSize := returndatasize()
// createEVM returns (uint256,address), i.e. exactly 64 bytes.
if iszero(eq(createEvmReturndataSize, 64)) {
revertWithReason(
ETH_CALL_ERR_CODE(),
1
)
}

returndatacopy(0, 0, 64)
deployedAddress := and(mload(32), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
}

function getVersionedCodeHashByAddress(addr) -> versionedCodeHash {
mstore(0, {{RIGHT_PADDED_GET_RAW_CODE_HASH_SELECTOR}})
mstore(4, addr)
let getRawCodeHashSuccess := staticcall(
gas(),
ACCOUNT_CODE_STORAGE_ADDR(),
0,
36,
0,
32
)
if iszero(getRawCodeHashSuccess) {
revertWithReason(
ETH_CALL_ERR_CODE(),
1
)
}

versionedCodeHash := mload(0)
}

function CODE_ORACLE_ADDR() -> ret {
ret := 0x0000000000000000000000000000000000008012
}

function fetchBytecodeByVersionedHash(versionedCodeHash) -> retSize {
// CodeOracle expects exactly one word of calldata: versioned code hash.
mstore(0, versionedCodeHash)
let codeOracleSuccess := staticcall(
gas(),
CODE_ORACLE_ADDR(),
0,
32,
0,
0
)
if iszero(codeOracleSuccess) {
revertWithReason(
ETH_CALL_ERR_CODE(),
1
)
}

retSize := returndatasize()
}

function returnEvmDeploymentBytecode() {
let deployedAddress := getCreateEvmDeployedAddressFromReturndata()
let versionedCodeHash := getVersionedCodeHashByAddress(deployedAddress)
let deployedBytecodeSize := fetchBytecodeByVersionedHash(versionedCodeHash)
let runtimeBytecodeSize := extcodesize(deployedAddress)
if gt(deployedBytecodeSize, runtimeBytecodeSize) {
deployedBytecodeSize := runtimeBytecodeSize
}

returndatacopy(0, 0, deployedBytecodeSize)
return(0, deployedBytecodeSize)
}
<!-- @endif -->

/// @dev Given the callee and the data to be called with,
Expand Down
1 change: 1 addition & 0 deletions system-contracts/scripts/preprocess-bootloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ const params = {
// Error
REVERT_ERROR_SELECTOR: padZeroRight(getRevertSelector(), PADDED_SELECTOR_LENGTH),
RIGHT_PADDED_VALIDATE_NONCE_USAGE_SELECTOR: getPaddedSelector("INonceHolder", "validateNonceUsage"),
INCREMENT_MIN_NONCE_IF_EQUALS_SELECTOR: getSelector("INonceHolder", "incrementMinNonceIfEquals"),
RIGHT_PADDED_MINT_ETHER_SELECTOR: getPaddedSelector("L2BaseToken", "mint"),
GET_TX_HASHES_SELECTOR: getSelector("BootloaderUtilities", "getTransactionHashes"),
CREATE_SELECTOR: getSelector("ContractDeployer", "create"),
Expand Down
Loading