• Stars
    star
    728
  • Rank 62,237 (Top 2 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 6 years ago
  • Updated almost 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Library for writing and testing smart contracts.

CI Discord

Ethereum Waffle

The most advanced framework for testing smart contracts.

Sweeter, simpler and faster.

Links

Philosophy

  • Simpler: Minimalistic, few dependencies.
  • Sweeter: Nice syntax, easy to extend.
  • Faster: Strong focus on the speed of test execution.

Features:

  • Sweet set of chai matchers, e.g.:
    • expect(...).to.be.revertedWith('Error message')
    • expect(...).to.emit(contract, 'EventName').withArgs(...))
  • Importing contracts from npm modules working out of the box, e.g.:
    • import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
  • Fixtures that help write fast and maintainable test suites, e.g.:
    • const {token} = await loadFixture(standardTokenWithBalance);
  • Customizable compilation options with native solc, dockerized solc and any version of solc-js loaded remotely at compiled time
  • Mocking smart contracts, e.g.:
    • const mockToken = await deployMockContract(wallet, IERC20.abi);
  • Support for promise-based configuration, e.g.:
    • use native solc binary for fast compilation in CI environment
    • use solc-js based on contract versions detected (async)
  • Support for TypeScript
  • Type-safe contract deployment and interactions with TypeChain
  • Documentation

Documentation

Documentation is available here.

Installation:

To get started install ethereum-waffle with yarn:

yarn add --dev ethereum-waffle

Or if you prefer using npm:

npm install --save-dev ethereum-waffle

Step by step guide

Add external dependency:

To add an external library install it using npm:

npm install @openzeppelin/contracts -D

or with yarn:

yarn add @openzeppelin/contracts -D

Note

Find this example in examples/basic and use it.

Example contract

Below is an example contract written in Solidity. Place it in contracts/BasicToken.sol file of your project:

pragma solidity ^0.6.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

// Example class - a mock class using delivering from ERC20
contract BasicToken is ERC20 {
    constructor(uint256 initialBalance) ERC20("Basic", "BSC") public {
        _mint(msg.sender, initialBalance);
    }
}

Example test

Below is an example test written for the contract above compiled with Waffle. Place it under test/BasicToken.test.ts file in your project directory:

import {expect, use} from 'chai';
import {Contract} from 'ethers';
import {deployContract, MockProvider, solidity} from 'ethereum-waffle';
import BasicToken from '../build/BasicToken.json';

use(solidity);

describe('BasicToken', () => {
  const [wallet, walletTo] = new MockProvider().getWallets();
  let token: Contract;

  beforeEach(async () => {
    token = await deployContract(wallet, BasicToken, [1000]);
  });

  it('Assigns initial balance', async () => {
    expect(await token.balanceOf(wallet.address)).to.equal(1000);
  });

  it('Transfer adds amount to destination account', async () => {
    await token.transfer(walletTo.address, 7);
    expect(await token.balanceOf(walletTo.address)).to.equal(7);
  });

  it('Transfer emits event', async () => {
    await expect(token.transfer(walletTo.address, 7))
      .to.emit(token, 'Transfer')
      .withArgs(wallet.address, walletTo.address, 7);
  });

  it('Can not transfer above the amount', async () => {
    await expect(token.transfer(walletTo.address, 1007)).to.be.reverted;
  });

  it('Can not transfer from empty account', async () => {
    const tokenFromOtherWallet = token.connect(walletTo);
    await expect(tokenFromOtherWallet.transfer(wallet.address, 1))
      .to.be.reverted;
  });

  it('Calls totalSupply on BasicToken contract', async () => {
    await token.totalSupply();
    expect('totalSupply').to.be.calledOnContract(token);
  });

  it('Calls balanceOf with sender address on BasicToken contract', async () => {
    await token.balanceOf(wallet.address);
    expect('balanceOf').to.be.calledOnContractWith(token, [wallet.address]);
  });
});

Note: You will also need to install the following dependencies to run the example above:

yarn add mocha -D
yarn add chai -D

Or with npm:

npm i chai -D
npm i mocha -D

Compiling

To compile your smart contracts run:

npx waffle

To compile using a custom configuration file run:

npx waffle config.json

Example configuration file looks like this (all fields optional):

{
  "sourceDirectory": "./custom_contracts",
  "outputDirectory": "./custom_build",
  "nodeModulesDirectory": "./custom_node_modules"
}

To enable generation of typechain artifacts:

{
  "typechainEnabled": true
}

Flattener

To flat your smart contracts run:

npx waffle flatten

In configuration file you can add optional field with path to flatten files:

{
  "flattenOutputDirectory": "./custom_flatten"
}

Running tests

To run the tests run the following command:

npx mocha

Adding an npm script

For convenience, you can add the following to your package.json:

{
  ...,
  "scripts": {
    "test": "waffle && mocha"
  }
}

Now you can build and test your contracts with one command:

npm test

Documentation

For detailed feature walkthrough checkout documentation.

Contributing

Contributions are always welcome, no matter how large or small. Before contributing, please read the code of conduct and contribution policy.

Before you issue pull request:

Make sure all tests and linters pass. Make sure you have test coverage for any new features.

Running tests

Note: To make end-to-end test pass, you need to:

  • have Docker installed, up and running
  • have Ethereum stable docker image pulled, if not run docker pull ethereum/solc:stable
  • have native solidity 0.5.* installed

To run tests type:

yarn test

To run linter type:

yarn lint

Building documentation

Install Sphinx to build documentation:

cd docs
make html

Before building documentation for the first time you may have to install required python packages:

pip3 install -r docs/requirements.txt

Roadmap

See #155

License

Waffle is released under the MIT License.

More Repositories

1

useDApp

Framework for rapid Dapp development. Simple. Robust. Extendable. Testable
TypeScript
854
star
2

ethereum.rb

Ethereum library for the Ruby language
Ruby
728
star
3

Mars

Mars is an infrastructure-as-code tool for Ethereum
TypeScript
77
star
4

Doppelganger

Smart contract mocking tool
TypeScript
59
star
5

AllSporter-TGE

AllSporter Crowdsale and Allsporter Token
JavaScript
27
star
6

ENSBuilder

A mock ENS system builder for developing and testing applications using ENS
JavaScript
20
star
7

reactive-properties

Simple reactive property system
TypeScript
19
star
8

bn-chai

BN chai extends Chai with bn.js operations.
JavaScript
14
star
9

ethworks-solidity

Library with common Solidity smart contracts
JavaScript
14
star
10

bem-components-react

A factory to create react components that follow BEM methodology with first-class typescript support.
TypeScript
13
star
11

dapp-boilerplate

A boilerplate for your DApp needs
TypeScript
12
star
12

truffle-zeppelin-boilerplate

Minimalistic boilerplate for using open zeppelin with truffle
JavaScript
12
star
13

hackathons

4
star
14

PingPongPairProgrammingDojo

JavaScript
3
star
15

ethereumjs-vm-benchmarks

JavaScript
3
star
16

ThinkCoinCrowdsaleContract

ThinCoin Token and Crowdsale Contract
JavaScript
3
star
17

zksync-spike

TypeScript
2
star
18

ts-esnure

TypeScript
2
star
19

statemine-asset-creator

TypeScript
2
star
20

status-waku

HTML
1
star
21

tech-talk-10

TypeScript
1
star
22

html-css-starter

Sass
1
star
23

0xstudents-homework

1
star
24

status-waku-voting

TypeScript
1
star
25

bootcamp

TypeScript
1
star
26

pair-programming-dojo

JavaScript
1
star
27

LiveCoding

TypeScript
1
star
28

react-boilerplate

TypeScript
1
star
29

external_call_bug_hunt

JavaScript
1
star
30

mimuw-zajecia

1
star
31

pair-programming

JavaScript
1
star
32

mini2018Z_workshop2

Materials for workshop 2 (MINI 2018Z edition)
JavaScript
1
star
33

useDot

TypeScript
1
star
34

restless-website

HTML
1
star
35

status-DApp-connect

HTML
1
star
36

circom-hello-world

Template to quickly learn circom
TypeScript
1
star
37

status-vac

HTML
1
star
38

react-template

JavaScript
1
star