_This is a_ [_in-depth series_](https://medium.com/@nicolezhu) _around_ [_Zeppelin_](https://openzeppelin.org/) _team’s_ [_smart contract security puzzles_](https://ethernaut.zeppelin.solutions/)_. I’ll give you the direct resources and key concepts you’ll need to solve the puzzles 100% on your own._ -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------  This levels requires you to exploit a poorly implemented `fallback` function to gain control of someone else’s smart contract. ### What is a Fallback function It is best practice to implement a **simple** `Fallback` function if you want your smart contract to **_generally_ receive Ether from other contracts and wallets**. > The Fallback function enables a smart contract’s inherent ability to **act like a wallet.** If I have your wallet address, I can send you Ethers without your permission. In most cases, you might want to enable this ease-of-payment feature for your smart contracts too. This way, other contracts/wallets can send Ether to your contract, without having to know your ABI or specific function names. > Note: without a fallback, or known payable functions, smart contracts can only receive Ether: i) as a mining bonus, or ii) as the backup wallet of another contract that has [self-destructed](http://solidity.readthedocs.io/en/v0.4.21/introduction-to-smart-contracts.html#self-destruct). **The problem is** when developers implement key logic _inside the fallback function_. Such bad practices include: changing contract ownership, transferring the funds, etc. inside the fallback function:  Bad practice: you should not reassign contract ownership in a fallback function This level demonstrates how you open up your contract to abuse, because **anyone can trigger a fallback function**. ### Ways to trigger the Fallback function Anyone can call a fallback function by: 1. Calling a **function that doesn’t exist** inside the contract, or 2. Calling a function **without passing in required data**, or 3. Sending **Ether** **without any data** to the contract ### Detailed Walkthrough There are two places inside Fallback.sol where, as the `msg.sender`, you can become the contract’s **owner**: The first option requires you to send `1000000000000000000000 wei`, or `1000 Ether` to this smart contract. You probably don’t have ~5 hours to slowly request 1000 ethers from Ropsten faucet, which heavily throttles you after the first few requests. So let’s fallback to the `fallback` option. #### **Notice the fallback function has two requirements:** require(msg.value > 0 && contributions\[msg.sender\] > 0); * Your account address needed to have donated Ether to this contract in the past * Your winning fallback function call needs to contain some Ether value #### Using [Remix IDE](http://remix.ethereum.org/): 1. Paste the contract code into the UI. This gives Remix the matching ABI to work with. 2. Make sure you are giving Remix the full import path. Ethernaut provides the short path for its dApp, which Remix does not recognize: import 'github.com/OpenZeppelin/zeppelin-solidity/contracts/ownership/Ownable.sol'; 3\. Retrieve your existing contract instance by loading the contract via the `instance` address:  Check ‘instance’ inside the console for your address. 0xb9bcfd… is my instance address. 4\. Donate a nominal amount of Ether to the contract, using the`contribute` function. Make sure you are donating from your `player` account address. **Note:** the `contribute()` function has the conditional statement:`require(msg.value < 0.001 ether);` Make sure your contribution `value` is less than 0.001 ether.  Check that you’re donating from your \`player\` wallet address 5\. Finally, add some arbitrary value into the `value` field and trigger the `(fallback)` function.  Inside the console, check that you now own the contract by typing`await contract.owner();` #### If using the console (not Remix): You can trigger the fallback function via sending transactions through the console, to the same effect: contract.sendTransaction({ from: player, value: toWei(...) }) // Make sure you leave the "data:" field empty ### Key Security Takeaways * If you implement a fallback function, **keep it simple** * Use fallback functions to **emit payment events to the transaction log** * Use fallback functions to **check simple conditional requirements** * **Think twice** before using fallback functions to change contract ownership, transfer funds, support low-level function calls, and more. ### More Levels [**Ethernaut Lvl 0 Walkthrough: ABIs, Web3, and how to abuse them** _Make a smart contract do things it didn’t want to…_hackernoon.com](https://hackernoon.com/ethernaut-lvl-0-walkthrough-abis-web3-and-how-to-abuse-them-d92a8842d71b "https://hackernoon.com/ethernaut-lvl-0-walkthrough-abis-web3-and-how-to-abuse-them-d92a8842d71b")[](https://hackernoon.com/ethernaut-lvl-0-walkthrough-abis-web3-and-how-to-abuse-them-d92a8842d71b) [**Ethernaut Lvl 2 Fallout Walkthrough: how simple developer errors become big mistakes** _This is a in-depth series around Zeppelin team’s smart contract security puzzles. I’ll give you the direct resources…_medium.com](https://medium.com/@nicolezhu/ethernaut-lvl-2-walkthrough-how-simple-developer-errors-become-big-mistakes-b705ff00a62f "https://medium.com/@nicolezhu/ethernaut-lvl-2-walkthrough-how-simple-developer-errors-become-big-mistakes-b705ff00a62f")[](https://medium.com/@nicolezhu/ethernaut-lvl-2-walkthrough-how-simple-developer-errors-become-big-mistakes-b705ff00a62f)