@@ -31,18 +31,33 @@ import (
3131var _ PrecompileEnvironment = (* environment )(nil )
3232
3333type environment struct {
34- evm * EVM
35- self * Contract
36- forceReadOnly bool
34+ evm * EVM
35+ self * Contract
36+ callType callType
3737}
3838
3939func (e * environment ) ChainConfig () * params.ChainConfig { return e .evm .chainConfig }
4040func (e * environment ) Rules () params.Rules { return e .evm .chainRules }
41- func (e * environment ) ReadOnly () bool { return e .forceReadOnly || e .evm .interpreter .readOnly }
4241func (e * environment ) ReadOnlyState () libevm.StateReader { return e .evm .StateDB }
4342func (e * environment ) BlockNumber () * big.Int { return new (big.Int ).Set (e .evm .Context .BlockNumber ) }
4443func (e * environment ) BlockTime () uint64 { return e .evm .Context .Time }
4544
45+ func (e * environment ) ReadOnly () bool {
46+ // A switch statement provides clearer code coverage for difficult-to-test
47+ // cases.
48+ switch {
49+ case e .callType == staticCall :
50+ // evm.interpreter.readOnly is only set to true via a call to
51+ // EVMInterpreter.Run() so, if a precompile is called directly with
52+ // StaticCall(), then readOnly might not be set yet.
53+ return true
54+ case e .evm .interpreter .readOnly :
55+ return true
56+ default :
57+ return false
58+ }
59+ }
60+
4661func (e * environment ) Addresses () * libevm.AddressContext {
4762 return & libevm.AddressContext {
4863 Origin : e .evm .Origin ,
@@ -83,7 +98,7 @@ func (e *environment) callContract(typ callType, addr common.Address, input []by
8398 in .evm .depth ++
8499 defer func () { in .evm .depth -- }()
85100
86- if e .forceReadOnly && ! in .readOnly { // i.e. the precompile was StaticCall()ed
101+ if e .ReadOnly () && ! in .readOnly { // i.e. the precompile was StaticCall()ed
87102 in .readOnly = true
88103 defer func () { in .readOnly = false }()
89104 }
@@ -95,6 +110,11 @@ func (e *environment) callContract(typ callType, addr common.Address, input []by
95110 // Note that, in addition to being unsafe, this breaks an EVM
96111 // assumption that the caller ContractRef is always a *Contract.
97112 caller = AccountRef (e .self .CallerAddress )
113+ if e .callType == delegateCall {
114+ // self was created with AsDelegate(), which means that
115+ // CallerAddress was inherited.
116+ caller = AccountRef (e .self .Address ())
117+ }
98118 case nil :
99119 default :
100120 return nil , gas , fmt .Errorf ("unsupported option %T" , o )
0 commit comments