// Copyright 2015-2020 Parity Technologies (UK) Ltd.
// This file is part of OpenEthereum.
// OpenEthereum is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// OpenEthereum is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with OpenEthereum. If not, see .
use super::interpreter::MAX_SUB_STACK_SIZE;
use ethereum_types::{Address, H256, U256};
use factory::Factory;
use hex_literal::hex;
use rustc_hex::FromHex;
use std::{
collections::{HashMap, HashSet},
fmt::Debug,
hash::Hash,
str::FromStr,
sync::Arc,
};
use vm::{
self,
tests::{test_finalize, FakeCall, FakeCallType, FakeExt},
ActionParams, ActionValue, Ext,
};
use vmtype::VMType;
evm_test! {test_add: test_add_int}
fn test_add(factory: super::Factory) {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let code = "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.address = address.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_988));
assert_store(
&ext,
0,
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
);
}
evm_test! {test_sha3: test_sha3_int}
fn test_sha3(factory: super::Factory) {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let code = "6000600020600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.address = address.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_961));
assert_store(
&ext,
0,
"c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
);
}
evm_test! {test_address: test_address_int}
fn test_address(factory: super::Factory) {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let code = "30600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.address = address.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_995));
assert_store(
&ext,
0,
"0000000000000000000000000f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
);
}
evm_test! {test_origin: test_origin_int}
fn test_origin(factory: super::Factory) {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let origin = Address::from_str("cd1722f2947def4cf144679da39c4c32bdc35681").unwrap();
let code = "32600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.address = address.clone();
params.origin = origin.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_995));
assert_store(
&ext,
0,
"000000000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681",
);
}
evm_test! {test_selfbalance: test_selfbalance_int}
fn test_selfbalance(factory: super::Factory) {
let own_addr = Address::from_str("1337000000000000000000000000000000000000").unwrap();
// 47 SELFBALANCE
// 60 ff PUSH ff
// 55 SSTORE
let code = hex!("47 60 ff 55").to_vec();
let mut params = ActionParams::default();
params.address = own_addr.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_istanbul();
ext.balances = {
let mut x = HashMap::new();
x.insert(own_addr, U256::from(1_025)); // 0x401
x
};
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_992)); // TODO[dvdplm]: do the sums here, SELFBALANCE-5 + PUSH1-3 + ONEBYTE-4 + SSTORE-?? = 100_000 - 79_992
assert_store(
&ext,
0xff,
"0000000000000000000000000000000000000000000000000000000000000401",
);
}
evm_test! {test_sender: test_sender_int}
fn test_sender(factory: super::Factory) {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let sender = Address::from_str("cd1722f2947def4cf144679da39c4c32bdc35681").unwrap();
let code = "33600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.address = address.clone();
params.sender = sender.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_995));
assert_store(
&ext,
0,
"000000000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681",
);
}
evm_test! {test_chain_id: test_chain_id_int}
fn test_chain_id(factory: super::Factory) {
// 46 CHAINID
// 60 00 PUSH 0
// 55 SSTORE
let code = hex!("46 60 00 55").to_vec();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_istanbul().with_chain_id(9);
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_995));
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000000009",
);
}
evm_test! {test_extcodecopy: test_extcodecopy_int}
fn test_extcodecopy(factory: super::Factory) {
// 33 - sender
// 3b - extcodesize
// 60 00 - push 0
// 60 00 - push 0
// 33 - sender
// 3c - extcodecopy
// 60 00 - push 0
// 51 - load word from memory
// 60 00 - push 0
// 55 - sstore
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let sender = Address::from_str("cd1722f2947def4cf144679da39c4c32bdc35681").unwrap();
let code = "333b60006000333c600051600055".from_hex().unwrap();
let sender_code = "6005600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.address = address.clone();
params.sender = sender.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
ext.codes.insert(sender, Arc::new(sender_code));
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_935));
assert_store(
&ext,
0,
"6005600055000000000000000000000000000000000000000000000000000000",
);
}
evm_test! {test_log_empty: test_log_empty_int}
fn test_log_empty(factory: super::Factory) {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let code = "60006000a0".from_hex().unwrap();
let mut params = ActionParams::default();
params.address = address.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(99_619));
assert_eq!(ext.logs.len(), 1);
assert_eq!(ext.logs[0].topics.len(), 0);
assert!(ext.logs[0].data.is_empty());
}
evm_test! {test_log_sender: test_log_sender_int}
fn test_log_sender(factory: super::Factory) {
// 60 ff - push ff
// 60 00 - push 00
// 53 - mstore
// 33 - sender
// 60 20 - push 20
// 60 00 - push 0
// a1 - log with 1 topic
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
let code = "60ff6000533360206000a1".from_hex().unwrap();
let mut params = ActionParams::default();
params.address = address.clone();
params.sender = sender.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(98_974));
assert_eq!(ext.logs.len(), 1);
assert_eq!(ext.logs[0].topics.len(), 1);
assert_eq!(
ext.logs[0].topics[0],
H256::from_str("000000000000000000000000cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()
);
assert_eq!(
ext.logs[0].data,
"ff00000000000000000000000000000000000000000000000000000000000000"
.from_hex()
.unwrap()
);
}
evm_test! {test_blockhash: test_blockhash_int}
fn test_blockhash(factory: super::Factory) {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let code = "600040600055".from_hex().unwrap();
let blockhash =
H256::from_str("123400000000000000000000cd1722f2947def4cf144679da39c4c32bdc35681").unwrap();
let mut params = ActionParams::default();
params.address = address.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
ext.blockhashes.insert(U256::zero(), blockhash.clone());
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_974));
assert_eq!(ext.store.get(&H256::new()).unwrap(), &blockhash);
}
evm_test! {test_calldataload: test_calldataload_int}
fn test_calldataload(factory: super::Factory) {
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let code = "600135600055".from_hex().unwrap();
let data = "0123ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23"
.from_hex()
.unwrap();
let mut params = ActionParams::default();
params.address = address.clone();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
params.data = Some(data);
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_991));
assert_store(
&ext,
0,
"23ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff23",
);
}
evm_test! {test_author: test_author_int}
fn test_author(factory: super::Factory) {
let author = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
let code = "41600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
ext.info.author = author;
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_995));
assert_store(
&ext,
0,
"0000000000000000000000000f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
);
}
evm_test! {test_timestamp: test_timestamp_int}
fn test_timestamp(factory: super::Factory) {
let timestamp = 0x1234;
let code = "42600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
ext.info.timestamp = timestamp;
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_995));
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000001234",
);
}
evm_test! {test_number: test_number_int}
fn test_number(factory: super::Factory) {
let number = 0x1234;
let code = "43600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
ext.info.number = number;
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_995));
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000001234",
);
}
evm_test! {test_difficulty: test_difficulty_int}
fn test_difficulty(factory: super::Factory) {
let difficulty = U256::from(0x1234);
let code = "44600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
ext.info.difficulty = difficulty;
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_995));
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000001234",
);
}
evm_test! {test_gas_limit: test_gas_limit_int}
fn test_gas_limit(factory: super::Factory) {
let gas_limit = U256::from(0x1234);
let code = "45600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
ext.info.gas_limit = gas_limit;
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(79_995));
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000001234",
);
}
evm_test! {test_mul: test_mul_int}
fn test_mul(factory: super::Factory) {
let code = "65012365124623626543219002600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"000000000000000000000000000000000000000000000000734349397b853383",
);
assert_eq!(gas_left, U256::from(79_983));
}
evm_test! {test_sub: test_sub_int}
fn test_sub(factory: super::Factory) {
let code = "65012365124623626543219003600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000012364ad0302",
);
assert_eq!(gas_left, U256::from(79_985));
}
evm_test! {test_div: test_div_int}
fn test_div(factory: super::Factory) {
let code = "65012365124623626543219004600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"000000000000000000000000000000000000000000000000000000000002e0ac",
);
assert_eq!(gas_left, U256::from(79_983));
}
evm_test! {test_div_zero: test_div_zero_int}
fn test_div_zero(factory: super::Factory) {
let code = "6501236512462360009004600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000000000",
);
assert_eq!(gas_left, U256::from(94_983));
}
evm_test! {test_mod: test_mod_int}
fn test_mod(factory: super::Factory) {
let code = "650123651246236265432290066000556501236512462360009006600155"
.from_hex()
.unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000076b4b",
);
assert_store(
&ext,
1,
"0000000000000000000000000000000000000000000000000000000000000000",
);
assert_eq!(gas_left, U256::from(74_966));
}
evm_test! {test_smod: test_smod_int}
fn test_smod(factory: super::Factory) {
let code = "650123651246236265432290076000556501236512462360009007600155"
.from_hex()
.unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000076b4b",
);
assert_store(
&ext,
1,
"0000000000000000000000000000000000000000000000000000000000000000",
);
assert_eq!(gas_left, U256::from(74_966));
}
evm_test! {test_sdiv: test_sdiv_int}
fn test_sdiv(factory: super::Factory) {
let code = "650123651246236265432290056000556501236512462360009005600155"
.from_hex()
.unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"000000000000000000000000000000000000000000000000000000000002e0ac",
);
assert_store(
&ext,
1,
"0000000000000000000000000000000000000000000000000000000000000000",
);
assert_eq!(gas_left, U256::from(74_966));
}
evm_test! {test_exp: test_exp_int}
fn test_exp(factory: super::Factory) {
let code = "6016650123651246230a6000556001650123651246230a6001556000650123651246230a600255"
.from_hex()
.unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"90fd23767b60204c3d6fc8aec9e70a42a3f127140879c133a20129a597ed0c59",
);
assert_store(
&ext,
1,
"0000000000000000000000000000000000000000000000000000012365124623",
);
assert_store(
&ext,
2,
"0000000000000000000000000000000000000000000000000000000000000001",
);
assert_eq!(gas_left, U256::from(39_923));
}
evm_test! {test_comparison: test_comparison_int}
fn test_comparison(factory: super::Factory) {
let code = "601665012365124623818181811060005511600155146002556415235412358014600355"
.from_hex()
.unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000000000",
);
assert_store(
&ext,
1,
"0000000000000000000000000000000000000000000000000000000000000001",
);
assert_store(
&ext,
2,
"0000000000000000000000000000000000000000000000000000000000000000",
);
assert_store(
&ext,
3,
"0000000000000000000000000000000000000000000000000000000000000001",
);
assert_eq!(gas_left, U256::from(49_952));
}
evm_test! {test_signed_comparison: test_signed_comparison_int}
fn test_signed_comparison(factory: super::Factory) {
let code = "60106000036010818112600055136001556010601060000381811260025513600355"
.from_hex()
.unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000000000",
);
assert_store(
&ext,
1,
"0000000000000000000000000000000000000000000000000000000000000001",
);
assert_store(
&ext,
2,
"0000000000000000000000000000000000000000000000000000000000000001",
);
assert_store(
&ext,
3,
"0000000000000000000000000000000000000000000000000000000000000000",
);
assert_eq!(gas_left, U256::from(49_940));
}
evm_test! {test_bitops: test_bitops_int}
fn test_bitops(factory: super::Factory) {
let code = "60ff610ff08181818116600055176001551860025560008015600355198015600455600555"
.from_hex()
.unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(150_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"00000000000000000000000000000000000000000000000000000000000000f0",
);
assert_store(
&ext,
1,
"0000000000000000000000000000000000000000000000000000000000000fff",
);
assert_store(
&ext,
2,
"0000000000000000000000000000000000000000000000000000000000000f0f",
);
assert_store(
&ext,
3,
"0000000000000000000000000000000000000000000000000000000000000001",
);
assert_store(
&ext,
4,
"0000000000000000000000000000000000000000000000000000000000000000",
);
assert_store(
&ext,
5,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
assert_eq!(gas_left, U256::from(44_937));
}
evm_test! {test_addmod_mulmod: test_addmod_mulmod_int}
fn test_addmod_mulmod(factory: super::Factory) {
let code = "60ff60f060108282820860005509600155600060f0601082828208196002550919600355"
.from_hex()
.unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000000001",
);
assert_store(
&ext,
1,
"000000000000000000000000000000000000000000000000000000000000000f",
);
assert_store(
&ext,
2,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
assert_store(
&ext,
3,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
assert_eq!(gas_left, U256::from(19_914));
}
evm_test! {test_byte: test_byte_int}
fn test_byte(factory: super::Factory) {
let code = "60f061ffff1a600055610fff601f1a600155".from_hex().unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000000000",
);
assert_store(
&ext,
1,
"00000000000000000000000000000000000000000000000000000000000000ff",
);
assert_eq!(gas_left, U256::from(74_976));
}
evm_test! {test_signextend: test_signextend_int}
fn test_signextend(factory: super::Factory) {
let code = "610fff60020b60005560ff60200b600155".from_hex().unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000000fff",
);
assert_store(
&ext,
1,
"00000000000000000000000000000000000000000000000000000000000000ff",
);
assert_eq!(gas_left, U256::from(59_972));
}
#[test] // JIT just returns out of gas
fn test_badinstruction_int() {
let factory = super::Factory::new(VMType::Interpreter, 1024 * 32);
let code = "af".from_hex().unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let err = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap_err()
};
match err {
vm::Error::BadInstruction { instruction: 0xaf } => (),
_ => assert!(false, "Expected bad instruction"),
}
}
evm_test! {test_pop: test_pop_int}
fn test_pop(factory: super::Factory) {
let code = "60f060aa50600055".from_hex().unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"00000000000000000000000000000000000000000000000000000000000000f0",
);
assert_eq!(gas_left, U256::from(79_989));
}
evm_test! {test_extops: test_extops_int}
fn test_extops(factory: super::Factory) {
let code = "5a6001555836553a600255386003553460045560016001526016590454600555"
.from_hex()
.unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(150_000);
params.gas_price = U256::from(0x32);
params.value = ActionValue::Transfer(U256::from(0x99));
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000000004",
); // PC / CALLDATASIZE
assert_store(
&ext,
1,
"00000000000000000000000000000000000000000000000000000000000249ee",
); // GAS
assert_store(
&ext,
2,
"0000000000000000000000000000000000000000000000000000000000000032",
); // GASPRICE
assert_store(
&ext,
3,
"0000000000000000000000000000000000000000000000000000000000000020",
); // CODESIZE
assert_store(
&ext,
4,
"0000000000000000000000000000000000000000000000000000000000000099",
); // CALLVALUE
assert_store(
&ext,
5,
"0000000000000000000000000000000000000000000000000000000000000032",
);
assert_eq!(gas_left, U256::from(29_898));
}
evm_test! {test_jumps: test_jumps_int}
fn test_jumps(factory: super::Factory) {
let code = "600160015560066000555b60016000540380806000551560245760015402600155600a565b"
.from_hex()
.unwrap();
let mut params = ActionParams::default();
params.gas = U256::from(150_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(ext.sstore_clears, ext.schedule().sstore_refund_gas as i128);
assert_store(
&ext,
0,
"0000000000000000000000000000000000000000000000000000000000000000",
); // 5!
assert_store(
&ext,
1,
"0000000000000000000000000000000000000000000000000000000000000078",
); // 5!
assert_eq!(gas_left, U256::from(54_117));
}
evm_test! {test_subs_simple: test_subs_simple_int}
fn test_subs_simple(factory: super::Factory) {
// as defined in https://eips.ethereum.org/EIPS/eip-2315
let code = hex!("60045e005c5d").to_vec();
let mut params = ActionParams::default();
params.gas = U256::from(18);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_berlin();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(0));
}
evm_test! {test_subs_two_levels: test_subs_two_levels_int}
fn test_subs_two_levels(factory: super::Factory) {
// as defined in https://eips.ethereum.org/EIPS/eip-2315
let code = hex!("6800000000000000000c5e005c60115e5d5c5d").to_vec();
let mut params = ActionParams::default();
params.gas = U256::from(36);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_berlin();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(0));
}
evm_test! {test_subs_invalid_jump: test_subs_invalid_jump_int}
fn test_subs_invalid_jump(factory: super::Factory) {
// as defined in https://eips.ethereum.org/EIPS/eip-2315
let code = hex!("6801000000000000000c5e005c60115e5d5c5d").to_vec();
let mut params = ActionParams::default();
params.gas = U256::from(24);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_berlin();
let current = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap())
};
let expected = Result::Err(vm::Error::BadJumpDestination { destination: 0xc });
assert_eq!(current, expected);
}
evm_test! {test_subs_shallow_return_stack: test_subs_shallow_return_stack_int}
fn test_subs_shallow_return_stack(factory: super::Factory) {
// as defined in https://eips.ethereum.org/EIPS/eip-2315
let code = hex!("5d5858").to_vec();
let mut params = ActionParams::default();
params.gas = U256::from(24);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_berlin();
let current = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap())
};
let expected = Result::Err(vm::Error::SubStackUnderflow {
wanted: 1,
on_stack: 0,
});
assert_eq!(current, expected);
}
evm_test! {test_subs_substack_limit: test_subs_substack_limit_int}
fn test_subs_substack_limit(factory: super::Factory) {
// PUSH
// JUMP a
// s: BEGINSUB
// a: JUMPDEST
// DUP1
// JUMPI c
// STOP
// c: JUMPDEST
// PUSH1 1
// SWAP
// SUB
// JUMPSUB s
let mut code = hex!("6104006007565c5b80600d57005b6001900360065e").to_vec();
code[1..3].copy_from_slice(&(MAX_SUB_STACK_SIZE as u16).to_be_bytes()[..]);
let mut params = ActionParams::default();
params.gas = U256::from(1_000_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_berlin();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(959_049));
}
evm_test! {test_subs_substack_out: test_subs_substack_out_int}
fn test_subs_substack_out(factory: super::Factory) {
let mut code = hex!("6104006007565c5b80600d57005b6001900360065e").to_vec();
code[1..3].copy_from_slice(&((MAX_SUB_STACK_SIZE + 1) as u16).to_be_bytes()[..]);
let mut params = ActionParams::default();
params.gas = U256::from(1_000_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_berlin();
let current = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap())
};
let expected = Result::Err(vm::Error::OutOfSubStack {
wanted: 1,
limit: MAX_SUB_STACK_SIZE,
});
assert_eq!(current, expected);
}
evm_test! {test_subs_sub_at_end: test_subs_sub_at_end_int}
fn test_subs_sub_at_end(factory: super::Factory) {
let code = hex!("6005565c5d5b60035e").to_vec();
let mut params = ActionParams::default();
params.gas = U256::from(30);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_berlin();
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_eq!(gas_left, U256::from(0));
}
evm_test! {test_subs_walk_into_subroutine: test_subs_walk_into_subroutine_int}
fn test_subs_walk_into_subroutine(factory: super::Factory) {
let code = hex!("5c5d00").to_vec();
let mut params = ActionParams::default();
params.gas = U256::from(100);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_berlin();
let current = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap())
};
let expected = Result::Err(vm::Error::InvalidSubEntry);
assert_eq!(current, expected);
}
evm_test! {test_calls: test_calls_int}
fn test_calls(factory: super::Factory) {
let code = "600054602d57600160005560006000600060006050610998610100f160006000600060006050610998610100f25b".from_hex().unwrap();
let address = Address::from(0x155);
let code_address = Address::from(0x998);
let mut params = ActionParams::default();
params.gas = U256::from(150_000);
params.code = Some(Arc::new(code));
params.address = address.clone();
let mut ext = FakeExt::new();
ext.balances = {
let mut s = HashMap::new();
s.insert(params.address.clone(), params.gas);
s
};
let gas_left = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_set_contains(
&ext.calls,
&FakeCall {
call_type: FakeCallType::Call,
create_scheme: None,
gas: U256::from(2556),
sender_address: Some(address.clone()),
receive_address: Some(code_address.clone()),
value: Some(U256::from(0x50)),
data: vec![],
code_address: Some(code_address.clone()),
},
);
assert_set_contains(
&ext.calls,
&FakeCall {
call_type: FakeCallType::Call,
create_scheme: None,
gas: U256::from(2556),
sender_address: Some(address.clone()),
receive_address: Some(address.clone()),
value: Some(U256::from(0x50)),
data: vec![],
code_address: Some(code_address.clone()),
},
);
assert_eq!(gas_left, U256::from(91_405));
assert_eq!(ext.calls.len(), 2);
}
evm_test! {test_create_in_staticcall: test_create_in_staticcall_int}
fn test_create_in_staticcall(factory: super::Factory) {
let code = "600060006064f000".from_hex().unwrap();
let address = Address::from(0x155);
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
params.address = address.clone();
let mut ext = FakeExt::new_byzantium();
ext.is_static = true;
let err = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap_err()
};
assert_eq!(err, vm::Error::MutableCallInStaticContext);
assert_eq!(ext.calls.len(), 0);
}
evm_test! {test_shl: test_shl_int}
fn test_shl(factory: super::Factory) {
push_two_pop_one_constantinople_test(
&factory,
0x1b,
"0000000000000000000000000000000000000000000000000000000000000001",
"00",
"0000000000000000000000000000000000000000000000000000000000000001",
);
push_two_pop_one_constantinople_test(
&factory,
0x1b,
"0000000000000000000000000000000000000000000000000000000000000001",
"01",
"0000000000000000000000000000000000000000000000000000000000000002",
);
push_two_pop_one_constantinople_test(
&factory,
0x1b,
"0000000000000000000000000000000000000000000000000000000000000001",
"ff",
"8000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1b,
"0000000000000000000000000000000000000000000000000000000000000001",
"0100",
"0000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1b,
"0000000000000000000000000000000000000000000000000000000000000001",
"0101",
"0000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1b,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"00",
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
push_two_pop_one_constantinople_test(
&factory,
0x1b,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"01",
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
);
push_two_pop_one_constantinople_test(
&factory,
0x1b,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"ff",
"8000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1b,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"0100",
"0000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1b,
"0000000000000000000000000000000000000000000000000000000000000000",
"01",
"0000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1b,
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"01",
"fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
);
}
evm_test! {test_shr: test_shr_int}
fn test_shr(factory: super::Factory) {
push_two_pop_one_constantinople_test(
&factory,
0x1c,
"0000000000000000000000000000000000000000000000000000000000000001",
"00",
"0000000000000000000000000000000000000000000000000000000000000001",
);
push_two_pop_one_constantinople_test(
&factory,
0x1c,
"0000000000000000000000000000000000000000000000000000000000000001",
"01",
"0000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1c,
"8000000000000000000000000000000000000000000000000000000000000000",
"01",
"4000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1c,
"8000000000000000000000000000000000000000000000000000000000000000",
"ff",
"0000000000000000000000000000000000000000000000000000000000000001",
);
push_two_pop_one_constantinople_test(
&factory,
0x1c,
"8000000000000000000000000000000000000000000000000000000000000000",
"0100",
"0000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1c,
"8000000000000000000000000000000000000000000000000000000000000000",
"0101",
"0000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1c,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"00",
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
push_two_pop_one_constantinople_test(
&factory,
0x1c,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"01",
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
push_two_pop_one_constantinople_test(
&factory,
0x1c,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"ff",
"0000000000000000000000000000000000000000000000000000000000000001",
);
push_two_pop_one_constantinople_test(
&factory,
0x1c,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"0100",
"0000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1c,
"0000000000000000000000000000000000000000000000000000000000000000",
"01",
"0000000000000000000000000000000000000000000000000000000000000000",
);
}
evm_test! {test_sar: test_sar_int}
fn test_sar(factory: super::Factory) {
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"0000000000000000000000000000000000000000000000000000000000000001",
"00",
"0000000000000000000000000000000000000000000000000000000000000001",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"0000000000000000000000000000000000000000000000000000000000000001",
"01",
"0000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"8000000000000000000000000000000000000000000000000000000000000000",
"01",
"c000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"8000000000000000000000000000000000000000000000000000000000000000",
"ff",
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"8000000000000000000000000000000000000000000000000000000000000000",
"0100",
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"8000000000000000000000000000000000000000000000000000000000000000",
"0101",
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"00",
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"01",
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"ff",
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"0100",
"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"0000000000000000000000000000000000000000000000000000000000000000",
"01",
"0000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"4000000000000000000000000000000000000000000000000000000000000000",
"fe",
"0000000000000000000000000000000000000000000000000000000000000001",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"f8",
"000000000000000000000000000000000000000000000000000000000000007f",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"fe",
"0000000000000000000000000000000000000000000000000000000000000001",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"ff",
"0000000000000000000000000000000000000000000000000000000000000000",
);
push_two_pop_one_constantinople_test(
&factory,
0x1d,
"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"0100",
"0000000000000000000000000000000000000000000000000000000000000000",
);
}
fn push_two_pop_one_constantinople_test(
factory: &super::Factory,
opcode: u8,
push1: &str,
push2: &str,
result: &str,
) {
let mut push1 = push1.from_hex().unwrap();
let mut push2 = push2.from_hex().unwrap();
assert!(push1.len() <= 32 && push1.len() != 0);
assert!(push2.len() <= 32 && push2.len() != 0);
let mut code = Vec::new();
code.push(0x60 + ((push1.len() - 1) as u8));
code.append(&mut push1);
code.push(0x60 + ((push2.len() - 1) as u8));
code.append(&mut push2);
code.push(opcode);
code.append(&mut vec![0x60, 0x00, 0x55]);
let mut params = ActionParams::default();
params.gas = U256::from(100_000);
params.code = Some(Arc::new(code));
let mut ext = FakeExt::new_constantinople();
let _ = {
let vm = factory.create(params, ext.schedule(), ext.depth());
test_finalize(vm.exec(&mut ext).ok().unwrap()).unwrap()
};
assert_store(&ext, 0, result);
}
fn assert_set_contains(set: &HashSet, val: &T) {
let contains = set.contains(val);
if !contains {
println!("Set: {:?}", set);
println!("Elem: {:?}", val);
}
assert!(contains, "Element not found in HashSet");
}
fn assert_store(ext: &FakeExt, pos: u64, val: &str) {
assert_eq!(
ext.store.get(&H256::from(pos)).unwrap(),
&H256::from_str(val).unwrap()
);
}