Skip to content

Commit

Permalink
Add create2 opcode
Browse files Browse the repository at this point in the history
  • Loading branch information
ManuelBilbao authored and jrchatruc committed Apr 29, 2024
1 parent c0f7a6b commit 35f3150
Showing 1 changed file with 106 additions and 165 deletions.
271 changes: 106 additions & 165 deletions system-contracts/contracts/EvmInterpreter.yul
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,49 @@ object "EVMInterpreter" {
}
}

function genericCreate(addr, offset, size, sp) -> result {
pop(warmAddress(addr))

let nonceNewAddr := getNonce(addr)
let bytecodeNewAddr := extcodesize(addr)
if or(gt(nonceNewAddr, 0), gt(bytecodeNewAddr, 0)) {
incrementNonce(address())
revert(0, 0)
}

offset := add(MEM_OFFSET_INNER(), offset)

sp := pushStackItem(sp, sub(offset, 0x80))
sp := pushStackItem(sp, sub(offset, 0x60))
sp := pushStackItem(sp, sub(offset, 0x40))
sp := pushStackItem(sp, 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)

result := call(gas(), DEPLOYER_SYSTEM_CONTRACT(), 0, sub(offset, 0x64), add(size, 0x64), 0, 0)

incrementNonce(address())

let back

back, sp := popStackItem(sp)
mstore(sub(offset, 0x20), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x40), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x60), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x80), back)
}

function getEVMGas() -> evmGas {
let GAS_DIVISOR, EVM_GAS_STIPEND, OVERHEAD := GAS_CONSTANTS()

Expand Down Expand Up @@ -1397,48 +1440,11 @@ object "EVMInterpreter" {

let addr := getNewAddress(address())

pop(warmAddress(addr))

let nonceNewAddr := getNonce(addr)
let bytecodeNewAddr := extcodesize(addr)
if or(gt(nonceNewAddr, 0), gt(bytecodeNewAddr, 0)) {
incrementNonce(address())
revert(0, 0)
}

offset := add(MEM_OFFSET_INNER(), offset)

sp := pushStackItem(sp, sub(offset, 0x80))
sp := pushStackItem(sp, sub(offset, 0x60))
sp := pushStackItem(sp, sub(offset, 0x40))
sp := pushStackItem(sp, 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)
let result := genericCreate(addr, offset, size, sp)

let result := call(gas(), DEPLOYER_SYSTEM_CONTRACT(), 0, sub(offset, 0x64), add(size, 0x64), 0, 0)

incrementNonce(address())

let back

back, sp := popStackItem(sp)
mstore(sub(offset, 0x20), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x40), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x60), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x80), back)

sp := pushStackItem(sp, addr)
switch result
case 0 { sp := pushStackItem(sp, 0) }
default { sp := pushStackItem(sp, addr) }
}
case 0xF5 { // OP_CREATE2
let value, offset, size, salt
Expand Down Expand Up @@ -1467,55 +1473,20 @@ object "EVMInterpreter" {

let hashedBytecode := keccak256(add(MEM_OFFSET_INNER(), offset), size)
mstore8(0, 0xFF)
mstore(0x01, shl(0x06, address()))
mstore(0x01, shl(0x60, address()))
mstore(0x15, salt)
mstore(0x35, hashedBytecode)

let addr := and(
keccak256(0, 0x55),
0xFFFFFFFFFFFFFFFFFFFFFFFF
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
)

pop(warmAddress(addr))

if or(gt(getNonce(addr), 0), gt(extcodesize(addr), 0)) {
incrementNonce(address())
revert(0, 0)
}

offset := add(MEM_OFFSET_INNER(), offset)
let result := genericCreate(addr, offset, size, sp)

sp := pushStackItem(sp, sub(offset, 0x80))
sp := pushStackItem(sp, sub(offset, 0x60))
sp := pushStackItem(sp, sub(offset, 0x40))
sp := pushStackItem(sp, 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)

let result := call(gas(), DEPLOYER_SYSTEM_CONTRACT(), 0, sub(offset, 0x64), add(size, 0x64), 0, 0)

incrementNonce(address())

let back

back, sp := popStackItem(sp)
mstore(sub(offset, 0x20), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x40), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x60), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x80), back)

sp := pushStackItem(sp, addr)
switch result
case 0 { sp := pushStackItem(sp, 0) }
default { sp := pushStackItem(sp, addr) }
}
// TODO: REST OF OPCODES
default {
Expand Down Expand Up @@ -1992,6 +1963,49 @@ object "EVMInterpreter" {
}
}

function genericCreate(addr, offset, size, sp) -> result {
pop(warmAddress(addr))

let nonceNewAddr := getNonce(addr)
let bytecodeNewAddr := extcodesize(addr)
if or(gt(nonceNewAddr, 0), gt(bytecodeNewAddr, 0)) {
incrementNonce(address())
revert(0, 0)
}

offset := add(MEM_OFFSET_INNER(), offset)

sp := pushStackItem(sp, sub(offset, 0x80))
sp := pushStackItem(sp, sub(offset, 0x60))
sp := pushStackItem(sp, sub(offset, 0x40))
sp := pushStackItem(sp, 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)

result := call(gas(), DEPLOYER_SYSTEM_CONTRACT(), 0, sub(offset, 0x64), add(size, 0x64), 0, 0)

incrementNonce(address())

let back

back, sp := popStackItem(sp)
mstore(sub(offset, 0x20), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x40), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x60), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x80), back)
}

////////////////////////////////////////////////////////////////
// FALLBACK
////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -2844,7 +2858,6 @@ object "EVMInterpreter" {
evmGasLeft := swapStackItem(sp, evmGasLeft, 16)
}
case 0xF0 { // OP_CREATE
printString("Hola!")
if isStatic {
revert(0, 0)
}
Expand Down Expand Up @@ -2874,48 +2887,11 @@ object "EVMInterpreter" {

let addr := getNewAddress(address())

pop(warmAddress(addr))

let nonceNewAddr := getNonce(addr)
let bytecodeNewAddr := extcodesize(addr)
if or(gt(nonceNewAddr, 0), gt(bytecodeNewAddr, 0)) {
incrementNonce(address())
revert(0, 0)
}

offset := add(MEM_OFFSET_INNER(), offset)

sp := pushStackItem(sp, sub(offset, 0x80))
sp := pushStackItem(sp, sub(offset, 0x60))
sp := pushStackItem(sp, sub(offset, 0x40))
sp := pushStackItem(sp, sub(offset, 0x20))
let result := genericCreate(addr, offset, size, sp)

// 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)

let result := call(gas(), DEPLOYER_SYSTEM_CONTRACT(), 0, sub(offset, 0x64), add(size, 0x64), 0, 0)

incrementNonce(address())

let back

back, sp := popStackItem(sp)
mstore(sub(offset, 0x20), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x40), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x60), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x80), back)

sp := pushStackItem(sp, addr)
switch result
case 0 { sp := pushStackItem(sp, 0) }
default { sp := pushStackItem(sp, addr) }
}
case 0xF5 { // OP_CREATE2
let value, offset, size, salt
Expand Down Expand Up @@ -2944,55 +2920,20 @@ object "EVMInterpreter" {

let hashedBytecode := keccak256(add(MEM_OFFSET_INNER(), offset), size)
mstore8(0, 0xFF)
mstore(0x01, shl(0x06, address()))
mstore(0x01, shl(0x60, address()))
mstore(0x15, salt)
mstore(0x35, hashedBytecode)

let addr := and(
keccak256(0, 0x55),
0xFFFFFFFFFFFFFFFFFFFFFFFF
0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
)

pop(warmAddress(addr))

if or(gt(getNonce(addr), 0), gt(extcodesize(addr), 0)) {
incrementNonce(address())
revert(0, 0)
}

offset := add(MEM_OFFSET_INNER(), offset)

sp := pushStackItem(sp, sub(offset, 0x80))
sp := pushStackItem(sp, sub(offset, 0x60))
sp := pushStackItem(sp, sub(offset, 0x40))
sp := pushStackItem(sp, 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)

let result := call(gas(), DEPLOYER_SYSTEM_CONTRACT(), 0, sub(offset, 0x64), add(size, 0x64), 0, 0)

incrementNonce(address())

let back

back, sp := popStackItem(sp)
mstore(sub(offset, 0x20), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x40), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x60), back)
back, sp := popStackItem(sp)
mstore(sub(offset, 0x80), back)
let result := genericCreate(addr, offset, size, sp)

sp := pushStackItem(sp, addr)
switch result
case 0 { sp := pushStackItem(sp, 0) }
default { sp := pushStackItem(sp, addr) }
}
// TODO: REST OF OPCODES
default {
Expand Down

0 comments on commit 35f3150

Please sign in to comment.