diff --git a/contracts/pricefeeds/EzETHExchangeRatePriceFeed.sol b/contracts/pricefeeds/EzETHExchangeRatePriceFeed.sol index 18c8590a6..fb66d61c7 100644 --- a/contracts/pricefeeds/EzETHExchangeRatePriceFeed.sol +++ b/contracts/pricefeeds/EzETHExchangeRatePriceFeed.sol @@ -66,6 +66,8 @@ contract EzETHExchangeRatePriceFeed is IPriceFeed { uint80 answeredInRound ) { uint256 rate = IBalancerRateProvider(underlyingPriceFeed).getRate(); + // protocol uses only the answer value. Other data fields are not provided by the underlying pricefeed and are not used in Comet protocol + // https://etherscan.io/address/0x387dBc0fB00b26fb085aa658527D5BE98302c84C#readProxyContract return (0, scalePrice(int256(rate)), 0, 0, 0); } diff --git a/contracts/test/MockOracle.sol b/contracts/test/MockOracle.sol new file mode 100644 index 000000000..11fc7c198 --- /dev/null +++ b/contracts/test/MockOracle.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity 0.8.15; + +import "../vendor/@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; + +/** + * @title Scaling price feed + * @notice A custom price feed that scales up or down the price received from an underlying Chainlink price feed and returns the result + * @author Compound + */ +contract MockOracle { + + /// @notice Number of decimals for returned prices + uint8 public immutable decimals; + + /// @notice Underlying Chainlink price feed where prices are fetched from + address public immutable underlyingPriceFeed; + + /** + * @notice Construct a new scaling price feed + * @param underlyingPriceFeed_ The address of the underlying price feed to fetch prices from + **/ + constructor(address underlyingPriceFeed_) { + underlyingPriceFeed = underlyingPriceFeed_; + decimals = AggregatorV3Interface(underlyingPriceFeed_).decimals(); + } + + /** + * @notice Price for the latest round + * @return roundId Round id from the underlying price feed + * @return answer Latest price for the asset in terms of ETH + * @return startedAt Timestamp when the round was started; passed on from underlying price feed + * @return updatedAt Timestamp when the round was last updated; passed on from underlying price feed + * @return answeredInRound Round id in which the answer was computed; passed on from underlying price feed + **/ + function latestRoundData() external view returns ( + uint80 roundId, + int256 answer, + uint256 startedAt, + uint256 updatedAt, + uint80 answeredInRound + ) { + (uint80 roundId_, int256 price, uint256 startedAt_, , uint80 answeredInRound_) = AggregatorV3Interface(underlyingPriceFeed).latestRoundData(); + return (roundId_, price, startedAt_, block.timestamp, answeredInRound_); + } +} \ No newline at end of file diff --git a/deployments/mainnet/weth/migrations/1718352598_add_ezeth_as_collateral.ts b/deployments/mainnet/weth/migrations/1718352598_add_ezeth_as_collateral.ts index ca9bbb78b..3e47b1995 100644 --- a/deployments/mainnet/weth/migrations/1718352598_add_ezeth_as_collateral.ts +++ b/deployments/mainnet/weth/migrations/1718352598_add_ezeth_as_collateral.ts @@ -5,7 +5,7 @@ import { exp, proposal } from '../../../../src/deploy'; const EZETH_ADDRESS = '0xbf5495Efe5DB9ce00f80364C8B423567e58d2110'; -const EZETH_PRICE_FEED_ADDRESS = '0x636A000262F6aA9e1F094ABF0aD8f645C44f641C'; +const EZETH_PRICE_FEED_ADDRESS = '0x387dBc0fB00b26fb085aa658527D5BE98302c84C'; export default migration('1718352598_add_ezeth_as_collateral', { async prepare(deploymentManager: DeploymentManager) { @@ -68,6 +68,7 @@ export default migration('1718352598_add_ezeth_as_collateral', { args: [configurator.address, comet.address], }, ]; + console.log('initial', (await deploymentManager.hre.ethers.provider.getBlock('latest')).timestamp); const description = '# Add rsETH, weETH and osETH as collaterals into cWETHv3 on Mainnet\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes to add rsETH, weETH and osETH 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 off of the [recommendations from Gauntlet weETH](https://www.comp.xyz/t/add-weeth-market-on-ethereum/5179/3), [recommendations from Gauntlet rsETH](https://www.comp.xyz/t/add-rseth-market-on-ethereum-mainnet/5118/8) and [recommendations from Gauntlet osETH](https://www.comp.xyz/t/add-oseth-as-a-collateral-on-ethereum-mainnet/5272/2).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/854), [deploy market GitHub action run]() and [forum discussion weETH](https://www.comp.xyz/t/add-weeth-market-on-ethereum/5179), [forum discussion rsETH](https://www.comp.xyz/t/add-rseth-market-on-ethereum-mainnet/5118) and [forum discussion osETH](https://www.comp.xyz/t/add-oseth-as-a-collateral-on-ethereum-mainnet/5272).\n\n\n## Proposal Actions\n\nThe first proposal action adds rsETH asset as collateral with corresponding configurations.\n\nThe second action adds weETH asset as collateral with corresponding configurations.\n\nThe third action adds osETH asset as collateral with corresponding configurations.\n\nThe fourth action sets new Annual Supply Interest Rate Slope High to 100%.\n\nThe fifth action sets new Annual Borrow Interest Rate Slope High to 115%.\n\nThe sixth action deploys and upgrades Comet to a new version.'; const txn = await deploymentManager.retry(async () => @@ -113,6 +114,8 @@ export default migration('1718352598_add_ezeth_as_collateral', { const cometEzETHAssetInfo = await comet.getAssetInfoByAddress( EZETH_ADDRESS ); + console.log(await comet.getPrice(cometEzETHAssetInfo.priceFeed)); + expect(ezETHAssetIndex).to.be.equal(cometEzETHAssetInfo.offset); expect(ezETHAssetConfig.asset).to.be.equal(cometEzETHAssetInfo.asset); expect(exp(1, ezETHAssetConfig.decimals)).to.be.equal( diff --git a/deployments/mainnet/weth/relations.ts b/deployments/mainnet/weth/relations.ts index 37278965c..f3a211c9c 100644 --- a/deployments/mainnet/weth/relations.ts +++ b/deployments/mainnet/weth/relations.ts @@ -13,5 +13,14 @@ export default { }, 'AppProxyUpgradeable': { artifact: 'contracts/ERC20.sol:ERC20', - } + }, + 'TransparentUpgradeableProxy': { + artifact: 'contracts/ERC20.sol:ERC20', + delegates: { + field: { + slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' + } + } + }, + }; \ No newline at end of file diff --git a/scenario/LiquidationBotScenario.ts b/scenario/LiquidationBotScenario.ts index 6cf5b64ec..c219f6edb 100644 --- a/scenario/LiquidationBotScenario.ts +++ b/scenario/LiquidationBotScenario.ts @@ -739,7 +739,7 @@ scenario( const assetAmounts = { mainnet: { usdc: ' == 5000', // COMP - weth: ' == 7000', // CB_ETH + weth: ' == 6000', // CB_ETH }, }; diff --git a/scenario/utils/index.ts b/scenario/utils/index.ts index 492c0ab8e..fa11d61d2 100644 --- a/scenario/utils/index.ts +++ b/scenario/utils/index.ts @@ -327,6 +327,36 @@ export async function fetchLogs( } } +async function redeployRenzoOracle(dm: DeploymentManager){ + if(dm.network === 'mainnet' && dm.deployment === 'weth') { + // renzo admin 0xD1e6626310fD54Eceb5b9a51dA2eC329D6D4B68A + const renzoOracle = new Contract( + '0x5a12796f7e7EBbbc8a402667d266d2e65A814042', + [ + 'function setOracleAddress(address _token, address _oracleAddress) external', + ], + dm.hre.ethers.provider + ); + + const admin = await impersonateAddress(dm, '0xD1e6626310fD54Eceb5b9a51dA2eC329D6D4B68A'); + // set balance + await dm.hre.ethers.provider.send('hardhat_setBalance', [ + admin.address, + dm.hre.ethers.utils.hexStripZeros(dm.hre.ethers.utils.parseUnits('100', 'ether').toHexString()), + ]); + + const newOracle = await dm.deploy( + 'stETH:Oracle', + 'test/MockOracle.sol', + [ + '0x86392dC19c0b719886221c78AB11eb8Cf5c52812', // stETH / ETH oracle address + ] + ); + + await renzoOracle.connect(admin).setOracleAddress('0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84', newOracle.address); + } +} + export async function executeOpenProposal( dm: DeploymentManager, { id, startBlock, endBlock }: OpenProposal @@ -370,6 +400,7 @@ export async function executeOpenProposal( await setNextBaseFeeToZero(dm); await governor.execute(id, { gasPrice: 0, gasLimit: 12000000 }); } + await redeployRenzoOracle(dm); } // Instantly executes some actions through the governance proposal process