Ethernaut Solutions: 18-MagicNumber

The idea we are exploring here is what is the least amount of code that a contract can contain. Here are the sources that helped me understand the basics: When we compile a .sol file, it creates two files: .ABI and .BIN. When we deploy a contract we have to create a transaction that … Read more

Ethernaut Solutions: 17-Recovery

We need to understand two concepts to be able to solve this challenge: How the deployment address of contracts are calculated? The address where a contract is deployed is deterministic and can be calculated as: keccak256(rlp_encoding(deployer_address + nonce)). The nonce starts at 0x1 for the first deployment and increments by 1 for each deployment thereafter. … Read more

Ethernaut Solutions: 16-Preservation

This challenge highlights the risks associated with using delegatecall. The primary concept to remember is that delegatecall works by affecting the storage slots of the caller contract. To solve this level, we deploy our own “Attacker” contract and call setFirstTime() with Attacker’s address expressed as a uint twice to override the address stored in the … Read more

Ethernaut Solutions: 15-NaughtCoin

This challenge highlights the risks that even well written base contracts can introduce in the child contracts. NaughtCoin contract wants to prevent the transfer of ERC20 tokens for 10 years. However someone possessing the tokens can easily use functions defined in the base contract to immediately transfer out the tokens and totally avoid the lock-in … Read more

Ethernaut Solutions: 14-Gatekeeper Two

To pass gateOne(), we simply have to call GatekeeperTwo contract from another contract instead of an EOA. For gateTwo(), we are using the “extcodesize” opcode which returns the size of the contract code that is deployed at an address. This technique is used by contracts to check if the caller is an EOA or a … Read more

Ethernaut Solutions: 13-Gatekeeper One

There are 3 modifiers that we need evaluated true to pass this challenge: gateOne(), gateTwo() and gateThree(): gateThree() This post helped me a lot to understand how conversions work in Solidity: In my case, tx.origin = 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 require(uint32(uint64(_gateKey)) == uint16(tx.origin), “GatekeeperOne: invalid gateThree part three”); uint16(tx.origin) keeps only the 2 bytes from the right … Read more

Ethernaut Solutions: 11-Elevator

The Elevator contract never lets the “top” state variable to be true and that’s what we want to defeat. This challenge highlights the problem with external contract referencing as the external contract may behave in unexpected ways. Here, we simply need to return “false” on the first call to building.isLastFloor() and “true” the next time. … Read more

Ethernaut Solutions: 10-Re-entrancy

Our donor contract mimics someone who has contributed some money into the Reentrance contract. Thereafter, our Attacker contract steals all the money by first making a small donation and then performs a re-entrancy attack by recursively calling the withdraw() function.

Ethernaut Solutions: 9-King

How to run: Deploy King contract with 5 wei. The deployer address is both the owner and the king and prize = 5 wei. Deploy both Player1 and Player2 contracts with 100 wei. Put King contract’s address in kingContract state variable. Take turns becoming king and winning the “prize” using the Player1 and Player2 contracts. … Read more