diff --git a/contracts/pcv/balancer/BalancerPool2Lens.sol b/contracts/pcv/balancer/BalancerPool2Lens.sol index ec9d45f4a..64a356451 100644 --- a/contracts/pcv/balancer/BalancerPool2Lens.sol +++ b/contracts/pcv/balancer/BalancerPool2Lens.sol @@ -119,6 +119,7 @@ contract BalancerPool2Lens is IPCVDepositBalances { } if (feiInPair) { uint256 otherReserves = _getIdealReserves(balances, prices, weights, j); + otherReserves = (otherReserves * bptsOwned) / totalSupply; return (reserves, otherReserves); } return (reserves, 0); diff --git a/proposals/dao/oa_cr_fix.ts b/proposals/dao/oa_cr_fix.ts new file mode 100644 index 000000000..f86f04563 --- /dev/null +++ b/proposals/dao/oa_cr_fix.ts @@ -0,0 +1,129 @@ +import hre, { ethers, artifacts } from 'hardhat'; +import { expect } from 'chai'; +import { + DeployUpgradeFunc, + NamedAddresses, + SetupUpgradeFunc, + TeardownUpgradeFunc, + ValidateUpgradeFunc +} from '@custom-types/types'; +import { ZERO_ADDRESS, overwriteChainlinkAggregator } from '@test/helpers'; + +const fipNumber = 'oa_cr_fix'; +let pcvStatsBefore; + +// Do any deployments +// This should exclusively include new contract deployments +const deploy: DeployUpgradeFunc = async (deployAddress: string, addresses: NamedAddresses, logging: boolean) => { + // Deploy lens to report B-30FEI-70WETH as WETH and protocol-owned FEI + // (The new contract contains a fix) + const balancerPool2LensFactory = await ethers.getContractFactory('BalancerPool2Lens'); + const balancerLensBpt30Fei70Weth = await balancerPool2LensFactory.deploy( + addresses.gaugeLensBpt30Fei70WethGauge, // address _depositAddress + addresses.wethERC20, // address _token + addresses.balancerFeiWethPool, // IWeightedPool _pool + addresses.chainlinkEthUsdOracleWrapper, // IOracle _reportedOracle + addresses.oneConstantOracle, // IOracle _otherOracle + false, // bool _feiIsReportedIn + true // bool _feiIsOther + ); + await balancerLensBpt30Fei70Weth.deployTransaction.wait(); + logging && console.log('balancerLensBpt30Fei70Weth: ', balancerLensBpt30Fei70Weth.address); + + return { + balancerLensBpt30Fei70Weth + }; +}; + +// Do any setup necessary for running the test. +// This could include setting up Hardhat to impersonate accounts, +// ensuring contracts have a specific state, etc. +const setup: SetupUpgradeFunc = async (addresses, oldContracts, contracts, logging) => { + console.log(`Setup of ${fipNumber} : reading CR oracle...`); + + // make sure ETH oracle is fresh (for B.AMM not to revert, etc) + // Read Chainlink ETHUSD price & override chainlink storage to make it a fresh value + const ethPrice = (await contracts.chainlinkEthUsdOracleWrapper.read())[0].toString() / 1e10; + await overwriteChainlinkAggregator(addresses.chainlinkEthUsdOracle, Math.round(ethPrice), '8'); + + // read pcvStats + pcvStatsBefore = await contracts.collateralizationOracle.pcvStats(); +}; + +// Tears down any changes made in setup() that need to be +// cleaned up before doing any validation checks. +const teardown: TeardownUpgradeFunc = async (addresses, oldContracts, contracts, logging) => { + console.log(`No actions to complete in teardown for fip${fipNumber}`); +}; + +// Run any validations required on the fip using mocha or console logging +// IE check balances, check state of contracts, etc. +const validate: ValidateUpgradeFunc = async (addresses, oldContracts, contracts, logging) => { + // Check the removed PCV Deposits + expect(await contracts.collateralizationOracle.depositToToken(addresses.rariPool8FeiPCVDepositWrapper)).to.be.equal( + ZERO_ADDRESS + ); + expect(await contracts.collateralizationOracle.depositToToken(addresses.rariPool8DaiPCVDeposit)).to.be.equal( + ZERO_ADDRESS + ); + expect(await contracts.collateralizationOracle.depositToToken(addresses.rariPool8LusdPCVDeposit)).to.be.equal( + ZERO_ADDRESS + ); + expect(await contracts.collateralizationOracle.depositToToken(addresses.rariPool18FeiPCVDepositWrapper)).to.be.equal( + ZERO_ADDRESS + ); + expect(await contracts.collateralizationOracle.depositToToken(addresses.rariPool27FeiPCVDepositWrapper)).to.be.equal( + ZERO_ADDRESS + ); + expect(await contracts.collateralizationOracle.depositToToken(addresses.rariPool90FeiPCVDepositWrapper)).to.be.equal( + ZERO_ADDRESS + ); + expect(await contracts.collateralizationOracle.depositToToken(addresses.rariPool146EthPCVDeposit)).to.be.equal( + ZERO_ADDRESS + ); + expect(await contracts.collateralizationOracle.depositToToken(addresses.convexPoolPCVDepositWrapper)).to.be.equal( + ZERO_ADDRESS + ); + + // Check the lens swap + expect(await contracts.collateralizationOracle.depositToToken(addresses.balancerLensBpt30Fei70WethOld)).to.be.equal( + ZERO_ADDRESS + ); + expect(await contracts.collateralizationOracle.depositToToken(addresses.balancerLensBpt30Fei70Weth)).to.be.equal( + addresses.weth + ); + + // Check the new lens returned values + const balance = (await contracts.balancerLensBpt30Fei70Weth.balance()) / 1e18; + const resistantBalanceAndFei = await contracts.balancerLensBpt30Fei70Weth.resistantBalanceAndFei(); + const resistantBalance = resistantBalanceAndFei[0] / 1e18; + const resistantFei = resistantBalanceAndFei[1] / 1e18; + // 15.86k ETH, 16.3M FEI on 2022-05-10 + expect(balance).to.be.at.least(14000); + expect(balance).to.be.at.most(18000); + expect(resistantBalance).to.be.at.least(14000); + expect(resistantBalance).to.be.at.most(18000); + expect(resistantFei).to.be.at.least(10e6); + expect(resistantFei).to.be.at.most(25e6); + + // display pcvStats + console.log('----------------------------------------------------'); + console.log(' pcvStatsBefore.protocolControlledValue [M]e18 ', pcvStatsBefore.protocolControlledValue / 1e24); + console.log(' pcvStatsBefore.userCirculatingFei [M]e18 ', pcvStatsBefore.userCirculatingFei / 1e24); + console.log(' pcvStatsBefore.protocolEquity [M]e18 ', pcvStatsBefore.protocolEquity / 1e24); + const pcvStatsAfter = await contracts.collateralizationOracle.pcvStats(); + console.log('----------------------------------------------------'); + console.log(' pcvStatsAfter.protocolControlledValue [M]e18 ', pcvStatsAfter.protocolControlledValue / 1e24); + console.log(' pcvStatsAfter.userCirculatingFei [M]e18 ', pcvStatsAfter.userCirculatingFei / 1e24); + console.log(' pcvStatsAfter.protocolEquity [M]e18 ', pcvStatsAfter.protocolEquity / 1e24); + console.log('----------------------------------------------------'); + const pcvDiff = pcvStatsAfter.protocolControlledValue.sub(pcvStatsBefore.protocolControlledValue); + const cFeiDiff = pcvStatsAfter.userCirculatingFei.sub(pcvStatsBefore.userCirculatingFei); + const eqDiff = pcvStatsAfter.protocolEquity.sub(pcvStatsBefore.protocolEquity); + console.log(' PCV diff [M]e18 ', pcvDiff / 1e24); + console.log(' Circ FEI diff [M]e18 ', cFeiDiff / 1e24); + console.log(' Equity diff [M]e18 ', eqDiff / 1e24); + console.log('----------------------------------------------------'); +}; + +export { deploy, setup, teardown, validate }; diff --git a/proposals/description/oa_cr_fix.ts b/proposals/description/oa_cr_fix.ts new file mode 100644 index 000000000..302941f97 --- /dev/null +++ b/proposals/description/oa_cr_fix.ts @@ -0,0 +1,35 @@ +import { ProposalDescription } from '@custom-types/types'; + +const fip_x: ProposalDescription = { + title: 'OA CR Fixes', + commands: [ + { + target: 'collateralizationOracle', + values: '0', + method: 'swapDeposit(address,address)', + arguments: ['{balancerLensBpt30Fei70WethOld}', '{balancerLensBpt30Fei70Weth}'], + description: 'Update B-70WETH-30FEI Lens' + }, + { + target: 'collateralizationOracle', + values: '0', + method: 'removeDeposits(address[])', + arguments: [ + [ + '{rariPool8FeiPCVDepositWrapper}', // Fuse Pool 8 FEI + '{rariPool8DaiPCVDeposit}', // Fuse Pool 8 DAI + '{rariPool8LusdPCVDeposit}', // Fuse Pool 8 LUSD + '{rariPool18FeiPCVDepositWrapper}', // Fuse Pool 18 FEI + '{rariPool27FeiPCVDepositWrapper}', // Fuse Pool 27 FEI + '{rariPool90FeiPCVDepositWrapper}', // Fuse Pool 90 FEI + '{rariPool146EthPCVDeposit}', // Fuse Pool 146 ETH + '{convexPoolPCVDepositWrapper}' // Fuse Pool 156 FEI + ] + ], + description: 'Remove PCV Deposits with bad debt' + } + ], + description: 'Fix Collateralization Oracle config after the Fuse May 2022 hack.' +}; + +export default fip_x; diff --git a/protocol-configuration/collateralizationOracle.ts b/protocol-configuration/collateralizationOracle.ts index b09a7a990..e748be1be 100644 --- a/protocol-configuration/collateralizationOracle.ts +++ b/protocol-configuration/collateralizationOracle.ts @@ -1,14 +1,10 @@ const collateralizationAddresses = { fei: [ 'feiOATimelockWrapper', - 'rariPool8FeiPCVDepositWrapper', 'rariPool6FeiPCVDepositWrapper', 'rariPool19FeiPCVDepositWrapper', 'rariPool24FeiPCVDepositWrapper', 'rariPool25FeiPCVDepositWrapper', - 'rariPool27FeiPCVDepositWrapper', - 'rariPool18FeiPCVDepositWrapper', - 'rariPool90FeiPCVDepositWrapper', 'aaveFeiPCVDepositWrapper', 'rariPool79FeiPCVDepositWrapper', 'rariPool31FeiPCVDepositWrapper', @@ -16,18 +12,11 @@ const collateralizationAddresses = { 'rariPool128FeiPCVDepositWrapper', 'rariPool22FeiPCVDepositWrapper', 'feiBuybackLensNoFee', - 'convexPoolPCVDepositWrapper', 'compoundFeiPCVDepositWrapper', 'turboFusePCVDeposit' ], - lusd: [ - 'liquityFusePoolLusdPCVDeposit', - 'rariPool7LusdPCVDeposit', - 'bammDeposit', - 'lusdPSM', - 'rariPool8LusdPCVDeposit' - ], - dai: ['compoundDaiPCVDepositWrapper', 'daiFixedPricePSM', 'rariPool8DaiPCVDeposit'], + lusd: ['liquityFusePoolLusdPCVDeposit', 'rariPool7LusdPCVDeposit', 'bammDeposit', 'lusdPSM'], + dai: ['compoundDaiPCVDepositWrapper', 'daiFixedPricePSM'], usd: ['namedStaticPCVDepositWrapper', 'd3poolCurvePCVDeposit', 'd3poolConvexPCVDeposit'], bal: ['balancerDepositBalWeth', 'balancerLensVeBalBal'], cream: ['creamDepositWrapper'], @@ -38,7 +27,6 @@ const collateralizationAddresses = { 'uniswapPCVDeposit', 'ethTokemakPCVDeposit', 'ethPSM', - 'rariPool146EthPCVDeposit', 'wethDepositWrapper', 'balancerDepositFeiWeth', 'balancerLensBpt30Fei70Weth', diff --git a/protocol-configuration/dependencies.ts b/protocol-configuration/dependencies.ts index b1ce07647..5a4bcb98c 100644 --- a/protocol-configuration/dependencies.ts +++ b/protocol-configuration/dependencies.ts @@ -73,7 +73,6 @@ const dependencies: DependencyMap = { 'liquityFusePoolLusdPCVDeposit', 'poolPartyFeiPCVDeposit', 'rariTimelock', - 'rariPool146EthPCVDeposit', 'rariPool18FeiPCVDeposit', 'rariPool19DpiPCVDeposit', 'rariPool19FeiPCVDeposit', @@ -90,7 +89,6 @@ const dependencies: DependencyMap = { 'rariPool7FeiPCVDeposit', 'rariPool7LusdPCVDeposit', 'rariPool8FeiPCVDeposit', - 'rariPool90FeiPCVDeposit', 'rariPool91FeiPCVDeposit', 'rariPool9FeiPCVDeposit', 'rariPool9RaiPCVDeposit', @@ -169,7 +167,6 @@ const dependencies: DependencyMap = { 'rariPool79FeiPCVDeposit', 'rariPool7FeiPCVDeposit', 'rariPool8FeiPCVDeposit', - 'rariPool90FeiPCVDeposit', 'rariPool91FeiPCVDeposit', 'rariPool9FeiPCVDeposit', 'restrictedPermissions', @@ -405,9 +402,6 @@ const dependencies: DependencyMap = { poolPartyFeiPCVDeposit: { contractDependencies: ['core', 'fei'] }, - rariPool146EthPCVDeposit: { - contractDependencies: ['core', 'rariPool146Eth'] - }, rariPool146Comptroller: { contractDependencies: ['rariPool146FuseAdmin', 'rariPool146Eth'] }, @@ -415,7 +409,7 @@ const dependencies: DependencyMap = { contractDependencies: ['rariPool146Comptroller'] }, rariPool146Eth: { - contractDependencies: ['rariPool146Comptroller', 'rariPool146EthPCVDeposit'] + contractDependencies: ['rariPool146Comptroller'] }, rariPool18FeiPCVDeposit: { contractDependencies: ['core', 'fei'] @@ -465,9 +459,6 @@ const dependencies: DependencyMap = { rariPool8FeiPCVDeposit: { contractDependencies: ['core', 'rariPool8Fei', 'fei'] }, - rariPool90FeiPCVDeposit: { - contractDependencies: ['core', 'fei', 'rariPool90FeiPCVDepositWrapper'] - }, rariPool91FeiPCVDeposit: { contractDependencies: ['core', 'fei'] }, @@ -523,23 +514,17 @@ const dependencies: DependencyMap = { 'feiBuybackLens', 'feiLusdLens', 'feiOATimelockWrapper', - 'rariPool18FeiPCVDepositWrapper', 'rariPool19DpiPCVDepositWrapper', 'rariPool19FeiPCVDepositWrapper', 'rariPool24FeiPCVDepositWrapper', 'rariPool25FeiPCVDepositWrapper', - 'rariPool27FeiPCVDepositWrapper', 'rariPool31FeiPCVDepositWrapper', 'rariPool6FeiPCVDepositWrapper', - 'rariPool8FeiPCVDepositWrapper', 'rariPool9RaiPCVDepositWrapper', - 'rariPool90FeiPCVDepositWrapper', 'rariPool79FeiPCVDepositWrapper', 'rariPool72FeiPCVDepositWrapper', 'rariPool128FeiPCVDepositWrapper', 'rariPool22FeiPCVDepositWrapper', - 'rariPool8LusdPCVDeposit', - 'rariPool8DaiPCVDeposit', 'voltFusePCVDeposit', 'voltOracle', 'turboFusePCVDeposit', @@ -594,9 +579,6 @@ const dependencies: DependencyMap = { feiOATimelockWrapper: { contractDependencies: ['collateralizationOracle'] }, - rariPool18FeiPCVDepositWrapper: { - contractDependencies: ['collateralizationOracle'] - }, rariPool19DpiPCVDepositWrapper: { contractDependencies: ['collateralizationOracle'] }, @@ -609,18 +591,12 @@ const dependencies: DependencyMap = { rariPool25FeiPCVDepositWrapper: { contractDependencies: ['collateralizationOracle'] }, - rariPool27FeiPCVDepositWrapper: { - contractDependencies: ['collateralizationOracle'] - }, rariPool31FeiPCVDepositWrapper: { contractDependencies: ['collateralizationOracle', 'rariPool31FeiPCVDeposit'] }, rariPool6FeiPCVDepositWrapper: { contractDependencies: ['collateralizationOracle'] }, - rariPool90FeiPCVDepositWrapper: { - contractDependencies: ['collateralizationOracle', 'rariPool90FeiPCVDeposit'] - }, rariPool79FeiPCVDepositWrapper: { contractDependencies: ['collateralizationOracle', 'rariPool79FeiPCVDeposit'] }, @@ -636,9 +612,6 @@ const dependencies: DependencyMap = { rariPool22FeiPCVDepositWrapper: { contractDependencies: ['collateralizationOracle', 'rariPool22FeiPCVDeposit'] }, - rariPool8FeiPCVDepositWrapper: { - contractDependencies: ['collateralizationOracle'] - }, rariPool9RaiPCVDepositWrapper: { contractDependencies: ['collateralizationOracle'] }, @@ -928,7 +901,7 @@ const dependencies: DependencyMap = { contractDependencies: ['rariPool8MasterOracle'] }, rariPool8Dai: { - contractDependencies: ['rariPool8Comptroller', 'rariPool8DaiIrm', 'rariPool8DaiPCVDeposit'] + contractDependencies: ['rariPool8Comptroller', 'rariPool8DaiIrm'] }, rariPool8DaiIrm: { contractDependencies: ['rariPool8Dai'] @@ -1008,14 +981,8 @@ const dependencies: DependencyMap = { delayedPCVMoverWethUniToBal: { contractDependencies: ['core', 'ratioPCVControllerV2'] }, - rariPool8DaiPCVDeposit: { - contractDependencies: ['rariPool8Dai', 'collateralizationOracle'] - }, - rariPool8LusdPCVDeposit: { - contractDependencies: ['rariPool8Lusd', 'collateralizationOracle'] - }, rariPool8Lusd: { - contractDependencies: ['rariPool8LusdPCVDeposit', 'rariPool8Comptroller'] + contractDependencies: ['rariPool8Comptroller'] }, timelock: { contractDependencies: ['feiDAOTimelock'] diff --git a/protocol-configuration/mainnetAddresses.ts b/protocol-configuration/mainnetAddresses.ts index 7d9b9ca02..5c3f82269 100644 --- a/protocol-configuration/mainnetAddresses.ts +++ b/protocol-configuration/mainnetAddresses.ts @@ -224,7 +224,7 @@ const MainnetAddresses: MainnetAddresses = { rariPool18FeiPCVDeposit: { artifactName: 'ERC20CompoundPCVDeposit', address: '0x5A8CB4556e5D5935Af06beab8292905f48131479', - category: AddressCategory.PCV_V1 + category: AddressCategory.Deprecated }, rariPool22FeiPCVDeposit: { artifactName: 'ERC20CompoundPCVDeposit', @@ -249,7 +249,7 @@ const MainnetAddresses: MainnetAddresses = { rariPool27FeiPCVDeposit: { artifactName: 'ERC20CompoundPCVDeposit', address: '0x91f50E3183a8CC30D2A981C3aFA85A2Bf6691c67', - category: AddressCategory.PCV_V1 + category: AddressCategory.Deprecated }, rariPool128FeiPCVDeposit: { artifactName: 'ERC20CompoundPCVDeposit', @@ -314,7 +314,7 @@ const MainnetAddresses: MainnetAddresses = { rariPool90FeiPCVDeposit: { artifactName: 'ERC20CompoundPCVDeposit', address: '0x61d26126D2F8A44b41c1D8E1B1F276551DC8EEc6', - category: AddressCategory.PCV_V1 + category: AddressCategory.Deprecated }, rariPool91FeiPCVDeposit: { artifactName: 'ERC20CompoundPCVDeposit', @@ -396,9 +396,14 @@ const MainnetAddresses: MainnetAddresses = { address: '0xa8E388a1f19f2b33Be8bf2cCeC43641C10b4D1e5', category: AddressCategory.External // not really External, but not PCV }, - balancerLensBpt30Fei70Weth: { + balancerLensBpt30Fei70WethOld: { artifactName: 'BalancerPool2Lens', address: '0xb31F75550e97A2C4c7AC8d4355032B8AE8b9584D', + category: AddressCategory.Deprecated + }, + balancerLensBpt30Fei70Weth: { + artifactName: 'BalancerPool2Lens', + address: '0x673f7DFA863b611dE657759aEDE629b260F4E682', category: AddressCategory.PCV }, balancerLensVeBalBal: { @@ -499,22 +504,22 @@ const MainnetAddresses: MainnetAddresses = { rariPool146EthPCVDeposit: { artifactName: 'EthCompoundPCVDeposit', address: '0xC68412B72e68c30D4E6c0854b439CBBe957146e4', - category: AddressCategory.PCV + category: AddressCategory.Deprecated }, rariPool8DaiPCVDeposit: { artifactName: 'ERC20CompoundPCVDeposit', address: '0x9CC46aB5A714f7cd24C59f33C5769039B5872491', - category: AddressCategory.PCV + category: AddressCategory.Deprecated }, rariPool8LusdPCVDeposit: { artifactName: 'ERC20CompoundPCVDeposit', address: '0xF846eE6E8EE9A6fbf51c7c65105CAbc041c048ad', - category: AddressCategory.PCV + category: AddressCategory.Deprecated }, rariPool18FeiPCVDepositWrapper: { artifactName: 'PCVDepositWrapper', address: '0x07F2DD7E6A78D96c08D0a8212f4097dCC129d629', - category: AddressCategory.PCV + category: AddressCategory.Deprecated }, rariPool19DpiPCVDepositWrapper: { artifactName: 'PCVDepositWrapper', @@ -544,7 +549,7 @@ const MainnetAddresses: MainnetAddresses = { rariPool27FeiPCVDepositWrapper: { artifactName: 'PCVDepositWrapper', address: '0xe2e35097638F0Ff2EeCA2EF70F352Be37431945f', - category: AddressCategory.PCV + category: AddressCategory.Deprecated }, rariPool6FeiPCVDepositWrapper: { artifactName: 'PCVDepositWrapper', @@ -559,7 +564,7 @@ const MainnetAddresses: MainnetAddresses = { rariPool8FeiPCVDepositWrapper: { artifactName: 'PCVDepositWrapper', address: '0xD6598a23418c7FEf7c0Dc863265515B623B720F9', - category: AddressCategory.PCV + category: AddressCategory.Deprecated }, rariPool9FeiPCVDepositWrapper: { artifactName: 'PCVDepositWrapper', @@ -579,7 +584,7 @@ const MainnetAddresses: MainnetAddresses = { rariPool90FeiPCVDepositWrapper: { artifactName: 'PCVDepositWrapper', address: '0xec54148CbC47bFF8FCc5e04e5E8083aDb8aF9aD9', - category: AddressCategory.PCV + category: AddressCategory.Deprecated }, rariPool91FeiPCVDepositWrapper: { artifactName: 'PCVDepositWrapper', @@ -1974,7 +1979,7 @@ const MainnetAddresses: MainnetAddresses = { convexPoolPCVDepositWrapper: { artifactName: 'PCVDepositWrapper', address: '0x1370CA8655C255948d6c6110066d78680601B7c2', - category: AddressCategory.PCV + category: AddressCategory.Deprecated }, compoundFeiPCVDepositWrapper: { artifactName: 'PCVDepositWrapper', diff --git a/test/integration/proposals_config.ts b/test/integration/proposals_config.ts index 8c87408e7..6c240ae19 100644 --- a/test/integration/proposals_config.ts +++ b/test/integration/proposals_config.ts @@ -1,6 +1,8 @@ import { ProposalCategory, ProposalsConfigMap } from '@custom-types/types'; +import oa_cr_fix from '@proposals/description/oa_cr_fix'; import withdraw_aave_comp_fei from '@proposals/description/withdraw_aave_comp_fei'; +// import fip_xx_proposal from '@proposals/description/fip_xx'; const proposals: ProposalsConfigMap = { withdraw_aave_comp_fei: { @@ -11,6 +13,25 @@ const proposals: ProposalsConfigMap = { affectedContractSignoff: [''], deprecatedContractSignoff: [''], category: ProposalCategory.TC + }, + oa_cr_fix: { + deploy: false, // deploy flag for whether to run deploy action during e2e tests or use mainnet state + totalValue: 0, // amount of ETH to send to DAO execution + proposal: oa_cr_fix, // full proposal file, imported from '@proposals/description/fip_xx.ts' + proposalId: '', + affectedContractSignoff: ['collateralizationOracle', 'balancerLensBpt30Fei70Weth'], + deprecatedContractSignoff: [ + 'balancerLensBpt30Fei70WethOld', + 'rariPool8FeiPCVDepositWrapper', + 'rariPool8DaiPCVDeposit', + 'rariPool8LusdPCVDeposit', + 'rariPool18FeiPCVDepositWrapper', + 'rariPool27FeiPCVDepositWrapper', + 'rariPool90FeiPCVDepositWrapper', + 'rariPool146EthPCVDeposit', + 'convexPoolPCVDepositWrapper' + ], + category: ProposalCategory.OA } }; diff --git a/test/integration/tests/dependencies.ts b/test/integration/tests/dependencies.ts index bfced5e5a..ce25a9cd3 100644 --- a/test/integration/tests/dependencies.ts +++ b/test/integration/tests/dependencies.ts @@ -112,7 +112,10 @@ describe('e2e-dependencies', function () { // addresses[deposit] may be undefined if a deposit is added to the // dependencies and permissions/collateralizationOracle files, but // is not yet deployed on the mainnet (i.e. in mainnetAddresses.ts). - expect(addresses[deposit].category).to.not.be.equal('Deprecated'); + expect(addresses[deposit].category).to.not.be.equal( + 'Deprecated', + 'Deposit [' + deposit + '] is in collateralizationoracle.ts and has AddressCategory.Deprecated' + ); } } } diff --git a/test/unit/pcv/balancer/BalancerPool2Lens.test.ts b/test/unit/pcv/balancer/BalancerPool2Lens.test.ts new file mode 100644 index 000000000..b65261f4c --- /dev/null +++ b/test/unit/pcv/balancer/BalancerPool2Lens.test.ts @@ -0,0 +1,115 @@ +import { getAddresses, getImpersonatedSigner, getCore, expectApproxAbs } from '@test/helpers'; +import chai, { expect } from 'chai'; +import CBN from 'chai-bn'; +import { ethers } from 'hardhat'; +import { Signer } from 'ethers'; +import { + BalancerPool2Lens, + MockERC20, + MockOracle, + MockVault, + MockPCVDepositV2, + MockWeightedPool +} from '@custom-types/contracts'; + +before(async () => { + chai.use(CBN(ethers.BigNumber)); +}); + +const toBN = ethers.BigNumber.from; + +describe('BalancerPool2Lens', function () { + let userAddress: string; + let pool: MockWeightedPool; + let vault: MockVault; + let token: MockERC20; + let oracle1: MockOracle; + let oracle2: MockOracle; + let deposit: MockPCVDepositV2; + let lens: BalancerPool2Lens; + + const impersonatedSigners: { [key: string]: Signer } = {}; + + before(async () => { + const addresses = await getAddresses(); + + // add any addresses you want to impersonate here + const impersonatedAddresses = [addresses.userAddress]; + + for (const address of impersonatedAddresses) { + impersonatedSigners[address] = await getImpersonatedSigner(address); + } + }); + + beforeEach(async function () { + ({ userAddress } = await getAddresses()); + + token = await (await ethers.getContractFactory('MockERC20')).deploy(); + const tokenB = await (await ethers.getContractFactory('MockERC20')).deploy(); + + vault = await (await ethers.getContractFactory('MockVault')).deploy([token.address, tokenB.address], userAddress); + + await vault.setBalances([ethers.constants.WeiPerEther.mul(20), ethers.constants.WeiPerEther.mul(30000)]); + + pool = await ethers.getContractAt('MockWeightedPool', await vault._pool()); + + const core = await getCore(); + deposit = await ( + await ethers.getContractFactory('MockPCVDepositV2') + ).deploy( + core.address, + pool.address, + 10000, // deposit reports 10000 LP tokens + 0 + ); + + await pool.mint(pool.address, 89999); + await pool.mint(deposit.address, 10000); + + // set weights to 70%, 30% + await pool.updateWeightsGradually(0, 0, [ + ethers.constants.WeiPerEther.div(100).mul(70), + ethers.constants.WeiPerEther.div(100).mul(30) + ]); + await pool.mockSetNormalizedWeights([ + ethers.constants.WeiPerEther.div(100).mul(70), + ethers.constants.WeiPerEther.div(100).mul(30) + ]); + + oracle1 = await (await ethers.getContractFactory('MockOracle')).deploy('3500'); + oracle2 = await (await ethers.getContractFactory('MockOracle')).deploy('1'); + + lens = await ( + await ethers.getContractFactory('BalancerPool2Lens') + ).deploy(deposit.address, token.address, pool.address, oracle1.address, oracle2.address, false, true); + }); + + // pool contains 20 tokenA, 30,000 tokenB + // tokenA price 3,500 $, tokenB price 1 $ + // -> pool contains 70,000$, 30,000$ + // pool weight 70% tokenA, 30% tokenB (currently balanced) + // userAddress owns 10% of the pool (10,000 / 100,000) + + it('initial state', async function () { + expect(await lens.balanceReportedIn()).to.be.equal(token.address); + expect(await lens.pool()).to.be.equal(pool.address); + expect(await lens.balancerVault()).to.be.equal(vault.address); + expect(await lens.feiInPair()).to.be.true; + expect(await lens.feiIsReportedIn()).to.be.false; + expect(await lens.reportedOracle()).to.be.equal(oracle1.address); + expect(await lens.otherOracle()).to.be.equal(oracle2.address); + + expect(await pool.balanceOf(pool.address)).to.be.equal('90000'); + expect(await pool.balanceOf(deposit.address)).to.be.equal('10000'); + }); + + it('balance', async function () { + expectApproxAbs(await lens.balance(), ethers.constants.WeiPerEther.mul('2'), '1'); + }); + + it('resistantBalanceAndFei', async function () { + const balances = await lens.resistantBalanceAndFei(); + expectApproxAbs(balances[0], ethers.constants.WeiPerEther.mul('2'), '1'); + expectApproxAbs(balances[1], ethers.constants.WeiPerEther.mul('3000'), '1'); + }); +});