Ethernaut Solutions: 21-Shop

The task is to ensure that the first call to _buyer.price() returns >= 100 and the next call to _buyer.price() returns < 100. To do that we monitor for a change in the value of boolean variable isSold in the Shop contract. We use an abstract class to execute Shop.buy() and to get the value … Read more

Ethernaut Solutions: 20-Denial

This is a good example of a DOS attack on a contract. Our task is to make the withdraw() fail when the owner calls it to withdraw ETH. The contract deployed at the “partner” address can easily do by spending all gas sent in the transaction through assert():

Ethernaut Solutions: 19-Alien Codex

We are presented with a simple contract “Alien Codex” that inherits from Ownable base contract. Our task is to become the owner of Alien Codex i.e. we should be able to manipulate the Ownable._owner private state variable and store an address of our choosing. Seeing how simple the Alien Codex contract is and the fact … Read more

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: https://www.youtube.com/watch?v=RxL_1AfV7N4https://blog.openzeppelin.com/deconstructing-a-solidity-contract-part-i-introduction-832efd2d7737/ 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: https://www.tutorialspoint.com/solidity/solidity_conversions.htm 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