1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
package script
import (
"bytes"
"math/big"
"github.com/holiman/uint256"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/tracing"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
)
// Warp implements https://book.getfoundry.sh/cheatcodes/warp
func (c *CheatCodesPrecompile) Warp(timestamp *big.Int) {
c.h.env.Context.Time = timestamp.Uint64()
}
// Roll implements https://book.getfoundry.sh/cheatcodes/roll
func (c *CheatCodesPrecompile) Roll(num *big.Int) {
c.h.env.Context.BlockNumber = num
}
// Fee implements https://book.getfoundry.sh/cheatcodes/fee
func (c *CheatCodesPrecompile) Fee(fee *big.Int) {
c.h.env.Context.BaseFee = fee
}
// GetBlockTimestamp implements https://book.getfoundry.sh/cheatcodes/get-block-timestamp
func (c *CheatCodesPrecompile) GetBlockTimestamp() *big.Int {
return new(big.Int).SetUint64(c.h.env.Context.Time)
}
// GetBlockNumber implements https://book.getfoundry.sh/cheatcodes/get-block-number
func (c *CheatCodesPrecompile) GetBlockNumber() *big.Int {
return c.h.env.Context.BlockNumber
}
// Difficulty implements https://book.getfoundry.sh/cheatcodes/difficulty
func (c *CheatCodesPrecompile) Difficulty(_ *big.Int) error {
return vm.ErrExecutionReverted // only post-merge is supported
}
// Prevrandao implements https://book.getfoundry.sh/cheatcodes/prevrandao
func (c *CheatCodesPrecompile) Prevrandao(v [32]byte) {
c.h.env.Context.Random = (*common.Hash)(&v)
}
// ChainId implements https://book.getfoundry.sh/cheatcodes/chain-id
func (c *CheatCodesPrecompile) ChainId(id *big.Int) {
c.h.env.ChainConfig().ChainID = id
c.h.chainCfg.ChainID = id
// c.h.env.rules.ChainID is unused, but should maybe also be modified
}
// Store implements https://book.getfoundry.sh/cheatcodes/store
func (c *CheatCodesPrecompile) Store(account common.Address, slot [32]byte, value [32]byte) {
c.h.state.SetState(account, slot, value)
}
// Load implements https://book.getfoundry.sh/cheatcodes/load
func (c *CheatCodesPrecompile) Load(account common.Address, slot [32]byte) [32]byte {
return c.h.state.GetState(account, slot)
}
// Etch implements https://book.getfoundry.sh/cheatcodes/etch
func (c *CheatCodesPrecompile) Etch(who common.Address, code []byte) {
c.h.state.SetCode(who, bytes.Clone(code)) // important to clone; geth EVM will reuse the calldata memory.
}
// Deal implements https://book.getfoundry.sh/cheatcodes/deal
func (c *CheatCodesPrecompile) Deal(who common.Address, newBalance *big.Int) {
c.h.state.SetBalance(who, uint256.MustFromBig(newBalance), tracing.BalanceChangeUnspecified)
}
// Prank_ca669fa7 implements https://book.getfoundry.sh/cheatcodes/prank
func (c *CheatCodesPrecompile) Prank_ca669fa7(sender common.Address) error {
return c.h.Prank(&sender, nil, false, false)
}
// Prank_47e50cce implements https://book.getfoundry.sh/cheatcodes/prank
func (c *CheatCodesPrecompile) Prank_47e50cce(sender common.Address, origin common.Address) error {
return c.h.Prank(&sender, &origin, false, false)
}
// StartPrank_06447d56 implements https://book.getfoundry.sh/cheatcodes/start-prank
func (c *CheatCodesPrecompile) StartPrank_06447d56(sender common.Address) error {
return c.h.Prank(&sender, nil, true, false)
}
// StartPrank_45b56078 implements https://book.getfoundry.sh/cheatcodes/start-prank
func (c *CheatCodesPrecompile) StartPrank_45b56078(sender common.Address, origin common.Address) error {
return c.h.Prank(&sender, &origin, true, false)
}
// StopPrank implements https://book.getfoundry.sh/cheatcodes/stop-prank
func (c *CheatCodesPrecompile) StopPrank() error {
return c.h.StopPrank(false)
}
// ReadCallers implements https://book.getfoundry.sh/cheatcodes/read-callers
func (c *CheatCodesPrecompile) ReadCallers() (callerMode *big.Int, msgSender common.Address, txOrigin common.Address) {
return c.h.CallerMode().Big(), c.h.MsgSender(), c.h.env.TxContext.Origin
}
// Record implements https://book.getfoundry.sh/cheatcodes/record
func (c *CheatCodesPrecompile) Record() error {
panic("vm.record not supported")
}
// Accesses implements https://book.getfoundry.sh/cheatcodes/accesses
func (c *CheatCodesPrecompile) Accesses() (reads [][32]byte, writes [][32]byte, err error) {
panic("vm.accesses not supported")
}
// RecordLogs implements https://book.getfoundry.sh/cheatcodes/record-logs
func (c *CheatCodesPrecompile) RecordLogs() error {
panic("vm.recordLogs not supported")
}
type Log struct {
Topics [][32]byte
Data []byte
Emitter common.Address
}
// GetRecordedLogs implements https://book.getfoundry.sh/cheatcodes/get-recorded-logs
//func (c *CheatCodesPrecompile) GetRecordedLogs() []Log {
// return nil // TODO
//}
// SetNonce implements https://book.getfoundry.sh/cheatcodes/set-nonce
func (c *CheatCodesPrecompile) SetNonce(account common.Address, nonce uint64) {
c.h.state.SetNonce(account, nonce)
}
// GetNonce implements https://book.getfoundry.sh/cheatcodes/get-nonce
func (c *CheatCodesPrecompile) GetNonce(addr common.Address) uint64 {
return c.h.state.GetNonce(addr)
}
func (c *CheatCodesPrecompile) ResetNonce(addr common.Address) {
// Undocumented cheatcode of forge, but used a lot.
// Resets nonce to 0 if EOA, or 1 if contract.
// In scripts often set code to empty first when using it, it then becomes 0.
if c.h.state.GetCodeHash(addr) == types.EmptyCodeHash {
c.h.state.SetNonce(addr, 0)
} else {
c.h.state.SetNonce(addr, 1)
}
}
// MockCall_b96213e4 implements https://book.getfoundry.sh/cheatcodes/mock-call
func (c *CheatCodesPrecompile) MockCall_b96213e4(where common.Address, data []byte, retdata []byte) error {
panic("mockCall not supported")
}
// MockCall_81409b91 implements https://book.getfoundry.sh/cheatcodes/mock-call
func (c *CheatCodesPrecompile) MockCall_81409b91(where common.Address, value *big.Int, data []byte, retdata []byte) error {
panic("vm.mockCall not supported")
}
// MockCallRevert_dbaad147 implements https://book.getfoundry.sh/cheatcodes/mock-call-revert
func (c *CheatCodesPrecompile) MockCallRevert_dbaad147(where common.Address, data []byte, retdata []byte) error {
panic("vm.mockCall not supported")
}
// MockCallRevert_d23cd037 implements https://book.getfoundry.sh/cheatcodes/mock-call-revert
func (c *CheatCodesPrecompile) MockCallRevert_d23cd037(where common.Address, value *big.Int, data []byte, retdata []byte) error {
panic("vm.mockCall not supported")
}
// ClearMockedCalls implements https://book.getfoundry.sh/cheatcodes/clear-mocked-calls
func (c *CheatCodesPrecompile) ClearMockedCalls() error {
panic("vm.clearMockedCalls not supported")
}
// Coinbase implements https://book.getfoundry.sh/cheatcodes/coinbase
func (c *CheatCodesPrecompile) Coinbase(addr common.Address) {
c.h.env.Context.Coinbase = addr
}
// Broadcast_afc98040 implements https://book.getfoundry.sh/cheatcodes/broadcast
func (c *CheatCodesPrecompile) Broadcast_afc98040() error {
return c.h.Prank(nil, nil, false, true)
}
// Broadcast_e6962cdb implements https://book.getfoundry.sh/cheatcodes/broadcast
func (c *CheatCodesPrecompile) Broadcast_e6962cdb(who common.Address) error {
return c.h.Prank(&who, nil, false, true)
}
// StartBroadcast_7fb5297f implements https://book.getfoundry.sh/cheatcodes/start-broadcast
func (c *CheatCodesPrecompile) StartBroadcast_7fb5297f() error {
return c.h.Prank(nil, nil, true, true)
}
// StartBroadcast_7fec2a8d implements https://book.getfoundry.sh/cheatcodes/start-broadcast
func (c *CheatCodesPrecompile) StartBroadcast_7fec2a8d(who common.Address) error {
return c.h.Prank(&who, nil, true, true)
}
// StopBroadcast implements https://book.getfoundry.sh/cheatcodes/stop-broadcast
func (c *CheatCodesPrecompile) StopBroadcast() error {
return c.h.StopPrank(true)
}
// PauseGasMetering implements https://book.getfoundry.sh/cheatcodes/pause-gas-metering
func (c *CheatCodesPrecompile) PauseGasMetering() error {
panic("vm.pauseGasMetering not supported")
}
// ResumeGasMetering implements https://book.getfoundry.sh/cheatcodes/resume-gas-metering
func (c *CheatCodesPrecompile) ResumeGasMetering() error {
panic("vm.resumeGasMetering not supported")
}
// TxGasPrice implements https://book.getfoundry.sh/cheatcodes/tx-gas-price
func (c *CheatCodesPrecompile) TxGasPrice(newGasPrice *big.Int) {
c.h.env.TxContext.GasPrice = newGasPrice
}
// StartStateDiffRecording implements https://book.getfoundry.sh/cheatcodes/start-state-diff-recording
func (c *CheatCodesPrecompile) StartStateDiffRecording() error {
panic("vm.startStateDiffRecording not supported")
}
// StopAndReturnStateDiff implements https://book.getfoundry.sh/cheatcodes/stop-and-return-state-diff
func (c *CheatCodesPrecompile) StopAndReturnStateDiff() error {
panic("vm.stopAndReturnStateDiff not supported")
}