Animoca Ethereum Contracts
Solidity contracts development helpers which uses HardHat consisting of Hardhat plugins and configurations, tooling and testing utilities.
Solidity contract helpers
HardHat plugins and configurations
A set of plugins and configurations are provided to improve the development experience. They can be used in your own project in your hardhat.config.js
:
const {mergeConfigs} = require('@animoca/ethereum-contract-helpers/src/config');
// load all the plugins (you can also load them one by one)
require("@animoca/ethereum-contract-helpers/hardhat-plugins");
// deep merges your config on top of the default provided config
module.exports = mergeConfigs(require("@animoca/ethereum-contract-helpers/hardhat-config"), {
// my config
});
See the README.md
of each plugin for more details.
Test helpers
Fixtures
To speed up tests execution, fixtures based one evm_snapshot
/evm_revert
can be used. For example:
const { loadFixture } = require("@animoca/ethereum-contract-helpers/src/test/fixtures");
describe("MyContract", function () {
const fixture = async function () {
// contract(s) initialization
};
beforeEach(async function () {
await loadFixture(fixture, this);
});
// tests
// ...
});
Diamond
Functions for managing deployment of diamonds and their facets are provided in src/test/diamond.js
.
Execution
A test runner function allows to test some contract logic in immutable, proxied or diamond setup. The contracts setup in handled via a configuration object, while the deployment logic is delegated to the tool via a function (deployFn
in the example below).
Here is a simple usage example where the same testing logic will be applied to the immutable, proxied and facet versions of a contract:
const { getDeployerAddress } = require("@animoca/ethereum-contract-helpers/src/test/accounts");
const { runBehaviorTests } = require("@animoca/ethereum-contract-helpers/src/test/run");
const { loadFixture } = require("@animoca/ethereum-contract-helpers/src/test/fixtures");
const config = {
immutable: { name: "MyImmutableContract", ctorArguments: ["myArg", "registry"] },
proxied: {
name: "MyProxiedContract",
ctorArguments: ["registry"],
init: { method: "init", arguments: ["myArg"] },
},
diamond: {
facets: [
{ name: "ProxyAdminFacet", ctorArguments: ["registry"], init: { method: "initProxyAdminStorage", arguments: ["initialAdmin"] } },
{ name: "DiamondCutFacet", ctorArguments: ["registry"], init: { method: "initDiamondCutStorage" } },
{
name: "MyFacetContract",
ctorArguments: ["registry"],
init: { method: "initMyStorage", arguments: ["myArg"] },
},
],
},
defaultArguments: {
registry: async () => {/* get registry address */},
initialAdmin: getDeployerAddress,
},
};
runBehaviorTests("MyContract", config, function (deployFn) {
const fixture = async function () {
this.contract = await deployFn({ myArg: "test" });
};
beforeEach(async function () {
await loadFixture(fixture, this);
});
// tests
// ...
});
Installation
To install the module in your project, add it as an npm dependency:
yarn add -D @animoca/ethereum-contract-helpers
or
npm add --save-dev @animoca/ethereum-contract-helpers