Deploying BZx on the Matic testnet

Matic Network is a sidechain based scaling solution for public blockchains. It is based on an adapted implementation of Plasma framework. Matic provides scalability while ensuring a superior user experience in a secured and decentralized manner.

BZx is a protocol for next generation (b)0x-standard relays.

This guide will take you through:

Deploy BZx contracts

Clone bZx-monorepo repository and checkout master branch, install node dependencies

$ git clone https://github.com/bZxNetwork/bZx-monorepo.git
$ cd bZx-monorepo/
$ git checkout master
$ yarn install

Open packages/contracts/truffle-config.js file, add matic config, you can replace fae420... with your private key

...
matic: {
    provider: () => new PrivateKeyProvider(
        'fae42052f82bed612a724fec3632f325f377120592c75bb78adfcceae6470c5a',
        'https://testnet2.matic.network'
    ),
    network_id: 8995,
    gas: 6721975,
    gasPrice: 0,
    confirmations: 0,
    timeoutBlocks: 200,
    skipDryRun: true
},
...

Open packages/contracts/protocol-config.js, add matic config

...
matic: {
    ZeroEx: {
        ExchangeV1: "0x6b3ed046d4b7c237c4849e2d7fbdb34e4a2a5a95",
        ExchangeV2: "0xd30d3d36daa6da31d481c19eaccd94558c1aa594",
        ERC20Proxy: "0x0a53e142138c0d68f5cf968cc74c6f633df57f6b",
        ERC721Proxy: "0x8fb632da59e73450e097847c0c75608f79770182",
        ZRXToken: "0xb1b57aca0977fdc772bda3ee292b189f363bcea0",
        AssetProxyOwner: "0x1f02042d523d9d8b5eafe6eb6d2945b1cf14dd2d",
        TokenTransferProxy: "0xd689d03d444d292642014354891d970ce9195848",
        WETH9: "0xbf4263c8842b48c2f7cb1ceb237ae0207952edab"
    },
    KyberContractAddress: "0xfB6bC957AcfcAd5bfe32dD66081F797fF6CD0974",
    DAITokenAddress: "",
},
...

These are 0x and Kyber addresses that i deployed on Matic, you could follow this guide and this guide to deploy them yourself.

Open packages.json add migrate:matic to scripts session

"migrate:matic": "truffle migrate --network matic",

Open packages/contracts/contracts/oracle/OracleInterface.sol file, go to line 105 and un-comment gasUsed parameter, otherwise the compiler will complain DocstringParsingError: Documented parameter "gasUsed" not found in the parameter list of the function.

function didPayInterestByLender(
    address lender,
    address interestTokenAddress,
    uint256 amountOwed,
    uint256 gasUsed)
    public
    returns (bool);

Modify migration scripts at these places:

  1. packages/contracts/migrations/5_deploy_BZRxToken.js, line 11, add } else if (network == "matic") {
  2. packages/contracts/migrations/7_deploy_BZRxTokenConvert.js, line 21, add this block
    else if (network == "matic") {
        bzrx_token_address = BZRxToken.address
        weth_token_address = config["addresses"][network]["ZeroEx"]["WETH9"]; //BZxEther.address; 
    } 
    
  3. packages/contracts/migrations/13_deploy_BZxOracle.js, comment out line 80-81, add this block at line 26
    else if (network == "matic") {
        weth_token_address = BZxEther.address;
    } 
    
  4. packages/contracts/migrations/17_deploy_TokenRegistry.js, line 15, comment out return;

Now deploy the contracts

$ cd packages/contracts/
$ yarn migrate:matic
...
Summary
=======
> Total deployments:   23
> Final cost:          0 ETH

Done in 1089.79s.

Next, we will update bzx.js package to support Matic testnet.

Build bzx.js

Still in packages/contracts/ directory, run this command to create packages/contracts/test_network folder

$ yarn network:deploy

Open packages/contracts/extra/generate_test_assets.js file, add matic case in the switch at line 100

case "matic":
    networkId = 8995;
    break;

Run these commands to create packages/contracts/html_public_test/deployed and move that folder to bzx.js/src/contracts

$ node ./extra/generate_test_assets.js matic
$ mv html_public_test/deployed/ ../bzx.js/src/contracts/matic 

Create packages/bzx.js/src/contracts/matic/TokenTransferProxy.json file with this content, use the same TokenTransferProxy address as in packages/contracts/protocol-config.js

{ "address": "0xd689d03d444d292642014354891d970ce9195848", "abi": [] }

Copy packages/bzx.js/src/contracts/kovan/index.js to packages/bzx.js/src/contracts/matic/

$ cp packages/bzx.js/src/contracts/kovan/index.js packages/bzx.js/src/contracts/matic/

Replace packages/bzx.js/src/contracts/index.js file with this content

import { map } from "ramda";
import _local from "./local";
import _mainnet, { TokenList as mainnetTokens } from "./mainnet";
import _ropsten, { TokenList as ropstenTokens } from "./ropsten";
import _rinkeby, { TokenList as rinkebyTokens } from "./rinkeby";
import _kovan from "./kovan";
import _matic from "./matic";

const toLowerCase = map(({ address, ...rest }) => ({
  address: address.toLowerCase(),
  ...rest
}));

const networksRaw = {
  local: _local,
  mainnet: _mainnet,
  ropsten: _ropsten,
  kovan: _kovan,
  rinkeby: _rinkeby,
  matic: _matic
};
const networks = map(network => toLowerCase(network), networksRaw);

export const { local, mainnet, ropsten, kovan, rinkeby, matic } = networks;

const networksById = {
  1: mainnet,
  3: ropsten,
  4: rinkeby,
  42: kovan,
  8995: matic
};

const tokensById = {
  1: mainnetTokens,
  3: ropstenTokens,
  4: rinkebyTokens
};

const oraclesById = {};

export const getContracts = (networkId = null) =>
  networksById[networkId] ? networksById[networkId] : local;

export const tokenList = (networkId = null) =>
  tokensById[networkId] ? toLowerCase(tokensById[networkId]) : undefined;

export const oracleList = (networkId = null) =>
  oraclesById[networkId] ? oraclesById[networkId] : undefined;

Build bzx.js package

$ cd ../bzx.js/
$ yarn build

Update BZx portal

Open packages/portal/package.json, change @bzxnetwork/bzx.js dependency to local

...
"dependencies": {
    ...
    "@bzxnetwork/bzx.js": "file:../bzx.js",
    ...
},
...

In packages/portal/src/orders/FillOrder/utils.jsx and packages/portal/src/orders/GenerateOrder/utils.jsx, replace the BZxJS import with import { BZxJS } from "@bzxnetwork/bzx.js";

Install dependencies and build portal package

$ cd ../portal/
$ yarn
$ yarn build

live_site folder will be created, you can deploy it to your web server or github pages.

Run a local web server to quickly check

$ cd live_site/
$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 ...

Go to http://localhost:8000, don’t forget installing Metamask and configuring it to Matic testnet. Follow the official document for more details.

matic20

Phew, that’s a lot of changes to make it works. You can checkout my branch here if there’s anything unsure.

Thanks for reading and I do hope you found this article somewhat helpful.