def test_timestamp(self): contract_a = make_contract("", "uint256") vm = create_evm_vm([contract_a], False, False) arbsys = contract_templates.get_arbsys() arbsys_abi = ContractABI(arbsys) arbinfo = contract_templates.get_info_contract() arbinfo_abi = ContractABI(arbinfo) output_handler = create_output_handler([contract_a, arbinfo_abi]) inbox = value.Tuple([]) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [0, address, arbsys_abi.timestampUpperBound(0, 0)]), 0)), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [0, address, arbsys_abi.currentMessageTimestamp(1, 0)]), 0, 543, )), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple([ CALL_TX_TYPE, address, arbsys_abi.call_timestampUpperBound() ]), 34, )), ) vm.env.messages = inbox run_until_block(vm, self) self.assertEqual(len(vm.logs), 3) parsed_out0 = output_handler(vm.logs[0]) parsed_out1 = output_handler(vm.logs[1]) parsed_out2 = output_handler(vm.logs[2]) self.assertIsInstance(parsed_out0, EVMReturn) self.assertIsInstance(parsed_out1, EVMReturn) self.assertIsInstance(parsed_out2, EVMReturn) self.assertEqual(parsed_out0.output_values[0], 73657336) self.assertEqual(parsed_out1.output_values[0], 543) self.assertEqual(parsed_out2.output_values[0], 73657336)
def test_clone_from_contract(self): evm_code = make_simple_code() contract_a = make_contract(evm_code, "uint256") evm_code2 = make_evm_clone_code(contract_a.address_string) contract_b = make_contract( evm_code2, "address", "0x0b55929f4095f677C9Ec1F4810C3E59CCD6D33C7" ) vm = create_evm_vm([contract_a, contract_b], False, False) output_handler = create_output_handler([contract_a, contract_b]) inbox = value.Tuple([]) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [0, address, contract_b.testMethod(0, 0)] ) # type # sender ) ), ) vm.env.messages = inbox run_until_block(vm, self) self.assertEqual(len(vm.logs), 1) parsed_out0 = output_handler(vm.logs[0]) self.assertIsInstance(parsed_out0, EVMReturn) self.assertEqual( parsed_out0.output_values[0], "0x76b4d51dcf8e85892588d43581540feb1c2d77ba" )
def test_codecopy_contract(self): offset = 30 length = 80 evm_code = make_evm_codecopy_code( offset, length, "0x895521964D724c8362A36608AAf09A3D7d0A0445") hex_code = assemble_hex(evm_code) contract_a = make_contract(evm_code, "bytes") contracts = create_many_contracts(contract_a) vm = create_evm_vm(contracts, True, False) output_handler = create_output_handler(contracts) vm.env.messages = messagestack.addMessage( value.Tuple([]), value.Tuple( make_msg_val( value.Tuple([0, 2345, contract_a.testMethod(0, 0)]) # type # sender )), ) run_until_block(vm, self) self.assertEqual(len(vm.logs), 1) val = vm.logs[0] parsed_out = output_handler(val) self.assertIsInstance(parsed_out, EVMReturn) self.assertEqual( parsed_out.output_values[0].hex(), hex_code[2 + offset * 2:2 + offset * 2 + length * 2], )
def test_codehash_contract(self): evm_code = make_evm_ext_code( disassemble_one(bytes.fromhex("3f")), "0x895521964D724c8362A36608AAf09A3D7d0A0445", ) hex_code = assemble_hex(evm_code) code_hash = int.from_bytes(eth_utils.crypto.keccak(hexstr=hex_code), byteorder="big") contract_a = make_contract(evm_code, "uint256") contracts = create_many_contracts(contract_a) vm = create_evm_vm(contracts, True, False) output_handler = create_output_handler(contracts) vm.env.messages = messagestack.addMessage( value.Tuple([]), value.Tuple( make_msg_val( value.Tuple([0, 2345, contract_a.testMethod(0, 0)]) # type # sender )), ) run_until_block(vm, self) self.assertEqual(len(vm.logs), 1) val = vm.logs[0] parsed_out = output_handler(val) self.assertIsInstance(parsed_out, EVMReturn) self.assertEqual(parsed_out.output_values[0], code_hash)
def test_codesize_contract(self): instruction_table = instruction_tables["byzantium"] evm_code = make_evm_ext_code( instruction_table["EXTCODESIZE"], "0x895521964D724c8362A36608AAf09A3D7d0A0445", ) code_size = len(evm_code) + sum(op.operand_size for op in evm_code) contract_a = make_contract(evm_code, "uint256") contracts = create_many_contracts(contract_a) vm = create_evm_vm(contracts, False, False) output_handler = create_output_handler(contracts) vm.env.messages = messagestack.addMessage( value.Tuple([]), value.Tuple( make_msg_val( value.Tuple([0, 2345, contract_a.testMethod(0, 0)]) # type # sender )), ) run_until_block(vm, self) self.assertEqual(len(vm.logs), 1) val = vm.logs[0] parsed_out = output_handler(val) self.assertIsInstance(parsed_out, EVMReturn) self.assertEqual(parsed_out.output_values[0], code_size)
def test_balance_succeed(self): instruction_table = instruction_tables["byzantium"] evm_code = make_evm_ext_code( instruction_table["BALANCE"], "0x895521964D724c8362A36608AAf09A3D7d0A0445") contract_a = make_contract(evm_code, "uint256") contracts = create_many_contracts(contract_a) vm = create_evm_vm(contracts, True, False) output_handler = create_output_handler(contracts) inbox = value.Tuple([]) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple([1, 2345, value.Tuple([2345, 100000])]) # type # sender )), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple([0, 2345, contract_a.testMethod(0, 62244) ] # type # sender ))), ) vm.env.messages = inbox run_until_block(vm, self) self.assertEqual(len(vm.logs), 2) parsed_out0 = output_handler(vm.logs[0]) parsed_out1 = output_handler(vm.logs[1]) self.assertIsInstance(parsed_out0, EVMStop) self.assertIsInstance(parsed_out1, EVMReturn) self.assertEqual(parsed_out1.output_values[0], 62244)
def test_codehash_empty(self): evm_code = make_evm_ext_code(disassemble_one(bytes.fromhex("3f")), "0x9999") contract_a = make_contract(evm_code, "uint256") contracts = create_many_contracts(contract_a) vm = create_evm_vm(contracts, True, False) output_handler = create_output_handler(contracts) vm.env.messages = messagestack.addMessage( value.Tuple([]), value.Tuple( make_msg_val( value.Tuple([0, 2345, contract_a.testMethod(0, 0)]) # type # sender )), ) run_until_block(vm, self) self.assertEqual(len(vm.logs), 1) val = vm.logs[0] parsed_out = output_handler(val) self.assertIsInstance(parsed_out, EVMReturn) self.assertEqual(parsed_out.output_values[0], 0)
def test_codecopy_empty(self): offset = 30 length = 80 evm_code = make_evm_codecopy_code(offset, length, "0x9999") contract_a = make_contract(evm_code, "bytes") contracts = create_many_contracts(contract_a) vm = create_evm_vm(contracts, True, False) output_handler = create_output_handler(contracts) vm.env.messages = messagestack.addMessage( value.Tuple([]), value.Tuple( make_msg_val( value.Tuple([0, 2345, contract_a.testMethod(0, 0)]) # type # sender )), ) run_until_block(vm, self) self.assertEqual(len(vm.logs), 1) val = vm.logs[0] parsed_out = output_handler(val) self.assertIsInstance(parsed_out, EVMReturn) self.assertEqual(parsed_out.output_values[0].hex(), "0" * (length * 2))
def test_codesize_empty(self): instruction_table = instruction_tables["byzantium"] evm_code = make_evm_ext_code(instruction_table["EXTCODESIZE"], "0x9999") contract_a = make_contract(evm_code, "uint256") contracts = create_many_contracts(contract_a) vm = create_evm_vm(contracts, True, False) output_handler = create_output_handler(contracts) vm.env.messages = messagestack.addMessage( value.Tuple([]), value.Tuple( make_msg_val( value.Tuple([0, 2345, contract_a.testMethod(0, 0)]) # type # sender )), ) run_until_block(vm, self) self.assertEqual(len(vm.logs), 1) val = vm.logs[0] parsed_out = output_handler(val) self.assertIsInstance(parsed_out, EVMReturn) self.assertEqual(parsed_out.output_values[0], 0)
def test_clone(self): evm_code = make_simple_code() contract_a = make_contract(evm_code, "uint256") arbsys = contract_templates.get_arbsys() arbsys_abi = ContractABI(arbsys) vm = create_evm_vm([contract_a], False, False) output_handler = create_output_handler([contract_a, arbsys_abi]) inbox = value.Tuple([]) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [0, address, contract_a.testMethod(0, 0)] ) # type # sender ) ), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [ 0, address, arbsys_abi.cloneContract(1, 0, contract_a.address_string), ] ) # type # sender ) ), ) vm.env.messages = inbox run_until_block(vm, self) self.assertEqual(len(vm.logs), 2) parsed_out0 = output_handler(vm.logs[0]) parsed_out1 = output_handler(vm.logs[1]) self.assertIsInstance(parsed_out0, EVMReturn) self.assertIsInstance(parsed_out1, EVMReturn) correct_value = parsed_out0.output_values[0] created_contract_address = parsed_out1.output_values[0] created_contract = make_contract(evm_code, "uint256", created_contract_address) fake_contract = make_contract( evm_code, "uint256", "0x3c1b4360234d8e65a9e162ef82d70bee71324512" ) output_handler = create_output_handler( [contract_a, arbsys_abi, created_contract, fake_contract] ) inbox = value.Tuple([]) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [0, address, fake_contract.testMethod(2, 0)] ) # type # sender ) ), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [0, address, created_contract.testMethod(3, 0)] ) # type # sender ) ), ) vm.env.messages = inbox run_until_block(vm, self) self.assertEqual(len(vm.logs), 4) parsed_out2 = output_handler(vm.logs[2]) parsed_out3 = output_handler(vm.logs[3]) self.assertIsInstance(parsed_out2, EVMStop) self.assertIsInstance(parsed_out3, EVMReturn) self.assertEqual(parsed_out3.output_values[0], correct_value)
def test_seq(self): contract_a = make_contract("", "uint256") vm = create_evm_vm([contract_a], False, False) arbsys = contract_templates.get_arbsys() arbsys_abi = ContractABI(arbsys) output_handler = create_output_handler([contract_a]) inbox = value.Tuple([]) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [1, 2345, value.Tuple([address, 100000])] ) # type # sender ) ), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [ CALL_TX_TYPE, address, arbsys_abi.call_getTransactionCount(address_string), ] ) # type # sender ) ), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [ 0, address, arbsys_abi.withdrawEth(0, 0, dest_address_string, 50000), ] ) # type # sender ) ), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [ CALL_TX_TYPE, address, arbsys_abi.call_getTransactionCount(address_string), ] ) # type # sender ) ), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [ 0, address, arbsys_abi.withdrawEth(5, 0, dest_address_string, 50000), ] ) # type # sender ) ), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [ 0, address, arbsys_abi.withdrawEth(1, 0, dest_address_string, 50000), ] ) # type # sender ) ), ) vm.env.messages = inbox run_until_block(vm, self) self.assertEqual(len(vm.logs), 6) parsed_out0 = output_handler(vm.logs[0]) parsed_out1 = output_handler(vm.logs[1]) parsed_out2 = output_handler(vm.logs[2]) parsed_out3 = output_handler(vm.logs[3]) parsed_out4 = output_handler(vm.logs[4]) parsed_out5 = output_handler(vm.logs[5]) self.assertIsInstance(parsed_out0, EVMStop) self.assertIsInstance(parsed_out1, EVMReturn) self.assertIsInstance(parsed_out2, EVMStop) self.assertIsInstance(parsed_out3, EVMReturn) self.assertIsInstance(parsed_out4, EVMInvalidSequence) self.assertIsInstance(parsed_out5, EVMStop) self.assertEqual(parsed_out1.output_values[0], 0) self.assertEqual(parsed_out3.output_values[0], 1) self.assertEqual(len(vm.sent_messages), 2) self.assertEqual( vm.sent_messages[0], value.Tuple([1, address, value.Tuple([dest_address, 50000])]), ) self.assertEqual( vm.sent_messages[1], value.Tuple([1, address, value.Tuple([dest_address, 50000])]), )
def test_erc721(self): contract_a = make_contract("", "uint256") vm = create_evm_vm([contract_a], False, False) output_handler = create_output_handler([contract_a]) erc721 = contract_templates.get_erc721_contract() erc721["address"] = "0xfff6baf0b45129dc8d4cd67ddc28a78d8c599faf" erc721_abi = ContractABI(erc721) inbox = value.Tuple([]) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [3, 2345, value.Tuple([erc721_abi.address, address, 100000])] ) # type # sender ) ), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [3, 2345, value.Tuple([erc721_abi.address, address, 150000])] ) # type # sender ) ), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [ CALL_TX_TYPE, address, erc721_abi.call_tokensOfOwner(address_string), ] ) # type # sender ) ), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [ 0, address, erc721_abi.withdraw(0, 0, dest_address_string, 50000), ] ) # type # sender ) ), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [ 0, address, erc721_abi.withdraw(1, 0, dest_address_string, 100000), ] ) # type # sender ) ), ) vm.env.messages = inbox run_until_block(vm, self) self.assertEqual(len(vm.logs), 5) parsed_out0 = output_handler(vm.logs[0]) parsed_out1 = output_handler(vm.logs[1]) parsed_out2 = output_handler(vm.logs[2]) parsed_out3 = output_handler(vm.logs[3]) parsed_out4 = output_handler(vm.logs[4]) self.assertIsInstance(parsed_out0, EVMStop) self.assertIsInstance(parsed_out1, EVMStop) self.assertIsInstance(parsed_out2, EVMReturn) self.assertIsInstance(parsed_out3, EVMRevert) self.assertIsInstance(parsed_out4, EVMStop) out = parsed_out2.output_values self.assertEqual(len(out), 1) self.assertEqual(out[0], (100000, 150000)) self.assertEqual(len(vm.sent_messages), 1) self.assertEqual( vm.sent_messages[0], value.Tuple( [3, address, value.Tuple([erc721_abi.address, dest_address, 100000])] ), )
def test_erc20(self): contract_a = make_contract("", "uint256") vm = create_evm_vm([contract_a], False, False) output_handler = create_output_handler([contract_a]) erc20 = contract_templates.get_erc20_contract() erc20["address"] = "0xfff6baf0b45129dc8d4cd67ddc28a78d8c599faf" erc20_abi = ContractABI(erc20) inbox = value.Tuple([]) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [2, 2345, value.Tuple([erc20_abi.address, address, 100000])] ) # type # sender ) ), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [ 0, address, erc20_abi.withdraw(0, 0, dest_address_string, 150000), ] ) # type # sender ) ), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [ 0, address, erc20_abi.withdraw(1, 0, dest_address_string, 50000), ] ) # type # sender ) ), ) vm.env.messages = inbox run_until_block(vm, self) self.assertEqual(len(vm.logs), 3) parsed_out0 = output_handler(vm.logs[0]) parsed_out1 = output_handler(vm.logs[1]) parsed_out2 = output_handler(vm.logs[2]) self.assertIsInstance(parsed_out0, EVMStop) self.assertIsInstance(parsed_out1, EVMRevert) self.assertIsInstance(parsed_out2, EVMStop) self.assertEqual(len(vm.sent_messages), 1) self.assertEqual( vm.sent_messages[0], value.Tuple( [2, address, value.Tuple([erc20_abi.address, dest_address, 50000])] ), )
def test_transfer_eth_from_contract(self): contract_address_string = "0x0b55929f4095f677C9Ec1F4810C3E59CCD6D33C7" contract_address = eth_utils.to_int(hexstr=contract_address_string) evm_code = make_evm_transfer_code(dest_address_string, 2000) contract_a = make_contract(evm_code, "address", contract_address_string) arbinfo = contract_templates.get_info_contract() arbinfo_abi = ContractABI(arbinfo) vm = create_evm_vm([contract_a], False, False) output_handler = create_output_handler([contract_a, arbinfo_abi]) inbox = value.Tuple([]) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple( [1, 2345, value.Tuple([contract_address, 2000])]) # type # sender )), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple([0, address, contract_a.testMethod(0, 0)]) # type # sender )), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple([ CALL_TX_TYPE, address, arbinfo_abi.call_getBalance(dest_address_string), ]) # type # sender )), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple([ CALL_TX_TYPE, address, arbinfo_abi.call_getBalance(contract_address_string), ]) # type # sender )), ) vm.env.messages = inbox run_until_block(vm, self) self.assertEqual(len(vm.logs), 4) parsed_outs = [output_handler(log) for log in vm.logs] self.assertIsInstance(parsed_outs[0], EVMStop) self.assertIsInstance(parsed_outs[1], EVMReturn) self.assertIsInstance(parsed_outs[2], EVMReturn) self.assertIsInstance(parsed_outs[3], EVMReturn) self.assertEqual( eth_utils.to_int(hexstr=parsed_outs[1].output_values[0]), 1) dest_balance = parsed_outs[2].output_values[0] contract_balance = parsed_outs[3].output_values[0] self.assertEqual(dest_balance, 2000) self.assertEqual(contract_balance, 0)
def test_insuffient_balance(self): contract_a = make_contract("", "uint256") vm = create_evm_vm([contract_a], False, False) arbinfo = contract_templates.get_info_contract() arbinfo_abi = ContractABI(arbinfo) output_handler = create_output_handler([contract_a, arbinfo_abi]) inbox = value.Tuple([]) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple([1, 2345, value.Tuple([address, 5000])]) # type # sender )), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple([ CALL_TX_TYPE, address, arbinfo_abi.call_getBalance(address_string), ]) # type # sender )), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple([ CALL_TX_TYPE, address, arbinfo_abi.call_getBalance(dest_address_string), ]) # type # sender )), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple([ 0, address, value.Tuple( [dest_address, 0, 10000, bytestack_frombytes(b"")]), ]) # type # sender )), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple([ CALL_TX_TYPE, address, arbinfo_abi.call_getBalance(address_string), ]) # type # sender )), ) inbox = messagestack.addMessage( inbox, value.Tuple( make_msg_val( value.Tuple([ CALL_TX_TYPE, address, arbinfo_abi.call_getBalance(dest_address_string), ]) # type # sender )), ) vm.env.messages = inbox run_until_block(vm, self) self.assertEqual(len(vm.logs), 6) parsed_outs = [output_handler(log) for log in vm.logs] self.assertIsInstance(parsed_outs[0], EVMStop) self.assertIsInstance(parsed_outs[1], EVMReturn) self.assertIsInstance(parsed_outs[2], EVMReturn) self.assertIsInstance(parsed_outs[3], EVMRevert) self.assertIsInstance(parsed_outs[4], EVMReturn) self.assertIsInstance(parsed_outs[5], EVMReturn) self.assertEqual(len(vm.sent_messages), 0) self.assertEqual(parsed_outs[1].output_values[0], parsed_outs[4].output_values[0]) self.assertEqual(parsed_outs[2].output_values[0], parsed_outs[5].output_values[0])