1
1
#! /usr/bin/env bash
2
2
3
- set -euo pipefail
4
-
5
3
# ------------------------------------------------
6
4
# CONFIGURATION
7
5
# ------------------------------------------------
8
6
9
- FUZZ_RUNS=100
10
- TESTNET_SLEEP=5
7
+ export SKIP_SETUP=${SKIP_SETUP:- 0}
8
+ export FUZZ_RUNS=${FUZZ_RUNS:- 100}
9
+ export TESTNET_SLEEP=${TESTNET_SLEEP:- 5}
10
+ export RINKEBY_RPC_URL=${RINKEBY_RPC_URL:- https:// rinkeby.infura.io/ v3/ 84842078b09946638c03157f83405213}
11
+ export ARCHIVE_NODE_URL=${ARCHIVE_NODE_URL:- https:// eth-mainnet.alchemyapi.io/ v2/ vpeKFsEF6PHifHzdtcwXSDbhV3ym5Ro4}
12
+ export ETHERSCAN_API_KEY=${ETHERSCAN_API_KEY:- 15IS6MMRAYB19NZN9VHH6H6P57892Z664M}
11
13
12
14
# ------------------------------------------------
13
15
# SHARED SETUP
14
16
# ------------------------------------------------
15
17
16
18
# we spin up a new testnet instance and share it between all tests
17
19
setup_suite () {
18
- if [[ -z " $SKIP_SETUP " ]]; then
19
- TMPDIR=$( mktemp -d)
20
+ if [[ " $SKIP_SETUP " != 1 ]]; then
21
+ export GETHDIR
22
+ GETHDIR=$( mktemp -d)
20
23
21
- dapp testnet --dir " $TMPDIR " &
24
+ dapp testnet --dir " $GETHDIR " &
22
25
# give it a few secs to start up
23
26
sleep " $TESTNET_SLEEP "
24
27
25
28
export ETH_RPC_URL=" http://127.0.0.1:8545"
26
- export ETH_KEYSTORE=" $TMPDIR /8545/keystore"
29
+ export ETH_KEYSTORE=" $GETHDIR /8545/keystore"
27
30
export ETH_PASSWORD=/dev/null
28
- read -r ROOT _ <<< " $(seth ls --keystore " $TMPDIR /8545/keystore" )"
31
+ read -r ROOT _ <<< " $(seth ls --keystore " $GETHDIR /8545/keystore" )"
29
32
fi
30
33
}
31
34
32
35
# cleanup the testnet
33
36
teardown_suite () {
34
- if [[ -z " $SKIP_SETUP " ]]; then
37
+ if [[ " $SKIP_SETUP " != 1 ]]; then
35
38
killall geth
36
- rm -rf " $TMPDIR "
39
+ rm -rf " $GETHDIR "
37
40
fi
38
41
}
39
42
40
43
# ------------------------------------------------
41
44
# TEST HELPERS
42
45
# ------------------------------------------------
43
46
44
- # Tests for resolve-name and lookup-address use a Rinkeby name that's been registered for 100 years and will not be changed
45
- # Infura ID source: https://github.com/ethers-io/ethers.js/blob/0d40156fcba5be155aa5def71bcdb95b9c11d889/packages/providers/src.ts/infura-provider.ts#L17
46
- RINKEBY_RPC_URL=https://rinkeby.infura.io/v3/84842078b09946638c03157f83405213
47
-
48
47
# generates a new account and gives it some eth, returns the address
49
48
fresh_account () {
50
49
wei_amount=${1:- $(seth --to-wei 42069 ether)}
@@ -115,43 +114,41 @@ alpha() {
115
114
# `seth run-tx`
116
115
# `hevm exec`
117
116
test_smoke () {
118
- local account
117
+ local account bytecode
119
118
account=$( fresh_account)
119
+ bytecode=$( mktemp -d)
120
120
121
121
# Deploy a simple contract:
122
- solc --bin --bin-runtime " $CONTRACTS /stateful.sol" -o " $TMPDIR "
122
+ solc --bin --bin-runtime " $CONTRACTS /stateful.sol" -o " $bytecode "
123
123
124
- A_ADDR=$( seth send --create " $( < " $TMPDIR " /A.bin) " " constructor(uint y)" 1 --from " $account " --keystore " $TMPDIR " /8545/keystore --password /dev/null --gas 0xffffff)
124
+ A_ADDR=$( seth send --create " $( < " $bytecode " /A.bin) " " constructor(uint y)" 1 --from " $account " --gas 0xffffff)
125
125
126
126
# Compare deployed code with what solc gives us
127
- assert_equals 0x" $( cat " $TMPDIR " /A.bin-runtime) " " $( seth code " $A_ADDR " ) "
127
+ assert_equals 0x" $( cat " $bytecode " /A.bin-runtime) " " $( seth code " $A_ADDR " ) "
128
128
129
129
# And with what hevm gives us
130
130
EXTRA_CALLDATA=$( seth --to-uint256 1)
131
- HEVM_RET=$( hevm exec --code " $( < " $TMPDIR " /A.bin) " " ${EXTRA_CALLDATA/ 0x/ } " --gas 0xffffff)
131
+ HEVM_RET=$( hevm exec --code " $( < " $bytecode " /A.bin) " " ${EXTRA_CALLDATA/ 0x/ } " --gas 0xffffff)
132
132
133
133
assert_equals " $HEVM_RET " " $( seth code " $A_ADDR " ) "
134
134
135
- TX=$( seth send " $A_ADDR " " off()" --gas 0xffff --password /dev/null --from " $account " --keystore " $TMPDIR " /8545/keystore -- async)
135
+ TX=$( seth send " $A_ADDR " " off()" --gas 0xffff --password /dev/null --from " $account " --async)
136
136
137
137
# since we have one tx per block, seth run-tx and seth debug are equivalent
138
- assert_equals 0x " $( seth run-tx " $TX " ) "
138
+ assert_equals 0x " $( seth run-tx " $TX " --no-src ) "
139
139
140
140
# dynamic fee transactions (EIP-1559)
141
141
seth send " $A_ADDR " " on()" \
142
142
--gas 0xffff \
143
143
--password /dev/null \
144
144
--from " $account " \
145
- --keystore " $TMPDIR " /8545/keystore \
146
145
--prio-fee 2gwei \
147
146
--gas-price 10gwei
148
147
149
- B_ADDR=$( seth send \
150
- --create 0x647175696e6550383480393834f3 \
148
+ B_ADDR=$( seth send --create 0x647175696e6550383480393834f3 \
151
149
--gas 0xffff \
152
150
--password /dev/null \
153
- --from " $ACC " \
154
- --keystore " $TMPDIR " /8545/keystore \
151
+ --from " $account " \
155
152
--prio-fee 2gwei \
156
153
--gas-price 10gwei)
157
154
@@ -161,28 +158,28 @@ test_smoke() {
161
158
# checks that seth send works with both checksummed and unchecksummed addresses
162
159
test_seth_send_address_formats () {
163
160
local account
164
- account =$( fresh_account)
161
+ acc =$( fresh_account)
165
162
166
- lower=$( echo " $account " | tr ' [:upper:]' ' [:lower:]' )
163
+ lower=$( echo " $acc " | tr ' [:upper:]' ' [:lower:]' )
167
164
export ETH_GAS=0xffff
168
165
169
166
# with checksummed
170
- tx=$( seth send " $ZERO " --from " $ACC " --password /dev/null --value " $( seth --to-wei 1 ether) " --keystore " $TMPDIR " /8545/keystore --async)
167
+ tx=$( seth send " $ZERO " --from " $acc " --password /dev/null --value " $( seth --to-wei 1 ether) " --async)
171
168
assert_equals " $lower " " $( seth tx " $tx " from) "
172
169
173
170
# without checksum
174
- tx=$( seth send " $ZERO " --from " $lower " --password /dev/null --value " $( seth --to-wei 1 ether) " --keystore " $TMPDIR " /8545/keystore -- async)
171
+ tx=$( seth send " $ZERO " --from " $lower " --password /dev/null --value " $( seth --to-wei 1 ether) " --async)
175
172
assert_equals " $lower " " $( seth tx " $tx " from) "
176
173
177
174
# try again with eth_rpc_accounts
178
175
export ETH_RPC_ACCOUNTS=true
179
176
180
177
# with checksummed
181
- tx=$( seth send " $ZERO " --from " $ACC " --password /dev/null --value " $( seth --to-wei 1 ether) " --keystore " $TMPDIR " /8545/keystore --async)
178
+ tx=$( seth send " $ZERO " --from " $acc " --password /dev/null --value " $( seth --to-wei 1 ether) " --async)
182
179
assert_equals " $lower " " $( seth tx " $tx " from) "
183
180
184
181
# without checksum
185
- tx=$( seth send " $ZERO " --from " $lower " --password /dev/null --value " $( seth --to-wei 1 ether) " --keystore " $TMPDIR " /8545/keystore -- async)
182
+ tx=$( seth send " $ZERO " --from " $lower " --password /dev/null --value " $( seth --to-wei 1 ether) " --async)
186
183
assert_equals " $lower " " $( seth tx " $tx " from) "
187
184
}
188
185
@@ -192,27 +189,27 @@ test_hevm_symbolic() {
192
189
193
190
solc --bin-runtime -o . --overwrite " $CONTRACTS /factor.sol"
194
191
# should find counterexample
195
- hevm symbolic --code " $( < A.bin-runtime) " --sig " factor(uint x, uint y)" --smttimeout 40000 --solver cvc4 && error || echo " hevm success: found counterexample"
196
- hevm symbolic --code " $( < " $CONTRACTS /dstoken.bin-runtime" ) " --sig " transferFrom(address, address, uint)" --get-models
192
+ hevm symbolic --code " $( < A.bin-runtime) " --sig " factor(uint x, uint y)" --smttimeout 40000 --solver cvc4 && fail || echo " hevm success: found counterexample"
193
+ hevm symbolic --code " $( < " $CONTRACTS /dstoken.bin-runtime" ) " --sig " transferFrom(address, address, uint)" --get-models & > /dev/null || fail
197
194
198
195
solc --bin-runtime -o . --overwrite " $CONTRACTS /token.sol"
199
196
# This one explores all paths (cvc4 is better at this)
200
- hevm symbolic --code " $( < Token.bin-runtime) " --solver cvc4
197
+ hevm symbolic --code " $( < Token.bin-runtime) " --solver cvc4 || fail
201
198
202
199
# The contracts A and B should be equivalent:
203
200
solc --bin-runtime -o . --overwrite " $CONTRACTS /AB.sol"
204
- hevm equivalence --code-a " $( < A.bin-runtime) " --code-b " $( < B.bin-runtime) " --solver cvc4
201
+ hevm equivalence --code-a " $( < A.bin-runtime) " --code-b " $( < B.bin-runtime) " --solver cvc4 || fail
205
202
}
206
203
207
204
test_custom_solc_json () {
208
- TMPDIR =$( mktemp -d)
205
+ tmp =$( mktemp -d)
209
206
210
207
# copy source file
211
- mkdir -p " $TMPDIR /src"
212
- cp " $CONTRACTS /factor.sol" " $TMPDIR /src"
208
+ mkdir -p " $tmp /src"
209
+ cp " $CONTRACTS /factor.sol" " $tmp /src"
213
210
214
211
# init dapp project
215
- cd " $TMPDIR " || exit
212
+ cd " $tmp " || exit
216
213
export GIT_CONFIG_NOSYSTEM=1
217
214
export GIT_AUTHOR_NAME=dapp
218
215
@@ -256,15 +253,15 @@ test_block_1() {
256
253
}
257
254
258
255
test_decimal_roundtrip () {
259
- for _ in $( seq $FUZZ_RUNS ) ; do
256
+ for _ in $( seq " $FUZZ_RUNS " ) ; do
260
257
local input
261
258
input=$( uint256)
262
259
assert_equals " $input " " $( seth --to-dec " $( seth --to-hex " $input " ) " ) "
263
260
done
264
261
}
265
262
266
263
test_hex_roundtrip () {
267
- for _ in $( seq $FUZZ_RUNS ) ; do
264
+ for _ in $( seq " $FUZZ_RUNS " ) ; do
268
265
local input
269
266
input=" 0x$( bytes32) "
270
267
lower=$( echo " $input " | tr ' [:upper:]' ' [:lower:]' )
@@ -273,22 +270,25 @@ test_hex_roundtrip() {
273
270
}
274
271
275
272
test_to_fix_roundtrip () {
276
- for _ in $( seq $FUZZ_RUNS ) ; do
273
+ for _ in $( seq " $FUZZ_RUNS " ) ; do
277
274
local input digits
278
275
input=" $( uint256) "
279
- digits=" $( mod " $( uint8) " 77) " # 78 decimal digits in max uint256
276
+
277
+ length=" ${# input} "
278
+ digits=" $( mod " $( uint8) " " $length " ) "
279
+
280
280
assert_equals " $input " " $( seth --from-fix " $digits " " $( seth --to-fix " $digits " " $input " ) " ) "
281
281
done
282
282
}
283
283
284
284
test_from_fix_roundtrip () {
285
- for _ in $( seq $FUZZ_RUNS ) ; do
285
+ for _ in $( seq " $FUZZ_RUNS " ) ; do
286
286
local input digits
287
287
input=" $( uint256) "
288
+
288
289
length=" ${# input} "
289
- digits=" $( mod " $( uint8) " 77 ) " # 78 decimal digits in max uint256
290
+ digits=" $( mod " $( uint8) " " $length " ) "
290
291
291
- [[ $digits -ge $length ]] && continue
292
292
whole_digits=$( bc <<< " $length - $digits" | tr -d ' \\\n' )
293
293
input=" ${input: 0: whole_digits} .${input: $whole_digits : $length } "
294
294
@@ -516,21 +516,21 @@ test_resolve_name1() {
516
516
517
517
test_resolve_name2 () {
518
518
assert_equals \
519
- " $( seth resolve-name seth-test.eth --rpc-url=$RINKEBY_RPC_URL ) " \
520
- " $( seth resolve-name sEtH-tESt.etH --rpc-url=$RINKEBY_RPC_URL ) "
519
+ " $( seth resolve-name seth-test.eth --rpc-url=" $RINKEBY_RPC_URL " ) " \
520
+ " $( seth resolve-name sEtH-tESt.etH --rpc-url=" $RINKEBY_RPC_URL " ) "
521
521
}
522
522
523
523
test_lookup_address1 () {
524
524
# using example from ethers docs: https://docs.ethers.io/v5/single-page/#/v5/api/providers/provider/-%23-Provider-lookupAddress
525
525
local output
526
- output=$( seth lookup-address 0x49c92F2cE8F876b070b114a6B2F8A60b83c281Ad --rpc-url=$RINKEBY_RPC_URL )
526
+ output=$( seth lookup-address 0x49c92F2cE8F876b070b114a6B2F8A60b83c281Ad --rpc-url=" $RINKEBY_RPC_URL " )
527
527
assert_equals " seth-test.eth" " $output "
528
528
}
529
529
530
530
test_lookup_address2 () {
531
531
assert_equals \
532
- " $( seth lookup-address 0x49c92F2cE8F876b070b114a6B2F8A60b83c281Ad --rpc-url=$RINKEBY_RPC_URL ) " \
533
- " $( seth lookup-address 0x49c92f2ce8f876b070b114a6b2f8a60b83c281ad --rpc-url=$RINKEBY_RPC_URL ) "
532
+ " $( seth lookup-address 0x49c92F2cE8F876b070b114a6B2F8A60b83c281Ad --rpc-url=" $RINKEBY_RPC_URL " ) " \
533
+ " $( seth lookup-address 0x49c92f2ce8f876b070b114a6b2f8a60b83c281ad --rpc-url=" $RINKEBY_RPC_URL " ) "
534
534
}
535
535
536
536
# SETH 4BYTE TESTS
@@ -573,3 +573,63 @@ test_to_fix3() {
573
573
test_to_fix4 () {
574
574
assert_equals 1.234567890000000000 " $( seth --to-fix 18 1234567890000000000) "
575
575
}
576
+
577
+ # SETH RUN-TX TESTS
578
+ test_run_tx_source_fetching () {
579
+ export ETH_RPC_URL=$ARCHIVE_NODE_URL
580
+ local out err
581
+ out=$( mktemp)
582
+ err=$( mktemp)
583
+
584
+ # prints a message when source is not available
585
+ seth run-tx 0xc1511d7fcc498ae8236a18a67786701e6980dcf641b72bcfd4c2a3cd45fb209c --trace 1> " $out " 2> " $err "
586
+ assert " grep -q 'Contract source code not verified' $err " 1
587
+ assert " grep -q 'delegatecall 0xAa1c1B3BbbB59930a4E88F87345B8C513cc56Fa6::0x526327f2' $err " 2
588
+ assert_equals " 0x188fffa3a6cd08bdcc3d5bf4add2a2c0ac5e9d94a278ea1630187b3da583a1f0" " $( cat " $out " ) "
589
+
590
+ local prefiles
591
+ prefiles=$( ls)
592
+
593
+ # seth pulls from etherscan by default (flattened)
594
+ seth run-tx 0x41ccbab4d7d0cd55f481df7fce449986364bf13e655dddfb30aa9b38a4340db7 --trace 1> " $out " 2> " $err "
595
+ assert " grep -q 'UniswapV2Pair@0x28d2DF1E3481Ba90D75E14b9C02cea85b7d6FA2C' $err " 3
596
+ assert " grep -q 'PairCreated(UniswapV2Pair@0x28d2DF1E3481Ba90D75E14b9C02cea85b7d6FA2C, 51691)' $err " 4
597
+ assert_equals " 0x00000000000000000000000028d2df1e3481ba90d75e14b9c02cea85b7d6fa2c" " $( cat " $out " ) "
598
+
599
+ # seth does not write any files to the cwd
600
+ assert_equals " $prefiles " " $( ls) "
601
+
602
+ # seth pulls from etherscan by default (stdjson)
603
+ seth run-tx 0x5da4bf1e5988cf94fd96d2c1dd3f420d2cea1aebe8d1e1c10dd9fe78a2147798 --trace 1> " $out " 2> " $err "
604
+ assert " grep -q 'ownerOf' $err " 5
605
+ assert " grep -q 'iFeather@0xD1edDfcc4596CC8bD0bd7495beaB9B979fc50336' $err " 6
606
+ assert_equals " 0x" " $( cat " $out " ) "
607
+
608
+ # seth does not write any files to the cwd
609
+ assert_equals " $prefiles " " $( ls) "
610
+
611
+ # seth does not pull from etherscan if --source is passed
612
+ seth run-tx 0x41ccbab4d7d0cd55f481df7fce449986364bf13e655dddfb30aa9b38a4340db7 --trace --source /dev/null 1> " $out " 2> " $err "
613
+ assert " grep -q 'call 0x28d2DF1E3481Ba90D75E14b9C02cea85b7d6FA2C::0x485cc9550000000000000000000000007fa7df4' $err " 7
614
+ assert " grep -q 'log3(0xd3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9, 0xffffffffffffffff' $err " 8
615
+ assert_equals " 0x00000000000000000000000028d2df1e3481ba90d75e14b9c02cea85b7d6fa2c" " $( cat " $out " ) "
616
+
617
+ # seth does not pull from etherscan if --no-src is passed at the command line
618
+ seth run-tx 0x41ccbab4d7d0cd55f481df7fce449986364bf13e655dddfb30aa9b38a4340db7 --trace --no-src 1> " $out " 2> " $err "
619
+ assert " grep -q 'call 0x28d2DF1E3481Ba90D75E14b9C02cea85b7d6FA2C::0x485cc9550000000000000000000000007fa7df4' $err " 9
620
+ assert " grep -q 'log3(0xd3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9, 0xffffffffffffffff' $err " 10
621
+ assert_equals " 0x00000000000000000000000028d2df1e3481ba90d75e14b9c02cea85b7d6fa2c" " $( cat " $out " ) "
622
+
623
+ # seth does not pull from etherscan if SETH_NOSRC is set to "yes"
624
+ SETH_NOSRC=yes seth run-tx 0x41ccbab4d7d0cd55f481df7fce449986364bf13e655dddfb30aa9b38a4340db7 --trace 1> " $out " 2> " $err "
625
+ assert " grep -q 'call 0x28d2DF1E3481Ba90D75E14b9C02cea85b7d6FA2C::0x485cc9550000000000000000000000007fa7df4' $err " 11
626
+ assert " grep -q 'log3(0xd3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9, 0xffffffffffffffff' $err " 12
627
+ assert_equals " 0x00000000000000000000000028d2df1e3481ba90d75e14b9c02cea85b7d6fa2c" " $( cat " $out " ) "
628
+
629
+ # seth does not pull from etherscan if ETHERSCAN_API_KEY is unset
630
+ unset ETHERSCAN_API_KEY
631
+ seth run-tx 0x41ccbab4d7d0cd55f481df7fce449986364bf13e655dddfb30aa9b38a4340db7 --trace 1> " $out " 2> " $err "
632
+ assert " grep -q 'call 0x28d2DF1E3481Ba90D75E14b9C02cea85b7d6FA2C::0x485cc9550000000000000000000000007fa7df4' $err " 13
633
+ assert " grep -q 'log3(0xd3648bd0f6ba80134a33ba9275ac585d9d315f0ad8355cddefde31afa28d0e9, 0xffffffffffffffff' $err " 14
634
+ assert_equals " 0x00000000000000000000000028d2df1e3481ba90d75e14b9c02cea85b7d6fa2c" " $( cat " $out " ) "
635
+ }
0 commit comments