---
# System prepended metadata

title: Security

---

<!-- ---
type: slide
--- -->

# Smart Contract Security


---

# Assets in Smart Contract


- [DeFi Market Cap](https://defillama.com/)
![](https://hackmd.io/_uploads/HkbzDAM02.png)
- **Manta Pacific**
    |Project|Assets|
    |---|---|
    |zkHoldem|Game Token|
    |zkSBT|NFT|
    |perpetual|WETH/USD...|
    |...|...|

---

# vulnerabilities
-  [Attacker : looking to profit by exploiting vulnerabilities](https://rekt.news/)

<div style="text-align:center;">
<img src="https://hackmd.io/_uploads/Skez50MRn.png" alt="rekt leaderboard" width="300" height="500">
</div>

---

<!-- # Pre-requisites

- fundamentals of smart contract development
- Adavaced Topics :
    - storage slot
    - evm execution context
    - call/delegate call
    - ....

--- -->


# Challenges : practice to learn security

- [Openzepplin Ethernaut](https://ethernaut.openzeppelin.com/) - Web3/Solidity-based wargame where each level is a smart contract that needs to be 'hacked'.
    - help, player, contract
    <div style="text-align:center;">
    <img src="https://hackmd.io/_uploads/Syn-MIA32.png" alt="ethernaut" width="500" height="300">
    </div>
- [BlockSec CTF](https://github.com/blockthreat/blocksec-ctfs) - Curated list of blockchain security wargames, challenges, and  competitions and solution writeups
- [manta-network/security](https://github.com/Manta-Network/security/tree/main/packages/contracts/contracts/security)


---

# Common vulnerabilities

- Integer Overflow and Underflow
- No Private in Contract
- Randomnes
- Fallback Function
    - Proxy Pattern
    - Re-Entrancy

---

## Integer Overflow and Underflow

|Problem|Analysis|Best Practice|
|---|---|---|
|[Ethernaut-05-Token](https://ethernaut.openzeppelin.com/level/0x478f3476358Eb166Cb7adE4666d04fbdDB56C407)|No built-in Compiler overflow Check for Solidity < 0.8|1.openzepplin.safeMath <br> 2. solidity 0.8 compiler check  |


```solidity=
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.6.0;

    contract c {
        function add(uint8 x) public returns(uint8) {
            return x + 1;
        }
    }
```

```typescript=
    // call add
    const res = await c.add(255)
    expect(res).eq(0)
```

---

## No Privacy in Contract

| Problem|Analysis|Best Practice|
|---|---|---|
|[Ethernaut-08-Vault](https://ethernaut.openzeppelin.com/level/0xB7257D8Ba61BD1b3Fb7249DCd9330a023a5F3670)|Everything you use in a smart contract is publicly visible, even local variables and state variables marked private.|1. do not use on-chain data as 'key'  |


```solidity=
    // solidity contract
    contract c {
      bool public locked;
      bytes32 private password;
        
        function open(uint key) {
            if (key == password) {
                locked = false;
            }
        }
    }
```

```typescript=
    // get locked
    const locked = await c.locked()

    // get password
    const slotIndex = 1
    const password = await provider.getStorageAt(c.address, slotIndex)
    await c.open(password)
```

---

## Randomnes

|Problem|Analysis|Best Practice|
|---|---|---|
|[Ethernaut-03-CoinFlip](https://ethernaut.openzeppelin.com/level/0xA62fE5344FE62AdC1F356447B669E9E6D10abaaF)|Using random numbers in smart contracts is quite tricky if you do not want miners to be able to cheat.|1. do not use block nubmer/hash/timestamp as random entropy <br> 2. [Chainlink VRF : Verifiable source of randomness](https://chain.link/vrf) <br> 3. [Verifiable Delay Functions (VDFs)](https://blog.trailofbits.com/2018/10/12/introduction-to-verifiable-delay-functions-vdfs/)  |


```solidity=
    // Contract
    function flip(bool _guess) public returns (bool) {
        uint256 blockValue = uint256(blockhash(block.number - 1));

        uint256 coinFlip = blockValue / FACTOR;
        bool side = coinFlip == 1 ? true : false;

        if (side == _guess) {
          return true;
        } else {
          return false;
        }
     }
```

```solidity=
    // Hacker
    contract HackCoinFlip {
        CoinFlip cf;
        constructor(address _cf) {
            cf = CoinFlip(_cf);
        }

        function getResult() public view returns (bool) {
            uint256 blockValue = uint256(blockhash(block.number - 1));

            uint256 coinFlip = blockValue / FACTOR;
            return coinFlip == 1 ? true : false;
        }

        function flip() public returns (bool) {
            return cf.flip(getResult());
        }
    }
```





---


## [Fallback Function](https://docs.soliditylang.org/en/v0.8.15/contracts.html#fallback-function)

|Problem|Analysis|Best Practice|
|---|---|---|
|[Ethernaut-10-Reentracy](https://ethernaut.openzeppelin.com/level/0x2a24869323C0B13Dff24E196Ba072dC790D52479)| 1. executed if none of the other functions match the given function name <br> 2. or .send()/.transfer() without a receive ether function.| recommended to define a receive Ether function as well, to distinguish Ether transfers from interface confusions |

```solidity
    // SPDX-License-Identifier: GPL-3.0
    pragma solidity >=0.6.2 <0.9.0;

    contract Test {
        uint x;
        // This function is called for all messages sent to
        // this contract (there is no other function).
        // Sending Ether to this contract will cause an exception,
        // because the fallback function does not have the `payable`
        // modifier.
        fallback() external { x = 1; }
    }
```



---


## Fallback User Case : Re-Entrancy

|Problem|Analysis|Best Practice|
|---|---|---|
|[Ethernaut-10-Reentracy](https://ethernaut.openzeppelin.com/level/0x2a24869323C0B13Dff24E196Ba072dC790D52479)| | [check-effects-interactions pattern](https://solidity.readthedocs.io/en/v0.5.8/security-considerations.html#use-the-checks-effects-interactions-pattern) : always first do checks and then state changes and only then external contracts calls or transfers  |

```solidity=
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.6.12;

    import 'openzeppelin-contracts-06/math/SafeMath.sol';

    contract Reentrance {

      using SafeMath for uint256;
      mapping(address => uint) public balances;

      function donate(address _to) public payable {
        balances[_to] = balances[_to].add(msg.value);
      }

      function balanceOf(address _who) public view returns (uint balance) {
        return balances[_who];
      }

      function withdraw(uint _amount) public {
        if(balances[msg.sender] >= _amount) {  
 // check
          balances[msg.sender] -= _amount;    // update
          (bool result,) = msg.sender.call{value:_amount}("");    // interaction
          if(result) {
            _amount;
          }

        }
      }

      receive() external payable {}
    }
```


---

# [Fallback User Case : Proxy Pattern]((https://blog.openzeppelin.com/proxy-patterns))


![](https://hackmd.io/_uploads/HkNzT-NCh.png)

<!-- [Puzzle-Ethernaut-PullzeWallet]([/O21qA4vuRdexEwGOQObtbA](https://ethernaut.openzeppelin.com/level/0x725595BA16E76ED1F6cC1e1b65A88365cC494824))

[Puzzle-Ethernaut-MotorBike](https://ethernaut.openzeppelin.com/level/0x3A78EE8462BD2e31133de2B8f1f9CBD973D6eDd6) -->

---


# Contract Upgrades



- [upgradeable zksbt on manta pacific](https://pacific-explorer.manta.network/address/0xFEe052821D8eFbE20a396695533Fb5B46765edA5)
- more details in ["Upgradable contracts: UUPS and Multi-faucet proxy" Course](https://www.notion.so/mantanetwork/Upgradable-contracts-UUPS-and-Multi-faucet-proxy-27732239d91d495f90fd5bebefaca565)


# Emergency stops

```solidity=

    contract EmergencyStop {

        bool isStopped = false;

        modifier stoppedInEmergency {
            require(!isStopped);
            _;
        }

        modifier onlyAuthorized {
            // Check for authorization of msg.sender here
            _;
        }

        function stopContract() public onlyAuthorized {
            isStopped = true;
        }

        function deposit() public payable stoppedInEmergency {
            // Deposit logic happening here
        }
    }

```

# Using Audit/Battle test library (Openzepplin)

- [SafeMath](https://docs.openzeppelin.com/contracts/4.x/api/utils#SafeMath)
- [access control](https://docs.openzeppelin.com/contracts/4.x/access-control)
    - Ownable pattern
    - role-based control
    - Using multi-signature wallets
- [ReentrancyGuard](https://docs.openzeppelin.com/contracts/4.x/api/security#ReentrancyGuard)
- ERC20, ERC721, Upgradable Proxy...



# 3rd-party review : Audit & Bug bounties

<!-- 
## mind note
![](https://hackmd.io/_uploads/B1jdwZon2.png) -->

---

## Advanced Topic

- Honey Pot
- [Flashloan](https://docs.aave.com/developers/guides/flash-loans)
- [Frontrun/Sandwich/Mev](https://eigenphi.io/mev/ethereum/sandwich)

---

# Reference

- [Solidity Security Considerations](https://docs.soliditylang.org/en/v0.8.15/security-considerations.html#security-considerations)
- [Consensys GitHub repo](https://docs.soliditylang.org/en/v0.8.15/security-considerations.html#security-considerations:~:text=the%20Consensys%20GitHub%20repo)
- [Ethereum Foundation EVM](https://ethereum.org/en/developers/docs/evm/)
- [Ethereum Foundation Security Guide](https://ethereum.org/en/developers/docs/smart-contracts/security/)
- [Master Ethereum : Gavin Wood](https://www.amazon.com/Mastering-Ethereum-Building-Smart-Contracts/dp/1491971940)
- [calyptus_web3](https://twitter.com/calyptus_web3)








<!-- ## Overview

Goal/Why

smart contracts hold Money

curve, ...

USD ?

Dune Boards ? TVL ?

open source, public execution.




- safe project :
    * perpetual/zksbt/zkholdem
- make money : bug bounty.
    * number of  -->

<!-- ___

## Compiler Bugs

- even if your smart contract code is bug-free, the compiler or the platform itself might have a bug.
    - curve
    - [list of known compiler bugs](https://docs.soliditylang.org/en/v0.8.15/bugs.html#known-bugs) -->


<!-- ---

## EVM Context && Msg.sender

[delegate call](https://docs.soliditylang.org/en/v0.8.15/introduction-to-smart-contracts.html?highlight=delegatecall#delegatecall-callcode-and-libraries)
- message call apart from the fact that the code at the target address is executed in the context
- dynamically load code from a different address at runtime (proxy paradigm)
- 

[Puzzle-Ethernaut-06](https://ethernaut.openzeppelin.com/level/0x73379d8B82Fda494ee59555f333DF7D44483fD58) 


---


<!-- solidity special functions -->
<!-- ## [Receive Ether Function](https://docs.soliditylang.org/en/v0.8.15/contracts.html#receive-ether-function)

|Problem|Analysis|Best Practice|
|---|---|---|
|[1. Ethernaut-02-Fallback](https://ethernaut.openzeppelin.com/level/0x3c34A342b2aF5e885FcaA3800dB5B205fEfa3ffB)<br> [2. Ethernaut-09-King](https://ethernaut.openzeppelin.com/level/0x3049C00639E6dfC269ED1451764a046f7aE500c6)|executed on plain Ether transfers (e.g. via .send() or .transfer())| | -->
<!-- 
    ```solidity
    // SPDX-License-Identifier: GPL-3.0
    pragma solidity >=0.6.0 <0.9.0;

    // This contract keeps all Ether sent to it with no way
    // to get it back.
    contract Sink {
        event Received(address, uint);
        receive() external payable {
            emit Received(msg.sender, msg.value);
        }
    }
    ``` -->