mirror of
https://github.com/Instadapp/dsa-governance.git
synced 2024-07-29 22:27:52 +00:00
Merge pull request #3 from Instadapp/deployment-script
Deployment script
This commit is contained in:
commit
3e554c4f3a
|
@ -0,0 +1,3 @@
|
||||||
|
ALCHEMY_ID="<>"
|
||||||
|
ETHERSCAN="<>"
|
||||||
|
PRIVATE_KEY="<>"
|
|
@ -9,15 +9,15 @@ import {
|
||||||
} from "./GovernorBravoInterfaces.sol";
|
} from "./GovernorBravoInterfaces.sol";
|
||||||
import { SafeMath } from "./SafeMath.sol";
|
import { SafeMath } from "./SafeMath.sol";
|
||||||
|
|
||||||
contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoEvents {
|
contract InstaGovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoEvents {
|
||||||
/// @notice The name of this contract
|
/// @notice The name of this contract
|
||||||
string public constant name = "DSL Governor Bravo";
|
string public constant name = "DSL Governor Bravo";
|
||||||
|
|
||||||
/// @notice The minimum setable proposal threshold
|
/// @notice The minimum setable proposal threshold
|
||||||
uint public constant MIN_PROPOSAL_THRESHOLD = 50000e18; // TODO - Update this
|
uint public constant MIN_PROPOSAL_THRESHOLD = 500000e18; // 500,000
|
||||||
|
|
||||||
/// @notice The maximum setable proposal threshold
|
/// @notice The maximum setable proposal threshold
|
||||||
uint public constant MAX_PROPOSAL_THRESHOLD = 100000e18; // TODO - Update this
|
uint public constant MAX_PROPOSAL_THRESHOLD = 50000000e18; // 5,000,000
|
||||||
|
|
||||||
/// @notice The minimum setable voting period
|
/// @notice The minimum setable voting period
|
||||||
uint public constant MIN_VOTING_PERIOD = 5760; // About 24 hours
|
uint public constant MIN_VOTING_PERIOD = 5760; // About 24 hours
|
||||||
|
@ -32,7 +32,7 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoE
|
||||||
uint public constant MAX_VOTING_DELAY = 40320; // About 1 week
|
uint public constant MAX_VOTING_DELAY = 40320; // About 1 week
|
||||||
|
|
||||||
/// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed
|
/// @notice The number of votes in support of a proposal required in order for a quorum to be reached and for a vote to succeed
|
||||||
uint public constant quorumVotes = 400000e18; // TODO - Update this
|
uint public constant quorumVotes = 4000000e18; // 4,000,000
|
||||||
|
|
||||||
/// @notice The maximum number of actions that can be included in a proposal
|
/// @notice The maximum number of actions that can be included in a proposal
|
||||||
uint public constant proposalMaxOperations = 10; // 10 actions
|
uint public constant proposalMaxOperations = 10; // 10 actions
|
||||||
|
@ -93,22 +93,6 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV1, GovernorBravoE
|
||||||
uint endBlock = SafeMath.add(startBlock, votingPeriod);
|
uint endBlock = SafeMath.add(startBlock, votingPeriod);
|
||||||
|
|
||||||
proposalCount++;
|
proposalCount++;
|
||||||
// Proposal memory newProposal = Proposal({
|
|
||||||
// id: proposalCount,
|
|
||||||
// proposer: msg.sender,
|
|
||||||
// eta: 0,
|
|
||||||
// targets: targets,
|
|
||||||
// values: values,
|
|
||||||
// signatures: signatures,
|
|
||||||
// calldatas: calldatas,
|
|
||||||
// startBlock: startBlock,
|
|
||||||
// endBlock: endBlock,
|
|
||||||
// forVotes: 0,
|
|
||||||
// againstVotes: 0,
|
|
||||||
// abstainVotes: 0,
|
|
||||||
// canceled: false,
|
|
||||||
// executed: false
|
|
||||||
// });
|
|
||||||
|
|
||||||
Proposal storage newProposal = proposals[proposalCount];
|
Proposal storage newProposal = proposals[proposalCount];
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
import { GovernorBravoDelegatorStorage, GovernorBravoEvents } from "./GovernorBravoInterfaces.sol";
|
import { GovernorBravoDelegatorStorage, GovernorBravoEvents } from "./GovernorBravoInterfaces.sol";
|
||||||
|
|
||||||
contract GovernorBravoDelegator is GovernorBravoDelegatorStorage, GovernorBravoEvents {
|
contract InstaGovernorBravoDelegator is GovernorBravoDelegatorStorage, GovernorBravoEvents {
|
||||||
constructor(
|
constructor(
|
||||||
address timelock_,
|
address timelock_,
|
||||||
address admin_,
|
address admin_,
|
||||||
|
|
|
@ -2,7 +2,7 @@ pragma solidity ^0.7.0;
|
||||||
|
|
||||||
import "./SafeMath.sol";
|
import "./SafeMath.sol";
|
||||||
|
|
||||||
contract Timelock {
|
contract InstaTimelock {
|
||||||
using SafeMath for uint;
|
using SafeMath for uint;
|
||||||
|
|
||||||
event NewAdmin(address indexed newAdmin);
|
event NewAdmin(address indexed newAdmin);
|
||||||
|
|
|
@ -4,13 +4,12 @@ pragma experimental ABIEncoderV2;
|
||||||
import { TokenDelegateStorageV1, TokenEvents} from "./TokenInterfaces.sol";
|
import { TokenDelegateStorageV1, TokenEvents} from "./TokenInterfaces.sol";
|
||||||
import { SafeMath } from "./SafeMath.sol";
|
import { SafeMath } from "./SafeMath.sol";
|
||||||
|
|
||||||
// TODO @thrilok209 @KaymasJain - Rename it
|
contract InstaTokenDelegate is TokenDelegateStorageV1, TokenEvents {
|
||||||
contract TokenDelegate is TokenDelegateStorageV1, TokenEvents {
|
|
||||||
/// @notice Minimum time between mints
|
/// @notice Minimum time between mints
|
||||||
uint32 public constant minimumTimeBetweenMints = 1 days * 7; // TODO @thrilok209 @KaymasJain - Replace it
|
uint32 public constant minimumTimeBetweenMints = 1 days * 365; // 365 days
|
||||||
|
|
||||||
/// @notice Cap on the percentage of totalSupply that can be minted at each mint
|
/// @notice Cap on the percentage of totalSupply that can be minted at each mint
|
||||||
uint8 public constant mintCap = 2; // TODO @thrilok209 @KaymasJain - Replace it
|
uint8 public constant mintCap = 2; // 2%
|
||||||
|
|
||||||
/// @notice The EIP-712 typehash for the contract's domain
|
/// @notice The EIP-712 typehash for the contract's domain
|
||||||
bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");
|
bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");
|
||||||
|
|
|
@ -3,13 +3,12 @@ pragma experimental ABIEncoderV2;
|
||||||
|
|
||||||
import { TokenDelegatorStorage, TokenEvents } from "./TokenInterfaces.sol";
|
import { TokenDelegatorStorage, TokenEvents } from "./TokenInterfaces.sol";
|
||||||
|
|
||||||
contract TokenDelegator is TokenDelegatorStorage, TokenEvents {
|
contract InstaToken is TokenDelegatorStorage, TokenEvents {
|
||||||
constructor(
|
constructor(
|
||||||
address account,
|
address account,
|
||||||
address implementation_,
|
address implementation_,
|
||||||
uint initialSupply_,
|
uint initialSupply_,
|
||||||
uint mintingAllowedAfter_,
|
uint mintingAllowedAfter_,
|
||||||
uint changeImplementationAfter_,
|
|
||||||
bool transferPaused_
|
bool transferPaused_
|
||||||
) {
|
) {
|
||||||
require(implementation_ != address(0), "TokenDelegator::constructor invalid address");
|
require(implementation_ != address(0), "TokenDelegator::constructor invalid address");
|
||||||
|
@ -26,8 +25,6 @@ contract TokenDelegator is TokenDelegatorStorage, TokenEvents {
|
||||||
|
|
||||||
implementation = implementation_;
|
implementation = implementation_;
|
||||||
|
|
||||||
changeImplementationAfter = changeImplementationAfter_;
|
|
||||||
|
|
||||||
emit NewImplementation(address(0), implementation);
|
emit NewImplementation(address(0), implementation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +34,6 @@ contract TokenDelegator is TokenDelegatorStorage, TokenEvents {
|
||||||
*/
|
*/
|
||||||
function _setImplementation(address implementation_) external isMaster {
|
function _setImplementation(address implementation_) external isMaster {
|
||||||
require(implementation_ != address(0), "TokenDelegator::_setImplementation: invalid implementation address");
|
require(implementation_ != address(0), "TokenDelegator::_setImplementation: invalid implementation address");
|
||||||
require(block.timestamp >= changeImplementationAfter, "TokenDelegator::_setImplementation: can change implementation changeImplementationAfter time only");
|
|
||||||
|
|
||||||
address oldImplementation = implementation;
|
address oldImplementation = implementation;
|
||||||
implementation = implementation_;
|
implementation = implementation_;
|
||||||
|
|
|
@ -39,19 +39,17 @@ contract TokenEvents {
|
||||||
}
|
}
|
||||||
|
|
||||||
contract TokenDelegatorStorage {
|
contract TokenDelegatorStorage {
|
||||||
|
/// @notice InstaIndex contract
|
||||||
IndexInterface constant public instaIndex = IndexInterface(0x2971AdFa57b20E5a416aE5a708A8655A9c74f723);
|
IndexInterface constant public instaIndex = IndexInterface(0x2971AdFa57b20E5a416aE5a708A8655A9c74f723);
|
||||||
|
|
||||||
/// @notice Active brains of Token
|
/// @notice Active brains of Token
|
||||||
address public implementation;
|
address public implementation;
|
||||||
|
|
||||||
/// @notice The timestamp after which implementation maybe change
|
|
||||||
uint public changeImplementationAfter;
|
|
||||||
|
|
||||||
/// @notice EIP-20 token name for this token
|
/// @notice EIP-20 token name for this token
|
||||||
string public name = "<Token Name>"; // TODO - Replace it
|
string public name = "Instadapp";
|
||||||
|
|
||||||
/// @notice EIP-20 token symbol for this token
|
/// @notice EIP-20 token symbol for this token
|
||||||
string public symbol = "<TKN>"; // TODO - Replace it
|
string public symbol = "INST";
|
||||||
|
|
||||||
/// @notice Total number of tokens in circulation
|
/// @notice Total number of tokens in circulation
|
||||||
uint public totalSupply;
|
uint public totalSupply;
|
||||||
|
|
|
@ -4,6 +4,7 @@ require("@nomiclabs/hardhat-etherscan");
|
||||||
|
|
||||||
require("dotenv").config();
|
require("dotenv").config();
|
||||||
const ALCHEMY_ID = process.env.ALCHEMY_ID;
|
const ALCHEMY_ID = process.env.ALCHEMY_ID;
|
||||||
|
const PRIVATE_KEY = process.env.PRIVATE_KEY;
|
||||||
|
|
||||||
// You need to export an object to set up your config
|
// You need to export an object to set up your config
|
||||||
// Go to https://hardhat.org/config/ to learn more
|
// Go to https://hardhat.org/config/ to learn more
|
||||||
|
@ -13,7 +14,15 @@ const ALCHEMY_ID = process.env.ALCHEMY_ID;
|
||||||
*/
|
*/
|
||||||
module.exports = {
|
module.exports = {
|
||||||
defaultNetwork: "hardhat",
|
defaultNetwork: "hardhat",
|
||||||
solidity: "0.7.3",
|
solidity: {
|
||||||
|
version: "0.7.3",
|
||||||
|
settings: {
|
||||||
|
optimizer: {
|
||||||
|
enabled: true,
|
||||||
|
runs: 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
networks: {
|
networks: {
|
||||||
hardhat: {
|
hardhat: {
|
||||||
forking: {
|
forking: {
|
||||||
|
@ -22,9 +31,13 @@ module.exports = {
|
||||||
},
|
},
|
||||||
blockGasLimit: 12000000,
|
blockGasLimit: 12000000,
|
||||||
},
|
},
|
||||||
|
kovan: {
|
||||||
|
url: `https://eth-kovan.alchemyapi.io/v2/${ALCHEMY_ID}`,
|
||||||
|
accounts: [`0x${PRIVATE_KEY}`],
|
||||||
|
gas: 12500000,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
etherscan: {
|
etherscan: {
|
||||||
apiKey: process.env.ETHERSCAN
|
apiKey: process.env.ETHERSCAN
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
3
package-lock.json
generated
3
package-lock.json
generated
|
@ -9,7 +9,8 @@
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nomiclabs/hardhat-etherscan": "^2.1.1",
|
"@nomiclabs/hardhat-etherscan": "^2.1.1",
|
||||||
"dotenv": "^8.2.0"
|
"dotenv": "^8.2.0",
|
||||||
|
"rlp": "^2.2.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nomiclabs/hardhat-etherscan": "^2.1.1",
|
"@nomiclabs/hardhat-etherscan": "^2.1.1",
|
||||||
"dotenv": "^8.2.0"
|
"dotenv": "^8.2.0",
|
||||||
|
"rlp": "^2.2.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
100
scripts/deploy.js
Normal file
100
scripts/deploy.js
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
const hre = require("hardhat");
|
||||||
|
const RLP = require('rlp');
|
||||||
|
const { ethers } = hre;
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const deployerAddress = '0xf6839085F692bDe6A8062573E3DA35E7e947C21E'
|
||||||
|
const initialSupply = ethers.utils.parseEther("100000000") // 100M supply
|
||||||
|
const initialHolder = '0xb1DC62EC38E6E3857a887210C38418E4A17Da5B2'
|
||||||
|
const mintingAfter = 1704067200 // Monday, 1 January 2024 00:00:00
|
||||||
|
const votingPeriod = 17280 // ~3 days in blocks (assuming 15s blocks)
|
||||||
|
const votingDelay = 1 // 1 block
|
||||||
|
const proposalThreshold = ethers.utils.parseEther("1000000") // 1M
|
||||||
|
const timelockDelay = 172800 // ~2 days in blocks (assuming 15s blocks)
|
||||||
|
|
||||||
|
const TokenDelegate = await ethers.getContractFactory("InstaTokenDelegate")
|
||||||
|
const tokenDelegate = await TokenDelegate.deploy()
|
||||||
|
|
||||||
|
await tokenDelegate.deployed()
|
||||||
|
|
||||||
|
const TokenDelegator = await ethers.getContractFactory("InstaToken")
|
||||||
|
const tokenDelegator = await TokenDelegator
|
||||||
|
.deploy(initialHolder, tokenDelegate.address, initialSupply, mintingAfter, false)
|
||||||
|
|
||||||
|
await tokenDelegator.deployed()
|
||||||
|
|
||||||
|
const txCount = await ethers.provider.getTransactionCount(deployerAddress) + 2
|
||||||
|
|
||||||
|
const timelockAddress = '0x' + ethers.utils.keccak256(RLP.encode([deployerAddress, txCount])).slice(12).substring(14)
|
||||||
|
|
||||||
|
const GovernorDelegate = await ethers.getContractFactory("InstaGovernorBravoDelegate")
|
||||||
|
const governorDelegate = await GovernorDelegate.deploy()
|
||||||
|
|
||||||
|
await governorDelegate.deployed()
|
||||||
|
|
||||||
|
const GovernorDelegator = await ethers.getContractFactory("InstaGovernorBravoDelegator")
|
||||||
|
const governorDelegator = await GovernorDelegator
|
||||||
|
.deploy(
|
||||||
|
timelockAddress,
|
||||||
|
timelockAddress,
|
||||||
|
tokenDelegator.address,
|
||||||
|
governorDelegate.address,
|
||||||
|
votingPeriod,
|
||||||
|
votingDelay,
|
||||||
|
proposalThreshold
|
||||||
|
)
|
||||||
|
|
||||||
|
await governorDelegator.deployed()
|
||||||
|
|
||||||
|
const Timelock = await ethers.getContractFactory("InstaTimelock")
|
||||||
|
const timelock = await Timelock.deploy(governorDelegator.address, timelockDelay)
|
||||||
|
|
||||||
|
await timelock.deployed()
|
||||||
|
|
||||||
|
console.log("InstaTokenDelegate: ", tokenDelegate.address)
|
||||||
|
console.log("InstaToken: ", tokenDelegator.address)
|
||||||
|
console.log("InstaTimelock: ", timelock.address)
|
||||||
|
console.log("InstaGovernorBravoDelegate: ", governorDelegate.address)
|
||||||
|
console.log("InstaGovernorBravoDelegator: ", governorDelegator.address)
|
||||||
|
console.log()
|
||||||
|
|
||||||
|
await hre.run("verify:verify", {
|
||||||
|
address: tokenDelegate.address,
|
||||||
|
constructorArguments: []
|
||||||
|
})
|
||||||
|
|
||||||
|
await hre.run("verify:verify", {
|
||||||
|
address: tokenDelegator.address,
|
||||||
|
constructorArguments: [initialHolder, tokenDelegate.address, initialSupply, mintingAfter, false]
|
||||||
|
})
|
||||||
|
|
||||||
|
await hre.run("verify:verify", {
|
||||||
|
address: governorDelegate.address,
|
||||||
|
constructorArguments: []
|
||||||
|
})
|
||||||
|
|
||||||
|
await hre.run("verify:verify", {
|
||||||
|
address: governorDelegator.address,
|
||||||
|
constructorArguments: [
|
||||||
|
timelockAddress,
|
||||||
|
timelockAddress,
|
||||||
|
tokenDelegator.address,
|
||||||
|
governorDelegate.address,
|
||||||
|
votingPeriod,
|
||||||
|
votingDelay,
|
||||||
|
proposalThreshold
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
await hre.run("verify:verify", {
|
||||||
|
address: timelock.address,
|
||||||
|
constructorArguments: [governorDelegator.address, timelockDelay]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
|
.then(() => process.exit(0))
|
||||||
|
.catch(error => {
|
||||||
|
console.error(error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user