|  | 
|  | 1 | +# Shooting 101 (very easy) | 
|  | 2 | +In this challenge we need to call some special functions on the contract. | 
|  | 3 | + | 
|  | 4 | +Let's take a look at the target contract: | 
|  | 5 | + | 
|  | 6 | +```solidity | 
|  | 7 | +pragma solidity ^0.8.18; | 
|  | 8 | +
 | 
|  | 9 | +contract ShootingArea { | 
|  | 10 | + bool public firstShot; | 
|  | 11 | + bool public secondShot; | 
|  | 12 | + bool public thirdShot; | 
|  | 13 | +
 | 
|  | 14 | + modifier firstTarget() { | 
|  | 15 | + require(!firstShot && !secondShot && !thirdShot); | 
|  | 16 | + _; | 
|  | 17 | + } | 
|  | 18 | +
 | 
|  | 19 | + modifier secondTarget() { | 
|  | 20 | + require(firstShot && !secondShot && !thirdShot); | 
|  | 21 | + _; | 
|  | 22 | + } | 
|  | 23 | +
 | 
|  | 24 | + modifier thirdTarget() { | 
|  | 25 | + require(firstShot && secondShot && !thirdShot); | 
|  | 26 | + _; | 
|  | 27 | + } | 
|  | 28 | +
 | 
|  | 29 | + receive() external payable secondTarget { | 
|  | 30 | + secondShot = true; | 
|  | 31 | + } | 
|  | 32 | +
 | 
|  | 33 | + fallback() external payable firstTarget { | 
|  | 34 | + firstShot = true; | 
|  | 35 | + } | 
|  | 36 | +
 | 
|  | 37 | + function third() public thirdTarget { | 
|  | 38 | + thirdShot = true; | 
|  | 39 | + } | 
|  | 40 | +} | 
|  | 41 | +``` | 
|  | 42 | + | 
|  | 43 | +The `Setup.sol` just contains the `isSolved()` function like the first challenge, however now it checks all three bolleans of the target contract whether they are true. | 
|  | 44 | + | 
|  | 45 | +We can also see that there are some `modifiers` that are applied to the functions. | 
|  | 46 | +This ensures the order in which they are called is first, second, then third. | 
|  | 47 | + | 
|  | 48 | +The first target is the `fallback` method. | 
|  | 49 | + | 
|  | 50 | +I saw that this is different from the other functions we had before, so I went to look for some information on `receive` and `fallback` and have found this [article](https://blog.soliditylang.org/2020/03/26/fallback-receive-split/). | 
|  | 51 | + | 
|  | 52 | +Here it says, that: | 
|  | 53 | +> receive() external payable — for empty calldata (and any value) | 
|  | 54 | +> fallback() external payable — when no other function matches (not even the receive function). Optionally payable. | 
|  | 55 | +
 | 
|  | 56 | +Both of these functions are triggered when sending just a transaction to the contract, and not directly calling any functions on it. | 
|  | 57 | + | 
|  | 58 | +The `receive` function is used when empty call data is received, and the `fallback` function is used when no other function on the contract matches. | 
|  | 59 | + | 
|  | 60 | +So to trigger `fallback` first, let's send a transaction, but with a non-empty data field. | 
|  | 61 | + | 
|  | 62 | +Next the second target is the `receive` function, let's send a transaction with empty data field. | 
|  | 63 | + | 
|  | 64 | +And finally the `third` is just a function like in the previous challange, we can just call it in the same way. | 
|  | 65 | + | 
|  | 66 | +`solve.py` performs these steps, although I couldn't make it work with a single invocation of the script. | 
|  | 67 | +For each of the step the script is executed once and then I just commented the steps that were already done. | 
|  | 68 | + | 
|  | 69 | +Sending 3 to the other endpoint that is not the RPC we get the flag. | 
0 commit comments