@dydxfoundation/governance
Version:
dYdX governance smart contracts
202 lines (201 loc) • 12.2 kB
JavaScript
"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;