fromweb3importWeb3fromweb3.middlewareimportgeth_poa_middlewareimportosimportjsonimporttimechallenge_id=int(input('The challenge you want to play (1 or 2 or 3): '))assertchallenge_id==1orchallenge_id==2orchallenge_id==3player_bytecode=bytes.fromhex(input('Player bytecode: '))print('Launching anvil...')os.system('anvil --silent --disable-console-log --ipc /dev/shm/eth.ipc &')time.sleep(2)w3=Web3(Web3.IPCProvider('/dev/shm/eth.ipc'))w3.middleware_onion.inject(geth_poa_middleware,layer=0)privatekey='0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'# anvil default private keyacct=w3.eth.account.from_key(privatekey)print('Deploying challenge contract...')bytecode,abi=json.load(open(f'contract{challenge_id}.json'))Challenge=w3.eth.contract(abi=abi,bytecode=bytecode)nonce=w3.eth.get_transaction_count(acct.address)tx=Challenge.constructor().build_transaction({'nonce':nonce,'from':acct.address})signed_tx=w3.eth.account.sign_transaction(tx,private_key=privatekey)tx_hash=w3.eth.send_raw_transaction(signed_tx.rawTransaction)tx_receipt=w3.eth.wait_for_transaction_receipt(tx_hash)asserttx_receipt.statusprint('Challenge contract address:',tx_receipt.contractAddress)challenge=w3.eth.contract(address=tx_receipt.contractAddress,abi=abi)print('Deploying player contract...')recipients=[]foriinrange(10):nonce=w3.eth.get_transaction_count(acct.address)tx={'to':None,'data':player_bytecode,'nonce':nonce,'from':acct.address,'gasPrice':w3.eth.gas_price,'gas':1000000}signed_tx=w3.eth.account.sign_transaction(tx,private_key=privatekey)tx_hash=w3.eth.send_raw_transaction(signed_tx.rawTransaction)tx_receipt=w3.eth.wait_for_transaction_receipt(tx_hash)ifnottx_receipt.status:print('Failed deploying player contract')exit(-1)recipients.append(tx_receipt.contractAddress)amounts=[w3.to_wei(1,'ether')]*10nonce=w3.eth.get_transaction_count(acct.address)tx=challenge.functions.batchTransfer(recipients,amounts).build_transaction({'nonce':nonce,'from':acct.address,'value':sum(amounts),'gas':1000000})signed_tx=w3.eth.account.sign_transaction(tx,private_key=privatekey)tx_hash=w3.eth.send_raw_transaction(signed_tx.rawTransaction)tx_receipt=w3.eth.wait_for_transaction_receipt(tx_hash)iftx_receipt.status:print('Transfer success, no flag.')exit(-1)print(open(f'flag{challenge_id}').read())
// SPDX-License-Identifier: MITpragmasolidity^0.8.0;contractBatchTransfer{functionbatchTransfer(addresspayable[]calldatarecipients,uint256[]calldataamounts)externalpayable{require(recipients.length==amounts.length,"Recipients and amounts length mismatch");uint256totalAmount=0;uint256i;for(i=0;i<amounts.length;i++){totalAmount+=amounts[i];}require(totalAmount==msg.value,"Incorrect total amount");for(i=0;i<recipients.length;i++){recipients[i].transfer(amounts[i]);}}}
// SPDX-License-Identifier: MITpragmasolidity^0.8.0;contractBatchTransfer{mapping(address=>uint256)publicpendingWithdrawals;functionbatchTransfer(addresspayable[]calldatarecipients,uint256[]calldataamounts)externalpayable{require(recipients.length==amounts.length,"Recipients and amounts length mismatch");uint256totalAmount=0;uint256i;for(i=0;i<amounts.length;i++){totalAmount+=amounts[i];}require(totalAmount==msg.value,"Incorrect total amount");for(i=0;i<recipients.length;i++){(boolsuccess,)=recipients[i].call{value:amounts[i]}("");if(!success){pendingWithdrawals[recipients[i]]+=amounts[i];}}}functionwithdrawPending()external{uint256amount=pendingWithdrawals[msg.sender];pendingWithdrawals[msg.sender]=0;(boolsuccess,)=payable(msg.sender).call{value:amount}("");require(success,"Withdrawal failed");}}
// SPDX-License-Identifier: MITpragmasolidity^0.8.0;contractBatchTransfer{mapping(address=>uint256)publicpendingWithdrawals;functionbatchTransfer(addresspayable[]calldatarecipients,uint256[]calldataamounts)externalpayable{require(recipients.length==amounts.length,"Recipients and amounts length mismatch");uint256totalAmount=0;uint256i;for(i=0;i<amounts.length;i++){totalAmount+=amounts[i];}require(totalAmount==msg.value,"Incorrect total amount");for(i=0;i<recipients.length;i++){(boolsuccess,)=recipients[i].call{value:amounts[i],gas:10000}("");if(!success){pendingWithdrawals[recipients[i]]+=amounts[i];}}}functionwithdrawPending()external{uint256amount=pendingWithdrawals[msg.sender];pendingWithdrawals[msg.sender]=0;(boolsuccess,)=payable(msg.sender).call{value:amount}("");require(success,"Withdrawal failed");}}