# Intro to Security First Development

## Intro

{% embed url="<https://youtu.be/72K57I9yvyI>" %}
Intro to Security First Development
{% endembed %}

This video showcased some vulnerable contracts.

## Round 1

Vulnerable contract:

```solidity
contract Auction {
    address highestBidder;
    uint256 highestBid;

    function bid() payable {
        require(msg.value > highestBid);

        // @audit-issue Highest bidder's `receive()` could always revert -> DoS
        highestBidder.transfer(highestBid);

        highestBidder = msg.sender;
        highestBid = msg.value;
    }
}
```

Mitigation: Pull-over-Push pattern

```solidity
contract Auction {
    address highestBidder;
    uint256 highestBid;
    mapping(address => uint256) refunds;

    function bid() payable {
        require(msg.value > highestBid);

        if (highestBidder != 0) {
            refunds[highestBidder] += highestBid;
        }

        highestBidder = msg.sender;
        highestBid = msg.value;
    }

    function withdrawRefund() external {
        uint256 refund = refunds[msg.sender];
        refunds[msg.sender] = 0;
        msg.sender.transfer(refund);
    }
}
```

## Round 2

Vulnerable contract:

```solidity
struct payee {
    address addr;
    uint256 value;
}

Payee[] payees;

function payOut() external {
    uint256 i;
    // @audit-issue Long `payees` could exceed block gas limit
    while (i < payees.length) {
        payees[i].addr.send(payees[i].value);
        i++;
    }
}
```

Mitigation: Batches

```solidity
struct payee {
    address addr;
    uint256 value;
}

Payee[] payees;
uint256 nextPayeeIndex;

function payOut(uint256 batchSize) external {
    uint256 i = nextPayeeIndex;
    while (i < nextPayeeIndex + batchSize) {
        payees[i].addr.send(payees[i].value);
        i++;
    }
    nextPayeeIndex = i;
}
```

## Round 3

Vulnerable contract:

```solidity
contract Bank {
    mapping(address => uint) private userBalances;

    // @audit-issue Does not follow checks-effects-interactions pattern
    function withdrawBalance() external {
        uint256 amountToWithdraw = userBalances[msg.sender];
        require(msg.sender.call{value: amountToWithdraw}(""));
        userBalances[msg.sender] = 0;
    }
}
```

Mitigation: Checks-Effects-Interactions pattern

```solidity
contract Bank {
    mapping(address => uint) private userBalances;

    // @audit-issue Does not follow checks-effects-interactions pattern
    function withdrawBalance() external {
        uint256 amountToWithdraw = userBalances[msg.sender];
        userBalances[msg.sender] = 0;
        require(msg.sender.call{value: amountToWithdraw}(""));
    }
}
```

## Round 4

Vulnerable:

```solidity
pragma solidity ^0.7.0;

contract Token {
    mapping (address => uint256) public balanceOf;

    function transfer(address _to, uint256 _value) external {
        /* Check if sender has balance */
        // @audit-issue Does not check for the underflow case
        require(balanceOf[msg.sender] - _value >= 0);
        /* Add and subtract new balances */
        balanceOf[msg.sender] -= _value;
        // @audit-issue Could overflow
        balanceOf[_to] += _value;
    }
}
```

Mitigation:

```solidity
pragma solidity ^0.7.0;

contract Token {
    mapping (address => uint256) public balanceOf;

    function transfer(address _to, uint256 _value) external {
        /* Check if sender has balance and for overflows/underflows */
        require(balanceOf[msg.sender] >= _value);
        require(balanceOf[_to] + _value >= balanceOf[_to]);
        /* Add and subtract new balances */
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;
    }
}
```

## Round 5

Vulnerable contract:

```solidity
contract TokenStore {
    uint256 public price;
    ERC20 public token;
    address public owner;

    function updatePrice(uint256 _price) {
        if (msg.sender == owner) {
            price = _price;
        }
    }

    function buy(uint256 quant) returns (uint256) {
        require(msg.value > quant * price);
        token.transfer(msg.sender. msg.value / price);
    }
}
```

Attacker can front-run user's `buy()` transaction by calling `updatePrice()` and pay higher gas. Attacker can set `price` much higher so that user receives no tokens.

Mitigation:

* Permissions on key functions
* Buyer specifies price
* Timelocks

## Round 6

Vulnerable contract:

```solidity
contract GetRandomness {
    function random() public returns (uint256 result) {
        // randomly choose a recent blocknumber
        // @audit-issue `block.number` can't be used to generate randomness
        uint256 seed = uint256(block.blockhash(block.number));
        uint256 lookBack = uint256(seed) % 300;

        bytes32 hash = block.blockhash(lookBack);
        uint256 randomNumber = uint256(hash);

        return uint256(randomNumber % 100);
    }
}
```

Mitigation: Use Chainlink VRF.

## Round 7

Vulnerable contract:

```solidity
contract EthWrapperToken {
    ...
    uint256 public totalSupply;
    mapping(address => uint256) public balanceOf;
    ...

    function transfer(address _to, uint256 _value) {
        /* Check if sender has balance */
        require(balanceOf[msg.sender] - _value >= 0);

        /* Add and subtract new balances */
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;

        // @audit-issue Attacker can forcefully send ethers to this contract
        require(this.balance == totalSupply);
    }
}
```

Mitigation: Use OpenZeppelin ERC20.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ret2basic.gitbook.io/ctfnote/web3-security-research/secureum/epoch-0/slot-4-pitfalls-and-best-practices-101/intro-to-security-first-development.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
