@nayms/contracts

Nayms smart contracts

Usage no npm install needed!

<script type="module">
  import naymsContracts from 'https://cdn.skypack.dev/@nayms/contracts';
</script>

README

CircleCI Coverage Status

Nayms Smart contracts.

NOTE: the old version of the contracts used to deploy the v1 pilots can be found via the v1_post_audit tag.

How to use

Install the package:

npm install @nayms/contracts

The package exposes the following properties:

  • contracts - the key contracts (see below)
  • rawContracts - ABIs of all Solidity contracts in the repo
  • addresses - contents of deployedAddresses.json
  • events - ABIs for events to listen for
  • releaseConfig - the contents of releaseConfig.json, this is used to keep track of the build number in VersionInfo.sol.
  • extractEventsFromAbis() - given an array of contract ABIs, this will extract the event ABIs within.
  • keccak256() - keccak256 hash function
  • ROLES - role constants
  • ROLEGROUPS - rolegroup constants
  • SETTINGS - settings constants

The key contracts are:

  • ACL (IACL.sol) - Interface for our access control system. We have a single global ACL for our platform.
  • AccessControl (AccessControl.sol) - Interface for obtaining ACL context info from deployed contracts.
  • EntityDeployer (IEntityDeployer.sol) - Interface for the entity deployer. We have a single global deployer for our platform.
  • Entity (IEntity.sol) - Interface for interacting with entities.
  • ERC20 (IERC20.sol) - Interface for interacting with ERC-20 contracts.
  • EtherToken (IEtherToken.sol) - Interface for interacting with wrapped ETH token contract. We have a single global instance for our platform.
  • Market (IMarket.sol) - Interface for interacting with our MakerOTC matching market. We have a single global instance for our platform.
  • Policy (IPolicy.sol) - Interface for interacting with policies.
  • Settings (ISettings.sol) - Interface for global settings. We have a single global settings instance for our platform.

The Nayms company entity and its address can be obtained via Settings.getAddress(SETTINGS.NAYMS_ENTITY).

Technical docs

An architectural overview can be found in docs/architecture.md.

Architectural Decision Records (ADRs) can be found in docs/adr.

Example usage

const ethers = require('ethers')
const { parseLog } = require('ethereum-event-logs')
const { contracts, addresses, events } = require('@nayms/contracts')

const mnemonic = '<mnemonic pass phrase>'

const init = async () => {
  const provider = new ethers.providers.InfuraProvider('rinkeby', '<infura token>')

  const wallet = ethers.Wallet.fromMnemonic(mnemonic).connect(provider)

  const deployer = new ethers.Contract(
    // '4' is Rinkeby (see https://chainid.network/chains/)
    addresses.EntityDeployer['4'].address,
    contracts.EntityDeployer.abi,
    wallet
  )

  // deploy a new Entity
  const tx = await deployer.deploy({
    gasPrice: '0x3B9ACA00', // 1,000,000,000
    gasLimit: '0x2DC6C0', // 1,500,000
  })

  console.log(`Tx hash: ${tx.hash}`)

  const receipt = await provider.waitForTransaction(tx.hash)

  const [ newEntityEvent ] = parseLog(receipt.logs, [ events.NewEntity ])
  const { args: { entity } } = newEntityEvent

  console.log(`New entity deployed at: ${entity}`)
}

init().catch(err => {
  console.error(err)
  process.exit(-1)
})

To deploy and use the contracts on your local chain please clone this repository and run the following deployment commands:

yarn compile
yarn deploy:local
# The addresses at which the contract are deployed will be output in the terminal.

Development

Requirements:

  • Node.js 14.16.0+
  • Yarn 1.22.10+ (use npm i -g yarn once Node.js is installed)

Install dependencies:

yarn

Initialize git submodules (for maker-otc trading engine):

git submodule init
git submodule update

First, run the dev network in a separate terminal:

yarn devnet

Compile the contracts:

yarn compile

Setup release config:

yarn setup-release-config-for-local

Now deploy the contracts to it:

yarn deploy:local

Now you can run the tests:

yarn test

To run a single test:

yarn hardhat test ./test/testName.js

You can use the admin dapp to interact with your locally deployed contracts.

First let's build it:

yarn build-admin-dapp

Then open Metamask in your browser and configure it to use our custom mnemonic and pointing to http://localhost:8545 as a Custom RPC endpoint (Note: you may already have a "Localhost 8545" entry in your Metamask network list, in which ase you don't need to add a new one).

Once done, start a lightweight HTTP server to serve up the admin dapp:

npx serve ./dapp

Visit the URL shown in the output and enjoy.

Deployments

NOTE: Rinkeby/Mainnet deployments are done using Nayms wallet 2, i.e. the second wallet generated from the Nayms company mnemonic - 0xfcE918c07BD4c900941500A6632deB24bA7897Ce. Also note that we use a dedicated Infura endpoint for smart contracts deployments (find it in 1password).

Set up the env vars:

export MNEMONIC="..."
export INFURA_KEY="..."

To upgrade existing Rinkeby contracts:

yarn setup-release-config-for-rinkeby
yarn deploy:rinkeby

For mainnet:

yarn setup-release-config-for-mainnet
yarn deploy:mainnet

By default all deployments are upgrade-only, meaning that the ACL, Settings and other such contracts won't get deployed - instead the existing addresses from deployedAddresses.json will be used. Existing Entity and Policy contracts will be upgraded to the latest implementations.

Fresh deployments

To deploy a fresh set of contracts and update deployedAddresses.json, edit releaseConfig.json and add the following keys before running the deploy command:

{
  ...
  "freshDeployment": true,
  "extractDeployedAddresses": true,
  ...
}

The deployedAddresses.json file will be modified once complete. Remember to commit this into Git and push since it contains the addresses of the newly deployed ACL, Settings, etc.

The release branch

Pushing to the release branch will result in a Rinkeby deployment (upgrade-only) as well as the admin dapp being deployed.

Known issues

When deploying to public networks, if deployment fails with a "transaction underpriced" error then it means there are pending transactions for the deployment account - you need to wait for these to complete before trying again.

Notes