diff --git a/addresses.json b/addresses.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/addresses.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/hardhat.config.js b/hardhat.config.js index 4ab2158..dcfbb32 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -5,7 +5,8 @@ require('@nomiclabs/hardhat-waffle'); require('@nomiclabs/hardhat-solhint'); require('solidity-coverage'); - + require("@nomiclabs/hardhat-etherscan"); + module.exports = { defaultNetwork: "hardhat", solidity: { @@ -28,7 +29,7 @@ blockNumber: 11997864, } }, - + mainnet: { accounts: { mnemonic: process.env.MNEMONIC @@ -37,7 +38,7 @@ chainId: 1, timeout: 2000000 }, - + kovan: { accounts: { mnemonic: process.env.MNEMONIC @@ -46,7 +47,7 @@ chainId: 42, timeout: 2000000 }, - + binance: { accounts: { mnemonic: process.env.MNEMONIC @@ -55,7 +56,7 @@ chainId: 56, timeout: 20000000 }, - + matic: { accounts: { mnemonic: process.env.MNEMONIC @@ -64,11 +65,13 @@ chainId: 137, timeout: 20000000 }, - }, - + + etherscan: { + apiKey: process.env.ETHERSCAN_API_KEY + }, + mocha: { timeout: 2000000 } }; - \ No newline at end of file diff --git a/package.json b/package.json index e754dce..a4dc1b3 100644 --- a/package.json +++ b/package.json @@ -7,12 +7,12 @@ "test": "npx hardhat test", "build": "hardhat compile", "console": "hardhat console", - "verify": "yarn hint && yarn test", "lint": "yarn solhint 'contracts/**/*.sol' && yarn prettier -c './**/*.js'", "format": "yarn prettier --write contracts/*.sol && yarn prettier --write test/*.js", "hint": "solhint \"contracts/**/*.sol\"", "coverage": "yarn hardhat coverage --testfiles \"test/*.js\"", - "upgrade-checks": "npx hardhat run scripts/upgradeChecks.js" + "upgrade-checks": "npx hardhat run scripts/upgradeChecks.js", + "verify": "npx hardhat run scripts/verify.js" }, "repository": { "type": "git", @@ -32,6 +32,7 @@ }, "devDependencies": { "@nomiclabs/hardhat-ethers": "^2.0.1", + "@nomiclabs/hardhat-etherscan": "^2.1.3", "@nomiclabs/hardhat-solhint": "^2.0.0", "@nomiclabs/hardhat-waffle": "^2.0.1", "chai": "^4.3.3", diff --git a/scripts/deploy.js b/scripts/deploy.js index 8e9d1a2..0ad9c2e 100644 --- a/scripts/deploy.js +++ b/scripts/deploy.js @@ -1,16 +1,17 @@ const config = require('../config.json'); +const fs = require('fs'); +let root = {}; +let network = 'mainnet'; async function main() { const addr = config.addresses; const netinfo = await ethers.provider.getNetwork(); - var network = netinfo.chainId === 1 ? "mainnet" : - netinfo.chainId === 42 ? "kovan" : - netinfo.chainId === 56 ? "binance" : - netinfo.chainId === 137 ? "matic" : - "mainnet"; - if (network === "unknown") - network = "mainnet"; + network = netinfo.chainId === 1 ? "mainnet" : + netinfo.chainId === 42 ? "kovan" : + netinfo.chainId === 56 ? "binance" : + netinfo.chainId === 137 ? "matic" : + "mainnet"; const chainId = netinfo.chainId; console.log("============================================================"); @@ -37,7 +38,7 @@ async function main() { // plexus reward token const PlexusCoin = await ethers.getContractFactory('PlexusTestCoin'); - + // get the signers let owner, addr1; [owner, addr1, ...addrs] = await ethers.getSigners(); @@ -50,8 +51,8 @@ async function main() { // then deploy the contracts and wait for them to be mined if (network === 'mainnet') { const wrapper = await deployWithProxy( - Wrapper, - OwnableProxy, + Wrapper, + OwnableProxy, 'WrapAndUnWrap', addr.tokens.WETH[network], addr.swaps.uniswap[network], @@ -63,8 +64,8 @@ async function main() { console.log("Wrapper is deployed at: ", wrapper.address); const wrapperSushi = await deployWithProxy( - WrapperSushi, - OwnableProxy, + WrapperSushi, + OwnableProxy, 'WrapAndUnWrapSushi', addr.tokens.WETH[network], addr.swaps.sushiswap[network], @@ -81,115 +82,115 @@ async function main() { 'TokenRewards' ); console.log("TokenRewards is deployed at: ", tokenRewards.address); - + const plexusOracle = await deployWithProxy( - PlexusOracle, - OwnableProxy, + PlexusOracle, + OwnableProxy, 'PlexusOracle', addr.swaps.uniswap[network], addr.tokens.USDC[network] ); console.log("PlexusOracle is deployed at: ", plexusOracle.address); - + const tier2Farm = await deployWithProxy( - Tier2Farm, - OwnableProxy, + Tier2Farm, + OwnableProxy, 'Tier2FarmController', addr.AutoStake[network], addr.tokens.FARM[network] ); console.log("Tier2Farm is deployed at: ", tier2Farm.address); - + const tier1Staking = await deployWithProxy( - Tier1Staking, - OwnableProxy, + Tier1Staking, + OwnableProxy, 'Tier1FarmController', tier2Farm.address, plexusOracle.address ); console.log("Tier1Staking is deployed at: ", tier1Staking.address); - + const core = await deployWithProxy( - Core, - OwnableProxy, + Core, + OwnableProxy, 'Core', addr.tokens.WETH[network], wrapper.address ); console.log("Core is deployed at: ", core.address); - + const tier2Aave = await deployWithProxy( - Tier2Aave, - OwnableProxy, + Tier2Aave, + OwnableProxy, 'Tier2AaveFarmController', addr.AaveLendingPoolV2[network], addr.tokens.DAI[network], addr.tokens.aDAI[network] ); console.log("Tier2Aave is deployed at: ", tier2Aave.address); - + const tier2Pickle = await deployWithProxy( - Tier2Pickle, - OwnableProxy, + Tier2Pickle, + OwnableProxy, 'Tier2PickleFarmController', addr.StakingRewards[network], addr.tokens.PICKLE[network] ); console.log("Tier2Pickle is deployed at: ", tier2Pickle.address); - + const lp2lp = await deployWithProxy( - LP2LP, - OwnableProxy, + LP2LP, + OwnableProxy, 'LP2LP', addr.tokens.vBNT[network] ); console.log("LP2LP is deployed at: ", lp2lp.address); - + const tier2Aggregator = await deployWithProxy( - Tier2Aggregator, - OwnableProxy, + Tier2Aggregator, + OwnableProxy, 'Tier2AggregatorFarmController', addr.tokens.pUNI_V2[network], addr.tokens.UNI_V2[network] ); console.log("Tier2Aggregator is deployed at: ", tier2Aggregator.address); - + const plexusCoin = await (await PlexusCoin.deploy()).deployed(); console.log("PlexusCoin is deployed at: ", plexusCoin.address); // airdrop const airdrop = await deployWithProxy( - Airdrop, - OwnableProxy, + Airdrop, + OwnableProxy, 'Airdrop', plexusCoin.address, [addr1.address, addrs[0].address] ); console.log("Airdrop is deployed at: ", airdrop.address); - + console.log(""); // then setup the contracts console.log("Setting up contracts... "); await tokenRewards.updateOracleAddress(plexusOracle.address); await tokenRewards.updateStakingTokenAddress(plexusCoin.address); - + await plexusOracle.updateRewardAddress(tokenRewards.address); await plexusOracle.updateCoreAddress(core.address); await plexusOracle.updateTier1Address(tier1Staking.address); - + await core.setOracleAddress(plexusOracle.address); await core.setStakingAddress(tier1Staking.address); await core.setConverterAddress(wrapper.address); - + await tier1Staking.updateOracleAddress(plexusOracle.address); - + console.log(""); // setup tier 1 staking console.log("Setting up Tier1Staking... "); await tier1Staking.addOrEditTier2ChildStakingContract("FARM", tier2Farm.address); await tier1Staking.addOrEditTier2ChildStakingContract("DAI", tier2Aave.address); await tier1Staking.addOrEditTier2ChildStakingContract("PICKLE", tier2Pickle.address); - + console.log(""); // setup ownership of tier2 contracts ownership console.log("Setting up ownerships of Tier2 contracts... "); @@ -198,8 +199,8 @@ async function main() { await tier2Pickle.changeOwner(tier1Staking.address); } else if (network === 'binance') { const wrapper = await deployWithProxy( - Wrapper, - OwnableProxy, + Wrapper, + OwnableProxy, 'WrapAndUnWrap', addr.tokens.WETH[network], addr.swaps.pancakeswap[network], @@ -216,54 +217,54 @@ async function main() { 'TokenRewards' ); console.log("TokenRewards is deployed at: ", tokenRewards.address); - + const plexusOracle = await deployWithProxy( - PlexusOracle, - OwnableProxy, + PlexusOracle, + OwnableProxy, 'PlexusOracle', addr.swaps.pancakeswap[network], addr.tokens.USDC[network] ); console.log("PlexusOracle is deployed at: ", plexusOracle.address); - + const core = await deployWithProxy( - Core, - OwnableProxy, + Core, + OwnableProxy, 'Core', addr.tokens.WETH[network], wrapper.address ); console.log("Core is deployed at: ", core.address); - + const plexusCoin = await (await PlexusCoin.deploy()).deployed(); console.log("PlexusCoin is deployed at: ", plexusCoin.address); // airdrop const airdrop = await deployWithProxy( - Airdrop, - OwnableProxy, + Airdrop, + OwnableProxy, 'Airdrop', plexusCoin.address, [addr1.address, addrs[0].address] ); console.log("Airdrop is deployed at: ", airdrop.address); - + console.log(""); // then setup the contracts console.log("Setting up contracts... "); await tokenRewards.updateOracleAddress(plexusOracle.address); await tokenRewards.updateStakingTokenAddress(plexusCoin.address); - + await plexusOracle.updateRewardAddress(tokenRewards.address); await plexusOracle.updateCoreAddress(core.address); await plexusOracle.updateTier1Address(tier1Staking.address); - + await core.setOracleAddress(plexusOracle.address); await core.setConverterAddress(wrapper.address); } else if (network === 'matic') { const wrapper = await deployWithProxy( - Wrapper, - OwnableProxy, + Wrapper, + OwnableProxy, 'WrapAndUnWrap', addr.tokens.WETH[network], addr.swaps.quickswap[network], @@ -280,54 +281,54 @@ async function main() { 'TokenRewards' ); console.log("TokenRewards is deployed at: ", tokenRewards.address); - + const plexusOracle = await deployWithProxy( - PlexusOracle, - OwnableProxy, + PlexusOracle, + OwnableProxy, 'PlexusOracle', addr.swaps.quickswap[network], addr.tokens.USDC[network] ); console.log("PlexusOracle is deployed at: ", plexusOracle.address); - + const core = await deployWithProxy( - Core, - OwnableProxy, + Core, + OwnableProxy, 'Core', addr.tokens.WETH[network], wrapper.address ); console.log("Core is deployed at: ", core.address); - + const plexusCoin = await (await PlexusCoin.deploy()).deployed(); console.log("PlexusCoin is deployed at: ", plexusCoin.address); // airdrop const airdrop = await deployWithProxy( - Airdrop, - OwnableProxy, + Airdrop, + OwnableProxy, 'Airdrop', plexusCoin.address, [addr1.address, addrs[0].address] ); console.log("Airdrop is deployed at: ", airdrop.address); - + console.log(""); // then setup the contracts console.log("Setting up contracts... "); await tokenRewards.updateOracleAddress(plexusOracle.address); await tokenRewards.updateStakingTokenAddress(plexusCoin.address); - + await plexusOracle.updateRewardAddress(tokenRewards.address); await plexusOracle.updateCoreAddress(core.address); await plexusOracle.updateTier1Address(tier1Staking.address); - + await core.setOracleAddress(plexusOracle.address); await core.setConverterAddress(wrapper.address); } else { const wrapper = await deployWithProxy( - Wrapper, - OwnableProxy, + Wrapper, + OwnableProxy, 'WrapAndUnWrap', addr.tokens.WETH[network], addr.swaps.uniswap[network], @@ -339,8 +340,8 @@ async function main() { console.log("Wrapper is deployed at: ", wrapper.address); const wrapperSushi = await deployWithProxy( - WrapperSushi, - OwnableProxy, + WrapperSushi, + OwnableProxy, 'WrapAndUnWrapSushi', addr.tokens.WETH[network], addr.swaps.sushiswap[network], @@ -357,115 +358,115 @@ async function main() { 'TokenRewards' ); console.log("TokenRewards is deployed at: ", tokenRewards.address); - + const plexusOracle = await deployWithProxy( - PlexusOracle, - OwnableProxy, + PlexusOracle, + OwnableProxy, 'PlexusOracle', addr.swaps.uniswap[network], addr.tokens.USDC[network] ); console.log("PlexusOracle is deployed at: ", plexusOracle.address); - + const tier2Farm = await deployWithProxy( - Tier2Farm, - OwnableProxy, + Tier2Farm, + OwnableProxy, 'Tier2FarmController', addr.AutoStake[network], addr.tokens.FARM[network] ); console.log("Tier2Farm is deployed at: ", tier2Farm.address); - + const tier1Staking = await deployWithProxy( - Tier1Staking, - OwnableProxy, + Tier1Staking, + OwnableProxy, 'Tier1FarmController', tier2Farm.address, plexusOracle.address ); console.log("Tier1Staking is deployed at: ", tier1Staking.address); - + const core = await deployWithProxy( - Core, - OwnableProxy, + Core, + OwnableProxy, 'Core', addr.tokens.WETH[network], wrapper.address ); console.log("Core is deployed at: ", core.address); - + const tier2Aave = await deployWithProxy( - Tier2Aave, - OwnableProxy, + Tier2Aave, + OwnableProxy, 'Tier2AaveFarmController', addr.AaveLendingPoolV2[network], addr.tokens.DAI[network], addr.tokens.aDAI[network] ); console.log("Tier2Aave is deployed at: ", tier2Aave.address); - + const tier2Pickle = await deployWithProxy( - Tier2Pickle, - OwnableProxy, + Tier2Pickle, + OwnableProxy, 'Tier2PickleFarmController', addr.StakingRewards[network], addr.tokens.PICKLE[network] ); console.log("Tier2Pickle is deployed at: ", tier2Pickle.address); - + const lp2lp = await deployWithProxy( - LP2LP, - OwnableProxy, + LP2LP, + OwnableProxy, 'LP2LP', addr.tokens.vBNT[network] ); console.log("LP2LP is deployed at: ", lp2lp.address); - + const tier2Aggregator = await deployWithProxy( - Tier2Aggregator, - OwnableProxy, + Tier2Aggregator, + OwnableProxy, 'Tier2AggregatorFarmController', addr.tokens.pUNI_V2[network], addr.tokens.UNI_V2[network] ); console.log("Tier2Aggregator is deployed at: ", tier2Aggregator.address); - + const plexusCoin = await (await PlexusCoin.deploy()).deployed(); console.log("PlexusCoin is deployed at: ", plexusCoin.address); // airdrop const airdrop = await deployWithProxy( - Airdrop, - OwnableProxy, + Airdrop, + OwnableProxy, 'Airdrop', plexusCoin.address, [addr1.address, addrs[0].address] ); console.log("Airdrop is deployed at: ", airdrop.address); - + console.log(""); // then setup the contracts console.log("Setting up contracts... "); await tokenRewards.updateOracleAddress(plexusOracle.address); await tokenRewards.updateStakingTokenAddress(plexusCoin.address); - + await plexusOracle.updateRewardAddress(tokenRewards.address); await plexusOracle.updateCoreAddress(core.address); await plexusOracle.updateTier1Address(tier1Staking.address); - + await core.setOracleAddress(plexusOracle.address); await core.setStakingAddress(tier1Staking.address); await core.setConverterAddress(wrapper.address); - + await tier1Staking.updateOracleAddress(plexusOracle.address); - + console.log(""); // setup tier 1 staking console.log("Setting up Tier1Staking... "); await tier1Staking.addOrEditTier2ChildStakingContract("FARM", tier2Farm.address); await tier1Staking.addOrEditTier2ChildStakingContract("DAI", tier2Aave.address); await tier1Staking.addOrEditTier2ChildStakingContract("PICKLE", tier2Pickle.address); - + console.log(""); // setup ownership of tier2 contracts ownership console.log("Setting up ownerships of Tier2 contracts... "); @@ -474,6 +475,11 @@ async function main() { await tier2Pickle.changeOwner(tier1Staking.address); } + console.log("Write addresses") + const json = JSON.stringify(root); + + fs.writeFileSync('addresses.json', json); + console.log(""); console.log("Successfully Deployed!"); console.log("============================================================"); @@ -481,13 +487,24 @@ async function main() { const deployWithProxy = async(contractFactory, proxyFactory, factoryName, ...params) => { let deployedContract = await (await contractFactory.deploy()).deployed(); + await writeAddress(factoryName, deployedContract.address, []) const deployedProxy = await (await proxyFactory.deploy(deployedContract.address)).deployed(); await deployedContract.setProxy(deployedProxy.address); deployedContract = await ethers.getContractAt(factoryName, deployedProxy.address); await deployedContract.initialize(...params); + await writeAddress(factoryName + 'Proxy', deployedProxy.address, []) + return deployedContract; } - + +const writeAddress = async (factoryName, address, args) => { + root[factoryName] = {} + root[factoryName][network] = { + address, + args + } +} + main() .then(() => process.exit(0)) .catch(error => { diff --git a/scripts/verify.js b/scripts/verify.js new file mode 100644 index 0000000..6ee1cd5 --- /dev/null +++ b/scripts/verify.js @@ -0,0 +1,78 @@ +const addresses = require('../addresses.json'); +const hre = require("hardhat"); + +async function main() { + const netinfo = await ethers.provider.getNetwork(); + let network = netinfo.name; + if (network === "unknown") + network = "mainnet"; + + // Verify Wrapper and Wrapper Proxy + const wrapper = addresses.WrapAndUnWrap + verifyContract(wrapper, network) + const wrapperProxy = addresses.WrapAndUnWrapProxy + verifyContract(wrapperProxy, network) + const wrapperSushi = addresses.WrapAndUnWrapSushi + verifyContract(wrapperSushi, network) + const wrapperSushiProxy = addresses.WrapAndUnWrapSushiProxy + verifyContract(wrapperSushiProxy, network) + const tokenRewards = addresses.TokenRewards + verifyContract(tokenRewards, network) + const tokenRewardsProxy = addresses.TokenRewardsProxy + verifyContract(tokenRewardsProxy, network) + const plexusOracle = addresses.PlexusOracle + verifyContract(plexusOracle, network) + const plexusOracleProxy = addresses.PlexusOracleProxy + verifyContract(plexusOracleProxy, network) + const tier1Staking = addresses.Tier1FarmController + verifyContract(tier1Staking, network) + const tier1StakingProxy = addresses.Tier1FarmControllerProxy + verifyContract(tier1StakingProxy, network) + const core = addresses.Core + verifyContract(core, network) + const coreProxy = addresses.CoreProxy + verifyContract(coreProxy, network) + const tier2Farm = addresses.Tier2FarmController + verifyContract(tier2Farm, network) + const tier2FarmProxy = addresses.Tier2FarmControllerProxy + verifyContract(tier2FarmProxy, network) + const tier2Aave = addresses.Tier2AaveFarmController + verifyContract(tier2Aave, network) + const tier2AaveProxy = addresses.Tier2AaveFarmControllerProxy + verifyContract(tier2AaveProxy, network) + const tier2Pickle = addresses.Tier2PickleFarmController + verifyContract(tier2Pickle, network) + const tier2PickleProxy = addresses.Tier2PickleFarmControllerProxy + verifyContract(tier2PickleProxy, network) + const lP2LP = addresses.LP2LP + verifyContract(lP2LP, network) + const lP2LPProxy = addresses.LP2LPProxy + verifyContract(lP2LPProxy, network) + const tier2Aggregator = addresses.Tier2AggregatorFarmController + verifyContract(tier2Aggregator, network) + const tier2AggregatorProxy = addresses.Tier2AggregatorFarmControllerProxy + verifyContract(tier2AggregatorProxy, network) + + console.log("============================================================"); +} + +function verifyContract(contractInfo, network) { + if (contractInfo) { + const contract = contractInfo[network] + if (contract) { + if (contract && contract.address.length > 0) { + hre.run("verify:verify", { + address: contract.address, + constructorArguments: contract.args || [], + }); + } + } + } +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + });