-
Notifications
You must be signed in to change notification settings - Fork 47
minter: Add inflation bounds to inflation adjustment algorithm #645
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
base: delta
Are you sure you want to change the base?
minter: Add inflation bounds to inflation adjustment algorithm #645
Conversation
Suggested further actions:
|
// Transfer state from old Minter | ||
currentMintableTokens = oldMinter.currentMintableTokens(); | ||
currentMintedTokens = oldMinter.currentMintedTokens(); | ||
inflation = oldMinter.inflation(); |
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.
Should we copy all fields including inflationChange
and targetBondingRate
to make sure we get a consistent state snaphot? Otherwise, we'd be relying on the transaction that constructed the contract to have initialized it with the same values as the current minter.
We usually run the contract creation separately so that we have a fixed address for the governor transaction. In that case it probably makes sense to make the upgrade tx "self-contained", copying all state, not relying on args configured in other txs. WDYT?
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.
There are two reasons why we thought it would rather be more confusing:
- We wouldn't be able to copy all possible fields, since
maxInflation
andminInflation
are not part of the currently deployed contract. In other words it would be confusing during the next upgrade that everything is copied except for those 2 values - The overwrite of other arguments is redundant and can create additional confusion. For example, in case governance decides to also change some of the configurable parameters (e.g.
inflationChange
) during the Minter upgrade, it will result in 1) deploying the contract with the new or some values 2) callingmigrateOldMinterState
that will reset them to the old state 3) callingset*
functions to set them to the new values
Based on this, we've decided to update only the minimum required state that is dynamically changing.
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.
The problem is that the contracts are not created on the governance transaction, so someone would need to have run a separate transaction first to deploy the new Minter
contract. This transaction would not be on governor-scripts
repo so it would need to be reviewed separately, creating further complexity on the deployment flow (or at least that's how I remember we did it before).
So IMO an extra transaction to change any other parameters that the governance wants would be preferred, as it would also be very explicit (and not set on a "deploy contract" transaction that is not necessarily audited on the governance process).
Regarding not copying the maxInflation
and minInflation
, I think it could be covered by a local comment saying that the fields were added with the migration function, so they should be copied if a new version is made. WDYT?
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.
creating further complexity on the deployment flow (or at least that's how I remember we did it before).
I'm not sure where the additional complexity is coming from, as the deployed contract and its state have to be reviewed anyway. Typically, the review of the contract should be part of the standard "governance payload review": if the payload mentions/interacts with a new contract, the code as well as the state have to be checked. In my opinion, having 2 places where a state variable is being modified is rather confusing than "explicit".
So IMO an extra transaction to change any other parameters that the governance wants would be preferred, as it would also be very explicit (and not set on a "deploy contract" transaction that is not necessarily audited on the governance process).
Same problem here: do you then would also suggest to set inflation ceiling and floor in the governance payload to make it explicit? (although those values have already been set at deployment via the constructor arguments)
Regarding not copying the
maxInflation
andminInflation
, I think it could be covered by a local comment
If we still would go with updating migrateOldMinterState
scope, what do you mean by the "local" comment? Some kind of TODO comment inside the function (e.g. "TODO: add inflationCeiling and inflationFloor once old miter has those values")?
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## delta #645 +/- ##
===============================================
Coverage 100.00000% 100.00000%
===============================================
Files 29 29
Lines 1331 1354 +23
Branches 223 232 +9
===============================================
+ Hits 1331 1354 +23
Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
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.
LGTM! The only required change is fixing the name of the setinflationCeiling/Floor
functions
contracts/token/IMinter.sol
Outdated
function inflationCeiling() external view returns (uint256); | ||
|
||
function minInflation() external view returns (uint256); | ||
function inflationFloor() external view returns (uint256); |
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.
I like the rename! Make sure there's no occurences of [Mm]ax.+[Ii]nflation
on the project anymore 👀
contracts/token/Minter.sol
Outdated
*/ | ||
function setMinInflation(uint256 _minInflation) external onlyControllerOwner { | ||
function setinflationFloor(uint256 _inflationFloor) external onlyControllerOwner { |
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.
Probably mis-replaced the name here:
function setinflationFloor(uint256 _inflationFloor) external onlyControllerOwner { | |
function setInflationFloor(uint256 _inflationFloor) external onlyControllerOwner { |
Will need to rename in other places like tests etc
contracts/token/Minter.sol
Outdated
*/ | ||
function setMaxInflation(uint256 _maxInflation) external onlyControllerOwner { | ||
function setinflationCeiling(uint256 _inflationCeiling) external onlyControllerOwner { |
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.
Same
function setinflationCeiling(uint256 _inflationCeiling) external onlyControllerOwner { | |
function setInflationCeiling(uint256 _inflationCeiling) external onlyControllerOwner { |
test/unit/Minter.js
Outdated
const startInflation = await minter.inflation() | ||
// Ensure the logic is unaffected by the target bonding rate | ||
for (const targetBondingRate of [400, 500, 600]) { | ||
it("inflation is increased IF inflation < inflationFloor (independent from bonding rate)", async () => { |
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.
nit: Even better than the parenthesis would be specifying the bonding rate on the test title
it("inflation is increased IF inflation < inflationFloor (independent from bonding rate)", async () => { | |
it($"inflation is increased IF inflation < inflationFloor (targetBondingRate=${targetBondingRate})", async () => { |
Same below
What does this pull request do? Explain your changes. (required)
This PR extends the original PR (introduced inflation bounds for the Minter) with tests and other changes required for deploying the contract and merging the PR.
Specific updates (required)
maxInflation
andminInflation
constructor arguments, setters and the updated inflation logicminInflation
lower bounddeploy_contracts.ts
logic to match on-chain stateIMinter.sol
interfaceHow did you test each of these updates (required)
We used the existing hardhat setup to extend the coverage for the newly added code:
maxInflation
constructor argument can’t be > 100%minInflation
constructor argument can’t be > 100%minInflation
constructor argument can’t be >maxInflation
minInflation
constructor argument can be same asmaxInflation
and can be0
setMinInflation
function can only be called by the Controller ownersetMinInflation
function fails if providedminInflation
> 100%setMinInflation
function fails if providedminInflation
>maxInflation
setMinInflation
can setminInflation
to 0,maxInflation
or other valid valuesetMaxInflation
function can only be called by the Controller ownersetMaxInflation
function fails if providedmaxInflation
> 100%setMaxInflation
function fails if providedmaxInflation
<minInflation
setMaxInflation
can setmaxInflation
to 0,minInflation
or other valid valuemigrateOldMinterState
function can only be called by the Controller ownermigrateOldMinterState
function can only be called when old minter is still registered in the controllermigrateOldMinterState
function successfully transfers old minter variables to the current minterinflation
is increased up tomaxInflation
IFcurrent < targetBondingRate
inflation
is increased up tominInflation
IFinflation < minInflation
(independent from the bonding rate)inflation
is decreased down tominInflation
IFcurrent > targetBondingRate
inflation
is decreased down tomaxInflation
IFinflation > maxInflation
(independent from the bonding rate)inflation
is maintained IFcurrent = targetBondingRate
AND withinminInflation
andmaxInflation
inflation
is maintained IFminInflation = maxInflation
(independent from the bonding rate)migrateToNewMinter
on the previous MintermigrateOldMinterState
on the new MinterMINTER_ROLE
to the new MinterMINTER_ROLE
from the previous MinterMinterUpgrade
that previously ensured that internal state is zeroed, changed to ensure state of the 3 “dynamic” variables is correctly migratedMinterUpgrade
that previously ensured that user received 0 rewards after the upgrade is changed to ensure received reward is greater than 0We also took an opportunity to improve the CI by:
test:coverage:check
command thatexit
s with non-zero code, if coverage is not 100%test.yaml
workflow that executes the above commandTo prepare for the new Minter deployment, we’ve also manually done the following checks:
@openzeppelin/contracts/token/ERC20/IERC20.sol
dependency was updated. Here is the diff: only comments and argument names were changed, this has no effect on the actual bytecode@openzeppelin/contracts/utils/math/SafeMath.sol
dependency was updated. Here is the diff: only comments and formatting of the code were changed, this has no effect on the actual bytecodecontracts/bonding/IBondingManager.sol
was updated. Here is the diff: 1 new event and 2 new functions were added, unused by the Minter contractDoes this pull request close any open issues?
No, but it addresses the discussion started on Livepeer Forum and in the original PR.
Checklist:
README and other documentation updatedℹ️ We found no relevant documentation of the Minter contract inside this repository
yarn test
passNext steps
maxInflation
andminInflation
values for the deployment (although not a blocker for this PR, since those values can be changed after the deployment during the actual governor update)