Automated test suite

Documentation Status

Mock smart contracts for writing Ethereum test suites

This package contains common Ethereum smart contracts to be used in automated test suites.
This was created for Trading Strategy, but can be used for any other
projects as well. As opposite to slower and messier mainnet forking test strategies,
this project aims to explicit clean deployments and very fast test execution.

Smart contract support includes

  • ERC-20 token
  • SushiSwap: router, factory, pool (Uniswap v2, PancakeSwape, QuickSwap, Trader Joe and others are 99% Sushiswap compatible)
  • High-quality API documentation
  • Full type hinting support for optimal developer experience
  • (More integrations to come)

Table of contents

Precompiled ABI file distribution

This package primarly supports Python, Web3.p3 and Brownie developers.
For other programming languages and frameworks,
you can find precompiled Solidity smart contracts in abi folder.

These files are good to go with any framework:

  • Web3.js
  • Ethers.js
  • Hardhat
  • Truffle
  • Web3j

Each JSON file has abi and bytecode keys you need to deploy a contract.

Just download and embed in your project.
The compiled source code files are mixture of MIT and GPL v2 license.

Python usage

The Python support is available as smart_contract_test_fixtures Python package.

The package depends only on and not others, like Brownie.
It grabs popular ABI files with their bytecode and compilation artifacts so that the contracts
are easily deployable on any Ethereum tester interface. No Ganache is needed and everything
can be executed on faster eth-tester enginer.

[Read the full API documnetation](High-quality API documentation).
For code examples please see below.


ERC-20 token example

To use the package to deploy a simple ERC-20 token in pytest testing:

import pytest
from web3 import Web3, EthereumTesterProvider

from smart_contracts_for_testing.token import create_token

def tester_provider():
    return EthereumTesterProvider()

def eth_tester(tester_provider):
    return tester_provider.ethereum_tester

def web3(tester_provider):
    return Web3(tester_provider)

def deployer(web3) -> str:
    """Deploy account."""
    return web3.eth.accounts[0]

def user_1(web3) -> str:
    """User account."""
    return web3.eth.accounts[1]

def user_2(web3) -> str:
    """User account."""
    return web3.eth.accounts[2]

def test_deploy_token(web3: Web3, deployer: str):
    """Deploy mock ERC-20."""
    token = create_token(web3, deployer, "Hentai books token", "HENTAI", 100_000 * 10**18)
    assert == "Hentai books token"
    assert token.functions.symbol().call() == "HENTAI"
    assert token.functions.totalSupply().call() == 100_000 * 10**18
    assert token.functions.decimals().call() == 18

def test_tranfer_tokens_between_users(web3: Web3, deployer: str, user_1: str, user_2: str):
    """Transfer tokens between users."""
    token = create_token(web3, deployer, "Telos EVM rocks", "TELOS", 100_000 * 10**18)

    # Move 10 tokens from deployer to user1
    token.functions.transfer(user_1, 10 * 10**18).transact({"from": deployer})
    assert token.functions.balanceOf(user_1).call() == 10 * 10**18

    # Move 10 tokens from deployer to user1
    token.functions.transfer(user_2, 6 * 10**18).transact({"from": user_1})
    assert token.functions.balanceOf(user_1).call() == 4 * 10**18
    assert token.functions.balanceOf(user_2).call() == 6 * 10**18

See full example.

For more information how to user in testing, see documentation.

Uniswap swap example

import pytest
from web3 import Web3
from web3.contract import Contract

from smart_contracts_for_testing.uniswap_v2 import UniswapV2Deployment, deploy_trading_pair, FOREVER_DEADLINE

def test_swap(web3: Web3, deployer: str, user_1: str, uniswap_v2: UniswapV2Deployment, weth: Contract, usdc: Contract):
    """User buys WETH on Uniswap v2 using mock USDC."""

    # Create the trading pair and add initial liquidity
        10 * 10**18,  # 10 ETH liquidity
        17_000 * 10**18,  # 17000 USDC liquidity

    router = uniswap_v2.router

    # Give user_1 500 dollars to buy ETH and approve it on the router
    usdc_amount_to_pay = 500 * 10**18
    usdc.functions.transfer(user_1, usdc_amount_to_pay).transact({"from": deployer})
    usdc.functions.approve(router.address, usdc_amount_to_pay).transact({"from": user_1})

    # Perform a swap USDC->WETH
    path = [usdc.address, weth.address]  # Path tell how the swap is routed
        "from": user_1

    # Check the user_1 received ~0.284 ethers
    assert weth.functions.balanceOf(user_1).call() / 1e18 == pytest.approx(0.28488156127668085)

See the full example.

How to use the library in your Python project

Add smart_contract_test_fixtures as a development dependency:

Using Poetry:

poetry add -D smart_contract_test_fixtures


This step will extract compiled smart contract from Sushiswap repository.


  • Node v14
  • npx
  • yarn
  • GNU Make
  • Unix shell


To build the ABI distribution:

git submodule update --recursive --init
make all

See SushiSwap continuous integration files for more information.

Version history

See change log.


Join Discord for any questions.


Currently there is no Brownie support.
To support Brownie, one would need to figure out how to import an existing Hardhat
based project (Sushiswap) to Brownie project format.




View Github