Skip to content

Commit

Permalink
feat: add tETH to mainnet-weth and neccesary chnages for the scenario…
Browse files Browse the repository at this point in the history
…n environment
  • Loading branch information
MishaShWoof committed Jan 22, 2025
1 parent 5fe26a2 commit d4dad32
Show file tree
Hide file tree
Showing 8 changed files with 250 additions and 31 deletions.
142 changes: 142 additions & 0 deletions deployments/mainnet/weth/migrations/1737538616_add_teth_collateral.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { expect } from 'chai';
import { DeploymentManager } from '../../../../plugins/deployment_manager/DeploymentManager';
import { migration } from '../../../../plugins/deployment_manager/Migration';
import { exp, proposal } from '../../../../src/deploy';

const TETH_ADDRESS = '0xD11c452fc99cF405034ee446803b6F6c1F6d5ED8';
const TETH_TO_WSTETH_PRICE_FEED = '0x7B2Fb2c667af80Bccc0B2556378352dFDE2be914';

let newPriceFeedAddress: string;

export default migration('1737538616_add_teth_collateral', {
async prepare(deploymentManager: DeploymentManager) {
const _wstETHToETHPriceFeed = await deploymentManager.fromDep('wstETH:priceFeed', 'mainnet', 'weth');
const tETHMultiplicativePriceFeed = await deploymentManager.deploy(
'tETH:priceFeed',
'pricefeeds/ReverseMultiplicativePriceFeed.sol',
[
TETH_TO_WSTETH_PRICE_FEED, // tETH / wstETH price feed
_wstETHToETHPriceFeed.address, // ETH / wstETH (reversed) price feed
8, // decimals
'tETH / ETH price feed' // description
]
);
return { tETHPriceFeedAddress: tETHMultiplicativePriceFeed.address };
},

async enact(deploymentManager: DeploymentManager, _, { tETHPriceFeedAddress }) {

const trace = deploymentManager.tracer();

const tETH = await deploymentManager.existing(
'tETH',
TETH_ADDRESS,
'mainnet',
'contracts/ERC20.sol:ERC20'
);
const tETHPriceFeed = await deploymentManager.existing(
'tETH:priceFeed',
tETHPriceFeedAddress,
'mainnet'
);

newPriceFeedAddress = tETHPriceFeedAddress;

const {
governor,
comet,
cometAdmin,
configurator,
} = await deploymentManager.getContracts();

const tETHAssetConfig = {
asset: tETH.address,
priceFeed: tETHPriceFeed.address,
decimals: await tETH.decimals(),
borrowCollateralFactor: exp(0.88, 18),
liquidateCollateralFactor: exp(0.91, 18),
liquidationFactor: exp(0.96, 18),
supplyCap: exp(4000, 18),
};

const mainnetActions = [
// 1. Add tETH as asset
{
contract: configurator,
signature: 'addAsset(address,(address,address,uint8,uint64,uint64,uint64,uint128))',
args: [comet.address, tETHAssetConfig],
},
// 2. Deploy and upgrade to a new version of Comet
{
contract: cometAdmin,
signature: 'deployAndUpgradeTo(address,address)',
args: [configurator.address, comet.address],
},
];

const description = '# Add tETH as collateral into cWETHv3 on Mainnet\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes to add tETH into cWETHv3 on Ethereum network. This proposal takes the governance steps recommended and necessary to update a Compound III WETH market on Ethereum. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based on the [recommendations from Gauntlet](https://www.comp.xyz/t/listing-teth-on-compound/5925/4).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/955) and [forum discussion](https://www.comp.xyz/t/listing-teth-on-compound/5925).\n\n\n## Proposal Actions\n\nThe first action adds tETH asset as collateral with corresponding configurations.\n\nThe second action deploys and upgrades Comet to a new version.';
// impersonate the proposer
await deploymentManager.hre.network.provider.request({
method: 'hardhat_impersonateAccount',
params: ['0x7e959eab54932f5cfd10239160a7fd6474171318'],
});
const signer = await deploymentManager.getSigner('0x7e959eab54932f5cfd10239160a7fd6474171318');
const txn = await deploymentManager.retry(async () =>
trace(
await governor.connect(signer).propose(...(await proposal(mainnetActions, description)))
)
);

const event = txn.events.find(
(event) => event.event === 'ProposalCreated'
);
const [proposalId] = event.args;
trace(`Created proposal ${proposalId}.`);
},

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

async verify(deploymentManager: DeploymentManager) {
const { comet, configurator } = await deploymentManager.getContracts();

const tETHAssetIndex = Number(await comet.numAssets()) - 1;

const tETH = await deploymentManager.existing(
'tETH',
TETH_ADDRESS,
'mainnet',
'contracts/ERC20.sol:ERC20'
);
const tETHAssetConfig = {
asset: tETH.address,
priceFeed: newPriceFeedAddress,
decimals: 18n,
borrowCollateralFactor: exp(0.88, 18),
liquidateCollateralFactor: exp(0.91, 18),
liquidationFactor: exp(0.96, 18),
supplyCap: exp(4000, 18),
};

// 1. Compare tETH asset config with Comet and Configurator asset info
const cometTETHAssetInfo = await comet.getAssetInfoByAddress(TETH_ADDRESS);
expect(tETHAssetIndex).to.be.equal(cometTETHAssetInfo.offset);
expect(tETHAssetConfig.asset).to.be.equal(cometTETHAssetInfo.asset);
expect(tETHAssetConfig.priceFeed).to.be.equal(cometTETHAssetInfo.priceFeed);
expect(exp(1, tETHAssetConfig.decimals)).to.be.equal(cometTETHAssetInfo.scale);
expect(tETHAssetConfig.borrowCollateralFactor).to.be.equal(cometTETHAssetInfo.borrowCollateralFactor);
expect(tETHAssetConfig.liquidateCollateralFactor).to.be.equal(cometTETHAssetInfo.liquidateCollateralFactor);
expect(tETHAssetConfig.liquidationFactor).to.be.equal(cometTETHAssetInfo.liquidationFactor);
expect(tETHAssetConfig.supplyCap).to.be.equal(cometTETHAssetInfo.supplyCap);

const configuratorTETHAssetConfig = (await configurator.getConfiguration(comet.address)).assetConfigs[tETHAssetIndex];
expect(tETHAssetConfig.asset).to.be.equal(configuratorTETHAssetConfig.asset);
expect(tETHAssetConfig.priceFeed).to.be.equal(configuratorTETHAssetConfig.priceFeed);
expect(tETHAssetConfig.decimals).to.be.equal(configuratorTETHAssetConfig.decimals);
expect(tETHAssetConfig.borrowCollateralFactor).to.be.equal(configuratorTETHAssetConfig.borrowCollateralFactor);
expect(tETHAssetConfig.liquidateCollateralFactor).to.be.equal(configuratorTETHAssetConfig.liquidateCollateralFactor);
expect(tETHAssetConfig.liquidationFactor).to.be.equal(configuratorTETHAssetConfig.liquidationFactor);
expect(tETHAssetConfig.supplyCap).to.be.equal(configuratorTETHAssetConfig.supplyCap);
},
});
8 changes: 8 additions & 0 deletions deployments/mainnet/weth/relations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,13 @@ export default {
}
}
},
'ERC1967Proxy': {
artifact: 'contracts/ERC20.sol:ERC20',
delegates: {
field: {
slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc'
}
}
},
};

4 changes: 2 additions & 2 deletions scenario/constraints/MigrationConstraint.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { StaticConstraint, Solution, World, debug } from '../../plugins/scenario';
import { CometContext, MigrationData } from '../context/CometContext';
import { Migration, loadMigrations, Actions } from '../../plugins/deployment_manager/Migration';
import { modifiedPaths, subsets } from '../utils';
import { modifiedPaths } from '../utils';
import { DeploymentManager } from '../../plugins/deployment_manager';
import { impersonateAddress } from '../../plugins/scenario/utils';
import { exp } from '../../test/helpers';
Expand All @@ -22,7 +22,7 @@ export class MigrationConstraint<T extends CometContext> implements StaticConstr
async solve(world: World) {
const label = `[${world.base.name}] {MigrationConstraint}`;
const solutions: Solution<T>[] = [];
const migrationPaths = [...subsets(await getMigrations(world))];
const migrationPaths = [await getMigrations(world)];

for (const migrationList of migrationPaths) {
if (migrationList.length == 0 && migrationPaths.length > 1) {
Expand Down
7 changes: 6 additions & 1 deletion scenario/constraints/ProposalConstraint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { IGovernorBravo, ProposalState, OpenProposal } from '../context/Gov';
import { CometContext } from '../context/CometContext';
import { fetchLogs } from '../utils';
import { DeploymentManager } from '../../plugins/deployment_manager';
import { isBridgedDeployment, executeOpenProposal, executeOpenProposalAndRelay } from '../utils';
import { isBridgedDeployment, executeOpenProposal, voteForOpenProposal, executeOpenProposalAndRelay } from '../utils';
import { getOpenBridgedProposals, executeBridgedProposal } from '../utils/bridgeProposal';

async function getOpenProposals(deploymentManager: DeploymentManager, governor: IGovernorBravo): Promise<OpenProposal[]> {
Expand Down Expand Up @@ -53,6 +53,11 @@ export class ProposalConstraint<T extends CometContext> implements StaticConstra
const governanceDeploymentManager = ctx.world.auxiliaryDeploymentManager || deploymentManager;
const governor = await governanceDeploymentManager.contract('governor') as IGovernorBravo;
const proposals = await getOpenProposals(governanceDeploymentManager, governor);

for (const proposal of proposals) {
await voteForOpenProposal(governanceDeploymentManager, proposal);
}

for (const proposal of proposals) {
const preExecutionBlockNumber = await ctx.world.deploymentManager.hre.ethers.provider.getBlockNumber();
let migrationData;
Expand Down
24 changes: 19 additions & 5 deletions scenario/context/CometContext.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BigNumber, BigNumberish } from 'ethers';
import { BigNumber, BigNumberish, Contract } from 'ethers';
import { Loader, World, debug } from '../../plugins/scenario';
import { Migration } from '../../plugins/deployment_manager';
import {
Expand Down Expand Up @@ -74,7 +74,7 @@ export class CometContext {
}

async getCompWhales(): Promise<string[]> {
const useMainnetComp = ['mainnet', 'polygon', 'arbitrum', 'base', 'optimism', 'scroll', 'mantle'].includes(this.world.base.network);
const useMainnetComp = ['mainnet', 'polygon', 'arbitrum', 'base', 'optimism', 'scroll', 'mantle', 'linea'].includes(this.world.base.network);
return COMP_WHALES[useMainnetComp ? 'mainnet' : 'testnet'];
}

Expand Down Expand Up @@ -151,11 +151,25 @@ export class CometContext {
async upgrade(configOverrides: ProtocolConfiguration): Promise<CometContext> {
const { world } = this;

const oldComet = await this.getComet();
const admin = await world.impersonateAddress(await oldComet.governor(), { value: 20n ** 18n });
const currentComet = await this.getComet();
const admin = await world.impersonateAddress(await currentComet.governor(), { value: 20n ** 18n });
const oldComet = new Contract(currentComet.address,
[
'function governor() view returns (address)',
'function assetList() view returns (address)',
'function assetListFactory() view returns (address)'
], admin);

const deploySpec = { cometMain: true, cometExt: true };
const deployed = await deployComet(this.world.deploymentManager, deploySpec, configOverrides, admin);
let withAssetList = false;
try {
await oldComet.assetList();
withAssetList = true;
}
catch (e) {
withAssetList = false;
}
const deployed = await deployComet(this.world.deploymentManager, deploySpec, configOverrides, withAssetList, admin);

await this.world.deploymentManager.spider(deployed);
await this.setAssets();
Expand Down
20 changes: 15 additions & 5 deletions scenario/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,11 +427,7 @@ async function mockRedstoneOracle(dm: DeploymentManager, feed: string){
await proxyAdmin.connect(owner).upgrade(feed, newImplementation.address);
}


export async function executeOpenProposal(
dm: DeploymentManager,
{ id, startBlock, endBlock }: OpenProposal
) {
export async function voteForOpenProposal(dm: DeploymentManager, { id, startBlock, endBlock }: OpenProposal) {
const governor = await dm.getContractOrThrow('governor');
const blockNow = await dm.hre.ethers.provider.getBlockNumber();
const blocksUntilStart = startBlock.toNumber() - blockNow;
Expand All @@ -454,6 +450,19 @@ export async function executeOpenProposal(
debug(`Error while voting for ${whale}`, err.message);
}
}
}
}


export async function executeOpenProposal(
dm: DeploymentManager,
{ id, startBlock, endBlock }: OpenProposal
) {
const governor = await dm.getContractOrThrow('governor');
const blockNow = await dm.hre.ethers.provider.getBlockNumber();
const blocksUntilEnd = endBlock.toNumber() - Math.max(startBlock.toNumber(), blockNow) + 1;

if (blocksUntilEnd > 0) {
await mineBlocks(dm, blocksUntilEnd);
}

Expand Down Expand Up @@ -501,6 +510,7 @@ export async function fastGovernanceExecute(
const proposeEvent = proposeTxn.events.find(event => event.event === 'ProposalCreated');
const [id, , , , , , startBlock, endBlock] = proposeEvent.args;

await voteForOpenProposal(dm, { id, startBlock, endBlock });
await executeOpenProposal(dm, { id, startBlock, endBlock });
}

Expand Down
75 changes: 57 additions & 18 deletions src/deploy/Network.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export async function deployNetworkComet(
deploymentManager: DeploymentManager,
deploySpec: DeploySpec = { all: true },
configOverrides: ProtocolConfiguration = {},
withAssetList = false,
adminSigner?: SignerWithAddress,
): Promise<Deployed> {
function maybeForce(flag?: boolean): boolean {
Expand Down Expand Up @@ -132,19 +133,47 @@ export async function deployNetworkComet(
name32: ethers.utils.formatBytes32String(name),
symbol32: ethers.utils.formatBytes32String(symbol)
};
const cometExt = await deploymentManager.deploy(
'comet:implementation:implementation',
'CometExt.sol',
[extConfiguration],
maybeForce(deploySpec.cometExt)
);
let cometExt;

if(withAssetList) {
const assetListFactory = await deploymentManager.deploy(
'assetListFactory',
'AssetListFactory.sol',
[],
maybeForce(deploySpec.cometExt)
);
cometExt = await deploymentManager.deploy(
'comet:implementation:implementation',
'CometExtAssetList.sol',
[extConfiguration, assetListFactory.address],
maybeForce(deploySpec.cometExt)
);
} else {
cometExt = await deploymentManager.deploy(
'comet:implementation:implementation',
'CometExt.sol',
[extConfiguration],
maybeForce(deploySpec.cometExt)
);
}

const cometFactory = await deploymentManager.deploy(
'cometFactory',
'CometFactory.sol',
[],
maybeForce(deploySpec.cometMain)
);
let cometFactory;
if(withAssetList) {
cometFactory = await deploymentManager.deploy(
'cometFactory',
'CometFactoryWithExtendedAssetList.sol',
[],
maybeForce(deploySpec.cometMain)
);
}
else {
cometFactory = await deploymentManager.deploy(
'cometFactory',
'CometFactory.sol',
[],
maybeForce(deploySpec.cometMain)
);
}

const configuration = {
governor,
Expand All @@ -170,12 +199,22 @@ export async function deployNetworkComet(
assetConfigs,
};

const tmpCometImpl = await deploymentManager.deploy(
'comet:implementation',
'Comet.sol',
[configuration],
maybeForce(),
);
let tmpCometImpl;
if(withAssetList) {
tmpCometImpl = await deploymentManager.deploy(
'comet:implementation',
'CometWithExtendedAssetList.sol',
[configuration],
maybeForce()
);
} else{
tmpCometImpl = await deploymentManager.deploy(
'comet:implementation',
'Comet.sol',
[configuration],
maybeForce(),
);
}
const cometProxy = await deploymentManager.deploy(
'comet',
'vendor/proxy/transparent/TransparentUpgradeableProxy.sol',
Expand Down
1 change: 1 addition & 0 deletions src/deploy/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export const WHALES = {
'0x43594da5d6A03b2137a04DF5685805C676dEf7cB', // rsETH whale
'0x3d9819210a31b4961b30ef54be2aed79b9c9cd3b',
'0x0B925eD163218f6662a35e0f0371Ac234f9E9371', // wstETH whale
'0xf0bb20865277aBd641a307eCe5Ee04E79073416C', // tETH whale
],
polygon: [
'0x2093b4281990a568c9d588b8bce3bfd7a1557ebd', // WETH whale
Expand Down

0 comments on commit d4dad32

Please sign in to comment.