Lesson 17 of 23
In Progress

Use of Security Tools and Frameworks (Mythril, Oyente)

As a blockchain developer, ensuring the security of your smart contracts is of the utmost importance. To do this, it is helpful to use security tools and frameworks that can help you identify and fix vulnerabilities in your code. In this article, we will explore two popular security tools: Mythril and Oyente.

What is Mythril?

Mythril is an open-source security tool that analyzes Ethereum smart contracts for vulnerabilities. It uses a technique called symbolic execution, which allows it to explore all possible paths of execution in a smart contract, to identify potential vulnerabilities. Mythril is able to detect a variety of vulnerabilities, including:

  • Reentrancy attacks
  • Transaction-ordering dependence (TOD)
  • Integer overflows and underflows

How to Use Mythril

Mythril can be used in a number of ways, including as a command-line tool, a Python library, and as a plugin for the Truffle development framework. Here’s an example of how to use Mythril as a command-line tool:

$ myth -x my_contract.sol

This will analyze the Solidity contract file my_contract.sol for vulnerabilities. Mythril will output a report detailing any vulnerabilities it finds, along with recommendations for how to fix them.

Here’s an example of how to use Mythril as a Python library:

from mythril.analysis.report import Issue
from mythril.analysis import solver
from mythril.analysis.security import MythrilAnalyzer

# Load contract bytecode
with open("my_contract.bin", "rb") as bytecode_file:
    bytecode = bytecode_file.read()

# Run Mythril analysis
issues = MythrilAnalyzer.analyze(bytecode)

# Print results
for issue in issues:
    print(f"Severity: {issue.severity}")
    print(f"Description: {issue.description}")
    print(f"Contract: {issue.contract}")
    print(f"Function: {issue.function}")
    print(f"PCI: {issue.pci}")

What is Oyente?

Oyente is another open-source security tool that analyzes Ethereum smart contracts for vulnerabilities. It uses a technique called static analysis, which examines the code of a smart contract without executing it, to identify potential vulnerabilities. Oyente is able to detect a range of vulnerabilities, including:

  • Reentrancy attacks
  • TOD
  • Integer overflows and underflows

How to Use Oyente

Oyente can be used as a command-line tool or as a Python library. Here’s an example of how to use Oyente as a command-line tool:

$ oyente -s my_contract.sol

This will analyze the Solidity contract file my_contract.sol for vulnerabilities. Oyente will output a report detailing any vulnerabilities it finds, along with recommendations for how to fix them.

Here’s an example of how to use Oyente as a Python library:

from oyente import Oyente

# Load contract source code
with open("my_contract.sol", "r") as source_file:
    source_code = source_file.read()

# Run Oyente analysis
issues = Oyente.analyze(source_code)

# Print results
for issue in issues:
    print(f"Severity: {issue.severity}")
    print(f"Description: {issue.description}")
    print(f"Contract: {issue.contract}")
    print(f"Function: {issue.function}")
    print(f"PCI: {issue.pci}")

Choosing the Right Tool

Both Mythril and Oyente are useful tools for ensuring the security of your smart contracts. However, they have different strengths and approaches to analysis, so you may want to use both tools to get a comprehensive view of the security of your contracts.

Mythril is particularly good at detecting vulnerabilities that are caused by the interaction of multiple functions in a smart contract. It is also able to analyze the bytecode of a contract, which can be useful if you do not have access to the source code.

Oyente is particularly good at detecting vulnerabilities that are caused by the interaction between a contract and external contracts. It is also able to analyze the source code of a contract, which can be useful for understanding the context of a vulnerability.

Conclusion

In this article, we have introduced two security tools for Ethereum smart contracts: Mythril and Oyente. Both tools are useful for identifying vulnerabilities in your contracts and helping you fix them. By using these tools, you can improve the security of your contracts and ensure that they function as intended.

Exercises

To review these concepts, we will go through a series of exercises designed to test your understanding and apply what you have learned.

In this exercise, you will fix the integer overflow vulnerability in the SimpleOverflow contract from the previous exercise.

Modify the SimpleOverflow contract to use the SafeMath library to prevent integer overflows:

pragma solidity ^0.6.0;

import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol";

contract SimpleOverflow {
    using SafeMath for uint;

    uint public balance;

    function increaseBalance(uint amount) public {
        balance = balance.add(amount);
    }
}

Run Mythril on the contract file:

$ myth -x SimpleOverflow.sol

Mythril should no longer output a report detailing an integer overflow vulnerability.

In this exercise, you will fix the integer underflow vulnerability in the SimpleUnderflow contract from the previous exercise.

Modify the SimpleUnderflow contract to use the SafeMath library to prevent integer underflows:

pragma solidity ^0.6.0;

import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol";

contract SimpleUnderflow {
    using SafeMath for uint;

    uint public balance;

    function decreaseBalance(uint amount) public {
        balance = balance.sub(amount);
    }
}

Run Oyente on the contract file:

$ oyente -s SimpleUnderflow.sol

Oyente should no longer output a report detailing an integer underflow vulnerability.

In this exercise, you will use Mythril to detect an unchecked call failure in a contract.

Create a file called UncheckedCall.sol with the following code:

pragma solidity ^0.6.0;

import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol";

contract UncheckedCall {
    using SafeMath for uint;

    uint public balance;

    function sendEther(address recipient, uint amount) public {
        require(recipient.call.value(amount)());
        balance = balance.sub(amount);
    }
}

Run Mythril on the contract file:

$ myth -x UncheckedCall.sol

Mythril should output a report detailing the unchecked call failure vulnerability.

In this exercise, you will fix the unchecked call failure vulnerability in the UncheckedCall contract from the previous exercise.

Modify the UncheckedCall contract to use the require function to check the return value of the external call:

pragma solidity ^0.6.0;

import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol";

contract UncheckedCall {
    using SafeMath for uint;

    uint public balance;

    function sendEther(address recipient, uint amount) public {
        require(recipient.call.value(amount)(), "Call failed");
        balance = balance.sub(amount);
    }
}

Run Mythril on the contract file:

$ myth -x UncheckedCall.sol

Mythril should no longer output a report detailing an unchecked call failure vulnerability.

In this exercise, you will use Mythril to detect an unsafe external call in a contract.

Create a file called UnsafeCall.sol with the following code:

pragma solidity ^0.6.0;

import "https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/math/SafeMath.sol";

contract UnsafeCall {
    using SafeMath for uint;

    uint public balance;

    function sendEther(address recipient, uint amount) public {
        recipient.call.value(amount)();
        balance = balance.sub(amount);
    }
}

Run Mythril on the contract file:

$ myth -x UnsafeCall.sol

Mythril should output a report detailing the unsafe external call vulnerability.