diff --git a/eth-contracts/common/deployment.ts b/eth-contracts/common/deployment.ts new file mode 100644 index 0000000..eb02d02 --- /dev/null +++ b/eth-contracts/common/deployment.ts @@ -0,0 +1,110 @@ +import { Contract } from "@ethersproject/contracts"; +import { ethers } from "hardhat"; + +interface Environment { + dioneToken: Contract; + dioneStaking: Contract; + dioneDispute: Contract; + dioneOracle: Contract; + mediator: Contract; +} + +interface DeploymentOptions { + reward: number; + minStake: number; + voteWindowTime: number; // in seconds + randomizeStake: boolean; + maxStake: number; // for randomizer + actualStake: number; // of each node + nodeCount: number; +} + +async function deploy(opts: DeploymentOptions): Promise { + const accounts = (await ethers.getSigners()).slice(0, opts.nodeCount); + + const DioneToken = await ethers.getContractFactory("DioneToken"); + const DioneOracle = await ethers.getContractFactory("DioneOracle"); + const DioneDispute = await ethers.getContractFactory("DioneDispute"); + const DioneStaking = await ethers.getContractFactory("DioneStaking"); + const Mediator = await ethers.getContractFactory("Mediator"); + + const dioneToken = await DioneToken.deploy(); + await dioneToken.deployed(); + console.log("DioneToken deployed to:", dioneToken.address); + + const dioneStaking = await DioneStaking.deploy(dioneToken.address, ethers.constants.WeiPerEther.mul(opts.reward), 0, ethers.constants.WeiPerEther.mul(opts.minStake)); + await dioneStaking.deployed(); + console.log("staking_contract_address = \"" + dioneStaking.address+ "\""); + + const dioneDispute = await DioneDispute.deploy(dioneStaking.address, opts.voteWindowTime); + await dioneDispute.deployed(); + console.log("dispute_contract_address = \"" + dioneDispute.address+ "\""); + + const dioneOracle = await DioneOracle.deploy(dioneStaking.address); + await dioneOracle.deployed(); + console.log("oracle_contract_address = \"" + dioneOracle.address+ "\""); + + const mediator = await Mediator.deploy(dioneOracle.address); + await mediator.deployed(); + console.log("mediator_contract_address = \"" + mediator.address +"\"") + + const env: Environment = { + dioneToken: dioneToken, + dioneStaking: dioneStaking, + dioneDispute: dioneDispute, + dioneOracle: dioneOracle, + mediator: mediator + } + + await dioneStaking.setOracleContractAddress(dioneOracle.address); + await dioneStaking.setDisputeContractAddress(dioneDispute.address); + + const stakeForEach: number[] = [] + var mintValue = opts.actualStake*opts.nodeCount + if (opts.randomizeStake) { + var sum = 0; + for (var i = 0; i < opts.nodeCount; i++) { + stakeForEach.push(randomInt(opts.minStake, opts.maxStake)); + sum += stakeForEach[i]; + } + mintValue = sum; + } + + await dioneToken.mint(accounts[0].address, ethers.constants.WeiPerEther.mul(mintValue)); + + var stakeValue = opts.actualStake; + for (var i = 0; i < accounts.length; i++) { + if(accounts[i] == accounts[0]) { + continue; + } + + if (opts.randomizeStake) { + stakeValue = stakeForEach[i]; + } + + await dioneToken.transfer(accounts[i].address, ethers.constants.WeiPerEther.mul(stakeValue)); + } + + await dioneToken.transferOwnership(dioneStaking.address); + + for (var i = 0; i < accounts.length; i++) { + const staking = dioneStaking.connect(accounts[i]); + const token = dioneToken.connect(accounts[i]); + if (opts.randomizeStake) { + stakeValue = stakeForEach[i]; + } + await token.approve(dioneStaking.address, ethers.constants.WeiPerEther.mul(stakeValue)); + await staking.stake(ethers.constants.WeiPerEther.mul(stakeValue)); + const stake = await dioneStaking.minerStake(accounts[i].address); + console.log(accounts[i].address, stake.toString()); + } + + return env; +} + +export default deploy; + +// min and max included +function randomInt(min: number, max: number){ + return Math.floor(Math.random() * (max - min + 1)) + min; +} \ No newline at end of file diff --git a/eth-contracts/hardhat.config.ts b/eth-contracts/hardhat.config.ts index a3fc950..95955a1 100644 --- a/eth-contracts/hardhat.config.ts +++ b/eth-contracts/hardhat.config.ts @@ -15,7 +15,7 @@ task("accounts", "Prints the list of accounts", async (args, hre) => { export default { solidity: "0.8.3", networks: { - ganache: { + geth: { url: `http://localhost:8545`, accounts: { mnemonic: "test test test test test test test test test test test junk" diff --git a/eth-contracts/package.json b/eth-contracts/package.json index b3013be..da273a4 100644 --- a/eth-contracts/package.json +++ b/eth-contracts/package.json @@ -1,11 +1,11 @@ { - "name": "eth-contracts", + "name": "dione-eth-contracts", "version": "1.0.0", "description": "", - "main": "index.js", + "main": "", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "deployLocal": "npx hardhat --network localhost run scripts/deploy.ts" + "test": "TS_NODE_FILES=true npx hardhat test", + "deployLocal": "TS_NODE_FILES=true npx hardhat --network geth run scripts/deploy.ts" }, "author": "", "license": "ISC", diff --git a/eth-contracts/scripts/deploy.ts b/eth-contracts/scripts/deploy.ts index 6ef8c31..91226d6 100644 --- a/eth-contracts/scripts/deploy.ts +++ b/eth-contracts/scripts/deploy.ts @@ -1,58 +1,19 @@ -import { run, ethers } from "hardhat"; +import { run } from "hardhat"; import "@nomiclabs/hardhat-ethers"; +import deploy from "../common/deployment"; async function main() { await run("compile"); - - const DioneToken = await ethers.getContractFactory("DioneToken"); - const DioneOracle = await ethers.getContractFactory("DioneOracle"); - const DioneDispute = await ethers.getContractFactory("DioneDispute"); - const DioneStaking = await ethers.getContractFactory("DioneStaking"); - const Mediator = await ethers.getContractFactory("Mediator"); - - const dioneToken = await DioneToken.deploy(); - await dioneToken.deployed(); - console.log("DioneToken deployed to:", dioneToken.address); - - const dioneStaking = await DioneStaking.deploy(dioneToken.address, ethers.constants.WeiPerEther.mul(100), 0, ethers.constants.WeiPerEther.mul(5000)); - await dioneStaking.deployed(); - console.log("staking_contract_address = \"" + dioneStaking.address+ "\""); - - const dioneDispute = await DioneDispute.deploy(dioneStaking.address, 5); - await dioneDispute.deployed(); - console.log("dispute_contract_address = \"" + dioneDispute.address+ "\""); - - const dioneOracle = await DioneOracle.deploy(dioneStaking.address); - await dioneOracle.deployed(); - console.log("oracle_contract_address = \"" + dioneOracle.address+ "\""); - - const mediator = await Mediator.deploy(dioneOracle.address); - await mediator.deployed(); - console.log("mediator_contract_address = \"" + mediator.address +"\"") - - await dioneStaking.setOracleContractAddress(dioneOracle.address); - await dioneStaking.setDisputeContractAddress(dioneDispute.address); - - const addresses = ["0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", "0x90F79bf6EB2c4f870365E785982E1f101E93b906"] - await dioneToken.mint(addresses[0], ethers.constants.WeiPerEther.mul(50000)); - for (const address of addresses) { - if(address == "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266") { - continue; - } - await dioneToken.transfer(address, ethers.constants.WeiPerEther.mul(6000)); - } - - await dioneToken.transferOwnership(dioneStaking.address); - - const signers = await ethers.getSigners(); - for (var i = 0; i < addresses.length; i++) { - const staking = dioneStaking.connect(signers[i]); - const token = dioneToken.connect(signers[i]); - await token.approve(dioneStaking.address, ethers.constants.WeiPerEther.mul(5000)); - await staking.stake(ethers.constants.WeiPerEther.mul(5000)); - const stake = await dioneStaking.minerStake(addresses[i]); - console.log(addresses[i], stake.toString()); - } + + await deploy({ + reward: 100, + minStake: 5000, + voteWindowTime: 5, + randomizeStake: false, + maxStake: 0, // don't use this deployment feature + actualStake: 5000, + nodeCount: 4 + }); } main() diff --git a/eth-contracts/test/.gitkeep b/eth-contracts/test/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/eth-contracts/test/DioneDispute.ts b/eth-contracts/test/DioneDispute.ts index cf3b74a..b29c9fa 100644 --- a/eth-contracts/test/DioneDispute.ts +++ b/eth-contracts/test/DioneDispute.ts @@ -1,65 +1,26 @@ import { ethers } from "hardhat"; -import { Signer, Contract } from "ethers"; +import { Contract } from "ethers"; import { expect } from "chai"; import { soliditySha3 } from "web3-utils"; +import deploy from "../common/deployment"; describe("DioneDispute", function () { let dioneDispute: Contract; let dioneStaking: Contract; beforeEach(async function () { - const DioneToken = await ethers.getContractFactory("DioneToken"); - const DioneOracle = await ethers.getContractFactory("DioneOracle"); - const DioneDispute = await ethers.getContractFactory("DioneDispute"); - const DioneStaking = await ethers.getContractFactory("DioneStaking"); - const Mediator = await ethers.getContractFactory("Mediator"); + const contracts = await deploy({ + reward: 100, + minStake: 5000, + voteWindowTime: 2, + randomizeStake: false, + maxStake: 0, // don't use this deployment feature + actualStake: 9000, + nodeCount: 4 + }); - const dioneToken = await DioneToken.deploy(); - await dioneToken.deployed(); - console.log("DioneToken deployed to:", dioneToken.address); - - const _dioneStaking = await DioneStaking.deploy(dioneToken.address, ethers.constants.WeiPerEther.mul(100), 0, ethers.constants.WeiPerEther.mul(5000)); - await _dioneStaking.deployed(); - console.log("staking_contract_address = \"" + _dioneStaking.address+ "\""); - - const _dioneDispute = await DioneDispute.deploy(_dioneStaking.address, 2); - await _dioneDispute.deployed(); - console.log("dispute_contract_address = \"" + _dioneDispute.address+ "\""); - - const dioneOracle = await DioneOracle.deploy(_dioneStaking.address); - await dioneOracle.deployed(); - console.log("oracle_contract_address = \"" + dioneOracle.address+ "\""); - - const mediator = await Mediator.deploy(dioneOracle.address); - await mediator.deployed(); - console.log("mediator_contract_address = \"" + mediator.address +"\"") - - await _dioneStaking.setOracleContractAddress(dioneOracle.address); - await _dioneStaking.setDisputeContractAddress(_dioneDispute.address); - - const addresses = ["0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", "0x90F79bf6EB2c4f870365E785982E1f101E93b906"] - await dioneToken.mint(addresses[0], ethers.constants.WeiPerEther.mul(36000)); - for (const address of addresses) { - if(address == "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266") { - continue; - } - await dioneToken.transfer(address, ethers.constants.WeiPerEther.mul(9000)); - } - - await dioneToken.transferOwnership(_dioneStaking.address); - - const signers = await ethers.getSigners(); - for (var i = 0; i < addresses.length; i++) { - const staking = _dioneStaking.connect(signers[i]); - const token = dioneToken.connect(signers[i]); - await token.approve(_dioneStaking.address, ethers.constants.WeiPerEther.mul(9000)); - await staking.stake(ethers.constants.WeiPerEther.mul(9000)); - const stake = await _dioneStaking.minerStake(addresses[i]); - console.log(addresses[i], stake.toString()); - } - - dioneDispute = _dioneDispute; - dioneStaking = _dioneStaking; + dioneDispute = contracts.dioneDispute; + dioneStaking = contracts.dioneStaking; }); it("should create dispute, vote it by various eth addresses and then finish it after 2 secs", async function () { diff --git a/eth-contracts/tsconfig.json b/eth-contracts/tsconfig.json new file mode 100644 index 0000000..d8b1055 --- /dev/null +++ b/eth-contracts/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es2018", + "module": "commonjs", + "strict": true, + "esModuleInterop": true, + "outDir": "dist" + }, + "include": ["./scripts", "./test", "./common"], + "files": ["./hardhat.config.ts"] +} \ No newline at end of file