UNPKG

@dydxfoundation/governance

Version:
202 lines (201 loc) 12.2 kB
"use strict"; /** * Perform all deployments which were used in the dYdX governance mainnet deployment. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.configureForTest = exports.executeGrantsProgramProposalForTest = exports.executeStarkProxyProposalForTest = exports.executeSafetyModuleRecoveryProposalsForTest = exports.deployContractsForTest = void 0; 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 constants_1 = require("../../src/lib/constants"); const deploy_stark_proxy_v2_1 = require("../../src/migrations/deploy-stark-proxy-v2"); const deploy_mocks_1 = require("../../src/migrations/helpers/deploy-mocks"); const impersonate_account_1 = require("../../src/migrations/helpers/impersonate-account"); const phase_1_1 = require("../../src/migrations/phase-1"); const phase_2_1 = require("../../src/migrations/phase-2"); const phase_3_1 = require("../../src/migrations/phase-3"); const safety_module_recovery_1 = require("../../src/migrations/safety-module-recovery"); const evm_1 = require("../helpers/evm"); const affected_stakers_1 = require("./affected-stakers"); const grants_program_proposal_1 = require("./grants-program-proposal"); const safety_module_compensation_1 = require("./safety-module-compensation"); const safety_module_fix_1 = require("./safety-module-fix"); const stark_proxy_fix_1 = require("./stark-proxy-fix"); /** * Perform all deployments steps for the test environment. * * We use the mainnet deployments scripts to mimic the mainnet environment as closely as possible. */ async function deployContractsForTest() { // Phase 1: Deploy core governance contracts. const phase1Contracts = await (0, phase_1_1.deployPhase1)(); const mockContracts = await (0, deploy_mocks_1.deployMocks)(); // Phase 2: Deploy and configure governance and incentive contracts. const phase2Contracts = await (0, phase_2_1.deployPhase2)({ // Mock contracts. starkPerpetualAddress: mockContracts.starkPerpetual.address, dydxCollateralTokenAddress: mockContracts.dydxCollateralToken.address, // Phase 1 contracts. dydxTokenAddress: phase1Contracts.dydxToken.address, governorAddress: phase1Contracts.governor.address, shortTimelockAddress: phase1Contracts.shortTimelock.address, merklePauserTimelockAddress: phase1Contracts.merklePauserTimelock.address, longTimelockAddress: phase1Contracts.longTimelock.address, }); // Phase 3: Finalize the deployment w/ actions that cannot be reversed without governance action. await (0, phase_3_1.deployPhase3)({ // Phase 1 deployed contracts. dydxTokenAddress: phase1Contracts.dydxToken.address, governorAddress: phase1Contracts.governor.address, shortTimelockAddress: phase1Contracts.shortTimelock.address, longTimelockAddress: phase1Contracts.longTimelock.address, // Phase 2 deployed contracts. rewardsTreasuryAddress: phase2Contracts.rewardsTreasury.address, rewardsTreasuryProxyAdminAddress: phase2Contracts.rewardsTreasuryProxyAdmin.address, safetyModuleAddress: phase2Contracts.safetyModule.address, safetyModuleProxyAdminAddress: phase2Contracts.safetyModuleProxyAdmin.address, communityTreasuryAddress: phase2Contracts.communityTreasury.address, communityTreasuryProxyAdminAddress: phase2Contracts.communityTreasuryProxyAdmin.address, rewardsTreasuryVesterAddress: phase2Contracts.rewardsTreasuryVester.address, communityTreasuryVesterAddress: phase2Contracts.communityTreasuryVester.address, liquidityStakingAddress: phase2Contracts.liquidityStaking.address, liquidityStakingProxyAdminAddress: phase2Contracts.liquidityStakingProxyAdmin.address, merkleDistributorAddress: phase2Contracts.merkleDistributor.address, merkleDistributorProxyAdminAddress: phase2Contracts.merkleDistributorProxyAdmin.address, starkProxyAddresses: phase2Contracts.starkProxies.map((sp) => sp.address), starkProxyProxyAdminAddresses: phase2Contracts.starkProxyProxyAdmins.map((spa) => spa.address), }); // Simulate mainnet staking activity with the broken Safety Module. const deployConfig = (0, deploy_config_1.getDeployConfig)(); await (0, evm_1.incrementTimeToTimestamp)(deployConfig.TRANSFERS_RESTRICTED_BEFORE); await (0, affected_stakers_1.simulateAffectedStakers)({ dydxTokenAddress: phase1Contracts.dydxToken.address, safetyModuleAddress: phase2Contracts.safetyModule.address, }); // Deploy contracts for Safety Module recovery. const smRecoveryContracts = await (0, safety_module_recovery_1.deploySafetyModuleRecovery)({ dydxTokenAddress: phase1Contracts.dydxToken.address, shortTimelockAddress: phase1Contracts.shortTimelock.address, rewardsTreasuryAddress: phase2Contracts.rewardsTreasury.address, }); // Deploy contracts for Stark Proxy recovery. const starkProxyRecoveryContracts = await (0, deploy_stark_proxy_v2_1.deployStarkProxyV2)({ liquidityStakingAddress: phase2Contracts.liquidityStaking.address, merkleDistributorAddress: phase2Contracts.merkleDistributor.address, starkPerpetualAddress: mockContracts.starkPerpetual.address, dydxCollateralTokenAddress: mockContracts.dydxCollateralToken.address, }); return { ...phase1Contracts, ...phase2Contracts, ...smRecoveryContracts, ...starkProxyRecoveryContracts, ...mockContracts, }; } exports.deployContractsForTest = deployContractsForTest; async function executeSafetyModuleRecoveryProposalsForTest(deployedContracts) { // Perform the safety module upgrade to recover funds and restore operation. if (config_1.default.TEST_SM_RECOVERY_WITH_PROPOSAL) { await (0, safety_module_fix_1.executeSafetyModuleUpgradeViaProposal)({ dydxTokenAddress: deployedContracts.dydxToken.address, governorAddress: deployedContracts.governor.address, longTimelockAddress: deployedContracts.longTimelock.address, safetyModuleAddress: deployedContracts.safetyModule.address, safetyModuleProxyAdminAddress: deployedContracts.safetyModuleProxyAdmin.address, safetyModuleNewImplAddress: deployedContracts.safetyModuleNewImpl.address, }); await (0, safety_module_compensation_1.fundSafetyModuleRecoveryViaProposal)({ dydxTokenAddress: deployedContracts.dydxToken.address, governorAddress: deployedContracts.governor.address, shortTimelockAddress: deployedContracts.shortTimelock.address, rewardsTreasuryAddress: deployedContracts.rewardsTreasury.address, safetyModuleRecoveryAddress: deployedContracts.safetyModuleRecovery.address, }); } else { // Simulate the execution of the proposals without actually using the governance process. await (0, safety_module_fix_1.executeSafetyModuleUpgradeNoProposal)({ longTimelockAddress: deployedContracts.longTimelock.address, safetyModuleAddress: deployedContracts.safetyModule.address, safetyModuleProxyAdminAddress: deployedContracts.safetyModuleProxyAdmin.address, safetyModuleNewImplAddress: deployedContracts.safetyModuleNewImpl.address, }); await (0, safety_module_compensation_1.fundSafetyModuleRecoveryNoProposal)({ dydxTokenAddress: deployedContracts.dydxToken.address, shortTimelockAddress: deployedContracts.shortTimelock.address, rewardsTreasuryAddress: deployedContracts.rewardsTreasury.address, safetyModuleRecoveryAddress: deployedContracts.safetyModuleRecovery.address, }); } } exports.executeSafetyModuleRecoveryProposalsForTest = executeSafetyModuleRecoveryProposalsForTest; async function executeStarkProxyProposalForTest(deployedContracts) { // Perform the safety module upgrade to recover funds and restore operation. if (config_1.default.TEST_SP_FIX_WITH_PROPOSAL) { await (0, stark_proxy_fix_1.executeStarkProxyUpgradeViaProposal)({ dydxTokenAddress: deployedContracts.dydxToken.address, governorAddress: deployedContracts.governor.address, shortTimelockAddress: deployedContracts.shortTimelock.address, starkProxyAddresses: deployedContracts.starkProxies.map((sp) => sp.address), starkProxyProxyAdminAddresses: deployedContracts.starkProxyProxyAdmins.map((sp) => sp.address), starkProxyNewImplAddress: deployedContracts.starkProxyNewImpl.address, }); } else { // Simulate the execution of the proposals without actually using the governance process. await (0, stark_proxy_fix_1.executeStarkProxyUpgradeNoProposal)({ shortTimelockAddress: deployedContracts.shortTimelock.address, starkProxyAddresses: deployedContracts.starkProxies.map((sp) => sp.address), starkProxyProxyAdminAddresses: deployedContracts.starkProxyProxyAdmins.map((sp) => sp.address), starkProxyNewImplAddress: deployedContracts.starkProxyNewImpl.address, }); } } exports.executeStarkProxyProposalForTest = executeStarkProxyProposalForTest; async function executeGrantsProgramProposalForTest(deployedContracts) { const deployConfig = (0, deploy_config_1.getDeployConfig)(); if (config_1.default.TEST_FUND_GRANTS_PROGRAM_WITH_PROPOSAL) { await (0, grants_program_proposal_1.fundGrantsProgramViaProposal)({ dydxTokenAddress: deployedContracts.dydxToken.address, governorAddress: deployedContracts.governor.address, shortTimelockAddress: deployedContracts.shortTimelock.address, communityTreasuryAddress: deployedContracts.communityTreasury.address, dgpMultisigAddress: deployConfig.DGP_MULTISIG_ADDRESS, }); } else { await (0, grants_program_proposal_1.fundGrantsProgramNoProposal)({ dydxTokenAddress: deployedContracts.dydxToken.address, shortTimelockAddress: deployedContracts.shortTimelock.address, communityTreasuryAddress: deployedContracts.communityTreasury.address, dgpMultisigAddress: deployConfig.DGP_MULTISIG_ADDRESS, }); } } exports.executeGrantsProgramProposalForTest = executeGrantsProgramProposalForTest; /** * After the deploy scripts have run, this function configures the contracts for testing. */ async function configureForTest(deployedContracts) { const { dydxToken, shortTimelock, safetyModule, } = deployedContracts; const deployer = await (0, get_deployer_address_1.getDeployerSigner)(); // Give some tokens back to the deployer to use during testing. const foundationAddress = (0, deploy_config_1.getDeployConfig)().TOKEN_ALLOCATIONS.DYDX_FOUNDATION.ADDRESS; const foundation = await (0, impersonate_account_1.impersonateAndFundAccount)(foundationAddress); const balance = await dydxToken.balanceOf(foundationAddress); await dydxToken.connect(foundation).transfer(deployer.address, balance); // Assign roles to the deployer for use during testing. const mockShortTimelock = await (0, impersonate_account_1.impersonateAndFundAccount)(shortTimelock.address); for (const role of constants_1.SM_ROLE_HASHES) { await safetyModule.connect(mockShortTimelock).grantRole(role, deployer.address); } // Advance to the the next epoch start, to ensure we don't begin the tests in a blackout window. const nextEpochStart = (await (0, evm_1.latestBlockTimestamp)() + Number(await deployedContracts.safetyModule.getTimeRemainingInCurrentEpoch())); await (0, evm_1.incrementTimeToTimestamp)(nextEpochStart); } exports.configureForTest = configureForTest;