UNPKG

@dydxfoundation/governance

Version:
114 lines (113 loc) 6.15 kB
"use strict"; 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)); } }