Git Product home page Git Product logo

truffle-plugin-verify's Introduction

⚠️ Truffle (and truffle-plugin-verify) has been sunset. It is recommended to move over to Hardhat or Foundry ⚠️

truffle-plugin-verify

NPM Version NPM Monthly Downloads NPM License

This truffle plugin allows you to automatically verify your smart contracts' source code on Etherscan and Sourcify, straight from the Truffle CLI.

I wrote a tutorial on my website that goes through the entire process of installing and using this plugin: Automatically verify Truffle smart contracts on Etherscan.

Note: This version of the plugin uses multi-file verification. If you want to use source code flattening instead for any reason, please use the legacy version (v0.4.x) of the plugin.

Installation / preparation

  1. Install the plugin with npm or yarn

    npm install -D truffle-plugin-verify
    yarn add -D truffle-plugin-verify
  2. Add the plugin to your truffle-config.js file

    module.exports = {
      /* ... rest of truffle-config */
    
      plugins: ['truffle-plugin-verify'],
    };

When only verifying on Sourcify, no more steps are required. When verifying on Etherscan (and derived explorers like PolygonScan), the appropriate API keys need to be specified:

  1. Generate an API Key on your Etherscan account (see the Etherscan website)

  2. Add your Etherscan API key to your truffle config (make sure to use something like dotenv so you don't commit the api key)

    module.exports = {
      /* ... rest of truffle-config */
    
      api_keys: {
        etherscan: 'MY_API_KEY',
      },
    };

Usage

Before running verification, make sure that you have successfully deployed your contracts to a supported network with Truffle. The contract deployment must have completely finished without errors. After deploying, run the following command with one or more contracts that you wish to verify:

truffle run verify SomeContractName AnotherContractName --network networkName [--debug] [--verifiers=etherscan,sourcify]

The network parameter should correspond to a network defined in the Truffle config file, with the correct network id set. For example, if we defined goerli as a network in Truffle, and we wish to verify the SimpleStorage contract:

truffle run verify SimpleStorage --network goerli

This can take some time, and will eventually either return Pass - Verified or Fail - Unable to verify for each contract. Since the information we get from the Etherscan API is quite limited, it is currently impossible to retrieve any more information on verification failure. There should be no reason though why the verification should fail if the usage is followed correctly. If you do receive a Fail - Unable to verify and you are sure that you followed the instructions correctly, please open an issue.

By default the plugin attempts to verify contracts both on Etherscan and Sourcify. If you only want to verify with one of them instead of both, you can specify so using the --verifiers argument.

truffle run verify SimpleStorage --network goerli --verifiers=etherscan
truffle run verify SimpleStorage --network goerli --verifiers=sourcify

Usage with the Truffle Dashboard

In 2022, Truffle launched an awesome new feature called the Truffle Dashboard that allows you to deploy your contracts using your MetaMask wallet. truffle-plugin-verify works with the Truffle Dashboard out of the box, but for it to work correctly you need to make sure that you are running the truffle dashboard, connected to the same network as you used for deployment while you're running truffle run verify ...

Usage with proxy contracts

This plugin supports EIP1967 proxies out of the box. If you try to verify a proxy contract (e.g. contracts deployed with OpenZeppelin's deployProxy), it will correctly verify the implementation contract and call Etherscan's "proxy verification" so that the proxy contract gets marked as a proxy on Etherscan (enabling Read/Write as Proxy). Note that EIP1967 Beacon contracts are not yet supported, and other types of non-standard proxies are also not supported.

When using OpenZeppelin's deployProxy functionality, proxy verification should work automatically. For custom proxy contracts you need to use the --custom-proxy flag. The name of the proxy contract should be passed after this flag.

truffle run verify SimpleTokenUpgradeable --network goerli
truffle run verify SimpleTokenUpgradeable --custom-proxy SimpleProxy --network goerli

Address override (Optional)

You can optionally provide an explicit address of the contract(s) that you wish to verify. This may be useful when you have deployed multiple instances of the same contract. The address is appended with @<address> as follows:

truffle run verify SimpleStorage@0x61C9157A9EfCaf6022243fA65Ef4666ECc9FD3D7 --network goerli

Run verification through an HTTP proxy (Optional)

In some cases the Etherscan or Sourcify websites may not be directly accessible. In this case it is possible to configure proxy settings so that the API requests will be made through this proxy. To use this feature, please add the relevant proxy settings to your truffle-config under verify.proxy.

module.exports = {
  /* ... rest of truffle-config */

  verify: {
    proxy: {
      host: '127.0.0.1',
      port: '1080',
    },
  },
};

Constructor arguments override (Optional)

You can additionally provide an explicit constructor arguments for the contract using the --forceConstructorArgs option. This is useful if the contract was created by another contract rather than an EOA, because truffle-plugin-verify cannot automatically retrieve constructor arguments in these cases. Note that the value needs to be prefixed with string: (e.g. --forceConstructorArgs string:0000).

truffle run verify MetaCoin --forceConstructorArgs string:0000000000000000000000000cb966d6a7702a4eff64009502653e302b3ec365 --network goerli

Debugging

You can pass an optional --debug flag into the plugin to display debug messages during the verification process. This is generally not necessary, but can be used to provide additional information when the plugin appears to malfunction.

truffle run verify SimpleStorage --network goerli --debug

Supported chains

These instructions were written for Ethereum mainnet and testnets, but it also works for verification on other platforms for other chains. Sourcify verification has support for many EVM based chains and no API keys are required. For verification on Etherscan-derived explorers you can refer to the list below for supported chains. Also make sure to request an API key from the platform that you're using and add it to your truffle-config.js file. If you want to verify your contracts on multiple chains, please provide separate API keys.

module.exports = {
  /* ... rest of truffle-config */

  api_keys: {
    etherscan: 'MY_API_KEY',
    optimistic_etherscan: 'MY_API_KEY',
    arbiscan: 'MY_API_KEY',
    nova_arbiscan: 'MY_API_KEY',
    bscscan: 'MY_API_KEY',
    opbnbscan: 'MY_API_KEY',
    snowtrace: 'MY_API_KEY',
    polygonscan: 'MY_API_KEY',
    zkevm_polygonscan: 'MY_API_KEY',
    ftmscan: 'MY_API_KEY',
    hecoinfo: 'MY_API_KEY',
    moonscan: 'MY_API_KEY',
    moonriver_moonscan: 'MY_API_KEY',
    bttcscan: 'MY_API_KEY',
    aurorascan: 'MY_API_KEY',
    cronoscan: 'MY_API_KEY',
    gnosisscan: 'MY_API_KEY',
    celoscan: 'MY_API_KEY',
    clvscan: 'MY_API_KEY',
  },
};

All supported Etherscan-derived platforms & networks

Usage with unsupported chains

In cases where the platform you want to use supports an Etherscan-compatible API but is not listed above, you may manually specify the apiUrl and explorerUrl (optional) for the platform. To use this feature, please add the relevant settings to your truffle-config under networks.<name of your network>.verify.

module.exports = {
  /* ... rest of truffle-config */

  networks: {
    /* ... other networks */

    network_with_custom_platform: {
      verify: {
        apiUrl: 'http://localhost:4000/api',
        apiKey: 'MY_API_KEY',
        explorerUrl: 'http://localhost:4000/address',
      },
    },
  },
};

Notes

This plugin has a naming conflict with the truffle-security plugin, so when using both truffle-security and truffle-plugin-verify in the same project, truffle run etherscan can be used instead of truffle run verify for truffle-plugin-verify.

truffle-plugin-verify's People

Contributors

albertov19 avatar alebanzas avatar avegancafe avatar chao-0 avatar d10r avatar denizsurmeli avatar fredlacs avatar fuchengshun avatar gnidan avatar hellwolf avatar jasoons avatar jijordre avatar katat avatar kuzdogan avatar mukundan314 avatar nhancv avatar niccolopetti avatar nozeroctnellav7 avatar oscarmartj avatar rkalis avatar seanjcasey avatar sebastian-baier avatar tcoulter avatar timonpeng avatar vinceau avatar whyvrafvr avatar xzjcool avatar zhangtianhao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

truffle-plugin-verify's Issues

Vulnerability with axios dependency (v0.5.4)

When installing v0.5.4 of truffle-plugin-verify, an npm audit shows the following high-risk vulnerability:

  • High: Server-Side Request Forgery
  • Package: axios
  • Patched in: >=0.21.1
  • Dependency of: truffle-plugin-verify
  • Path: truffle-plugin-verify > axios
  • More info: https://npmjs.com/advisories/1594

Would it be possible to upgrade the axios dependency in the next release or have a workaround for the current one?

Questions about ABIEncoderV2 for multiple contracts

Hi @rkalis

I'm struggling with Etherscan verification issues on ABIEncoderV2.

I got multiple contracts like this https://github.com/Computable-Finance/CoFiX/blob/master/contracts/CoFiXFactory.sol

pragma solidity ^0.6.6;

import './interface/ICoFiXFactory.sol';
import './interface/ICoFiXController.sol';
import './CoFiXPair.sol';

contract CoFiXFactory is ICoFiXFactory {
}

And CoFiXPair.sol is the only contract which adopts ABIEncoderV2.

// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity ^0.6.6;
pragma experimental ABIEncoderV2;

import "./interface/ICoFiXPair.sol";
import "./CoFiXERC20.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./interface/ICoFiXFactory.sol";
import "./interface/ICoFiXController.sol";
import "./lib/TransferHelper.sol";
import "./lib/ABDKMath64x64.sol";

contract CoFiXPair is ICoFiXPair, CoFiXERC20 {
}

I noticed the limitation on README:

Due to some limitations in the Etherscan verification engine, if you want to use pragma experimental ABIEncoderV2;, this statement should be the first line in your contract file (even above the pragma solidity ^0.6.0; statement).

I also found the flattened source file would only keep one pragma experimental ABIEncoderV2; statement before the code, which I think would affect all contracts.

Does it mean I should put pragma experimental ABIEncoderV2; statement before each contract if I'm trying to deploy by truffle and verify by this tool?

I have done some experiments and there's a big difference in bytecode if I'm not adding the pragma experimental ABIEncoderV2; statement before each contract.

Failing to verify contract: "Cannot find module"

D:\oracle\onchain>yarn run truffle run verify Oracle --network ropsten --debug
yarn run v1.22.4
$ D:\oracle\onchain\node_modules\.bin\truffle run verify Oracle --network ropsten --debug
DEBUG logging is turned ON
Running truffle-plugin-verify v0.5.2
Verifying Oracle
Reading artifact file at D:\oracle\onchain\build\contracts\Oracle.json
Retrieving constructor parameters from https://api-ropsten.etherscan.io/api?apiKey=VALIDAPIKEY&module=account&action=txlist&address=0x97879655Da10D93EaDA1a35665adeB94834A9fB3&page=1&sort=asc&offset=1
Constructor parameters retrieved: 0x
Cannot find module '/D/oracle/onchain/contracts/Oracle.sol'
Require stack:
- D:\oracle\onchain\node_modules\truffle-plugin-verify\verify.js
- D:\oracle\onchain\node_modules\original-require\index.js
- D:\oracle\onchain\node_modules\truffle\build\cli.bundled.js
Failed to verify 1 contract(s): Oracle

I'm trying to verify my contract but the plugin doesn't find it,

D:\oracle\onchain\contracts>ls
Migrations.sol  Oracle.sol

I am running on windows10 with node v12.18.0,
and the lastest versions of truffle and truffle-plugin-verify
How can I solve this?

Fail - Unable to verify

I'm having the old-and-familiar issue with verification.
The contract was compiled and deployed.

The deployed contract can be found at 0x35c850e8c31fab411dde65f94142f25029229a75

CBToken.sol

pragma solidity ^0.5.0;

import "openzeppelin-solidity/contracts/ownership/Ownable.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20Mintable.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20Pausable.sol";

contract CBToken is Ownable, ERC20Mintable, ERC20Pausable, ERC20Detailed {
    constructor(string memory _name, 
                string memory _symbol, 
                uint8 _decimals)
        ERC20Detailed(_name, _symbol, _decimals)
        public
    {
    }
}

package.json

{
  "name": "marketplace",
  "version": "1.0.1",
  "description": "online marketplace, crowdsale and token control",
  "scripts": {
    "lint": "eslint ./",
    "test": "mocha",
    "build": "rimraf public && webpack -p --config webpack.production.config.js",
    "dev": "concurrently --kill-others \"webpack-dev-server\" \"node .\\server\\server.js dev build\"",
    "server": "node server/server.js"
  },
  "author": "RENESALIS DOO",
  "license": "MIT",
  "devDependencies": {
    "chai": "^4.2.0",
    "chai-as-promised": "^7.1.1",
    "concurrently": "^4.1.0",
    "eslint": "^3.14.0",
    "eslint-config-standard": "^6.0.0",
    "eslint-plugin-babel": "^4.0.0",
    "eslint-plugin-promise": "^3.0.0",
    "eslint-plugin-standard": "^2.0.0",
    "webpack-dev-server": "^3.1.14",
    "openzeppelin-solidity": "2.1.2",
    "openzeppelin-test-helpers": "^0.1.2",
    "truffle-hdwallet-provider": "^1.0.0-web3one.3"
  },
  "dependencies": {
    "@babel/cli": "^7.2.3",
    "@babel/core": "^7.2.2",
    "@babel/plugin-transform-runtime": "^7.2.0",
    "@babel/polyfill": "^7.2.5",
    "@babel/preset-env": "^7.3.1",
    "@babel/register": "^7.0.0",
    "@babel/runtime": "^7.3.1",
    "@poanet/solidity-flattener": "^3.0.6",
    "babel-eslint": "^10.0.1",
    "babel-loader": "^8.0.5",
    "copy-webpack-plugin": "^4.6.0",
    "css-loader": "^2.0.1",
    "express": "4.16.4",
    "ipfs-mini": "^1.1.2",
    "log-timestamp": "^0.3.0",
    "mocha": "^5.2.0",
    "mongoose": "^5.4.6",
    "morgan": "^1.9.1",
    "rc": "^1.2.8",
    "scrypt": "github:barrysteyn/node-scrypt#fb60a8d3c158fe115a624b5ffa7480f3a24b03fb",
    "style-loader": "^0.13.1",
    "truffle-contract": "^4.0.4",
    "truffle-plugin-verify": "^0.4.0",
    "web3": "1.0.0-beta.37",
    "webpack": "^4.29.3",
    "webpack-cli": "^3.2.3"
  }
}

deploy.js

const Token = artifacts.require("./CBToken.sol");

async function doDeploy(deployer, network, accounts) {
  const _name     = "Demblock-Marketplace-TGE";
  const _symbol   = "dbto1";
  const _decimals = 18;
  await deployer.deploy(Token, _name, _symbol, _decimals);
}

module.exports = (deployer, network, accounts) => {
  deployer.then(async () => await doDeploy(deployer, network, accounts));
};

truffle-config.js

// Includes
require("@babel/register");
const path = require("path");
const WalletProvider = require("truffle-hdwallet-provider");
const HTTP_WEB3_PATH = require("./configs/params").dapp.HTTP_WEB3_PATH;

/// Key configs
let MAINNET_PROVIDER = new WalletProvider(
    [process.env.PRIVATE_KEYS || ""],
    HTTP_WEB3_PATH
);

/// Configs export
module.exports = {
    contracts_build_directory: path.join(process.cwd(), "src/"),
    networks: {
        mainnet: {
            provider: MAINNET_PROVIDER,
            gasPrice: 10000000000,
            gas: 3600000,
            network_id: 1
        }
    },
    compilers: {
        solc: {
            version: "^0.5.0", # deployed via 0.5.2+commit.1df8f40c.Emscripten.clang
        },
    },
    plugins: [
        'truffle-plugin-verify'
    ],
    api_keys: {
        etherscan: '########'
    }
};

Fails to verify Argent contracts

I have added the plugin to my truffle setup here argentlabs/argent-contracts@54d619e
Running verification for two different contracts produces the same issue. Example below is the output for GuardianStorage validation

$ npx truffle run verify GuardianStorage --network ropsten --debug
DEBUG logging is turned ON
Running truffle-plugin-verify v0.5.0
Verifying GuardianStorage
Reading artifact file at /argent-contracts/build/contracts/GuardianStorage.json
Retrieving constructor parameters from https://api-ropsten.etherscan.io/api?apiKey=xxx&module=account&action=txlist&address=0x2a7c09350fc7c2D84577001A89FA9b37BB5F36bF&page=1&sort=asc&offset=1
Constructor parameters retrieved: 0x
Sending verify request with POST arguments:
{
  "apikey": "xxx",
  "module": "contract",
  "action": "verifysourcecode",
  "contractaddress": "0x2a7c09350fc7c2D84577001A89FA9b37BB5F36bF",
  "sourceCode": "{\"language\":\"Solidity\",\"sources\":{\"/Users/Elena/Source/argent-contracts/contracts/infrastructure/storage/IGuardianStorage.sol\":{\"content\":\"// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>\\n\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\\n\\n// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.5.4 <0.7.0;\\n\\ninterface IGuardianStorage {\\n\\n    /**\\n     * @notice Lets an authorised module add a guardian to a wallet.\\n     * @param _wallet The target wallet.\\n     * @param _guardian The guardian to add.\\n     */\\n    function addGuardian(address _wallet, address _guardian) external;\\n\\n    /**\\n     * @notice Lets an authorised module revoke a guardian from a wallet.\\n     * @param _wallet The target wallet.\\n     * @param _guardian The guardian to revoke.\\n     */\\n    function revokeGuardian(address _wallet, address _guardian) external;\\n\\n    /**\\n     * @notice Checks if an account is a guardian for a wallet.\\n     * @param _wallet The target wallet.\\n     * @param _guardian The account.\\n     * @return true if the account is a guardian for a wallet.\\n     */\\n    function isGuardian(address _wallet, address _guardian) external view returns (bool);\\n\\n    function isLocked(address _wallet) external view returns (bool);\\n\\n    function getLock(address _wallet) external view returns (uint256);\\n\\n    function getLocker(address _wallet) external view returns (address);\\n\\n    function setLock(address _wallet, uint256 _releaseAfter) external;\\n\\n    function getGuardians(address _wallet) external view returns (address[] memory);\\n\\n    function guardianCount(address _wallet) external view returns (uint256);\\n}\"},\"/Users/Elena/Source/argent-contracts/contracts/infrastructure/storage/Storage.sol\":{\"content\":\"// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>\\n\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\\n\\n// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.5.4 <0.7.0;\\n\\nimport \\\"../../wallet/IWallet.sol\\\";\\n\\n/**\\n * @title Storage\\n * @notice Base contract for the storage of a wallet.\\n * @author Julien Niset - <[email protected]>\\n */\\ncontract Storage {\\n\\n    /**\\n     * @notice Throws if the caller is not an authorised module.\\n     */\\n    modifier onlyModule(address _wallet) {\\n        require(IWallet(_wallet).authorised(msg.sender), \\\"TS: must be an authorized module to call this method\\\");\\n        _;\\n    }\\n}\"},\"/Users/Elena/Source/argent-contracts/contracts/infrastructure_0.5/storage/GuardianStorage.sol\":{\"content\":\"// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>\\n\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\\n\\npragma solidity ^0.5.4;\\n\\nimport \\\"../../infrastructure/storage/Storage.sol\\\";\\nimport \\\"../../infrastructure/storage/IGuardianStorage.sol\\\";\\n\\n/**\\n * @title GuardianStorage\\n * @notice Contract storing the state of wallets related to guardians and lock.\\n * The contract only defines basic setters and getters with no logic. Only modules authorised\\n * for a wallet can modify its state.\\n * @author Julien Niset - <[email protected]>\\n * @author Olivier Van Den Biggelaar - <[email protected]>\\n */\\ncontract GuardianStorage is IGuardianStorage, Storage {\\n\\n    struct GuardianStorageConfig {\\n        // the list of guardians\\n        address[] guardians;\\n        // the info about guardians\\n        mapping (address => GuardianInfo) info;\\n        // the lock's release timestamp\\n        uint256 lock;\\n        // the module that set the last lock\\n        address locker;\\n    }\\n\\n    struct GuardianInfo {\\n        bool exists;\\n        uint128 index;\\n    }\\n\\n    // wallet specific storage\\n    mapping (address => GuardianStorageConfig) internal configs;\\n\\n    // *************** External Functions ********************* //\\n\\n    /**\\n     * @notice Lets an authorised module add a guardian to a wallet.\\n     * @param _wallet The target wallet.\\n     * @param _guardian The guardian to add.\\n     */\\n    function addGuardian(address _wallet, address _guardian) external onlyModule(_wallet) {\\n        GuardianStorageConfig storage config = configs[_wallet];\\n        config.info[_guardian].exists = true;\\n        config.info[_guardian].index = uint128(config.guardians.push(_guardian) - 1);\\n    }\\n\\n    /**\\n     * @notice Lets an authorised module revoke a guardian from a wallet.\\n     * @param _wallet The target wallet.\\n     * @param _guardian The guardian to revoke.\\n     */\\n    function revokeGuardian(address _wallet, address _guardian) external onlyModule(_wallet) {\\n        GuardianStorageConfig storage config = configs[_wallet];\\n        address lastGuardian = config.guardians[config.guardians.length - 1];\\n        if (_guardian != lastGuardian) {\\n            uint128 targetIndex = config.info[_guardian].index;\\n            config.guardians[targetIndex] = lastGuardian;\\n            config.info[lastGuardian].index = targetIndex;\\n        }\\n        config.guardians.length--;\\n        delete config.info[_guardian];\\n    }\\n\\n    /**\\n     * @notice Returns the number of guardians for a wallet.\\n     * @param _wallet The target wallet.\\n     * @return the number of guardians.\\n     */\\n    function guardianCount(address _wallet) external view returns (uint256) {\\n        return configs[_wallet].guardians.length;\\n    }\\n\\n    /**\\n     * @notice Gets the list of guaridans for a wallet.\\n     * @param _wallet The target wallet.\\n     * @return the list of guardians.\\n     */\\n    function getGuardians(address _wallet) external view returns (address[] memory) {\\n        GuardianStorageConfig storage config = configs[_wallet];\\n        address[] memory guardians = new address[](config.guardians.length);\\n        for (uint256 i = 0; i < config.guardians.length; i++) {\\n            guardians[i] = config.guardians[i];\\n        }\\n        return guardians;\\n    }\\n\\n    /**\\n     * @notice Checks if an account is a guardian for a wallet.\\n     * @param _wallet The target wallet.\\n     * @param _guardian The account.\\n     * @return true if the account is a guardian for a wallet.\\n     */\\n    function isGuardian(address _wallet, address _guardian) external view returns (bool) {\\n        return configs[_wallet].info[_guardian].exists;\\n    }\\n\\n    /**\\n     * @notice Lets an authorised module set the lock for a wallet.\\n     * @param _wallet The target wallet.\\n     * @param _releaseAfter The epoch time at which the lock should automatically release.\\n     */\\n    function setLock(address _wallet, uint256 _releaseAfter) external onlyModule(_wallet) {\\n        configs[_wallet].lock = _releaseAfter;\\n        if (_releaseAfter != 0 && msg.sender != configs[_wallet].locker) {\\n            configs[_wallet].locker = msg.sender;\\n        }\\n    }\\n\\n    /**\\n     * @notice Checks if the lock is set for a wallet.\\n     * @param _wallet The target wallet.\\n     * @return true if the lock is set for the wallet.\\n     */\\n    function isLocked(address _wallet) external view returns (bool) {\\n        return configs[_wallet].lock > block.timestamp;\\n    }\\n\\n    /**\\n     * @notice Gets the time at which the lock of a wallet will release.\\n     * @param _wallet The target wallet.\\n     * @return the time at which the lock of a wallet will release, or zero if there is no lock set.\\n     */\\n    function getLock(address _wallet) external view returns (uint256) {\\n        return configs[_wallet].lock;\\n    }\\n\\n    /**\\n     * @notice Gets the address of the last module that modified the lock for a wallet.\\n     * @param _wallet The target wallet.\\n     * @return the address of the last module that modified the lock for a wallet.\\n     */\\n    function getLocker(address _wallet) external view returns (address) {\\n        return configs[_wallet].locker;\\n    }\\n}\"},\"/Users/Elena/Source/argent-contracts/contracts/wallet/IWallet.sol\":{\"content\":\"// Copyright (C) 2018  Argent Labs Ltd. <https://argent.xyz>\\n\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\\n// GNU General Public License for more details.\\n\\n// You should have received a copy of the GNU General Public License\\n// along with this program.  If not, see <http://www.gnu.org/licenses/>.\\n\\n// SPDX-License-Identifier: GPL-3.0-only\\npragma solidity >=0.5.4 <0.7.0;\\n\\n/**\\n * @title IWallet\\n * @notice Interface for the BaseWallet\\n */\\ninterface IWallet {\\n    /**\\n     * @notice Returns the wallet owner.\\n     * @return The wallet owner address.\\n     */\\n    function owner() external view returns (address);\\n\\n    /**\\n     * @notice Returns the number of authorised modules.\\n     * @return The number of authorised modules.\\n     */\\n    function modules() external view returns (uint);\\n\\n    /**\\n     * @notice Sets a new owner for the wallet.\\n     * @param _newOwner The new owner.\\n     */\\n    function setOwner(address _newOwner) external;\\n\\n    /**\\n     * @notice Checks if a module is authorised on the wallet.\\n     * @param _module The module address to check.\\n     * @return `true` if the module is authorised, otherwise `false`.\\n     */\\n    function authorised(address _module) external view returns (bool);\\n\\n    /**\\n     * @notice Returns the module responsible for a static call redirection.\\n     * @param _sig The signature of the static call.\\n     * @return the module doing the redirection\\n     */\\n    function enabled(bytes4 _sig) external view returns (address);\\n\\n    /**\\n     * @notice Enables/Disables a module.\\n     * @param _module The target module.\\n     * @param _value Set to `true` to authorise the module.\\n     */\\n    function authoriseModule(address _module, bool _value) external;\\n\\n    /**\\n    * @notice Enables a static method by specifying the target module to which the call must be delegated.\\n    * @param _module The target module.\\n    * @param _method The static method signature.\\n    */\\n    function enableStaticCall(address _module, bytes4 _method) external;\\n}\"}},\"settings\":{\"remappings\":[],\"optimizer\":{\"enabled\":true,\"runs\":999},\"evmVersion\":\"byzantium\",\"libraries\":{\"\":{}}}}",
  "codeformat": "solidity-standard-json-input",
  "contractname": "/Users/Elena/Source/argent-contracts/contracts/infrastructure_0.5/storage/GuardianStorage.sol:GuardianStorage",
  "compilerversion": "v0.5.4+commit.9549d8ff.Linux.g++",
  "constructorArguements": ""
}
Checking status of verification request cnvw4fqmrlyscrwxrgpebdngpehylcdib61vydtusrgn71nfqh
Fail - Unable to verify
Failed to verify 1 contract(s): GuardianStorage

When checking on the EtherScan API the result for the above verification request I get:

{"status":"0","message":"NOTOK","result":"Fail - Unable to verify"}

I haven't been able to get anything more descriptive than that error and I have been able to verify that contract (on a different network) manually. Any help is appreciated.

Fail - Unable to verify

Token is compiled and deployed.
When I try to verify it I get:

truffle run verify TestToken --network mainnet
> Warning: possible unsupported (undocumented in help) command line option: --network
Verifying TestToken
Fail - Unable to verify

Failed to verify 1 contract(s): TestToken

contracts/Token.sol

pragma solidity ^0.5.1;

import "openzeppelin-solidity/contracts/token/ERC777/ERC777.sol";

contract TestToken is ERC777(
  "Test token",
  "TSX",
  new address[](0)
) {
  constructor() public {
    _mint(
      msg.sender,
      0x476Bb28Bc6D0e9De04dB5E19912C392F9a76535d,
      1000000000 * 10 ** uint256(decimals()),
      "",
      ""
    );
  }
}

package.json

{
  "name": "ERC777",
  "version": "1.0.0",
  "description": "ERC777 token",
  "main": "truffle-config.js",
  "directories": {
    "test": "test"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "[email protected]",
  "license": "ISC",
  "dependencies": {
    "@truffle/hdwallet-provider": "1.0.18",
    "openzeppelin-solidity": "2.3.0",
    "truffle-plugin-verify": "0.3.3"
  },
  "devDependencies": {
    "chai": "^4.2.0",
    "chai-bn": "^0.1.1"
  }
}

migrations/2_deploy_contracts.js

const TestToken = artifacts.require("TestToken");

module.exports = function(deployer, network, accounts) {
  deployer.deploy(TestToken).then(function() {
      const aTestTokenAddress = TestToken.address;
      console.log("Token address:", aTestTokenAddress)
      return TestToken.deployed();
  });
};

truffle-config.js

const HDWalletProvider = require('@truffle/hdwallet-provider');
const infuraKey = "YOUR_INFURA_KEY_HERE"; // TODO: place your infura.io API Key here

const fs = require('fs');
// TODO: place your private key or seed phrase in a file named .secret in the directory root
const mnemonic = fs.readFileSync(".secret").toString().trim();
// const mnemonic = "";

module.exports = {
  plugins: [
    'truffle-plugin-verify'
  ],
  api_keys: {
    etherscan: 'YOUR_ETHERSCAN_KEY_HERE' // TODO: place your etherscan.io API key here
  },
  /**
   * Networks define how you connect to your ethereum client and let you set the
   * defaults web3 uses to send transactions. If you don't specify one truffle
   * will spin up a development blockchain for you on port 9545 when you
   * run `develop` or `test`. You can ask a truffle command to use a specific
   * network from the command line, e.g
   *
   * $ truffle test --network <network-name>
   */

  networks: {
    // Useful for testing. The `development` name is special - truffle uses it by default
    // if it's defined here and no other network is specified at the command line.
    // You should run a client (like ganache-cli, geth or parity) in a separate terminal
    // tab if you use this network and you must also set the `host`, `port` and `network_id`
    // options below to some value.
    //
    development: {
     host: "127.0.0.1",     // Localhost (default: none)
     // port: 8545,            // Standard Ethereum port (default: none)
     port: 9545,            // Standard Ethereum port (default: none)
     network_id: "*",       // Any network (default: none)
     gas: 6721975,           // Gas sent with each transaction (default: ~6700000)
     gasPrice: 1,  // wei
     skipDryRun: false,
    },

    // Another network with more advanced options...
    // advanced: {
      // port: 8777,             // Custom port
      // network_id: 1342,       // Custom network
      // gas: 8500000,           // Gas sent with each transaction (default: ~6700000)
      // gasPrice: 20000000000,  // 20 gwei (in wei) (default: 100 gwei)
      // from: <address>,        // Account to send txs from (default: accounts[0])
      // websockets: true        // Enable EventEmitter interface for web3 (default: false)
    // },

    // Useful for deploying to a public network.
    // NB: It's important to wrap the provider as a function.
    ropsten: {
      provider: () => new HDWalletProvider(mnemonic, "https://ropsten.infura.io/v3/" + infuraKey),
      network_id: 3,       // Ropsten's id
      gas: 5500000,        // Ropsten has a lower block limit than mainnet
      gasPrice: 20 * 1e9,  // 20 gwei (in wei) (default: 100 gwei)
      confirmations: 1,    // # of confs to wait between deployments. (default: 0)
      timeoutBlocks: 200,  // # of blocks before a deployment times out  (minimum/default: 50)
      skipDryRun: true     // Skip dry run before migrations? (default: false for public nets )
    },

    rinkeby: {
      provider: () => new HDWalletProvider(mnemonic, "https://rinkeby.infura.io/v3/" + infuraKey),
      network_id: 4,       // Ropsten's id
      gas: 5500000,        // Ropsten has a lower block limit than mainnet
      gasPrice: 20 * 1e9,  // 20 gwei (in wei) (default: 100 gwei)
      confirmations: 1,    // # of confs to wait between deployments. (default: 0)
      timeoutBlocks: 200,  // # of blocks before a deployment times out  (minimum/default: 50)
      skipDryRun: true     // Skip dry run before migrations? (default: false for public nets )
    },

    // Useful for deploying to a public network.
    // NB: It's important to wrap the provider as a function.
    mainnet: {
      provider: () => new HDWalletProvider(mnemonic, "https://mainnet.infura.io/v3/" + infuraKey),
      network_id: 1,       // mainnet's id
      gas: 8500000,        // Ropsten has a lower block limit than mainnet
      gasPrice: 2 * 1e9,  // 11 gwei (in wei) (default: 100 gwei)
      confirmations: 1,    // # of confs to wait between deployments. (default: 0)
      timeoutBlocks: 2000,  // # of blocks before a deployment times out  (minimum/default: 50)
      skipDryRun: true     // Skip dry run before migrations? (default: false for public nets )
    },

    // Useful for private networks
    // private: {
    //   provider: () => new HDWalletProvider(mnemonic, `http://127.0.0.1:8545`),
    //   network_id: 6660001,   // This network is yours, in the cloud.
    //   production: true    // Treats this network as if it was a public net. (default: false)
    // }
  },

  // Set default mocha options here, use special reporters etc.
  mocha: {
    // timeout: 100000
  },

  // Configure your compilers
  compilers: {
    solc: {
      version: "0.5.2",    // Fetch exact version from solc-bin (default: truffle's version)
      // docker: true,        // Use "0.5.1" you've installed locally with docker (default: false)
      settings: {          // See the solidity docs for advice about optimization and evmVersion
       optimizer: {
         enabled: true,
         runs: 400
       },
       // evmVersion: "byzantium",
      }
    }
  }
}

Fail - Unable to verify, Failed to verify 1 contract(s): LoadToken

DEBUG logging is turned ON
Running truffle-plugin-verify v0.3.11
Verifying LoadToken
Reading artifact file at /Users/mac/Documents/Code/apps/solidity/defi/reloaded-bal/build/contracts/LoadToken.json
Retrieving constructor parameters from https://api-kovan.etherscan.io/api?apiKey=XXX&module=account&action=txlist&address=0x43074672e4b7711CA33266807DaF2213A8CdA4Ad&page=1&sort=asc&offset=1
Constructor parameters received: 0x
Flattening source file /Users/mac/Documents/Code/apps/solidity/defi/reloaded-bal/contracts/value/LoadToken.sol
Sending verify request with POST arguments:
{
  "apikey": "XXX",
  "module": "contract",
  "action": "verifysourcecode",
  "contractaddress": "0x43074672e4b7711CA33266807DaF2213A8CdA4Ad",
  "sourceCode": "pragma solidity 0.6.12;\n\n\n// SPDX-License-Identifier: MIT\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address payable) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes memory) {\n        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n        return msg.data;\n    }\n}\n\n// SPDX-License-Identifier: MIT\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n\n// SPDX-License-Identifier: MIT\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     *\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a, \"SafeMath: addition overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return sub(a, b, \"SafeMath: subtraction overflow\");\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     *\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b <= a, errorMessage);\n        uint256 c = a - b;\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     *\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n        // benefit is lost if 'b' is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n        if (a == 0) {\n            return 0;\n        }\n\n        uint256 c = a * b;\n        require(c / a == b, \"SafeMath: multiplication overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return div(a, b, \"SafeMath: division by zero\");\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b > 0, errorMessage);\n        uint256 c = a / b;\n        // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return mod(a, b, \"SafeMath: modulo by zero\");\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts with custom message when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     *\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b != 0, errorMessage);\n        return a % b;\n    }\n}\n\n// SPDX-License-Identifier: MIT\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize, which returns 0 for contracts in\n        // construction, since the code is only stored at the end of the\n        // constructor execution.\n\n        uint256 size;\n        // solhint-disable-next-line no-inline-assembly\n        assembly { size := extcodesize(account) }\n        return size > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n        (bool success, ) = recipient.call{ value: amount }(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain`call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n      return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, bytes memory returndata) = target.call{ value: value }(data);\n        return _verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        // solhint-disable-next-line avoid-low-level-calls\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return _verifyCallResult(success, returndata, errorMessage);\n    }\n\n    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                // solhint-disable-next-line no-inline-assembly\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n\n// SPDX-License-Identifier: MIT\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n    using SafeMath for uint256;\n\n    mapping (address => uint256) private _balances;\n\n    mapping (address => mapping (address => uint256)) private _allowances;\n\n    uint256 private _totalSupply;\n\n    string private _name;\n    string private _symbol;\n    uint8 private _decimals;\n\n    /**\n     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n     * a default value of 18.\n     *\n     * To select a different value for {decimals}, use {_setupDecimals}.\n     *\n     * All three of these values are immutable: they can only be set once during\n     * construction.\n     */\n    constructor (string memory name_, string memory symbol_) public {\n        _name = name_;\n        _symbol = symbol_;\n        _decimals = 18;\n    }\n\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() public view returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Returns the symbol of the token, usually a shorter version of the\n     * name.\n     */\n    function symbol() public view returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns the number of decimals used to get its user representation.\n     * For example, if `decimals` equals `2`, a balance of `505` tokens should\n     * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n     *\n     * Tokens usually opt for a value of 18, imitating the relationship between\n     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n     * called.\n     *\n     * NOTE: This information is only used for _display_ purposes: it in\n     * no way affects any of the arithmetic of the contract, including\n     * {IERC20-balanceOf} and {IERC20-transfer}.\n     */\n    function decimals() public view returns (uint8) {\n        return _decimals;\n    }\n\n    /**\n     * @dev See {IERC20-totalSupply}.\n     */\n    function totalSupply() public view override returns (uint256) {\n        return _totalSupply;\n    }\n\n    /**\n     * @dev See {IERC20-balanceOf}.\n     */\n    function balanceOf(address account) public view override returns (uint256) {\n        return _balances[account];\n    }\n\n    /**\n     * @dev See {IERC20-transfer}.\n     *\n     * Requirements:\n     *\n     * - `recipient` cannot be the zero address.\n     * - the caller must have a balance of at least `amount`.\n     */\n    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n        _transfer(_msgSender(), recipient, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-allowance}.\n     */\n    function allowance(address owner, address spender) public view virtual override returns (uint256) {\n        return _allowances[owner][spender];\n    }\n\n    /**\n     * @dev See {IERC20-approve}.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function approve(address spender, uint256 amount) public virtual override returns (bool) {\n        _approve(_msgSender(), spender, amount);\n        return true;\n    }\n\n    /**\n     * @dev See {IERC20-transferFrom}.\n     *\n     * Emits an {Approval} event indicating the updated allowance. This is not\n     * required by the EIP. See the note at the beginning of {ERC20}.\n     *\n     * Requirements:\n     *\n     * - `sender` and `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     * - the caller must have allowance for ``sender``'s tokens of at least\n     * `amount`.\n     */\n    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n        _transfer(sender, recipient, amount);\n        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n        return true;\n    }\n\n    /**\n     * @dev Atomically increases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     */\n    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n        return true;\n    }\n\n    /**\n     * @dev Atomically decreases the allowance granted to `spender` by the caller.\n     *\n     * This is an alternative to {approve} that can be used as a mitigation for\n     * problems described in {IERC20-approve}.\n     *\n     * Emits an {Approval} event indicating the updated allowance.\n     *\n     * Requirements:\n     *\n     * - `spender` cannot be the zero address.\n     * - `spender` must have allowance for the caller of at least\n     * `subtractedValue`.\n     */\n    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n        return true;\n    }\n\n    /**\n     * @dev Moves tokens `amount` from `sender` to `recipient`.\n     *\n     * This is internal function is equivalent to {transfer}, and can be used to\n     * e.g. implement automatic token fees, slashing mechanisms, etc.\n     *\n     * Emits a {Transfer} event.\n     *\n     * Requirements:\n     *\n     * - `sender` cannot be the zero address.\n     * - `recipient` cannot be the zero address.\n     * - `sender` must have a balance of at least `amount`.\n     */\n    function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n        require(sender != address(0), \"ERC20: transfer from the zero address\");\n        require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n        _beforeTokenTransfer(sender, recipient, amount);\n\n        _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n        _balances[recipient] = _balances[recipient].add(amount);\n        emit Transfer(sender, recipient, amount);\n    }\n\n    /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n     * the total supply.\n     *\n     * Emits a {Transfer} event with `from` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `to` cannot be the zero address.\n     */\n    function _mint(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: mint to the zero address\");\n\n        _beforeTokenTransfer(address(0), account, amount);\n\n        _totalSupply = _totalSupply.add(amount);\n        _balances[account] = _balances[account].add(amount);\n        emit Transfer(address(0), account, amount);\n    }\n\n    /**\n     * @dev Destroys `amount` tokens from `account`, reducing the\n     * total supply.\n     *\n     * Emits a {Transfer} event with `to` set to the zero address.\n     *\n     * Requirements:\n     *\n     * - `account` cannot be the zero address.\n     * - `account` must have at least `amount` tokens.\n     */\n    function _burn(address account, uint256 amount) internal virtual {\n        require(account != address(0), \"ERC20: burn from the zero address\");\n\n        _beforeTokenTransfer(account, address(0), amount);\n\n        _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n        _totalSupply = _totalSupply.sub(amount);\n        emit Transfer(account, address(0), amount);\n    }\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n     *\n     * This internal function is equivalent to `approve`, and can be used to\n     * e.g. set automatic allowances for certain subsystems, etc.\n     *\n     * Emits an {Approval} event.\n     *\n     * Requirements:\n     *\n     * - `owner` cannot be the zero address.\n     * - `spender` cannot be the zero address.\n     */\n    function _approve(address owner, address spender, uint256 amount) internal virtual {\n        require(owner != address(0), \"ERC20: approve from the zero address\");\n        require(spender != address(0), \"ERC20: approve to the zero address\");\n\n        _allowances[owner][spender] = amount;\n        emit Approval(owner, spender, amount);\n    }\n\n    /**\n     * @dev Sets {decimals} to a value other than the default one of 18.\n     *\n     * WARNING: This function should only be called from the constructor. Most\n     * applications that interact with token contracts will not expect\n     * {decimals} to ever change, and may work incorrectly if it does.\n     */\n    function _setupDecimals(uint8 decimals_) internal {\n        _decimals = decimals_;\n    }\n\n    /**\n     * @dev Hook that is called before any transfer of tokens. This includes\n     * minting and burning.\n     *\n     * Calling conditions:\n     *\n     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n     * will be to transferred to `to`.\n     * - when `from` is zero, `amount` tokens will be minted for `to`.\n     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n     * - `from` and `to` are never both zero.\n     *\n     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n     */\n    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n\n// SPDX-License-Identifier: MIT\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n    using SafeMath for uint256;\n    using Address for address;\n\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n    }\n\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n    }\n\n    /**\n     * @dev Deprecated. This function has issues similar to the ones found in\n     * {IERC20-approve}, and its usage is discouraged.\n     *\n     * Whenever possible, use {safeIncreaseAllowance} and\n     * {safeDecreaseAllowance} instead.\n     */\n    function safeApprove(IERC20 token, address spender, uint256 value) internal {\n        // safeApprove should only be called when setting an initial allowance,\n        // or when resetting it to zero. To increase and decrease it, use\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n        // solhint-disable-next-line max-line-length\n        require((value == 0) || (token.allowance(address(this), spender) == 0),\n            \"SafeERC20: approve from non-zero to non-zero allowance\"\n        );\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n    }\n\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 newAllowance = token.allowance(address(this), spender).add(value);\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n        uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n    }\n\n    /**\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\n     * @param token The token targeted by the call.\n     * @param data The call data (encoded using abi.encode or one of its variants).\n     */\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n        // the target address contains contract code and also asserts for success in the low-level call.\n\n        bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n        if (returndata.length > 0) { // Return data is optional\n            // solhint-disable-next-line max-line-length\n            require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n        }\n    }\n}\n\n// SPDX-License-Identifier: MIT\n/**\n * @notice Reload Liquidity (LOAD) with Governance Alpha\n */\ncontract LoadToken is ERC20 {\n    using SafeERC20 for IERC20;\n    using SafeMath for uint256;\n\n    // IERC20 public reLoad;\n\n    address public governance;\n    // uint256 public cap;\n    // uint256 public reLoadLockedBalance;\n    mapping(address => bool) public minters;\n\n    event Deposit(address indexed dst, uint amount);\n    event Withdrawal(address indexed src, uint amount);\n\n    // constructor (IERC20 _reLoad, uint256 _cap) public ERC20(\"Reloaded Governance Token\", \"LOAD\")\n    constructor () public ERC20(\"Reloaded Governance Token\", \"LOAD\") {\n        governance = msg.sender;\n        // reLoad = _reLoad;\n        // cap = _cap;\n    }\n\n    function mint(address _to, uint256 _amount) public {\n        require(msg.sender == governance || minters[msg.sender], \"!governance && !minter\");\n        _mint(_to, _amount);\n        _moveDelegates(address(0), _delegates[_to], _amount);\n    }\n\n    function burn(uint256 _amount) public {\n        _burn(msg.sender, _amount);\n        _moveDelegates(_delegates[msg.sender], address(0), _amount);\n    }\n\n    function burnFrom(address _account, uint256 _amount) public {\n        uint256 decreasedAllowance = allowance(_account, msg.sender).sub(_amount, \"ERC20: burn amount exceeds allowance\");\n        _approve(_account, msg.sender, decreasedAllowance);\n        _burn(_account, _amount);\n        _moveDelegates(_delegates[_account], address(0), _amount);\n    }\n\n    function setGovernance(address _governance) public {\n        require(msg.sender == governance, \"!governance\");\n        governance = _governance;\n    }\n\n    function addMinter(address _minter) public {\n        require(msg.sender == governance, \"!governance\");\n        minters[_minter] = true;\n    }\n\n    function removeMinter(address _minter) public {\n        require(msg.sender == governance, \"!governance\");\n        minters[_minter] = false;\n    }\n\n    // function setCap(uint256 _cap) public {\n    //     require(msg.sender == governance, \"!governance\");\n    //     require(_cap.add(reLoadLockedBalance) >= totalSupply(), \"_cap (plus reLoadLockedBalance) is below current supply\");\n    //     cap = _cap;\n    // }\n\n    // function deposit(uint256 _amount) public {\n    //     reLoad.safeTransferFrom(msg.sender, address(this), _amount);\n    //     reLoadLockedBalance = reLoadLockedBalance.add(_amount);\n    //     _mint(msg.sender, _amount);\n    //     _moveDelegates(address(0), _delegates[msg.sender], _amount);\n    //     Deposit(msg.sender, _amount);\n    // }\n\n    // function withdraw(uint256 _amount) public {\n    //     reLoadLockedBalance = reLoadLockedBalance.sub(_amount, \"There is not enough locked LOAD to withdraw\");\n    //     reLoad.safeTransfer(msg.sender, _amount);\n    //     _burn(msg.sender, _amount);\n    //     _moveDelegates(_delegates[msg.sender], address(0), _amount);\n    //     Withdrawal(msg.sender, _amount);\n    // }\n\n    // This function allows governance to take unsupported tokens out of the contract.\n    // This is in an effort to make someone whole, should they seriously mess up.\n    // There is no guarantee governance will vote to return these.\n    // It also allows for removal of airdropped tokens.\n    // function governanceRecoverUnsupported(IERC20 _token, address _to, uint256 _amount) external {\n    //     require(msg.sender == governance, \"!governance\");\n    //     if (_token == reLoad) {\n    //         uint256 reLoadBalance = reLoad.balanceOf(address(this));\n    //         require(_amount <= reLoadBalance.sub(reLoadLockedBalance), \"cant withdraw more then stuck amount\");\n    //     }\n    //     _token.safeTransfer(_to, _amount);\n    // }\n\n    // /**\n    //  * @dev See {ERC20-_beforeTokenTransfer}.\n    //  *\n    //  * Requirements:\n    //  *\n    //  * - minted tokens must not cause the total supply to go over the cap.\n    //  */\n    // function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual override {\n    //     super._beforeTokenTransfer(from, to, amount);\n\n    //     if (from == address(0)) {// When minting tokens\n    //         require(totalSupply().add(amount) <= cap.add(reLoadLockedBalance), \"ERC20Capped: cap exceeded\");\n    //     }\n    // }\n\n    // Copied and modified from YAM code:\n    // https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernanceStorage.sol\n    // https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernance.sol\n    // Which is copied and modified from COMPOUND:\n    // https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/Comp.sol\n\n    /// @dev A record of each accounts delegate\n    mapping(address => address) internal _delegates;\n\n    /// @notice A checkpoint for marking number of votes from a given block\n    struct Checkpoint {\n        uint32 fromBlock;\n        uint256 votes;\n    }\n\n    /// @notice A record of votes checkpoints for each account, by index\n    mapping(address => mapping(uint32 => Checkpoint)) public checkpoints;\n\n    /// @notice The number of checkpoints for each account\n    mapping(address => uint32) public numCheckpoints;\n\n    /// @notice The EIP-712 typehash for the contract's domain\n    bytes32 public constant DOMAIN_TYPEHASH = keccak256(\"EIP712Domain(string name,uint256 chainId,address verifyingContract)\");\n\n    /// @notice The EIP-712 typehash for the delegation struct used by the contract\n    bytes32 public constant DELEGATION_TYPEHASH = keccak256(\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\");\n\n    /// @notice A record of states for signing / validating signatures\n    mapping(address => uint) public nonces;\n\n    /// @notice An event thats emitted when an account changes its delegate\n    event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\n\n    /// @notice An event thats emitted when a delegate account's vote balance changes\n    event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);\n\n    /**\n     * @notice Delegate votes from `msg.sender` to `delegatee`\n     * @param delegator The address to get delegatee for\n     */\n    function delegates(address delegator)\n     external\n     view\n     returns (address)\n     {\n        return _delegates[delegator];\n    }\n\n    /**\n     * @notice Delegate votes from `msg.sender` to `delegatee`\n     * @param delegatee The address to delegate votes to\n     */\n    function delegate(address delegatee) external {\n        return _delegate(msg.sender, delegatee);\n    }\n\n    /**\n     * @notice Delegates votes from signatory to `delegatee`\n     * @param delegatee The address to delegate votes to\n     * @param nonce The contract state required to match the signature\n     * @param expiry The time at which to expire the signature\n     * @param v The recovery byte of the signature\n     * @param r Half of the ECDSA signature pair\n     * @param s Half of the ECDSA signature pair\n     */\n    function delegateBySig(\n        address delegatee,\n        uint nonce,\n        uint expiry,\n        uint8 v,\n        bytes32 r,\n        bytes32 s\n     )\n     external\n     {\n        bytes32 domainSeparator = keccak256(\n            abi.encode(\n                DOMAIN_TYPEHASH,\n                keccak256(bytes(name())),\n                getChainId(),\n                address(this)\n            )\n        );\n\n        bytes32 structHash = keccak256(\n            abi.encode(\n                DELEGATION_TYPEHASH,\n                delegatee,\n                nonce,\n                expiry\n            )\n        );\n\n        bytes32 digest = keccak256(\n            abi.encodePacked(\n                \"\\x19\\x01\",\n                domainSeparator,\n                structHash\n            )\n        );\n        address signatory = ecrecover(digest, v, r, s);\n        require(signatory != address(0), \"LOAD::delegateBySig: invalid signature\");\n        require(nonce == nonces[signatory]++, \"LOAD::delegateBySig: invalid nonce\");\n        require(now <= expiry, \"LOAD::delegateBySig: signature expired\");\n        return _delegate(signatory, delegatee);\n    }\n\n    /**\n     * @notice Gets the current votes balance for `account`\n     * @param account The address to get votes balance\n     * @return The number of current votes for `account`\n     */\n    function getCurrentVotes(address account)\n     external\n     view\n     returns (uint256)\n     {\n        uint32 nCheckpoints = numCheckpoints[account];\n        return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;\n    }\n\n    /**\n     * @notice Determine the prior number of votes for an account as of a block number\n     * @dev Block number must be a finalized block or else this function will revert to prevent misinformation.\n     * @param account The address of the account to check\n     * @param blockNumber The block number to get the vote balance at\n     * @return The number of votes the account had as of the given block\n     */\n    function getPriorVotes(address account, uint blockNumber)\n     external\n     view\n     returns (uint256)\n     {\n        require(blockNumber < block.number, \"LOAD::getPriorVotes: not yet determined\");\n\n        uint32 nCheckpoints = numCheckpoints[account];\n        if (nCheckpoints == 0) {\n            return 0;\n        }\n\n        // First check most recent balance\n        if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {\n            return checkpoints[account][nCheckpoints - 1].votes;\n        }\n\n        // Next check implicit zero balance\n        if (checkpoints[account][0].fromBlock > blockNumber) {\n            return 0;\n        }\n\n        uint32 lower = 0;\n        uint32 upper = nCheckpoints - 1;\n        while (upper > lower) {\n            uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow\n            Checkpoint memory cp = checkpoints[account][center];\n            if (cp.fromBlock == blockNumber) {\n                return cp.votes;\n            } else if (cp.fromBlock < blockNumber) {\n                lower = center;\n            } else {\n                upper = center - 1;\n            }\n        }\n        return checkpoints[account][lower].votes;\n    }\n\n    function _delegate(address delegator, address delegatee)\n     internal\n     {\n        address currentDelegate = _delegates[delegator];\n        uint256 delegatorBalance = balanceOf(delegator); // balance of underlying LOADs (not scaled);\n        _delegates[delegator] = delegatee;\n\n        emit DelegateChanged(delegator, currentDelegate, delegatee);\n\n        _moveDelegates(currentDelegate, delegatee, delegatorBalance);\n    }\n\n    function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal {\n        if (srcRep != dstRep && amount > 0) {\n            if (srcRep != address(0)) {\n                // decrease old representative\n                uint32 srcRepNum = numCheckpoints[srcRep];\n                uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;\n                uint256 srcRepNew = srcRepOld.sub(amount);\n                _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);\n            }\n\n            if (dstRep != address(0)) {\n                // increase new representative\n                uint32 dstRepNum = numCheckpoints[dstRep];\n                uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;\n                uint256 dstRepNew = dstRepOld.add(amount);\n                _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);\n            }\n        }\n    }\n\n    function _writeCheckpoint(\n        address delegatee,\n        uint32 nCheckpoints,\n        uint256 oldVotes,\n        uint256 newVotes\n     )\n     internal\n     {\n        uint32 blockNumber = safe32(block.number, \"LOAD::_writeCheckpoint: block number exceeds 32 bits\");\n\n        if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {\n            checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;\n        } else {\n            checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);\n            numCheckpoints[delegatee] = nCheckpoints + 1;\n        }\n\n        emit DelegateVotesChanged(delegatee, oldVotes, newVotes);\n    }\n\n    function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {\n        require(n < 2 ** 32, errorMessage);\n        return uint32(n);\n    }\n\n    function getChainId() internal pure returns (uint) {\n        uint256 chainId;\n        assembly {chainId := chainid()}\n        return chainId;\n    }\n}",
  "codeformat": "solidity-single-file",
  "contractname": "LoadToken",
  "compilerversion": "v0.6.12+commit.27d51765",
  "optimizationUsed": 1,
  "runs": 200,
  "constructorArguements": ""
}
Checking status of verification request icgmtc2ejgicka1vxczpmexycuwthj2bab4jydccbmcuhhdkdy
Fail - Unable to verify
Failed to verify 1 contract(s): LoadToken

Unable to verify contracts on Etherscan programatically, manually works

I'm unable to verify my contract via the plugin, but if I copy the source directly into the verifier on Rinkeby Etherscan the verification works perfectly.

I noticed the API call is stripping the multiline comments from the "sourceCode" field in the API call, but that is the only thing I can see that's different. The compiler version, runs, etc. are all the same. Here's the output of the debug call if it helps:

DEBUG logging is turned ON
Verifying PromotedPool@0x3D0Cb6CC9ddc16e96B26b4a0613bb46667ff2928
Reading artifact file at /Users/chrispiatt/workspace/blocklytics/promoted-pools/contracts/build/contracts/PromotedPool.json
Custom address 0x3D0Cb6CC9ddc16e96B26b4a0613bb46667ff2928 specified
Retrieving constructor parameters from https://api-rinkeby.etherscan.io/api?module=account&action=txlist&address=0x3D0Cb6CC9ddc16e96B26b4a0613bb46667ff2928&page=1&sort=asc&offset=1
Constructor parameters received: 0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000f57b2c51ded3a29e6891aba85459d600256cf317000000000000000000000000000000000000000000000000000000000000000f506f6f6c732e6679692050726f6d6f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034659490000000000000000000000000000000000000000000000000000000000
Flattening source file /Users/chrispiatt/workspace/blocklytics/promoted-pools/contracts/contracts/PromotedPool.sol
Sending verify request with POST arguments:
{
  "apikey": "27M9WCQP64YCKCZ74ENNVKCVR771X76BZM",
  "module": "contract",
  "action": "verifysourcecode",
  "contractaddress": "0x3D0Cb6CC9ddc16e96B26b4a0613bb46667ff2928",
  "sourceCode": "pragma solidity ^0.5.0;\n\n\ncontract Context {\n    // Empty internal constructor, to prevent people from mistakenly deploying\n    // an instance of this contract, which should be used via inheritance.\n    constructor () internal { }\n    // solhint-disable-previous-line no-empty-blocks\n\n    function _msgSender() internal view returns (address payable) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view returns (bytes memory) {\n        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n        return msg.data;\n    }\n}\n\ninterface IERC165 {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n\ncontract IERC721 is IERC165 {\n    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\n    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\n    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\n\n    /**\n     * @dev Returns the number of NFTs in `owner`'s account.\n     */\n    function balanceOf(address owner) public view returns (uint256 balance);\n\n    /**\n     * @dev Returns the owner of the NFT specified by `tokenId`.\n     */\n    function ownerOf(uint256 tokenId) public view returns (address owner);\n\n    /**\n     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to\n     * another (`to`).\n     *\n     *\n     *\n     * Requirements:\n     * - `from`, `to` cannot be zero.\n     * - `tokenId` must be owned by `from`.\n     * - If the caller is not `from`, it must be have been allowed to move this\n     * NFT by either {approve} or {setApprovalForAll}.\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) public;\n    /**\n     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to\n     * another (`to`).\n     *\n     * Requirements:\n     * - If the caller is not `from`, it must be approved to move this NFT by\n     * either {approve} or {setApprovalForAll}.\n     */\n    function transferFrom(address from, address to, uint256 tokenId) public;\n    function approve(address to, uint256 tokenId) public;\n    function getApproved(uint256 tokenId) public view returns (address operator);\n\n    function setApprovalForAll(address operator, bool _approved) public;\n    function isApprovedForAll(address owner, address operator) public view returns (bool);\n\n\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;\n}\n\ncontract IERC721Receiver {\n    /**\n     * @notice Handle the receipt of an NFT\n     * @dev The ERC721 smart contract calls this function on the recipient\n     * after a {IERC721-safeTransferFrom}. This function MUST return the function selector,\n     * otherwise the caller will revert the transaction. The selector to be\n     * returned can be obtained as `this.onERC721Received.selector`. This\n     * function MAY throw to revert and reject the transfer.\n     * Note: the ERC721 contract address is always the message sender.\n     * @param operator The address which called `safeTransferFrom` function\n     * @param from The address which previously owned the token\n     * @param tokenId The NFT identifier which is being transferred\n     * @param data Additional data with no specified format\n     * @return bytes4 `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n     */\n    function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)\n    public returns (bytes4);\n}\n\nlibrary SafeMath {\n    /**\n     * @dev Returns the addition of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `+` operator.\n     *\n     * Requirements:\n     * - Addition cannot overflow.\n     */\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\n        uint256 c = a + b;\n        require(c >= a, \"SafeMath: addition overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     * - Subtraction cannot overflow.\n     */\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n        return sub(a, b, \"SafeMath: subtraction overflow\");\n    }\n\n    /**\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n     * overflow (when the result is negative).\n     *\n     * Counterpart to Solidity's `-` operator.\n     *\n     * Requirements:\n     * - Subtraction cannot overflow.\n     *\n     * _Available since v2.4.0._\n     */\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b <= a, errorMessage);\n        uint256 c = a - b;\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the multiplication of two unsigned integers, reverting on\n     * overflow.\n     *\n     * Counterpart to Solidity's `*` operator.\n     *\n     * Requirements:\n     * - Multiplication cannot overflow.\n     */\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n        // benefit is lost if 'b' is also tested.\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n        if (a == 0) {\n            return 0;\n        }\n\n        uint256 c = a * b;\n        require(c / a == b, \"SafeMath: multiplication overflow\");\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\n        return div(a, b, \"SafeMath: division by zero\");\n    }\n\n    /**\n     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n     * division by zero. The result is rounded towards zero.\n     *\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\n     * uses an invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     *\n     * _Available since v2.4.0._\n     */\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        // Solidity only automatically asserts when dividing by 0\n        require(b > 0, errorMessage);\n        uint256 c = a / b;\n        // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n        return c;\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     */\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n        return mod(a, b, \"SafeMath: modulo by zero\");\n    }\n\n    /**\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n     * Reverts with custom message when dividing by zero.\n     *\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\n     * invalid opcode to revert (consuming all remaining gas).\n     *\n     * Requirements:\n     * - The divisor cannot be zero.\n     *\n     * _Available since v2.4.0._\n     */\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n        require(b != 0, errorMessage);\n        return a % b;\n    }\n}\n\nlibrary Address {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * This test is non-exhaustive, and there may be false-negatives: during the\n     * execution of a contract's constructor, its address will be reported as\n     * not containing a contract.\n     *\n     * IMPORTANT: It is unsafe to assume that an address for which this\n     * function returns false is an externally-owned account (EOA) and not a\n     * contract.\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies in extcodesize, which returns 0 for contracts in\n        // construction, since the code is only stored at the end of the\n        // constructor execution.\n\n        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts\n        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned\n        // for accounts without code, i.e. `keccak256('')`\n        bytes32 codehash;\n        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;\n        // solhint-disable-next-line no-inline-assembly\n        assembly { codehash := extcodehash(account) }\n        return (codehash != 0x0 && codehash != accountHash);\n    }\n\n    /**\n     * @dev Converts an `address` into `address payable`. Note that this is\n     * simply a type cast: the actual underlying value is not changed.\n     *\n     * _Available since v2.4.0._\n     */\n    function toPayable(address account) internal pure returns (address payable) {\n        return address(uint160(account));\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     *\n     * _Available since v2.4.0._\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        // solhint-disable-next-line avoid-call-value\n        (bool success, ) = recipient.call.value(amount)(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n}\n\nlibrary Counters {\n    using SafeMath for uint256;\n\n    struct Counter {\n        // This variable should never be directly accessed by users of the library: interactions must be restricted to\n        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\n        // this feature: see https://github.com/ethereum/solidity/issues/4637\n        uint256 _value; // default: 0\n    }\n\n    function current(Counter storage counter) internal view returns (uint256) {\n        return counter._value;\n    }\n\n    function increment(Counter storage counter) internal {\n        counter._value += 1;\n    }\n\n    function decrement(Counter storage counter) internal {\n        counter._value = counter._value.sub(1);\n    }\n}\n\ncontract ERC165 is IERC165 {\n    /*\n     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7\n     */\n    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;\n\n    /**\n     * @dev Mapping of interface ids to whether or not it's supported.\n     */\n    mapping(bytes4 => bool) private _supportedInterfaces;\n\n    constructor () internal {\n        // Derived contracts need only register support for their own interfaces,\n        // we register support for ERC165 itself here\n        _registerInterface(_INTERFACE_ID_ERC165);\n    }\n\n    /**\n     * @dev See {IERC165-supportsInterface}.\n     *\n     * Time complexity O(1), guaranteed to always use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool) {\n        return _supportedInterfaces[interfaceId];\n    }\n\n    /**\n     * @dev Registers the contract as an implementer of the interface defined by\n     * `interfaceId`. Support of the actual ERC165 interface is automatic and\n     * registering its interface id is not required.\n     *\n     * See {IERC165-supportsInterface}.\n     *\n     * Requirements:\n     *\n     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).\n     */\n    function _registerInterface(bytes4 interfaceId) internal {\n        require(interfaceId != 0xffffffff, \"ERC165: invalid interface id\");\n        _supportedInterfaces[interfaceId] = true;\n    }\n}\n\ncontract ERC721 is Context, ERC165, IERC721 {\n    using SafeMath for uint256;\n    using Address for address;\n    using Counters for Counters.Counter;\n\n    // Equals to `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`\n    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`\n    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;\n\n    // Mapping from token ID to owner\n    mapping (uint256 => address) private _tokenOwner;\n\n    // Mapping from token ID to approved address\n    mapping (uint256 => address) private _tokenApprovals;\n\n    // Mapping from owner to number of owned token\n    mapping (address => Counters.Counter) private _ownedTokensCount;\n\n    // Mapping from owner to operator approvals\n    mapping (address => mapping (address => bool)) private _operatorApprovals;\n\n    /*\n     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231\n     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e\n     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3\n     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc\n     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465\n     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5\n     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd\n     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e\n     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde\n     *\n     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^\n     *        0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd\n     */\n    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;\n\n    constructor () public {\n        // register the supported interfaces to conform to ERC721 via ERC165\n        _registerInterface(_INTERFACE_ID_ERC721);\n    }\n\n    /**\n     * @dev Gets the balance of the specified address.\n     * @param owner address to query the balance of\n     * @return uint256 representing the amount owned by the passed address\n     */\n    function balanceOf(address owner) public view returns (uint256) {\n        require(owner != address(0), \"ERC721: balance query for the zero address\");\n\n        return _ownedTokensCount[owner].current();\n    }\n\n    /**\n     * @dev Gets the owner of the specified token ID.\n     * @param tokenId uint256 ID of the token to query the owner of\n     * @return address currently marked as the owner of the given token ID\n     */\n    function ownerOf(uint256 tokenId) public view returns (address) {\n        address owner = _tokenOwner[tokenId];\n        require(owner != address(0), \"ERC721: owner query for nonexistent token\");\n\n        return owner;\n    }\n\n    /**\n     * @dev Approves another address to transfer the given token ID\n     * The zero address indicates there is no approved address.\n     * There can only be one approved address per token at a given time.\n     * Can only be called by the token owner or an approved operator.\n     * @param to address to be approved for the given token ID\n     * @param tokenId uint256 ID of the token to be approved\n     */\n    function approve(address to, uint256 tokenId) public {\n        address owner = ownerOf(tokenId);\n        require(to != owner, \"ERC721: approval to current owner\");\n\n        require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),\n            \"ERC721: approve caller is not owner nor approved for all\"\n        );\n\n        _tokenApprovals[tokenId] = to;\n        emit Approval(owner, to, tokenId);\n    }\n\n    /**\n     * @dev Gets the approved address for a token ID, or zero if no address set\n     * Reverts if the token ID does not exist.\n     * @param tokenId uint256 ID of the token to query the approval of\n     * @return address currently approved for the given token ID\n     */\n    function getApproved(uint256 tokenId) public view returns (address) {\n        require(_exists(tokenId), \"ERC721: approved query for nonexistent token\");\n\n        return _tokenApprovals[tokenId];\n    }\n\n    /**\n     * @dev Sets or unsets the approval of a given operator\n     * An operator is allowed to transfer all tokens of the sender on their behalf.\n     * @param to operator address to set the approval\n     * @param approved representing the status of the approval to be set\n     */\n    function setApprovalForAll(address to, bool approved) public {\n        require(to != _msgSender(), \"ERC721: approve to caller\");\n\n        _operatorApprovals[_msgSender()][to] = approved;\n        emit ApprovalForAll(_msgSender(), to, approved);\n    }\n\n    /**\n     * @dev Tells whether an operator is approved by a given owner.\n     * @param owner owner address which you want to query the approval of\n     * @param operator operator address which you want to query the approval of\n     * @return bool whether the given operator is approved by the given owner\n     */\n    function isApprovedForAll(address owner, address operator) public view returns (bool) {\n        return _operatorApprovals[owner][operator];\n    }\n\n    /**\n     * @dev Transfers the ownership of a given token ID to another address.\n     * Usage of this method is discouraged, use {safeTransferFrom} whenever possible.\n     * Requires the msg.sender to be the owner, approved, or operator.\n     * @param from current owner of the token\n     * @param to address to receive the ownership of the given token ID\n     * @param tokenId uint256 ID of the token to be transferred\n     */\n    function transferFrom(address from, address to, uint256 tokenId) public {\n        //solhint-disable-next-line max-line-length\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n\n        _transferFrom(from, to, tokenId);\n    }\n\n    /**\n     * @dev Safely transfers the ownership of a given token ID to another address\n     * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received},\n     * which is called upon a safe transfer, and return the magic value\n     * `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`; otherwise,\n     * the transfer is reverted.\n     * Requires the msg.sender to be the owner, approved, or operator\n     * @param from current owner of the token\n     * @param to address to receive the ownership of the given token ID\n     * @param tokenId uint256 ID of the token to be transferred\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId) public {\n        safeTransferFrom(from, to, tokenId, \"\");\n    }\n\n    /**\n     * @dev Safely transfers the ownership of a given token ID to another address\n     * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received},\n     * which is called upon a safe transfer, and return the magic value\n     * `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`; otherwise,\n     * the transfer is reverted.\n     * Requires the _msgSender() to be the owner, approved, or operator\n     * @param from current owner of the token\n     * @param to address to receive the ownership of the given token ID\n     * @param tokenId uint256 ID of the token to be transferred\n     * @param _data bytes data to send along with a safe transfer check\n     */\n    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721: transfer caller is not owner nor approved\");\n        _safeTransferFrom(from, to, tokenId, _data);\n    }\n\n    /**\n     * @dev Safely transfers the ownership of a given token ID to another address\n     * If the target address is a contract, it must implement `onERC721Received`,\n     * which is called upon a safe transfer, and return the magic value\n     * `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`; otherwise,\n     * the transfer is reverted.\n     * Requires the msg.sender to be the owner, approved, or operator\n     * @param from current owner of the token\n     * @param to address to receive the ownership of the given token ID\n     * @param tokenId uint256 ID of the token to be transferred\n     * @param _data bytes data to send along with a safe transfer check\n     */\n    function _safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) internal {\n        _transferFrom(from, to, tokenId);\n        require(_checkOnERC721Received(from, to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n    }\n\n    /**\n     * @dev Returns whether the specified token exists.\n     * @param tokenId uint256 ID of the token to query the existence of\n     * @return bool whether the token exists\n     */\n    function _exists(uint256 tokenId) internal view returns (bool) {\n        address owner = _tokenOwner[tokenId];\n        return owner != address(0);\n    }\n\n    /**\n     * @dev Returns whether the given spender can transfer a given token ID.\n     * @param spender address of the spender to query\n     * @param tokenId uint256 ID of the token to be transferred\n     * @return bool whether the msg.sender is approved for the given token ID,\n     * is an operator of the owner, or is the owner of the token\n     */\n    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {\n        require(_exists(tokenId), \"ERC721: operator query for nonexistent token\");\n        address owner = ownerOf(tokenId);\n        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));\n    }\n\n    /**\n     * @dev Internal function to safely mint a new token.\n     * Reverts if the given token ID already exists.\n     * If the target address is a contract, it must implement `onERC721Received`,\n     * which is called upon a safe transfer, and return the magic value\n     * `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`; otherwise,\n     * the transfer is reverted.\n     * @param to The address that will own the minted token\n     * @param tokenId uint256 ID of the token to be minted\n     */\n    function _safeMint(address to, uint256 tokenId) internal {\n        _safeMint(to, tokenId, \"\");\n    }\n\n    /**\n     * @dev Internal function to safely mint a new token.\n     * Reverts if the given token ID already exists.\n     * If the target address is a contract, it must implement `onERC721Received`,\n     * which is called upon a safe transfer, and return the magic value\n     * `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`; otherwise,\n     * the transfer is reverted.\n     * @param to The address that will own the minted token\n     * @param tokenId uint256 ID of the token to be minted\n     * @param _data bytes data to send along with a safe transfer check\n     */\n    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal {\n        _mint(to, tokenId);\n        require(_checkOnERC721Received(address(0), to, tokenId, _data), \"ERC721: transfer to non ERC721Receiver implementer\");\n    }\n\n    /**\n     * @dev Internal function to mint a new token.\n     * Reverts if the given token ID already exists.\n     * @param to The address that will own the minted token\n     * @param tokenId uint256 ID of the token to be minted\n     */\n    function _mint(address to, uint256 tokenId) internal {\n        require(to != address(0), \"ERC721: mint to the zero address\");\n        require(!_exists(tokenId), \"ERC721: token already minted\");\n\n        _tokenOwner[tokenId] = to;\n        _ownedTokensCount[to].increment();\n\n        emit Transfer(address(0), to, tokenId);\n    }\n\n    /**\n     * @dev Internal function to burn a specific token.\n     * Reverts if the token does not exist.\n     * Deprecated, use {_burn} instead.\n     * @param owner owner of the token to burn\n     * @param tokenId uint256 ID of the token being burned\n     */\n    function _burn(address owner, uint256 tokenId) internal {\n        require(ownerOf(tokenId) == owner, \"ERC721: burn of token that is not own\");\n\n        _clearApproval(tokenId);\n\n        _ownedTokensCount[owner].decrement();\n        _tokenOwner[tokenId] = address(0);\n\n        emit Transfer(owner, address(0), tokenId);\n    }\n\n    /**\n     * @dev Internal function to burn a specific token.\n     * Reverts if the token does not exist.\n     * @param tokenId uint256 ID of the token being burned\n     */\n    function _burn(uint256 tokenId) internal {\n        _burn(ownerOf(tokenId), tokenId);\n    }\n\n    /**\n     * @dev Internal function to transfer ownership of a given token ID to another address.\n     * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\n     * @param from current owner of the token\n     * @param to address to receive the ownership of the given token ID\n     * @param tokenId uint256 ID of the token to be transferred\n     */\n    function _transferFrom(address from, address to, uint256 tokenId) internal {\n        require(ownerOf(tokenId) == from, \"ERC721: transfer of token that is not own\");\n        require(to != address(0), \"ERC721: transfer to the zero address\");\n\n        _clearApproval(tokenId);\n\n        _ownedTokensCount[from].decrement();\n        _ownedTokensCount[to].increment();\n\n        _tokenOwner[tokenId] = to;\n\n        emit Transfer(from, to, tokenId);\n    }\n\n    /**\n     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.\n     * The call is not executed if the target address is not a contract.\n     *\n     * This function is deprecated.\n     * @param from address representing the previous owner of the given token ID\n     * @param to target address that will receive the tokens\n     * @param tokenId uint256 ID of the token to be transferred\n     * @param _data bytes optional data to send along with the call\n     * @return bool whether the call correctly returned the expected magic value\n     */\n    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)\n        internal returns (bool)\n    {\n        if (!to.isContract()) {\n            return true;\n        }\n\n        bytes4 retval = IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data);\n        return (retval == _ERC721_RECEIVED);\n    }\n\n    /**\n     * @dev Private function to clear current approval of a given token ID.\n     * @param tokenId uint256 ID of the token to be transferred\n     */\n    function _clearApproval(uint256 tokenId) private {\n        if (_tokenApprovals[tokenId] != address(0)) {\n            _tokenApprovals[tokenId] = address(0);\n        }\n    }\n}\n\ncontract IERC721Enumerable is IERC721 {\n    function totalSupply() public view returns (uint256);\n    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId);\n\n    function tokenByIndex(uint256 index) public view returns (uint256);\n}\n\ncontract ERC721Enumerable is Context, ERC165, ERC721, IERC721Enumerable {\n    // Mapping from owner to list of owned token IDs\n    mapping(address => uint256[]) private _ownedTokens;\n\n    // Mapping from token ID to index of the owner tokens list\n    mapping(uint256 => uint256) private _ownedTokensIndex;\n\n    // Array with all token ids, used for enumeration\n    uint256[] private _allTokens;\n\n    // Mapping from token id to position in the allTokens array\n    mapping(uint256 => uint256) private _allTokensIndex;\n\n    /*\n     *     bytes4(keccak256('totalSupply()')) == 0x18160ddd\n     *     bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59\n     *     bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7\n     *\n     *     => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63\n     */\n    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;\n\n    /**\n     * @dev Constructor function.\n     */\n    constructor () public {\n        // register the supported interface to conform to ERC721Enumerable via ERC165\n        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);\n    }\n\n    /**\n     * @dev Gets the token ID at a given index of the tokens list of the requested owner.\n     * @param owner address owning the tokens list to be accessed\n     * @param index uint256 representing the index to be accessed of the requested tokens list\n     * @return uint256 token ID at the given index of the tokens list owned by the requested address\n     */\n    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {\n        require(index < balanceOf(owner), \"ERC721Enumerable: owner index out of bounds\");\n        return _ownedTokens[owner][index];\n    }\n\n    /**\n     * @dev Gets the total amount of tokens stored by the contract.\n     * @return uint256 representing the total amount of tokens\n     */\n    function totalSupply() public view returns (uint256) {\n        return _allTokens.length;\n    }\n\n    /**\n     * @dev Gets the token ID at a given index of all the tokens in this contract\n     * Reverts if the index is greater or equal to the total number of tokens.\n     * @param index uint256 representing the index to be accessed of the tokens list\n     * @return uint256 token ID at the given index of the tokens list\n     */\n    function tokenByIndex(uint256 index) public view returns (uint256) {\n        require(index < totalSupply(), \"ERC721Enumerable: global index out of bounds\");\n        return _allTokens[index];\n    }\n\n    /**\n     * @dev Internal function to transfer ownership of a given token ID to another address.\n     * As opposed to transferFrom, this imposes no restrictions on msg.sender.\n     * @param from current owner of the token\n     * @param to address to receive the ownership of the given token ID\n     * @param tokenId uint256 ID of the token to be transferred\n     */\n    function _transferFrom(address from, address to, uint256 tokenId) internal {\n        super._transferFrom(from, to, tokenId);\n\n        _removeTokenFromOwnerEnumeration(from, tokenId);\n\n        _addTokenToOwnerEnumeration(to, tokenId);\n    }\n\n    /**\n     * @dev Internal function to mint a new token.\n     * Reverts if the given token ID already exists.\n     * @param to address the beneficiary that will own the minted token\n     * @param tokenId uint256 ID of the token to be minted\n     */\n    function _mint(address to, uint256 tokenId) internal {\n        super._mint(to, tokenId);\n\n        _addTokenToOwnerEnumeration(to, tokenId);\n\n        _addTokenToAllTokensEnumeration(tokenId);\n    }\n\n    /**\n     * @dev Internal function to burn a specific token.\n     * Reverts if the token does not exist.\n     * Deprecated, use {ERC721-_burn} instead.\n     * @param owner owner of the token to burn\n     * @param tokenId uint256 ID of the token being burned\n     */\n    function _burn(address owner, uint256 tokenId) internal {\n        super._burn(owner, tokenId);\n\n        _removeTokenFromOwnerEnumeration(owner, tokenId);\n        // Since tokenId will be deleted, we can clear its slot in _ownedTokensIndex to trigger a gas refund\n        _ownedTokensIndex[tokenId] = 0;\n\n        _removeTokenFromAllTokensEnumeration(tokenId);\n    }\n\n    /**\n     * @dev Gets the list of token IDs of the requested owner.\n     * @param owner address owning the tokens\n     * @return uint256[] List of token IDs owned by the requested address\n     */\n    function _tokensOfOwner(address owner) internal view returns (uint256[] storage) {\n        return _ownedTokens[owner];\n    }\n\n    /**\n     * @dev Private function to add a token to this extension's ownership-tracking data structures.\n     * @param to address representing the new owner of the given token ID\n     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\n     */\n    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\n        _ownedTokensIndex[tokenId] = _ownedTokens[to].length;\n        _ownedTokens[to].push(tokenId);\n    }\n\n    /**\n     * @dev Private function to add a token to this extension's token tracking data structures.\n     * @param tokenId uint256 ID of the token to be added to the tokens list\n     */\n    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\n        _allTokensIndex[tokenId] = _allTokens.length;\n        _allTokens.push(tokenId);\n    }\n\n    /**\n     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\n     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\n     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\n     * This has O(1) time complexity, but alters the order of the _ownedTokens array.\n     * @param from address representing the previous owner of the given token ID\n     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\n     */\n    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\n        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\n        // then delete the last slot (swap and pop).\n\n        uint256 lastTokenIndex = _ownedTokens[from].length.sub(1);\n        uint256 tokenIndex = _ownedTokensIndex[tokenId];\n\n        // When the token to delete is the last token, the swap operation is unnecessary\n        if (tokenIndex != lastTokenIndex) {\n            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];\n\n            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n        }\n\n        // This also deletes the contents at the last position of the array\n        _ownedTokens[from].length--;\n\n        // Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occupied by\n        // lastTokenId, or just over the end of the array if the token was the last one).\n    }\n\n    /**\n     * @dev Private function to remove a token from this extension's token tracking data structures.\n     * This has O(1) time complexity, but alters the order of the _allTokens array.\n     * @param tokenId uint256 ID of the token to be removed from the tokens list\n     */\n    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\n        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\n        // then delete the last slot (swap and pop).\n\n        uint256 lastTokenIndex = _allTokens.length.sub(1);\n        uint256 tokenIndex = _allTokensIndex[tokenId];\n\n        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\n        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\n        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\n        uint256 lastTokenId = _allTokens[lastTokenIndex];\n\n        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\n        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\n\n        // This also deletes the contents at the last position of the array\n        _allTokens.length--;\n        _allTokensIndex[tokenId] = 0;\n    }\n}\n\ncontract IERC721Metadata is IERC721 {\n    function name() external view returns (string memory);\n    function symbol() external view returns (string memory);\n    function tokenURI(uint256 tokenId) external view returns (string memory);\n}\n\ncontract ERC721Metadata is Context, ERC165, ERC721, IERC721Metadata {\n    // Token name\n    string private _name;\n\n    // Token symbol\n    string private _symbol;\n\n    // Optional mapping for token URIs\n    mapping(uint256 => string) private _tokenURIs;\n\n    /*\n     *     bytes4(keccak256('name()')) == 0x06fdde03\n     *     bytes4(keccak256('symbol()')) == 0x95d89b41\n     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd\n     *\n     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f\n     */\n    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;\n\n    /**\n     * @dev Constructor function\n     */\n    constructor (string memory name, string memory symbol) public {\n        _name = name;\n        _symbol = symbol;\n\n        // register the supported interfaces to conform to ERC721 via ERC165\n        _registerInterface(_INTERFACE_ID_ERC721_METADATA);\n    }\n\n    /**\n     * @dev Gets the token name.\n     * @return string representing the token name\n     */\n    function name() external view returns (string memory) {\n        return _name;\n    }\n\n    /**\n     * @dev Gets the token symbol.\n     * @return string representing the token symbol\n     */\n    function symbol() external view returns (string memory) {\n        return _symbol;\n    }\n\n    /**\n     * @dev Returns an URI for a given token ID.\n     * Throws if the token ID does not exist. May return an empty string.\n     * @param tokenId uint256 ID of the token to query\n     */\n    function tokenURI(uint256 tokenId) external view returns (string memory) {\n        require(_exists(tokenId), \"ERC721Metadata: URI query for nonexistent token\");\n        return _tokenURIs[tokenId];\n    }\n\n    /**\n     * @dev Internal function to set the token URI for a given token.\n     * Reverts if the token ID does not exist.\n     * @param tokenId uint256 ID of the token to set its URI\n     * @param uri string URI to assign\n     */\n    function _setTokenURI(uint256 tokenId, string memory uri) internal {\n        require(_exists(tokenId), \"ERC721Metadata: URI set of nonexistent token\");\n        _tokenURIs[tokenId] = uri;\n    }\n\n    /**\n     * @dev Internal function to burn a specific token.\n     * Reverts if the token does not exist.\n     * Deprecated, use _burn(uint256) instead.\n     * @param owner owner of the token to burn\n     * @param tokenId uint256 ID of the token being burned by the msg.sender\n     */\n    function _burn(address owner, uint256 tokenId) internal {\n        super._burn(owner, tokenId);\n\n        // Clear metadata (if any)\n        if (bytes(_tokenURIs[tokenId]).length != 0) {\n            delete _tokenURIs[tokenId];\n        }\n    }\n}\n\ncontract ERC721Full is ERC721, ERC721Enumerable, ERC721Metadata {\n    constructor (string memory name, string memory symbol) public ERC721Metadata(name, symbol) {\n        // solhint-disable-previous-line no-empty-blocks\n    }\n}\n\ncontract ERC721Burnable is Context, ERC721 {\n    /**\n     * @dev Burns a specific ERC721 token.\n     * @param tokenId uint256 id of the ERC721 token to be burned.\n     */\n    function burn(uint256 tokenId) public {\n        //solhint-disable-next-line max-line-length\n        require(_isApprovedOrOwner(_msgSender(), tokenId), \"ERC721Burnable: caller is not owner nor approved\");\n        _burn(tokenId);\n    }\n}\n\ncontract Ownable is Context {\n    address private _owner;\n\n    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n    /**\n     * @dev Initializes the contract setting the deployer as the initial owner.\n     */\n    constructor () internal {\n        _owner = _msgSender();\n        emit OwnershipTransferred(address(0), _owner);\n    }\n\n    /**\n     * @dev Returns the address of the current owner.\n     */\n    function owner() public view returns (address) {\n        return _owner;\n    }\n\n    /**\n     * @dev Throws if called by any account other than the owner.\n     */\n    modifier onlyOwner() {\n        require(isOwner(), \"Ownable: caller is not the owner\");\n        _;\n    }\n\n    /**\n     * @dev Returns true if the caller is the current owner.\n     */\n    function isOwner() public view returns (bool) {\n        return _msgSender() == _owner;\n    }\n\n    /**\n     * @dev Leaves the contract without owner. It will not be possible to call\n     * `onlyOwner` functions anymore. Can only be called by the current owner.\n     *\n     * NOTE: Renouncing ownership will leave the contract without an owner,\n     * thereby removing any functionality that is only available to the owner.\n     */\n    function renounceOwnership() public onlyOwner {\n        emit OwnershipTransferred(_owner, address(0));\n        _owner = address(0);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     * Can only be called by the current owner.\n     */\n    function transferOwnership(address newOwner) public onlyOwner {\n        _transferOwnership(newOwner);\n    }\n\n    /**\n     * @dev Transfers ownership of the contract to a new account (`newOwner`).\n     */\n    function _transferOwnership(address newOwner) internal {\n        require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n        emit OwnershipTransferred(_owner, newOwner);\n        _owner = newOwner;\n    }\n}\n\nlibrary Strings {\n  // via https://github.com/oraclize/ethereum-api/blob/master/oraclizeAPI_0.5.sol\n  function strConcat(string memory _a, string memory _b, string memory _c, string memory _d, string memory _e) internal pure returns (string memory) {\n      bytes memory _ba = bytes(_a);\n      bytes memory _bb = bytes(_b);\n      bytes memory _bc = bytes(_c);\n      bytes memory _bd = bytes(_d);\n      bytes memory _be = bytes(_e);\n      string memory abcde = new string(_ba.length + _bb.length + _bc.length + _bd.length + _be.length);\n      bytes memory babcde = bytes(abcde);\n      uint k = 0;\n      for (uint i = 0; i < _ba.length; i++) babcde[k++] = _ba[i];\n      for (uint i = 0; i < _bb.length; i++) babcde[k++] = _bb[i];\n      for (uint i = 0; i < _bc.length; i++) babcde[k++] = _bc[i];\n      for (uint i = 0; i < _bd.length; i++) babcde[k++] = _bd[i];\n      for (uint i = 0; i < _be.length; i++) babcde[k++] = _be[i];\n      return string(babcde);\n    }\n\n    function strConcat(string memory _a, string memory _b, string memory _c, string memory _d) internal pure returns (string memory) {\n        return strConcat(_a, _b, _c, _d, \"\");\n    }\n\n    function strConcat(string memory _a, string memory _b, string memory _c) internal pure returns (string memory) {\n        return strConcat(_a, _b, _c, \"\", \"\");\n    }\n\n    function strConcat(string memory _a, string memory _b) internal pure returns (string memory) {\n        return strConcat(_a, _b, \"\", \"\", \"\");\n    }\n\n    function uint2str(uint _i) internal pure returns (string memory _uintAsString) {\n        if (_i == 0) {\n            return \"0\";\n        }\n        uint j = _i;\n        uint len;\n        while (j != 0) {\n            len++;\n            j /= 10;\n        }\n        bytes memory bstr = new bytes(len);\n        uint k = len - 1;\n        while (_i != 0) {\n            bstr[k--] = byte(uint8(48 + _i % 10));\n            _i /= 10;\n        }\n        return string(bstr);\n    }\n}\n\ncontract OwnableDelegateProxy { }\n\ncontract ProxyRegistry {\n    mapping(address => OwnableDelegateProxy) public proxies;\n}\n\ncontract PromotedPool is ERC721Full, ERC721Burnable, Ownable {\n  using Strings for string;\n\n  address proxyRegistryAddress;\n  uint256 private _currentTokenId;\n  uint256 private _activeTokenId;\n  uint8 public currentTermsVersion;\n\n  struct PromotionPeriod {\n    uint256 startTime;\n    uint256 endTime;\n  }\n\n  struct PoolProposal {\n    address proposedPool;\n    address approvedPool;\n  }\n\n  mapping (uint256 => PromotionPeriod) promotionPeriods;\n  mapping (uint256 => PoolProposal) proposedPools;\n  mapping (uint256 => uint8) termsVersions;\n  mapping (uint8 => string) terms;\n\n  event MintedToken(uint256 indexed tokenId, address indexed tokenOwner, uint256 indexed startTime, uint256 endTime);\n  event PromotedPoolProposed(address indexed poolAddress, uint256 indexed tokenId, uint256 indexed startTime, uint256 endTime);\n  event PromotedPoolApproved(address indexed poolAddress, uint256 indexed tokenId, uint256 indexed startTime, uint256 endTime);\n  event ActiveTokenUpdated(uint256 indexed tokenId);\n  event PromotedPoolReset(uint256 indexed tokenId);\n\n  constructor(string memory _name, string memory _symbol, address _proxyRegistryAddress) ERC721Full(_name, _symbol) public {\n    proxyRegistryAddress = _proxyRegistryAddress;\n  }\n\n  /**\n    * @dev Mints a token to an address with a tokenURI.\n    * @param _to address of the future owner of the token\n    */\n  function mintTo(address _to, uint256 _startTime, uint256 _endTime, string memory _termsHash, uint8 _termsVersion) public onlyOwner {\n    require(_startTime > now, \"Token must have start time in the future.\");\n    require(_startTime > promotionPeriods[_currentTokenId].endTime, \"Token must have start time > most recent token's end time\");\n    if(promotionPeriods[_currentTokenId].endTime != 0) {\n      require(_startTime - promotionPeriods[_currentTokenId].endTime < 7890000 , \"Token must have start time < 1 year after the most recent token's end time\");\n    }\n    uint256 newTokenId = _getNextTokenId();\n    _mint(_to, newTokenId);\n    _incrementTokenId();\n    promotionPeriods[newTokenId] = PromotionPeriod(_startTime, _endTime);\n    proposedPools[newTokenId] = PoolProposal(address(0), address(0));\n    if(_termsVersion > currentTermsVersion) {\n      terms[_termsVersion] = _termsHash;\n      currentTermsVersion = _termsVersion;\n    }\n    termsVersions[newTokenId] = _termsVersion;\n    emit MintedToken(newTokenId, _to, _startTime, _endTime);\n  }\n\n  function proposePromotedPool(uint256 _tokenId, address _poolAddress) public {\n    require(msg.sender == ownerOf(_tokenId), \"You must be the owner of a valid token to propose a promoted pool\");\n    require(promotionPeriods[_tokenId].endTime > now, \"Sorry, this token has expired\");\n    proposedPools[_tokenId].proposedPool = _poolAddress;\n    emit PromotedPoolProposed(_poolAddress, _tokenId, promotionPeriods[_tokenId].startTime, promotionPeriods[_tokenId].endTime);\n  }\n\n  function approvePromotedPool(uint256 _tokenId, address _poolAddress) public onlyOwner {\n    require(proposedPools[_tokenId].proposedPool == _poolAddress, \"Pool address must match pool proposed by token holder\");\n    require(promotionPeriods[_tokenId].endTime > now, \"This token has expired\");\n    proposedPools[_tokenId].approvedPool = _poolAddress;\n    emit PromotedPoolApproved(_poolAddress, _tokenId, promotionPeriods[_tokenId].startTime, promotionPeriods[_tokenId].endTime);\n  }\n\n  function resetPromotedPool(uint256 _tokenId) public onlyOwner {\n    proposedPools[_tokenId].approvedPool = address(0);\n    emit PromotedPoolReset(_tokenId);\n  }\n\n  function getPromotedPool() public view returns (address) {\n    return proposedPools[_activeTokenId].approvedPool;\n  }\n\n  function setPromotedPool() public {\n    require(_currentTokenId > _activeTokenId, \"Mint new token first.\");\n    if (now >= promotionPeriods[_activeTokenId].endTime) {\n      ++_activeTokenId;\n      emit ActiveTokenUpdated(_activeTokenId);\n    }\n  }\n\n  function getTermsHash(uint8 _termsVersion) public view returns(string memory) {\n    return terms[_termsVersion];\n  }\n\n  function getTermsVersion(uint256 _tokenId) public view returns(uint8) {\n    return termsVersions[_tokenId];\n  }\n\n  /**\n    * @dev calculates the next token ID based on value of _currentTokenId \n    * @return uint256 for the next token ID\n    */\n  function _getNextTokenId() private view returns (uint256) {\n    return _currentTokenId.add(1);\n  }\n\n  /**\n    * @dev increments the value of _currentTokenId \n    */\n  function _incrementTokenId() private  {\n    _currentTokenId++;\n  }\n\n  function baseTokenURI() public view returns (string memory) {\n    return \"https://promoted-pools.herokuapp.com/\";\n  }\n\n  function tokenURI(uint256 _tokenId) external view returns (string memory) {\n    return Strings.strConcat(\n        baseTokenURI(),\n        Strings.uint2str(_tokenId)\n    );\n  }\n\n  /**\n   * Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-less listings.\n   */\n  function isApprovedForAll(\n    address owner,\n    address operator\n  )\n    public\n    view\n    returns (bool)\n  {\n    // Whitelist OpenSea proxy contract for easy trading.\n    ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);\n    if (address(proxyRegistry.proxies(owner)) == operator) {\n        return true;\n    }\n\n    return super.isApprovedForAll(owner, operator);\n  }\n}",
  "codeformat": "solidity-single-file",
  "contractname": "PromotedPool",
  "compilerversion": "v0.5.12+commit.7709ece9",
  "optimizationUsed": 0,
  "runs": 200,
  "constructorArguements": "000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000f57b2c51ded3a29e6891aba85459d600256cf317000000000000000000000000000000000000000000000000000000000000000f506f6f6c732e6679692050726f6d6f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034659490000000000000000000000000000000000000000000000000000000000"
}
Checking status of verification request g1n6nymenzuc4aim5qfyzwird8nmbh4z8nmwnuy96zb9rxrarb
Fail - Unable to verify
Failed to verify 1 contract(s): PromotedPool@0x3D0Cb6CC9ddc16e96B26b4a0613bb46667ff2928

Any thoughts/additional checks I can do?

Support for contracts deployed via a factory?

Hello! Thanks for your work on this! This is very exciting for us!

That said, we have a challenge because the contract we'd like to verify (this one for example) is deployed via another contract.

It looks like this causes 2 different issues:

  1. It needs an address inside of the PublicLock.json. This is one is easy, I just manually updated the json file to add one of an existing deployed contract
  2. It needs to find the input field on the transaction which instantiated the contract. This one is trickier, because that transaction was not tiggered by me and since this is an "internal" transaction we do not get to access the input field.

Any way you could support the factories?

rinkeby verify error

Hostname/IP does not match certificate's altnames: Host: api-rinkeby.etherscan.io. is not in the cert's altnames: DNS:.facebook.com, DNS:.facebook.net, DNS:.fbcdn.net, DNS:.fbsbx.com, DNS:.m.facebook.com, DNS:.messenger.com, DNS:.xx.fbcdn.net, DNS:.xy.fbcdn.net, DNS:*.xz.fbcdn.net, DNS:facebook.com, DNS:messenger.com
Failed to connect to Etherscan API at url https://api-rinkeby.etherscan.io/api
Failed to verify 1 contract(s): MetaCoin

Could not retrieve constructor parameters

following is the log ,I did have the constructor parameters but cannot Retrieving them,it may be the failed reason

DEBUG logging is turned ON
Running truffle-plugin-verify v0.5.2
Verifying ShardsMarket
Reading artifact file at /Users/admin/myproject/NFT/build/contracts/ShardsMarket.json
Retrieving constructor parameters from https://api-kovan.etherscan.io/api?apiKey=GF7C2KTUTRMJUW72WAJBINX8IQGAMKVI27&module=account&action=txlist&address=0xee9E5C8496774396026Ef2c61e53989a3B8a12f6&page=1&sort=asc&offset=1
Could not retrieve constructor parameters, using empty parameters as fallback
Sending verify request with POST arguments:
{
  "apikey": "GF7C2KTUTRMJUW72WAJBINX8IQGAMKVI27",
  "module": "contract",
  "action": "verifysourcecode",
  "contractaddress": "0xee9E5C8496774396026Ef2c61e53989a3B8a12f6",
  "sourceCode":
},\"settings\":{\"remappings\":[],\"optimizer\":{\"enabled\":true,\"runs\":100},\"evmVersion\":\"istanbul\",\"libraries\":{\"\":{}}}}",
  "codeformat": "solidity-standard-json-input",
  "contractname": "/Users/admin/myproject/NFT/contracts/ShardsMarket.sol:ShardsMarket",
  "compilerversion": "v0.6.12+commit.27d51765",
  "constructorArguements": ""
}
Failed to verify 1 contract(s): ShardsMarket

issues with solc 0.5.10 and truffle v5.0.24

Truffle v5.0.24 (core: 5.0.24)
Solidity v0.5.0 (solc-js)
Node v11.13.0
Web3.js v1.0.0-beta.37

Verifying SyscoinBattleManager
{"status":"0","message":"NOTOK","result":"Fail - Unable to verify"}
Fail - Unable to verify

Failed to verify 1 contract(s): SyscoinBattleManager

The input is like this:
{ apikey: '',
module: 'contract',
action: 'verifysourcecode',
contractaddress: '0x47C450C0c189E4E6DdbE84AdCB4FF7E3e06d0601',
sourceCode:
'pragma solidity ^0.5.10;\n\n/\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * SafeMath restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's + operator.\n *\n * Requirements:\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, "SafeMath: addition overflow");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's - operator.\n *\n * Requirements:\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n require(b <= a, "SafeMath: subtraction overflow");\n ........

The contract can be found here if you wanna try: https://github.com/syscoin/sysethereum-contracts. All of the contracts fail to verify.

Notice the '\n' characters.. those are added to the sourceMap and etherscan doesn't seem to like it. Is there a way to strip them out before giving to etherscan? I manually tried a file and confirmed it works but when using the '\n' sourcemap it complains manually aswell.

Thanks for the look!

Fail - Unable to verify

Hi,

I'm trying to verify the WFILFactory contract on rinkeby via truffle-plugin-verify v0.5.2:
npx truffle run verify WFILFactory --network rinkeby

als tried with v0.4.1:
npx truffle run verify WFILFactory --network rinkeby --licence

I get:

Verifying WFILFactory
Fail - Unable to verify
Failed to verify 1 contract(s): WFILFactory

with --debug:

DEBUG logging is turned ON
Running truffle-plugin-verify v0.5.2
Verifying WFILFactory
Reading artifact file at /home/hackfs/wfil-factory/build/contracts/WFILFactory.json
Retrieving constructor parameters from https://api-rinkeby.etherscan.io/api?apiKey=<API-KEY>&module=account&action=txlist&address=0xD27B309B0Fd0E251674a6A52765934ef961E38Df&page=1&sort=asc&offset=1
Constructor parameters retrieved: 0x000000000000000000000000a04bbe85d91c3125d577af17e4eb5d4e579100cf0000000000000000000000003bbca3216dbafdfa61b3bbaacb9c6febe4c45f2f
Sending verify request with POST arguments:
{
  "apikey": "<API-KEY>",
  "module": "contract",
  "action": "verifysourcecode",
  "contractaddress": "0xD27B309B0Fd0E251674a6A52765934ef961E38Df",
  "sourceCode": "{\"language\":\"Solidity\",\"sources\":{\"/home/hackfs/wfil-factory/contracts/WFILFactory.sol\":{\"content\":\"/// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity 0.6.12;\\n\\n/// Copyright (C) 2020 WFIL Labs, Inc.\\n/// @title WFILFactory\\n/// @author Nazzareno Massari @naszam\\n/// @notice Wrapped Filecoin (WFIL) Factory\\n/// @dev All function calls are currently implemented without side effects through TDD approach\\n/// @dev OpenZeppelin library is used for secure contract development\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/AccessControl.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Pausable.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/Counters.sol\\\";\\n\\ninterface WFILToken {\\n  function wrap(address to, uint256 amount) external returns (bool);\\n  function unwrapFrom(address account, uint256 amount) external returns (bool);\\n}\\n\\ncontract WFILFactory is AccessControl, Pausable {\\n\\n    /// @dev Libraries\\n    using SafeERC20 for IERC20;\\n    using Counters for Counters.Counter;\\n\\n    enum RequestStatus {PENDING, CANCELED, APPROVED, REJECTED}\\n\\n    struct Request {\\n      address requester; // sender of the request.\\n      address custodian; // custodian associated to sender\\n      uint256 amount; // amount of fil to mint/burn.\\n      string deposit; // custodian's fil address in mint, merchant's fil address in burn.\\n      string txId; // filcoin txId for sending/redeeming fil in the mint/burn process.\\n      uint256 nonce; // serial number allocated for each request.\\n      uint256 timestamp; // time of the request creation.\\n      RequestStatus status; // status of the request.\\n    }\\n\\n    WFILToken internal immutable wfil;\\n\\n    /// @dev Counters\\n    Counters.Counter private _mintsIdTracker;\\n    Counters.Counter private _burnsIdTracker;\\n\\n    /// @dev Storage\\n    mapping(address => string) public custodianDeposit;\\n    mapping(address => string) public merchantDeposit;\\n    mapping(bytes32 => uint256) public mintNonce;\\n    mapping(bytes32 => uint256) public burnNonce;\\n    mapping(uint256 => Request) public mints;\\n    mapping(uint256 => Request) public burns;\\n\\n    /// @dev Roles\\n    bytes32 public constant CUSTODIAN_ROLE = keccak256(\\\"CUSTODIAN_ROLE\\\");\\n    bytes32 public constant MERCHANT_ROLE = keccak256(\\\"MERCHANT_ROLE\\\");\\n    bytes32 public constant PAUSER_ROLE = keccak256(\\\"PAUSER_ROLE\\\");\\n\\n    /// @dev Events\\n    event CustodianDepositSet(address indexed merchant, address indexed custodian, string deposit);\\n    event MerchantDepositSet(address indexed merchant, string deposit);\\n    event MintRequestAdd(\\n        uint256 indexed nonce,\\n        address indexed requester,\\n        address indexed custodian,\\n        uint256 amount,\\n        string deposit,\\n        string txId,\\n        uint256 timestamp,\\n        bytes32 requestHash\\n    );\\n    event MintRequestCancel(uint256 indexed nonce, address indexed requester, bytes32 requestHash);\\n    event MintConfirmed(\\n        uint256 indexed nonce,\\n        address indexed requester,\\n        address indexed custodian,\\n        uint256 amount,\\n        string deposit,\\n        string txId,\\n        uint256 timestamp,\\n        bytes32 requestHash\\n    );\\n    event MintRejected(\\n        uint256 indexed nonce,\\n        address indexed requester,\\n        address indexed custodian,\\n        uint256 amount,\\n        string deposit,\\n        string txId,\\n        uint256 timestamp,\\n        bytes32 requestHash\\n    );\\n    event Burned(\\n        uint256 indexed nonce,\\n        address indexed requester,\\n        address indexed custodian,\\n        uint256 amount,\\n        string deposit,\\n        uint256 timestamp,\\n        bytes32 requestHash\\n    );\\n    event BurnConfirmed(\\n        uint256 indexed nonce,\\n        address indexed requester,\\n        address indexed custodian,\\n        uint256 amount,\\n        string deposit,\\n        string txId,\\n        uint256 timestamp,\\n        bytes32 inputRequestHash\\n    );\\n    event BurnRejected(\\n        uint256 indexed nonce,\\n        address indexed requester,\\n        address indexed custodian,\\n        uint256 amount,\\n        string deposit,\\n        string txId,\\n        uint256 timestamp,\\n        bytes32 inputRequestHash\\n    );\\n    event TokenClaimed(IERC20 indexed token, address indexed recipient, uint256 amount);\\n\\n    constructor(address wfil_, address dao_)\\n        public\\n    {\\n        require(wfil_ != address(0), \\\"WFILFactory: wfil token set to zero address\\\");\\n        require(dao_ != address(0), \\\"WFILFactory: dao set to zero address\\\");\\n\\n        _setupRole(DEFAULT_ADMIN_ROLE, dao_);\\n        _setupRole(PAUSER_ROLE, dao_);\\n\\n        wfil = WFILToken(wfil_);\\n\\n    }\\n\\n    /// @notice Fallback function\\n    /// @dev Added not payable to revert transactions not matching any other function which send value\\n    fallback() external {\\n        revert(\\\"WFILFactory: function not matching any other\\\");\\n    }\\n\\n    /// @notice Set Custodian Deposit Address\\n    /// @dev Access restricted only for Custodian\\n    /// @param merchant Merchant Address\\n    /// @param deposit Custodian deposit address\\n    function setCustodianDeposit(address merchant, string calldata deposit)\\n      external\\n      whenNotPaused\\n    {\\n        require(hasRole(CUSTODIAN_ROLE, msg.sender), \\\"WFILFactory: caller is not a custodian\\\");\\n        require(merchant != address(0), \\\"WFILFactory: invalid merchant address\\\");\\n        require(hasRole(MERCHANT_ROLE, merchant), \\\"WFILFactory: merchant address does not have merchant role\\\");\\n        require(!_isEmpty(deposit), \\\"WFILFactory: invalid asset deposit address\\\");\\n        require(!_compareStrings(deposit, custodianDeposit[merchant]), \\\"WFILFactory: custodian deposit address already set\\\");\\n\\n        custodianDeposit[merchant] = deposit;\\n        emit CustodianDepositSet(merchant, msg.sender, deposit);\\n    }\\n\\n    /// @notice Set Merchant Deposit Address\\n    /// @dev Access restricted only for Merchant\\n    /// @param deposit Merchant deposit address\\n    function setMerchantDeposit(string calldata deposit)\\n        external\\n        whenNotPaused\\n    {\\n        require(hasRole(MERCHANT_ROLE, msg.sender), \\\"WFILFactory: caller is not a merchant\\\");\\n        require(!_isEmpty(deposit), \\\"WFILFactory: invalid asset deposit address\\\");\\n        require(!_compareStrings(deposit, merchantDeposit[msg.sender]), \\\"WFILFactory: merchant deposit address already set\\\");\\n\\n        merchantDeposit[msg.sender] = deposit;\\n        emit MerchantDepositSet(msg.sender, deposit);\\n    }\\n\\n    /// @notice Add Merchant WFIL Mint Request\\n    /// @dev Access restricted only for Merchant\\n    /// @param amount Ammount of WFIL to mint\\n    /// @param txId Transaction Id of the FIL transaction\\n    /// @param custodian Custodian address\\n    function addMintRequest(uint256 amount, string calldata txId, address custodian)\\n        external\\n        whenNotPaused\\n    {\\n        require(hasRole(MERCHANT_ROLE, msg.sender), \\\"WFILFactory: caller is not a merchant\\\");\\n        require(amount > 0, \\\"WFILFactory: amount is zero\\\");\\n        require(!_isEmpty(txId), \\\"WFILFactory: invalid filecoin txId\\\");\\n        require(hasRole(CUSTODIAN_ROLE, custodian), \\\"WFILFactory: custodian has not the custodian role\\\");\\n\\n        string memory deposit = custodianDeposit[msg.sender];\\n        require(!_isEmpty(deposit), \\\"WFILFactory: custodian filecoin deposit address was not set\\\");\\n\\n        uint256 nonce = _mintsIdTracker.current();\\n        uint256 timestamp = _timestamp();\\n\\n        mints[nonce].requester = msg.sender;\\n        mints[nonce].custodian = custodian;\\n        mints[nonce].amount = amount;\\n        mints[nonce].deposit = deposit;\\n        mints[nonce].txId = txId;\\n        mints[nonce].nonce = nonce;\\n        mints[nonce].timestamp = timestamp;\\n        mints[nonce].status = RequestStatus.PENDING;\\n\\n        bytes32 requestHash = _hash(mints[nonce]);\\n        mintNonce[requestHash] = nonce;\\n        _mintsIdTracker.increment();\\n\\n        emit MintRequestAdd(nonce, msg.sender, custodian, amount, deposit, txId, timestamp, requestHash);\\n    }\\n\\n    /// @notice Cancel Merchant WFIL Mint Request\\n    /// @dev Access restricted only for Merchant\\n    /// @param requestHash Hash of the merchant mint request metadata\\n    function cancelMintRequest(bytes32 requestHash) external whenNotPaused {\\n        require(hasRole(MERCHANT_ROLE, msg.sender), \\\"WFILFactory: caller is not a merchant\\\");\\n\\n        (uint256 nonce, Request memory request) = _getPendingMintRequest(requestHash);\\n\\n        require(msg.sender == request.requester, \\\"WFILFactory: cancel caller is different than pending request initiator\\\");\\n        mints[nonce].status = RequestStatus.CANCELED;\\n\\n        emit MintRequestCancel(nonce, msg.sender, requestHash);\\n    }\\n\\n    /// @notice Confirm Merchant WFIL Mint Request\\n    /// @dev Access restricted only for Custodian\\n    /// @param requestHash Hash of the merchant mint request metadata\\n    function confirmMintRequest(bytes32 requestHash) external whenNotPaused {\\n        require(hasRole(CUSTODIAN_ROLE, msg.sender), \\\"WFILFactory: caller is not a custodian\\\");\\n\\n        (uint256 nonce, Request memory request) = _getPendingMintRequest(requestHash);\\n\\n        require(msg.sender == request.custodian, \\\"WFILFactory: confirm caller is different than pending request custodian\\\");\\n\\n        mints[nonce].status = RequestStatus.APPROVED;\\n\\n        emit MintConfirmed(\\n            request.nonce,\\n            request.requester,\\n            request.custodian,\\n            request.amount,\\n            request.deposit,\\n            request.txId,\\n            request.timestamp,\\n            requestHash\\n        );\\n\\n        require(wfil.wrap(request.requester, request.amount), \\\"WFILFactory: mint failed\\\");\\n    }\\n\\n    /// @notice Reject Merchant WFIL Mint Request\\n    /// @dev Access restricted only for Custodian\\n    /// @param requestHash Hash of the merchant mint request metadata\\n    function rejectMintRequest(bytes32 requestHash) external whenNotPaused {\\n        require(hasRole(CUSTODIAN_ROLE, msg.sender), \\\"WFILFactory: caller is not a custodian\\\");\\n\\n        (uint256 nonce, Request memory request) = _getPendingMintRequest(requestHash);\\n\\n        require(msg.sender == request.custodian, \\\"WFILFactory: reject caller is different than pending request custodian\\\");\\n\\n        mints[nonce].status = RequestStatus.REJECTED;\\n\\n        emit MintRejected(\\n            request.nonce,\\n            request.requester,\\n            request.custodian,\\n            request.amount,\\n            request.deposit,\\n            request.txId,\\n            request.timestamp,\\n            requestHash\\n        );\\n    }\\n\\n    /// @notice Add Merchant WFIL Burn Request\\n    /// @dev Access restricted only for Merchant\\n    /// @dev Set txId as empty since it is not known yet.\\n    /// @param amount Amount of WFIL to burn\\n    /// @param custodian Custodian Address\\n    function addBurnRequest(uint256 amount, address custodian) external whenNotPaused {\\n        require(hasRole(MERCHANT_ROLE, msg.sender), \\\"WFILFactory: caller is not a merchant\\\");\\n        require(amount > 0, \\\"WFILFactory: amount is zero\\\");\\n        require(hasRole(CUSTODIAN_ROLE, custodian), \\\"WFILFactory: custodian has not the custodian role\\\");\\n\\n        string memory deposit = merchantDeposit[msg.sender];\\n        require(!_isEmpty(deposit), \\\"WFILFactory: merchant filecoin deposit address was not set\\\");\\n\\n        uint256 nonce = _burnsIdTracker.current();\\n        uint256 timestamp = _timestamp();\\n\\n        string memory txId = \\\"\\\";\\n\\n        burns[nonce].requester = msg.sender;\\n        burns[nonce].custodian = custodian;\\n        burns[nonce].amount = amount;\\n        burns[nonce].deposit = deposit;\\n        burns[nonce].txId = txId;\\n        burns[nonce].nonce = nonce;\\n        burns[nonce].timestamp = timestamp;\\n        burns[nonce].status = RequestStatus.PENDING;\\n\\n        bytes32 requestHash = _hash(burns[nonce]);\\n        burnNonce[requestHash] = nonce;\\n        _burnsIdTracker.increment();\\n\\n        emit Burned(nonce, msg.sender, custodian, amount, deposit, timestamp, requestHash);\\n\\n        require(wfil.unwrapFrom(msg.sender, amount), \\\"WFILFactory: burn failed\\\");\\n    }\\n\\n    /// @notice Confirm Merchant Burn Request\\n    /// @dev Access restricted only for Custodian\\n    /// @param requestHash Hash of the merchant burn request metadata\\n    /// @param txId Transaction Id of the FIL transaction\\n    function confirmBurnRequest(bytes32 requestHash, string calldata txId) external whenNotPaused {\\n        require(hasRole(CUSTODIAN_ROLE, msg.sender), \\\"WFILFactory: caller is not a custodian\\\");\\n        require(!_isEmpty(txId), \\\"WFILFactory: invalid filecoin txId\\\");\\n\\n        (uint256 nonce, Request memory request) = _getPendingBurnRequest(requestHash);\\n\\n        require(msg.sender == request.custodian, \\\"WFILFactory: confirm caller is different than pending request custodian\\\");\\n\\n        burns[nonce].txId = txId;\\n        burns[nonce].status = RequestStatus.APPROVED;\\n        burnNonce[_hash(burns[nonce])] = nonce;\\n\\n        emit BurnConfirmed(\\n            request.nonce,\\n            request.requester,\\n            request.custodian,\\n            request.amount,\\n            request.deposit,\\n            txId,\\n            request.timestamp,\\n            requestHash\\n        );\\n    }\\n\\n    /// @notice Reject Merchant WFIL Burn Request\\n    /// @dev Access restricted only for Custodian\\n    /// @param requestHash Hash of the merchant burn request metadata\\n    function rejectBurnRequest(bytes32 requestHash) external whenNotPaused {\\n        require(hasRole(CUSTODIAN_ROLE, msg.sender), \\\"WFILFactory: caller is not a custodian\\\");\\n\\n        (uint256 nonce, Request memory request) = _getPendingBurnRequest(requestHash);\\n\\n        require(msg.sender == request.custodian, \\\"WFILFactory: reject caller is different than pending request custodian\\\");\\n\\n        burns[nonce].status = RequestStatus.REJECTED;\\n\\n        emit BurnRejected(\\n            request.nonce,\\n            request.requester,\\n            request.custodian,\\n            request.amount,\\n            request.deposit,\\n            request.txId,\\n            request.timestamp,\\n            requestHash\\n        );\\n\\n        require(wfil.wrap(request.requester, request.amount), \\\"WFILFactory: mint failed\\\");\\n    }\\n\\n    /// @notice Mint Request Getter\\n    /// @param nonce Mint Request Nonce\\n    /// @return requestNonce requester amount deposit txId timestamp status requestHash\\n    function getMintRequest(uint256 nonce)\\n        external\\n        view\\n        returns (\\n            uint256 requestNonce,\\n            address requester,\\n            address custodian,\\n            uint256 amount,\\n            string memory deposit,\\n            string memory txId,\\n            uint256 timestamp,\\n            string memory status,\\n            bytes32 requestHash\\n        )\\n    {\\n        require(_mintsIdTracker.current() > nonce, \\\"WFILFactory: invalid mint request nonce\\\");\\n        Request memory request = mints[nonce];\\n        string memory statusString = _getStatusString(request.status);\\n\\n        requestNonce = request.nonce;\\n        requester = request.requester;\\n        custodian = request.custodian;\\n        amount = request.amount;\\n        deposit = request.deposit;\\n        txId = request.txId;\\n        timestamp = request.timestamp;\\n        status = statusString;\\n        requestHash = _hash(request);\\n    }\\n\\n    /// @notice Mint Request Count Getter\\n    /// @return count Current number of mint requests\\n    function getMintRequestsCount() external view returns (uint256 count) {\\n        return _mintsIdTracker.current();\\n    }\\n\\n    /// @notice Burn Request Getter\\n    /// @param nonce Burn Request Nonce\\n    /// @return requestNonce requester amount deposit txId timestamp status requestHash\\n    function getBurnRequest(uint256 nonce)\\n        external\\n        view\\n        returns (\\n            uint256 requestNonce,\\n            address requester,\\n            address custodian,\\n            uint256 amount,\\n            string memory deposit,\\n            string memory txId,\\n            uint256 timestamp,\\n            string memory status,\\n            bytes32 requestHash\\n        )\\n    {\\n        require(_burnsIdTracker.current() > nonce, \\\"WFILFactory: invalid burn request nonce\\\");\\n        Request memory request = burns[nonce];\\n        string memory statusString = _getStatusString(request.status);\\n\\n        requestNonce = request.nonce;\\n        requester = request.requester;\\n        custodian = request.custodian;\\n        amount = request.amount;\\n        deposit = request.deposit;\\n        txId = request.txId;\\n        timestamp = request.timestamp;\\n        status = statusString;\\n        requestHash = _hash(request);\\n    }\\n\\n    /// @notice Burn Request Count Getter\\n    /// @return count Current number of burn requests\\n    function getBurnRequestsCount() external view returns (uint256 count) {\\n        return _burnsIdTracker.current();\\n    }\\n\\n\\n    /// @notice Reclaim all ERC20 compatible tokens\\n    /// @dev Access restricted only for Default Admin\\n    /// @dev `recipient` cannot be the zero address\\n    /// @param token IERC20 address of the token contract\\n    /// @param recipient Recipient address\\n    function reclaimToken(IERC20 token, address recipient) external {\\n        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \\\"WFILFactory: caller is not the default admin\\\");\\n        require(recipient != address(0), \\\"WFILFactory: recipient is the zero address\\\");\\n        uint256 balance = token.balanceOf(address(this));\\n        token.safeTransfer(recipient, balance);\\n        emit TokenClaimed(token, recipient, balance);\\n    }\\n\\n\\n    /// @notice Add a new Custodian\\n    /// @dev Access restricted only for Default Admin\\n    /// @param account Address of the new Custodian\\n    /// @return True if account is added as Custodian\\n    function addCustodian(address account) external returns (bool) {\\n        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \\\"WFILFactory: caller is not the default admin\\\");\\n        require(account != address(0), \\\"WFILFactory: account is the zero address\\\");\\n        require(!hasRole(CUSTODIAN_ROLE, account), \\\"WFILFactory: account is already a custodian\\\");\\n        grantRole(CUSTODIAN_ROLE, account);\\n        return true;\\n    }\\n\\n    /// @notice Remove a Custodian\\n    /// @dev Access restricted only for Default Admin\\n    /// @param account Address of the Custodian\\n    /// @return True if account is removed as Custodian\\n    function removeCustodian(address account) external returns (bool) {\\n        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \\\"WFILFactory: caller is not the default admin\\\");\\n        require(hasRole(CUSTODIAN_ROLE, account), \\\"WFILFactory: account is not a custodian\\\");\\n        revokeRole(CUSTODIAN_ROLE, account);\\n        return true;\\n    }\\n\\n    /// @notice Add a new Merchant\\n    /// @dev Access restricted only for Default Admin\\n    /// @param account Address of the new Merchant\\n    /// @return True if account is added as Merchant\\n    function addMerchant(address account) external returns (bool) {\\n        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \\\"WFILFactory: caller is not the default admin\\\");\\n        require(account != address(0), \\\"WFILFactory: account is the zero address\\\");\\n        require(!hasRole(MERCHANT_ROLE, account), \\\"WFILFactory: account is already a merchant\\\");\\n        grantRole(MERCHANT_ROLE, account);\\n        return true;\\n    }\\n\\n    /// @notice Remove a Merchant\\n    /// @dev Access restricted only for Default Admin\\n    /// @param account Address of the Merchant\\n    /// @return True if account is removed as Merchant\\n    function removeMerchant(address account) external returns (bool) {\\n        require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), \\\"WFILFactory: caller is not the default admin\\\");\\n        require(hasRole(MERCHANT_ROLE, account), \\\"WFILFactory: account is not a merchant\\\");\\n        revokeRole(MERCHANT_ROLE, account);\\n        return true;\\n    }\\n\\n    /// @notice Pause all the functions\\n    /// @dev the caller must have the 'PAUSER_ROLE'\\n    function pause() external {\\n        require(hasRole(PAUSER_ROLE, msg.sender), \\\"WFILFactory: must have pauser role to pause\\\");\\n        _pause();\\n    }\\n\\n    /// @notice Unpause all the functions\\n    /// @dev the caller must have the 'PAUSER_ROLE'\\n    function unpause() external {\\n        require(hasRole(PAUSER_ROLE, msg.sender), \\\"WFILFactory: must have pauser role to unpause\\\");\\n        _unpause();\\n    }\\n\\n    /// @notice Compare Strings\\n    /// @dev compare the hash of two strings\\n    /// @param a String A\\n    /// @param b String B\\n    /// @return True if the strings matches\\n    function _compareStrings(string memory a, string memory b) internal pure returns (bool) {\\n        return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b));\\n    }\\n\\n    /// @notice Check for Empty String\\n    /// @dev compare a string with \\\"\\\"\\n    /// @param a String A\\n    /// @return True if the string is empty\\n    function _isEmpty(string memory a) internal pure returns (bool) {\\n       return bytes(a).length == 0;\\n    }\\n\\n    /// @notice Return Current Block Timestamp\\n    /// @dev block.timestamp is only used for data maintaining purpose, it is not relied on for critical logic\\n    function _timestamp() internal view returns (uint256) {\\n      return block.timestamp;\\n    }\\n\\n    /// @notice Hash the Request Metadata\\n    /// @param request Request\\n    /// @return hash Hash of the request metadata\\n    function _hash(Request memory request) internal pure returns (bytes32 hash) {\\n        return keccak256(abi.encode(\\n            request.requester,\\n            request.custodian,\\n            request.amount,\\n            request.deposit,\\n            request.txId,\\n            request.nonce,\\n            request.timestamp\\n        ));\\n    }\\n\\n    /// @notice Get Pending Mint Requests\\n    /// @param requestHash Hash of the merchant mint request metadata\\n    /// @return nonce request\\n    function _getPendingMintRequest(bytes32 requestHash) internal view returns (uint256 nonce, Request memory request) {\\n        require(requestHash != 0, \\\"WFILFactory: request hash is 0\\\");\\n        nonce = mintNonce[requestHash];\\n        request = mints[nonce];\\n        _check(request, requestHash);\\n    }\\n\\n    /// @notice Get Pending Burn Requests\\n    /// @param requestHash Hash of the merchant burn request metadata\\n    /// @return nonce request\\n    function _getPendingBurnRequest(bytes32 requestHash) internal view returns (uint256 nonce, Request memory request) {\\n        require(requestHash != 0, \\\"WFILFactory: request hash is 0\\\");\\n            nonce = burnNonce[requestHash];\\n            request = burns[nonce];\\n            _check(request, requestHash);\\n    }\\n\\n    /// @notice Validate Pending Mint/Burn Requests\\n    /// @dev Revert on not valid requests\\n    /// @dev Hook used in _getPendingMintRequest and _getPendingBurnRequest\\n    /// @param request Request\\n    /// @param requestHash Hash of the merchant mint/burn request metadata\\n    function _check(Request memory request, bytes32 requestHash) internal pure {\\n        require(request.status == RequestStatus.PENDING, \\\"WFILFactory: request is not pending\\\");\\n        require(requestHash == _hash(request), \\\"WFILFactory: given request hash does not match a pending request\\\");\\n    }\\n\\n    /// @notice Return Request Status String\\n    /// @dev decode enum into string\\n    /// @param status Request Status\\n    /// @return request status string\\n    function _getStatusString(RequestStatus status) internal pure returns (string memory) {\\n        if (status == RequestStatus.PENDING) return \\\"pending\\\";\\n        else if (status == RequestStatus.CANCELED) return \\\"canceled\\\";\\n        else if (status == RequestStatus.APPROVED) return \\\"approved\\\";\\n        else if (status == RequestStatus.REJECTED) return \\\"rejected\\\";\\n        else revert(\\\"WFILFactory: unknown status\\\");\\n    }\\n}\\n\"},\"@openzeppelin/contracts/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n    function _msgSender() internal view virtual returns (address payable) {\\n        return msg.sender;\\n    }\\n\\n    function _msgData() internal view virtual returns (bytes memory) {\\n        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n        return msg.data;\\n    }\\n}\\n\"},\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../utils/EnumerableSet.sol\\\";\\nimport \\\"../utils/Address.sol\\\";\\nimport \\\"../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```\\n * function foo() public {\\n *     require(hasRole(MY_ROLE, msg.sender));\\n *     ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it.\\n */\\nabstract contract AccessControl is Context {\\n    using EnumerableSet for EnumerableSet.AddressSet;\\n    using Address for address;\\n\\n    struct RoleData {\\n        EnumerableSet.AddressSet members;\\n        bytes32 adminRole;\\n    }\\n\\n    mapping (bytes32 => RoleData) private _roles;\\n\\n    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n    /**\\n     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n     *\\n     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n     * {RoleAdminChanged} not being emitted signaling this.\\n     *\\n     * _Available since v3.1._\\n     */\\n    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n    /**\\n     * @dev Emitted when `account` is granted `role`.\\n     *\\n     * `sender` is the account that originated the contract call, an admin role\\n     * bearer except when using {_setupRole}.\\n     */\\n    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n    /**\\n     * @dev Emitted when `account` is revoked `role`.\\n     *\\n     * `sender` is the account that originated the contract call:\\n     *   - if using `revokeRole`, it is the admin role bearer\\n     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n     */\\n    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n    /**\\n     * @dev Returns `true` if `account` has been granted `role`.\\n     */\\n    function hasRole(bytes32 role, address account) public view returns (bool) {\\n        return _roles[role].members.contains(account);\\n    }\\n\\n    /**\\n     * @dev Returns the number of accounts that have `role`. Can be used\\n     * together with {getRoleMember} to enumerate all bearers of a role.\\n     */\\n    function getRoleMemberCount(bytes32 role) public view returns (uint256) {\\n        return _roles[role].members.length();\\n    }\\n\\n    /**\\n     * @dev Returns one of the accounts that have `role`. `index` must be a\\n     * value between 0 and {getRoleMemberCount}, non-inclusive.\\n     *\\n     * Role bearers are not sorted in any particular way, and their ordering may\\n     * change at any point.\\n     *\\n     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n     * you perform all queries on the same block. See the following\\n     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n     * for more information.\\n     */\\n    function getRoleMember(bytes32 role, uint256 index) public view returns (address) {\\n        return _roles[role].members.at(index);\\n    }\\n\\n    /**\\n     * @dev Returns the admin role that controls `role`. See {grantRole} and\\n     * {revokeRole}.\\n     *\\n     * To change a role's admin, use {_setRoleAdmin}.\\n     */\\n    function getRoleAdmin(bytes32 role) public view returns (bytes32) {\\n        return _roles[role].adminRole;\\n    }\\n\\n    /**\\n     * @dev Grants `role` to `account`.\\n     *\\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\\n     * event.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must have ``role``'s admin role.\\n     */\\n    function grantRole(bytes32 role, address account) public virtual {\\n        require(hasRole(_roles[role].adminRole, _msgSender()), \\\"AccessControl: sender must be an admin to grant\\\");\\n\\n        _grantRole(role, account);\\n    }\\n\\n    /**\\n     * @dev Revokes `role` from `account`.\\n     *\\n     * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must have ``role``'s admin role.\\n     */\\n    function revokeRole(bytes32 role, address account) public virtual {\\n        require(hasRole(_roles[role].adminRole, _msgSender()), \\\"AccessControl: sender must be an admin to revoke\\\");\\n\\n        _revokeRole(role, account);\\n    }\\n\\n    /**\\n     * @dev Revokes `role` from the calling account.\\n     *\\n     * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n     * purpose is to provide a mechanism for accounts to lose their privileges\\n     * if they are compromised (such as when a trusted device is misplaced).\\n     *\\n     * If the calling account had been granted `role`, emits a {RoleRevoked}\\n     * event.\\n     *\\n     * Requirements:\\n     *\\n     * - the caller must be `account`.\\n     */\\n    function renounceRole(bytes32 role, address account) public virtual {\\n        require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n        _revokeRole(role, account);\\n    }\\n\\n    /**\\n     * @dev Grants `role` to `account`.\\n     *\\n     * If `account` had not been already granted `role`, emits a {RoleGranted}\\n     * event. Note that unlike {grantRole}, this function doesn't perform any\\n     * checks on the calling account.\\n     *\\n     * [WARNING]\\n     * ====\\n     * This function should only be called from the constructor when setting\\n     * up the initial roles for the system.\\n     *\\n     * Using this function in any other way is effectively circumventing the admin\\n     * system imposed by {AccessControl}.\\n     * ====\\n     */\\n    function _setupRole(bytes32 role, address account) internal virtual {\\n        _grantRole(role, account);\\n    }\\n\\n    /**\\n     * @dev Sets `adminRole` as ``role``'s admin role.\\n     *\\n     * Emits a {RoleAdminChanged} event.\\n     */\\n    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n        emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);\\n        _roles[role].adminRole = adminRole;\\n    }\\n\\n    function _grantRole(bytes32 role, address account) private {\\n        if (_roles[role].members.add(account)) {\\n            emit RoleGranted(role, account, _msgSender());\\n        }\\n    }\\n\\n    function _revokeRole(bytes32 role, address account) private {\\n        if (_roles[role].members.remove(account)) {\\n            emit RoleRevoked(role, account, _msgSender());\\n        }\\n    }\\n}\\n\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n    /**\\n     * @dev Returns the addition of two unsigned integers, reverting on\\n     * overflow.\\n     *\\n     * Counterpart to Solidity's `+` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - Addition cannot overflow.\\n     */\\n    function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n        uint256 c = a + b;\\n        require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n        return c;\\n    }\\n\\n    /**\\n     * @dev Returns the subtraction of two unsigned integers, reverting on\\n     * overflow (when the result is negative).\\n     *\\n     * Counterpart to Solidity's `-` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - Subtraction cannot overflow.\\n     */\\n    function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n     * overflow (when the result is negative).\\n     *\\n     * Counterpart to Solidity's `-` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - Subtraction cannot overflow.\\n     */\\n    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n        require(b <= a, errorMessage);\\n        uint256 c = a - b;\\n\\n        return c;\\n    }\\n\\n    /**\\n     * @dev Returns the multiplication of two unsigned integers, reverting on\\n     * overflow.\\n     *\\n     * Counterpart to Solidity's `*` operator.\\n     *\\n     * Requirements:\\n     *\\n     * - Multiplication cannot overflow.\\n     */\\n    function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n        // benefit is lost if 'b' is also tested.\\n        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n        if (a == 0) {\\n            return 0;\\n        }\\n\\n        uint256 c = a * b;\\n        require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n        return c;\\n    }\\n\\n    /**\\n     * @dev Returns the integer division of two unsigned integers. Reverts on\\n     * division by zero. The result is rounded towards zero.\\n     *\\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n     * uses an invalid opcode to revert (consuming all remaining gas).\\n     *\\n     * Requirements:\\n     *\\n     * - The divisor cannot be zero.\\n     */\\n    function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return div(a, b, \\\"SafeMath: division by zero\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n     * division by zero. The result is rounded towards zero.\\n     *\\n     * Counterpart to Solidity's `/` operator. Note: this function uses a\\n     * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n     * uses an invalid opcode to revert (consuming all remaining gas).\\n     *\\n     * Requirements:\\n     *\\n     * - The divisor cannot be zero.\\n     */\\n    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n        require(b > 0, errorMessage);\\n        uint256 c = a / b;\\n        // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n        return c;\\n    }\\n\\n    /**\\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n     * Reverts when dividing by zero.\\n     *\\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\\n     * invalid opcode to revert (consuming all remaining gas).\\n     *\\n     * Requirements:\\n     *\\n     * - The divisor cannot be zero.\\n     */\\n    function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n        return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n    }\\n\\n    /**\\n     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n     * Reverts with custom message when dividing by zero.\\n     *\\n     * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n     * opcode (which leaves remaining gas untouched) while Solidity uses an\\n     * invalid opcode to revert (consuming all remaining gas).\\n     *\\n     * Requirements:\\n     *\\n     * - The divisor cannot be zero.\\n     */\\n    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n        require(b != 0, errorMessage);\\n        return a % b;\\n    }\\n}\\n\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n    /**\\n     * @dev Returns the amount of tokens in existence.\\n     */\\n    function totalSupply() external view returns (uint256);\\n\\n    /**\\n     * @dev Returns the amount of tokens owned by `account`.\\n     */\\n    function balanceOf(address account) external view returns (uint256);\\n\\n    /**\\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Returns the remaining number of tokens that `spender` will be\\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n     * zero by default.\\n     *\\n     * This value changes when {approve} or {transferFrom} are called.\\n     */\\n    function allowance(address owner, address spender) external view returns (uint256);\\n\\n    /**\\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n     * that someone may use both the old and the new allowance by unfortunate\\n     * transaction ordering. One possible solution to mitigate this race\\n     * condition is to first reduce the spender's allowance to 0 and set the\\n     * desired value afterwards:\\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n     *\\n     * Emits an {Approval} event.\\n     */\\n    function approve(address spender, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n     * allowance mechanism. `amount` is then deducted from the caller's\\n     * allowance.\\n     *\\n     * Returns a boolean value indicating whether the operation succeeded.\\n     *\\n     * Emits a {Transfer} event.\\n     */\\n    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n    /**\\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n     * another (`to`).\\n     *\\n     * Note that `value` may be zero.\\n     */\\n    event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n    /**\\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n     * a call to {approve}. `value` is the new allowance.\\n     */\\n    event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n    using SafeMath for uint256;\\n    using Address for address;\\n\\n    function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n    }\\n\\n    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n    }\\n\\n    /**\\n     * @dev Deprecated. This function has issues similar to the ones found in\\n     * {IERC20-approve}, and its usage is discouraged.\\n     *\\n     * Whenever possible, use {safeIncreaseAllowance} and\\n     * {safeDecreaseAllowance} instead.\\n     */\\n    function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n        // safeApprove should only be called when setting an initial allowance,\\n        // or when resetting it to zero. To increase and decrease it, use\\n        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n        // solhint-disable-next-line max-line-length\\n        require((value == 0) || (token.allowance(address(this), spender) == 0),\\n            \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n        );\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n    }\\n\\n    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n        uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n    }\\n\\n    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n        uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n    }\\n\\n    /**\\n     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n     * on the return value: the return value is optional (but if data is returned, it must not be false).\\n     * @param token The token targeted by the call.\\n     * @param data The call data (encoded using abi.encode or one of its variants).\\n     */\\n    function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n        // the target address contains contract code and also asserts for success in the low-level call.\\n\\n        bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n        if (returndata.length > 0) { // Return data is optional\\n            // solhint-disable-next-line max-line-length\\n            require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n        }\\n    }\\n}\\n\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.2 <0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n    /**\\n     * @dev Returns true if `account` is a contract.\\n     *\\n     * [IMPORTANT]\\n     * ====\\n     * It is unsafe to assume that an address for which this function returns\\n     * false is an externally-owned account (EOA) and not a contract.\\n     *\\n     * Among others, `isContract` will return false for the following\\n     * types of addresses:\\n     *\\n     *  - an externally-owned account\\n     *  - a contract in construction\\n     *  - an address where a contract will be created\\n     *  - an address where a contract lived, but was destroyed\\n     * ====\\n     */\\n    function isContract(address account) internal view returns (bool) {\\n        // This method relies on extcodesize, which returns 0 for contracts in\\n        // construction, since the code is only stored at the end of the\\n        // constructor execution.\\n\\n        uint256 size;\\n        // solhint-disable-next-line no-inline-assembly\\n        assembly { size := extcodesize(account) }\\n        return size > 0;\\n    }\\n\\n    /**\\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n     * `recipient`, forwarding all available gas and reverting on errors.\\n     *\\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n     * imposed by `transfer`, making them unable to receive funds via\\n     * `transfer`. {sendValue} removes this limitation.\\n     *\\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n     *\\n     * IMPORTANT: because control is transferred to `recipient`, care must be\\n     * taken to not create reentrancy vulnerabilities. Consider using\\n     * {ReentrancyGuard} or the\\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n     */\\n    function sendValue(address payable recipient, uint256 amount) internal {\\n        require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n        (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n        require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n    }\\n\\n    /**\\n     * @dev Performs a Solidity function call using a low level `call`. A\\n     * plain`call` is an unsafe replacement for a function call: use this\\n     * function instead.\\n     *\\n     * If `target` reverts with a revert reason, it is bubbled up by this\\n     * function (like regular Solidity function calls).\\n     *\\n     * Returns the raw returned data. To convert to the expected return value,\\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n     *\\n     * Requirements:\\n     *\\n     * - `target` must be a contract.\\n     * - calling `target` with `data` must not revert.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n      return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n     * `errorMessage` as a fallback revert reason when `target` reverts.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, 0, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but also transferring `value` wei to `target`.\\n     *\\n     * Requirements:\\n     *\\n     * - the calling contract must have an ETH balance of at least `value`.\\n     * - the called Solidity function must be `payable`.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n        return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\\n     *\\n     * _Available since v3.1._\\n     */\\n    function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n        require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n        require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n        // solhint-disable-next-line avoid-low-level-calls\\n        (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n        return _verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n        return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n    }\\n\\n    /**\\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n     * but performing a static call.\\n     *\\n     * _Available since v3.3._\\n     */\\n    function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n        require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n        // solhint-disable-next-line avoid-low-level-calls\\n        (bool success, bytes memory returndata) = target.staticcall(data);\\n        return _verifyCallResult(success, returndata, errorMessage);\\n    }\\n\\n    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n        if (success) {\\n            return returndata;\\n        } else {\\n            // Look for revert reason and bubble it up if present\\n            if (returndata.length > 0) {\\n                // The easiest way to bubble the revert reason is using memory via assembly\\n\\n                // solhint-disable-next-line no-inline-assembly\\n                assembly {\\n                    let returndata_size := mload(returndata)\\n                    revert(add(32, returndata), returndata_size)\\n                }\\n            } else {\\n                revert(errorMessage);\\n            }\\n        }\\n    }\\n}\\n\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../math/SafeMath.sol\\\";\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}\\n * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never\\n * directly accessed.\\n */\\nlibrary Counters {\\n    using SafeMath for uint256;\\n\\n    struct Counter {\\n        // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n        // this feature: see https://github.com/ethereum/solidity/issues/4637\\n        uint256 _value; // default: 0\\n    }\\n\\n    function current(Counter storage counter) internal view returns (uint256) {\\n        return counter._value;\\n    }\\n\\n    function increment(Counter storage counter) internal {\\n        // The {SafeMath} overflow check can be skipped here, see the comment at the top\\n        counter._value += 1;\\n    }\\n\\n    function decrement(Counter storage counter) internal {\\n        counter._value = counter._value.sub(1);\\n    }\\n}\\n\"},\"@openzeppelin/contracts/utils/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n *     // Add the library methods\\n *     using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n *     // Declare a set state variable\\n *     EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n    // To implement this library for multiple types with as little code\\n    // repetition as possible, we write it in terms of a generic Set type with\\n    // bytes32 values.\\n    // The Set implementation uses private functions, and user-facing\\n    // implementations (such as AddressSet) are just wrappers around the\\n    // underlying Set.\\n    // This means that we can only create new EnumerableSets for types that fit\\n    // in bytes32.\\n\\n    struct Set {\\n        // Storage of set values\\n        bytes32[] _values;\\n\\n        // Position of the value in the `values` array, plus 1 because index 0\\n        // means a value is not in the set.\\n        mapping (bytes32 => uint256) _indexes;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function _add(Set storage set, bytes32 value) private returns (bool) {\\n        if (!_contains(set, value)) {\\n            set._values.push(value);\\n            // The value is stored at length-1, but we add 1 to all indexes\\n            // and use 0 as a sentinel value\\n            set._indexes[value] = set._values.length;\\n            return true;\\n        } else {\\n            return false;\\n        }\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function _remove(Set storage set, bytes32 value) private returns (bool) {\\n        // We read and store the value's index to prevent multiple reads from the same storage slot\\n        uint256 valueIndex = set._indexes[value];\\n\\n        if (valueIndex != 0) { // Equivalent to contains(set, value)\\n            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n            // the array, and then remove the last element (sometimes called as 'swap and pop').\\n            // This modifies the order of the array, as noted in {at}.\\n\\n            uint256 toDeleteIndex = valueIndex - 1;\\n            uint256 lastIndex = set._values.length - 1;\\n\\n            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs\\n            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.\\n\\n            bytes32 lastvalue = set._values[lastIndex];\\n\\n            // Move the last value to the index where the value to delete is\\n            set._values[toDeleteIndex] = lastvalue;\\n            // Update the index for the moved value\\n            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based\\n\\n            // Delete the slot where the moved value was stored\\n            set._values.pop();\\n\\n            // Delete the index for the deleted slot\\n            delete set._indexes[value];\\n\\n            return true;\\n        } else {\\n            return false;\\n        }\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n        return set._indexes[value] != 0;\\n    }\\n\\n    /**\\n     * @dev Returns the number of values on the set. O(1).\\n     */\\n    function _length(Set storage set) private view returns (uint256) {\\n        return set._values.length;\\n    }\\n\\n   /**\\n    * @dev Returns the value stored at position `index` in the set. O(1).\\n    *\\n    * Note that there are no guarantees on the ordering of values inside the\\n    * array, and it may change when more values are added or removed.\\n    *\\n    * Requirements:\\n    *\\n    * - `index` must be strictly less than {length}.\\n    */\\n    function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n        require(set._values.length > index, \\\"EnumerableSet: index out of bounds\\\");\\n        return set._values[index];\\n    }\\n\\n    // Bytes32Set\\n\\n    struct Bytes32Set {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n        return _add(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n        return _remove(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n        return _contains(set._inner, value);\\n    }\\n\\n    /**\\n     * @dev Returns the number of values in the set. O(1).\\n     */\\n    function length(Bytes32Set storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n   /**\\n    * @dev Returns the value stored at position `index` in the set. O(1).\\n    *\\n    * Note that there are no guarantees on the ordering of values inside the\\n    * array, and it may change when more values are added or removed.\\n    *\\n    * Requirements:\\n    *\\n    * - `index` must be strictly less than {length}.\\n    */\\n    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n        return _at(set._inner, index);\\n    }\\n\\n    // AddressSet\\n\\n    struct AddressSet {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(AddressSet storage set, address value) internal returns (bool) {\\n        return _add(set._inner, bytes32(uint256(value)));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(AddressSet storage set, address value) internal returns (bool) {\\n        return _remove(set._inner, bytes32(uint256(value)));\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(AddressSet storage set, address value) internal view returns (bool) {\\n        return _contains(set._inner, bytes32(uint256(value)));\\n    }\\n\\n    /**\\n     * @dev Returns the number of values in the set. O(1).\\n     */\\n    function length(AddressSet storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n   /**\\n    * @dev Returns the value stored at position `index` in the set. O(1).\\n    *\\n    * Note that there are no guarantees on the ordering of values inside the\\n    * array, and it may change when more values are added or removed.\\n    *\\n    * Requirements:\\n    *\\n    * - `index` must be strictly less than {length}.\\n    */\\n    function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n        return address(uint256(_at(set._inner, index)));\\n    }\\n\\n\\n    // UintSet\\n\\n    struct UintSet {\\n        Set _inner;\\n    }\\n\\n    /**\\n     * @dev Add a value to a set. O(1).\\n     *\\n     * Returns true if the value was added to the set, that is if it was not\\n     * already present.\\n     */\\n    function add(UintSet storage set, uint256 value) internal returns (bool) {\\n        return _add(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Removes a value from a set. O(1).\\n     *\\n     * Returns true if the value was removed from the set, that is if it was\\n     * present.\\n     */\\n    function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n        return _remove(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Returns true if the value is in the set. O(1).\\n     */\\n    function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n        return _contains(set._inner, bytes32(value));\\n    }\\n\\n    /**\\n     * @dev Returns the number of values on the set. O(1).\\n     */\\n    function length(UintSet storage set) internal view returns (uint256) {\\n        return _length(set._inner);\\n    }\\n\\n   /**\\n    * @dev Returns the value stored at position `index` in the set. O(1).\\n    *\\n    * Note that there are no guarantees on the ordering of values inside the\\n    * array, and it may change when more values are added or removed.\\n    *\\n    * Requirements:\\n    *\\n    * - `index` must be strictly less than {length}.\\n    */\\n    function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n        return uint256(_at(set._inner, index));\\n    }\\n}\\n\"},\"@openzeppelin/contracts/utils/Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract Pausable is Context {\\n    /**\\n     * @dev Emitted when the pause is triggered by `account`.\\n     */\\n    event Paused(address account);\\n\\n    /**\\n     * @dev Emitted when the pause is lifted by `account`.\\n     */\\n    event Unpaused(address account);\\n\\n    bool private _paused;\\n\\n    /**\\n     * @dev Initializes the contract in unpaused state.\\n     */\\n    constructor () internal {\\n        _paused = false;\\n    }\\n\\n    /**\\n     * @dev Returns true if the contract is paused, and false otherwise.\\n     */\\n    function paused() public view returns (bool) {\\n        return _paused;\\n    }\\n\\n    /**\\n     * @dev Modifier to make a function callable only when the contract is not paused.\\n     *\\n     * Requirements:\\n     *\\n     * - The contract must not be paused.\\n     */\\n    modifier whenNotPaused() {\\n        require(!_paused, \\\"Pausable: paused\\\");\\n        _;\\n    }\\n\\n    /**\\n     * @dev Modifier to make a function callable only when the contract is paused.\\n     *\\n     * Requirements:\\n     *\\n     * - The contract must be paused.\\n     */\\n    modifier whenPaused() {\\n        require(_paused, \\\"Pausable: not paused\\\");\\n        _;\\n    }\\n\\n    /**\\n     * @dev Triggers stopped state.\\n     *\\n     * Requirements:\\n     *\\n     * - The contract must not be paused.\\n     */\\n    function _pause() internal virtual whenNotPaused {\\n        _paused = true;\\n        emit Paused(_msgSender());\\n    }\\n\\n    /**\\n     * @dev Returns to normal state.\\n     *\\n     * Requirements:\\n     *\\n     * - The contract must be paused.\\n     */\\n    function _unpause() internal virtual whenPaused {\\n        _paused = false;\\n        emit Unpaused(_msgSender());\\n    }\\n}\\n\"}},\"settings\":{\"remappings\":[],\"optimizer\":{\"enabled\":true,\"runs\":200},\"evmVersion\":\"byzantium\",\"libraries\":{\"\":{}}}}",
  "codeformat": "solidity-standard-json-input",
  "contractname": "/home/hackfs/wfil-factory/contracts/WFILFactory.sol:WFILFactory",
  "compilerversion": "v0.6.12+commit.27d51765",
  "constructorArguements": "000000000000000000000000a04bbe85d91c3125d577af17e4eb5d4e579100cf0000000000000000000000003bbca3216dbafdfa61b3bbaacb9c6febe4c45f2f"
}
Checking status of verification request nj6vgmv93yerhwqslvqdpc9jqp8h8e69dniarnw5a9jxltiki4
Fail - Unable to verify
Failed to verify 1 contract(s): WFILFactory

The contract is compiled with optimizer enabled:

  compilers: {
    solc: {
       version: "0.6.12",    // Fetch exact version from solc-bin (default: truffle's version)
      // docker: true,        // Use "0.5.1" you've installed locally with docker (default: false)
        settings: {          // See the solidity docs for advice about optimization and evmVersion
          optimizer: {
          enabled: true,
          runs: 200
        },
        evmVersion: "byzantium"
       }
    },
  },

source code: https://github.com/wfil/wfil-factory/blob/main/contracts/WFILFactory.sol
Truffle v5.1.58 (core: 5.1.58)
Solidity - 0.6.12 (solc-js)
Node v12.19.0
Web3.js v1.2.9

The reason Failed to connect to Etherscan API at url https://api-rinkeby.etherscan.io/api

The reason is probably because ethersan.io is blocked in china mainland.

I use my own computer (in China) to call truffle verify, the system prompts: failed to connect to Etherscan API at URL https://api-rinkeby.etherscan.io/api

And then, The same code, I use the U.S. cloud server, success verified.

In china mianland, the access status as follows:
https://etherscan.io/ (404)
https://cn.etherscan.com/ (Can access)
https://rinkeby.etherscan.io/ (404)
https://kovan.etherscan.io/ (404)

The following things are strange:

1、https://api-rinkeby.etherscan.io/api?apiKey=CVXXXXXXXXXXXXXXXXXXXXXX3Y&module=account&action=txlist&address=0xb546dda73132E82Edfdb6598C31b3188585b5722&page=1&sort=asc&offset=1

this link can access in china mainland, the "status":"1","message":"OK", but truffle verify failed, maybe the verify code not only access this link.

2、After using VPN, the chinese coder can access all the ethercan link, but the truffle verify still failed.

The above is my experience.

Invalid API Key

Every time I try to verify I get "Invalid API Key" it worked 1 time, 2nd time it fails every time.

cd-bank truffle run verify CDRW --network goerli
> Warning: possible unsupported (undocumented in help) command line option: --network
Verifying CDRW
Invalid API Key

Failed to verify 1 contract(s): CDRW


Verifying contracts with structs in external file

Hi there!

I'm facing the issue with source code verification in case when structs are placed in a separate file (it is allowed since 0.6.0 version of Solidity compiler) and then imported where needed. In debug mode, I found out that imported structs are not added in the flattened source code. Thus, the code cannot be compiled on Etherscan side.

Support EVM version target

Truffle allows you to specify an EVM version in the compiler settings. Etherscan allows you to specify this EVM version as well in the verify wizard on their website. However, there's no option for this in the Etherscan verify API, making it impossible for truffle-plugin-verify to support these EVM version targets.

If this is added to the Etherscan API support can be added to the plugin.

No support for emojis in the comments 😿

General exception occured when attempting to insert record
Failed to verify 1 contract(s): Assurance

Running with --debug

Noticed emoji in the comments.

Removed emoji.

Now works.

Verifying stuck

I'm having a problem for the last two days (at least) that when I run verifying it just stuck. So it says

Verifying Name_of_contract

and it stays like that for at least one hour (I stopped after that). I have connection to the internet and my API key is valid (even tried changing it to the new one)

Include file comments in verified contracts

Feature Request

Include the comments on the file level for the flattened files. The flattened/verified file would ideally contain all file level comments.

Comment example

/**
 * @notice This is the notice
 * @dev Dev comments
 */
contract MyContract {

Doesn't work in yarn workspaces

Yarn workspaces is this new way of intelligently managing your npm modules in a monorepo by installing them only once (or multiple times if there are overlapping versions). What it does is that it aggregates all the modules at the root of your project.

If I install truffle-plugin-verify in the "contracts" package of this monorepo and I try to run it, I get the following error:

Error: truffle-plugin-verify listed as a plugin, but not found in global or local node modules!

Of course, I moved on and installed the module globally, but I can't use this plugin on CI.

Support Vyper verification

when I try to verity vyper contract I get the error:

Unexpected token u in JSON at position 0
Failed to verify 1 contract(s)

Ipfs connect fail when verify contracts

Query:
truffle plugin run verify contract-name --network ropsten [--debug]

Output:

> Warning: possible unsupported (undocumented in help) command line option: --network
Finding publishable artifacts...
Uploading sources and publishing to registry...
Error: [ipfs-mini] status 0: Error: connect ETIMEDOUT 67.228.102.32:5001
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1107:14)
    at exports.XMLHttpRequest.request.onreadystatechange (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/ipfs-mini/src/index.js:63:1)
    at exports.XMLHttpRequest.dispatchEvent (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:591:1)
    at setState (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:610:1)
    at exports.XMLHttpRequest.handleError (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:532:1)
    at ClientRequest.errorHandler (/usr/local/lib/node_modules/truffle/build/webpack:/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:459:1)
    at ClientRequest.emit (events.js:198:13)
    at TLSSocket.socketErrorListener (_http_client.js:392:9)
    at TLSSocket.emit (events.js:198:13)
    at emitErrorNT (internal/streams/destroy.js:91:8)
    at emitErrorAndCloseNT (internal/streams/destroy.js:59:3)
    at process._tickCallback (internal/process/next_tick.js:63:19)
Truffle v5.1.5 (core: 5.1.5)
Node v10.18.0

In order to identify whether my local network problem,i test the ip by http://port.ping.pe, unfortunately all of them connect fail

31.13.72.34:5001        
66.220.151.20:5001       
67.228.74.123:5001  
67.228.102.32:5001     
67.228.235.93:5001       
67.228.235.91:5001       
69.171.227.37:5001       
75.126.115.192:5001      
208.43.237.140:5001      
199.59.150.49:5001 

Cannot verify complex contract infrastructure

Hi,

I am trying to verify contracts from this repo https://github.com/swarmfund/swarm-compliant-contract.

But my contracts cannot get verified.

Here are the migration scripts.

1_deploy_src20registry.js


require('dotenv').config({path: '../.env'});
const Registry = artifacts.require("SRC20Registry");
const MockToken = artifacts.require("SwarmTokenMock");

const {
  ERC20_SWM,
  DEVELOPMENT_SWM_TOKEN_OWNER,
  DEVELOPMENT_SWM_TOTAL_SUPPLY
} = process.env;

module.exports = function (deployer, network) {
  if (!network.includes('mainnet')) {
    return deployer.deploy(MockToken,
      DEVELOPMENT_SWM_TOKEN_OWNER,
      DEVELOPMENT_SWM_TOTAL_SUPPLY
    ).then(async function (token) {
      return deployer.deploy(Registry,
        token.address
      );
    });
  } else {
    deployer.deploy(Registry,
      ERC20_SWM
    );
  }
};

2_deploy_factory.js

const Factory = artifacts.require("SRC20Factory");
const Registry = artifacts.require("SRC20Registry");

module.exports = function (deployer) {
  deployer.then(function () {
    return Registry.deployed().then(registry => {
      return deployer.deploy(Factory,
        registry.address
      ).then(async factory => {
        await registry.addFactory(factory.address);
      });
    });
  });
};

Here is truffle-config.js

/**
 * Use this file to configure your truffle project. It's seeded with some
 * common settings for different networks and features like migrations,
 * compilation and testing. Uncomment the ones you need or modify
 * them to suit your project as necessary.
 *
 * More information about configuration can be found at:
 *
 * truffleframework.com/docs/advanced/configuration
 *
 * To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider)
 * to sign your transactions before they're sent to a remote public node. Infura API
 * keys are available for free at: infura.io/register
 *
 * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate
 * public/private key pairs. If you're publishing your code to GitHub make sure you load this
 * phrase from a file you've .gitignored so it doesn't accidentally become public.
 *
 */

require('dotenv').config();

const {
  ETHERSCAN_API_KEY,
  INFURA_KEY
} = process.env;

const HDWalletProvider = require('truffle-hdwallet-provider');
const PrivateKeyProvider = require("truffle-privatekey-provider");
const infuraKey = INFURA_KEY;

const fs = require('fs');
const mnemonic = fs.readFileSync(".secret").toString().trim();
const privateKey = fs.readFileSync(".private_key").toString().trim();

module.exports = {
  /**
   * Networks define how you connect to your ethereum client and let you set the
   * defaults web3 uses to send transactions. If you don't specify one truffle
   * will spin up a development blockchain for you on port 9545 when you
   * run `develop` or `test`. You can ask a truffle command to use a specific
   * network from the command line, e.g
   *
   * $ truffle test --network <network-name>
   */
  networks: {
    // Useful for testing. The `development` name is special - truffle uses it by default
    // if it's defined here and no other network is specified at the command line.
    // You should run a client (like ganache-cli, geth or parity) in a separate terminal
    // tab if you use this network and you must also set the `host`, `port` and `network_id`
    // options below to some value.
    //
    // development: {
    //   host: "127.0.0.1",     // Localhost (default: none)
    //   port: 9545,            // Standard Ethereum port (default: none)
    //   network_id: "*",       // Any network (default: none)
    // },

    // Another network with more advanced options...
    // advanced: {
      // port: 8777,             // Custom port
      // network_id: 1342,       // Custom network
      // gas: 8500000,           // Gas sent with each transaction (default: ~6700000)
      // gasPrice: 20000000000,  // 20 gwei (in wei) (default: 100 gwei)
      // from: <address>,        // Account to send txs from (default: accounts[0])
      // websockets: true        // Enable EventEmitter interface for web3 (default: false)
    // },

    // Useful for deploying to a public network.
    // NB: It's important to wrap the provider as a function.
    rinkebyMnemonic: {
      provider: () => new HDWalletProvider(mnemonic, `https://rinkeby.infura.io/v3/${infuraKey}`),
      network_id: 4,       // rinkeby's id
      gas: 5500000,        // rinkeby has a lower block limit than mainnet
      confirmations: 2,    // # of confs to wait between deployments. (default: 0)
      timeoutBlocks: 200,  // # of blocks before a deployment times out  (minimum/default: 50)
      skipDryRun: false     // Skip dry run before migrations? (default: false for public nets )
    },

    rinkebyPrivateKey: {
      provider: () => new PrivateKeyProvider(privateKey, `https://rinkeby.infura.io/v3/${infuraKey}`),
      network_id: 4,       // rinkeby's id
      gas: 5500000,        // rinkeby has a lower block limit than mainnet
      confirmations: 2,    // # of confs to wait between deployments. (default: 0)
      timeoutBlocks: 200,  // # of blocks before a deployment times out  (minimum/default: 50)
      skipDryRun: false     // Skip dry run before migrations? (default: false for public nets )
    },

    mainnetPrivateKey: {
      provider: () => new PrivateKeyProvider(privateKey, `https://mainnet.infura.io/v3/${infuraKey}`),
      network_id: 1,       // Mainnet's id
      gas: 8000000,        // Mainnet has a lower block limit than mainnet
      confirmations: 20,    // # of confs to wait between deployments. (default: 0)
      timeoutBlocks: 200,  // # of blocks before a deployment times out  (minimum/default: 50)
      skipDryRun: false     // Skip dry run before migrations? (default: false for public nets )
      // gasPrice: 100000  // gas price in wei
    },

    mainnetMnemonic: {
      provider: () => new HDWalletProvider(mnemonic, `https://mainnet.infura.io/v3/${infuraKey}`),
      network_id: 1,       // Mainnet's id
      gas: 8000000,        // Mainnet has a lower block limit than mainnet
      confirmations: 20,    // # of confs to wait between deployments. (default: 0)
      timeoutBlocks: 200,  // # of blocks before a deployment times out  (minimum/default: 50)
      skipDryRun: false     // Skip dry run before migrations? (default: false for public nets )
      // gasPrice: 100000  // gas price in wei
    },

    // Useful for private networks
    // private: {
      // provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
      // network_id: 2111,   // This network is yours, in the cloud.
      // production: true    // Treats this network as if it was a public net. (default: false)
    // }
  },

  plugins: [
    'truffle-plugin-verify'
  ],

  api_keys: {
    etherscan: ETHERSCAN_API_KEY,
  },

  // Set default mocha options here, use special reporters etc.
  mocha: {
    // timeout: 100000
  },

  // Configure your compilers
  compilers: {
    solc: {
      version: '^0.5.2', // Fetch exact version from solc-bin (default: truffle's version)
      // docker: true,        // Use "0.5.1" you've installed locally with docker (default: false)
      // settings: {          // See the solidity docs for advice about optimization and evmVersion
      //  optimizer: {
      //    enabled: false,
      //    runs: 200
      //  },
      // evmVersion: "byzantine"
      // }
    }
  }
};

Looking forward to this issue beeing fixed @rkalis :)

verifying contracts that was not deployed using truffle

Without something like this:

 24       if (!(options.networkId in artifact.networks)) {
 25         artifact.networks[`${options.networkId}`] = {};
 26       }
 27       if (contractAddress) {
 28         artifact.networks[`${options.networkId}`]
 29         artifact.networks[`${options.networkId}`].address = contractAddress
 30       }

We would have error "Cannot set property 'address' of undefined"

Found duplicate SPDX-License-Identifiers in the Solidity code

Hi, I'm trying to verify my Solidity file, but it throws an error despite using the new `--license`` parameter:

C:\Projects\Galaxias\file-storage>truffle run verify --licence UNLICENSED Files --network rinkeby      
Verifying Files
Found duplicate SPDX-License-Identifiers in the Solidity code, please provide the correct license with 
--license <license identifier>
Failed to verify 1 contract(s): Files

I have removed the SPDX comment from the Files.sol file, but it uses an OZ file (which might use others), and that's where it could get it.

My truffle-plugin-verify version is 0.4.0.

Etherscan request times out when requesting constructor args

I followed the instructions but failed.

Running truffle-plugin-verify v0.4.0
Verifying Token
Reading artifact file at E:\MyProject\BlockChain\truffle-contracts\abis/Token.json
Retrieving constructor parameters from https://api-ropsten.etherscan.io/api?apiKey=my_api_key&module=account&action=txlist&address=0x4C9D6ed005bfB301726cA23adE690890B853fB60&page=1&sort=asc&offset=1
Failed to connect to Etherscan API at url https://api-ropsten.etherscan.io/api
Failed to verify 1 contract(s): Token

It seems the network problem. But It migrated successfully. when I try to connect to the verify url, it returns right:

PS E:\MyProject\BlockChain\truffle-contracts> curl https://api-ropsten.etherscan.io/api          

StatusCode        : 200
StatusDescription : OK
Content           : {"status":"0","message":"NOTOK-Missing/Invalid API Key, rate limit of 1/5sec 
                     applied","result":"Error! Missing Or invalid Module name"}
RawContent        : HTTP/1.1 200 OK
...

VSCode IDE
truffle version: v5.1.48
OS: windows 10

Thanks!

Cannot find module 'openzeppelin-solidity/contracts/GSN/Context.sol'

I am trying to verify the oceanprotocol/contracts. Unfortunately it returns Cannot find module 'openzeppelin-solidity/ and it is not clear to me where is the issue!. So I am listing below the required steps to reproduce the same error:

  • Downloading the repo:
git clone https://github.com/oceanprotocol/contracts.git
npm i
  • Installing the plugin:
npm i truffle-plugin-verify --save-dev
  • Updating the truffle-config.js
    ...
    plugins: [
        'solidity-coverage',
        'truffle-plugin-verify'
    ],
    api_keys: {
        // etherscan: 'MY_API_KEY'
        etherscan: 'MY_ETHERSCAN_API_KEY'
    },
   ....
  • Finally verifying one of the contracts (DataTokenTemplate). The mainnet contracts deployment can be found here
truffle run verify DataTokenTemplate@0x081d1AE20E83D955d1B2E517238F32B8e8DeaDD2 --network mainnet --license Apache-2.0 --debug
DEBUG logging is turned ON
Running truffle-plugin-verify v0.5.0
Verifying DataTokenTemplate@0x081d1AE20E83D955d1B2E517238F32B8e8DeaDD2
Reading artifact file at /Users/ahmedali/Desktop/work/mainnet-deployment/ocean-contracts/build/contracts/DataTokenTemplate.json
Custom address 0x081d1AE20E83D955d1B2E517238F32B8e8DeaDD2 specified
Retrieving constructor parameters from https://api.etherscan.io/api?apiKey=APIKEY&module=account&action=txlist&address=0x081d1AE20E83D955d1B2E517238F32B8e8DeaDD2&page=1&sort=asc&offset=1
Constructor parameters retrieved: 0x00000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000d6e0f938323a9d9d52b26700716e2e8e027f3795000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000000000000001400000000000000000000000002e6ff1f888425e6eac81cf3360bb805ab40ecc1a000000000000000000000000000000000000000000000000000000000000001144617461546f6b656e54656d706c617465000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000344545400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018687474703a2f2f6f6365616e70726f746f636f6c2e636f6d0000000000000000
Cannot find module 'openzeppelin-solidity/contracts/GSN/Context.sol'
Failed to verify 1 contract(s): DataTokenTemplate@0x081d1AE20E83D955d1B2E517238F32B8e8DeaDD2

Even if the file already exists"

ahmedali@ahmeds-mbp ocean-contracts % ls node_modules/openzeppelin-solidity/contracts/GSN/Context.sol 
node_modules/openzeppelin-solidity/contracts/GSN/Context.sol

why artifact.networks is empty?

got this :
Verifying UniswapV2Factory
Reading artifact file at D:\codes\uniswap-v2-core\build\contracts/UniswapV2Factory.json
artifact.networks: {} ----------->new log added.
No instance of contract UniswapV2Factory found for network id 4
Failed to verify 1 contract(s): UniswapV2Factory

Failing to verify flattened ERC777 token

Attaching a repository to reproduce: <Made private, attaching code below>

Long story short: this a simple flattened ERC777 that fails to verify through the plugin. Even if I remove constructor args from the Solidity code, it fails.

It comes from a multifile truffle project where I have the ERC777 implementation of open-zeppelin linked. That project verifies OK, but the moment I flatten the contract the plugin fails. Truth is, the way I 've always used to verify manually does not work either. I have always checked out bytecode, transaction input data and got the diff between them at the end of the input data, but it is not working.

This has lead me to directly output the encoded args with web3.eth.abi.encodeParameters during deployment. If I take the output and use it in the manual verification process, it goes ok..

It is super weird and I don't know if I may be doing something wrong. Weirdest part is as I said, the non-flattened code verifies perfectly. Dunno, bytecode management is a bit magicz territory for me (yet). If anything, I think you have cooperated with truffle before, I would request that the truffle JSON artifact that generates when building / deploying attaches constructor args to the network entry, as in:

"networks": {
    "4": {
    ...
       "links": {},
      "address": "0x1e08289Cb8E303dD2fE36BcF0562947664885987",
      "transactionHash": "0xeea8b203d796c750dd3e8dcf0e732cd4f4c319c7828350762971c2f03cf8773b"
      "abi-encoded-constructor-args": "000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000b5365636f6e642074657374000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000454535432000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
    },
    ...
}

Or maybe I am totally missing on something.

EDIT. Another way would be to let the user specify the args through an option, ex. --args 0000

EDIT2. Further research makes me think that it is not constructor args what is wrong here. sol-merger Seems to be skipping the Ownable contract for unknown reasons, so the compilation fails when Pausable references Ownable. Although this seems like a fix for sol-merger, it would be a good idea to analyze if the source code features import statements in order to skip a merge if the target source is flat.

EDIT3. Since this is a sol-merger bug, I am hiding somethings that no longer are relevant. The flattened conflicting code is below:

pragma solidity 0.5.7;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, "SafeMath: division by zero");
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}






/**
 * @dev Interface of the ERC777Token standard as defined in the EIP.
 *
 * This contract uses the
 * [ERC1820 registry standard](https://eips.ethereum.org/EIPS/eip-1820) to let
 * token holders and recipients react to token movements by using setting implementers
 * for the associated interfaces in said registry. See `IERC1820Registry` and
 * `ERC1820Implementer`.
 */
interface IERC777 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the smallest part of the token that is not divisible. This
     * means all token operations (creation, movement and destruction) must have
     * amounts that are a multiple of this number.
     *
     * For most token contracts, this value will equal 1.
     */
    function granularity() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by an account (`owner`).
     */
    function balanceOf(address owner) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * If send or receive hooks are registered for the caller and `recipient`,
     * the corresponding functions will be called with `data` and empty
     * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.
     *
     * Emits a `Sent` event.
     *
     * Requirements
     *
     * - the caller must have at least `amount` tokens.
     * - `recipient` cannot be the zero address.
     * - if `recipient` is a contract, it must implement the `tokensReceived`
     * interface.
     */
    function send(address recipient, uint256 amount, bytes calldata data) external;

    /**
     * @dev Destroys `amount` tokens from the caller's account, reducing the
     * total supply.
     *
     * If a send hook is registered for the caller, the corresponding function
     * will be called with `data` and empty `operatorData`. See `IERC777Sender`.
     *
     * Emits a `Burned` event.
     *
     * Requirements
     *
     * - the caller must have at least `amount` tokens.
     */
    function burn(uint256 amount, bytes calldata data) external;

    /**
     * @dev Returns true if an account is an operator of `tokenHolder`.
     * Operators can send and burn tokens on behalf of their owners. All
     * accounts are their own operator.
     *
     * See `operatorSend` and `operatorBurn`.
     */
    function isOperatorFor(address operator, address tokenHolder) external view returns (bool);

    /**
     * @dev Make an account an operator of the caller.
     *
     * See `isOperatorFor`.
     *
     * Emits an `AuthorizedOperator` event.
     *
     * Requirements
     *
     * - `operator` cannot be calling address.
     */
    function authorizeOperator(address operator) external;

    /**
     * @dev Make an account an operator of the caller.
     *
     * See `isOperatorFor` and `defaultOperators`.
     *
     * Emits a `RevokedOperator` event.
     *
     * Requirements
     *
     * - `operator` cannot be calling address.
     */
    function revokeOperator(address operator) external;

    /**
     * @dev Returns the list of default operators. These accounts are operators
     * for all token holders, even if `authorizeOperator` was never called on
     * them.
     *
     * This list is immutable, but individual holders may revoke these via
     * `revokeOperator`, in which case `isOperatorFor` will return false.
     */
    function defaultOperators() external view returns (address[] memory);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must
     * be an operator of `sender`.
     *
     * If send or receive hooks are registered for `sender` and `recipient`,
     * the corresponding functions will be called with `data` and
     * `operatorData`. See `IERC777Sender` and `IERC777Recipient`.
     *
     * Emits a `Sent` event.
     *
     * Requirements
     *
     * - `sender` cannot be the zero address.
     * - `sender` must have at least `amount` tokens.
     * - the caller must be an operator for `sender`.
     * - `recipient` cannot be the zero address.
     * - if `recipient` is a contract, it must implement the `tokensReceived`
     * interface.
     */
    function operatorSend(
        address sender,
        address recipient,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;

    /**
     * @dev Destoys `amount` tokens from `account`, reducing the total supply.
     * The caller must be an operator of `account`.
     *
     * If a send hook is registered for `account`, the corresponding function
     * will be called with `data` and `operatorData`. See `IERC777Sender`.
     *
     * Emits a `Burned` event.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     * - the caller must be an operator for `account`.
     */
    function operatorBurn(
        address account,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;

    event Sent(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 amount,
        bytes data,
        bytes operatorData
    );

    event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);

    event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);

    event AuthorizedOperator(address indexed operator, address indexed tokenHolder);

    event RevokedOperator(address indexed operator, address indexed tokenHolder);
}



/**
 * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.
 *
 * Accounts can be notified of `IERC777` tokens being sent to them by having a
 * contract implement this interface (contract holders can be their own
 * implementer) and registering it on the
 * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).
 *
 * See `IERC1820Registry` and `ERC1820Implementer`.
 */
interface IERC777Recipient {
    /**
     * @dev Called by an `IERC777` token contract whenever tokens are being
     * moved or created into a registered account (`to`). The type of operation
     * is conveyed by `from` being the zero address or not.
     *
     * This call occurs _after_ the token contract's state is updated, so
     * `IERC777.balanceOf`, etc., can be used to query the post-operation state.
     *
     * This function may revert to prevent the operation from being executed.
     */
    function tokensReceived(
        address operator,
        address from,
        address to,
        uint amount,
        bytes calldata userData,
        bytes calldata operatorData
    ) external;
}



/**
 * @dev Interface of the ERC777TokensSender standard as defined in the EIP.
 *
 * `IERC777` Token holders can be notified of operations performed on their
 * tokens by having a contract implement this interface (contract holders can be
 *  their own implementer) and registering it on the
 * [ERC1820 global registry](https://eips.ethereum.org/EIPS/eip-1820).
 *
 * See `IERC1820Registry` and `ERC1820Implementer`.
 */
interface IERC777Sender {
    /**
     * @dev Called by an `IERC777` token contract whenever a registered holder's
     * (`from`) tokens are about to be moved or destroyed. The type of operation
     * is conveyed by `to` being the zero address or not.
     *
     * This call occurs _before_ the token contract's state is updated, so
     * `IERC777.balanceOf`, etc., can be used to query the pre-operation state.
     *
     * This function may revert to prevent the operation from being executed.
     */
    function tokensToSend(
        address operator,
        address from,
        address to,
        uint amount,
        bytes calldata userData,
        bytes calldata operatorData
    ) external;
}



/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see `ERC20Detailed`.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a `Transfer` event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through `transferFrom`. This is
     * zero by default.
     *
     * This value changes when `approve` or `transferFrom` are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * > Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an `Approval` event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a `Transfer` event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to `approve`. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}




/**
 * @dev Collection of functions related to the address type,
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * This test is non-exhaustive, and there may be false-negatives: during the
     * execution of a contract's constructor, its address will be reported as
     * not containing a contract.
     *
     * > It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies in extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }
}



/**
 * @dev Interface of the global ERC1820 Registry, as defined in the
 * [EIP](https://eips.ethereum.org/EIPS/eip-1820). Accounts may register
 * implementers for interfaces in this registry, as well as query support.
 *
 * Implementers may be shared by multiple accounts, and can also implement more
 * than a single interface for each account. Contracts can implement interfaces
 * for themselves, but externally-owned accounts (EOA) must delegate this to a
 * contract.
 *
 * `IERC165` interfaces can also be queried via the registry.
 *
 * For an in-depth explanation and source code analysis, see the EIP text.
 */
interface IERC1820Registry {
    /**
     * @dev Sets `newManager` as the manager for `account`. A manager of an
     * account is able to set interface implementers for it.
     *
     * By default, each account is its own manager. Passing a value of `0x0` in
     * `newManager` will reset the manager to this initial state.
     *
     * Emits a `ManagerChanged` event.
     *
     * Requirements:
     *
     * - the caller must be the current manager for `account`.
     */
    function setManager(address account, address newManager) external;

    /**
     * @dev Returns the manager for `account`.
     *
     * See `setManager`.
     */
    function getManager(address account) external view returns (address);

    /**
     * @dev Sets the `implementer` contract as `account`'s implementer for
     * `interfaceHash`.
     *
     * `account` being the zero address is an alias for the caller's address.
     * The zero address can also be used in `implementer` to remove an old one.
     *
     * See `interfaceHash` to learn how these are created.
     *
     * Emits an `InterfaceImplementerSet` event.
     *
     * Requirements:
     *
     * - the caller must be the current manager for `account`.
     * - `interfaceHash` must not be an `IERC165` interface id (i.e. it must not
     * end in 28 zeroes).
     * - `implementer` must implement `IERC1820Implementer` and return true when
     * queried for support, unless `implementer` is the caller. See
     * `IERC1820Implementer.canImplementInterfaceForAddress`.
     */
    function setInterfaceImplementer(address account, bytes32 interfaceHash, address implementer) external;

    /**
     * @dev Returns the implementer of `interfaceHash` for `account`. If no such
     * implementer is registered, returns the zero address.
     *
     * If `interfaceHash` is an `IERC165` interface id (i.e. it ends with 28
     * zeroes), `account` will be queried for support of it.
     *
     * `account` being the zero address is an alias for the caller's address.
     */
    function getInterfaceImplementer(address account, bytes32 interfaceHash) external view returns (address);

    /**
     * @dev Returns the interface hash for an `interfaceName`, as defined in the
     * corresponding
     * [section of the EIP](https://eips.ethereum.org/EIPS/eip-1820#interface-name).
     */
    function interfaceHash(string calldata interfaceName) external pure returns (bytes32);

    /**
     *  @notice Updates the cache with whether the contract implements an ERC165 interface or not.
     *  @param account Address of the contract for which to update the cache.
     *  @param interfaceId ERC165 interface for which to update the cache.
     */
    function updateERC165Cache(address account, bytes4 interfaceId) external;

    /**
     *  @notice Checks whether a contract implements an ERC165 interface or not.
     *  If the result is not cached a direct lookup on the contract address is performed.
     *  If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling
     *  'updateERC165Cache' with the contract address.
     *  @param account Address of the contract to check.
     *  @param interfaceId ERC165 interface to check.
     *  @return True if `account.address()` implements `interfaceId`, false otherwise.
     */
    function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);

    /**
     *  @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.
     *  @param account Address of the contract to check.
     *  @param interfaceId ERC165 interface to check.
     *  @return True if `account.address()` implements `interfaceId`, false otherwise.
     */
    function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);

    event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);

    event ManagerChanged(address indexed account, address indexed newManager);
}


/**
 * @dev Implementation of the `IERC777` interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using `_mint`.
 *
 * Support for ERC20 is included in this contract, as specified by the EIP: both
 * the ERC777 and ERC20 interfaces can be safely used when interacting with it.
 * Both `IERC777.Sent` and `IERC20.Transfer` events are emitted on token
 * movements.
 *
 * Additionally, the `granularity` value is hard-coded to `1`, meaning that there
 * are no special restrictions in the amount of tokens that created, moved, or
 * destroyed. This makes integration with ERC20 applications seamless.
 */
contract ERC777 is IERC777, IERC20 {
    using SafeMath for uint256;
    using Address for address;

    IERC1820Registry private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);

    mapping(address => uint256) private _balances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.
    // See https://github.com/ethereum/solidity/issues/4024.

    // keccak256("ERC777TokensSender")
    bytes32 constant private TOKENS_SENDER_INTERFACE_HASH =
        0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;

    // keccak256("ERC777TokensRecipient")
    bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH =
        0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;

    // This isn't ever read from - it's only used to respond to the defaultOperators query.
    address[] private _defaultOperatorsArray;

    // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).
    mapping(address => bool) private _defaultOperators;

    // For each account, a mapping of its operators and revoked default operators.
    mapping(address => mapping(address => bool)) private _operators;
    mapping(address => mapping(address => bool)) private _revokedDefaultOperators;

    // ERC20-allowances
    mapping (address => mapping (address => uint256)) private _allowances;

    /**
     * @dev `defaultOperators` may be an empty array.
     */
    constructor(
        string memory name,
        string memory symbol,
        address[] memory defaultOperators
    ) public {
        _name = name;
        _symbol = symbol;

        _defaultOperatorsArray = defaultOperators;
        for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {
            _defaultOperators[_defaultOperatorsArray[i]] = true;
        }

        // register interfaces
        _erc1820.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this));
        _erc1820.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this));
    }

    /**
     * @dev See `IERC777.name`.
     */
    function name() public view returns (string memory) {
        return _name;
    }

    /**
     * @dev See `IERC777.symbol`.
     */
    function symbol() public view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See `ERC20Detailed.decimals`.
     *
     * Always returns 18, as per the
     * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).
     */
    function decimals() public pure returns (uint8) {
        return 18;
    }

    /**
     * @dev See `IERC777.granularity`.
     *
     * This implementation always returns `1`.
     */
    function granularity() public view returns (uint256) {
        return 1;
    }

    /**
     * @dev See `IERC777.totalSupply`.
     */
    function totalSupply() public view returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev Returns the amount of tokens owned by an account (`tokenHolder`).
     */
    function balanceOf(address tokenHolder) public view returns (uint256) {
        return _balances[tokenHolder];
    }

    /**
     * @dev See `IERC777.send`.
     *
     * Also emits a `Transfer` event for ERC20 compatibility.
     */
    function send(address recipient, uint256 amount, bytes calldata data) external {
        _send(msg.sender, msg.sender, recipient, amount, data, "", true);
    }

    /**
     * @dev See `IERC20.transfer`.
     *
     * Unlike `send`, `recipient` is _not_ required to implement the `tokensReceived`
     * interface if it is a contract.
     *
     * Also emits a `Sent` event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool) {
        require(recipient != address(0), "ERC777: transfer to the zero address");

        address from = msg.sender;

        _callTokensToSend(from, from, recipient, amount, "", "");

        _move(from, from, recipient, amount, "", "");

        _callTokensReceived(from, from, recipient, amount, "", "", false);

        return true;
    }

    /**
     * @dev See `IERC777.burn`.
     *
     * Also emits a `Transfer` event for ERC20 compatibility.
     */
    function burn(uint256 amount, bytes calldata data) external {
        _burn(msg.sender, msg.sender, amount, data, "");
    }

    /**
     * @dev See `IERC777.isOperatorFor`.
     */
    function isOperatorFor(
        address operator,
        address tokenHolder
    ) public view returns (bool) {
        return operator == tokenHolder ||
            (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||
            _operators[tokenHolder][operator];
    }

    /**
     * @dev See `IERC777.authorizeOperator`.
     */
    function authorizeOperator(address operator) external {
        require(msg.sender != operator, "ERC777: authorizing self as operator");

        if (_defaultOperators[operator]) {
            delete _revokedDefaultOperators[msg.sender][operator];
        } else {
            _operators[msg.sender][operator] = true;
        }

        emit AuthorizedOperator(operator, msg.sender);
    }

    /**
     * @dev See `IERC777.revokeOperator`.
     */
    function revokeOperator(address operator) external {
        require(operator != msg.sender, "ERC777: revoking self as operator");

        if (_defaultOperators[operator]) {
            _revokedDefaultOperators[msg.sender][operator] = true;
        } else {
            delete _operators[msg.sender][operator];
        }

        emit RevokedOperator(operator, msg.sender);
    }

    /**
     * @dev See `IERC777.defaultOperators`.
     */
    function defaultOperators() public view returns (address[] memory) {
        return _defaultOperatorsArray;
    }

    /**
     * @dev See `IERC777.operatorSend`.
     *
     * Emits `Sent` and `Transfer` events.
     */
    function operatorSend(
        address sender,
        address recipient,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    )
    external
    {
        require(isOperatorFor(msg.sender, sender), "ERC777: caller is not an operator for holder");
        _send(msg.sender, sender, recipient, amount, data, operatorData, true);
    }

    /**
     * @dev See `IERC777.operatorBurn`.
     *
     * Emits `Sent` and `Transfer` events.
     */
    function operatorBurn(address account, uint256 amount, bytes calldata data, bytes calldata operatorData) external {
        require(isOperatorFor(msg.sender, account), "ERC777: caller is not an operator for holder");
        _burn(msg.sender, account, amount, data, operatorData);
    }

    /**
     * @dev See `IERC20.allowance`.
     *
     * Note that operator and allowance concepts are orthogonal: operators may
     * not have allowance, and accounts with allowance may not be operators
     * themselves.
     */
    function allowance(address holder, address spender) public view returns (uint256) {
        return _allowances[holder][spender];
    }

    /**
     * @dev See `IERC20.approve`.
     *
     * Note that accounts cannot have allowance issued by their operators.
     */
    function approve(address spender, uint256 value) external returns (bool) {
        address holder = msg.sender;
        _approve(holder, spender, value);
        return true;
    }

   /**
    * @dev See `IERC20.transferFrom`.
    *
    * Note that operator and allowance concepts are orthogonal: operators cannot
    * call `transferFrom` (unless they have allowance), and accounts with
    * allowance cannot call `operatorSend` (unless they are operators).
    *
    * Emits `Sent` and `Transfer` events.
    */
    function transferFrom(address holder, address recipient, uint256 amount) external returns (bool) {
        require(recipient != address(0), "ERC777: transfer to the zero address");
        require(holder != address(0), "ERC777: transfer from the zero address");

        address spender = msg.sender;

        _callTokensToSend(spender, holder, recipient, amount, "", "");

        _move(spender, holder, recipient, amount, "", "");
        _approve(holder, spender, _allowances[holder][spender].sub(amount));

        _callTokensReceived(spender, holder, recipient, amount, "", "", false);

        return true;
    }

    /**
     * @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * If a send hook is registered for `raccount`, the corresponding function
     * will be called with `operator`, `data` and `operatorData`.
     *
     * See `IERC777Sender` and `IERC777Recipient`.
     *
     * Emits `Sent` and `Transfer` events.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - if `account` is a contract, it must implement the `tokensReceived`
     * interface.
     */
    function _mint(
        address operator,
        address account,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData
    )
    internal
    {
        require(account != address(0), "ERC777: mint to the zero address");

        // Update state variables
        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);

        _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);

        emit Minted(operator, account, amount, userData, operatorData);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Send tokens
     * @param operator address operator requesting the transfer
     * @param from address token holder address
     * @param to address recipient address
     * @param amount uint256 amount of tokens to transfer
     * @param userData bytes extra information provided by the token holder (if any)
     * @param operatorData bytes extra information provided by the operator (if any)
     * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
     */
    function _send(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData,
        bool requireReceptionAck
    )
        private
    {
        require(from != address(0), "ERC777: send from the zero address");
        require(to != address(0), "ERC777: send to the zero address");

        _callTokensToSend(operator, from, to, amount, userData, operatorData);

        _move(operator, from, to, amount, userData, operatorData);

        _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);
    }

    /**
     * @dev Burn tokens
     * @param operator address operator requesting the operation
     * @param from address token holder address
     * @param amount uint256 amount of tokens to burn
     * @param data bytes extra information provided by the token holder
     * @param operatorData bytes extra information provided by the operator (if any)
     */
    function _burn(
        address operator,
        address from,
        uint256 amount,
        bytes memory data,
        bytes memory operatorData
    )
        private
    {
        require(from != address(0), "ERC777: burn from the zero address");

        _callTokensToSend(operator, from, address(0), amount, data, operatorData);

        // Update state variables
        _totalSupply = _totalSupply.sub(amount);
        _balances[from] = _balances[from].sub(amount);

        emit Burned(operator, from, amount, data, operatorData);
        emit Transfer(from, address(0), amount);
    }

    function _move(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData
    )
        private
    {
        _balances[from] = _balances[from].sub(amount);
        _balances[to] = _balances[to].add(amount);

        emit Sent(operator, from, to, amount, userData, operatorData);
        emit Transfer(from, to, amount);
    }

    function _approve(address holder, address spender, uint256 value) private {
        // TODO: restore this require statement if this function becomes internal, or is called at a new callsite. It is
        // currently unnecessary.
        //require(holder != address(0), "ERC777: approve from the zero address");
        require(spender != address(0), "ERC777: approve to the zero address");

        _allowances[holder][spender] = value;
        emit Approval(holder, spender, value);
    }

    /**
     * @dev Call from.tokensToSend() if the interface is registered
     * @param operator address operator requesting the transfer
     * @param from address token holder address
     * @param to address recipient address
     * @param amount uint256 amount of tokens to transfer
     * @param userData bytes extra information provided by the token holder (if any)
     * @param operatorData bytes extra information provided by the operator (if any)
     */
    function _callTokensToSend(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData
    )
        private
    {
        address implementer = _erc1820.getInterfaceImplementer(from, TOKENS_SENDER_INTERFACE_HASH);
        if (implementer != address(0)) {
            IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);
        }
    }

    /**
     * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but
     * tokensReceived() was not registered for the recipient
     * @param operator address operator requesting the transfer
     * @param from address token holder address
     * @param to address recipient address
     * @param amount uint256 amount of tokens to transfer
     * @param userData bytes extra information provided by the token holder (if any)
     * @param operatorData bytes extra information provided by the operator (if any)
     * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
     */
    function _callTokensReceived(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData,
        bool requireReceptionAck
    )
        private
    {
        address implementer = _erc1820.getInterfaceImplementer(to, TOKENS_RECIPIENT_INTERFACE_HASH);
        if (implementer != address(0)) {
            IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);
        } else if (requireReceptionAck) {
            require(!to.isContract(), "ERC777: token recipient contract has no implementer for ERC777TokensRecipient");
        }
    }
}





/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be aplied to your functions to restrict their use to
 * the owner.
 */
contract Ownable {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), _owner);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == _owner;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * > Note: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * Based on openzeppelin Pausable contract, modified to give the pause function to the owner.
 */
contract Pausable is Ownable {
    /**
     * @dev Emitted when the pause is triggered by a pauser (`account`).
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by a pauser (`account`).
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state. Assigns the Pauser role
     * to the deployer.
     */
    constructor () internal {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     */
    modifier whenNotPaused() {
        require(!_paused);
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     */
    modifier whenPaused() {
        require(_paused);
        _;
    }

    /**
     * @dev Called by the owner, triggers stopped state.
     */
    function pause() public onlyOwner whenNotPaused {
        _paused = true;
        emit Paused(msg.sender);
    }

    /**
     * @dev Called by the owner, returns to normal state.
     */
    function unpause() public onlyOwner whenPaused {
        _paused = false;
        emit Unpaused(msg.sender);
    }
}


contract TestToken is Pausable, ERC777 {
  using SafeMath for uint256;
  
  uint256 constant public preAssigned = 300000000000000000000000000; // 300 hundred millions of tokens

  event LogReward(
    address indexed sender,
    address indexed origin,
    address indexed to,
    uint256 amount
  );

  constructor(
    string memory name,
    string memory symbol,
    address[] memory defaultOperators
  ) ERC777(name, symbol, defaultOperators)
    public {
      _mint(msg.sender, msg.sender, preAssigned, "", "");
      _mint(msg.sender, msg.sender, preAssigned, "", "");
  }
  

}

Missing Comments?

Hey there! Loving this tool so far -- the only issue is that it appears that comments aren't preserved after verifying?

You can see comments here:

Screen Shot 2019-11-26 at 12 25 10 AM

but not showing up on etherscan verification:

Screen Shot 2019-11-26 at 12 24 15 AM

Lemme know if you need any more details or if this is a known issue :)

merging not working with ecma6 style imports

Hi There,

These are my contracts, which are a part of the bridge work from Syscoin <-> Ethereum:

https://etherscan.io/address/0x197a2f58c94eff4b2c6ae0922fbc840080f839c2#contracts
https://etherscan.io/address/0x94bb1afd55616daae06c5014d083f506c5a02619#contracts
https://etherscan.io/address/0x35dfdcf5bb289a8bb994e0a4e3554a4dae504483#contracts
https://etherscan.io/address/0xced7ce5c336bb31f35bc5bdc86c651c7136b3825#contracts
https://etherscan.io/address/0xb64f4f0aeb3ec6cd423df3402909fef5963c1fd6#contracts

I was able to verify them via etherescan online single file verify but noticed a two issues that I hope we can resolve here and upstream on sol-merger. I will explain how.

The first issue I had was that sol-merger is using a regex that does not support ecma6 style imports you can see the fix for the regex here:

https://regex101.com/r/CNPTp4/2

The old regex is here: https://github.com/RyuuGan/sol-merger/blob/master/lib/merger.js#L27

Which only works for standard import '' statements. So the merged code wasn't working and thus not verifiable since the verifier through the API doesn't support import statements on etherscan. The regex is correct from that link as you can see.

The second issue I had was that there is not library linking support. You can see here that you are not pushing libraries: https://github.com/rkalis/truffle-plugin-verify/blob/master/verify.js#L42 and my json artifact has the library linked like below:
For example this is the SyscoinSuperblocks.json:

...
  "networks": {
    "1": {
      "events": {},
      "links": {
        "SyscoinMessageLibrary": "0x1b081401c98ed6e62b01bc5379d52abee85ae1e9"
      },
      "address": "0xced7ce5c336bb31f35bc5bdc86c651c7136b3825",
      "transactionHash": "0x8374d59e2fc38328b75295b9c4d0e1d0d91bd71f85a8b8d2fb77eb50dff198ce"
    }
  },
...

So SyscoinMessageLibrary should be added as a library link. I noticed that the Etherscan single file verification needed me to enter the library link in order for it to finally verify.

From the API example docs on etherscan we can see the example of how to enter the library links (https://etherscan.io/apis#contracts):

    $.ajax({
        type: "POST",                       //Only POST supported  
        url: "//api.etherscan.io/api", //Set to the  correct API url for Other Networks
        data: {
            apikey: $('#apikey').val(),                     //A valid API-Key is required        
            module: 'contract',                             //Do not change
            action: 'verifysourcecode',                     //Do not change
            contractaddress: $('#contractaddress').val(),   //Contract Address starts with 0x...     
            sourceCode: $('#sourceCode').val(),             //Contract Source Code (Flattened if necessary)
            contractname: $('#contractname').val(),         //ContractName
            compilerversion: $('#compilerversion').val(),   // see http://etherscan.io/solcversions for list of support versions
            optimizationUsed: $('#optimizationUsed').val(), //0 = Optimization used, 1 = No Optimization
            runs: 200,                                      //set to 200 as default unless otherwise         
            constructorArguements: $('#constructorArguements').val(),   //if applicable
            libraryname1: $('#libraryname1').val(),         //if applicable, a matching pair with libraryaddress1 required
            libraryaddress1: $('#libraryaddress1').val(),   //if applicable, a matching pair with libraryname1 required
            libraryname2: $('#libraryname2').val(),         //if applicable, matching pair required
            libraryaddress2: $('#libraryaddress2').val(),   //if applicable, matching pair required
            libraryname3: $('#libraryname3').val(),         //if applicable, matching pair required
            libraryaddress3: $('#libraryaddress3').val(),   //if applicable, matching pair required
            libraryname4: $('#libraryname4').val(),         //if applicable, matching pair required
            libraryaddress4: $('#libraryaddress4').val(),   //if applicable, matching pair required
            libraryname5: $('#libraryname5').val(),         //if applicable, matching pair required
            libraryaddress5: $('#libraryaddress5').val(),   //if applicable, matching pair required
            libraryname6: $('#libraryname6').val(),         //if applicable, matching pair required
            libraryaddress6: $('#libraryaddress6').val(),   //if applicable, matching pair required
            libraryname7: $('#libraryname7').val(),         //if applicable, matching pair required
            libraryaddress7: $('#libraryaddress7').val(),   //if applicable, matching pair required
            libraryname8: $('#libraryname8').val(),         //if applicable, matching pair required
            libraryaddress8: $('#libraryaddress8').val(),   //if applicable, matching pair required
            libraryname9: $('#libraryname9').val(),         //if applicable, matching pair required
            libraryaddress9: $('#libraryaddress9').val(),   //if applicable, matching pair required
            libraryname10: $('#libraryname10').val(),       //if applicable, matching pair required
            libraryaddress10: $('#libraryaddress10').val()  //if applicable, matching pair required
        },
        success: function (result) {
            console.log(result);
            if (result.status == "1") {
                //1 = submission success, use the guid returned (result.result) to check the status of your submission.
                // Average time of processing is 30-60 seconds
                document.getElementById("postresult").innerHTML = result.status + ";" + result.message + ";" + result.result;
                // result.result is the GUID receipt for the submission, you can use this guid for checking the verification status
            } else {
                //0 = error
                document.getElementById("postresult").innerHTML = result.status + ";" + result.message + ";" + result.result;
            }
            console.log("status : " + result.status);
            console.log("result : " + result.result);
        },
        error: function (result) {
            console.log("error!");
            document.getElementById("postresult").innerHTML = "Unexpected Error"
        }
    });

Doing these two changes should make truffle-plugin-verify work OOTB for most contracts (simple or advanced).

Thanks for your work!

Failure to verify smart contracts using solidity ^0.6.0

Query:
truffle run verify NFWalletFactory --network rinkeby --debug

Output:

DEBUG logging is turned ON
Verifying NFWalletFactory
Reading artifact file at /home/amxx/Work/Projects/NFWallets/solidity/build/contracts/NFWalletFactory.json
Retrieving constructor parameters from https://api-rinkeby.etherscan.io/api?module=account&action=txlist&address=0x19631cB609b85FE81A00b4935A044E3A7d30F8db&page=1&sort=asc&offset=1
Constructor parameters received: 0x
Flattening source file /home/amxx/Work/Projects/NFWallets/solidity/contracts/NFWalletFactory.sol
Sending verify request with POST arguments:
{
  "apikey": "......",
  "module": "contract",
  "action": "verifysourcecode",
  "contractaddress": "0x19631cB609b85FE81A00b4935A044E3A7d30F8db",
  "sourceCode": "pragma solidity ^0.6.0;",
  "codeformat": "solidity-single-file",
  "contractname": "NFWalletFactory",
  "compilerversion": "v0.6.6+commit.6c089d02",
  "optimizationUsed": 1,
  "runs": 200,
  "constructorArguements": ""
}
Checking status of verification request uxjyzgtg9qgmhrstkbcdnaiqbhkhsk7bgkrg8tccq173zzfi1y
Fail - Unable to verify
Failed to verify 1 contract(s): NFWalletFactory

My guess is that the flatening fails. Source code and artefacts are here: https://github.com/Amxx/NFWallet/tree/master/solidity

Not working for Kovan

It seems that the verifier isn't working for the last two days.

Steps to reproduce:
Create new repo, follow all instructions from readme file with some simple test contract and try to verify on Kovan test network, haven't checked for other networks,

for Kovan it says "Unable to verify",
for Mainnet says "No instance of contract Test found for network id 1"

Verifying with ABIEncoderV2 troubles

Hi there,

Trying to verify some contracts using ABIEncoderV2 and I seem to be running into trouble. Here is a simple repo demonstrating the issue.

https://github.com/mrwillis/abiencoder-truffle-verification

I read in the README the pragma experimental ABIEncoderV2 has to come before the solidity pragma, but I've tried both orders and neither seems to work. Have also tried using a higher solidity version (0.6.11), but also fails.

Any ideas?

Output using debug:

julian@julian-wilson:~/betx/abiencoder-truffle-verification$ truffle run verify MetaCoin --network rinkeby --debug
DEBUG logging is turned ON
Running truffle-plugin-verify v0.3.11
Verifying MetaCoin
Reading artifact file at /home/julian/betx/abiencoder-truffle-verification/build/contracts/MetaCoin.json
Retrieving constructor parameters from https://api-rinkeby.etherscan.io/api?apiKey=[key]&module=account&action=txlist&address=0x9E8C724d9EAf24C34CcA3bDC7De469492051af84&page=1&sort=asc&offset=1
Constructor parameters received: 0x
Flattening source file /home/julian/betx/abiencoder-truffle-verification/contracts/MetaCoin.sol
Sending verify request with POST arguments:
{
"apikey": "[key]",
"module": "contract",
"action": "verifysourcecode",
"contractaddress": "0x9E8C724d9EAf24C34CcA3bDC7De469492051af84",
"sourceCode": "pragma solidity 0.5.16;\npragma experimental ABIEncoderV2;\n\n\n// SPDX-License-Identifier: MIT\nlibrary ConvertLib {\n\tfunction convert(uint amount,uint conversionRate) internal pure returns (uint convertedAmount)\n\t{\n\t\treturn amount * conversionRate;\n\t}\n}\n\n// SPDX-License-Identifier: MIT\n// This is just a simple example of a coin-like contract.\n// It is not standards compatible and cannot be expected to talk to other\n// coin/token contracts. If you want to create a standards-compliant\n// token, see: https://github.com/ConsenSys/Tokens. Cheers!\ncontract MetaCoin {\n\tmapping (address => uint) balances;\n\n\tevent Transfer(address indexed _from, address indexed _to, uint256 _value);\n\n\tconstructor() public {\n\t\tbalances[tx.origin] = 10000;\n\t}\n\n\tfunction sendCoin(address receiver, uint amount) public returns(bool sufficient) {\n\t\tif (balances[msg.sender] < amount) return false;\n\t\tbalances[msg.sender] -= amount;\n\t\tbalances[receiver] += amount;\n\t\temit Transfer(msg.sender, receiver, amount);\n\t\treturn true;\n\t}\n\n\tfunction getBalanceInEth(address addr) public view returns(uint){\n\t\treturn ConvertLib.convert(getBalance(addr),2);\n\t}\n\n\tfunction getBalance(address addr) public view returns(uint) {\n\t\treturn balances[addr];\n\t}\n}",
"codeformat": "solidity-single-file",
"contractname": "MetaCoin",
"compilerversion": "v0.5.16+commit.9c3226ce",
"optimizationUsed": 1,
"runs": 200,
"constructorArguements": ""
}
Checking status of verification request 3vngcqycsnakc8wa4i92bbg5imqtdsw7byksdcfibmfwtvcyt5
Fail - Unable to verify
Failed to verify 1 contract(s): MetaCoin

JavaScript heap out of memory when verifying contracts with circular dependencies

I get the following error:

<--- Last few GCs --->

[38003:0x102804000] 172720 ms: Scavenge 1214.8 (1437.4) -> 1199.8 (1438.4) MB, 3.3 / 0.0 ms (average mu = 0.282, current mu = 0.184) allocation failure
[38003:0x102804000] 173260 ms: Mark-sweep 1215.2 (1438.4) -> 1196.5 (1436.4) MB, 516.1 / 0.0 ms (average mu = 0.387, current mu = 0.474) allocation failure scavenge might not succeed
[38003:0x102804000] 173326 ms: Scavenge 1212.1 (1436.4) -> 1197.0 (1437.9) MB, 3.5 / 0.0 ms (average mu = 0.387, current mu = 0.474) allocation failure

<--- JS stacktrace --->

==== JS stack trace =========================================

0: ExitFrame [pc: 0x20779e1dbe3d]
1: StubFrame [pc: 0x20779e1dd3c6]

Security context: 0x167c9529e6e9
2: /* anonymous */ [0x167c603a2509] [/Users/USER/FOLDER/github/TOKEN/node_modules/sol-merger/dist/lib/fileAnalyzer.js:~38] [pc=0x20779e668601](this=0x167c603a24e9 )
3: next [0x167c95299de9](this=0x167c603a2841 ,0x167c603babc1 <Very long string[3528]>)
4: fulfi...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
1: 0x10003d035 node::Abort() [/Users/USER/.nvm/versions/node/v10.16.3/bin/node]
2: 0x10003d23f node::OnFatalError(char const*, char const*) [/Users/USER/.nvm/versions/node/v10.16.3/bin/node]
3: 0x1001b8e15 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/Users/USER/.nvm/versions/node/v10.16.3/bin/node]
4: 0x100586d72 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/Users/USER/.nvm/versions/node/v10.16.3/bin/node]
5: 0x100589845 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [/Users/USER/.nvm/versions/node/v10.16.3/bin/node]
6: 0x1005856ef v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/Users/USER/.nvm/versions/node/v10.16.3/bin/node]
7: 0x1005838c4 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/Users/USER/.nvm/versions/node/v10.16.3/bin/node]
8: 0x10059015c v8::internal::Heap::AllocateRawWithLigthRetry(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Users/USER/.nvm/versions/node/v10.16.3/bin/node]
9: 0x1005901df v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Users/USER/.nvm/versions/node/v10.16.3/bin/node]
10: 0x10055fb24 v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [/Users/USER/.nvm/versions/node/v10.16.3/bin/node]
11: 0x1007e7e04 v8::internal::Runtime_AllocateInNewSpace(int, v8::internal::Object**, v8::internal::Isolate*) [/Users/USER/.nvm/versions/node/v10.16.3/bin/node]
12: 0x20779e1dbe3d
Abort trap: 6

"Invalid constructor arguments" error, running immediately after deployment

Hello, I'm running:

truffle migrate --network mainnet --reset

And then I'm immediately running

truffle run verify ContractName@address --network mainnet

and I get "Invalid constructor arguments provided. Please verify that they are in ABI-encoded format".

How can they be invalid when I've only just deployed it?

Btw. I love this plugin so much :) it has worked many times in the past

Fix "ParserError: Multiple SPDX license identifiers found in source file"

When you have two contracts, one depending form another, since solc v0.6.8, all of them should contain the SPDX license.

When I try truffle run verify it would yield the error

General exception occured when attempting to insert record 
Failed to verify 1 contract(s): <name of your contact>

If I do manually npx truffle-flattener and upload it for etherscan I get the more detailed error:

Error! Unable to generate Contract ByteCode and ABI (General Exception, unable to get compiled [bytecode])
...
myc: ParserError: Multiple SPDX license identifiers found in source file. Use "AND" or "OR" to combine multiple licenses. Please see https://spdx.org for more information.
  • when I remove the duplicates of // SPDX-License-Identifier from contact before upload to etherscan this error disappears. So I assume that corresponding fix is needed.

Can't verify contract

Hello, I updated to 0.5.1 and this is the first time having issues verifying a contract with your plugin.

Code is at: Macarse/yearn-truffle-verify@b443582
output.txt

The output.txt is after running:
truffle run verify GenericDyDx@0xeBb622A21Cc341E3A293E892D16C34A39f8b3c34 --network infuraMainnet

Any idea how to debug?

Multi-file verification file order

When verifying with multi-file verification, the plugin orders the files alphabetically by file path. A more intuitive orde would be by their appearance in the source code. This was discussed while implementing multi-file verification (see #37).

I proposed an algorithm like this:

for node in artifact.ast.nodes:
  if node.nodeType == "ImportDirective":
    add node.absolutePath to ordered list of source paths
    compute the artifact path for this source path
    recursively apply the same algorithm to this artifact's AST

But that turned out to be more difficult because of this:

I tried to do this today, but I ran into some issues in the step "compute the artifact path for this source path", since it's pretty difficult to find out the artifact file(s) corresponding to a Solidity file, since a file can include one or more contracts with different names.

So we'll have to figure out the best way to get the correct ordering.

Support multi file verification on Etherscan

Feature Request

Support multi file verification on Etherscan using Truffle.
This is instead of flattening contracts.

Flattened contracts:

  • Can only contain one SPDX License Identifier (introduced in Solidity 0.6.8) per file. Risking license identifiers being removed, especially from third party libraries.
  • Remove import statements, making it harder to identify how contracts have been imported and from what sources such as an installed npm package
  • Generally harder to ready and identify any inheritance used, including third party libraries such as OpenZeppelin Contracts.

Steps to Reproduce

Verify the following contract inheriting from OpenZeppelin Contracts v3.2.0

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

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

/**
 * @title SimpleToken
 * @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
 * Note they can later distribute these tokens as they wish using `transfer` and other
 * `ERC20` functions.
 */
contract SimpleToken is ERC20 {
    /**
     * @dev Constructor that gives msg.sender all of existing tokens.
     */
    constructor() public ERC20("Simple Token", "SIM") {
        _mint(msg.sender, 100000000 * (10**uint256(decimals())));
    }
}

Ideal Behavior

Ideally the contract would be verified as multiple files.
The following example shows the six files that make up the contract:
https://rinkeby.etherscan.io/address/0x3fFfF0a40E2E3152ab35D78cC49218dD2C35c6cc#code

The contract was verified using https://github.com/nomiclabs/buidler/tree/development/packages/buidler-etherscan which ideally there would be a Truffle plugin that supports multi file verification.

Actual Results

https://github.com/rkalis/truffle-plugin-verify flattens the contracts, removes SPDX License Identifiers and replaces with a single SPDX License Identifier and removes imports so that the contract can compile.

The following example shows a single flattened file for the contract:
https://rinkeby.etherscan.io/address/0x5D226974f9ce71179a68B8EDcC7EeE99df8FC3C5#code

Environment

  • Operating System: WSL2 Ubuntu 18.0.4
  • Truffle version:
$ npx truffle version
Truffle v5.1.44 (core: 5.1.44)
Solidity - 0.6.12 (solc-js)
Node v10.21.0
Web3.js v1.2.1

First raised in Truffle: trufflesuite/truffle#3366

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.