<!-- ---
type: slide
--- -->
# Smart Contract Security
---
# Assets in Smart Contract
- [DeFi Market Cap](https://defillama.com/)

- **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))

<!-- [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
 -->
---
## 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);
}
}
``` -->