Skip to content

Commit

Permalink
feat: vm.PrecompiledStatefulContract can make CALLs
Browse files Browse the repository at this point in the history
  • Loading branch information
ARR4N committed Sep 26, 2024
1 parent 53ef071 commit 9328628
Showing 1 changed file with 23 additions and 13 deletions.
36 changes: 23 additions & 13 deletions core/vm/contracts.libevm.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,19 +122,9 @@ type PrecompileEnvironment interface {
BlockHeader() (types.Header, error)
BlockNumber() *big.Int
BlockTime() uint64
}

//
// ****** SECURITY ******
//
// If you are updating PrecompileEnvironment to provide the ability to call back
// into another contract, you MUST revisit the evmCallArgs.forceReadOnly flag.
//
// It is possible that forceReadOnly is true but evm.interpreter.readOnly is
// false. This is safe for now, but may not be if recursive calling *from* a
// precompile is enabled.
//
// ****** SECURITY ******
Call(common.Address, []byte, uint64, *uint256.Int) ([]byte, uint64, error)
}

var _ PrecompileEnvironment = (*evmCallArgs)(nil)

Expand Down Expand Up @@ -168,11 +158,13 @@ func (args *evmCallArgs) ReadOnlyState() libevm.StateReader {
return args.evm.StateDB
}

func (args *evmCallArgs) self() common.Address { return args.addr }

func (args *evmCallArgs) Addresses() *libevm.AddressContext {
return &libevm.AddressContext{
Origin: args.evm.TxContext.Origin,
Caller: args.caller.Address(),
Self: args.addr,
Self: args.self(),
}
}

Expand All @@ -194,6 +186,24 @@ func (args *evmCallArgs) BlockNumber() *big.Int {

func (args *evmCallArgs) BlockTime() uint64 { return args.evm.Context.Time }

func (args *evmCallArgs) Call(addr common.Address, input []byte, gas uint64, value *uint256.Int) ([]byte, uint64, error) {
in := args.evm.interpreter

// The precompile run didn't increment the depth so this is necessary even
// though Call() will eventually result in it being done again.
in.evm.depth++
defer func() { in.evm.depth-- }()

// This will happen if the precompile was invoked via StaticCall() from a
// non read-only state.
if args.readWrite == forceReadOnly && !in.readOnly {
in.readOnly = true
defer func() { in.readOnly = false }()
}

return args.evm.Call(AccountRef(args.self()), addr, input, gas, value)
}

var (
// These lock in the assumptions made when implementing [evmCallArgs]. If
// these break then the struct fields SHOULD be changed to match these
Expand Down

0 comments on commit 9328628

Please sign in to comment.