Force – Level 7 Walkthrough
Welcome to the Force level of the Ethernaut wargame by OpenZeppelin. This challenge demonstrates how ETH can be sent to a contract even if it lacks payable functions or a fallback/receive function.
Objective
The contract in this level has no payable functions and no receive/fallback function. Your goal is to force ETH into the contract’s balance and complete the level.
Getting Started
- 
Select the “Force” level 
- 
Click “Get new instance” and approve the transaction via MetaMask 
- 
Once the instance is deployed, the contractobject is available in your browser console
- 
Note the address of the deployed instance: contract.address
Walkthrough
The only way to send ETH to this contract is by using the selfdestruct() function in another contract. This opcode forces a balance transfer to any address, regardless of whether the recipient contract can receive ETH via normal means.
Step 1: Write the Exploit Contract
Create a new file in Remix IDE called ForceAttack.sol and paste the following code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
contract ForceAttack {
     constructor() public payable {}
     function attack(address payable target) public {
          selfdestruct(target);
     }
}
How it works:
- The constructor is payable, so you can send ETH when deploying.
- The attack()function callsselfdestruct(target), which destroys the contract and sends its ETH balance to the target address, even if the target contract can’t normally receive ETH.
Step 2: Deploy the Attack Contract
- In Remix, compile the contract with Solidity 0.6.0
- Deploy the contract, specifying a small amount of ETH (e.g., 1 wei) in the value field
- Use the Injected Web3 environment (MetaMask) and ensure you’re on the correct testnet
Step 3: Execute the Attack
- 
After deployment, expand your contract in Remix 
- 
Call the attack()function, passing your Ethernaut instance address as the parameter:attack("0xInstanceAddress")
- 
Confirm the transaction in MetaMask 
Step 4: Verify the Transfer
Check the balance of your Ethernaut contract instance:
await web3.eth.getBalance(contract.address)
The balance should now be greater than 0 (in wei).
Step 5: Submit the Level
Click Submit Instance in the Ethernaut UI and confirm in MetaMask.
🎉 Done! You’ve completed the Force level.
💡 What You Learn
- ETH can be forcibly sent to any contract using selfdestruct
- Contracts can receive ETH even if they don’t have payable functions or a fallback/receive function
- Smart contract logic should not rely solely on balance checks for security