Skip to content

Commit

Permalink
Add migration for mantle
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinNagpal committed Jan 6, 2025
1 parent f2c299e commit a5a5f51
Show file tree
Hide file tree
Showing 6 changed files with 394 additions and 226 deletions.
193 changes: 193 additions & 0 deletions deployments/mantle/usde/migrations/1729593027_gov_marketupdates.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import {expect} from 'chai';
import {DeploymentManager} from '../../../../plugins/deployment_manager/DeploymentManager';
import {migration} from '../../../../plugins/deployment_manager/Migration';
import {proposal} from '../../../../src/deploy';
import {
CometProxyAdmin,
Configurator,
MarketAdminPermissionChecker,
MarketUpdateProposer,
MarketUpdateTimelock,
} from './../../../../build/types';


const marketAdminAddress = '0x7e14050080306cd36b47DE61ce604b3a1EC70c4e';

const localTimelockAddress = '0x16C7B5C1b10489F4B111af11de2Bd607c9728107';

const marketUpdateTimelockAddress = '0x1DCAF012D3Cdb4539701e3aFDb96aA4301353A07';
const marketUpdateProposerAddress = '0xea45D76425be2a1de4EC5FE24fCe992e3e8593FD';
const newConfiguratorImplementationAddress = '0x1A00C1470132567D1Ba0146B591a58cAe1Ec9868';
const newCometProxyAdminAddress = '0x258Ba415E5de9e8929d95853AdD4bE483C968E6d';
const marketAdminPermissionCheckerAddress = '0x7658E37933937ab5BBd9D15C6Df0424Cd4c53c34';

const communityMultiSigAddress = '0x2127338F0ff71Ecc779dce407D95C7D32f7C5F45';

const cometProxyAdminOldAddress = '0xe268B436E75648aa0639e2088fa803feA517a0c7';
const configuratorProxyAddress = '0xb77Cd4cD000957283D8BAf53cD782ECf029cF7DB';
const cometProxyUSDeAddress = '0x606174f62cd968d8e684c645080fa694c1D7786E';

export default migration('1729593027_gov_marketupdates', {
prepare: async () => {
return {};
},

enact: async (
deploymentManager: DeploymentManager,
govDeploymentManager: DeploymentManager,
) => {
console.log('Enacting proposal...');
const trace = deploymentManager.tracer();
const ethers = (deploymentManager.hre as any).ethers;
const { utils } = ethers;

const { bridgeReceiver } = await deploymentManager.getContracts();

const { opL1CrossDomainMessenger, governor } =
await govDeploymentManager.getContracts();

const changeProxyAdminForCometProxyUSDeCalldata = utils.defaultAbiCoder.encode(
['address', 'address'],
[cometProxyUSDeAddress, newCometProxyAdminAddress]
);


const changeProxyAdminForConfiguratorProxyCalldata =
utils.defaultAbiCoder.encode(
['address', 'address'],
[configuratorProxyAddress, newCometProxyAdminAddress]
);

const upgradeConfiguratorProxyCalldata = utils.defaultAbiCoder.encode(
['address', 'address'],
[configuratorProxyAddress, newConfiguratorImplementationAddress]
);

const setMarketAdminPermissionCheckerForConfiguratorProxyCalldata =
utils.defaultAbiCoder.encode(
['address'],
[marketAdminPermissionCheckerAddress]
);

const l2ProposalData = utils.defaultAbiCoder.encode(
['address[]', 'uint256[]', 'string[]', 'bytes[]'],
[
[
cometProxyAdminOldAddress,
cometProxyAdminOldAddress,
newCometProxyAdminAddress,
configuratorProxyAddress,
],
[0, 0, 0, 0],
[
'changeProxyAdmin(address,address)',
'changeProxyAdmin(address,address)',
'upgrade(address,address)',
'setMarketAdminPermissionChecker(address)',
],
[
changeProxyAdminForCometProxyUSDeCalldata,
changeProxyAdminForConfiguratorProxyCalldata,
upgradeConfiguratorProxyCalldata,
setMarketAdminPermissionCheckerForConfiguratorProxyCalldata,
],
]
);

const actions = [
// 1. Set Comet configuration + deployAndUpgradeTo new Comet and set reward config on Optimism.
{
contract: opL1CrossDomainMessenger,
signature: 'sendMessage(address,bytes,uint32)',
args: [bridgeReceiver.address, l2ProposalData, 2_500_000],
}
];

const description =
`# Alternate Governance track for Market Updates - Mantle\n\n## Proposal summary\n\nDoDAO has been examining various areas where improvements can be made to governance in Compound through tooling or automation. A significant issue raised repeatedly by many members concerns the time and effort required to apply Market Updates.
Currently, approximately 70-90% of the proposals pertain solely to updating market parameters. Gauntlet uses analytics and algorithms to determine new parameters based on current market conditions. These proposals are highly specific and require unique skills for validation. So far, we have seen minimal participation from other community members or teams in validating these parameters.
Assuming the total cost of reviewing a proposal (including the effort of all delegates) is $2,000 per proposal, we are spending upwards of $300,000 per year on a process that currently acts more as a friction layer without much safeguard, as these market update proposals are rarely reviewed thoroughly.
This not only slows down the process but also diverts focus from reviewing essential proposals related to new partnerships, the addition of new chains, and the introduction of assets, etc.
We propose a parallel process specifically for market updates that can bypass the normal governance lifecycle. This would enable us, as a Compound community, to move faster and concentrate on the most critical decisions.
This proposal has already been discussed here - https://www.comp.xyz/t/market-updates-alternate-governance-track/5379
The forum post includes two solutions, and OpenZeppelin has provided details and feedback on those solutions.
After discussing with OpenZeppelin, DoDAO and OZ together believe that given the amount of changes, updating the Configurator could be the best solution. OpenZeppelin mentioned a couple of important points in the forum post:
1. Grant the market admin role to an Safe address, which can be maintained by Gauntlet or other community members.
2. Market Updates to the Configurator will go through a timelock, providing sufficient time for the community to review or even block the market updates via this alternate route.
`;

console.log('Creating proposal...');
const txn = await govDeploymentManager.retry(async () =>
trace(await governor.propose(...(await proposal(actions, description))))
);

const event = txn.events.find((event) => event.event === 'ProposalCreated');

const [proposalId] = event.args;

trace(`Created proposal ${proposalId}.`);
},

async enacted(_deploymentManager: DeploymentManager): Promise<boolean> {
return false;
},

async verify(deploymentManager: DeploymentManager) {
await deploymentManager.spider();
const tracer = deploymentManager.tracer();
const ethers = (deploymentManager.hre as any).ethers;

const { configurator } = await deploymentManager.getContracts();

const marketAdminPermissionChecker = (await ethers.getContractAt(
'MarketAdminPermissionChecker',
marketAdminPermissionCheckerAddress
)) as MarketAdminPermissionChecker;

const marketUpdateTimelock = (await ethers.getContractAt(
'MarketUpdateTimelock',
marketUpdateTimelockAddress
)) as MarketUpdateTimelock;

const marketUpdateProposer = (await ethers.getContractAt(
'MarketUpdateProposer',
marketUpdateProposerAddress
)) as MarketUpdateProposer;

const cometProxyAdminNew = (await ethers.getContractAt(
'CometProxyAdmin',
newCometProxyAdminAddress
)) as CometProxyAdmin;

expect(configurator.address).to.be.equal(configuratorProxyAddress);
expect(await (configurator as Configurator).governor()).to.be.equal(localTimelockAddress);
expect(await (configurator as Configurator).marketAdminPermissionChecker()).to.be.equal(marketAdminPermissionCheckerAddress);

expect(await cometProxyAdminNew.marketAdminPermissionChecker()).to.be.equal(marketAdminPermissionChecker.address);
expect(await cometProxyAdminNew.owner()).to.be.equal(localTimelockAddress);

expect(await marketAdminPermissionChecker.marketAdmin()).to.be.equal(marketUpdateTimelockAddress);
expect(await marketAdminPermissionChecker.owner()).to.be.equal(localTimelockAddress);
expect(await marketAdminPermissionChecker.marketAdminPauseGuardian()).to.be.equal(communityMultiSigAddress);

expect(await marketUpdateTimelock.marketUpdateProposer()).to.be.equal(marketUpdateProposer.address);
expect(await marketUpdateTimelock.governor()).to.be.equal(localTimelockAddress);
expect(await marketUpdateTimelock.delay()).to.be.equal(2 * 24 * 60 * 60);

expect(await marketUpdateProposer.governor()).to.be.equal(localTimelockAddress);
expect(await marketUpdateProposer.marketAdmin()).to.be.equal(marketAdminAddress);

expect(await marketUpdateProposer.timelock()).to.be.equal(marketUpdateTimelock.address);
expect(await marketUpdateProposer.proposalGuardian()).to.be.equal(communityMultiSigAddress);

tracer('All checks passed.');
},
});
22 changes: 10 additions & 12 deletions forge/script/marketupdates/helpers/ChainAddresses.sol
Original file line number Diff line number Diff line change
Expand Up @@ -85,16 +85,14 @@ library ChainAddresses {
address constant public OPTIMISM_MARKET_UPDATE_PAUSE_GUARDIAN = 0x3fFd6c073a4ba24a113B18C8F373569640916A45; // See - https://optimistic.etherscan.io/address/0xE36A30D249f7761327fd973001A32010b521b6Fd#readProxyContract
address constant public OPTIMISM_MARKET_UPDATE_PROPOSAL_GUARDIAN = 0x3fFd6c073a4ba24a113B18C8F373569640916A45; // See - https://optimistic.etherscan.io/address/0xE36A30D249f7761327fd973001A32010b521b6Fd#readProxyContract

address constant public MANTLE_MARKET_ADMIN = 0x7e14050080306cd36b47DE61ce604b3a1EC70c4e;
address constant public MANTLE_MARKET_UPDATE_PAUSE_GUARDIAN = 0x2127338F0ff71Ecc779dce407D95C7D32f7C5F45;
address constant public MANTLE_MARKET_UPDATE_PROPOSAL_GUARDIAN = 0x2127338F0ff71Ecc779dce407D95C7D32f7C5F45;

address constant public MANTLE_LOCAL_TIMELOCK = 0x16C7B5C1b10489F4B111af11de2Bd607c9728107; // See - https://mantlescan.xyz/address/0x6d903f6003cca6255D85CcA4D3B5E5146dC33925
address constant public MANTLE_CONFIGURATOR_PROXY = 0xb77Cd4cD000957283D8BAf53cD782ECf029cF7DB; // See - https://mantlescan.xyz/address/0xb77Cd4cD000957283D8BAf53cD782ECf029cF7DB
address constant public MANTLE_COMET_PROXY_ADMIN = 0xe268B436E75648aa0639e2088fa803feA517a0c7; // See - https://mantlescan.xyz/address/0xe268B436E75648aa0639e2088fa803feA517a0c7
address constant public MANTLE_BRIDGE_RECEIVER = 0xc91EcA15747E73d6dd7f616C49dAFF37b9F1B604; // See - https://mantlescan.xyz/address/0xc91EcA15747E73d6dd7f616C49dAFF37b9F1B604

address constant public MANTLE_MARKET_ADMIN = 0x7e14050080306cd36b47DE61ce604b3a1EC70c4e; // See - https://explorer.mantle.xyz/address/0x7e14050080306cd36b47DE61ce604b3a1EC70c4e
address constant public MANTLE_MARKET_UPDATE_PAUSE_GUARDIAN = 0x2127338F0ff71Ecc779dce407D95C7D32f7C5F45; // See - https://explorer.mantle.xyz/address/0x2127338F0ff71Ecc779dce407D95C7D32f7C5F45
address constant public MANTLE_MARKET_UPDATE_PROPOSAL_GUARDIAN = 0x2127338F0ff71Ecc779dce407D95C7D32f7C5F45; // See - https://explorer.mantle.xyz/address/0x2127338F0ff71Ecc779dce407D95C7D32f7C5F45

address constant public MANTLE_LOCAL_TIMELOCK = 0x16C7B5C1b10489F4B111af11de2Bd607c9728107; // See - https://explorer.mantle.xyz/address/0x16C7B5C1b10489F4B111af11de2Bd607c9728107
address constant public MANTLE_CONFIGURATOR_PROXY = 0xb77Cd4cD000957283D8BAf53cD782ECf029cF7DB; // See - https://explorer.mantle.xyz/address/0xb77Cd4cD000957283D8BAf53cD782ECf029cF7DB
address constant public MANTLE_COMET_PROXY_ADMIN = 0xe268B436E75648aa0639e2088fa803feA517a0c7; // See - https://explorer.mantle.xyz/address/0xe268B436E75648aa0639e2088fa803feA517a0c7
address constant public MANTLE_BRIDGE_RECEIVER = 0xc91EcA15747E73d6dd7f616C49dAFF37b9F1B604; // See - https://explorer.mantle.xyz/address/0xc91EcA15747E73d6dd7f616C49dAFF37b9F1B604

function getChainAddresses(Chain chain) internal pure returns (ChainAddressesStruct memory) {
if (chain == Chain.ETHEREUM) {
Expand Down Expand Up @@ -165,9 +163,9 @@ library ChainAddresses {
governorTimelockAddress: MANTLE_LOCAL_TIMELOCK,
configuratorProxyAddress: MANTLE_CONFIGURATOR_PROXY,
cometProxyAdminAddress: MANTLE_COMET_PROXY_ADMIN,
marketUpdatePauseGuardian: address(0),
marketUpdateProposalGuardian: address(0),
marketAdmin: address(0)
marketUpdatePauseGuardian: MANTLE_MARKET_UPDATE_PAUSE_GUARDIAN,
marketUpdateProposalGuardian: MANTLE_MARKET_UPDATE_PROPOSAL_GUARDIAN,
marketAdmin: MANTLE_MARKET_ADMIN
});
} else {
revert("MarketUpdateAddresses: Chain not supported");
Expand Down
17 changes: 7 additions & 10 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,19 +281,16 @@ const config: HardhatUserConfig = {
berlin: 0,
shanghai: 0,
}
},
5000: {
hardforkHistory: {
london: 0,
berlin: 0,
shanghai: 0,
}
}
}
},
localhost: {
url: 'http://127.0.0.1:8545',
loggingEnabled: true,
gas: 120000000,
gasPrice: 'auto',
blockGasLimit: 120000000,
accounts: { mnemonic: MNEMONIC, accountsBalance: (10n ** 36n).toString() },
// this should only be relied upon for test harnesses and coverage (which does not use viaIR flag)
allowUnlimitedContractSize: true,
},
},

// See https://hardhat.org/plugins/nomiclabs-hardhat-etherscan.html#multiple-api-keys-and-alternative-block-explorers
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
"eslint": "^8.12.0",
"ethers": "^5.7.2",
"fast-glob": "^3.2.7",
"hardhat": "^2.12.2",
"hardhat": "^2.22.17",
"hardhat-chai-matchers": "https://github.com/jflatow/hardhat/releases/download/viaIR/nomicfoundation-hardhat-chai-matchers-v1.0.4.tgz",
"hardhat-change-network": "^0.0.7",
"hardhat-contract-sizer": "^2.10.0",
Expand Down
8 changes: 4 additions & 4 deletions plugins/scenario/utils/hreForBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ export function nonForkedHreForBase(base: ForkSpec): HardhatRuntimeEnvironment {
}
},
ctx.tasksDSL.getTaskDefinitions(),
ctx.extendersManager.getExtenders(),
ctx.experimentalHardhatNetworkMessageTraceHooks,
ctx.tasksDSL.getScopesDefinitions(),
ctx.environmentExtenders,
userConfig
);
}
Expand Down Expand Up @@ -105,8 +105,8 @@ export function forkedHreForBase(base: ForkSpec): HardhatRuntimeEnvironment {
forkedConfig,
hardhatArguments,
ctx.tasksDSL.getTaskDefinitions(),
ctx.extendersManager.getExtenders(),
ctx.experimentalHardhatNetworkMessageTraceHooks,
ctx.tasksDSL.getScopesDefinitions(),
ctx.environmentExtenders,
userConfig
);
}
Expand Down
Loading

0 comments on commit a5a5f51

Please sign in to comment.