Skip to content

Commit

Permalink
fix(EVM): Fix precompiles gas flow (#998)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xVolosnikov authored Oct 25, 2024
1 parent 2fb5df4 commit 9555afc
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 59 deletions.
4 changes: 2 additions & 2 deletions system-contracts/SystemContractsHashes.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@
"contractName": "EvmEmulator",
"bytecodePath": "contracts-preprocessed/artifacts/EvmEmulator.yul/EvmEmulator.yul.zbin",
"sourceCodePath": "contracts-preprocessed/EvmEmulator.yul",
"bytecodeHash": "0x01000cd17989fbfbda00c1058d3cbe559dcd05ff07a71e9182f198e22d622cc0",
"sourceCodeHash": "0x43c82a32662ed95d5ecb809535f8487a04c14cbeedcd67eeb29bb33bf5bc74fd"
"bytecodeHash": "0x01000cfb8eb0e02f35ed77623c89d2d3c34783721996aa70190c90b187ed851e",
"sourceCodeHash": "0x2bb96c3957fdee6343c64d00921914c4b01aaad70d6c3ff2bd263c1fbd67110a"
},
{
"contractName": "EvmGasManager",
Expand Down
112 changes: 74 additions & 38 deletions system-contracts/contracts/EvmEmulator.yul
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,14 @@ object "EvmEmulator" {

gasToPass := capGasForCall(evmGasLeft, gasToPass)

let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize)
if precompileCost {
if lt(gasToPass, precompileCost) {
evmGasLeft := chargeGas(evmGasLeft, gasToPass)
gasToPass := 0
}
}

let success, frameGasLeft := _performCall(
addr,
gasToPass,
Expand All @@ -641,19 +649,20 @@ object "EvmEmulator" {
retSize
)

let gasUsed := 0
let gasUsedByCall := sub(gasToPass, frameGasLeft)

// TODO precompile should be called, but return nothing if gasPassed is too low
let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize)
switch iszero(precompileCost)
case 1 {
gasUsed := sub(gasToPass, frameGasLeft)
}
default {
gasUsed := precompileCost
if precompileCost {
switch success
case 0 {
gasUsedByCall := gasToPass
}
default {
gasUsedByCall := precompileCost
}
}

newGasLeft := chargeGas(evmGasLeft, gasUsed)
newGasLeft := chargeGas(evmGasLeft, gasUsedByCall)

stackHead := success
}

Expand Down Expand Up @@ -686,6 +695,14 @@ object "EvmEmulator" {

gasToPass := capGasForCall(evmGasLeft, gasToPass)

let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize)
if precompileCost {
if lt(gasToPass, precompileCost) {
evmGasLeft := chargeGas(evmGasLeft, gasToPass)
gasToPass := 0
}
}

let success, frameGasLeft := _performStaticCall(
addr,
gasToPass,
Expand All @@ -695,18 +712,19 @@ object "EvmEmulator" {
retSize
)

let gasUsed := 0
let gasUsedByCall := sub(gasToPass, frameGasLeft)

let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize)
switch iszero(precompileCost)
case 1 {
gasUsed := sub(gasToPass, frameGasLeft)
}
default {
gasUsed := precompileCost
if precompileCost {
switch success
case 0 {
gasUsedByCall := gasToPass
}
default {
gasUsedByCall := precompileCost
}
}

newGasLeft := chargeGas(evmGasLeft, gasUsed)
newGasLeft := chargeGas(evmGasLeft, gasUsedByCall)

stackHead := success
}
Expand Down Expand Up @@ -3640,6 +3658,14 @@ object "EvmEmulator" {

gasToPass := capGasForCall(evmGasLeft, gasToPass)

let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize)
if precompileCost {
if lt(gasToPass, precompileCost) {
evmGasLeft := chargeGas(evmGasLeft, gasToPass)
gasToPass := 0
}
}

let success, frameGasLeft := _performCall(
addr,
gasToPass,
Expand All @@ -3650,19 +3676,20 @@ object "EvmEmulator" {
retSize
)

let gasUsed := 0
let gasUsedByCall := sub(gasToPass, frameGasLeft)

// TODO precompile should be called, but return nothing if gasPassed is too low
let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize)
switch iszero(precompileCost)
case 1 {
gasUsed := sub(gasToPass, frameGasLeft)
}
default {
gasUsed := precompileCost
if precompileCost {
switch success
case 0 {
gasUsedByCall := gasToPass
}
default {
gasUsedByCall := precompileCost
}
}

newGasLeft := chargeGas(evmGasLeft, gasUsed)
newGasLeft := chargeGas(evmGasLeft, gasUsedByCall)

stackHead := success
}

Expand Down Expand Up @@ -3695,6 +3722,14 @@ object "EvmEmulator" {

gasToPass := capGasForCall(evmGasLeft, gasToPass)

let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize)
if precompileCost {
if lt(gasToPass, precompileCost) {
evmGasLeft := chargeGas(evmGasLeft, gasToPass)
gasToPass := 0
}
}

let success, frameGasLeft := _performStaticCall(
addr,
gasToPass,
Expand All @@ -3704,18 +3739,19 @@ object "EvmEmulator" {
retSize
)

let gasUsed := 0
let gasUsedByCall := sub(gasToPass, frameGasLeft)

let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize)
switch iszero(precompileCost)
case 1 {
gasUsed := sub(gasToPass, frameGasLeft)
}
default {
gasUsed := precompileCost
if precompileCost {
switch success
case 0 {
gasUsedByCall := gasToPass
}
default {
gasUsedByCall := precompileCost
}
}

newGasLeft := chargeGas(evmGasLeft, gasUsed)
newGasLeft := chargeGas(evmGasLeft, gasUsedByCall)

stackHead := success
}
Expand Down
56 changes: 37 additions & 19 deletions system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,14 @@ function performCall(oldSp, evmGasLeft, oldStackHead) -> newGasLeft, sp, stackHe

gasToPass := capGasForCall(evmGasLeft, gasToPass)

let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize)
if precompileCost {
if lt(gasToPass, precompileCost) {
evmGasLeft := chargeGas(evmGasLeft, gasToPass)
gasToPass := 0
}
}

let success, frameGasLeft := _performCall(
addr,
gasToPass,
Expand All @@ -587,19 +595,20 @@ function performCall(oldSp, evmGasLeft, oldStackHead) -> newGasLeft, sp, stackHe
retSize
)

let gasUsed := 0
let gasUsedByCall := sub(gasToPass, frameGasLeft)

// TODO precompile should be called, but return nothing if gasPassed is too low
let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize)
switch iszero(precompileCost)
case 1 {
gasUsed := sub(gasToPass, frameGasLeft)
}
default {
gasUsed := precompileCost
if precompileCost {
switch success
case 0 {
gasUsedByCall := gasToPass
}
default {
gasUsedByCall := precompileCost
}
}

newGasLeft := chargeGas(evmGasLeft, gasUsed)
newGasLeft := chargeGas(evmGasLeft, gasUsedByCall)

stackHead := success
}

Expand Down Expand Up @@ -632,6 +641,14 @@ function performStaticCall(oldSp, evmGasLeft, oldStackHead) -> newGasLeft, sp, s

gasToPass := capGasForCall(evmGasLeft, gasToPass)

let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize)
if precompileCost {
if lt(gasToPass, precompileCost) {
evmGasLeft := chargeGas(evmGasLeft, gasToPass)
gasToPass := 0
}
}

let success, frameGasLeft := _performStaticCall(
addr,
gasToPass,
Expand All @@ -641,18 +658,19 @@ function performStaticCall(oldSp, evmGasLeft, oldStackHead) -> newGasLeft, sp, s
retSize
)

let gasUsed := 0
let gasUsedByCall := sub(gasToPass, frameGasLeft)

let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize)
switch iszero(precompileCost)
case 1 {
gasUsed := sub(gasToPass, frameGasLeft)
}
default {
gasUsed := precompileCost
if precompileCost {
switch success
case 0 {
gasUsedByCall := gasToPass
}
default {
gasUsedByCall := precompileCost
}
}

newGasLeft := chargeGas(evmGasLeft, gasUsed)
newGasLeft := chargeGas(evmGasLeft, gasUsedByCall)

stackHead := success
}
Expand Down

0 comments on commit 9555afc

Please sign in to comment.