-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CR Oracle + Timelock Ops #925
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
14967500 | ||
15004720 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { ERC20PCVDepositWrapper__factory } from '@custom-types/contracts'; | ||
import { | ||
DeployUpgradeFunc, | ||
NamedAddresses, | ||
SetupUpgradeFunc, | ||
TeardownUpgradeFunc, | ||
ValidateUpgradeFunc | ||
} from '@custom-types/types'; | ||
import chai, { expect } from 'chai'; | ||
import hre from 'hardhat'; | ||
import { time } from '@test/helpers'; | ||
import { ethers } from 'ethers'; | ||
import CBN from 'chai-bn'; | ||
|
||
chai.use(CBN(ethers.BigNumber)); | ||
|
||
const fipNumber = 'tip_115'; | ||
|
||
// Do any deployments | ||
// This should exclusively include new contract deployments | ||
const deploy: DeployUpgradeFunc = async (deployAddress: string, addresses: NamedAddresses, logging: boolean) => { | ||
const factory = (await hre.ethers.getContractFactory('ERC20PCVDepositWrapper')) as ERC20PCVDepositWrapper__factory; | ||
const rariTimelockFeiOldLens = await factory.deploy(addresses.rariInfraFeiTimelock, addresses.fei, true); | ||
await rariTimelockFeiOldLens.deployTransaction.wait(); | ||
|
||
const tribalCouncilTimelockFeiLens = await factory.deploy(addresses.tribalCouncilTimelock, addresses.fei, true); | ||
await tribalCouncilTimelockFeiLens.deployTransaction.wait(); | ||
|
||
return { rariTimelockFeiOldLens, tribalCouncilTimelockFeiLens }; | ||
}; | ||
|
||
// 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(`No actions to complete in setup for fip ${fipNumber}`); | ||
}; | ||
|
||
// 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) => { | ||
expect(await contracts.rariInfraFeiTimelock.beneficiary()).to.be.equal(addresses.tribalCouncilTimelock); | ||
expect(await contracts.rariInfraTribeTimelock.beneficiary()).to.be.equal(addresses.tribalCouncilTimelock); | ||
expect(await contracts.rariTimelockFeiOldLens.balance()).to.be.equal('3178504756468797564687976'); | ||
expect(await contracts.tribalCouncilTimelockFeiLens.balance()).to.be.equal('0'); | ||
expect(await contracts.rariTimelockFeiOldLens.balanceReportedIn()).to.be.equal(addresses.fei); | ||
expect(await contracts.tribalCouncilTimelockFeiLens.balanceReportedIn()).to.be.equal(addresses.fei); | ||
expect(await contracts.namedStaticPCVDepositWrapper.numDeposits()).to.be.equal('0'); | ||
expect(await contracts.ethToDaiLBPSwapper.swapEndTime()).to.be.gt( | ||
ethers.BigNumber.from((await time.latest()).toString()) | ||
); | ||
}; | ||
|
||
export { deploy, setup, teardown, validate }; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { TemplatedProposalDescription } from '@custom-types/types'; | ||
|
||
const tip_115: TemplatedProposalDescription = { | ||
title: 'TIP-115: Collateralization and Operations Updates', | ||
commands: [ | ||
{ | ||
target: 'collateralizationOracle', | ||
values: '0', | ||
method: 'addDeposit(address)', | ||
arguments: (addresses) => [addresses.rariTimelockFeiOldLens], | ||
description: 'Add FEI lens to CR oracle for old timelocked FEI' | ||
}, | ||
{ | ||
target: 'collateralizationOracle', | ||
values: '0', | ||
method: 'addDeposit(address)', | ||
arguments: (addresses) => [addresses.tribalCouncilTimelockFeiLens], | ||
description: 'Add FEI lens to CR oracle for tribal council timelock FEI' | ||
}, | ||
{ | ||
target: 'collateralizationOracle', | ||
values: '0', | ||
method: 'removeDeposit(address)', | ||
arguments: (addresses) => [addresses.namedStaticPCVDepositWrapper], | ||
description: 'Remove NamedStaticPCVDepositWrapper from CR oracle' | ||
}, | ||
{ | ||
target: 'namedStaticPCVDepositWrapper', | ||
values: '0', | ||
method: 'removeDeposit(uint256)', | ||
arguments: (addresses) => [1], | ||
description: 'Remove NamedStaticPCVDepositWrapper FEI deposit' | ||
}, | ||
{ | ||
target: 'namedStaticPCVDepositWrapper', | ||
values: '0', | ||
method: 'removeDeposit(uint256)', | ||
arguments: (addresses) => [0], | ||
description: 'Remove NamedStaticPCVDepositWrapper INDEX deposit' | ||
}, | ||
{ | ||
target: 'rariInfraFeiTimelock', | ||
values: '0', | ||
method: 'acceptBeneficiary()', | ||
arguments: (addresses) => [], | ||
description: 'Accept beneficiary of rari infra fei timelock' | ||
}, | ||
{ | ||
target: 'rariInfraTribeTimelock', | ||
values: '0', | ||
method: 'acceptBeneficiary()', | ||
arguments: (addresses) => [], | ||
description: 'Accept beneficiary of rari infra tribe timelock' | ||
}, | ||
|
||
//// Trigger new LBP of ETH | ||
{ | ||
target: 'pcvGuardianNew', | ||
values: '0', | ||
method: 'withdrawToSafeAddress(address,address,uint256,bool,bool)', | ||
arguments: (addresses) => [ | ||
addresses.daiFixedPricePSM, | ||
addresses.ethToDaiLBPSwapper, | ||
'1000000000000000000000000', | ||
false, | ||
false | ||
], | ||
description: 'Withdraw 1M DAI to LBP Swapper' | ||
}, | ||
{ | ||
target: 'pcvGuardianNew', | ||
values: '0', | ||
method: 'withdrawToSafeAddress(address,address,uint256,bool,bool)', | ||
arguments: (addresses) => [ | ||
addresses.ethPSM, | ||
addresses.ethToDaiLBPSwapper, | ||
'10000000000000000000000', | ||
false, | ||
false | ||
], | ||
description: 'Withdraw 10k ETH to LBP Swapper' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Weights are 95 / 5 . You're sending $1m DAI and ~$10.5m ETH. So overfunding by $500k, should be fine |
||
}, | ||
{ | ||
target: 'ethToDaiLBPSwapper', | ||
values: '0', | ||
method: 'swap()', | ||
arguments: (addresses) => [], | ||
description: 'Trigger new ETH LBP swap' | ||
}, | ||
{ | ||
target: 'core', | ||
values: '0', | ||
method: 'grantRole(bytes32,address)', | ||
arguments: (addresses) => [ | ||
'0x471cfe1a44bf1b786db7d7104d51e6728ed7b90a35394ad7cc424adf8ed16816', // SWAP_ADMIN_ROLE | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit, you can import |
||
addresses.tribalCouncilSafe | ||
], | ||
description: 'Grant SWAP_ADMIN_ROLE to Tribal Council multisig' | ||
} | ||
], | ||
description: `Executes a few cleanup actions related to collateralization and operations: | ||
1. Add a collateralization FEI lens to the FEI in the tribal council timelock and old rari timelocks | ||
2. Accept beneficiary of the old rari timelocks to tribal council timelock. | ||
3. Remove deprecated namedStaticPCVDeposit from collateralization oracle. | ||
4. Trigger new ETH LBP to convert 10k ETH to DAI. | ||
5. Grant tribal council safe the SWAP_ADMIN_ROLE to initiate LBPs after governance funds them. | ||
` | ||
}; | ||
|
||
export default tip_115; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -130,57 +130,4 @@ describe('e2e-buybacks', function () { | |
expectApprox(afterStats[2], beforeStats[2].sub(beforeBalance)); | ||
}); | ||
}); | ||
|
||
describe('Collateralization Oracle Keeper', async function () { | ||
it('can only call when deviation or time met', async function () { | ||
const { namedStaticPCVDepositWrapper, collateralizationOracleWrapper, collateralizationOracleKeeper, fei } = | ||
contracts; | ||
|
||
const beforeBalance = await fei.balanceOf(deployAddress); | ||
|
||
// set Chainlink ETHUSD to a fixed 4,000$ value | ||
await overwriteChainlinkAggregator(contractAddresses.chainlinkEthUsdOracle, '400000000000', '8'); | ||
|
||
await collateralizationOracleWrapper.update(); | ||
|
||
// After updating everything should be up to date | ||
expect(await collateralizationOracleWrapper.isOutdatedOrExceededDeviationThreshold()).to.be.false; | ||
|
||
// After time increase, should be outdated | ||
await increaseTime(await collateralizationOracleWrapper.remainingTime()); | ||
|
||
expect(await collateralizationOracleWrapper.isOutdatedOrExceededDeviationThreshold()).to.be.true; | ||
expect(await collateralizationOracleWrapper.isOutdated()).to.be.true; | ||
expect(await collateralizationOracleWrapper.isExceededDeviationThreshold()).to.be.false; | ||
|
||
// UpdateIfOutdated succeeds | ||
await collateralizationOracleWrapper.updateIfOutdated(); | ||
|
||
expect(await collateralizationOracleWrapper.isOutdatedOrExceededDeviationThreshold()).to.be.false; | ||
|
||
// Increase PCV balance to exceed deviation threshold | ||
const pcvStats = await collateralizationOracleWrapper.pcvStats(); | ||
await namedStaticPCVDepositWrapper.addDeposit({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this test relies on named static PCV deposit which will be deprecated in this proposal. Erwan's #923 also deprecates the keeper |
||
depositName: 'massive test deposit', | ||
usdAmount: pcvStats[0], | ||
feiAmount: 1, | ||
underlyingTokenAmount: 1, | ||
underlyingToken: ethers.constants.AddressZero | ||
}); | ||
|
||
expect(await collateralizationOracleWrapper.isOutdatedOrExceededDeviationThreshold()).to.be.true; | ||
expect(await collateralizationOracleWrapper.isOutdated()).to.be.false; | ||
expect(await collateralizationOracleWrapper.isExceededDeviationThreshold()).to.be.true; | ||
|
||
// Keeper is incentivized to update oracle | ||
await increaseTime(await collateralizationOracleKeeper.MIN_MINT_FREQUENCY()); | ||
|
||
await collateralizationOracleKeeper.mint(); | ||
|
||
const incentive = await collateralizationOracleKeeper.incentiveAmount(); | ||
expect(beforeBalance.add(incentive)).to.be.equal(await fei.balanceOf(deployAddress)); | ||
|
||
expect(await collateralizationOracleWrapper.isOutdatedOrExceededDeviationThreshold()).to.be.false; | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depends how confident are, but I would probably make sure you can do a swap via the LBP pool here