@dydxfoundation/governance
Version:
dYdX governance smart contracts
114 lines (113 loc) • 6.15 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.fundGrantsProgramNoProposal = exports.fundGrantsProgramViaProposal = void 0;
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const config_1 = __importDefault(require("../../src/config"));
const deploy_config_1 = require("../../src/deploy-config");
const get_deployer_address_1 = require("../../src/deploy-config/get-deployer-address");
const logging_1 = require("../../src/lib/logging");
const util_1 = require("../../src/lib/util");
const grants_program_proposal_1 = require("../../src/migrations/grants-program-proposal");
const impersonate_account_1 = require("../../src/migrations/helpers/impersonate-account");
const types_1 = require("../../types");
const evm_1 = require("../helpers/evm");
const MOCK_PROPOSAL_IPFS_HASH = ('0x0000000000000000000000000000000000000000000000000000000000000000');
async function fundGrantsProgramViaProposal({ dydxTokenAddress, governorAddress, shortTimelockAddress, communityTreasuryAddress, dgpMultisigAddress, }) {
const deployConfig = (0, deploy_config_1.getDeployConfig)();
const deployer = await (0, get_deployer_address_1.getDeployerSigner)();
const dydxToken = new types_1.DydxToken__factory(deployer).attach(dydxTokenAddress);
const governor = new types_1.DydxGovernor__factory(deployer).attach(governorAddress);
await fundCommunityTreasuryFromFoundationIfNecessary({
dydxTokenAddress,
communityTreasuryAddress,
minTreasuryBalance: deployConfig.DGP_FUNDING_AMOUNT,
});
// Pick a voter with enough tokens to meet the quorum requirement.
const voterAddress = deployConfig.TOKEN_ALLOCATIONS.DYDX_TRADING.ADDRESS;
const voter = await (0, impersonate_account_1.impersonateAndFundAccount)(voterAddress);
const voterBalance = await dydxToken.balanceOf(voterAddress);
if (voterBalance.lt(new bignumber_js_1.default('2e25').toFixed())) {
throw new Error('Not enough votes to pass the proposal.');
}
// Vote on an existing proposal (can be used with mainnet forking).
let proposalId;
if (config_1.default.FUND_GRANTS_PROGRAM_PROPOSAL_ID !== null) {
proposalId = config_1.default.FUND_GRANTS_PROGRAM_PROPOSAL_ID;
}
else {
(0, logging_1.log)('Creating proposal');
({ proposalId } = await (0, grants_program_proposal_1.createGrantsProgramProposal)({
proposalIpfsHashHex: MOCK_PROPOSAL_IPFS_HASH,
dydxTokenAddress,
governorAddress,
shortTimelockAddress,
communityTreasuryAddress,
dgpMultisigAddress,
signer: voter,
}));
(0, logging_1.log)('Waiting for voting to begin');
for (let i = 0; i < deployConfig.VOTING_DELAY_BLOCKS + 1; i++) {
if (i > 0 && i % 2000 === 0) {
(0, logging_1.log)('mining', i);
}
await (0, evm_1.advanceBlock)();
}
}
let proposalState = await governor.getProposalState(proposalId);
if (proposalState !== 2) {
throw new Error('Expected proposal to be in the voting phase.');
}
(0, logging_1.log)('Submitting vote');
await (0, util_1.waitForTx)(await governor.connect(voter).submitVote(proposalId, true));
(0, logging_1.log)('Waiting for voting to end');
let minedCount = 0;
for (;;) {
for (let i = 0; i < 2000; i++) {
await (0, evm_1.advanceBlock)();
minedCount++;
}
(0, logging_1.log)('mining', minedCount);
proposalState = await governor.getProposalState(proposalId);
if (proposalState !== 2) {
break;
}
}
if (proposalState !== 4) {
throw new Error(`Expected proposal to have succeeded but state was ${proposalState}`);
}
(0, logging_1.log)('Queueing the proposal');
await (0, util_1.waitForTx)(await governor.queue(proposalId));
const delaySeconds = deployConfig.SHORT_TIMELOCK_CONFIG.DELAY;
await (0, evm_1.increaseTimeAndMine)(delaySeconds);
(0, logging_1.log)('Executing the proposal');
await (0, util_1.waitForTx)(await governor.execute(proposalId));
(0, logging_1.log)('Proposal executed');
(0, logging_1.log)('\n=== GRANTS PROGRAM FUNDING COMPLETE ===\n');
}
exports.fundGrantsProgramViaProposal = fundGrantsProgramViaProposal;
async function fundGrantsProgramNoProposal({ dydxTokenAddress, shortTimelockAddress, communityTreasuryAddress, dgpMultisigAddress, }) {
const deployConfig = (0, deploy_config_1.getDeployConfig)();
const mockShortTimelock = await (0, impersonate_account_1.impersonateAndFundAccount)(shortTimelockAddress);
const communityTreasury = new types_1.Treasury__factory(mockShortTimelock).attach(communityTreasuryAddress);
await fundCommunityTreasuryFromFoundationIfNecessary({
dydxTokenAddress,
communityTreasuryAddress,
minTreasuryBalance: deployConfig.DGP_FUNDING_AMOUNT,
});
await (0, util_1.waitForTx)(await communityTreasury.transfer(dydxTokenAddress, dgpMultisigAddress, deployConfig.DGP_FUNDING_AMOUNT));
(0, logging_1.log)('\n=== GRANTS PROGRAM FUNDING COMPLETE ===\n');
}
exports.fundGrantsProgramNoProposal = fundGrantsProgramNoProposal;
async function fundCommunityTreasuryFromFoundationIfNecessary({ dydxTokenAddress, communityTreasuryAddress, minTreasuryBalance, }) {
const deployConfig = (0, deploy_config_1.getDeployConfig)();
const mockFoundation = await (0, impersonate_account_1.impersonateAndFundAccount)(deployConfig.TOKEN_ALLOCATIONS.DYDX_FOUNDATION.ADDRESS);
const dydxToken = new types_1.DydxToken__factory(mockFoundation).attach(dydxTokenAddress);
const communityTreasuryBalance = await dydxToken.balanceOf(communityTreasuryAddress);
if (communityTreasuryBalance.lt(minTreasuryBalance)) {
// Transfer necessary funds to the treasury.
await (0, util_1.waitForTx)(await dydxToken.transfer(communityTreasuryAddress, minTreasuryBalance));
}
}