def set_nonce(world,address,nonce): while world.get_nonce(address)<nonce: world.increase_nonce(address) #Initialize wallets and contracts contract_balance = ??? # set to the value of the CTF contract attacker_balance = ??? # we don't need any for this exploit creator_account = m.create_account(address=contract_creator_address,balance=contract_balance) attacker_account = m.create_account(address=from_address,balance=attacker_balance) # The 'getTransactionCount' for geth currently counts contract creation as a transaction for the created contract # A contract nonce starts at '1' (EIP 161) so this works out well for us (we don't need to change it) # The nonce for the attacker account is your current wallet's nonce, we'll use this to get the right address for # the created generic exploit # For the attacker account (us) we want the nonce to be up to date (we will create the contract in the future) set_nonce(m.get_world(),attacker_account.address,???) # get this from geth's getTransactionCount function # If you use the current nonce of the CTF creator contract in this file, you'll have to re-create the ctf level # You could also find the current nonce and count back to find it's value when this contract was created # Finding the nonce for this creator address can be difficult, another way to complete this level is to manually # change the address after an exploit has been generated. In this case, you can just leave this nonce as '1' set_nonce(m.get_world(),creator_account.address,???) # get this from geth's getTransactionCount function # create our victim contract contract_account = m.solidity_create_contract(contract_source_code, contract_name="TrustFund", owner=creator_account, address=si_level_address, # this will cause the program to fail if you've entered the wrong nonce args=(0,0), balance=contract_balance) print("calculated victim contract address: "+hex(contract_account.address))
attacker_balance = ??? # Create the TrustFund level using the TrustFund launcher and give it # the initial balance for the level creator_account = m.create_account(address=contract_creator_address,balance=contract_balance) # Create your wallet account and set its balance attacker_account = m.create_account(address=from_address,balance=attacker_balance) # Set the nonce for your account. The nonce for an address starts at '1' # (EIP 161) and is incremented by one for each transaction. The nonce for # the attacker account is your current wallet's nonce. It is needed to get # the right address for the created generic exploit contract. You can obtain # its value either via Metamask or from geth via the call # eth.getTransactionCount(eth.accounts[0]). set_nonce(m.get_world(),attacker_account.address,???) # We need the address of the TrustFund level we're attacking. This is # calculated by the address of the launcher and its nonce at the time # the level was deployed. You can find this via examining the contract # transaction on Etherscan. If it is not set appropriately, you will # need to manually change the addresses in the exploit that has been # generated to fix the victim's address. One option would be to # leave this nonce as '1', then manually change the victim contract # address set_nonce(m.get_world(),creator_account.address,???) # Create the TrustFund CTF level contract on the EVM using launcher wallet. # We specify the address of the victim as a sanity check. If the nonce # and creator address don't result in the address passed in via "address", # an error will be thrown.